View previous topic :: View next topic |
Author |
Message |
s_g_robertson
Joined: 21 Mar 2005 Posts: 7
|
Interrupt flag not being cleared on 18F452 |
Posted: Mon Mar 21, 2005 7:16 am |
|
|
I'm having a problem with an application using the USART on the 18F452. The problem is that the RCIF flag is not being cleared either by the getc() function or by the complier generated
BCF F9E.5
instruction at the end of the ISR. I can step through the code using a Microchip ICD2 and these lines of assembly are stepped through but they seeme to have no effect on the PIR1 register. What is more puzzling is that the application can run for a few hours with the flag being cleared as intended. Any suggestions?
Stephen |
|
|
bluetooth
Joined: 08 Jan 2005 Posts: 74
|
|
Posted: Mon Mar 21, 2005 7:30 am |
|
|
Are you specifying the ERRORS option in your #USE RS-232?
Sounds like FERR or OERR is not being tested/handled to me.... |
|
|
s_g_robertson
Joined: 21 Mar 2005 Posts: 7
|
|
Posted: Mon Mar 21, 2005 7:50 am |
|
|
Yes I do have ERRORS in my #use. I've checked that a few times to make really sure!! I have managed to step through the code when it is running and observed the FERR and OERR flags being cleared.
Stephen. |
|
|
bluetooth
Joined: 08 Jan 2005 Posts: 74
|
|
Posted: Mon Mar 21, 2005 7:57 am |
|
|
Stephen:
When it locks up (not clearing RCIF), are FERR and/or OERR set? |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 21, 2005 7:59 am |
|
|
Is there any way the interrupt routine could bypass the getc?.
The 'error clearing' function, only happens when getc is actually called. Hence if the code in the interrupt handler can decide not to call getc, the system can get into the hung up state.
Post the code from your ISR.
Best Wishes |
|
|
s_g_robertson
Joined: 21 Mar 2005 Posts: 7
|
|
Posted: Mon Mar 21, 2005 8:16 am |
|
|
Thanks for your reply. Apologies for the state of the code. It is a horrendous function so I have tried to strip out as much as possible to make it slighlty more readable.
The one thing I have noticed is that my switch(mode) does not have a default case so i suppose in some way that might muck things up.
What puzzles me though is that I can watch the debugger step through the assembler for the getc generated by the compiler when the system is in a fault condition and the flag is not cleared, but if I run it now and step through the same lines of code it works exactly as I would expect.
Stephen
Code: |
//******************************* RS232 Rx Buffer ISR ******************************/
/*There are three modes:
DownloadMode - In this mode the loopback has been deteceted and we are communicating directly with a PC
NormalMode - In this mode we are communicating with the modem. This has multiple states
INIT - Setting up the mode
IDLE - Waiting on incoming call
WAITING - Answered a call and waiting on a command
SENDING - Sending data.
GPSMode - In this mode we are communicating with the GPS and parsing/validating the message received.
*/
#INT_RDA
void RS232_RX_ISR()
{
int8 ch =0;
static char key;
static int1 i1_GPSMessageReceived;
char IDSTRING[6] ="GPRMC";
static int8 GPSRxStringPosition;
static int8 field ;
static int8 IDPos ;
static int1 IDValid;
char ch2;
int8 dummy=0;
switch (mode)
{
case DownloadMode:
{
ch=getc();
if (ch ==XON)
{
FlowControl = GO;
}
else if (ch ==XOFF)
{
FlowControl = STOP;
}
else if (ch == 0x0d)
{
InputBuffer[InputBufferCount] = ch;
switch (InputBuffer[0] )
{
[SNIP]
}
InputBufferCount =0;
}
else
{
InputBuffer[InputBufferCount++] = ch;
}
break;
}
case NormalMode:
{
ch=getc();
switch(ModemMode)
{
case MODEMINIT:
{
}
case IDLE:
{
[SNIP]
}
case WAITING:
{
timeoutcount =0;//reset timer. If this timer interrupts then time out and go back and re-initialise modem.
if(ch == '3')
{
//Line dropped
ModemMode = MODEMINIT;
break;
}
switch(RXState)
{
case Reset:
{
if (ch == 0x05)//ENQ)
{
RXState = FoundENQ;
InputBufferCount =1;
}
break;
}
case FoundENQ:
{
}
}
break;
}
case SENDING:
{
switch(ch)
{
}
break;
}
}
break;
}
case GPSMode:
{
ch=getc();
switch(ch)
[snip]
switch(field)
{
// switch(field)
skip:;
if(i1_GPSMessageReceived == TRUE) // If we have a complete message
{
[SNIP]
}
break;
}//case GPSMode
}//switch(mode)
}//ISR function
|
|
|
|
s_g_robertson
Joined: 21 Mar 2005 Posts: 7
|
|
Posted: Mon Mar 21, 2005 8:17 am |
|
|
bluetooth wrote: | Stephen:
When it locks up (not clearing RCIF), are FERR and/or OERR set? |
I am not certain but I think so.
Stephen. |
|
|
bluetooth
Joined: 08 Jan 2005 Posts: 74
|
|
Posted: Mon Mar 21, 2005 8:21 am |
|
|
Try moving the getc() to the beginning of the ISR - or add the default.
After some thought, the FERR and OERR might have been set by new chars coming after the error occurs...
Also, interrupt debugging with the ICD2 is problematic - you need an ICE to do that effectively. Good news is, I don't think you need that here!
Last edited by bluetooth on Mon Mar 21, 2005 8:21 am; edited 1 time in total |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 21, 2005 8:21 am |
|
|
Make one major change. Read the character outside the switch statement.
As it stands, the case 'sending', will cause problems. If there has been a receive interrupt, there _is_ a character to receive. In the sending state, you do not read this, and if a couple of characters arrive, the OERR flag will be set, and not cleared...
Make it a general layout for receive ISR's
read the character
decide what to do with it (ignore if required).
Best Wishes |
|
|
s_g_robertson
Joined: 21 Mar 2005 Posts: 7
|
|
Posted: Mon Mar 21, 2005 8:28 am |
|
|
I take your point about moving the getc, I don't actually know why I have that layout, I think there was a reason way back in the mists of time!
Though the top level switch of the ISR has three case's Normal, Download, or GPS. The sending case is within the normal case which has a getc at the start of it. Although itis entirely possible that I can't see a problem because I have been staring at it for too long.
Stephen |
|
|
bluetooth
Joined: 08 Jan 2005 Posts: 74
|
|
Posted: Mon Mar 21, 2005 8:32 am |
|
|
Stephen:
If "mode" never gets scrogged, the getc() will be called... but if something *did* happen to "mode", this is the problem you would see.
So, the odds are good that if you move the getc() outside the switch, this problem will go away.
But you still may want to find out what was happening to "mode". Could you tell us if it was valid when you are in the lockup state? |
|
|
s_g_robertson
Joined: 21 Mar 2005 Posts: 7
|
|
Posted: Mon Mar 21, 2005 8:34 am |
|
|
bluetooth wrote: | Try moving the getc() to the beginning of the ISR - or add the default.
After some thought, the FERR and OERR might have been set by new chars coming after the error occurs...
Also, interrupt debugging with the ICD2 is problematic - you need an ICE to do that effectively. Good news is, I don't think you need that here! |
I was very suspicious of using the ICD for that very reason. I do still get the problem if I run it without the ICD, but I may not be seeing the real problem when I use the debugger.
I think I will implement both of those suggestions, both should improve things at least.
Stephen |
|
|
s_g_robertson
Joined: 21 Mar 2005 Posts: 7
|
|
Posted: Mon Mar 21, 2005 8:41 am |
|
|
bluetooth wrote: | Stephen:
If "mode" never gets scrogged, the getc() will be called... but if something *did* happen to "mode", this is the problem you would see.
So, the odds are good that if you move the getc() outside the switch, this problem will go away.
But you still may want to find out what was happening to "mode". Could you tell us if it was valid when you are in the lockup state? |
The short and honest answer is not for certain. I seem to remember that I was suspicious of mode being invalid at the time, Friday, but that seems like a long time ago.
I've made the changes that you both suggested and will now have to let it run and hope the problem goes away. Slightly worrying if something is messing up the mode variable though, need to keep an eye on that as well.
Thank you both very much for your prompt and constructive help. It's much appreciated.
Stephen. |
|
|
bluetooth
Joined: 08 Jan 2005 Posts: 74
|
|
Posted: Mon Mar 21, 2005 8:46 am |
|
|
Stephen:
I don't think that running with the ICD would cause the problem - it's pretty much transparent when you're running. It's just not effective for certain kinds of interrupt debugging.
Sounds like you're on the right track. Please be sure to let us know what you find! |
|
|
|