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

Add RP2350 support #4459

Draft
wants to merge 15 commits into
base: dev
Choose a base branch
from
Binary file added blinky1.elf
Binary file not shown.
87 changes: 87 additions & 0 deletions src/machine/machine_rp2350.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//go:build rp2350

package machine

import (
"device/rp"
)

const deviceName = rp.Device

//go:linkname machineInit runtime.machineInit
func machineInit() {
}

// GPIO pins
const (
GPIO0 Pin = 0
GPIO1 Pin = 1
GPIO2 Pin = 2
GPIO3 Pin = 3
GPIO4 Pin = 4
GPIO5 Pin = 5
GPIO6 Pin = 6
GPIO7 Pin = 7
GPIO8 Pin = 8
GPIO9 Pin = 9
GPIO10 Pin = 10
GPIO11 Pin = 11
GPIO12 Pin = 12
GPIO13 Pin = 13
GPIO14 Pin = 14
GPIO15 Pin = 15
GPIO16 Pin = 16
GPIO17 Pin = 17
GPIO18 Pin = 18
GPIO19 Pin = 19
GPIO20 Pin = 20
GPIO21 Pin = 21
GPIO22 Pin = 22
GPIO23 Pin = 23
GPIO24 Pin = 24
GPIO25 Pin = 25
GPIO26 Pin = 26
GPIO27 Pin = 27
GPIO28 Pin = 28
GPIO29 Pin = 29

LED = GPIO26
)

const (
PinOutput PinMode = iota
)

// PinMode sets the direction and pull mode of the pin. For example, PinOutput
// sets the pin as an output and PinInputPullup sets the pin as an input with a
// pull-up.
// type PinMode uint8

// type PinConfig struct {
// Mode PinMode
// }

func (p Pin) Set(b bool) {}
soypat marked this conversation as resolved.
Show resolved Hide resolved
func (p Pin) Get() bool { return false }
func (p Pin) Configure(PinConfig) {}
func putchar(b byte) {}

type timeUnit int64

// ticks returns the number of ticks (microseconds) elapsed since power up.
//
//go:linkname ticks runtime.machineTicks
func ticks() uint64 {
soypat marked this conversation as resolved.
Show resolved Hide resolved
return 0
}

//go:linkname machineLightSleep runtime.machineLightSleep
func machineLightSleep(uint64) {}

func nanosecondsToTicks(ns int64) timeUnit {
return timeUnit(ns / 1000)
}

func ticksToNanoseconds(ticks timeUnit) int64 {
return int64(ticks) * 1000
}
83 changes: 83 additions & 0 deletions src/runtime/runtime_rp2350.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//go:build rp2350

package runtime

import (
"device/arm"
"machine"
)

// machineTicks is provided by package machine.
func machineTicks() uint64

// machineLightSleep is provided by package machine.
func machineLightSleep(uint64)

type timeUnit int64
soypat marked this conversation as resolved.
Show resolved Hide resolved

// ticks returns the number of ticks (microseconds) elapsed since power up.
func ticks() timeUnit {
t := machineTicks()
return timeUnit(t)
}

func ticksToNanoseconds(ticks timeUnit) int64 {
return int64(ticks) * 1000
}

func nanosecondsToTicks(ns int64) timeUnit {
return timeUnit(ns / 1000)
}

func sleepTicks(d timeUnit) {
if d <= 0 {
return
}

if hasScheduler {
// With scheduler, sleepTicks may return early if an interrupt or
// event fires - so scheduler can schedule any go routines now
// eligible to run
machineLightSleep(uint64(d))
return
}

// Busy loop
sleepUntil := ticks() + d
for ticks() < sleepUntil {
soypat marked this conversation as resolved.
Show resolved Hide resolved
}
}

func waitForEvents() {
arm.Asm("wfe")
}

func putchar(c byte) {
machine.Serial.WriteByte(c)
}

func getchar() byte {
for machine.Serial.Buffered() == 0 {
Gosched()
}
v, _ := machine.Serial.ReadByte()
return v
}

func buffered() int {
return machine.Serial.Buffered()
}

// machineInit is provided by package machine.
func machineInit()

func init() {
machineInit()
}

//export Reset_Handler
func main() {
preinit()
run()
exit(0)
}
10 changes: 10 additions & 0 deletions targets/pico2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"inherits": [
"rp2350"
],
"build-tags": ["pico2"],
"linkerscript": "targets/pico2.ld",
"extra-files": [
"targets/pico_boot_stage2.S"
]
}
19 changes: 19 additions & 0 deletions targets/rp2350.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"inherits": ["cortex-m33"],
"build-tags": ["rp2350", "rp"],
"flash-1200-bps-reset": "true",
"flash-method": "msd",
"serial": "usb",
"msd-volume-name": ["RP2350"],
"msd-firmware-name": "firmware.uf2",
"binary-format": "uf2",
"uf2-family-id": "0xe48bff59","comment":"See page 393 of RP2350 datasheet: RP2350 Arm Secure image (i.e. one intended to be booted directly by the bootrom)",
"rp2040-boot-patch": true,
"extra-files": [
"src/device/rp/rp2040.s"
],
"linkerscript": "targets/rp2350.ld",
"openocd-interface": "picoprobe",
"openocd-transport": "swd",
"openocd-target": "rp2350"
}
45 changes: 45 additions & 0 deletions targets/rp2350.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* See Rust for a more complete reference: https://github.com/rp-rs/rp-hal/blob/main/rp235x-hal-examples/memory.x */
MEMORY
{
/* 2MiB safe default. */
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these known to match the machine hardware? This is one of the places you really want to get it right, or you'll be in Debug Hell forever.

FLASH : ORIGIN = 0x10000000, LENGTH = 2048k
/* RAM consists of 8 banks, SRAM0..SRAM7 with striped mapping. */
SRAM : ORIGIN = 0x20000000, LENGTH = 512k
/* Banks 8 and 9 use direct mapping which can be
specailized for applications where predictable access time is beneficial.
i.e: Separate stacks for core0 and core1. */
SRAM4 : ORIGIN = 0x20080000, LENGTH = 4k
SRAM5 : ORIGIN = 0x20081000, LENGTH = 4k
/* Reserve exactly 256 bytes at start of flash for second stage bootloader */
BOOT2_TEXT (rx) : ORIGIN = 0x10000000, LENGTH = 256
FLASH_TEXT (rx) : ORIGIN = 0x10000000 + 256, LENGTH = 2048k - 256
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 512k
}

_stack_size = 2K;

SECTIONS
{
/* Second stage bootloader is prepended to the image. It must be 256 bytes
and checksummed. The gap to the checksum is zero-padded.
*/
.boot2 : {
__boot2_start__ = .;
KEEP (*(.boot2));

/* Explicitly allocate space for CRC32 checksum at end of second stage
bootloader
*/
. = __boot2_start__ + 256 - 4;
LONG(0)
} > BOOT2_TEXT = 0x0

/* The second stage will always enter the image at the start of .text.
The debugger will use the ELF entry point, which is the _entry_point
symbol if present, otherwise defaults to start of .text.
This can be used to transfer control back to the bootrom on debugger
launches only, to perform proper flash setup.
*/
}

INCLUDE "targets/arm.ld"
Loading
Loading