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 RX missing bytes

Other Parts Discussed in Thread: CC2540

We encountered byte-missing problem in UART RX, which is mostly severe in the first few seconds after CC2540 boot-up. Almost all bytes received are garbage. But after a few seconds, it seems to begin to work correctly.

Our design is simple: Connecting a WiFi module (Microchip RN171) to CC2540 via UART.  After CC2540 boot-up, it send some strings to configure WiFi module and establish a connection with remote web server (tcp). Then it begins to listen advertisement packet and send the received device info (bdaddr, rssi etc.) to web server.

The software are modified from SimpleBLEObserver code. With UART configured as 9600bps, no flowcontrol, HAL_UART_ISR defined as 1 and  HAL_UART_DMA defined as 0. Use ISR for UART RX.

Because data transmission protocol with WiFi module requires many wait and check operation, and there is no simple delay function in osal, we use the lightweight protothread library. It use some tricky macros to implement the local continuation of the function. The task send a (custom) self message and never clear the bit in event bitmask, so the message arrived again and again. I placed the handler as the last priority so I don't think it will starve other task.

Each time the (self) message arrived the so-called proto thread  is called. Essentially it is a state machine which preserve all function executing states (no locals in fact) and position (tricky, use __LINE__ macro) and evaluate a condition, if true, move on and if false return, yield the cpu and waiting for next event. I don't know if this pattern influence the UART driver. But in my case the UART RX only misfunction in the first few seconds after CC2540 bootup. The same code works perfectly if the chip has worked for a while after reset. (The chip is constantly powered.)

We do not use UART callback. Just call HalUARTRead each time the self message fired. We modified the UART buffer size in _hal_uart_isr.c, but seemed no help.

Power saving feature are disabled by removing POWER_SAVING macro.

So before I dive into the HAL driver code to check what really happened, I would like to have some advices on how to probe the problem and what are the possible reasons.

I have search the forum. Some threads point out that if there is radio activity, the CPU may be halted. My CC2540 worked as a silent observer, no broadcast, no connection. So does that mean the cpu won't halt to cause problem in my case?

What i cannot understand is that the error occurs only in the first few seconds (<15). If I reset the wifi module several times by CC2540, each time the module will spit out about 100-200 bytes and I am sure the RX buffer is not large enough to hold all those bytes. Then after a while the HalUARTRead begin to return the correct bytes.

On oscilloscope the waveform of UART signal (from wifi module tx) are perfect. We pick this signal via seperate UART to USB convert and all bytes received on PC are correct, at the sames time, HalUARTRead returns are totally garbage.

and should I use flow control?

BLE version 1.4.

Since there is no Rx buffer flush function provided, we use " char c, while (HalUARTRead(HAL_UART_PORT_0, &c, 1){} to clear the buffer. Don't know if this is the recommended way. Further more, there is no Rx Arrive event for uart callback, so i dont know what is the recommended way to process the rx bytes as soon as possible, to prevent the rx buffer from being overflowed.

Any clues or advice? or somebody else encountered the similar problems before?

  • Hi,

    You basically use the Coco-os trick for cooperative multithreading then?

    ISR-based serial communication is not recommeded, because of the radio-interrupts that can both preempt and block your UART Isrs. I recommend that you use DMA.

    You should perhaps also use flow control. If you use flow control it may even be feasible to use Isr-based UART, but I can't say for sure.

    BR,
    Aslak