SPI Overview
SPI (serial peripheral interface) is a four-wire synchronous serial protocol. SPI is considered an advanced topic. A good knowledge of the protocol is recommended. Troubleshooting may require a logic analyzer or oscilloscope.
T-series SPI Support
T-Series devices support Serial Peripheral Interface (SPI) communication as the master only. Four digital IO lines are used: MISO (data line; Master In Slave Out), MOSI (data line; Master Out Slave In), CLK (clock), and CS (chip select).
Lua scripting is often convenient for serial applications. For example, a script can run the serial communication at a specified interval, and put the results in USER_RAM registers. The host software can read from the USER_RAM registers when convenient. This puts the complications of serial communication in a script running on the T-series device. The Lua examples contain several serial communication examples.
SPI is not an alternative to the USB connection. Rather, the host application will write/read data to/from the T-series device, and the T-series device communicates with some other device using the serial protocol.
How-To
Running a SPI operation on a T-series device requires:
- Initial configuration.
- Send load data to the slave device.
- Execute the SPI operation.
- Read the data that was read from the slave device.
1. Initial configuration.
Several registers need to be written to configure the T-series device.
DIO lines need to be selected to act as MISO, MOSI, CLK, and CS:
Name |
Start Address |
Type |
Access |
SPI_CS_DIONUM
The DIO line for Chip-Select.
|
5000 |
UINT16 |
R/W
|
SPI_CS_DIONUM
- Address: 5000
The DIO line for Chip-Select.
- Data type: UINT16 (type index = 0)
-
Readable and writable
- Default value: 0
|
SPI_CLK_DIONUM
The DIO line for Clock.
|
5001 |
UINT16 |
R/W
|
SPI_CLK_DIONUM
- Address: 5001
The DIO line for Clock.
- Data type: UINT16 (type index = 0)
-
Readable and writable
- Default value: 0
|
SPI_MISO_DIONUM
The DIO line for Master-In-Slave-Out.
|
5002 |
UINT16 |
R/W
|
SPI_MISO_DIONUM
- Address: 5002
The DIO line for Master-In-Slave-Out.
- Data type: UINT16 (type index = 0)
-
Readable and writable
- Default value: 0
|
SPI_MOSI_DIONUM
The DIO line for Master-Out-Slave-In.
|
5003 |
UINT16 |
R/W
|
SPI_MOSI_DIONUM
- Address: 5003
The DIO line for Master-Out-Slave-In.
- Data type: UINT16 (type index = 0)
-
Readable and writable
- Default value: 0
|
The SPI mode controls which edge of clock signals value data, and whether the clock will idle high or low:
Name |
Start Address |
Type |
Access |
SPI_MODE
The SPI mode controls the clock idle state and which edge clocks the data. Bit 1 is CPOL and Bit 0 is CPHA, so CPOL/CPHA for different decimal values:<br>0 = 0/0 = b00,<br>1 = 0/1 = b01,<br>2 = 1/0 = b10,<br>3 = 1/1 = b11.<br>For CPOL and CPHA explanations, see Wikipedia article: <a target='_blank' href='https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus'>https://e... style='margin-right: -1;' src='https://ljsimpleregisterlookup.herokuapp.com/static/images/ui-icons-extl... />.
|
5004 |
UINT16 |
R/W
|
SPI_MODE
- Address: 5004
The SPI mode controls the clock idle state and which edge clocks the data. Bit 1 is CPOL and Bit 0 is CPHA, so CPOL/CPHA for different decimal values: 0 = 0/0 = b00, 1 = 0/1 = b01, 2 = 1/0 = b10, 3 = 1/1 = b11. For CPOL and CPHA explanations, see Wikipedia article: https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus .
- Data type: UINT16 (type index = 0)
-
Readable and writable
- Default value: 0
|
Set the clock speed with SPI_SPEED_THROTTLE:
Name |
Start Address |
Type |
Access |
SPI_SPEED_THROTTLE
This value controls the SPI clock frequency. Pass 0-65535. Default=0 corresponds to 65536 internally which results in ~800 kHz.<br>65500 = ~100 kHz,<br>65100 = ~10 kHz,<br>61100 = ~1 kHz,<br>21000 = ~100 Hz,<br>and 1 = ~67 Hz.<br>Avoid setting too low such that the entire transaction lasts longer than the 250 millisecond timeout of the internal watchdog timer.
|
5005 |
UINT16 |
R/W
|
SPI_SPEED_THROTTLE
- Address: 5005
This value controls the SPI clock frequency. Pass 0-65535. Default=0 corresponds to 65536 internally which results in ~800 kHz. 65500 = ~100 kHz, 65100 = ~10 kHz, 61100 = ~1 kHz, 21000 = ~100 Hz, and 1 = ~67 Hz. Avoid setting too low such that the entire transaction lasts longer than the 250 millisecond timeout of the internal watchdog timer.
- Data type: UINT16 (type index = 0)
-
Readable and writable
- Default value: 0
|
Starting with a low clock speed and increasing the speed after everything is working is usually a good idea.
The following table lists approximate clock rates measured for various values of SPI_SPEED_THROTTLE with T7 firmware 1.0150:
Throttle value |
Clock Speed (kHz) |
0 |
780 |
65530 |
380 |
65500 |
100 |
65100 |
10 |
61100 |
1 |
21000 |
0.1 |
1 |
0.067 |
Lastly, set SPI_OPTIONS:
Name |
Start Address |
Type |
Access |
SPI_OPTIONS
Bit 0 is Auto-CS-Disable. When bit 0 is 0, CS is enabled. When bit 0 is 1, CS is disabled.<br>Bit 1: 0 = Set DIO directions before starting the SPI operations, 1 = Do not set DIO directions.<br>Bit 2: 0 = Transmit data MSB first, 1 = LSB first.<br>Bits 4-7: This value sets the number of bits that will be transmitted during the last byte of the SPI operation. Default is 8, valid options are 1-8.
|
5006 |
UINT16 |
R/W
|
SPI_OPTIONS
- Address: 5006
Bit 0 is Auto-CS-Disable. When bit 0 is 0, CS is enabled. When bit 0 is 1, CS is disabled. Bit 1: 0 = Set DIO directions before starting the SPI operations, 1 = Do not set DIO directions. Bit 2: 0 = Transmit data MSB first, 1 = LSB first. Bits 4-7: This value sets the number of bits that will be transmitted during the last byte of the SPI operation. Default is 8, valid options are 1-8.
- Data type: UINT16 (type index = 0)
-
Readable and writable
- Default value: 0
|
Setting SPI_OPTIONS is normally not needed, but can help with compatibility in the following situations:
- If the hardware setup does not require a CS line.
- If the hardware setup requires special digital IO configuration.
- If data needs to be transmitted LSB first.
- If the number of bits to be transferred is not an even multiple of eight.
2. Send load data to the slave device.
Name |
Start Address |
Type |
Access |
SPI_NUM_BYTES
The number of bytes to transfer. The maximum transfer size is 100 bytes.
|
5009 |
UINT16 |
W
|
SPI_NUM_BYTES
- Address: 5009
The number of bytes to transfer. The maximum transfer size is 100 bytes.
- Data type: UINT16 (type index = 0)
-
Write-only
- Default value: 0
|
SPI_DATA_TX
Write data here. This register is a buffer.
|
5010 |
BYTE |
W
|
SPI_DATA_TX
- Address: 5010
Write data here. This register is a buffer.
- Data type: BYTE (type index = 99)
-
Write-only
- Default value: 0
- This register is a Buffer Register
|
SPI is full duplex. That means that data is sent in both directions at the same time. The number of bytes read from the slave must always equal the number of bytes written to the slave and the maximum transfer size is 100 bytes. To read data from a slave device without sending data to it, load dummy data into SPI_DATA_TX.
3. Execute the SPI operation.
Name |
Start Address |
Type |
Access |
SPI_GO
Write 1 to begin the configured SPI transaction.
|
5007 |
UINT16 |
W
|
SPI_GO
- Address: 5007
Write 1 to begin the configured SPI transaction.
- Data type: UINT16 (type index = 0)
-
Write-only
- Default value: 0
- This register uses system RAM. The maximum RAM is 64KB. For more information, see 4.4 RAM
|
4. Read the data that was read from the slave device.
Name |
Start Address |
Type |
Access |
SPI_DATA_RX
Read data here. This register is a buffer. Underrun behavior - fill with zeros.
|
5050 |
BYTE |
R
|
SPI_DATA_RX
- Address: 5050
Read data here. This register is a buffer. Underrun behavior - fill with zeros.
- Data type: BYTE (type index = 99)
-
Read-only
- Default value: 0
- This register is a Buffer Register
|
Common Issues
1. Timeouts
T-Series devices have an internal watchdog that will timeout, and cause the device to reboot, if a single SPI transaction lasts longer than 250 ms. Stay safely above the following measured minimum values where device did not reboot for different numbers of bytes:
#Bytes |
ThrottleValue |
ClockRateHz |
1 |
1 |
67 Hz (minimum) |
2 |
4900 |
73 Hz |
3 |
23900 |
106 Hz |
4 |
33900 |
140 Hz |
10 |
52600 |
342 Hz |
16 |
57400 |
544 Hz |
32 |
61500 |
1095 Hz |
2. Noise Immunity
The clock input on the slave device can be vulnerable to noise. The clock input will notice quick edges caused by noise. If you suspect this to be a problem, add a capacitor close to the clock input of the slave. Suggested value is equal to or less than:
1 / (2 * pi * f * R)
...where f is the SPI frequency and R is the source impedance—which is dominated in this case by the DIO (use 550 ohms for FIO and 180 ohms for EIO).
Example
The following demonstrates a simple loop-back test. Connect a jumper between DIO2 and DIO3. Data will be sent out DIO3 and read from DIO2.
SPI_CS_DIONUM = 0 // Use DIO0 as chip select.
SPI_CLK_DIONUM = 1 // Use DIO1 as Clock
SPI_MISO_DIONUM = 2 // Use DIO2 as MISO
SPI_MOSI_DIONUM = 3 // Use DIO3 as MOSI
SPI_MODE = 0 // Select mode zero.
SPI_SPEED_THROTTLE = 65500 // Set clock speed to ~100 kHz.
SPI_OPTIONS = 0 // No special operation
SPI_NUM_BYTES = 1 // Transfer one byte.
SPI_DATA_TX = 0x55 // Load a test data byte. eWriteNameByteArray is the easiest way to write the outgoing SPI data.
SPI_GO = 1 // Initiate the transfer
At this point the T4/T7 will run the SPI transaction. If no errors are returned, the received data can be read.
SPI_DATA_RX = ? - Read a test data byte. eReadNameByteArray is the easiest way to read the received SPI data.
Because of the loop-back, the data read from SPI_DATA_RX will match the data written to SPI_DATA_TX.