From f36df37d29bb139f09a613bdba1edf42495c557e Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Wed, 19 Nov 2025 00:36:39 +0100 Subject: [PATCH 01/16] WIP --- .gitmodules | 3 +++ lib/py32-svd | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/py32-svd diff --git a/.gitmodules b/.gitmodules index 1f8c63a673..b09cf7fb2e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -41,3 +41,6 @@ [submodule "lib/bdwgc"] path = lib/bdwgc url = https://github.com/ivmai/bdwgc.git +[submodule "lib/py32-svd"] + path = lib/py32-svd + url = https://github.com/burgrp/py32-svd.git diff --git a/lib/py32-svd b/lib/py32-svd new file mode 160000 index 0000000000..d98c758f53 --- /dev/null +++ b/lib/py32-svd @@ -0,0 +1 @@ +Subproject commit d98c758f530cfa61e607334b50e19f6c113f8d1d From 2854e2ea1c623e8405a7b76451cdfed1d9102048 Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Wed, 19 Nov 2025 00:36:48 +0100 Subject: [PATCH 02/16] WIP --- .gitignore | 2 ++ GNUmakefile | 6 +++++- src/runtime/runtime_py32.go | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/runtime/runtime_py32.go diff --git a/.gitignore b/.gitignore index 2761d1fcc7..0b03c83ead 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,8 @@ src/device/renesas/*.go src/device/renesas/*.s src/device/rp/*.go src/device/rp/*.s +src/device/py32/*.go +src/device/py32/*.s ./vendor llvm-build llvm-project diff --git a/GNUmakefile b/GNUmakefile index 99dc3913b6..69689a0a33 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -187,7 +187,7 @@ fmt-check: ## Warn if any source needs reformatting @unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1 -gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-kendryte gen-device-nxp gen-device-rp ## Generate microcontroller-specific sources +gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-kendryte gen-device-nxp gen-device-rp gen-device-py32 ## Generate microcontroller-specific sources ifneq ($(RENESAS), 0) gen-device: gen-device-renesas endif @@ -242,6 +242,10 @@ gen-device-renesas: build/gen-device-svd ./build/gen-device-svd -source=https://github.com/cmsis-svd/cmsis-svd-data/tree/master/data/Renesas lib/cmsis-svd/data/Renesas/ src/device/renesas/ GO111MODULE=off $(GO) fmt ./src/device/renesas +gen-device-py32: build/gen-device-svd + ./build/gen-device-svd -source=https://github.com/tinygo-org/py32-svd lib/py32-svd/svd src/device/py32/ + GO111MODULE=off $(GO) fmt ./src/device/py32 + $(LLVM_PROJECTDIR)/llvm: git clone -b xtensa_release_19.1.2 --depth=1 https://github.com/espressif/llvm-project $(LLVM_PROJECTDIR) llvm-source: $(LLVM_PROJECTDIR)/llvm ## Get LLVM sources diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go new file mode 100644 index 0000000000..72c5029f2a --- /dev/null +++ b/src/runtime/runtime_py32.go @@ -0,0 +1,19 @@ +//go:build py32 + +package runtime + +func ticksToNanoseconds(ticks timeUnit) int64 { + return 0 +} + +func nanosecondsToTicks(ns int64) timeUnit { + return 0 +} + +//go:linkname ticks runtime.ticks +func ticks() timeUnit { + return 0 +} + +func sleepTicks(d timeUnit) { +} From 1c6f4cdb36f3cf8a68ad9b543453e08158329eaf Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Fri, 21 Nov 2025 23:35:27 +0100 Subject: [PATCH 03/16] WIP --- src/runtime/runtime_py32.go | 13 +++++++++++++ targets/py32.json | 10 ++++++++++ targets/py32f002a.json | 12 ++++++++++++ targets/py32f002a.ld | 10 ++++++++++ 4 files changed, 45 insertions(+) create mode 100644 targets/py32.json create mode 100644 targets/py32f002a.json create mode 100644 targets/py32f002a.ld diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 72c5029f2a..e5bdee94b7 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -2,6 +2,16 @@ package runtime +//export Reset_Handler +func main() { + // initSystem() + // arm.Asm("CPSIE i") + // initInternal() + + run() + exit(0) +} + func ticksToNanoseconds(ticks timeUnit) int64 { return 0 } @@ -17,3 +27,6 @@ func ticks() timeUnit { func sleepTicks(d timeUnit) { } + +func putchar(c byte) { +} diff --git a/targets/py32.json b/targets/py32.json new file mode 100644 index 0000000000..6424ef633a --- /dev/null +++ b/targets/py32.json @@ -0,0 +1,10 @@ +{ + "inherits": [ + "cortex-m0plus" + ], + "scheduler": "none", + "gc": "none", + "build-tags": [ + "py32" + ] +} \ No newline at end of file diff --git a/targets/py32f002a.json b/targets/py32f002a.json new file mode 100644 index 0000000000..f1ce0b7b65 --- /dev/null +++ b/targets/py32f002a.json @@ -0,0 +1,12 @@ +{ + "inherits": [ + "py32" + ], + "build-tags": [ + "py32f002axx" + ], + "linkerscript": "targets/py32f002a.ld", + "extra-files": [ + "src/device/py32/py32f002axx.s" + ] +} \ No newline at end of file diff --git a/targets/py32f002a.ld b/targets/py32f002a.ld new file mode 100644 index 0000000000..3ed1dc12d0 --- /dev/null +++ b/targets/py32f002a.ld @@ -0,0 +1,10 @@ + +MEMORY +{ + FLASH_TEXT (rx) : ORIGIN = 0x08000000, LENGTH = 20K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 3K +} + +_stack_size = 512; + +INCLUDE "targets/arm.ld" \ No newline at end of file From db8a7b1f5fee10763e29452e77e1331b8ce15b0d Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sat, 22 Nov 2025 00:01:14 +0100 Subject: [PATCH 04/16] WIP --- src/runtime/runtime_cortexm_hardfault.go | 2 +- src/runtime/runtime_cortexm_hardfault_debug.go | 2 +- src/runtime/runtime_py32.go | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/runtime/runtime_cortexm_hardfault.go b/src/runtime/runtime_cortexm_hardfault.go index b2449ed910..c5d2444e59 100644 --- a/src/runtime/runtime_cortexm_hardfault.go +++ b/src/runtime/runtime_cortexm_hardfault.go @@ -1,4 +1,4 @@ -//go:build atsamd21 || nrf51 +//go:build atsamd21 || nrf51 || py32 package runtime diff --git a/src/runtime/runtime_cortexm_hardfault_debug.go b/src/runtime/runtime_cortexm_hardfault_debug.go index ea6c507028..f54a4d6cae 100644 --- a/src/runtime/runtime_cortexm_hardfault_debug.go +++ b/src/runtime/runtime_cortexm_hardfault_debug.go @@ -1,4 +1,4 @@ -//go:build cortexm && !atsamd21 && !nrf51 +//go:build cortexm && !atsamd21 && !nrf51 && !py32 package runtime diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index e5bdee94b7..943f2a7e62 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -2,6 +2,8 @@ package runtime +import "device/py32" + //export Reset_Handler func main() { // initSystem() @@ -29,4 +31,6 @@ func sleepTicks(d timeUnit) { } func putchar(c byte) { + // jenom aby tady něco bylo + py32.GPIOA.SetMODER_MODE0(py32.GPIO_MODER_MODE0_Output) } From fbb18225f0fb2c7238098fffab53e03d11c2fa63 Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Fri, 28 Nov 2025 21:06:53 +0100 Subject: [PATCH 05/16] WIP --- src/runtime/runtime_py32.go | 12 +++- targets/embedfire-py32f002b.json | 74 ++++++++++++++++++++++ targets/{py32f002a.json => py32f002b.json} | 4 +- targets/{py32f002a.ld => py32f002b.ld} | 0 4 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 targets/embedfire-py32f002b.json rename targets/{py32f002a.json => py32f002b.json} (67%) rename targets/{py32f002a.ld => py32f002b.ld} (100%) diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 943f2a7e62..5e6011c698 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -2,7 +2,9 @@ package runtime -import "device/py32" +import ( + "device/py32" +) //export Reset_Handler func main() { @@ -10,8 +12,12 @@ func main() { // arm.Asm("CPSIE i") // initInternal() - run() - exit(0) + for { + putchar('A') + } + + // run() + // exit(0) } func ticksToNanoseconds(ticks timeUnit) int64 { diff --git a/targets/embedfire-py32f002b.json b/targets/embedfire-py32f002b.json new file mode 100644 index 0000000000..9f513050c4 --- /dev/null +++ b/targets/embedfire-py32f002b.json @@ -0,0 +1,74 @@ +{ + "inherits": ["py32f002b"], + "flash-command": "pyocd load -t py32f002bx5 {bin}" +} + +/* + +https://splitbrain.github.io/pinoutleaf + +title: "embedfire-py32f002b" + +# dimensions counted in pins +width: 8 +height: 11 + + +# images can be URLs, use adjustments to fit the pins +image: + front: + src: "https://i.ibb.co/5X0J6D3Y/fg.png" + top: -450 + left: -90 + right: -90 + bottom: -450 + back: + src: "https://i.ibb.co/ycSZp21x/bg.png" + top: -450 + left: -90 + right: -90 + bottom: -450 + +# Define the pins (label:type), use empty entries when offsets are needed +pins: + left: + - [ "5V:power" ] + - [ "PB2:gpio" ] + - [ "PB1:gpio" ] + - [ "PB0:gpio" ] + - [ "KEY2:button", "PA0:gpio" ] + - [ "LED2:led", "PA1:gpio" ] + - [ "SWCLK:prog", "PA2:gpio" ] + - [ "KEY1:button", "PA3:gpio" ] + - [ "LED4:led", "PA4:gpio"] + - [ "RESET:button", "PC0:gpio"] + - [ "GND:gnd"] + right: + - [ "3V3:power" ] + - [ "PB5:gpio" ] + - [ "PB4:gpio" ] + - [ "PB3:gpio" ] + - [ "SWDIO:prog", "PB6:gpio" ] + - [ "PB7:gpio" ] + - [ "PC1:gpio" ] + - [ "LED3:led", "PA5:gpio" ] + - [ "PA7:gpio"] + - [ "PA6:gpio"] + - [ "GND:gnd"] + +types: + gpio: + label: 'GPIO' + bgcolor: '#00A060' + prog: + label: 'SWD' + bgcolor: '#FFCC00' + led: + label: 'LED' + bgcolor: '#0099FF' + button: + label: 'Button' + bgcolor: '#B0B0B0' + + +*/ \ No newline at end of file diff --git a/targets/py32f002a.json b/targets/py32f002b.json similarity index 67% rename from targets/py32f002a.json rename to targets/py32f002b.json index f1ce0b7b65..7630f5dc89 100644 --- a/targets/py32f002a.json +++ b/targets/py32f002b.json @@ -3,9 +3,9 @@ "py32" ], "build-tags": [ - "py32f002axx" + "py32f002bxx" ], - "linkerscript": "targets/py32f002a.ld", + "linkerscript": "targets/py32f002b.ld", "extra-files": [ "src/device/py32/py32f002axx.s" ] diff --git a/targets/py32f002a.ld b/targets/py32f002b.ld similarity index 100% rename from targets/py32f002a.ld rename to targets/py32f002b.ld From 03b994a3e1d61d86174060f775751d64f43af5d9 Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sat, 29 Nov 2025 19:51:22 +0100 Subject: [PATCH 06/16] WIP --- src/machine/board_embedfire_py32f002b copy.go | 20 +++ src/machine/board_embedfire_py32f002b.go | 20 +++ src/machine/machine_py32.go | 155 ++++++++++++++++++ src/runtime/runtime_py32.go | 13 +- targets/embedfire-py32f002b.json | 8 +- targets/embedfire-py32f030.json | 86 ++++++++++ targets/py32f030.json | 11 ++ targets/py32f030_64k_8k.json | 9 + targets/py32f030_64k_8k.ld | 10 ++ 9 files changed, 318 insertions(+), 14 deletions(-) create mode 100644 src/machine/board_embedfire_py32f002b copy.go create mode 100644 src/machine/board_embedfire_py32f002b.go create mode 100644 src/machine/machine_py32.go create mode 100644 targets/embedfire-py32f030.json create mode 100644 targets/py32f030.json create mode 100644 targets/py32f030_64k_8k.json create mode 100644 targets/py32f030_64k_8k.ld diff --git a/src/machine/board_embedfire_py32f002b copy.go b/src/machine/board_embedfire_py32f002b copy.go new file mode 100644 index 0000000000..b2980b092b --- /dev/null +++ b/src/machine/board_embedfire_py32f002b copy.go @@ -0,0 +1,20 @@ +//go:build embedfire_py32f002b + +// Pin mappings for the Embedfire PY32F002B board. +// Only LED and button aliases are provided. + +package machine + +// LEDs +const ( + LED2 = PA1 + LED3 = PA5 + LED4 = PA4 + LED = LED2 +) + +// Buttons +const ( + KEY1 = PA3 + KEY2 = PA0 +) diff --git a/src/machine/board_embedfire_py32f002b.go b/src/machine/board_embedfire_py32f002b.go new file mode 100644 index 0000000000..e628238930 --- /dev/null +++ b/src/machine/board_embedfire_py32f002b.go @@ -0,0 +1,20 @@ +//go:build embedfire_py32f030 + +// Pin mappings for the Embedfire PY32F030 board. +// Only LED and button aliases are provided. + +package machine + +// LEDs +const ( + LED2 = PA2 + LED3 = PA3 + LED4 = PA4 + LED = LED2 +) + +// Buttons +const ( + KEY1 = PA5 + KEY2 = PA6 +) diff --git a/src/machine/machine_py32.go b/src/machine/machine_py32.go new file mode 100644 index 0000000000..5aa1f6be6b --- /dev/null +++ b/src/machine/machine_py32.go @@ -0,0 +1,155 @@ +//go:build py32 + +package machine + +import ( + "device/py32" + "unsafe" +) + +const deviceName = py32.Device + +// Peripheral port offsets. Keep the same spacing used on other MCUs so helpers +// like Pin.getPort can keep using simple division by 16 even though PY32 ports +// only expose 8 pins each. +const ( + portA Pin = iota * 16 + portB + portC +) + +// Port A pins. +const ( + PA0 Pin = portA + iota + PA1 + PA2 + PA3 + PA4 + PA5 + PA6 + PA7 +) + +// Port B pins. +const ( + PB0 Pin = portB + iota + PB1 + PB2 + PB3 + PB4 + PB5 + PB6 + PB7 +) + +// Port C pins. +const ( + PC0 Pin = portC + iota + PC1 + PC2 + PC3 + PC4 + PC5 + PC6 + PC7 +) + +// PinMode values specific to PY32: only GPIO direction and pull configuration. +const ( + PinOutput PinMode = iota + PinInputFloating + PinInputPulldown + PinInputPullup + PinInputAnalog +) +const PinInput PinMode = PinInputFloating + +// Internal helpers for GPIO configuration. +const ( + gpioModeInput = 0 + gpioModeOutput = 1 + gpioModeAnalog = 3 + gpioModeMask = 0x3 + + gpioPullFloating = 0 + gpioPullUp = 1 + gpioPullDown = 2 + gpioPullMask = 0x3 + + gpioOutputSpeedHigh = 2 + gpioOutputSpeedMask = 0x3 +) + +// // CPUFrequency returns the core clock frequency. +// func CPUFrequency() uint32 { +// return 48_000_000 +// } + +func (p Pin) getPortNumber() uint8 { + return uint8(p) >> 4 + +} + +func (p Pin) getPinNumber() uint8 { + return uint8(p) & 0x0F +} + +func (p Pin) getPort() (*py32.GPIO_Type, uint8) { + offset := uintptr(p.getPortNumber()) * (uintptr(unsafe.Pointer(py32.GPIOB)) - uintptr(unsafe.Pointer(py32.GPIOA))) + return (*py32.GPIO_Type)(unsafe.Pointer(uintptr(unsafe.Pointer(py32.GPIOA)) + offset)), p.getPinNumber() +} + +func (p Pin) Set(high bool) { + port, pin := p.getPort() + if high { + port.BSRR.Set(1 << pin) + } else { + port.BSRR.Set(1 << (pin + 16)) + } +} + +func (p Pin) Get() bool { + port, pin := p.getPort() + val := port.IDR.Get() & (1 << pin) + return val > 0 +} + +func (p Pin) Configure(config PinConfig) { + p.enableClock() + port, pin := p.getPort() + pos := (pin % 16) * 2 + + switch config.Mode { + + case PinInputFloating: + port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos) + port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos) + case PinInputPulldown: + port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos) + port.PUPDR.ReplaceBits(gpioPullDown, gpioPullMask, pos) + case PinInputPullup: + port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos) + port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos) + case PinOutput: + port.MODER.ReplaceBits(gpioModeOutput, gpioModeMask, pos) + port.OTYPER.ReplaceBits(py32.GPIO_OTYPER_OT0_PushPull, py32.GPIO_OTYPER_OT0_Msk, pos>>1) + port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos) + case PinInputAnalog: + port.MODER.ReplaceBits(gpioModeAnalog, gpioModeMask, pos) + port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos) + } +} + +func (p Pin) SetAltFunc(af uint8) { + port, pin := p.getPort() + if pin >= 8 { + port.AFRH.ReplaceBits(uint32(af), 0xF, (pin%8)*4) + } else { + port.AFRL.ReplaceBits(uint32(af), 0xF, (pin%8)*4) + } +} + +func (p Pin) enableClock() { + portNo := p.getPortNumber() + py32.RCC.IOPENR.SetBits(1 << portNo) +} diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 5e6011c698..16c6eb5ce7 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -8,16 +8,9 @@ import ( //export Reset_Handler func main() { - // initSystem() - // arm.Asm("CPSIE i") - // initInternal() - - for { - putchar('A') - } - - // run() - // exit(0) + preinit() + run() + exit(0) } func ticksToNanoseconds(ticks timeUnit) int64 { diff --git a/targets/embedfire-py32f002b.json b/targets/embedfire-py32f002b.json index 9f513050c4..b3d339bc79 100644 --- a/targets/embedfire-py32f002b.json +++ b/targets/embedfire-py32f002b.json @@ -1,6 +1,7 @@ { "inherits": ["py32f002b"], - "flash-command": "pyocd load -t py32f002bx5 {bin}" + "flash-command": "pyocd load -t py32f002bx5 {bin}", + "build-tags": ["embedfire_py32f002b"] } /* @@ -13,17 +14,16 @@ title: "embedfire-py32f002b" width: 8 height: 11 - # images can be URLs, use adjustments to fit the pins image: front: - src: "https://i.ibb.co/5X0J6D3Y/fg.png" + src: "https://img.sanishtech.com/u/8f427259002707501b471ef06a77134c.png" top: -450 left: -90 right: -90 bottom: -450 back: - src: "https://i.ibb.co/ycSZp21x/bg.png" + src: "https://img.sanishtech.com/u/3650f247f0b77ef5efbcfca3d75f29aa.png" top: -450 left: -90 right: -90 diff --git a/targets/embedfire-py32f030.json b/targets/embedfire-py32f030.json new file mode 100644 index 0000000000..b198c38c95 --- /dev/null +++ b/targets/embedfire-py32f030.json @@ -0,0 +1,86 @@ +{ + "inherits": ["py32f030_64k_8k"], + "flash-command": "pyocd load -t py32f003x8 {bin}", + "build-tags": ["embedfire_py32f030"] +} + +/* + +https://splitbrain.github.io/pinoutleaf + +title: "embedfire-py32f030" + +# dimensions counted in pins +width: 8 +height: 16 + +# images can be URLs, use adjustments to fit the pins +image: + front: + src: "https://img.sanishtech.com/u/d7efa5b8e309a987d89bf3f031a4b5e3.png" + top: -520 + left: -120 + right: -120 + bottom: -470 + back: + src: "https://img.sanishtech.com/u/cfc8cd0828646e3bde5c1364fca33458.png" + top: -450 + left: -100 + right: -120 + bottom: -470 + +# Define the pins (label:type), use empty entries when offsets are needed +pins: + left: + - [ "3V3:power" ] + - [ "PA12:gpio" ] + - [ "SWDIO:prog", "PA13:gpio" ] + - [ "SWCLK:prog", "PA14:gpio" ] + - [ "PA11:gpio" ] + - [ "PA15:gpio" ] + - [ "PB3:gpio" ] + - [ "PB4:gpio" ] + - [ "PB5:gpio"] + - [ "PB6:gpio"] + - [ "PB7:gpio"] + - [ "BOOT0:config", "PF4:gpio"] + - [ "PB8:gpio"] + - [ "PF3:gpio"] + - [ "RESET:button", "PF2:gpio"] + - [ "GND:gnd"] + right: + - [ "3V3:power" ] + - [ "5V:power" ] + - [ "PA8:gpio" ] + - [ "PB2:gpio" ] + - [ "PB1:gpio" ] + - [ "PB0:gpio" ] + - [ "PA7:gpio" ] + - [ "KEY2:button", "PA6:gpio" ] + - [ "KEY1:button", "PA5:gpio"] + - [ "LED4:led", "PA4:gpio"] + - [ "LED3:led", "PA3:gpio"] + - [ "LED2:led", "PA2:gpio"] + - [ "PA1:gpio"] + - [ "PA0:gpio"] + - [ "GND:gnd"] + - [ "GND:gnd"] + +types: + gpio: + label: 'GPIO' + bgcolor: '#00A060' + prog: + label: 'SWD' + bgcolor: '#FFCC00' + led: + label: 'LED' + bgcolor: '#0099FF' + button: + label: 'Button' + bgcolor: '#B0B0B0' + config: + label: 'Config' + bgcolor: '#A060FF' + +*/ \ No newline at end of file diff --git a/targets/py32f030.json b/targets/py32f030.json new file mode 100644 index 0000000000..e1bc19bed0 --- /dev/null +++ b/targets/py32f030.json @@ -0,0 +1,11 @@ +{ + "inherits": [ + "py32" + ], + "build-tags": [ + "py32f030", "py32f030xx" + ], + "extra-files": [ + "src/device/py32/py32f030xx.s" + ] +} \ No newline at end of file diff --git a/targets/py32f030_64k_8k.json b/targets/py32f030_64k_8k.json new file mode 100644 index 0000000000..6a248733d8 --- /dev/null +++ b/targets/py32f030_64k_8k.json @@ -0,0 +1,9 @@ +{ + "inherits": [ + "py32f030" + ], + "build-tags": [ + "py32f030_64k_8k" + ], + "linkerscript": "targets/py32f030_64k_8k.ld" +} \ No newline at end of file diff --git a/targets/py32f030_64k_8k.ld b/targets/py32f030_64k_8k.ld new file mode 100644 index 0000000000..380a4d3811 --- /dev/null +++ b/targets/py32f030_64k_8k.ld @@ -0,0 +1,10 @@ + +MEMORY +{ + FLASH_TEXT (rx) : ORIGIN = 0x08000000, LENGTH = 64K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K +} + +_stack_size = 512; + +INCLUDE "targets/arm.ld" \ No newline at end of file From 53e9c9d737c5ff67885769fb7bb647c2ed17a21f Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sat, 29 Nov 2025 23:15:49 +0100 Subject: [PATCH 07/16] WIP --- .../{machine_py32.go => machine_py32_pin.go} | 39 +++++++++++++++++++ src/machine/machine_py32_systick.go | 30 ++++++++++++++ src/runtime/runtime_py32.go | 21 +++++++--- 3 files changed, 84 insertions(+), 6 deletions(-) rename src/machine/{machine_py32.go => machine_py32_pin.go} (91%) create mode 100644 src/machine/machine_py32_systick.go diff --git a/src/machine/machine_py32.go b/src/machine/machine_py32_pin.go similarity index 91% rename from src/machine/machine_py32.go rename to src/machine/machine_py32_pin.go index 5aa1f6be6b..a135c6a2b2 100644 --- a/src/machine/machine_py32.go +++ b/src/machine/machine_py32_pin.go @@ -16,6 +16,9 @@ const ( portA Pin = iota * 16 portB portC + portD + portE + portF ) // Port A pins. @@ -54,6 +57,42 @@ const ( PC7 ) +// Port D pins. +const ( + PD0 Pin = portD + iota + PD1 + PD2 + PD3 + PD4 + PD5 + PD6 + PD7 +) + +// Port E pins. +const ( + PE0 Pin = portE + iota + PE1 + PE2 + PE3 + PE4 + PE5 + PE6 + PE7 +) + +// Port F pins. +const ( + PF0 Pin = portF + iota + PF1 + PF2 + PF3 + PF4 + PF5 + PF6 + PF7 +) + // PinMode values specific to PY32: only GPIO direction and pull configuration. const ( PinOutput PinMode = iota diff --git a/src/machine/machine_py32_systick.go b/src/machine/machine_py32_systick.go new file mode 100644 index 0000000000..526a514857 --- /dev/null +++ b/src/machine/machine_py32_systick.go @@ -0,0 +1,30 @@ +//go:build py32 + +package machine + +import ( + "device/arm" +) + +var msCounter uint64 + +// CPUFrequency returns the core clock frequency. +func CPUFrequency() uint32 { + return 4_000_000 +} + +func Init() { + LED4.Configure(PinConfig{Mode: PinOutput}) + arm.SetupSystemTimer(CPUFrequency() / 1000) +} + +//export SysTick_Handler +func handleSysTick() { + msCounter = msCounter + 1 + LED4.Set(!LED4.Get()) +} + +// Ticks returns the number of milliseconds since boot. +func GetTicks() uint64 { + return msCounter +} diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 16c6eb5ce7..34e59cd040 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -3,33 +3,42 @@ package runtime import ( - "device/py32" + "device/arm" + "machine" ) //export Reset_Handler func main() { preinit() + machine.Init() run() exit(0) } func ticksToNanoseconds(ticks timeUnit) int64 { - return 0 + return int64(ticks * 1_000_000) } func nanosecondsToTicks(ns int64) timeUnit { - return 0 + return timeUnit(ns / 1_000_000) } //go:linkname ticks runtime.ticks func ticks() timeUnit { - return 0 + return timeUnit(machine.GetTicks()) } func sleepTicks(d timeUnit) { + if d <= 0 { + return + } + start := ticks() + stop := start + d + for ticks() < stop { + arm.Asm("wfe") + } } func putchar(c byte) { - // jenom aby tady něco bylo - py32.GPIOA.SetMODER_MODE0(py32.GPIO_MODER_MODE0_Output) + } From a1b04eeb00b08a79023062d5a933dd6bb417ab1b Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sun, 30 Nov 2025 00:25:07 +0100 Subject: [PATCH 08/16] WIP --- src/machine/machine_py32_systick.go | 30 --------------------------- src/runtime/runtime_py32.go | 32 +++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 34 deletions(-) delete mode 100644 src/machine/machine_py32_systick.go diff --git a/src/machine/machine_py32_systick.go b/src/machine/machine_py32_systick.go deleted file mode 100644 index 526a514857..0000000000 --- a/src/machine/machine_py32_systick.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build py32 - -package machine - -import ( - "device/arm" -) - -var msCounter uint64 - -// CPUFrequency returns the core clock frequency. -func CPUFrequency() uint32 { - return 4_000_000 -} - -func Init() { - LED4.Configure(PinConfig{Mode: PinOutput}) - arm.SetupSystemTimer(CPUFrequency() / 1000) -} - -//export SysTick_Handler -func handleSysTick() { - msCounter = msCounter + 1 - LED4.Set(!LED4.Get()) -} - -// Ticks returns the number of milliseconds since boot. -func GetTicks() uint64 { - return msCounter -} diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 34e59cd040..b7d43401b1 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -4,28 +4,41 @@ package runtime import ( "device/arm" + "machine" ) //export Reset_Handler func main() { preinit() - machine.Init() + + machine.LED4.Configure(machine.PinConfig{Mode: machine.PinOutput}) + + ConfigureSystemTimer(8e6) + run() exit(0) } +const shift = 15 + +func ConfigureSystemTimer(systemFrequencyHz uint32) { + arm.SetupSystemTimer(systemFrequencyHz / 1000) +} + func ticksToNanoseconds(ticks timeUnit) int64 { - return int64(ticks * 1_000_000) + return int64(ticks * 10_000_000) } func nanosecondsToTicks(ns int64) timeUnit { - return timeUnit(ns / 1_000_000) + return timeUnit(ns / 10_000_000) } +var tickCounter uint64 + //go:linkname ticks runtime.ticks func ticks() timeUnit { - return timeUnit(machine.GetTicks()) + return timeUnit(tickCounter) } func sleepTicks(d timeUnit) { @@ -42,3 +55,14 @@ func sleepTicks(d timeUnit) { func putchar(c byte) { } + +//export SysTick_Handler +func handleSysTick() { + tickCounter = tickCounter + 1 + //machine.LED4.Set(!machine.LED4.Get()) + machine.LED4.High() + for i := 0; i < 100; i++ { + arm.Asm("nop") + } + machine.LED4.Low() +} From 7e7ddd2283b3736f138f75353cb2c87f4a8bd9d2 Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sun, 30 Nov 2025 00:29:09 +0100 Subject: [PATCH 09/16] WIP --- src/runtime/runtime_py32.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index b7d43401b1..0e3ccfb639 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -27,11 +27,11 @@ func ConfigureSystemTimer(systemFrequencyHz uint32) { } func ticksToNanoseconds(ticks timeUnit) int64 { - return int64(ticks * 10_000_000) + return int64(ticks * 1_000_000) } func nanosecondsToTicks(ns int64) timeUnit { - return timeUnit(ns / 10_000_000) + return timeUnit(ns / 1_000_000) } var tickCounter uint64 From 443dce604c1061c913b403fa07cb47b178f8d248 Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sun, 30 Nov 2025 00:56:06 +0100 Subject: [PATCH 10/16] WIP --- src/runtime/runtime_py32.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 0e3ccfb639..510295a501 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -6,6 +6,8 @@ import ( "device/arm" "machine" + + "device/py32" ) //export Reset_Handler @@ -14,24 +16,24 @@ func main() { machine.LED4.Configure(machine.PinConfig{Mode: machine.PinOutput}) - ConfigureSystemTimer(8e6) + py32.RCC.SetICSCR_HSI_FS(py32.RCC_ICSCR_HSI_FS_Freq24MHz) + + ConfigureSystemTimer(24e6) run() exit(0) } -const shift = 15 - func ConfigureSystemTimer(systemFrequencyHz uint32) { arm.SetupSystemTimer(systemFrequencyHz / 1000) } func ticksToNanoseconds(ticks timeUnit) int64 { - return int64(ticks * 1_000_000) + return int64(ticks * 1000_000) } func nanosecondsToTicks(ns int64) timeUnit { - return timeUnit(ns / 1_000_000) + return timeUnit(ns / 1000_000) } var tickCounter uint64 From 40ae2b11ca9199b21613d95f86dc80515999ff7d Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sun, 30 Nov 2025 15:03:11 +0100 Subject: [PATCH 11/16] WIP --- src/runtime/runtime_py32.go | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 510295a501..0c1c975c1a 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -5,8 +5,6 @@ package runtime import ( "device/arm" - "machine" - "device/py32" ) @@ -14,8 +12,6 @@ import ( func main() { preinit() - machine.LED4.Configure(machine.PinConfig{Mode: machine.PinOutput}) - py32.RCC.SetICSCR_HSI_FS(py32.RCC_ICSCR_HSI_FS_Freq24MHz) ConfigureSystemTimer(24e6) @@ -24,6 +20,8 @@ func main() { exit(0) } +// Configure SysTick to fire every 1ms on given system frequency. +// This should be called after any changes to the system clock frequency. func ConfigureSystemTimer(systemFrequencyHz uint32) { arm.SetupSystemTimer(systemFrequencyHz / 1000) } @@ -61,10 +59,4 @@ func putchar(c byte) { //export SysTick_Handler func handleSysTick() { tickCounter = tickCounter + 1 - //machine.LED4.Set(!machine.LED4.Get()) - machine.LED4.High() - for i := 0; i < 100; i++ { - arm.Asm("nop") - } - machine.LED4.Low() } From 6b9b48db9318bc6132c69828c32c42453941adc4 Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sun, 30 Nov 2025 18:07:08 +0100 Subject: [PATCH 12/16] WIP --- src/runtime/runtime_py32.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 0c1c975c1a..ae647b8493 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -4,6 +4,7 @@ package runtime import ( "device/arm" + "machine" "device/py32" ) @@ -15,6 +16,7 @@ func main() { py32.RCC.SetICSCR_HSI_FS(py32.RCC_ICSCR_HSI_FS_Freq24MHz) ConfigureSystemTimer(24e6) + machine.InitSerial() run() exit(0) @@ -53,7 +55,15 @@ func sleepTicks(d timeUnit) { } func putchar(c byte) { + machine.Serial.WriteByte(c) +} +func getchar() byte { + for machine.Serial.Buffered() == 0 { + Gosched() + } + v, _ := machine.Serial.ReadByte() + return v } //export SysTick_Handler From d10680ccce4cddbd05f83c5346400e5c70bd0e4f Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sun, 30 Nov 2025 20:09:39 +0100 Subject: [PATCH 13/16] WIP --- src/machine/board_embedfire_py32f002b copy.go | 20 ---- src/machine/board_embedfire_py32f002b.go | 20 +++- src/machine/board_embedfire_py32f030.go | 28 +++++ src/machine/machine_py32_pin.go | 57 ++++++++-- src/machine/machine_py32_pin_afrh.go | 12 ++ src/machine/machine_py32_pin_no_afrh.go | 8 ++ src/machine/machine_py32_uart.go | 104 ++++++++++++++++++ src/machine/uart.go | 2 +- src/runtime/runtime_py32.go | 2 +- 9 files changed, 216 insertions(+), 37 deletions(-) delete mode 100644 src/machine/board_embedfire_py32f002b copy.go create mode 100644 src/machine/board_embedfire_py32f030.go create mode 100644 src/machine/machine_py32_pin_afrh.go create mode 100644 src/machine/machine_py32_pin_no_afrh.go create mode 100644 src/machine/machine_py32_uart.go diff --git a/src/machine/board_embedfire_py32f002b copy.go b/src/machine/board_embedfire_py32f002b copy.go deleted file mode 100644 index b2980b092b..0000000000 --- a/src/machine/board_embedfire_py32f002b copy.go +++ /dev/null @@ -1,20 +0,0 @@ -//go:build embedfire_py32f002b - -// Pin mappings for the Embedfire PY32F002B board. -// Only LED and button aliases are provided. - -package machine - -// LEDs -const ( - LED2 = PA1 - LED3 = PA5 - LED4 = PA4 - LED = LED2 -) - -// Buttons -const ( - KEY1 = PA3 - KEY2 = PA0 -) diff --git a/src/machine/board_embedfire_py32f002b.go b/src/machine/board_embedfire_py32f002b.go index e628238930..2d0f501902 100644 --- a/src/machine/board_embedfire_py32f002b.go +++ b/src/machine/board_embedfire_py32f002b.go @@ -1,20 +1,28 @@ -//go:build embedfire_py32f030 +//go:build embedfire_py32f002b -// Pin mappings for the Embedfire PY32F030 board. +// Pin mappings for the Embedfire PY32F002B board. // Only LED and button aliases are provided. package machine // LEDs const ( - LED2 = PA2 - LED3 = PA3 + LED2 = PA1 + LED3 = PA5 LED4 = PA4 LED = LED2 ) // Buttons const ( - KEY1 = PA5 - KEY2 = PA6 + KEY1 = PA3 + KEY2 = PA0 +) + +// UART +const ( + DEFAULT_UART_TX_PIN = PA6 + DEFAULT_UART_RX_PIN = PA7 + DEFAULT_UART_TX_PIN_AF = 1 + DEFAULT_UART_RX_PIN_AF = 3 ) diff --git a/src/machine/board_embedfire_py32f030.go b/src/machine/board_embedfire_py32f030.go new file mode 100644 index 0000000000..d000aef6ca --- /dev/null +++ b/src/machine/board_embedfire_py32f030.go @@ -0,0 +1,28 @@ +//go:build embedfire_py32f030 + +// Pin mappings for the Embedfire PY32F030 board. +// Only LED and button aliases are provided. + +package machine + +// LEDs +const ( + LED2 = PA2 + LED3 = PA3 + LED4 = PA4 + LED = LED2 +) + +// Buttons +const ( + KEY1 = PA5 + KEY2 = PA6 +) + +// UART +const ( + DEFAULT_UART_TX_PIN = PA7 + DEFAULT_UART_RX_PIN = PA8 + DEFAULT_UART_TX_PIN_AF = 8 + DEFAULT_UART_RX_PIN_AF = 8 +) diff --git a/src/machine/machine_py32_pin.go b/src/machine/machine_py32_pin.go index a135c6a2b2..2c94c37134 100644 --- a/src/machine/machine_py32_pin.go +++ b/src/machine/machine_py32_pin.go @@ -31,6 +31,14 @@ const ( PA5 PA6 PA7 + PA8 + PA9 + PA10 + PA11 + PA12 + PA13 + PA14 + PA15 ) // Port B pins. @@ -43,6 +51,14 @@ const ( PB5 PB6 PB7 + PB8 + PB9 + PB10 + PB11 + PB12 + PB13 + PB14 + PB15 ) // Port C pins. @@ -55,6 +71,14 @@ const ( PC5 PC6 PC7 + PC8 + PC9 + PC10 + PC11 + PC12 + PC13 + PC14 + PC15 ) // Port D pins. @@ -67,6 +91,14 @@ const ( PD5 PD6 PD7 + PD8 + PD9 + PD10 + PD11 + PD12 + PD13 + PD14 + PD15 ) // Port E pins. @@ -79,6 +111,14 @@ const ( PE5 PE6 PE7 + PE8 + PE9 + PE10 + PE11 + PE12 + PE13 + PE14 + PE15 ) // Port F pins. @@ -91,6 +131,14 @@ const ( PF5 PF6 PF7 + PF8 + PF9 + PF10 + PF11 + PF12 + PF13 + PF14 + PF15 ) // PinMode values specific to PY32: only GPIO direction and pull configuration. @@ -179,15 +227,6 @@ func (p Pin) Configure(config PinConfig) { } } -func (p Pin) SetAltFunc(af uint8) { - port, pin := p.getPort() - if pin >= 8 { - port.AFRH.ReplaceBits(uint32(af), 0xF, (pin%8)*4) - } else { - port.AFRL.ReplaceBits(uint32(af), 0xF, (pin%8)*4) - } -} - func (p Pin) enableClock() { portNo := p.getPortNumber() py32.RCC.IOPENR.SetBits(1 << portNo) diff --git a/src/machine/machine_py32_pin_afrh.go b/src/machine/machine_py32_pin_afrh.go new file mode 100644 index 0000000000..67c742b513 --- /dev/null +++ b/src/machine/machine_py32_pin_afrh.go @@ -0,0 +1,12 @@ +//go:build py32 && !py32f002bxx + +package machine + +func (p Pin) SetAltFunc(af uint8) { + port, pin := p.getPort() + if pin >= 8 { + port.AFRH.ReplaceBits(uint32(af), 0xF, (pin%8)*4) + } else { + port.AFRL.ReplaceBits(uint32(af), 0xF, (pin%8)*4) + } +} diff --git a/src/machine/machine_py32_pin_no_afrh.go b/src/machine/machine_py32_pin_no_afrh.go new file mode 100644 index 0000000000..8b0297a289 --- /dev/null +++ b/src/machine/machine_py32_pin_no_afrh.go @@ -0,0 +1,8 @@ +//go:build py32 && py32f002bxx + +package machine + +func (p Pin) SetAltFunc(af uint8) { + port, pin := p.getPort() + port.AFRL.ReplaceBits(uint32(af), 0xF, (pin%8)*4) +} diff --git a/src/machine/machine_py32_uart.go b/src/machine/machine_py32_uart.go new file mode 100644 index 0000000000..8cbe6fc27c --- /dev/null +++ b/src/machine/machine_py32_uart.go @@ -0,0 +1,104 @@ +//go:build py32 + +package machine + +import ( + "device/py32" + "runtime/interrupt" +) + +// Remember the clock used for baud rate calculations so Configure() can be +// called without explicitly passing the clock. +var py32UARTClockHz uint32 = 24_000_000 + +// UART implements a minimal USART1 driver for PY32 parts. +type UART struct { + Bus *py32.USART_Type + Buffer *RingBuffer + irq interrupt.Interrupt +} + +var DefaultUART = &UART{Bus: py32.USART1, Buffer: NewRingBuffer()} + +// ConfigureWithClock initializes the UART using the provided peripheral clock +// frequency (in Hz). This avoids assuming a fixed MCU clock. +func (uart *UART) ConfigureWithClock(config UARTConfig, clockHz uint32) error { + if config.BaudRate == 0 { + config.BaudRate = 115200 + } + + // Configure default pins if they weren't provided. + if config.TX == 0 { + ConfigureUARTPin(DEFAULT_UART_TX_PIN, DEFAULT_UART_TX_PIN_AF) + } + + if config.RX == 0 { + ConfigureUARTPin(DEFAULT_UART_RX_PIN, DEFAULT_UART_RX_PIN_AF) + } + + // Enable peripheral clock. + py32.RCC.APBENR2.SetBits(py32.RCC_APBENR2_USART1EN) + + // Reset control registers to a known state. + uart.Bus.CR1.Set(0) + uart.Bus.CR2.Set(0) + uart.Bus.CR3.Set(0) + + // Oversampling by 16: BRR expects fck/baud. + divider := (clockHz + (config.BaudRate / 2)) / config.BaudRate + uart.Bus.BRR.Set(divider) + + // Enable transmitter, receiver, RX interrupt, and the peripheral. + uart.Bus.CR1.Set(py32.USART_CR1_TE | py32.USART_CR1_RE | py32.USART_CR1_RXNEIE | py32.USART_CR1_UE) + + // Hook interrupt. + uart.irq = interrupt.New(py32.IRQ_USART1, handleUartInterrupt) + uart.irq.SetPriority(0xc0) + uart.irq.Enable() + + return nil +} + +// Configure uses the last stored clock (defaulting to 24 MHz). Call +// ConfigureWithClock for explicit control. +func (uart *UART) Configure(config UARTConfig) error { + return uart.ConfigureWithClock(config, py32UARTClockHz) +} + +// InitSerialWithClock configures the default Serial using the supplied +// peripheral clock frequency. +func InitSerialWithClock(clockHz uint32) { + py32UARTClockHz = clockHz + //Serial.ConfigureWithClock(UARTConfig{}, clockHz) +} + +// Configure pin for use by UART +func ConfigureUARTPin(pin Pin, af uint8) { + pin.enableClock() + port, n := pin.getPort() + pos := (n % 16) * 2 + + // Alternate function mode is encoded as 0b10. + port.MODER.ReplaceBits(2, gpioModeMask, pos) + port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos) + port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos) + pin.SetAltFunc(af) +} + +func handleUartInterrupt(interrupt.Interrupt) { + uart := DefaultUART + data := uint8(uart.Bus.DR.Get()) + uart.Receive(data) +} + +func (uart *UART) writeByte(c byte) error { + for uart.Bus.SR.Get()&py32.USART_SR_TXE == 0 { + } + uart.Bus.DR.Set(uint32(c)) + return nil +} + +func (uart *UART) flush() { + for uart.Bus.SR.Get()&py32.USART_SR_TC == 0 { + } +} diff --git a/src/machine/uart.go b/src/machine/uart.go index 32462587b1..e154672e0c 100644 --- a/src/machine/uart.go +++ b/src/machine/uart.go @@ -1,4 +1,4 @@ -//go:build atmega || esp || nrf || sam || sifive || stm32 || k210 || nxp || rp2040 || rp2350 +//go:build atmega || esp || nrf || sam || sifive || stm32 || k210 || nxp || rp2040 || rp2350 || py32 package machine diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index ae647b8493..5a922ad98b 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -15,7 +15,7 @@ func main() { py32.RCC.SetICSCR_HSI_FS(py32.RCC_ICSCR_HSI_FS_Freq24MHz) - ConfigureSystemTimer(24e6) + ConfigureSystemTimer(24_000_000) machine.InitSerial() run() From eda6f5263a93ab748e10a2f81d823798722e7d7d Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sun, 30 Nov 2025 21:08:06 +0100 Subject: [PATCH 14/16] WIP --- src/runtime/runtime_py32.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 5a922ad98b..20dbc9dd70 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -50,10 +50,14 @@ func sleepTicks(d timeUnit) { start := ticks() stop := start + d for ticks() < stop { - arm.Asm("wfe") + waitForEvents() } } +func waitForEvents() { + arm.Asm("wfe") +} + func putchar(c byte) { machine.Serial.WriteByte(c) } From 7f917c31ce3de97babf7c96388c58c526bb3d30f Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Sun, 30 Nov 2025 21:27:10 +0100 Subject: [PATCH 15/16] WIP --- src/machine/board_embedfire_py32f002b.go | 6 +++--- src/machine/board_embedfire_py32f030.go | 6 +++--- src/runtime/runtime_py32.go | 10 ++++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/machine/board_embedfire_py32f002b.go b/src/machine/board_embedfire_py32f002b.go index 2d0f501902..1877b756d1 100644 --- a/src/machine/board_embedfire_py32f002b.go +++ b/src/machine/board_embedfire_py32f002b.go @@ -7,9 +7,9 @@ package machine // LEDs const ( - LED2 = PA1 - LED3 = PA5 - LED4 = PA4 + LED1 = PA1 + LED2 = PA5 + LED3 = PA4 LED = LED2 ) diff --git a/src/machine/board_embedfire_py32f030.go b/src/machine/board_embedfire_py32f030.go index d000aef6ca..93f5caca5e 100644 --- a/src/machine/board_embedfire_py32f030.go +++ b/src/machine/board_embedfire_py32f030.go @@ -7,9 +7,9 @@ package machine // LEDs const ( - LED2 = PA2 - LED3 = PA3 - LED4 = PA4 + LED1 = PA2 + LED2 = PA3 + LED3 = PA4 LED = LED2 ) diff --git a/src/runtime/runtime_py32.go b/src/runtime/runtime_py32.go index 20dbc9dd70..4088d49b62 100644 --- a/src/runtime/runtime_py32.go +++ b/src/runtime/runtime_py32.go @@ -7,8 +7,12 @@ import ( "machine" "device/py32" + + "runtime/volatile" ) +var tickCounter volatile.Register64 + //export Reset_Handler func main() { preinit() @@ -36,11 +40,9 @@ func nanosecondsToTicks(ns int64) timeUnit { return timeUnit(ns / 1000_000) } -var tickCounter uint64 - //go:linkname ticks runtime.ticks func ticks() timeUnit { - return timeUnit(tickCounter) + return timeUnit(tickCounter.Get()) } func sleepTicks(d timeUnit) { @@ -72,5 +74,5 @@ func getchar() byte { //export SysTick_Handler func handleSysTick() { - tickCounter = tickCounter + 1 + tickCounter.Set(tickCounter.Get() + 1) } From 8e141795dada3b87debb1da9f6052c113c9d3cc7 Mon Sep 17 00:00:00 2001 From: Pavel Burgr Date: Tue, 2 Dec 2025 17:01:08 +0100 Subject: [PATCH 16/16] WIP --- src/machine/board_embedfire_py32f002b.go | 1 - src/machine/board_embedfire_py32f030.go | 1 - src/machine/machine_py32_pin.go | 19 +++---------------- src/machine/machine_py32_pin_afrh.go | 2 +- src/machine/machine_py32_pin_no_afrh.go | 2 +- targets/py32f002b.json | 2 +- 6 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/machine/board_embedfire_py32f002b.go b/src/machine/board_embedfire_py32f002b.go index 1877b756d1..ab5ef80a6f 100644 --- a/src/machine/board_embedfire_py32f002b.go +++ b/src/machine/board_embedfire_py32f002b.go @@ -1,7 +1,6 @@ //go:build embedfire_py32f002b // Pin mappings for the Embedfire PY32F002B board. -// Only LED and button aliases are provided. package machine diff --git a/src/machine/board_embedfire_py32f030.go b/src/machine/board_embedfire_py32f030.go index 93f5caca5e..7d32dab314 100644 --- a/src/machine/board_embedfire_py32f030.go +++ b/src/machine/board_embedfire_py32f030.go @@ -1,7 +1,6 @@ //go:build embedfire_py32f030 // Pin mappings for the Embedfire PY32F030 board. -// Only LED and button aliases are provided. package machine diff --git a/src/machine/machine_py32_pin.go b/src/machine/machine_py32_pin.go index 2c94c37134..d244439408 100644 --- a/src/machine/machine_py32_pin.go +++ b/src/machine/machine_py32_pin.go @@ -9,9 +9,9 @@ import ( const deviceName = py32.Device -// Peripheral port offsets. Keep the same spacing used on other MCUs so helpers -// like Pin.getPort can keep using simple division by 16 even though PY32 ports -// only expose 8 pins each. +// Peripheral port offsets. +// Keep the same spacing used on other MCUs so helpers like Pin.getPortNumber +// can keep using simple division by 16. const ( portA Pin = iota * 16 portB @@ -21,7 +21,6 @@ const ( portF ) -// Port A pins. const ( PA0 Pin = portA + iota PA1 @@ -41,7 +40,6 @@ const ( PA15 ) -// Port B pins. const ( PB0 Pin = portB + iota PB1 @@ -61,7 +59,6 @@ const ( PB15 ) -// Port C pins. const ( PC0 Pin = portC + iota PC1 @@ -81,7 +78,6 @@ const ( PC15 ) -// Port D pins. const ( PD0 Pin = portD + iota PD1 @@ -101,7 +97,6 @@ const ( PD15 ) -// Port E pins. const ( PE0 Pin = portE + iota PE1 @@ -121,7 +116,6 @@ const ( PE15 ) -// Port F pins. const ( PF0 Pin = portF + iota PF1 @@ -141,7 +135,6 @@ const ( PF15 ) -// PinMode values specific to PY32: only GPIO direction and pull configuration. const ( PinOutput PinMode = iota PinInputFloating @@ -151,7 +144,6 @@ const ( ) const PinInput PinMode = PinInputFloating -// Internal helpers for GPIO configuration. const ( gpioModeInput = 0 gpioModeOutput = 1 @@ -167,11 +159,6 @@ const ( gpioOutputSpeedMask = 0x3 ) -// // CPUFrequency returns the core clock frequency. -// func CPUFrequency() uint32 { -// return 48_000_000 -// } - func (p Pin) getPortNumber() uint8 { return uint8(p) >> 4 diff --git a/src/machine/machine_py32_pin_afrh.go b/src/machine/machine_py32_pin_afrh.go index 67c742b513..7077bd4de8 100644 --- a/src/machine/machine_py32_pin_afrh.go +++ b/src/machine/machine_py32_pin_afrh.go @@ -1,4 +1,4 @@ -//go:build py32 && !py32f002bxx +//go:build py32 && !no_gpio_afrh package machine diff --git a/src/machine/machine_py32_pin_no_afrh.go b/src/machine/machine_py32_pin_no_afrh.go index 8b0297a289..fb674db8f4 100644 --- a/src/machine/machine_py32_pin_no_afrh.go +++ b/src/machine/machine_py32_pin_no_afrh.go @@ -1,4 +1,4 @@ -//go:build py32 && py32f002bxx +//go:build py32 && no_gpio_afrh package machine diff --git a/targets/py32f002b.json b/targets/py32f002b.json index 7630f5dc89..2c0c82d8bc 100644 --- a/targets/py32f002b.json +++ b/targets/py32f002b.json @@ -3,7 +3,7 @@ "py32" ], "build-tags": [ - "py32f002bxx" + "py32f002bxx", "no_gpio_afrh" ], "linkerscript": "targets/py32f002b.ld", "extra-files": [