aboutsummaryrefslogtreecommitdiffstats
path: root/src/rp2040
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2024-10-29 12:28:24 -0400
committerKevin O'Connor <kevin@koconnor.net>2024-11-14 11:24:47 -0500
commitf6718291b78488c46de97888ff5764ed2895a9c6 (patch)
tree51b4122aaad225c0907af1e3d6bf5c9e0ab8d787 /src/rp2040
parent8a203cf2cbd805f627c138a48780183c783451cc (diff)
downloadkutter-f6718291b78488c46de97888ff5764ed2895a9c6.tar.gz
kutter-f6718291b78488c46de97888ff5764ed2895a9c6.tar.xz
kutter-f6718291b78488c46de97888ff5764ed2895a9c6.zip
rp2040: Add rp2350 bootrom based chipid and reboot to bootloader code
This adds the bootrom code needed to implement "reboot into bootloader" and "chipid" capabilities. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/rp2040')
-rw-r--r--src/rp2040/Kconfig2
-rw-r--r--src/rp2040/Makefile9
-rw-r--r--src/rp2040/main.c4
-rw-r--r--src/rp2040/rp2350_bootrom.c59
4 files changed, 65 insertions, 9 deletions
diff --git a/src/rp2040/Kconfig b/src/rp2040/Kconfig
index 2749db08..523ab6d9 100644
--- a/src/rp2040/Kconfig
+++ b/src/rp2040/Kconfig
@@ -10,7 +10,7 @@ config RPXXXX_SELECT
select HAVE_GPIO_SPI
select HAVE_GPIO_I2C
select HAVE_STRICT_TIMING
- select HAVE_CHIPID if MACH_RP2040
+ select HAVE_CHIPID
select HAVE_GPIO_HARD_PWM
select HAVE_STEPPER_BOTH_EDGE
select HAVE_BOOTLOADER_REQUEST
diff --git a/src/rp2040/Makefile b/src/rp2040/Makefile
index 8e2bf57b..f7c38dab 100644
--- a/src/rp2040/Makefile
+++ b/src/rp2040/Makefile
@@ -18,15 +18,14 @@ CFLAGS += -Ilib/pico-sdk/$(MCU)/cmsis_include -Ilib/fast-hash -Ilib/can2040
src-y += rp2040/main.c rp2040/watchdog.c rp2040/gpio.c rp2040/adc.c
src-y += generic/armcm_boot.c generic/armcm_irq.c
src-y += generic/armcm_reset.c generic/crc16_ccitt.c
-chipid-src-$(CONFIG_MACH_RP2040) := rp2040/chipid.c
src-$(CONFIG_MACH_RP2040) += rp2040/timer.c generic/timer_irq.c rp2040/bootrom.c
-src-$(CONFIG_MACH_RP2350) += generic/armcm_timer.c
-src-$(CONFIG_USBSERIAL) += rp2040/usbserial.c generic/usb_cdc.c $(chipid-src-y)
+src-$(CONFIG_MACH_RP2350) += generic/armcm_timer.c rp2040/rp2350_bootrom.c
+src-$(CONFIG_USBSERIAL) += rp2040/usbserial.c generic/usb_cdc.c rp2040/chipid.c
src-$(CONFIG_SERIAL) += rp2040/serial.c generic/serial_irq.c
-src-$(CONFIG_CANSERIAL) += rp2040/can.c $(chipid-src-y) ../lib/can2040/can2040.c
+src-$(CONFIG_CANSERIAL) += rp2040/can.c rp2040/chipid.c ../lib/can2040/can2040.c
src-$(CONFIG_CANSERIAL) += generic/canserial.c generic/canbus.c
src-$(CONFIG_CANSERIAL) += ../lib/fast-hash/fasthash.c
-src-$(CONFIG_USBCANBUS) += rp2040/can.c $(chipid-src-y) ../lib/can2040/can2040.c
+src-$(CONFIG_USBCANBUS) += rp2040/can.c rp2040/chipid.c ../lib/can2040/can2040.c
src-$(CONFIG_USBCANBUS) += generic/canserial.c generic/usb_canbus.c
src-$(CONFIG_USBCANBUS) += ../lib/fast-hash/fasthash.c rp2040/usbserial.c
src-$(CONFIG_HAVE_GPIO_HARD_PWM) += rp2040/hard_pwm.c
diff --git a/src/rp2040/main.c b/src/rp2040/main.c
index 95fa5f15..144b8796 100644
--- a/src/rp2040/main.c
+++ b/src/rp2040/main.c
@@ -49,9 +49,7 @@ bootloader_request(void)
{
watchdog_hw->ctrl = 0;
try_request_canboot();
- // Use the bootrom-provided code to reset into BOOTSEL mode
- if (CONFIG_MACH_RP2040)
- bootrom_reboot_usb_bootloader();
+ bootrom_reboot_usb_bootloader();
}
diff --git a/src/rp2040/rp2350_bootrom.c b/src/rp2040/rp2350_bootrom.c
new file mode 100644
index 00000000..257fb3d4
--- /dev/null
+++ b/src/rp2040/rp2350_bootrom.c
@@ -0,0 +1,59 @@
+// Code for interacting with bootrom on rp235x chips
+//
+// Copyright (C) 2024 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include <stdint.h> // uint32_t
+#include "boot/picoboot_constants.h" // REBOOT2_FLAG_REBOOT_TYPE_BOOTSEL
+#include "hardware/address_mapped.h" // static_assert
+#include "internal.h" // bootrom_read_unique_id
+#include "pico/bootrom_constants.h" // RT_FLAG_FUNC_ARM_NONSEC
+
+static void *
+rom_func_lookup(uint32_t code)
+{
+ typedef void *(*rom_table_lookup_fn)(uint32_t code, uint32_t mask);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+ rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn)
+ (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET);
+#pragma GCC diagnostic pop
+ return rom_table_lookup(code, RT_FLAG_FUNC_ARM_SEC);
+}
+
+
+/****************************************************************
+ * Reboot to USB rom bootloader
+ ****************************************************************/
+
+void
+bootrom_reboot_usb_bootloader(void)
+{
+ typedef int (*rom_reboot_fn)(uint32_t flags, uint32_t delay_ms
+ , uint32_t p0, uint32_t p1);
+ rom_reboot_fn func = rom_func_lookup(ROM_FUNC_REBOOT);
+ func(REBOOT2_FLAG_REBOOT_TYPE_BOOTSEL | REBOOT2_FLAG_NO_RETURN_ON_SUCCESS
+ , 10, 0, 0);
+}
+
+
+/****************************************************************
+ * Unique id reading
+ ****************************************************************/
+
+#define PICO_UNIQUE_BOARD_ID_SIZE_BYTES 8
+
+void
+bootrom_read_unique_id(uint8_t *out, uint32_t maxlen)
+{
+ typedef int (*rom_get_sys_info_fn)(uint8_t *out_buffer
+ , uint32_t out_buffer_word_size
+ , uint32_t flags);
+ rom_get_sys_info_fn func = rom_func_lookup(ROM_FUNC_GET_SYS_INFO);
+ uint8_t data[9 * 4];
+ func(data, 9, SYS_INFO_CHIP_INFO);
+ int i;
+ for (i = 0; i < PICO_UNIQUE_BOARD_ID_SIZE_BYTES; i++)
+ out[i] = data[PICO_UNIQUE_BOARD_ID_SIZE_BYTES - 1 + 2 * 4 - i];
+}