Snooze: Calling a function on a pin interrupt?

Status
Not open for further replies.
I'm missing something basic here. The attachInterrupt feature lets you specify a function to call when the interrupt is triggered:
Code:
pinMode(21, INPUT_PULLUP);
attachInterrupt(21, [B]ISR_Function[/B], FALLING);

The Snooze library combines attachInterrupt into one line with pinMode, but it doesn't let you define a function to call:
Code:
digital.pinMode(21, INPUT_PULLUP, FALLING);

Can someone tell me what I'm missing?
Sorry for absence, but a extended family member has covid so I'm dealing with that now.

This was a bad attempt at trying to explain how the internal function of the Low Power mode wakeup for Digital Pins works and not how you go about using it. To wakeup from sleep, deepSleep or hibernate on Teensy 3.2 you do not attach your own callback function. (It should work with already attached callbacks though, it just won't use them during wakeups.) Since Snooze reuses the same interrupt function for all wakeups, providing a callback for the user is not recommended because of race conditions that can occur if the code in the wakeup ISR is not done right and I do not want to provide support for all the ways a person could screw it up. Also there is differences in how you configure everything between sleep and deepSleep and hibernate that further would confuse the user so I hide most of the complex code from the user to make Snooze usable for beginners. I'll update Snooze to make this clear since I see why you would think there is a callback you could attach to the wakeup.

While saying that I have thought about opening up the internals for an "Advanced" use cases where you would be able to configure the wakeups however you want and provide only the glue to the actual mcu sleep code. This would be to let you do what you want but then I think it will be a major headache because I don't want to debug everyones implementation of their wakeup code so most likely that will be far off if ever I get to it.
 
So the interrupt control code monitoring for digital.pinMode() during sleep is still fully active after snooze returns?

Would it be easy enough to just register a myCallBack() for when snooze is awake and pass events back to running sketch in some fashion when it is triggered after wake?

Would have to have one per pin or a way to indicate the pin and perhaps the interrupt transition type and if the goal of the sketch - as here - is to just get back to sleep ASAP there could be interrupts racing during the intended transition to snooze. Or maybe just a single callback that says 'ask snooze about the interrupt' and provide a function to call similar to :: who = Snooze.deepSleep( config_teensy32 ); // return module that woke processor
It would not be a sleep request - but a what just happened call : Snooze.PinISR(). Of course that could be complicated by having to queue up multiple interrupts as one or more could happen at once or during processing between calls to Snooze.PinISR()
Also if the myCallBack was registered and .deepSleep() was requested - maybe it should immediately return and not go to sleep if there are pending interrupts based on the above - or instead of???
 
So the interrupt control code monitoring for digital.pinMode() during sleep is still fully active after snooze returns?

Would it be easy enough to just register a myCallBack() for when snooze is awake and pass events back to running sketch in some fashion when it is triggered after wake?
Yes that's how it should work, your attached callback should work as normal after waking up and returned to the users code. So you should only have to call attachInterrupt only once in the setup function and thats it.
 
While saying that I have thought about opening up the internals for an "Advanced" use cases where you would be able to configure the wakeups however you want and provide only the glue to the actual mcu sleep code. This would be to let you do what you want but then I think it will be a major headache because I don't want to debug everyones implementation of their wakeup code so most likely that will be far off if ever I get to it.
To answer my own question I do already have something for this as with the example SkeletonDriverClass in which you could rewrite any of the Drivers to better match what you are trying to do and use it like any other driver. Just make sure you name it something that doesn't conflict with any other driver names. But again I'm not trying to debug everyones attempt to do this so I will help but will not rewrite anything and will not do any extensive testing, that will be up to the user and she/he should have good grasp of how the low power subsystem works for whatever Teensy she/he is working with. This requires an thorough reading of the ref manual.
 
Thanks for the thoughtful responses duff and defragster! Duff, I really hope all is well on the homefront. Thanks for taking the time to respond.

... Would it be easy enough to just register a myCallBack() for when snooze is awake and pass events back to running sketch in some fashion when it is triggered after wake? ...

If I could repeat it back:
* When a pin wakes the processor, it doesn't trigger the attachInterrupt callback. It instead jumps to the loop to read the 'who' variable and do it's thing.
* While awake, pin interrupts will process callbacks as expected.

So, if I do the following, it should cover me:
* Define the attachInterrupt callback as I normally would.
Code:
pinMode(22, INPUT_PULLUP);
attachInterrupt(22, myCallBack, FALLING);

* Add the same callback to the 'if (who == 22)'
Code:
  if (who == 22) { 
    myCallBack();
  }

Does that sound correct?

Question for housekeeping: Does the who variable get reset when Snoozing? I'm trying to determine if a "who = 0;" at the end of the loop is needed.
 
* When a pin wakes the processor, it doesn't trigger the attachInterrupt callback. It instead jumps to the loop to read the 'who' variable and do it's thing.
* While awake, pin interrupts will process callbacks as expected.

So, if I do the following, it should cover me:
* Define the attachInterrupt callback as I normally would.
Code:
pinMode(22, INPUT_PULLUP);
attachInterrupt(22, myCallBack, FALLING);

* Add the same callback to the 'if (who == 22)'
Code:
  if (who == 22) { 
    myCallBack();
  }

Does that sound correct?
Yes you can do this but realize that as soon as the Teensy wakes up your attachInterrupt callback interrupt is activated again and your callback function could be called by that interrupt anytime even if you are manually calling that callback function in user code. I would disable interrupts before calling that callback function and re-enable them after.

Question for housekeeping: Does the who variable get reset when Snoozing? I'm trying to determine if a "who = 0;" at the end of the loop is needed.
Yes, whenever you call sleep, deepSleep, hibernate it will return the latest wakeup unit being either the PIN number or the Module number i.e. timer, rtc, etc. This will show up on the "who" variable or whatever you want to call it. Internally this comes from the "wakeup_source" variable in hal.c. Sorry for convoluted answer here hope it makes sense? So no it should not be needed.

I do have plans to add a failed sleep code to the wakeup source but it is not currently in the latest code on GitHub.
 
Thanks duff. Sorry for dragging this out... life, you know?

Another question if I may. After a wakeup, how/when does the Teensy actually go back to sleep? If Snooze wakes up on pin 22, does the Teensy go back to sleep immediately after processing whatever routines are in the "if(who==22)" section of the sketch? Is there a delay before that happens?

Reason for asking: When pin 22 gets triggered at 1hz, and the alarm goes off every three seconds, everything appears to work. If I increase the trigger speed to 4hz (for example) the alarm never goes off. I assume that's because the Teensy is still awake from pin 22, but that routine only increments a counter, so it's about as brief an interrupt as you can imagine.

For what it's worth, I'm generating these triggers with a separate Teensy/2N3904, so it's not a question of things being synchronized.
 
Thanks duff. Sorry for dragging this out... life, you know?
Ya I know it seems to get harder not easier now a days...

Another question if I may. After a wakeup, how/when does the Teensy actually go back to sleep? If Snooze wakes up on pin 22, does the Teensy go back to sleep immediately after processing whatever routines are in the "if(who==22)" section of the sketch? Is there a delay before that happens?
It will only go back to sleep when you call any of the Snooze sleep functions, i.e. "sleep", "deepSleep" or "hibernate". There are some house keeping to get out of sleep mode that is handled by the library so it will have some latency from when it wakes until you get to your code.

Reason for asking: When pin 22 gets triggered at 1hz, and the alarm goes off every three seconds, everything appears to work. If I increase the trigger speed to 4hz (for example) the alarm never goes off. I assume that's because the Teensy is still awake from pin 22, but that routine only increments a counter, so it's about as brief an interrupt as you can imagine.

For what it's worth, I'm generating these triggers with a separate Teensy/2N3904, so it's not a question of things being synchronized.
Can you post a simplified version of what you are doing that doesn't need any special hardware?
 
Status
Not open for further replies.
Back
Top