UART Rx not working unless reset

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

cross mob
KevinE
Level 3
Level 3
10 sign-ins 10 replies posted 5 sign-ins

I have a PSoC5LP device communicating to an embedded linux application (LTE Module) using UART. 

When the embedded Linux processor resets / reboots, the PSoC5 UART Rx ISR no longer works.

I think this is a PSoC5 Issue because I can recover the functionality of the UART Rx ISR on the PSoC5 side if I do the following (Without resetting the Embedded Linux (LTE Module)side):

 - Software Reset
 - XRES Hardware Reset

 

This is not ideal, as I would rather find a way to programmatically reset the UART peripheral, but I have not had any luck doing so. 

This may seem haphazard, but my attempts to reset the UART peripheral include the following but have not worked. 

UART_Stop();
UART_ISR_RX_Stop();
UART_ClearRxBuffer();
UART_ClearTxBuffer();
UART_ISR_RX_ClearPending();
CyDelay(10);
UART_Start();
UART_ISR_RX_StartEx(RxIsr);

For reference, here's the ISR routine for the UART Rx on the PSoC5 side:

KevinE_0-1664228529330.png

 

Can someone point me in the right direction for being able to reset the UART peripheral without needing to perform a software / hardware reset?


0 Likes
1 Solution

As they say "a picture says a thousand words".  Thanks for configuration images.

With a 4-byte fifo, that simplifies things.  Fewer things can go wrong.

I noticed in the ISR, the 'while' is testing stale data.  It will likely always loop back to the top of ISR, read RxStatus of null and then check if fifo_not_empty.  Then because fifo is empty, it will check fifo_not_empty one last time before exiting.  Kind'a defeats the purpose of saving ISR time (by checking for more data before leaving).

Alternatively, check UART_GetRxBufferSize(void) for more Rx data at the "while" to leave ISR if truely, fifo is empty.

Is Repeater.uart.UARTerrorStatus cleared somewhere after an error occurs?  Otherwise, when it's OR'd with new Rx Status bits, any previously stored error bits will show up again.

Is it possible the LTE module puts its Tx pin into a tri-state mode while resetting itself?  You might want to configure 5LP Rx pin input with a pull-up resistor.  Or externally, add a 4.7k-10k Ohm resistor to 5LP Rx pin.  Alternatively, configure with a pull-down resistor.  If LTE Tx pin does go tri-state, you'll receive a break condition or false Stop bit condition (STOP_ERROR).

So, after LTE module resets, 5LP doesn't even see 1 interrupt when LTE starts transmitting again?  That is really bizarre.  Makes me wonder how the two processors get through a power ON sequence and can start talking to each other in the first place.

edit: I just noticed, if there's more than 1 byte in fifo, and the ISR loops around, reading the second byte will over-write the first byte that was read since there's no buffering, only the rxdata variable.  So, you might consider removing the "do-while".  It likely works with the do-while since the ISR executes faster than another byte can be received.  But, over-writing is a possibility.  Something to think about.

View solution in original post

0 Likes
9 Replies
PandaS
Moderator
Moderator
Moderator
250 replies posted 100 solutions authored 5 likes given

Hi @KevinE ,

If I understood correct, When you reset the Linux System - UART RX Interrupt doesn't trigger on PSoC5LP.

Could you please explain, what happens to the GPIO which is connected to the UART Rx Pin upon Linux System getting reset. Does it keeps the line low or high?

Or is it the interrupt is triggered, it enters the RX_ISR but the UART peripheral stops working ?

Warm regards

Sobhit

0 Likes
KevinE
Level 3
Level 3
10 sign-ins 10 replies posted 5 sign-ins

Hello, Sorry for any confusion. I will try to explain in greater detail.

From power on of the PSoC5 and LTE Module, the PSoC5 is the UART slave and the LTE module is the UART Master.

The LTE Module will send a byte to the PSoC5 periodically and the PSoC5 UART ISR will fire each time.

During normal operation, if the LTE Module resets for any reason, then the PSoC5 UART Rx ISR no longer responds to incoming data.

Once the LTE Module reset happens the PSoC5 UART Rx ISR no longer responds to data and the only way I have been able to demonstrate recovery to normal operation is to reset the PSoC5 using software reset API, or using a pushbutton tied to XRES HW reset pin.

The pin state of the Tx and Rx lines is logic high or 3.3v - The lines are not held low during this event.

 

thank you

0 Likes

Hello.

How do you determine the RxISR is no longer running?

I'd suggest setting a GPIO pin High when entering the RxISR and clearing GPIO pin Low when exiting.  Monitor this activity with an oscilloscope if available.  Maybe attach an LED (although it would wink too fast to visually see).

