add week start setting

This commit is contained in:
Shuanglei Tao
2025-07-03 11:51:37 +08:00
parent 714adab127
commit f821b56c0b
6 changed files with 60 additions and 32 deletions

View File

@@ -17,6 +17,7 @@ typedef struct
uint8_t led_pin;
uint8_t en_pin;
uint8_t display_mode;
uint8_t week_start;
} epd_config_t;
#define EPD_CONFIG_SIZE (sizeof(epd_config_t) / sizeof(uint8_t))

View File

@@ -44,6 +44,7 @@ static void epd_gui_update(void * p_event_data, uint16_t event_size)
.width = epd->width,
.height = epd->height,
.timestamp = event->timestamp,
.week_start = p_epd->config.week_start,
.temperature = epd->drv->read_temp(),
.voltage = EPD_ReadVoltage(),
};
@@ -182,6 +183,14 @@ static void epd_service_on_write(ble_epd_t * p_epd, uint8_t * p_data, uint16_t l
ble_epd_on_timer(p_epd, timestamp, true);
} break;
case EPD_CMD_SET_WEEK_START:
if (length < 2) return;
if (p_data[1] < 7 && p_data[1] != p_epd->config.week_start) {
p_epd->config.week_start = p_data[1];
epd_config_write(&p_epd->config);
}
break;
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] >> 4) == 0x00, (p_data[1] & 0x0F) == 0x0F, &p_data[2], length - 2);
@@ -366,6 +375,8 @@ uint32_t ble_epd_init(ble_epd_t * p_epd)
memcpy(&p_epd->config, cfg, sizeof(cfg));
if (p_epd->config.display_mode == 0xFF)
p_epd->config.display_mode = MODE_CALENDAR;
if (p_epd->config.week_start == 0xFF)
p_epd->config.week_start = 0;
epd_config_write(&p_epd->config);
}

View File

