diff options
author | sago35 <[email protected]> | 2022-07-14 22:04:31 +0900 |
---|---|---|
committer | Ron Evans <[email protected]> | 2022-07-15 09:41:32 +0200 |
commit | f370cd18fc0279b5465bc4eb80ec748ab8e6858a (patch) | |
tree | db3de06f9678cd5a54045b3e65510c59a87491ee | |
parent | a1d7cab080270d93f0dad1c90b768b7398e30167 (diff) | |
download | tinygo-f370cd18fc0279b5465bc4eb80ec748ab8e6858a.tar.gz tinygo-f370cd18fc0279b5465bc4eb80ec748ab8e6858a.zip |
rp2040: add support for EnterBootloader()
-rw-r--r-- | src/machine/machine_rp2040_enter_bootloader.go | 53 | ||||
-rw-r--r-- | src/machine/machine_rp2040_usb.go | 31 | ||||
-rw-r--r-- | targets/rp2040.json | 1 |
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", |