This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2540: Connection Timeout during OAD

Part Number: CC2540


We are currently implementing OAD Firmware updates for our Apps and Windows software and have discovered very odd behavior. We use custom boards with a CC2540 and on some of them the OAD update fails due to potential connection timeouts (I've attached sniffer logs to verify this).

All of the boards we are using are identical and we can successfully update all of them using the TI iOS App and also our own iOS/Android Apps. Right now it seems like only the Windows implementation has this problem and only on some devices (even though all of them are identical).

Here is what happens:

The device connects successfully and the OAD Header gets send to the device. The device answers by requesting the first Block via the Block Characteristic. Then the Windows App sends the first block of data. Now nothing happens and after 10secs the device disconnects and reconnects to repeat these steps indefinitely. This seems like the connection times out because to default connection timeout matches those 10secs.

Using the sniffer it seems like the device drops the connection. I've attached sniffer logs of the same code and firmware running on two different devices. On the first one it times out and on the second one it doesn't. Same firmware, same windows app, just different boards but both boards can be updated using the TI App or out own Apps.

I guess my question is, am I right in assuming the device drops the connection? And if yes how is it possible that the windows App causes the device to disconnect? I don't think there is a hardware malfunction since all boards can be updated via one method. Right now only the OAD Update on Windows causes this. The odd thing is, it seems like the device causes the timeout but the windows app causes this problem to occur, how can this be?

EDIT: I think this question might also apply to non OAD related behavior. I can write to the image identify characteristic just fine, the problem only happens after writing to the block characteristic. I am receiving something on that characteristic beforehand maybe this causes a hiccup or something?

This is the sniffer log for the time out. The first ATT_Write_Req is the header, the device answers by requesting block 0, then the ATT_Write_Command with Block 0 and then nothing but M -> S with no response from the device:

And this is a working case but here the device answers by requesting block 01 and so on. There seems to be a little bit of a problem as well with some ACK Status retries but maybe this isn't such a problem at all. This OAD however succeeds. 

  • HI,

    I have assigned an expert to comment.

    Best regards,

  • To add a little bit of extra information: I can send the first block of data not to the block characteristic but instead to the image identify one. This is obviously wrong and results in a response from the device on the the identify characteristic. However, the connection stays active, no timeouts or sudden disconnects. Only if I send the first block on the characteristic for the blocks the connection seems to drop immediately.

  • Hello Sebastian,

    Thanks for the detailed description. I am not quite sure, but here is a list of some investigative actions for you:

    1) Have you tried to disable the halt cpu during RF?

    Call this during your application init:

    HCI_EXT_HaltDuringRfCmd(HCI_EXT_HALT_DURING_RF_DISABLE) 

    HCI_EXT_OverlappedProcessingCmd(HCI_EXT_ENABLE_OVERLAPPED_PROCESSING);

    2) What are the connection settings?

    3) Maybe you need to adjust the Sleep Clock Accuracy on the peripheral (SCA):

    https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/538/t/189253

  • 1)/3) I've just added the "Halt" and "Overlapp" commands to the SimpleBLEPeripheral_Init() like this:

    HCI_EXT_HaltDuringRfCmd(HCI_EXT_HALT_DURING_RF_DISABLE);
    HCI_EXT_OverlappedProcessingCmd(HCI_EXT_ENABLE_OVERLAPPED_PROCESSING);  
    HCI_EXT_SetSCACmd(500);

    Sadly it didn't work, then I also added the SetSCA Command with a value of 500 to get the worst case scenario (energy during a couple minutes of firmware update won't be an issue anyways) but it also didn't stop the device from disconnecting.

    2) Connection settings are:

    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    #define DEFAULT_ENABLE_UPDATE_REQUEST         FALSE
    #define DEFAULT_CONN_PAUSE_PERIPHERAL         6

    Update requests cause severe slowdowns on android but the disconnects on windows happen regardless.

    Also so far as I can see the device seems to drop the connection immediately after receiving the first block. I haven't found anything in the OAD target code that would cause this per design so it must be something on a deeper level going wrong. Is there maybe a good place for a breakpoint within the OAD firmware to catch a connection problem like this? I have tried some breakpoints within the OAD_target.c section that handles receiving new blocks but wasn't able to catch the moment where the connection gets dropped.

     

    EDIT: Since this has only happend under windows, I wouldn't rule out something going wrong on that side?

     

  • I tested all of the recommendations but wasn't able to recognize any differences.

    Also so far as I can see the device seems to drop the connection immediately after receiving the first block. I haven't found anything in the OAD target code that would cause this per design so it must be something on a deeper level going wrong. Is there maybe a good place for a breakpoint within the OAD firmware to catch a connection problem like this? I have tried some breakpoints in the OAD_target.c section that handles receiving new blocks but wasn't able to catch the moment where the connection gets dropped.

    If there is a better way to debug this I could provide you with maybe more useful information.

  • Hello Sebastian,

    I would 

    1) Those are the desired connection settings from the peripheral, but the master decides the connection settings.and they are given in the initial CON_IND packet. Please review the connection establishment in the sniffer log for both (and if you can please paste them here as well). Then we can compare the different connection settings and any initial connection configuration. 

    2) Perhaps, for some reason, the heap is exhausted and therefore you cannot allocate space for stack commands and payloads. Try to profile dynamic memory usage (refer to section 3.4 Heap Manager in TI_BLE_Software_Developer's_Guide).

    3) I would start by placing a breakpoint in oadWriteAttrCB (oad_target.c) and follow this flow:

    oadImgBlockWrite -> oadImgBlockReq -> noti.pValue = GATT_bm_alloc

    then verify that the allocation from the heap for the notification was successful and that the subsequent GATT_Notification call returns success.

  • I'm going to close this post due to inactivity. If you have feedback within a few days you can post a follow up question which will automatically reopen this thread. If it takes longer than please post a new thread by pressing the orange button + Ask a related questions. Otherwise, after 30-days of inactivity from this post, this thread will lock.