From: Keith Packard Date: Thu, 20 Jun 2024 06:02:30 +0000 (-0700) Subject: telelco-v3.0: Support ambient light sensor X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=ff6116f1a65a1a623a5b00759e5b922c3f482278;hp=18f3c100b7073bd9aeaedfacc25324a7771b0723;p=fw%2Faltos telelco-v3.0: Support ambient light sensor A TEPT5700 ALS and 15k resistor from 3.3V to ground hooked to ADC10 on PC0. Signed-off-by: Keith Packard --- diff --git a/src/drivers/ao_lco.h b/src/drivers/ao_lco.h index e1468b28..47d587bb 100644 --- a/src/drivers/ao_lco.h +++ b/src/drivers/ao_lco.h @@ -56,7 +56,7 @@ extern struct ao_pad_query ao_pad_query; /* Last received QUERY from pad */ # define AO_LCO_BOX_FIRST AO_LCO_CONTRAST # endif # endif -# ifdef AO_LCO_HAS_BACKLIGHT +# ifdef AO_LCO_HAS_BACKLIGHT_UI # define AO_LCO_BACKLIGHT -1 # ifndef AO_LCO_BOX_FIRST # define AO_LCO_BOX_FIRST AO_LCO_BACKLIGHT diff --git a/src/drivers/ao_lco_bits.c b/src/drivers/ao_lco_bits.c index 202e35c2..0d922d6e 100644 --- a/src/drivers/ao_lco_bits.c +++ b/src/drivers/ao_lco_bits.c @@ -273,7 +273,7 @@ ao_lco_step_pad(int8_t dir) break; } #endif -#ifdef AO_LCO_HAS_BACKLIGHT +#ifdef AO_LCO_HAS_BACKLIGHT_UI case AO_LCO_BACKLIGHT: { int32_t backlight = ao_lco_get_backlight(); diff --git a/src/telelco-v3.0/Makefile b/src/telelco-v3.0/Makefile index 2531374b..fae076ad 100644 --- a/src/telelco-v3.0/Makefile +++ b/src/telelco-v3.0/Makefile @@ -48,7 +48,8 @@ ALTOS_SRC = \ ao_timer.c \ ao_mutex.c \ ao_freq.c \ - ao_adc_single_stm.c \ + ao_adc_stm.c \ + ao_data.c \ ao_dma_stm.c \ ao_spi_stm.c \ ao_beep_stm.c \ diff --git a/src/telelco-v3.0/ao_lco_v3.c b/src/telelco-v3.0/ao_lco_v3.c index 701a3cbf..2f4c1dbe 100644 --- a/src/telelco-v3.0/ao_lco_v3.c +++ b/src/telelco-v3.0/ao_lco_v3.c @@ -24,6 +24,7 @@ #include #include #include +#include #define WIDTH AO_ST7565_WIDTH #define HEIGHT AO_ST7565_HEIGHT @@ -106,6 +107,9 @@ static uint8_t ao_lco_event_debug; static uint8_t ao_lco_display_mutex; +static uint8_t ao_sample_data; +static struct ao_data ao_data_cur; + static void _ao_center_text(int16_t x, int16_t y, const struct ao_font *font, const char *str) { @@ -154,7 +158,7 @@ _ao_lco_show_contrast(void) } #endif -#if AO_LCO_HAS_BACKLIGHT +#if AO_LCO_HAS_BACKLIGHT_UI static void _ao_lco_show_backlight(void) { @@ -187,13 +191,11 @@ static void _ao_lco_show_lco_info(void) { char battery[7]; - struct ao_adc packet; int16_t decivolt; ao_logo_poly(&fb, &show_transform, AO_BLACK, AO_COPY); - ao_adc_single_get(&packet); - decivolt = ao_battery_decivolt(packet.v_batt); + decivolt = ao_battery_decivolt(ao_data_cur.adc.v_batt); _ao_format_voltage(battery, sizeof(battery), (uint16_t) decivolt); info_y = INFO_START_Y; @@ -238,6 +240,86 @@ _ao_lco_show_pad_info(void) } } +#define AO_LCO_DIM_BACKLIGHT (AO_LCO_MIN_BACKLIGHT + 3 * AO_LCO_BACKLIGHT_STEP) +#define AO_AUTO_BACKLIGHT_RANGE (AO_LCO_MAX_BACKLIGHT - AO_LCO_DIM_BACKLIGHT) +#define AO_AUTO_BACKLIGHT_GAP AO_ADC_MAX / 6 + +static struct { + int16_t v_als; + int32_t backlight; +} ao_lco_backlight_map[] = { + { .v_als = AO_ADC_MAX / 6, .backlight = AO_LCO_DIM_BACKLIGHT }, + { .v_als = AO_ADC_MAX / 3, .backlight = (AO_LCO_MAX_BACKLIGHT - AO_LCO_MIN_BACKLIGHT) / 2 }, + { .v_als = AO_ADC_MAX / 2, .backlight = AO_LCO_MAX_BACKLIGHT }, + { .v_als = AO_ADC_MAX * 3 / 4, .backlight = 0 }, +}; + +#define NUM_BACKLIGHT_MAP sizeof(ao_lco_backlight_map)/sizeof(ao_lco_backlight_map[0]) + +static unsigned ao_backlight_prev = NUM_BACKLIGHT_MAP - 1; + +static void +ao_auto_backlight(int16_t als_min, int16_t als_max) +{ + unsigned ao_backlight; + + PRINTD("ao_auto_backlight min %d max %d\n", als_min, als_max); + ao_backlight = ao_backlight_prev; + while (als_min > ao_lco_backlight_map[ao_backlight].v_als + AO_AUTO_BACKLIGHT_GAP) { + if (ao_backlight == NUM_BACKLIGHT_MAP - 1) + break; + ao_backlight++; + } + while (als_max < ao_lco_backlight_map[ao_backlight].v_als - AO_AUTO_BACKLIGHT_GAP) { + if (ao_backlight == 0) + return; + ao_backlight--; + } + if (ao_backlight != ao_backlight_prev) + { + PRINTD(" set backlight to %ld\n", ao_lco_backlight_map[ao_backlight].backlight); + ao_lco_set_backlight(ao_lco_backlight_map[ao_backlight].backlight); + ao_backlight_prev = ao_backlight; + } +} + +#define AO_LCO_BACKLIGHT_INTERVAL AO_SEC_TO_TICKS(2) + +static void +ao_lco_data(void) +{ + AO_TICK_TYPE backlight_tick = ao_time() + AO_LCO_BACKLIGHT_INTERVAL; + AO_TICK_TYPE now; + int16_t als_min = INT16_MAX; + int16_t als_max = INT16_MIN; + + ao_timer_set_adc_interval(AO_MS_TO_TICKS(100)); + for (;;) { + ao_sleep((void *) &ao_data_head); + + while (ao_sample_data != ao_data_head) { + struct ao_data *ao_data; + + /* Capture a sample */ + ao_data = (struct ao_data *) &ao_data_ring[ao_sample_data]; + + ao_data_cur = *ao_data; + if (ao_data_cur.adc.v_als < als_min) + als_min = ao_data_cur.adc.v_als; + if (ao_data_cur.adc.v_als > als_max) + als_max = ao_data_cur.adc.v_als; + ao_sample_data = ao_data_ring_next(ao_sample_data); + } + now = ao_time(); + if ((AO_TICK_SIGNED) (backlight_tick - now) < 0) { + backlight_tick = now + AO_LCO_BACKLIGHT_INTERVAL; + ao_auto_backlight(als_min, als_max); + als_min = INT16_MAX; + als_max = INT16_MIN; + } + } +} + void ao_lco_show(void) { @@ -249,7 +331,7 @@ ao_lco_show(void) _ao_lco_show_contrast(); break; #endif -#if AO_LCO_HAS_BACKLIGHT +#if AO_LCO_HAS_BACKLIGHT_UI case AO_LCO_BACKLIGHT: _ao_lco_show_backlight(); break; @@ -428,6 +510,7 @@ ao_lco_display_test(void) static struct ao_task ao_lco_input_task; static struct ao_task ao_lco_monitor_task; +static struct ao_task ao_lco_data_task; static struct ao_task ao_lco_arm_warn_task; static struct ao_task ao_lco_igniter_status_task; @@ -525,6 +608,7 @@ void ao_lco_init(void) { ao_add_task(&ao_lco_monitor_task, ao_lco_main, "lco monitor"); + ao_add_task(&ao_lco_data_task, ao_lco_data, "lco data"); #if DEBUG ao_cmd_register(&ao_lco_cmds[0]); #endif diff --git a/src/telelco-v3.0/ao_pins.h b/src/telelco-v3.0/ao_pins.h index 2ed88d3b..b1af364f 100644 --- a/src/telelco-v3.0/ao_pins.h +++ b/src/telelco-v3.0/ao_pins.h @@ -229,8 +229,8 @@ #define AO_BUTTON_0 1 #define AO_BUTTON_DRAG_SELECT 1 -#define AO_BUTTON_1_PORT &stm_gpioc -#define AO_BUTTON_1 0 +#define AO_BUTTON_1_PORT &stm_gpiod +#define AO_BUTTON_1 2 #define AO_BUTTON_SPARE1 2 #define AO_BUTTON_2_PORT &stm_gpiob @@ -262,14 +262,9 @@ /* ADC */ -struct ao_adc { - int16_t v_batt; -}; - -#define AO_ADC_DUMP(p) \ - printf("batt: %5d\n", (p)->v_batt) +#define AO_DATA_RING 8 -#define HAS_ADC_SINGLE 1 +#define HAS_ADC 1 #define HAS_ADC_TEMP 0 #define HAS_BATTERY_REPORT 1 @@ -277,12 +272,33 @@ struct ao_adc { #define AO_ADC_V_BATT_PORT (&stm_gpioa) #define AO_ADC_V_BATT_PIN 2 +#define AO_ADC_V_ALS 10 +#define AO_ADC_V_ALS_PORT (&stm_gpioc) +#define AO_ADC_V_ALS_PIN 0 + #define AO_ADC_PIN0_PORT AO_ADC_V_BATT_PORT #define AO_ADC_PIN0_PIN AO_ADC_V_BATT_PIN +#define AO_ADC_PIN1_PORT AO_ADC_V_ALS_PORT +#define AO_ADC_PIN1_PIN AO_ADC_V_ALS_PIN + #define AO_ADC_SQ1 AO_ADC_V_BATT +#define AO_ADC_SQ2 AO_ADC_V_ALS -#define AO_NUM_ADC 1 +#define AO_NUM_ADC 2 + +struct ao_adc { + union { + struct { + int16_t v_batt; + int16_t v_als; + }; + int16_t v_vals[AO_NUM_ADC]; + }; +}; + +#define AO_ADC_DUMP(p) \ + printf("batt: %5d als %5d\n", (p)->adc.v_batt, (p)->adc.v_als) /* * Voltage divider on ADC battery sampler diff --git a/src/telelco-v3.0/ao_telelco.c b/src/telelco-v3.0/ao_telelco.c index a8d740a9..6293edd3 100644 --- a/src/telelco-v3.0/ao_telelco.c +++ b/src/telelco-v3.0/ao_telelco.c @@ -44,7 +44,7 @@ main(void) ao_spi_init(); ao_dma_init(); ao_exti_init(); - ao_adc_single_init(); + ao_adc_init(); ao_beep_init(); ao_pwm_init();