OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [soc_spi.adoc] - Blame information for rev 73

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 60 zero_gravi
<<<
2
:sectnums:
3
==== Serial Peripheral Interface Controller (SPI)
4
 
5
[cols="<3,<3,<4"]
6
[frame="topbot",grid="none"]
7
|=======================
8
| Hardware source file(s): | neorv32_spi.vhd |
9
| Software driver file(s): | neorv32_spi.c |
10
|                          | neorv32_spi.h |
11
| Top entity port:         | `spi_sck_o` | 1-bit serial clock output
12 65 zero_gravi
|                          | `spi_sdo_o` | 1-bit serial data output
13
|                          | `spi_sdi_i` | 1-bit serial data input
14 60 zero_gravi
|                          | `spi_csn_i` | 8-bit dedicated chip select (low-active)
15
| Configuration generics:  | _IO_SPI_EN_ | implement SPI controller when _true_
16
| CPU interrupts:          | fast IRQ channel 6 | transmission done interrupt (see <<_processor_interrupts>>)
17
|=======================
18
 
19 65 zero_gravi
 
20 60 zero_gravi
**Theory of Operation**
21
 
22 65 zero_gravi
SPI is a synchronous serial transmission interface for fast on-board communications.
23
The NEORV32 SPI transceiver supports 8-, 16-, 24- and 32-bit wide transmissions.
24
The unit provides 8 dedicated chip select signals via the top entity's `spi_csn_o` signal, which are
25
directly controlled by the SPI module (no additional GPIO required).
26 60 zero_gravi
 
27 66 zero_gravi
[NOTE]
28
The NEORV32 SPI module only supports _host mode_. Transmission are initiated only by the processor's SPI module
29
(and not by an external SPI module).
30
 
31 65 zero_gravi
The SPI unit is enabled by setting the _SPI_CTRL_EN_ bit in the `CTRL` control register. No transfer can be initiated
32
and no interrupt request will be triggered if this bit is cleared. Furthermore, a transfer being in process
33
can be terminated at any time by clearing this bit.
34 60 zero_gravi
 
35 66 zero_gravi
[IMPORTANT]
36
Changes to the `CTRL` control register should be made only when the SPI module is idle as they directly effect
37
transmissions being in-progress.
38
 
39
[TIP]
40
A transmission can be terminated at any time by disabling the SPI module
41
by clearing the _SPI_CTRL_EN_ control register bit.
42
 
43 65 zero_gravi
The data quantity to be transferred within a single transmission is defined via the _SPI_CTRL_SIZEx_ bits.
44 66 zero_gravi
The SPI module supports 8-bit (`00`), 16-bit (`01`), 24-bit (`10`) and 32-bit (`11`) transfers.
45 60 zero_gravi
 
46 65 zero_gravi
A transmission is started when writing data to the `DATA` register. The data must be LSB-aligned. So if
47
the SPI transceiver is configured for less than 32-bit transfers data quantity, the transmit data must be placed
48
into the lowest 8/16/24 bit of `DATA`. Vice versa, the received data is also always LSB-aligned. Application
49
software should only actually process the amount of bits that were configured using _SPI_CTRL_SIZEx_ when
50
reading `DATA`.
51 60 zero_gravi
 
52 66 zero_gravi
[NOTE]
53
The NEORV32 SPI module only support MSB-first mode. Data can be reversed before writing `DATA` (for TX) / after
54
reading `DATA` (for RX) to implement LSB-first transmissions. Note that in both cases data in ` DATA` still
55
needs to be LSB-aligned.
56 65 zero_gravi
 
57
[TIP]
58
The actual transmission length is left to the user: after asserting chip-select an arbitrary amount of
59
transmission with arbitrary data quantity (_SPI_CTRL_SIZEx_) can be made before de-asserting chip-select again.
60
 
61 66 zero_gravi
The SPI controller features 8 dedicated chip-select lines. These lines are controlled via the control register's
62
_SPI_CTRL_CSx_ bits. When a specific _SPI_CTRL_CSx_ bit is **set**, the according chip-select line `spi_csn_o(x)`
63
goes **low** (low-active chip-select lines).
64 65 zero_gravi
 
65 66 zero_gravi
[TIP]
66
The dedicated SPI chip-select signals can be seen as _general purpose_ outputs. These are intended to control
67
the accessed device's chip-select signal but can also be use for controlling other shift register signals
68
(like data strobe or output-enables).
69 65 zero_gravi
 
70
 
71
**SPI Clock Configuration**
72
 
73
The SPI module supports all _standard SPI clock modes_ (0, 1, 2, 3), which is via the two control register bits
74
_SPI_CTRL_CPHA_ and _SPI_CTRL_CPOL_. The _SPI_CTRL_CPHA_ bit defines the _clock phase_ and the _SPI_CTRL_CPOL_
75
bit defines the _clock polarity_.
76
 
77
.SPI clock modes; image from https://en.wikipedia.org/wiki/File:SPI_timing_diagram2.svg (license: (Wikimedia) https://en.wikipedia.org/wiki/Creative_Commons[Creative Commons] https://creativecommons.org/licenses/by-sa/3.0/deed.en[Attribution-Share Alike 3.0 Unported])
78
image::SPI_timing_diagram2.wikimedia.png[]
79
 
