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.

UART Bytes missing with ISR

Other Parts Discussed in Thread: CC2540, Z-STACK

It seems that every hundred bytes or so, I miss a single byte from a uart packet that comes in through the ISR RX routine.  

I know that the transmission to the CC2540 is good because I am probing it with a secondary UART->RS232 converter that is showing the correct data. 

I was wondering if anyone has seen this issue before.

My RX Routine looks like: 

HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR )
{

URX0IF = 0;
jcBuffer[jcCount++] = U0DBUF;


//find a carriage return
if(U0DBUF== '\r'){

     isrCfg.uartCB(HAL_UART_ISR-1, HAL_UART_RX_CR);
}else if(U0DBUF== '>'){
     len=0;
     isrCfg.uartCB(HAL_UART_ISR-1, HAL_UART_RX_ARROW);
     jcCount = 0;
}
}

Could this be a problem with a possible bad internal clock in the CC2540 that is timing the UART port properly?  Is there anything else i can dig into to find the root cause of this problem?

  • Hi Jonathan,

    I know that there has been some problems with using the UART driver in  BLEv1.2.1 (and older versions), especially with ISR. In BLEv1.3, the UART driver has been updated to run stable.

    Best Regards

  • ahh, this is news to me. Has this been discussed before in the forum or just internal TI knowledge?

    I've torn this driver apart trying to figure out why i lose bytes on random transmissions.

    Thanks

  • Hi Nick,

    Good news to me, too.

    Would you please let me know the new version release schedule?

    Thank you.

  • Hey Nick,

    Sorry to keep harping on this topic, but i was wondering if you or someone else on the TI team could share any more details regarding this issue.

    The peripheral I am working on uses significant UART communications and I'd like to be able confirm that this may not be a problem on our end.

    I appreciate it,

    Thank you

    Jonathan

  • Hi Jonathan,

    A couple of possible causes I can imagine:

    a. Timing wrt connection events, as the main cpu clock is halted during transmissions. If the uart HW buffer is partially filled when halting the cpu, a new byte will perhaps mess things up.

    b. Some issue wrt sleep, as clock source is changed during entering sleep, which could potentially cause a problem

    If you could try some combinations of 1) doing uart without being in a connection, 2) doing uart without power saving and 3) both, that could help pinpoint the problem.

    Best regards,
    Aslak 

  • Hey Aslak,

    Great Points.

    I have disabled power saving mode on my device, since it wont be powered from a coin cell, so that doesn't seem to affect it.

    As for the connection test. Most of my debugging has been when the device is not connected to any central device.  That being said, I have configured my peripheral to constantly broadcast, which may be causing the cpu-clock-halt problem you described in (a).

    Could broadcasting have this effect on the Uart Buffer? And more specifically, is this a 'bug' that may be fixed in 1.3 that Nick was referring to? Or is this a scenario which the developer must avoid (uart communication in parallel with BLE communication)

    Thanks

  • Hi Jonathan,

    Yes, broadcast also halts the cpu, everything radiotransmission-related does. Try to turn this off to see if this is the issue.

    Best regards,
    Aslak 

  •   Hi Aslak,

     Could the same happen during DMA transfer to and from SPI (there are two channels fired up simultaneously by RX interrupt)?

    Thanks,

     

     

  • Aslak,

    I performed the test as you asked, and you are correct! If I disable broadcasting on start, and don't allow any BLE traffic, UART ISRs work just fine.

    So now the question is... 

    Will this be fixed in v1.3, or is this a physical limitation of the stack + chip, and therefore some clever semaphore trick is going to have to be used to ensure both the radio and uart ports don't talk at the same time.

    I'm hoping this will be fixed, otherwise this could cause some major problems down the road.  

    Thanks!

  •  Hi, Jonathan

     

    Just a heads-up - I've ran a typical test (~1 million of 32-byte exchanges via SPI with error checking), exchanging data between our SPI master (C5515) and SPI slave (CC2540), with BLE advertising disabled. No faults. So it seems that an assumption that RF exchanges/transfers stop the core so it can miss occasional interrupt is correct.

    Either we should consider it a design feature of CC254x, or I am yet to find a way to mate SPI slave functionality without crippling radio. I am probably missing out :)

  • Hi Oleg and Jonathan,

    In the next version (1.3), there will be an option / HCI function call to keep the cpu core running while the radio is operation. This should mediate the problem somewhat.

    That being said, the only sane/robust solution in a real-time/time-critical system is to implement some manner of flow control, such that you will not receive data when you cannot receive data. My suggestion would be to:

    1. In the RX ISR, use the function LL_TimeToNextRfEvent (http://e2e.ti.com/support/low_power_rf/f/538/t/220317.aspx), and tell the other side that you can't receive more data if there is no time. Timing and implementation of this depends entirely on your serial connection type and settings, and how the implementation is on both sides wrt flow control.

    2. Set an event flag (perhaps with a delay timer) if you don't have enough time to receive more uart or spi data, so that you can check and check again in the task event-processing until you do have enough time to receive data, in which case you notify the other side of the serial comm, and comm continues via ISR interrupts.

    In 1.3 there will be a possibility to get an event set by the stack when RF event is complete, so you won't need to implement step 2 by checking with TimeToNext.. yourself.

    Best regards,
    Aslak 

  •  Hi, Aslak

    Thanks for the update! This answers quite a few questions :) IMHO, this deserves some document or small design note. 

     

    The basic workaround is clear, indeed - do not allow USART operation without somehow synchronizing it to RF activity (otherwise, the latter will sooner or later stop CC25xx core during USART transfer, thus producing a glitch). Good thing is that for many systems, it comes naturally (in my current project).

    Oleg.

  • No that i'm thinking, is the same behavior could happen in Z-stack + CC253x?

  • Aslak N. said:

    In the next version (1.3), there will be an option / HCI function call to keep the cpu core running while the radio is operation. This should mediate the problem somewhat.

    Aslak, what would be the downside of this? Battery life? transmission power? 

    Thanks

  • Jonathan,

    The downside is voltage drop that can take you below brown out level, if you are running on a battery with high internal resistance such as a coin cell, because current draw => v drop. So yes, on coin cell, battery life is impacted, but not because the battery is depleted. This is not really a problem on many other battery types.

    Check out http://data.energizer.com/DataSheets.aspx and other vendors' data sheets.

    Also, you can expect the total energy expended to be the about same, because halting the cpu only postpones whatever processing is scheduled.

    Best regards,
    Aslak 

  • Aslak, That all makes sense and is relatively good news for me. My power source is not a coin cell and would be able to support the voltage drop that you are talking about.  I guess I'll have to wait for 1.3 to enable the option to keep the cpu running while the radio is operating.

    Thanks!

  • --- Update ---

    I've tested BLE Stack 1.3 and unfortunately the problem still persists.  Bytes get lost during UART RX ISR and the entire chip has a tendency to lock up when BLE data and UART data are being sent at the same time.

    Aslak, could you explain how to enable the option to keep the cpu core running while the radio is operation?

    I found in hci_tl.h the following, but I am not using the device in hci mode

    HCI_EXT_HALT_DURING_RF_EVENT 0x0419

    I also found the NPI layer, but the npi_uart and npi_spi.c files are missing from the Stack 1.3 distribution.

  • >> and the entire chip has a tendency to lock up when BLE data and UART data are being sent at the same time.

     Now that is something I have not run into yet. Does it happen under 1.3 only? I've had every possible glitch with losing USART data due to RF core stopping MCU, but RF core itself was running safe&sound.

    BR,

    Oleg

  • So as for the bytes missing during UART ISR, this problem is resolved with 1.3 using the following command:

    HCI_EXT_HaltDuringRfCmd(HCI_EXT_HALT_DURING_RF_DISABLE);

    As for the entire chip locking up, I believe this is a bug that I have to resolve on my own and is probably unrelated to the issue described in this thread.

    Thanks again to Oleg, Aslak and the TI Team for putting this fix in place in stack 1.3

  • Hello,

    On the UART side. We recommended DMA for communication during RF in 1.2.1. While RX worked well with DMA, the TX had a problem in that the last char might not always get sent. The solution in 1.3 is to use DMA on RX and ISR on TX.  This has proven robust for customers.   The HALT_DURING_RF_DISABLE will also work, but will increase power consumption some during RF - about 5ma. If you are using short intervals and running short on MIPS processing power, then the HALT_DURING_RF_DISABLE will help.

    BR,

    -Greg

  • Hi Jonathan,

    To leave the CPU running during RF events, use the command HCI_EXT_HaltDuringRfCmd.

    To turn off clock division on halt use HCI_EXT_ClkDivOnHaltCmd. Clock division, if enabled, reduces the speed of the peripheral clocks as well, in an effort to save power.

    The latter is often the culprit in disturbing serial communication. The definitions of these commands can be found in hci.h.

    Best regards,
    Aslak 

  • Hello TI experts:

    I am testing UART function in TI stack 1.3 too and I use default setting as: RX - DMA, TX - ISR. Then I try to send a serial array of UART message from PC via hyper terminal program. I found that if the size of array is smaller than 4 bytes, there was no problem at all. But if the size of array increases to 10 bytes or more, CC2540 chip starts to drop arrays.

    Here is my UART callback which works well in stack 1.2 (porting from CC253x):

    void MT_UARTCallback(uint8 port, uint8 event)
    {

      (void)event; // Intentionally unreferenced parameter

      while (Hal_UART_RxBufLen(port))
      {
        HalUARTRead(port, &ch, 1);

        switch (state)
        {
          case SOP_STATE:

            break;

          case LEN_STATE:

            break;

          case CMD_STATE:

            break;

          case DATA_STATE:

            break;

          case CRC_STATE:

            break;

          default:
            break;
        }
      }
    }

    Is there any modification which is needed for stack 1.3?

    Or could you provide your test code of UART callback?

    Thank you!

    Best Regards

    Joe

  • Hi, I'm running 1.4 and am experiencing the same problem described in this thread. That is, I'm missing UART RX interrupts while the BLE radio is active. This thread references an option "to keep the cpu core running while the radio is in operation".

    What is that option?

  • Hi,

    It means calling HCI_EXT_HaltDuringRfCmd(HCI_EXT_HALT_DURING_RF_DISABLE);

    Aslak