diff options
author | Keith Packard <keithp@keithp.com> | 2019-05-03 21:51:28 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2019-05-03 21:51:28 -0700 |
commit | a6e8b739c47c50fa472e3f2a41cf13abb8d82c07 (patch) | |
tree | 451161e26210144182043a52ea6dafe4ddadb04b /src | |
parent | 1d3a8443d8de832b8e76a005e56ac5ff09b71849 (diff) |
altos: Directly compute radio tuning values from frequency
The 8051 compiler doesn't support 64-bit ints, so the old
code used an iterative method in 32-bit values. That could take
a long time when the frequency was mis-entered in Hz or MHz instead of
kHz.
This direct-computation uses 64-bit ints, but takes a fixed amount of
time for any inputs.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/ao_freq.c | 42 |
1 files changed, 15 insertions, 27 deletions
diff --git a/src/kernel/ao_freq.c b/src/kernel/ao_freq.c index 81640ce8..5a701b91 100644 --- a/src/kernel/ao_freq.c +++ b/src/kernel/ao_freq.c @@ -21,36 +21,24 @@ /* * The provided 'calibration' value is * that needed to tune the radio to precisely 434550kHz. - * Use that to 'walk' to the target frequency by following - * a 'bresenham' line from 434550kHz to the target - * frequency, and updating the radio setting along the way + * The relation between value and freq is linear, so + * to get the value for an arbitrary frequency: + * + * target_value target_freq + * ------------ = ------------ + * cal_value cal_freq + * + * cal_value * target_freq + * target_value = ----------------------- + * cal_freq */ -int32_t ao_freq_to_set(int32_t freq, int32_t cal) +int32_t ao_freq_to_set(int32_t target_freq, int32_t cal_value) { - static int32_t set; - static uint8_t neg; - static int32_t error; + int64_t prod = (int64_t) target_freq * (int64_t) cal_value; - set = 0; - neg = 0; - error = -434550 / 2; + /* Round to nearest */ + int32_t target_value = (prod + (434550 / 2)) / 434550; - if ((freq -= 434550) < 0) { - neg = 1; - freq = -freq; - } - for (;;) { - if (error > 0) { - error -= 434550; - set++; - } else { - error += cal; - if (--freq < 0) - break; - } - } - if (neg) - set = -set; - return cal + set; + return target_value; } |