| nRF5 SDK v12.0.0 |

Choose documentation: | nRF5 SDK | S130 SoftDevice API | S132 SoftDevice API | S212 SoftDevice API | S332 SoftDevice API

All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
SPI slave

The SPI slave driver includes two layers: the hardware access layer (HAL) and the driver layer (DRV).

The hardware access layer provides basic APIs for accessing the registers of the SPIS peripheral. See the API documentation for the SPIS HAL for details.

The driver layer provides APIs on a higher level than the HAL. See the API documentation for the SPI slave driver for details.

Key features include:

- Multi-instance support
- SPI slave EasyDMA functionality for reading from and writing to the RAM

Note that peripherals using EasyDMA can work only with buffers that are placed in the data RAM region. Under certain circumstances, compilers might choose to use a different region for data placement and, for example, place a constant buffer in the code FLASH. In such a case, the SPIS peripheral cannot be used to transfer data from the buffer.

To quickly get started, use the sample code from the SPI Slave Example.

# Driver configuration

The SPI slave driver can use multiple instances of SPIS. The instances of the peripherals that are to be assigned to the driver must be selected statically in `sdk_config.h`, for example:

#define SPIS1_ENABLED 1

For enabled instances, you can use the macro that provides the default configuration - NRF_DRV_SPIS_DEFAULT_CONFIG. The settings for this macro are defined in `sdk.config.h`, for example:

#define SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 6
#define SPIS_DEFAULT_MODE 0
#define SPIS_DEFAULT_DEF 255
#define SPIS_DEFAULT_ORC 255

The macro sets pins to value NRF_DRV_SPIS_PIN_NOT_USED. Remember to refer to the nrf_drv_spis_config_t struct and set proper pins.

# Using the SPI slave driver

Call the NRF_DRV_SPIS_INSTANCE macro with the ID of the peripheral instance that you want to use to create a driver instance. For example, this code will create a driver instance that uses the SPIS1 peripheral:

static const nrf_drv_spis_t m_spi_slave_1 = NRF_DRV_SPIS_INSTANCE(1);

Next, call nrf_drv_spis_init to initialize and configure the instance. See the nrf_drv_spis_config_t structure documentation for possible configuration options. To receive data, the SPI buffers must be set by calling nrf_drv_spis_buffers_set after initialization.

For example:

static volatile uint8_t m_slave_tx_buffer[8];
static volatile uint8_t m_slave_rx_buffer[8];
static void spi_slave_handler(nrf_drv_spis_event_t event)
{
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
{
// Received bytes: event.rx_amount.
}
}
/* ... */
uint32_t err_code;
nrf_drv_spis_config_t config = NRF_DRV_SPIS_DEFAULT_CONFIG(1);
config.mode = NRF_DRV_SPIS_MODE_3;
config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST;
err_code = nrf_drv_spis_init(&m_spi_slave_1, &config, spi_slave_handler);
if (err_code != NRF_SUCCESS)
{
// Initialization failed. Take recovery action.
}
err_code = nrf_drv_spis_buffers_set(mp_spis,
(uint8_t*) m_slave_tx_buffer, sizeof(m_slave_tx_buffer),
(uint8_t*) m_slave_rx_buffer, sizeof(m_slave_rx_buffer));
if (err_code != NRF_SUCCESS)
{
// Buffer setup failed. Take recovery action.
}

The callback handler function will be called after every successful buffer setup and every completed transfer. New buffers must be set by calling nrf_drv_spis_buffers_set after every finished transaction. Otherwise, the transaction is ignored, and the default character is clocked out.

When the SPI slave driver instance is no longer needed or its configuration must be changed, call nrf_drv_spis_uninit.