@@ -626,7 +626,6 @@ const nrf_drv_twis_t *jshGetTWIS(IOEventFlags device) {
626626#endif
627627
628628void TIMER1_IRQHandler (void ) {
629- nrf_timer_task_trigger (NRF_TIMER1 , NRF_TIMER_TASK_CLEAR );
630629 nrf_timer_event_clear (NRF_TIMER1 , NRF_TIMER_EVENT_COMPARE0 );
631630 jstUtilTimerInterruptHandler ();
632631}
@@ -2776,17 +2775,43 @@ void jshUtilTimerReschedule(JsSysTime period) {
27762775 period = NRF_TIMER_MAX ;
27772776 }
27782777 //jsiConsolePrintf("Sleep for %d %d -> %d\n", (uint32_t)(t>>32), (uint32_t)(t), (uint32_t)(period));
2779- if (utilTimerActive ) nrf_timer_task_trigger (NRF_TIMER1 , NRF_TIMER_TASK_STOP );
2780- nrf_timer_task_trigger (NRF_TIMER1 , NRF_TIMER_TASK_CLEAR );
2781- nrf_timer_cc_write (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 , (uint32_t )period );
2782- if (utilTimerActive ) nrf_timer_task_trigger (NRF_TIMER1 , NRF_TIMER_TASK_START );
2778+
2779+ /* Setting the timer is complicated because the compare register only compares for equality,
2780+ so if we set the compare register even 1 less than the current timer it won't fire for 2^32 microsec
2781+
2782+ That would be fine but we're not ever allowed to totally disable interrupts so we have to check *after*
2783+ we set it just to make sure it hasn't overflowed and if so to redo it.
2784+ */
2785+ if (utilTimerActive ) { // Reschedule an active timer...
2786+ // Find out what our last trigger time was
2787+ uint32_t lastCC = nrf_timer_cc_read (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 );
2788+ // schedule timer to trigger at the last time we triggered PLUS our period
2789+ uint32_t thisCC = lastCC + period ;
2790+ bool needsReschedule ;
2791+ do {
2792+ // set up the timer
2793+ nrf_timer_cc_write (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 , (uint32_t )thisCC );
2794+ needsReschedule = false;
2795+ // Check that the timer hasn't already passed this value? Reschedule it 2us in the future
2796+ NRF_TIMER1 -> TASKS_CAPTURE [1 ] = 1 ; // get current timer value
2797+ uint32_t current = NRF_TIMER1 -> CC [1 ];
2798+ if (((int32_t )thisCC - (int32_t )current ) < 2 ) { // it it's closer than 2us (or has already passed!)
2799+ thisCC = current + 2 ; // reschedule into the future
2800+ needsReschedule = true;
2801+ }
2802+ } while (needsReschedule );
2803+ } else {
2804+ // timer is off, it'll be cleared to literally just set the period
2805+ nrf_timer_cc_write (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 , (uint32_t )period );
2806+ }
27832807}
27842808
27852809/// Start the timer and get it to interrupt after 'period'
27862810void jshUtilTimerStart (JsSysTime period ) {
27872811 jshUtilTimerReschedule (period );
27882812 if (!utilTimerActive ) {
27892813 utilTimerActive = true;
2814+ nrf_timer_task_trigger (NRF_TIMER1 , NRF_TIMER_TASK_CLEAR );
27902815 nrf_timer_task_trigger (NRF_TIMER1 , NRF_TIMER_TASK_START );
27912816 }
27922817}
0 commit comments