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

SDK 15.0 SPIM Example Issue on nRF52840

Hey all,

I am trying to run the "nrfx_spim" example on my nRF52840 USB Dongle (Makerdiary nRF52840 USB dongle), however it is not working. It looks like the code is never reaching the interrupt handler "spim_event_handler()". The example code is using SPI3 to run this example, and I confirmed that NRFX_SPIM3 is enabled in the sdk_config.h.

This is a dongle, so I don't have a way of seeing any of the NRF_LOG entries unfortunately.

nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
spi_config.frequency      = NRF_SPIM_FREQ_1M;
spi_config.ss_pin         = NRFX_SPIM_SS_PIN;
spi_config.miso_pin       = NRFX_SPIM_MISO_PIN;
spi_config.mosi_pin       = NRFX_SPIM_MOSI_PIN;
spi_config.sck_pin        = NRFX_SPIM_SCK_PIN;
spi_config.dcx_pin        = NRFX_SPIM_DCX_PIN;
spi_config.use_hw_ss      = true;
spi_config.ss_active_high = true;
spi_config.mode           = NRF_SPIM_MODE_1; 

APP_ERROR_CHECK(nrfx_spim_init(&spi, &spi_config, spim_event_handler, NULL));

Here is the interrupt handler:

void spim_event_handler(nrfx_spim_evt_t const * p_event,
                       void *                  p_context)
{
	bsp_board_led_invert(BSP_BOARD_LED_1);

    spi_xfer_done = true;
    NRF_LOG_INFO("Transfer completed.");
    if (m_rx_buf[0] != 0)
    {
        NRF_LOG_INFO(" Received:");
        NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
    }
}

Here is the main loop that is supposed to send out a packet every 200 ms:

while (1)
{
    // Reset rx buffer and transfer done flag
    memset(m_rx_buf, 0, m_length);
    spi_xfer_done = false;

	APP_ERROR_CHECK(nrfx_spim_xfer(&spi, &xfer_desc, 0));


    while (!spi_xfer_done)
    {
        __WFE();
    }

    NRF_LOG_FLUSH();

    bsp_board_led_invert(BSP_BOARD_LED_1);
    nrf_delay_ms(200);
}

I checked the SPI lines on my oscilloscope, and I see that the SS pin goes high (I have it set to active high polarity), the SPI clock runs, and I can see data being pushed out on the MOSI pin. However, after the transaction ends, the SS pin does not go back low, and the interrupt handler does not trigger. I reckon the issue is with the end of the transaction, but can't figure out what's wrong. I hope someone can help, thanks!

Parents
  • This seems to be a common mistake when using SPI, covered quite a few times here on the devzone so maybe worth looking through some of those posts. In brief the received data is actually the 2nd byte, not the 1st byte. Change this:

        if (m_rx_buf[0] != 0)

    to this:

        if (m_rx_buf[1] != 0)

    mrxbuf must of course be at least 2 bytes long, and the requested received data length must be at least 2 bytes; 1 byte will not work as the SPI slave doesn't know what data to send until it has received and decoded the first transmitted byte.

Reply
  • This seems to be a common mistake when using SPI, covered quite a few times here on the devzone so maybe worth looking through some of those posts. In brief the received data is actually the 2nd byte, not the 1st byte. Change this:

        if (m_rx_buf[0] != 0)

    to this:

        if (m_rx_buf[1] != 0)

    mrxbuf must of course be at least 2 bytes long, and the requested received data length must be at least 2 bytes; 1 byte will not work as the SPI slave doesn't know what data to send until it has received and decoded the first transmitted byte.

Children
Related