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.

SimpleBLEPeripheral stops advertising

Other Parts Discussed in Thread: CC2540, CC2541

Hello,

I am working with the TI CC2540 chip and am attempting to control a motor based on inputs from two optocouplers and a mobile phone. I just modified the default SimpleBLEPeripheral code by adding some constants, variables and events. The idea is to periodically (every 30s) check if the current position of the motor is different to the desired position. If it is, then a for loop calls a while loop to bring the motor position to its desired place. The desired position is sent from the phone. The motor only moves (homes to zero first then moves onto desired position) after the desired position is received from the phone.

The problem is that when I send the desired position from the phone, the motor homes properly. But when it starts moving onto the desired position, the device chip stops advertising and thereafter is non discoverable by any phone. This is quite strange as I have built the application on SimpleBLEPeripheral with infinte advertising and have changed nothing related to GAP or GATT. I only added 12 characteristics to SimpleGATTProfile. I have also checked the memory map (attached) and it seems ok. Can anyone please help me figure this non advertising problem out?

Thanks

3718.SimpleBLEPeripheral.rtf

  • Hello,

    CC2540 is not multi threaded, so if your motor process is not letting OSAL loop through task, then you would block the radio from running.  This is just a guess as to what may be happening.  General adv is parsed by stack by looking at advertisement data flags, so make sure that is being set correctly also.

    BR,

    -Greg

  • Hi Greg,

    Thanks for the information and help. I may be incorrect, but I believe the motor process is letting the OSAL loop through because I have the desired position changing with time using the osal_GetSystemClock timer and for the timer to update properly, control has to be returned to the OSAL loop. The timing of the motor movements is working well.

    I will have a look at the advertisement flags. I would appreciate any other thoughts as well. 

    Best regards,

    Osman

  • Hi All,

    Im experiancing the same problem.

    I have modified the SimpleBlePeripheral for advertise indefinetly and i have compiled it for CC2540 256K Flash.

    It's seems to work fine on TI 2540 KeyFob and i can scan it from at least two weeks without any problem.

    If I compile the same code for CC2541 256K Flash or 128 K Flash, the device (TI SensorTag or BLE113) stop to advertise in undefined time (one/two hours or one day). I need to remove the battery in order to reset the device.

    I also tried to enable the watchdog at one second  and restart it in osal process event ever500 millisecond but, when the device stop to advertise, the watchdog does not intervene.

    Seems that the osal loop is still running when the chip stop to advertise.

    I tried to test the WatchDog writing a infinite loop in the code and it works fine (after one second reset the chip).

    I also tried to re-enable the advertising in osal event every one secon with no success.

    I notice that when the chip stop to advertise, it dry the battery very fast.

    Do you know if there is some bug in CC2541 BLE 1.4 library ?

    Maybe I'm wrong or missing someting, but the strange is that on CC2540 it seems to work but on the CC2541 it is instable.

    I tried this code on two different TI SensorTag devices and also on two BlueGiga ble113 devices (the ble113 is equipped with TI CC2541 128K).
    All these devices stop to advertise randomly.

    Any Idea in order to fix this problem ?

    Thanks in advance,

    Vittorio

  • Hi Vittorio,

    Try changing this from 25 to 35

    #define HAL_SLEEP_ADJ_TICKS                 35

    This has to do with possibly missing a RF wakeup due to some timer wakeup and different path through HAL sleep code. This was rare though and a watchdog should catch it, so might not be issue. 

    Is there anything else going on besides advertisements?  OSAL timers other?

    BR,

    -Greg

  • Hi Greg,

    I'm using the osal timer for restart the WD, read the last rssi and read the battery level and report these value in scan respons array.

    I have also modified the ProfileChange callback in order to store on the Flash the new value of the Attribute but this function is called only when we modify the attribute and the device must be connected with the client.
    My problem is during the normal advertisement and non durig a connection.


    Following the code that i have modified:

    Vittorio


    uint16 PullsarBeacon_ProcessEvent( uint8 task_id, uint16 events )
    {
     
      VOID task_id; // OSAL required parameter that isn't used in this function

      if ( events & SYS_EVENT_MSG )
      {
        uint8 *pMsg;

        if ( (pMsg = osal_msg_receive( PullsarBeacon_TaskID )) != NULL )
        {
          PullsarBeacon_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );

          // Release the OSAL message
          VOID osal_msg_deallocate( pMsg );
        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }

      if ( events & SBP_START_DEVICE_EVT )
      {
        // Start the Device
        VOID GAPRole_StartDevice( &PullsarBeacon_PeripheralCBs );

        // Start Bond Manager
        VOID GAPBondMgr_Register( &PullsarBeacon_BondMgrCBs );

        // Set timer for reset watchdog event // 500 ms
        osal_start_timerEx( PullsarBeacon_TaskID, SBP_WATCHDOG_EVT, SBP_WATCHDOG_PERIOD );

        // Set timer for read rssi event // 1 Sec
        osal_start_timerEx( PullsarBeacon_TaskID, SBP_RSSI_CHECK_EVT, SBP_RSSI_EVT_PERIOD );

        // Set timer for first periodic event  20 Sec
        osal_start_timerEx( PullsarBeacon_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );

        return ( events ^ SBP_START_DEVICE_EVT );
      }

        if ( events & SBP_WATCHDOG_EVT )
      {
        // Restart timer
        if ( SBP_WATCHDOG_PERIOD )
        {
          osal_start_timerEx( PullsarBeacon_TaskID, SBP_WATCHDOG_EVT, SBP_WATCHDOG_PERIOD );
        }
       
     
          //while (1);
         // reset watchdog
         WDCTL = (0xA0 | WDCTL & 0x0F);
         WDCTL = (0x50 | WDCTL & 0x0F);
        
       return (events ^ SBP_WATCHDOG_EVT);
      }
     
     
      if ( events & SBP_RSSI_CHECK_EVT )
      {
        // Restart timer
        if ( SBP_RSSI_EVT_PERIOD )
        {
          osal_start_timerEx( PullsarBeacon_TaskID, SBP_RSSI_CHECK_EVT, SBP_RSSI_EVT_PERIOD );
        }
       
         scanRspData[14] = PHY_GetLastRssi();
         GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );

        return (events ^ SBP_RSSI_CHECK_EVT);
      }
     
     
      if ( events & SBP_PERIODIC_EVT )
      {
        // Restart timer
        if ( SBP_PERIODIC_EVT_PERIOD )
        {
          osal_start_timerEx( PullsarBeacon_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
        }

        // perform battery level check
            scanRspData[13] = battMeasure();
            GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );

        return (events ^ SBP_PERIODIC_EVT);
      }

     
      // Discard unknown events
      return 0;
    }


    static void PullsarBeaconProfileChangeCB( uint8 paramID )
    {
      uint8 newValue1;
      uint8 newValue2[BEACONPROFILE_CHAR2_LEN+1];
      uint8 count;
     
      switch( paramID )
      {
        case BEACONPROFILE_CHAR1:
          PullsarBeaconProfile_GetParameter( BEACONPROFILE_CHAR1, &newValue1 );
          if (newValue1 < 16)
            {
              scanRspData[30] = (uint8) PowerTable[newValue1];
            }
          else
            {
              scanRspData[30] = 0;
            }     
          SetTxPower(newValue1);
          for (count = 0; count < BEACONPROFILE_CHAR2_LEN; count ++ ) newValue2[count] = scanRspData[count+2];
          newValue2[11] = newValue1 ;
          osal_snv_write(0x80, BEACONPROFILE_CHAR2_LEN+1, newValue2 ); 
          break;

        case BEACONPROFILE_CHAR2:
          PullsarBeaconProfile_GetParameter( BEACONPROFILE_CHAR2, newValue2 );
          PullsarBeaconProfile_GetParameter( BEACONPROFILE_CHAR1, &newValue1 );
          for (count = 0; count < BEACONPROFILE_CHAR2_LEN; count ++ )  scanRspData[count+2] = newValue2[count];
          newValue2[11] =  newValue1;
          osal_snv_write(0x80, BEACONPROFILE_CHAR2_LEN+1, newValue2 ); 
          break;

        default:
          // should not reach here!
          break;
      }
    }


    static uint8 battMeasure( void )
    {
      uint16 adc;
      uint8 percent;


      // Configure ADC and perform a read
      HalAdcSetReference( HAL_ADC_REF_125V );
      adc = HalAdcRead( HAL_ADC_CHANNEL_VDD, HAL_ADC_RESOLUTION_10 );

      if (adc >= BATT_ADC_LEVEL_3V)
      {
        percent = 100;
      }
      else if (adc <= BATT_ADC_LEVEL_2V)
      {
        percent = 0;
      }
      else
      {
          uint16 range =  BATT_ADC_LEVEL_3V - BATT_ADC_LEVEL_2V + 1;

          // optional if you want to keep it even, otherwise just take floor of divide
          // range += (range & 1);
          range >>= 2; // divide by 4

          percent = (uint8) ((((adc - BATT_ADC_LEVEL_2V) * 25) + (range - 1)) / range);
      }

      return percent;
    }

  • I am experiencing the same issue, that the device suddenly stops advertising. Sometimes it goes to high current and drains the battery quickly. On other times I can re-enable the device with the side-key (on the SensorTag design), since I left the code for the key handling in.

    One thing I figured out is that on the SensorTag design the battery buffering C2 is not populated. So measuring the battery voltage during active processing shows that the battery drops about 0.5V. So in case the battery goes empty the voltage drop gets eventually below 2V resulting in a crash. I also observed that the battery gets an higher internal resistance when it is cold, so it stopped working by putting it into the fridge. By populating 100uF (and I disabled all other sensors besides humidity/temp) I was able to get the design working even in the freezer showing -27.8°C.

    So I was hopeful that loosing the adverting was coupled to this.... but it turned out that I still have the issue, less frequently, but it still happens. Sometimes it is within a day, sometimes it takes 4 days. I observed this now with several different SensorTags and my own design :-(

    I am now looking into fixing this by enabling periodically the advertising:

    {
    uint8 new_adv_enabled_status;
    // Find the current GAP advertising status
    GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &current_adv_enabled_status );
    if( current_adv_enabled_status == FALSE )
    {
    new_adv_enabled_status = TRUE;
    }
    else
    {
    new_adv_enabled_status = FALSE;
    }
    // Change the GAP advertisement status to opposite of current status
    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status );
    }
    Does have anybody have other ideas or observations on this topic?
    TX, Kai

  • Hi Kai,

    I fixed my problem changing the HAL_SLEEP_ADJ_TICKS value from 25 to 35

    #define HAL_SLEEP_ADJ_TICKS                 35

    Vittorio

  • I'm having a similar issue. GregS, can you clarify what this change is doing?

  • The variable HAL_SLEEP_ADJ_TICKS is adjusting the sleep timer compare value to compensate for the time the stack uses in the function halSleep.

    For the CC2541, this is by default set to 25 sleep timer ticks instead of 35 (default) in the latest stack in hal_sleep.c.

    This might cause the radio to fail since the device woke up to late to have the crystal settle properly before the radio should event should happen.

    If your crystal startup time is slower than our reference design, you may need to increase this pre-wakeup guardtime by changing HAL_SLEEP_ADJ_TICKS.

    Regards,
    Svend

  • Hi Svend,

    I think I am experience very similar problem, my device is designed to advertise indefinitely till it is connected. And it can be connected from time to time. Since it is run on a power source, POWER_SAVE is turned off. What I have seen is that some time(once every 2 or 3 days) it just stops advertising without any reason. The gapRole is still showing advertising but no advertisement can be seen. And after sometime(half to one hour), the advertising suddenly starts by itself.

    And when this happens, if I simply stop advertising and restart advertising will make it advertise again. The problem is that I can not detect the problem from the device itself so rekick the advertisement programmatically is not possible.

    I have been struggling with this for some time now. Any help/hint would be appreciated very much.   

    Best regards,

    Hongli

  • Hi Hongli,

    Does the rest of the application still execute fine or has everything stopped when you see this?

    Regards,
    Svend
  • Hongli,

    You're problem may be due to a link layer timer overflow. Check this thread for details and a solution: https://e2e.ti.com/support/wireless_connectivity/f/538/p/294169/1183832#1183832.

    Svendbt, 

    Has this issue been fixed in the v1.4.1 BLE stack?

  • Hi Svend,

    Thanks for looking into this, yes, the rest of the application runs perfectly, since it is not advertising, it can not be connected till it magically comes back by itself.

    Best regards,
    Hongli
  • Hi Peter,

    Thank you very much for the link and your investigation on this topic, I think it is very close to my problem. I will do more digging to see and will report back my finding.

    Best regards,
    Hongli
  • Hi Peter,

    I have been testing my device for last couple of days with your patch in it, it does seem to fix my problem. Thanks a lot!

    Hongli

  • Hi Greg.
    Thank you so much!!!
    Up to now, your advice is being very good.... my project is running for four hours or more without stops the advertiser.... great!
    I will continue to monitoring!!
    In my project we use the CC2541 in two modes, peripheral role and central role at the same time... not exactly....
    But it`s works!!
    For more than 20 days I try to resolve this suddenly advertiser stops problem.... with no success!
    But now I have hope that problem is resolved!!!

    Tks!

  • The problem was not resolved. I will have to implement the call back.....

  • Is changing HAL_SLEEP_ADJ_TICKS from 25 to 35 only valid for the CC2540? I just had a CC2541 device get into a state where it was not advertising. I had to power cycle to get it back. If I change HAL_SLEEP_ADJ_TICKS to 35 could this possibly help avoid this? Stack is 1.4.