Add support for quad color epaper
highlight_color2 is now available for pixel value 0b11. Black is 0b00, white is 0b01 and highlight_color is 0b10. Also add support for multibit values written with one command when color_command isn't provided.
This commit is contained in:
parent
5202246182
commit
2e183f4c00
7 changed files with 56 additions and 19 deletions
|
|
@ -54,6 +54,7 @@
|
||||||
//| write_color_ram_command: Optional[int] = None,
|
//| write_color_ram_command: Optional[int] = None,
|
||||||
//| color_bits_inverted: bool = False,
|
//| color_bits_inverted: bool = False,
|
||||||
//| highlight_color: int = 0x000000,
|
//| highlight_color: int = 0x000000,
|
||||||
|
//| highlight_color2: int = 0x000000,
|
||||||
//| refresh_display_command: Union[int, circuitpython_typing.ReadableBuffer],
|
//| refresh_display_command: Union[int, circuitpython_typing.ReadableBuffer],
|
||||||
//| refresh_time: float = 40,
|
//| refresh_time: float = 40,
|
||||||
//| busy_pin: Optional[microcontroller.Pin] = None,
|
//| busy_pin: Optional[microcontroller.Pin] = None,
|
||||||
|
|
@ -97,6 +98,7 @@
|
||||||
//| :param int write_color_ram_command: Command used to write pixels values into the update region
|
//| :param int write_color_ram_command: Command used to write pixels values into the update region
|
||||||
//| :param bool color_bits_inverted: True if 0 bits are used to show the color. Otherwise, 1 means to show color.
|
//| :param bool color_bits_inverted: True if 0 bits are used to show the color. Otherwise, 1 means to show color.
|
||||||
//| :param int highlight_color: RGB888 of source color to highlight with third ePaper color.
|
//| :param int highlight_color: RGB888 of source color to highlight with third ePaper color.
|
||||||
|
//| :param int highlight_color2: RGB888 of source color to highlight with fourth ePaper color.
|
||||||
//| :param int refresh_display_command: Command used to start a display refresh. Single int or byte-packed command sequence
|
//| :param int refresh_display_command: Command used to start a display refresh. Single int or byte-packed command sequence
|
||||||
//| :param float refresh_time: Time it takes to refresh the display before the stop_sequence should be sent. Ignored when busy_pin is provided.
|
//| :param float refresh_time: Time it takes to refresh the display before the stop_sequence should be sent. Ignored when busy_pin is provided.
|
||||||
//| :param microcontroller.Pin busy_pin: Pin used to signify the display is busy
|
//| :param microcontroller.Pin busy_pin: Pin used to signify the display is busy
|
||||||
|
|
@ -117,7 +119,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type,
|
||||||
ARG_ram_width, ARG_ram_height, ARG_colstart, ARG_rowstart, ARG_rotation,
|
ARG_ram_width, ARG_ram_height, ARG_colstart, ARG_rowstart, ARG_rotation,
|
||||||
ARG_set_column_window_command, ARG_set_row_window_command, ARG_set_current_column_command,
|
ARG_set_column_window_command, ARG_set_row_window_command, ARG_set_current_column_command,
|
||||||
ARG_set_current_row_command, ARG_write_black_ram_command, ARG_black_bits_inverted,
|
ARG_set_current_row_command, ARG_write_black_ram_command, ARG_black_bits_inverted,
|
||||||
ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color,
|
ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color, ARG_highlight_color2,
|
||||||
ARG_refresh_display_command, ARG_refresh_time, ARG_busy_pin, ARG_busy_state,
|
ARG_refresh_display_command, ARG_refresh_time, ARG_busy_pin, ARG_busy_state,
|
||||||
ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_advanced_color_epaper, ARG_spectra6,
|
ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_advanced_color_epaper, ARG_spectra6,
|
||||||
ARG_two_byte_sequence_length, ARG_start_up_time, ARG_address_little_endian };
|
ARG_two_byte_sequence_length, ARG_start_up_time, ARG_address_little_endian };
|
||||||
|
|
@ -141,6 +143,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type,
|
||||||
{ MP_QSTR_write_color_ram_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
|
{ MP_QSTR_write_color_ram_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
|
||||||
{ MP_QSTR_color_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
{ MP_QSTR_color_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||||
{ MP_QSTR_highlight_color, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} },
|
{ MP_QSTR_highlight_color, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} },
|
||||||
|
{ MP_QSTR_highlight_color2, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} },
|
||||||
{ MP_QSTR_refresh_display_command, MP_ARG_OBJ | MP_ARG_REQUIRED },
|
{ MP_QSTR_refresh_display_command, MP_ARG_OBJ | MP_ARG_REQUIRED },
|
||||||
{ MP_QSTR_refresh_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(40)} },
|
{ MP_QSTR_refresh_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(40)} },
|
||||||
{ MP_QSTR_busy_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
|
{ MP_QSTR_busy_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
|
||||||
|
|
@ -181,6 +184,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type,
|
||||||
|
|
||||||
mp_int_t write_color_ram_command = NO_COMMAND;
|
mp_int_t write_color_ram_command = NO_COMMAND;
|
||||||
mp_int_t highlight_color = args[ARG_highlight_color].u_int;
|
mp_int_t highlight_color = args[ARG_highlight_color].u_int;
|
||||||
|
mp_int_t highlight_color2 = args[ARG_highlight_color2].u_int;
|
||||||
if (args[ARG_write_color_ram_command].u_obj != mp_const_none) {
|
if (args[ARG_write_color_ram_command].u_obj != mp_const_none) {
|
||||||
write_color_ram_command = mp_obj_get_int(args[ARG_write_color_ram_command].u_obj);
|
write_color_ram_command = mp_obj_get_int(args[ARG_write_color_ram_command].u_obj);
|
||||||
}
|
}
|
||||||
|
|
@ -216,7 +220,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type,
|
||||||
args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int,
|
args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int,
|
||||||
args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int,
|
args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int,
|
||||||
args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command,
|
args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command,
|
||||||
args[ARG_color_bits_inverted].u_bool, highlight_color, refresh_buf, refresh_buf_len, refresh_time,
|
args[ARG_color_bits_inverted].u_bool, highlight_color, highlight_color2, refresh_buf, refresh_buf_len, refresh_time,
|
||||||
busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame,
|
busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame,
|
||||||
args[ARG_always_toggle_chip_select].u_bool, args[ARG_grayscale].u_bool, args[ARG_advanced_color_epaper].u_bool, args[ARG_spectra6].u_bool,
|
args[ARG_always_toggle_chip_select].u_bool, args[ARG_grayscale].u_bool, args[ARG_advanced_color_epaper].u_bool, args[ARG_spectra6].u_bool,
|
||||||
two_byte_sequence_length, args[ARG_address_little_endian].u_bool
|
two_byte_sequence_length, args[ARG_address_little_endian].u_bool
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla
|
||||||
uint16_t set_column_window_command, uint16_t set_row_window_command,
|
uint16_t set_column_window_command, uint16_t set_row_window_command,
|
||||||
uint16_t set_current_column_command, uint16_t set_current_row_command,
|
uint16_t set_current_column_command, uint16_t set_current_row_command,
|
||||||
uint16_t write_black_ram_command, bool black_bits_inverted,
|
uint16_t write_black_ram_command, bool black_bits_inverted,
|
||||||
uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color,
|
uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint32_t highlight_color2,
|
||||||
const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time,
|
const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time,
|
||||||
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame,
|
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame,
|
||||||
bool always_toggle_chip_select, bool grayscale, bool acep, bool spectra6, bool two_byte_sequence_length,
|
bool always_toggle_chip_select, bool grayscale, bool acep, bool spectra6, bool two_byte_sequence_length,
|
||||||
|
|
|
||||||
|
|
@ -163,8 +163,13 @@ uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color) {
|
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color) {
|
||||||
|
if (pixel_chroma <= 16) {
|
||||||
|
if (!colorspace->grayscale) {
|
||||||
|
*color = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
int16_t hue_diff = colorspace->tricolor_hue - pixel_hue;
|
int16_t hue_diff = colorspace->tricolor_hue - pixel_hue;
|
||||||
if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) {
|
if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) {
|
||||||
if (colorspace->grayscale) {
|
if (colorspace->grayscale) {
|
||||||
|
|
@ -177,6 +182,21 @@ void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayio_colorconverter_compute_fourcolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color) {
|
||||||
|
*color >>= 1;
|
||||||
|
if (pixel_chroma <= 16) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int16_t hue_diff = colorspace->tricolor_hue - pixel_hue;
|
||||||
|
if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) {
|
||||||
|
*color = 2;
|
||||||
|
}
|
||||||
|
int16_t hue_diff2 = colorspace->fourcolor_hue - pixel_hue;
|
||||||
|
if ((-10 <= hue_diff2 && hue_diff2 <= 10) || hue_diff2 <= -220 || hue_diff2 >= 220) {
|
||||||
|
*color = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, uint32_t input_color, uint32_t *output_color) {
|
void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, uint32_t input_color, uint32_t *output_color) {
|
||||||
displayio_input_pixel_t input_pixel;
|
displayio_input_pixel_t input_pixel;
|
||||||
input_pixel.pixel = input_color;
|
input_pixel.pixel = input_color;
|
||||||
|
|
@ -313,18 +333,17 @@ void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dit
|
||||||
output_color->pixel = packed;
|
output_color->pixel = packed;
|
||||||
output_color->opaque = true;
|
output_color->opaque = true;
|
||||||
return;
|
return;
|
||||||
} else if (colorspace->tricolor) {
|
} else if (colorspace->tricolor || colorspace->fourcolor) {
|
||||||
uint8_t luma = displayio_colorconverter_compute_luma(pixel);
|
uint8_t luma = displayio_colorconverter_compute_luma(pixel);
|
||||||
|
uint8_t pixel_chroma = displayio_colorconverter_compute_chroma(pixel);
|
||||||
output_color->pixel = luma >> (8 - colorspace->depth);
|
output_color->pixel = luma >> (8 - colorspace->depth);
|
||||||
if (displayio_colorconverter_compute_chroma(pixel) <= 16) {
|
|
||||||
if (!colorspace->grayscale) {
|
|
||||||
output_color->pixel = 0;
|
|
||||||
}
|
|
||||||
output_color->opaque = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uint8_t pixel_hue = displayio_colorconverter_compute_hue(pixel);
|
uint8_t pixel_hue = displayio_colorconverter_compute_hue(pixel);
|
||||||
displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, &output_color->pixel);
|
if (colorspace->tricolor) {
|
||||||
|
displayio_colorconverter_compute_tricolor(colorspace, pixel_chroma, pixel_hue, &output_color->pixel);
|
||||||
|
} else if (colorspace->fourcolor) {
|
||||||
|
displayio_colorconverter_compute_fourcolor(colorspace, pixel_chroma, pixel_hue, &output_color->pixel);
|
||||||
|
}
|
||||||
|
output_color->opaque = true;
|
||||||
return;
|
return;
|
||||||
} else if (colorspace->grayscale && colorspace->depth <= 8) {
|
} else if (colorspace->grayscale && colorspace->depth <= 8) {
|
||||||
uint8_t luma = displayio_colorconverter_compute_luma(pixel);
|
uint8_t luma = displayio_colorconverter_compute_luma(pixel);
|
||||||
|
|
|
||||||
|
|
@ -43,4 +43,5 @@ uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888);
|
||||||
uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888);
|
uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888);
|
||||||
uint8_t displayio_colorconverter_compute_sixcolor(uint32_t color_rgb888);
|
uint8_t displayio_colorconverter_compute_sixcolor(uint32_t color_rgb888);
|
||||||
uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888);
|
uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888);
|
||||||
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color);
|
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color);
|
||||||
|
void displayio_colorconverter_compute_fourcolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color);
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,11 @@ typedef struct {
|
||||||
uint8_t depth;
|
uint8_t depth;
|
||||||
uint8_t bytes_per_cell;
|
uint8_t bytes_per_cell;
|
||||||
uint8_t tricolor_hue;
|
uint8_t tricolor_hue;
|
||||||
uint8_t tricolor_luma;
|
uint8_t fourcolor_hue;
|
||||||
uint8_t grayscale_bit; // The lowest grayscale bit. Normally 8 - depth.
|
uint8_t grayscale_bit; // The lowest grayscale bit. Normally 8 - depth.
|
||||||
bool grayscale;
|
bool grayscale;
|
||||||
bool tricolor;
|
bool tricolor;
|
||||||
|
bool fourcolor;
|
||||||
bool sixcolor; // Spectra6 e-ink screens.
|
bool sixcolor; // Spectra6 e-ink screens.
|
||||||
bool sevencolor; // Acep e-ink screens.
|
bool sevencolor; // Acep e-ink screens.
|
||||||
bool pixels_in_byte_share_row;
|
bool pixels_in_byte_share_row;
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,7 @@ void reset_displays(void) {
|
||||||
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
|
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
|
||||||
mp_const_obj_t display_bus_type = display_buses[i].bus_base.type;
|
mp_const_obj_t display_bus_type = display_buses[i].bus_base.type;
|
||||||
if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
|
if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
|
||||||
|
display_buses[i].bus_base.type = &mp_type_NoneType;
|
||||||
continue;
|
continue;
|
||||||
#if CIRCUITPY_FOURWIRE
|
#if CIRCUITPY_FOURWIRE
|
||||||
} else if (display_bus_type == &fourwire_fourwire_type) {
|
} else if (display_bus_type == &fourwire_fourwire_type) {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla
|
||||||
uint16_t set_column_window_command, uint16_t set_row_window_command,
|
uint16_t set_column_window_command, uint16_t set_row_window_command,
|
||||||
uint16_t set_current_column_command, uint16_t set_current_row_command,
|
uint16_t set_current_column_command, uint16_t set_current_row_command,
|
||||||
uint16_t write_black_ram_command, bool black_bits_inverted,
|
uint16_t write_black_ram_command, bool black_bits_inverted,
|
||||||
uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color,
|
uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint32_t highlight_color2,
|
||||||
const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time,
|
const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time,
|
||||||
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame,
|
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame,
|
||||||
bool chip_select, bool grayscale, bool acep, bool spectra6, bool two_byte_sequence_length, bool address_little_endian) {
|
bool chip_select, bool grayscale, bool acep, bool spectra6, bool two_byte_sequence_length, bool address_little_endian) {
|
||||||
|
|
@ -42,10 +42,16 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla
|
||||||
if (highlight_color != 0x000000) {
|
if (highlight_color != 0x000000) {
|
||||||
self->core.colorspace.tricolor = true;
|
self->core.colorspace.tricolor = true;
|
||||||
self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color);
|
self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color);
|
||||||
self->core.colorspace.tricolor_luma = displayio_colorconverter_compute_luma(highlight_color);
|
|
||||||
} else {
|
} else {
|
||||||
self->core.colorspace.tricolor = false;
|
self->core.colorspace.tricolor = false;
|
||||||
}
|
}
|
||||||
|
if (highlight_color != 0x000000 && highlight_color2 != 0x000000) {
|
||||||
|
self->core.colorspace.tricolor = false;
|
||||||
|
self->core.colorspace.fourcolor = true;
|
||||||
|
self->core.colorspace.fourcolor_hue = displayio_colorconverter_compute_hue(highlight_color2);
|
||||||
|
} else {
|
||||||
|
self->core.colorspace.fourcolor = false;
|
||||||
|
}
|
||||||
self->acep = acep || spectra6;
|
self->acep = acep || spectra6;
|
||||||
self->core.colorspace.sixcolor = spectra6;
|
self->core.colorspace.sixcolor = spectra6;
|
||||||
self->core.colorspace.sevencolor = acep;
|
self->core.colorspace.sevencolor = acep;
|
||||||
|
|
@ -54,6 +60,11 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla
|
||||||
grayscale = false;
|
grayscale = false;
|
||||||
core_grayscale = false;
|
core_grayscale = false;
|
||||||
}
|
}
|
||||||
|
if ((highlight_color != 0x000000 || highlight_color2 != 0x000000) && write_color_ram_command == NO_COMMAND) {
|
||||||
|
color_depth = 2;
|
||||||
|
core_grayscale = false;
|
||||||
|
grayscale = false;
|
||||||
|
}
|
||||||
|
|
||||||
displayio_display_core_construct(&self->core, width, height, rotation, color_depth, core_grayscale, true, 1, true, true);
|
displayio_display_core_construct(&self->core, width, height, rotation, color_depth, core_grayscale, true, 1, true, true);
|
||||||
displayio_display_bus_construct(&self->bus, bus, ram_width, ram_height,
|
displayio_display_bus_construct(&self->bus, bus, ram_width, ram_height,
|
||||||
|
|
@ -90,7 +101,7 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the color memory if it isn't in use.
|
// Clear the color memory if it isn't in use.
|
||||||
if (highlight_color == 0x00 && write_color_ram_command != NO_COMMAND) {
|
if (highlight_color == 0x00 && highlight_color2 == 0x00 && write_color_ram_command != NO_COMMAND) {
|
||||||
// TODO: Clear
|
// TODO: Clear
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue