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.

CC2640: Problem with BLE Radio

Part Number: CC2640
Other Parts Discussed in Thread: CC2650, CC2541, HDC1000

Hello,

I have problem with my project based on CC2640. I used the expample the simpleBLEperipheral project and I added a I2C interface (temperatury and humidity sensor), 2 new characteristics and ADC (for measure a battery level). My problem is freeeing a radio BLE after random time (15 min - 2 h), I have to reset the whole CC2640 to start again advertising.
When the radio stops working, I can see a clock interrupt on the oscyloscope.
I found a little solution, everthing wroking fine, when I disabled the Power Saving. But now there is a much bigger power consumption.
Maybe someone had similar problem. Could you give some advice or solution?

Have a nice day,
SK

  • Hello SK,

    I can't tell from the description alone (you did not provide details on the dev kit or custom PCB as well as BLE SW version), but I would suggest going through the Debugging chapter in the CC2640 SW Developer's Guide (SWRU393). I would check for heap memory exhaustion and if you are getting any events from the BLE stack. Also, adding your features individually to confirm when the problem occurs is recommended.

    Best wishes
  • Hi,

    Thanks for your respond. When I used a debugger everything works fine (Without and with the PowerSaving option). The problem occurs when I'm using a battery or DC (3.3) supply. On battery supply device works better, I can see less "radio freeze".
    Maybe problem is clock resposible for the advertising?

    I also tried adding features invidually but this only change time of crash.

    I tested software on borads:
    - the custom board based on the CC2640 (5x5),
    - the custom borad based on the CC2640 (4x4),
    - the LSR Sable-x dev board (4x4),
    - the LaunchPad CC2650 (7x7).

    If the error occurs beacuse of stack overflow, so this should occur in the same on time all board. Am I right?
    Best wishes,

  • Hello,

    Which board(s) does your SW work correctly on? If you remove the I2C and ADC, does your SW work correctly?

    Please note that the LSR SaBLE-x is a 5x5 with CC2650EM_5XD antenna layout.

    Best wishes
  • Hello,

    I checked and changed a board files for all CC2640 boards.

    SW works correctly on all boards when I disabled the PowerSaving options. Also, I can see that on a battery supply device is working better. On the Sable-x dev board radio crash occurs sporadically (one for 3,4 days).

    The clean SimpleBLEPeriheral project without I2C and ADC (PowerSaving enable) works fine on all board.

    Best wishes,
  • Can you check follow the software developer's guide section 9 to implement exception handle to see if you are able to extract more information when it's not running?
  • Hello Christin,

    I can't catch any exception handle. The main Cortex's still wroking, I can see clock interupts and fleshing LED. I suppose that there is a problem with a clock, which is responsible for awakening the advertisement state from idle task. This confirms a different work on different boards, wchich have vary power supply filtration.

    What is a diffrence between debugger version stack and release?

    Regars
  • If the clock object is still running, that means the scheduler has no problem. SW clock is derived from the same clock source that schedules wakeup.

    Can you use range extender to check if there is actually no radio activity? You can find the wikipage below with the information you need :
    processors.wiki.ti.com/.../CC26xx_Range_Extender_Control

    The main difference with debugger attached and not if that the device will enter proper standby state when the debugger is not attached.
    The JTAG domain will stay on in the debugger is attached.
    In another word, there is no actual difference in the software stack.
  • At the present moment I'm not able to use range extender. I can only check radio activity on an oscyloscope and sniffer. When the radio is in the "freeze" state I'm not able to connect to it (There is any BLE respons for a connect inquiry). And on oscyloscope shows only clock iterrupt.
    Do you have any idea what might cause this issue?

    Best Regards

  • I would suggest that you comment out the added code segment by segment, and see what part of the code is causing it.
  • Hi,

    I found this topic:
    e2e.ti.com/.../314805
    This is about CC25xx, but describes a similar problem.

    "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."

    Is there any equivalent parameter in CC2640 library?
    Can I reset only radio part of CC2640 without eraseing values in the RAM memory?

    Best regards,
  • CC26xx has totally different architecture than CC2541. This is not applicable to what you are seeing here. Again, I would recommend you to add the code segment by segment and see what part of the code crashes the program
  • I did some tests. It's hard to say wchich segement of code is guilty. Because devices has different times before "freeze" (for example 4 days). It seems that problem is connection with sensor controller. The radio crash occurs more often when I use I2C and ADC.

  • Can you either post code snippet or some simple explanation of how you integrate the code together?
  • Thank you for help.

    I can send you via mail my i2c library and fragment of code which I changed.
    This is changes compared to the SimpleBLEPeripheral:
    - disable ScanRsponse,
    - set SBP_TASK_STACK_SIZE=1024,
    - own advertisementData with actual measurements (battery level, temp, humidity),
    - add two characteristics, and change their premission on read, write (one with notification and length = 20),
    - change the service UUID,
    - add function which is responsible for sending notifiaction,
    - delete Display.h, and part of code conncetion with this library,
    - change of parameters: advertisement interval (200 ms), max_Connection_interval,
    - add SBP_ADV_CB_EVT (event after advertisement),
    - add i2c library driver (without semaphore - I tested with sempahore, the same result),
    - add SHT20 library,
    - predefined TI_DRIVERS_i2C_INCLUDE,
    - add this fragment to boardfile:
    /* ============================= I2C Begin=====================================
    */
    /* Place into subsections to allow the TI linker to remove items properly */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_SECTION(I2C_config, ".const:I2C_config")
    #pragma DATA_SECTION(i2cCC26xxHWAttrs, ".const:i2cCC26xxHWAttrs")
    #endif

    /* Include drivers */
    #include <ti/drivers/i2c/I2CCC26XX.h>

    /* I2C objects */
    I2CCC26XX_Object i2cCC26xxObjects[1];

    /* I2C configuration structure, describing which pins are to be used */
    const I2CCC26XX_HWAttrsV1 i2cCC26xxHWAttrs[1] = {
    {
    .baseAddr = I2C0_BASE,
    .powerMngrId = PowerCC26XX_PERIPH_I2C0,
    .intNum = INT_I2C_IRQ,
    .intPriority = ~0,
    .swiPriority = 0,
    .sdaPin = IOID_2,
    .sclPin = IOID_1,
    }
    };

    const I2C_Config I2C_config[] = {
    {
    .fxnTablePtr = &I2CCC26XX_fxnTable,
    .object = &i2cCC26xxObjects[0],
    .hwAttrs = &i2cCC26xxHWAttrs[0]
    },
    {NULL, NULL, NULL}
    };
    /*
    * ========================== I2C end =========================================
    */

    Best Regards
  • Under what condition you execute I2C and ADC?
  • i2c is execute in the periodic clock event:

    bool SensorHdc1010_start(void)
    {
    uint8_t val;

    SENSOR_SELECT();

    val = HDC1000_REG_TEMP;
    success = SensorI2C_write(&val, sizeof(val));

    SENSOR_DESELECT();
    return success;
    }

    between DELAY_MS(15);

    bool SensorHdc1010_read(uint8_t *rawTemp, uint8_t *rawHum)
    {
    bool valid;
    uint8_t bufor[4];
    if (success)
    {
    if (!SENSOR_SELECT())
    {
    return false;
    }

    success = SensorI2C_read(bufor, 4);
    DELAY_MS(1);
    SENSOR_DESELECT();

    // Store temperature
    rawTemp[0] = bufor[0];
    rawTemp[1] = bufor[1];

    // Store humidity
    rawHum[0] = bufor[2];
    rawHum[1] = bufor[3];
    }
    valid = success;
    success = true; // Ready for next cycle

    return valid;
    }

    Later I update advertData.
    I2C is open for all the time.

    And ADC I use in the end of advertisement evet:
    if(pEvt->event_flag & SBP_ADV_CB_EVT){
    sumBAT++;
    if(sumBAT > DEFAULT_BATTERY_INTERVAL/(25*advertData[AdvIntervalN])){
    advertData[BatteryN] = battMeasure();
    sumBAT=0;
    GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
    }
    }



    uint8_t battMeasure(void)
    {
    uint32_t percent;

    // Read the battery voltage (V), only the first 12 bits
    percent = AONBatMonBatteryVoltageGet();

    // Convert to from V to mV to avoid fractions.
    // Fractional part is in the lower 8 bits thus converting is done as follows:
    // (1/256)/(1/1000) = 1000/256 = 125/32
    // This is done most effectively by multiplying by 125 and then shifting
    // 5 bits to the right.
    percent = (percent * 125) >> 5;
    // Convert to percentage of maximum voltage.
    percent = ((percent* 100) / BATT_MAX_VOLTAGE);

    return percent;
    }
  • From the code you posted, it does not look like you are using sensor controller engine for your program. The problem you are having should not have anything to do with sensor controller.

    When you said ADC, you meant using the on chip battery monitor ADC for battery voltage return.

    If it's possible, can you try to exclude all the I2C part and just run the battery monitor part of the code? I believe that part is not the reason for the program crashing.

    What's the periodic clock period for I2C task?
  • Range is form 1 - 20 seconds. I thought that the module i2c and adc are part of the sensor controller.
    I don't know why, everything works fine, when I disable a POWERSAVING mode.

    Yes, I can. But this tests take a lot of time, beacse some crash occurs after two days.

    Best Regards