Setting Up SPI in nRF52xx
Image for post

Prerequisites

This is tutorial is not intended to be a guide for learning C language or about the Nordic SDK platform. It’s primary target is to provide developers a concise guide about integrating peripheral modules and features into active applications.

If you are a beginner, I would recommend you look into an nRF52 Project Setup guide like this one.

https://medium.com/vicara-hardware-university/nrf52-project-setup-with-segger-embedded-system-f64958052a2d

Another easy way to get started with coding, without bothering with all basic stuff like files and driver inclusion, check out this Code Generation Tool

nrf52 Code Generator: https://vicara.co/nrf52-code-generator

SPI

Serial Peripheral Interface is a communication protocol for sending and receiving data between many devices in a serial and synchronous method. It can be a 4 channel or a 3-channel method depending on the users choice of configuration.

The most popular one is 3-channel, with MOSI, MISO and SCK. MOSI (Master Out Slave In), writes data to a slave device. MISO (Master In Slave Out) reads data from slave device. SCK is the clock signal which synchronizes communication between devices. Devices like IMU, Motor Control Units and Sensor interfaces use SPI.

There may also be the IRQ pin for interrupt and CS/SS for Chip Enable on SPI devices.

Image for post

Implementing SPI in nRF52832

In the following section, I will provide a guide as it has been tested in the nRF52832 Dev Kit. However, the same structure will remain common across all nRF52 devices.

Including correct Headers

Image for post

Include the SPI Driver files. This file should be titled, nrf_drv_spi.c It is at SDK/integration/nrfx/legacy folder.

Update sdk_config.h File

  • SPI_ENABLED has to be set to

In main.c File

Header File

#include "nrf_drv_spi.h"

Define SPI Instance

staticconstnrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(1);

Define Callback Function


staticvoidspi_event_handler(nrf_drv_spi_evt_tconst * p_event,
void *                    p_context)
{//Callback which is triggered when a SPI transfer occcurs

}

Initialize SPI Instance

staticvoidspi_init(void)
{
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
 spi_config.frequency = NRF_DRV_SPI_FREQ_4M;
 spi_config.mode = NRF_DRV_SPI_MODE_0;
 spi_config.ss_pin   = 7;
 spi_config.miso_pin = 4;
 spi_config.mosi_pin = 5;
 spi_config.sck_pin  = 6;
 spi_config.orc = 0xFF;
 spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
 spi_config.irq_priority = APP_IRQ_PRIORITY_LOW;

 APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
}

Note: The number of pins linked to each instance of this peripheral is always 4.

Add spi_init() to main()

spi_init();

Conclusion

With the above steps anyone can easily get started with incorporating SPI.

NOTE

There is another easier method to initialize and auto-generate code for nRF52. This tool, will handle all library additions and code generations for a variety of peripherals like SPI, I2C, UART etc.

Link: https://vicara.co/nrf52-code-generator