21. Serial Peripheral Interface (SPI) Module¶
This chapter will discuss the operation of the Serial Peripheral Interface (SPI) module instantiated in this design.
21.1. IP Details and Available Configuration¶
Table 21.1 provides details of the source of the IP and and details of the memory map.
Value |
|
---|---|
Provider |
gitlab |
Vendor |
incoresemi |
Library |
blocks/devices |
Version |
1.4.0 |
Ip Type |
memory_mapped |
Numer of Config Registers |
12 |
Direct Memory Region |
None |
Configuration Register Alignment (bytes) |
4 |
Table 21.2 provides information of the various parameters of the IP available at design time and their description
Configuration |
Options |
Description |
---|---|---|
Bus interfaces |
APB, AXI4L, AXI4 |
Choice of bus interface protocol supported on this IP |
Base address |
Integer |
The base address where the memory map of the configuration register starts |
Bytes reserved |
Integer >= 0X30 |
The number of bytes reserved for this instance. This can be much larger than the actual bytes required for the configuration registers but cannot be smaller than the value indicated. |
periph_count |
Integer > 0 and < 8 |
An integer indicating number of peripherals that can be controlled by SPI module. |
fifo_depth |
Integer > 2 and < 256 |
An integer indicating depth of FIFO used by tx_fifo and rx_fifo. |
This IP adheres to the redefined SPI Signal names
Discontinued Name |
Redefined Name |
---|---|
Master |
Controller |
Slave |
Peripheral |
MISO |
CIPO |
MOSI |
COPI |
Slave Select |
Chip Select / Peripheral Select |
21.2. SPI Instance Details¶
Table 21.4 shows the values assigned to parameters of this instance of the IP.
Parameter Name |
Value Assigned |
---|---|
Base Address |
0X20100 |
Bound Address |
0X201FF |
Bytes reserved |
0XFF |
Bus Interface |
APB |
periph_count |
0X1 |
fifo_depth |
0X14 |
21.3. SPI Features¶
The SPI module implements the standard SPI communication as controller & peripheral configuration supporting:
Custom Setup / Hold / Inter-Transfer delays in controller mode
16-bit Prescalar for selecting Baudrate in controller mode
CRC based Hashing for Rx/Tx Data
Bit-controlled data transfer
Interrupt line that gets connected to PLIC.
Fig. 21.1 shows Highlevel Architecture, Different Modes used to sample data and the peripheral support delays provided by the SPI modules.
Fig. 21.1 SPI Architecture.¶
The following parameters can be configured in software:
Clock Phase and Polarity using
CPHA
&&CPOL
Communication mode using
DPLX
Setup, Hold & Inter Transfer delays using
SPI_DR
Registers (in Controller mode)CRC of Transmitted and Received Data
Interrupt to write AND/OR Read from TxR and RxR respectively.
Bit wise control of data Tx/Rx.
The following parameters can be configured in the hardware:
Number of peripherals that can be controlled using the SPI module (
periph_count
)Depth of FIFO can be chosen (
fifo_depth
)
21.4. Register Map¶
The register map for the SPI control registers is shown in Table 21.5.
Register-Name |
Offset(hex) |
Size(Bits) |
Reset(hex) |
Description |
---|---|---|---|---|
SPI_CR1 |
0X0 |
32 |
0X4 |
Various fields to control SPI parameters |
SPI_CR2 |
0X4 |
32 |
0X0 |
Various fields to control secondary SPI parameters |
SPI_EN |
0X8 |
8 |
0X0 |
Master control for SPI module |
SPI_SR |
0XC |
32 |
0X0 |
Various fields that indicate status of SPI module. |
TXR |
0X10 |
32 |
0X0 |
Register to Holds data that needs to be sent over SPI |
RXR |
0X14 |
32 |
0X0 |
Register to Hold data that is received over the SPI |
RX_CRC |
0X18 |
16 |
0X0 |
Register to store so far received data’s CRC (only on CRC_EN) |
TX_CRC |
0X1C |
16 |
0X0 |
Register to store so far transmitted data’s CRC (only on CRC_EN). |
SPI_DR |
0X20 |
32 |
0X0 |
Register to control delay parameters to support slow peripherals. ( In controller mode only ) |
SPI_PSCR |
0X24 |
16 |
0X4 |
Prescalar value that divides bus clock and provides sclk (In controller mode only) |
SPI_CRCPR |
0X28 |
16 |
0X0 |
CRC Polynomial to use with CRC module |
SPI_CRCINOUT |
0X2C |
32 |
0X0 |
CRC Initial Value & Xor Out to use with CRC module |
All addresses not mentioned in the above table within Base Address
and
Bound Address
are reserved and accesses to those regions will generate a
slave error on the bus interface
The register access attributes for the SPI control registers are shown in Table 21.6.
Register-Name |
Access Type |
Reset Type |
Min Access |
Max Access |
---|---|---|---|---|
SPI_CR1 |
read-write |
synchronous |
4B |
4B |
SPI_CR2 |
read-write |
synchronous |
4B |
4B |
SPI_EN |
read-write |
synchronous |
1B |
4B |
SPI_SR |
read-only |
synchronous |
4B |
4B |
TXR |
read-write |
synchronous |
4B |
4B |
RXR |
read-only |
synchronous |
4B |
4B |
RX_CRC |
read-only |
synchronous |
2B |
4B |
TX_CRC |
read-only |
synchronous |
2B |
4B |
SPI_DR |
read-write |
synchronous |
4B |
4B |
SPI_PSCR |
read-write |
synchronous |
2B |
4B |
SPI_CRCPR |
read-write |
synchronous |
2B |
4B |
SPI_CRCINOUT |
read-write |
synchronous |
4B |
4B |
21.5. SPI_CR1 Register¶
This is a 32-bit register which allows primary controls of SPI module including Phase, Polarity, controller / peripheral modes, data format, communication modes, Bits to transmit/receive.
Communication Mode |
Configuration |
---|---|
Duplex Mode (Tx & Rx) |
Set |
Simplex Mode (Tx Only) |
Set |
Simplex Mode (Rx Only) |
Set dplx` = 0 , |
Half Duplex Mode (First Tx then Rx) |
Set |
Half Duplex Mode (First Rx then Tx) |
Set |
Warning
On choosing unlimited transactions using ( tx_bits
= 255 or rx_bits
= 255),
User should be aware that:
In Duplex transactions, if either rx_fifo is full or tx_fifo is empty, spi will terminate
- In Other transactions,
During Rx phase, if rx_fifo is full, spi will terminate
During Tx phase, if tx_fifo is empty, spi will terminate
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[0:0] |
cpha |
read-write |
Selects clock phase for data capture |
[1:1] |
cpol |
read-write |
Selects clock polarity for data capture |
[2:2] |
ctrler |
read-write |
Selects SPI Operational mode as Controller(1) / peripheral (0). Default is Controller mode. |
[5:3] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[6:6] |
is_rx_first |
read-write |
During a Half-duplex transaction, this bit decides whether RX(1) happens first or TX(0) happens first |
[7:7] |
lsb_1st |
read-write |
Bit transfer in LSB(1) / MSB(0) First |
[9:8] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[10:10] |
clr_state |
read-write |
Clears the internal FIFO and resets Tx/Rx States. This bit will be unset on clearing internal states. |
[11:11] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[12:12] |
crc_len |
read-write |
CRC Length 8-bit (0) / 16-bit (1) |
[13:13] |
crc_en |
read-write |
CRC Check Enable |
[14:14] |
dplx |
read-write |
Selects mode of Communication Duplex (1) / Simplex (0) |
[15:15] |
spi_dis_sync |
read-write |
If enabled (1), when
SPI_EN is written with 0, the disable will
happen after the existing ‘byte’ has been transferred/received.If disabled (0), when
SPI_EN is written with 0, the disable will
happen immediately |
[23:16] |
tx_bits |
read-write |
to transmit (1-254) for bit transmission, 255 for unlimited data transfer |
[31:24] |
rx_bits |
read-write |
to receive (1-254) for bit reception, 255 for unlimited data receive. |
21.6. SPI_CR2 Register¶
This is a 32-bit register which allows secondary controls of SPI module including Interrupt Controls, Idle pulse states & CRC controls.
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[1:0] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[2:2] |
cs_puls |
read-write |
CS Goes High [1] or Keeps Low [0] during inter-transfer delay (See SPI_DR[3]). (Applicable in Controller mode (SPI_CR1[2] == 1) only) |
[3:3] |
idle_out |
read-write |
Keeps Output line High [1] or Low [0] during (Half)duplex transaction’s idle phase. |
[4:4] |
rx_th_ie |
read-write |
Enable Interrupt when RX FIFO reaches the threshold specified in |
[5:5] |
err_ie |
read-write |
Enable Interrupt for Errors |
[6:6] |
rxne_ie |
read-write |
Enable Interrupt when RxR is NOT empty |
[7:7] |
txe_ie |
read-write |
Enable Interrupt when TxR is empty |
[11:8] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[12:12] |
fifo_rx_th |
read-write |
Sets Threshold for RX FIFO at Half(0) or 3/4th (1). This threshold is used to generate threshold interrupt |
[15:13] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[16:16] |
crc_rin |
read-write |
Reflect the data fed for CRC - www.crccalc.com |
[17:17] |
crc_rout |
read-write |
Reflect the CRC output - www.crccalc.com |
[23:18] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[26:24] |
periph_id |
read-write |
Chip Selector (NCS_P) where P=0 to 7 (depends on the |
[31:27] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
21.7. SPI_EN Register¶
8-bit register that acts as control bit for the SPI module.
On completion of transaction this bit will be unset by SPI module.
.. note :: Read all the warnings and notes in the TXR
and RXR
registers before
using this register
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[0:0] |
enable |
read-write |
Enables (1) / Disables (0) the SPI module |
[7:1] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
21.8. SPI_SR Register¶
32-bit register that indicates status of SPI module, including the status to write/read TxR/RxR respectively along with internal FIFO status.
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[0:0] |
rxne |
read-only |
RxR is not empty (when set, Ready to read RxR) |
[1:1] |
txe |
read-only |
TxR is empty (when set, Ready in writing to TxR) |
[2:2] |
rxf |
read-only |
RxFIFO is full |
[3:3] |
txnf |
read-only |
TxFIFO is not full (Data from TxR will be enqueued as long as this field is set ) |
[9:4] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[10:10] |
ovrf |
read-only |
Overflow Flag (Tx FIFO overflow) |
[11:11] |
bsy |
read-only |
SPI is performing Transactions (1) / IDLE (0) |
[15:12] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[23:16] |
ftcnt |
read-only |
Yet- to -transmit bytes in Tx FIFO ( Indicates number of bytes filled in FIFO) |
[31:24] |
frcnt |
read-only |
Unread bytes in Rx FIFO ( Indicates number of bytes filled in FIFO) |
21.9. TXR Register¶
lsb_1st
.txnf
is set, data can be written into this register that will be queued
into TxFIFO whose filled status can be found from ftcnt
.Note
This register can be written even during SPI_EN
is disabled. This allows
Tx Data to be written to FIFO then enable the SPI.
Note
txbits
> 0 and txbits
< fifo_depth x 8
, transaction will
only start after tx_fifo gets filled.fifo_depth
to
start the transaction.Note
Total Tx capacity = fifo_depth
+ 4 ( TXR
) bytes and the ftcnt
only shows the number of bytes held in tx_fifo
Warning
ftcnt
frcnt
is a good practice to avoid stale data from previous transactions.RXR
,``TXR`` should be read
to discard and FIFO can be cleared by clr_state
bit.Note
It is better practice to fill the data into fifo and then assert SPI_EN
= 1
21.10. RXR Register¶
rxne
is set and each read is aligned
according to the lsb_1st
.frcnt
to know how many bytes are yet to be
read from internal RxFIFO.Note
This register can be read even after SPI_EN
is disabled. This allows
Rx Data to be read from FIFO after transaction completes.
Note
Total Rx capacity = fifo_depth
+ 4 ( RXR
) bytes and the frcnt
only shows the number of bytes held in rx_fifo
.
Warning
frcnt=0
although 4 bytes were received. from 5th byte the frcnt
will increment.Warning
Contents of FIFO will get cleared on setting clr_state
bit.
21.11. RX_CRC Register¶
crc_poly
, crc_init
, crc_xor
, crc_en
, crc_len
,crc_rin
& crc_rout
parameters. Intermediate hashes are stored into this
register periodically. Final hash can be read from this register when transaction
winds up.Note
The CRC is calculated whenever RX_FIFO
is enqueued. It should be noted
that the data stored in RX_FIFO
is passed into RXR
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[15:0] |
rxcrc |
read-only |
CRC Hash for data received during Rxn |
21.12. TX_CRC Register¶
crc_poly
, crc_init
, crc_xor
, crc_en
, crc_len
,crc_rin
& crc_rout
parameters. Intermediate hashes are stored into this
register periodically. Final hash can be read from this register when transaction
winds up.Note
The CRC is calculated whenever TX_FIFO
is enqueued. It should be noted
that the data written into TXR
is enqueued into TX_FIFO
.
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[15:0] |
txcrc |
read-only |
CRC Hash for data received during Txn |
21.13. SPI_DR Register¶
The mathematical relationship of Abs. Delay in terms of bus clock is provided below.
condition |
Setup |
Hold |
Xfer |
---|---|---|---|
*_EN is 0 |
2 |
3 |
3 |
*_EN is 1
clk_src = 0
|
Refer Equation (21.1) |
Refer Equation (21.1) |
Refer Equation (21.3) |
*_EN is 1
clk_src = 1
|
Refer Equation (21.2) |
Refer Equation (21.2) |
Refer Equation (21.4) |
Note
Use cpol
value specified in the SPI_CR1[2] bit in the below equations.
- Setup / Hold Delay,
when
clk_src = 0
, Delay is represented as(21.1)¶\[Abs. delay = SETUP\_DELAY + 4\]whenclk_src = 1
and \(SETUP\_DELAY \neq 0\)Abs. Delay is represented as(21.2)¶\[Abs. delay = ( SETUP\_DELAY \times prescalar ) + 4 - \left((1 - \mathbf{cpol} ) \times \frac{prescalar}{2}\right)\]- Xfer Delay ,
when
clk_src = 0
, Delay is represented as(21.3)¶\[Abs. delay = XFER\_DELAY + 5\]whenclk_src = 1
and \(XFER\_DELAY \neq 0\)Abs. Delay is represented as(21.4)¶\[Abs. delay = ( XFER\_DELAY \times prescalar ) + 5 - \left((1 - \mathbf{cpol} ) \times \frac{prescalar}{2}\right)\]Note
During the xfer delay, ncs follows the
cs_puls
, and xfer delay is valid only for Half-duplex Transactions.Note
By default, when all delays are disabled, there’s implicit setup , xfer and hold Abs. delays of 2 , 3 & 3 bus clocks respectively.
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[0:0] |
clk_src |
read-write |
Selects bus clock(0) / SPI clock(1) for delays |
[1:1] |
sd_en |
read-write |
Enable Setup delay |
[2:2] |
hd_en |
read-write |
Enable Hold Delay |
[3:3] |
xd_en |
read-write |
Enable Transfer Delay (Applicable for Half Duplex transactions only) |
[7:4] |
Reserved |
read-write |
Reads will return zeros and writes will have no effect |
[15:8] |
setup_delay |
read-write |
8 bit delay for setup time |
[23:16] |
hold_delay |
read-write |
8-bit delay for Hold time |
[31:24] |
xfer_delay |
read-write |
8-bit delay between transactions (idles to CS_PULS) |
21.14. SPI_PSCR Register¶
The prescalar value is the divisor value for clock. Prescalar minimum value is 2 and maximum value is 65534.
Note
Prescalar should be an even value in controller
mode. if odd value is sent, it will be added
‘+1’ to make it even. This field has no significance in peripheral
mode.
Warning
In Controller
mode, recommended Minimum value is 4. When Using prescalar
value of 2, the SPI runs at half the frequency of bus clock. Hence, during
transactions intermediate delays might be observable.
Warning
When the SPI Module is operated in peripheral mode
, the Max. frequency
of clock driving sclk
should be
\(\mathbf{max\_sclk\_frequency} \leq \frac{\mathbf{bus\_clock\_frequency}}{4}\)
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[15:0] |
prescalar |
read-write |
value > 1 and < 65535 are valid values for dividing bus clock. |
21.15. SPI_CRCPR Register¶
This 16-bit register holds the value of polynomial according to the crc_len that dictates between CRC8 / CRC16
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[15:0] |
crc_poly |
read-write |
Polynomial to be used for generating CRC Hash |
21.16. SPI_CRCINOUT Register¶
This 32-bit register holds the value of initial and Output XOR values according to the crc_len that dictates between CRC8 / CRC16
Bits |
Field Name |
Attribute |
Description |
---|---|---|---|
[15:0] |
crc_init |
read-write |
Initial value of CRC Algo. that is used to generate Hash. |
[31:16] |
crc_xor_out |
read-write |
Value with which final output should be XORed - www.crccalc.com |
21.17. IO and Sideband Signals¶
The following table describes the io-signals generated from this IP that may directly or indirectly drive certain IO pads.
Signal Name (RTL) |
Size |
Direction |
Description |
---|---|---|---|
copi_in |
1 |
input |
Peripheral Input |
copi_out_en |
1 |
output |
Tristate control Signal OE=1 |
copi_out |
1 |
output |
Controller Output |
cipo_in |
1 |
input |
Controller Input |
cipo_out_en |
1 |
output |
Tristate control Signal OE=1 |
cipo_out |
1 |
output |
Peripheral Output |
sclk_in |
1 |
input |
Serial Clock (Used in Peripheral mode) |
sclk_out_en |
1 |
output |
Tristate control Signal OE=1 |
sclk_out |
1 |
output |
Serial Clock (Used in Controller mode) |
ncs_in |
1 |
input |
Chip Select ( Active Low ) (Used in Peripheral mode) |
ncs_out_en |
1 |
output |
Tristate control Signal OE=1 |
ncs_out |
1 |
output |
Chip Select ( Active Low ) (Used in Controller mode) |
Note
some of these signals may be muxed with other functional IO from different ips and users should refer to any pinmux module available on chip
Signal Name (RTL) |
Size |
Direction |
Description |
---|---|---|---|
interrupt |
1 |
output |
Signal indicating an interrupt has been raised by the SPI if enabled in control register (SPI_CR2). Signal is connected to PLIC. |
21.18. Usage of SPI Module¶
If CRC is being used, Enable CRC Module
SPI_CR1[13]
and Specify CRC LengthSPI_CR1[12]
Specify Polynomial in
SPI_CRCPR
, Initial & XOR value inSPI_CRCINOUT
Specify CRC Reflect options in
SPI_CR2[17:16]
and Select Slave IDSPI_CR2[26:24]
‘appropriately’.Specify device Operation
SPI_CR1[2]
ModeSPI_CR1[1:0]
, Communication ModeSPI_CR1[6]
,SPI_CR1[14]
& FormatSPI_CR1[7]
.Specify Prescalar in
SPI_PSCR
and Delays (if needed and applicable in controller mode only) inSPI_DR
Specify Interrupts (if needed) in
SPI_CR2[7:5]
Clear the internal States
SPI_CR1[10]
and Specify TX and RX bits inSPI_CR1[23:16
,SPI_CR1[31:24]
respectively.Enable SPI in
SPI_EN
Using Status Register
SPI_SR
fillTXR
and / or readRXR
appropriately.Once Transaction is complete
RX_CRC
andTX_CRC
can be read (if being used)
Last 4 steps can be iteratively performed per transaction.