@@ -289,8 +289,9 @@ int utilTimerGetUnusedIndex(bool wait) {
289289 * task.time is the delay at which to execute the task. If timerOffset!==NULL then
290290 * task.time is relative to the time at which timerOffset=jstGetUtilTimerOffset().
291291 * This allows pulse trains/etc to be scheduled in sync.
292+ * If firstOnly=true, only insert the task if it'll be the first in the queue (otherwise set task type to UET_NONE and exit)
292293 */
293- void utilTimerInsertTask (uint8_t taskIdx , uint32_t * timerOffset ) {
294+ bool utilTimerInsertTask (uint8_t taskIdx , uint32_t * timerOffset , bool firstOnly ) {
294295 assert (!utilTimerIsFull ()); // queue should not be full since we had to allocate a task to get the index
295296 UtilTimerTask * task = & utilTimerTaskInfo [taskIdx ];
296297
@@ -302,8 +303,14 @@ void utilTimerInsertTask(uint8_t taskIdx, uint32_t *timerOffset) {
302303 int timePassed = utilTimerOn ? (jshGetSystemTime () - utilTimerSetTime ) : 0 ;
303304 // find out where to insert
304305 unsigned char insertPos = utilTimerTasksTail ;
305- while (insertPos != utilTimerTasksHead && utilTimerTaskInfo [utilTimerTasks [insertPos ]].time < (task -> time + timePassed ))
306+ while (insertPos != utilTimerTasksHead && utilTimerTaskInfo [utilTimerTasks [insertPos ]].time < (task -> time + timePassed )) {
307+ if (firstOnly ) { // if we're only allowed to schedule as the first item, we must bail out now
308+ jshInterruptOn ();
309+ utilTimerTaskInfo [taskIdx ].type = UET_NONE ;
310+ return false;
311+ }
306312 insertPos = (insertPos + 1 ) & (UTILTIMERTASK_TASKS - 1 );
313+ }
307314 bool haveChangedTimer = insertPos == utilTimerTasksTail ;
308315 //jsiConsolePrintf("Insert at %d, Tail is %d\n",insertPos,utilTimerTasksTail);
309316 // shift items forward
@@ -336,6 +343,7 @@ void utilTimerInsertTask(uint8_t taskIdx, uint32_t *timerOffset) {
336343 jstRestartUtilTimer ();
337344 }
338345 jshInterruptOn ();
346+ return true;
339347}
340348
341349/// Find a task that 'checkCallback' returns true for. Returns -1 if none found
@@ -460,7 +468,7 @@ bool jstPinOutputAtTime(JsSysTime time, uint32_t *timerOffset, Pin *pins, int pi
460468 for (i = 0 ;i < UTILTIMERTASK_PIN_COUNT ;i ++ )
461469 task -> data .set .pins [i ] = (Pin )((i < pinCount ) ? pins [i ] : PIN_UNDEFINED );
462470 task -> data .set .value = value ;
463- utilTimerInsertTask (idx , timerOffset );
471+ utilTimerInsertTask (idx , timerOffset , false /*doesn't have to be first*/ );
464472 return true;
465473}
466474
@@ -551,8 +559,8 @@ bool jstPinPWM(JsVarFloat freq, JsVarFloat dutyCycle, Pin pin) {
551559 jshPinSetValue (pin , 1 );
552560 uint32_t timerOffset = jstGetUtilTimerOffset ();
553561 // now start the 2 PWM tasks
554- utilTimerInsertTask (onidx , & timerOffset );
555- utilTimerInsertTask (offidx , & timerOffset );
562+ utilTimerInsertTask (onidx , & timerOffset , false /*doesn't have to be first*/ );
563+ utilTimerInsertTask (offidx , & timerOffset , false /*doesn't have to be first*/ );
556564 return true;
557565}
558566
@@ -568,7 +576,7 @@ bool jstExecuteFn(UtilTimerTaskExecFn fn, void *userdata, JsSysTime startTime, u
568576 task -> type = UET_EXECUTE ;
569577 task -> data .execute .fn = fn ;
570578 task -> data .execute .userdata = userdata ;
571- utilTimerInsertTask (idx , timerOffset );
579+ utilTimerInsertTask (idx , timerOffset , false /*doesn't have to be first*/ );
572580 return true;
573581}
574582
@@ -581,35 +589,18 @@ bool jstStopExecuteFn(UtilTimerTaskExecFn fn, void *userdata) {
581589}
582590
583591/// Set the utility timer so we're woken up in whatever time period
584- bool jstSetWakeUp (JsSysTime period ) {
592+ void jstSetWakeUp (JsSysTime period ) {
585593 bool hasTimer = false;
586594 int wakeupTime = (int )period ;
587595 int nextTime ;
588596
589-
590- // work out if we're waiting for a timer,
591- // and if so, when it's going to be
592- jshInterruptOff ();
593- if (utilTimerTasksTail != utilTimerTasksHead ) {
594- hasTimer = true;
595- nextTime = utilTimerTaskInfo [utilTimerTasks [utilTimerTasksTail ]].time ;
596- }
597- jshInterruptOn ();
598- JsSysTime currTime = jshGetSystemTime ();
599- if (hasTimer && ((currTime + wakeupTime ) >= (utilTimerSetTime + nextTime ))) {
600- // we already had a timer, and it's going to wake us up sooner.
601- // don't create a WAKEUP timer task
602- return true;
603- }
604-
605597 int idx = utilTimerGetUnusedIndex (false/*don't wait*/ );
606- if (idx < 0 ) return false ; // no free tasks!
598+ if (idx < 0 ) return ; // no free tasks!
607599 UtilTimerTask * task = & utilTimerTaskInfo [idx ];
608600 task -> type = UET_WAKEUP ;
609601 task -> time = wakeupTime ;
610602 task -> repeatInterval = 0 ;
611- utilTimerInsertTask (idx , NULL );
612- return true;
603+ utilTimerInsertTask (idx , NULL , true/* must be first! If not something else will wake us first so don't bother. */ );
613604}
614605
615606/** If the first timer task is a wakeup task, remove it. This stops
@@ -664,7 +655,7 @@ int jstStartSignal(JsSysTime startTime, JsSysTime period, Pin pin, Pin npin, JsV
664655 task -> data .buffer .nextBuffer = 0 ;
665656 }
666657 jstUtilTimerSetupBuffer (task );
667- utilTimerInsertTask (idx , NULL );
658+ utilTimerInsertTask (idx , NULL , false /*doesn't have to be first*/ );
668659 return idx ;
669660}
670661
0 commit comments