View previous topic :: View next topic |
Author |
Message |
DaveKush Guest
|
lockups when using delays in the main loop w/ I2C bus |
Posted: Tue Jan 10, 2006 6:01 pm |
|
|
I'm experiencing consistent lockups when I use any type of delay or printf command inside the main while loop. The I2C interrupt routine is active, and this seems to be the source of the problems. It is looking like the program never returns correctly after servicing the I2C interrupt . The code model looks like this:
while (1) {
//An I2C transaction happens here
if (I2C_byte == 1) {
delay_ms(500);
//lockup happens here like the I2C never interrupt never returned correctly
}
}
Any ideas guys?
Dave |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 10, 2006 6:09 pm |
|
|
Are you using any CCS delay function inside your isr ? |
|
|
Dave Kush Guest
|
lockups when using delays in the main loop w/ I2C bus |
Posted: Tue Jan 10, 2006 6:11 pm |
|
|
No delays in the I2C interrupt handler, just the main loop. I configured I2C manually because the CCS routines didn't seem to work with the PIC18f6585. Everything works great with the I2C both directions unless I have a pause in the main loop. Weird, yes.
Dave |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 10, 2006 6:14 pm |
|
|
The implication is that the delay routine is disabling global interrupts.
Do you have a CCS delay routine inside any isr (not just the i2c isr) ? |
|
|
DaveKush
Joined: 10 Jan 2006 Posts: 6
|
lockups when using delays in the main loop w/ I2C bus |
Posted: Tue Jan 10, 2006 6:27 pm |
|
|
Yes, I do have a delay in another external interrupt to handle a switch debounce, but the problem persists even if I never touch the switch.
Dave |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 10, 2006 6:47 pm |
|
|
If you have compiler warnings enabled (in MPLAB Project/Build Options),
you will see a message like this:
Quote: | Line 29(0,1): Interrupts disabled during call to prevent re-entrancy: (@delay_ms1) |
This means the compiler has added code to turn off interrupts
during the call to delay_ms(500) in main().
To avoid this problem, you can create a 2nd instance of the CCS
library code for delay_ms(). To do this, you just add another
#use delay() statement after your isr. Add the line shown in
bold, below. Because there are now two instances of the code,
the compiler doesn't have to disable interrupts, and you won't see
that warning message.
Quote: | #include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#INT_EXT
void int_ext_isr(void)
{
delay_ms(1);
}
#use delay(clock=4000000)
//=====================================
void main()
{
delay_ms(500);
while(1);
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 11, 2006 12:59 am |
|
|
quote]I do have a delay in another external interrupt to handle a switch debounce.
[/quote]
One additional comment:
There are no nested interrupts. So if you have a delay in your INT_EXT
isr, you will lock out all of your i2c interrupts for the duration of that
delay and until you exit the isr.
Suppose you're running i2c at 100 KHz. Then at 10 bits/char, you could
get interrupted at roughly a 10 KHz rate. That's once every 100 us.
If your debounce delay in the isr lasts 1 ms, or 10 ms, you'll miss
large numbers of i2c interrupts. So I think you have to do your
debounce in a different way.
One way might be to start a timer in the INT_EXT isr. (and disable further
INT_EXT interrupts). Setup the timer so that it will roll over and cause a
timer interrupt in 10 ms. This is your debounce delay. Then handle the
key press in the timer isr. Then clear the INT_EXT interrupt flag and
and re-enable INT_EXT interrupts. Also disable the timer. |
|
|
DaveKush
Joined: 10 Jan 2006 Posts: 6
|
|
Posted: Wed Jan 11, 2006 10:31 am |
|
|
Thanks for the suggestions PCM Programmer. I can't seem to get those warnings turned on in the compiler though. The switches I'm using are: +DF +LN +T -A +M +Z +Y=9 +EA +EW +FH but I still see no warnings like you mentioned.
On a side note, is there any docs that show which subroutine calls cause interrupts to be disabled with the CCS compiler? My code is getting complicated enough where this would now be helpful.
Dave |
|
|
DaveKush
Joined: 10 Jan 2006 Posts: 6
|
|
Posted: Wed Jan 11, 2006 11:08 am |
|
|
Looks like I figured it out. Apparently the SSP interrupt wasn't being cleared correctly right before the call to the printf or delay. I inserted a clear_interrupt(INT_SSP) and this fixed the problem. I'm guessing that my interrupt handler isn't working correctly though. Time to dig into that.
Dave |
|
|
|