- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.