Skip to content

Commit 2e183f4

Browse files
committed
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.
1 parent 5202246 commit 2e183f4

File tree

7 files changed

+56
-19
lines changed

7 files changed

+56
-19
lines changed

shared-bindings/epaperdisplay/EPaperDisplay.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
//| write_color_ram_command: Optional[int] = None,
5555
//| color_bits_inverted: bool = False,
5656
//| highlight_color: int = 0x000000,
57+
//| highlight_color2: int = 0x000000,
5758
//| refresh_display_command: Union[int, circuitpython_typing.ReadableBuffer],
5859
//| refresh_time: float = 40,
5960
//| busy_pin: Optional[microcontroller.Pin] = None,
@@ -97,6 +98,7 @@
9798
//| :param int write_color_ram_command: Command used to write pixels values into the update region
9899
//| :param bool color_bits_inverted: True if 0 bits are used to show the color. Otherwise, 1 means to show color.
99100
//| :param int highlight_color: RGB888 of source color to highlight with third ePaper color.
101+
//| :param int highlight_color2: RGB888 of source color to highlight with fourth ePaper color.
100102
//| :param int refresh_display_command: Command used to start a display refresh. Single int or byte-packed command sequence
101103
//| :param float refresh_time: Time it takes to refresh the display before the stop_sequence should be sent. Ignored when busy_pin is provided.
102104
//| :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,
117119
ARG_ram_width, ARG_ram_height, ARG_colstart, ARG_rowstart, ARG_rotation,
118120
ARG_set_column_window_command, ARG_set_row_window_command, ARG_set_current_column_command,
119121
ARG_set_current_row_command, ARG_write_black_ram_command, ARG_black_bits_inverted,
120-
ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color,
122+
ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color, ARG_highlight_color2,
121123
ARG_refresh_display_command, ARG_refresh_time, ARG_busy_pin, ARG_busy_state,
122124
ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_advanced_color_epaper, ARG_spectra6,
123125
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,
141143
{ MP_QSTR_write_color_ram_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
142144
{ MP_QSTR_color_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
143145
{ MP_QSTR_highlight_color, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} },
146+
{ MP_QSTR_highlight_color2, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} },
144147
{ MP_QSTR_refresh_display_command, MP_ARG_OBJ | MP_ARG_REQUIRED },
145148
{ MP_QSTR_refresh_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(40)} },
146149
{ 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,
181184

182185
mp_int_t write_color_ram_command = NO_COMMAND;
183186
mp_int_t highlight_color = args[ARG_highlight_color].u_int;
187+
mp_int_t highlight_color2 = args[ARG_highlight_color2].u_int;
184188
if (args[ARG_write_color_ram_command].u_obj != mp_const_none) {
185189
write_color_ram_command = mp_obj_get_int(args[ARG_write_color_ram_command].u_obj);
186190
}
@@ -216,7 +220,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type,
216220
args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int,
217221
args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int,
218222
args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command,
219-
args[ARG_color_bits_inverted].u_bool, highlight_color, refresh_buf, refresh_buf_len, refresh_time,
223+
args[ARG_color_bits_inverted].u_bool, highlight_color, highlight_color2, refresh_buf, refresh_buf_len, refresh_time,
220224
busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame,
221225
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,
222226
two_byte_sequence_length, args[ARG_address_little_endian].u_bool

shared-bindings/epaperdisplay/EPaperDisplay.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla
2323
uint16_t set_column_window_command, uint16_t set_row_window_command,
2424
uint16_t set_current_column_command, uint16_t set_current_row_command,
2525
uint16_t write_black_ram_command, bool black_bits_inverted,
26-
uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color,
26+
uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint32_t highlight_color2,
2727
const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time,
2828
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame,
2929
bool always_toggle_chip_select, bool grayscale, bool acep, bool spectra6, bool two_byte_sequence_length,

shared-module/displayio/ColorConverter.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,13 @@ uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888) {
163163
}
164164
}
165165

166-
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color) {
167-
166+
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color) {
167+
if (pixel_chroma <= 16) {
168+
if (!colorspace->grayscale) {
169+
*color = 0;
170+
}
171+
return;
172+
}
168173
int16_t hue_diff = colorspace->tricolor_hue - pixel_hue;
169174
if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) {
170175
if (colorspace->grayscale) {
@@ -177,6 +182,21 @@ void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *co
177182
}
178183
}
179184

