Buy an Axon, Axon II, or Axon Mote and build a great robot, while helping to support SoR.
0 Members and 1 Guest are viewing this topic.
attach an ISR routine "process" for external interrupt to pins A, B and Cprocess if the pin is high do some stuff clear any pending interrupts for A, B and C
void myHandler(const IOPin* io, boolean high, volatile void* data){ if(high) { // do some stuff } PCIFR = _BV(PCINT2);}TICK_COUNT appInitSoftware(TICK_COUNT loopStart){ // snip pin_change_attach(K5, &myHandler, NULL); pin_change_attach(K6, &myHandler, NULL); pin_change_attach(K7, &myHandler, NULL);}
thanks Tim, just to be sure, that means that any of those interrupts queued to fire won't execute? (Rather than just disabling the interrupt, which I dont want to do. i.e. I do want to listen for interrupts that occur after my routine has executed, just don't want to execute due to any interrupts that were queued while my routine was executing.)
what if I just wanted to clear any pending on K6 only, is there a way to do that?
Just a silly question but . . . it sounds like you expect a bunch of interrupts to get triggered all at once? Perhaps at the *exact* same time? But you only want your mcu to respond once to this event, no matter which pins were triggered?This would mean you'd need to clear all interrupts before leaving the interrupt event handling function.I don't see any way to do this in the WebbotLib manual . . .My best guess is to detach the pins within the interrupt, and then reattach after exiting the interrupt function.
When a pin change interrupt happens the registers are in groups of 8 I/O pins. ie one interrupt happens if ANY of the 8 io pins change. So in order to work out 'which' of the 8 pins has 'caused' the interrupt then I have to store the old I/O pin values (from the previous interrupt). An exclusive-or then says which pins out of the 8 have actually changed.
So you may well loose 'pin changes'
Just a silly question but . . . it sounds like you expect a bunch of interrupts to get triggered all at once? Perhaps at the *exact* same time? But you only want your mcu to respond once to this event, no matter which pins were triggered?
This would mean you'd need to clear all interrupts before leaving the interrupt event handling function.I don't see any way to do this in the WebbotLib manual . . .
My best guess is to detach the pins within the interrupt, and then reattach after exiting the interrupt function.
If your handler for K0 wanted to 'forget' about any changes on pin K6 then it could read the K6 pin and store the value in the 'lastValue' member of the PIN_CHANGE structure for K6. Your K0 handler then returns to my handler, as normal, which then tests the other bits.It should now ignore K6 as you have changed its 'remembered' value to be the new 'value' and so my handler wont think it has changed.What you may choose to do is set up the interrupts so that they all point to the handler. Your handler could then change the remembered value for all 8 pins. This way your handler would only get called once irrespective of which pin changed.
That's going to give you problems (I think).....When a pin change interrupt happens the registers are in groups of 8 I/O pins. ie one interrupt happens if ANY of the 8 io pins change. So in order to work out 'which' of the 8 pins has 'caused' the interrupt then I have to store the old I/O pin values (from the previous interrupt). An exclusive-or then says which pins out of the 8 have actually changed.So assume PINx was low, and PINy was low. If PINx goes high and causes and interrupt then I know that its coz of PINx changing. If PINy goes high at around the same time - but you have cleared the interrupt whilst processing PINx- then the lib never knows that it went high. So when PINy goes low, and causes another interrupt then the lib may get confused as it never knew that PINy was high in the first place - so it won't think PINy has actually changed.So you may well loose 'pin changes'
Quote from: Webbot on April 16, 2010, 08:10:49 PMThat's going to give you problems (I think).....When a pin change interrupt happens the registers are in groups of 8 I/O pins. ie one interrupt happens if ANY of the 8 io pins change. So in order to work out 'which' of the 8 pins has 'caused' the interrupt then I have to store the old I/O pin values (from the previous interrupt). An exclusive-or then says which pins out of the 8 have actually changed.So assume PINx was low, and PINy was low. If PINx goes high and causes and interrupt then I know that its coz of PINx changing. If PINy goes high at around the same time - but you have cleared the interrupt whilst processing PINx- then the lib never knows that it went high. So when PINy goes low, and causes another interrupt then the lib may get confused as it never knew that PINy was high in the first place - so it won't think PINy has actually changed.So you may well loose 'pin changes'Assuming PINx and PINy both trigger the same pin change interrupt, and both pins changed at the same time so the ISR for that group of pins is executed. By the time the ISR is executed, both pins have already changed. So when you capture and compare the current state of the pins with their previous states, you can always figure out which pins changed, whether it was just PINx, or both PINx and PINy. The pin change interrupt does not care whether the pins transitioned from low to high or from high to low, it only cares that a pin change occurred. So what is there to be confused about?
Quote from: Admin on April 16, 2010, 08:57:47 PMMy best guess is to detach the pins within the interrupt, and then reattach after exiting the interrupt function.I did try that actually but I think the flags for "interrupt event happened" would still get set even though the callback was dettached so when I re-attached they'd get examined and my routine would get called. ( Though my understanding could be completely skew whiff here )
When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled.The user software can write logic one to the I-bit to enable nested interrupts. All enabledinterrupts can then interrupt the current interrupt routine. The I-bit is automatically set when aReturn from Interrupt instruction – RETI – is executed.
According to page 17 of the ATmega640 datasheet,QuoteWhen an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled.The user software can write logic one to the I-bit to enable nested interrupts. All enabledinterrupts can then interrupt the current interrupt routine. The I-bit is automatically set when aReturn from Interrupt instruction – RETI – is executed.Nested interrupts must be manually enabled in your ISR. So how about not manually enabling nested interrupts, instead of manually detaching and reattaching handlers? If you are extra paranoid like me, then you can manually disable global interrupts in your ISR with the CLI instruction.