SPI
Functionality overview
Red Pitaya SPI does not use the standard cpol and cpha parameters, instead the mode can be one of the following:
LISL- Low idle level, sample on leading edge - equivalent tocpol=0, cpha=0LIST- Low idle level, sample on trailing edge - equivalent tocpol=0, cpha=1HISL- High idle level, sample on leading edge - equivalent tocpol=1, cpha=0HIST- High idle level, sample on trailing edge - equivalent tocpol=1, cpha=1
Figure 3.11 SPI modes (Image source)
The SPI commands feature three different function to configure the buffers for messages (using SCPI commands for explanation, but the same applies to the API commands).
SPI:MSG<n>:TX<m>:RX- Creates both the read (receive) and write (send) buffers for the specified message.SPI:MSG<n>:TX<m>- Creates only the write buffer for the specified message. Deletes any previously created read buffer for the same message.SPI:MSG<n>:RX<m>- Creates only the read buffer for the specified message. Deletes any previously created write buffer for the same message.
In the background (API commands) all the commands call the same function rp_SPI_SetBufferForMessage() which initializes the data for both the buffers for sending and receiving at the same time.
Calling the function multiple times for the same message will delete the previous buffers and create new ones. This means that to create both the buffers for sending and receiving you have to use the SPI:MSG<n>:TX<m>:RX command.
Calling the SPI:MSG<n>:TX<m> command and then the SPI:MSG<n>:RX<m> command will first create the buffer for sending (and not initialize the receiving buffer), then the second command will delete the previously created buffer for sending and create a new one for receiving.
Consequently, it is impossible to create both the buffers for sending and receiving using a sequence of SPI:MSG<n>:TX<m> and SPI:MSG<n>:RX<m> commands as one of the buffers will never be initialized, resulting in an error when trying to read or write data (for SCPI commands this can result in an infinite loop when attempting to read the data from a nonexisting buffer).
Adding the :CS suffix (or setting the cs_change to true) to the command will toggle the CS line after sending/receiving the message. For most basic applications this is not needed.
Important notes
The SPI device path on Gen 2 boards is “/dev/spidev2.0” instead of the classic “/dev/spidev1.0”.
Code examples
Here are some examples of how to use the SPI commands on Red Pitaya:
Parameters and command table
Parameter options:
<mode> = {LISL, LIST, HISL, HIST}Default:LISL<cs_mode> = {NORMAL, HIGH}Default:NORMAL<bits> = {7, 8}Default:8<speed> = {1...100000000}Default:50000000<data> = {XXX, ... | #HXX, ... | #QXXX, ... | #BXXXXXXXX, ... }Array of data separated by commasXXX= Dec format#HXX= Hex format#QXXX= Oct format#BXXXXXXXX= Bin format
Available Jupyter and API macros:
SPI mode -
RP_SPI_MODE_LISL, RP_SPI_MODE_LIST, RP_SPI_MODE_HISL, RP_SPI_MODE_HISTSPI bit order -
RP_SPI_ORDER_BIT_MSB, RP_SPI_ORDER_BIT_LSBSPI state -
RP_SPI_STATE_NOT, RP_SPI_STATE_READYSPI CS mode -
RP_SPI_CS_NORMAL, RP_SPI_CS_HIGH
SCPI |
API, Jupyter |
DESCRIPTION |
ECOSYSTEM |
|---|---|---|---|
SPI:INITExample:
SPI:INIT |
C++:
rp_SPI_Init()Python:
rp_SPI_Init() |
Initializes the API for working with SPI. |
1.04-18 and up |
SPI:INIT:DEV <path>Example:
SPI:INIT:DEV "/dev/spidev1.0" |
C++:
rp_SPI_InitDevice(const char *device)Python:
rp_SPI_InitDevice(<device>) |
Initializes the API for working with SPI.
<path> - Path to the SPI device.On some boards, it may be different from the standard: /dev/spidev1.0
Shoulld be set to /dev/spidev2.0 on Gen 2 boards.
|
1.04-18 and up |
SPI:RELEASEExample:
SPI:RELEASE |
C++:
rp_SPI_Release()Python:
rp_SPI_Release() |
Releases all used resources. |
1.04-18 and up |
SPI:SETtings:DEFaultExample:
SPI:SETtings:DEFault |
C++:
rp_SPI_SetDefaultSettings()Python:
rp_SPI_SetDefaultSettings() |
Sets the settings for SPI to default values. |
1.04-18 and up |
SPI:SETtings:SETExample:
SPI:SETtings:SET |
C++:
rp_SPI_SetSettings()Python:
rp_SPI_SetSettings() |
Sets the specified settings for SPI.
Executed after specifying the parameters of communication.
|
1.04-18 and up |
SPI:SETtings:GETExample:
SPI:SETtings:GET |
C++:
rp_SPI_GetSettings()Python:
rp_SPI_GetSettings() |
Gets the specified SPI settings. |
1.04-18 and up |
SPI:SETtings:MODE <mode>Example:
SPI:SETtings:MODE LIST |
C++:
rp_SPI_SetMode(rp_spi_mode_t mode)Python:
rp_SPI_SetMode(<mode>) |
Sets the mode for SPI.
- LISL = Low idle level, Sample on leading edge
- LIST = Low idle level, Sample on trailing edge
- HISL = High idle level, Sample on leading edge
- HIST = High idle level, Sample on trailing edge
|
1.04-18 and up |
SPI:SETtings:MODE? > <mode>Example:
SPI:SETtings:MODE? > LIST |
C++:
rp_SPI_GetMode(rp_spi_mode_t *mode)Python:
rp_SPI_GetMode() |
Gets the specified mode for SPI. |
1.04-18 and up |
SPI:SETtings:CSMODE <cs_mode>Example:
SPI:SETtings:CSMODE NORMAL |
C++:
rp_SPI_SetCSMode(rp_spi_cs_mode_t cs_mode)Python:
rp_SPI_SetCSMode(<cs_mode>) |
Sets the mode for CS.
- NORMAL = After the message is transmitted,
the CS line is set to the HIGH state.
- HIGH = After the message has been transmitted,
the CS line is set to the LOW state.
|
2.00-18 and up |
SPI:SETtings:CSMODE? > <cs_mode>Example:
SPI:SETtings:CSMODE? > NORMAL |
C++:
rp_SPI_GetCSMode(rp_spi_cs_mode_t *cs_mode)Python:
rp_SPI_GetCSMode() |
Gets the specified CS mode for SPI. |
2.00-18 and up |
- (NA)
|
C++:
rp_SPI_SetOrderBit(rp_spi_order_bit_t order)Python:
rp_SPI_SetOrderBit(<order>) |
Set SPI bit order. |
2.04-35 and up |
- (NA)
|
C++:
rp_SPI_GetOrderBit(rp_spi_order_bit_t *order)Python:
rp_SPI_GetOrderBit() |
Get SPI bit order. |
2.04-35 and up |
SPI:SETtings:SPEED <speed>Example:
SPI:SETtings:SPEED 1000000 |
C++:
rp_SPI_SetSpeed(int speed)Python:
rp_SPI_SetSpeed(<speed>) |
Sets the speed of the SPI connection. |
1.04-18 and up |
SPI:SETings:SPEED? > <speed>Example:
SPI:SETtings:SPEED? > 1000000 |
C++:
rp_SPI_GetSpeed(int *speed)Python:
rp_SPI_GetSpeed() |
Gets the speed of the SPI connection. |
1.04-18 and up |
SPI:SETtings:WORD <bits>Example:
SPI:SETtings:WORD 8 |
C++:
rp_SPI_SetWordLen(int len)Python:
rp_SPI_SetWordLen(<len>) |
Specifies the length of the word in bits. Must be greater than or equal to 7. |
1.04-18 and up |
SPI:SETtings:WORD? > <bits>Example:
SPI:SETtings:WORD? > 8 |
C++:
rp_SPI_GetWordLen(int *len)Python:
rp_SPI_GetWordLen() |
Returns the length of a word. |
1.04-18 and up |
SPI:MSG:CREATE <n>Example:
SPI:MSG:CREATE 1 |
C++:
rp_SPI_CreateMessage(size_t len)Python:
rp_SPI_CreateMessage(<len>) |
Creates a message queue for SPI (reserves the space for data buffers)
Once created, they need to be initialized.
<n> - The number of messages in the queue.The message queue can operate within a single CS state switch.
|
1.04-18 and up |
SPI:MSG:DELExample:
SPI:MSG:DEL |
C++:
rp_SPI_DestroyMessage()Python:
rp_SPI_DestroyMessage() |
Deletes all messages and data buffers allocated for them. |
1.04-18 and up |
SPI:MSG:SIZE? > <n>Example:
SPI:MSG:SIZE? > 1 |
C++:
rp_SPI_GetMessageLen(size_t *len)Python:
rp_SPI_GetMessageLen() |
Returns the length of the message queue. |
1.04-18 and up |
SPI:MSG<n>:TX<m> <data>SPI:MSG<n>:TX<m>:CS <data>Example:
SPI:MSG0:TX4 1,2,3,4SPI:MSG1:TX3:CS 2,3,4 |
C++:
rp_SPI_SetBufferForMessage(size_t msg,const uint8_t *tx_buffer,bool init_rx_buffer,size_t len, bool cs_change)Python:
rp_SPI_SetBufferForMessage(<msg>, <tx_buffer>, <init_rx_buffer>, <len>, <cs_change>) |
Sets data for the write buffer for the specified message.
CS - Toggles CS state after sending/receiving this message.
<n> - index of message 0 <= n < msg queue size.<m> - TX buffer length.Sends
<m> ‘bytes’ from message <n>. No data is received. |
1.04-18 and up |
SPI:MSG<n>:TX<m>:RX <data>SPI:MSG<n>:TX<m>:RX:CS <data>Example:
SPI:MSG0:TX4:RX 1,2,3,4SPI:MSG1:TX3:RX:CS 2,3,4 |
C++:
rp_SPI_SetBufferForMessage(size_t msg,const uint8_t *tx_buffer,bool init_rx_buffer,size_t len, bool cs_change)Python:
rp_SPI_SetBufferForMessage(<msg>, <tx_buffer>, <init_rx_buffer>, <len>, <cs_change>) |
Sets data for the read and write buffers for the specified message.
CS - Toggles CS state after sending/receiving this message.
<n> - index of message 0 <= n < msg queue size.<m> - TX buffer length.The read buffer is also created with the same length and initialized with zeros.
Sends
<m> ‘bytes’ from message <n> and receives the same amount of datafrom the dataline
|
1.04-18 and up |
SPI:MSG<n>:RX<m>SPI:MSG<n>:RX<m>:CSExample:
SPI:MSG0:RX4SPI:MSG1:RX5:CS |
C++:
rp_SPI_SetBufferForMessage(size_t msg,const uint8_t *tx_buffer,bool init_rx_buffer,size_t len, bool cs_change)Python:
rp_SPI_SetBufferForMessage(<msg>, <tx_buffer>, <init_rx_buffer>, <len>, <cs_change>) |
Initializes a buffer for reading the specified message.
CS - Toggles CS state after receiving message.
<n> - index of message 0 <= n < msg queue size.<m> - RX buffer length.Receives
<m> ‘bytes’ into message <n>. No data is transmitted. |
1.04-18 and up |
SPI:MSG<n>:RX? > <data>Example:
SPI:MSG1:RX? > {2,4,5} |
C++:
rp_SPI_GetRxBuffer(size_t msg, const uint8_t **buffer, size_t *len)Python:
rp_SPI_GetRxBuffer(<msg>) |
Returns a read buffer for the specified message. |
1.04-18 and up |
SPI:MSG<n>:TX? > <data>Example:
SPI:MSG1:TX? > {2,4,5} |
C++:
rp_SPI_GetTxBuffer(size_t msg, const uint8_t **buffer, size_t *len)Python:
rp_SPI_GetTxBuffer(<msg>) |
Returns the write buffer for the specified message. |
1.04-18 and up |
SPI:MSG<n>:CS? > ON|OFFExample:
SPI:MSG1:CS? > ON |
C++:
rp_SPI_GetCSChangeState(size_t msg, bool *cs_change)Python:
rp_SPI_GetCSChangeState(<msg>) |
Returns the setting for CS mode for the specified message. |
1.04-18 and up |
SPI:PASSExample:
SPI:PASS |
C++:
rp_SPI_ReadWrite()Python:
rp_SPI_ReadWrite() |
Sends the prepared messages to the SPI device. |
1.04-18 and up |
- (NA)
|
C++: NA
Python:
Buffer(<size>) |
Creates a buffer for sending and receiving data. |
2.04-35 and up |