Ok so I am trying to integrate SPI master and slave initialization code. I am very confused about legacy and non-legacy drivers and HAL. I am getting strange compilation and linking errors. Please help me out on this.
I am compiling following SPI related driver files in my IAR project:
- modules\nrfx\drivers\src\nrfx_spi.c
- modules\nrfx\drivers\src\nrfx_spis.c
- modules\nrfx\drivers\src\nrfx_spim.c
- integration\nrfx\legacy\nrf_drv_spi.c
- integration\nrfx\legacy\nrf_drv_spis.c
sdk_config.h settings for SPI:
// <e> NRFX_SPIM_ENABLED - nrfx_spim - SPIM peripheral driver //========================================================== #ifndef NRFX_SPIM_ENABLED #define NRFX_SPIM_ENABLED 0 #endif // <q> NRFX_SPIM0_ENABLED - Enable SPIM0 instance #ifndef NRFX_SPIM0_ENABLED #define NRFX_SPIM0_ENABLED 0 #endif // <q> NRFX_SPIM1_ENABLED - Enable SPIM1 instance #ifndef NRFX_SPIM1_ENABLED #define NRFX_SPIM1_ENABLED 0 #endif // <q> NRFX_SPIM2_ENABLED - Enable SPIM2 instance #ifndef NRFX_SPIM2_ENABLED #define NRFX_SPIM2_ENABLED 0 #endif // <e> NRFX_SPIS_ENABLED - nrfx_spis - SPIS peripheral driver //========================================================== #ifndef NRFX_SPIS_ENABLED #define NRFX_SPIS_ENABLED 1 #endif // <q> NRFX_SPIS0_ENABLED - Enable SPIS0 instance #ifndef NRFX_SPIS0_ENABLED #define NRFX_SPIS0_ENABLED 1 #endif // <q> NRFX_SPIS1_ENABLED - Enable SPIS1 instance #ifndef NRFX_SPIS1_ENABLED #define NRFX_SPIS1_ENABLED 0 #endif // <q> NRFX_SPIS2_ENABLED - Enable SPIS2 instance #ifndef NRFX_SPIS2_ENABLED #define NRFX_SPIS2_ENABLED 0 #endif // <e> NRFX_SPI_ENABLED - nrfx_spi - SPI peripheral driver //========================================================== #ifndef NRFX_SPI_ENABLED #define NRFX_SPI_ENABLED 1 #endif // <q> NRFX_SPI0_ENABLED - Enable SPI0 instance #ifndef NRFX_SPI0_ENABLED #define NRFX_SPI0_ENABLED 1 #endif // <q> NRFX_SPI1_ENABLED - Enable SPI1 instance #ifndef NRFX_SPI1_ENABLED #define NRFX_SPI1_ENABLED 0 #endif // <q> NRFX_SPI2_ENABLED - Enable SPI2 instance #ifndef NRFX_SPI2_ENABLED #define NRFX_SPI2_ENABLED 0 #endif // <e> SPIS_ENABLED - nrf_drv_spis - SPIS peripheral driver - legacy layer //========================================================== #ifndef SPIS_ENABLED #define SPIS_ENABLED 1 #endif // <q> SPIS0_ENABLED - Enable SPIS0 instance #ifndef SPIS0_ENABLED #define SPIS0_ENABLED 1 #endif // <q> SPIS1_ENABLED - Enable SPIS1 instance #ifndef SPIS1_ENABLED #define SPIS1_ENABLED 0 #endif // <q> SPIS2_ENABLED - Enable SPIS2 instance #ifndef SPIS2_ENABLED #define SPIS2_ENABLED 0 #endif // <e> SPI_ENABLED - nrf_drv_spi - SPI/SPIM peripheral driver - legacy layer //========================================================== #ifndef SPI_ENABLED #define SPI_ENABLED 1 #endif // <e> SPI0_ENABLED - Enable SPI0 instance //========================================================== #ifndef SPI0_ENABLED #define SPI0_ENABLED 1 #endif // <e> SPI1_ENABLED - Enable SPI1 instance //========================================================== #ifndef SPI1_ENABLED #define SPI1_ENABLED 0 #endif // <e> SPI2_ENABLED - Enable SPI2 instance //========================================================== #ifndef SPI2_ENABLED #define SPI2_ENABLED 0 #endif
init.c#include "common.h"
#include "nrf_drv_spi.h"
#include "nrf_drv_spis.h"
volatile bool bSpiMasterTxRxDone = false;
volatile bool bSpiSlaveTxRxDone = false;
nrf_drv_spi_t const hSpiMasterDev0 = NRF_DRV_SPI_INSTANCE(SPI_DEV_ID_0);
nrf_drv_spis_t const hSpiSlaveDev0 = NRF_DRV_SPIS_INSTANCE(SPI_DEV_ID_0);
/**
* @brief SPI master event handler.
* @param event
*/
static void spi_master_event_handler(nrf_drv_spi_evt_t const * p_event,
void * p_context)
{
bSpiMasterTxRxDone = true;
NRF_LOG_INFO("Transfer completed.");
}
/**
* @brief SPI Slave event handler.
*
* @param event
*/
static void spis_slave_event_handler(nrf_drv_spis_event_t event)
{
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
{
bSpiSlaveTxRxDone = true;
}
}
/**@brief Function for initializing SPI controller in master or slave mode
*/
void spi_init(void const * pHSpiDev,
SPI_MODE_TYPE const spi_mode)
{
ret_code_t err_code;
if( SPI_MODE_MASTER == spi_mode)
{
assert( pHSpiDev != NULL );
nrf_drv_spi_config_t spi_master_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_master_config.ss_pin = SPI_CS_PIN;
spi_master_config.miso_pin = SPI_MISO_PIN;
spi_master_config.mosi_pin = SPI_MOSI_PIN;
spi_master_config.sck_pin = SPI_SCK_PIN;
spi_master_config.frequency = SPI_MASTER_BIT_RATE;
spi_master_config.bit_order = SPI_MASTER_BIT_ORDER;
spi_master_config.mode = SPI_MASTER_MODE;
spi_master_config.orc = 255;
err_code = nrf_drv_spi_init((nrf_drv_spi_t const*)pHSpiDev, &spi_master_config, spi_master_event_handler, NULL);
APP_ERROR_CHECK(err_code);
}
else if(SPI_MODE_SLAVE == spi_mode)
{
assert( pHSpiDev != NULL );
nrf_drv_spis_config_t spi_slave_config = NRF_DRV_SPIS_DEFAULT_CONFIG;
spi_slave_config.miso_pin = SPI_MISO_PIN;
spi_slave_config.mosi_pin = SPI_MOSI_PIN;
spi_slave_config.sck_pin = SPI_SCK_PIN;
spi_slave_config.csn_pin = SPI_CS_PIN;
spi_slave_config.mode = SPI_SLAVE_MODE;
spi_slave_config.bit_order = SPI_SLAVE_BIT_ORDER;
spi_slave_config.def = 255;
spi_slave_config.orc = 255;
// How to specify SCK for SPI slave ?????
err_code = nrf_drv_spis_init((nrf_drv_spis_t const*)pHSpiDev, &spi_slave_config, spis_slave_event_handler);
APP_ERROR_CHECK(err_code);
}
else
{
// Default SPI mode is slave
}
}
common.h
#ifndef COMMON_H
#define COMMON_H
/* SPI Modes */
typedef enum
{
SPI_MODE_MASTER,
SPI_MODE_SLAVE
}SPI_MODE_TYPE;
/* GPIO pin for SPI MOSI(12/P0.13) */
#define SPI_MOSI_PIN ((nrfx_gpiote_pin_t)13)
/* GPIO pin for SPI MISO(14/P0.14) */
#define SPI_MISO_PIN ((nrfx_gpiote_pin_t)14)
/* GPIO pin for SPI SCK(13/P0.12)*/
#define SPI_SCK_PIN ((nrfx_gpiote_pin_t)12)
/* GPIO pin for SPI CS(11/P0.15)*/
#define SPI_CS_PIN ((nrfx_gpiote_pin_t)15)
#define SPI_MASTER_BIT_RATE NRF_DRV_SPI_FREQ_125K
#define SPI_SLAVE_BIT_RATE ???????
#define SPI_MASTER_BIT_ORDER NRF_DRV_SPI_BIT_ORDER_MSB_FIRST
#define SPI_SLAVE_BIT_ORDER NRF_SPIS_BIT_ORDER_MSB_FIRST
#define SPI_MASTER_MODE NRF_DRV_SPI_MODE_0
#define SPI_SLAVE_MODE NRF_SPIS_MODE_0
#define SPI_DEV_ID_0 0
extern void spi_init(void const * pHSpiDev,
SPI_MODE_TYPE const spi_mode);
#endif /* COMMON_H */
main.c
#include "common.h" #include "nrf_drv_spi.h" #include "nrf_drv_spis.h" extern nrf_drv_spi_t const hSpiMasterDev0; extern nrf_drv_spis_t const hSpiSlaveDev0; int main() { // various init codes // ... //.. // spi init spi_init(&hSpiSlaveDev0, BMNL_SPI_MODE_SLAVE ); }
What I need:
- One SPI controller on nrf52832 that I want o use in either master or mode (as I have just four hardwired GPIO pins connected to my another device on my custom board. ). I will switch the mode of the same SPI controller device from slave to master and vice versa as needed(depends on which state my nrf52 is in).
- Specify frequency(mbps,hz) for both master/slave configuration. I did find this setting for master, but for some reason I cannot locate this in initialization C structures for slave configuration.
- Blocking/non-blocking modes in DMA/non-DMA configuration
- I prefer not to use any legacy SPI driver/hal unless I will compromise on above requirements.
So here are my questions:
- Which SPI driver/HAL header (.h) files should I use in my C code and which C driver/HAL files should I compile & link with my project ?
- What is the different between SPI, SPIM and SPIS ? Which one should I use for master and which one for slave ?
- Which of the following flags should I enable to use 0th SPI controller instance for master/slave ?
- How do I specify frequency configuration for SPI slave configuration ?