aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorsago35 <[email protected]>2022-07-14 22:04:31 +0900
committerRon Evans <[email protected]>2022-07-15 09:41:32 +0200
commitf370cd18fc0279b5465bc4eb80ec748ab8e6858a (patch)
treedb3de06f9678cd5a54045b3e65510c59a87491ee
parenta1d7cab080270d93f0dad1c90b768b7398e30167 (diff)
downloadtinygo-f370cd18fc0279b5465bc4eb80ec748ab8e6858a.tar.gz
tinygo-f370cd18fc0279b5465bc4eb80ec748ab8e6858a.zip
rp2040: add support for EnterBootloader()
-rw-r--r--src/machine/machine_rp2040_enter_bootloader.go53
-rw-r--r--src/machine/machine_rp2040_usb.go31
-rw-r--r--targets/rp2040.json1
3 files changed, 72 insertions, 13 deletions
diff --git a/src/machine/machine_rp2040_enter_bootloader.go b/src/machine/machine_rp2040_enter_bootloader.go
new file mode 100644
index 000000000..7259b060b
--- /dev/null
+++ b/src/machine/machine_rp2040_enter_bootloader.go
@@ -0,0 +1,53 @@
+//go:build rp2040
+// +build rp2040
+
+package machine
+
+/*
+// https://github.com/raspberrypi/pico-sdk
+// src/rp2_common/pico_bootrom/include/pico/bootrom.h
+
+#define ROM_FUNC_POPCOUNT32 ROM_TABLE_CODE('P', '3')
+#define ROM_FUNC_REVERSE32 ROM_TABLE_CODE('R', '3')
+#define ROM_FUNC_CLZ32 ROM_TABLE_CODE('L', '3')
+#define ROM_FUNC_CTZ32 ROM_TABLE_CODE('T', '3')
+#define ROM_FUNC_MEMSET ROM_TABLE_CODE('M', 'S')
+#define ROM_FUNC_MEMSET4 ROM_TABLE_CODE('S', '4')
+#define ROM_FUNC_MEMCPY ROM_TABLE_CODE('M', 'C')
+#define ROM_FUNC_MEMCPY44 ROM_TABLE_CODE('C', '4')
+#define ROM_FUNC_RESET_USB_BOOT ROM_TABLE_CODE('U', 'B')
+#define ROM_FUNC_CONNECT_INTERNAL_FLASH ROM_TABLE_CODE('I', 'F')
+#define ROM_FUNC_FLASH_EXIT_XIP ROM_TABLE_CODE('E', 'X')
+#define ROM_FUNC_FLASH_RANGE_ERASE ROM_TABLE_CODE('R', 'E')
+#define ROM_FUNC_FLASH_RANGE_PROGRAM ROM_TABLE_CODE('R', 'P')
+#define ROM_FUNC_FLASH_FLUSH_CACHE ROM_TABLE_CODE('F', 'C')
+#define ROM_FUNC_FLASH_ENTER_CMD_XIP ROM_TABLE_CODE('C', 'X')
+
+#define ROM_TABLE_CODE(c1, c2) ((c1) | ((c2) << 8))
+
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+typedef unsigned long uintptr_t;
+
+typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code);
+typedef void __attribute__((noreturn)) (*rom_reset_usb_boot_fn)(uint32_t, uint32_t);
+#define rom_hword_as_ptr(rom_address) (void *)(uintptr_t)(*(uint16_t *)(uintptr_t)(rom_address))
+
+void *rom_func_lookup(uint32_t code) {
+ rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) rom_hword_as_ptr(0x18);
+ uint16_t *func_table = (uint16_t *) rom_hword_as_ptr(0x14);
+ return rom_table_lookup(func_table, code);
+}
+
+void reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask) {
+ rom_reset_usb_boot_fn func = (rom_reset_usb_boot_fn) rom_func_lookup(ROM_FUNC_RESET_USB_BOOT);
+ func(usb_activity_gpio_pin_mask, disable_interface_mask);
+}
+*/
+import "C"
+
+// EnterBootloader should perform a system reset in preparation
+// to switch to the bootloader to flash new firmware.
+func EnterBootloader() {
+ C.reset_usb_boot(0, 0)
+}
diff --git a/src/machine/machine_rp2040_usb.go b/src/machine/machine_rp2040_usb.go
index faa311b5f..c5ac0ada2 100644
--- a/src/machine/machine_rp2040_usb.go
+++ b/src/machine/machine_rp2040_usb.go
@@ -4,7 +4,6 @@
package machine
import (
- "device/arm"
"device/rp"
"machine/usb"
"runtime/interrupt"
@@ -153,7 +152,8 @@ func initEndpoint(ep, config uint32) {
case usb.ENDPOINT_TYPE_CONTROL:
val |= usbEpControlEndpointTypeControl
- usbDPSRAM.EPxBufferControl[ep].Out.Set(usbBuf0CtrlAvail)
+ usbDPSRAM.EPxBufferControl[ep].Out.Set(usbBuf0CtrlData1Pid)
+ usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlAvail)
}
}
@@ -207,6 +207,21 @@ func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {
var b [cdcLineInfoSize]byte
+ ep := 0
+
+ for !usbDPSRAM.EPxBufferControl[ep].Out.HasBits(usbBuf0CtrlFull) {
+ // TODO: timeout
+ }
+
+ ctrl := usbDPSRAM.EPxBufferControl[ep].Out.Get()
+ usbDPSRAM.EPxBufferControl[ep].Out.Set(USBBufferLen & usbBuf0CtrlLenMask)
+ sz := ctrl & usbBuf0CtrlLenMask
+
+ copy(b[:], usbDPSRAM.EPxBuffer[ep].Buffer0[:sz])
+
+ usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlData1Pid)
+ usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlAvail)
+
return b, nil
}
@@ -218,7 +233,7 @@ func handleEndpointRx(ep uint32) []byte {
copy(buf, usbDPSRAM.EPxBuffer[ep].Buffer0[:sz])
epXdata0[ep] = !epXdata0[ep]
- if epXdata0[ep] {
+ if epXdata0[ep] || ep == 0 {
usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlData1Pid)
}
@@ -259,16 +274,6 @@ func sendStallViaEPIn(ep uint32) {
usbDPSRAM.EPxBufferControl[ep&0x7F].In.Set(val)
}
-// EnterBootloader should perform a system reset in preparation
-// to switch to the bootloader to flash new firmware.
-func EnterBootloader() {
- arm.DisableInterrupts()
-
- // TODO: Perform magic reset into bootloader
-
- arm.SystemReset()
-}
-
type USBDPSRAM struct {
// Note that EPxControl[0] is not EP0Control but 8-byte setup data.
EPxControl [16]USBEndpointControlRegister
diff --git a/targets/rp2040.json b/targets/rp2040.json
index b06e2c09d..23edc5f68 100644
--- a/targets/rp2040.json
+++ b/targets/rp2040.json
@@ -1,6 +1,7 @@
{
"inherits": ["cortex-m0plus"],
"build-tags": ["rp2040", "rp"],
+ "flash-1200-bps-reset": "true",
"flash-method": "msd",
"serial": "usb",
"msd-volume-name": "RPI-RP2",