diff options
author | David Phillips <david@yeah.nah.nz> | 2021-02-20 17:43:24 +1300 |
---|---|---|
committer | David Phillips <david@yeah.nah.nz> | 2021-02-27 21:54:56 +1300 |
commit | 27d6d2fc5a1647395a7a9074faf8362d6d0c358a (patch) | |
tree | 81f81c6b4a5a835e01968e0059271bb90c3768ab /timer.c | |
parent | e843e9da835f058e09810cfeba7c60d0b270e7b3 (diff) | |
download | altimeter-27d6d2fc5a1647395a7a9074faf8362d6d0c358a.tar.xz |
Use more generic interface for barometer and timer
This patch abstracts the global symbols for getting barometer readings behind
a "struct of function pointers" interface as popular in Linux Kernel, U-Boot
and others. This means that unit testing can take place with mocked hardware
peripherals. The old "global" drivers are still available, behind explicit
function calls required to access the now-static functions.
This patch also introduces a timer peripheral software module with the same
model, to support future unit testing of altitude rate etc.
Diffstat (limited to 'timer.c')
-rw-r--r-- | timer.c | 47 |
1 files changed, 47 insertions, 0 deletions
@@ -0,0 +1,47 @@ +#include <avr/io.h> +#include <stdint.h> + +#include "timer.h" + +/* On AVR, two 16-bit timers are used: + * timer1 for emitting a low frequency IRQ to update the display + * timer3 freerunning quickly for timestamping purposes + * + * XXX note: most of the functions in this module must be called with + * interrupts already disabled in order to be safe + */ + +/* XXX hardcoded based upon TCCR3B selecting /256 prescaled clock */ +#define TIMER_HZ (F_CPU / 256) + +static void timer_init(void) +{ + /* timer1 has /1024 prescaler, 1 Hz comparator val, enable IRQ */ + TCCR1B |= (1 << CS10) | (1 << CS12) | (1 << WGM12); + TIMSK1 |= (1 << OCIE1A); + OCR1A = F_CPU / 1024; + + /* timer3 has /256 prescaler, no comparartor (free-running with overflow) + * and no IRQ enabled. /256 chosen so that the counter doesn't overflow + * within a 1 second window */ + + TCCR3B |= (1 << CS32); +} + +static float timer_stamps_to_seconds(uint16_t start, uint16_t end) +{ + return (float)(end - start) / TIMER_HZ; +} + +static uint16_t timer_get_value(void) +{ + return TCNT3; +} + +/**/ + +void get_system_timer(struct timer *timer) +{ + timer->init = timer_init; + timer->get_time = timer_get_value; +} |