View previous topic :: View next topic |
Author |
Message |
zonemikel
Joined: 13 Oct 2007 Posts: 53 Location: Texas
|
Can interrupts be interrupted ? Is there a workaround ? |
Posted: Tue Jul 13, 2010 8:51 am |
|
|
Basically I'm using a rcr and rct 433 mhz transmitter from radiotronix. The receiver is getting tons of garbage so I'm filtering it out by scanning the input for a "id" or "preamble" before I actually process the input.
I have a interrupt set to fire when i receive transmission on the pic. This checks the first two chars coming in to see if they match the "id" if so it processes the third char as valid info.
My dilemma is that if it receives the first correct char in the "id" it will hang and wait for the next char. So in the odd quinkydink that another char does not come in quickly this will cause the unit to hang while waiting for the next char to come in.
The solution I came up with was to use a timer1 based interrupt that fires every .52 seconds and basically stops all motors and resets the interrupts, so the pic will go back to other processing instead of waiting. And since the rda interrupt resets the timer1 timer, the timer1 interrupt should not be called unless there is no valid input for .52sec. I dont think the timer1 interrupt is able to interrupt the rda interrupt.
I'm using a 4Mhz internal and a pic 887. I calculated .52sec by (1/4e6)*8*2^16=.52
So my question(s) are these
1.) can one interrupt interrupt another
2.) where will processing return when leaving a interrupt ? (eg. where will pc point to, where it was b4 going into the int?)
Here is some code too look at
Code: |
// timers, these should be close to ints because they are related !!
setup_spi(SPI_SS_DISABLED); // not using this, yet.
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // for pwm on motors !
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 ); // int 16 bit timer to interupt
void initInits(){
// interrupts
enable_interrupts(INT_TIMER1); // enable .5sec failsafe
enable_interrupts(INT_RDA); // enable int on rx from wireless
enable_interrupts(GLOBAL); // enable ints (master switch)
}
// interupt on uart data in (somone sends data to jinx)
#int_rda
void serial_isr() {
disable_interrupts(int_rda); // stop this int
clear_interrupt(int_rda); // clear it so we can be interrupted
if(kbhit(wireless)){ // if there is a char ready
if(fgetc(wireless)==preamble[1]){ // check first char of id/preamble
if(fgetc(wireless)==preamble[1]){ // check second char
fprintf(wireless, "Rx\n\r"); // we got rx
handle(fgetc(wireless)); // process third char
}
}
}
set_timer1(0); // get in and out b4 time up !
// then reset timer
enable_interrupts(int_rda); // resetup interrupt
}
// timer1 - 8*65536*1usec = 0.52 sec <- div by 8, we get int in .52sec
#int_TIMER1
void TIMER1_isr()
{
disable_interrupts(global);
fprintf(wireless, "Timer1 Overflow\n\r"); // let them know this happened
clear_interrupt(int_timer1); // reset flag
setSpeed(0, 's'); // stop motors
initInits(); // reset all interrupts
} |
I hope to use the timer1 interrupt to kind of maintain things in case of lost transmission. This is for a mobile thing so when I stop sending it input I want it to stop moving. _________________ Smart people know how stupid they are. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Tue Jul 13, 2010 9:26 am |
|
|
First answer. No.
Unless you go to a 18 family PIC, where you can have a higher hardware priority for interrupts.
Second part. Old answer. Don't sit waiting in interrupts for things. The RDA interrupt is saying 'one character is waiting to be read'. Read just that one charcater, put it into a RAM buffer (look at ex_sisr.c) and get out of the interurpt. Then in your main code loop, use a state machine. Have this sit in state '0'. When the correct first character is seen, advance to the next state. When the second correct charcater is seen, move to the next state. You can either wait in later states, with an interrupt driven timeout, or keep doing other things till the code advances to the 'I have seen the right message' state.
Best Wishes |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
|
zonemikel
Joined: 13 Oct 2007 Posts: 53 Location: Texas
|
|
Posted: Tue Jul 13, 2010 10:54 am |
|
|
Thanks, I was looking all over the place to see if interrupts can interrupt interrupts but of course thats not really a search engine friendly term.
Ya i should just get the hell out of the int, I knew i was in there too long. I'll do the state machine like you said.
Oh and I love the lock code nice . . .
Just wondering you have the "enable tbe" interrupt commented out, did that part work ? I'm going to need transmit buffers and such also. I love your code I'll do something similar in mine, that gives me a lot of flexibility since I plan on making my own packets and sending them.
You were getting 9600bps on a wireless connection ... _________________ Smart people know how stupid they are. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Tue Jul 13, 2010 11:04 am |
|
|
The TBE interrupt is commented out because the wizard puts the enable there. Leaving it there will cause the PIC to hang because it's not handled properly. Have a look through the code and you'll find that the TBE interrupt is only enabled when you have data to send.
The 9600 baud rate was used (if I remember correctly) because the modules the guy was using used 9600. The code, as configured, is capable of any speed - but - the wireless links may not work too well at higher speeds. Start slow and work your way up until you find the limit of your wireless link. |
|
|
|