aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.gitmodules3
-rw-r--r--Makefile13
m---------lib/cmsis-svd0
-rw-r--r--src/machine/machine_dummy.go2
-rw-r--r--src/machine/machine_stm32.go81
-rw-r--r--src/runtime/runtime_stm32.go34
-rw-r--r--targets/bluepill.json8
-rw-r--r--targets/stm32.ld10
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
diff --git a/Makefile b/Makefile
index 0bfda8bab..ed5fda5fb 100644
--- a/Makefile
+++ b/Makefile
@@ -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"