get rid of global EPD var

This commit is contained in:
Shuanglei Tao
2025-10-15 17:12:00 +08:00
parent c044759262
commit 1ac6b8473f
10 changed files with 119 additions and 150 deletions

View File

@@ -17,9 +17,6 @@ static uint32_t EPD_BS_PIN = 13;
static uint32_t EPD_EN_PIN = 0xFF;
static uint32_t EPD_LED_PIN = 0xFF;
// EPD model
static epd_model_t *EPD = NULL;
#define SPI_INSTANCE 0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
@@ -343,19 +340,15 @@ static epd_model_t *epd_models[] = {
&epd_jd79668_420,
};
epd_model_t *epd_get(void)
{
return EPD == NULL ? epd_models[0] : EPD;
}
epd_model_t *epd_init(epd_model_id_t id)
{
epd_model_t *epd = NULL;
for (uint8_t i = 0; i < ARRAY_SIZE(epd_models); i++) {
if (epd_models[i]->id == id) {
EPD = epd_models[i];
epd = epd_models[i];
}
}
if (EPD == NULL) EPD = epd_models[0];
EPD->drv->init();
return EPD;
if (epd == NULL) epd = epd_models[0];
epd->drv->init(epd);
return epd;
}

View File

@@ -32,22 +32,12 @@ typedef enum
EPD_DRIVER_IC_SSD1677 = 6,
} epd_driver_ic_t;
/**@brief EPD driver structure.
*
* @details This structure contains epd driver functions.
*/
typedef struct
typedef enum
{
epd_driver_ic_t ic; /**< EPD driver IC type */
void (*init)(); /**< Initialize the e-Paper register */
void (*clear)(bool refresh); /**< Clear screen */
void (*write_image)(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h); /**< write image */
void (*write_ram)(uint8_t cfg, uint8_t *data, uint8_t len); /* write data to epd ram */
void (*refresh)(void); /**< Sends the image buffer in RAM to e-Paper and displays */
void (*sleep)(void); /**< Enter sleep mode */
int8_t (*read_temp)(void); /**< Read temperature from driver chip */
} epd_driver_t;
BW = 1,
BWR = 2,
BWRY = 3,
} epd_color_t;
typedef enum
{
@@ -64,22 +54,33 @@ typedef enum
EPD_SSD1677_750_HD_BWR = 11,
} epd_model_id_t;
typedef enum
{
BW = 1,
BWR = 2,
BWRY = 3,
} epd_color_t;
struct epd_driver;
typedef struct
{
epd_model_id_t id;
epd_color_t color;
epd_driver_t *drv;
struct epd_driver *drv;
uint16_t width;
uint16_t height;
} epd_model_t;
/**@brief EPD driver structure.
*
* @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, uint16_t h); /**< write image */
void (*write_ram)(epd_model_t *epd, uint8_t cfg, uint8_t *data, uint8_t len); /* write data to epd ram */
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 */
} epd_driver_t;
#define LOW (0x0)
#define HIGH (0x1)
@@ -129,7 +130,6 @@ void EPD_LED_BLINK(void);
// VDD voltage
float EPD_ReadVoltage(void);
epd_model_t *epd_get(void);
epd_model_t *epd_init(epd_model_id_t id);
#endif

View File

