update epd driver code

This commit is contained in:
Shuanglei Tao
2026-01-16 20:29:42 +08:00
parent 3f97bcfdef
commit 463d66d341
7 changed files with 61 additions and 54 deletions

View File

@@ -1,5 +1,5 @@
#ifndef __EPD_CONFIG_H
#define __EPD_CONFIG_H
#ifndef __EPD_CONFIG_H__
#define __EPD_CONFIG_H__
#include <stdbool.h>
#include <stdint.h>

View File

@@ -2,7 +2,6 @@
#include "app_error.h"
#include "nrf_drv_spi.h"
#include "nrf_log.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define BUFFER_SIZE 128
@@ -203,7 +202,7 @@ 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");
EPD_DEBUG("check busy");
while (EPD_ReadBusy() == status) {
if (timeout % 100 == 0) {
app_feed_wdt();
@@ -212,11 +211,11 @@ void EPD_WaitBusy(bool status, uint16_t timeout) {
delay(1);
timeout--;
if (timeout == 0) {
NRF_LOG_DEBUG("[EPD]: busy timeout!\n");
EPD_DEBUG("busy timeout!");
break;
}
}
NRF_LOG_DEBUG("[EPD]: busy release\n");
EPD_DEBUG("busy release");
// restore led status
if (led_status == LOW)
@@ -290,7 +289,7 @@ uint16_t EPD_ReadVoltage(void) {
NRF_ADC->TASKS_STOP = 1;
NRF_ADC->ENABLE = 0;
#endif
NRF_LOG_DEBUG("ADC value: %d\n", value);
EPD_DEBUG("ADC value: %d", value);
return (value * 3600) / (1 << 10);
}

View File

@@ -1,5 +1,5 @@
#ifndef __EPD_DRIVER_H
#define __EPD_DRIVER_H
#ifndef __EPD_DRIVER_H__
#define __EPD_DRIVER_H__
#include <stdbool.h>
#include <stdint.h>
@@ -8,6 +8,9 @@
#include "EPD_config.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "nrf_log.h"
#define EPD_DEBUG(fmt, ...) NRF_LOG_DEBUG("EPD: " fmt "\r\n", ##__VA_ARGS__)
// UC81xx commands
enum {

View File

@@ -10,8 +10,8 @@
*
*/
#ifndef __EPD_SERVICE_H
#define __EPD_SERVICE_H
#ifndef __EPD_SERVICE_H__
#define __EPD_SERVICE_H__
#include <inttypes.h>
#include <stdbool.h>

View File

@@ -1,5 +1,4 @@
#include "EPD_driver.h"
#include "nrf_log.h"
bool SSD16xx_ReadBusy(epd_model_t* epd) { return EPD_ReadBusy(); }
@@ -10,14 +9,14 @@ static void SSD16xx_Update(uint8_t seq) {
EPD_WriteCmd(SSD16xx_MASTER_ACTIVATE);
}
int8_t SSD16xx_Read_Temp(epd_model_t* epd) {
int8_t SSD16xx_ReadTemp(epd_model_t* epd) {
SSD16xx_Update(0xB1);
SSD16xx_WaitBusy(500);
EPD_WriteCmd(SSD16xx_TSENSOR_READ);
return (int8_t)EPD_ReadByte();
}
static void _setPartialRamArea(epd_model_t* epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
static void SSD16xx_SetWindow(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
switch (epd->ic) {
case DRV_IC_SSD1677:
@@ -43,25 +42,24 @@ void SSD16xx_Init(epd_model_t* epd) {
EPD_Write(SSD16xx_BORDER_CTRL, 0x01);
EPD_Write(SSD16xx_TSENSOR_CTRL, 0x80);
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
SSD16xx_SetWindow(epd, 0, 0, epd->width, epd->height);
}
static void SSD16xx_Refresh(epd_model_t* epd) {
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));
EPD_DEBUG("refresh begin");
EPD_DEBUG("temperature: %d", SSD16xx_ReadTemp(epd));
SSD16xx_Update(0xF7);
SSD16xx_WaitBusy(UINT16_MAX);
NRF_LOG_DEBUG("[EPD]: refresh end\n");
_setPartialRamArea(epd, 0, 0, epd->width, epd->height); // DO NOT REMOVE!
EPD_DEBUG("refresh end");
SSD16xx_SetWindow(epd, 0, 0, epd->width, epd->height); // DO NOT REMOVE!
}
void SSD16xx_Clear(epd_model_t* epd, bool refresh) {
uint32_t ram_bytes = ((epd->width + 7) / 8) * epd->height;
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
SSD16xx_SetWindow(epd, 0, 0, epd->width, epd->height);
EPD_FillRAM(SSD16xx_WRITE_RAM1, 0xFF, ram_bytes);
EPD_FillRAM(SSD16xx_WRITE_RAM2, 0xFF, ram_bytes);
@@ -69,14 +67,14 @@ void SSD16xx_Clear(epd_model_t* epd, bool refresh) {
if (refresh) SSD16xx_Refresh(epd);
}
void SSD16xx_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w,
uint16_t h) {
void SSD16xx_WriteImage(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
w = wb * 8; // byte boundary
if (x + w > epd->width || y + h > epd->height) return;
_setPartialRamArea(epd, x, y, w, h);
SSD16xx_SetWindow(epd, x, y, w, h);
EPD_WriteCmd(SSD16xx_WRITE_RAM1);
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);
@@ -92,9 +90,10 @@ void SSD16xx_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint1
}
}
void SSD16xx_Write_Ram(epd_model_t* epd, uint8_t cfg, uint8_t* data, uint8_t len) {
void SSD16xx_WriteRam(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 && black) SSD16xx_SetWindow(epd, 0, 0, epd->width, epd->height);
if (begin) {
if (epd->color == COLOR_BWR)
EPD_WriteCmd(black ? SSD16xx_WRITE_RAM1 : SSD16xx_WRITE_RAM2);
@@ -112,11 +111,11 @@ void SSD16xx_Sleep(epd_model_t* epd) {
static const epd_driver_t epd_drv_ssd16xx = {
.init = SSD16xx_Init,
.clear = SSD16xx_Clear,
.write_image = SSD16xx_Write_Image,
.write_ram = SSD16xx_Write_Ram,
.write_image = SSD16xx_WriteImage,
.write_ram = SSD16xx_WriteRam,
.refresh = SSD16xx_Refresh,
.sleep = SSD16xx_Sleep,
.read_temp = SSD16xx_Read_Temp,
.read_temp = SSD16xx_ReadTemp,
.read_busy = SSD16xx_ReadBusy,
};

View File

@@ -1,5 +1,4 @@
#include "EPD_driver.h"
#include "nrf_log.h"
bool UC81xx_ReadBusy(epd_model_t* epd) { return EPD_ReadBusy() == false; }
@@ -17,13 +16,13 @@ static void UC81xx_PowerOff(epd_model_t* epd) {
}
// Read temperature from driver chip
int8_t UC81xx_Read_Temp(epd_model_t* epd) {
int8_t UC81xx_ReadTemp(epd_model_t* epd) {
EPD_WriteCmd(UC81xx_TSC);
UC81xx_WaitBusy(100);
return (int8_t)EPD_ReadByte();
}
static void _setPartialRamArea(epd_model_t* epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
static void UC81xx_SetWindow(epd_model_t* epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
switch (epd->ic) {
case DRV_IC_JD79668:
case DRV_IC_JD79665:
@@ -42,16 +41,16 @@ static void _setPartialRamArea(epd_model_t* epd, uint16_t x, uint16_t y, uint16_
}
void UC81xx_Refresh(epd_model_t* epd) {
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
EPD_DEBUG("refresh begin");
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
UC81xx_SetWindow(epd, 0, 0, epd->width, epd->height);
EPD_WriteCmd(UC81xx_DRF);
if (epd->color == COLOR_BWRY) EPD_WriteByte(0x00);
delay(100);
UC81xx_WaitBusy(UINT16_MAX);
NRF_LOG_DEBUG("[EPD]: refresh end\n");
EPD_DEBUG("refresh end");
}
void UC81xx_Init(epd_model_t* epd) {
@@ -106,6 +105,7 @@ void UC81xx_Init(epd_model_t* epd) {
break;
}
UC81xx_PowerOn(epd);
UC81xx_SetWindow(epd, 0, 0, epd->width, epd->height);
}
void UC81xx_Clear(epd_model_t* epd, bool refresh) {
@@ -139,15 +139,15 @@ void UC81xx_Clear(epd_model_t* epd, bool refresh) {
if (refresh) UC81xx_Refresh(epd);
}
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) {
void UC8176_WriteImage(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
w = wb * 8; // byte boundary
if (x + w > epd->width || y + h > epd->height) return;
EPD_WriteCmd(UC81xx_PTIN); // partial in
_setPartialRamArea(epd, x, y, w, h);
UC81xx_SetWindow(epd, x, y, w, h);
if (epd->color == COLOR_BWR) {
EPD_WriteCmd(UC81xx_DTM1);
for (uint16_t i = 0; i < h; i++) {
@@ -166,7 +166,7 @@ void UC8176_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16
EPD_WriteCmd(UC81xx_PTOUT); // partial out
}
static void UC8159_Send_Pixel(uint8_t black_data, uint8_t color_data) {
static void UC8159_SendPixel(uint8_t black_data, uint8_t color_data) {
uint8_t data;
for (uint8_t j = 0; j < 8; j++) {
if ((color_data & 0x80) == 0x00)
@@ -191,15 +191,15 @@ static void UC8159_Send_Pixel(uint8_t black_data, uint8_t color_data) {
}
}
void UC8159_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w,
uint16_t h) {
void UC8159_WriteImage(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
w = wb * 8; // byte boundary
if (x + w > epd->width || y + h > epd->height) return;
EPD_WriteCmd(UC81xx_PTIN); // partial in
_setPartialRamArea(epd, x, y, w, h);
UC81xx_SetWindow(epd, x, y, w, h);
EPD_WriteCmd(UC81xx_DTM1);
for (uint16_t i = 0; i < h; i++) {
for (uint16_t j = 0; j < w / 8; j++) {
@@ -207,20 +207,20 @@ void UC8159_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16
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);
UC8159_SendPixel(black_data, color_data);
}
}
EPD_WriteCmd(UC81xx_PTOUT); // partial out
}
void JD79668_Write_Image(epd_model_t* epd, uint8_t* black, uint8_t* color, uint16_t x, uint16_t y, uint16_t w,
uint16_t h) {
void JD79668_WriteImage(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 + 3) / 4; // width bytes, bitmaps are padded
x -= x % 4; // byte boundary
w = wb * 4; // byte boundary
if (x + w > epd->width || y + h > epd->height) return;
_setPartialRamArea(epd, x, y, w, h);
UC81xx_SetWindow(epd, x, y, w, h);
EPD_WriteCmd(UC81xx_DTM1);
for (uint16_t i = 0; i < h; i++) {
for (uint16_t j = 0; j < wb; j++) {
@@ -231,25 +231,26 @@ 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) {
void UC81xx_WriteImage(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);
UC8159_WriteImage(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);
JD79668_WriteImage(epd, black, color, x, y, w, h);
break;
default:
UC8176_Write_Image(epd, black, color, x, y, w, h);
UC8176_WriteImage(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) {
void UC81xx_WriteRam(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 && black) UC81xx_SetWindow(epd, 0, 0, epd->width, epd->height);
switch (epd->ic) {
case DRV_IC_UC8159:
case DRV_IC_JD79665:
@@ -279,11 +280,11 @@ void UC81xx_Sleep(epd_model_t* epd) {
static const epd_driver_t epd_drv_uc81xx = {
.init = UC81xx_Init,
.clear = UC81xx_Clear,
.write_image = UC81xx_Write_Image,
.write_ram = UC81xx_Write_Ram,
.write_image = UC81xx_WriteImage,
.write_ram = UC81xx_WriteRam,
.refresh = UC81xx_Refresh,
.sleep = UC81xx_Sleep,
.read_temp = UC81xx_Read_Temp,
.read_temp = UC81xx_ReadTemp,
.read_busy = UC81xx_ReadBusy,
};

5
main.h
View File

@@ -1,6 +1,11 @@
#ifndef _MAIN_H_
#define _MAIN_H_
#include <stdint.h>
uint32_t timestamp(void);
void set_timestamp(uint32_t timestamp);
void sleep_mode_enter(void);
void app_feed_wdt(void);
#endif