spi
Vitis Drivers API Documentation
spi Documentation

This component contains the implementation of the XSpi component. It is the driver for an SPI master or slave device. It supports 8-bit, 16-bit and 32-bit wide data transfers.

SPI is a 4-wire serial interface. It is a full-duplex, synchronous bus that facilitates communication between one master and one slave. The device is always full-duplex, which means that for every byte sent, one is received, and vice-versa. The master controls the clock, so it can regulate when it wants to send or receive data. The slave is under control of the master, it must respond quickly since it has no control of the clock and must send/receive data as fast or as slow as the master does.

The application software between master and slave must implement a higher layer protocol so that slaves know what to transmit to the master and when.

Initialization & Configuration

The XSpi_Config structure is used by the driver to configure itself. This configuration structure is typically created by the tool-chain based on HW build properties.

To support multiple runtime loading and initialization strategies employed by various operating systems, the driver instance can be initialized in one of the following ways:

  • XSpi_Initialize(InstancePtr, DeviceId) - The driver looks up its own configuration structure created by the tool-chain based on an ID provided by the tool-chain.
  • XSpi_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a configuration structure provided by the caller. If running in a system with address translation, the provided virtual memory base address replaces the physical address present in the configuration structure.

Multiple Masters

More than one master can exist, but arbitration is the responsibility of the higher layer software. The device driver does not perform any type of arbitration.

Multiple Slaves

Multiple slaves are supported by adding additional slave select (SS) signals to each device, one for each slave on the bus. The driver ensures that only one slave can be selected at any one time.

FIFOs

The SPI hardware is parameterized such that it can be built with or without FIFOs. When using FIFOs, both send and receive must have FIFOs. The driver will not function correctly if one direction has a FIFO but the other direction does not. The frequency of the interrupts which occur is proportional to the data rate such that high data rates without the FIFOs could cause the software to consume large amounts of processing time. The driver is designed to work with or without the FIFOs.

Interrupts

The user must connect the interrupt handler of the driver, XSpi_InterruptHandler to an interrupt system such that it will be called when an interrupt occurs. This function does not save and restore the processor context such that the user must provide this processing.

The driver handles the following interrupts:

  • Data Transmit Register/FIFO Empty
  • Data Transmit FIFO Half Empty
  • Data Transmit Register/FIFO Underrun
  • Data Receive Register/FIFO Overrun
  • Mode Fault Error
  • Slave Mode Fault Error
  • Slave Mode Select
  • Data Receive FIFO not Empty

The Data Transmit Register/FIFO Empty interrupt indicates that the SPI device has transmitted all the data available to transmit, and now its data register (or FIFO) is empty. The driver uses this interrupt to indicate progress while sending data. The driver may have more data to send, in which case the data transmit register (or FIFO) is filled for subsequent transmission. When this interrupt arrives and all the data has been sent, the driver invokes the status callback with a value of XST_SPI_TRANSFER_DONE to inform the upper layer software that all data has been sent.

The Data Transmit FIFO Half Empty interrupt indicates that the SPI device has transmitted half of the data available, in the FIFO, to transmit. The driver uses this interrupt to indicate progress while sending data. The driver may have more data to send, in which case the data transmit FIFO is filled for subsequent transmission. This interrupt is particualrly useful in slave mode, while transferring more than FIFO_DEPTH number of bytes. In this case, the driver ensures that the FIFO is never empty during a transfer and avoids master receiving invalid data.

The Data Transmit Register/FIFO Underrun interrupt indicates that, as slave, the SPI device was required to transmit but there was no data available to transmit in the transmit register (or FIFO). This may not be an error if the master is not expecting data, but in the case where the master is expecting data this serves as a notification of such a condition. The driver reports this condition to the upper layer software through the status handler.

The Data Receive Register/FIFO Overrun interrupt indicates that the SPI device received data and subsequently dropped the data because the data receive register (or FIFO) was full. The interrupt applies to both master and slave operation. The driver reports this condition to the upper layer software through the status handler. This likely indicates a problem with the higher layer protocol, or a problem with the slave performance.