185+
void displayio_colorconverter_compute_fourcolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color) {
186+
*color >>= 1;
187+
if (pixel_chroma <= 16) {
188+
return;
189+
}
190+
int16_t hue_diff = colorspace->tricolor_hue - pixel_hue;
191+
if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) {
192+
*color = 2;
193+
}
194+
int16_t hue_diff2 = colorspace->fourcolor_hue - pixel_hue;
195+
if ((-10 <= hue_diff2 && hue_diff2 <= 10) || hue_diff2 <= -220 || hue_diff2 >= 220) {
196+
*color = 3;
197+
}
198+
}
199+
180200
void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, uint32_t input_color, uint32_t *output_color) {
181201
displayio_input_pixel_t input_pixel;
182202
input_pixel.pixel = input_color;
@@ -313,18 +333,17 @@ void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dit
313333
output_color->pixel = packed;
314334
output_color->opaque = true;
315335
return;
316-
} else if (colorspace->tricolor) {
336+
} else if (colorspace->tricolor || colorspace->fourcolor) {
317337
uint8_t luma = displayio_colorconverter_compute_luma(pixel);
338+
uint8_t pixel_chroma = displayio_colorconverter_compute_chroma(pixel);
318339
output_color->pixel = luma >> (8 - colorspace->depth);
319-
if (displayio_colorconverter_compute_chroma(pixel) <= 16) {
320-
if (!colorspace->grayscale) {
321-
output_color->pixel = 0;
322-
}
323-
output_color->opaque = true;
324-
return;
325-
}
326340
uint8_t pixel_hue = displayio_colorconverter_compute_hue(pixel);
327-
displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, &output_color->pixel);
341+
if (colorspace->tricolor) {
342+
displayio_colorconverter_compute_tricolor(colorspace, pixel_chroma, pixel_hue, &output_color->pixel);
343+
} else if (colorspace->fourcolor) {
344+
displayio_colorconverter_compute_fourcolor(colorspace, pixel_chroma, pixel_hue, &output_color->pixel);
345+
}
346+
output_color->opaque = true;
328347
return;
329348
} else if (colorspace->grayscale && colorspace->depth <= 8) {
330349
uint8_t luma = displayio_colorconverter_compute_luma(pixel);

shared-module/displayio/ColorConverter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888);
4343
uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888);
4444
uint8_t displayio_colorconverter_compute_sixcolor(uint32_t color_rgb888);
4545
uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888);
46-
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color);
46+
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color);
47+
void displayio_colorconverter_compute_fourcolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color);

shared-module/displayio/Palette.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ typedef struct {
1515
uint8_t depth;
1616
uint8_t bytes_per_cell;
1717
uint8_t tricolor_hue;
18-
uint8_t tricolor_luma;
18+
uint8_t fourcolor_hue;
1919
uint8_t grayscale_bit; // The lowest grayscale bit. Normally 8 - depth.
2020
bool grayscale;
2121
bool tricolor;
22+
bool fourcolor;
2223
bool sixcolor; // Spectra6 e-ink screens.
2324
bool sevencolor; // Acep e-ink screens.
2425
bool pixels_in_byte_share_row;

shared-module/displayio/__init__.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ void reset_displays(void) {
198198
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
199199
mp_const_obj_t display_bus_type = display_buses[i].bus_base.type;
200200
if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
201+
display_buses[i].bus_base.type = &mp_type_NoneType;
201202
continue;
202203
#if CIRCUITPY_FOURWIRE
203204
} else if (display_bus_type == &fourwire_fourwire_type) {

shared-module/epaperdisplay/EPaperDisplay.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla
3333
uint16_t set_column_window_command, uint16_t set_row_window_command,
3434
uint16_t set_current_column_command, uint16_t set_current_row_command,
3535
uint16_t write_black_ram_command, bool black_bits_inverted,
36-
uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color,
36+
uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint32_t highlight_color2,
3737
const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time,
3838
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame,
3939
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
4242
if (highlight_color != 0x000000) {
4343
self->core.colorspace.tricolor = true;
4444
self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color);
45-
self->core.colorspace.tricolor_luma = displayio_colorconverter_compute_luma(highlight_color);
4645
} else {
4746
self->core.colorspace.tricolor = false;
4847
}
48+
if (highlight_color != 0x000000 && highlight_color2 != 0x000000) {
49+
self->core.colorspace.tricolor = false;
50+
self->core.colorspace.fourcolor = true;
51+
self->core.colorspace.fourcolor_hue = displayio_colorconverter_compute_hue(highlight_color2);
52+
} else {
53+
self->core.colorspace.fourcolor = false;
54+
}
4955
self->acep = acep || spectra6;
5056
self->core.colorspace.sixcolor = spectra6;
5157
self->core.colorspace.sevencolor = acep;
@@ -54,6 +60,11 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla
5460
grayscale = false;
5561
core_grayscale = false;
5662
}
63+
if ((highlight_color != 0x000000 || highlight_color2 != 0x000000) && write_color_ram_command == NO_COMMAND) {
64+
color_depth = 2;
65+
core_grayscale = false;
66+
grayscale = false;
67+
}
5768

5869
displayio_display_core_construct(&self->core, width, height, rotation, color_depth, core_grayscale, true, 1, true, true);
5970
displayio_display_bus_construct(&self->bus, bus, ram_width, ram_height,
@@ -90,7 +101,7 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla
90101
}
91102

92103
// Clear the color memory if it isn't in use.
93-
if (highlight_color == 0x00 && write_color_ram_command != NO_COMMAND) {
104+
if (highlight_color == 0x00 && highlight_color2 == 0x00 && write_color_ram_command != NO_COMMAND) {
94105
// TODO: Clear
95106
}
96107

0 commit comments

Comments
 (0)