# micropython v1.28.0 — PWM on alif and stm32, new machine.CAN API, t-strings and weakref module - Product: micropython (https://whatsnew.fyi/product/micropython) - Vendor: micropython - Date: 2026-04-06 - Version: v1.28.0 - Original notes: https://github.com/micropython/micropython/releases/tag/v1.28.0 - Permalink: https://whatsnew.fyi/product/micropython/releases/v1.28.0 What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. --- - **added** — Add machine.PWM support to the stm32 port with freq(), duty_u16(), duty_ns() methods and output inversion - **added** — Add machine.PWM support to the alif port with freq(), duty_u16(), duty_ns() methods, invert keyword argument, and 11 independent timers with 22 PWM outputs - **added** — Add machine.CAN class with documentation, bindings, comprehensive tests, and implementation for the stm32 port - **added** — Add template strings (t-strings) as per PEP 750, with similar syntax to f-strings but keeping components separate within a Template object - **added** — Add support for nested f-strings within expressions within f-string literals - **added** — Add weakref module with weakref.ref and weakref.finalize classes for registering callbacks when objects are garbage collected - **added** — Add RISC-V 32-bit architecture flag zcmp for targets supporting compressed instructions, using Zcmp opcodes for function prologues and epilogues - **added** — Add support for configuring MicroPython to load native code from .mpy files without the native emitter enabled - **added** — Add inline Xtensa assembler support on windowed cores like the esp32 - **added** — Enable ROM filesystem support and VfsRom class on mimxrt, nrf, renesas-ra and samd ports - **added** — Add machine.Counter and machine.Encoder classes to the mimxrt port with min/max values, index, reset, match pins, cycle counting and IRQ callbacks - **added** — Add SPARKFUN_THINGPLUS_ESP32C5 and SEEED_XIAO_ESP32C6 boards to the esp32 port - **added** — Add PHYBOARD_RT1170 board to the mimxrt port - **changed** — Update alif port with alif_ensemble-cmsis-dfp library to v1.3.4 - **changed** — Add external flash sleep support to the alif port - **changed** — Improve deepsleep power saving modes in the alif port with wake-up from falling GPIO or RTC alarm - **changed** — Add new LDO driver to the esp32 port - **changed** — Enable Zcmp opcodes for ESP32-P4 SoCs in the esp32 port - **changed** — Improve os.dupterm() reading in the esp32 port, removing the need to call os.dupterm_notify() - **changed** — Update esp32 port to support ESP-IDF versions 5.3 and up to 5.5.1, dropping support for IDF below v5.3 - **changed** — Update mimxrt port nxp_driver SDK to MCUX_2.16.100 - **changed** — Add PSRAM support to the mimxrt port - **changed** — Add DP83867 PHY Ethernet support to the mimxrt port - **changed** — Increase RTC resolution in the mimxrt port from 1 second to 1/32768 seconds - **changed** — Update rp2 port pico-sdk to version 2.2.0 - **changed** — Switch all RNG sources in the rp2 port from ROSC to the pico_rand component - **changed** — Enable Zcmp opcodes for RP2350 in RV32 mode in the rp2 port This release of MicroPython sees `machine.PWM` support finally added to the stm32 port, as well as the alif port. This rounds out PWM support to all Tier 1 and Tier 2 microcontroller-based ports, making it easy to create and control PWM outputs in a consistent way. A new `machine.CAN` class that has been in development for a couple of years has now been finalised in this release, with added documentation, a common set of bindings, comprehensive tests, and an implementation for the stm32 port. This is a big step forward for a consistent way to use CAN across all of the ports, and implementations for other ports will follow soon. This release also sees the addition of template strings as per PEP 750 https://peps.python.org/pep-0750/. Template strings (or t-strings) are similar to f-strings, allowing expressions within the string literal. But unlike f-strings, t-strings do not concatenate the pieces of the literal, rather they remain as separate components within a `Template` object. MicroPython's t-strings match CPython almost exactly, except for a few minor differences (the a/ascii conversion specifier and space after a conversion specifier are not supported). Template strings are enabled at the "full feature" level, which includes the alif, mimxrt, samd (SAMD51 only) and webassembly (pyscript variant) ports. The t-string parsing code is an extension of the existing f-string parser, and in order to support nested t-string, f-strings now also support nested f-strings: f-strings within expressions within f-string literals. Another Python feature added in this release is the `weakref` module with `weakref.ref` and `weakref.finalize` classes. These classes allow registering a callback to be called when an object is reclaimed by the garbage collector. The semantics of this follow very closely the weakref semantics in CPython (except for the fact that MicroPython does not use reference counting). Due to the memory and garbage collector overhead, this module is currently only enabled on the webassembly pyscript variant, although it can be manually enabled on any port if needed. An outline of MicroPython's design values has been added to the main README. This aims to put into words some of the more intangible aspects of the project, in the hope that it will help strengthen and maintain those values moving forward. All MicroPython users and developers are encouraged to read these values, which can be found at https://github.com/micropython/micropython/blob/master/README.md#micropython-design-values In the native emitter component, the RISC-V 32-bit emitter has a new architecture flag "zcmp" which can be enabled for RV32 targets that support compressed instructions. When this flag is enabled, Zcmp opcodes are used for function prologues and epilogues. There have also been some optimisations to generated native code, as well as added support for inline Xtensa assembler on windowed cores (like the esp32). Furthermore, it's now possible to configure MicroPython (at build time) to be able to load native code from .mpy files without having the native emitter enabled. As usual, work has continued on the test suite, making it more robust to target failures, better able to skip tests that can't run on a target, and run consistently across a broader range of targets. All these things help maintain the high quality of the MicroPython code base. ROM filesystem support and the VfsRom class have been enabled on a few more ports, namely: mimxrt, nrf, renesas-ra and samd (both SAMD21 and SAMD51). The alif port sees the `alif_ensemble-cmsis-dfp` library updated to v1.3.4, support to put external flash to sleep, and improved support for deepsleep power saving modes, with wake-up from deepsleep via a falling GPIO or RTC alarm (the latter is available by the standard `timeout_ms` argument to `machine.deepsleep()`). As mentioned above, this port now has PWM support via the standard `machine.PWM` interface, and provi _[Truncated at 4000 characters — full notes: https://github.com/micropython/micropython/releases/tag/v1.28.0]_