The Mode Fault Error interrupt indicates that while configured as a master, the device was selected as a slave by another master. This can be used by the application for arbitration in a multimaster environment or to indicate a problem with arbitration. When this interrupt occurs, the driver invokes the status callback with a status value of XST_SPI_MODE_FAULT. It is up to the application to resolve the conflict.

The Slave Mode Fault Error interrupt indicates that a slave device was selected as a slave by a master, but the slave device was disabled. This can be used during system debugging or by the slave application to learn when the slave application has not prepared for a master operation in a timely fashion. This likely indicates a problem with the higher layer protocol, or a problem with the slave performance.

The Slave Mode Select interrupt indicates that the SPI device was selected as a slave by a master. The driver reports this condition to the upper layer software through the status handler.

Data Receive FIFO not Empty interrupt indicates that the SPI device, in slave mode, has received a data byte in the Data Receive FIFO, after the master has started a transfer. The driver reports this condition to the upper layer software through the status handler.

Polled Operation

This driver operates in polled mode operation too. To put the driver in polled mode the Global Interrupt must be disabled after the Spi is Initialized and Spi driver is started.

Statistics are not updated in this mode of operation.

Device Busy

Some operations are disallowed when the device is busy. The driver tracks whether a device is busy. The device is considered busy when a data transfer request is outstanding, and is considered not busy only when that transfer completes (or is aborted with a mode fault error). This applies to both master and slave devices.

Device Configuration

The device can be configured in various ways during the FPGA implementation process. Configuration parameters are stored in the xspi_g.c file or passed in via _CfgInitialize(). A table is defined where each entry contains configuration information for an SPI device. This information includes such things as the base address of the memory-mapped device, the number of slave select bits in the device, and whether the device has FIFOs and is configured as slave-only.

RTOS Independence

This driver is intended to be RTOS and processor independent. It works with physical addresses only. Any needs for dynamic memory management, threads or thread mutual exclusion, virtual memory, or cache control must be satisfied by the layer above this driver.

MODIFICATION HISTORY:
Ver   Who  Date     Changes


