summaryrefslogtreecommitdiff
path: root/shared-module/displayio/Display.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared-module/displayio/Display.c')
-rw-r--r--shared-module/displayio/Display.c95
1 files changed, 92 insertions, 3 deletions
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
index 7946111b7..ef0334d10 100644
--- a/shared-module/displayio/Display.c
+++ b/shared-module/displayio/Display.c
@@ -29,7 +29,10 @@
#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"
#include <stdint.h>
@@ -40,16 +43,19 @@
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;
self->set_column_command = set_column_command;
self->set_row_command = set_row_command;
self->write_ram_command = write_ram_command;
+ self->refresh = false;
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;
@@ -86,9 +92,33 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
i += 2 + data_size;
}
self->end_transaction(self->bus);
+
+ supervisor_start_terminal(width, height);
+
+ // Set the group after initialization otherwise we may send pixels while we delay in
+ // initialization.
+ 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) {
+ 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);
+ }
+ }
}
void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
+ if (root_group == NULL) {
+ root_group = &circuitpython_splash;
+ }
self->current_group = root_group;
common_hal_displayio_display_refresh_soon(self);
}
@@ -105,6 +135,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);
@@ -114,8 +180,8 @@ void displayio_display_start_region_update(displayio_display_obj_t* self, uint16
data[1] = __builtin_bswap16(x1 - 1 + self->colstart);
self->send(self->bus, false, (uint8_t*) data, 4);
self->send(self->bus, true, &self->set_row_command, 1);
- data[0] = __builtin_bswap16(y0 + 1 + self->rowstart);
- data[1] = __builtin_bswap16(y1 + self->rowstart);
+ data[0] = __builtin_bswap16(y0 + self->rowstart);
+ data[1] = __builtin_bswap16(y1 - 1 + self->rowstart);
self->send(self->bus, false, (uint8_t*) data, 4);
self->send(self->bus, true, &self->write_ram_command, 1);
}
@@ -145,3 +211,26 @@ 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;
+ }
+ // 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;
+}
+
+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);
+ }
+}