@@ -29,11 +29,10 @@ unsigned int utilTimerBit;
2929bool utilTimerInIRQ = false;
3030unsigned int utilTimerData ;
3131uint16_t utilTimerReload0H , utilTimerReload0L , utilTimerReload1H , utilTimerReload1L ;
32- /// When we last started the timer, how far in the future were we meant to get called?
32+ /// When did the timer last run? This is used for timekeeping. Should be jshGetSystemTime() cropped to 32 bits
33+ volatile int utilTimerTime ;
34+ /// When we rescheduled the timer, how far in the future were we meant to get called?
3335int utilTimerPeriod ;
34- /** When we last started the timer, this was the RTC time. We need this if we need to
35- reschedule the timer */
36- JsSysTime utilTimerScheduleTime ;
3736
3837
3938#ifndef SAVE_ON_FLASH
@@ -94,14 +93,11 @@ void jstUtilTimerInterruptHandler() {
9493 jshPinOutput (31 ,1 );
9594 if (utilTimerOn ) {
9695 utilTimerInIRQ = true;
97- // Update the time of each timer task with the actual timer delay
98- unsigned char t = utilTimerTasksTail ;
99- while (t != utilTimerTasksHead ) {
100- utilTimerTasks [t ].timeLeft -= utilTimerPeriod ;
101- t = (t + 1 ) & (UTILTIMERTASK_TASKS - 1 );
102- }
96+ // Increment estimated timer time
97+ // TODO: use SysTick to estimate time in this fn and update utilTimerTime accordingly
98+ utilTimerTime += utilTimerPeriod ;
10399 // execute any timers that are due
104- while (utilTimerTasksTail != utilTimerTasksHead && utilTimerTasks [utilTimerTasksTail ].timeLeft <=0 ) {
100+ while (utilTimerTasksTail != utilTimerTasksHead && ( utilTimerTasks [utilTimerTasksTail ].time - utilTimerTime ) <=0 ) {
105101 UtilTimerTask * task = & utilTimerTasks [utilTimerTasksTail ];
106102 void (* executeFn )(JsSysTime time , void * userdata ) = 0 ;
107103 void * executeData = 0 ;
@@ -171,12 +167,13 @@ void jstUtilTimerInterruptHandler() {
171167 // If we need to repeat
172168 if (task -> repeatInterval ) {
173169 // update time (we know time > task->time)
174- task -> timeLeft += task -> repeatInterval ;
170+ task -> time += task -> repeatInterval ;
171+
175172 // do an in-place bubble sort to ensure that times are still in the right order
176173 unsigned char ta = utilTimerTasksTail ;
177174 unsigned char tb = (ta + 1 ) & (UTILTIMERTASK_TASKS - 1 );
178175 while (tb != utilTimerTasksHead ) {
179- if (utilTimerTasks [ta ].timeLeft > utilTimerTasks [tb ].timeLeft ) {
176+ if (( utilTimerTasks [ta ].time - utilTimerTime ) > ( utilTimerTasks [tb ].time - utilTimerTime ) ) {
180177 UtilTimerTask task = utilTimerTasks [ta ];
181178 utilTimerTasks [ta ] = utilTimerTasks [tb ];
182179 utilTimerTasks [tb ] = task ;
@@ -195,9 +192,8 @@ void jstUtilTimerInterruptHandler() {
195192
196193 // re-schedule the timer if there is something left to do
197194 if (utilTimerTasksTail != utilTimerTasksHead ) {
198- utilTimerPeriod = utilTimerTasks [utilTimerTasksTail ].timeLeft ;
195+ utilTimerPeriod = utilTimerTasks [utilTimerTasksTail ].time - utilTimerTime ;
199196 if (utilTimerPeriod < 0 ) utilTimerPeriod = 0 ;
200- utilTimerScheduleTime = jshGetSystemTime ();
201197 jshUtilTimerReschedule (utilTimerPeriod );
202198 } else {
203199 utilTimerOn = false;
@@ -229,13 +225,9 @@ static bool utilTimerIsFull() {
229225/* Restart the utility timer with the right period. This should not normally
230226need to be called by anything outside jstimer.c */
231227void jstRestartUtilTimer () {
232- // disabling here stops jshUtilTimerStart trying to schedule the timer including the time that has already passed
233- jshUtilTimerDisable ();
234- // Work out how long we've got to go
235- utilTimerPeriod = utilTimerTasks [utilTimerTasksTail ].timeLeft ;
228+ utilTimerTime = (int )jshGetSystemTime ();
229+ utilTimerPeriod = utilTimerTasks [utilTimerTasksTail ].time - utilTimerTime ;
236230 if (utilTimerPeriod < 0 ) utilTimerPeriod = 0 ;
237- utilTimerScheduleTime = jshGetSystemTime ();
238- // reschedule
239231 jshUtilTimerStart (utilTimerPeriod );
240232}
241233
@@ -247,11 +239,9 @@ bool utilTimerInsertTask(UtilTimerTask *task) {
247239
248240 if (!utilTimerInIRQ ) jshInterruptOff ();
249241
250- // time between when utilTimerTasks was last updated and time now
251- int timeDiff = jshGetSystemTime ()- utilTimerScheduleTime ;
252242 // find out where to insert
253243 unsigned char insertPos = utilTimerTasksTail ;
254- while (insertPos != utilTimerTasksHead && ( utilTimerTasks [insertPos ].timeLeft - timeDiff ) < task -> timeLeft )
244+ while (insertPos != utilTimerTasksHead && utilTimerTasks [insertPos ].time < task -> time )
255245 insertPos = (insertPos + 1 ) & (UTILTIMERTASK_TASKS - 1 );
256246
257247 bool haveChangedTimer = insertPos == utilTimerTasksTail ;
@@ -261,21 +251,18 @@ bool utilTimerInsertTask(UtilTimerTask *task) {
261251 while (i != insertPos ) {
262252 unsigned char next = (i + UTILTIMERTASK_TASKS - 1 ) & (UTILTIMERTASK_TASKS - 1 );
263253 utilTimerTasks [i ] = utilTimerTasks [next ];
264- if (haveChangedTimer ) {
265- // if we changed the timer, we're rescheduling so must change
266- // the times in all tasks
267- utilTimerTasks [i ].timeLeft -= timeDiff ;
268- }
269254 i = next ;
270255 }
271256 // add new item
272257 utilTimerTasks [insertPos ] = * task ;
273258 // increase task list size
274259 utilTimerTasksHead = (utilTimerTasksHead + 1 ) & (UTILTIMERTASK_TASKS - 1 );
260+
261+ //jsiConsolePrint("Head is %d\n", utilTimerTasksHead);
275262 // now set up timer if not already set up...
276263 if (!utilTimerOn || haveChangedTimer ) {
277- jstRestartUtilTimer ();
278264 utilTimerOn = true;
265+ jstRestartUtilTimer ();
279266 }
280267
281268 if (!utilTimerInIRQ ) jshInterruptOn ();
@@ -381,7 +368,7 @@ bool jstGetLastBufferTimerTask(JsVar *var, UtilTimerTask *task) {
381368bool jstPinOutputAtTime (JsSysTime time , Pin * pins , int pinCount , uint8_t value ) {
382369 assert (pinCount <=UTILTIMERTASK_PIN_COUNT );
383370 UtilTimerTask task ;
384- task .timeLeft = (int )( time - jshGetSystemTime ()) ;
371+ task .time = (int )time ;
385372 task .repeatInterval = 0 ;
386373 task .type = UET_SET ;
387374 int i ;
@@ -430,10 +417,10 @@ bool jstPinPWM(JsVarFloat freq, JsVarFloat dutyCycle, Pin pin) {
430417 }
431418 if (ptaskon && ptaskoff ) {
432419 // Great! We have PWM... Just update it
433- if (ptaskoff -> timeLeft > ptaskon -> timeLeft )
434- ptaskoff -> timeLeft = ptaskon -> timeLeft + pulseLength ;
420+ if (ptaskoff -> time > ptaskon -> time )
421+ ptaskoff -> time = ptaskon -> time + pulseLength ;
435422 else
436- ptaskoff -> timeLeft = ptaskon -> timeLeft + pulseLength - (unsigned int )period ;
423+ ptaskoff -> time = ptaskon -> time + pulseLength - (unsigned int )period ;
437424 ptaskon -> repeatInterval = (unsigned int )period ;
438425 ptaskoff -> repeatInterval = (unsigned int )period ;
439426 /* don't bother rescheduling - everything will work out next time
@@ -448,12 +435,12 @@ bool jstPinPWM(JsVarFloat freq, JsVarFloat dutyCycle, Pin pin) {
448435 if (ptaskon || ptaskoff ) {
449436 while (utilTimerRemoveTask (jstPinTaskChecker , (void * )& pin ));
450437 }
451-
438+ JsSysTime time = jshGetSystemTime ();
452439 UtilTimerTask taskon , taskoff ;
453440 taskon .data .set .value = 1 ;
454441 taskoff .data .set .value = 0 ;
455- taskon .timeLeft = 0 ;
456- taskoff .timeLeft = (int )(taskon . timeLeft + pulseLength );
442+ taskon .time = ( int ) time ;
443+ taskoff .time = (int )(time + pulseLength );
457444 taskon .repeatInterval = (unsigned int )period ;
458445 taskoff .repeatInterval = (unsigned int )period ;
459446 taskon .type = UET_SET ;
@@ -475,7 +462,7 @@ bool jstPinPWM(JsVarFloat freq, JsVarFloat dutyCycle, Pin pin) {
475462/// Execute the given function repeatedly after the given time period
476463bool jstExecuteFn (UtilTimerTaskExecFn fn , void * userdata , JsSysTime startTime , uint32_t period ) {
477464 UtilTimerTask task ;
478- task .timeLeft = (int )( startTime - jshGetSystemTime ()) ;
465+ task .time = (int )startTime ;
479466 task .repeatInterval = period ;
480467 task .type = UET_EXECUTE ;
481468 task .data .execute .fn = fn ;
@@ -496,7 +483,7 @@ bool jstStopExecuteFn(UtilTimerTaskExecFn fn, void *userdata) {
496483/// Set the utility timer so we're woken up in whatever time period
497484bool jstSetWakeUp (JsSysTime period ) {
498485 UtilTimerTask task ;
499- task .timeLeft = (int )period ;
486+ task .time = (int )( jshGetSystemTime () + period ) ;
500487 task .repeatInterval = 0 ;
501488 task .type = UET_WAKEUP ;
502489
@@ -508,11 +495,11 @@ bool jstSetWakeUp(JsSysTime period) {
508495 jshInterruptOff ();
509496 if (utilTimerTasksTail != utilTimerTasksHead ) {
510497 hasTimer = true;
511- nextTime = utilTimerTasks [utilTimerTasksTail ].timeLeft ;
498+ nextTime = utilTimerTasks [utilTimerTasksTail ].time ;
512499 }
513500 jshInterruptOn ();
514501
515- if (hasTimer && task .timeLeft >= nextTime ) {
502+ if (hasTimer && ( task .time - utilTimerTime ) >= ( nextTime - utilTimerTime ) ) {
516503 // we already had a timer, and it's going to wake us up sooner.
517504 // don't create a WAKEUP timer task
518505 return true;
@@ -549,7 +536,7 @@ bool jstStartSignal(JsSysTime startTime, JsSysTime period, Pin pin, JsVar *curre
549536 if (!jshIsPinValid (pin )) return false;
550537 UtilTimerTask task ;
551538 task .repeatInterval = (unsigned int )period ;
552- task .timeLeft = (int )(startTime + period - jshGetSystemTime () );
539+ task .time = (int )(startTime + period );
553540 task .type = type ;
554541 if (UET_IS_BUFFER_WRITE_EVENT (type )) {
555542 task .data .buffer .pinFunction = jshGetCurrentPinFunction (pin );
@@ -589,14 +576,19 @@ bool jstStopBufferTimerTask(JsVar *var) {
589576void jstReset () {
590577 jshUtilTimerDisable ();
591578 utilTimerTasksTail = utilTimerTasksHead = 0 ;
579+ utilTimerTime = (int )jshGetSystemTime ();
592580 utilTimerPeriod = 0 ;
593- utilTimerScheduleTime = jshGetSystemTime ();
594581}
595582
596583/** when system time is changed, also change the time in the timers.
597584This should be done with interrupts off */
598585void jstSystemTimeChanged (JsSysTime diff ) {
599- utilTimerScheduleTime += diff ;
586+ unsigned char t = utilTimerTasksTail ;
587+ while (t != utilTimerTasksHead ) {
588+ utilTimerTasks [t ].time += diff ;
589+ t = (t + 1 ) & (UTILTIMERTASK_TASKS - 1 );
590+ }
591+ utilTimerTime += diff ;
600592}
601593
602594void jstDumpUtilityTimers () {
@@ -607,15 +599,17 @@ void jstDumpUtilityTimers() {
607599 uTimerTasks [i ] = utilTimerTasks [i ];
608600 unsigned char uTimerTasksHead = utilTimerTasksHead ;
609601 unsigned char uTimerTasksTail = utilTimerTasksTail ;
602+ int uTimerTime = utilTimerTime ;
610603 jshInterruptOn ();
611604
605+ jsiConsolePrintf ("Current timer difference %d us" , (int )(1000 * jshGetMillisecondsFromTime (jshGetSystemTime ()- uTimerTime )));
612606 unsigned char t = uTimerTasksTail ;
613607 bool hadTimers = false;
614608 while (t != uTimerTasksHead ) {
615609 hadTimers = true;
616610
617611 UtilTimerTask task = uTimerTasks [t ];
618- jsiConsolePrintf ("%08d us" , (int )(1000 * jshGetMillisecondsFromTime (task .timeLeft )));
612+ jsiConsolePrintf ("%08d us" , (int )(1000 * jshGetMillisecondsFromTime (task .time - uTimerTime )));
619613 jsiConsolePrintf (", repeat %08d us" , (int )(1000 * jshGetMillisecondsFromTime (task .repeatInterval )));
620614 jsiConsolePrintf (" : " );
621615
0 commit comments