3.2 KiB
3.2 KiB
Display Refresh Mechanism
This document explains the dual-core architecture used to handle USB keyboard input and e-Paper display updates efficiently on the Raspberry Pi Pico.
Architecture Overview
The system utilizes both cores of the RP2040 to ensure that the slow refresh rate of the e-Paper display does not block or lag the USB keyboard input.
Core 0: Input Handling (Producer)
- Role: Handles USB Host tasks, processes keyboard reports, and manages the text buffer.
- Behavior:
- Receives key presses via TinyUSB callbacks.
- Updates the local text buffer (
g_entry_list). - Triggers a display update via
send_display_update().
- Non-Blocking Transmission:
- When an update is needed, Core 0 allocates a
DisplayMessageon the heap. - It attempts to push the message pointer to the Multicore FIFO.
- Critical Optimization: It uses
multicore_fifo_wready()to check if the FIFO has space.- If Ready: Pushes the message.
- If Full: Immediately frees the message and skips the update. This ensures Core 0 never waits for Core 1, keeping typing responsive.
- When an update is needed, Core 0 allocates a
Core 1: Display Driver (Consumer)
- Role: Manages the e-Paper hardware and performs the actual drawing operations.
- Behavior:
- Initializes the e-Paper display.
- Waits for messages in the Multicore FIFO.
- Smart Refresh (Accumulation):
- When Core 1 wakes up to process a message, it first checks if more messages have arrived while it was sleeping or busy.
- FIFO Draining: It loops through the FIFO, popping and freeing all intermediate messages, keeping only the latest one.
- This ensures that if the user types "Hello World" quickly, Core 1 might skip rendering "Hello " and jump straight to rendering "Hello World", preventing a queue of obsolete updates from slowing down the display.
Data Flow Diagram
sequenceDiagram
participant User
participant Core0 as Core 0 (USB/Input)
participant FIFO as Multicore FIFO
participant Core1 as Core 1 (Display)
User->>Core0: Types 'A'
Core0->>FIFO: Push Msg('A')
User->>Core0: Types 'B'
Core0->>FIFO: Push Msg('AB')
Note over Core1: Busy refreshing...
User->>Core0: Types 'C'
alt FIFO is Full
Core0->>Core0: Drop Msg('ABC') (Free memory)
else FIFO has space
Core0->>FIFO: Push Msg('ABC')
end
Core1->>FIFO: Pop Msg('A')
Note over Core1: Checks FIFO for newer msgs
FIFO->>Core1: Msg('AB') exists
Core1->>Core1: Free Msg('A'), use Msg('AB')
FIFO->>Core1: Msg('ABC') exists
Core1->>Core1: Free Msg('AB'), use Msg('ABC')
Core1->>Display: Render('ABC')
Key Functions
send_display_update(const char *entry, bool finish_line):- Allocates memory.
- Checks FIFO status.
- Pushes or drops message.
core1_display_init():- Main loop for Core 1.
- Drains FIFO to find the latest message.
- Calls e-Paper drawing functions.
Memory Management
- Messages are
malloc'd by Core 0. - Messages are
free'd by Core 1 (after processing or dropping). - If Core 0 drops a message because the FIFO is full, it
frees it immediately.