From 8f964b9597922bd6d14f5ae8420dfbd2925cf128 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Mon, 18 May 2015 14:32:12 -0700 Subject: [PATCH] add timer.starta and timer.stopa to stop and start a systimer that calls a bitlash function --- src/Scout.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Scout.h | 8 ++++++++ src/Shell.cpp | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/src/Scout.cpp b/src/Scout.cpp index 3fa0b83..6dbc365 100644 --- a/src/Scout.cpp +++ b/src/Scout.cpp @@ -21,6 +21,8 @@ static void scoutDigitalStateChangeTimerHandler(SYS_Timer_t *timer); static void scoutAnalogStateChangeTimerHandler(SYS_Timer_t *timer); static void scoutPeripheralStateChangeTimerHandler(SYS_Timer_t *timer); +static void timerAHandler(SYS_Timer_t *timer); + #ifndef lengthof #define lengthof(x) (sizeof(x)/sizeof(*x)) #endif @@ -94,6 +96,7 @@ PinoccioScout::PinoccioScout() { sleepPending = false; postSleepFunction = NULL; + timerAFunction = NULL; } PinoccioScout::~PinoccioScout() { } @@ -302,6 +305,52 @@ void PinoccioScout::stopPeripheralStateChangeEvents() { SYS_TimerStop(&peripheralStateChangeTimer); } + +void PinoccioScout::startTimerA(uint32_t ms, const char *func, bool continuous) { + stopTimerA(); + + timerA.interval = ms; + timerA.handler = timerAHandler; + + if (continuous) { + timerA.mode = SYS_TIMER_PERIODIC_MODE; + } else { + timerA.mode = SYS_TIMER_INTERVAL_MODE; + } + + if(timerAFunction){ + free(timerAFunction); + timerAFunction = NULL; + } + timerAFunction = func ? strdup(func) : NULL; + + SYS_TimerStart(&timerA); +} + +void PinoccioScout::stopTimerA() { + if(SYS_TimerStarted(&timerA)){ + SYS_TimerStop(&timerA); + } + + if(timerAFunction){ + free(timerAFunction); + timerAFunction = NULL; + } +} + +static void timerAHandler(SYS_Timer_t *timer) { + + if(Scout.timerAFunction){ + + Shell.eval(Scout.timerAFunction); + + if(SYS_TIMER_PERIODIC_MODE != timer->mode){ + free(Scout.timerAFunction); + Scout.timerAFunction = NULL; + } + } +} + void PinoccioScout::setStateChangeEventCycle(uint32_t digitalInterval, uint32_t analogInterval, uint32_t peripheralInterval) { stopDigitalStateChangeEvents(); digitalStateChangeTimer.interval = digitalInterval; diff --git a/src/Scout.h b/src/Scout.h index a8c7571..423b4fa 100644 --- a/src/Scout.h +++ b/src/Scout.h @@ -68,6 +68,9 @@ class PinoccioScout : public PinoccioClass { bool factoryReset(); void reboot(); + void startTimerA(uint32_t ms, const char *func, bool continuous); + void stopTimerA(); + void startDigitalStateChangeEvents(); void stopDigitalStateChangeEvents(); void startAnalogStateChangeEvents(); @@ -143,6 +146,9 @@ class PinoccioScout : public PinoccioClass { PINMODE_INPUT_PULLUP = 2, PINMODE_PWM = 3, }; + + char * timerAFunction; + protected: uint32_t lastIndicate = 0; void checkStateChange(); @@ -157,6 +163,8 @@ class PinoccioScout : public PinoccioClass { SYS_Timer_t analogStateChangeTimer; SYS_Timer_t peripheralStateChangeTimer; + SYS_Timer_t timerA; + bool sleepPending; // The original sleep time, used to pass to the callback and to // re-sleep. The actual sleep time for the next sleep is stored by diff --git a/src/Shell.cpp b/src/Shell.cpp index 15bfc27..b4da77e 100644 --- a/src/Shell.cpp +++ b/src/Shell.cpp @@ -481,6 +481,35 @@ static numvar powerWakeupPin(void) { * RGB LED HANDLERS * \****************************/ +static numvar startTimerA(void) { + if (!checkArgs(2, 3, F("usage: timer.starta(ms, \"function\", [continuous])"))) { + return 0; + } + + const char *func = NULL; + if (isstringarg(2)) + func = (const char*)getarg(2); + else + func = keyGet(getarg(2)); + + bool periodic = getarg(0) == 3 ? getarg(3) : 0; + + if (func && !Shell.defined(func)) { + sp("Must be the name of function: "); + speol(func); + return 0; + } + + Scout.startTimerA(getarg(1), func, periodic); + return 1; +} + +static numvar stopTimerA(void) { + + Scout.stopTimerA(); + return 1; +} + static StringBuffer ledReportHQ(void) { StringBuffer report(100); report.appendSprintf("[%d,[%d,%d],[[%d,%d,%d],[%d,%d,%d]]]", @@ -2528,6 +2557,9 @@ void PinoccioShell::setup() { addFunction("events.setcycle", setEventCycle); addFunction("events.verbose", setEventVerbose); + addFunction("timer.starta", startTimerA); + addFunction("timer.stopa", stopTimerA); + addFunction("key", keyMap); addFunction("key.free", keyFree); addFunction("key.print", keyPrint);