summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2019-05-03 21:51:28 -0700
committerKeith Packard <keithp@keithp.com>2019-05-03 21:51:28 -0700
commita6e8b739c47c50fa472e3f2a41cf13abb8d82c07 (patch)
tree451161e26210144182043a52ea6dafe4ddadb04b /src
parent1d3a8443d8de832b8e76a005e56ac5ff09b71849 (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.c42
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;
}