80
.SPI standard clock modes
81
[cols="<2,^1,^1,^1,^1"]
82
[options="header",grid="rows"]
83
|=======================
84
|                 | Mode 0 | Mode 1 | Mode 2 | Mode 4
85
| _SPI_CTRL_CPOL_ |    `0` |    `0` |    `1` |    `1`
86
| _SPI_CTRL_CPHA_ |    `0` |    `1` |    `0` |    `1`
87
|=======================
88
 
89
The SPI clock frequency (`spi_sck_o`) is programmed by the 3-bit _SPI_CTRL_PRSCx_ clock prescaler.
90
The following prescalers are available:
91
 
92 60 zero_gravi
.SPI prescaler configuration
93
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
94
[options="header",grid="rows"]
95
|=======================
96 64 zero_gravi
| **`SPI_CTRL_PRSCx`**        | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
97 60 zero_gravi
| Resulting `clock_prescaler` |       2 |       4 |       8 |      64 |     128 |    1024 |    2048 |    4096
98
|=======================
99
 
100 65 zero_gravi
Based on the _SPI_CTRL_PRSCx_ configuration, the actual SPI clock frequency f~SPI~ is derived from the processor's
101
main clock f~main~ and is determined by:
102 60 zero_gravi
 
103
_**f~SPI~**_ = _f~main~[Hz]_ / (2 * `clock_prescaler`)
104
 
105 65 zero_gravi
Hence, the maximum SPI clock is f~main~ / 4.
106 60 zero_gravi
 
107 70 zero_gravi
.High-Speed SPI mode
108
[TIP]
109
The module provides a "high-speed" SPI mode. In this mode the clock prescaler configuration (SPI_CTRL_PRSCx) is ignored
110
and the SPI clock operates at f~main~ / 2 (half of the processor's main clock). High speed SPI mode is enabled by setting
111
the control register's _SPI_CTRL_HIGHSPEED_ bit.
112 65 zero_gravi
 
113 70 zero_gravi
 
114 65 zero_gravi
**SPI Interrupt**
115
 
116 68 zero_gravi
The SPI module provides a single interrupt to signal "transmission done" to the CPU. Whenever the SPI
117 69 zero_gravi
module completes the current transfer operation, the interrupt is triggered and has to be explicitly cleared again
118 73 zero_gravi
by writing zero to the according <<_mip>> CSR bit.
119 65 zero_gravi
 
120
 
121 64 zero_gravi
.SPI register map (`struct NEORV32_SPI`)
122 60 zero_gravi
[cols="<2,<2,<4,^1,<7"]
123
[options="header",grid="all"]
124
|=======================
125
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
126 70 zero_gravi
.19+<| `0xffffffa8` .19+<| `NEORV32_SPI.CTRL` <|`0` _SPI_CTRL_CS0_        ^| r/w .8+<| Direct chip-select 0..7; setting `spi_csn_o(x)` low when set
127
                                              <|`1` _SPI_CTRL_CS1_        ^| r/w
128
                                              <|`2` _SPI_CTRL_CS2_        ^| r/w
129
                                              <|`3` _SPI_CTRL_CS3_        ^| r/w
130
                                              <|`4` _SPI_CTRL_CS4_        ^| r/w
131
                                              <|`5` _SPI_CTRL_CS5_        ^| r/w
132
                                              <|`6` _SPI_CTRL_CS6_        ^| r/w
133
                                              <|`7` _SPI_CTRL_CS7_        ^| r/w
134
                                              <|`8` _SPI_CTRL_EN_         ^| r/w <| SPI enable
135
                                              <|`9` _SPI_CTRL_CPHA_       ^| r/w <| clock phase (`0`=sample RX on rising edge & update TX on falling edge; `1`=sample RX on falling edge & update TX on rising edge)
136
                                              <|`10` _SPI_CTRL_PRSC0_     ^| r/w .3+| 3-bit clock prescaler select
137
                                              <|`11` _SPI_CTRL_PRSC1_     ^| r/w
138
                                              <|`12` _SPI_CTRL_PRSC2_     ^| r/w
139
                                              <|`13` _SPI_CTRL_SIZE0_     ^| r/w .2+<| transfer size (`00`=8-bit, `01`=16-bit, `10`=24-bit, `11`=32-bit)
140
                                              <|`14` _SPI_CTRL_SIZE1_     ^| r/w
141
                                              <|`15` _SPI_CTRL_CPOL_      ^| r/w <| clock polarity
142
                                              <|`16` _SPI_CTRL_HIGHSPEED_ ^| r/w <| enable SPI high-speed mode (ignoring _SPI_CTRL_PRSC_)
143
                                              <|`17:30`                   ^| r/- <| _reserved, read as zero
144
                                              <|`31` _SPI_CTRL_BUSY_      ^| r/- <| transmission in progress when set
145 64 zero_gravi
| `0xffffffac` | `NEORV32_SPI.DATA` |`31:0` | r/w | receive/transmit data, LSB-aligned
146 60 zero_gravi
|=======================

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.