This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SDK 15.3.0 nrfx drivers, SPIM, compile errors: "'NRF_DRV_SPI_INSTANCE_2' undeclared here"

In migrating a project from SDK 14.2.0 to SDK 15.3.0, I'm also trying to move from the "legacy" non Easy DMA SPI driver to the Easy DMA one. I don't much care whether I use the nrfx driver or the nrf_drv one.

Here are the compilation errors I'm getting:

Compiling file: gps_ubx_g8020.c

In file included from ./../gps_ubx_g8020.c:14:0:

/usr/local/nRF5_SDK_15.3.0_59ac345/integration/nrfx/legacy/nrf_drv_spi.h:120:37: error: 'NRF_DRV_SPI_INSTANCE_2' undeclared here (not in a function); did you mean 'NRF_DRV_SPI_INSTANCE_'?

#define NRF_DRV_SPI_INSTANCE_(id)   NRF_DRV_SPI_INSTANCE_ ## id

                                     ^

/usr/local/nRF5_SDK_15.3.0_59ac345/integration/nrfx/legacy/nrf_drv_spi.h:119:37: note: in expansion of macro 'NRF_DRV_SPI_INSTANCE_'

#define NRF_DRV_SPI_INSTANCE(id)    NRF_DRV_SPI_INSTANCE_(id)

                                     ^~~~~~~~~~~~~~~~~~~~~

./../gps_ubx_g8020.c:215:36: note: in expansion of macro 'NRF_DRV_SPI_INSTANCE'

static const nrf_drv_spi_t m_spi = NRF_DRV_SPI_INSTANCE(2);

                                    ^~~~~~~~~~~~~~~~~~~~

make: *** [_build/app/gps_ubx_g8020.c.o] Error 1

And here's my app_config.h:

#define SPIM_ENABLED 1
#define SPIM0_ENABLED 0
#define SPIM1_ENABLED 0
#define SPIM2_ENABLED 1
#define SPIM_MISO_PULL_CFG 0
#define SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 6
#define SPIM_CONFIG_LOG_ENABLED 1
#define SPIM_CONFIG_LOG_LEVEL 4
#define SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1
I've also tried with all of these:
#define NRFX_SPIM_ENABLED 1
#define NRFX_SPIM0_ENABLED 0
#define NRFX_SPIM1_ENABLED 0
#define NRFX_SPIM2_ENABLED 1
#define NRFX_SPIM_MISO_PULL_CFG 0
#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 6
#define NRFX_SPIM_CONFIG_LOG_ENABLED 1
#define NRFX_SPIM_CONFIG_LOG_LEVEL 4
#define NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1
In general, I find this nrfx legacy stuff very confusing, and this kind of thing in nrf_drv_spi.h more or less impossible to understand:
#if defined(SPI_PRESENT) && !defined(SPIM_PRESENT)
#define NRF_DRV_SPI_WITH_SPI
#elif !defined(SPI_PRESENT) && defined(SPIM_PRESENT)
// Bike Tracker: We are here.
#define NRF_DRV_SPI_WITH_SPIM
#else
#if (NRFX_CHECK(SPI0_ENABLED) && NRFX_CHECK(SPI0_USE_EASY_DMA)) || \
(NRFX_CHECK(SPI1_ENABLED) && NRFX_CHECK(SPI1_USE_EASY_DMA)) || \
(NRFX_CHECK(SPI2_ENABLED) && NRFX_CHECK(SPI2_USE_EASY_DMA))
#define NRF_DRV_SPI_WITH_SPIM
#endif
#if (NRFX_CHECK(SPI0_ENABLED) && !NRFX_CHECK(SPI0_USE_EASY_DMA)) || \
(NRFX_CHECK(SPI1_ENABLED) && !NRFX_CHECK(SPI1_USE_EASY_DMA)) || \
(NRFX_CHECK(SPI2_ENABLED) && !NRFX_CHECK(SPI2_USE_EASY_DMA))
#define NRF_DRV_SPI_WITH_SPI
#endif
#endif
#if defined(NRF_DRV_SPI_WITH_SPIM) && defined(NRF_DRV_SPI_WITH_SPI)
#define NRF_DRV_SPI_USE_SPIM (p_instance->use_easy_dma)
#elif defined(NRF_DRV_SPI_WITH_SPIM)
// Bike Tracker: We are here.
#define NRF_DRV_SPI_USE_SPIM true
#else
#define NRF_DRV_SPI_USE_SPIM false
#endif
#define NRF_DRV_SPI_USE_SPI (!NRF_DRV_SPI_USE_SPIM)
What do I do?
[Edit]
Here's how I init the SPI driver:
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;

// These pin definitions work on both our custom board and the DK. For the DK they all just end up as NRF_DRV_SPI_PIN_NOT_USED.
spi_config.ss_pin = PIN_DEF_GPS_SPI1_CS;
spi_config.miso_pin = PIN_DEF_GPS_SPI1_MISO;
spi_config.mosi_pin = PIN_DEF_GPS_SPI1_MOSI;
spi_config.sck_pin = PIN_DEF_GPS_SPI1_SCK;

// SPI mode. uBlox datasheet: SPI modes 0-3 are implemented. Wisol support: use mode 1. Wisol driver: use mode 0. In testing, both mode 0 and mode 1 work.
spi_config.mode = NRF_DRV_SPI_MODE_0;

