Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add backlight dimming after timeout #17

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
54 changes: 53 additions & 1 deletion app/backlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,71 @@
#include <hardware/pwm.h>
#include <pico/stdlib.h>

#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);

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;
}
}
2 changes: 2 additions & 0 deletions app/backlight.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include <stdint.h>
#include <stdbool.h>

void backlight_trigger(void);
void backlight_sync(void);
void backlight_init(void);
7 changes: 4 additions & 3 deletions app/keyboard.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "app_config.h"
#include "fifo.h"
#include "keyboard.h"
#include "backlight.h"
#include "reg.h"

#include <pico/stdlib.h>
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
4 changes: 4 additions & 0 deletions app/reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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);
}
2 changes: 2 additions & 0 deletions app/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
2 changes: 2 additions & 0 deletions app/touchpad.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "touchpad.h"

#include "keyboard.h"
#include "backlight.h"

#include <hardware/i2c.h>
#include <pico/binary_info.h>
Expand Down Expand Up @@ -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;

Expand Down