smooth refresh with aggregated changes

This commit is contained in:
Adolfo Reyna
2025-11-29 23:33:02 -05:00
parent 7ebfbcb0fb
commit 2738c4ac3d

View File

@@ -108,8 +108,10 @@ void init_epaper_display() {
/**
* Add an entry to the display list and send update to core 1
* @param entry The text to display
* @param finish_line If true, commits the line (moves to next line). If false, updates current line.
*/
void send_display_update(const char *entry) {
void send_display_update(const char *entry, bool finish_line) {
if (!g_display_ready) return; // Don't send if display isn't ready
// Check if list is at capacity
@@ -120,10 +122,9 @@ void send_display_update(const char *entry) {
g_force_full_refresh = true;
}
// Add entry to global list
// Update the current entry (at g_entry_list.count)
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++;
// Allocate message structure
DisplayMessage *msg = (DisplayMessage *)malloc(sizeof(DisplayMessage));
@@ -134,6 +135,8 @@ void send_display_update(const char *entry) {
// Copy entry list to message
msg->entries = g_entry_list;
// We want to show the current line being edited, so we treat count as count + 1 for display purposes
msg->entries.count = g_entry_list.count + 1;
// Decide whether to use partial or full refresh
msg->use_partial = !g_force_full_refresh;
@@ -149,11 +152,18 @@ void send_display_update(const char *entry) {
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);
// Send message pointer to core 1 if FIFO has space
if (multicore_fifo_wready()) {
multicore_fifo_push_blocking((uint32_t)msg);
} else {
printf("[Core 0] FIFO full, skipping display update\n");
free(msg);
}
// Wait for core 1 to complete the update
multicore_fifo_pop_blocking();
// If finishing the line, increment count for next time
if (finish_line) {
g_entry_list.count++;
}
}
/**
@@ -175,6 +185,14 @@ void core1_display_init() {
// Read the message pointer
uint32_t msg_addr = multicore_fifo_pop_blocking();
DisplayMessage *msg = (DisplayMessage *)msg_addr;
// Drain FIFO to get the latest message
while (multicore_fifo_rvalid()) {
printf("[Core 1] Skipping intermediate update\n");
free(msg); // Free the stale message
msg_addr = multicore_fifo_pop_blocking();
msg = (DisplayMessage *)msg_addr;
}
printf("[Core 1] Updating display with %d entries\n", msg->entries.count);
@@ -199,8 +217,8 @@ void core1_display_init() {
// Draw all entries starting below header
UWORD y_pos = 0;
// paint only the last 3 entries
int start_index = msg->entries.count > 2 ? msg->entries.count - 2 : 0;
// paint only the last 10 entries
int start_index = msg->entries.count > 10 ? msg->entries.count - 10 : 0;
for (int i = start_index; i < msg->entries.count; i++) {
if (y_pos + 25 < 480) { //Don't draw beyond screen
Paint_DrawString_EN(20, i*25, msg->entries.entries[i], &Font16, WHITE, BLACK);
@@ -216,9 +234,6 @@ void core1_display_init() {
// Free the message (it was allocated by core 0)
free(msg);
// Signal back to core 0 that update is complete
multicore_fifo_push_blocking(1);
}
sleep_ms(10);
@@ -359,49 +374,55 @@ static void process_kbd_report(hid_keyboard_report_t const *report) {
uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0];
if (ch) {
printf("%c", ch);
if (ch == '\r' || ch == '\n') {
printf("\n");
// Process command
g_input_buffer[g_buffer_index] = '\0';
// Echo logic
echo_and_reset(g_input_buffer, &g_buffer_index);
// Save last echoed (all caps) for display
size_t k = 0;
for (; g_input_buffer[k] != '\0' && k < sizeof(g_last_echo) - 1; ++k) {
g_last_echo[k] = g_input_buffer[k];
bool is_enter = (ch == '\r' || ch == '\n');
bool is_backspace = (ch == '\b' || ch == 127);
bool is_printable = !is_enter && !is_backspace; // Includes space
if (is_backspace) {
if (g_buffer_index > 0) {
printf("\b \b");
g_buffer_index--;
g_input_buffer[g_buffer_index] = '\0';
// Update OLED
if (g_display_manager) g_display_manager->refresh(g_input_buffer, g_last_echo);
// Update e-Paper (in-place)
send_display_update(g_input_buffer, false);
}
g_last_echo[k] = '\0';
} else if (is_enter) {
printf("\n");
// Update displays
// Update e-Paper (commit line)
send_display_update(g_input_buffer, true);
// Save to last echo
strncpy(g_last_echo, g_input_buffer, sizeof(g_last_echo) - 1);
g_last_echo[sizeof(g_last_echo) - 1] = '\0';
// Clear buffer
g_buffer_index = 0;
g_input_buffer[0] = '\0';
// Update OLED
if (g_display_manager) {
g_display_manager->set_last_echo(g_last_echo);
g_display_manager->refresh("", g_last_echo);
}
send_display_update(g_last_echo);
// Reset buffer
g_buffer_index = 0;
g_input_buffer[0] = '\0';
} else if (ch == '\b' || ch == 127) {
if (g_buffer_index > 0) {
g_buffer_index--;
} else if (is_printable) {
printf("%c", ch);
if (g_buffer_index < MAX_INPUT_LEN - 1) {
g_input_buffer[g_buffer_index++] = ch;
g_input_buffer[g_buffer_index] = '\0';
if (g_display_manager) {
g_display_manager->refresh(g_input_buffer, g_last_echo);
// Update OLED
if (g_display_manager) g_display_manager->refresh(g_input_buffer, g_last_echo);
// Update e-Paper ONLY if space (per user request)
if (ch == ' ') {
send_display_update(g_input_buffer, false);
}
}
} else if (g_buffer_index < MAX_INPUT_LEN - 1) {
g_input_buffer[g_buffer_index] = ch;
g_buffer_index++;
g_input_buffer[g_buffer_index] = '\0';
if (g_display_manager) {
g_display_manager->refresh(g_input_buffer, g_last_echo);
}
}
}
}