diff --git a/epaper.c b/epaper.c index 6ac27b8..86d6385 100644 --- a/epaper.c +++ b/epaper.c @@ -39,6 +39,7 @@ int main() { uint16_t i; uint16_t j; + absolute_time_t t; stdio_init_all(); @@ -103,20 +104,29 @@ int main() epd_font_set(&epd0, epd_font_inr21_mf); epd_draw_str(&epd0, 250, 154, "Sigma-wrapped text."); epd_update(&epd0); + sleep_ms(2000); - for(;;) + t = make_timeout_time_ms(180000); /* full screen refresh every 180 s */ + for (;;) { uint32_t x; uint32_t y; x = get_rand_32() % EPD_4P2MONO_WIDTH; - y = (get_rand_32() % (EPD_4P2MONO_HEIGHT - 42) + 21); + y = (get_rand_32() % (EPD_4P2MONO_HEIGHT - 28) + 23); - epd_dbuf_clear(&epd0); + //epd_dbuf_clear(&epd0); epd_font_set(&epd0, epd_font_inr21_mf); epd_draw_str(&epd0, x, y, "Sigma-wrapped text."); - epd_update(&epd0); - sleep_ms(1000); + //epd_update(&epd0); + /* FIXME: should accept width in pixels and convert to bytes internally */ + epd_update_partial(&epd0, x % 100, x, y < 23 ? 0 : y - 23, y + 5); + //sleep_ms(1000); + if(absolute_time_diff_us(t, get_absolute_time()) > 0) + { + epd_update(&epd0); + t = make_timeout_time_ms(180000); + } } return 0; diff --git a/epd/epd.c b/epd/epd.c index 114f240..1cc1082 100644 --- a/epd/epd.c +++ b/epd/epd.c @@ -190,3 +190,33 @@ int32_t epd_update(epd_t *epd) return epd->display.write(epd); } + +/** + * \brief send the dbuf to the display + * + * \details Display the contents of the dbuf on the screen within a specified + * window. Falls back on a full update if the display does not implement + * partial updates. + * + * \param[in,out] epd pointer to an epd_t + * \param[in] x0 x-coordinate of first pixel in window + * \param[in] x1 x-coordinate of last pixel in window + * \param[in] y0 y-coordinate of first pixel in window + * \param[in] y1 y-coordinate of last pixel in window + * + * \returns 0 on success + */ +int32_t epd_update_partial(epd_t *epd, uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1) +{ + return_val_if_fail(epd, -1); + return_val_if_fail(epd->dbuf, -1); + + if(epd->display.write_partial) + { + return epd->display.write_partial(epd, x0, x1, y0, y1); + } + else + { + return epd->display.write(epd); + } +} diff --git a/epd/epd.h b/epd/epd.h index 6987776..27c8825 100644 --- a/epd/epd.h +++ b/epd/epd.h @@ -35,10 +35,12 @@ typedef struct epd_platform_config_s { void *udata; } epd_platform_config_t; typedef int32_t (*epd_write_dbuf)(epd_t *); +typedef int32_t (*epd_write_dbuf_partial)(epd_t *, uint16_t, uint16_t, uint16_t, uint16_t); typedef struct epd_display_config_s { uint32_t w; uint32_t h; epd_write_dbuf write; + epd_write_dbuf_partial write_partial; } epd_display_config_t; typedef uint16_t (*epd_char_cb)(epd_t *epd, uint8_t b); typedef struct epd_font_decode_s @@ -87,5 +89,6 @@ int8_t epd_dbuf_set(epd_t *epd, epd_dbuf_t *dbuf); int8_t epd_dbuf_clear(epd_t *epd); void epd_draw_line(epd_t *epd, uint16_t x, uint16_t y, uint16_t len, epd_dir_t dir); int32_t epd_update(epd_t *epd); +int32_t epd_update_partial(epd_t *epd, uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1); #endif /* EPD_H_ */ diff --git a/epd/epd_4p2mono.c b/epd/epd_4p2mono.c index 7e6d5de..52efb20 100644 --- a/epd/epd_4p2mono.c +++ b/epd/epd_4p2mono.c @@ -987,6 +987,7 @@ static const uint8_t testimg[] = { /* Function Prototypes */ static int32_t epd_4p2mono_write_dbuf(epd_t *epd); +static int32_t epd_4p2mono_write_dbuf_partial(epd_t *epd, uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1); /* Function Definitions */ static inline void epd_rst(epd_t *epd) @@ -1027,9 +1028,10 @@ static inline void busy_wait(epd_t *epd) void epd_4p2mono_init(epd_t *epd) { epd_display_config_t cfg = { - .w = EPD_4P2MONO_WIDTH, - .h = EPD_4P2MONO_HEIGHT, - .write = epd_4p2mono_write_dbuf + .w = EPD_4P2MONO_WIDTH, + .h = EPD_4P2MONO_HEIGHT, + .write = epd_4p2mono_write_dbuf, + .write_partial = epd_4p2mono_write_dbuf_partial }; /* configure the display */ @@ -1140,3 +1142,46 @@ static int32_t epd_4p2mono_write_dbuf(epd_t *epd) return 0; } + +static int32_t epd_4p2mono_write_dbuf_partial(epd_t *epd, uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1) +{ + const uint32_t w = (EPD_4P2MONO_WIDTH % 8) ? (EPD_4P2MONO_WIDTH / 8 + 1) : (EPD_4P2MONO_WIDTH / 8); + const uint16_t x0b = x0 / 8; + const uint16_t x1b = ((x1 % 8) ? (x1 / 8 + 1) : (x1 / 8)) - 1; + uint32_t i; + uint32_t j; + const uint8_t hrstu = (uint8_t) (x0b >> 5) & 0x01; + const uint8_t hrstl = (uint8_t) (x0b << 3); + const uint8_t hredu = (uint8_t) (x1b >> 5) & 0x01; + const uint8_t hredl = (uint8_t) (x1b << 3); + const uint8_t vrstu = (uint8_t) (y0 >> 8) & 0x01; + const uint8_t vrstl = (uint8_t) (y0); + const uint8_t vredu = (uint8_t) (y1 >> 8) & 0x01; + const uint8_t vredl = (uint8_t) (y1); + + cmd_byte(epd, CMD_PTL); + data_byte(epd, hrstu); /* HRST[8] */ + data_byte(epd, hrstl); /* HRST[7:3] */ + data_byte(epd, hredu); /* HRED[8] */ + data_byte(epd, hredl); /* HRED7:3] */ + data_byte(epd, vrstu); /* VRST[8] */ + data_byte(epd, vrstl); /* VRST[7:0] */ + data_byte(epd, vredu); /* VRED[8] */ + data_byte(epd, vredl); /* VRED7:0] */ + data_byte(epd, 0x00); /* PT_SCAN */ + cmd_byte(epd, CMD_PTIN); + cmd_byte(epd, CMD_DTM2); + for(j = y0; j <= y1; j++) + { + for(i = x0b; i <= x1b; i++) + { + data_byte(epd, epd->dbuf[i + (w * j)]); + } + } + cmd_byte(epd, CMD_DRF); + busy_wait(epd); + cmd_byte(epd, CMD_PTOUT); + busy_wait(epd); + + return 0; +}