From f821b56c0bfed807568fd0ec5b0a98da268aea08 Mon Sep 17 00:00:00 2001 From: Shuanglei Tao Date: Thu, 3 Jul 2025 11:51:37 +0800 Subject: [PATCH] add week start setting --- EPD/EPD_config.h | 1 + EPD/EPD_service.c | 11 +++++++++++ EPD/EPD_service.h | 27 ++++++++++++++------------- GUI/GUI.c | 37 ++++++++++++++++++++++--------------- GUI/GUI.h | 1 + emulator.c | 15 +++++++++++---- 6 files changed, 60 insertions(+), 32 deletions(-) diff --git a/EPD/EPD_config.h b/EPD/EPD_config.h index 72a798d..ba9b4c9 100644 --- a/EPD/EPD_config.h +++ b/EPD/EPD_config.h @@ -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)) diff --git a/EPD/EPD_service.c b/EPD/EPD_service.c index 8621190..f363848 100644 --- a/EPD/EPD_service.c +++ b/EPD/EPD_service.c @@ -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); } diff --git a/EPD/EPD_service.h b/EPD/EPD_service.h index 2afcf77..608013a 100644 --- a/EPD/EPD_service.h +++ b/EPD/EPD_service.h @@ -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. diff --git a/GUI/GUI.c b/GUI/GUI.c index 6d8918e..9f4be7a 100644 --- a/GUI/GUI.c +++ b/GUI/GUI.c @@ -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; diff --git a/GUI/GUI.h b/GUI/GUI.h index e93d926..12e0f5f 100644 --- a/GUI/GUI.h +++ b/GUI/GUI.h @@ -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]; diff --git a/emulator.c b/emulator.c index fe0f25f..53ad33e 100644 --- a/emulator.c +++ b/emulator.c @@ -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