From bc524878fc0ca1592e5f257bfe5dc094c470f061 Mon Sep 17 00:00:00 2001 From: Matthias Blankertz Date: Thu, 8 Jun 2023 18:17:23 +0200 Subject: [PATCH] Add pitch mode properly, add boot to bootloader, refactor rotary_event and friends --- src/main.c | 168 +++++++++++++++++++++++++------------------------ src/sevenseg.c | 22 +++++-- src/sevenseg.h | 2 + 3 files changed, 104 insertions(+), 88 deletions(-) diff --git a/src/main.c b/src/main.c index f72f010..c9d0e0a 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include "usb_config.h" @@ -16,19 +17,17 @@ PIO pio = pio0; static void hid_task(void); // USB report structs -__attribute__((packed)) struct light_data { - uint8_t leds[16]; -}; - __attribute__((packed)) struct button_report { uint32_t buttons; }; #define APP_MODE_MASK 0x0f #define APP_FLAG_MACH 0x10 +#define APP_FLAG_PITCH 0x20 #define APP_UPDATE 0 #define APP_INIT 1 +#define APP_BOOTLOADER 2 // request to reboot to bootloader __attribute__((packed)) struct app_report { uint8_t type; @@ -49,10 +48,9 @@ __attribute__((packed)) struct app_report { }; }; -static struct light_data the_light_data; - -static bool show_vs = false, show_as = false; +static bool show_vs = false, show_as = false, show_hdg = true, show_alt = true; static bool mach_mode = false; +static bool pitch_mode = false; static volatile unsigned hdg = 0; static volatile unsigned alt = 0; @@ -64,49 +62,66 @@ static int min_as = 0, max_as = 999, max_mach = 990; #define BUTTON_HDG_SYNC 1 #define BUTTON_ALT_SYNC 7 +static void render_uint(int start, int len, unsigned val, bool leading_zeros) +{ + const int end = start + len - 1; + for (int i = 0; i < len; ++i) { + if (val || i == 0 || leading_zeros) + sevenseg_set_digit(end - i, val % 10); + else + sevenseg_set_digit(end - i, LED_BLANK); + val /= 10; + } +} + +static void render_blank(int start, int len) +{ + for (int i = 0; i < len; ++i) { + sevenseg_set_digit(start + i, LED_BLANK); + } +} + static void update_hdg_display(void) { - sevenseg_set_digit(0, hdg / 100); - sevenseg_set_digit(1, hdg / 10 % 10); - sevenseg_set_digit(2, hdg % 10); + if (show_hdg) { + render_uint(0, 3, hdg, true); + } else { + render_blank(0, 3); + } } static void update_alt_display(void) { - int val = alt; - for (int i = 0; i < 5; ++i) { - if (val || i == 0) - sevenseg_set_digit(7 - i, val % 10); - else - sevenseg_set_digit(7 - i, LED_BLANK); - val /= 10; + if (show_alt) { + render_uint(3, 5, alt, false); + } else { + render_blank(3, 5); } } static void update_vs_display(void) { - if (show_vs) { + if (pitch_mode) { int val = vs; - unsigned val_abs = val < 0 ? -val : val; - for (int i = 0; i < 3; ++i) { - if (val_abs || i == 0) { - sevenseg_set_digit(11 - i, val_abs % 10); - } else { - sevenseg_set_digit(11 - i, LED_BLANK); - } - val_abs /= 10; - } - if (val >= 1000 || val <= -1000) { - sevenseg_set_digit(8, (val_abs % 10) | (val < 0 ? LED_DECIMAL : 0)); - } else if (val < 0) { + unsigned int val_abs = val < 0 ? -val : val; + if (val < 0) { sevenseg_set_digit(8, LED_MINUS); } else { sevenseg_set_digit(8, LED_BLANK); } - } else { - for (int i = 0; i < 4; ++i) { - sevenseg_set_digit(11 - i, LED_BLANK); + render_uint(9, 2, val_abs, false); + sevenseg_set_digit(11, LED_DEGREE); + } else if (show_vs) { + int val = vs; + unsigned val_abs = val < 0 ? -val : val; + render_uint(8, 4, val_abs, false); + if (val >= 1000 || val <= -1000) { + sevenseg_mod_digit(8, val < 0 ? LED_DECIMAL : 0); + } else if (val < 0) { + sevenseg_set_digit(8, LED_MINUS); } + } else { + render_blank(8, 4); } } @@ -116,74 +131,50 @@ static void update_as_display(void) int val = as; if (mach_mode) { sevenseg_set_digit(12, 0 | LED_DECIMAL); - for (int i = 0; i < 3; ++i) { - sevenseg_set_digit(15 - i, val % 10); - val /= 10; - } + render_uint(13, 3, val, true); } else { - for (int i = 0; i < 4; ++i) { - if (val || i == 0) - sevenseg_set_digit(15 - i, val % 10); - else - sevenseg_set_digit(15 - i, LED_BLANK); - val /= 10; - } + render_uint(12, 4, val, false); } } else { - for (int i = 0; i < 4; ++i) { - sevenseg_set_digit(15 - i, LED_BLANK); - } + render_blank(12, 4); } } -static int16_t clamp(int16_t cur, int16_t min, int16_t max) +static int crement_val(bool inc, int val, int min, int max, int step, bool wrap) { - return cur >= min ? (cur <= max ? cur : max) : min; + // round to step in correct direction + if (inc) { + val = ((val - step + 1) / step) * step; + } else { + val = ((val + step - 1) / step) * step; + } + if (inc) { + return val >= max - step + 1 ? (wrap ? min : max) : val + step; + } else { + return val <= min + step ? (wrap ? max : min) : val - step; + } } void rotary_event(int rot_ch, bool ccw) { - /* if (ccw) */ - /* rotary_events = (rotary_events & ~(0x3<<(rot_ch*2))) | (0x1<<(rot_ch*2)); */ - /* else */ - /* rotary_events = (rotary_events & ~(0x3<<(rot_ch*2))) | (0x3<<(rot_ch*2)); */ - /* rotary_events |= 1<<(rot_ch*2 + ccw); */ - /* sevenseg_set_digit(0, rot_ch); */ - /* sevenseg_set_digit(1, ccw); */ if (rot_ch == 3) { - if (ccw) { - hdg = hdg == 0 ? 359 : hdg - 1; - } else { - hdg = hdg == 359 ? 0 : hdg + 1; - } + hdg = crement_val(!ccw, hdg, 0, 359, 1, true); update_hdg_display(); } else if (rot_ch == 2) { - if (ccw) { - alt = alt == 0 ? 0 : ((alt + 99) / 100) * 100 - 100; - } else { - alt = alt == 50000 ? 50000 : (alt / 100) * 100 + 100; - } + alt = crement_val(!ccw, alt, 0, 50000, 100, false); update_alt_display(); } else if (rot_ch == 1) { - if (ccw) { - vs = vs == -5000 ? -5000 : ((vs < 0 ? vs : vs + 99) / 100) * 100 - 100; + if (pitch_mode) { + vs = crement_val(!ccw, vs, -20, 20, 1, false); } else { - vs = vs == 5000 ? 5000 : ((vs > 0 ? vs : vs - 99) / 100) * 100 + 100; + vs = crement_val(!ccw, vs, -5000, 5000, 100, false); } update_vs_display(); } else { if (mach_mode) { - if (ccw) { - as = clamp(((as + 9) / 10) * 10 - 10, 0, max_mach); - } else { - as = clamp((as / 10) * 10 + 10, 0, max_mach); - } + as = crement_val(!ccw, as, 0, 990, 10, false); } else { - if (ccw) { - as = clamp(as - 1, min_as, max_as); - } else { - as = clamp(as + 1, min_as, max_as); - } + as = crement_val(!ccw, as, min_as, max_as, 1, false); } update_as_display(); } @@ -205,6 +196,7 @@ int main() update_as_display(); irq_set_enabled(PIO0_IRQ_1, true); + statusleds_set(0); printf("Hello, world!\n"); while (1) { @@ -266,15 +258,24 @@ static void hid_task(void) static void app_update_report(struct app_report const *report) { mach_mode = report->type & APP_FLAG_MACH; + pitch_mode = report->type & APP_FLAG_PITCH; if (report->update.hdg >= 0) { hdg = report->update.hdg; update_hdg_display(); send_heading_reports = true; + show_hdg = true; + } else if (report->update.hdg == -2) { + show_hdg = false; } if (report->update.alt != 0xffff) { - alt = report->update.alt; - update_alt_display(); - send_alt_reports = true; + if (report->update.alt == 0xfffe) { + show_alt = false; + } else { + alt = report->update.alt; + update_alt_display(); + send_alt_reports = true; + show_alt = true; + } } if (report->update.vs != -1) { if (report->update.vs == -2) { @@ -328,6 +329,9 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_ case APP_INIT: app_init_report(&report); break; + case APP_BOOTLOADER: + reset_usb_boot(0, 0); + break; default: break; } diff --git a/src/sevenseg.c b/src/sevenseg.c index c915cba..71487cb 100644 --- a/src/sevenseg.c +++ b/src/sevenseg.c @@ -29,9 +29,8 @@ static void txnfull_isr(void) } } -static const uint8_t digit_row_map[NUM_DIGITS] = { - 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x58, 0x5e, 0x79, 0x71, 0x00, 0x40, -}; +static const uint8_t digit_row_map[NUM_DIGITS] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, + 0x77, 0x7c, 0x58, 0x5e, 0x79, 0x71, 0x00, 0x40, 0x63 }; void sevenseg_set_digit(int index, enum sevenseg_digits digit) { @@ -50,6 +49,15 @@ void sevenseg_set_digit(int index, enum sevenseg_digits digit) } } +void sevenseg_mod_digit(int index, enum sevenseg_digits digit) +{ + if (digit & LED_DECIMAL) { + row_vals[7] |= (1 << index); + } else { + row_vals[7] &= ~(1 << index); + } +} + void sevenseg_init(void) { uint offset = pio_add_program(pio, &sevenseg_program); @@ -59,13 +67,15 @@ void sevenseg_init(void) sm_config_set_sideset_pins(&c, SEVENSEG_SCLK_PIN); sm_config_set_out_shift(&c, false, false, 24); sm_config_set_clkdiv(&c, 245.28f); // 20 kHz refresh cycle, 53 pio instrs/cycle - pio_sm_set_pindirs_with_mask(pio, sm, (1u << SEVENSEG_SDO_PIN) | (1u << SEVENSEG_SCLK_PIN) | (1u << SEVENSEG_FCLK_PIN) | (1u << SEVENSEG_OE_PIN), - (1u << SEVENSEG_SDO_PIN) | (1u << SEVENSEG_SCLK_PIN) | (1u << SEVENSEG_FCLK_PIN) | (1u << SEVENSEG_OE_PIN)); + pio_sm_set_pindirs_with_mask( + pio, sm, + (1u << SEVENSEG_SDO_PIN) | (1u << SEVENSEG_SCLK_PIN) | (1u << SEVENSEG_FCLK_PIN) | (1u << SEVENSEG_OE_PIN), + (1u << SEVENSEG_SDO_PIN) | (1u << SEVENSEG_SCLK_PIN) | (1u << SEVENSEG_FCLK_PIN) | (1u << SEVENSEG_OE_PIN)); pio_gpio_init(pio, SEVENSEG_SDO_PIN); pio_gpio_init(pio, SEVENSEG_SCLK_PIN); pio_gpio_init(pio, SEVENSEG_FCLK_PIN); pio_gpio_init(pio, SEVENSEG_OE_PIN); - pio_set_irq0_source_enabled(pio, PIO_INTR_SM0_TXNFULL_LSB+sm, true); + pio_set_irq0_source_enabled(pio, PIO_INTR_SM0_TXNFULL_LSB + sm, true); irq_set_exclusive_handler(PIO0_IRQ_0, &txnfull_isr); irq_set_enabled(PIO0_IRQ_0, true); pio_sm_init(pio, sm, offset, &c); diff --git a/src/sevenseg.h b/src/sevenseg.h index 33846ca..5b41676 100644 --- a/src/sevenseg.h +++ b/src/sevenseg.h @@ -19,10 +19,12 @@ enum sevenseg_digits { LED_F, LED_BLANK, LED_MINUS, + LED_DEGREE, NUM_DIGITS, LED_DECIMAL = 0x100, }; void sevenseg_set_digit(int index, enum sevenseg_digits digit); +void sevenseg_mod_digit(int index, enum sevenseg_digits digit); void sevenseg_init(void);