// Other config values from NRF_DRV_SPI_DEFAULT_CONFIG:
// .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY (defined in sdk_config.h as 6)
// .orc = 0xFF
// ORC: Over-run character. This character is used when all bytes from the TX buffer are sent, but the transfer continues due to RX.
// uBlox: When no data is available to be written to the receiver, MOSI should be held logic high, i.e. all bytes written to the receiver are set to 0xFF.
// .frequency = NRF_DRV_SPI_FREQ_4M
// uBlox: u-blox 8 / u-blox M8 receivers support a maximum SPI clock speed of 5.5 MHz. Wisol's driver uses 125K frequency, not the default 4M. In testing, 4M works fine though, so we may as well go faster.
// .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST

// Async:
err_code = nrf_drv_spi_init(&m_spi, &spi_config, gps_spi_event_handler, NULL); // No context.
APP_ERROR_CHECK(err_code);
And here are my pin numbers from custom_board.h:
#define PIN_DEF_GPS_SPI1_MISO (28) // I High GPS SPI master in slave out
#define PIN_DEF_GPS_SPI1_MOSI (29) // O High GPS SPI master out slave in
#define PIN_DEF_GPS_SPI1_SCK (30) // O High GPS SPI serial clock
#define PIN_DEF_GPS_SPI1_CS (31) // O Low GPS SPI slave select
Parents
  • I would strongly advise starting with high drive on both high and low levels for SPI output signals, particularly at 4MHz; once everything is running then maybe try reducing the low or high drive to see if it still works. I would personally leave at highdrive though.
    After this call:

    err_code = nrf_drv_spi_init(&m_spi, &spi_config, gps_spi_event_handler, NULL);

    Turn on high drive for the 3 output signals from nRF52:

       // High power output pins in active-low state only
       nrf_gpio_cfg(PIN_DEF_GPS_SPI1_CS,
                    NRF_GPIO_PIN_DIR_OUTPUT,
                    NRF_GPIO_PIN_INPUT_DISCONNECT,
                    NRF_GPIO_PIN_NOPULL,
                    NRF_GPIO_PIN_H0H1,       // Start with High Drive both high and low levels
                    NRF_GPIO_PIN_NOSENSE);
    
       nrf_gpio_cfg(PIN_DEF_GPS_SPI1_SCK,
                    NRF_GPIO_PIN_DIR_OUTPUT,
                    NRF_GPIO_PIN_INPUT_DISCONNECT,
                    NRF_GPIO_PIN_NOPULL,
                    NRF_GPIO_PIN_H0H1,       // Start with High Drive both high and low levels
                    NRF_GPIO_PIN_NOSENSE);
    
       nrf_gpio_cfg(PIN_DEF_GPS_SPI1_MOSI,
                    NRF_GPIO_PIN_DIR_OUTPUT,
                    NRF_GPIO_PIN_INPUT_DISCONNECT,
                    NRF_GPIO_PIN_NOPULL,
                    NRF_GPIO_PIN_H0H1,       // Start with High Drive both high and low levels
                    NRF_GPIO_PIN_NOSENSE);

    This step has solved a few similar issues.

    One other item, on the nRF52832 pins 28, 29 30 and 31 are recommended "Low drive, low frequency I/O only" as they are sited close to the radio and are therefore not recommended for use as SPI if using the radio. On the nRF52840 these 4 pins are not available in High Drive for the same reason.

Reply
  • I would strongly advise starting with high drive on both high and low levels for SPI output signals, particularly at 4MHz; once everything is running then maybe try reducing the low or high drive to see if it still works. I would personally leave at highdrive though.
    After this call:

    err_code = nrf_drv_spi_init(&m_spi, &spi_config, gps_spi_event_handler, NULL);

    Turn on high drive for the 3 output signals from nRF52:

       // High power output pins in active-low state only
       nrf_gpio_cfg(PIN_DEF_GPS_SPI1_CS,
                    NRF_GPIO_PIN_DIR_OUTPUT,
                    NRF_GPIO_PIN_INPUT_DISCONNECT,
                    NRF_GPIO_PIN_NOPULL,
                    NRF_GPIO_PIN_H0H1,       // Start with High Drive both high and low levels
                    NRF_GPIO_PIN_NOSENSE);
    
       nrf_gpio_cfg(PIN_DEF_GPS_SPI1_SCK,
                    NRF_GPIO_PIN_DIR_OUTPUT,
                    NRF_GPIO_PIN_INPUT_DISCONNECT,
                    NRF_GPIO_PIN_NOPULL,
                    NRF_GPIO_PIN_H0H1,       // Start with High Drive both high and low levels
                    NRF_GPIO_PIN_NOSENSE);
    
       nrf_gpio_cfg(PIN_DEF_GPS_SPI1_MOSI,
                    NRF_GPIO_PIN_DIR_OUTPUT,
                    NRF_GPIO_PIN_INPUT_DISCONNECT,
                    NRF_GPIO_PIN_NOPULL,
                    NRF_GPIO_PIN_H0H1,       // Start with High Drive both high and low levels
                    NRF_GPIO_PIN_NOSENSE);

    This step has solved a few similar issues.

    One other item, on the nRF52832 pins 28, 29 30 and 31 are recommended "Low drive, low frequency I/O only" as they are sited close to the radio and are therefore not recommended for use as SPI if using the radio. On the nRF52840 these 4 pins are not available in High Drive for the same reason.

Children
Related