diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 08f5ff97b7eaad401e360875c5bd8cd040f9a704..e794743925a9971e586b6c1d2f8294c7d8067a8a 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -54,6 +54,7 @@ typedef _Bool bool; #define API_DISP_PIXEL 0x28 #define API_DISP_FRAMEBUFFER 0x29 #define API_DISP_BACKLIGHT 0x2a +#define API_DISP_SET_ALL 0x2b /* API_BATTERY_VOLTAGE 0x30 */ #define API_BATTERY_CURRENT 0x31 @@ -1336,6 +1337,7 @@ API(API_DISP_CIRC, */ API(API_DISP_FRAMEBUFFER, int epic_disp_framebuffer(union disp_framebuffer *fb)); +API(API_DISP_SET_ALL, int epic_disp_set_all(int32_t w, int32_t h, uint8_t *color)); /** * Set the backlight brightness value diff --git a/epicardium/modules/display.c b/epicardium/modules/display.c index c8dc51492ba51f3867405784e30719935282147b..0fc402fc5affdccbdc9a20851718cfbc8b6b0f49 100644 --- a/epicardium/modules/display.c +++ b/epicardium/modules/display.c @@ -48,6 +48,17 @@ int epic_disp_clear(uint16_t color) } } +int epic_disp_set_all(int32_t w, int32_t h, uint8_t *color) +{ + int cl = check_lock(); + if (cl < 0) { + return cl; + } else { + gfx_set_all(&display_screen, w, h, color); + return 0; + } +} + int epic_disp_pixel(uint16_t x, uint16_t y, uint16_t color) { int cl = check_lock(); diff --git a/lib/gfx/gfx.c b/lib/gfx/gfx.c index 55f1debf584f7df765e71015cf2f792628286ab8..1298758f53116a6c8596d56ea08108eeed0922a8 100644 --- a/lib/gfx/gfx.c +++ b/lib/gfx/gfx.c @@ -13,6 +13,23 @@ const struct gfx_color_rgb gfx_colors_rgb[COLORS] = { { 255, 255, 0 } /* YELLOW */ }; +void gfx_set_all(struct gfx_region *r, int32_t w, int32_t h, uint8_t *color) +{ + for (int32_t i = 0; i < w * h; i++) { + fb_setpixel( + r->fb, + (i % w), + (i / w), + fb_encode_color_rgb( + r->fb, + color[(3 * i) + 0], + color[(3 * i) + 1], + color[(3 * i) + 2]) + ); + } + r->fb->update(r->fb); +} + void gfx_setpixel(struct gfx_region *r, int x, int y, Color c) { if (x < 0 || y < 0) diff --git a/lib/gfx/gfx.h b/lib/gfx/gfx.h index 428b196c6a41465230538da60a6ff0ce3fccafb5..7fee0608bfc3c365a56338c84850a1bb58f0f589 100644 --- a/lib/gfx/gfx.h +++ b/lib/gfx/gfx.h @@ -12,6 +12,7 @@ struct gfx_region { size_t height; }; +void gfx_set_all(struct gfx_region *r, int32_t w, int32_t h, uint8_t *color); void gfx_setpixel(struct gfx_region *r, int x, int y, Color c); struct gfx_region gfx_screen(struct framebuffer *fb); void gfx_putchar(sFONT *font, struct gfx_region *reg, int x, int y, char ch, diff --git a/pycardium/modules/py/display.py b/pycardium/modules/py/display.py index e957977d6fc3603889f3155e515d351dc8f1753b..df1c7a61ad97253e142cd7444ea8829f4acd774a 100644 --- a/pycardium/modules/py/display.py +++ b/pycardium/modules/py/display.py @@ -101,6 +101,17 @@ class Display: sys_display.backlight(brightness) return self + def set_all(self, w, h, colors): + """ + Draw entire image on the display + + :param w: width, 0 < w <= 160 + :param h: height, 0 < h <= 80 + :param colors: w*h*3 RGB values + """ + sys_display.set_all(w, h, colors) + return self + def line(self, xs, ys, xe, ye, *, col=None, dotted=False, size=1): """ Draws a line on the display. diff --git a/pycardium/modules/sys_display.c b/pycardium/modules/sys_display.c index f5523d54831695679965ddcb76e7df8c6fa2ba29..ffa98fb68c3adf244af22c8c8e86f7f027673d51 100644 --- a/pycardium/modules/sys_display.c +++ b/pycardium/modules/sys_display.c @@ -53,6 +53,31 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( display_print_obj, 5, 5, mp_display_print ); +static mp_obj_t +mp_display_set_all(mp_obj_t w_in, mp_obj_t h_in, mp_obj_t color_in) +{ + uint32_t len = mp_obj_get_int(mp_obj_len(color_in)); + uint32_t w = mp_obj_get_int(w_in); + uint32_t h = mp_obj_get_int(h_in); + if (w * h * 3 != len) { + mp_raise_ValueError( + "width * height * 3 does not match frame size" + ); + } + uint8_t pattern[len]; + for (int32_t i = 0; i < len; i++) { + pattern[i] = mp_obj_get_int(mp_obj_subscr( + color_in, mp_obj_new_int(i), MP_OBJ_SENTINEL) + ); + } + int res = epic_disp_set_all(w, h, (uint8_t *)pattern); + if (res < 0) { + mp_raise_OSError(-res); + } + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_3(display_set_all_obj, mp_display_set_all); + /* draw pixel on the display */ static mp_obj_t mp_display_pixel(size_t n_args, const mp_obj_t *args) { @@ -236,6 +261,7 @@ static const mp_rom_map_elem_t display_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&display_print_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&display_pixel_obj) }, { MP_ROM_QSTR(MP_QSTR_backlight), MP_ROM_PTR(&display_backlight_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_all), MP_ROM_PTR(&display_set_all_obj) }, { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&display_line_obj) }, { MP_ROM_QSTR(MP_QSTR_rect), MP_ROM_PTR(&display_rect_obj) }, { MP_ROM_QSTR(MP_QSTR_circ), MP_ROM_PTR(&display_circ_obj) },