2. SPI Adapters Concept

This section explains the procedure to enable and correctly configure the peripheral adapters for SPI functionality. The procedure is a three-step process which can be applied to almost every type of adapter including serial peripheral adapters (I2C, UART) and GPADC adapters.

'The Three-Step Process for Setting the SPI Adapter Mechanism'

Figure 1 The Three-Step Process for Setting the SPI Adapter Mechanism

2.1. Preparing the SPI Adapter

  1. The first step for configuring the SPI adapter mechanism is to enable it by defining the following macros in /config/custom_config_xxx.h file:

/*
 * Macros for enabling SPI operations using Adapters
 */
#define dg_configUSE_HW_SPI                     (1)
#define dg_configSPI_ADAPTER                    (1)

From this point onwards, the overall adapter implementation with all its integrated functions is available.

  1. The second step is to declare IO bus as well as driver configurations for all the devices externally connected on the SPI bus. These settings are applied every time the slave SPI device is selected and used. All the configurations should be placed in platform_devices.c file.

  2. Once the SPI adapter mechanism is enabled, the developer can use all the available APIs for performing SPI transactions. The following steps describe the required sequence of APIs in an application to successfully execute an SPI write/read operation.

    1. ad_spi_init()

      This must be called once at either platform start (system_init()) or task initialization to perform all the necessary SPI initialization routines.

    2. ad_spi_open()

      Before using the SPI interface, the application task must open the device that will access the SPI block. Opening a device involves acquiring all the required resources as well as configuring the SPI controller with the target device and IO bus settings. This function returns a handler to the main flow for use in subsequent adapter functions. Note that this function will block until it acquires all controller resources.

    3. ad_spi_ctivate_cs()

      Before interacting with the target SPI device, the master controller should deassert the Chip Select line (that is, from logic high to logic zero)

    4. Perform a write/read transaction either synchronously or asynchronously.

      After opening a device, the application task can perform any read/write SPI transaction either synchronously or asynchronously. In synchronous mode, the calling task is blocked for the duration of the write/read transaction but other tasks are not. In asynchronous mode, the calling task is not blocked by the write or read operation and thus the application task can continue with other operations while waiting for a user-defined callback function to be called, signaling the completion of the SPI transaction.

      • User-defined callback functions are called from within Interrupt Service Routine (ISR) context. Therefore, callback’s execution time should be as short as possible and not contain complex calculations. Please note that for as long as a system interrupt is serviced, the main application is halted.

      • Do not call asynchronous related APIs consecutively without guaranteeing that the previous asynchronous transaction is finished.

    5. ad_spi_deactivate_cs()

      When the interaction with the target SPI device is done, the master controller should assert the Chip Select line (that is, from logic zero to logic high)

    6. ad_spi_close()

      After all user operations are done and the device is no longer needed, it should be closed. This step involves disabling and de-initializing the SPI block used as well as releasing all the previously acquired resources.

Note

For more detailed information on the SPI APIs please refer to sdk\adapters\include\ad_template.h file.