URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
[/] [neorv32/] [trunk/] [docs/] [datasheet/] [soc_spi.adoc] - Rev 73
Compare with Previous | Blame | View Log
<<<:sectnums:==== Serial Peripheral Interface Controller (SPI)[cols="<3,<3,<4"][frame="topbot",grid="none"]|=======================| Hardware source file(s): | neorv32_spi.vhd || Software driver file(s): | neorv32_spi.c || | neorv32_spi.h || Top entity port: | `spi_sck_o` | 1-bit serial clock output| | `spi_sdo_o` | 1-bit serial data output| | `spi_sdi_i` | 1-bit serial data input| | `spi_csn_i` | 8-bit dedicated chip select (low-active)| Configuration generics: | _IO_SPI_EN_ | implement SPI controller when _true_| CPU interrupts: | fast IRQ channel 6 | transmission done interrupt (see <<_processor_interrupts>>)|=======================**Theory of Operation**SPI is a synchronous serial transmission interface for fast on-board communications.The NEORV32 SPI transceiver supports 8-, 16-, 24- and 32-bit wide transmissions.The unit provides 8 dedicated chip select signals via the top entity's `spi_csn_o` signal, which aredirectly controlled by the SPI module (no additional GPIO required).[NOTE]The NEORV32 SPI module only supports _host mode_. Transmission are initiated only by the processor's SPI module(and not by an external SPI module).The SPI unit is enabled by setting the _SPI_CTRL_EN_ bit in the `CTRL` control register. No transfer can be initiatedand no interrupt request will be triggered if this bit is cleared. Furthermore, a transfer being in processcan be terminated at any time by clearing this bit.[IMPORTANT]Changes to the `CTRL` control register should be made only when the SPI module is idle as they directly effecttransmissions being in-progress.[TIP]A transmission can be terminated at any time by disabling the SPI moduleby clearing the _SPI_CTRL_EN_ control register bit.The data quantity to be transferred within a single transmission is defined via the _SPI_CTRL_SIZEx_ bits.The SPI module supports 8-bit (`00`), 16-bit (`01`), 24-bit (`10`) and 32-bit (`11`) transfers.A transmission is started when writing data to the `DATA` register. The data must be LSB-aligned. So ifthe SPI transceiver is configured for less than 32-bit transfers data quantity, the transmit data must be placedinto the lowest 8/16/24 bit of `DATA`. Vice versa, the received data is also always LSB-aligned. Applicationsoftware should only actually process the amount of bits that were configured using _SPI_CTRL_SIZEx_ whenreading `DATA`.[NOTE]The NEORV32 SPI module only support MSB-first mode. Data can be reversed before writing `DATA` (for TX) / afterreading `DATA` (for RX) to implement LSB-first transmissions. Note that in both cases data in ` DATA` stillneeds to be LSB-aligned.[TIP]The actual transmission length is left to the user: after asserting chip-select an arbitrary amount oftransmission with arbitrary data quantity (_SPI_CTRL_SIZEx_) can be made before de-asserting chip-select again.The SPI controller features 8 dedicated chip-select lines. These lines are controlled via the control register's_SPI_CTRL_CSx_ bits. When a specific _SPI_CTRL_CSx_ bit is **set**, the according chip-select line `spi_csn_o(x)`goes **low** (low-active chip-select lines).[TIP]The dedicated SPI chip-select signals can be seen as _general purpose_ outputs. These are intended to controlthe accessed device's chip-select signal but can also be use for controlling other shift register signals(like data strobe or output-enables).**SPI Clock Configuration**The SPI module supports all _standard SPI clock modes_ (0, 1, 2, 3), which is via the two control register bits_SPI_CTRL_CPHA_ and _SPI_CTRL_CPOL_. The _SPI_CTRL_CPHA_ bit defines the _clock phase_ and the _SPI_CTRL_CPOL_bit defines the _clock polarity_..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])image::SPI_timing_diagram2.wikimedia.png[].SPI standard clock modes[cols="<2,^1,^1,^1,^1"][options="header",grid="rows"]|=======================| | Mode 0 | Mode 1 | Mode 2 | Mode 4| _SPI_CTRL_CPOL_ | `0` | `0` | `1` | `1`| _SPI_CTRL_CPHA_ | `0` | `1` | `0` | `1`|=======================The SPI clock frequency (`spi_sck_o`) is programmed by the 3-bit _SPI_CTRL_PRSCx_ clock prescaler.The following prescalers are available:.SPI prescaler configuration[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"][options="header",grid="rows"]|=======================| **`SPI_CTRL_PRSCx`** | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096|=======================Based on the _SPI_CTRL_PRSCx_ configuration, the actual SPI clock frequency f~SPI~ is derived from the processor'smain clock f~main~ and is determined by:_**f~SPI~**_ = _f~main~[Hz]_ / (2 * `clock_prescaler`)Hence, the maximum SPI clock is f~main~ / 4..High-Speed SPI mode[TIP]The module provides a "high-speed" SPI mode. In this mode the clock prescaler configuration (SPI_CTRL_PRSCx) is ignoredand the SPI clock operates at f~main~ / 2 (half of the processor's main clock). High speed SPI mode is enabled by settingthe control register's _SPI_CTRL_HIGHSPEED_ bit.**SPI Interrupt**The SPI module provides a single interrupt to signal "transmission done" to the CPU. Whenever the SPImodule completes the current transfer operation, the interrupt is triggered and has to be explicitly cleared againby writing zero to the according <<_mip>> CSR bit..SPI register map (`struct NEORV32_SPI`)[cols="<2,<2,<4,^1,<7"][options="header",grid="all"]|=======================| Address | Name [C] | Bit(s), Name [C] | R/W | Function.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<|`1` _SPI_CTRL_CS1_ ^| r/w<|`2` _SPI_CTRL_CS2_ ^| r/w<|`3` _SPI_CTRL_CS3_ ^| r/w<|`4` _SPI_CTRL_CS4_ ^| r/w<|`5` _SPI_CTRL_CS5_ ^| r/w<|`6` _SPI_CTRL_CS6_ ^| r/w<|`7` _SPI_CTRL_CS7_ ^| r/w<|`8` _SPI_CTRL_EN_ ^| r/w <| SPI enable<|`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)<|`10` _SPI_CTRL_PRSC0_ ^| r/w .3+| 3-bit clock prescaler select<|`11` _SPI_CTRL_PRSC1_ ^| r/w<|`12` _SPI_CTRL_PRSC2_ ^| r/w<|`13` _SPI_CTRL_SIZE0_ ^| r/w .2+<| transfer size (`00`=8-bit, `01`=16-bit, `10`=24-bit, `11`=32-bit)<|`14` _SPI_CTRL_SIZE1_ ^| r/w<|`15` _SPI_CTRL_CPOL_ ^| r/w <| clock polarity<|`16` _SPI_CTRL_HIGHSPEED_ ^| r/w <| enable SPI high-speed mode (ignoring _SPI_CTRL_PRSC_)<|`17:30` ^| r/- <| _reserved, read as zero<|`31` _SPI_CTRL_BUSY_ ^| r/- <| transmission in progress when set| `0xffffffac` | `NEORV32_SPI.DATA` |`31:0` | r/w | receive/transmit data, LSB-aligned|=======================
