Searching \ for '[PIC] handling USART errors' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/ios.htm?key=usart
Search entire site for: 'handling USART errors'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] handling USART errors'
2007\03\30@171503 by David

flavicon
face
I am a bit confused over correct handling of Usart errors. From
searching across the net and looking through Microchip archives it seems
that
the code below is what I need to handle reception errors effectively.

Is this correct ? Basically each time an RCIF occurs the OERR and FERR
errors are checked and if no error then use the RCREG byte.

I call RFErrorFree when I initialize the USART at start of program.

Also, Do I need to check for Overrun in the main loop as I am not sure
if a interrupt will occur in the event of an overrun and if it does not
them my error checking routine would never be called and RX would hang ??

Any help much appreciated. Code example below.

char RFErrorFree(void)
{
 if(OERR2)
 {
   CREN2 = false;
   RCREG2;
   RCREG2;
   RCREG2;
   CREN2 = true;
   return false;
 }
 else if(FERR2)
 {
   RCREG2;
   return false;
 }
 else rf_char = RCREG2;
 return true;
}


// Interrupt service
if((RC2IF)&&(RC2IE))
 {
     if(RFErrorFree()) GetRF();
 }

2007\03\30@175222 by Nigel Duckworth

picon face
Hi David,

Can you read a register with just  "RCREG2;"?
(as opposed to something like Fred = RCREG2;)

We discussed this a few days ago, did the code I posted not work for you?

My 18F452 was polling a CO2 sensor module once per second over several
metres of unscreened cable using RS232. Every now and then my comms
would hang until I used the below approach and since then no problems. I
called these two functions before polling.    

if(OERR)
   {
     do{
           temp = RCREG;
           temp = RCREG;
           temp = RCREG;
           CREN = 0;
           CREN = 1;
         }while(OERR);
   }

if(FERR)
 {
   temp = RCREG;
   TXEN = 0;
   TXEN = 1;
 }
       

I suspect spurious noise on my Rx line was setting the above flags.

Regards,

Nigel




David wrote:
{Quote hidden}

2007\03\30@182252 by David

flavicon
face
Nigel,

According to Hi-Tech you don't need to assign the RECREG to anything
just referencing it will clear it. But having said that maybe I should
stay with the norm to be sure.

The problem is that the "hanging of USART" only occurs very occasionally
and otherwise all works perfectly fine so it is difficult to determine
if the error handling is working correctly.

My setup is that the data is coming from a Radio unit. The unit does not
have a squelch so random "data" is always on the port pin even when
nothing is being sent. Once transmission starts, I do get reliable data.
I use  a state machine to look for a specific header to know when the
data packet is beginning.

Do you check for errors in your main loop ? From your email I propose to
try this.... Does this look correct, or have I misinterpreted something
? (I have not shown all code but just the bits I think are relevant to
handling of the serial errors

Thanks in advance, much appreciated

//********** This code placed in Serial.c module **************

Void RFErrorFree(void)
{
if(OERR)
   {
     do{
           temp = RCREG;
           temp = RCREG;
           temp = RCREG;
           CREN = 0;
           CREN = 1;
         }while(OERR);
   }

if(FERR)
 {
   temp = RCREG;
   TXEN = 0;
   TXEN = 1;
 }
}

void GetRF(void)
{
 rf_char = RCREG2;
 switch(RF.State)
 { ...........      //other state machine code
   RF.State = IDLE; //If error during state machine processing (ie. incorrect data size, incomplete header etc)
   ...........      //other state machine code
   RF.DatainBuf = true;  // when packet complete
 }
}

//************************ This code in interrupt.c module *********************
void interrupt ISR(void)
{
 if((RC2IE)&&(RC2IF))
 {
   if(RFErrorFree()&&(!RF.DatainBuf)) GetRF(); else rf_char = RCREG2;   //If ignoring data then read RCREG to clear RCIF
 }
}

//********************** part of main loop in main.c module ********************************
void main(void)
{
 Init_Serial();   //set up UART
 RFErrorFree();   //ensure no errors in USART
 RCIE = true;     //enable serial int
 for(;;)
 {
   RFErrorFree();   //***************Not sure if this is required ???????

   if(RF.DatainBuf)
   {
     ProcessPacket();
     RF.State = IDLE;
   }
 }
}


I expect this to drop all error bytes and pass all other bytes to state machine if we have not already received a packet to be processed in main loop.
If we have received an entire packet then we set the flag so that further bytes are error checked but not passed to the state machine.



Nigel Duckworth wrote:
{Quote hidden}

2007\03\30@183720 by David

flavicon
face
Opps,

RFError() free actually returns a result.

char RFErrorFree(void)
if(OERR)
   {
     do{
           temp = RCREG;
           temp = RCREG;
           temp = RCREG;
           CREN = 0;
           CREN = 1;
         }while(OERR);
         return false;
   }

if(FERR)
 {
   temp = RCREG;
   TXEN = 0;
   TXEN = 1;
   return false;
 }
return true;
}



Nigel Duckworth wrote:
{Quote hidden}

2007\03\31@034945 by Nigel Duckworth

picon face
Hi David,

My application is different to yours because any data received outside
of my polling function is definitely noise.

To catch some noise I enable serial port interrupts in between one
second polling and discard any data received, I disable the interrupt
when I'm expecting a reply.

I don't check for framing or over-run errors in my main loop, only just
prior to sending data requests to the CO2 meter.  

Please feel free to email me off-list.

Good luck.

Nigel


David wrote:
{Quote hidden}

More... (looser matching)
- Last day of these posts
- In 2007 , 2008 only
- Today
- New search...