@@ -37,12 +37,13 @@ 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 = {
.mode = (display_mode_t)p_epd->config.display_mode,
.color = epd->color,
.width = epd->width,
.height = epd->height,
.timestamp = event->timestamp,
.week_start = p_epd->config.week_start,
.temperature = epd->drv->read_temp(),
.temperature = epd->drv->read_temp(epd),
.voltage = EPD_ReadVoltage(),
};
@@ -51,8 +52,8 @@ static void epd_gui_update(void * p_event_data, uint16_t event_size)
if (err_code == NRF_SUCCESS && dev_name_len > 0)
data.ssid[dev_name_len] = '\0';
DrawGUI(&data, epd->drv->write_image, (display_mode_t)p_epd->config.display_mode);
epd->drv->refresh();
DrawGUI(&data, (buffer_callback)epd->drv->write_image, epd);
epd->drv->refresh(epd);
EPD_GPIO_Uninit();
app_feed_wdt();
@@ -78,7 +79,7 @@ static void on_disconnect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
{
UNUSED_PARAMETER(p_ble_evt);
p_epd->conn_handle = BLE_CONN_HANDLE_INVALID;
p_epd->epd->drv->sleep();
p_epd->epd->drv->sleep(p_epd->epd);
nrf_delay_ms(200); // for sleep
EPD_GPIO_Uninit();
}
@@ -132,20 +133,19 @@ static void epd_service_on_write(ble_epd_t * p_epd, uint8_t * p_data, uint16_t l
EPD_GPIO_Init();
break;
case EPD_CMD_INIT: {
uint8_t id = length > 1 ? p_data[1] : p_epd->config.model_id;
if (id != p_epd->config.model_id) {
p_epd->config.model_id = id;
case EPD_CMD_INIT:
p_epd->epd = epd_init((epd_model_id_t)(length > 1 ? p_data[1] : p_epd->config.model_id));
if (p_epd->epd->id != p_epd->config.model_id) {
p_epd->config.model_id = p_epd->epd->id;
epd_config_write(&p_epd->config);
}
p_epd->epd = epd_init((epd_model_id_t)id);
epd_send_mtu(p_epd);
epd_send_time(p_epd);
} break;
break;
case EPD_CMD_CLEAR:
epd_update_display_mode(p_epd, MODE_PICTURE);
p_epd->epd->drv->clear(length > 1 ? p_data[1] : true);
p_epd->epd->drv->clear(p_epd->epd, length > 1 ? p_data[1] : true);
break;
case EPD_CMD_SEND_COMMAND:
@@ -159,11 +159,11 @@ static void epd_service_on_write(ble_epd_t * p_epd, uint8_t * p_data, uint16_t l
case EPD_CMD_REFRESH:
epd_update_display_mode(p_epd, MODE_PICTURE);
p_epd->epd->drv->refresh();
p_epd->epd->drv->refresh(p_epd->epd);
break;
case EPD_CMD_SLEEP:
p_epd->epd->drv->sleep();
p_epd->epd->drv->sleep(p_epd->epd);
break;
case EPD_CMD_SET_TIME: {
@@ -189,7 +189,7 @@ static void epd_service_on_write(ble_epd_t * p_epd, uint8_t * p_data, uint16_t l
case EPD_CMD_WRITE_IMAGE: // MSB=0000: ram begin, LSB=1111: black
if (length < 3) return;
p_epd->epd->drv->write_ram(p_data[1], &p_data[2], length - 2);
p_epd->epd->drv->write_ram(p_epd->epd, p_data[1], &p_data[2], length - 2);
break;
case EPD_CMD_SET_CONFIG:

View File

@@ -69,7 +69,7 @@ static void SSD16xx_Update(uint8_t seq)
EPD_WriteCmd(CMD_MASTER_ACTIVATE);
}
int8_t SSD16xx_Read_Temp(void)
int8_t SSD16xx_Read_Temp(epd_model_t *epd)
{
SSD16xx_Update(0xB1);
SSD16xx_WaitBusy(500);
@@ -77,12 +77,10 @@ int8_t SSD16xx_Read_Temp(void)
return (int8_t)EPD_ReadByte();
}
static void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
static void _setPartialRamArea(epd_model_t *epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{
epd_model_t *EPD = epd_get();
EPD_Write(CMD_ENTRY_MODE, 0x03); // set ram entry mode: x increase, y increase
if (EPD->drv->ic == EPD_DRIVER_IC_SSD1677) {
if (epd->drv->ic == EPD_DRIVER_IC_SSD1677) {
EPD_Write(CMD_RAM_XPOS,
x % 256, x / 256,
(x + w - 1) % 256,
@@ -115,10 +113,8 @@ void SSD16xx_Dump_LUT(void)
NRF_LOG_DEBUG("=== LUT END ===\n");
}
void SSD16xx_Init()
void SSD16xx_Init(epd_model_t *epd)
{
epd_model_t *EPD = epd_get();
EPD_Reset(HIGH, 10);
EPD_WriteCmd(CMD_SW_RESET);
@@ -127,51 +123,47 @@ void SSD16xx_Init()
EPD_Write(CMD_BORDER_CTRL, 0x01);
EPD_Write(CMD_TSENSOR_CTRL, 0x80);
_setPartialRamArea(0, 0, EPD->width, EPD->height);
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
}
static void SSD16xx_Refresh(void)
static void SSD16xx_Refresh(epd_model_t *epd)
{
epd_model_t *EPD = epd_get();
EPD_Write(CMD_DISP_CTRL1, EPD->color == 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", SSD16xx_Read_Temp());
NRF_LOG_DEBUG("[EPD]: temperature: %d\n", SSD16xx_Read_Temp(epd));
SSD16xx_Update(0xF7);
SSD16xx_WaitBusy(30000);
NRF_LOG_DEBUG("[EPD]: refresh end\n");
// SSD16xx_Dump_LUT();
_setPartialRamArea(0, 0, EPD->width, EPD->height); // DO NOT REMOVE!
_setPartialRamArea(epd, 0, 0, epd->width, epd->height); // DO NOT REMOVE!
SSD16xx_Update(0x83); // power off
}
void SSD16xx_Clear(bool refresh)
void SSD16xx_Clear(epd_model_t *epd, bool refresh)
{
epd_model_t *EPD = epd_get();
uint32_t ram_bytes = ((EPD->width + 7) / 8) * EPD->height;
uint32_t ram_bytes = ((epd->width + 7) / 8) * epd->height;
_setPartialRamArea(0, 0, EPD->width, EPD->height);
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
EPD_FillRAM(CMD_WRITE_RAM1, 0xFF, ram_bytes);
EPD_FillRAM(CMD_WRITE_RAM2, 0xFF, ram_bytes);
if (refresh)
SSD16xx_Refresh();
SSD16xx_Refresh(epd);
}
void SSD16xx_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
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)
{
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)
if (x + w > epd->width || y + h > epd->height)
return;
_setPartialRamArea(x, y, w, h);
_setPartialRamArea(epd, x, y, w, h);
EPD_WriteCmd(CMD_WRITE_RAM1);
for (uint16_t i = 0; i < h; i++)
{
@@ -183,7 +175,7 @@ void SSD16xx_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->color == BWR)
if (epd->color == BWR)
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
else
EPD_WriteByte(black[j + i * wb]);
@@ -191,13 +183,12 @@ void SSD16xx_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y,
}
}
void SSD16xx_Write_Ram(uint8_t cfg, uint8_t *data, uint8_t len)
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) {
epd_model_t *EPD = epd_get();
if (EPD->color == BWR)
if (epd->color == BWR)
EPD_WriteCmd(black ? CMD_WRITE_RAM1 : CMD_WRITE_RAM2);
else
EPD_WriteCmd(CMD_WRITE_RAM1);
@@ -205,7 +196,7 @@ void SSD16xx_Write_Ram(uint8_t cfg, uint8_t *data, uint8_t len)
EPD_WriteData(data, len);
}
void SSD16xx_Sleep(void)
void SSD16xx_Sleep(epd_model_t *epd)
{
EPD_Write(CMD_SLEEP_MODE, 0x01);
delay(100);

View File

@@ -62,18 +62,16 @@ static void UC81xx_PowerOff(void)
}
// Read temperature from driver chip
int8_t UC81xx_Read_Temp(void)
int8_t UC81xx_Read_Temp(epd_model_t *epd)
{
EPD_WriteCmd(CMD_TSC);
UC81xx_WaitBusy(100);
return (int8_t)EPD_ReadByte();
}
static void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
static void _setPartialRamArea(epd_model_t *epd, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{
epd_model_t *EPD = epd_get();
if (EPD->drv->ic == EPD_DRIVER_IC_JD79668) {
if (epd->drv->ic == EPD_DRIVER_IC_JD79668) {
EPD_Write(0x83, // partial window
x / 256, x % 256,
(x + w - 1) / 256, (x + w - 1) % 256,
@@ -93,21 +91,19 @@ static void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
}
}
void UC81xx_Refresh(void)
void UC81xx_Refresh(epd_model_t *epd)
{
epd_model_t *EPD = epd_get();
NRF_LOG_DEBUG("[EPD]: refresh begin\n");
if (EPD->drv->ic != EPD_DRIVER_IC_JD79668)
if (epd->drv->ic != EPD_DRIVER_IC_JD79668)
UC81xx_PowerOn();
_setPartialRamArea(0, 0, EPD->width, EPD->height);
_setPartialRamArea(epd, 0, 0, epd->width, epd->height);
EPD_WriteCmd(CMD_DRF);
delay(100);
UC81xx_WaitBusy(30000);
if (EPD->drv->ic != EPD_DRIVER_IC_JD79668)
if (epd->drv->ic != EPD_DRIVER_IC_JD79668)
UC81xx_PowerOff();
NRF_LOG_DEBUG("[EPD]: refresh end\n");
}
@@ -129,22 +125,18 @@ void UC81xx_Dump_OTP(void)
UC81xx_PowerOff();
}
void UC81xx_Init()
void UC81xx_Init(epd_model_t *epd)
{
epd_model_t *EPD = epd_get();
EPD_Reset(HIGH, 10);
// UC81xx_Dump_OTP();
EPD_Write(CMD_PSR, EPD->color == BWR ? 0x0F : 0x1F);
EPD_Write(CMD_CDI, EPD->color == BWR ? 0x77 : 0x97);
EPD_Write(CMD_PSR, epd->color == BWR ? 0x0F : 0x1F);
EPD_Write(CMD_CDI, epd->color == BWR ? 0x77 : 0x97);
}
void UC8159_Init()
void UC8159_Init(epd_model_t *epd)
{
epd_model_t *EPD = epd_get();
EPD_Reset(HIGH, 10);
EPD_Write(CMD_PWR, 0x37, 0x00);
@@ -157,16 +149,14 @@ void UC8159_Init()
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);
epd->width >> 8,
epd->width & 0xff,
epd->height >> 8,
epd->height & 0xff);
}
void JD79668_Init()
void JD79668_Init(epd_model_t *epd)
{
epd_model_t *EPD = epd_get();
EPD_Reset(HIGH, 50);
EPD_Write(0x4D, 0x78);
@@ -175,8 +165,8 @@ void JD79668_Init()
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->width / 256, epd->width % 256,
epd->height / 256, epd->height % 256);
EPD_Write(0xAE, 0xCF);
EPD_Write(0xB0, 0x13);
@@ -187,25 +177,23 @@ void JD79668_Init()
UC81xx_PowerOn();
}
void UC81xx_Clear(bool refresh)
void UC81xx_Clear(epd_model_t *epd, bool refresh)
{
epd_model_t *EPD = epd_get();
uint32_t ram_bytes = ((EPD->width + 7) / 8) * EPD->height;
uint32_t ram_bytes = ((epd->width + 7) / 8) * epd->height;
EPD_FillRAM(CMD_DTM1, 0xFF, ram_bytes);
EPD_FillRAM(CMD_DTM2, 0xFF, ram_bytes);
if (refresh)
UC81xx_Refresh();
UC81xx_Refresh(epd);
}
void UC8159_Clear(bool refresh)
void UC8159_Clear(epd_model_t *epd, bool refresh)
{
epd_model_t *EPD = epd_get();
uint32_t wb = (EPD->width + 7) / 8;
uint32_t wb = (epd->width + 7) / 8;
EPD_WriteCmd(CMD_DTM1);
for (uint32_t j = 0; j < EPD->height; j++) {
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);
@@ -214,32 +202,30 @@ void UC8159_Clear(bool refresh)
}
if (refresh)
UC81xx_Refresh();
UC81xx_Refresh(epd);
}
void JD79668_Clear(bool refresh)
void JD79668_Clear(epd_model_t *epd, bool refresh)
{
epd_model_t *EPD = epd_get();
uint32_t ram_bytes = ((EPD->width + 3) / 4) * EPD->height;
uint32_t ram_bytes = ((epd->width + 3) / 4) * epd->height;
EPD_FillRAM(CMD_DTM1, 0x55, ram_bytes);
if (refresh)
UC81xx_Refresh();
UC81xx_Refresh(epd);
}
void UC81xx_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
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)
{
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)
if (x + w > epd->width || y + h > epd->height)
return;
EPD_WriteCmd(CMD_PTIN); // partial in
_setPartialRamArea(x, y, w, h);
if (EPD->color == BWR)
_setPartialRamArea(epd, x, y, w, h);
if (epd->color == BWR)
{
EPD_WriteCmd(CMD_DTM1);
for (uint16_t i = 0; i < h; i++)
@@ -253,7 +239,7 @@ void UC81xx_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->color == BWR)
if (epd->color == BWR)
EPD_WriteByte(color ? color[j + i * wb] : 0xFF);
else
EPD_WriteByte(black[j + i * wb]);
@@ -281,17 +267,16 @@ static void UC8159_Send_Pixel(uint8_t black_data, uint8_t color_data) {
}
}
void UC8159_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
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)
{
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)
if (x + w > epd->width || y + h > epd->height)
return;
EPD_WriteCmd(CMD_PTIN); // partial in
_setPartialRamArea(x, y, w, h);
_setPartialRamArea(epd, x, y, w, h);
EPD_WriteCmd(CMD_DTM1);
for (uint16_t i = 0; i < h; i++)
{
@@ -307,16 +292,15 @@ void UC8159_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y,
EPD_WriteCmd(CMD_PTOUT); // partial out
}
void JD79668_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
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)
{
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)
if (x + w > epd->width || y + h > epd->height)
return;
_setPartialRamArea(x, y, w, h);
_setPartialRamArea(epd, x, y, w, h);
EPD_WriteCmd(CMD_DTM1);
for (uint16_t i = 0; i < h * 2; i++) // 2 bits per pixel
{
@@ -325,13 +309,12 @@ void JD79668_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y,
}
}
void UC81xx_Write_Ram(uint8_t cfg, uint8_t *data, uint8_t len)
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) {
epd_model_t *EPD = epd_get();
if (EPD->color == BWR)
if (epd->color == BWR)
EPD_WriteCmd(black ? CMD_DTM1 : CMD_DTM2);
else
EPD_WriteCmd(CMD_DTM2);
@@ -340,7 +323,7 @@ void UC81xx_Write_Ram(uint8_t cfg, uint8_t *data, uint8_t len)
}
// Write native data to ram, format should be 2pp or above
void UC81xx_Write_Ram_Native(uint8_t cfg, uint8_t *data, uint8_t len)
void UC81xx_Write_Ram_Native(epd_model_t *epd, uint8_t cfg, uint8_t *data, uint8_t len)
{
bool begin = (cfg >> 4) == 0x00;
bool black = (cfg & 0x0F) == 0x0F;
@@ -348,7 +331,7 @@ void UC81xx_Write_Ram_Native(uint8_t cfg, uint8_t *data, uint8_t len)
EPD_WriteData(data, len);
}
void UC81xx_Sleep(void)
void UC81xx_Sleep(epd_model_t *epd)
{
UC81xx_PowerOff();
delay(100);

View File

@@ -130,7 +130,7 @@ void GFX_firstPage(Adafruit_GFX *gfx) {
gfx->current_page = 0;
}
bool GFX_nextPage(Adafruit_GFX *gfx, buffer_callback callback) {
bool GFX_nextPage(Adafruit_GFX *gfx, buffer_callback callback, void *user_data) {
if (callback) {
int16_t page_ys = gfx->current_page * gfx->page_height;
if (gfx->px != 0 || gfx->py != 0 || gfx->pw != gfx->_width || gfx->ph != gfx->_height) {
@@ -138,10 +138,10 @@ bool GFX_nextPage(Adafruit_GFX *gfx, buffer_callback callback) {
uint16_t dest_ys = gfx->py + page_ys; // transposed
uint16_t dest_ye = MIN(gfx->py + gfx->ph, gfx->py + page_ye);
if (dest_ye > dest_ys)
callback(gfx->buffer, gfx->color, gfx->px, dest_ys, gfx->pw, dest_ye - dest_ys);
callback(user_data, gfx->buffer, gfx->color, gfx->px, dest_ys, gfx->pw, dest_ye - dest_ys);
} else {
int16_t height = MIN(gfx->page_height, gfx->HEIGHT - page_ys);
callback(gfx->buffer, gfx->color, 0, page_ys, gfx->WIDTH, height);
callback(user_data, gfx->buffer, gfx->color, 0, page_ys, gfx->WIDTH, height);
}
}

View File

@@ -14,7 +14,7 @@
#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);
typedef void (*buffer_callback)(void *user_data, uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
typedef enum {
GFX_ROTATE_0 = 0,
@@ -51,7 +51,7 @@ 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_setWindow(Adafruit_GFX *gfx, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void GFX_firstPage(Adafruit_GFX *gfx);
bool GFX_nextPage(Adafruit_GFX *gfx, buffer_callback callback);
bool GFX_nextPage(Adafruit_GFX *gfx, buffer_callback callback, void *user_data);
void GFX_end(Adafruit_GFX *gfx);
// DRAW API

View File

@@ -420,7 +420,7 @@ static void DrawClock(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, gui
}
}
void DrawGUI(gui_data_t *data, buffer_callback draw, display_mode_t mode)
void DrawGUI(gui_data_t *data, buffer_callback callback, void *callback_data)
{
if (data->week_start > 6) data->week_start = 0;
@@ -445,7 +445,7 @@ void DrawGUI(gui_data_t *data, buffer_callback draw, display_mode_t mode)
LUNAR_SolarToLunar(&Lunar, tm.tm_year + YEAR0, tm.tm_mon + 1, tm.tm_mday);
switch (mode) {
switch (data->mode) {
case MODE_CALENDAR:
DrawCalendar(&gfx, &tm, &Lunar, data);
break;
@@ -455,11 +455,11 @@ void DrawGUI(gui_data_t *data, buffer_callback draw, display_mode_t mode)
default:
break;
}
if ((mode == MODE_CALENDAR || mode == MODE_CLOCK) &&
if ((data->mode == MODE_CALENDAR || data->mode == MODE_CLOCK) &&
(tm.tm_year + YEAR0 == 2025 && tm.tm_mon + 1 == 1)) {
DrawTimeSyncTip(&gfx, data);
}
} while(GFX_nextPage(&gfx, draw));
} while(GFX_nextPage(&gfx, callback, callback_data));
GFX_end(&gfx);
}

View File

@@ -10,6 +10,7 @@ typedef enum {
} display_mode_t;
typedef struct {
display_mode_t mode;
uint16_t color;
uint16_t width;
uint16_t height;
@@ -20,6 +21,6 @@ typedef struct {
char ssid[20];
} gui_data_t;
void DrawGUI(gui_data_t *data, buffer_callback draw, display_mode_t mode);
void DrawGUI(gui_data_t *data, buffer_callback callback, void *callback_data);
#endif

View File

@@ -23,7 +23,7 @@ time_t g_display_time;
struct tm g_tm_time;
// Implementation of the buffer_callback function
void DrawBitmap(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
void DrawBitmap(void *user_data, uint8_t *black, uint8_t *color, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
HDC hdc = g_paintHDC;
if (!hdc) return;
@@ -228,6 +228,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
// Use the stored timestamp
gui_data_t data = {
.mode = g_display_mode,
.color = g_bwr_mode ? 2 : 1,
.width = BITMAP_WIDTH,
.height = BITMAP_HEIGHT,
@@ -239,7 +240,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
};
// Call DrawGUI to render the interface
DrawGUI(&data, DrawBitmap, g_display_mode);
DrawGUI(&data, DrawBitmap, NULL);
// Clear the global HDC
g_paintHDC = NULL;