13 Replies Latest reply on Dec 5, 2014 7:37 AM by user_14586677

    Recovering from UART error

    user_343349849

       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

        • 1. Re: Recovering from UART error
          user_343349849

           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;

             

                   }

             

              }

             

          }

          • 2. Re: Recovering from UART error
            user_1377889

            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

            • 3. Re: Recovering from UART error
              user_343349849

               Thanks Bob,

                 

              How do we handle this?

              • 4. Re: Recovering from UART error
                devendra.gajjar
                        is there any method to clear interrupt bit after interrupt subroutine???   
                • 5. Re: Recovering from UART error
                  user_1377889

                  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

                  • 6. Re: Recovering from UART error
                    user_343349849

                     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?

                    • 7. Re: Recovering from UART error
                      devendra.gajjar

                      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[a]=UART_1_cReadChar();   
                                  //UART_1_PutChar(cUARTData1[a]);   
                                   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;    
                         
                         
                             }   
                      • 8. Re: Recovering from UART error
                        user_1377889

                        @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
                         

                        • 9. Re: Recovering from UART error
                          user_343349849

                           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.

                          • 10. Re: Recovering from UART error
                            user_1377889

                            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

                            • 11. Re: Recovering from UART error
                              user_343349849

                               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.

                              • 12. Re: Recovering from UART error
                                user_1377889

                                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

                                • 13. Re: Recovering from UART error
                                  user_14586677

                                  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.