CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

RS232 Errors not working

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JerryR



Joined: 07 Feb 2008
Posts: 164

View user's profile Send private message

RS232 Errors not working
PostPosted: Fri Apr 04, 2008 3:12 pm     Reply with quote

We're using a PIC18F4525, v3.249 PCWH

Even though we have used the Errors in the USE rs(232) below. we are not able to clear an int _rda lockup problem. We understand that if a rx buffer overflow problem occurs subsequent interrupts from int_rda are discontinued. However, we believe that the use of the ERRORS in the use232 statement would reset the overflow issue allowing continued int_rda action.

Is this true?

Code showing use of Errors option

Code:

#include <18F4525.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT

#use delay(clock=10000000)

#use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, ERRORS, stream=GPS)

#use rs232(baud=4800, xmit=PIN_D7, rcv=PIN_D6,stream=PC)
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Fri Apr 04, 2008 3:22 pm     Reply with quote

Kind of right.
Quote:
if a rx buffer overflow

no its when your interupt doesn't get the data from the usart (RCREG) fast enough. I normally think of a buffer as something I set
up in firmware
eg: the RX_BUF below..
Code:
//=======================RXisr============================//
//Takes RX data from a stream and puts it into a buffer via interrupts
#INT_RDA
void RXisr(void)
{
  idle_bus=FALSE;
  set_timer1(Timer1_Initial_Value);
  RX_BUF[rx_indx]=RCREG;
  rx_indx++;
  if (rx_indx==MAXHEADER+MAXDATA+1) // check for buffer overflow
  {
    bit_set(ERRORS,2);//set error flag bit 2 for RXbuffer overflow
  }
  if (OERR)
  {
    bit_set(ERRORS,0);//set error flag bit 0 for USART overflow
    CREN = 0;
    CREN = 1;
  }
}

but errors is to allow for clearing the USART overflow error.
18.2.2 page 215 item 9 of the 18F4525.pdf
Ttelmah
Guest







PostPosted: Fri Apr 04, 2008 3:33 pm     Reply with quote

'ERRORS' will clear the error, but _only when a character is read_.
If you come into an interrupt, and the service time is slow enough that the error triggers between reading the character at the start of the routine, and exiting the routine, the interrupt, won't trigger again, and the UART will still be hung.
If you re-code the interrupt handler like:
Code:

#INT_RDA noclear
void int_handler(void) {
    int temp;
    do {
         temp=getc();
         clear_interrupts(INT_RDA);
         //store your character here
     } while(kbhit());
}

The ERRORS problem should disappear.
Treitmey's solution can still give the same problem, if data is arriving really fast, and the loop time into the handler is long, but it will massively reduce the likelyhood of this happening (there are only a couple of instruction times in the entire loop, where it can occur).
The most likely cause of problems in all cases, is a interrupt routine that is much slower than it should be...

Best Wishes
KU5D



Joined: 10 Feb 2008
Posts: 46
Location: Asheville, North Carolina

View user's profile Send private message

PostPosted: Sun Apr 06, 2008 8:01 pm     Reply with quote

What if we want to hold off on the hardware usart and do other things? We can go without data from the port for a few seconds, but even if we disable the INT_RDA, if a character hits the port and we don't read it, it hangs the port and the interrupt no longer fires. I've tried something cheesy like:

char junk;
if(kbhit(thatPort)) { junk = getc(thatPort); }

That doesn't work since the event has long since past...seems once the buffer is full, life is over. I don't want to directly call getc in case there's nothing connected to the port...that'd hang us forever as well.

Is there a way to clear the buffer if we find it full when we get to it?
_________________
Confidence is the feeling you have right before you fully understand the situation...
Ttelmah
Guest







PostPosted: Mon Apr 07, 2008 4:01 am     Reply with quote

What you post should clear the error, but would need to be in the 'main', before you re-enable the interrupt.
However, Treitmey's solution is also good:
Code:

#byte RCSTA=0xFAB
#bit CREN=RCSTA.4
#byte INTCON=0xFF2
#bit RBIF=INTCON.0
#byte RCREG=0xFAD

void restart_RS232() {
    int8 temp;
    CREN=false; //turn off the UART
    while (RBIF) temp=RCREG; //ensure buffer is flushed
    CREN=true;  //re-enable the receive - clears the error
    enable_interrupts(INT_RXD);
}

This will clear both overrun errors, and framing errors, then re-enable the interrupts.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group