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.
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.
After that in for the Configuration of the Pin go to
user_periph_setup.c
and then in functionvoid 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.