mirror of
https://github.com/tsl0922/EPD-nRF5.git
synced 2026-03-14 11:13:16 +08:00
refactor epd drivers
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -78,6 +78,9 @@ _build/
|
||||
*.l2p
|
||||
*.iex
|
||||
|
||||
# Vscode config files
|
||||
.vscode/
|
||||
|
||||
# To explicitly override the above, define any exceptions here; e.g.:
|
||||
# !my_customized_scatter_file.sct
|
||||
|
||||
|
||||
@@ -187,20 +187,22 @@ 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);
|
||||
void EPD_Reset(bool status, uint16_t duration) {
|
||||
digitalWrite(EPD_RST_PIN, status);
|
||||
delay(duration);
|
||||
digitalWrite(EPD_RST_PIN, (value == LOW) ? HIGH : LOW);
|
||||
digitalWrite(EPD_RST_PIN, status ? LOW : HIGH);
|
||||
delay(duration);
|
||||
digitalWrite(EPD_RST_PIN, value);
|
||||
digitalWrite(EPD_RST_PIN, status);
|
||||
delay(duration);
|
||||
}
|
||||
|
||||
void EPD_WaitBusy(uint32_t value, uint16_t timeout) {
|
||||
bool EPD_ReadBusy(void) { return digitalRead(EPD_BUSY_PIN); }
|
||||
|
||||
void EPD_WaitBusy(bool status, uint16_t timeout) {
|
||||
uint32_t led_status = digitalRead(EPD_LED_PIN);
|
||||
|
||||
NRF_LOG_DEBUG("[EPD]: check busy\n");
|
||||
while (digitalRead(EPD_BUSY_PIN) == value) {
|
||||
while (EPD_ReadBusy() == status) {
|
||||
if (timeout % 100 == 0) EPD_LED_Toggle();
|
||||
delay(1);
|
||||
timeout--;
|
||||
@@ -303,10 +305,9 @@ extern epd_model_t epd_jd79665_750_bwry;
|
||||
extern epd_model_t epd_jd79665_583_bwry;
|
||||
|
||||
static epd_model_t* epd_models[] = {
|
||||
&epd_uc8176_420_bw, &epd_uc8176_420_bwr, &epd_uc8159_750_bw, &epd_uc8159_750_bwr,
|
||||
&epd_uc8179_750_bw, &epd_uc8179_750_bwr, &epd_ssd1619_420_bwr, &epd_ssd1619_420_bw,
|
||||
&epd_ssd1677_750_bwr, &epd_ssd1677_750_bw, &epd_jd79668_420_bwry, &epd_jd79665_750_bwry,
|
||||
&epd_jd79665_583_bwry,
|
||||
&epd_uc8176_420_bw, &epd_uc8176_420_bwr, &epd_uc8159_750_bw, &epd_uc8159_750_bwr, &epd_uc8179_750_bw,
|
||||
&epd_uc8179_750_bwr, &epd_ssd1619_420_bwr, &epd_ssd1619_420_bw, &epd_ssd1677_750_bwr, &epd_ssd1677_750_bw,
|
||||
&epd_jd79668_420_bwry, &epd_jd79665_750_bwry, &epd_jd79665_583_bwry,
|
||||
};
|
||||
|
||||
epd_model_t* epd_init(epd_model_id_t id) {
|
||||
|
||||
@@ -9,17 +9,6 @@
|
||||
#include "nrf_delay.h"
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
// EPD driver IC types
|
||||
typedef enum {
|
||||
EPD_DRIVER_IC_UC8159 = 0x10,
|
||||
EPD_DRIVER_IC_UC8176 = 0x11,
|
||||
EPD_DRIVER_IC_UC8179 = 0x12,
|
||||
EPD_DRIVER_IC_SSD1619 = 0x20,
|
||||
EPD_DRIVER_IC_SSD1677 = 0x21,
|
||||
EPD_DRIVER_IC_JD79668 = 0x30,
|
||||
EPD_DRIVER_IC_JD79665 = 0x31,
|
||||
} epd_driver_ic_t;
|
||||
|
||||
// UC81xx commands
|
||||
enum {
|
||||
UC81xx_PSR = 0x00, // Panel Setting
|
||||
@@ -121,36 +110,48 @@ enum {
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
BW = 1,
|
||||
BWR = 2,
|
||||
BWRY = 3,
|
||||
COLOR_BW = 1,
|
||||
COLOR_BWR = 2,
|
||||
COLOR_BWRY = 3,
|
||||
} epd_color_t;
|
||||
|
||||
// EPD driver IC types
|
||||
typedef enum {
|
||||
DRV_IC_UC8159 = 0x10,
|
||||
DRV_IC_UC8176 = 0x11,
|
||||
DRV_IC_UC8179 = 0x12,
|
||||
DRV_IC_SSD1619 = 0x20,
|
||||
DRV_IC_SSD1677 = 0x21,
|
||||
DRV_IC_JD79668 = 0x30,
|
||||
DRV_IC_JD79665 = 0x31,
|
||||
} epd_drv_ic_t;
|
||||
|
||||
// Do not change the existing IDs!
|
||||
typedef enum {
|
||||
EPD_UC8176_420_BW = 1,
|
||||
EPD_UC8176_420_BWR = 3,
|
||||
EPD_SSD1619_420_BWR = 2,
|
||||
EPD_SSD1619_420_BW = 4,
|
||||
EPD_JD79668_420_BWRY = 5,
|
||||
EPD_UC8179_750_BW = 6,
|
||||
EPD_UC8179_750_BWR = 7,
|
||||
EPD_UC8159_750_LOW_BW = 8,
|
||||
EPD_UC8159_750_LOW_BWR = 9,
|
||||
EPD_SSD1677_750_HD_BW = 10,
|
||||
EPD_SSD1677_750_HD_BWR = 11,
|
||||
EPD_JD79665_750_BWRY = 12,
|
||||
EPD_JD79665_583_BWRY = 13,
|
||||
UC8176_420_BW = 1,
|
||||
UC8176_420_BWR = 3,
|
||||
SSD1619_420_BWR = 2,
|
||||
SSD1619_420_BW = 4,
|
||||
JD79668_420_BWRY = 5,
|
||||
UC8179_750_BW = 6,
|
||||
UC8179_750_BWR = 7,
|
||||
UC8159_750_LOW_BW = 8,
|
||||
UC8159_750_LOW_BWR = 9,
|
||||
SSD1677_750_HD_BW = 10,
|
||||
SSD1677_750_HD_BWR = 11,
|
||||
JD79665_750_BWRY = 12,
|
||||
JD79665_583_BWRY = 13,
|
||||
} epd_model_id_t;
|
||||
|
||||
struct epd_driver;
|
||||
|
||||
typedef struct {
|
||||
epd_model_id_t id;
|
||||
epd_color_t color;
|
||||
struct epd_driver* drv;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
const epd_model_id_t id;
|
||||
const epd_color_t color;
|
||||
const struct epd_driver* drv;
|
||||
const epd_drv_ic_t ic;
|
||||
const uint16_t width;
|
||||
const uint16_t height;
|
||||
} epd_model_t;
|
||||
|
||||
/**@brief EPD driver structure.
|
||||
@@ -158,7 +159,6 @@ typedef struct {
|
||||
* @details This structure contains epd driver functions.
|
||||
*/
|
||||
typedef struct epd_driver {
|
||||
epd_driver_ic_t ic; /**< EPD driver IC type */
|
||||
void (*init)(epd_model_t* epd); /**< Initialize the e-Paper register */
|
||||
void (*clear)(epd_model_t* epd, bool refresh); /**< Clear screen */
|
||||
void (*write_image)(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w,
|
||||
@@ -167,6 +167,7 @@ typedef struct epd_driver {
|
||||
void (*refresh)(epd_model_t* epd); /**< Sends the image buffer in RAM to e-Paper and displays */
|
||||
void (*sleep)(epd_model_t* epd); /**< Enter sleep mode */
|
||||
int8_t (*read_temp)(epd_model_t* epd); /**< Read temperature from driver chip */
|
||||
bool (*read_busy)(epd_model_t* epd); /**< Read busy pin level */
|
||||
} epd_driver_t;
|
||||
|
||||
#define LOW (0x0)
|
||||
@@ -206,8 +207,9 @@ uint8_t EPD_ReadByte(void);
|
||||
EPD_WriteData(_data, sizeof(_data)); \
|
||||
} while (0)
|
||||
void EPD_FillRAM(uint8_t cmd, uint8_t value, uint32_t len);
|
||||
void EPD_Reset(uint32_t value, uint16_t duration);
|
||||
void EPD_WaitBusy(uint32_t value, uint16_t timeout);
|
||||
void EPD_Reset(bool status, uint16_t duration);
|
||||
bool EPD_ReadBusy(void);
|
||||
void EPD_WaitBusy(bool status, uint16_t timeout);
|
||||
|
||||
// LED
|
||||
void EPD_LED_ON(void);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "EPD_driver.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
static void SSD16xx_WaitBusy(uint16_t timeout) { EPD_WaitBusy(HIGH, timeout); }
|
||||
bool SSD16xx_ReadBusy(epd_model_t* epd) { return EPD_ReadBusy(); }
|
||||
|
||||
static void SSD16xx_WaitBusy(uint16_t timeout) { EPD_WaitBusy(true, timeout); }
|
||||
|
||||
static void SSD16xx_Update(uint8_t seq) {
|
||||
EPD_Write(SSD16xx_DISP_CTRL2, seq);
|
||||
@@ -17,18 +19,20 @@ int8_t SSD16xx_Read_Temp(epd_model_t* epd) {
|
||||
|
||||
static void _setPartialRamArea(epd_model_t* epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
EPD_Write(SSD16xx_ENTRY_MODE, 0x03); // set ram entry mode: x increase, y increase
|
||||
if (epd->drv->ic == EPD_DRIVER_IC_SSD1677) {
|
||||
EPD_Write(SSD16xx_RAM_XPOS, x % 256, x / 256, (x + w - 1) % 256, (x + w - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_XCOUNT, x % 256, x / 256);
|
||||
} else {
|
||||
EPD_Write(SSD16xx_RAM_XPOS, x / 8, (x + w - 1) / 8);
|
||||
EPD_Write(SSD16xx_RAM_YPOS, y % 256, y / 256, (y + h - 1) % 256, (y + h - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_XCOUNT, x / 8);
|
||||
switch (epd->ic) {
|
||||
case DRV_IC_SSD1677:
|
||||
EPD_Write(SSD16xx_RAM_XPOS, x % 256, x / 256, (x + w - 1) % 256, (x + w - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_XCOUNT, x % 256, x / 256);
|
||||
break;
|
||||
default:
|
||||
EPD_Write(SSD16xx_RAM_XPOS, x / 8, (x + w - 1) / 8);
|
||||
EPD_Write(SSD16xx_RAM_YPOS, y % 256, y / 256, (y + h - 1) % 256, (y + h - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_XCOUNT, x / 8);
|
||||
break;
|
||||
}
|
||||
EPD_Write(SSD16xx_RAM_YPOS, y % 256, y / 256, (y + h - 1) % 256, (y + h - 1) / 256);
|
||||
EPD_Write(SSD16xx_RAM_YCOUNT, y % 256, y / 256);
|
||||
}
|
||||
|
||||
void SSD16xx_Dump_LUT(void) {
|
||||
uint8_t lut[128];
|
||||
|
||||
@@ -41,7 +45,7 @@ void SSD16xx_Dump_LUT(void) {
|
||||
}
|
||||
|
||||
void SSD16xx_Init(epd_model_t* epd) {
|
||||
EPD_Reset(HIGH, 10);
|
||||
EPD_Reset(true, 10);
|
||||
|
||||
EPD_WriteCmd(SSD16xx_SW_RESET);
|
||||
SSD16xx_WaitBusy(200);
|
||||
@@ -53,7 +57,7 @@ void SSD16xx_Init(epd_model_t* epd) {
|
||||
}
|
||||
|
||||
static void SSD16xx_Refresh(epd_model_t* epd) {
|
||||
EPD_Write(SSD16xx_DISP_CTRL1, epd->color == BWR ? 0x80 : 0x40, 0x00);
|
||||
EPD_Write(SSD16xx_DISP_CTRL1, epd->color == COLOR_BWR ? 0x80 : 0x40, 0x00);
|
||||
|
||||
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
||||
NRF_LOG_DEBUG("[EPD]: temperature: %d\n", SSD16xx_Read_Temp(epd));
|
||||
@@ -64,7 +68,6 @@ static void SSD16xx_Refresh(epd_model_t* epd) {
|
||||
// SSD16xx_Dump_LUT();
|
||||
|
||||
_setPartialRamArea(epd, 0, 0, epd->width, epd->height); // DO NOT REMOVE!
|
||||
SSD16xx_Update(0x83); // power off
|
||||
}
|
||||
|
||||
void SSD16xx_Clear(epd_model_t* epd, bool refresh) {
|
||||
@@ -93,7 +96,7 @@ void SSD16xx_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint1
|
||||
EPD_WriteCmd(SSD16xx_WRITE_RAM2);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
if (epd->color == BWR)
|
||||
if (epd->color == COLOR_BWR)
|
||||
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
|
||||
else
|
||||
EPD_WriteByte(black[j + i * wb]);
|
||||
@@ -105,7 +108,7 @@ void SSD16xx_Write_Ram(epd_model_t* epd, uint8_t cfg, uint8_t* data, uint8_t len
|
||||
bool begin = (cfg >> 4) == 0x00;
|
||||
bool black = (cfg & 0x0F) == 0x0F;
|
||||
if (begin) {
|
||||
if (epd->color == BWR)
|
||||
if (epd->color == COLOR_BWR)
|
||||
EPD_WriteCmd(black ? SSD16xx_WRITE_RAM1 : SSD16xx_WRITE_RAM2);
|
||||
else
|
||||
EPD_WriteCmd(SSD16xx_WRITE_RAM1);
|
||||
@@ -118,19 +121,7 @@ void SSD16xx_Sleep(epd_model_t* epd) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
static epd_driver_t epd_drv_ssd1619 = {
|
||||
.ic = EPD_DRIVER_IC_SSD1619,
|
||||
.init = SSD16xx_Init,
|
||||
.clear = SSD16xx_Clear,
|
||||
.write_image = SSD16xx_Write_Image,
|
||||
.write_ram = SSD16xx_Write_Ram,
|
||||
.refresh = SSD16xx_Refresh,
|
||||
.sleep = SSD16xx_Sleep,
|
||||
.read_temp = SSD16xx_Read_Temp,
|
||||
};
|
||||
|
||||
static epd_driver_t epd_drv_ssd1677 = {
|
||||
.ic = EPD_DRIVER_IC_SSD1677,
|
||||
static const epd_driver_t epd_drv_ssd16xx = {
|
||||
.init = SSD16xx_Init,
|
||||
.clear = SSD16xx_Clear,
|
||||
.write_image = SSD16xx_Write_Image,
|
||||
@@ -138,13 +129,14 @@ static epd_driver_t epd_drv_ssd1677 = {
|
||||
.refresh = SSD16xx_Refresh,
|
||||
.sleep = SSD16xx_Sleep,
|
||||
.read_temp = SSD16xx_Read_Temp,
|
||||
.read_busy = SSD16xx_ReadBusy,
|
||||
};
|
||||
|
||||
// SSD1619 400x300 Black/White/Red
|
||||
const epd_model_t epd_ssd1619_420_bwr = {EPD_SSD1619_420_BWR, BWR, &epd_drv_ssd1619, 400, 300};
|
||||
const epd_model_t epd_ssd1619_420_bwr = {SSD1619_420_BWR, COLOR_BWR, &epd_drv_ssd16xx, DRV_IC_SSD1619, 400, 300};
|
||||
// SSD1619 400x300 Black/White
|
||||
const epd_model_t epd_ssd1619_420_bw = {EPD_SSD1619_420_BW, BW, &epd_drv_ssd1619, 400, 300};
|
||||
const epd_model_t epd_ssd1619_420_bw = {SSD1619_420_BW, COLOR_BW, &epd_drv_ssd16xx, DRV_IC_SSD1619, 400, 300};
|
||||
// SSD1677 880x528 Black/White/Red
|
||||
const epd_model_t epd_ssd1677_750_bwr = {EPD_SSD1677_750_HD_BWR, BWR, &epd_drv_ssd1677, 880, 528};
|
||||
const epd_model_t epd_ssd1677_750_bwr = {SSD1677_750_HD_BWR, COLOR_BWR, &epd_drv_ssd16xx, DRV_IC_SSD1677, 880, 528};
|
||||
// SSD1677 880x528 Black/White
|
||||
const epd_model_t epd_ssd1677_750_bw = {EPD_SSD1677_750_HD_BW, BW, &epd_drv_ssd1677, 880, 528};
|
||||
const epd_model_t epd_ssd1677_750_bw = {SSD1677_750_HD_BW, COLOR_BW, &epd_drv_ssd16xx, DRV_IC_SSD1677, 880, 528};
|
||||
|
||||
328
EPD/UC81xx.c
328
EPD/UC81xx.c
@@ -1,7 +1,9 @@
|
||||
#include "EPD_driver.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
static void UC81xx_WaitBusy(uint16_t timeout) { EPD_WaitBusy(LOW, timeout); }
|
||||
bool UC81xx_ReadBusy(epd_model_t* epd) { return EPD_ReadBusy() == false; }
|
||||
|
||||
static void UC81xx_WaitBusy(uint16_t timeout) { EPD_WaitBusy(false, timeout); }
|
||||
|
||||
static void UC81xx_PowerOn(epd_model_t* epd) {
|
||||
EPD_WriteCmd(UC81xx_PON);
|
||||
@@ -9,10 +11,8 @@ static void UC81xx_PowerOn(epd_model_t* epd) {
|
||||
}
|
||||
|
||||
static void UC81xx_PowerOff(epd_model_t* epd) {
|
||||
if (epd->drv->ic == EPD_DRIVER_IC_JD79665)
|
||||
EPD_Write(UC81xx_POF, 0x00);
|
||||
else
|
||||
EPD_WriteCmd(UC81xx_POF);
|
||||
EPD_WriteCmd(UC81xx_POF);
|
||||
if (epd->color == COLOR_BWRY) EPD_WriteByte(0x00);
|
||||
UC81xx_WaitBusy(200);
|
||||
}
|
||||
|
||||
@@ -24,40 +24,39 @@ int8_t UC81xx_Read_Temp(epd_model_t* epd) {
|
||||
}
|
||||
|
||||
static void _setPartialRamArea(epd_model_t* epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
if (epd->drv->ic == EPD_DRIVER_IC_JD79668 || epd->drv->ic == EPD_DRIVER_IC_JD79665) {
|
||||
EPD_Write(0x83, // partial window
|
||||
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);
|
||||
} else {
|
||||
uint16_t xe = (x + w - 1) | 0x0007; // byte boundary inclusive (last byte)
|
||||
uint16_t ye = y + h - 1;
|
||||
x &= 0xFFF8; // byte boundary
|
||||
EPD_Write(UC81xx_PTL, // partial window
|
||||
x / 256, x % 256, xe / 256, xe % 256, y / 256, y % 256, ye / 256, ye % 256, 0x00);
|
||||
switch (epd->ic) {
|
||||
case DRV_IC_JD79668:
|
||||
case DRV_IC_JD79665:
|
||||
EPD_Write(0x83, // partial window
|
||||
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);
|
||||
break;
|
||||
default: {
|
||||
uint16_t xe = (x + w - 1) | 0x0007; // byte boundary inclusive (last byte)
|
||||
uint16_t ye = y + h - 1;
|
||||
x &= 0xFFF8; // byte boundary
|
||||
EPD_Write(UC81xx_PTL, // partial window
|
||||
x / 256, x % 256, xe / 256, xe % 256, y / 256, y % 256, ye / 256, ye % 256, 0x00);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void UC81xx_Refresh(epd_model_t* epd) {
|
||||
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
|
||||
if (epd->drv->ic != EPD_DRIVER_IC_JD79668 && epd->drv->ic != EPD_DRIVER_IC_JD79665) UC81xx_PowerOn(epd);
|
||||
|
||||
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
|
||||
|
||||
EPD_WriteCmd(UC81xx_DRF);
|
||||
if (epd->drv->ic == EPD_DRIVER_IC_JD79668 || epd->drv->ic == EPD_DRIVER_IC_JD79665) {
|
||||
EPD_WriteByte(0x00);
|
||||
}
|
||||
if (epd->color == COLOR_BWRY) EPD_WriteByte(0x00);
|
||||
delay(100);
|
||||
UC81xx_WaitBusy(30000);
|
||||
|
||||
if (epd->drv->ic != EPD_DRIVER_IC_JD79668 && epd->drv->ic != EPD_DRIVER_IC_JD79665) UC81xx_PowerOff(epd);
|
||||
NRF_LOG_DEBUG("[EPD]: refresh end\n");
|
||||
}
|
||||
|
||||
void UC81xx_Dump_OTP(epd_model_t* epd) {
|
||||
uint8_t data[128];
|
||||
|
||||
UC81xx_PowerOn(epd);
|
||||
EPD_Write(UC81xx_ROTP, 0x00);
|
||||
|
||||
NRF_LOG_DEBUG("=== OTP BEGIN ===\n");
|
||||
@@ -66,118 +65,94 @@ void UC81xx_Dump_OTP(epd_model_t* epd) {
|
||||
NRF_LOG_HEXDUMP_DEBUG(data, sizeof(data));
|
||||
}
|
||||
NRF_LOG_DEBUG("=== OTP END ===\n");
|
||||
|
||||
UC81xx_PowerOff(epd);
|
||||
}
|
||||
|
||||
void UC81xx_Init(epd_model_t* epd) {
|
||||
EPD_Reset(HIGH, 10);
|
||||
|
||||
// UC81xx_Dump_OTP(epd);
|
||||
|
||||
EPD_Write(UC81xx_PSR, epd->color == BWR ? 0x0F : 0x1F);
|
||||
EPD_Write(UC81xx_CDI, epd->color == BWR ? 0x77 : 0x97);
|
||||
}
|
||||
|
||||
void UC8159_Init(epd_model_t* epd) {
|
||||
EPD_Reset(HIGH, 10);
|
||||
|
||||
EPD_Write(UC81xx_PWR, 0x37, 0x00);
|
||||
EPD_Write(UC81xx_PSR, 0xCF, 0x08);
|
||||
EPD_Write(UC81xx_PLL, 0x3A);
|
||||
EPD_Write(UC81xx_VDCS, 0x28);
|
||||
EPD_Write(UC81xx_BTST, 0xc7, 0xcc, 0x15);
|
||||
EPD_Write(UC81xx_CDI, 0x77);
|
||||
EPD_Write(UC81xx_TCON, 0x22);
|
||||
EPD_Write(0x65, 0x00); // FLASH CONTROL
|
||||
EPD_Write(0xe5, 0x03); // FLASH MODE
|
||||
EPD_Write(UC81xx_TRES, epd->width >> 8, epd->width & 0xff, epd->height >> 8, epd->height & 0xff);
|
||||
}
|
||||
|
||||
void JD79668_Init(epd_model_t* epd) {
|
||||
EPD_Reset(HIGH, 50);
|
||||
|
||||
EPD_Write(0x4D, 0x78);
|
||||
EPD_Write(UC81xx_PSR, 0x0F, 0x29);
|
||||
EPD_Write(UC81xx_BTST, 0x0D, 0x12, 0x24, 0x25, 0x12, 0x29, 0x10);
|
||||
EPD_Write(UC81xx_PLL, 0x08);
|
||||
EPD_Write(UC81xx_CDI, 0x37);
|
||||
EPD_Write(UC81xx_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);
|
||||
|
||||
UC81xx_PowerOn(epd);
|
||||
}
|
||||
|
||||
void JD79665_Init(epd_model_t* epd) {
|
||||
EPD_Reset(HIGH, 50);
|
||||
UC81xx_WaitBusy(1000);
|
||||
|
||||
EPD_Write(0x4D, 0x78);
|
||||
EPD_Write(UC81xx_PSR, 0x2F, 0x29);
|
||||
EPD_Write(UC81xx_BTST, 0x0F, 0x8B, 0x93, 0xA1);
|
||||
EPD_Write(UC81xx_TSE, 0x00);
|
||||
EPD_Write(UC81xx_CDI, 0x37);
|
||||
EPD_Write(UC81xx_TCON, 0x02, 0x02);
|
||||
EPD_Write(UC81xx_TRES, epd->width / 256, epd->width % 256, epd->height / 256, epd->height % 256);
|
||||
EPD_Write(0x62, 0x98, 0x98, 0x98, 0x75, 0xCA, 0xB2, 0x98, 0x7E);
|
||||
|
||||
if (epd->id == EPD_JD79665_750_BWRY) {
|
||||
EPD_Write(UC81xx_GSST, 0x00, 0x00, 0x00, 0x00);
|
||||
} else {
|
||||
EPD_Write(UC81xx_GSST, 0x00, 0x10, 0x00, 0x00);
|
||||
EPD_Reset(true, 10);
|
||||
switch (epd->ic) {
|
||||
case DRV_IC_UC8159:
|
||||
EPD_Write(UC81xx_PWR, 0x37, 0x00);
|
||||
EPD_Write(UC81xx_PSR, 0xCF, 0x08);
|
||||
EPD_Write(UC81xx_PLL, 0x3A);
|
||||
EPD_Write(UC81xx_VDCS, 0x28);
|
||||
EPD_Write(UC81xx_BTST, 0xc7, 0xcc, 0x15);
|
||||
EPD_Write(UC81xx_CDI, 0x77);
|
||||
EPD_Write(UC81xx_TCON, 0x22);
|
||||
EPD_Write(0x65, 0x00); // FLASH CONTROL
|
||||
EPD_Write(0xe5, 0x03); // FLASH MODE
|
||||
EPD_Write(UC81xx_TRES, epd->width >> 8, epd->width & 0xff, epd->height >> 8, epd->height & 0xff);
|
||||
break;
|
||||
case DRV_IC_JD79668:
|
||||
EPD_Write(0x4D, 0x78);
|
||||
EPD_Write(UC81xx_PSR, 0x0F, 0x29);
|
||||
EPD_Write(UC81xx_BTST, 0x0D, 0x12, 0x24, 0x25, 0x12, 0x29, 0x10);
|
||||
EPD_Write(UC81xx_PLL, 0x08);
|
||||
EPD_Write(UC81xx_CDI, 0x37);
|
||||
EPD_Write(UC81xx_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);
|
||||
break;
|
||||
case DRV_IC_JD79665:
|
||||
EPD_Write(0x4D, 0x78);
|
||||
EPD_Write(UC81xx_PSR, 0x2F, 0x29);
|
||||
EPD_Write(UC81xx_BTST, 0x0F, 0x8B, 0x93, 0xA1);
|
||||
EPD_Write(UC81xx_TSE, 0x00);
|
||||
EPD_Write(UC81xx_CDI, 0x37);
|
||||
EPD_Write(UC81xx_TCON, 0x02, 0x02);
|
||||
EPD_Write(UC81xx_TRES, epd->width / 256, epd->width % 256, epd->height / 256, epd->height % 256);
|
||||
EPD_Write(0x62, 0x98, 0x98, 0x98, 0x75, 0xCA, 0xB2, 0x98, 0x7E);
|
||||
if (epd->id == JD79665_750_BWRY)
|
||||
EPD_Write(UC81xx_GSST, 0x00, 0x00, 0x00, 0x00);
|
||||
else
|
||||
EPD_Write(UC81xx_GSST, 0x00, 0x10, 0x00, 0x00);
|
||||
EPD_Write(0xE7, 0x1C);
|
||||
EPD_Write(UC81xx_PWS, 0x00);
|
||||
EPD_Write(0xE9, 0x01);
|
||||
EPD_Write(UC81xx_PLL, 0x08);
|
||||
break;
|
||||
default:
|
||||
EPD_Write(UC81xx_PSR, epd->color == COLOR_BWR ? 0x0F : 0x1F);
|
||||
EPD_Write(UC81xx_CDI, epd->color == COLOR_BWR ? 0x77 : 0x97);
|
||||
break;
|
||||
}
|
||||
|
||||
EPD_Write(0xE7, 0x1C);
|
||||
EPD_Write(UC81xx_PWS, 0x00);
|
||||
EPD_Write(0xE9, 0x01);
|
||||
EPD_Write(UC81xx_PLL, 0x08);
|
||||
|
||||
UC81xx_PowerOn(epd);
|
||||
}
|
||||
|
||||
void UC81xx_Clear(epd_model_t* epd, bool refresh) {
|
||||
uint32_t ram_bytes = ((epd->width + 7) / 8) * epd->height;
|
||||
|
||||
EPD_FillRAM(UC81xx_DTM1, 0xFF, ram_bytes);
|
||||
EPD_FillRAM(UC81xx_DTM2, 0xFF, ram_bytes);
|
||||
|
||||
if (refresh) UC81xx_Refresh(epd);
|
||||
}
|
||||
|
||||
void UC8159_Clear(epd_model_t* epd, bool refresh) {
|
||||
uint32_t wb = (epd->width + 7) / 8;
|
||||
|
||||
EPD_WriteCmd(UC81xx_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);
|
||||
switch (epd->ic) {
|
||||
case DRV_IC_UC8159:
|
||||
EPD_WriteCmd(UC81xx_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DRV_IC_JD79668:
|
||||
case DRV_IC_JD79665:
|
||||
wb = (epd->width + 3) / 4; // 2bpp
|
||||
EPD_WriteCmd(UC81xx_DTM1);
|
||||
for (uint16_t i = 0; i < epd->height; i++) {
|
||||
for (uint16_t j = 0; j < wb; j++) {
|
||||
EPD_WriteByte(0x55);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
EPD_FillRAM(UC81xx_DTM1, 0xFF, wb * epd->height);
|
||||
EPD_FillRAM(UC81xx_DTM2, 0xFF, wb * epd->height);
|
||||
break;
|
||||
}
|
||||
|
||||
if (refresh) UC81xx_Refresh(epd);
|
||||
}
|
||||
|
||||
void JD79668_Clear(epd_model_t* epd, bool refresh) {
|
||||
uint16_t wb = (epd->width + 3) / 4;
|
||||
|
||||
EPD_WriteCmd(UC81xx_DTM1);
|
||||
for (uint16_t i = 0; i < epd->height; i++) {
|
||||
for (uint16_t j = 0; j < wb; j++) {
|
||||
EPD_WriteByte(0x55);
|
||||
}
|
||||
}
|
||||
|
||||
if (refresh) UC81xx_Refresh(epd);
|
||||
}
|
||||
|
||||
void UC81xx_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w,
|
||||
void UC8176_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w,
|
||||
uint16_t h) {
|
||||
uint16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded
|
||||
x -= x % 8; // byte boundary
|
||||
@@ -186,7 +161,7 @@ void UC81xx_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16
|
||||
|
||||
EPD_WriteCmd(UC81xx_PTIN); // partial in
|
||||
_setPartialRamArea(epd, x, y, w, h);
|
||||
if (epd->color == BWR) {
|
||||
if (epd->color == COLOR_BWR) {
|
||||
EPD_WriteCmd(UC81xx_DTM1);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) EPD_WriteByte(black ? black[j + i * wb] : 0xFF);
|
||||
@@ -195,7 +170,7 @@ void UC81xx_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16
|
||||
EPD_WriteCmd(UC81xx_DTM2);
|
||||
for (uint16_t i = 0; i < h; i++) {
|
||||
for (uint16_t j = 0; j < w / 8; j++) {
|
||||
if (epd->color == BWR)
|
||||
if (epd->color == COLOR_BWR)
|
||||
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
|
||||
else
|
||||
EPD_WriteByte(black[j + i * wb]);
|
||||
@@ -269,23 +244,42 @@ void JD79668_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint1
|
||||
}
|
||||
}
|
||||
|
||||
void UC81xx_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w,
|
||||
uint16_t h) {
|
||||
switch (epd->ic) {
|
||||
case DRV_IC_UC8159:
|
||||
UC8159_Write_Image(epd, black, color, x, y, w, h);
|
||||
break;
|
||||
case DRV_IC_JD79668:
|
||||
case DRV_IC_JD79665:
|
||||
JD79668_Write_Image(epd, black, color, x, y, w, h);
|
||||
break;
|
||||
default:
|
||||
UC8176_Write_Image(epd, black, color, x, y, w, h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UC81xx_Write_Ram(epd_model_t* epd, uint8_t cfg, uint8_t* data, uint8_t len) {
|
||||
bool begin = (cfg >> 4) == 0x00;
|
||||
bool black = (cfg & 0x0F) == 0x0F;
|
||||
if (begin) {
|
||||
if (epd->color == BWR)
|
||||
EPD_WriteCmd(black ? UC81xx_DTM1 : UC81xx_DTM2);
|
||||
else
|
||||
EPD_WriteCmd(UC81xx_DTM2);
|
||||
switch (epd->ic) {
|
||||
case DRV_IC_UC8159:
|
||||
case DRV_IC_JD79665:
|
||||
case DRV_IC_JD79668:
|
||||
if (begin) EPD_WriteCmd(UC81xx_DTM1);
|
||||
EPD_WriteData(data, len);
|
||||
break;
|
||||
default:
|
||||
if (begin) {
|
||||
if (epd->color == COLOR_BWR)
|
||||
EPD_WriteCmd(black ? UC81xx_DTM1 : UC81xx_DTM2);
|
||||
else
|
||||
EPD_WriteCmd(UC81xx_DTM2);
|
||||
}
|
||||
EPD_WriteData(data, len);
|
||||
break;
|
||||
}
|
||||
EPD_WriteData(data, len);
|
||||
}
|
||||
|
||||
// Write native data to ram, format should be 2pp or above
|
||||
void UC81xx_Write_Ram_Native(epd_model_t* epd, uint8_t cfg, uint8_t* data, uint8_t len) {
|
||||
bool begin = (cfg >> 4) == 0x00;
|
||||
if (begin) EPD_WriteCmd(UC81xx_DTM1);
|
||||
EPD_WriteData(data, len);
|
||||
}
|
||||
|
||||
void UC81xx_Sleep(epd_model_t* epd) {
|
||||
@@ -295,8 +289,7 @@ void UC81xx_Sleep(epd_model_t* epd) {
|
||||
}
|
||||
|
||||
// Declare driver and models
|
||||
static epd_driver_t epd_drv_uc8176 = {
|
||||
.ic = EPD_DRIVER_IC_UC8176,
|
||||
static const epd_driver_t epd_drv_uc81xx = {
|
||||
.init = UC81xx_Init,
|
||||
.clear = UC81xx_Clear,
|
||||
.write_image = UC81xx_Write_Image,
|
||||
@@ -304,67 +297,24 @@ static epd_driver_t epd_drv_uc8176 = {
|
||||
.refresh = UC81xx_Refresh,
|
||||
.sleep = UC81xx_Sleep,
|
||||
.read_temp = UC81xx_Read_Temp,
|
||||
};
|
||||
|
||||
static epd_driver_t epd_drv_uc8159 = {
|
||||
.ic = EPD_DRIVER_IC_UC8159,
|
||||
.init = UC8159_Init,
|
||||
.clear = UC8159_Clear,
|
||||
.write_image = UC8159_Write_Image,
|
||||
.write_ram = UC81xx_Write_Ram_Native,
|
||||
.refresh = UC81xx_Refresh,
|
||||
.sleep = UC81xx_Sleep,
|
||||
.read_temp = UC81xx_Read_Temp,
|
||||
};
|
||||
|
||||
static epd_driver_t epd_drv_uc8179 = {
|
||||
.ic = EPD_DRIVER_IC_UC8179,
|
||||
.init = UC81xx_Init,
|
||||
.clear = UC81xx_Clear,
|
||||
.write_image = UC81xx_Write_Image,
|
||||
.write_ram = UC81xx_Write_Ram,
|
||||
.refresh = UC81xx_Refresh,
|
||||
.sleep = UC81xx_Sleep,
|
||||
.read_temp = UC81xx_Read_Temp,
|
||||
};
|
||||
|
||||
static epd_driver_t epd_drv_jd79668 = {
|
||||
.ic = EPD_DRIVER_IC_JD79668,
|
||||
.init = JD79668_Init,
|
||||
.clear = JD79668_Clear,
|
||||
.write_image = JD79668_Write_Image,
|
||||
.write_ram = UC81xx_Write_Ram_Native,
|
||||
.refresh = UC81xx_Refresh,
|
||||
.sleep = UC81xx_Sleep,
|
||||
.read_temp = UC81xx_Read_Temp,
|
||||
};
|
||||
|
||||
static epd_driver_t epd_drv_jd79665 = {
|
||||
.ic = EPD_DRIVER_IC_JD79665,
|
||||
.init = JD79665_Init,
|
||||
.clear = JD79668_Clear,
|
||||
.write_image = JD79668_Write_Image,
|
||||
.write_ram = UC81xx_Write_Ram_Native,
|
||||
.refresh = UC81xx_Refresh,
|
||||
.sleep = UC81xx_Sleep,
|
||||
.read_temp = UC81xx_Read_Temp,
|
||||
.read_busy = UC81xx_ReadBusy,
|
||||
};
|
||||
|
||||
// UC8176 400x300 Black/White
|
||||
const epd_model_t epd_uc8176_420_bw = {EPD_UC8176_420_BW, BW, &epd_drv_uc8176, 400, 300};
|
||||
const epd_model_t epd_uc8176_420_bw = {UC8176_420_BW, COLOR_BW, &epd_drv_uc81xx, DRV_IC_UC8176, 400, 300};
|
||||
// UC8176 400x300 Black/White/Red
|
||||
const epd_model_t epd_uc8176_420_bwr = {EPD_UC8176_420_BWR, BWR, &epd_drv_uc8176, 400, 300};
|
||||
const epd_model_t epd_uc8176_420_bwr = {UC8176_420_BWR, COLOR_BWR, &epd_drv_uc81xx, DRV_IC_UC8176, 400, 300};
|
||||
// UC8159 640x384 Black/White
|
||||
const epd_model_t epd_uc8159_750_bw = {EPD_UC8159_750_LOW_BW, BW, &epd_drv_uc8159, 640, 384};
|
||||
const epd_model_t epd_uc8159_750_bw = {UC8159_750_LOW_BW, COLOR_BW, &epd_drv_uc81xx, DRV_IC_UC8159, 640, 384};
|
||||
// UC8159 640x384 Black/White/Red
|
||||
const epd_model_t epd_uc8159_750_bwr = {EPD_UC8159_750_LOW_BWR, BWR, &epd_drv_uc8159, 640, 384};
|
||||
const epd_model_t epd_uc8159_750_bwr = {UC8159_750_LOW_BWR, COLOR_BWR, &epd_drv_uc81xx, DRV_IC_UC8159, 640, 384};
|
||||
// UC8179 800x480 Black/White/Red
|
||||
const epd_model_t epd_uc8179_750_bw = {EPD_UC8179_750_BW, BW, &epd_drv_uc8179, 800, 480};
|
||||
const epd_model_t epd_uc8179_750_bw = {UC8179_750_BW, COLOR_BW, &epd_drv_uc81xx, DRV_IC_UC8179, 800, 480};
|
||||
// UC8179 800x480 Black/White/Red
|
||||
const epd_model_t epd_uc8179_750_bwr = {EPD_UC8179_750_BWR, BWR, &epd_drv_uc8179, 800, 480};
|
||||
const epd_model_t epd_uc8179_750_bwr = {UC8179_750_BWR, COLOR_BWR, &epd_drv_uc81xx, DRV_IC_UC8179, 800, 480};
|
||||
// JD79668 400x300 Black/White/Red/Yellow
|
||||
const epd_model_t epd_jd79668_420_bwry = {EPD_JD79668_420_BWRY, BWRY, &epd_drv_jd79668, 400, 300};
|
||||
const epd_model_t epd_jd79668_420_bwry = {JD79668_420_BWRY, COLOR_BWRY, &epd_drv_uc81xx, DRV_IC_JD79668, 400, 300};
|
||||
// JD79665 800x480 Black/White/Red/Yellow
|
||||
const epd_model_t epd_jd79665_750_bwry = {EPD_JD79665_750_BWRY, BWRY, &epd_drv_jd79665, 800, 480};
|
||||
const epd_model_t epd_jd79665_750_bwry = {JD79665_750_BWRY, COLOR_BWRY, &epd_drv_uc81xx, DRV_IC_JD79665, 800, 480};
|
||||
// JD79665 648x480 Black/White/Red/Yellow
|
||||
const epd_model_t epd_jd79665_583_bwry = {EPD_JD79665_583_BWRY, BWRY, &epd_drv_jd79665, 648, 480};
|
||||
const epd_model_t epd_jd79665_583_bwry = {JD79665_583_BWRY, COLOR_BWRY, &epd_drv_uc81xx, DRV_IC_JD79665, 648, 480};
|
||||
|
||||
Reference in New Issue
Block a user