Repository navigation
Releases
v0.1.6
Every board now runs on omnipython-lvgl 665dec5, the RP2350 included, and every board has been tested on hardware with this firmware.
| Board | File | State |
|---|---|---|
| STM32H7_CORE V1.0 + IPS 1024x600 | STM32H7_CORE-V10-v0.1.6.dfu, .hex |
tested on hardware: board checks, SD card, perf; on c34fbee: 15 min soak, touch |
| STM32H7_CORE V1.3 + IPS 1024x600 | STM32H7_CORE-V13-v0.1.6.dfu, .hex |
tested on hardware: board checks, SD card, perf; on c34fbee: 15 min soak, touch 5/5, the 10 examples |
| DEV190806042 + IPS 1024x600 | DEV190806042-v0.1.6.dfu, .hex |
tested on hardware: board checks, perf; on c34fbee: 15 min soak, touch 5/5, the 10 examples |
| FK743M5-XIH6 + IPS 1024x600 | FK743M5-XIH6-v0.1.6.dfu, .hex |
tested on hardware: board checks, SD card, perf; on c34fbee: 15 min soak, touch 5/5, the 10 examples |
| Waveshare RP2350-Touch-LCD-4 | WAVESHARE_RP2350_TOUCH_LCD_4-v0.1.6.uf2 |
tested on hardware: tile CRCs, panel, perf; on c34fbee: 1 h soak, touch, the 10 examples |
| ESP32-4848S040 | ESP32_4848S040-v0.1.6.bin |
tested on hardware: panel, perf; on c34fbee: pools, 15 min soak, the 10 examples |
The checks before "on c34fbee" ran on these very files (2026-11-11). The rest ran the day before on the same sources with omnipython-lvgl c34fbee; the only change since is its #19, the LVGL assert handler, which every board was re-checked for.
What changes
- SD card on the STM32H743 boards. It never worked: the SDMMC kernel clock was 480 MHz, so the card got 960 kHz at init and 120 MHz in transfers. Now 240 kHz and 30 MHz. Tested on the V1.0 (SDMMC2), V1.3 and FK743M5-XIH6 (SDMMC1): mounted at boot as
/sd, reads of 8.7-12.5 MB/s. SPI1-3 share that clock;machine.SPIreads the real frequency. - UART flasher (
scripts/stm32_uart_flash.py) fixed for images over 1 MB, which every STM32 image since v0.1.5 is: the script of v0.1.5 stops withcmd 31: timeoutafter erasing the second flash bank. Use the script of this release. - The RP2350 moves to omnipython-lvgl from the archived lvgl-micropython, with LVGL's memory pools: a redraw costs the same whatever the state of the heap (26.5 ms with two buffers, against up to 43.8 ms without), for about 26 KB of heap. Same image as before (tile CRCs), 1 h soak at 57.7 fps.
- omnipython-lvgl 665dec5: an LVGL assert raises
RuntimeError: LVGL assert failed at lv_display.c:614and LVGL keeps running; images 46-50 KB smaller than v0.1.5. - ESP32-4848S040: 64 KB more free heap than v0.1.5. With code run from PSRAM, ESP-IDF keeps whole 64 KB pages of PSRAM for the code and the constants; v0.1.5's constants crossed into one more page (not 128 KB as the v0.1.5 notes said, and the cause is now known). 665dec5 brings them back.
Flashing
- STM32 boards over USB:
dfu-util -a 0 -d 0483:df11 -D <board>-v0.1.6.dfu, with the board in DFU mode:machine.bootloader()from v0.1.5 on, or BOOT0 held while pressing RESET. Seedocs/flash-dfu.md. - STM32 boards over UART1:
scripts/stm32_uart_flash.py flash <board>-v0.1.6.hex --verify, with the script of this release (seedocs/stm32h743.md). - RP2350-Touch-LCD-4:
machine.bootloader()(or hold BOOT and press RESET), then copy the.uf2to the RP2350 drive. - ESP32-4848S040, from v0.1.0 or later, keeping your files:
esptool.py --chip esp32s3 -p <port> -b 460800 write_flash 0x0 ESP32_4848S040-v0.1.6.bin. From other firmware,erase_flashfirst (it erases everything on the board).
Good to know
- FAT file names that are not UTF-8 (written by some PCs) make
os.listdir()withstrpaths raiseUnicodeError; withbytespaths (os.listdir(b"/sd")) they list fine. That is MicroPython's FAT driver.
Sources: MicroPython 1.29.0, omnipython-lvgl 665dec5, ESP-IDF 5.5.2. Measurements and logs: docs/stm32h743.md, docs/rp2350-touch-lcd4.md, docs/esp32-4848s040.md, docs/log/. Checksums: SHA256SUMS.
v0.1.5
All boards except the RP2350 move to omnipython-lvgl c34fbee, the successor of the archived lvgl-micropython, with LVGL's memory in TLSF pools. The RP2350 is unchanged: use v0.1.0.
| Board | File | State |
|---|---|---|
| STM32H7_CORE V1.0 + IPS 1024x600 | STM32H7_CORE-V10-v0.1.5.dfu, .hex |
tested on hardware: this firmware (board checks, soft resets, the 10 examples); these sources: 15 min soak, touch |
| ESP32-4848S040 | ESP32_4848S040-v0.1.5.bin |
tested on hardware: this firmware (the 10 examples, the shell); these sources: pools, 15 min soak |
| STM32H7_CORE V1.3 | STM32H7_CORE-V13-v0.1.5.hex |
builds; same code as the V1.0, not run on this binding yet |
| DEV190806042 | DEV190806042-v0.1.5.hex |
builds, never run on a board: use at your own risk |
| FK743M5-XIH6 | FK743M5-XIH6-v0.1.5.hex |
builds, never run on a board: use at your own risk |
What changes
- LVGL no longer slows down with a fragmented heap. Without the pools, LVGL's allocations walk MicroPython's heap from its first free block: with one free block below an application's data, a full redraw took 360 ms instead of 69 on the STM32H7_CORE (28 MB heap), 86 instead of 51 with a 490 KB heap, 470 instead of 71 on the ESP32. With the pools it stays at the fresh-heap time. They cost about 25 KB of heap and 1.5-4 ms per
gc.collect(). machine.bootloader()enters USB DFU on the STM32H743 boards, no buttons: thendfu-utilas usual. It used to reset into MicroPython: the port jumped to 0x1ff00000, which reads as zeros on the H743, instead of the ROM bootloader at 0x1ff09800. Tested on the STM32H7_CORE V1.0.- Touch on the STM32 boards within the GT911's 400 kHz: the bus ran at 1.07 MHz on the STM32H7_CORE V1.0 and 500 kHz over SoftI2C. The rare touch read errors (about 1 in 30 000 to 150 000) were only seen above the rating; a read with no touch now takes 241 us instead of 80.
- Examples:
examples/shell, a shell for an ANSI terminal withviandedit; Ctrl-C on an empty line leaves it.
Good to know
- ESP32-4848S040: about 128 KB less free heap than v0.1.4 (4.61 MB after
import display_driver), with or without the pools. The cause is not known yet.
Flashing
- STM32H7_CORE V1.0:
dfu-util -a 0 -d 0483:df11 -D STM32H7_CORE-V10-v0.1.5.dfu, with the board in DFU mode:machine.bootloader()from v0.1.5 on, or BOOT0 held while pressing RESET. Seedocs/flash-dfu.md. - Other STM32 boards:
scripts/stm32_uart_flash.py flash <file>.hex --verify, through the ST bootloader on UART1 (seedocs/stm32h743.md). - ESP32-4848S040, from v0.1.0 or later, keeping your files:
esptool.py --chip esp32s3 -p <port> -b 460800 write_flash 0x0 ESP32_4848S040-v0.1.5.bin. From other firmware,erase_flashfirst (it erases everything on the board).
Sources: MicroPython 1.29.0, omnipython-lvgl c34fbee (STM32 and ESP32), ESP-IDF 5.5.2. Measurements and logs: docs/stm32h743.md, docs/esp32-4848s040.md, docs/log/. Checksums: SHA256SUMS.
v0.1.4
ESP32-4848S040 only: adjustable brightness, and a weather station. The other boards are unchanged: use v0.1.0.
- Brightness:
display_driver.backlight(percent)is now PWM on GPIO 38, no longer on/off. The display starts at 70%. Below about 30% the panel can no longer be read. weather.py: current weather, wind and 5 days of forecast from Open-Meteo (no key, free for non-commercial use), with icons drawn by LVGL. Setup on the touchscreen: WiFi, place, style, brightness, and dimming at night between two times you choose. Copy it to the board, or save it asmain.pyto start at power-on.- SD card:
machine.SDCardworks afterimport display_driver.weather.pysaves its settings there, or in the internal flash without a card.
import machine, os, display_driver
os.mount(machine.SDCard(slot=2, sck=48, miso=41, mosi=47, cs=42, freq=10_000_000), "/sd")Good to know: weather.py keeps the WiFi password in clear in its settings file, and uses plain HTTP. The fonts have no accented letters, so "Forlì" shows as "Forli".
Tested on hardware: brightness by eye and after soft resets, t05_perf.py, t07_audio.py, weather.py by hand with an SD card.
Flash, on a board that had other firmware (this erases everything on it, your files too):
esptool.py --chip esp32s3 -p <port> erase_flash
esptool.py --chip esp32s3 -p <port> -b 460800 write_flash 0x0 ESP32_4848S040-v0.1.4.binWithout erase_flash the board can stop at boot with "The filesystem appears to be corrupted". To update a board already on v0.1.0 or later and keep its files, skip erase_flash.
v0.1.3
ESP32-4848S040 only: smoother LVGL, and two bugs fixed. The other boards are unchanged: use v0.1.0.
The periodic display timer kept MicroPython's schedule queue full during time.sleep_ms(), and anything else scheduled was dropped with no error. It is now a one-shot timer, armed again after each lv.timer_handler().
| Measure | v0.1.2 | v0.1.3 |
|---|---|---|
| 15 min soak, LVGL redraws per second | 39.1 | 47.6 |
| Longest animation gap during a download | up to 1015 ms | up to 215 ms |
| Sounds that never ended, during long sleeps | 20 of 24 | 0 of 24 |
audiono longer loses its I2S callback.audio.stallsis gone: it counted those losses.- In an application with a UI, read sockets non-blocking: LVGL stays at 50-54 redraws per second during a download, against 13-48 with a blocking read, which can wait 100 ms at a time without running the scheduler.
Known issues: gaps of 100-200 ms remain during downloads, and download speed varies from 0.35 to 6 Mbit/s between runs, cause not found. HTTPS not tested.
Not on boards with the relays fitted: audio and buzzer use the relay pins (GPIO 1, 2, 40).
Tested on hardware: t05_perf.py, t06_wifi.py, t07_audio.py, 4 runs with soft resets. The 15 min soak ran with the same code loaded as files, before the build.
Flash, on a board that had other firmware (this erases everything on it, your files too):
esptool.py --chip esp32s3 -p <port> erase_flash
esptool.py --chip esp32s3 -p <port> -b 460800 write_flash 0x0 ESP32_4848S040-v0.1.3.binWithout erase_flash the board can stop at boot with "The filesystem appears to be corrupted". To update a board already on v0.1.0, v0.1.1 or v0.1.2 and keep its files, skip erase_flash.
v0.1.2
ESP32-4848S040 only: sound on the speaker. The other boards are unchanged: use v0.1.0.
audio: beeps, tones and WAV files (PCM, 16 bit, mono or stereo) in the background, with no measurable effect on the animation.buzzerplays through it, so Breakout, Pong, Snake and Simon now have sound on this board.- The speaker is on GPIO 1, 2 and 40, which are also the relay pins. Do not use
audioorbuzzeron a board with the relays fitted.
import audio
audio.beep()
audio.play("/sound.wav")A sound comes out about 150 ms after the call. A stereo file plays one channel only.
WiFi was already in the firmware and is now measured with LVGL animating: connection, reconnection and HTTP work. Known issue: during a TCP download the animation can stop for about 1 s and drop to 11 redraws per second, at 1 to 6 Mbit/s, cause not found yet. HTTPS not tested.
Tested on hardware: sound by ear, t07_audio.py, t06_wifi.py, Breakout with sound.
Flash, on a board that had other firmware (this erases everything on it, your files too):
esptool.py --chip esp32s3 -p <port> erase_flash
esptool.py --chip esp32s3 -p <port> -b 460800 write_flash 0x0 ESP32_4848S040-v0.1.2.binWithout erase_flash the board can stop at boot with "The filesystem appears to be corrupted". To update a board already on v0.1.0 or v0.1.1 and keep its files, skip erase_flash.
v0.1.1
ESP32-4848S040 only: full-screen redraws about 1.6 times faster. The other boards are unchanged: use v0.1.0.
| Measure | v0.1.0 | v0.1.1 |
|---|---|---|
| Full redraw, 48 buttons, back to back | 155 ms | 95 ms |
| Small label change | 5 ms | 2.9 ms |
gc.collect() |
190 ms | 120 ms |
Bigger caches (16 KB less internal RAM, 131 KB in the largest block), and the panel's interrupt moved off MicroPython's core. Tested on hardware: panel, touch, 3 soft resets, a WiFi scan, 15 min soak with no errors.
Flash, on a board that had other firmware (this erases everything on it, your files too):
esptool.py --chip esp32s3 -p <port> erase_flash
esptool.py --chip esp32s3 -p <port> -b 460800 write_flash 0x0 ESP32_4848S040-v0.1.1.binWithout erase_flash the board can stop at boot with "The filesystem appears to be corrupted". To update a board already on this firmware and keep its files, skip erase_flash.
v0.1.0
First release: MicroPython 1.29 and LVGL 9.5 firmware for boards that upstream MicroPython does not cover. import display_driver is all an application needs, and the examples fit any resolution.
| Board | File | State |
|---|---|---|
| STM32H7_CORE V1.3 + IPS 1024x600 | STM32H7_CORE-V13-v0.1.0.hex |
tested on hardware: this firmware, 58 fps, soak on the previous firmware |
| ESP32-4848S040 | ESP32_4848S040-v0.1.0.bin |
tested on hardware: 42 fps, 15 min soak |
| Waveshare RP2350-Touch-LCD-4 | WAVESHARE_RP2350_TOUCH_LCD_4-v0.1.0.uf2 |
tested on hardware: this firmware, 57.8 fps, works at 240x240 (no PSRAM) |
| STM32H7_CORE V1.0 | STM32H7_CORE-V10-v0.1.0.dfu, .hex |
tested on hardware: this firmware, 58 fps, 15 min soak |
| DEV190806042 | DEV190806042-v0.1.0.hex |
builds, never run on a board: use at your own risk |
| FK743M5-XIH6 | FK743M5-XIH6-v0.1.0.hex |
builds, never run on a board: use at your own risk |
Flashing
- STM32:
scripts/stm32_uart_flash.py flash <file>.hex --verify, through the ST bootloader on UART1 with DTR on BOOT0 and RTS on NRST (seedocs/stm32h743.md). It is the only method tested on the other STM32 boards. - STM32H7_CORE V1.0:
dfu-util -a 0 -d 0483:df11 -D STM32H7_CORE-V10-v0.1.0.dfu, with the board in DFU mode: hold BOOT0 and press RESET, then press RESET again after writing. Seedocs/flash-dfu.md. - ESP32-4848S040:
esptool.py --chip esp32s3 -p <port> erase_flash, thenesptool.py --chip esp32s3 -p <port> -b 460800 write_flash 0x0 <file>.bin.erase_flasherases everything on the board; without it, a board that had other firmware can stop at boot with "The filesystem appears to be corrupted". The native USB is off: use the board's USB-UART. - RP2350: hold BOOTSEL while connecting, copy the
.uf2to the drive.
Known limits
- ESP32-4848S040: a full-screen redraw takes about 155 ms, and
gc.collect()190 ms, a visible pause in animations. - A Python
flush_cbcan hang the board on Ctrl-C;display_driveris not affected, its flush is in C. - Running out of memory while LVGL renders hangs the board: there is no way to catch it. Mainly a risk on the RP2350 (no PSRAM).
- Backlight is on/off on the STM32 and ESP32 boards.
Sources: MicroPython 1.29.0, ESP-IDF 5.5.2. STM32 and RP2350 on lvgl-micropython 3e287e7 with patches/; ESP32 on omnipython-lvgl 92f8c0a. Details: docs/. Checksums: SHA256SUMS.