*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
/*
* 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) __reentrant
+uint32_t ao_freq_to_set(uint32_t target_freq, uint32_t cal_value)
{
- static __pdata int32_t set;
- static __pdata uint8_t neg;
- static __pdata int32_t error;
+ uint64_t prod = (uint64_t) target_freq * (uint64_t) cal_value;
- set = 0;
- neg = 0;
- error = -434550 / 2;
+ /* Round to nearest */
+ uint32_t target_value = (uint32_t) ((prod + (434550U / 2U)) / 434550U);
- 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;
}