This project implements a simple interactive shell environment for the Clockwork PicoCalc device, utilizing its ILI9488 display and keypad.
The goal is to create a basic terminal-like interface directly on the PicoCalc hardware. Users can type characters using the physical keypad, and the corresponding text appears on the display. This serves as a foundation for potentially more complex applications running directly on the device.
This firmware is designed specifically for the Clockwork PicoCalc Mainboard V2.0.
Key components utilized:
- CPU: Raspberry Pi Pico (RP2040)
- Display: ILI9488 TFT LCD (320x320, SPI Interface)
- Input: I2C-based keyboard controller on the PicoCalc
The PicoCalc uses a dual-MCU architecture:
- A dedicated keyboard controller handles the physical keyboard matrix scanning
- The Raspberry Pi Pico handles the display, application logic, and communicates with the keyboard controller over I2C
For detailed hardware specifications, pinouts, and schematics, please refer to the PICOCALC_SPECS.md
document in this repository.
After extensive reverse engineering and analysis, we successfully implemented communication with the PicoCalc's keyboard controller:
- The keyboard controller is accessible via I2C
- Communication parameters:
- I2C Bus: 1
- SDA Pin: 6
- SCL Pin: 7
- I2C Address: 0x1F
We've documented the keyboard controller's proprietary protocol:
- Command Byte: Send 0x09 to initiate a status read
- Status Word: Read 2 bytes from the controller
- For normal keys: High byte (MSB) is the event type, Low byte (LSB) is the key code
- For Enter key: Type is 0x0A, code is 0x01 or 0x03
- For Ctrl key: Special status words 0xA502 (press) and 0xA503 (release)
Special key codes are translated to appropriate characters/control codes:
- Function keys (F1-F10): 0x81-0x8A, 0x90
- Arrow keys: UP (0xB5), DOWN (0xB6), RIGHT (0xB7), LEFT (0xB4)
- Enter key: 0x01/0x03 with type 0x0A → translated to CR (13)
- Standard printable ASCII characters are passed through
- ✅ Initialization of the ILI9488 display
- ✅ Basic screen clearing and pixel writing
- ✅ Bitmap font rendering with all printable ASCII characters
- ✅ Keyboard interface with the I2C controller
- ✅ Working shell interface with character input and command processing
- ✅ Support for special keys (Enter, Backspace, etc.)
main.py
: Main application entry pointili9488.py
: Display driver for the ILI9488 TFT LCDfont.py
: Bitmap font definitions for all ASCII charactersgraphics.py
: Graphics drawing functionskeyboard.py
: I2C-based keyboard interface modulei2c_scanner.py
: Utility for general I2C device detection
- Install MicroPython: Flash the latest stable MicroPython firmware for the Raspberry Pi Pico onto your PicoCalc. You can find the firmware and instructions on the Raspberry Pi documentation site. Remember to put the Pico into BOOTSEL mode (hold SW1 while plugging in USB).
- Copy Files: Connect to the Pico's REPL (e.g., using Thonny IDE). Copy all the required
.py
files to the root directory of the Pico's filesystem. - Reset: Reset the Pico (either physically or via CTRL+D in the REPL). The
main.py
script should run automatically.
Once the firmware is running:
- The display will initialize and show a prompt (e.g.,
>
). - Press keys on the physical keypad. The corresponding characters should appear on the screen.
- Use Backspace for text deletion and Enter to execute "commands".
- The shell supports all alphanumeric keys and special characters.
- Basic Display Initialization
- Refactor display logic into
ili9488.py
- Implement bitmap font (
font.py
) and character drawing (graphics.py
) - Implement proper communication with the keyboard controller via I2C
- Integrate components into
main.py
to create the interactive shell loop - Add basic scrolling or line wrapping
- Specification:
- The display supports 40 characters per line and 40 lines.
- When text input reaches the 41st character on a line, the cursor should automatically wrap to the beginning of the next line.
- When text input reaches the 41st line (i.e., attempting to draw on the line after the last visible line), the entire screen content should scroll up by one line height.
- The oldest line at the top will be discarded.
- The new line of text will appear on the newly cleared bottom line.
- Backspace should correctly handle moving the cursor up to the end of the previous line if deleting the first character of a wrapped line.
- Specification:
- Implement command processing functions
Feel free to submit issues or pull requests if you have suggestions or improvements.
Our development process involved significant reverse engineering of the PicoCalc hardware:
-
Initial Approach: We first attempted direct GPIO matrix scanning, assuming the keyboard was directly connected to the Pico.
-
Discovery: Using I2C scanning tools, we identified a keyboard controller at address 0x1F on the I2C1 bus (SDA=GP6, SCL=GP7).
-
Protocol Analysis: Through testing and debugging, we discovered:
- Special command byte (0x09) initiates status reads
- 2-byte status words encode key type and value
- Special handling for Enter key (which sends two different codes)
- Different byte order interpretation for normal keys vs. Enter key
-
Implementation: We built a robust keyboard driver that handles all key types, special key codes, and properly debounces input.
This work has resulted in a fully functional keyboard interface that accurately translates physical key presses to on-screen characters with proper handling of special keys.
This project was developed with Cursor, an AI-powered code editor.