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: BLE Stack Interrupt loss issue

Part Number: CC2540

Hi,

I am using the CC2540 with the BLE Stack version 1.4.2.2 and using IAR workbench version 9.30. My application using serial port communication. It happens that when the BLE is advertising the interrupt blocks for a very long time and characters received from the serial port are lost. This problem also happen during a connection but it is much less frequent.

  You can see an example in the picture below, I recorded the serial port input and use an out port to demonstrate inert and another to notify whenever there is an unexpected input. In the first example the interrupt was blocked for ~100uS the second show an example where the interrupt blocked for  350uS and short time after that for 1.39mS . It is clear to me this is a bug in the BLE stack, interrupts should not be blocked for so long. I assume I am not the first one encountered with this issue. I can think of some workarounds, however each workarounds has limitations and not always implementable in my system.

My question is if you have any intention to fix these serious BLE library bugs and if so can you provide and expected date for such a fix?

Thanks,

Eitan

  • Hello Eitan,

    While critical sections are a necessary part of any realtime software solution, I do agree that the ones that you have observed are quite large.
    Looking at our database of tickets, I do not see any current issues assigned related to critical sections.

    However, we are always interested in improving the quality of the stack. Can you provide some code that reproduces your issue so that we can look into it?
  • Hi,

    Thanks for your response. As mentioned I am using the simpleBLEPeripheral example code from TI. The serial port is connected to a cellular modem, and I am sending in a loop a test message comparing the results to what is expected ind signal if something is wrong. As long at the BLE advertising is off - everything runs smoothly, no errors, no interrupt losses, as soon as I turn on the Advertisement I am starting to loose data from time to time.

    This is the UART initialization code:

    /******************************************************************************
    * @fn CellInit
    *
    * @brief Initialize the UART for the Cellular Module Communication
    *
    * @param none
    *
    * @return none
    *****************************************************************************/
    void CellInit()
    {
    U1CSR = 0xC0;
    //U1BAUD = BAUDM_57600;
    //U1GCR = BAUDE_57600;
    U1BAUD = BAUDM_115200;
    U1GCR = BAUDE_115200;
    current_rx_buf = 0;
    UARTrxLen[0] = 0;
    UARTrxLen[1] = 0;
    IP0 |= 8; // Heigher UART1 interrupt priotity
    IP1 |= 8;
    // Enable RX interrupts
    URX1IE = 1;
    }

    Here is the UART Interrupt section:

    #define SYNC_CHAR 'K'
    char rx_error;
    char s;
    bool sync = true;
    char exp_str[] = {"\r\nat+cops?\r\r\n+COPS: 0,0,\"Partner\",0\r\n\r\nOK"}; // Expected string
    // UART1 RX Interrupt
    HAL_ISR_FUNCTION(HalUARTrxIsr,URX1_VECTOR)
    {
    cmd_req = 1; // This marks enterinh the ISR for LA recording
    cmd_req = 0;
    //task_hold = 3;
    char c = U1DBUF;
    if (sync)
    {
    if (c == SYNC_CHAR) { sync = false; s = 0;}
    } else
    if ( exp_str[s++] != c)
    {
    sel = 0; // Test - marks an error for LA recording
    rx_error++;
    sync = true;
    sel = 1; // Turn off marking
    }
    if (s == sizeof(exp_str) -1) s = 0;

    if (UARTrxLen[current_rx_buf] == UART_BUF_LEN/2) {
    rx_overflow = true;
    return;
    }
    UARTrxBuf[current_rx_buf][UARTrxLen[current_rx_buf]++] = c;

    }

    Regards,

    Eitan

  • Hi Eitan,

    Thanks for providing the code snippet.
    I have reported your issue as well as the code snippet to our R&D team.
  • Hi,

    Thanks, I will wait for the response. In the meantime I further investigated this issue and identified a very strange behavior, it looks like its not that the interrupts are disabled but more like the CPU clock speed is changed to a very low speed or maybe the CPU halts - I conclude this because if this phenomena happens during serial port transmission - the transmission stops for a while and in practice the data is corrupted if it happens in the middle of a character transmission.  Also If I starts a counter, the counting of this counter stops and the timing is incorrect.

    Best Regards,

    Eitan

  • Sean,

    I would like to add some more data, maybe it will helping you to analyze this issue, it seems like the source of the problem is not loosing interrupts but the CPU clock changed. It looks like the CPU clock is divided by 32 at certain time when advertising. Look at the picture below - it depicts an output of a free running counter configured to toggle every 256 CPU clocks i.e. the frequency is 25Mhz / 512 = 62.5 Khz. During advertising the CPU clock is divided by 32 - i.e. instead of 32Mhz it is only 1 Mhz. This results in undesired behavior such as the serial port baud rate is now 1/32 than the desired rate, if there is a receive or transmit during this period the data is corrupted.   

    Best Regards,

    Eitan

  • Hi Eitan,

    Sorry for the delay in reply.
    Do you have POWER_SAVING enabled in your project? If so this means that the stack/OSAL layer will put the device into sleep whenever possible. While asleep, the device can only be woke by interrupts. What interrupts exactly can wake the device are dependent on which type of sleep is selected given the next link layer event.

    osal_pwrmgr_powerconserve() will run at the end of the OSAL superloop and will put the device into a given sleep mode.
    I would do some debugging using halSleep() to see if when you observe the reduced frequency waveform it corresponds to the device being put to sleep.

    you can also test to see if the issue occurs with POWER_SAVING disabled.