diff --git a/hello_usb.cpp b/hello_usb.cpp index 4ef2a71..e9b2eb8 100644 --- a/hello_usb.cpp +++ b/hello_usb.cpp @@ -29,13 +29,26 @@ static char g_last_echo[128] = ""; static UBYTE *g_epd_image = NULL; // Black image buffer static UBYTE *g_epd_red = NULL; // Red image buffer +// Entry list for display +#define MAX_ENTRIES 10 +#define ENTRY_LENGTH 64 +typedef struct { + char entries[MAX_ENTRIES][ENTRY_LENGTH]; + int count; +} EntryList; +static EntryList g_entry_list = {{}, 0}; + // Synchronization flag for multicore initialization static volatile bool g_display_ready = false; // Display update message structure for inter-core communication typedef struct { - char line1[64]; - char line2[64]; + EntryList entries; + bool use_partial; // Use partial refresh instead of full refresh + UWORD xstart; // Partial refresh region + UWORD ystart; + UWORD xend; + UWORD yend; } DisplayMessage; void init_epaper_display() { @@ -77,43 +90,20 @@ void init_epaper_display() { Paint_SelectImage(g_epd_image); Paint_Clear(WHITE); - // Draw "Hello World" on the display - printf("Drawing\r\n"); - Paint_DrawString_EN(10, 10, "Hello World!", &Font24, WHITE, BLACK); - Paint_DrawString_EN(10, 60, "7.5\" e-Paper Initialized", &Font16, WHITE, BLACK); + // Draw header + // printf("Drawing header\r\n"); + // Paint_DrawString_EN(10, 10, "What's new today:", &Font24, BLACK, WHITE); // Display the image with both black and red buffers - printf("display text\r\n"); + // printf("display text\r\n"); EPD_7IN5B_V2_Display(g_epd_image, g_epd_red); - printf("delay\r\n"); - DEV_Delay_ms(2000); + // printf("delay\r\n"); + // DEV_Delay_ms(1000); printf("e-Paper display ready!\r\n"); // EPD_7IN5B_V2_Sleep(); } -void update_epaper_display(const char *line1, const char *line2) { - if (g_epd_image == NULL || g_epd_red == NULL) return; - - // Clear and prepare buffers - UWORD imagesize = (EPD_7IN5B_V2_WIDTH / 8) * EPD_7IN5B_V2_HEIGHT; - for (UWORD i = 0; i < imagesize; i++) { - g_epd_red[i] = 0xFF; // No red pixels - } - - Paint_SelectImage(g_epd_image); - Paint_Clear(WHITE); - - if (line1) { - Paint_DrawString_EN(50, 100, (char *)line1, &Font16, BLACK, WHITE); - } - if (line2) { - Paint_DrawString_EN(50, 150, (char *)line2, &Font16, BLACK, WHITE); - } - - EPD_7IN5B_V2_Display(g_epd_image, g_epd_red); -} - // Define the maximum size for the input string buffer #define MAX_INPUT_LEN 64 // Define the timeout period: 5 seconds in microseconds @@ -122,11 +112,25 @@ void update_epaper_display(const char *line1, const char *line2) { #define ASCII_BACKSPACE 8 /** - * Send a display update message to core 1 via FIFO + * Add an entry to the display list and send update to core 1 */ -void send_display_update(const char *line1, const char *line2) { +void send_display_update(const char *entry) { if (!g_display_ready) return; // Don't send if display isn't ready + // Add entry to global list + if (g_entry_list.count < MAX_ENTRIES) { + strncpy(g_entry_list.entries[g_entry_list.count], entry, ENTRY_LENGTH - 1); + g_entry_list.entries[g_entry_list.count][ENTRY_LENGTH - 1] = '\0'; + g_entry_list.count++; + } else { + // Shift entries up and add new one at bottom + for (int i = 0; i < MAX_ENTRIES - 1; i++) { + strcpy(g_entry_list.entries[i], g_entry_list.entries[i + 1]); + } + strncpy(g_entry_list.entries[MAX_ENTRIES - 1], entry, ENTRY_LENGTH - 1); + g_entry_list.entries[MAX_ENTRIES - 1][ENTRY_LENGTH - 1] = '\0'; + } + // Allocate message structure DisplayMessage *msg = (DisplayMessage *)malloc(sizeof(DisplayMessage)); if (msg == NULL) { @@ -134,18 +138,21 @@ void send_display_update(const char *line1, const char *line2) { return; } - // Copy strings into message - strncpy(msg->line1, line1 ? line1 : "", sizeof(msg->line1) - 1); - msg->line1[sizeof(msg->line1) - 1] = '\0'; + // Copy entry list to message + msg->entries = g_entry_list; - strncpy(msg->line2, line2 ? line2 : "", sizeof(msg->line2) - 1); - msg->line2[sizeof(msg->line2) - 1] = '\0'; + // Setup partial refresh region (text area at top of display) + msg->use_partial = true; + msg->xstart = 0; + msg->ystart = 50; // Start below the header + msg->xend = 800; // Full width + msg->yend = 480; // Full height from header onwards // Send message pointer to core 1 multicore_fifo_push_blocking((uint32_t)msg); // Wait for core 1 to complete the update - // multicore_fifo_pop_blocking(); + multicore_fifo_pop_blocking(); } /** @@ -157,6 +164,9 @@ void core1_display_init() { printf("[Core 1] Display ready, waiting for update messages...\n"); + // Initialize for partial refresh on second call + EPD_7IN5B_V2_Init_Part(); + // Core 1 main loop: handle display updates via FIFO while (true) { // Check if there's a message from core 0 @@ -165,26 +175,55 @@ void core1_display_init() { uint32_t msg_addr = multicore_fifo_pop_blocking(); DisplayMessage *msg = (DisplayMessage *)msg_addr; - printf("[Core 1] Updating display: '%s' / '%s'\n", msg->line1, msg->line2); + printf("[Core 1] Updating display with %d entries\n", msg->entries.count); // Update the e-Paper display if (g_epd_image != NULL && g_epd_red != NULL) { UWORD imagesize = (EPD_7IN5B_V2_WIDTH / 8) * EPD_7IN5B_V2_HEIGHT; - for (UWORD i = 0; i < imagesize; i++) { - g_epd_red[i] = 0xFF; + + // For partial refresh, only clear the text area + UWORD width = (EPD_7IN5B_V2_WIDTH / 8); + UWORD y_start = msg->ystart; + UWORD y_end = msg->yend; + + if (msg->use_partial) { + // Clear only the affected region in the buffers + for (UWORD y = y_start; y < y_end; y++) { + for (UWORD x = 0; x < width; x++) { + g_epd_image[x + y * width] = 0xFF; // White + g_epd_red[x + y * width] = 0xFF; // No red + } + } + } else { + // Full clear + for (UWORD i = 0; i < imagesize; i++) { + g_epd_image[i] = 0xFF; + g_epd_red[i] = 0xFF; + } } - // Paint_SelectImage(g_epd_image); - // Paint_Clear(WHITE); + Paint_SelectImage(g_epd_image); - if (msg->line1[0] != '\0') { - Paint_DrawString_EN(50, 100, msg->line1, &Font16, BLACK, WHITE); - } - if (msg->line2[0] != '\0') { - Paint_DrawString_EN(50, 150, msg->line2, &Font16, BLACK, WHITE); + // Draw header + Paint_DrawString_EN(10, 10, "What's new today:", &Font24, WHITE, BLACK); + + // Draw all entries starting below header + UWORD y_pos = 50; + for (int i = 0; i < msg->entries.count; i++) { + if (y_pos + 20 < 480) { // Don't draw beyond screen + Paint_DrawString_EN(20, y_pos, msg->entries.entries[i], &Font16, WHITE, BLACK); + y_pos += 25; // Space between entries + } } - EPD_7IN5B_V2_Display(g_epd_image, g_epd_red); + // Use partial or full refresh + if (msg->use_partial) { + printf("[Core 1] Using partial refresh\n"); + EPD_7IN5B_V2_Display_Partial(g_epd_image, msg->xstart, msg->ystart, msg->xend, msg->yend); + } else { + printf("[Core 1] Using full refresh\n"); + EPD_7IN5B_V2_Display(g_epd_image, g_epd_red); + } } // Free the message (it was allocated by core 0) @@ -240,7 +279,7 @@ void run_echo_session(DisplayManager &display) { // Update both displays to show cleared input and last echo display.set_last_echo(g_last_echo); display.refresh("", g_last_echo); - send_display_update("", g_last_echo); + send_display_update(g_last_echo); } else if (buffer_index < (MAX_INPUT_LEN - 1) && isprint(input_char)) { printf("%c", input_char); input_buffer[buffer_index] = input_char;