Node to Node Uart Communication Echo Test Issue

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

cross mob
lock attach
Attachments are accessible only for community members.
jaro_4346051
Level 2
Level 2
First like received First like given

Hello,

I am working on a project where a custom piece of hardware is using a PSoC 5LP as the controller, this hardware will be called a node. The project is composed of many of these nodes, connected together in a network like a linked list. Each node has a north and south port and each port has its own Full Duplex Uart. Each node also has a debug port which is used for a console and is the only way I can interface the node with the computer.

Each node has the same external crystal (70.77888 MHz) and each Uart is running on 737280 baud (master clock divided by 12, 8x oversampling then gives rate). I am using external Rx Interrupts on byte received for the Uarts and have written my own Uart C and H files to allow for my project to interface with the demands I need. This file is called UartHandler.c/.h. I have created an echo project where one node will send a buffer of length 288 to the other node. The other node will check if the bytes follow the proper format (proper format predetermined to ensure Uarts are not mis-reading bytes), then ping the array back. This will happen back and forth forever.

Unfortunately after a random number of times (usually under 20) one of the Uarts has a Timeout because it receives less than the 288 bytes. Because the clock rates of each node are the same I should not be experiencing byte misses like this.

If someone could look at my UartHandler file and let me know if there are any blatant logic issues that would be appreciated.

I have attached my project below. Thank you.

0 Likes
1 Solution
DoBa_1705086
Level 3
Level 3
First like received First like given

At this high data rate you most definitely should switch to using DMA rather than interrupts to handle the I/O.  I would be quite easy to overrun the UART's internal buffer while handling interrupts on the other port.  Configure the UART for the maximum 16 bytes of internal buffering as well for an extra margin of safety. 

Also consider the signal integrity of the UART interconnect.  You did not indicate if you are using RS232 or RS48X signaling.  Transmission line effects and cross-coupling between Rx and Tx wires will start to come into play with long cable lengths.  You might also have challenges with ground loops, so watch your system ground integrity carefully!  Differential signaling might be necessary for long cable runs.

Doug

View solution in original post

7 Replies
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Although I have not read your project well,

but at first glance I noticed that you left the buffer size of UART as default 4 bytes

000-uComSoUart.JPG

Since you know that the size of data is 288, how about make the buffer size as large or slightly bigger?

In the following screen shot I set it to 300.

001-UcomSoUart-300.JPG

moto

0 Likes

Thank you for taking a look at my project. I didn't change that parameter on the Uart because I am servicing the Uart with my own ISR which I have the external Rx interrupt set to byte received. The code below shows the variables I am using to service the ISR. One note is the NorthBufferPtr and SouthBufferPtr are set to either one of its array's 0 or 1. These are implemented so I can have ping pong buffer functionality.

volatile uint8* NorthBufferPtr;

volatile uint8 NorthBuffer0[UART_BUFFER_SIZE];

volatile uint8 NorthBuffer1[UART_BUFFER_SIZE];

volatile uint16 NorthIndex;

CY_ISR(NorthReceiveByte) {

    NorthBufferPtr[NorthIndex++] = uComNoUart_RXDATA_REG;

}

volatile uint8* SouthBufferPtr;

volatile uint8 SouthBuffer0[UART_BUFFER_SIZE];

volatile uint8 SouthBuffer1[UART_BUFFER_SIZE];

volatile uint16 SouthIndex;

CY_ISR(SouthReceiveByte) {

    SouthBufferPtr[SouthIndex++] = uComSoUart_RXDATA_REG;

}

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

> Unfortunately after a random number of times (usually under 20) one of the Uarts has a Timeout

> because it receives less than the 288 bytes.

I think this symptom happens when we fail to salvage data from the UART RxBuffer before more data is incoming.

Since you are sending 288 bytes, but the hardware buffer is only 4 bytes,

and an interrupt takes dozen of cycles to call and return, dropping data can easily happen.

So just for test, could you increase the UART rx buffer size to 300 or at least 16 or more to see if there is/are any improvement?

moto

0 Likes

I would need to rewrite my library to do this because making the buffer greater than 4 enables the IRQ which will not pair well with my interrupt that is already servicing the uart. Also the IRQ interrupt routine is very large compared to my small Interrupt routine. Will try to use it though.

0 Likes
AnSa_1225656
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

This is a case where DMA would shine!  Look for example application from Cypress.

DoBa_1705086
Level 3
Level 3
First like received First like given

At this high data rate you most definitely should switch to using DMA rather than interrupts to handle the I/O.  I would be quite easy to overrun the UART's internal buffer while handling interrupts on the other port.  Configure the UART for the maximum 16 bytes of internal buffering as well for an extra margin of safety. 

Also consider the signal integrity of the UART interconnect.  You did not indicate if you are using RS232 or RS48X signaling.  Transmission line effects and cross-coupling between Rx and Tx wires will start to come into play with long cable lengths.  You might also have challenges with ground loops, so watch your system ground integrity carefully!  Differential signaling might be necessary for long cable runs.

Doug

The PCB that was being used seemed to have an issue with the specific port I was using and when switching to the other serial port there were no issues. The hardware must be inspected now.

As for the ISR handling: the master clock is 70.77888 MHz, the baud rate is 737280, 10 bits per byte makes byte rate 73728, this allows (70778880 / 73728) 960 processor cycles per byte received. This should be enough to handle transferring a single byte from one register to another and increment a variable.

CY_ISR(NorthReceiveByte) {

     NorthBufferPtr[NorthIndex++] = uComNoUart_RXDATA_REG;

}

Thank you for the response I appreciate all the help here!

0 Likes