smooth refresh with aggregated changes
This commit is contained in:
103
hello_usb.cpp
103
hello_usb.cpp
@@ -108,8 +108,10 @@ void init_epaper_display() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an entry to the display list and send update to core 1
|
* 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
|
if (!g_display_ready) return; // Don't send if display isn't ready
|
||||||
|
|
||||||
// Check if list is at capacity
|
// Check if list is at capacity
|
||||||
@@ -120,10 +122,9 @@ void send_display_update(const char *entry) {
|
|||||||
g_force_full_refresh = true;
|
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);
|
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.entries[g_entry_list.count][ENTRY_LENGTH - 1] = '\0';
|
||||||
g_entry_list.count++;
|
|
||||||
|
|
||||||
// Allocate message structure
|
// Allocate message structure
|
||||||
DisplayMessage *msg = (DisplayMessage *)malloc(sizeof(DisplayMessage));
|
DisplayMessage *msg = (DisplayMessage *)malloc(sizeof(DisplayMessage));
|
||||||
@@ -134,6 +135,8 @@ void send_display_update(const char *entry) {
|
|||||||
|
|
||||||
// Copy entry list to message
|
// Copy entry list to message
|
||||||
msg->entries = g_entry_list;
|
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
|
// Decide whether to use partial or full refresh
|
||||||
msg->use_partial = !g_force_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->xend = 800; // Full width
|
||||||
msg->yend = 480; // Full height from header onwards
|
msg->yend = 480; // Full height from header onwards
|
||||||
|
|
||||||
// Send message pointer to core 1
|
// Send message pointer to core 1 if FIFO has space
|
||||||
|
if (multicore_fifo_wready()) {
|
||||||
multicore_fifo_push_blocking((uint32_t)msg);
|
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
|
// If finishing the line, increment count for next time
|
||||||
multicore_fifo_pop_blocking();
|
if (finish_line) {
|
||||||
|
g_entry_list.count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,6 +186,14 @@ void core1_display_init() {
|
|||||||
uint32_t msg_addr = multicore_fifo_pop_blocking();
|
uint32_t msg_addr = multicore_fifo_pop_blocking();
|
||||||
DisplayMessage *msg = (DisplayMessage *)msg_addr;
|
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);
|
printf("[Core 1] Updating display with %d entries\n", msg->entries.count);
|
||||||
|
|
||||||
// Update the e-Paper display
|
// Update the e-Paper display
|
||||||
@@ -199,8 +217,8 @@ void core1_display_init() {
|
|||||||
|
|
||||||
// Draw all entries starting below header
|
// Draw all entries starting below header
|
||||||
UWORD y_pos = 0;
|
UWORD y_pos = 0;
|
||||||
// paint only the last 3 entries
|
// paint only the last 10 entries
|
||||||
int start_index = msg->entries.count > 2 ? msg->entries.count - 2 : 0;
|
int start_index = msg->entries.count > 10 ? msg->entries.count - 10 : 0;
|
||||||
for (int i = start_index; i < msg->entries.count; i++) {
|
for (int i = start_index; i < msg->entries.count; i++) {
|
||||||
if (y_pos + 25 < 480) { //Don't draw beyond screen
|
if (y_pos + 25 < 480) { //Don't draw beyond screen
|
||||||
Paint_DrawString_EN(20, i*25, msg->entries.entries[i], &Font16, WHITE, BLACK);
|
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 the message (it was allocated by core 0)
|
||||||
free(msg);
|
free(msg);
|
||||||
|
|
||||||
// Signal back to core 0 that update is complete
|
|
||||||
multicore_fifo_push_blocking(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep_ms(10);
|
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];
|
uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0];
|
||||||
|
|
||||||
if (ch) {
|
if (ch) {
|
||||||
printf("%c", ch);
|
bool is_enter = (ch == '\r' || ch == '\n');
|
||||||
|
bool is_backspace = (ch == '\b' || ch == 127);
|
||||||
|
bool is_printable = !is_enter && !is_backspace; // Includes space
|
||||||
|
|
||||||
if (ch == '\r' || ch == '\n') {
|
if (is_backspace) {
|
||||||
printf("\n");
|
if (g_buffer_index > 0) {
|
||||||
// Process command
|
printf("\b \b");
|
||||||
|
g_buffer_index--;
|
||||||
g_input_buffer[g_buffer_index] = '\0';
|
g_input_buffer[g_buffer_index] = '\0';
|
||||||
|
|
||||||
// Echo logic
|
// Update OLED
|
||||||
echo_and_reset(g_input_buffer, &g_buffer_index);
|
if (g_display_manager) g_display_manager->refresh(g_input_buffer, g_last_echo);
|
||||||
|
|
||||||
// Save last echoed (all caps) for display
|
// Update e-Paper (in-place)
|
||||||
size_t k = 0;
|
send_display_update(g_input_buffer, false);
|
||||||
for (; g_input_buffer[k] != '\0' && k < sizeof(g_last_echo) - 1; ++k) {
|
|
||||||
g_last_echo[k] = g_input_buffer[k];
|
|
||||||
}
|
}
|
||||||
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) {
|
if (g_display_manager) {
|
||||||
g_display_manager->set_last_echo(g_last_echo);
|
g_display_manager->set_last_echo(g_last_echo);
|
||||||
g_display_manager->refresh("", g_last_echo);
|
g_display_manager->refresh("", g_last_echo);
|
||||||
}
|
}
|
||||||
send_display_update(g_last_echo);
|
} else if (is_printable) {
|
||||||
|
printf("%c", ch);
|
||||||
// Reset buffer
|
if (g_buffer_index < MAX_INPUT_LEN - 1) {
|
||||||
g_buffer_index = 0;
|
g_input_buffer[g_buffer_index++] = ch;
|
||||||
g_input_buffer[0] = '\0';
|
|
||||||
|
|
||||||
} else if (ch == '\b' || ch == 127) {
|
|
||||||
if (g_buffer_index > 0) {
|
|
||||||
g_buffer_index--;
|
|
||||||
g_input_buffer[g_buffer_index] = '\0';
|
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