From 2f0aa6f83c3d0314a9d7b906076a7b9a133abeaa Mon Sep 17 00:00:00 2001 From: Shuanglei Tao Date: Mon, 13 Oct 2025 08:30:15 +0800 Subject: [PATCH] add uc8159 driver --- EPD/EPD_driver.c | 18 ++----- EPD/EPD_driver.h | 2 + EPD/UC81xx.c | 133 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 135 insertions(+), 18 deletions(-) diff --git a/EPD/EPD_driver.c b/EPD/EPD_driver.c index 50dc18f..15ef844 100644 --- a/EPD/EPD_driver.c +++ b/EPD/EPD_driver.c @@ -1,17 +1,3 @@ -/***************************************************************************** -* | File : DEV_Config.cpp -* | Author : Waveshare team -* | Function : -* | Info : -* Image scanning -* Please use progressive scanning to generate images or fonts -*---------------- -* | This version: V1.0 -* | Date : 2018-01-11 -* | Info : Basic version -* -******************************************************************************/ - #include "app_error.h" #include "nrf_drv_spi.h" #include "EPD_driver.h" @@ -333,6 +319,8 @@ float EPD_ReadVoltage(void) // EPD models extern epd_model_t epd_uc8176_420_bw; extern epd_model_t epd_uc8176_420_bwr; +extern epd_model_t epd_uc8159_750_bwr; +extern epd_model_t epd_uc8179_750_bwr; extern epd_model_t epd_ssd1619_420_bwr; extern epd_model_t epd_ssd1619_420_bw; extern epd_model_t epd_jd79668_420; @@ -340,6 +328,8 @@ extern epd_model_t epd_jd79668_420; static epd_model_t *epd_models[] = { &epd_uc8176_420_bw, &epd_uc8176_420_bwr, + &epd_uc8159_750_bwr, + &epd_uc8179_750_bwr, &epd_ssd1619_420_bwr, &epd_ssd1619_420_bw, &epd_jd79668_420, diff --git a/EPD/EPD_driver.h b/EPD/EPD_driver.h index cb82626..6a55d0e 100644 --- a/EPD/EPD_driver.h +++ b/EPD/EPD_driver.h @@ -46,6 +46,8 @@ typedef enum EPD_SSD1619_420_BWR = 2, EPD_SSD1619_420_BW = 4, EPD_JD79668_420_BWRY = 5, + EPD_UC8179_750_BWR = 6, + EPD_UC8159_750_LOW_BWR = 7, } epd_model_id_t; typedef enum diff --git a/EPD/UC81xx.c b/EPD/UC81xx.c index a0fdd86..8b79041 100644 --- a/EPD/UC81xx.c +++ b/EPD/UC81xx.c @@ -93,7 +93,7 @@ static void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h) xe / 256, xe % 256, y / 256, y % 256, ye / 256, ye % 256, - 0x01); + 0x00); } void UC81xx_Dump_OTP(void) @@ -125,6 +125,28 @@ void UC81xx_Init() EPD_Write(CMD_CDI, EPD->color == BWR ? 0x77 : 0x97); } +void UC8159_Init() +{ + epd_model_t *EPD = epd_get(); + + EPD_Reset(HIGH, 10); + + EPD_Write(CMD_PWR, 0x37, 0x00); + EPD_Write(CMD_PSR, 0xCF, 0x08); + EPD_Write(CMD_PLL, 0x3A); + EPD_Write(CMD_VDCS, 0x28); + EPD_Write(CMD_BTST, 0xc7, 0xcc, 0x15); + EPD_Write(CMD_CDI, 0x77); + EPD_Write(CMD_TCON, 0x22); + EPD_Write(0x65, 0x00); // FLASH CONTROL + EPD_Write(0xe5, 0x03); // FLASH MODE + EPD_Write(CMD_TRES, + EPD->width >> 8, + EPD->width & 0xff, + EPD->height >> 8, + EPD->height & 0xff); +} + void UC81xx_Clear(bool refresh) { epd_model_t *EPD = epd_get(); @@ -137,6 +159,24 @@ void UC81xx_Clear(bool refresh) UC81xx_Refresh(); } +void UC8159_Clear(bool refresh) +{ + epd_model_t *EPD = epd_get(); + uint32_t wb = (EPD->width + 7) / 8; + + EPD_WriteCmd(CMD_DTM1); + for (uint32_t j = 0; j < EPD->height; j++) { + for (uint32_t i = 0; i < wb; i++) { + for (uint8_t k = 0; k < 4; k++) { + EPD_WriteByte(0x33); + } + } + } + + if (refresh) + UC81xx_Refresh(); +} + void UC81xx_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(); @@ -171,6 +211,51 @@ void UC81xx_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, EPD_WriteCmd(CMD_PTOUT); // partial out } +static void UC8159_Send_Pixel(uint8_t black_data, uint8_t color_data) { + uint8_t data; + for (uint8_t j = 0; j < 8; j++) { + if ((color_data & 0x80) == 0x00) data = 0x04; // red + else if ((black_data & 0x80) == 0x00) data = 0x00; // black + else data = 0x03; // white + data = (data << 4) & 0xFF; + black_data = (black_data << 1) & 0xFF; + color_data = (color_data << 1) & 0xFF; + j++; + if ((color_data & 0x80) == 0x00) data |= 0x04; // red + else if ((black_data & 0x80) == 0x00) data |= 0x00; // black + else data |= 0x03; // white + black_data = (black_data << 1) & 0xFF; + color_data = (color_data << 1) & 0xFF; + EPD_WriteByte(data); + } +} + +void UC8159_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; + + EPD_WriteCmd(CMD_PTIN); // partial in + _setPartialRamArea(x, y, w, h); + EPD_WriteCmd(CMD_DTM1); + for (uint16_t i = 0; i < h; i++) + { + for (uint16_t j = 0; j < w / 8; j++) + { + uint8_t black_data = 0xFF; + uint8_t color_data = 0xFF; + if (black) black_data = black[j + i * wb]; + if (color) color_data = color[j + i * wb]; + UC8159_Send_Pixel(black_data, color_data); + } + } + EPD_WriteCmd(CMD_PTOUT); // partial out +} + void UC81xx_Wite_Ram(bool begin, bool black, uint8_t *data, uint8_t len) { if (begin) { @@ -183,6 +268,16 @@ void UC81xx_Wite_Ram(bool begin, bool black, uint8_t *data, uint8_t len) EPD_WriteData(data, len); } +// only black pixels are handled +void UC8159_Wite_Ram(bool begin, bool black, uint8_t *data, uint8_t len) +{ + if (begin && black) EPD_WriteCmd(CMD_DTM1); + for (uint8_t i = 0; i < len; i ++) { + uint8_t black_data = data[i]; + UC8159_Send_Pixel(black_data, 0xFF); + } +} + void UC81xx_Sleep(void) { UC81xx_PowerOff(); @@ -191,7 +286,7 @@ void UC81xx_Sleep(void) } // Declare driver and models -static epd_driver_t epd_drv_uc8176 = { +static epd_driver_t epd_drv_uc81xx = { .init = UC81xx_Init, .clear = UC81xx_Clear, .write_image = UC81xx_Write_Image, @@ -201,11 +296,22 @@ static epd_driver_t epd_drv_uc8176 = { .read_temp = UC81xx_Read_Temp, }; +static epd_driver_t epd_drv_uc8159 = { + .init = UC8159_Init, + .clear = UC8159_Clear, + .write_image = UC8159_Write_Image, + .write_ram = UC8159_Wite_Ram, + .refresh = UC81xx_Refresh, + .sleep = UC81xx_Sleep, + .read_temp = UC81xx_Read_Temp, +}; + + // UC8176 400x300 Black/White const epd_model_t epd_uc8176_420_bw = { .id = EPD_UC8176_420_BW, .color = BW, - .drv = &epd_drv_uc8176, + .drv = &epd_drv_uc81xx, .width = 400, .height = 300, }; @@ -214,7 +320,26 @@ const epd_model_t epd_uc8176_420_bw = { const epd_model_t epd_uc8176_420_bwr = { .id = EPD_UC8176_420_BWR, .color = BWR, - .drv = &epd_drv_uc8176, + .drv = &epd_drv_uc81xx, .width = 400, .height = 300, }; + +// UC8159 640x384 Black/White/Red +const epd_model_t epd_uc8159_750_bwr = { + .id = EPD_UC8159_750_LOW_BWR, + .color = BWR, + .drv = &epd_drv_uc8159, + .width = 640, + .height = 384, +}; + +// UC8179 800x480 Black/White/Red +const epd_model_t epd_uc8179_750_bwr = { + .id = EPD_UC8179_750_BWR, + .color = BWR, + .drv = &epd_drv_uc81xx, + .width = 800, + .height = 480, +}; +