@@ -2765,14 +2765,13 @@ bool jshSleep(JsSysTime timeUntilWake) {
2765
2765
return true;
2766
2766
}
2767
2767
2768
- volatile bool utilTimerActive = false;
2769
- volatile uint32_t utilTimerTriggerTime = 0 ;
2768
+ bool utilTimerActive = false;
2770
2769
2771
2770
/// Reschedule the timer (it should already be running) to interrupt after 'period'
2772
2771
void jshUtilTimerReschedule (JsSysTime period ) {
2773
2772
if (period < JSSYSTIME_MAX / NRF_TIMER_FREQ ) {
2774
2773
period = period * NRF_TIMER_FREQ / (long long )SYSCLK_FREQ ;
2775
- if (period < 0 ) period = 0 ;
2774
+ if (period < 1 ) period = 1 ;
2776
2775
if (period > NRF_TIMER_MAX ) period = NRF_TIMER_MAX ;
2777
2776
} else {
2778
2777
// it's too big to do maths on... let's just use the maximum period
@@ -2783,45 +2782,35 @@ void jshUtilTimerReschedule(JsSysTime period) {
2783
2782
/* Setting the timer is complicated because the compare register only compares for equality,
2784
2783
so if we set the compare register even 1 less than the current timer it won't fire for 2^32 microsec
2785
2784
2786
- That would be fine but we're not ever allowed to totally disable the timer so we have to check *after*
2787
- we set it just to make sure it hasn't overflowed and if so go ahead and trigger the interrupt ourselves .
2785
+ That would be fine but we're not ever allowed to totally disable interrupts so we have to check *after*
2786
+ we set it just to make sure it hasn't overflowed and if so to redo it .
2788
2787
*/
2789
2788
if (utilTimerActive ) { // Reschedule an active timer...
2789
+ // Find out what our last trigger time was
2790
+ uint32_t lastCC = nrf_timer_cc_read (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 );
2790
2791
// schedule timer to trigger at the last time we triggered PLUS our period
2791
- uint32_t thisCC = (utilTimerTriggerTime + period ) & NRF_TIMER_MAX ;
2792
- // set up the timer
2793
- nrf_timer_cc_write (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 , (uint32_t )thisCC );
2794
- // Check that the timer hasn't already passed this value?
2795
- NRF_TIMER1 -> TASKS_CAPTURE [1 ] = 1 ; // get current timer value
2796
- uint32_t current = NRF_TIMER1 -> CC [1 ];
2797
- if (((int32_t )thisCC - (int32_t )current ) <= - (int32_t )(NRF_TIMER_MAX >> 2 )) { // if we can't keep up and are already fairly far behind
2798
- // skip ahead to avoid falling victim to timer wraparound
2799
- // and potentially forgetting to schedule stuff altogether for some time
2800
- thisCC = current ;
2801
- nrf_timer_cc_write (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 , (uint32_t )current );
2802
- }
2803
- utilTimerTriggerTime = thisCC ;
2804
- if (((int32_t )thisCC - (int32_t )current ) < 2 ) { // if it's closer than 2us (or has already passed!)
2805
- // make sure that the timer doesn't trigger the interrupt shortly afterwards
2806
- nrf_timer_cc_write (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 , (uint32_t )(current - 1 ));
2807
- // and manually trigger the interrupt now
2808
- NVIC_SetPendingIRQ (TIMER1_IRQn );
2809
- }
2792
+ uint32_t thisCC = lastCC + period ;
2793
+ bool needsReschedule ;
2794
+ do {
2795
+ // set up the timer
2796
+ nrf_timer_cc_write (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 , (uint32_t )thisCC );
2797
+ needsReschedule = false;
2798
+ // Check that the timer hasn't already passed this value? Reschedule it 2us in the future
2799
+ NRF_TIMER1 -> TASKS_CAPTURE [1 ] = 1 ; // get current timer value
2800
+ uint32_t current = NRF_TIMER1 -> CC [1 ];
2801
+ if (((int32_t )thisCC - (int32_t )current ) < 2 ) { // it it's closer than 2us (or has already passed!)
2802
+ thisCC = current + 2 ; // reschedule into the future
2803
+ needsReschedule = true;
2804
+ }
2805
+ } while (needsReschedule );
2810
2806
} else {
2811
2807
// timer is off, it'll be cleared to literally just set the period
2812
- utilTimerTriggerTime = period ;
2813
2808
nrf_timer_cc_write (NRF_TIMER1 , NRF_TIMER_CC_CHANNEL0 , (uint32_t )period );
2814
2809
}
2815
2810
}
2816
2811
2817
2812
/// Start the timer and get it to interrupt after 'period'
2818
2813
void jshUtilTimerStart (JsSysTime period ) {
2819
- if (utilTimerActive ) {
2820
- // schedule at the current time + period
2821
- // by pretending that the last time we wanted to be called at is now
2822
- NRF_TIMER1 -> TASKS_CAPTURE [1 ] = 1 ; // get current timer value
2823
- utilTimerTriggerTime = NRF_TIMER1 -> CC [1 ];
2824
- }
2825
2814
jshUtilTimerReschedule (period );
2826
2815
if (!utilTimerActive ) {
2827
2816
utilTimerActive = true;
0 commit comments