6. SPI Interface

In this document we show how to initiate SPI communication on SDK6. To gain a better understanding of the SPI interface please take a look at SPI Architecture, Timing and SPI Controller Enhancements in DA1453x or DA1458x datasheets.

Please take a look at the following references:

6.1. Features

  • Slave and master mode

  • From 4-bit to up to 32-bit operation

  • SPI Master clock line speed up to 32 MHz, SPI Slave clock line speed up to 16 MHz

  • SPI mode 0, 1, 2, and 3 support (clock edge and phase)

  • Built-in separate 8-bit wide and 4-byte deep RX/TX FIFOs for continuous SPI bursts

  • Maskable interrupt generation based on TX or RX FIFO thresholds

  • DMA support

6.2. SPI configuration in SDK6:

To start any peripheral project we suggest to start with empty_peripheral_template from SDK6 projects here we will only show how to configure SPI interface.

SPI examples

There are two examples in BLE SDK6 examples , Please take a look to see how to use SPI in action:

  • DA14531 SPI Master Slave example .This example describes how to perform SPI data buffer transmission/reception between two DA14531 devices (you can also use other members of DA1453x family for this example) via DMA. The project is split in two parts: The master board and the slave board.

  • SPI or I2C reading with DMA . This example demonstrates how to use SPI or I2C to interface with the LIS2DH accelerometer.

  1. In SDK6 the peripheral configuration can be done in user_periph_setup module. Make sure to include SPI header in your project:

#include "spi.h"

In user_periph_setup.h the SPI Configuration for master is as follow:

#define SPI_EN_PORT             GPIO_PORT_0
#define SPI_EN_PIN              GPIO_PIN_8

#define SPI_CLK_PORT            GPIO_PORT_0
#define SPI_CLK_PIN             GPIO_PIN_6

#define SPI_DO_PORT             GPIO_PORT_0
#define SPI_DO_PIN              GPIO_PIN_9

#define SPI_DI_PORT             GPIO_PORT_0
#define SPI_DI_PIN              GPIO_PIN_11

#define SPI_MS_MODE             SPI_MS_MODE_MASTER
#define SPI_CP_MODE             SPI_CP_MODE_0
#define SPI_WSZ                 SPI_MODE_8BIT
#define SPI_CS                  SPI_CS_0

#define SPI_SPEED_MODE          SPI_SPEED_MODE_2MHz
#define SPI_EDGE_CAPTURE        SPI_MASTER_EDGE_CAPTURE

For the slave only you need to change the configuration between SPI_DI_PIN and SPI_DO_PIN.

To customize the desired parameters , you can change macros in user_periph_setup.h:
  • SPI_MS_MODE: SPI Mode (Master or Slave).

  • SPI_CP_MODE: SPI Clock Polarity mode.

  • SPI_WSZ: SPI Word Size.

  • SPI_CS: SPI Chip Select.

  • SPI_SPEED_MODE: SPI Speed mode.

  • SPI_EDGE_CAPTURE: SPI Edge Capture mode for Master.

Warning

The above configuration is based on DA14531 SPI Master Slave example You can change based on your requirements.

  1. After that in for the Configuration of the Pin go to user_periph_setup.c and then in function void set_pad_functions(void) set the pins function:

// Configure SPI pins
GPIO_ConfigurePin(SPI_EN_PORT, SPI_EN_PIN, OUTPUT, PID_SPI_EN, true);
GPIO_ConfigurePin(SPI_CLK_PORT, SPI_CLK_PIN, OUTPUT, PID_SPI_CLK, false);
GPIO_ConfigurePin(SPI_DO_PORT, SPI_DO_PIN, OUTPUT, PID_SPI_DO, false);
GPIO_ConfigurePin(SPI_DI_PORT, SPI_DI_PIN, INPUT, PID_SPI_DI, false);

The initialization of the SPI is performed in the spi_initialize(&spi_cfg) function call within the periph_init function. This function is the combination of the steps we explained before:

In this example spi_cfg is used to hold configuration parameters for SPI peripheral.

static const spi_cfg_t spi_cfg = {
    .spi_ms = SPI_MS_MODE,
    .spi_cp = SPI_CP_MODE,
    .spi_speed = SPI_SPEED_MODE,
    .spi_wsz = SPI_WSZ,
    .spi_cs = SPI_CS,
    .cs_pad.port = SPI_EN_PORT,
    .cs_pad.pin = SPI_EN_PIN,
    .spi_capture = SPI_EDGE_CAPTURE,
#if defined (CFG_SPI_DMA_SUPPORT)
    .spi_dma_channel = SPI_DMA_CHANNEL_01,
    .spi_dma_priority = DMA_PRIO_0,
#endif
};

The SPI communication then will initialized during the peripheral initialization through the function periph_init() function at the beginning of the main program (system_init()). The spi_transfer function is called to start sending/receiving data to/from SPI in full duplex mode.