Recovering from UART error

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

cross mob
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 I have an application that is polling a remote device for data. The polling device needs to be able to determine when the remote unit is responding or not.

   

At the moment I have an error count that increments each time the poll is not responded to and when count is exceeded the operator gets a warning. If the remote unit starts to respond again then operator gets indication that remote unit is ok.

   

During testing, I remove the cable to remote unit and get the warning. However, when reconnecting Somethings the system detects the device available and gives notice but often it does not and the code appears to stop responding. As the "Pause" function does not work when this happens, I cannot look at the call stack to see where it s.

   

What I am doing after loss of remote reposnse is to stop and restart the UART component. I don't think this is the best approach and cannot find a clear tutorial regarding recovering from UART errors.

   

Is there a status I can read and reset the flags after error detected so the UART can recover after hardware fault (serial lines being disconnected and reconnected)

   

 

   

Thanks

0 Likes
13 Replies
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 I have managed to get it running but not sure if I have capruted the errors properly. When my code detects no response from the remote unit I do this

   

RS485_Stop();

   

CyDelay(500);

   

RS485_Start();

   

I also reset the circular buffer

   

The RX interrupt looks like this...

   

CY_ISR(COM_INT){ 

   

    uint8 rec_status;

   

    rec_status = RS485_RXSTATUS_REG;

   

     if(!(rec_status & RS485_RX_STS_STOP_ERROR)&&!(rec_status & RS485_RX_STS_OVERRUN)){

   

         Next_Head = (Head_Ptr + 1) % COMBUFSIZE;

   

         if(Next_Head != Tail_Ptr){

   

           In_Buf[Head_Ptr] = RS485_GetByte();

   

           Head_Ptr = Next_Head;

   

         }

   

    }

   

}

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

In your interrupt handler which you enter when something has happened you only read-off a received byte when there was no error. So in case of an error (which is likely to happen when the connection is opened) the byte stays in the receiver and the interrupt is not cleared. This can be an infinite loop; when the handler exits, the interrupt still exists and will be handled again and again...

   

 

   

Bob

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 Thanks Bob,

   

How do we handle this?

0 Likes
Anonymous
Not applicable
        is there any method to clear interrupt bit after interrupt subroutine???   
0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

The interrupt gets cleared when

   

The status is red

   

AND

   

The receive buffer is red (RS485_GetByte();)

   

So you should read the byte in any case and decide later whether to store it in your buffer.

   

 

   

Bob

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 Hey Bob,

   

Does that mean my Interrupt code should be rearranged like this...

   

CY_ISR(COM_INT){ 

   

    uint8 rec_status;

   

    uint8 rec_data;

   

 

   

    rec_status = RS485_RXSTATUS_REG;

   

    rec_data = RS485_GetByte();

   

 

   

     if(!(rec_status & RS485_RX_STS_STOP_ERROR)&&!(rec_status & RS485_RX_STS_OVERRUN)){

   

         Next_Head = (Head_Ptr + 1) % COMBUFSIZE;

   

         if(Next_Head != Tail_Ptr){

   

           In_Buf[Head_Ptr] = rec_data;

   

           Head_Ptr = Next_Head;

   

         }

   

    }

   

}

   

 

   

I assume I can ignore parity errors if parity is OFF.

   

 

   

Finally, do I have to set the RX INT on the component on the worksheet for STOP Error and OVER run?

   

 

   

I also assume we don't need to worry about BREAK as this is not a fault?

0 Likes
Anonymous
Not applicable

here is my code

   

i am trying to get 32byte data from uart using intrrupt  but its not working.. 

   

when i sent 32 byte train ,iintrupt is  trigred but its not storing data

   

but while intrupt is trigrred i sent it again data stored ..

   

and it is also returning from subroutine but it again goes to intrupt subroutine

   

 

   

 

   

unsigned char cUARTData1[31];

   

 

   

void main(void)
{UART_1_Start(UART_PARITY_NONE);
 

   

start:
UART_1_CPutString("\r\nSTART\r\n");
a=0;x=0;
UART_1_IntCntl(UART_1_ENABLE_RX_INT);
while(!x);
goto start;

   

}

