aboutsummaryrefslogtreecommitdiff
path: root/altimeter.c
diff options
context:
space:
mode:
authorDavid Phillips <david@yeah.nah.nz>2020-12-13 16:35:58 +1300
committerDavid Phillips <david@yeah.nah.nz>2020-12-13 20:42:33 +1300
commit7e26f31e221665ee059b02fc6beda025d39d6e75 (patch)
tree1a5f66e12680778b001f3cb1d2c49b0f2ce0f04c /altimeter.c
downloadaltimeter-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.c100
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();
+ }
+}