pictographer
Well-known member
In the example below, if delay() is changed to LP.delay(), I get a hang as described in the code comments below.
Paul and duff, thank you for making such wonderful stuff.
Cheers,
John
Code:
// LowPower_Teensy3 example demonstrating touch-to-wake functionality and
// a bug in the delay(uint32_t msec, uint32_t cpu).
//
// Expected behavior: When power is first applied, the built-in LED blinks once.
// When pin 0 is touched, the built-in LED blinks once follwed by a pause and
// blinks twice more.
//
// Buggy behavior: if LP.delay is used instead of delay, the power-on blink occurs,
// however, the first time pin 0 is touched, only one bink occurs and the device becomes
// unresponsive.
//
// Tested with Mac OSX 10.9.4, Arduino 1.0.5, Teensyduino 1.20-rc1 using the
// master branch of the LowPower_Teensy3 Library obtained July 31, 2014.
//
// Note: It is necessary to press the reset button to download new binaries
// while running this example.
//
// John D. Corbett
// corbett@pictographer.com
// August 3, 2014
#include <LowPower_Teensy3.h>
TEENSY3_LP LP = TEENSY3_LP();
sleep_block_t LP_config;
//XXX If we use LP.delay instead of delay, the touchCallback does not get called.
void delayBug(int ms) {
delay(ms);
//LP.delay(ms, TWO_MHZ);
}
// Blink n times followed by an additional delay so consecutive calls can
// be distinguished.
void blink(int n) {
for (int i = 0; i < n; ++i) {
digitalWrite(LED_BUILTIN, HIGH);
delayBug(50);
digitalWrite(LED_BUILTIN, LOW);
delayBug(100);
}
delayBug(500);
}
// Blinks twice. Enters hibernation state.
void touchCallback() {
blink(2);
LP.Hibernate(&LP_config);
}
// Blinks once. Configures hibernation mode to wake when pin 0 is touched. Enters
// hibernation state.
void setup()
{
pinMode(13, OUTPUT);
blink(1);
// Configure waking on a touch event.
LP_config.modules = TSI_WAKE;
LP_config.tsi_pin = 0;
// Calibrate touchRead by taking a reading. If the user is touching the pin when
// this calibration is perfomed, the threshold may be too high to recognize
// subsequent touch actions.
LP_config.tsi_threshold = touchRead(LP_config.tsi_pin) + 4;
LP_config.callback = touchCallback;
// Enter hibernation until a touch event. Exit hibernation state via
LP.Hibernate(&LP_config);
}
void loop() {
// Not reached.
//
// After power is applied, the following sequence occurs:
// setup:
// * Blinks once
// * Configures an interrupt for a touch event on pin 0.
// * Hibernates, suspending execution until a touch occurs on pin 0.
//
// After a touch interrupt is triggered, the following sequence occurs:
// setup:
// * Performs steps listed above.
// LP_config.callback:
// * Blinks twice
// * Hibernates as described above.
}
Paul and duff, thank you for making such wonderful stuff.
Cheers,
John