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

BLE disconnects during multiple SPI transfers on nrf52832

Hello everyone,

I have a nrf52832 (SDK v15.2.0) that is connected to a tablet via BLE.  However, if I have several SPI transfers one after another, the BLE suddenly disconnects. It doesn't make a difference neither if I use the DMA or if I'm blocking. The priority of the SPI interrupts is also very low and equal to 6. I need to mention that all the SPI transfers are done in the function I schedule once (which is called do_all_the_xfers() here). So it looks the following:

static void do_all_the_xfers(void * data, uint16_t len) {
    for(uint32_t i = 0; i < 4294967295; i++) {
        status = pltf_spim_xfer2();
        if(status != NO_ERROR) return;
    }
}

While pltf_spim_xfer2() looks like this:

static const nrfx_spi_t spi = NRFX_SPI_INSTANCE(FLASH_SPI_INSTANCE);
bool spi_xfer_done = false;

void spi_event_handler(nrfx_spi_evt_t const * p_event,
                       void *                    p_context) {
    spi_xfer_done = true;
}

status_t pltf_spim_xfer2(void) {
   uint32_t err_code, flags;

   flags = 0;
   spi_xfer_done = false;
   nrfx_spi_xfer_desc_t xfer;
   char read_id_cmd = 0x9F;
   char rx_buf[3];
  
   xfer.p_tx_buffer = &read_id_cmd;
   xfer.tx_length = 1;
   xfer.p_rx_buffer = NULL;
   xfer.rx_length   = 0;

   nrf_gpio_pin_clear(FLASH_SPI_SS_PIN);
   err_code = nrfx_spi_xfer(&spi, &xfer, flags);
   if(err_code != 0) { NRF_LOG_INFO("err_code: %i", err_code); NRF_LOG_FLUSH(); }

   while(!spi_xfer_done){};

   spi_xfer_done = false;
   xfer.p_tx_buffer = NULL;
   xfer.tx_length = 0;
   xfer.p_rx_buffer = rx_buf;
   xfer.rx_length   = 3;

   nrf_gpio_pin_clear(FLASH_SPI_SS_PIN);
   err_code = nrfx_spi_xfer(&spi, &xfer, flags);
   if(err_code != 0) { NRF_LOG_INFO("err_code: %i", err_code); NRF_LOG_FLUSH(); }

   while(!spi_xfer_done){};

   return  NO_ERROR;
}

Therefore, the scheduler doesn't go back to the main loop until its done with all the transfers. Nevertheless, according to my understanding the Bluetooth has such a high priority that even in case of a while(1) loop, its interrupts are handled. So what could be the problem?

Thanks in advance!

Parents
  • Hello,

    From where do you call do_all_the_xfers()?

    The SPI interrupt priority decides the interrupt priority, that is, what priority SPI messages from the external device will use.

    If you call do_all_the_xfers() from a callback with higher priority, that will be the priority that this SPI transfer use.

    So where do you call do_all_the_xfers() from?

  • Hi Edvin,

    After pressing a certain button on the tablet I receive a Bluetooth callback on the nrf side. Within this callback I call app_sched_event_put(NULL, 0, do_all_the_xfers); I guess, this should be ok, since it will be worked off by the main thread afterwards, right?

  • Hello pingu. The nrf_delay_ms() is not recommended when you are using the softdevice. As long as it is called from a low enough priority, it doesn't necessarily harm anything,  but the only thing it does is to halt the CPU, drawing power for the delay that you use (10ms), because it is preventing it from going to sleep.

    Just to confirm, the BLE_HCI_CONNECTION_TIMEOUT is the reason you receive on the NRF, right?

    Is it possible to provide a sniffer trace? A trace captured with nRF Sniffer is sufficient.

    Do you by chance have SVCALL_AS_NORMAL_FUNCTION defined?

  • Hi Edvin,

    Just to confirm, the BLE_HCI_CONNECTION_TIMEOUT is the reason you receive on the NRF, right

    that's correct.

    I captured a trace with the nRF Sniffer, however, the disconnection event doesn't pop up on wireshark. So after it happened, I don't see any traffic anymore. I'm not sure if this is due to the sniffer setup (it turned out to be a little bit buggy and it is quite difficult to capture a trace, sometimes nothing is traced)... The SVCALL_AS_NORMAL_FUNCTION  is not defined.nrf52832 trace.pcapng

  • Hello,

    Do you have 20 seconds supervision timeout?

    There is no disconnection event packet when the disconnect reason is BLE_HCI_CONNECTION TIMEOUT. It basically means that the connected device doesn't respond anymore. Now, since you are seeing this event from the peripheral, but we can't see any packets from the peripheral in the trace for the last 20 seconds, it means that it wasn't responding to the master. It may have tried to send out the packets, but at least they weren't sent on the correct time, as a reply to the master/central.

    Is there a way for me to replicate this on a DK? Or is it at least possible to send me a project that can replicate this, so that I can see if I find anything in the implementation?

  • Hello,

    Are you still having problems with this issue? I saw that you sent me a PM, but this ticket wasn't updated, so I forgot about it. I wanted to check, since it has been a while.

    Best regards,

    Edvin

  • Hi Edvin,

    I managed to get an DK with the nrf52832 on it and run my code on that one. I couldn't reproduce the problem on it, so I still have to figure out what the differences between my board and the DK are. It might also be a hardware issue, since I only change the board files for code execution. I'll get back to you if I have more information.

    Best regards,
    pingu

Reply
  • Hi Edvin,

    I managed to get an DK with the nrf52832 on it and run my code on that one. I couldn't reproduce the problem on it, so I still have to figure out what the differences between my board and the DK are. It might also be a hardware issue, since I only change the board files for code execution. I'll get back to you if I have more information.

    Best regards,
    pingu

Children
No Data
Related