1.00a rpm 10/11/01 First release 1.00b jhl 03/14/02 Repartitioned driver for smaller files. 1.01a jvb 12/14/05 I separated dependency on the static config table and xparameters.h from the driver initialization by moving _Initialize and _LookupConfig to _sinit.c. I also added the new _CfgInitialize routine. 1.11a wgr 03/22/07 Converted to new coding style. 1.11a sv 02/22/08 Added the definition of LSB-MSB first option in xspi_l.h. 1.12a sdm 03/22/08 Updated the code to support 16/32 bit transfer width and polled mode of operation, removed the macros in xspi_l.h, added macros in xspi.h file, moved the interrupt register/bit definitions from xspi_i.h to xpsi_l.h. Even for the polled mode of operation the Interrupt Logic in the core should be included. The driver can be put in polled mode of operation by disabling the Global Interrupt after the Spi Initialization is completed and Spi is started. 2.00a sdm 07/30/08 Updated the code to support 16/32 bit transfer width and polled mode of operation, removed the macros in xspi_l.h, added macros in xspi.h file, moved the interrupt register/bit definitions from xspi_i.h to xpsi_l.h. Even for the polled mode of operation the Interrupt Logic in the core should be included. The driver can be put in polled mode of operation by disabling the Global Interrupt after the Spi Initialization is completed and Spi is started. 2.01a sdm 08/22/08 Removed support for static interrupt handlers from the MDD file 2.01b sdm 04/08/09 Fixed an issue in the XSpi_Transfer function where the Global Interrupt is being enabled in polled mode when a slave is not selected. 3.00a ktn 10/22/09 Converted all register accesses to 32 bit access. Updated driver to use the HAL APIs/macros. Removed the macro XSpi_mReset, XSpi_Reset API should be used in its place. The macros have been renamed to remove _m from the name XSpi_mIntrGlobalEnable is renamed XSpi_IntrGlobalEnable, XSpi_mIntrGlobalDisable is now XSpi_IntrGlobalDisable, XSpi_mIsIntrGlobalEnabled is now XSpi_IsIntrGlobalEnabled, XSpi_mIntrGetStatus is now XSpi_IntrGetStatus, XSpi_mIntrClear is now XSpi_IntrClear, XSpi_mIntrEnable is now XSpi_IntrEnable, XSpi_mIntrDisable is now XSpi_IntrDisable, XSpi_mIntrGetEnabled is now XSpi_IntrGetEnabled, XSpi_mSetControlReg is now XSpi_SetControlReg, XSpi_mGetControlReg is now XSpi_GetControlReg, XSpi_mGetStatusReg is now XSpi_GetStatusReg, XSpi_mSetSlaveSelectReg is now XSpi_SetSlaveSelectReg, XSpi_mGetSlaveSelectReg is now XSpi_GetSlaveSelectReg, XSpi_mEnable is now XSpi_Enable, XSpi_mDisable is now XSpi_Disable. 3.01a sdm 04/23/10 Updated the driver to handle new slave mode interrupts and the DTR Half Empty interrupt. 3.02a sdm 03/30/11 Updated to support axi_qspi. 3.03a sdm 08/09/11 Updated the selftest to check for a correct default value in the case of axi_qspi - CR 620502 Updated tcl to generate a config parameter for C_SPI_MODE 3.04a bss 03/21/12 Updated XSpi_Config and XSpi instance structure to support XIP Mode. Updated XSpi_CfgInitialize to support XIP Mode Added XIP Mode Register masks in xspi_l.h Tcl Script changes: Added C_TYPE_OF_AXI4_INTERFACE, C_AXI4_BASEADDR and C_XIP_MODE to config structure. Modified such that based on C_XIP_MODE and C_TYPE_OF_AXI4_INTERFACE parameters C_BASEADDR will be updated with C_AXI4_BASEADDR. Modified such that C_FIFO_EXIST will be updated based on C_FIFO_DEPTH for compatibility of the driver with Axi Spi. 3.05a adk 18/04/13 Updated the code to avoid unused variable warnings when compiling with the -Wextra -Wall flags In the file xspi.c. CR:705005. 3.06a adk 07/08/13 Added a dummy read in the CfgInitialize(), if startup block is used in the h/w design (CR 721229). 3.07a adk 11/10/13 Fixed CR:732962 Changes are made in the xspi.c file 4.0 adk 19/12/13 Updated as per the New Tcl API's 4.1 bss 08/07/14 Modified XSpi_Transfer in xspi.c and LoopbackTest in xspi_selftest.c to check for Interrupt Status register Tx Empty bit instead of Status register CR#810294. 4.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425. Changed the prototype of XSpi_CfgInitialize API. ms 01/23/17 Added xil_printf statement in main function for all examples to ensure that "Successfully ran" and "Failed" strings are available in all examples. This is a fix for CR-965028. ms 03/17/17 Added readme.txt file in examples folder for doxygen generation. ms 04/05/17 Modified Comment lines in functions of spi examples to follow doxygen rules. 4.3 ms 04/18/17 Modified tcl file to add suffix U for all macros definitions of spi in xparameters.h 4.4 tjs 11/28/17 When receive fifo exists, we need to check for status register rx fifo empty flag. If clear we can proceed for read. Otherwise we will hit exception. CR# 989938 4.5 akm 05/29/19 Removed master inhibit dependency while writing DTR in between multiple transfers. 4.5 akm 07/12/19 Fixed compilation error in spi interrupt example by passing the correct interrupt controller instance to SpiIntrExample() function (CR-1035793). 4.7 akm 09/02/20 Updated the Makefile to support parallel make execution. 4.7 akm 10/22/20 Removed dependency of Tx_Full flag while writing DTR in between multiple transfers. 4.8 akm 01/19/21 Fix multiple byte transfer hang issue, when FIFOs are disabled. 4.9 adk 31/01/22 Fix interrupt controller name in SMP designs, Changes are made in the interrupt app tcl file. 4.10 akm 02/21/23 Avoid data loss in interrupt mode with TX HALF EMPTY Interrupt enabled. 4.11 sb 07/11/23 Added support for system device-tree flow.