@@ -62,22 +62,23 @@ void ble_epd_evt_handler(ble_evt_t const * p_ble_evt, void * p_context);
/**< EPD Service command IDs. */
enum EPD_CMDS
{
EPD_CMD_SET_PINS = 0x00, /**< set EPD pin mapping. */
EPD_CMD_INIT = 0x01, /**< init EPD display driver */
EPD_CMD_CLEAR = 0x02, /**< clear EPD screen */
EPD_CMD_SEND_COMMAND = 0x03, /**< send command to EPD */
EPD_CMD_SEND_DATA = 0x04, /**< send data to EPD */
EPD_CMD_REFRESH = 0x05, /**< diaplay EPD ram on screen */
EPD_CMD_SLEEP = 0x06, /**< EPD enter sleep mode */
EPD_CMD_SET_PINS = 0x00, /**< set EPD pin mapping. */
EPD_CMD_INIT = 0x01, /**< init EPD display driver */
EPD_CMD_CLEAR = 0x02, /**< clear EPD screen */
EPD_CMD_SEND_COMMAND = 0x03, /**< send command to EPD */
EPD_CMD_SEND_DATA = 0x04, /**< send data to EPD */
EPD_CMD_REFRESH = 0x05, /**< diaplay EPD ram on screen */
EPD_CMD_SLEEP = 0x06, /**< EPD enter sleep mode */
EPD_CMD_SET_TIME = 0x20, /** < set time with unix timestamp */
EPD_CMD_SET_TIME = 0x20, /** < set time with unix timestamp */
EPD_CMD_SET_WEEK_START = 0x21, /** < set week start day (0: Sunday, 1: Monday, ...) */
EPD_CMD_WRITE_IMAGE = 0x30, /** < write image data to EPD ram */
EPD_CMD_WRITE_IMAGE = 0x30, /** < write image data to EPD ram */
EPD_CMD_SET_CONFIG = 0x90, /**< set full EPD config */
EPD_CMD_SYS_RESET = 0x91, /**< MCU reset */
EPD_CMD_SYS_SLEEP = 0x92, /**< MCU enter sleep mode */
EPD_CMD_CFG_ERASE = 0x99, /**< Erase config and reset */
EPD_CMD_SET_CONFIG = 0x90, /**< set full EPD config */
EPD_CMD_SYS_RESET = 0x91, /**< MCU reset */
EPD_CMD_SYS_SLEEP = 0x92, /**< MCU enter sleep mode */
EPD_CMD_CFG_ERASE = 0x99, /**< Erase config and reset */
};
/**@brief EPD Service structure.

View File

@@ -208,34 +208,39 @@ static void DrawDateHeader(Adafruit_GFX *gfx, int16_t x, int16_t y, tm_t *tm, st
GFX_printf(gfx, "%s", data->ssid);
}
static void DrawWeekHeader(Adafruit_GFX *gfx, int16_t x, int16_t y)
static void DrawWeekHeader(Adafruit_GFX *gfx, int16_t x, int16_t y, gui_data_t *data)
{
GFX_fillRect(gfx, x, y, 380, 24, GFX_RED);
GFX_fillRect(gfx, x + 50, y, 280, 24, GFX_BLACK);
GFX_setFont(gfx, u8g2_font_wqy9_t_lunar);
uint8_t w = (data->width - 2 * x) / 7;
uint8_t r = (data->width - 2 * x) % 7;
for (int i = 0; i < 7; i++) {
GFX_setTextColor(gfx, GFX_WHITE, (i > 0 && i < 6) ? GFX_BLACK : GFX_RED);
GFX_setCursor(gfx, x + 15 + i * 55, y + 16);
GFX_printf(gfx, "%s", Lunar_DayString[i]);
uint8_t day = (data->week_start + i) % 7;
uint16_t bg = (day == 0 || day == 6) ? GFX_RED : GFX_BLACK;
GFX_fillRect(gfx, x + i * w, y, i == 6 ? (w + r) : w, 24, bg);
GFX_setTextColor(gfx, GFX_WHITE, bg);
GFX_setCursor(gfx, x + 18 + i * w, y + 16);
GFX_printf(gfx, "%s", Lunar_DayString[day]);
}
}
static void DrawMonthDays(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar)
static void DrawMonthDays(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, gui_data_t *data)
{
uint8_t firstDayWeek = get_first_day_week(tm->tm_year + YEAR0, tm->tm_mon + 1);
int8_t adjustedFirstDay = (firstDayWeek - data->week_start + 7) % 7;
uint8_t monthMaxDays = thisMonthMaxDays(tm->tm_year + YEAR0, tm->tm_mon + 1);
uint8_t monthDayRows = 1 + (monthMaxDays - (7 - firstDayWeek) + 6) / 7;
uint8_t monthDayRows = 1 + (monthMaxDays - (7 - adjustedFirstDay) + 6) / 7;
for (uint8_t i = 0; i < monthMaxDays; i++) {
uint16_t year = tm->tm_year + YEAR0;
uint8_t month = tm->tm_mon + 1;
uint8_t day = i + 1;
int16_t week = (firstDayWeek + i) % 7;
bool weekend = (week == 0) || (week == 6);
int16_t actualWeek = (firstDayWeek + i) % 7;
int16_t displayWeek = (adjustedFirstDay + i) % 7;
bool weekend = (actualWeek == 0) || (actualWeek == 6);
int16_t x = 22 + week * 55;
int16_t y = (monthDayRows > 5 ? 69 : 72) + (firstDayWeek + i) / 7 * (monthDayRows > 5 ? 39 : 48);
int16_t x = 22 + displayWeek * 55;
int16_t y = (monthDayRows > 5 ? 69 : 72) + (adjustedFirstDay + i) / 7 * (monthDayRows > 5 ? 39 : 48);
if (day == tm->tm_mday) {
GFX_fillCircle(gfx, x + 11, y + (monthDayRows > 5 ? 10 : 12), 22, GFX_RED);
@@ -252,7 +257,7 @@ static void DrawMonthDays(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar)
LUNAR_SolarToLunar(Lunar, year, month, day);
char festival[10] = {0};
if (GetFestival(year, month, day, week, Lunar, festival)) {
if (GetFestival(year, month, day, actualWeek, Lunar, festival)) {
if (day != tm->tm_mday) GFX_setTextColor(gfx, GFX_RED, GFX_WHITE);
GFX_setCursor(gfx, strlen(festival) > 6 ? x - 6 : x, y + 24);
GFX_printf(gfx, "%s", festival);
@@ -281,8 +286,8 @@ static void DrawMonthDays(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar)
static void DrawCalendar(Adafruit_GFX *gfx, tm_t *tm, struct Lunar_Date *Lunar, gui_data_t *data)
{
DrawDateHeader(gfx, 10, 28, tm, Lunar, data);
DrawWeekHeader(gfx, 10, 32);
DrawMonthDays(gfx, tm, Lunar);
DrawWeekHeader(gfx, 10, 32, data);
DrawMonthDays(gfx, tm, Lunar, data);
}
/* Routine to Draw Large 7-Segment formated number
@@ -369,6 +374,8 @@ 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)
{
if (data->week_start > 6 || data->week_start < 0) data->week_start = 0;
tm_t tm = {0};
struct Lunar_Date Lunar;

View File

@@ -18,6 +18,7 @@ typedef struct {
uint16_t width;
uint16_t height;
uint32_t timestamp;
uint8_t week_start; // 0: Sunday, 1: Monday
int8_t temperature;
float voltage;
char ssid[13];

View File

@@ -16,13 +16,15 @@
// Global variables
HINSTANCE g_hInstance;
HWND g_hwnd;
HDC g_paintHDC = NULL;
display_mode_t g_display_mode = MODE_CALENDAR; // Default to calendar mode
BOOL g_bwr_mode = TRUE; // Default to BWR mode
uint8_t g_week_start = 0; // Default week start (0=Sunday, 1=Monday, etc.)
time_t g_display_time;
struct tm g_tm_time;
// Add a global variable for the paint HDC
static HDC g_paintHDC = NULL;
// Help text for hotkeys
static const wchar_t helpText[] = L"空格 - 切换时钟 | R - 切换颜色 | W - 星期起点 | 方向键 - 调整日期/月份";
// 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) {
@@ -195,8 +197,6 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
);
HFONT oldFont = SelectObject(hdc, helpFont);
wchar_t helpText[] = L"快捷键: 空格 - 切换模式 | R - 切换BWR | 方向键 - 调整日期/月份";
// Calculate text width for centering
SIZE textSize;
GetTextExtentPoint32W(hdc, helpText, wcslen(helpText), &textSize);
@@ -213,6 +213,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
.width = BITMAP_WIDTH,
.height = BITMAP_HEIGHT,
.timestamp = g_display_time,
.week_start = g_week_start,
.temperature = 25,
.voltage = 3.2f,
.ssid = "NRF_EPD_84AC",
@@ -243,6 +244,12 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
g_bwr_mode = !g_bwr_mode;
InvalidateRect(hwnd, NULL, TRUE);
}
// Increase week start with W key
else if (wParam == 'W') {
g_week_start++;
if (g_week_start > 6) g_week_start = 0; // Wrap around
InvalidateRect(hwnd, NULL, TRUE);
}
// Handle arrow keys for month/day adjustment
else if (wParam == VK_UP || wParam == VK_DOWN || wParam == VK_LEFT || wParam == VK_RIGHT) {
// Get the current time structure