diff options
author | David Phillips <david@yeah.nah.nz> | 2020-12-13 16:35:58 +1300 |
---|---|---|
committer | David Phillips <david@yeah.nah.nz> | 2020-12-13 20:42:33 +1300 |
commit | 7e26f31e221665ee059b02fc6beda025d39d6e75 (patch) | |
tree | 1a5f66e12680778b001f3cb1d2c49b0f2ce0f04c /altimeter.c | |
download | altimeter-7e26f31e221665ee059b02fc6beda025d39d6e75.tar.xz |
Initial prototype
This patch adds a skeleton of AVR code for a "simulator" target (atmega2560)
and for the real intended hardware target (atmega32u4). The simulator target
is one that is supported by the QEMU AVR emulator, while the 32u4 is currently
not.
Diffstat (limited to 'altimeter.c')
-rw-r--r-- | altimeter.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/altimeter.c b/altimeter.c new file mode 100644 index 0000000..2aef956 --- /dev/null +++ b/altimeter.c @@ -0,0 +1,100 @@ +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <avr/sleep.h> +#include <avr/interrupt.h> + +#include "barometer.h" +#include "display.h" +#include "util.h" + +/* ISR for collecting and displaying pressure, altitude data etc */ +ISR(TIMER1_COMPA_vect) +{ + PORTD ^= 1 << 5; + int tcnt1_start = TCNT1; + static volatile float setting = 1040.21; /* FIXME volatile for gdb hacks */ + static float last_height = 0; + float pressure = 0; + float height_m = 0; + float rate_m_s; + char rate_sym; + pressure = barometer_read(); + height_m = pressure_to_metres_asl(pressure, setting); + rate_m_s = height_m - last_height; + last_height = height_m; + + if (rate_m_s < 0) { + rate_sym = C_DESC; + } else if (rate_m_s == 0) { + rate_sym = C_IDLE; + } else { + rate_sym = C_ASC; + } + + char line[LCD_WIDTH+1]; + /* line 1 */ + int alt_m_int; + float alt_m_float; + split_float(height_m, &alt_m_int, &alt_m_float); + snprintf(line, sizeof(line), "%d.%d m %c%d m/s", alt_m_int, (int)(round(alt_m_float*10)), rate_sym, abs(rate_m_s)); + blank_to_eol(line, sizeof(line)); + display_set_cursor(0, 0); + display_write(line); + + + /* line 2 */ + int pressure_hpa_int; + float pressure_hpa_float; + split_float(pressure, &pressure_hpa_int, &pressure_hpa_float); + snprintf(line, sizeof(line), "%d.%d hPa", pressure_hpa_int, (int)(round(pressure_hpa_float*100))); + blank_to_eol(line, sizeof(line)); + display_set_cursor(0, 1); + display_write(line); + + /* line 3 */ + int setting_hpa_int; + float setting_hpa_float; + split_float(setting, &setting_hpa_int, &setting_hpa_float); + snprintf(line, sizeof(line), "SET %d.%d hPa", setting_hpa_int, (int)(round(setting_hpa_float*100))); + blank_to_eol(line, sizeof(line)); + display_set_cursor(0, 2); + display_write(line); + + int tcnt1_end = TCNT1; + /* line 4 */ + snprintf(line, sizeof(line), "TCNT1 delta %u", tcnt1_end - tcnt1_start); + blank_to_eol(line, sizeof(line)); + display_set_cursor(0, 3); + display_write(line); + return; +} + +int main(void) +{ + /* Initialise display before enabling interrupts */ + display_init(); + display_clear(); + + DDRB |= 1 << 0; + DDRD |= 1 << 5; + + /* Initialise timers for /1024 prescaler, 1 Hz comparator val */ + TCCR1B |= (1 << CS10) | (1 << CS12) | (1 << WGM12); + TIMSK1 |= (1 << OCIE1A); + OCR1A = 15624; + +#ifdef USBCON + /* Disable USB controller if one is present - this spams (latches?) USB_GEN + * interrupt which we're not handling for now */ + USBCON &= ~(1 << USBE); +#endif + + sei(); + while(1) { + set_sleep_mode(SLEEP_MODE_IDLE); + sleep_mode(); + } +} |