CircuitPython display driver and LVGL integration for the Waveshare ESP32-S3 Touch AMOLED 2.41 board.
Based on official CircuitPython 10.1.3 with custom RM690B0 display driver and LVGL integration.
Complete CircuitPython support for the Waveshare ESP32-S3 Touch AMOLED 2.41 board featuring:
- Production-ready display driver (
rm690b0) with native text rendering - LVGL 8.x integration (
rm690b0_lvgl) with Python widget API - 7 built-in fonts (8×8 to 32×48 pixels)
- Hardware-accelerated graphics (DMA, JPEG decoder)
- 25+ example applications (games, demos, tests)
- Comprehensive documentation (6,700+ lines)
| Component | Specification |
|---|---|
| Board | Waveshare ESP32-S3 Touch AMOLED 2.41 |
| MCU | ESP32-S3 (Dual-core Xtensa LX7) |
| Flash | 16 MB |
| PSRAM | 8 MB |
| Display | RM690B0 AMOLED, 600×450 pixels |
| Interface | QSPI (80 MHz) |
| Touch | FT6336U I2C Capacitive Touch |
📁 docs/ - Complete Documentation
- RM690B0_DRIVER.md (1,668 lines) - Display driver API reference
- RM690B0_LVGL.md (3,234 lines) - LVGL integration guide
- TECHNICAL_NOTES.md (1,655 lines) - Architecture and troubleshooting
- project_status_summary.md - Current project status
- README.md - Documentation index
📁 examples/ - 25+ Ready-to-Run Examples
Display Driver Examples:
test_basic_gfx.py- Interactive graphics and fontstest_all_fonts.py- All 7 fonts showcasetest_animation.py- 60 FPS animationtest_sd_gfx.py- BMP/JPEG loading
LVGL Examples:
lvgl_test_gui.py- Complete widget demolvgl_test_symbols.py- LVGL symbols
Games:
game_flappy_bird.py- Flappy Bird clonegame_snake.py- Snake with joystick/touchgame_pacman.py- Pac-Man with ghost AIgame_sokoban.py- Puzzle gamegame_minesweeper.py- Minesweeper clonegame_robbo.py- Robbo puzzle platformer
Hardware Tests:
test_board_hardware.py- Complete validationtest_hw_nav_switch.py- I2C joysticktest_espnow.py- ESP-NOW validation
Benchmarks:
benchmark_gfx_conversion.py- Image conversion performancebenchmark_gfx_display.py- Primitive throughputbenchmark_simple_flush.py- DMA/flush stress test
See examples/README.md for complete documentation.
📁 fonts/ - TTF to Bitmap Converter
Convert any TrueType font to RM690B0 format:
ttf_to_rm690b0.py- Font convertertest_converted_font.py- Font validator- Complete documentation in fonts/README.md
📁 firmware/ - Pre-built Firmware
Two versions available:
firmware-rm690b0.bin- Stable (display driver only)firmware-rm690b0-lvgl.bin- Beta (with LVGL)
See firmware/README.md for flashing instructions.
📁 build/ - Build Scripts
build_waveshare.sh- Automated build scriptrequirements.txt- Python dependencies
-
Download firmware:
- Stable:
firmware/firmware-rm690b0.bin - Beta (LVGL):
firmware/firmware-rm690b0-lvgl.bin
- Stable:
-
Flash to board:
esptool.py --chip esp32s3 -p /dev/ttyACM0 \ --baud 921600 write_flash 0x0 firmware/firmware-rm690b0.bin
-
Deploy examples:
cp examples/test_all_fonts.py /media/CIRCUITPY/code.py
See firmware/README.md for detailed instructions.
-
Clone repository:
# Stable branch git clone https://github.com/ppsx/circuitpython.git -b rm690b0-standalone # Or LVGL branch git clone https://github.com/ppsx/circuitpython.git -b lvgl
-
Build:
cd circuitpython make -C ports/espressif BOARD=waveshare_esp32_s3_amoled_241 -
Flash:
make -C ports/espressif BOARD=waveshare_esp32_s3_amoled_241 flash
import rm690b0
# Initialize
display = rm690b0.RM690B0()
display.init_display()
# Draw graphics
display.fill_color(rm690b0.BLACK)
display.fill_circle(300, 225, 100, rm690b0.RED)
# Draw text
display.set_font(rm690b0.FONT_16x16)
display.text(50, 200, "Hello, World!", rm690b0.WHITE)
# Update display
display.swap_buffers()import time
import board
import busio
import rm690b0
import rm690b0_lvgl
# Initialize
display = rm690b0.RM690B0()
display.init_display()
lvgl = rm690b0_lvgl.RM690B0_LVGL()
lvgl.init_display()
i2c = busio.I2C(board.TP_SCL, board.TP_SDA, frequency=400000)
lvgl.init_touch(i2c)
# Create widgets
button = rm690b0_lvgl.Button(text="Click Me")
button.x = 200
button.y = 200
button.on_click = lambda btn: print("Clicked!")
# Main loop
while True:
lvgl.task_handler()
time.sleep(0.01)See docs/RM690B0_DRIVER.md and docs/RM690B0_LVGL.md for complete API documentation.
✅ Production Ready - Stable and optimized
✅ Native Text - 7 built-in fonts (8×8 to 32×48)
✅ Graphics - Lines, circles, rectangles, fills
✅ Images - BMP and JPEG with hardware decoder
✅ Double Buffering - Zero tearing animations
✅ Performance - 60+ FPS capable
✅ Rich Widgets - 20+ widget types
✅ TTF Fonts - Custom font support
✅ Touch Input - Automatic coordinate transformation
✅ Event System - Python callbacks
Available Widgets: Label, Button, Slider, Checkbox, Switch, Bar, Arc, Dropdown, Roller, Spinner, Container, Tabview, Table, Buttonmatrix, Textarea, Keyboard, Chart, Canvas, Image, Calendar, Msgbox, and more.
| Operation | Time | Notes |
|---|---|---|
| Full screen fill | ~25 ms | Hardware DMA limit |
| Circle (r=50) | ~2 ms | Optimized algorithm |
| Text (16×16) | ~1.2 ms | Native font rendering |
| JPEG decode | ~145 ms | Hardware decoder |
See docs/TECHNICAL_NOTES.md for detailed benchmarks.
- Waveshare ESP32-S3 Touch AMOLED 2.41 board
- USB-C cable (data-capable)
- SparkFun Qwiic Joystick (digital I2C)
- microSD card
- Additional I2C devices
| Function | GPIO | Device | I2C Address |
|---|---|---|---|
| Display QSPI | 9-14, 21, 16 | RM690B0 | - |
| Touch I2C | 47 (SDA), 48 (SCL) | FT6336U | 0x38 |
| RTC I2C | 47, 48 | PCF85063 | 0x51 |
| IMU I2C | 47, 48 | QMI8658C | 0x6B |
| IO Expander | 47, 48 | PCA9554 | 0x20 |
| SD Card SPI | 2, 4-6 | Optional | - |
See docs/TECHNICAL_NOTES.md#pin-configuration for complete details.
| Document | Description |
|---|---|
| RM690B0_DRIVER.md | Complete display driver API |
| RM690B0_LVGL.md | LVGL widgets and integration |
| TECHNICAL_NOTES.md | Architecture and troubleshooting |
| MIGRATION_GUIDE.md | v1.x -> v2.0 migration guide |
| TESTING_GUIDE.md | Hardware test procedure (P1-P4) |
| CHANGES.md | v2.0 release changelog |
| examples/README.md | All examples documentation |
| firmware/README.md | Flashing instructions |
| fonts/README.md | Font converter guide |
Repository: https://github.com/ppsx/circuitpython/tree/rm690b0-standalone
Status: Production Ready
Use for: Production applications, games, embedded displays
Repository: https://github.com/ppsx/circuitpython/tree/lvgl
Status: Functional with known GC/touch issue
Use for: Prototyping, rich UIs, widget-based interfaces
Phase 5: ✅ Complete
Phase 6: ✅ Complete (Final documentation package)
- rm690b0 driver - Stable and fast
- Native text system - 7 fonts + converter
- Graphics primitives - All optimized
- Image support - BMP/JPEG working
- Documentation - 6,700+ lines
- Examples - 25+ demos
- LVGL+touch freeze under heavy GC pressure
- Workaround: Avoid
gc.collect()in UI loop, load TTF fonts once at startup
See docs/project_status_summary.md for complete status.
Display shows nothing:
- Check
display.init_display()was called - Try
display.brightness = 1.0
Touch not working:
- Use
board.TP_SCLandboard.TP_SDA(notboard.SCL/SDA) - Initialize after display:
lvgl.init_touch(i2c)
LVGL touch freezes:
- Avoid
gc.collect()in main loop - Load TTF fonts once at startup
Memory errors:
- Use
swap_buffers(copy=False)for animations - Close files after reading
See docs/RM690B0_DRIVER.md#troubleshooting and docs/RM690B0_LVGL.md#troubleshooting for detailed solutions.
Contributions welcome! Please:
- Fork the appropriate branch
- Test on actual hardware
- Document changes
- Submit pull request
Areas for contribution: LVGL widgets, performance optimizations, bug fixes, documentation, examples.
MIT License
Based on CircuitPython 10.1.3 (MIT License)
Built-in fonts use Liberation fonts (SIL OFL 1.1)
See full license in source code.
Repositories:
- Main: https://github.com/ppsx/circuitpython/tree/rm690b0-standalone
- LVGL: https://github.com/ppsx/circuitpython/tree/lvgl
Hardware:
- Waveshare: https://www.waveshare.com/wiki/ESP32-S3-Touch-AMOLED-2.41
- ESP32-S3: https://www.espressif.com/
Documentation:
Developed by: Przemyslaw Patrick Socha and AI agents
Based on: CircuitPython 10.1.3, LVGL 8.x, ESP-IDF
Hardware: Waveshare ESP32-S3 Touch AMOLED 2.41
Enjoy building with RM690B0 on ESP32-S3! 🎉
A highly optimized port of Doom running natively on this board using ESP-IDF.
- Performance: 65 FPS (stable) at full 600x450 resolution.
- Optimizations: QSPI 80MHz, Double Buffered DMA, Internal RAM.
- Repo: https://github.com/ppsx/esp32-doom