smooth refresh with aggregated changes
This commit is contained in:
113
hello_usb.cpp
113
hello_usb.cpp
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user