diff --git a/EPD/EPD_driver.c b/EPD/EPD_driver.c index e8ce3b1..50dc18f 100644 --- a/EPD/EPD_driver.c +++ b/EPD/EPD_driver.c @@ -224,7 +224,7 @@ void EPD_FillRAM(uint8_t cmd, uint8_t value, uint32_t len) void EPD_Reset(uint32_t value, uint16_t duration) { digitalWrite(EPD_RST_PIN, value); - delay(10); + delay(duration); digitalWrite(EPD_RST_PIN, (value == LOW) ? HIGH : LOW); delay(duration); digitalWrite(EPD_RST_PIN, value); @@ -335,12 +335,14 @@ extern epd_model_t epd_uc8176_420_bw; extern epd_model_t epd_uc8176_420_bwr; extern epd_model_t epd_ssd1619_420_bwr; extern epd_model_t epd_ssd1619_420_bw; +extern epd_model_t epd_jd79668_420; static epd_model_t *epd_models[] = { &epd_uc8176_420_bw, &epd_uc8176_420_bwr, &epd_ssd1619_420_bwr, &epd_ssd1619_420_bw, + &epd_jd79668_420, }; epd_model_t *epd_get(void) diff --git a/EPD/EPD_driver.h b/EPD/EPD_driver.h index f793648..2f0100a 100644 --- a/EPD/EPD_driver.h +++ b/EPD/EPD_driver.h @@ -47,15 +47,23 @@ typedef enum EPD_UC8176_420_BWR = 3, EPD_SSD1619_420_BWR = 2, EPD_SSD1619_420_BW = 4, + EPD_JD79668_420_BWRY = 5, } epd_model_id_t; +typedef enum +{ + BW = 1, + BWR = 2, + BWRY = 3, +} epd_color_t; + typedef struct { epd_model_id_t id; + epd_color_t color; epd_driver_t *drv; uint16_t width; uint16_t height; - bool bwr; } epd_model_t; #define LOW (0x0) diff --git a/EPD/EPD_service.c b/EPD/EPD_service.c index d4c4d5f..537879a 100644 --- a/EPD/EPD_service.c +++ b/EPD/EPD_service.c @@ -40,7 +40,7 @@ static void epd_gui_update(void * p_event_data, uint16_t event_size) EPD_GPIO_Init(); epd_model_t *epd = epd_init((epd_model_id_t)p_epd->config.model_id); gui_data_t data = { - .bwr = epd->bwr, + .color = epd->color, .width = epd->width, .height = epd->height, .timestamp = event->timestamp, diff --git a/EPD/JD79668.c b/EPD/JD79668.c new file mode 100644 index 0000000..bf72e68 --- /dev/null +++ b/EPD/JD79668.c @@ -0,0 +1,203 @@ +/** + * Based on GDEM042F52 driver from Good Display + * https://www.good-display.com/product/564.html + */ +#include "EPD_driver.h" +#include "nrf_log.h" + +// Driver command list. +#define CMD_PSR 0x00 // Panel Setting Register +#define CMD_PWR 0x01 // Power Setting Register +#define CMD_POF 0x02 // Power OFF Command +#define CMD_PFS 0x03 // Power OFF Sequence Setting +#define CMD_PON 0x04 // Power ON Command +#define CMD_BTST 0x06 // Booster Soft Start Command +#define CMD_DSLP 0x07 // Deep sleep Command +#define CMD_DTM 0x10 // Display Start Transmission Register +#define CMD_DSP 0x11 // Data Stop Command +#define CMD_DRF 0x12 // Display Refresh Command +#define CMD_AUTO 0x17 // Auto Sequence +#define CMD_PLL 0x30 // PLL control Register +#define CMD_TSC 0x40 // Temperature Sensor Command +#define CMD_TSE 0x41 // Temperature Sensor Calibration Register +#define CMD_TSW 0x42 // Temperature Sensor Write Register +#define CMD_TSR 0x43 // Temperature Sensor Read Register +#define CMD_CDI 0x50 // VCOM and DATA interval setting Register +#define CMD_LPD 0x51 // Lower Power Detection Register +#define CMD_TRES 0x61 // Resolution setting +#define CMD_GSST 0x65 // Gate/Source Start Setting Register +#define CMD_REV 0x70 // REVISION Register +#define CMD_AMV 0x80 // Auto Measure VCOM Register +#define CMD_VV 0x81 // VCOM Value Register +#define CMD_VDCS 0x82 // VCOM_DC Setting Register +#define CMD_PTL 0x83 // Partial Window Register +#define CMD_PGM 0x90 // Program Mode +#define CMD_APG 0x91 // Active Program +#define CMD_RMTP 0x92 // Read MTP Data +#define CMD_PGM_CFG 0xA2 // MTP Program Config Register +#define CMD_CCSET 0xE0 // Cascade Setting +#define CMD_PWS 0xE3 // Power Saving Register +#define CMD_LVSEL 0xE4 // LVD Voltage Select Register + +static void JD79668_WaitBusy(uint16_t timeout) +{ + EPD_WaitBusy(LOW, timeout); +} + +static void JD79668_PowerOn(void) +{ + EPD_WriteCmd(CMD_PON); + JD79668_WaitBusy(200); +} + +static void JD79668_PowerOff(void) +{ + EPD_WriteCmd(CMD_POF); + JD79668_WaitBusy(200); +} + +int8_t JD79668_Read_Temp(void) +{ + EPD_WriteCmd(CMD_TSC); + JD79668_WaitBusy(100); + return (int8_t)EPD_ReadByte(); +} + +void JD79668_Force_Temp(int8_t value) +{ + EPD_Write(CMD_CCSET, 0x02); + EPD_Write(0xE6, value); +} + +static void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h) +{ + EPD_Write(CMD_PTL, + x / 256, x % 256, + (x + w - 1) / 256, (x + w - 1) % 256, + y / 256, y % 256, + (y + h - 1) / 256, (y + h - 1) % 256, + 0x01); +} + +// Full update: 20s +void JD79668_Init() +{ + epd_model_t *EPD = epd_get(); + + EPD_Reset(HIGH, 50); + + EPD_Write(0x4D, 0x78); + EPD_Write(CMD_PSR, 0x0F, 0x29); + EPD_Write(CMD_BTST, 0x0D, 0x12, 0x24, 0x25, 0x12, 0x29, 0x10); + EPD_Write(CMD_PLL, 0x08); + EPD_Write(CMD_CDI, 0x37); + EPD_Write(CMD_TRES, + EPD->width / 256, EPD->width % 256, + EPD->height / 256, EPD->height % 256); + + EPD_Write(0xAE, 0xCF); + EPD_Write(0xB0, 0x13); + EPD_Write(0xBD, 0x07); + EPD_Write(0xBE, 0xFE); + EPD_Write(0xE9, 0x01); +} + +// Fast update: 12s +void JD79668_Init_Fast() +{ + epd_model_t *EPD = epd_get(); + + EPD_Reset(HIGH, 50); + + EPD_Write(0x4D, 0x78); + EPD_Write(CMD_PSR, 0x0F, 0x29); + EPD_Write(CMD_PWR, 0x07, 0x00); + EPD_Write(CMD_PFS, 0x10, 0x54, 0x44); + EPD_Write(CMD_BTST, 0x0F, 0x0A, 0x2F, 0x25, 0x22, 0x2E, 0x21); + EPD_Write(CMD_CDI, 0x37); + EPD_Write(CMD_TRES, + EPD->width / 256, EPD->width % 256, + EPD->height / 256, EPD->height % 256); + + EPD_Write(CMD_PWS, 0x22); + EPD_Write(0xB6, 0x6F); + EPD_Write(0xB4, 0xD0); + EPD_Write(0xE9, 0x01); + EPD_Write(CMD_PLL, 0x08); + + JD79668_PowerOn(); + EPD_Write(CMD_CCSET, 0x02); + EPD_Write(0xE6, 0x5A); + EPD_Write(0xA5, 0x00); + JD79668_WaitBusy(200); + JD79668_PowerOff(); +} + +static void JD79668_Refresh(void) +{ + NRF_LOG_DEBUG("[EPD]: refresh begin\n"); + epd_model_t *EPD = epd_get(); + JD79668_PowerOn(); + _setPartialRamArea(0, 0, EPD->width, EPD->height); + EPD_Write(CMD_DRF, 0x00); + JD79668_WaitBusy(30000); + JD79668_PowerOff(); + NRF_LOG_DEBUG("[EPD]: refresh end\n"); +} + +void JD79668_Clear(bool refresh) +{ + epd_model_t *EPD = epd_get(); + uint32_t ram_bytes = ((EPD->width + 3) / 4) * EPD->height; + + EPD_FillRAM(CMD_DTM, 0x55, ram_bytes); + if (refresh) + JD79668_Refresh(); +} + +void JD79668_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h) +{ + epd_model_t *EPD = epd_get(); + uint16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded + x -= x % 8; // byte boundary + w = wb * 8; // byte boundary + if (x + w > EPD->width || y + h > EPD->height) + return; + + _setPartialRamArea(x, y, w, h); + EPD_WriteCmd(CMD_DTM); + for (uint16_t i = 0; i < h * 2; i++) // 2 bits per pixel + { + for (uint16_t j = 0; j < w / 8; j++) + EPD_WriteByte(black ? black[j + i * wb] : 0x55); + } +} + +void JD79668_Sleep(void) +{ + EPD_Write(CMD_POF, 0x00); // power off + JD79668_WaitBusy(200); + delay(100); + EPD_Write(CMD_DSLP, 0xA5); // deep sleep +} + +static epd_driver_t epd_drv_JD79668 = { + .init = JD79668_Init, + .clear = JD79668_Clear, + .write_image = JD79668_Write_Image, + .refresh = JD79668_Refresh, + .sleep = JD79668_Sleep, + .read_temp = JD79668_Read_Temp, + .force_temp = JD79668_Force_Temp, + .cmd_write_ram1 = CMD_DTM, + .cmd_write_ram2 = CMD_DTM, +}; + +// JD79668 400x300 Black/White/Red/Yellow +const epd_model_t epd_jd79668_420 = { + .id = EPD_JD79668_420_BWRY, + .color = BWRY, + .drv = &epd_drv_JD79668, + .width = 400, + .height = 300, +}; diff --git a/EPD/SSD1619.c b/EPD/SSD1619.c index 270471b..1727ba9 100644 --- a/EPD/SSD1619.c +++ b/EPD/SSD1619.c @@ -131,7 +131,7 @@ static void SSD1619_Refresh(void) { epd_model_t *EPD = epd_get(); - EPD_Write(CMD_DISP_CTRL1, EPD->bwr ? 0x80 : 0x40, 0x00); + EPD_Write(CMD_DISP_CTRL1, EPD->color == BWR ? 0x80 : 0x40, 0x00); NRF_LOG_DEBUG("[EPD]: refresh begin\n"); NRF_LOG_DEBUG("[EPD]: temperature: %d\n", SSD1619_Read_Temp()); @@ -178,7 +178,7 @@ void SSD1619_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, { for (uint16_t j = 0; j < w / 8; j++) { - if (EPD->bwr) + if (EPD->color == BWR) EPD_WriteByte(color ? color[j + i * wb] : 0xFF); else EPD_WriteByte(black[j + i * wb]); @@ -207,17 +207,17 @@ static epd_driver_t epd_drv_ssd1619 = { // SSD1619 400x300 Black/White/Red const epd_model_t epd_ssd1619_420_bwr = { .id = EPD_SSD1619_420_BWR, + .color = BWR, .drv = &epd_drv_ssd1619, .width = 400, .height = 300, - .bwr = true, }; // SSD1619 400x300 Black/White const epd_model_t epd_ssd1619_420_bw = { .id = EPD_SSD1619_420_BW, + .color = BW, .drv = &epd_drv_ssd1619, .width = 400, .height = 300, - .bwr = false, }; diff --git a/EPD/UC8176.c b/EPD/UC8176.c index 3e1ba85..92c534e 100644 --- a/EPD/UC8176.c +++ b/EPD/UC8176.c @@ -157,8 +157,8 @@ void UC8176_Init() // UC8176_Dump_OTP(); - EPD_Write(CMD_PSR, EPD->bwr ? 0x0F : 0x1F); - EPD_Write(CMD_CDI, EPD->bwr ? 0x77 : 0x97); + EPD_Write(CMD_PSR, EPD->color == BWR ? 0x0F : 0x1F); + EPD_Write(CMD_CDI, EPD->color == BWR ? 0x77 : 0x97); } void UC8176_Clear(bool refresh) @@ -184,7 +184,7 @@ void UC8176_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, EPD_WriteCmd(CMD_PTIN); // partial in _setPartialRamArea(x, y, w, h); - if (EPD->bwr) + if (EPD->color == BWR) { EPD_WriteCmd(CMD_DTM1); for (uint16_t i = 0; i < h; i++) @@ -198,7 +198,7 @@ void UC8176_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, { for (uint16_t j = 0; j < w / 8; j++) { - if (EPD->bwr) + if (EPD->color == BWR) EPD_WriteByte(color ? color[j + i * wb] : 0xFF); else EPD_WriteByte(black[j + i * wb]); @@ -230,17 +230,17 @@ static epd_driver_t epd_drv_uc8176 = { // UC8176 400x300 Black/White const epd_model_t epd_uc8176_420_bw = { .id = EPD_UC8176_420_BW, + .color = BW, .drv = &epd_drv_uc8176, .width = 400, .height = 300, - .bwr = false, }; // UC8176 400x300 Black/White/Red const epd_model_t epd_uc8176_420_bwr = { .id = EPD_UC8176_420_BWR, + .color = BWR, .drv = &epd_drv_uc8176, .width = 400, .height = 300, - .bwr = true, }; diff --git a/GUI/Adafruit_GFX.c b/GUI/Adafruit_GFX.c index 5660389..f4a7157 100644 --- a/GUI/Adafruit_GFX.c +++ b/GUI/Adafruit_GFX.c @@ -100,11 +100,26 @@ void GFX_begin(Adafruit_GFX *gfx, int16_t w, int16_t h, int16_t buffer_height) { /**************************************************************************/ void GFX_begin_3c(Adafruit_GFX *gfx, int16_t w, int16_t h, int16_t buffer_height) { GFX_begin(gfx, w, h, buffer_height); - gfx->page_height = buffer_height / 2; + gfx->page_height /= 2; gfx->color = gfx->buffer + ((gfx->WIDTH + 7) / 8) * gfx->page_height; gfx->total_pages = (gfx->HEIGHT / gfx->page_height) + (gfx->HEIGHT % gfx->page_height > 0); } +/**************************************************************************/ +/*! + @brief Instatiate a 4-color GFX context for graphics + @param w Display width, in pixels + @param h Display height, in pixels + @param buffer_height Page buffer height, should be multiple of 2 +*/ +/**************************************************************************/ +void GFX_begin_4c(Adafruit_GFX *gfx, int16_t w, int16_t h, int16_t buffer_height) { + GFX_begin(gfx, w, h, buffer_height); + gfx->page_height /= 2; + gfx->color = gfx->buffer; + gfx->total_pages = (gfx->HEIGHT / gfx->page_height) + (gfx->HEIGHT % gfx->page_height > 0); +} + void GFX_end(Adafruit_GFX *gfx) { if (gfx->buffer) free(gfx->buffer); } @@ -148,7 +163,39 @@ void GFX_setRotation(Adafruit_GFX *gfx, GFX_Rotate r) { } } - +static uint8_t color4(uint16_t color) { + static uint16_t _prev_color = GFX_BLACK; + static uint8_t _prev_color4 = 0x00; // black + if (color == _prev_color) return _prev_color4; + uint8_t cv4 = 0x00; + switch (color) + { + case GFX_BLACK: cv4 = 0x00; break; + case GFX_WHITE: cv4 = 0x01; break; + case GFX_GREEN: cv4 = 0x02; break; // use yellow? + case GFX_BLUE: cv4 = 0x00; break; // use black + case GFX_RED: cv4 = 0x03; break; + case GFX_YELLOW: cv4 = 0x02; break; + case GFX_ORANGE: cv4 = 0x02; break; // use yellow? + default: { + uint16_t red = color & 0xF800; + uint16_t green = (color & 0x07E0) << 5; + uint16_t blue = (color & 0x001F) << 11; + if ((red < 0x8000) && (green < 0x8000) && (blue < 0x8000)) cv4 = 0x00; // black + else if ((red >= 0x8000) && (green >= 0x8000) && (blue >= 0x8000)) cv4 = 0x01; // white + else if ((red >= 0x8000) && (blue >= 0x8000)) cv4 = 0x03; // red, blue > red + else if ((green >= 0x8000) && (blue >= 0x8000)) cv4 = 0x01; // green, blue > white + else if ((red >= 0x8000) && (green >= 0xC000)) cv4 = 0x02; // yellow + else if ((red >= 0x8000) && (green >= 0x4000)) cv4 = 0x03; // orange > red + else if (red >= 0x8000) cv4 = 0x03; // red + else if (green >= 0x8000) cv4 = 0x00; // green > black + else cv4 = 0x03; // blue + } break; + } + _prev_color = color; + _prev_color4 = cv4; + return cv4; +} /**************************************************************************/ /*! @brief Draw a pixel @@ -180,15 +227,25 @@ void GFX_drawPixel(Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t color) { y -= gfx->current_page * gfx->page_height; if (y < 0 || y >= gfx->page_height) return; - uint16_t i = x / 8 + y * (gfx->WIDTH / 8); - if (gfx->color != NULL) { + if (gfx->color == gfx->buffer) { // 4c + uint32_t i = x / 4 + ((uint32_t)y) * (gfx->WIDTH / 4); + uint8_t pv = color4(color); + switch(x % 4) { + case 0: gfx->buffer[i] = (gfx->buffer[i] & 0x3F) | (pv << 6); break; + case 1: gfx->buffer[i] = (gfx->buffer[i] & 0xCF) | (pv << 4); break; + case 2: gfx->buffer[i] = (gfx->buffer[i] & 0xF3) | (pv << 2); break; + case 3: gfx->buffer[i] = (gfx->buffer[i] & 0xFC) | pv; break; + } + } else if (gfx->color != NULL) { // 3c + uint16_t i = x / 8 + y * (gfx->WIDTH / 8); gfx->buffer[i] |= 0x80 >> (x & 7); // white gfx->color[i] |= 0x80 >> (x & 7); if (color == GFX_BLACK) gfx->buffer[i] &= ~(0x80 >> (x & 7)); - else if (color == GFX_RED) + else if (color != GFX_WHITE) gfx->color[i] &= ~(0x80 >> (x & 7)); } else { + uint16_t i = x / 8 + y * (gfx->WIDTH / 8); if (color == GFX_WHITE) gfx->buffer[i] |= 0x80 >> (x & 7); else @@ -299,9 +356,14 @@ void GFX_fillRect(Adafruit_GFX *gfx, int16_t x, int16_t y, int16_t w, int16_t h, /**************************************************************************/ void GFX_fillScreen(Adafruit_GFX *gfx, uint16_t color) { uint32_t size = ((gfx->WIDTH + 7) / 8) * gfx->page_height; - memset(gfx->buffer, color == GFX_WHITE ? 0xFF : 0x00, size); - if (gfx->color != NULL) - memset(gfx->color, color == GFX_RED ? 0x00 : 0xFF, size); + if (gfx->color == gfx->buffer) { // 4c + uint8_t pv = color4(color) * 0x55; // 0b01010101 + memset(gfx->buffer, pv, size * 2); + } else { + memset(gfx->buffer, color == GFX_WHITE ? 0xFF : 0x00, size); + if (gfx->color != NULL) + memset(gfx->color, color == GFX_RED ? 0x00 : 0xFF, size); + } } /**************************************************************************/ diff --git a/GUI/Adafruit_GFX.h b/GUI/Adafruit_GFX.h index 5986dad..848c03c 100644 --- a/GUI/Adafruit_GFX.h +++ b/GUI/Adafruit_GFX.h @@ -8,7 +8,11 @@ #define GFX_BLACK 0x0000 #define GFX_WHITE 0xFFFF -#define GFX_RED 0xF800 +#define GFX_RED 0xF800 // 255, 0, 0 +#define GFX_YELLOW 0xFFE0 // 255, 255, 0 +#define GFX_BLUE 0x001F // 0, 0, 255 +#define GFX_GREEN 0x07E0 // 0, 255, 0 +#define GFX_ORANGE 0xFC00 // 255, 128, 0 typedef void (*buffer_callback)(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h); @@ -33,7 +37,7 @@ typedef struct { uint8_t utf8_state; // current state of the utf-8 decoder, contains the remaining bytes for a detected unicode glyph uint8_t *buffer; // black pixel buffer - uint8_t *color; // color pixel buffer + uint8_t *color; // color pixel buffer (3c only) int16_t page_height; int16_t current_page; int16_t total_pages; @@ -42,6 +46,7 @@ typedef struct { // CONTROL API void GFX_begin(Adafruit_GFX *gfx, int16_t w, int16_t h, int16_t buffer_height); void GFX_begin_3c(Adafruit_GFX *gfx, int16_t w, int16_t h, int16_t buffer_height); +void GFX_begin_4c(Adafruit_GFX *gfx, int16_t w, int16_t h, int16_t buffer_height); void GFX_setRotation(Adafruit_GFX *gfx, GFX_Rotate r); void GFX_firstPage(Adafruit_GFX *gfx); bool GFX_nextPage(Adafruit_GFX *gfx, buffer_callback callback); diff --git a/GUI/GUI.c b/GUI/GUI.c index 2f4b432..e21fa3d 100644 --- a/GUI/GUI.c +++ b/GUI/GUI.c @@ -350,8 +350,10 @@ void DrawGUI(gui_data_t *data, buffer_callback draw, display_mode_t mode) Adafruit_GFX gfx; - if (data->bwr) + if (data->color == 2) GFX_begin_3c(&gfx, data->width, data->height, PAGE_HEIGHT); + else if (data->color == 3) + GFX_begin_4c(&gfx, data->width, data->height, PAGE_HEIGHT); else GFX_begin(&gfx, data->width, data->height, PAGE_HEIGHT); diff --git a/GUI/GUI.h b/GUI/GUI.h index 8da03d0..906e7e3 100644 --- a/GUI/GUI.h +++ b/GUI/GUI.h @@ -14,7 +14,7 @@ typedef enum { } display_mode_t; typedef struct { - bool bwr; + uint16_t color; uint16_t width; uint16_t height; uint32_t timestamp; diff --git a/Keil/EPD-nRF51.uvprojx b/Keil/EPD-nRF51.uvprojx index 4a72667..e231ee8 100644 --- a/Keil/EPD-nRF51.uvprojx +++ b/Keil/EPD-nRF51.uvprojx @@ -424,6 +424,11 @@ 1 ..\EPD\SSD1619.c + + JD79668.c + 1 + ..\EPD\JD79668.c + @@ -1061,6 +1066,11 @@ 1 ..\EPD\SSD1619.c + + JD79668.c + 1 + ..\EPD\JD79668.c + diff --git a/Keil/EPD-nRF52.uvprojx b/Keil/EPD-nRF52.uvprojx index 8ecaa6c..4aa03c3 100644 --- a/Keil/EPD-nRF52.uvprojx +++ b/Keil/EPD-nRF52.uvprojx @@ -424,6 +424,11 @@ 1 ..\EPD\SSD1619.c + + JD79668.c + 1 + ..\EPD\JD79668.c + @@ -1181,6 +1186,11 @@ 1 ..\EPD\SSD1619.c + + JD79668.c + 1 + ..\EPD\JD79668.c + diff --git a/Makefile.nRF51 b/Makefile.nRF51 index bbff0a3..eb69927 100644 --- a/Makefile.nRF51 +++ b/Makefile.nRF51 @@ -46,6 +46,7 @@ SRC_FILES += \ $(PROJ_DIR)/EPD/EPD_service.c \ $(PROJ_DIR)/EPD/UC8176.c \ $(PROJ_DIR)/EPD/SSD1619.c \ + $(PROJ_DIR)/EPD/JD79668.c \ $(PROJ_DIR)/GUI/GUI.c \ $(PROJ_DIR)/GUI/Lunar.c \ $(PROJ_DIR)/GUI/fonts.c \ diff --git a/Makefile.nRF52 b/Makefile.nRF52 index 9c9b94c..268c2b0 100644 --- a/Makefile.nRF52 +++ b/Makefile.nRF52 @@ -70,6 +70,7 @@ SRC_FILES += \ $(PROJ_DIR)/EPD/EPD_service.c \ $(PROJ_DIR)/EPD/UC8176.c \ $(PROJ_DIR)/EPD/SSD1619.c \ + $(PROJ_DIR)/EPD/JD79668.c \ $(PROJ_DIR)/GUI/GUI.c \ $(PROJ_DIR)/GUI/Lunar.c \ $(PROJ_DIR)/GUI/fonts.c \ diff --git a/emulator.c b/emulator.c index e08d543..c139026 100644 --- a/emulator.c +++ b/emulator.c @@ -180,7 +180,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) // Use the stored timestamp gui_data_t data = { - .bwr = g_bwr_mode, + .color = g_bwr_mode ? 2 : 1, .width = BITMAP_WIDTH, .height = BITMAP_HEIGHT, .timestamp = g_display_time,