Skip to content

Commit 5570bfb

Browse files
committed
Revert "nRF52: Further improve software timer accuracy"
This causes Puck.IR to fail as per https://github.com/orgs/espruino/discussions/7774 This reverts commit b4543cb.
1 parent c1be967 commit 5570bfb

File tree

1 file changed

+20
-31
lines changed

1 file changed

+20
-31
lines changed

targets/nrf5x/jshardware.c

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,14 +2765,13 @@ bool jshSleep(JsSysTime timeUntilWake) {
27652765
return true;
27662766
}
27672767

2768-
volatile bool utilTimerActive = false;
2769-
volatile uint32_t utilTimerTriggerTime = 0;
2768+
bool utilTimerActive = false;
27702769

27712770
/// Reschedule the timer (it should already be running) to interrupt after 'period'
27722771
void jshUtilTimerReschedule(JsSysTime period) {
27732772
if (period < JSSYSTIME_MAX / NRF_TIMER_FREQ) {
27742773
period = period * NRF_TIMER_FREQ / (long long)SYSCLK_FREQ;
2775-
if (period < 0) period=0;
2774+
if (period < 1) period=1;
27762775
if (period > NRF_TIMER_MAX) period=NRF_TIMER_MAX;
27772776
} else {
27782777
// it's too big to do maths on... let's just use the maximum period
@@ -2783,45 +2782,35 @@ void jshUtilTimerReschedule(JsSysTime period) {
27832782
/* Setting the timer is complicated because the compare register only compares for equality,
27842783
so if we set the compare register even 1 less than the current timer it won't fire for 2^32 microsec
27852784
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.
27882787
*/
27892788
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);
27902791
// 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);
28102806
} else {
28112807
// timer is off, it'll be cleared to literally just set the period
2812-
utilTimerTriggerTime = period;
28132808
nrf_timer_cc_write(NRF_TIMER1, NRF_TIMER_CC_CHANNEL0, (uint32_t)period);
28142809
}
28152810
}
28162811

28172812
/// Start the timer and get it to interrupt after 'period'
28182813
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-
}
28252814
jshUtilTimerReschedule(period);
28262815
if (!utilTimerActive) {
28272816
utilTimerActive = true;

0 commit comments

Comments
 (0)