mirror of
https://github.com/jam422470459/EPD-nRF52-hema213.git
synced 2025-12-06 08:32:54 +08:00
add JD79668 support
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
203
EPD/JD79668.c
Normal file
203
EPD/JD79668.c
Normal file
@@ -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,
|
||||
};
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
12
EPD/UC8176.c
12
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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user