Changelog#
v0.1 — First Public Alpha#
Language#
try / except / raise / finally— AVR targets via avr-libcsetjmp/longjmp; single nesting level per function; exception codes imported frompymcu.exceptionsValueError,TypeError,IndexError,KeyError,NotImplementedErrorare now builtins — no import required, identical to CPython;pymcu.exceptionsstill exports the codes for IDE support and explicit imports from library codeCompileErrorintrinsic —raise CompileError("msg")aborts compilation with aCompileError:diagnostic; never generates runtime code; used in HAL modules for unsupported arch/chip guards; cannot be caught bytry/exceptNotImplementedErroradded topymcu.exceptions(code 5)
Compiler#
HAL ZCA configuration parameters typed as
const—Pin(name, mode)now requiresmode: const[uint8];if mode == 2:branches fold at compile time; open-drain mode on unsupported targets aborts withCompileError: Open-drain mode not supported on AVRArchitectureErrorC# class — mapsraise CompileError(...)in Python source to a compiler diagnostic withTypeName = "CompileError"; emitted by all HAL modules for unsupported arch/chip combinations
AVR backend#
Unhandled exception UART output — when a
raisereaches__pymcu_unhandled_exnwith no activeexcepthandler, the runtime prints"E:<TypeName>\r\n"to UART0 (if initialized) then halts withcli; rjmp .-2; only exception types actually raised in the program have their name strings emitted in flash; no overhead when noraiseis present in the program; chips without standard UART0 (attiny85 etc.) emit only the halt loop
RP2040 / ARM backend (new, alpha)#
New
pymcu-armpackage adds therp2040target (Raspberry Pi Pico) — lowers PyMCU’s target-agnostic IR to LLVM IR (thumbv6m-none-eabi, Cortex-M0+) and drives an LLVM toolchain (opt→llc→ld.lld→llvm-objcopy) to a flat flash image (dist/firmware.bin, generic crc32 boot2 at offset 0)Supported HAL on RP2040:
pymcu.hal.gpio.Pin(single-cycle IO) andpymcu.hal.uart.UART(PL011) on core 0;delay_ms/delay_usvia the hardware microsecond TIMERMicroPython (
machine.Pin/machine.UART) and CircuitPython (board,digitalio,busio) shims compile unmodified to RP2040 firmwareLLVM tools resolved from the
pymcu-arm-toolchainwheel or a system LLVMNot yet on this backend: GC
list[T], exceptions, soft-float, dual-core,@extern, and every peripheral beyond GPIO/UART0 (SPI, I2C, PWM, ADC, PIO, USB, timers, EEPROM, watchdog)Firmware images are validated headlessly by the RP2040Sharp emulator (
PicoSimulation.LoadFlash) in CI
HAL#
pymcu.hal.spi,pymcu.hal.eeprom,pymcu.hal.watchdog,pymcu.hal.power— all unsupported arch/chip fallbacks now raiseCompileError(replaces silentreturn 0/ missing defaults); allmatch __CHIP__blocks havecase _:guards
Language (core)#
if / elif / else,while,for,match / case,def,class,return,pass,global,with,assert,raisefor i in range(n),for x in array,for i, x in enumerate(iterable),for x, y in zip(a, b)Fixed-size arrays
arr: uint8[N], constant and variable indexing, slice indexingTuple literals, tuple unpacking, multi-return functions
match / caseOR patterns, guardif cond, sequence patterns, capture patterns@property/@name.setter, single-level ZCA class inheritance,super(),class Foo(Enum)with obj:/with a as x, b as y:,lambda x: expr(no capture),nonlocalin@inlinein/not in,is/is not,divmod,bitcast,hex,bin,sum,any,allbytesliteralb"\x00",bytearray,int.from_bytesRaw strings
r"\n",str(n)compile-time,pow/**Extended unpacking
first, *rest = tup, nested list comprehensions,iffilter in comprehensions__name__guard (if __name__ == "__main__":)Dunder operator overloading (
__add__,__sub__, comparisons, bitwise,__len__, etc.)@extern("symbol")— external C symbol interop with AVR ABI
MCU extensions#
uint8 / int8 / uint16 / int16 / uint32 / int32typed annotations (required)intbuilt-in maps toint16ptr[T]/const[T],asm("instr"),@inline,@interrupt(vector)delay_ms(n)/delay_us(n),millis()/micros()__CHIP__/__FREQ__compile-time constants
HAL (ATmega328P)#
pymcu.hal.gpio—Pin: high/low/toggle/value/irq/pulse_inpymcu.hal.uart—UART: write/read/read_line/write_str/println/print_byte/available + RX interruptpymcu.hal.adc—AnalogPin: poll + interrupt;adc_read_temp_raw()internal sensorpymcu.hal.timer—Timer(n, prescaler), Timer0/1/2, CTC modepymcu.hal.pwm—PWM: start/stop/set_duty/set_freqpymcu.hal.spi—SPI+SoftSPIpymcu.hal.i2c—I2C+SoftI2C,write_to/read_from/write_bytes/writeto_mem/readfrom_mem_intopymcu.hal.eeprom—EEPROM: write/readpymcu.hal.watchdog—Watchdog: enable/disable/feedpymcu.hal.power— sleep_idle / adc_noise / power_down / power_save / standby
Drivers#
pymcu.drivers.dht11— DHT11 temperature + humiditypymcu.drivers.ds18b20— DS18B20 1-Wire precision temperature (12-bit)pymcu.drivers.lm35— LM35 analog temperature (ADC)pymcu.drivers.hd44780— HD44780 LCD (4-bit parallel)pymcu.drivers.ssd1306— SSD1306 OLED (I2C, 128×64)pymcu.drivers.max7219— MAX7219 7-segment display (SPI)pymcu.drivers.bmp280— BMP280 barometer (I2C)pymcu.drivers.neopixel— WS2812 NeoPixel
Compatibility layers#
pymcu.compat.micropython—machine,utime,micropythonmodulespymcu.compat.circuitpython—board,digitalio,analogio,pwmio,timemodules
Boards#
pymcu.boards.arduino_uno— D0–D13, A0–A5, LED_BUILTINpymcu.boards.arduino_mega— D0–D53, A0–A15, LED_BUILTINpymcu.boards.arduino_leonardo— D0–D13, A0–A5, LED_BUILTIN
Toolchain#
Programmer plugin system — custom backends via
pymcu.pluginsentry-point group[tool.pymcu.ffi]— C/C++ interop: sources, include_dirs, cflags