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.

long task execution causes advertising to fail

We are using BLE v1.3 in our peripheral device which is line-powered (doesn't use any power-saving).

At times our task performs lengthy number crunching that can take 200-300 msecs to complete. When this happens, the device stops advertising. After calculations are completed and our task gives control back to OSAL, the device does not resume advertising.

In limited discovery mode, this problem 'heals itself' because eventually, the limited discoverability time expires and peripheral state machine goes into WAITING state and then re-starts advertising automatically.

However, in general discovery mode, advertising is permanently dead, i.e. device never advertises again. There are no peripheral callbacks associated with this failure; the only callbacks are GAPROLE_STARTED and GAPROLE_ADVERTISING, both of which occur before the failure.

  • Hi Richard,

    This is caused by the advertising start-time ending up in the past. Advertising will probably resume after 10485.76 seconds, being the wraparound time of the 24 bit coarse timer.

    There is no workaround except for updated library files that restart advertising when this is detected. This will unfortunately not be included in BLE v1.4.0.

    Alternatively, you can split up the crunching into several OSAL events so that LL can schedule the advertisement while it's still in the future. Alternatively, stop and restart advertising periodically.

    Best regards,
    Aslak 

  • I am having a similar problem with a much shorter periodic event  ~10ms. I rarely stop advertising, but I have confirmed it happening multiple times. A debug LED tells me that the app layer thinks its advertising, though I can see on an o-scope that the advertising packets aren't being sent.

    "when this is detected". Is there a way for us to detect this, or is the time hidden in the link layer?

    The easiest way I can think of periodically stopping and starting advertising is to use limited discovery mode and turn advertising back on when we get the peripheral callback for the waiting state. What is the maximum time that can be set for TGAP_LIM_ADV_TIMEOUT? The documentation only says the default is 180 seconds. 

    Also, you say the timer can wait 10485 seconds with a 24 bit counter which work out to a 1600Hz clock. (10485/(2^24))^-1. What are you using fro that clock source? How doe you divide the 32K clock by 20?

     

    For anyone else having trouble with advertising, this thread gives an alternative solution for a similar situation: http://e2e.ti.com/support/wireless_connectivity/f/538/p/314805/1125365.aspx#1125365

    It didn't work for me though...

  • Hi Peter,

    You can call a function called "HCI_EXT_AdvEventNoticeCmd" described in hci.h. This will give you a callback (osal event) every time the radio has completed an advertising event.

    In this callback you can restart an OSAL timer, which when it times out you make it restart advertising.

    A better approach would be to also reduce the size of the computation blocks in your application, yielding control by setting osal events on itself for example.

    BR,
    Aslak

  • Which OSAL timer tells me when the next advertising event is scheduled to happen? I want to make sure your supposed 3 hour wait time is my problem before making the solution. How can I tell if this long wait will happen?

  • I found the function LL_TimeToNextRfEvent( uint32 *sleepTimer, uint32 *timeout ); but there's not documentation on how it works. Would this tell me when the next RF event will happen? 

    What is sleepTimer and what is timeout?

    Others have a similar questions: http://e2e.ti.com/support/wireless_connectivity/f/538/p/297533/1184280.aspx#1184280

    http://e2e.ti.com/support/wireless_connectivity/f/538/p/205314/935934.aspx#935934

  • Hey guys. I used context clues to figure the LL_TimeToNextRfEvent is telling me that the next event will happen in 170750091 32KHz clock ticks or in 5336 seconds. This is pretty far from the value Aslak quoted (10485 seconds).  

    Advertising stopped a few seconds before this high number was detected. I use the TI packet sniffer and I filter by the advertising addrdess (base/MAC address) of my device. I put a breakpoint in a simple if statment

    if(llTimeout > 2000){
    uint8 dummy;
    dummy = 0;
    dummy++;
    }

    What could cause this delay? Why is my delay different from Aslak's?

    I still need documentation on LL_TimeToNextRfEvent. I'm making assumption on how it works

  • Could you explain how the osal timer can be reset? Are you proposing using osal_stop_timerEx()?

    How does this timer affect advertising events?

    I see that the osal clock is determined by adding the output of ll_McuPrecisionCount() to a uint32. Is this the timer you are suggesting setting to zero? Are advertising events scheduled by using the osal clock? I don't understand how this fixes the system because I set a debug pin to toggle event time something in the task array happens, but this doesn't appear to be triggered by advertisements. 

    My most important question that succeeds all of this remains: How can I verify the workaround wont cause devices to stop advertising?