Skip to content

Releases

v0.1.6

Choose a tag to compare

@nuraci nuraci released this 11 Nov 03:59

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.SPI reads 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 with cmd 31: timeout after 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:614 and 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. See docs/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 (see docs/stm32h743.md).
  • RP2350-Touch-LCD-4: machine.bootloader() (or hold BOOT and press RESET), then copy the .uf2 to 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_flash first (it erases everything on the board).

Good to know

  • FAT file names that are not UTF-8 (written by some PCs) make os.listdir() with str paths raise UnicodeError; with bytes paths (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

Choose a tag to compare

@nuraci nuraci released this 10 Nov 14:10

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: then dfu-util as 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 with vi and edit; 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. See docs/flash-dfu.md.
  • Other STM32 boards: scripts/stm32_uart_flash.py flash <file>.hex --verify, through the ST bootloader on UART1 (see docs/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_flash first (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

Choose a tag to compare

@nuraci nuraci released this 06 Nov 08:11

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 as main.py to start at power-on.
  • SD card: machine.SDCard works after import display_driver. weather.py saves 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.bin

Without 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

Choose a tag to compare

@nuraci nuraci released this 06 Nov 06:33

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
  • audio no longer loses its I2S callback. audio.stalls is 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.bin

Without 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

Choose a tag to compare

@nuraci nuraci released this 06 Nov 04:52

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.
  • buzzer plays 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 audio or buzzer on 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.bin

Without 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

Choose a tag to compare

@nuraci nuraci released this 05 Nov 15:25

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.bin

Without 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

Choose a tag to compare

@nuraci nuraci released this 05 Nov 14:08

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 (see docs/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. See docs/flash-dfu.md.
  • ESP32-4848S040: esptool.py --chip esp32s3 -p <port> erase_flash, then esptool.py --chip esp32s3 -p <port> -b 460800 write_flash 0x0 <file>.bin. erase_flash erases 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 .uf2 to 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_cb can hang the board on Ctrl-C; display_driver is 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.