Add knobs for SSD1322 and two fixes.
* Fix terminal clear after first successful code.py run. * Fix transmitting too many bytes for column constraint with single byte bounds.
This commit is contained in:
parent
d99d3bd471
commit
af8cfbedfb
@ -51,7 +51,7 @@
|
||||
//| Most people should not use this class directly. Use a specific display driver instead that will
|
||||
//| contain the initialization sequence at minimum.
|
||||
//|
|
||||
//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, grayscale=False, pixels_in_byte_share_row=True, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None, brightness_command=None, brightness=1.0, auto_brightness=False, single_byte_bounds=False, data_as_commands=False)
|
||||
//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, grayscale=False, pixels_in_byte_share_row=True, bytes_per_cell=1, reverse_pixels_in_byte=False, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None, brightness_command=None, brightness=1.0, auto_brightness=False, single_byte_bounds=False, data_as_commands=False)
|
||||
//|
|
||||
//| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`).
|
||||
//|
|
||||
@ -90,6 +90,8 @@
|
||||
//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.)
|
||||
//| :param bool grayscale: True if the display only shows a single color.
|
||||
//| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column.
|
||||
//| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row.
|
||||
//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.)
|
||||
//| :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. Ignored if data_as_commands is set.
|
||||
@ -102,7 +104,7 @@
|
||||
//| :param bool data_as_commands: Treat all init and boundary data as SPI commands. Certain displays require this.
|
||||
//|
|
||||
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_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands };
|
||||
enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands };
|
||||
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 },
|
||||
@ -114,6 +116,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
|
||||
{ MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} },
|
||||
{ MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||
{ MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} },
|
||||
{ MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} },
|
||||
{ MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||
{ 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} },
|
||||
@ -163,7 +167,8 @@ 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, rotation,
|
||||
args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool, args[ARG_pixels_in_byte_share_row].u_bool,
|
||||
args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool,
|
||||
args[ARG_pixels_in_byte_share_row].u_bool, args[ARG_bytes_per_cell].u_bool, args[ARG_reverse_pixels_in_byte].u_bool,
|
||||
args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int,
|
||||
args[ARG_write_ram_command].u_int,
|
||||
args[ARG_set_vertical_scroll].u_int,
|
||||
@ -199,7 +204,10 @@ STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in)
|
||||
group = MP_OBJ_TO_PTR(native_group(group_in));
|
||||
}
|
||||
|
||||
common_hal_displayio_display_show(self, group);
|
||||
bool ok = common_hal_displayio_display_show(self, group);
|
||||
if (!ok) {
|
||||
mp_raise_ValueError(translate("Group already used"));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show);
|
||||
|
@ -40,7 +40,8 @@ extern const mp_obj_type_t displayio_display_type;
|
||||
|
||||
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 rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row,
|
||||
int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale,
|
||||
bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte,
|
||||
uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll,
|
||||
uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command,
|
||||
mp_float_t brightness, bool auto_brightness,
|
||||
@ -48,7 +49,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
|
||||
|
||||
int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self);
|
||||
|
||||
void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group);
|
||||
bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group);
|
||||
|
||||
void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self);
|
||||
|
||||
|
@ -44,7 +44,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 rotation,
|
||||
uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row,
|
||||
uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte,
|
||||
uint8_t set_column_command, uint8_t set_row_command,
|
||||
uint8_t write_ram_command, uint8_t set_vertical_scroll, uint8_t* init_sequence, uint16_t init_sequence_len,
|
||||
const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command, mp_float_t brightness, bool auto_brightness,
|
||||
@ -52,6 +52,8 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
|
||||
self->colorspace.depth = color_depth;
|
||||
self->colorspace.grayscale = grayscale;
|
||||
self->colorspace.pixels_in_byte_share_row = pixels_in_byte_share_row;
|
||||
self->colorspace.bytes_per_cell = bytes_per_cell;
|
||||
self->colorspace.reverse_pixels_in_byte = reverse_pixels_in_byte;
|
||||
self->set_column_command = set_column_command;
|
||||
self->set_row_command = set_row_command;
|
||||
self->write_ram_command = write_ram_command;
|
||||
@ -195,17 +197,25 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
|
||||
common_hal_displayio_display_show(self, &circuitpython_splash);
|
||||
}
|
||||
|
||||
void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
|
||||
bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
|
||||
if (root_group == NULL) {
|
||||
root_group = &circuitpython_splash;
|
||||
}
|
||||
if (root_group == self->current_group) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (root_group->in_group) {
|
||||
return false;
|
||||
}
|
||||
if (self->current_group != NULL) {
|
||||
self->current_group->in_group = false;
|
||||
}
|
||||
displayio_group_update_transform(root_group, &self->transform);
|
||||
root_group->in_group = true;
|
||||
self->current_group = root_group;
|
||||
self->full_refresh = true;
|
||||
common_hal_displayio_display_refresh_soon(self);
|
||||
return true;
|
||||
}
|
||||
|
||||
void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self) {
|
||||
@ -299,11 +309,11 @@ void displayio_display_set_region_to_update(displayio_display_obj_t* self, displ
|
||||
if (self->colorspace.depth < 8) {
|
||||
uint8_t pixels_per_byte = 8 / self->colorspace.depth;
|
||||
if (self->colorspace.pixels_in_byte_share_row) {
|
||||
x1 /= pixels_per_byte;
|
||||
x2 /= pixels_per_byte;
|
||||
x1 /= pixels_per_byte * self->colorspace.bytes_per_cell;
|
||||
x2 /= pixels_per_byte * self->colorspace.bytes_per_cell;
|
||||
} else {
|
||||
y1 /= pixels_per_byte;
|
||||
y2 /= pixels_per_byte;
|
||||
y1 /= pixels_per_byte * self->colorspace.bytes_per_cell;
|
||||
y2 /= pixels_per_byte * self->colorspace.bytes_per_cell;
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,7 +328,6 @@ void displayio_display_set_region_to_update(displayio_display_obj_t* self, displ
|
||||
if (self->single_byte_bounds) {
|
||||
data[data_length++] = x1 + self->colstart;
|
||||
data[data_length++] = x2 - 1 + self->colstart;
|
||||
data_length += 2;
|
||||
} else {
|
||||
x1 += self->colstart;
|
||||
x2 += self->colstart - 1;
|
||||
@ -413,7 +422,7 @@ bool displayio_display_clip_area(displayio_display_obj_t *self, const displayio_
|
||||
// Expand the area if we have multiple pixels per byte and we need to byte
|
||||
// align the bounds.
|
||||
if (self->colorspace.depth < 8) {
|
||||
uint8_t pixels_per_byte = 8 / self->colorspace.depth;
|
||||
uint8_t pixels_per_byte = 8 / self->colorspace.depth * self->colorspace.bytes_per_cell;
|
||||
if (self->colorspace.pixels_in_byte_share_row) {
|
||||
if (clipped->x1 % pixels_per_byte != 0) {
|
||||
clipped->x1 -= clipped->x1 % pixels_per_byte;
|
||||
|
@ -36,6 +36,8 @@ typedef struct {
|
||||
uint8_t depth;
|
||||
bool grayscale;
|
||||
bool pixels_in_byte_share_row;
|
||||
uint8_t bytes_per_cell;
|
||||
bool reverse_pixels_in_byte;
|
||||
uint8_t hue;
|
||||
} _displayio_colorspace_t;
|
||||
|
||||
|
@ -436,7 +436,11 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_c
|
||||
// asm("bkpt");
|
||||
// }
|
||||
}
|
||||
((uint8_t*)buffer)[offset / pixels_per_byte] |= pixel << ((offset % pixels_per_byte) * colorspace->depth);
|
||||
uint8_t shift = (offset % pixels_per_byte) * colorspace->depth;
|
||||
if (colorspace->reverse_pixels_in_byte) {
|
||||
shift = (pixels_per_byte - 1) * colorspace->depth - shift;
|
||||
}
|
||||
((uint8_t*)buffer)[offset / pixels_per_byte] |= pixel << shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,35 +209,35 @@ void reset_displays(void) {
|
||||
}
|
||||
}
|
||||
} else if (displays[i].i2cdisplay_bus.base.type == &displayio_i2cdisplay_type) {
|
||||
displayio_i2cdisplay_obj_t* i2c = &displays[i].i2cdisplay_bus;
|
||||
if (((uint32_t) i2c->bus) < ((uint32_t) &displays) ||
|
||||
((uint32_t) i2c->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) {
|
||||
busio_i2c_obj_t* original_i2c = i2c->bus;
|
||||
#if BOARD_I2C
|
||||
// We don't need to move original_i2c if it is the board.SPI object because it is
|
||||
// statically allocated already. (Doing so would also make it impossible to reference in
|
||||
// a subsequent VM run.)
|
||||
if (original_i2c == common_hal_board_get_i2c()) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
memcpy(&i2c->inline_bus, original_i2c, sizeof(busio_i2c_obj_t));
|
||||
i2c->bus = &i2c->inline_bus;
|
||||
// Check for other displays that use the same i2c bus and swap them too.
|
||||
for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) {
|
||||
if (displays[i].i2cdisplay_bus.base.type == &displayio_i2cdisplay_type &&
|
||||
displays[i].i2cdisplay_bus.bus == original_i2c) {
|
||||
displays[i].i2cdisplay_bus.bus = &i2c->inline_bus;
|
||||
}
|
||||
displayio_i2cdisplay_obj_t* i2c = &displays[i].i2cdisplay_bus;
|
||||
if (((uint32_t) i2c->bus) < ((uint32_t) &displays) ||
|
||||
((uint32_t) i2c->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) {
|
||||
busio_i2c_obj_t* original_i2c = i2c->bus;
|
||||
#if BOARD_I2C
|
||||
// We don't need to move original_i2c if it is the board.SPI object because it is
|
||||
// statically allocated already. (Doing so would also make it impossible to reference in
|
||||
// a subsequent VM run.)
|
||||
if (original_i2c == common_hal_board_get_i2c()) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
memcpy(&i2c->inline_bus, original_i2c, sizeof(busio_i2c_obj_t));
|
||||
i2c->bus = &i2c->inline_bus;
|
||||
// Check for other displays that use the same i2c bus and swap them too.
|
||||
for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) {
|
||||
if (displays[i].i2cdisplay_bus.base.type == &displayio_i2cdisplay_type &&
|
||||
displays[i].i2cdisplay_bus.bus == original_i2c) {
|
||||
displays[i].i2cdisplay_bus.bus = &i2c->inline_bus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
|
||||
if (displays[i].display.base.type == NULL) {
|
||||
} else {
|
||||
// Not an active display.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reset the displayed group. Only the first will get the terminal but
|
||||
// that's ok.
|
||||
displayio_display_obj_t* display = &displays[i].display;
|
||||
display->auto_brightness = true;
|
||||
common_hal_displayio_display_show(display, &circuitpython_splash);
|
||||
|
@ -229,5 +229,6 @@ displayio_group_t circuitpython_splash = {
|
||||
.size = 2,
|
||||
.max_size = 2,
|
||||
.children = splash_children,
|
||||
.item_removed = false
|
||||
.item_removed = false,
|
||||
.in_group = false
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user