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

SPIM driver stuck on nrfx_spim_xfer

I'm trying to use the SPIM driver on nRF52832. The setup is:

Chip: nRF52832

SDK: 15

Softdevice: s132 v6

Toolchain: GCC

For some reason the call to nrfx_spim_xfer never returns.

The code:

nrfx_gpiote_in_config_t icm_int1 = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    //icm_int1.pull = NRF_GPIO_PIN_PULLUP;
    nrfx_gpiote_in_init(1, &icm_int1, OnPinEventHandler);
    nrfx_gpiote_in_event_enable(1, true);

    nrfx_spim_config_t spi_cfg =
    {
        .sck_pin = 10, // 10
        .mosi_pin = 9, // 9
        .miso_pin = 3, // 3
        .ss_pin = 2, // 2
        .ss_active_high = false,
        .irq_priority = NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY,
        .orc = 0xFF,
        .frequency = NRF_SPIM_FREQ_1M,
        .mode = NRF_SPIM_MODE_3,
        .bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST,
        NRFX_SPIM_DEFAULT_EXTENDED_CONFIG
    };

    APP_ERROR_CHECK(nrfx_spim_init(&_spi_instance, &spi_cfg, NULL, NULL));

    uint8_t tx[2] = { 0x00 | 0x80, 0 };
    uint8_t rx[2] = { 0 };

    nrfx_spim_xfer_desc_t xfer =
    {
        .p_tx_buffer = tx,
        .tx_length = 2,
        .p_rx_buffer = rx,
        .rx_length= 2,
    };
    
    NRF_LOG_INFO("manual xfer");

    nrfx_spim_xfer(&_spi_instance, &xfer, 0);

    NRF_LOG_INFO("ICM20649: WHOAMI = 0x%X", rx[1]);

This is what I get in the RTT logger:

 0> <info> app: Setting vector table to bootloader: 0x00078000
 0> <info> app: Setting vector table to main app: 0x00026000
 0> <info> SPIM: Function: nrfx_spim_init, error code: NRF_SUCCESS.
 0> <info> app: manual xfer

I've tried to where exactly it got stuck with GDB, so I ran it and stopped the program manually after a few seconds (I've tried it multiple times and got the same results):

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0002dd16 in nrf_spim_event_check (p_reg=0x40003000, spim_event=NRF_SPIM_EVENT_END)
    at D:/nrf/nRF5_SDK_15.0.0_a53641a/modules/nrfx/hal/nrf_spim.h:525
525         return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event);
(gdb) list
520     }
521
522     __STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_reg,
523                                               nrf_spim_event_t spim_event)
524     {
525         return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event);
526     }
527
528     __STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_reg,
529                                                         nrf_spim_event_t spim_event)
(gdb) bt
#0  0x0002dd16 in nrf_spim_event_check (p_reg=0x40003000, spim_event=NRF_SPIM_EVENT_END)
    at D:/nrf/nRF5_SDK_15.0.0_a53641a/modules/nrfx/hal/nrf_spim.h:525
#1  0x0002e464 in spim_xfer (p_spim=0x40003000, p_cb=0x20002dac <m_cb>, p_xfer_desc=0x2000ffb8, flags=0)
    at D:/nrf/nRF5_SDK_15.0.0_a53641a/modules/nrfx/drivers/src/nrfx_spim.c:509
#2  0x0002e59e in nrfx_spim_xfer (p_instance=0x39c6c <_spi_instance>, p_xfer_desc=0x2000ffb8, flags=0)
    at D:/nrf/nRF5_SDK_15.0.0_a53641a/modules/nrfx/drivers/src/nrfx_spim.c:593
#3  0x00036d32 in main () at src/main.c:1036
(gdb)

Looks like the SPIM driver gets stuck waiting for NRF_SPIM_EVENT_END event?

By the way, looking with an oscilloscope on the relevant pins I see no traffic except for the chip select pin.

I ran this test both on our custom PCB (where the SPI slave chip was connected) and on the PCA10040 eval board, both showed the exact same results.

  • I have not spotted any issues with the code you included. Can you upload a full example that demonstrate the issue?

  • I've created a project by copying the example from "\nRF5_SDK_15.0.0_a53641a\examples\peripheral\spi\pca10040\blank" and modified it to use the exact same code. So in this project there is no Softdevice, but this problem still happens both on our custom board and the PCA10040 custom board.

    Note that if you modify, for example, the sck_pin in the config to 11 instead of 10, it will work which is very weird.

    This is the project:

    https://www.dropbox.com/s/6o51dvgcexqmgzt/spi.zip?dl=0\

    The only thing you need to change is the SDK location in the make file, and then use "make flash"

    Alternatively you can modify the example that I modified and paste the following code to main.c:

  • We managed to solve it.

    We found that pins 9 and 10 are shared with the NFC pins, and according to the documentation they are enabled as NFC pins by default. So all we had to do to solve this was adding CONFIG_NFCT_PINS_AS_GPIOS definition in the Makefile.

    P.S

    This exact same code did work before without CONFIG_NFCT_PINS_AS_GPIOS . I suspect that when we started developing the bootloader for our product, and did a lot of full chip erases this setting suddenly came back. Is that a bug or there's some something related to those pins saved in the flash?

  • Hi,I have met it too. Have you solved? I develop based on freertos, but i don't think it is related with os.