The driver provides basic SPI functionality supporting both Master and Slave, each with or without interrupts.
The SPI driver is configured using MCC/START. The user can choose from the four modes of operation (master/slave, polled/IRQ). MCC/START also allows the user to select SCK frequency, data order, data polarity and data phase.
The SPI must be opened by calling <component_name>_open() before it can be used. After use, the SPI is closed by calling <component_name>_close(). A call to <component_name>_open() for a SPI which is already open will return a false value, indicating that the SPI is already busy on behalf of another process.
If several SPI hardware instances are available on the device, the user can select which SPI instance the driver shall use.
When in master mode, the SPI generates the SCK clock. Data is driven out on the MOSI I/O pin according to the configured phase and polarity.
When in slave mode, the SPI receives the SCK clock from the master and uses this to sample data on the MOSI I/O pin. The phase and polarity must be configured according to the values used by the master.
All these functions are blocking: The functions will not return before the operations have completed.
The functions checking the SPI bus status are included in the interrupt driven driver to allow the application to know the state of the SPI transfer. They are not needed in the polled driver since this driver blocks until the operation has completed.
The SPI bus is in one of the states listed in spi_transfer_status_t. The bus state is used by the exchange one byte function: This function will wait until the SPI bus is no longer BUSY before exchanging a byte. This allows the exchange byte function to work seamlessly with the exchange, receive and transmit block functions.
In IRQ mode, the ISR can be configured to call a callback function before exiting. This is done by calling the function <component_name>_register_callback() with a pointer to the callback function as parameter. Registering a NULL pointer as callback causes no callback function to be called. NULL is the default value of the callback function pointer.
A SPI master usually controls a Slave Select pin to choose the slave to communicate with. The SPI driver does not manipulate the Slave Select (SS_bar) I/O pin. If the user wants to control SS_bar before and after a transfer, this has to be done using normal I/O port operations.
The <component_name>_open()-function takes a parameter, namely the name of the configuration to use when opening the SPI. A configuration is a set of SPI-related parameters such as SCK frequency, SPI phase and polarity etc. The parameters controlled by a configuration depends on the underlying hardware the SPI Basic driver uses.
Different configurations allows the SPI to use one setup when communicating with one SPI slave, and another configuration when communicating with another slave. As an example, assume a SPI system with one master and two slaves SLAVE_A and SLAVE_B.
To open a connection to SLAVE_A, the master would call <component_name>_open(SLAVE_A), to open a connection to SLAVE_B, <component_name>_open(SLAVE_B) would be called. These calls would reconfigure the SPI hardware appropriately.
The SPI Basic driver provides one configuration named DEFAULT. This is the configuration that the user configured in MCC/START. The user can provide additional configurations by modifying spi.c and spi.h appropriately.
The SPI Basic driver usually uses some sort of hardware that implements SPI functionality, even though it is possible to implement a software SPI implemented by bit-banging I/O pins.
Different MCUs have SPI hardware with different names and functionalities, such as UART, SPI, USI etc. In MCC/START, the user selects a device and adds the SPI driver. A device may have several possible hardware resources available for the driver, such as SPI0, SPI1 etc. In this case the user must select which one to use.
The configuration options in MCC/START displays options that are dependent on the hardware used to implement the SPI driver. For example, an option may allow changing the baud rate used to drive the underlying SPI hardware.
The interrupt-driven configurations use the interrupt functionality of the underlying SPI hardware. Make sure that global interrupts are enabled and that the Interrupt Controller, if present, is configured so that any interrupts are serviced correctly.