SCB UART how to receive 0 (zero) in RX Buffer

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

cross mob
Antonio
Level 2
Level 2
First like received 10 replies posted 5 replies posted

Hello,

I'm using PSoC Creator 4.4 and a PSoC 4 4100 PS (CY8C4145PVI-PS421) in a board self made.

I'm using a SCB UART component to communicate with a PC, it works very good up to I use a message that contains the byte 0

I'm using the UART_SpiUartGetRxBufferSize() function to exsaminate the RX buffer, and I noted with debugger that if in the message there is a 0 the function give me the number of byte until the zero, so for exsample:

if I had this message

16-2-91-86-13-16-3 I receive all the packet

if I had this message

16-2-91-87-8-4-0-16-3 I receive only 16-2-91-87-8-4 because after the '4' there is 0

I tried to use UART_SpiUartReadRxData() but don't change.

In the PSoC 5 LP I never have this problem.

Please help me

0 Likes
1 Solution
BiBi_1928986
Level 7
Level 7
First comment on blog 500 replies posted 250 replies posted

Hello.

I tried the functions you showed and could not get a failed result.
I used the SCB UART with all default settings.  The FIFO is only 8 bytes, so I only sent 8 bytes, including the 0.  It passed.

I used the SCB UART with all default settings except I changed the FIFO to 16 bytes.  I only sent the 9 bytes you listed and it passed.

Questions:

1) did you change anything in the SCB UART configuration?
2) are you using interrupts or polling?
3) does s/w wait long enough for all the bytes to be received?
4) does s/w wait to read a block of received bytes, or read bytes as soon as each is received?

I checked the source code for the functions UART_SpiUartGetRxBufferSize() and UART_SpiUartReadRxData().  These do not filter any data so all received bytes are available to read.

There were only 2 ways I could make this fail.
a) by not waiting long enough for the 0 byte to be received (reading data as a block)
b) used 8 byte FIFO (default) and placed 0 as the 9th byte (reading data as a block)

BTW, there are some very good UART utilities written by Moto.
https://community.cypress.com/t5/Code-Examples/MCU-Tester-a-Swiss-Army-Knife-for-PSoC-CY8CKIT-059-ve...

Here's the code I ran.  I connected TX to RX for a loopback.  My UART component is named UART_1.  I set the UART buffer size TX/RX to 16.  I use a single LED to indicate status.

#include <project.h>

int main()
{
UART_1_Start(); /* Start UART operation */

CyGlobalIntEnable;

#define ArraySize 9
uint8 SendDataArray [] ={16,2,91,87,8,4,0,16,3};
uint8 CompareDataArray []={16,2,91,87,8,4,0,16,3};

/* 16-2-91-87-8-4-0-16-3 */

/* transmit the data bytes */

uint8 j;
for (j=0;j<=ArraySize-1;j=j+1){
UART_1_SpiUartWriteTxData(SendDataArray[j]);
}
CyDelay(100); /* wait for transmission to complete */

/* check number of received bytes by blinking the LED */

uint32 temp = UART_1_SpiUartGetRxBufferSize();
uint8 i;
for (i=0;i<=temp-1;i=i+1){
LED_1_Write(1u); /* LED ON */
CyDelay(500);
LED_1_Write(0u); /* LED OFF */
CyDelay(500);
} /* end for */

CyDelay(2000); /* simple delay to know where we are */

/* check received bytes against compare data array */

for (j=0;j<=temp-1;j=j+1){
if (UART_1_SpiUartReadRxData() == CompareDataArray[j]){
LED_1_Write(1u); /* LED ON */
CyDelay(500);
LED_1_Write(0u); /* LED OFF */
CyDelay(500);
} /* end if */
else {
for(;;) /* stop here if data mismatch */
{}
} /* end else */
} /* end for */

/* do nothing after testing completed */
for(;;)
{
}

} /* end main */

View solution in original post

3 Replies
BiBi_1928986
Level 7
Level 7
First comment on blog 500 replies posted 250 replies posted

Hello.

I tried the functions you showed and could not get a failed result.
I used the SCB UART with all default settings.  The FIFO is only 8 bytes, so I only sent 8 bytes, including the 0.  It passed.

