diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | Makefile | 13 | ||||
m--------- | lib/cmsis-svd | 0 | ||||
-rw-r--r-- | src/machine/machine_dummy.go | 2 | ||||
-rw-r--r-- | src/machine/machine_stm32.go | 81 | ||||
-rw-r--r-- | src/runtime/runtime_stm32.go | 34 | ||||
-rw-r--r-- | targets/bluepill.json | 8 | ||||
-rw-r--r-- | targets/stm32.ld | 10 |
9 files changed, 152 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore index ff2563eba..890c77b2d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ src/device/avr/*.go src/device/avr/*.ld src/device/nrf/*.go src/device/nrf/*.s +src/device/stm32/*.go +src/device/stm32/*.s diff --git a/.gitmodules b/.gitmodules index a879dba48..c9e2db4ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "lib/avr"] path = lib/avr url = https://github.com/avr-rust/avr-mcu.git +[submodule "lib/cmsis-svd"] + path = lib/cmsis-svd + url = https://github.com/posborne/cmsis-svd @@ -15,6 +15,12 @@ else ifeq ($(TARGET),pca10040) OBJCOPY = arm-none-eabi-objcopy TGOFLAGS += -target $(TARGET) +else ifeq ($(TARGET),bluepill) +# "blue pill" development board +# See: https://wiki.stm32duino.com/index.php?title=Blue_Pill +OBJCOPY = arm-none-eabi-objcopy +TGOFLAGS += -target $(TARGET) + else ifeq ($(TARGET),arduino) OBJCOPY = avr-objcopy TGOFLAGS += -target $(TARGET) @@ -39,6 +45,9 @@ flash-%: build/%.hex else ifeq ($(TARGET),arduino) flash-%: build/%.hex avrdude -c arduino -p atmega328p -P /dev/ttyACM0 -U flash:w:$< +else ifeq ($(TARGET),bluepill) +flash-%: build/%.hex + openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c 'program $< reset exit' endif clean: @@ -57,6 +66,10 @@ gen-device-avr: ./tools/gen-device-avr.py lib/avr/packs/atmega src/device/avr/ go fmt ./src/device/avr +gen-device-stm32: + ./tools/gen-device-svd.py lib/cmsis-svd/data/STMicro/ src/device/stm32/ --source=https://github.com/posborne/cmsis-svd/tree/master/data/STMicro + go fmt ./src/device/stm32 + # Build the Go compiler. build/tgo: *.go diff --git a/lib/cmsis-svd b/lib/cmsis-svd new file mode 160000 +Subproject 2ab163c2aea83eb9b39c163856450089255ce4f diff --git a/src/machine/machine_dummy.go b/src/machine/machine_dummy.go index 0c2a59159..99237d2c5 100644 --- a/src/machine/machine_dummy.go +++ b/src/machine/machine_dummy.go @@ -1,4 +1,4 @@ -// +build !avr,!nrf +// +build !avr,!nrf,!stm32 package machine diff --git a/src/machine/machine_stm32.go b/src/machine/machine_stm32.go new file mode 100644 index 000000000..9fe9a7b56 --- /dev/null +++ b/src/machine/machine_stm32.go @@ -0,0 +1,81 @@ +// +build stm32 + +package machine + +// Peripheral abstraction layer for the stm32. + +import ( + "device/stm32" +) + +type GPIOMode uint8 + +const ( + GPIO_INPUT = 0 // Input mode + GPIO_OUTPUT = 2 // Output mode, max speed 2MHz +) + +const ( + portA = iota * 16 + portB + portC + portD + portE + portF + portG +) + +const ( + LED = portC + 13 +) + +func (p GPIO) getPort() *stm32.GPIO_Type { + switch p.Pin / 16 { + case 0: + return stm32.GPIOA + case 1: + return stm32.GPIOB + case 2: + return stm32.GPIOC + case 3: + return stm32.GPIOD + case 4: + return stm32.GPIOE + case 5: + return stm32.GPIOF + case 6: + return stm32.GPIOG + default: + panic("machine: unknown port") + } +} + +// Configure this pin with the given configuration. +func (p GPIO) Configure(config GPIOConfig) { + // Enable clock. + // Do this always, as it isn't known whether the clock has already been + // enabled. + stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_IOPCEN_Msk; + + // Configure the GPIO pin. + port := p.getPort() + pin := p.Pin % 16 + pos := p.Pin % 8 * 4 + if pin < 8 { + port.CRL = stm32.RegValue((uint32(port.CRL) &^ (0xf << pos)) | (uint32(config.Mode) << pos)) + } else { + port.CRH = stm32.RegValue((uint32(port.CRH) &^ (0xf << pos)) | (uint32(config.Mode) << pos)) + } +} + +// Set the pin to high or low. +// Warning: only use this on an output pin! +func (p GPIO) Set(high bool) { + port := p.getPort() + pin := p.Pin % 16 + if high { + port.BSRR = 1 << pin + } else { + port.BSRR = 1 << (pin + 16) + } +} diff --git a/src/runtime/runtime_stm32.go b/src/runtime/runtime_stm32.go new file mode 100644 index 000000000..c2e6e2b1a --- /dev/null +++ b/src/runtime/runtime_stm32.go @@ -0,0 +1,34 @@ +// +build stm32 + +package runtime + +import ( + "device/arm" +) + +type timeUnit int64 + +const tickMicros = 1 // TODO + +//go:export Reset_Handler +func handleReset() { + main() +} + +func init() { +} + +func putchar(c byte) { + // TODO +} + +func sleepTicks(d timeUnit) { + // TODO: use a real timer here + for i := 0; i < int(d/535); i++ { + arm.Asm("") + } +} + +func ticks() timeUnit { + return 0 // TODO +} diff --git a/targets/bluepill.json b/targets/bluepill.json new file mode 100644 index 000000000..63563ffeb --- /dev/null +++ b/targets/bluepill.json @@ -0,0 +1,8 @@ +{ + "llvm-target": "armv7m-none-eabi", + "build-tags": ["stm32", "stm32f103xx", "arm", "js", "wasm"], + "linker": "arm-none-eabi-gcc", + "pre-link-args": ["-nostdlib", "-nostartfiles", "-mcpu=cortex-m3", "-mthumb", "-T", "targets/stm32.ld", "-Wl,--gc-sections", "-fno-exceptions", "-fno-unwind-tables", "-ffunction-sections", "-fdata-sections", "-Os", "src/device/stm32/stm32f103xx.s"], + "objcopy": "arm-none-eabi-objcopy", + "flash": "openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c 'program {hex} reset exit'" +} diff --git a/targets/stm32.ld b/targets/stm32.ld new file mode 100644 index 000000000..2953742ef --- /dev/null +++ b/targets/stm32.ld @@ -0,0 +1,10 @@ + +MEMORY +{ + FLASH_TEXT (rw) : ORIGIN = 0x08000000, LENGTH = 64K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K +} + +_stack_size = 2K; + +INCLUDE "targets/arm.ld" |