mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
Stop the utility timer queue filling with WAKEUP tasks if Espruino gets woken up early
This commit is contained in:
parent
814f29c547
commit
5e1b2118cd
@ -3,6 +3,7 @@
|
||||
Fixed exception catching
|
||||
Fix Serial1 initialisation after 'reset()'
|
||||
Fix parsing of try..catch when a serious error (not an exception) occurred
|
||||
Stop the utility timer queue filling with WAKEUP tasks if Espruino gets woken up early
|
||||
|
||||
1v66 : Ensure that analogWrite(pin,1) works on negated outputs
|
||||
Allow multiple Waveform playback on one pin (+ wave fixes)
|
||||
|
||||
@ -234,6 +234,10 @@ else:
|
||||
bufferSizeIO = 64 if board.chip["ram"]<20 else 128
|
||||
bufferSizeTX = 32 if board.chip["ram"]<20 else 128
|
||||
bufferSizeTimer = 4 if board.chip["ram"]<20 else 16
|
||||
|
||||
if 'util_timer_tasks' in board.info:
|
||||
bufferSizeTimer = board.info['util_timer_tasks']
|
||||
|
||||
codeOut("#define IOBUFFERMASK "+str(bufferSizeIO-1)+" // (max 255) amount of items in event buffer - events take ~9 bytes each")
|
||||
codeOut("#define TXBUFFERMASK "+str(bufferSizeTX-1)+" // (max 255)")
|
||||
codeOut("#define UTILTIMERTASK_TASKS ("+str(bufferSizeTimer)+") // Must be power of 2 - and max 256")
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
*/
|
||||
#include "jstimer.h"
|
||||
#include "jsparse.h"
|
||||
#include "jsinteractive.h"
|
||||
|
||||
UtilTimerTask utilTimerTasks[UTILTIMERTASK_TASKS];
|
||||
volatile unsigned char utilTimerTasksHead = 0;
|
||||
@ -279,14 +280,51 @@ bool jstPinOutputAtTime(JsSysTime time, Pin *pins, int pinCount, uint8_t value)
|
||||
/// Set the utility timer so we're woken up in whatever time period
|
||||
bool jstSetWakeUp(JsSysTime period) {
|
||||
UtilTimerTask task;
|
||||
task.repeatInterval = 0;
|
||||
task.time = jshGetSystemTime() + period;
|
||||
task.repeatInterval = 0;
|
||||
task.type = UET_WAKEUP;
|
||||
|
||||
bool hasTimer = false;
|
||||
JsSysTime nextTime;
|
||||
|
||||
// work out if we're waiting for a timer,
|
||||
// and if so, when it's going to be
|
||||
jshInterruptOff();
|
||||
if (utilTimerTasksTail!=utilTimerTasksHead) {
|
||||
hasTimer = true;
|
||||
nextTime = utilTimerTasks[utilTimerTasksTail].time;
|
||||
}
|
||||
jshInterruptOn();
|
||||
|
||||
if (hasTimer && task.time >= nextTime) {
|
||||
// we already had a timer, and it's going to wake us up sooner.
|
||||
// don't create a WAKEUP timer task
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ok = utilTimerInsertTask(&task);
|
||||
// We wait until the timer is out of the reload event, because the reload event itself would wake us up
|
||||
return ok;
|
||||
}
|
||||
|
||||
/** If the first timer task is a wakeup task, remove it. This stops
|
||||
* us filling the timer full of wakeup events if we wake up from sleep
|
||||
* before the wakeup event */
|
||||
void jstClearWakeUp() {
|
||||
bool removedTimer = false;
|
||||
jshInterruptOff();
|
||||
// while the first item is a wakeup, remove it
|
||||
while (utilTimerTasksTail!=utilTimerTasksHead &&
|
||||
utilTimerTasks[utilTimerTasksTail].type == UET_WAKEUP) {
|
||||
utilTimerTasksTail = (utilTimerTasksTail+1) & (UTILTIMERTASK_TASKS-1);
|
||||
removedTimer = true;
|
||||
}
|
||||
// if the queue is now empty, and we stop the timer
|
||||
if (utilTimerTasksTail==utilTimerTasksHead && removedTimer)
|
||||
jshUtilTimerDisable();
|
||||
jshInterruptOn();
|
||||
}
|
||||
|
||||
#ifndef SAVE_ON_FLASH
|
||||
bool jstStartSignal(JsSysTime startTime, JsSysTime period, Pin pin, JsVar *currentData, JsVar *nextData, UtilTimerEventType type) {
|
||||
if (!jshIsPinValid(pin)) return false;
|
||||
@ -332,7 +370,7 @@ bool jstStopBufferTimerTask(JsVar *var) {
|
||||
if (UET_IS_BUFFER_EVENT(utilTimerTasks[ptr].type)) {
|
||||
if (utilTimerTasks[ptr].data.buffer.currentBuffer==ref || utilTimerTasks[ptr].data.buffer.nextBuffer==ref) {
|
||||
// shift tail back along
|
||||
int next = (ptr+UTILTIMERTASK_TASKS-1) & (UTILTIMERTASK_TASKS-1);
|
||||
unsigned char next = (ptr+UTILTIMERTASK_TASKS-1) & (UTILTIMERTASK_TASKS-1);
|
||||
while (next!=endPtr) {
|
||||
utilTimerTasks[ptr] = utilTimerTasks[next];
|
||||
ptr = next;
|
||||
@ -356,3 +394,37 @@ void jstReset() {
|
||||
jshUtilTimerDisable();
|
||||
utilTimerTasksTail = utilTimerTasksHead = 0;
|
||||
}
|
||||
|
||||
void jstDumpUtilityTimers() {
|
||||
int i;
|
||||
UtilTimerTask uTimerTasks[UTILTIMERTASK_TASKS];
|
||||
jshInterruptOff();
|
||||
for (i=0;i<UTILTIMERTASK_TASKS;i++)
|
||||
uTimerTasks[i] = utilTimerTasks[i];
|
||||
unsigned char uTimerTasksHead = utilTimerTasksHead;
|
||||
unsigned char uTimerTasksTail = utilTimerTasksTail;
|
||||
jshInterruptOn();
|
||||
|
||||
unsigned char t = uTimerTasksTail;
|
||||
while (t!=uTimerTasksHead) {
|
||||
UtilTimerTask task = uTimerTasks[t];
|
||||
jsiConsolePrintf("%08d us : ", (int)(1000*jshGetMillisecondsFromTime(task.time-jsiLastIdleTime)));
|
||||
|
||||
switch (task.type) {
|
||||
case UET_WAKEUP : jsiConsolePrintf("WAKEUP\n"); break;
|
||||
case UET_SET : jsiConsolePrintf("SET ");
|
||||
for (i=0;i<UTILTIMERTASK_PIN_COUNT;i++)
|
||||
jsiConsolePrintf("%p=%d,", task.data.set.pins[i], (task.data.set.value>>i)&i);
|
||||
jsiConsolePrintf("\n");
|
||||
break;
|
||||
case UET_WRITE_BYTE : jsiConsolePrintf("WRITE_BYTE\n"); break;
|
||||
case UET_READ_BYTE : jsiConsolePrintf("READ_BYTE\n"); break;
|
||||
case UET_WRITE_SHORT : jsiConsolePrintf("WRITE_SHORT\n"); break;
|
||||
case UET_READ_SHORT : jsiConsolePrintf("READ_SHORT\n"); break;
|
||||
default : jsiConsolePrintf("Unknown type %d\n", task.type); break;
|
||||
}
|
||||
|
||||
t = (t+1) & (UTILTIMERTASK_TASKS-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -105,6 +105,11 @@ bool jstPinOutputAtTime(JsSysTime time, Pin *pins, int pinCount, uint8_t value);
|
||||
/// Set the utility timer so we're woken up in whatever time period
|
||||
bool jstSetWakeUp(JsSysTime period);
|
||||
|
||||
/** If the first timer task is a wakeup task, remove it. This stops
|
||||
* us filling the timer full of wakeup events if we wake up from sleep
|
||||
* before the wakeup event */
|
||||
void jstClearWakeUp();
|
||||
|
||||
/// Start writing a string out at the given period between samples
|
||||
bool jstStartSignal(JsSysTime startTime, JsSysTime period, Pin pin, JsVar *currentData, JsVar *nextData, UtilTimerEventType type);
|
||||
|
||||
@ -114,5 +119,8 @@ bool jstStopBufferTimerTask(JsVar *var);
|
||||
/// Stop ALL timer tasks (including digitalPulse - use this when resetting the VM)
|
||||
void jstReset();
|
||||
|
||||
/// Dump the current list of timers
|
||||
void jstDumpUtilityTimers();
|
||||
|
||||
#endif /* JSTIMER_H_ */
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "jswrap_math.h"
|
||||
#include "jswrapper.h"
|
||||
#include "jsinteractive.h"
|
||||
#include "jstimer.h"
|
||||
|
||||
/*JSON{ "type":"class",
|
||||
"class" : "E",
|
||||
@ -497,3 +498,13 @@ int jswrap_espruino_reverseByte(int v) {
|
||||
return (((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
/*JSON{ "type":"staticmethod",
|
||||
"class" : "E", "name" : "dumpTimers", "ifndef":"RELEASE",
|
||||
"description" : ["Output the current list of Utility Timer Tasks - for debugging only"],
|
||||
"generate" : "jswrap_espruino_dumpTimers"
|
||||
}*/
|
||||
void jswrap_espruino_dumpTimers() {
|
||||
jstDumpUtilityTimers();
|
||||
}
|
||||
|
||||
|
||||
@ -28,3 +28,4 @@ JsVarFloat jswrap_espruino_interpolate2d(JsVar *array, int width, JsVarFloat x,
|
||||
void jswrap_espruino_enableWatchdog(JsVarFloat time);
|
||||
JsVar *jswrap_espruino_toArrayBuffer(JsVar *str);
|
||||
int jswrap_espruino_reverseByte(int v);
|
||||
void jswrap_espruino_dumpTimers();
|
||||
|
||||
@ -2459,10 +2459,13 @@ bool jshSleep(JsSysTime timeUntilWake) {
|
||||
// we're going to wake on a System Tick timer anyway, so don't bother
|
||||
}
|
||||
|
||||
// TODO: we can do better than this. look at lastSysTickTime
|
||||
jsiSetSleep(JSI_SLEEP_ASLEEP);
|
||||
__WFI(); // Wait for Interrupt
|
||||
jsiSetSleep(JSI_SLEEP_AWAKE);
|
||||
|
||||
/* We may have woken up before the wakeup event. If so
|
||||
then make sure we clear the event */
|
||||
jstClearWakeUp();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2600,7 +2603,7 @@ void jshSetOutputValue(JshPinFunction func, int value) {
|
||||
} else if (JSH_PINFUNCTION_IS_TIMER(func)) {
|
||||
TIM_TypeDef* TIMx = getTimerFromPinFunction(func);
|
||||
if (TIMx) {
|
||||
unsigned int period = (int)TIMx->ARR; // No getter available
|
||||
unsigned int period = (unsigned int)TIMx->ARR; // No getter available
|
||||
uint16_t timerVal = (uint16_t)(((unsigned int)value * period) >> 16);
|
||||
switch (func & JSH_MASK_TIMER_CH) {
|
||||
case JSH_TIMER_CH1: TIM_SetCompare1(TIMx, timerVal); break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user