void UART_1_RX_ISR_C(void)   
{UART_1_IntCntl(UART_1_DISABLE_RX_INT);   
 UART_1_CPutString("\r\n*I*\r\n");   
    
             a=0;   
        rpt:        
         if(UART_1_bReadRxStatus() & UART_1_RX_COMPLETE )//if (UART_1_bCmdCheck())   
             {   
            cUARTData1=UART_1_cReadChar();   
            //UART_1_PutChar(cUARTData1);   
             a++;   
             LED_4_Switch(0x01);   
            }   
            if(a<32){goto rpt;}   
              
 UART_1_PutChar(cUARTData1[0]);   
UART_1_PutChar(cUARTData1[1]);   
UART_1_PutChar(cUARTData1[2]);   
UART_1_PutChar(cUARTData1[3]);   
UART_1_PutChar(cUARTData1[4]);   
UART_1_PutChar(cUARTData1[5]);   
UART_1_PutChar(cUARTData1[6]);   
UART_1_PutChar(cUARTData1[7]);   
UART_1_PutChar(cUARTData1[8]);   
UART_1_PutChar(cUARTData1[9]);   
UART_1_PutChar(cUARTData1[10]);   
UART_1_PutChar(cUARTData1[11]);   
UART_1_PutChar(cUARTData1[12]);   
UART_1_PutChar(cUARTData1[13]);   
UART_1_PutChar(cUARTData1[14]);   
UART_1_PutChar(cUARTData1[15]);   
UART_1_PutChar(cUARTData1[16]);   
UART_1_PutChar(cUARTData1[17]);   
UART_1_PutChar(cUARTData1[18]);   
UART_1_PutChar(cUARTData1[19]);   
UART_1_PutChar(cUARTData1[20]);   
UART_1_PutChar(cUARTData1[21]);   
UART_1_PutChar(cUARTData1[22]);   
UART_1_PutChar(cUARTData1[23]);   
UART_1_PutChar(cUARTData1[24]);   
UART_1_PutChar(cUARTData1[25]);   
UART_1_PutChar(cUARTData1[26]);   
UART_1_PutChar(cUARTData1[27]);   
UART_1_PutChar(cUARTData1[28]);   
UART_1_PutChar(cUARTData1[29]);   
UART_1_PutChar(cUARTData1[30]);   
UART_1_PutChar(cUARTData1[31]);   
   
        x=1;   
return;    
   
   
       }   
0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

@devo36

   

Please do not hijack a thread from sombody else, you may always start a new thread with a new headline, so every member of this forum is able to consider to answer to that query.

   

Congratulations! This is the very first time I found a "goto" statement in the code snippets presented here.

   

Sending a character via UART will use a blocking function which is an absolute no-go in an interrupt handler. When you describe a bit more what you intend to do (and why) and when you post your complete project with all of your settings we will be able to help you much better. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.



Bob
 

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 Bob,

   

I wondered what was happening as I received a "reply" to my post and it was not replated to our discussion.

   

Does the last bit of code I posted look ok?

   

ie. 

   

Read data into a variable,

   

Check that no overrun or stop error occurred

   

If not then place byte into the circular buffer (gets processed later in main loop)

   

My code appears to be running but not sure if there is still a hidden "gotcha" where it has potential to lock up when serial port cable removed and re-connected.

   

It seems also, that my code only works if I actually stop and restart the UART once a non-response from remote unit is detected.

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

Sorry, but I thought it was obvious that your code now reflects exactly what I suggested. Make sure that your head-pointer is defined volatile.

   

 

   

Bob

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 Bob,

   

OK, I see. Thanks.

   

I have almost all the code in the projects running now (Bluetooth, RS485, SPI routines for clock and FRAM, EEPROM storage) just working on the USB-UART and the PT100 thermal project (had to order new batch of chips as the 099 variant of 5LP did not have the 20 bit ADC, but the 096 variant does.

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

There is an Application note concerning layout for min noise. Let me see if I can find it...

   

Found: here it is www.cypress.com/

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

I have some additional info on PCB layout and signal integrity, cannot

   

seem to post the zip file, if you want it post your email address.

   

 

   

Regarding ISR's, generally speaking you want to minimize f() calls as that

   

results in a lot of stack push and robs MIPs, adds to latency. Best way is to

   

set a flag, exit, and process in main() the ISR handling.

   

 

   

Regards, Dana.

0 Likes