This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Increasing bluetooth speed without blocking other peripherals

Hi,

I'm putting together some firmware that takes packets received over SPI and then streams them over BLE. I'm trying to run the BLE at close to 1Mb/s (which is still within spec from my understanding) but I'm getting some inconsistent packet dropping. After some debugging, I have come to some roadblocks.

1) Is there a way to confirm that I'm properly queueing BLE packets? I've instantiated the queued write module and enabled the length extension with the following code:

NRF_BLE_QWR_DEF(m_qwr);   

...
...

err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);

...
...

bool conn_evt_len_ext_enabled;
ble_opt_t  opt;

conn_evt_len_ext_enabled = true;

memset(&opt, 0x00, sizeof(opt));
opt.common_opt.conn_evt_ext.enable = conn_evt_len_ext_enabled ? 1 : 0;

err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);
APP_ERROR_CHECK(err_code);


and when I want to send bluetooth packets I just use: 

ble_nus_data_send(&m_nus, ble_tx_buf, &ble_packet_length, m_conn_handle);


My understanding is that with my current setup, I can keep running 'ble_nus_data_send' and the microcontroller will just queue whatever I want to send to be sent later. Is that correct? Do I have to wait to receive NRF_SUCCESS?

2) I was reading this blog post: https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/throughput-and-long-range-demo and went through the demo code and it seems like I can increase BLE transfer speeds by boosting my tx power. Is it recommended to change the tx power and link budget or should I not touch those? During run-time I set my PHY to 2M - does that automatically alter my tx power and link budget?

I should note that I'm building my peripheral FW off of the ble_app_uart example and my central FW off a ble_app_uart_c example - but I've added USB functionality. I'm more than happy to provide any/all code if there are any questions.

Thank you so much!

Ryan

Parents
  • Hi Ryan

    The sample project that is used in the novelbits blog post is the ble_app_mtu_throughput example that lets you transmit longer packets (up to 247 bytes in a packet).

    Best regards,

    Simon

  • Hi Simon,

    In the end, I think I've figured it all out, let me summarize my issue and solution below for any other people who may come to this thread:


    My main problem was that my bluetooth transfers were blocking my spi transfers from happening as often as I wanted to. This was because my bluetooth transfers were occurring in the spi_interrupt_handler with the following code:

    while(ble_nus_data_send(&m_nus, ble_tx_buf, &ble_packet_length, m_conn_handle) != NRF_SUCCESS);


    So I removed the while loop but then I ran into the problem that ble_nus_data_send() wouldn't actually complete properly by the next spi transaction (meaning only 1/5 calls to ble_nus_data_send() were actually successful).

    In order to solve this I had to make 4 changes:

    1) enable data length extension (so that multiple packets could be sent during a single connection)
    2) Increase my HVN queue size to 400 (so that the notification system would queue any notifications that couldn't be sent in time - this gives me a little leeway in case there are any flukes)
    3) Adjusting my ble stack settings to achieve a theoretical throughput of 1.2 Mbps (I figured these out by testing different parameters in the ble_app_mtu_throughput example)
    4) I began double buffering and adding a check in the CPU to retry sending the packet if ble_nus_data_send doesn't return success.

    Furthermore, to answer my earlier question - In order to send multiple packets during a single connection, all you need to do is call ble_nus_data_send() multiple times. If you have an HVN queue large enough, all of your packets will get queued and sent without you having to worry.

Reply
  • Hi Simon,

    In the end, I think I've figured it all out, let me summarize my issue and solution below for any other people who may come to this thread:


    My main problem was that my bluetooth transfers were blocking my spi transfers from happening as often as I wanted to. This was because my bluetooth transfers were occurring in the spi_interrupt_handler with the following code:

    while(ble_nus_data_send(&m_nus, ble_tx_buf, &ble_packet_length, m_conn_handle) != NRF_SUCCESS);


    So I removed the while loop but then I ran into the problem that ble_nus_data_send() wouldn't actually complete properly by the next spi transaction (meaning only 1/5 calls to ble_nus_data_send() were actually successful).

    In order to solve this I had to make 4 changes:

    1) enable data length extension (so that multiple packets could be sent during a single connection)
    2) Increase my HVN queue size to 400 (so that the notification system would queue any notifications that couldn't be sent in time - this gives me a little leeway in case there are any flukes)
    3) Adjusting my ble stack settings to achieve a theoretical throughput of 1.2 Mbps (I figured these out by testing different parameters in the ble_app_mtu_throughput example)
    4) I began double buffering and adding a check in the CPU to retry sending the packet if ble_nus_data_send doesn't return success.

    Furthermore, to answer my earlier question - In order to send multiple packets during a single connection, all you need to do is call ble_nus_data_send() multiple times. If you have an HVN queue large enough, all of your packets will get queued and sent without you having to worry.

Children
No Data
Related