diff --git a/README.md b/README.md index 10f1559..bee9572 100644 --- a/README.md +++ b/README.md @@ -305,6 +305,25 @@ It is recommended to read the value of this register often, or data loss might o Default value: 0 +### Backlight dimming timeout (REG_ID_BK3 = 0x17) + +This is a read-write register, it is 1 byte in size. + +The value of this register (expressed in units of 500ms) is used to determine when the backlight should be dimmed. + +Set to 0 to disable backlight dimming entirely. + +Default value: 0 + +### Backlight dimming level (REG_ID_BK4 = 0x18) + +This is a read-write register, it is 1 byte in size. + +The value of this register is used to determine the backlight level when it is the dimmed state. This value has no effect if REG_ID_BK3 is set to 0. + +Default value: 96 + + ## Version history v1.0: diff --git a/app/backlight.c b/app/backlight.c index f56e1d0..cbeb3fe 100644 --- a/app/backlight.c +++ b/app/backlight.c @@ -4,13 +4,58 @@ #include #include +#define BACKLIGHT_IDLE_POLLING_RATE_MS 500 + +static struct { + uint64_t last_triggered; + bool idling; + bool alarm_is_set; + uint8_t backlight_level; +} self; + void backlight_sync(void) { - pwm_set_gpio_level(PIN_BKL, reg_get_value(REG_ID_BKL) * 0x80); + pwm_set_gpio_level(PIN_BKL, self.backlight_level * 0x80); +} + +static int64_t idle_detector_timer_task(alarm_id_t id, void *user_data) +{ + (void)id; + (void)user_data; + + uint8_t current_dimming_delay = reg_get_value(REG_ID_BK3); + if (current_dimming_delay == 0) { + self.idling = true; + cancel_alarm(id); + self.alarm_is_set = false; + } else if (!self.idling && to_ms_since_boot(get_absolute_time()) - self.last_triggered > (current_dimming_delay * 500)) { + self.idling = true; + cancel_alarm(id); + self.alarm_is_set = false; + self.backlight_level = reg_get_value(REG_ID_BK4); + backlight_sync(); + } + return BACKLIGHT_IDLE_POLLING_RATE_MS * 1000; +} + +void backlight_trigger(void) +{ + self.idling = false; + self.last_triggered = to_ms_since_boot(get_absolute_time()); + uint8_t desired_brightness = reg_get_value(REG_ID_BKL); + if (self.backlight_level < desired_brightness) { + self.backlight_level = desired_brightness; + backlight_sync(); + } + if (!self.alarm_is_set) { + add_alarm_in_ms(BACKLIGHT_IDLE_POLLING_RATE_MS, idle_detector_timer_task, NULL, true); + self.alarm_is_set = true; + } } void backlight_init(void) { + self.idling = false; gpio_set_function(PIN_BKL, GPIO_FUNC_PWM); const uint slice_num = pwm_gpio_to_slice_num(PIN_BKL); @@ -18,5 +63,12 @@ void backlight_init(void) pwm_config config = pwm_get_default_config(); pwm_init(slice_num, &config, true); + self.backlight_level = reg_get_value(REG_ID_BKL); backlight_sync(); + self.last_triggered = 0; + + if (reg_get_value(REG_ID_BK3) > 0) { + add_alarm_in_ms(BACKLIGHT_IDLE_POLLING_RATE_MS, idle_detector_timer_task, NULL, true); + self.alarm_is_set = true; + } } diff --git a/app/backlight.h b/app/backlight.h index 035f426..f4ece8a 100644 --- a/app/backlight.h +++ b/app/backlight.h @@ -1,6 +1,8 @@ #pragma once #include +#include +void backlight_trigger(void); void backlight_sync(void); void backlight_init(void); diff --git a/app/keyboard.c b/app/keyboard.c index 5b624cc..dfcf8dc 100644 --- a/app/keyboard.c +++ b/app/keyboard.c @@ -1,6 +1,7 @@ #include "app_config.h" #include "fifo.h" #include "keyboard.h" +#include "backlight.h" #include "reg.h" #include @@ -132,7 +133,7 @@ static void transition_to(struct list_item * const p_item, const enum key_state if (p_item->effective_key == '\0') return; - + backlight_trigger(); keyboard_inject_event(p_item->effective_key, next_state); } @@ -210,7 +211,7 @@ static void next_item_state(struct list_item * const p_item, const bool pressed) } } -static int64_t timer_task(alarm_id_t id, void *user_data) +static int64_t idle_detector_timer_task(alarm_id_t id, void *user_data) { (void)id; (void)user_data; @@ -411,5 +412,5 @@ void keyboard_init(void) } #endif - add_alarm_in_ms(reg_get_value(REG_ID_FRQ), timer_task, NULL, true); + add_alarm_in_ms(reg_get_value(REG_ID_FRQ), idle_detector_timer_task, NULL, true); } diff --git a/app/reg.c b/app/reg.c index fbf9abe..a562cc5 100644 --- a/app/reg.c +++ b/app/reg.c @@ -49,6 +49,8 @@ void reg_process_packet(uint8_t in_reg, uint8_t in_data, uint8_t *out_buffer, ui case REG_ID_FRQ: case REG_ID_BKL: case REG_ID_BK2: + case REG_ID_BK3: + case REG_ID_BK4: case REG_ID_GIC: case REG_ID_GIN: case REG_ID_HLD: @@ -200,6 +202,8 @@ void reg_init(void) reg_set_value(REG_ID_ADR, 0x1F); reg_set_value(REG_ID_IND, 1); // ms reg_set_value(REG_ID_CF2, CF2_TOUCH_INT | CF2_USB_KEYB_ON | CF2_USB_MOUSE_ON); + reg_set_value(REG_ID_BK3, 0); // 500ms units, 0 = no dimming timeout (don't dim) + reg_set_value(REG_ID_BK4, 96); touchpad_add_touch_callback(&touch_callback); } diff --git a/app/reg.h b/app/reg.h index c1c305a..51e514b 100644 --- a/app/reg.h +++ b/app/reg.h @@ -27,6 +27,8 @@ enum reg_id REG_ID_CF2 = 0x14, // config 2 REG_ID_TOX = 0x15, // touch delta x since last read, at most (-128 to 127) REG_ID_TOY = 0x16, // touch delta y since last read, at most (-128 to 127) + REG_ID_BK3 = 0x17, // Backlight dimming delay (0 = no dimming, 1 = 500ms, 2 = 1000ms, etc.) + REG_ID_BK4 = 0x18, // Backlight dimming level REG_ID_LAST, }; diff --git a/app/touchpad.c b/app/touchpad.c index f8c842a..9654921 100644 --- a/app/touchpad.c +++ b/app/touchpad.c @@ -1,6 +1,7 @@ #include "touchpad.h" #include "keyboard.h" +#include "backlight.h" #include #include @@ -104,6 +105,7 @@ void touchpad_gpio_irq(uint gpio, uint32_t events) } } } else { + backlight_trigger(); if (self.callbacks) { struct touch_callback *cb = self.callbacks;