diff --git a/src/machine/board_k210.go b/src/machine/board_k210.go new file mode 100644 index 00000000..c72f8fe0 --- /dev/null +++ b/src/machine/board_k210.go @@ -0,0 +1,55 @@ +// +build maixbit + +package machine + +// K210 IO pins. +const ( + P00 Pin = 0 + P01 Pin = 1 + P02 Pin = 2 + P03 Pin = 3 + P04 Pin = 4 + P05 Pin = 5 + P06 Pin = 6 + P07 Pin = 7 + P08 Pin = 8 + P09 Pin = 9 + P10 Pin = 10 + P11 Pin = 11 + P12 Pin = 12 + P13 Pin = 13 + P14 Pin = 14 + P15 Pin = 15 + P16 Pin = 16 + P17 Pin = 17 + P18 Pin = 18 + P19 Pin = 19 + P20 Pin = 20 + P21 Pin = 21 + P22 Pin = 22 + P23 Pin = 23 + P24 Pin = 24 + P25 Pin = 25 + P26 Pin = 26 + P27 Pin = 27 + P28 Pin = 28 + P29 Pin = 29 + P30 Pin = 30 + P31 Pin = 31 + P32 Pin = 32 + P33 Pin = 33 + P34 Pin = 34 + P35 Pin = 35 + P36 Pin = 36 + P37 Pin = 37 + P38 Pin = 38 + P39 Pin = 39 + P40 Pin = 40 + P41 Pin = 41 + P42 Pin = 42 + P43 Pin = 43 + P44 Pin = 44 + P45 Pin = 45 + P46 Pin = 46 + P47 Pin = 47 +) diff --git a/src/machine/board_maixbit.go b/src/machine/board_maixbit.go new file mode 100644 index 00000000..c68542e8 --- /dev/null +++ b/src/machine/board_maixbit.go @@ -0,0 +1,61 @@ +// +build maixbit + +package machine + +// GPIO pins. +const ( + D0 = P08 + D1 = P09 + D2 = P10 + D3 = P11 + D4 = P12 + D5 = P13 + D6 = P14 + D7 = P15 +) + +// High-speed GPIO pins (GPIOHS). +const ( + DHS0 = P16 + DHS1 = P17 + DHS2 = P18 + DHS3 = P19 + DHS4 = P20 + DHS5 = P21 + DHS6 = P22 + DHS7 = P23 + DHS8 = P24 + DHS9 = P25 + DHS10 = P26 + DHS11 = P27 + DHS12 = P28 + DHS13 = P29 + DHS14 = P30 + DHS15 = P31 + DHS16 = P32 + DHS17 = P33 + DHS18 = P34 + DHS19 = P35 + DHS20 = P36 + DHS21 = P37 + DHS22 = P38 + DHS23 = P39 + DHS24 = P40 + DHS25 = P41 + DHS26 = P42 + DHS27 = P43 + DHS28 = P44 + DHS29 = P45 + DHS30 = P46 + DHS31 = P47 +) + +const ( + LED = LED1 + LED1 = LED_RED + LED2 = LED_GREEN + LED3 = LED_BLUE + LED_RED = D5 + LED_GREEN = D4 + LED_BLUE = D6 +) diff --git a/src/machine/machine_k210.go b/src/machine/machine_k210.go new file mode 100644 index 00000000..deff5472 --- /dev/null +++ b/src/machine/machine_k210.go @@ -0,0 +1,30 @@ +// +build k210 + +package machine + +func CPUFrequency() uint32 { + return 400000000 +} + +type PinMode uint8 + +const ( + PinInput PinMode = iota + PinOutput + PinPWM + PinSPI + PinI2C = PinSPI +) + +// Configure this pin with the given configuration. +func (p Pin) Configure(config PinConfig) { +} + +// Set the pin to high or low. +func (p Pin) Set(high bool) { +} + +// Get returns the current value of a GPIO pin. +func (p Pin) Get() bool { + return true +} diff --git a/src/runtime/runtime_k210.go b/src/runtime/runtime_k210.go new file mode 100644 index 00000000..5486a3e9 --- /dev/null +++ b/src/runtime/runtime_k210.go @@ -0,0 +1,110 @@ +// +build k210 + +// This file implements target-specific things for the K210 chip as used in the +// MAix Bit with Mic. + +package runtime + +import ( + "unsafe" + + "device/riscv" + "runtime/volatile" +) + +type timeUnit int64 + +func postinit() {} + +//export main +func main() { + // todo + + // Set the interrupt address. + // Note that this address must be aligned specially, otherwise the MODE bits + // of MTVEC won't be zero. + riscv.MTVEC.Set(uintptr(unsafe.Pointer(&handleInterruptASM))) + + // Reset the MIE register and enable external interrupts. + // It must be reset here because it not zeroed at startup. + riscv.MIE.Set(1 << 11) // bit 11 is for machine external interrupts + + // Enable global interrupts now that they've been set up. + riscv.MSTATUS.SetBits(1 << 3) // MIE + + preinit() + initPeripherals() + run() + abort() +} + +//go:extern handleInterruptASM +var handleInterruptASM [0]uintptr + +//export handleInterrupt +func handleInterrupt() { + cause := riscv.MCAUSE.Get() + code := uint(cause &^ (1 << 31)) + if cause&(1<<31) != 0 { + // Topmost bit is set, which means that it is an interrupt. + switch code { + case 7: // Machine timer interrupt + // Signal timeout. + timerWakeup.Set(1) + // Disable the timer, to avoid triggering the interrupt right after + // this interrupt returns. + riscv.MIE.ClearBits(1 << 7) // MTIE bit + case 11: // Machine external interrupt + // Claim this interrupt. + //id := sifive.PLIC.CLAIM.Get() + // Call the interrupt handler, if any is registered for this ID. + callInterruptHandler(int(0)) + // Complete this interrupt. + //sifive.PLIC.CLAIM.Set(id) + } + } else { + // Topmost bit is clear, so it is an exception of some sort. + // We could implement support for unsupported instructions here (such as + // misaligned loads). However, for now we'll just print a fatal error. + handleException(code) + } +} + +// initPeripherals configures periperhals the way the runtime expects them. +func initPeripherals() { + // todo +} + +func putchar(c byte) { + //machine.UART0.WriteByte(c) +} + +const asyncScheduler = false + +var timerWakeup volatile.Register8 + +func ticks() timeUnit { + // todo +} + +func sleepTicks(d timeUnit) { + // todo +} + +// handleException is called from the interrupt handler for any exception. +// Exceptions can be things like illegal instructions, invalid memory +// read/write, and similar issues. +func handleException(code uint) { + // For a list of exception codes, see: + // https://content.riscv.org/wp-content/uploads/2019/08/riscv-privileged-20190608-1.pdf#page=49 + print("fatal error: exception with mcause=") + print(code) + print(" pc=") + print(riscv.MEPC.Get()) + println() + abort() +} + +// callInterruptHandler is a compiler-generated function that calls the +// appropriate interrupt handler for the given interrupt ID. +func callInterruptHandler(id int) diff --git a/src/runtime/runtime_k210_baremetal.go b/src/runtime/runtime_k210_baremetal.go new file mode 100644 index 00000000..47f862bc --- /dev/null +++ b/src/runtime/runtime_k210_baremetal.go @@ -0,0 +1,27 @@ +// +build k210,!qemu + +package runtime + +import ( + "device/kendryte" + "device/riscv" +) + +var clockFrequency uint32 = kendryte.SYSCTL.CLK_FREQ.Get() + +// ticksToNanoseconds converts RTC ticks to nanoseconds. +func ticksToNanoseconds(ticks timeUnit) int64 { + return int64(ticks) * 1e9 / clockFrequency +} + +// nanosecondsToTicks converts nanoseconds to RTC ticks. +func nanosecondsToTicks(ns int64) timeUnit { + return timeUnit(ns * 64 / 1953125) +} + +func abort() { + // lock up forever + for { + riscv.Asm("wfi") + } +} diff --git a/targets/maixbit.json b/targets/maixbit.json index f0f5e8b2..eb664a48 100644 --- a/targets/maixbit.json +++ b/targets/maixbit.json @@ -2,5 +2,5 @@ "inherits": ["k210"], "build-tags": ["maixbit"], "linkerscript": "targets/maixbit.ld", - "flash-command": "kflash -p /dev/ttyUSB0 {hex}" + "flash-command": "kflash -p {port} {hex}" }