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

BLE NUS CENTRAL not ready for comms after receiving BLE_NUS_C_EVT_DISCOVERY_COMPLETE

Hi

I have a modified version of the BLE_NUS Central sample which connects to my production board for production test purposes.

All works fine, and Rx and Tx comms passed to/from the UART to the RX and Tx characteristics of the custom service running on my peripheral.

My issue is that after the central gets BLE_NUS_C_EVT_DISCOVERY_COMPLETE, if I immediately try to perform a GATT_Write on the peripherals RX characteristic, the Central Hangs

 ble_gattc_write_params_t const write_params =
    {
        .write_op = BLE_GATT_OP_WRITE_CMD,
        .flags    = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
        .handle   = p_ble_nus_c->handles.nus_rx_handle,
        .offset   = 0,
        .len      = length,
        .p_value  = p_string
    };

    return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);

If I run the exact same code a fraction of a second later, it succeeds.

After connection and discovery of my service (and after setting up Notify for the RX and TX characteristics), I need to inform my peripheral who it was that just connected - in this case 'ProductionTestBoard' 0x07. I do this via a protocol structure I use everywhere else in the product.

My question is, can I test wait for any other event, or test the softdevice to wait until it REALLY HAS connected to my peripheral? I tried the usual 'sleep' before the gattc_write to no avail.

Nigel

Parents
  • Hi

    Annoyingly this turned out to be because on my central I had wrapped the BLE comms session back to the peripheral with a timeout (using the APP_TIMER_DEF macro). The timer does not call the completion routine when it expires, and thus does not set the flag to 'true' and my while loop after the sd_ble_gattc_write never exits: while (!fAckRxOnTxCharacteristicCompleted && !fBleTxRxTimerExpired) { }. I use the timer to time a transaction at my application layer - sending of data and receipt of an ACK from peripheral.

    Its a little odd, as I use the identical code to wrap many other comms operations with timers. I am assuming that the current interrupt level means that timers cannot be used here?

    This code is on a production test board, so I have simply removed the 'while'. The same timer code is wrapping all comms (BLE and SPI) on the peripheral where it works just fine. 

    Nigel

  • Hi,

    Glad to hear that you found the problem. 

    veletron said:
    Its a little odd, as I use the identical code to wrap many other comms operations with timers. I am assuming that the current interrupt level means that timers cannot be used here?

    The app timer uses interrupt priority 6 or 7 depending on SDK version and configuration, same applies for Softdevice events. However, I think it's best when you can avoid blocking functions in ISRs.

    Vidar  

Reply
  • Hi,

    Glad to hear that you found the problem. 

    veletron said:
    Its a little odd, as I use the identical code to wrap many other comms operations with timers. I am assuming that the current interrupt level means that timers cannot be used here?

    The app timer uses interrupt priority 6 or 7 depending on SDK version and configuration, same applies for Softdevice events. However, I think it's best when you can avoid blocking functions in ISRs.

    Vidar  

Children
No Data
Related