I used the SCB UART with all default settings except I changed the FIFO to 16 bytes.  I only sent the 9 bytes you listed and it passed.

Questions:

1) did you change anything in the SCB UART configuration?
2) are you using interrupts or polling?
3) does s/w wait long enough for all the bytes to be received?
4) does s/w wait to read a block of received bytes, or read bytes as soon as each is received?

I checked the source code for the functions UART_SpiUartGetRxBufferSize() and UART_SpiUartReadRxData().  These do not filter any data so all received bytes are available to read.

There were only 2 ways I could make this fail.
a) by not waiting long enough for the 0 byte to be received (reading data as a block)
b) used 8 byte FIFO (default) and placed 0 as the 9th byte (reading data as a block)

BTW, there are some very good UART utilities written by Moto.
https://community.cypress.com/t5/Code-Examples/MCU-Tester-a-Swiss-Army-Knife-for-PSoC-CY8CKIT-059-ve...

Here's the code I ran.  I connected TX to RX for a loopback.  My UART component is named UART_1.  I set the UART buffer size TX/RX to 16.  I use a single LED to indicate status.

#include <project.h>

int main()
{
UART_1_Start(); /* Start UART operation */

CyGlobalIntEnable;

#define ArraySize 9
uint8 SendDataArray [] ={16,2,91,87,8,4,0,16,3};
uint8 CompareDataArray []={16,2,91,87,8,4,0,16,3};

/* 16-2-91-87-8-4-0-16-3 */

/* transmit the data bytes */

uint8 j;
for (j=0;j<=ArraySize-1;j=j+1){
UART_1_SpiUartWriteTxData(SendDataArray[j]);
}
CyDelay(100); /* wait for transmission to complete */

/* check number of received bytes by blinking the LED */

uint32 temp = UART_1_SpiUartGetRxBufferSize();
uint8 i;
for (i=0;i<=temp-1;i=i+1){
LED_1_Write(1u); /* LED ON */
CyDelay(500);
LED_1_Write(0u); /* LED OFF */
CyDelay(500);
} /* end for */

CyDelay(2000); /* simple delay to know where we are */

/* check received bytes against compare data array */

for (j=0;j<=temp-1;j=j+1){
if (UART_1_SpiUartReadRxData() == CompareDataArray[j]){
LED_1_Write(1u); /* LED ON */
CyDelay(500);
LED_1_Write(0u); /* LED OFF */
CyDelay(500);
} /* end if */
else {
for(;;) /* stop here if data mismatch */
{}
} /* end else */
} /* end for */

/* do nothing after testing completed */
for(;;)
{
}

} /* end main */

Antonio
Level 2
Level 2
First like received 10 replies posted 5 replies posted

Hello,
first of all thank you very much for the reply.
I had spent too much time on reception, and your answer gave me confidence that it was right, so I shifted my focus to transmission.
In fact the error was in the transmission, in the transmitter device there was a UART_PutString which obviously finding 0 stopped, once replaced with a for and a PutChar it worked fine.
Then I also had another problem, but it is not related to the problem, but I don't know if it can be a starting point for other reflections.
In the external UART routine as per datasheet I used
if ((UART_GetRxInterruptSourceMasked () & UART_INTR_RX_NOT_EMPTY)! = 0)
but I noticed that the first time it never entered the if, while the following ones did, since I only use the RX_NOT_EMPTY interrupt I don't need to filter the type of interrupt and I removed the if, anyway, I plan to look for the solution.
Thanks again for the answer.
Greetings

0 Likes

Hello.

Good to hear you got it working.

For the other issue:
A possibility is, RX_NOT_EMPTY might be self clearing when the status register is read with only a single byte in the buffer.

I've had problems in the past where performing (UART_GetRxInterruptSourceMasked () & UART_INTR_RX_NOT_EMPTY) inside the "if" didn't work.  I had to move the & operation outside the "if".

temp = (UART_GetRxInterruptSourceMasked () & UART_INTR_RX_NOT_EMPTY);
if (temp != 0)

I have no idea why there was a problem with the "&" inside the "if", but that was the solution I used to make it work.

Good luck with your project.

0 Likes