X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Ftelelco-v3.0%2Fao_lco_v3.c;h=2055701b7eb48f7c1a5b27b45d67a6909e7195c3;hb=f9103d13f620cb06642aacdff9dcaf05e87d671f;hp=90334602fd2f9cfdacc3847d2fca47291423be03;hpb=31756e065828ca5c1779f1349c38d29196f4798d;p=fw%2Faltos diff --git a/src/telelco-v3.0/ao_lco_v3.c b/src/telelco-v3.0/ao_lco_v3.c index 90334602..2055701b 100644 --- a/src/telelco-v3.0/ao_lco_v3.c +++ b/src/telelco-v3.0/ao_lco_v3.c @@ -21,6 +21,67 @@ #include #include #include +#include +#include +#include + +#define WIDTH AO_ST7565_WIDTH +#define HEIGHT AO_ST7565_HEIGHT +#define STRIDE AO_BITMAP_STRIDE(WIDTH) + +static uint32_t image[STRIDE * HEIGHT]; + +static struct ao_bitmap fb = { + .base = image, + .stride = STRIDE, + .width = WIDTH, + .height = HEIGHT, + .damage = AO_BOX_INIT, +}; + +static const struct ao_transform logo_transform = { + .x_scale = 48, .x_off = 2, + .y_scale = 48, .y_off = 0, +}; + +static const struct ao_transform show_transform = { + .x_scale = 36, .x_off = 100, + .y_scale = 36, .y_off = 0, +}; + +#define BIG_FONT BitstreamVeraSans_Roman_58_font +#define VOLT_FONT BitstreamVeraSans_Roman_58_font +#define SMALL_FONT BitstreamVeraSans_Roman_12_font +#define TINY_FONT BitstreamVeraSans_Roman_10_font +#define LOGO_FONT BenguiatGothicStd_Bold_26_font + +#define LABEL_Y (int16_t) (SMALL_FONT.ascent) +#define VALUE_Y (int16_t) (LABEL_Y + BIG_FONT.ascent + 5) +#define BOX_X 2 +#define PAD_X 90 +#define BOX_LABEL_X 30 +#define VOLT_LABEL_X 25 +#define RSSI_LABEL_X 15 +#define PAD_LABEL_X 95 +#define SEP_X (PAD_X - 8) +#define SCAN_X (WIDTH - 100) / 2 +#define SCAN_Y 50 +#define SCAN_HEIGHT 3 +#define FOUND_Y 63 +#define FOUND_X 6 +#define FOUND_WIDTH (WIDTH - 6) +#define CONTRAST_LABEL_X 37 +#define CONTRAST_WIDTH 100 +#define CONTRAST_X (WIDTH - CONTRAST_WIDTH) / 2 +#define CONTRAST_Y 20 +#define CONTRAST_HEIGHT 20 +#define BACKLIGHT_LABEL_X 37 +#define BACKLIGHT_WIDTH 100 +#define BACKLIGHT_X (WIDTH - BACKLIGHT_WIDTH) / 2 +#define BACKLIGHT_Y 20 +#define BACKLIGHT_HEIGHT 20 +#define INFO_START_Y ((int16_t) (SMALL_FONT.ascent + 2)) +#define INFO_STEP_Y ((int16_t) (SMALL_FONT.ascent + 3)) #define AO_LCO_DRAG_RACE_START_TIME AO_SEC_TO_TICKS(5) #define AO_LCO_DRAG_RACE_STOP_TIME AO_SEC_TO_TICKS(2) @@ -35,60 +96,127 @@ static uint8_t ao_lco_event_debug; static uint8_t ao_lco_display_mutex; -void -ao_lco_show_pad(uint8_t pad) +static void +_ao_lco_show_pad(uint8_t pad) { - ao_mutex_get(&ao_lco_display_mutex); - (void) pad; -// ao_seven_segment_set(AO_LCO_PAD_DIGIT, (uint8_t) (pad | (ao_lco_drag_race << 4))); - ao_mutex_put(&ao_lco_display_mutex); + char str[5]; + + snprintf(str, sizeof(str), "%d", pad); + ao_text(&fb, &BIG_FONT, PAD_X, VALUE_Y, str, AO_BLACK, AO_COPY); + ao_text(&fb, &SMALL_FONT, PAD_LABEL_X, LABEL_Y, "Pad", AO_BLACK, AO_COPY); } -void -ao_lco_show_box(uint16_t box) + +static void +_ao_lco_show_box(int16_t box) { - ao_mutex_get(&ao_lco_display_mutex); - (void) box; -// ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, (uint8_t) (box % 10 | (ao_lco_drag_race << 4))); -// ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, (uint8_t) (box / 10 | (ao_lco_drag_race << 4))); - ao_mutex_put(&ao_lco_display_mutex); + char str[7]; + + snprintf(str, sizeof(str), "%2d", box); + ao_text(&fb, &BIG_FONT, BOX_X, VALUE_Y, str, AO_BLACK, AO_COPY); + ao_text(&fb, &SMALL_FONT, BOX_LABEL_X, LABEL_Y, "Box", AO_BLACK, AO_COPY); } static void -ao_lco_show_voltage(uint16_t decivolts) +_ao_lco_show_voltage(uint16_t decivolts, const char *label) { - uint8_t tens, ones, tenths; + char str[7]; PRINTD("voltage %d\n", decivolts); - tenths = (uint8_t) (decivolts % 10); - ones = (uint8_t) ((decivolts / 10) % 10); - tens = (uint8_t) ((decivolts / 100) % 10); - ao_mutex_get(&ao_lco_display_mutex); - (void) tenths; - (void) ones; - (void) tens; -// ao_seven_segment_set(AO_LCO_PAD_DIGIT, tenths); -// ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, ones | 0x10); -// ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, tens); - ao_mutex_put(&ao_lco_display_mutex); + snprintf(str, sizeof(str), "%2d.%d", decivolts / 10, decivolts % 10); + ao_text(&fb, &VOLT_FONT, BOX_X, VALUE_Y, str, AO_BLACK, AO_COPY); + ao_text(&fb, &SMALL_FONT, VOLT_LABEL_X, LABEL_Y, label, AO_BLACK, AO_COPY); } -void -ao_lco_show(void) +static void +_ao_lco_batt_voltage(void) { - if (ao_lco_pad == AO_LCO_PAD_VOLTAGE) { - ao_lco_show_voltage(ao_pad_query.battery); - } else { - ao_lco_show_pad(ao_lco_pad); - ao_lco_show_box(ao_lco_box); - } + struct ao_adc packet; + int16_t decivolt; + + ao_adc_single_get(&packet); + decivolt = ao_battery_decivolt(packet.v_batt); + _ao_lco_show_voltage((uint16_t) decivolt, "LCO battery"); + ao_st7565_update(&fb); +} + +static void +_ao_lco_show_contrast(void) +{ + uint8_t brightness = ao_st7565_get_brightness(); + int16_t contrast = (int16_t) (brightness * CONTRAST_WIDTH / AO_LCO_MAX_CONTRAST); + + ao_text(&fb, &SMALL_FONT, CONTRAST_LABEL_X, LABEL_Y, "Contrast", AO_BLACK, AO_COPY); + ao_rect(&fb, CONTRAST_X, CONTRAST_Y, contrast, CONTRAST_HEIGHT, AO_BLACK, AO_COPY); +} + +static void +_ao_lco_show_backlight(void) +{ + int32_t backlight = ao_lco_get_backlight(); + int16_t value = (int16_t) (backlight * BACKLIGHT_WIDTH / AO_LCO_MAX_BACKLIGHT); + + ao_text(&fb, &SMALL_FONT, BACKLIGHT_LABEL_X, LABEL_Y, "Backlight", AO_BLACK, AO_COPY); + ao_rect(&fb, BACKLIGHT_X, BACKLIGHT_Y, value, BACKLIGHT_HEIGHT, AO_BLACK, AO_COPY); +} + +static int16_t info_y; + +static void +_ao_lco_info(const char *format, ...) +{ + va_list a; + char buf[20]; + va_start(a, format); + vsnprintf(buf, sizeof(buf), format, a); + va_end(a); + ao_text(&fb, &SMALL_FONT, 0, info_y, buf, AO_BLACK, AO_COPY); + info_y += INFO_STEP_Y; +} + +static void +_ao_lco_show_info(void) +{ + info_y = INFO_START_Y; + ao_logo_poly(&fb, &show_transform, AO_BLACK, AO_COPY); + _ao_lco_info("%s", ao_product); + _ao_lco_info("Version: %s", ao_version); + _ao_lco_info("Serial: %d", ao_serial_number); + _ao_lco_info("Callsign: %s", ao_config.callsign); + _ao_lco_info("Frequency: %ld.%03d", + ao_config.frequency / 1000, + (int) (ao_config.frequency % 1000)); } -uint8_t -ao_lco_box_present(uint16_t box) +void +ao_lco_show(void) { - if (box >= AO_PAD_MAX_BOXES) - return 0; - return (ao_lco_box_mask[AO_LCO_MASK_ID(box)] >> AO_LCO_MASK_SHIFT(box)) & 1; + ao_mutex_get(&ao_lco_display_mutex); + ao_rect(&fb, 0, 0, WIDTH, HEIGHT, AO_WHITE, AO_COPY); + switch (ao_lco_box) { + case AO_LCO_LCO_VOLTAGE: + _ao_lco_batt_voltage(); + break; + case AO_LCO_CONTRAST: + _ao_lco_show_contrast(); + break; + case AO_LCO_BACKLIGHT: + _ao_lco_show_backlight(); + break; + case AO_LCO_INFO: + _ao_lco_show_info(); + break; + default: + if (ao_lco_pad == AO_LCO_PAD_VOLTAGE) { + _ao_lco_show_voltage(ao_pad_query.battery, "Pad battery"); + } else { + _ao_lco_show_pad(ao_lco_pad); + _ao_lco_show_box(ao_lco_box); + ao_rect(&fb, SEP_X, 0, 2, HEIGHT, AO_BLACK, AO_COPY); + } + break; + } + ao_st7565_update(&fb); + ao_mutex_put(&ao_lco_display_mutex); } static void @@ -113,21 +241,32 @@ ao_lco_set_select(void) } } -static void -ao_lco_step_box(int8_t dir) + +void +ao_lco_set_contrast(int32_t contrast) { - int32_t new_box = (int32_t) ao_lco_box; - - do { - new_box += dir; - if (new_box > ao_lco_max_box) - new_box = ao_lco_min_box; - else if (new_box < ao_lco_min_box) - new_box = ao_lco_max_box; - if (new_box == ao_lco_box) - break; - } while (!ao_lco_box_present((uint16_t) new_box)); - ao_lco_set_box((uint16_t) new_box); + ao_st7565_set_brightness((uint8_t) contrast); +} + +int32_t +ao_lco_get_contrast(void) +{ + return (int32_t) ao_st7565_get_brightness(); +} + +static uint16_t ao_backlight; + +void +ao_lco_set_backlight(int32_t backlight) +{ + ao_backlight = (uint16_t) backlight; + ao_pwm_set(AO_LCD_BL_PWM_CHAN, ao_backlight); +} + +int32_t +ao_lco_get_backlight(void) +{ + return (int32_t) ao_backlight; } static struct ao_task ao_lco_drag_task; @@ -222,39 +361,57 @@ ao_lco_input(void) static void ao_lco_display_test(void) { - ao_mutex_get(&ao_lco_display_mutex); -// ao_seven_segment_set(AO_LCO_PAD_DIGIT, 8 | 0x10); -// ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, 8 | 0x10); -// ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, 8 | 0x10); - ao_mutex_put(&ao_lco_display_mutex); ao_led_on(AO_LEDS_AVAILABLE); - ao_delay(AO_MS_TO_TICKS(1000)); + ao_rect(&fb, 0, 0, WIDTH, HEIGHT, AO_BLACK, AO_COPY); + ao_st7565_update(&fb); + ao_delay(AO_MS_TO_TICKS(250)); ao_led_off(AO_LEDS_AVAILABLE); } -static void -ao_lco_batt_voltage(void) -{ - struct ao_adc packet; - int16_t decivolt; - -// ao_adc_single_get(&packet); - packet.v_batt = 0; - decivolt = ao_battery_decivolt(packet.v_batt); - ao_lco_show_voltage((uint16_t) decivolt); - ao_delay(AO_MS_TO_TICKS(1000)); -} - static struct ao_task ao_lco_input_task; static struct ao_task ao_lco_monitor_task; static struct ao_task ao_lco_arm_warn_task; static struct ao_task ao_lco_igniter_status_task; +static int16_t found_x; + +void +ao_lco_search_start(void) +{ + ao_rect(&fb, 0, 0, WIDTH, HEIGHT, AO_WHITE, AO_COPY); + ao_logo(&fb, &logo_transform, &LOGO_FONT, AO_BLACK, AO_COPY); + found_x = FOUND_X; +} + +void +ao_lco_search_box_check(int16_t box) +{ + if (box > 0) + ao_rect(&fb, SCAN_X, SCAN_Y, box, SCAN_HEIGHT, AO_BLACK, AO_COPY); + ao_st7565_update(&fb); +} + +void +ao_lco_search_box_present(int16_t box) +{ + char str[8]; + if (found_x < FOUND_WIDTH) + { + snprintf(str, sizeof(str), "%s%02u", found_x ? ", " : "", box); + found_x = ao_text(&fb, &TINY_FONT, found_x, FOUND_Y, str, AO_BLACK, AO_COPY); + } +} + +void +ao_lco_search_done(void) +{ + ao_st7565_update(&fb); +} + static void ao_lco_main(void) { ao_lco_display_test(); - ao_lco_batt_voltage(); ao_lco_search(); ao_add_task(&ao_lco_input_task, ao_lco_input, "lco input"); ao_add_task(&ao_lco_arm_warn_task, ao_lco_arm_warn, "lco arm warn");