Skip to content

Commit 55f68b3

Browse files
committed
stmhal, timer: Improve accuracy of freq computation.
1 parent 97ef94d commit 55f68b3

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

stmhal/timer.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,11 @@ STATIC uint32_t compute_prescaler_period_from_freq(pyb_timer_obj_t *self, mp_obj
307307
if (freq <= 0) {
308308
goto bad_freq;
309309
}
310-
period = MAX(1, source_freq / freq);
310+
while (freq < 1 && prescaler < 6553) {
311+
prescaler *= 10;
312+
freq *= 10;
313+
}
314+
period = (float)source_freq / freq;
311315
#endif
312316
} else {
313317
mp_int_t freq = mp_obj_get_int(freq_in);
@@ -316,11 +320,22 @@ STATIC uint32_t compute_prescaler_period_from_freq(pyb_timer_obj_t *self, mp_obj
316320
bad_freq:
317321
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "must have positive freq"));
318322
}
319-
period = MAX(1, source_freq / freq);
323+
period = source_freq / freq;
320324
}
325+
period = MAX(1, period);
321326
while (period > TIMER_CNT_MASK(self)) {
322-
prescaler <<= 1;
323-
period >>= 1;
327+
// if we can divide exactly, do that first
328+
if (period % 5 == 0) {
329+
prescaler *= 5;
330+
period /= 5;
331+
} else if (period % 3 == 0) {
332+
prescaler *= 3;
333+
period /= 3;
334+
} else {
335+
// may not divide exactly, but loses minimal precision
336+
prescaler <<= 1;
337+
period >>= 1;
338+
}
324339
}
325340
*period_out = (period - 1) & TIMER_CNT_MASK(self);
326341
return (prescaler - 1) & 0xffff;

0 commit comments

Comments
 (0)