From 1a1dbef992442682413f6103e36440a26bc2dad7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 25 Jan 2019 16:59:18 -0800 Subject: Hook up the terminal based on the first display. --- shared-bindings/displayio/Display.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'shared-bindings/displayio/Display.c') diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index d61732f6f..1838228af 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -133,11 +133,15 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a //| STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type); - if (native_layer == MP_OBJ_NULL) { - mp_raise_ValueError(translate("Must be a Group subclass.")); + displayio_group_t* group = NULL; + if (group_in != mp_const_none) { + mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type); + if (native_layer == MP_OBJ_NULL) { + mp_raise_ValueError(translate("Must be a Group subclass.")); + } + group = MP_OBJ_TO_PTR(native_layer); } - displayio_group_t* group = MP_OBJ_TO_PTR(native_layer); + common_hal_displayio_display_show(self, group); return mp_const_none; } -- cgit v1.2.3 From 69bc5e189baef183918dc21dadaacf55ce66bee3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 25 Jan 2019 18:31:27 -0800 Subject: Rudamentary backlight support --- ports/atmel-samd/boards/pyportal/board.c | 3 +- ports/atmel-samd/common-hal/pulseio/PWMOut.c | 47 +++++++++++++++++++++------- shared-bindings/displayio/Display.c | 3 +- shared-bindings/displayio/Display.h | 2 +- shared-bindings/pulseio/PWMOut.c | 11 ++++++- shared-bindings/pulseio/PWMOut.h | 14 ++++++++- shared-module/displayio/Display.c | 43 ++++++++++++++++++++++++- shared-module/displayio/Display.h | 14 ++++++++- shared-module/displayio/__init__.c | 3 ++ 9 files changed, 122 insertions(+), 18 deletions(-) (limited to 'shared-bindings/displayio/Display.c') diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index 6e5b37dd2..980a28e9b 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -87,7 +87,8 @@ void board_init(void) { MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command display_init_sequence, - sizeof(display_init_sequence)); + sizeof(display_init_sequence), + &pin_PB31); } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.c b/ports/atmel-samd/common-hal/pulseio/PWMOut.c index 825bdd181..2740a9e55 100644 --- a/ports/atmel-samd/common-hal/pulseio/PWMOut.c +++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.c @@ -58,6 +58,26 @@ uint8_t tcc_channels[3]; // Set by pwmout_reset() to {0xf0, 0xfc, 0xfc} initia uint8_t tcc_channels[5]; // Set by pwmout_reset() to {0xc0, 0xf0, 0xf8, 0xfc, 0xfc} initially. #endif +static uint8_t never_reset_tc_or_tcc[TC_INST_NUM + TCC_INST_NUM]; + +void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { + if (self->timer->is_tc) { + never_reset_tc_or_tcc[self->timer->index] += 1; + } else { + never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] += 1; + } + + never_reset_pin_number(self->pin->number); +} + +void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) { + if (self->timer->is_tc) { + never_reset_tc_or_tcc[self->timer->index] -= 1; + } else { + never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] -= 1; + } +} + void pwmout_reset(void) { // Reset all timers for (int i = 0; i < TCC_INST_NUM; i++) { @@ -66,6 +86,9 @@ void pwmout_reset(void) { } Tcc *tccs[TCC_INST_NUM] = TCC_INSTS; for (int i = 0; i < TCC_INST_NUM; i++) { + if (never_reset_tc_or_tcc[TC_INST_NUM + i] > 0) { + continue; + } // Disable the module before resetting it. if (tccs[i]->CTRLA.bit.ENABLE == 1) { tccs[i]->CTRLA.bit.ENABLE = 0; @@ -81,6 +104,9 @@ void pwmout_reset(void) { } Tc *tcs[TC_INST_NUM] = TC_INSTS; for (int i = 0; i < TC_INST_NUM; i++) { + if (never_reset_tc_or_tcc[i] > 0) { + continue; + } tcs[i]->COUNT16.CTRLA.bit.SWRST = 1; while (tcs[i]->COUNT16.CTRLA.bit.SWRST == 1) { } @@ -99,11 +125,11 @@ bool channel_ok(const pin_timer_t* t) { t->is_tc; } -void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, - const mcu_pin_obj_t* pin, - uint16_t duty, - uint32_t frequency, - bool variable_frequency) { +pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, + const mcu_pin_obj_t* pin, + uint16_t duty, + uint32_t frequency, + bool variable_frequency) { self->pin = pin; self->variable_frequency = variable_frequency; @@ -113,11 +139,11 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, && pin->timer[2].index >= TCC_INST_NUM #endif ) { - mp_raise_ValueError(translate("Invalid pin")); + return PWMOUT_INVALID_PIN; } if (frequency == 0 || frequency > 6000000) { - mp_raise_ValueError(translate("Invalid PWM frequency")); + return PWMOUT_INVALID_FREQUENCY; } // Figure out which timer we are using. @@ -184,11 +210,9 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, if (timer == NULL) { if (found) { - mp_raise_ValueError(translate("All timers for this pin are in use")); - } else { - mp_raise_RuntimeError(translate("All timers in use")); + return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; } - return; + return PWMOUT_ALL_TIMERS_IN_USE; } uint8_t resolution = 0; @@ -259,6 +283,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, gpio_set_pin_function(pin->number, GPIO_PIN_FUNCTION_E + mux_position); common_hal_pulseio_pwmout_set_duty_cycle(self, duty); + return PWMOUT_OK; } bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 1838228af..398bca166 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -119,10 +119,11 @@ 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")); } self->base.type = &displayio_display_type; + // TODO(tannewt): Support backlight pin. 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, 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); + args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len, NULL); return self; } diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index 4cec66058..181afc941 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -40,7 +40,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t color_depth, uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, - uint8_t* init_sequence, uint16_t init_sequence_len); + uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin); int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self); diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c index ed3acd804..bba5fe883 100644 --- a/shared-bindings/pulseio/PWMOut.c +++ b/shared-bindings/pulseio/PWMOut.c @@ -108,7 +108,16 @@ STATIC mp_obj_t pulseio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args // create PWM object from the given pin pulseio_pwmout_obj_t *self = m_new_obj(pulseio_pwmout_obj_t); self->base.type = &pulseio_pwmout_type; - common_hal_pulseio_pwmout_construct(self, pin, duty_cycle, frequency, variable_frequency); + pwmout_result_t result = common_hal_pulseio_pwmout_construct(self, pin, duty_cycle, frequency, variable_frequency); + if (result == PWMOUT_INVALID_PIN) { + mp_raise_ValueError(translate("Invalid pin")); + } else if (result == PWMOUT_INVALID_FREQUENCY) { + mp_raise_ValueError(translate("Invalid PWM frequency")); + } else if (result == PWMOUT_ALL_TIMERS_ON_PIN_IN_USE) { + mp_raise_ValueError(translate("All timers for this pin are in use")); + } else if (result == PWMOUT_ALL_TIMERS_IN_USE) { + mp_raise_RuntimeError(translate("All timers in use")); + } return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/pulseio/PWMOut.h b/shared-bindings/pulseio/PWMOut.h index 0b630816b..c01e0c926 100644 --- a/shared-bindings/pulseio/PWMOut.h +++ b/shared-bindings/pulseio/PWMOut.h @@ -32,7 +32,15 @@ extern const mp_obj_type_t pulseio_pwmout_type; -extern void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, +typedef enum { + PWMOUT_OK, + PWMOUT_INVALID_PIN, + PWMOUT_INVALID_FREQUENCY, + PWMOUT_ALL_TIMERS_ON_PIN_IN_USE, + PWMOUT_ALL_TIMERS_IN_USE +} pwmout_result_t; + +extern pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency, bool variable_frequency); extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self); @@ -43,4 +51,8 @@ extern void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, extern uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self); extern bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self); +// This is used by the supervisor to claim PWMOut devices indefinitely. +extern void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self); +extern void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PWMOUT_H diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index fd082c19d..504f130c7 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -29,6 +29,7 @@ #include "py/runtime.h" #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/ParallelBus.h" +#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/time/__init__.h" #include "shared-module/displayio/__init__.h" #include "supervisor/shared/display.h" @@ -42,7 +43,8 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t color_depth, uint8_t set_column_command, uint8_t set_row_command, - uint8_t write_ram_command, uint8_t* init_sequence, uint16_t init_sequence_len) { + uint8_t write_ram_command, uint8_t* init_sequence, uint16_t init_sequence_len, + const mcu_pin_obj_t* backlight_pin) { self->width = width; self->height = height; self->color_depth = color_depth; @@ -96,6 +98,19 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, // initialization. self->refresh = true; self->current_group = &circuitpython_splash; + + if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { + pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 5000, false); + if (result != PWMOUT_OK) { + self->backlight_inout.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); + never_reset_pin_number(backlight_pin->number); + } else { + self->backlight_pwm.base.type = &pulseio_pwmout_type; + 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) { @@ -158,3 +173,29 @@ bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixe self->send(self->bus, false, (uint8_t*) pixels, length * 4); return true; } + +void displayio_display_update_backlight(displayio_display_obj_t* self) { + if (!self->auto_brightness || self->updating_backlight) { + return; + } + if (ticks_ms - self->last_backlight_refresh < 100) { + return; + } + self->updating_backlight = true; + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, 0xffff); + } 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; +} + +void release_display(displayio_display_obj_t* self) { + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm); + common_hal_pulseio_pwmout_deinit(&self->backlight_pwm); + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); + } +} diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h index 1f1355d31..0d7393aff 100644 --- a/shared-module/displayio/Display.h +++ b/shared-module/displayio/Display.h @@ -27,7 +27,9 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H #define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H -#include "shared-module/displayio/Group.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/pulseio/PWMOut.h" typedef bool (*display_bus_begin_transaction)(mp_obj_t bus); typedef void (*display_bus_send)(mp_obj_t bus, bool command, uint8_t *data, uint32_t data_length); @@ -50,6 +52,16 @@ typedef struct { display_bus_begin_transaction begin_transaction; display_bus_send send; display_bus_end_transaction end_transaction; + union { + digitalio_digitalinout_obj_t backlight_inout; + pulseio_pwmout_obj_t backlight_pwm; + }; + uint64_t last_backlight_refresh; + bool auto_brightness:1; + bool updating_backlight:1; } displayio_display_obj_t; +void displayio_display_update_backlight(displayio_display_obj_t* self); +void release_display(displayio_display_obj_t* self); + #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index dbfeacc3d..8e4904954 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -20,6 +20,7 @@ void displayio_refresh_displays(void) { continue; } displayio_display_obj_t* display = &displays[i].display; + displayio_display_update_backlight(display); if (!displayio_display_frame_queued(display)) { return; @@ -82,6 +83,7 @@ void common_hal_displayio_release_displays(void) { displays[i].fourwire_bus.base.type = &mp_type_NoneType; } for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + release_display(&displays[i].display); displays[i].display.base.type = &mp_type_NoneType; } @@ -117,6 +119,7 @@ void reset_displays(void) { continue; } displayio_display_obj_t* display = &displays[i].display; + display->auto_brightness = true; common_hal_displayio_display_show(display, &circuitpython_splash); } } -- cgit v1.2.3 From 6145f08cc89946d138737b149d390265def67077 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 28 Jan 2019 18:23:32 -0800 Subject: Support adjustable backlight brightness --- main.c | 2 +- shared-bindings/displayio/Display.c | 71 +++++++++++++++++++++++++++++++++++-- shared-bindings/displayio/Display.h | 6 ++++ shared-module/displayio/Display.c | 49 ++++++++++++++++++++----- shared-module/terminalio/Terminal.c | 1 + shared-module/terminalio/Terminal.h | 1 + 6 files changed, 118 insertions(+), 12 deletions(-) (limited to 'shared-bindings/displayio/Display.c') diff --git a/main.c b/main.c index 45c6da817..39d1cd3d0 100755 --- a/main.c +++ b/main.c @@ -223,7 +223,7 @@ bool run_code_py(safe_mode_t safe_mode) { // Wait for connection or character. 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; diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 398bca166..e59905258 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -84,9 +84,10 @@ //| :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 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) { - 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[] = { { MP_QSTR_display_bus, 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_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_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_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_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; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { 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")); } self->base.type = &displayio_display_type; - // TODO(tannewt): Support backlight pin. 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, 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; } @@ -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); +//| .. 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[] = { { 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_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); diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index 181afc941..906c3620d 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -56,4 +56,10 @@ bool displayio_display_refresh_queued(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 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 diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 504f130c7..a2a60227d 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -55,6 +55,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, self->current_group = NULL; self->colstart = colstart; self->rowstart = rowstart; + self->auto_brightness = false; if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { 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); } } - self->auto_brightness = true; } 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; } +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) { // TODO(tannewt): Handle displays with single byte bounds. 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) { return; } - self->updating_backlight = true; - if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { - common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, 0xffff); - } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { - common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, true); - } - self->updating_backlight = false; + // TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target + // should account for ambient light when possible. + common_hal_displayio_display_set_brightness(self, 1.0); + self->last_backlight_refresh = ticks_ms; } diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index 1cd5d341e..444bf53ad 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -34,6 +34,7 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, d self->tilegrid = tilegrid; self->unicode_characters = unicode_characters; 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) { diff --git a/shared-module/terminalio/Terminal.h b/shared-module/terminalio/Terminal.h index 1896075f3..fe9dcf0c4 100644 --- a/shared-module/terminalio/Terminal.h +++ b/shared-module/terminalio/Terminal.h @@ -40,6 +40,7 @@ typedef struct { displayio_tilegrid_t* tilegrid; const byte* unicode_characters; uint16_t unicode_characters_len; + uint16_t first_row; } terminalio_terminal_obj_t; #endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */ -- cgit v1.2.3 From 2c069a5685c9e5bf6b1a081d5566357139c4dff3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 31 Jan 2019 10:29:29 -0800 Subject: Polish up comments --- shared-bindings/displayio/Display.c | 3 ++- shared-bindings/terminalio/Terminal.c | 4 ++-- shared-bindings/terminalio/__init__.c | 8 ++++---- shared-bindings/terminalio/__init__.h | 12 +++++------- shared-module/displayio/__init__.c | 1 - 5 files changed, 13 insertions(+), 15 deletions(-) (limited to 'shared-bindings/displayio/Display.c') diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index e59905258..0d056bc3b 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -134,7 +134,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a //| .. method:: show(group) //| -//| Switches to displaying the given group of layers. +//| Switches to displaying the given group of layers. When group is None, the default +//| CircuitPython terminal will be shown. //| STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c index f460f4abd..67c7ead57 100644 --- a/shared-bindings/terminalio/Terminal.c +++ b/shared-bindings/terminalio/Terminal.c @@ -39,8 +39,8 @@ //| .. currentmodule:: terminalio //| -//| :class:`Terminal` -- manage a -//| ============================================================== +//| :class:`Terminal` -- display a character stream with a TileGrid +//| ================================================================ //| //| .. class:: Terminal(tilegrid, *, unicode_characters="") //| diff --git a/shared-bindings/terminalio/__init__.c b/shared-bindings/terminalio/__init__.c index 1031124dc..482cb78e6 100644 --- a/shared-bindings/terminalio/__init__.c +++ b/shared-bindings/terminalio/__init__.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,13 +34,13 @@ #include "py/runtime.h" -//| :mod:`terminalio` --- MIDI over USB +//| :mod:`terminalio` --- Displays text in a TileGrid //| ================================================= //| //| .. module:: terminalio -//| :synopsis: MIDI over USB +//| :synopsis: Displays text in a TileGrid //| -//| The `terminalio` module contains classes to transmit and receive MIDI messages over USB +//| The `terminalio` module contains classes to display a character stream on a display //| //| Libraries //| diff --git a/shared-bindings/terminalio/__init__.h b/shared-bindings/terminalio/__init__.h index e81818e04..4be14dfc6 100644 --- a/shared-bindings/terminalio/__init__.h +++ b/shared-bindings/terminalio/__init__.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft + * Copyright (c) 2019 Scott Shawcroft * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,11 +24,9 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO___INIT___H -#include "py/obj.h" +// Nothing now. -extern mp_obj_dict_t usb_midi_module_globals; - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO___INIT___H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 32fe6ac5e..f09e4e791 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -2,7 +2,6 @@ #include #include "shared-module/displayio/__init__.h" - #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/Group.h" -- cgit v1.2.3 From 354a26963b9df6dcf281e49954483f147a6394a8 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 31 Jan 2019 11:00:12 -0800 Subject: Correctly handle no backlight pin. --- shared-bindings/displayio/Display.c | 11 ++++++++--- shared-module/displayio/Display.c | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'shared-bindings/displayio/Display.c') diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 0d056bc3b..109df8af4 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -109,8 +109,13 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; 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); + mp_obj_t backlight_pin_obj = args[ARG_backlight_pin].u_obj; + assert_pin(backlight_pin_obj, true); + const mcu_pin_obj_t* backlight_pin = NULL; + if (backlight_pin_obj != NULL && backlight_pin_obj != mp_const_none) { + backlight_pin = MP_OBJ_TO_PTR(backlight_pin_obj); + assert_pin_free(backlight_pin); + } displayio_display_obj_t *self = NULL; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { @@ -127,7 +132,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a 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, 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, backlight_pin); + args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len, MP_OBJ_TO_PTR(backlight_pin)); return self; } diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index ac1d0e933..ef0334d10 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -100,6 +100,8 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, self->refresh = true; self->current_group = &circuitpython_splash; + // Always set the backlight type in case we're reusing memory. + self->backlight_inout.base.type = &mp_type_NoneType; if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 5000, false); if (result != PWMOUT_OK) { -- cgit v1.2.3