Support adjustable backlight brightness
This commit is contained in:
parent
69bc5e189b
commit
6145f08cc8
2
main.c
2
main.c
|
@ -223,7 +223,7 @@ bool run_code_py(safe_mode_t safe_mode) {
|
||||||
|
|
||||||
// Wait for connection or character.
|
// Wait for connection or character.
|
||||||
if (!serial_connected_at_start) {
|
if (!serial_connected_at_start) {
|
||||||
serial_write_compressed(translate("\nCode done running. Waiting for USB.\n"));
|
serial_write_compressed(translate("\nCode done running. Waiting for reload.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serial_connected_before_animation = false;
|
bool serial_connected_before_animation = false;
|
||||||
|
|
|
@ -84,9 +84,10 @@
|
||||||
//| :param int set_column_command: Command used to set the start and end columns to update
|
//| :param int set_column_command: Command used to set the start and end columns to update
|
||||||
//| :param int set_row_command: Command used so set the start and end rows to update
|
//| :param int set_row_command: Command used so set the start and end rows to update
|
||||||
//| :param int write_ram_command: Command used to write pixels values into the update region
|
//| :param int write_ram_command: Command used to write pixels values into the update region
|
||||||
|
//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight
|
||||||
//|
|
//|
|
||||||
STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command };
|
enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_backlight_pin };
|
||||||
static const mp_arg_t allowed_args[] = {
|
static const mp_arg_t allowed_args[] = {
|
||||||
{ MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
{ MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||||
{ MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
{ MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||||
|
@ -98,6 +99,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
|
||||||
{ MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} },
|
{ MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} },
|
||||||
{ MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} },
|
{ MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} },
|
||||||
{ MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} },
|
{ MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} },
|
||||||
|
{ MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
|
||||||
};
|
};
|
||||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
@ -107,6 +109,9 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ);
|
mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ);
|
||||||
|
|
||||||
|
mp_obj_t backlight_pin = args[ARG_backlight_pin].u_obj;
|
||||||
|
assert_pin_free(backlight_pin);
|
||||||
|
|
||||||
displayio_display_obj_t *self = NULL;
|
displayio_display_obj_t *self = NULL;
|
||||||
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
|
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
|
||||||
if (displays[i].display.base.type == NULL ||
|
if (displays[i].display.base.type == NULL ||
|
||||||
|
@ -119,11 +124,10 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
|
||||||
mp_raise_RuntimeError(translate("Too many displays"));
|
mp_raise_RuntimeError(translate("Too many displays"));
|
||||||
}
|
}
|
||||||
self->base.type = &displayio_display_type;
|
self->base.type = &displayio_display_type;
|
||||||
// TODO(tannewt): Support backlight pin.
|
|
||||||
common_hal_displayio_display_construct(self,
|
common_hal_displayio_display_construct(self,
|
||||||
display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int,
|
display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int,
|
||||||
args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int,
|
args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int,
|
||||||
args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len, NULL);
|
args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len, backlight_pin);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -170,11 +174,72 @@ STATIC mp_obj_t displayio_display_obj_wait_for_frame(mp_obj_t self_in) {
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_display_obj_wait_for_frame);
|
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_display_obj_wait_for_frame);
|
||||||
|
|
||||||
|
//| .. attribute:: brightness
|
||||||
|
//|
|
||||||
|
//| The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When
|
||||||
|
//| `auto_brightness` is True this value will change automatically and setting it will have no
|
||||||
|
//| effect. To control the brightness, auto_brightness must be false.
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t displayio_display_obj_get_brightness(mp_obj_t self_in) {
|
||||||
|
displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
mp_float_t brightness = common_hal_displayio_display_get_brightness(self);
|
||||||
|
if (brightness < 0) {
|
||||||
|
mp_raise_RuntimeError(translate("Brightness not adjustable"));
|
||||||
|
}
|
||||||
|
return mp_obj_new_float(brightness);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_brightness_obj, displayio_display_obj_get_brightness);
|
||||||
|
|
||||||
|
STATIC mp_obj_t displayio_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness) {
|
||||||
|
displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
bool ok = common_hal_displayio_display_set_brightness(self, mp_obj_get_float(brightness));
|
||||||
|
if (!ok) {
|
||||||
|
mp_raise_RuntimeError(translate("Brightness not adjustable"));
|
||||||
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_brightness_obj, displayio_display_obj_set_brightness);
|
||||||
|
|
||||||
|
const mp_obj_property_t displayio_display_brightness_obj = {
|
||||||
|
.base.type = &mp_type_property,
|
||||||
|
.proxy = {(mp_obj_t)&displayio_display_get_brightness_obj,
|
||||||
|
(mp_obj_t)&displayio_display_set_brightness_obj,
|
||||||
|
(mp_obj_t)&mp_const_none_obj},
|
||||||
|
};
|
||||||
|
|
||||||
|
//| .. attribute:: auto_brightness
|
||||||
|
//|
|
||||||
|
//| True when the display brightness is auto adjusted.
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t displayio_display_obj_get_auto_brightness(mp_obj_t self_in) {
|
||||||
|
displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
return mp_obj_new_bool(common_hal_displayio_display_get_auto_brightness(self));
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_auto_brightness_obj, displayio_display_obj_get_auto_brightness);
|
||||||
|
|
||||||
|
STATIC mp_obj_t displayio_display_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) {
|
||||||
|
displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
|
||||||
|
common_hal_displayio_display_set_auto_brightness(self, mp_obj_is_true(auto_brightness));
|
||||||
|
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_auto_brightness_obj, displayio_display_obj_set_auto_brightness);
|
||||||
|
|
||||||
|
const mp_obj_property_t displayio_display_auto_brightness_obj = {
|
||||||
|
.base.type = &mp_type_property,
|
||||||
|
.proxy = {(mp_obj_t)&displayio_display_get_auto_brightness_obj,
|
||||||
|
(mp_obj_t)&displayio_display_set_auto_brightness_obj,
|
||||||
|
(mp_obj_t)&mp_const_none_obj},
|
||||||
|
};
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_display_refresh_soon_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_display_refresh_soon_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_display_wait_for_frame_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_display_wait_for_frame_obj) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&displayio_display_brightness_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&displayio_display_auto_brightness_obj) },
|
||||||
};
|
};
|
||||||
STATIC MP_DEFINE_CONST_DICT(displayio_display_locals_dict, displayio_display_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(displayio_display_locals_dict, displayio_display_locals_dict_table);
|
||||||
|
|
||||||
|
|
|
@ -56,4 +56,10 @@ bool displayio_display_refresh_queued(displayio_display_obj_t* self);
|
||||||
void displayio_display_finish_refresh(displayio_display_obj_t* self);
|
void displayio_display_finish_refresh(displayio_display_obj_t* self);
|
||||||
bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length);
|
bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length);
|
||||||
|
|
||||||
|
bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self);
|
||||||
|
void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness);
|
||||||
|
|
||||||
|
mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self);
|
||||||
|
bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H
|
||||||
|
|
|
@ -55,6 +55,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
|
||||||
self->current_group = NULL;
|
self->current_group = NULL;
|
||||||
self->colstart = colstart;
|
self->colstart = colstart;
|
||||||
self->rowstart = rowstart;
|
self->rowstart = rowstart;
|
||||||
|
self->auto_brightness = false;
|
||||||
|
|
||||||
if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) {
|
if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) {
|
||||||
self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction;
|
self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction;
|
||||||
|
@ -110,7 +111,6 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
|
||||||
common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm);
|
common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self->auto_brightness = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
|
void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
|
||||||
|
@ -133,6 +133,42 @@ int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* sel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self) {
|
||||||
|
return self->auto_brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness) {
|
||||||
|
self->auto_brightness = auto_brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self) {
|
||||||
|
if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
|
||||||
|
uint16_t duty_cycle = common_hal_pulseio_pwmout_get_duty_cycle(&self->backlight_pwm);
|
||||||
|
return duty_cycle / ((mp_float_t) 0xffff);
|
||||||
|
} else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
|
||||||
|
if (common_hal_digitalio_digitalinout_get_value(&self->backlight_inout)) {
|
||||||
|
return 1.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness) {
|
||||||
|
self->updating_backlight = true;
|
||||||
|
bool ok = false;
|
||||||
|
if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
|
||||||
|
common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness));
|
||||||
|
ok = true;
|
||||||
|
} else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
|
||||||
|
common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99);
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
self->updating_backlight = false;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
void displayio_display_start_region_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
void displayio_display_start_region_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||||
// TODO(tannewt): Handle displays with single byte bounds.
|
// TODO(tannewt): Handle displays with single byte bounds.
|
||||||
self->begin_transaction(self->bus);
|
self->begin_transaction(self->bus);
|
||||||
|
@ -181,13 +217,10 @@ void displayio_display_update_backlight(displayio_display_obj_t* self) {
|
||||||
if (ticks_ms - self->last_backlight_refresh < 100) {
|
if (ticks_ms - self->last_backlight_refresh < 100) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self->updating_backlight = true;
|
// TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target
|
||||||
if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
|
// should account for ambient light when possible.
|
||||||
common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, 0xffff);
|
common_hal_displayio_display_set_brightness(self, 1.0);
|
||||||
} else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
|
|
||||||
common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, true);
|
|
||||||
}
|
|
||||||
self->updating_backlight = false;
|
|
||||||
self->last_backlight_refresh = ticks_ms;
|
self->last_backlight_refresh = ticks_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, d
|
||||||
self->tilegrid = tilegrid;
|
self->tilegrid = tilegrid;
|
||||||
self->unicode_characters = unicode_characters;
|
self->unicode_characters = unicode_characters;
|
||||||
self->unicode_characters_len = unicode_characters_len;
|
self->unicode_characters_len = unicode_characters_len;
|
||||||
|
self->first_row = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) {
|
size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) {
|
||||||
|
|
|
@ -40,6 +40,7 @@ typedef struct {
|
||||||
displayio_tilegrid_t* tilegrid;
|
displayio_tilegrid_t* tilegrid;
|
||||||
const byte* unicode_characters;
|
const byte* unicode_characters;
|
||||||
uint16_t unicode_characters_len;
|
uint16_t unicode_characters_len;
|
||||||
|
uint16_t first_row;
|
||||||
} terminalio_terminal_obj_t;
|
} terminalio_terminal_obj_t;
|
||||||
|
|
||||||
#endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */
|
#endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */
|
||||||
|
|
Loading…
Reference in New Issue