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

SPI Slave interrupt by the Bluetooth

Hi. I am using nrf52840 with Softdevice 16.0.0 + BLE_uart_peripheral.

The SPI master transmits 2 SPI packets every 10 ms. At the the SPIS event handler, I call ble_nus_data_send() to send the SPI packet out.

However, I found the first couple bytes of the second packet are quite often be zero or lost. But as far as I disconnected the bluetooth to the central, the packets are fine.

I put a GPIO lines before and after the ble_nus_data_send() to tell the master hold the spi transmission but the problem still there.

However, I found if I added 1 ms between the spi cs line low and start the first byte, and also 1 ms after cs line goes high, the chances to get a corrupted spi packet is significantly reduced.

I think it might be the issue similar to this post:

https://devzone.nordicsemi.com/f/nordic-q-a/4034/spi-slave-with-heavy-interrupt-in-btle#post-id-17712

I preferred the GPIO solution mentioned in the post rather than the time delay. 

Could you help to the GPIO in the right position?

Parents Reply Children
  • Perhaps I was too vague and quick to answer; this is a typical invocation of ble_nus_data_send():

        do
        {
           uint16_t length = (uint16_t)index;
           err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
           // Also now check BLE_ERROR_GATTS_SYS_ATTR_MISSING or correctly set up due to timer race hazard
           if ((err_code != NRF_ERROR_INVALID_STATE)
            && (err_code != NRF_ERROR_RESOURCES)
            && (err_code != NRF_ERROR_NOT_FOUND)
            && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING))
           {
              APP_ERROR_CHECK(err_code);
           }
        } while (err_code == NRF_ERROR_RESOURCES);

    This effectively blocks within an interrupt, which is to be discouraged. Blocking in the foreground is fine. The master may be sending the next SPI packet while the previous SPI interrupt is still active;  simple to test, maybe it'll help. Buffering (copying) the received data might also help, hard to say without sight of the SPI handler

  • I understand. But I scoped the gpio line which toggling at the entrance and exit of spi handler. I cant trigger my scope without single stepping, which suggests the time is very very short. Much less than 1 ms.

  • I cant trigger my scope without single stepping

    Try increasing the 'scope io pin drive to H0H1 in case the probes are very capacitive; it would have to be a very slow 'scope not to catch that toggle (must set Trig to Normal). Adding a second pin to the 'scope (also H0H1) which is driven on the packet corrupted condition might provide some useful information.

  • I tried storing spi receive data into fifo and call m_ble_send in the main loop. But it doesnt help Disappointed. I found the problem became worse when my ble central (another 52840 chip) connected the first device and scanning for the second device. It backs to the normal problem behavior after both devices connected. 

Related