Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for the CH32V003 chip #4321

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ src/device/kendryte/*.go
src/device/kendryte/*.s
src/device/rp/*.go
src/device/rp/*.s
src/device/wch/*.go
src/device/wch/*.s
vendor
llvm-build
llvm-project
Expand Down
8 changes: 7 additions & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ fmt-check:
@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
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-wch
ifneq ($(STM32), 0)
gen-device: gen-device-stm32
endif
Expand Down Expand Up @@ -237,6 +237,10 @@ gen-device-renesas: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/tinygo-org/renesas-svd lib/renesas-svd/ src/device/renesas/
GO111MODULE=off $(GO) fmt ./src/device/renesas

gen-device-wch: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/ch32-rs/ch32-rs/ lib/cmsis-svd/data/WCH-Community/ src/device/wch
GO111MODULE=off $(GO) fmt ./src/device/wch

# Get LLVM sources.
$(LLVM_PROJECTDIR)/llvm:
git clone -b tinygo_xtensa_release_18.1.2 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR)
Expand Down Expand Up @@ -783,6 +787,8 @@ endif
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=maixbit examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=nanoch32v003 examples/blinky1
@$(MD5SUM) test.hex
ifneq ($(WASM), 0)
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/export
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/main
Expand Down
1 change: 1 addition & 0 deletions builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func TestClangAttributes(t *testing.T) {
"cortex-m33",
"cortex-m4",
"cortex-m7",
"ch32v003",
"esp32c3",
"fe310",
"gameboy-advance",
Expand Down
5 changes: 5 additions & 0 deletions src/device/riscv/handleinterrupt.S
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// We don't support RV32E at the moment.
#if !defined(__riscv_32e)

#ifdef __riscv_flen
#define NREG 48
#define LFREG flw
Expand Down Expand Up @@ -128,3 +131,5 @@ handleInterruptASM:
LREG ra, 0*REGSIZE(sp)
addi sp, sp, NREG*REGSIZE
mret

#endif
5 changes: 5 additions & 0 deletions src/internal/task/task_stack_tinygoriscv.S
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//go:build tinygo

// We don't support RV32E at the moment.
#if !defined(__riscv_32e)

.section .text.tinygo_startTask
.global tinygo_startTask
.type tinygo_startTask, %function
Expand Down Expand Up @@ -69,3 +72,5 @@ tinygo_swapTask:

// Return into the task.
ret

#endif
5 changes: 5 additions & 0 deletions src/machine/board_nanoch32v003.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//go:build nanoch32v003

package machine

const LED = PD6
72 changes: 72 additions & 0 deletions src/machine/machine_ch32v003.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//go:build ch32v003

package machine

import "device/wch"

const deviceName = wch.Device

const (
PA0 Pin = 0 + 0
PA1 Pin = 0 + 1
PA2 Pin = 0 + 2
PA3 Pin = 0 + 3
PA4 Pin = 0 + 4
PA5 Pin = 0 + 5
PA6 Pin = 0 + 6
PA7 Pin = 0 + 7
PC0 Pin = 16 + 0
PC1 Pin = 16 + 1
PC2 Pin = 16 + 2
PC3 Pin = 16 + 3
PC4 Pin = 16 + 4
PC5 Pin = 16 + 5
PC6 Pin = 16 + 6
PC7 Pin = 16 + 7
PD0 Pin = 24 + 0
PD1 Pin = 24 + 1
PD2 Pin = 24 + 2
PD3 Pin = 24 + 3
PD4 Pin = 24 + 4
PD5 Pin = 24 + 5
PD6 Pin = 24 + 6
PD7 Pin = 24 + 7
)

const (
PinInput PinMode = 0
PinOutput PinMode = 3
)

func (p Pin) getPortPin() (port *wch.GPIO_Type, pin uint32) {
portNum := uint32(p) >> 3
pin = uint32(p) & 0b111
switch portNum {
case 0:
port = wch.GPIOA
case 2:
port = wch.GPIOC
case 3:
port = wch.GPIOD
}
return
}

func (p Pin) Configure(config PinConfig) {
port, pin := p.getPortPin()
reg := port.CFGLR.Get()
reg &^= (0xf << (4 * pin))
reg |= 0b0000 << (4 * pin)
reg |= 0b11 << (4 * pin)
port.CFGLR.Set(reg)
}

// Set the pin to high or low.
func (p Pin) Set(high bool) {
port, pin := p.getPortPin()
if high {
port.BSHR.Set(1 << pin)
} else {
port.BCR.Set(1 << pin)
}
}
5 changes: 5 additions & 0 deletions src/runtime/asm_riscv.S
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// We don't support RV32E at the moment.
#if !defined(__riscv_32e)

#if __riscv_xlen==64
#define REGSIZE 8
#define SREG sd
Expand Down Expand Up @@ -50,3 +53,5 @@ tinygo_longjmp:
lw sp, 0(a0) // jumpSP
lw a1, REGSIZE(a0) // jumpPC
jr a1

#endif
75 changes: 75 additions & 0 deletions src/runtime/runtime_ch32v003.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//go:build ch32v003

package runtime

import (
"device/wch"
"runtime/volatile"
)

//export main
func main() {
// Initialize main clock.
wch.RCC.CTLR.Set(wch.RCC_CTLR_HSION | wch.RCC_CTLR_PLLON)
wch.RCC.CFGR0.Set(0<<wch.RCC_CFGR0_HPRE_Pos | 0<<wch.RCC_CFGR0_PLLSRC_Pos)
wch.FLASH.ACTLR.Set(1 << wch.FLASH_ACTLR_LATENCY_Pos)
wch.RCC.INTR.Set(0x009F0000)
for (wch.RCC.CTLR.Get() & wch.RCC_CTLR_PLLRDY) == 0 {
}
wch.RCC.SetCFGR0_SW(0b10)
for (wch.RCC.CFGR0.Get() & wch.RCC_CFGR0_SWS_Msk) != 0x08 {
}

// Enable all GPIO pins (port A, C and D).
wch.RCC.APB2PCENR.SetBits(wch.RCC_APB2PCENR_IOPAEN | wch.RCC_APB2PCENR_IOPDEN | wch.RCC_APB2PCENR_IOPCEN)

run()
exit(0)
}

type timeUnit int64

var currentTicks timeUnit

func putchar(c byte) {
// TODO
}

func exit(code int) {
abort()
}

func ticks() timeUnit {
return currentTicks
}

// ticksToNanoseconds converts RTC ticks (at 32768Hz) to nanoseconds.
func ticksToNanoseconds(ticks timeUnit) int64 {
// The following calculation is actually the following, but with both sides
// reduced to reduce the risk of overflow:
// ticks * 1e9 / 32768
return int64(ticks) * 1953125 / 64
}

// nanosecondsToTicks converts nanoseconds to RTC ticks (running at 32768Hz).
func nanosecondsToTicks(ns int64) timeUnit {
// The following calculation is actually the following, but with both sides
// reduced to reduce the risk of overflow:
// ns * 32768 / 1e9
return timeUnit(ns * 64 / 1953125)
}

var dummyVolatile volatile.Register32

func sleepTicks(ticks timeUnit) {
// TODO: use a timer (using the low-speed clock)
loops := ticks * 70
for i := timeUnit(0); i < loops; i++ {
dummyVolatile.Get()
}
}

func abort() {
for {
}
}
17 changes: 17 additions & 0 deletions targets/ch32v003.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"inherits": ["riscv32"],
"target-abi": "ilp32e",
"features": "+32bit,+c,+e,-a,-d,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-i,-m,-relax,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
"build-tags": ["ch32v003", "ch32v00xxx", "wch"],
"scheduler": "none",
"gc": "leaking",
"rtlib": "compiler-rt",
"libc": "picolibc",
"cflags": [
"-march=rv32ec"
],
"linkerscript": "targets/ch32v003.ld",
"extra-files": [
],
"flash-command": "probe-rs download --chip=CH32V003 {elf}"
}
9 changes: 9 additions & 0 deletions targets/ch32v003.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
MEMORY
{
FLASH_TEXT (rw) : ORIGIN = 0x00000000, LENGTH = 16K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2K
}

_stack_size = 1K;

INCLUDE "targets/riscv.ld"
4 changes: 4 additions & 0 deletions targets/nanoch32v003.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"inherits": ["ch32v003"],
"build-tags": ["nanoch32v003"]
}
Loading