Is it possible the 5LP is stuck in RxISR infinite loop?

You could also try multiple readings of Rxdata reg to (manually) clear the fifo's.  Same for RxStatus reg's.

0 Likes
KevinE
Level 3
Level 3
10 sign-ins 10 replies posted 5 sign-ins

I determine the ISR is no longer working because I set a breakpoint in the ISR while in debug.

After the event occurs, the breakpoint is no longer reached, even when manually sending data from the LTE Module.


"You could also try multiple readings of Rxdata reg to (manually) clear the fifo's. Same for RxStatus reg's."

Thank you for this advice - I will try this.

would this mean multiple reads from this register?

rxData = UART_RXDATA_REG;

Can you explain further how to perform multiple reads to clear the fifo?

0 Likes

Hi.

Yes, you have the right idea.

rxData = UART_RXDATA_REG;
rxData = UART_RXDATA_REG;
rxData = UART_RXDATA_REG;
rxData = UART_RXDATA_REG;
rxData = UART_RXDATA_REG;
And ignore whatever data appears.  Do similar to UART_RXSTATUS_REG.  I'd include UART_GetRxInterruptSource() as well.

I forgot to ask.  What's the Rx fifo depth?  The default size is 4 bytes.

0 Likes
KevinE
Level 3
Level 3
10 sign-ins 10 replies posted 5 sign-ins

I am currently waiting for hardware to return from another coworker to try this out. thank you for clarifying.

in the meantime:

KevinE_0-1664310805882.png

KevinE_1-1664310824519.png

 

0 Likes

As they say "a picture says a thousand words".  Thanks for configuration images.

With a 4-byte fifo, that simplifies things.  Fewer things can go wrong.

I noticed in the ISR, the 'while' is testing stale data.  It will likely always loop back to the top of ISR, read RxStatus of null and then check if fifo_not_empty.  Then because fifo is empty, it will check fifo_not_empty one last time before exiting.  Kind'a defeats the purpose of saving ISR time (by checking for more data before leaving).

Alternatively, check UART_GetRxBufferSize(void) for more Rx data at the "while" to leave ISR if truely, fifo is empty.

Is Repeater.uart.UARTerrorStatus cleared somewhere after an error occurs?  Otherwise, when it's OR'd with new Rx Status bits, any previously stored error bits will show up again.

Is it possible the LTE module puts its Tx pin into a tri-state mode while resetting itself?  You might want to configure 5LP Rx pin input with a pull-up resistor.  Or externally, add a 4.7k-10k Ohm resistor to 5LP Rx pin.  Alternatively, configure with a pull-down resistor.  If LTE Tx pin does go tri-state, you'll receive a break condition or false Stop bit condition (STOP_ERROR).

So, after LTE module resets, 5LP doesn't even see 1 interrupt when LTE starts transmitting again?  That is really bizarre.  Makes me wonder how the two processors get through a power ON sequence and can start talking to each other in the first place.

edit: I just noticed, if there's more than 1 byte in fifo, and the ISR loops around, reading the second byte will over-write the first byte that was read since there's no buffering, only the rxdata variable.  So, you might consider removing the "do-while".  It likely works with the do-while since the ISR executes faster than another byte can be received.  But, over-writing is a possibility.  Something to think about.

0 Likes

Your comment about UARTerrorStatus got me thinking so I started to tinker around with that.

I arrived at the following cut down ISR routine and the issue appears to be resolved.

I think the main thing that fixed it was commenting the conditional at line 160.

But this means the ISR is now firing, which is wasn't before...unsure of what changed on that front, trying to understand that.

I need to go back and understand the condition that causes UARTerrorStatus to be set in such a way where it is not equal to 0, but wanted to update this as soon as possible.

I also took your advice on the do while, because I am only reading one byte, it doesn't make sense to loop through the rest of the fifo.

 

Thank you for all your support - it truly helped me

 

KevinE_1-1664393746707.png

 

0 Likes

Good to hear it all worked out.

I haven't figured out a scenario to explain why removing the status test (line 160) resulted in good serial communication.  That said, I have never had success with mask AND's/OR's in an IF statement.  So, I do the masking logic before hitting the IF using a temp place holder.

int temp = maskbit0 | maskbit 4|etc...  ;
if (temp != 0u)

So, if you disassemble in debug mode (or look at listing file) associated with ISR and follow the assembler logic, you might discover line 150 (and possibly line 153) did not perform the logic equation you expected.  It drove me nuts debugging this.  My solution was to use the "temp", then it all worked as designed.

Good luck with your project.  Sounds like an interesting one.

0 Likes