summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/timer.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-10-04 14:59:35 +0100
committerDamien George <damien.p.george@gmail.com>2014-10-05 17:52:45 +0100
commit55f68b3ce809cb6331fb500fa10331b16cbc6c13 (patch)
tree780f3f59afa5e8a56789a146c20380017123aa16 /stmhal/timer.c
parent97ef94df83238e58fd7a084c3ca0e8af164136e0 (diff)
downloadmicropython-55f68b3ce809cb6331fb500fa10331b16cbc6c13.tar.gz
micropython-55f68b3ce809cb6331fb500fa10331b16cbc6c13.zip
stmhal, timer: Improve accuracy of freq computation.
Diffstat (limited to 'stmhal/timer.c')
-rw-r--r--stmhal/timer.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/stmhal/timer.c b/stmhal/timer.c
index 3465003135..1a4fd66ea1 100644
--- a/stmhal/timer.c
+++ b/stmhal/timer.c
@@ -307,7 +307,11 @@ STATIC uint32_t compute_prescaler_period_from_freq(pyb_timer_obj_t *self, mp_obj
if (freq <= 0) {
goto bad_freq;
}
- period = MAX(1, source_freq / freq);
+ while (freq < 1 && prescaler < 6553) {
+ prescaler *= 10;
+ freq *= 10;
+ }
+ period = (float)source_freq / freq;
#endif
} else {
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
bad_freq:
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "must have positive freq"));
}
- period = MAX(1, source_freq / freq);
+ period = source_freq / freq;
}
+ period = MAX(1, period);
while (period > TIMER_CNT_MASK(self)) {
- prescaler <<= 1;
- period >>= 1;
+ // if we can divide exactly, do that first
+ if (period % 5 == 0) {
+ prescaler *= 5;
+ period /= 5;
+ } else if (period % 3 == 0) {
+ prescaler *= 3;
+ period /= 3;
+ } else {
+ // may not divide exactly, but loses minimal precision
+ prescaler <<= 1;
+ period >>= 1;
+ }
}
*period_out = (period - 1) & TIMER_CNT_MASK(self);
return (prescaler - 1) & 0xffff;