[docs] add new SDI module

This commit is contained in:
stnolting 2023-02-25 17:58:58 +01:00
parent 59739bc8ca
commit 1886d003ac
8 changed files with 146 additions and 13 deletions

View file

@ -153,7 +153,8 @@ allows booting application code via UART or from external SPI flash
* standard serial interfaces
([UART](https://stnolting.github.io/neorv32/#_primary_universal_asynchronous_receiver_and_transmitter_uart0),
[SPI](https://stnolting.github.io/neorv32/#_serial_peripheral_interface_controller_spi),
[SPI](https://stnolting.github.io/neorv32/#_serial_peripheral_interface_controller_spi) (host),
[SDI](https://stnolting.github.io/neorv32/#_serial_data_interface_controller_sdi) (SPI device),
[TWI/I²C](https://stnolting.github.io/neorv32/#_two_wire_serial_interface_controller_twi)),
[ONEWIRE/1-Wire](https://stnolting.github.io/neorv32/#_one_wire_serial_interface_controller_onewire))
* general purpose IOs ([GPIO](https://stnolting.github.io/neorv32/#_general_purpose_input_and_output_port_gpio)) and

View file

@ -86,7 +86,7 @@ include::rationale.adoc[]
* highly-configurable full-scale microcontroller-like processor system
* based on the NEORV32 CPU
* optional standard serial interfaces (UART, TWI, SPI, 1-Wire)
* optional standard serial interfaces (UART, TWI, SPI (host and device), 1-Wire)
* optional timers and counters (watchdog, system timer)
* optional general purpose IO and PWM; a native NeoPixel(c)-compatible smart LED interface
* optional embedded memories / caches for data, instructions and bootloader
@ -210,7 +210,8 @@ neorv32_top.vhd - NEORV32 Processor top entity
├neorv32_neoled.vhd - NeoPixel (TM) compatible smart LED interface
├neorv32_onewire.vhd - One-Wire serial interface controller
├neorv32_pwm.vhd - Pulse-width modulation controller
├neorv32_spi.vhd - Serial peripheral interface controller
├neorv32_sdi.vhd - Serial data interface controller (SPI device)
├neorv32_spi.vhd - Serial peripheral interface controller (SPI host)
├neorv32_sysinfo.vhd - System configuration information memory
├neorv32_trng.vhd - True random number generator
├neorv32_twi.vhd - Two wire serial interface controller
@ -319,6 +320,7 @@ https://stnolting.github.io/neorv32/ug/#_application_specific_processor_configur
| ONEWIRE | 1-wire interface | 107 | 77 | 0 | 0
| PWM | Pulse_width modulation controller (8 channels) | 128 | 117 | 0 | 0
| SPI | Serial peripheral interface | 114 | 94 | 0 | 0
| SDI | Serial data interface | 72 | 66 | 0 | 0
| **SYSINFO** | System configuration information memory | 13 | 11 | 0 | 0
| TRNG | True random number generator | 89 | 79 | 0 | 0
| TWI | Two-wire interface | 77 | 43 | 0 | 0

View file

@ -22,7 +22,8 @@ image::neorv32_processor.png[align=center]
* _optional_ internal bootloader (<<_bootloader_rom_bootrom,**BOOTROM**>>) with UART console & SPI flash boot option
* _optional_ machine system timer (<<_machine_system_timer_mtime,**MTIME**>>), RISC-V-compatible
* _optional_ two independent universal asynchronous receivers and transmitters (<<_primary_universal_asynchronous_receiver_and_transmitter_uart0,**UART0**>>, <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1,**UART1**>>) with optional hardware flow control (RTS/CTS) and optional RX/TX FIFOs
* _optional_ 8/16/24/32-bit serial peripheral interface controller (<<_serial_peripheral_interface_controller_spi,**SPI**>>) with 8 dedicated CS lines
* _optional_ 8/16/24/32-bit serial peripheral interface host controller (<<_serial_peripheral_interface_controller_spi,**SPI**>>) with 8 dedicated CS lines
* _optional_ 8-bit serial data device interface (<<_serial_data_interface_controller_spi,**SDI**>>)
* _optional_ two wire serial interface controller (<<_two_wire_serial_interface_controller_twi,**TWI**>>), compatible to the I²C standard
* _optional_ general purpose parallel IO port (<<_general_purpose_input_and_output_port_gpio,**GPIO**>>), 64xOut, 64xIn
* _optional_ 32-bit external bus interface, Wishbone b4 / AXI4-Lite compatible (<<_processor_external_memory_interface_wishbone_axi4_lite,**WISHBONE**>>)
@ -113,7 +114,12 @@ bits/channels are hardwired to zero.
| `spi_clk_o` | 1 | out | controller clock line
| `spi_dat_o` | 1 | out | serial data output
| `spi_dat_i` | 1 | in | serial data input
| `spi_csn_o` | 8 | out | dedicated chip select (low-active)
| `spi_csn_o` | 8 | out | select (low-active)
4+^| **Serial Data Interface Controller (<<_serial_data_interface_controller_spi,SDI>>)**
| `sdi_clk_i` | 1 | in | controller clock line
| `sdi_dat_o` | 1 | out | serial data output
| `sdi_dat_i` | 1 | in | serial data input
| `sdi_csn_i` | 1 | in | chip select (low-active)
4+^| **Two-Wire Interface Controller (<<_two_wire_serial_interface_controller_twi,TWI>>)**
| `twi_sda_io` | 1 | inout | serial data line
| `twi_scl_io` | 1 | inout | serial clock line
@ -839,7 +845,7 @@ GPIO controller is not implemented at all.
[frame="all",grid="none"]
|======
| **IO_SPI_EN** | _boolean_ | false
3+| Implement <<_serial_peripheral_interface_controller_spi>> module when true.
3+| Implement <<_serial_peripheral_interface_controller_spi>> module when true (SPI host).
|======
@ -851,7 +857,30 @@ GPIO controller is not implemented at all.
|======
| **IO_SPI_FIFO** | _natural_ | 0
3+| Depth of the <<_serial_peripheral_interface_controller_spi>> FIFO. Has to be zero or a power of two.
Maximum value is 32*1024.
Maximum value is 32768.
|======
:sectnums!:
===== _IO_SDI_EN_
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_SDI_EN** | _boolean_ | false
3+| Implement <<_serial_data_interface_controller_sdi>> module when true (SPI device).
|======
:sectnums!:
===== _IO_SDI_FIFO_
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_SDI_FIFO** | _natural_ | 1
3+| Depth of the <<_serial_data_interface_controller_sdi>> FIFO. Has to be at least 1 or a power of two.
Maximum value is 32768.
|======
@ -1158,12 +1187,12 @@ table (the channel number also corresponds to the according FIRQ priority: 0 = h
| 3 | <<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>> | UART0 sending done interrupt (TX complete)
| 4 | <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1,UART1>> | UART1 data received interrupt (RX complete)
| 5 | <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1,UART1>> | UART1 sending done interrupt (TX complete)
| 6 | <<_serial_peripheral_interface_controller_spi,SPI>> | SPI transmission done interrupt
| 6 | <<_serial_peripheral_interface_controller_spi,SPI>> | Configurable SPI interrupt
| 7 | <<_two_wire_serial_interface_controller_twi,TWI>> | TWI transmission done interrupt
| 8 | <<_external_interrupt_controller_xirq,XIRQ>> | External interrupt controller interrupt
| 9 | <<_smart_led_interface_neoled,NEOLED>> | NEOLED TX buffer interrupt
| 10 | - | _reserved_, will never fire
| 11 | - | _reserved_, will never fire
| 11 | <<_serial_data_interface_controller_sdi,SDI>> | Configurable SDI interrupt
| 12 | <<_general_purpose_timer_gptmr,GPTMR>> | General purpose timer interrupt
| 13 | <<_one_wire_serial_interface_controller_onewire,ONEWIRE>> | 1-wire operation done interrupt
| 14 | - | _reserved_, will never fire
@ -1548,6 +1577,8 @@ include::soc_uart.adoc[]
include::soc_spi.adoc[]
include::soc_sdi.adoc[]
include::soc_twi.adoc[]
include::soc_onewire.adoc[]

View file

@ -0,0 +1,97 @@
<<<
:sectnums:
==== Serial Data Interface Controller (SDI)
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_sdi.vhd |
| Software driver file(s): | neorv32_sdi.c |
| | neorv32_sdi.h |
| Top entity port: | `sdi_clk_i` | 1-bit serial clock input
| | `sdi_dat_o` | 1-bit serial data output
| | `sdi_dat_i` | 1-bit serial data input
| | `sdi_csn_i` | 1-bit chip-select input (low-active)
| Configuration generics: | _IO_SDI_EN_ | implement SDI controller when _true_
| | _IO_SDI_FIFO_ | data FIFO size, has to be at least 1 or a power of two
| CPU interrupts: | fast IRQ channel 11 | configurable SDI interrupt (see <<_processor_interrupts>>)
|=======================
**Overview**
The serial data interface module provides a **device-class** SPI interface and allows to connect the processor
to an external SPI _host_, which is responsible for triggering (clocking) the actual transmission - the SDI is entirely
passive. An optional receive/transmit FIFO can be configured via the _IO_SDI_FIFO_ generic to support block-based
transmissions without CPU interaction.
.Device-Mode Only
[NOTE]
The NEORV32 SDI module only supports _device mode_. Transmission are initiated by an external host and not by the
the processor itself. If you are looking for a _host-mode_ serial peripheral interface (transactions
initiated by the NEORV32) check out the <<_serial_peripheral_interface_spi>> module.
The SDI module provides a single control register `CTRL` to configure the module and to check it's status
and a single data register `DATA` for receiving/transmitting data.
**Theory of Operation**
The SDI module is enabled by setting the _SDI_CTRL_EN_ bit in the `CTRL` control register. Clearing this bit
resets the entire module including the RX and TX FIFOs.
The SDI operates on byte-level only. Data written to the `DATA` register will be pushed to the TX FIFO. Received
data can be retrieved by reading the RX FIFO via the `DATA` register. The current state of these FIFOs is available
via the control register's _SDI_CTRL_RX_*_ and _SDI_CTRL_TX_*_ flags. The RX FIFO can be manually cleared at any time
by setting the _SDI_CTRL_CLR_RX_ bit.
.MSB-first Only
[NOTE]
The NEORV32 SDI module only supports MSB-first mode.
**SDI Clocking**
The SDI module supports both SPI clock polarity modes ("CPOL") but regarding the clock phase only "CPHA=0" is supported
yet. All SDI operations are clocked by the external `sdi_clk_i` signal. This signal is synchronized to the processor's
clock domain to simplify timing behavior. However, the clock synchronization requires that the external SDI clock
(`sdi_clk_i`) does **not exceed 1/4 of the processor's main clock**.
**SDI Interrupt**
The SDI module provides a set of interrupt conditions based on the level of the RX & TX FIFOs. The different
interrupt sources are enabled by the setting the control register's _SDI_CTRL_IRQ_ bits. All enabled interrupter
conditions are logically OR-ed so any enabled interrupt source will trigger the module's interrupt signal.
Once the SDI interrupt has fired it will remain active until the actual cause of the interrupt is resolved; for
example if just the _SDI_CTRL_IRQ_RX_AVAIL_ bit is set, the interrupt will keep firing until the RX FIFO is empty again.
Furthermore, an active SDI interrupt has to be explicitly cleared again by writing zero to the according
<<_mip>> CSR bit inside the SPI trap handler.
**Register Map**
.SDI register map (`struct NEORV32_SDI`)
[cols="<2,<2,<4,^1,<7"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.16+<| `0xfffffff0` .16+<| `NEORV32_SDI.CTRL` <|`0` _SDI_CTRL_EN_ ^| r/w <| SDI module enable
<|`1` _SDI_CTRL_CLR_RX_ ^| -/w <| clear RX FIFO when set, bit auto-clears
<|`3:2` _reserved_ ^| r/- <| reserved, read as zero
<|`7:4` _SDI_CTRL_FIFO_MSB_ : _SDI_CTRL_FIFO_LSB_ ^| r/- <| FIFO depth; log2(_IO_SDI_FIFO_)
<|`14:8` _reserved_ ^| r/- <| reserved, read as zero
<|`15` _SDI_CTRL_IRQ_RX_AVAIL_ ^| r/w <| fire interrupt if RX FIFO is not empty
<|`16` _SDI_CTRL_IRQ_RX_HALF_ ^| r/w <| fire interrupt if RX FIFO is at least half full
<|`17` _SDI_CTRL_IRQ_RX_FULL_ ^| r/w <| fire interrupt if if RX FIFO is full
<|`18` _SDI_CTRL_IRQ_TX_EMPTY_ ^| r/w <| fire interrupt if TX FIFO is empty
<|`22:19` _reserved_ ^| r/- <| reserved, read as zero
<|`23` _SDI_CTRL_RX_AVAIL_ ^| r/- <| RX FIFO data available (RX FIFO not empty)
<|`24` _SDI_CTRL_RX_HALF_ ^| r/- <| RX FIFO at least half full
<|`25` _SDI_CTRL_RX_FULL_ ^| r/- <| RX FIFO full
<|`26` _SDI_CTRL_TX_EMPTY_ ^| r/- <| TX FIFO empty
<|`27` _SDI_CTRL_TX_FULL_ ^| r/- <| TX FIFO full
<|`31:28` _reserved_ ^| r/- <| reserved, read as zero
| `0xfffffff4` | `NEORV32_SDI.DATA` |`7:0` | r/w | receive/transmit data (FIFO)
|=======================

View file

@ -11,10 +11,10 @@
| Top entity port: | `spi_clk_o` | 1-bit serial clock output
| | `spi_dat_o` | 1-bit serial data output
| | `spi_dat_i` | 1-bit serial data input
| | `spi_csn_i` | 8-bit dedicated chip select (low-active)
| | `spi_csn_o` | 8-bit dedicated chip select output (low-active)
| Configuration generics: | _IO_SPI_EN_ | implement SPI controller when _true_
| | _IO_SPI_FIFO_ | data FIFO size, has to be zero or a power of two
| CPU interrupts: | fast IRQ channel 6 | transmission done interrupt (see <<_processor_interrupts>>)
| CPU interrupts: | fast IRQ channel 6 | configurable SPI interrupt (see <<_processor_interrupts>>)
|=======================
@ -29,7 +29,8 @@ implemented via the _IO_SPI_FIFO_ generic to support block-based transmissions w
.Host-Mode Only
[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.
and not by an external SPI module. If you are looking for a _device-mode_ serial peripheral interface (transactions
initiated by an external host) check out the <<_serial_data_interface_sdi>> module..
The SPI module provides a single control register `CTRL` to configure the module and to check it's status
and a single data register `DATA` for receiving/transmitting data. If the data FIFO is implemented, this register

View file

@ -70,7 +70,7 @@ will signal a "DEVICE ERROR" in this case.
| `22` | _SYSINFO_SOC_IO_WDT_ | set if the WDT is implemented (via top's <<_io_wdt_en>> generic)
| `23` | _SYSINFO_SOC_IO_CFS_ | set if the custom functions subsystem is implemented (via top's <<_io_cfs_en>> generic)
| `24` | _SYSINFO_SOC_IO_TRNG_ | set if the TRNG is implemented (via top's _IO_TRNG_EN_ generic)
| `25` | - | _reserved_, read as zero
| `25` | _SYSINFO_SOC_IO_SDI_ | set if the SDI is implemented (via top's <<_io_sdi_en>> generic)
| `26` | _SYSINFO_SOC_IO_UART1_ | set if the secondary UART1 is implemented (via top's <<_io_uart1_en>> generic)
| `27` | _SYSINFO_SOC_IO_NEOLED_ | set if the NEOLED is implemented (via top's <<_io_neoled_en>> generic)
| `28` | _SYSINFO_SOC_IO_XIRQ_ | set if the XIRQ is implemented (via top's <<_xirq_num_ch>> generic)

View file

@ -94,6 +94,7 @@ footnote:[This driver file only represents a stub, since the real CFS drivers ar
| `neorv32_onewire.c` | `neorv32_onewire.h` | HW driver functions for the **ONEWIRE**
| `neorv32_pwm.c` | `neorv32_pwm.h` | HW driver functions for the **PWM**
| `neorv32_rte.c` | `neorv32_rte.h` | NEORV32 **runtime environment** and helper functions
| `neorv32_sdi.c` | `neorv32_sdi.h` | HW driver functions for the **SDI**
| `neorv32_spi.c` | `neorv32_spi.h` | HW driver functions for the **SPI**
| `neorv32_trng.c` | `neorv32_trng.h` | HW driver functions for the **TRNG**
| `neorv32_twi.c` | `neorv32_twi.h` | HW driver functions for the **TWI**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Before After
Before After