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?

  • Hi Edvin,

    My nrf is connected to a Samsung tablet S4 and the nrf is acting as peripheral while the tablet acts as central. I checked the disconnection reason and it turns out that it is an connection timeout (BLE_HCI_CONNECTION_TIMEOUT). In my opinion this kinda means that the nrf is too busy doing other stuff than to handle the bluetooth connection. The connection parameters are initially negotiated between the nrf and the tablet, I can try to tune these parameters but I don't think that this is the actual reason. Also, when adding nrf_delay_ms(10); every time after an spi transaction it doesn't happen anymore, but just slows things down too much. Is there a possibility to check the current priority since you mentioned that this changes depending on the context you call a function from? I still think that this is not the issue, since the function is processed in the main thread but just to be 100% sure.

    Thanks and best regards,

    pingu

  • 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

Reply Children
  • 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

Related