Rudamentary backlight support
This commit is contained in:
parent
1a1dbef992
commit
69bc5e189b
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user