Skip to content

Commit

Permalink
rp2040: Add rp2350 bootrom based chipid and reboot to bootloader code
Browse files Browse the repository at this point in the history
This adds the bootrom code needed to implement "reboot into
bootloader" and "chipid" capabilities.

Signed-off-by: Kevin O'Connor <[email protected]>
  • Loading branch information
KevinOConnor committed Nov 14, 2024
1 parent 8a203cf commit f671829
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/rp2040/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 4 additions & 5 deletions src/rp2040/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions src/rp2040/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}


Expand Down
59 changes: 59 additions & 0 deletions src/rp2040/rp2350_bootrom.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Code for interacting with bootrom on rp235x chips
//
// Copyright (C) 2024 Kevin O'Connor <[email protected]>
//
// 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];
}

0 comments on commit f671829

Please sign in to comment.