UART Buffer

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
ScEn_283436
Level 5
Level 5
5 sign-ins First solution authored 100 replies posted

Hi,

   

I'm using the PSoC 3 UART function and seem to be having problems getting the data in a simple application.

   

If I am using a terminal window to type characters, everything works fine but if I programmatically send a string, it appears that the FIFO wraps around and the LF winds up in the first character in the buffer.

   

What I tried to do is read the status to see when a character comes in (UART_1_RX_STS_FIFO_NOTEMPTY), then go into a loop almost identical to the example in the datasheet.that takes all the characters until the CR-LF. .

   

I have put a UART_1_GetRxBufferSize() to see if more than one character has arrived but I never see more than one at a time.

   

Any ideas to prevent me from days of hacking and guessing?

   

Regards,

   

Nick

0 Likes
11 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

When you provide us a bit more with settings and selected properties it would be rather helpful to clear your issue. Can you create a "Workspace Bundle" and upload it here (NOT USING chrome, won't work)?

   

Both of your principles usually do work, so the cause must be at a different place.

   

 

   

Bob

0 Likes
ScEn_283436
Level 5
Level 5
5 sign-ins First solution authored 100 replies posted

Bob,

   

Yes, I'll upload it but I have subsequently done an experiment where I sent only 4 bytes (default Rx buffer size) to the device and didn't see any problems. It got all 4 bytes 10 times out of 10. Do you have to configure your receive buffer size to account for worst case?

   

Nick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

The UART FIFO is exactly 4 bytes deep, that might be the reason why that test worked. When you set the Rx buffersize larger than 4 an internal interrupt is generated, so that you will not be able to catch a non-empty FIFO-state or an empty Rx register, only checking the buffersize will work.

   

At this point (you are not the first having problems here) I usually suggest to write an interrupt-driven circular buffer to handle incoming characters.

   

 

   

Bob

0 Likes
ScEn_283436
Level 5
Level 5
5 sign-ins First solution authored 100 replies posted

Bob,

   

Thanks, that makes sense. I'm a little confused about the internal interrupt. I don't have to write a special interupt handler or do I?

   

Can I simply set the buffer size to something like 48, then do a UART_GetRxBufferSize() call to determine when to retrieve the data as I pass through the main loop?

   

Nick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Exactly.

   

while( UART_GetRxBufferSize() )

   

{

   

   RetrieveOneCharacter(); // Use the appropiate UART API here

   

}

   

 

   

Boib

0 Likes
Anonymous
Not applicable

Hello Bob,

I am trying to send 1024 bytes of data as a single command via UART to a PSoC 5LP device. As a simple test  once I receive 1024 bytes I just echo it back to verify. I have set the FIFO size as 1024 for Rx and Tx. I have an array of 1024 size and as I receive each byte I move it to a local array. I use UART_ReadRxData() for reading the byte. It works as I expected.

While reading the datasheet and going through the UART.c source code (automatic generated) I found the following array which I think the program is using internally:

volatile uint8 UART_rxBuffer[UART_RX_BUFFER_SIZE]

I tried to read this array from my main program but was not successful. I thought if the automatic generated source code is already using an array, why can't I just use that, so that there's no need of another local array. And I also found that the UART_rxBuffer[] is a global variable.

Is this array not user accessible or am is there something wrong with my understanding?

Any help is appreciated.

Regards, Sinoj

0 Likes

The UART internal buffer is a "Circular Buffer" which is used to store incoming (and a second one for outgoing) data. Because this buffer changes with the reception of data it is not recommended to access it directly. Furthermore it is not guaranteed that your first byte is stored at buffer[0], there are separate read and write indices.

A tip: Declare the RX and TX buffers larger than the data you are expecting. That will prevent overwriting in the case you are not fast enough reading the data from the buffer.

Bob

ScEn_283436
Level 5
Level 5
5 sign-ins First solution authored 100 replies posted

Bob,

   

Thanks a million. That works a lot better. The key was using the GetRxBufferSize as opposed to check RxStatus. I still occasionally miss a character but very rarely and can probably tune that out. My application is a small RS485 network. It seems like the 4 byte buffer is good for a human typing commands from a terminal but I need to be able to do both terminal and automated serial commands and this works well for both. I had a similar issue with the USBUART and it seems like the GetRxBufferSize is a close cousin of the USBUART_GetAll() command.

   

To simplify matters, I get everything with the GetRxBufferSize in the while loop like you suggested, then call UART_ClearRxBuffer. There might be a better way using pointers or a better time to do that and it may be the source of my occasionally miss.

   

Thanks again,

   

Nick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

The "ClearBuffer()" might be the cause for missing characters sometimes, it throws away any information still stored in the buffer. Retrieving a character from the buffer removes it from the queue, so there is no need (except for a software resetting) to use ClearBuffer().

   

When time is not pressing: Again I would suggest you to write your own circular buffer. Not because you need to, but only to understand one of the basic pronciples to solve the problem of storing incoming data and retrieve them later.

   

 

   

Bob

0 Likes
ScEn_283436
Level 5
Level 5
5 sign-ins First solution authored 100 replies posted

Yes, I'll try that immediately while I actually have the time.

   

One other question. Which function do you prefer to retrieve the data? I have used the UART_GetChar and UART_ReadRxData and they both seem to work about the same with the GetRxBufferSize() loop approach.

   

Nick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

UART_GetChar() includes a status info and cannot be used for binary data.

   

UART_ReadRxData() assumes that the state is already checked (as it is the case in your example) and as opposed to GetChar() you may receive a binary 0x00. This is the way I prefer.

   

 

   

Bob