-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
I haven't had time to investigate this further, but in one of my test systems, I have to use TimerCounter::start instead of TimerCounter::restart to get the intended/expected behaviour for an aperiodic TimerCounter?
See the "else if (tapCounter == 2)" block below:
#include <System.h>
#include <TimerCounter.h>
using namespace SAMD21LPE;
#define EXT_INT_PIN PIN_A0
TimerCounter timer;
const byte GCLKGEN_ID_1K = 6;
const uint32_t timerDuration = 800; // 800 ms
bool timerFlag = false;
uint8_t tapCounter = 0;
void externalInterruptHandler()
{
tapCounter++;
}
void timerInterruptHandler()
{
timerFlag = true;
}
void setupEIC()
{
noInterrupts();
System::reducePowerConsumption(); // disable non essential MCU modules (incl. USB, PORT and EIC)
// enable PORT and EIC modules
System::enablePORT();
System::enableEIC();
// Enable external interrupt on pin A0/D0
pinMode(EXT_INT_PIN, INPUT_PULLUP);
attachInterrupt(EXT_INT_PIN, externalInterruptHandler, FALLING);
// Configure low power clock generator to run at 1024 Hz
System::setupClockGenOSCULP32K(GCLKGEN_ID_1K, 4); // DIV = 2^(4+1) = 32, clkGenFrequency = 32768/DIV = 1024 Hz
// Change clock generator for EIC from 0 (DFLL48M, assigned by attachInterrupt) to 6 (OSCULP32K), which stays enabled in standby (required for input edge detection)
System::enableClock(GCM_EIC, GCLKGEN_ID_1K);
interrupts();
}
void setup()
{
// Setup external interrupt controller
setupEIC();
// Select sleep mode STANDBY between ISR calls and disable sleep-on-exit mode
System::setSleepOnExitISR(false);
System::setSleepMode(System::STANDBY);
}
void loop()
{
System::sleep(); // Sleep until external interrupt
if (timerFlag)
{
timerFlag = false; // Clear timer flag
tapCounter = 0; // Reset tap count
timer.disable(); // Disable timer counter
digitalWrite(PIN_LED3, HIGH); // Turn off LED3
digitalWrite(PIN_LED, LOW); // Toggle LED
delay(500);
digitalWrite(PIN_LED, HIGH);
}
// Triple Tap Detection with "timerDuration" timeout between taps
if (tapCounter == 1)
{
digitalWrite(PIN_LED3, HIGH); // Turn off LED3
timerFlag = false; // Clear timer flag
timer.enable(4, GCLKGEN_ID_1K, 1024, TimerCounter::DIV1, TimerCounter::RES16, 1000, true); // Configure and enable timer counter
timer.start(timerDuration, false, timerInterruptHandler); // Run timer for "timerDuration" milliseconds
}
else if (tapCounter == 2)
{
timerFlag = false; // Clear timer flag
// timer.restart(); // Restart timer, (retaining previous start settings), (this doesn't seem to properly restart the counter?)
timer.start(timerDuration, false, timerInterruptHandler); // Run timer for "timerDuration" milliseconds
}
else if (tapCounter >= 3)
{
timer.disable(); // Disable timer counter
digitalWrite(PIN_LED3, LOW); // Toggle LED3
delay(500);
digitalWrite(PIN_LED3, HIGH);
tapCounter = 0; // Reset tap count
}
}
Metadata
Metadata
Assignees
Labels
No labels