diff --git a/.github/workflows/choco_packages.config b/.github/workflows/choco_packages.config index d443f751..9f1dea0e 100644 --- a/.github/workflows/choco_packages.config +++ b/.github/workflows/choco_packages.config @@ -2,5 +2,5 @@ - + diff --git a/bazel/config/BUILD.bazel b/bazel/config/BUILD.bazel index 4e622af5..3d75654e 100644 --- a/bazel/config/BUILD.bazel +++ b/bazel/config/BUILD.bazel @@ -186,6 +186,12 @@ int_flag( build_setting_default = 0, ) +# PICO_BAZEL_CONFIG: PICO_TINYUSB_CONFIG, [Bazel only] The library that provides TinyUSB config header (e.g. tusb_config.h), default=//src/rp2_common/pico_stdio_usb:tusb_config, group=build +label_flag( + name = "PICO_TINYUSB_CONFIG", + build_setting_default = "//src/rp2_common/pico_stdio_usb:tusb_config", +) + # PICO_BAZEL_CONFIG: PICO_TINYUSB_LIB, [Bazel only] The library that provides TinyUSB, default=@tinyusb//:tinyusb, group=build label_flag( name = "PICO_TINYUSB_LIB", diff --git a/cmake/pico_pre_load_platform.cmake b/cmake/pico_pre_load_platform.cmake index df9aebdd..ea112757 100644 --- a/cmake/pico_pre_load_platform.cmake +++ b/cmake/pico_pre_load_platform.cmake @@ -122,7 +122,7 @@ if (PICO_PREVIOUS_PLATFORM AND NOT PICO_PREVIOUS_PLATFORM STREQUAL PICO_PLATFORM The best practice is to use separate build directories for different platforms.") endif() set(PICO_PLATFORM ${PICO_PLATFORM} CACHE STRING "PICO Build platform (e.g. rp2040, rp2350, rp2350-riscv, host)" FORCE) -set(PICO_PREVIOUS_PLATFORM ${PICO_PLATFORM} CACHE STRING "Saved PICO Build platform (e.g. rp2040, rp2350, rp2350-riscv, host)" INTERNAL) +set(PICO_PREVIOUS_PLATFORM ${PICO_PLATFORM} CACHE INTERNAL "Saved PICO Build platform (e.g. rp2040, rp2350, rp2350-riscv, host)") # PICO_CMAKE_CONFIG: PICO_CMAKE_PRELOAD_PLATFORM_FILE, Custom CMake file to use to set up the platform environment, type=string, group=build set(PICO_CMAKE_PRELOAD_PLATFORM_FILE ${PICO_CMAKE_PRELOAD_PLATFORM_FILE} CACHE INTERNAL "") diff --git a/docs/index.h b/docs/index.h index b760936c..a4f88a43 100644 --- a/docs/index.h +++ b/docs/index.h @@ -48,9 +48,9 @@ * \cond hardware_watchdog \defgroup hardware_watchdog hardware_watchdog \endcond * \cond hardware_xip_cache \defgroup hardware_xip_cache hardware_xip_cache \endcond * \cond hardware_xosc \defgroup hardware_xosc hardware_xosc \endcond - * \cond hardware_powman hardware_powman - * \cond hardware_hazard3 hardware_hazard3 - * \cond hardware_riscv hardware_riscv + * \cond hardware_powman \defgroup hardware_powman hardware_powman \endcond + * \cond hardware_hazard3 \defgroup hardware_hazard3 hardware_hazard3 \endcond + * \cond hardware_riscv \defgroup hardware_riscv hardware_riscv \endcond * @} * diff --git a/src/BUILD.bazel b/src/BUILD.bazel index 58d564ba..a397b486 100644 --- a/src/BUILD.bazel +++ b/src/BUILD.bazel @@ -19,6 +19,7 @@ alias( "//src/rp2_common/boot_bootrom_headers:__pkg__", "//src/rp2_common/hardware_boot_lock:__pkg__", "//src/rp2_common/pico_flash:__pkg__", + "//src/rp2_common/hardware_rcp:__pkg__", ], ) diff --git a/src/boards/include/boards/amethyst_fpga.h b/src/boards/include/boards/amethyst_fpga.h index ea6b9a2d..190a0767 100644 --- a/src/boards/include/boards/amethyst_fpga.h +++ b/src/boards/include/boards/amethyst_fpga.h @@ -9,8 +9,6 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// FIXME delete this file before release (board file for Amethyst FPGA platform) - // pico_cmake_set PICO_PLATFORM=rp2350 #ifndef _BOARDS_AMETHYST_FPGA_H diff --git a/src/boards/include/boards/eelectronicparts_picomini_16mb.h b/src/boards/include/boards/eelectronicparts_picomini_16mb.h new file mode 100644 index 00000000..52a53081 --- /dev/null +++ b/src/boards/include/boards/eelectronicparts_picomini_16mb.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// +//------------------------------------------------------------------------------------------ +// Board definition for the E Electronic Parts "Pico_Mini RP2040" +// +// This header may be included by other board headers as "boards/eelectronicparts_picomini_16mb.h" + +// pico_cmake_set PICO_PLATFORM=rp2040 + +#ifndef _BOARDS_EELECTRONICPARTS_PICOMINI_16MB_H +#define _BOARDS_EELECTRONICPARTS_PICOMINI_16MB_H + +// For board detection +#define EELECTRONICPARTS_PICOMINI_16MB + +#ifndef PICO_DEFAULT_UART +#define PICO_DEFAULT_UART 0 +#endif +#ifndef PICO_DEFAULT_UART_TX_PIN +#define PICO_DEFAULT_UART_TX_PIN 0 +#endif +#ifndef PICO_DEFAULT_UART_RX_PIN +#define PICO_DEFAULT_UART_RX_PIN 1 +#endif + +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif +#ifndef PICO_DEFAULT_WS2812_PIN +#define PICO_DEFAULT_WS2812_PIN 16 +#endif + +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 0 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 16 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 17 +#endif + +// --- SPI --- +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 1 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 10 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 11 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 12 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 13 +#endif + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +#ifndef PICO_FLASH_SIZE_BYTES +// This board comes in 2MB, 4MB, 8MB, and 16MB variants +#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) +#endif +// All boards have B1 RP2040 + +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif diff --git a/src/boards/include/boards/eelectronicparts_picomini_2mb.h b/src/boards/include/boards/eelectronicparts_picomini_2mb.h new file mode 100644 index 00000000..e0fcab1f --- /dev/null +++ b/src/boards/include/boards/eelectronicparts_picomini_2mb.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// +//------------------------------------------------------------------------------------------ +// Board definition for the E Electronic Parts "Pico_Mini RP2040" +// +// This header may be included by other board headers as "boards/eelectronicparts_picomini_2mb.h" + +// pico_cmake_set PICO_PLATFORM=rp2040 + +#ifndef _BOARDS_EELECTRONICPARTS_PICOMINI_2MB_H +#define _BOARDS_EELECTRONICPARTS_PICOMINI_2MB_H + +// For board detection +#define EELECTRONICPARTS_PICOMINI_2MB + +#ifndef PICO_DEFAULT_UART +#define PICO_DEFAULT_UART 0 +#endif +#ifndef PICO_DEFAULT_UART_TX_PIN +#define PICO_DEFAULT_UART_TX_PIN 0 +#endif +#ifndef PICO_DEFAULT_UART_RX_PIN +#define PICO_DEFAULT_UART_RX_PIN 1 +#endif + +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif +#ifndef PICO_DEFAULT_WS2812_PIN +#define PICO_DEFAULT_WS2812_PIN 16 +#endif + +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 0 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 16 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 17 +#endif + +// --- SPI --- +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 1 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 10 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 11 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 12 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 13 +#endif + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +#ifndef PICO_FLASH_SIZE_BYTES +// This board comes in 2MB, 4MB, 8MB, and 16MB variants +#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) +#endif +// All boards have B1 RP2040 + +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif diff --git a/src/boards/include/boards/eelectronicparts_picomini_4mb.h b/src/boards/include/boards/eelectronicparts_picomini_4mb.h new file mode 100644 index 00000000..132dc0c9 --- /dev/null +++ b/src/boards/include/boards/eelectronicparts_picomini_4mb.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// +//------------------------------------------------------------------------------------------ +// Board definition for the E Electronic Parts "Pico_Mini RP2040" +// +// This header may be included by other board headers as "boards/eelectronicparts_picomini_4mb.h" + +// pico_cmake_set PICO_PLATFORM=rp2040 + +#ifndef _BOARDS_EELECTRONICPARTS_PICOMINI_4MB_H +#define _BOARDS_EELECTRONICPARTS_PICOMINI_4MB_H + +// For board detection +#define EELECTRONICPARTS_PICOMINI_4MB + +#ifndef PICO_DEFAULT_UART +#define PICO_DEFAULT_UART 0 +#endif +#ifndef PICO_DEFAULT_UART_TX_PIN +#define PICO_DEFAULT_UART_TX_PIN 0 +#endif +#ifndef PICO_DEFAULT_UART_RX_PIN +#define PICO_DEFAULT_UART_RX_PIN 1 +#endif + +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif +#ifndef PICO_DEFAULT_WS2812_PIN +#define PICO_DEFAULT_WS2812_PIN 16 +#endif + +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 0 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 16 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 17 +#endif + +// --- SPI --- +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 1 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 10 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 11 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 12 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 13 +#endif + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +#ifndef PICO_FLASH_SIZE_BYTES +// This board comes in 2MB, 4MB, 8MB, and 16MB variants +#define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) +#endif +// All boards have B1 RP2040 + +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif diff --git a/src/boards/include/boards/eelectronicparts_picomini_8mb.h b/src/boards/include/boards/eelectronicparts_picomini_8mb.h new file mode 100644 index 00000000..479e1105 --- /dev/null +++ b/src/boards/include/boards/eelectronicparts_picomini_8mb.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// +//------------------------------------------------------------------------------------------ +// Board definition for the E Electronic Parts "Pico_Mini RP2040" +// +// This header may be included by other board headers as "boards/eelectronicparts_picomini_8mb.h" + +// pico_cmake_set PICO_PLATFORM=rp2040 + +#ifndef _BOARDS_EELECTRONICPARTS_PICOMINI_8MB_H +#define _BOARDS_EELECTRONICPARTS_PICOMINI_8MB_H + +// For board detection +#define EELECTRONICPARTS_PICOMINI_8MB + +#ifndef PICO_DEFAULT_UART +#define PICO_DEFAULT_UART 0 +#endif +#ifndef PICO_DEFAULT_UART_TX_PIN +#define PICO_DEFAULT_UART_TX_PIN 0 +#endif +#ifndef PICO_DEFAULT_UART_RX_PIN +#define PICO_DEFAULT_UART_RX_PIN 1 +#endif + +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif +#ifndef PICO_DEFAULT_WS2812_PIN +#define PICO_DEFAULT_WS2812_PIN 16 +#endif + +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 0 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 16 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 17 +#endif + +// --- SPI --- +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 1 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 10 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 11 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 12 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 13 +#endif + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +#ifndef PICO_FLASH_SIZE_BYTES +// This board comes in 2MB, 4MB, 8MB, and 16MB variants +#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) +#endif +// All boards have B1 RP2040 + +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif diff --git a/src/boards/include/boards/hellbender_0001.h b/src/boards/include/boards/hellbender_0001.h index 9091f912..9f43803e 100644 --- a/src/boards/include/boards/hellbender_0001.h +++ b/src/boards/include/boards/hellbender_0001.h @@ -138,7 +138,7 @@ #define HELLBENDER_0001_BLACKBOX_FLASH_SIZE_BYTES (16 * 1024 * 1024) // --- RP2350 VARIANT --- -#define PICO_RP2350B 1 +#define PICO_RP2350A 0 // pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 #ifndef PICO_RP2350_A2_SUPPORTED diff --git a/src/boards/include/boards/pimoroni_pga2350.h b/src/boards/include/boards/pimoroni_pga2350.h index f4f0a3d2..1bd02dc4 100644 --- a/src/boards/include/boards/pimoroni_pga2350.h +++ b/src/boards/include/boards/pimoroni_pga2350.h @@ -20,6 +20,9 @@ #define PIMORONI_PGA2350 #define PIMORONI_PGA2350_16MB +// --- RP2350 VARIANT --- +#define PICO_RP2350A 0 + // --- BOARD SPECIFIC --- #define PIMORONI_PGA2350_PSRAM_CS_PIN 47 diff --git a/src/boards/include/boards/pimoroni_pico_plus2_rp2350.h b/src/boards/include/boards/pimoroni_pico_plus2_rp2350.h index 34c5fb38..40fff17d 100644 --- a/src/boards/include/boards/pimoroni_pico_plus2_rp2350.h +++ b/src/boards/include/boards/pimoroni_pico_plus2_rp2350.h @@ -19,6 +19,9 @@ // For board detection #define PIMORONI_PICO_PLUS2_RP2350 +// --- RP2350 VARIANT --- +#define PICO_RP2350A 0 + // --- BOARD SPECIFIC --- #define SPCE_SPI 0 #define SPCE_TX_MISO_PIN 32 diff --git a/src/boards/include/boards/pimoroni_pico_plus2_w_rp2350.h b/src/boards/include/boards/pimoroni_pico_plus2_w_rp2350.h index ba3c0e56..7a4f1741 100644 --- a/src/boards/include/boards/pimoroni_pico_plus2_w_rp2350.h +++ b/src/boards/include/boards/pimoroni_pico_plus2_w_rp2350.h @@ -20,6 +20,9 @@ // For board detection #define PIMORONI_PICO_PLUS2_W_RP2350 +// --- RP2350 VARIANT --- +#define PICO_RP2350A 0 + // --- BOARD SPECIFIC --- #define PIMORONI_PICO_PLUS2_W_USER_SW_PIN 45 #define PIMORONI_PICO_PLUS2_W_PSRAM_CS_PIN 47 diff --git a/src/boards/include/boards/seeed_xiao_rp2350.h b/src/boards/include/boards/seeed_xiao_rp2350.h index 52e16365..69a2ba40 100644 --- a/src/boards/include/boards/seeed_xiao_rp2350.h +++ b/src/boards/include/boards/seeed_xiao_rp2350.h @@ -17,6 +17,9 @@ // For board detection #define SEEED_XIAO_RP2350 +// --- RP2350 VARIANT --- +#define PICO_RP2350A 1 + //------------- UART -------------// #ifndef PICO_DEFAULT_UART #define PICO_DEFAULT_UART 0 diff --git a/src/boards/include/boards/sparkfun_xrp_controller.h b/src/boards/include/boards/sparkfun_xrp_controller.h new file mode 100644 index 00000000..70c2f13c --- /dev/null +++ b/src/boards/include/boards/sparkfun_xrp_controller.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2024 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// Board definition for the SparkFun XRP Controller +// +// This header may be included by other board headers as "boards/sparkfun_xrp_controller.h" + +// pico_cmake_set PICO_PLATFORM=rp2350 +// pico_cmake_set PICO_CYW43_SUPPORTED = 1 + +#ifndef _BOARDS_SPARKFUN_XRP_CONTROLLER_H +#define _BOARDS_SPARKFUN_XRP_CONTROLLER_H + +// For board detection +#define SPARKFUN_XRP_CONTROLLER + +// --- RP2350 VARIANT --- +#define PICO_RP2350A 0 + +// --- UART --- +#ifndef PICO_DEFAULT_UART +#define PICO_DEFAULT_UART 0 +#endif +#ifndef PICO_DEFAULT_UART_TX_PIN +#define PICO_DEFAULT_UART_TX_PIN 12 +#endif +#ifndef PICO_DEFAULT_UART_RX_PIN +#define PICO_DEFAULT_UART_RX_PIN 13 +#endif + +// --- LED --- +// no PICO_DEFAULT_LED_PIN - LED is on Wireless chip +#ifndef PICO_DEFAULT_WS2812_PIN +#define PICO_DEFAULT_WS2812_PIN 37 +#endif + +// --- I2C --- Qwiic connector is on these pins +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 0 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 4 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 5 +#endif + +// --- SPI --- +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 0 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 18 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 19 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 16 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 17 +#endif + +// --- FLASH --- + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) +#endif + +#ifndef CYW43_WL_GPIO_COUNT +#define CYW43_WL_GPIO_COUNT 3 +#endif + +#ifndef CYW43_WL_GPIO_LED_PIN +#define CYW43_WL_GPIO_LED_PIN 0 +#endif + +// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +// cyw43 SPI pins can't be changed at runtime +#ifndef CYW43_PIN_WL_DYNAMIC +#define CYW43_PIN_WL_DYNAMIC 0 +#endif + +// gpio pin to power up the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_REG_ON +#define CYW43_DEFAULT_PIN_WL_REG_ON 26u +#endif + +// gpio pin for spi data out to the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_DATA_OUT +#define CYW43_DEFAULT_PIN_WL_DATA_OUT 29u +#endif + +// gpio pin for spi data in from the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_DATA_IN +#define CYW43_DEFAULT_PIN_WL_DATA_IN 29u +#endif + +// gpio (irq) pin for the irq line from the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_HOST_WAKE +#define CYW43_DEFAULT_PIN_WL_HOST_WAKE 29u +#endif + +// gpio pin for the spi clock line to the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_CLOCK +#define CYW43_DEFAULT_PIN_WL_CLOCK 28u +#endif + +// gpio pin for the spi chip select to the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_CS +#define CYW43_DEFAULT_PIN_WL_CS 27u +#endif + +#endif diff --git a/src/cmake/rp2_common.cmake b/src/cmake/rp2_common.cmake index 726bab93..9e6f9f3f 100644 --- a/src/cmake/rp2_common.cmake +++ b/src/cmake/rp2_common.cmake @@ -82,6 +82,7 @@ endif() # Basic bootrom headers pico_add_subdirectory(rp2_common/boot_bootrom_headers) +pico_add_subdirectory(rp2_common/pico_platform_common) pico_add_subdirectory(rp2_common/pico_platform_compiler) pico_add_subdirectory(rp2_common/pico_platform_sections) pico_add_subdirectory(rp2_common/pico_platform_panic) diff --git a/src/common/pico_base_headers/BUILD.bazel b/src/common/pico_base_headers/BUILD.bazel index 5525c309..c22f9ae8 100644 --- a/src/common/pico_base_headers/BUILD.bazel +++ b/src/common/pico_base_headers/BUILD.bazel @@ -112,6 +112,7 @@ cc_library( "//src/rp2_common/hardware_watchdog:__pkg__", "//src/rp2_common/hardware_xosc:__pkg__", "//src/rp2_common/pico_crt0:__pkg__", + "//src/rp2_common/pico_platform_common:__pkg__", "//src/rp2_common/pico_printf:__pkg__", "//src/rp2_common/pico_runtime:__pkg__", "//src/rp2_common/pico_runtime_init:__pkg__", diff --git a/src/common/pico_base_headers/include/pico/types.h b/src/common/pico_base_headers/include/pico/types.h index 2e9c3964..010181ee 100644 --- a/src/common/pico_base_headers/include/pico/types.h +++ b/src/common/pico_base_headers/include/pico/types.h @@ -23,18 +23,18 @@ typedef unsigned int uint; #endif /*! \typedef absolute_time_t - \brief An opaque 64 bit timestamp in microseconds - - The type is used instead of a raw uint64_t to prevent accidentally passing relative times or times in the wrong - time units where an absolute time is required. - - note: As of SDK 2.0.0 this type defaults to being a uin64_t (i.e. no protection); it is enabled - by setting PICO_OPAQUE_ABSOLUTE_TIME_T to 1 - - \see to_us_since_boot() - \see update_us_since_boot() - \ingroup timestamp -*/ + * \brief An opaque 64 bit timestamp in microseconds + * + * The type is used instead of a raw uint64_t to prevent accidentally passing relative times or times in the wrong + * time units where an absolute time is required. + * + * note: As of SDK 2.0.0 this type defaults to being a uin64_t (i.e. no protection); it is enabled + * by setting PICO_OPAQUE_ABSOLUTE_TIME_T to 1 + * + * \see to_us_since_boot() + * \see update_us_since_boot() + * \ingroup timestamp + */ #if PICO_OPAQUE_ABSOLUTE_TIME_T typedef struct { uint64_t _private_us_since_boot; diff --git a/src/common/pico_sync/include/pico/critical_section.h b/src/common/pico_sync/include/pico/critical_section.h index 0e9907a9..9874f9ff 100644 --- a/src/common/pico_sync/include/pico/critical_section.h +++ b/src/common/pico_sync/include/pico/critical_section.h @@ -7,6 +7,7 @@ #ifndef _PICO_CRITICAL_SECTION_H #define _PICO_CRITICAL_SECTION_H +#include "pico.h" #include "pico/lock_core.h" #ifdef __cplusplus @@ -58,7 +59,7 @@ void critical_section_init_with_lock_num(critical_section_t *crit_sec, uint lock * * \param crit_sec Pointer to critical_section structure */ -static inline void critical_section_enter_blocking(critical_section_t *crit_sec) { +__force_inline static void critical_section_enter_blocking(critical_section_t *crit_sec) { crit_sec->save = spin_lock_blocking(crit_sec->spin_lock); } @@ -67,7 +68,7 @@ static inline void critical_section_enter_blocking(critical_section_t *crit_sec) * * \param crit_sec Pointer to critical_section structure */ -static inline void critical_section_exit(critical_section_t *crit_sec) { +__force_inline static void critical_section_exit(critical_section_t *crit_sec) { spin_unlock(crit_sec->spin_lock, crit_sec->save); } diff --git a/src/common/pico_time/include/pico/time.h b/src/common/pico_time/include/pico/time.h index 771fe42d..43d5ed7a 100644 --- a/src/common/pico_time/include/pico/time.h +++ b/src/common/pico_time/include/pico/time.h @@ -216,7 +216,7 @@ static inline bool is_nil_time(absolute_time_t t) { * \note These functions should not be called from an IRQ handler. * * \note Lower powered sleep requires use of the \link alarm_pool_get_default default alarm pool\endlink which may - * be disabled by the PICO_TIME_DEFAULT_ALARM_POOL_DISABLED #define or currently full in which case these functions + * be disabled by the PICO_TIME_DEFAULT_ALARM_POOL_DISABLED \#define or currently full in which case these functions * become busy waits instead. * * \note Whilst \a sleep_ functions are preferable to \a busy_wait functions from a power perspective, the \a busy_wait equivalent function @@ -420,7 +420,7 @@ alarm_pool_timer_t *alarm_pool_get_default_timer(void); * \param max_timers the maximum number of timers * \note For implementation reasons this is limited to PICO_PHEAP_MAX_ENTRIES which defaults to 255 * \sa alarm_pool_get_default() - * \sa hardware_claiming + * \sa hardware_claim */ static inline alarm_pool_t *alarm_pool_create(uint timer_alarm_num, uint max_timers) { return alarm_pool_create_on_timer(alarm_pool_get_default_timer(), timer_alarm_num, max_timers); @@ -443,7 +443,7 @@ alarm_pool_t *alarm_pool_create_on_timer_with_unused_hardware_alarm(alarm_pool_t * \param max_timers the maximum number of timers * \note For implementation reasons this is limited to PICO_PHEAP_MAX_ENTRIES which defaults to 255 * \sa alarm_pool_get_default() - * \sa hardware_claiming + * \sa hardware_claim */ static inline alarm_pool_t *alarm_pool_create_with_unused_hardware_alarm(uint max_timers) { return alarm_pool_create_on_timer_with_unused_hardware_alarm(alarm_pool_get_default_timer(), max_timers); diff --git a/src/host/hardware_irq/include/hardware/irq.h b/src/host/hardware_irq/include/hardware/irq.h index 0e881b7a..ef90ee70 100644 --- a/src/host/hardware_irq/include/hardware/irq.h +++ b/src/host/hardware_irq/include/hardware/irq.h @@ -128,7 +128,7 @@ extern "C" { typedef void (*irq_handler_t)(void); static inline void check_irq_param(__unused uint num) { - invalid_params_if(HARDWARE_IRQ, num >= NUM_IRQS); + invalid_params_if(HARDWARE_IRQ, num >= PICO_NUM_VTABLE_IRQS); } /*! \brief Set specified interrupt's priority diff --git a/src/host/hardware_irq/irq.c b/src/host/hardware_irq/irq.c index ad793c19..db452ab1 100644 --- a/src/host/hardware_irq/irq.c +++ b/src/host/hardware_irq/irq.c @@ -96,7 +96,7 @@ void PICO_WEAK_FUNCTION_IMPL_NAME(irq_init_priorities)() { } static uint get_user_irq_claim_index(uint irq_num) { - invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= NUM_IRQS); + invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= PICO_NUM_VTABLE_IRQS); // we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31 static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today. return NUM_IRQS - irq_num - 1u; diff --git a/src/host/pico_platform/include/pico/platform.h b/src/host/pico_platform/include/pico/platform.h index 2854ab6f..0338354e 100644 --- a/src/host/pico_platform/include/pico/platform.h +++ b/src/host/pico_platform/include/pico/platform.h @@ -60,6 +60,12 @@ extern void tight_loop_contents(); #define __noinline __attribute__((noinline)) #endif +#ifndef __force_inline +// don't think it is critical to inline in host mode, and this is simpler than picking the +// correct attribute incantation for always_inline on different compiler versions +#define __force_inline inline +#endif + #ifndef __aligned #define __aligned(x) __attribute__((aligned(x))) #endif diff --git a/src/rp2040/hardware_regs/RP2040.svd b/src/rp2040/hardware_regs/RP2040.svd index 2bac8265..50a5a93f 100644 --- a/src/rp2040/hardware_regs/RP2040.svd +++ b/src/rp2040/hardware_regs/RP2040.svd @@ -51022,5 +51022,38 @@ SPDX-License-Identifier: BSD-3-Clause + + SPARE_IRQ + 0x00000000 + + 0 + 4 + reserved + + + SPARE_IRQ_0 + 26 + + + SPARE_IRQ_1 + 27 + + + SPARE_IRQ_2 + 28 + + + SPARE_IRQ_3 + 29 + + + SPARE_IRQ_4 + 30 + + + SPARE_IRQ_5 + 31 + + diff --git a/src/rp2040/hardware_regs/include/hardware/regs/intctrl.h b/src/rp2040/hardware_regs/include/hardware/regs/intctrl.h index 3190b413..71c6eb90 100644 --- a/src/rp2040/hardware_regs/include/hardware/regs/intctrl.h +++ b/src/rp2040/hardware_regs/include/hardware/regs/intctrl.h @@ -39,6 +39,12 @@ #define I2C0_IRQ 23 #define I2C1_IRQ 24 #define RTC_IRQ 25 +#define SPARE_IRQ_0 26 +#define SPARE_IRQ_1 27 +#define SPARE_IRQ_2 28 +#define SPARE_IRQ_3 29 +#define SPARE_IRQ_4 30 +#define SPARE_IRQ_5 31 #else /** * \brief Interrupt numbers on RP2040 (used as typedef \ref irq_num_t) @@ -71,6 +77,12 @@ typedef enum irq_num_rp2040 { I2C0_IRQ = 23, ///< Select I2C0's IRQ output I2C1_IRQ = 24, ///< Select I2C1's IRQ output RTC_IRQ = 25, ///< Select RTC's IRQ output + SPARE_IRQ_0 = 26, ///< Select SPARE IRQ 0 + SPARE_IRQ_1 = 27, ///< Select SPARE IRQ 1 + SPARE_IRQ_2 = 28, ///< Select SPARE IRQ 2 + SPARE_IRQ_3 = 29, ///< Select SPARE IRQ 3 + SPARE_IRQ_4 = 30, ///< Select SPARE IRQ 4 + SPARE_IRQ_5 = 31, ///< Select SPARE IRQ 5 IRQ_COUNT } irq_num_t; #endif @@ -101,6 +113,12 @@ typedef enum irq_num_rp2040 { #define isr_i2c0 isr_irq23 #define isr_i2c1 isr_irq24 #define isr_rtc isr_irq25 +#define isr_spare_0 isr_irq26 +#define isr_spare_1 isr_irq27 +#define isr_spare_2 isr_irq28 +#define isr_spare_3 isr_irq29 +#define isr_spare_4 isr_irq30 +#define isr_spare_5 isr_irq31 #endif // _INTCTRL_H diff --git a/src/rp2040/pico_platform/BUILD.bazel b/src/rp2040/pico_platform/BUILD.bazel index bc860f1f..47b90e43 100644 --- a/src/rp2040/pico_platform/BUILD.bazel +++ b/src/rp2040/pico_platform/BUILD.bazel @@ -27,6 +27,7 @@ cc_library( deps = [ "//src/rp2040/hardware_regs", "//src/rp2040/hardware_regs:platform_defs", + "//src/rp2_common/pico_platform_common:pico_platform_common_headers", "//src/rp2_common/pico_platform_compiler", "//src/rp2_common/pico_platform_panic:pico_platform_panic_headers", "//src/rp2_common/pico_platform_sections", @@ -44,6 +45,7 @@ cc_library( "//src/rp2040/hardware_regs", "//src/rp2040/hardware_regs:platform_defs", "//src/rp2_common/hardware_base", + "//src/rp2_common/pico_platform_common", "//src/rp2_common/pico_platform_compiler", "//src/rp2_common/pico_platform_panic", "//src/rp2_common/pico_platform_sections", diff --git a/src/rp2040/pico_platform/CMakeLists.txt b/src/rp2040/pico_platform/CMakeLists.txt index f7c607a4..9c91df3e 100644 --- a/src/rp2040/pico_platform/CMakeLists.txt +++ b/src/rp2040/pico_platform/CMakeLists.txt @@ -17,6 +17,7 @@ if (NOT TARGET pico_platform) target_link_libraries(pico_platform_headers INTERFACE hardware_regs) pico_mirrored_target_link_libraries(pico_platform INTERFACE + pico_platform_common pico_platform_compiler pico_platform_panic pico_platform_sections diff --git a/src/rp2040/pico_platform/include/pico/platform.h b/src/rp2040/pico_platform/include/pico/platform.h index 5c157f53..437ff31f 100644 --- a/src/rp2040/pico_platform/include/pico/platform.h +++ b/src/rp2040/pico_platform/include/pico/platform.h @@ -23,6 +23,7 @@ #include "pico/platform/compiler.h" #include "pico/platform/sections.h" #include "pico/platform/panic.h" +#include "pico/platform/common.h" #include "hardware/regs/addressmap.h" #include "hardware/regs/sio.h" @@ -66,10 +67,6 @@ #define PICO_RP2040_B2_SUPPORTED 1 #endif -#ifndef PICO_RAM_VECTOR_TABLE_SIZE -#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS) -#endif - // PICO_CONFIG: PICO_CLKDIV_ROUND_NEAREST, True if floating point clock divisors should be rounded to the nearest possible clock divisor by default rather than rounding down, type=bool, default=1, group=pico_platform #ifndef PICO_CLKDIV_ROUND_NEAREST #define PICO_CLKDIV_ROUND_NEAREST 1 @@ -80,16 +77,6 @@ #ifdef __cplusplus extern "C" { #endif - -/*! \brief No-op function for the body of tight loops - * \ingroup pico_platform - * - * No-op function intended to be called by any tight hardware polling loop. Using this ubiquitously - * makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup - * debugging might be added - */ -static __force_inline void tight_loop_contents(void) {} - /*! \brief Helper method to busy-wait for at least the given number of cycles * \ingroup pico_platform * @@ -112,17 +99,6 @@ static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) { ); } -// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime -#ifndef PICO_NO_FPGA_CHECK -#define PICO_NO_FPGA_CHECK 1 -#endif - -#if PICO_NO_FPGA_CHECK -static inline bool running_on_fpga(void) {return false;} -#else -bool running_on_fpga(void); -#endif - /*! \brief Execute a breakpoint instruction * \ingroup pico_platform */ @@ -158,9 +134,6 @@ static __force_inline uint __get_current_exception(void) { return exception; } -#define host_safe_hw_ptr(x) ((uintptr_t)(x)) -#define native_safe_hw_ptr(x) host_safe_hw_ptr(x) - /*! \brief Returns the RP2040 chip revision number * \ingroup pico_platform * @return the RP2040 chip revision number (1 for B0/B1, 2 for B2) diff --git a/src/rp2040/pico_platform/platform.c b/src/rp2040/pico_platform/platform.c index 9b001653..5468670d 100644 --- a/src/rp2040/pico_platform/platform.c +++ b/src/rp2040/pico_platform/platform.c @@ -6,23 +6,8 @@ #include "pico.h" #include "hardware/address_mapped.h" -#include "hardware/regs/tbman.h" #include "hardware/regs/sysinfo.h" -// Note we leave the FPGA check in by default so that we can run bug repro -// binaries coming in from the wild on the FPGA platform. It takes up around -// 48 bytes if you include all the calls, so you can pass PICO_NO_FPGA_CHECK=1 -// to remove it. The FPGA check is used to skip initialisation of hardware -// (mainly clock generators and oscillators) that aren't present on FPGA. - -#if !PICO_NO_FPGA_CHECK -// Inline stub provided in header if this code is unused (so folding can be -// done in each TU instead of relying on LTO) -bool running_on_fpga(void) { - return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS; -} -#endif - #define MANUFACTURER_RPI 0x927 #define PART_RP2 0x2 diff --git a/src/rp2350/hardware_regs/RP2350.svd b/src/rp2350/hardware_regs/RP2350.svd index fc6479eb..c942b3a5 100644 --- a/src/rp2350/hardware_regs/RP2350.svd +++ b/src/rp2350/hardware_regs/RP2350.svd @@ -105846,5 +105846,40 @@ SPDX-License-Identifier: BSD-3-Clause + + + SPARE_IRQ + 0x00000000 + + 0 + 4 + reserved + + + SPARE_IRQ_0 + 46 + + + SPARE_IRQ_1 + 47 + + + SPARE_IRQ_2 + 48 + + + SPARE_IRQ_3 + 49 + + + SPARE_IRQ_4 + 50 + + + SPARE_IRQ_5 + 51 + + + diff --git a/src/rp2350/hardware_regs/include/hardware/regs/intctrl.h b/src/rp2350/hardware_regs/include/hardware/regs/intctrl.h index 96ce815e..4db58399 100644 --- a/src/rp2350/hardware_regs/include/hardware/regs/intctrl.h +++ b/src/rp2350/hardware_regs/include/hardware/regs/intctrl.h @@ -59,12 +59,12 @@ #define PLL_USB_IRQ 43 #define POWMAN_IRQ_POW 44 #define POWMAN_IRQ_TIMER 45 -#define SPAREIRQ_IRQ_0 46 -#define SPAREIRQ_IRQ_1 47 -#define SPAREIRQ_IRQ_2 48 -#define SPAREIRQ_IRQ_3 49 -#define SPAREIRQ_IRQ_4 50 -#define SPAREIRQ_IRQ_5 51 +#define SPARE_IRQ_0 46 +#define SPARE_IRQ_1 47 +#define SPARE_IRQ_2 48 +#define SPARE_IRQ_3 49 +#define SPARE_IRQ_4 50 +#define SPARE_IRQ_5 51 #else /** * \brief Interrupt numbers on RP2350 (used as typedef \ref irq_num_t) diff --git a/src/rp2350/pico_platform/BUILD.bazel b/src/rp2350/pico_platform/BUILD.bazel index 8b51a2dd..b24291a2 100644 --- a/src/rp2350/pico_platform/BUILD.bazel +++ b/src/rp2350/pico_platform/BUILD.bazel @@ -27,6 +27,7 @@ cc_library( deps = [ "//src/rp2350/hardware_regs", "//src/rp2350/hardware_regs:platform_defs", + "//src/rp2_common/pico_platform_common:pico_platform_common_headers", "//src/rp2_common/pico_platform_compiler", "//src/rp2_common/pico_platform_panic:pico_platform_panic_headers", "//src/rp2_common/pico_platform_sections", @@ -44,6 +45,7 @@ cc_library( "//src/rp2350/hardware_regs", "//src/rp2350/hardware_regs:platform_defs", "//src/rp2_common/hardware_base", + "//src/rp2_common/pico_platform_common", "//src/rp2_common/pico_platform_compiler", "//src/rp2_common/pico_platform_panic", "//src/rp2_common/pico_platform_sections", diff --git a/src/rp2350/pico_platform/CMakeLists.txt b/src/rp2350/pico_platform/CMakeLists.txt index 80a5103e..7f875bf3 100644 --- a/src/rp2350/pico_platform/CMakeLists.txt +++ b/src/rp2350/pico_platform/CMakeLists.txt @@ -23,6 +23,7 @@ if (NOT TARGET pico_platform) hardware_regs ) pico_mirrored_target_link_libraries(pico_platform INTERFACE + pico_platform_common pico_platform_compiler pico_platform_panic pico_platform_sections diff --git a/src/rp2350/pico_platform/include/pico/platform.h b/src/rp2350/pico_platform/include/pico/platform.h index 35a6a0bd..571efd8b 100644 --- a/src/rp2350/pico_platform/include/pico/platform.h +++ b/src/rp2350/pico_platform/include/pico/platform.h @@ -23,13 +23,14 @@ #include "pico/platform/compiler.h" #include "pico/platform/sections.h" #include "pico/platform/panic.h" +#include "pico/platform/common.h" #include "hardware/regs/addressmap.h" #include "hardware/regs/sio.h" #ifdef __riscv #include "hardware/regs/rvcsr.h" #endif -// PICO_CONFIG: PICO_RP2350A, Whether the current board has an RP2350 in an A (30 GPIO) package, type=bool, default=Usually provided via board header, group=pico_platform +// PICO_CONFIG: PICO_RP2350A, Whether the current board has an RP2350 in an A (30 GPIO) package - set to 0 for RP2350 in a B (48 GPIO) package, type=bool, default=Usually provided via board header, group=pico_platform #if 0 // make tooling checks happy #define PICO_RP2350A 0 #endif @@ -54,10 +55,6 @@ #define PICO_NO_RAM_VECTOR_TABLE 0 #endif -#ifndef PICO_RAM_VECTOR_TABLE_SIZE -#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS) -#endif - // PICO_CONFIG: PICO_USE_STACK_GUARDS, Enable/disable stack guards, type=bool, default=0, advanced=true, group=pico_platform #ifndef PICO_USE_STACK_GUARDS #define PICO_USE_STACK_GUARDS 0 @@ -73,16 +70,6 @@ #ifdef __cplusplus extern "C" { #endif - -/*! \brief No-op function for the body of tight loops - * \ingroup pico_platform - * - * No-op function intended to be called by any tight hardware polling loop. Using this ubiquitously - * makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup - * debugging might be added - */ -static __force_inline void tight_loop_contents(void) {} - /*! \brief Helper method to busy-wait for at least the given number of cycles * \ingroup pico_platform * @@ -116,27 +103,6 @@ static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) { ); } -// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime -#ifndef PICO_NO_FPGA_CHECK -#define PICO_NO_FPGA_CHECK 1 -#endif - -// PICO_CONFIG: PICO_NO_SIM_CHECK, Remove the SIM platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime -#ifndef PICO_NO_SIM_CHECK -#define PICO_NO_SIM_CHECK 1 -#endif - -#if PICO_NO_FPGA_CHECK -static inline bool running_on_fpga(void) {return false;} -#else -bool running_on_fpga(void); -#endif -#if PICO_NO_SIM_CHECK -static inline bool running_in_sim(void) {return false;} -#else -bool running_in_sim(void); -#endif - /*! \brief Execute a breakpoint instruction * \ingroup pico_platform */ @@ -221,9 +187,6 @@ __force_inline static bool pico_processor_state_is_nonsecure(void) { #endif } -#define host_safe_hw_ptr(x) ((uintptr_t)(x)) -#define native_safe_hw_ptr(x) host_safe_hw_ptr(x) - /*! \brief Returns the RP2350 chip revision number * \ingroup pico_platform * @return the RP2350 chip revision number (1 for B0/B1, 2 for B2) diff --git a/src/rp2350/pico_platform/platform.c b/src/rp2350/pico_platform/platform.c index 97960478..a71b8a0a 100644 --- a/src/rp2350/pico_platform/platform.c +++ b/src/rp2350/pico_platform/platform.c @@ -6,28 +6,8 @@ #include "pico.h" #include "hardware/address_mapped.h" -#include "hardware/regs/tbman.h" #include "hardware/regs/sysinfo.h" -// Note we leave the FPGA check in by default so that we can run bug repro -// binaries coming in from the wild on the FPGA platform. It takes up around -// 48 bytes if you include all the calls, so you can pass PICO_NO_FPGA_CHECK=1 -// to remove it. The FPGA check is used to skip initialisation of hardware -// (mainly clock generators and oscillators) that aren't present on FPGA. - -#if !PICO_NO_FPGA_CHECK -// Inline stub provided in header if this code is unused (so folding can be -// done in each TU instead of relying on LTO) -bool __attribute__((weak)) running_on_fpga(void) { - return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS; -} -#endif -#if !PICO_NO_SIM_CHECK -bool __attribute__((weak)) running_in_sim(void) { - return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_HDLSIM_BITS; -} -#endif - #define MANUFACTURER_RPI 0x926 #define PART_RP4 0x4 @@ -36,9 +16,9 @@ uint8_t rp2350_chip_version(void) { uint32_t chip_id = *((io_ro_32*)(SYSINFO_BASE + SYSINFO_CHIP_ID_OFFSET)); uint32_t __unused manufacturer = chip_id & SYSINFO_CHIP_ID_MANUFACTURER_BITS; uint32_t __unused part = (chip_id & SYSINFO_CHIP_ID_PART_BITS) >> SYSINFO_CHIP_ID_PART_LSB; - assert(manufacturer == MANUFACTURER_RPI); - assert(part == PART_RP4); + assert(manufacturer == MANUFACTURER_RPI && part == PART_RP4); // 0 == A0, 1 == A1, 2 == A2 - uint version = (chip_id & SYSINFO_CHIP_ID_REVISION_BITS) >> SYSINFO_CHIP_ID_REVISION_LSB; + uint32_t version = (chip_id & SYSINFO_CHIP_ID_REVISION_BITS) >> SYSINFO_CHIP_ID_REVISION_LSB; + version = (version & 3u) | ((version & 8u) >> 1); return (uint8_t)version; } \ No newline at end of file diff --git a/src/rp2_common/hardware_dma/include/hardware/dma.h b/src/rp2_common/hardware_dma/include/hardware/dma.h index 94b74cb7..27dd9228 100644 --- a/src/rp2_common/hardware_dma/include/hardware/dma.h +++ b/src/rp2_common/hardware_dma/include/hardware/dma.h @@ -123,7 +123,7 @@ int dma_claim_unused_channel(bool required); * \param channel the dma channel * \return true if the channel is claimed, false otherwise * \see dma_channel_claim - * \see dma_channel_claim_mask + * \see dma_claim_mask */ bool dma_channel_is_claimed(uint channel); diff --git a/src/rp2_common/hardware_exception/exception.c b/src/rp2_common/hardware_exception/exception.c index d3134fbc..52a5b64c 100644 --- a/src/rp2_common/hardware_exception/exception.c +++ b/src/rp2_common/hardware_exception/exception.c @@ -31,12 +31,14 @@ static inline exception_handler_t *get_exception_table(void) { #endif } +#if !PICO_NO_RAM_VECTOR_TABLE static void set_raw_exception_handler_and_restore_interrupts(enum exception_number num, exception_handler_t handler, uint32_t save) { // update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness) get_exception_table()[num] = handler; __dmb(); restore_interrupts_from_disabled(save); } +#endif static inline void check_exception_param(__unused enum exception_number num) { invalid_params_if(HARDWARE_EXCEPTION, num < MIN_EXCEPTION_NUM || num > MAX_EXCEPTION_NUM); @@ -54,10 +56,12 @@ exception_handler_t exception_set_exclusive_handler(enum exception_number num, e exception_handler_t current = exception_get_vtable_handler(num); hard_assert(handler == current || exception_is_compile_time_default(current)); set_raw_exception_handler_and_restore_interrupts(num, handler, save); + return current; #else + ((void)num); + ((void)handler); panic_unsupported(); #endif - return current; } void exception_restore_handler(enum exception_number num, exception_handler_t original_handler) { @@ -66,6 +70,8 @@ void exception_restore_handler(enum exception_number num, exception_handler_t or uint32_t save = save_and_disable_interrupts(); set_raw_exception_handler_and_restore_interrupts(num, original_handler, save); #else + ((void)num); + ((void)original_handler); panic_unsupported(); #endif } diff --git a/src/rp2_common/hardware_gpio/include/hardware/gpio.h b/src/rp2_common/hardware_gpio/include/hardware/gpio.h index bd1f4b68..f05bc000 100644 --- a/src/rp2_common/hardware_gpio/include/hardware/gpio.h +++ b/src/rp2_common/hardware_gpio/include/hardware/gpio.h @@ -204,6 +204,11 @@ enum gpio_irq_level { */ typedef void (*gpio_irq_callback_t)(uint gpio, uint32_t event_mask); +/*! \brief GPIO override modes + * \ingroup hardware_gpio + * + * \sa gpio_set_irqover, gpio_set_outover, gpio_set_inover, gpio_set_oeover + */ enum gpio_override { GPIO_OVERRIDE_NORMAL = 0, ///< peripheral signal selected via \ref gpio_set_function GPIO_OVERRIDE_INVERT = 1, ///< invert peripheral signal selected via \ref gpio_set_function @@ -782,6 +787,8 @@ static inline void gpio_add_raw_irq_handler(uint gpio, irq_handler_t handler) { * * This method removes such a callback, and enables the "default" callback for the specified GPIOs. * + * \note You should always use the same gpio_mask as you used when you added the raw IRQ handler. + * * @param gpio_mask a bit mask of the GPIO numbers that will now be passed to the default callback for this core * @param handler the handler to remove from the list of GPIO IRQ handlers for this core */ diff --git a/src/rp2_common/hardware_i2c/include/hardware/i2c.h b/src/rp2_common/hardware_i2c/include/hardware/i2c.h index 604b89f9..5453752e 100644 --- a/src/rp2_common/hardware_i2c/include/hardware/i2c.h +++ b/src/rp2_common/hardware_i2c/include/hardware/i2c.h @@ -324,10 +324,10 @@ int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t * (for example) without having to send address byte(s) repeatedly * * \param i2c Either \ref i2c0 or \ref i2c1 - * \param addr 7-bit address of device to read from - * \param dst Pointer to buffer to receive data - * \param len Length of data in bytes to receive - * \return Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged or no device present. + * \param addr 7-bit address of device to write to + * \param src Pointer to data to send + * \param len Length of data in bytes to send + * \return Number of bytes written, or PICO_ERROR_GENERIC if address not acknowledged or no device present. */ int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len); diff --git a/src/rp2_common/hardware_interp/include/hardware/interp.h b/src/rp2_common/hardware_interp/include/hardware/interp.h index 634af0f4..befe1f8c 100644 --- a/src/rp2_common/hardware_interp/include/hardware/interp.h +++ b/src/rp2_common/hardware_interp/include/hardware/interp.h @@ -107,7 +107,7 @@ void interp_unclaim_lane(interp_hw_t *interp, uint lane); */ bool interp_lane_is_claimed(interp_hw_t *interp, uint lane); -/*! \brief Release previously claimed interpolator lanes \see interp_claim_lane_mask +/*! \brief Release previously claimed interpolator lanes, see \ref interp_claim_lane_mask * \ingroup hardware_interp * * \param interp Interpolator on which to release lanes. interp0 or interp1 diff --git a/src/rp2_common/hardware_irq/include/hardware/irq.h b/src/rp2_common/hardware_irq/include/hardware/irq.h index d671903d..0dcc49d5 100644 --- a/src/rp2_common/hardware_irq/include/hardware/irq.h +++ b/src/rp2_common/hardware_irq/include/hardware/irq.h @@ -195,7 +195,7 @@ extern "C" { typedef void (*irq_handler_t)(void); static inline void check_irq_param(__unused uint num) { - invalid_params_if(HARDWARE_IRQ, num >= NUM_IRQS); + invalid_params_if(HARDWARE_IRQ, num >= PICO_NUM_VTABLE_IRQS); } /*! \brief Set specified interrupt's priority diff --git a/src/rp2_common/hardware_irq/irq.c b/src/rp2_common/hardware_irq/irq.c index b06db13c..9b6f5ecd 100644 --- a/src/rp2_common/hardware_irq/irq.c +++ b/src/rp2_common/hardware_irq/irq.c @@ -15,6 +15,12 @@ PICO_RUNTIME_INIT_FUNC_PER_CORE(runtime_init_per_core_irq_priorities, PICO_RUNTIME_INIT_PER_CORE_IRQ_PRIORITIES); #endif +static_assert(IRQ_COUNT == NUM_IRQS, ""); +// "USER IRQs" use the spare irq numbers +#if NUM_USER_IRQS +static_assert(IRQ_COUNT - NUM_USER_IRQS == SPARE_IRQ_0, ""); +#endif + #if PICO_VTABLE_PER_CORE static uint8_t user_irq_claimed[NUM_CORES]; static inline uint8_t *user_irq_claimed_ptr(void) { @@ -51,13 +57,6 @@ static inline void *remove_thumb_bit(void *addr) { #endif } -static void set_raw_irq_handler_and_unlock(uint num, irq_handler_t handler, uint32_t save) { - // update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness) - get_vtable()[VTABLE_FIRST_IRQ + num] = handler; - __dmb(); - spin_unlock(spin_lock_instance(PICO_SPINLOCK_ID_IRQ), save); -} - void irq_set_enabled(uint num, bool enabled) { check_irq_param(num); // really should update irq_set_mask_enabled? @@ -76,7 +75,7 @@ bool irq_is_enabled(uint num) { } static inline void irq_set_mask_n_enabled_internal(uint n, uint32_t mask, bool enabled) { - invalid_params_if(HARDWARE_IRQ, n * 32u >= ((NUM_IRQS + 31u) & ~31u)); + invalid_params_if(HARDWARE_IRQ, n * 32u >= ((PICO_NUM_VTABLE_IRQS + 31u) & ~31u)); #if defined(__riscv) if (enabled) { hazard3_irqarray_clear(RVCSR_MEIFA_OFFSET, 2 * n, mask & 0xffffu); @@ -129,7 +128,7 @@ void irq_set_pending(uint num) { #endif } -#if !PICO_DISABLE_SHARED_IRQ_HANDLERS +#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE // limited by 8 bit relative links (and reality) static_assert(PICO_MAX_SHARED_IRQ_HANDLERS >= 1 && PICO_MAX_SHARED_IRQ_HANDLERS < 0x7f, ""); @@ -197,31 +196,38 @@ static inline bool is_shared_irq_raw_handler(irq_handler_t raw_handler) { return (uintptr_t)raw_handler - (uintptr_t)irq_handler_chain_slots < sizeof(irq_handler_chain_slots); } -bool irq_has_handler(uint irq_num) { - check_irq_param(irq_num); - irq_handler_t handler = irq_get_vtable_handler(irq_num); - return handler && handler != __unhandled_user_irq; -} - bool irq_has_shared_handler(uint irq_num) { check_irq_param(irq_num); irq_handler_t handler = irq_get_vtable_handler(irq_num); return is_shared_irq_raw_handler(handler); } -#else // PICO_DISABLE_SHARED_IRQ_HANDLERS +static void set_raw_irq_handler_and_unlock(uint num, irq_handler_t handler, uint32_t save) { + // update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness) + get_vtable()[VTABLE_FIRST_IRQ + num] = handler; + __dmb(); + spin_unlock(spin_lock_instance(PICO_SPINLOCK_ID_IRQ), save); +} + +#else // PICO_DISABLE_SHARED_IRQ_HANDLERS && PICO_NO_RAM_VECTOR_TABLE #define is_shared_irq_raw_handler(h) false bool irq_has_shared_handler(uint irq_num) { + ((void)irq_num); return false; } #endif - irq_handler_t irq_get_vtable_handler(uint num) { check_irq_param(num); return get_vtable()[VTABLE_FIRST_IRQ + num]; } +bool irq_has_handler(uint irq_num) { + check_irq_param(irq_num); + irq_handler_t handler = irq_get_vtable_handler(irq_num); + return handler && handler != __unhandled_user_irq; +} + void irq_set_exclusive_handler(uint num, irq_handler_t handler) { check_irq_param(num); #if !PICO_NO_RAM_VECTOR_TABLE @@ -231,6 +237,7 @@ void irq_set_exclusive_handler(uint num, irq_handler_t handler) { hard_assert(current == __unhandled_user_irq || current == handler); set_raw_irq_handler_and_unlock(num, handler, save); #else + ((void)handler); panic_unsupported(); #endif } @@ -252,7 +259,7 @@ irq_handler_t irq_get_exclusive_handler(uint num) { } -#if !PICO_DISABLE_SHARED_IRQ_HANDLERS +#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE #ifndef __riscv @@ -362,6 +369,8 @@ static inline int8_t get_slot_index(struct irq_handler_chain_slot *slot) { void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority) { check_irq_param(num); #if PICO_NO_RAM_VECTOR_TABLE + ((void)handler); + ((void)order_priority); panic_unsupported(); #elif PICO_DISABLE_SHARED_IRQ_HANDLERS irq_set_exclusive_handler(num, handler); @@ -455,7 +464,7 @@ void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_prior #endif // !PICO_NO_RAM_VECTOR_TABLE && !PICO_DISABLE_SHARED_IRQ_HANDLERS } -#if !PICO_DISABLE_SHARED_IRQ_HANDLERS +#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE static inline irq_handler_t handler_from_slot(struct irq_handler_chain_slot *slot) { #ifndef __riscv return slot->handler; @@ -580,6 +589,8 @@ void irq_remove_handler(uint num, irq_handler_t handler) { } set_raw_irq_handler_and_unlock(num, vtable_handler, save); #else + ((void)num); + ((void)handler); panic_unsupported(); #endif } @@ -620,7 +631,7 @@ uint irq_get_priority(uint num) { #endif } -#if !PICO_DISABLE_SHARED_IRQ_HANDLERS +#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE // used by irq_handler_chain.S to remove the last link in a handler chain after it executes // note this must be called only with the last slot in a chain (and during the exception) void irq_add_tail_to_free_list(struct irq_handler_chain_slot *slot) { @@ -664,7 +675,7 @@ __weak void runtime_init_per_core_irq_priorities(void) { *p++ = prio4; } #else - for (uint i = 0; i < NUM_IRQS; ++i) { + for (uint i = 0; i < PICO_NUM_VTABLE_IRQS; ++i) { irq_set_priority(i, PICO_DEFAULT_IRQ_PRIORITY); } #endif @@ -672,7 +683,7 @@ __weak void runtime_init_per_core_irq_priorities(void) { } static uint get_user_irq_claim_index(uint irq_num) { - invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= NUM_IRQS); + invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= PICO_NUM_VTABLE_IRQS); // we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31 static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today. return NUM_IRQS - irq_num - 1u; diff --git a/src/rp2_common/hardware_pio/include/hardware/pio.h b/src/rp2_common/hardware_pio/include/hardware/pio.h index b1173309..8654d32a 100644 --- a/src/rp2_common/hardware_pio/include/hardware/pio.h +++ b/src/rp2_common/hardware_pio/include/hardware/pio.h @@ -680,7 +680,7 @@ static inline void sm_config_set_out_shift(pio_sm_config *c, bool shift_right, b * \ingroup sm_config * * \param c Pointer to the configuration structure to modify - * \param join Specifies the join type. \see enum pio_fifo_join + * \param join Specifies the join type. See \ref pio_fifo_join */ static inline void sm_config_set_fifo_join(pio_sm_config *c, enum pio_fifo_join join) { valid_params_if(HARDWARE_PIO, join == PIO_FIFO_JOIN_NONE || join == PIO_FIFO_JOIN_TX || join == PIO_FIFO_JOIN_RX @@ -720,7 +720,7 @@ static inline void sm_config_set_out_special(pio_sm_config *c, bool sticky, bool * \ingroup sm_config * * \param c Pointer to the configuration structure to modify - * \param status_sel the status operation selector. \see enum pio_mov_status_type + * \param status_sel the status operation selector. See \ref pio_mov_status_type * \param status_n parameter for the mov status operation (currently a bit count) */ static inline void sm_config_set_mov_status(pio_sm_config *c, enum pio_mov_status_type status_sel, uint status_n) { @@ -849,7 +849,7 @@ static inline uint pio_get_index(PIO pio) { * * \param pio The PIO instance; e.g. \ref pio0 or \ref pio1 * \return the PIO instance number (0, 1, ...) - * \see gpio_function + * \see gpio_function_t */ static inline uint pio_get_funcsel(PIO pio) { check_pio_param(pio); @@ -948,7 +948,7 @@ bool pio_can_add_program_at_offset(PIO pio, const pio_program_t *program, uint o /*! \brief Attempt to load the program * \ingroup hardware_pio * - * \see pio_can_add_program() if you need to check whether the program can be loaded + * See pio_can_add_program() if you need to check whether the program can be loaded * * \param pio The PIO instance; e.g. \ref pio0 or \ref pio1 * \param program the program definition @@ -960,7 +960,7 @@ int pio_add_program(PIO pio, const pio_program_t *program); /*! \brief Attempt to load the program at the specified instruction memory offset * \ingroup hardware_pio * - * \see pio_can_add_program_at_offset() if you need to check whether the program can be loaded + * See pio_can_add_program_at_offset() if you need to check whether the program can be loaded * * \param pio The PIO instance; e.g. \ref pio0 or \ref pio1 * \param program the program definition @@ -998,7 +998,7 @@ void pio_clear_instruction_memory(PIO pio); * * The state machine is left disabled on return from this call. * -* * \if rp2350_specific + * \if rp2350_specific * See \ref sm_config_pins "sm_config_ pins" for more detail on why this method might fail on RP2350B * \endif * @@ -1006,7 +1006,7 @@ void pio_clear_instruction_memory(PIO pio); * \param sm State machine index (0..3) * \param initial_pc the initial program memory offset to run from * \param config the configuration to apply (or NULL to apply defaults) - * \return PICO_OK, or < 0 for an error (see \enum pico_error_codes) + * \return PICO_OK, or < 0 for an error (see \ref pico_error_codes) */ int pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config); @@ -1029,7 +1029,7 @@ static inline void pio_sm_set_enabled(PIO pio, uint sm, bool enabled) { * Note that this method just sets the enabled state of the state machine; * if now enabled they continue exactly from where they left off. * - * \see pio_enable_sm_mask_in_sync() if you wish to enable multiple state machines + * See pio_enable_sm_mask_in_sync() if you wish to enable multiple state machines * and ensure their clock dividers are in sync. * * \param pio The PIO instance; e.g. \ref pio0 or \ref pio1 @@ -1049,7 +1049,7 @@ static inline void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled) * Note that this method just sets the enabled state of the state machine; * if now enabled they continue exactly from where they left off. * - * \see pio_enable_sm_mask_in_sync() if you wish to enable multiple state machines + * See pio_enable_sm_mask_in_sync() if you wish to enable multiple state machines * and ensure their clock dividers are in sync. * * \param pio The PIO instance; e.g. \ref pio0 or \ref pio1 @@ -1419,7 +1419,7 @@ static inline uint8_t pio_sm_get_pc(PIO pio, uint sm) { * * This instruction is executed instead of the next instruction in the normal control flow on the state machine. * Subsequent calls to this method replace the previous executed - * instruction if it is still running. \see pio_sm_is_exec_stalled() to see if an executed instruction + * instruction if it is still running. See pio_sm_is_exec_stalled() to see if an executed instruction * is still running (i.e. it is stalled on some condition) * * \param pio The PIO instance; e.g. \ref pio0 or \ref pio1 @@ -1450,7 +1450,7 @@ static inline bool pio_sm_is_exec_stalled(PIO pio, uint sm) { * * This instruction is executed instead of the next instruction in the normal control flow on the state machine. * Subsequent calls to this method replace the previous executed - * instruction if it is still running. \see pio_sm_is_exec_stalled() to see if an executed instruction + * instruction if it is still running. See pio_sm_is_exec_stalled() to see if an executed instruction * is still running (i.e. it is stalled on some condition) * * \param pio The PIO instance; e.g. \ref pio0 or \ref pio1 @@ -1982,7 +1982,7 @@ bool pio_sm_is_claimed(PIO pio, uint sm); * \param sm Returns the index of the PIO state machine that was claimed * \param offset Returns the instruction memory offset of the start of the program * \return true on success, false otherwise - * \see pio_remove_program_unclaim_sm + * \see pio_remove_program_and_unclaim_sm */ bool pio_claim_free_sm_and_add_program(const pio_program_t *program, PIO *pio, uint *sm, uint *offset); @@ -1994,7 +1994,7 @@ bool pio_claim_free_sm_and_add_program(const pio_program_t *program, PIO *pio, u * PIO instance can interact with both pins 0->15 or 32->47 at the same time. * * This method takes additional information about the GPIO pins needed (via gpio_base and gpio_count), - * and optionally will set the GPIO base (\see pio_set_gpio_base) of an unused PIO instance if necessary + * and optionally will set the GPIO base (see \ref pio_set_gpio_base) of an unused PIO instance if necessary * * \param program PIO program to add * \param pio Returns the PIO hardware instance or NULL if no PIO is available @@ -2006,7 +2006,7 @@ bool pio_claim_free_sm_and_add_program(const pio_program_t *program, PIO *pio, u * instance, then that PIO will be reconfigured so that this method can succeed * * \return true on success, false otherwise - * \see pio_remove_program_unclaim_sm + * \see pio_remove_program_and_unclaim_sm */ bool pio_claim_free_sm_and_add_program_for_gpio_range(const pio_program_t *program, PIO *pio, uint *sm, uint *offset, uint gpio_base, uint gpio_count, bool set_gpio_base); diff --git a/src/rp2_common/hardware_rcp/BUILD.bazel b/src/rp2_common/hardware_rcp/BUILD.bazel index 750ae819..6f8be1be 100644 --- a/src/rp2_common/hardware_rcp/BUILD.bazel +++ b/src/rp2_common/hardware_rcp/BUILD.bazel @@ -2,6 +2,19 @@ load("//bazel:defs.bzl", "compatible_with_rp2") package(default_visibility = ["//visibility:public"]) +# Picotool needs this (transitively through +# //src/rp2_common/pico_bootrom:pico_bootrom_headers), so we can't strictly +# constrain compatibility. +cc_library( + name = "hardware_rcp_headers", + hdrs = ["include/hardware/rcp.h"], + includes = ["include"], + visibility = ["//src/rp2_common/pico_bootrom:__pkg__"], + deps = [ + "//src:pico_platform_internal", + ], +) + cc_library( name = "hardware_rcp", hdrs = ["include/hardware/rcp.h"], diff --git a/src/rp2_common/hardware_rcp/include/hardware/rcp.h b/src/rp2_common/hardware_rcp/include/hardware/rcp.h index b75f182d..64c88c5a 100644 --- a/src/rp2_common/hardware_rcp/include/hardware/rcp.h +++ b/src/rp2_common/hardware_rcp/include/hardware/rcp.h @@ -15,13 +15,15 @@ */ // ---------------------------------------------------------------------------- -// RCP instructions (this header is Arm-only) -#if defined(PICO_RP2350) && !defined(__riscv) +// RCP masks +#if !PICO_RP2040 #define RCP_MASK_TRUE _u(0xa500a500) #define RCP_MASK_FALSE _u(0x00c300c3) #define RCP_MASK_INTXOR _u(0x96009600) +// RCP instructions (these instructions are Arm-only) +#if HAS_REDUNDANCY_COPROCESSOR // ---------------------------------------------------------------------------- // Macros and inline functions for use in C files #ifndef __ASSEMBLER__ @@ -994,7 +996,8 @@ rcp_switch_u8_to_ch_cl rcp_canary_check_nodelay_impl \tag, \x cdp p7, #0, c0, c0, c0, #1 .endm -#endif // !__riscv +#endif // HAS_REDUNDANCY_COPROCESSOR +#endif // !PICO_RP2040 #endif // __ASSEMBLER__ // ---------------------------------------------------------------------------- diff --git a/src/rp2_common/hardware_resets/include/hardware/resets.h b/src/rp2_common/hardware_resets/include/hardware/resets.h index 8baef728..f7577571 100644 --- a/src/rp2_common/hardware_resets/include/hardware/resets.h +++ b/src/rp2_common/hardware_resets/include/hardware/resets.h @@ -23,6 +23,8 @@ * * Multiple blocks are referred to using a bitmask as follows: * + * \if rp2040_specific + * For RP2040: * Block to reset | Bit * ---------------|---- * USB | 24 @@ -41,15 +43,51 @@ * PIO 1 | 11 * PIO 0 | 10 * Pads - QSPI | 9 - * Pads - bank 0 | 8 + * Pads - Bank 0 | 8 * JTAG | 7 - * IO Bank 1 | 6 + * IO QSPI | 6 * IO Bank 0 | 5 * I2C 1 | 4 * I2C 0 | 3 * DMA | 2 * Bus Control | 1 * ADC 0 | 0 + * \endif + * + * \if rp2350_specific + * For RP2350: + * Block to reset | Bit + * ---------------|---- + * USB | 28 + * UART 1 | 27 + * UART 0 | 26 + * TRNG | 25 + * Timer 1 | 24 + * Timer 0 | 23 + * TB Manager | 22 + * SysInfo | 21 + * System Config | 20 + * SPI 1 | 19 + * SPI 0 | 18 + * SHA256 | 17 + * PWM | 16 + * PLL USB | 15 + * PLL System | 14 + * PIO 2 | 13 + * PIO 1 | 12 + * PIO 0 | 11 + * Pads - QSPI | 10 + * Pads - Bank 0 | 9 + * JTAG | 8 + * IO QSPI | 7 + * IO Bank 0 | 6 + * I2C 1 | 5 + * I2C 0 | 4 + * HSTX | 3 + * DMA | 2 + * Bus Control | 1 + * ADC 0 | 0 + * \endif * * \subsection reset_example Example * \addtogroup hardware_resets diff --git a/src/rp2_common/hardware_sha256/include/hardware/sha256.h b/src/rp2_common/hardware_sha256/include/hardware/sha256.h index db8fca6f..dcbf1043 100644 --- a/src/rp2_common/hardware_sha256/include/hardware/sha256.h +++ b/src/rp2_common/hardware_sha256/include/hardware/sha256.h @@ -122,7 +122,7 @@ static inline bool sha256_is_sum_valid(void) { * \ingroup hardware_sha256 * * After writing 64 bytes of data to the hardware, it will be unable to accept more data for a time. - * Call this to check if the hardware is ready for more data to be written. \see sha256_err_not_ready + * Call this to check if the hardware is ready for more data to be written. See \ref sha256_err_not_ready * * \return True if the hardware is ready to receive more data */ diff --git a/src/rp2_common/hardware_spi/include/hardware/spi.h b/src/rp2_common/hardware_spi/include/hardware/spi.h index cf79645d..bd83770c 100644 --- a/src/rp2_common/hardware_spi/include/hardware/spi.h +++ b/src/rp2_common/hardware_spi/include/hardware/spi.h @@ -202,7 +202,7 @@ uint spi_set_baudrate(spi_inst_t *spi, uint baudrate); /*! \brief Get SPI baudrate * \ingroup hardware_spi * - * Get SPI baudrate which was set by \see spi_set_baudrate + * Get SPI baudrate which was set by \ref spi_set_baudrate * * \param spi SPI instance specifier, either \ref spi0 or \ref spi1 * \return The actual baudrate set diff --git a/src/rp2_common/hardware_timer/include/hardware/timer.h b/src/rp2_common/hardware_timer/include/hardware/timer.h index 289a28a3..b2696408 100644 --- a/src/rp2_common/hardware_timer/include/hardware/timer.h +++ b/src/rp2_common/hardware_timer/include/hardware/timer.h @@ -351,7 +351,7 @@ typedef void (*hardware_alarm_callback_t)(uint alarm_num); * \param timer the timer instance * \param alarm_num the hardware alarm to claim * \sa hardware_alarm_claim - * \sa hardware_claiming + * \sa hardware_claim */ void timer_hardware_alarm_claim(timer_hw_t *timer, uint alarm_num); @@ -362,7 +362,7 @@ void timer_hardware_alarm_claim(timer_hw_t *timer, uint alarm_num); * * \param alarm_num the hardware alarm to claim * \sa timer_hardware_alarm_claim - * \sa hardware_claiming + * \sa hardware_claim */ void hardware_alarm_claim(uint alarm_num); @@ -375,7 +375,7 @@ void hardware_alarm_claim(uint alarm_num); * \param required if true the function will panic if none are available * \return alarm_num the hardware alarm claimed or -1 if required was false, and none are available * \sa hardware_alarm_claim_unused - * \sa hardware_claiming + * \sa hardware_claim */ int timer_hardware_alarm_claim_unused(timer_hw_t *timer, bool required); @@ -387,7 +387,7 @@ int timer_hardware_alarm_claim_unused(timer_hw_t *timer, bool required); * \param required if true the function will panic if none are available * \return alarm_num the hardware alarm claimed or -1 if required was false, and none are available * \sa timer_hardware_alarm_claim_unused - * \sa hardware_claiming + * \sa hardware_claim */ int hardware_alarm_claim_unused(bool required); @@ -397,7 +397,7 @@ int hardware_alarm_claim_unused(bool required); * \param timer the timer instance * \param alarm_num the hardware alarm to unclaim * \sa hardware_alarm_unclaim - * \sa hardware_claiming + * \sa hardware_claim */ void timer_hardware_alarm_unclaim(timer_hw_t *timer, uint alarm_num); @@ -406,7 +406,7 @@ void timer_hardware_alarm_unclaim(timer_hw_t *timer, uint alarm_num); * * \param alarm_num the hardware alarm to unclaim * \sa timer_hardware_alarm_unclaim - * \sa hardware_claiming + * \sa hardware_claim */ void hardware_alarm_unclaim(uint alarm_num); diff --git a/src/rp2_common/pico_async_context/include/pico/async_context.h b/src/rp2_common/pico_async_context/include/pico/async_context.h index 6f7c4f0d..8a19b9ca 100644 --- a/src/rp2_common/pico_async_context/include/pico/async_context.h +++ b/src/rp2_common/pico_async_context/include/pico/async_context.h @@ -84,8 +84,8 @@ typedef struct async_context async_context_t; * A "timeout" represents some future action that must be taken at a specific time. * Its methods are called from the async_context under lock at the given time * - * \see async_context_add_worker_at - * \see async_context_add_worker_in_ms + * \see async_context_add_at_time_worker_at + * \see async_context_add_at_time_worker_in_ms */ typedef struct async_work_on_timeout { /*! @@ -119,8 +119,8 @@ typedef struct async_work_on_timeout { * to some external stimulus (usually an IRQ). * Its methods are called from the async_context under lock at the given time * - * \see async_context_add_worker_at - * \see async_context_add_worker_in_ms + * \see async_context_add_at_time_worker_at + * \see async_context_add_at_time_worker_in_ms */ typedef struct async_when_pending_worker { /*! diff --git a/src/rp2_common/pico_bootrom/BUILD.bazel b/src/rp2_common/pico_bootrom/BUILD.bazel index 53a24b10..1463216d 100644 --- a/src/rp2_common/pico_bootrom/BUILD.bazel +++ b/src/rp2_common/pico_bootrom/BUILD.bazel @@ -18,6 +18,7 @@ cc_library( "//src/rp2_common/boot_bootrom_headers", "//src/rp2_common/hardware_boot_lock:hardware_boot_lock_headers", "//src/rp2_common/pico_flash:pico_flash_headers", + "//src/rp2_common/hardware_rcp:hardware_rcp_headers", ] + select({ "//bazel/constraint:host": ["//src/host/hardware_sync"], "//conditions:default": ["//src/rp2_common/hardware_sync"], diff --git a/src/rp2_common/pico_bootrom/bootrom.c b/src/rp2_common/pico_bootrom/bootrom.c index 1120f006..cedc27fc 100644 --- a/src/rp2_common/pico_bootrom/bootrom.c +++ b/src/rp2_common/pico_bootrom/bootrom.c @@ -7,6 +7,9 @@ #include "pico/bootrom.h" #include "boot/picoboot.h" #include "boot/picobin.h" +#if !PICO_RP2040 +#include "hardware/rcp.h" +#endif /// \tag::table_lookup[] @@ -108,4 +111,89 @@ int rom_add_flash_runtime_partition(uint32_t start_offset, uint32_t size, uint32 } return PICO_ERROR_INSUFFICIENT_RESOURCES; } + +int rom_pick_ab_update_partition(uint32_t *workarea_base, uint32_t workarea_size, uint partition_a_num) { +#if PICO_RP2350 + // Generated from adding the following code into the bootrom + // scan_workarea_t* scan_workarea = (scan_workarea_t*)workarea; + // printf("VERSION_DOWNGRADE_ERASE_ADDR %08x\n", &(always->zero_init.version_downgrade_erase_flash_addr)); + // printf("TBYB_FLAG_ADDR %08x\n", &(always->zero_init.tbyb_flag_flash_addr)); + // printf("IMAGE_DEF_VERIFIED %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.verified) - (uint32_t)scan_workarea); + // printf("IMAGE_DEF_TBYB_FLAGGED %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.tbyb_flagged) - (uint32_t)scan_workarea); + // printf("IMAGE_DEF_BASE %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.enclosing_window.base) - (uint32_t)scan_workarea); + // printf("IMAGE_DEF_REL_BLOCK_OFFSET %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.window_rel_block_offset) - (uint32_t)scan_workarea); + #define VERSION_DOWNGRADE_ERASE_ADDR *(uint32_t*)0x400e0338 + #define TBYB_FLAG_ADDR *(uint32_t*)0x400e0348 + #define IMAGE_DEF_VERIFIED(scan_workarea) *(uint32_t*)(0x64 + (uint32_t)scan_workarea) + #define IMAGE_DEF_TBYB_FLAGGED(scan_workarea) *(bool*)(0x4c + (uint32_t)scan_workarea) + #define IMAGE_DEF_BASE(scan_workarea) *(uint32_t*)(0x54 + (uint32_t)scan_workarea) + #define IMAGE_DEF_REL_BLOCK_OFFSET(scan_workarea) *(uint32_t*)(0x5c + (uint32_t)scan_workarea) +#else + // Prevent linting errors + #define VERSION_DOWNGRADE_ERASE_ADDR *(uint32_t*)NULL + #define TBYB_FLAG_ADDR *(uint32_t*)NULL + #define IMAGE_DEF_VERIFIED(scan_workarea) *(uint32_t*)(NULL + (uint32_t)scan_workarea) + #define IMAGE_DEF_TBYB_FLAGGED(scan_workarea) *(bool*)(NULL + (uint32_t)scan_workarea) + #define IMAGE_DEF_BASE(scan_workarea) *(uint32_t*)(NULL + (uint32_t)scan_workarea) + #define IMAGE_DEF_REL_BLOCK_OFFSET(scan_workarea) *(uint32_t*)(NULL + (uint32_t)scan_workarea) + + panic_unsupported(); +#endif + + uint32_t flash_update_base = 0; + bool tbyb_boot = false; + uint32_t saved_erase_addr = 0; + if (rom_get_last_boot_type() == BOOT_TYPE_FLASH_UPDATE) { + // For a flash update boot, get the flash update base + boot_info_t boot_info = {}; + int ret = rom_get_boot_info(&boot_info); + if (ret) { + flash_update_base = boot_info.reboot_params[0]; + if (boot_info.tbyb_and_update_info & BOOT_TBYB_AND_UPDATE_FLAG_BUY_PENDING) { + // A buy is pending, so the main software has not been bought + tbyb_boot = true; + // Save the erase address, as this will be overwritten by rom_pick_ab_partition + saved_erase_addr = VERSION_DOWNGRADE_ERASE_ADDR; + } + } + } + + int rc = rom_pick_ab_partition((uint8_t*)workarea_base, workarea_size, partition_a_num, flash_update_base); + + if (IMAGE_DEF_VERIFIED(workarea_base) != RCP_MASK_TRUE) { + // Chosen partition failed verification + return BOOTROM_ERROR_NOT_FOUND; + } + + if (IMAGE_DEF_TBYB_FLAGGED(workarea_base)) { + // The chosen partition is TBYB + if (tbyb_boot) { + // The boot partition is also TBYB - cannot update both, so prioritise boot partition + // Restore the erase address saved earlier + VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr; + return BOOTROM_ERROR_NOT_PERMITTED; + } else { + // Update the tbyb flash address, so that explicit_buy will clear the flag for the chosen partition + TBYB_FLAG_ADDR = + IMAGE_DEF_BASE(workarea_base) + + IMAGE_DEF_REL_BLOCK_OFFSET(workarea_base) + 4; + } + } else { + // The chosen partition is not TBYB + if (tbyb_boot && saved_erase_addr) { + // The boot partition was TBYB, and requires an erase + if (VERSION_DOWNGRADE_ERASE_ADDR) { + // But both the chosen partition requires an erase too + // As before, prioritise the boot partition, and restore it's saved erase_address + VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr; + return BOOTROM_ERROR_NOT_PERMITTED; + } else { + // The chosen partition doesn't require an erase, so we're fine + VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr; + } + } + } + + return rc; +} #endif \ No newline at end of file diff --git a/src/rp2_common/pico_bootrom/include/pico/bootrom.h b/src/rp2_common/pico_bootrom/include/pico/bootrom.h index bb5b8ba2..db2f23d2 100644 --- a/src/rp2_common/pico_bootrom/include/pico/bootrom.h +++ b/src/rp2_common/pico_bootrom/include/pico/bootrom.h @@ -749,6 +749,9 @@ static inline int rom_load_partition_table(uint8_t *workarea_base, uint32_t work * * NOTE: This method does not look at owner partitions, only the A partition passed and it's corresponding B partition. * + * NOTE: You should not call this method directly when performing a Flash Update Boot before calling `explicit_buy`, as it may prevent + * any version downgrade from occuring - instead see \ref rom_pick_ab_update_partition() which wraps this function. + * * \param workarea_base base address of work area * \param workarea_size size of work area * \param partition_a_num the A partition of the pair @@ -1091,6 +1094,30 @@ static inline int rom_get_last_boot_type(void) { */ int rom_add_flash_runtime_partition(uint32_t start_offset, uint32_t size, uint32_t permissions); +/*! \brief Pick A/B partition without disturbing any in progress update or TBYB boot + * \ingroup pico_bootrom + * + * This will call `rom_pick_ab_partition` using the `flash_update_boot_window_base` from the current boot, while performing extra checks to prevent disrupting + * a main image TBYB boot. It requires the same minimum workarea size as `rom_pick_ab_partition`. + * \see rom_pick_ab_partition() + * + * For example, if an `explicit_buy` is pending then calling `pick_ab_partition` would normally clear the saved flash erase address for the version downgrade, + * so the required erase of the other partition would not occur when `explicit_buy` is called - this function saves and restores that address to prevent this + * issue, and returns `BOOTROM_ERROR_NOT_PERMITTED` if the partition chosen by `pick_ab_partition` also requires a flash erase version downgrade (as you can't + * erase 2 partitions with one `explicit_buy` call). + * + * It also checks that the chosen partition contained a valid image (e.g. a signed image when using secure boot), and returns `BOOTROM_ERROR_NOT_FOUND` + * if it does not. + * + * \param workarea_base base address of work area + * \param workarea_size size of work area + * \param partition_a_num the A partition of the pair + * \return >= 0 the partition number picked + * BOOTROM_ERROR_NOT_PERMITTED if not possible to do an update correctly, e.g. if both main image and data image are TBYB + * BOOTROM_ERROR_NOT_FOUND if the chosen partition failed verification + */ +int rom_pick_ab_update_partition(uint32_t *workarea_base, uint32_t workarea_size, uint partition_a_num); + #endif #ifdef __cplusplus diff --git a/src/rp2_common/pico_btstack/CMakeLists.txt b/src/rp2_common/pico_btstack/CMakeLists.txt index 010cc9e3..dcfcad4f 100644 --- a/src/rp2_common/pico_btstack/CMakeLists.txt +++ b/src/rp2_common/pico_btstack/CMakeLists.txt @@ -308,6 +308,9 @@ if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) find_package (Python3 REQUIRED COMPONENTS Interpreter) get_filename_component(GATT_NAME "${GATT_FILE}" NAME_WE) get_filename_component(GATT_PATH "${GATT_FILE}" PATH) + if (NOT GATT_PATH) + set(GATT_PATH "${CMAKE_CURRENT_LIST_DIR}") + endif() set(TARGET_GATT "${TARGET_LIB}_gatt_header") set(GATT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated/${TARGET_GATT}") set(GATT_HEADER "${GATT_BINARY_DIR}/${GATT_NAME}.h") diff --git a/src/rp2_common/pico_crt0/crt0.S b/src/rp2_common/pico_crt0/crt0.S index e408b7de..eb477bd1 100644 --- a/src/rp2_common/pico_crt0/crt0.S +++ b/src/rp2_common/pico_crt0/crt0.S @@ -23,14 +23,23 @@ pico_default_asm_setup +#ifdef PICO_NO_STORED_VECTOR_TABLE +#warning PICO_NO_STORED_VECTOR_TABLE is no longer used. PICO_MINIMAL_STORED_VECTOR_TABLE is not identical but usually serves the same purpose +#endif + .section .vectors, "ax" .align 2 -.global __vectors, __VECTOR_TABLE +.global __vectors, __VECTOR_TABLE, __vectors_end __VECTOR_TABLE: __vectors: .word __StackTop .word _reset_handler + +#if PICO_MINIMAL_STORED_VECTOR_TABLE +.word isr_invalid // NMI +.word isr_invalid // HardFault +#else .word isr_nmi .word isr_hardfault .word isr_invalid // Reserved, should never fire @@ -45,15 +54,9 @@ __vectors: .word isr_invalid // Reserved, should never fire .word isr_pendsv .word isr_systick -#if PICO_NO_STORED_VECTOR_TABLE && !PICO_NO_FLASH // note in no flash binary, we only have the single RAM vector table anyway -#if PICO_NO_RAM_VECTOR_TABLE -#error Can't specify PICO_NO_STORED_VECTOR_TABLE and PICO_NO_RAM_VECTOR_TABLE -#endif -// we don't include any IRQ vectors; we will initialize them during runtime_init in the RAM vector table -#else .macro if_irq_word num func -.if \num < NUM_IRQS +.if \num < PICO_NUM_VTABLE_IRQS .word \func .endif .endm @@ -142,10 +145,11 @@ if_irq_word 76 isr_irq76 if_irq_word 77 isr_irq77 if_irq_word 78 isr_irq78 if_irq_word 79 isr_irq79 -#if NUM_IRQS > 80 +#if PICO_NUM_VTABLE_IRQS > 80 #error more IRQ entries required #endif -#endif +#endif // #if !PICO_MINIMAL_STORED_VECTOR_TABLE +__vectors_end: // all default exception handlers do nothing, and we can check for them being set to our // default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end @@ -164,24 +168,14 @@ __default_isrs_start: bkpt #0 .endm -// these are separated out for clarity -decl_isr_bkpt isr_invalid -decl_isr_bkpt isr_nmi -decl_isr_bkpt isr_hardfault -decl_isr_bkpt isr_svcall -decl_isr_bkpt isr_pendsv -decl_isr_bkpt isr_systick - -.global __default_isrs_end -__default_isrs_end: - .altmacro .macro decl_isr name -#if !PICO_NO_STORED_VECTOR_TABLE | PICO_NO_FLASH +#if !PICO_MINIMAL_STORED_VECTOR_TABLE | PICO_NO_FLASH // We declare a weak label, so user can override .weak \name #else -// We declare a strong label, so user can't override (their version would not automatically be used) +// We declare a strong global label, so user can't override (their version would not automatically be used) +.global \name #endif .type \name,%function .thumb_func @@ -189,8 +183,14 @@ __default_isrs_end: .endm .macro if_irq_decl num func -.if \num < NUM_IRQS +.if \num < PICO_NUM_VTABLE_IRQS decl_isr \func +.elseif \num < NUM_IRQS +// We declare a strong global label, so user can't override (their version would not automatically be used) +.global \func +.type \func,%function +.thumb_func +\func: .endif .endm @@ -274,7 +274,7 @@ if_irq_decl 76 isr_irq76 if_irq_decl 77 isr_irq77 if_irq_decl 78 isr_irq78 if_irq_decl 79 isr_irq79 -#if NUM_IRQS > 80 +#if PICO_NUM_VTABLE_IRQS > 80 #error more IRQ entries required #endif @@ -282,12 +282,30 @@ if_irq_decl 79 isr_irq79 .global __unhandled_user_irq .thumb_func __unhandled_user_irq: +// if we include the implementation if there could be a valid IRQ hanler in the vtable that uses it +#if !(PICO_NO_RAM_VECTOR_TABLE && PICO_MINIMAL_STORED_VECTOR_TABLE) mrs r0, ipsr subs r0, #16 .global unhandled_user_irq_num_in_r0 unhandled_user_irq_num_in_r0: +#endif + // note the next instruction is a breakpoint too, however we have a 2 byte alignment hole + // and it is preferrable to have distinct labels, to inform the user what has happened in the debugger. bkpt #0 +decl_isr_bkpt isr_invalid +#if !PICO_MINIMAL_STORED_VECTOR_TABLE +// these are separated out for clarity +decl_isr_bkpt isr_nmi +decl_isr_bkpt isr_hardfault +decl_isr_bkpt isr_svcall +decl_isr_bkpt isr_pendsv +decl_isr_bkpt isr_systick +#endif + +.global __default_isrs_end +__default_isrs_end: + // ---------------------------------------------------------------------------- .section .binary_info_header, "a" diff --git a/src/rp2_common/pico_crt0/crt0_riscv.S b/src/rp2_common/pico_crt0/crt0_riscv.S index 0e89ab15..e9fc7d94 100644 --- a/src/rp2_common/pico_crt0/crt0_riscv.S +++ b/src/rp2_common/pico_crt0/crt0_riscv.S @@ -160,64 +160,22 @@ check_irq_before_exit: addi sp, sp, 80 mret + // Default software vector table for system interrupts, routed through // mip.meip. Note this is assumed in e.g. hardware_irq to begin exactly 0x34 // words after the hardware vector table indicated by mtvec (defined above). .p2align 4 .global __soft_vector_table __soft_vector_table: -.word isr_irq0 -.word isr_irq1 -.word isr_irq2 -.word isr_irq3 -.word isr_irq4 -.word isr_irq5 -.word isr_irq6 -.word isr_irq7 -.word isr_irq8 -.word isr_irq9 -.word isr_irq10 -.word isr_irq11 -.word isr_irq12 -.word isr_irq13 -.word isr_irq14 -.word isr_irq15 -.word isr_irq16 -.word isr_irq17 -.word isr_irq18 -.word isr_irq19 -.word isr_irq20 -.word isr_irq21 -.word isr_irq22 -.word isr_irq23 -.word isr_irq24 -.word isr_irq25 -.word isr_irq26 -.word isr_irq27 -.word isr_irq28 -.word isr_irq29 -.word isr_irq30 -.word isr_irq31 -.word isr_irq32 -.word isr_irq33 -.word isr_irq34 -.word isr_irq35 -.word isr_irq36 -.word isr_irq37 -.word isr_irq38 -.word isr_irq39 -.word isr_irq40 -.word isr_irq41 -.word isr_irq42 -.word isr_irq43 -.word isr_irq44 -.word isr_irq45 -.word isr_irq46 -.word isr_irq47 -.word isr_irq48 -.word isr_irq49 -.word isr_irq50 -.word isr_irq51 +.macro vtable_irq_n n +.word isr_irq\n +.endm + +.set IRQN, 0 +.rept PICO_NUM_VTABLE_IRQS +vtable_irq_n IRQN +.set IRQN, IRQN + 1 +.endr // all default trap handlers do nothing, and we can check for them being set to our // default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end @@ -252,58 +210,23 @@ decl_isr isr_riscv_machine_exception decl_isr_bkpt isr_riscv_machine_timer decl_isr_bkpt isr_riscv_machine_soft_irq -decl_isr isr_irq0 -decl_isr isr_irq1 -decl_isr isr_irq2 -decl_isr isr_irq3 -decl_isr isr_irq4 -decl_isr isr_irq5 -decl_isr isr_irq6 -decl_isr isr_irq7 -decl_isr isr_irq8 -decl_isr isr_irq9 -decl_isr isr_irq10 -decl_isr isr_irq11 -decl_isr isr_irq12 -decl_isr isr_irq13 -decl_isr isr_irq14 -decl_isr isr_irq15 -decl_isr isr_irq16 -decl_isr isr_irq17 -decl_isr isr_irq18 -decl_isr isr_irq19 -decl_isr isr_irq20 -decl_isr isr_irq21 -decl_isr isr_irq22 -decl_isr isr_irq23 -decl_isr isr_irq24 -decl_isr isr_irq25 -decl_isr isr_irq26 -decl_isr isr_irq27 -decl_isr isr_irq28 -decl_isr isr_irq29 -decl_isr isr_irq30 -decl_isr isr_irq31 -decl_isr isr_irq32 -decl_isr isr_irq33 -decl_isr isr_irq34 -decl_isr isr_irq35 -decl_isr isr_irq36 -decl_isr isr_irq37 -decl_isr isr_irq38 -decl_isr isr_irq39 -decl_isr isr_irq40 -decl_isr isr_irq41 -decl_isr isr_irq42 -decl_isr isr_irq43 -decl_isr isr_irq44 -decl_isr isr_irq45 -decl_isr isr_irq46 -decl_isr isr_irq47 -decl_isr isr_irq48 -decl_isr isr_irq49 -decl_isr isr_irq50 -decl_isr isr_irq51 +// Declare all the ISR labels +.macro decl_isr_n n +.if \n < PICO_NUM_VTABLE_IRQS + decl_isr isr_irq\n +.elseif \n < NUM_IRQS + // We declare a strong label, so user can't override, since there is no vtable entry + .type isr_irq\n,%function + .thumb_func + isr_irq\n: +.endif +.endm + +.set IRQN, 0 +.rept PICO_NUM_VTABLE_IRQS +decl_isr_n IRQN +.set IRQN, IRQN + 1 +.endr // fall through // All unhandled USER IRQs fall through to here. Note there is no way to get diff --git a/src/rp2_common/pico_crt0/embedded_start_block.inc.S b/src/rp2_common/pico_crt0/embedded_start_block.inc.S index 8f1b622d..e4632255 100644 --- a/src/rp2_common/pico_crt0/embedded_start_block.inc.S +++ b/src/rp2_common/pico_crt0/embedded_start_block.inc.S @@ -41,7 +41,7 @@ embedded_block: PICOBIN_IMAGE_TYPE_EXE_CPU_AS_BITS(RISCV) | \ PICOBIN_IMAGE_TYPE_EXE_CHIP_AS_BITS(RP2350) | \ CRT0_TBYB_FLAG -#elif defined(PICO_RP2040) +#elif PICO_RP2040 .hword PICOBIN_IMAGE_TYPE_IMAGE_TYPE_AS_BITS(EXE) | \ PICOBIN_IMAGE_TYPE_EXE_SECURITY_AS_BITS(NS) | \ PICOBIN_IMAGE_TYPE_EXE_CPU_AS_BITS(ARM) | \ @@ -84,7 +84,7 @@ embedded_block: .word SRAM_END // stack pointer #endif -#ifndef PICO_RP2040 +#if !PICO_RP2040 #if PICO_NO_FLASH // If no_flash bin, then include a vector table item .byte PICOBIN_BLOCK_ITEM_1BS_VECTOR_TABLE diff --git a/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h b/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h index 46aa0989..5eb43d1b 100644 --- a/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h +++ b/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h @@ -59,7 +59,7 @@ extern "C" { * * As of right now, lwIP is the only supported TCP/IP stack, however the use of \c pico_cyw43_arch is intended to be independent of * the particular TCP/IP stack used (and possibly Bluetooth stack used) in the future. For this reason, the integration of lwIP - * is handled in the base (\c pico_cyw43_arch) library based on the #define \ref CYW43_LWIP used by the \c cyw43_driver. + * is handled in the base (\c pico_cyw43_arch) library based on the \#define \ref CYW43_LWIP used by the \c cyw43_driver. * * \note As of version 1.5.0 of the Raspberry Pi Pico SDK, the \c pico_cyw43_arch library no longer directly implements * the distinct behavioral abstractions. This is now handled by the more general \ref pico_async_context library. The @@ -169,7 +169,7 @@ extern "C" { * \ref cyw43_arch_init_default_async_context, however the user can specify use of their own async_context * by calling \ref cyw43_arch_set_async_context() before calling this method * - * \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes + * \return 0 if the initialization is successful, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_init(void); @@ -186,7 +186,7 @@ int cyw43_arch_init(void); * by calling \ref cyw43_arch_set_async_context() before calling this method * * \param country the country code to use (see \ref CYW43_COUNTRY_) - * \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes + * \return 0 if the initialization is successful, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_init_with_country(uint32_t country); @@ -399,7 +399,7 @@ void cyw43_arch_disable_ap_mode(void); * \param auth the authorization type to use when the password is enabled. Values are \ref CYW43_AUTH_WPA_TKIP_PSK, * \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_) * - * \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes + * \return 0 if the initialization is successful, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_wifi_connect_blocking(const char *ssid, const char *pw, uint32_t auth); @@ -413,7 +413,7 @@ int cyw43_arch_wifi_connect_blocking(const char *ssid, const char *pw, uint32_t * \param auth the authorization type to use when the password is enabled. Values are \ref CYW43_AUTH_WPA_TKIP_PSK, * \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_) * - * \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes + * \return 0 if the initialization is successful, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_wifi_connect_bssid_blocking(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth); @@ -427,7 +427,7 @@ int cyw43_arch_wifi_connect_bssid_blocking(const char *ssid, const uint8_t *bssi * \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_) * \param timeout how long to wait in milliseconds for a connection to succeed before giving up * - * \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes + * \return 0 if the initialization is successful, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_wifi_connect_timeout_ms(const char *ssid, const char *pw, uint32_t auth, uint32_t timeout); @@ -442,7 +442,7 @@ int cyw43_arch_wifi_connect_timeout_ms(const char *ssid, const char *pw, uint32_ * \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_) * \param timeout how long to wait in milliseconds for a connection to succeed before giving up * - * \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes + * \return 0 if the initialization is successful, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_wifi_connect_bssid_timeout_ms(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth, uint32_t timeout); @@ -458,7 +458,7 @@ int cyw43_arch_wifi_connect_bssid_timeout_ms(const char *ssid, const uint8_t *bs * \param auth the authorization type to use when the password is enabled. Values are \ref CYW43_AUTH_WPA_TKIP_PSK, * \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_) * - * \return 0 if the scan was started successfully, an error code otherwise \see pico_error_codes + * \return 0 if the scan was started successfully, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_wifi_connect_async(const char *ssid, const char *pw, uint32_t auth); @@ -475,7 +475,7 @@ int cyw43_arch_wifi_connect_async(const char *ssid, const char *pw, uint32_t aut * \param auth the authorization type to use when the password is enabled. Values are \ref CYW43_AUTH_WPA_TKIP_PSK, * \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_) * - * \return 0 if the scan was started successfully, an error code otherwise \see pico_error_codes + * \return 0 if the scan was started successfully, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_wifi_connect_bssid_async(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth); diff --git a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c index 787eeff5..30b18473 100644 --- a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c +++ b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c @@ -451,13 +451,6 @@ static inline int _cyw43_write_reg(cyw43_int_t *self, uint32_t fn, uint32_t reg, uint32_t buf[2]; buf[0] = make_cmd(true, true, fn, reg, size); buf[1] = val; - if (fn == BACKPLANE_FUNCTION) { - // In case of f1 overflow - self->last_size = 8; - self->last_header[0] = buf[0]; - self->last_header[1] = buf[1]; - self->last_backplane_window = self->cur_backplane_window; - } if (fn == BACKPLANE_FUNCTION) { logic_debug_set(pin_BACKPLANE_WRITE, 1); diff --git a/src/rp2_common/pico_divider/divider_hardware.S b/src/rp2_common/pico_divider/divider_hardware.S index cb3f5416..049c6f75 100644 --- a/src/rp2_common/pico_divider/divider_hardware.S +++ b/src/rp2_common/pico_divider/divider_hardware.S @@ -12,21 +12,27 @@ #warning "Building divider_hardware.S on a platform with no SIO divider hardware" #endif -// PICO_CONFIG: PICO_DIVIDER_DISABLE_INTERRUPTS, Disable interrupts around division such that divider state need not be saved/restored in exception handlers, default=0, group=pico_divider +// PICO_CONFIG: PICO_DIVIDER_DISABLE_INTERRUPTS, Disable interrupts around division such that divider state need not be saved/restored in exception handlers, default=0, type=bool, group=pico_divider +#if 0 // make tooling checks happy +#define PICO_DIVIDER_DISABLE_INTERRUPTS 0 +#endif -// PICO_CONFIG: PICO_DIVIDER_CALL_IDIV0, Whether 32 bit division by zero should call __aeabi_idiv0, default=1, group=pico_divider +// PICO_CONFIG: PICO_DIVIDER_CALL_IDIV0, Whether 32 bit division by zero should call __aeabi_idiv0, default=1, type=bool, group=pico_divider #ifndef PICO_DIVIDER_CALL_IDIV0 #define PICO_DIVIDER_CALL_IDIV0 1 #endif -// PICO_CONFIG: PICO_DIVIDER_CALL_IDIV0, Whether 64 bit division by zero should call __aeabi_ldiv0, default=1, group=pico_divider +// PICO_CONFIG: PICO_DIVIDER_CALL_LDIV0, Whether 64 bit division by zero should call __aeabi_ldiv0, default=1, type=bool, group=pico_divider #ifndef PICO_DIVIDER_CALL_LDIV0 #define PICO_DIVIDER_CALL_LDIV0 1 #endif pico_default_asm_setup -// PICO_CONFIG: PICO_DIVIDER_IN_RAM, Whether divider functions should be placed in RAM, default=0, group=pico_divider +// PICO_CONFIG: PICO_DIVIDER_IN_RAM, Whether divider functions should be placed in RAM, default=0, type=bool, group=pico_divider +#if 0 // make tooling checks happy +#define PICO_DIVIDER_IN_RAM 0 +#endif .macro div_section name #if PICO_DIVIDER_IN_RAM .section RAM_SECTION_NAME(\name), "ax" diff --git a/src/rp2_common/pico_lwip/CMakeLists.txt b/src/rp2_common/pico_lwip/CMakeLists.txt index 1a523b78..e412f372 100644 --- a/src/rp2_common/pico_lwip/CMakeLists.txt +++ b/src/rp2_common/pico_lwip/CMakeLists.txt @@ -299,8 +299,7 @@ if (EXISTS ${PICO_LWIP_PATH}/${LWIP_TEST_PATH}) pico_mirrored_target_link_libraries(pico_lwip_freertos INTERFACE pico_async_context_base pico_lwip - pico_lwip_contrib_freertos - pico_rand) + pico_lwip_contrib_freertos) pico_add_subdirectory(tools) pico_promote_common_scope_vars() diff --git a/src/rp2_common/pico_multicore/include/pico/multicore.h b/src/rp2_common/pico_multicore/include/pico/multicore.h index 5eb49ddc..9b4622a9 100644 --- a/src/rp2_common/pico_multicore/include/pico/multicore.h +++ b/src/rp2_common/pico_multicore/include/pico/multicore.h @@ -151,7 +151,7 @@ static inline bool multicore_fifo_rvalid(void) { * * See the note in the \ref multicore_fifo section for considerations regarding use of the inter-core FIFOs * - * @return true if the FIFO has room for more data, false otherwise + * \return true if the FIFO has room for more data, false otherwise */ static inline bool multicore_fifo_wready(void) { return sio_hw->fifo_st & SIO_FIFO_ST_RDY_BITS; @@ -316,7 +316,7 @@ static inline void check_doorbell_num_param(__unused uint doorbell_num) { * * \param doorbell_num the doorbell number to claim * \param core_mask 0b01: core 0, 0b10: core 1, 0b11 both core 0 and core 1 - * \sa hardware_claiming + * \sa hardware_claim */ void multicore_doorbell_claim(uint doorbell_num, uint core_mask); @@ -328,7 +328,7 @@ void multicore_doorbell_claim(uint doorbell_num, uint core_mask); * \param core_mask 0b01: core 0, 0b10: core 1, 0b11 both core 0 and core 1 * \param required if true the function will panic if none are available * \return the doorbell number claimed or -1 if required was false, and none are available - * \sa hardware_claiming + * \sa hardware_claim */ int multicore_doorbell_claim_unused(uint core_mask, bool required); @@ -337,7 +337,7 @@ int multicore_doorbell_claim_unused(uint core_mask, bool required); * * \param doorbell_num the doorbell number to unclaim * \param core_mask 0b01: core 0, 0b10: core 1, 0b11 both core 0 and core 1 - * \sa hardware_claiming + * \sa hardware_claim */ void multicore_doorbell_unclaim(uint doorbell_num, uint core_mask); diff --git a/src/rp2_common/pico_platform_common/BUILD.bazel b/src/rp2_common/pico_platform_common/BUILD.bazel new file mode 100644 index 00000000..18a373a5 --- /dev/null +++ b/src/rp2_common/pico_platform_common/BUILD.bazel @@ -0,0 +1,25 @@ +load("//bazel:defs.bzl", "compatible_with_rp2") + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "pico_platform_common_headers", + hdrs = ["include/pico/platform/common.h"], + includes = ["include"], + visibility = [ + "//src/rp2040/pico_platform:__pkg__", + "//src/rp2350/pico_platform:__pkg__", + ], +) + +cc_library( + name = "pico_platform_common", + srcs = ["common.c"], + target_compatible_with = compatible_with_rp2(), + deps = [ + ":pico_platform_common_headers", + "//src/rp2_common:platform_defs", + "//src/rp2_common/hardware_base", + "//src/common/pico_base_headers", + ], +) diff --git a/src/rp2_common/pico_platform_common/CMakeLists.txt b/src/rp2_common/pico_platform_common/CMakeLists.txt new file mode 100644 index 00000000..8e6da4e1 --- /dev/null +++ b/src/rp2_common/pico_platform_common/CMakeLists.txt @@ -0,0 +1,8 @@ +if (NOT TARGET pico_platform_common) + pico_add_library(pico_platform_common) + target_sources(pico_platform_common INTERFACE ${CMAKE_CURRENT_LIST_DIR}/common.c) + + target_include_directories(pico_platform_common_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) + + target_link_libraries(pico_platform_common_headers INTERFACE hardware_regs) +endif() diff --git a/src/rp2_common/pico_platform_common/common.c b/src/rp2_common/pico_platform_common/common.c new file mode 100644 index 00000000..af5bf183 --- /dev/null +++ b/src/rp2_common/pico_platform_common/common.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "pico.h" +#include "hardware/address_mapped.h" +#include "hardware/regs/tbman.h" + +// Note we leave the FPGA check in by default so that we can run bug repro +// binaries coming in from the wild on the FPGA platform. It takes up around +// 48 bytes if you include all the calls, so you can pass PICO_NO_FPGA_CHECK=1 +// to remove it. The FPGA check is used to skip initialisation of hardware +// (mainly clock generators and oscillators) that aren't present on FPGA. + +#if !PICO_NO_FPGA_CHECK +// Inline stub provided in header if this code is unused (so folding can be +// done in each TU instead of relying on LTO) +bool __attribute__((weak)) running_on_fpga(void) { + return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS; +} +#endif + +#if !PICO_NO_SIM_CHECK +bool __attribute__((weak)) running_in_sim(void) { + return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_HDLSIM_BITS; +} +#endif + diff --git a/src/rp2_common/pico_platform_common/include/pico/platform/common.h b/src/rp2_common/pico_platform_common/include/pico/platform/common.h new file mode 100644 index 00000000..c4645d6e --- /dev/null +++ b/src/rp2_common/pico_platform_common/include/pico/platform/common.h @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2025 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _PICO_PLATFORM_COMMON_H +#define _PICO_PLATFORM_COMMON_H + +/** \file pico/platform/common.h + * \ingroup pico_platform + * + * \brief Macros and definitions common to all rp2 platforms but not specific to any library + * + * This header may be included by assembly code + * + * Note certain library specific defines are defined here when they are interdpedent across libraries, + * but making an explicit library dependency does not make sense. + */ + +// PICO_CONFIG: PICO_MINIMAL_STORED_VECTOR_TABLE, Only store a very minimal vector table in the binary on Arm, type=bool, default=0, advanced=true, group=pico_crt0 +#ifndef PICO_MINIMAL_STORED_VECTOR_TABLE +#define PICO_MINIMAL_STORED_VECTOR_TABLE 0 +#endif + +#if PICO_MINIMAL_STORED_VECTOR_TABLE && (PICO_NO_FLASH && !defined(__riscv)) +#if PICO_NUM_VTABLE_IRQS +#warning PICO_NUM_VTABLE_IRQS is specied with PICO_MINIMAL_STORED_VECTOR_TABLE for NO_FLASH Arm binary; ignored +#undef PICO_NUM_VTABLE_IRQS +#endif +#define PICO_NUM_VTABLE_IRQS 0 +#else +// PICO_CONFIG: PICO_NUM_VTABLE_IRQS, Number of IRQ handlers in the vector table - can be lowered to save space if you aren't using some higher IRQs, type=int, default=NUM_IRQS, group=hardware_irq +#ifndef PICO_NUM_VTABLE_IRQS +#define PICO_NUM_VTABLE_IRQS NUM_IRQS +#endif +#endif + +#ifndef __ASSEMBLER__ + +// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime +#ifndef PICO_NO_FPGA_CHECK +#define PICO_NO_FPGA_CHECK 1 +#endif + +// PICO_CONFIG: PICO_NO_SIM_CHECK, Remove the SIM platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime +#ifndef PICO_NO_SIM_CHECK +#define PICO_NO_SIM_CHECK 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if PICO_NO_FPGA_CHECK +static inline bool running_on_fpga(void) {return false;} +#else +bool running_on_fpga(void); +#endif + +#if PICO_NO_SIM_CHECK +static inline bool running_in_sim(void) {return false;} +#else +bool running_in_sim(void); +#endif + +/*! \brief No-op function for the body of tight loops + * \ingroup pico_platform + * + * No-op function intended to be called by any tight hardware polling loop. Using this ubiquitously + * makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup + * debugging might be added + */ +static __force_inline void tight_loop_contents(void) {} + +#define host_safe_hw_ptr(x) ((uintptr_t)(x)) +#define native_safe_hw_ptr(x) host_safe_hw_ptr(x) + +#ifdef __cplusplus +} +#endif +#endif // __ASSEMBLER__ + + +#endif \ No newline at end of file diff --git a/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h b/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h index 486758be..7f24008a 100644 --- a/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h +++ b/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h @@ -7,8 +7,8 @@ #ifndef _PICO_PLATFORM_COMPILER_H #define _PICO_PLATFORM_COMPILER_H -/** \file platform_compiler.h - * \defgroup pico_platform pico_platform +/** \file pico/platform/compiler.h + * \ingroup pico_platform * * \brief Macros and definitions (and functions when included by non assembly code) to adapt for different compilers * diff --git a/src/rp2_common/pico_rand/include/pico/rand.h b/src/rp2_common/pico_rand/include/pico/rand.h index b0a337f2..e3bbe2df 100644 --- a/src/rp2_common/pico_rand/include/pico/rand.h +++ b/src/rp2_common/pico_rand/include/pico/rand.h @@ -25,7 +25,7 @@ extern "C" { * The random numbers (32 to 128 bit) to be supplied are read from the PRNG which is used * to help provide a large number space. * - * The following (multiple) sources of entropy are available (of varying quality), each enabled by a #define: + * The following (multiple) sources of entropy are available (of varying quality), each enabled by a \#define: * * - The Ring Oscillator (ROSC) (\ref PICO_RAND_ENTROPY_SRC_ROSC == 1): * \ref PICO_RAND_ROSC_BIT_SAMPLE_COUNT bits are gathered from the ring oscillator "random bit" and mixed in each @@ -47,7 +47,7 @@ extern "C" { * - Time (\ref PICO_RAND_SEED_ENTROPY_SRC_TIME == 1): The 64-bit microsecond timer is mixed into the seed. * - Board Identifier (PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID == 1): The board id via \ref pico_get_unique_board_id * is mixed into the seed. - * - RAM hash (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH): The hashed contents of a + * - RAM hash (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH): The hashed contents of a * subset of RAM are mixed in. Initial RAM contents are undefined on power up, so provide a reasonable source of entropy. * By default the last 1K of RAM (which usually contains the core 0 stack) is hashed, which may also provide for differences * after each warm reset. diff --git a/src/rp2_common/pico_runtime_init/runtime_init.c b/src/rp2_common/pico_runtime_init/runtime_init.c index 2b69c806..2e1ce89f 100644 --- a/src/rp2_common/pico_runtime_init/runtime_init.c +++ b/src/rp2_common/pico_runtime_init/runtime_init.c @@ -195,23 +195,32 @@ PICO_RUNTIME_INIT_FUNC_RUNTIME(runtime_init_spin_locks_reset, PICO_RUNTIME_INIT_ // RISC-V to have an initial flash-resident vector table at a well-known // location, unlike Cortex-M which can take an NMI on cycle 0. #ifndef __riscv +#include "hardware/structs/scb.h" +#include "hardware/irq.h" #if !PICO_RUNTIME_NO_INIT_INSTALL_RAM_VECTOR_TABLE -uint32_t __attribute__((section(".ram_vector_table"))) ram_vector_table[PICO_RAM_VECTOR_TABLE_SIZE]; - -#include "hardware/structs/scb.h" -void runtime_init_install_ram_vector_table(void) { - // Note on RISC-V the RAM vector table is initialised during crt0 -#if !(PICO_NO_RAM_VECTOR_TABLE || PICO_NO_FLASH) && !defined(__riscv) -#if !PICO_NO_STORED_VECTOR_TABLE - __builtin_memcpy(ram_vector_table, (uint32_t *) scb_hw->vtor, sizeof(ram_vector_table)); -#else - __builtin_memcpy(ram_vector_table, (uint32_t *) scb_hw->vtor, MIN(VTABLE_FIRST_IRQ, sizeof(ram_vector_table))); - for(uint i = VTABLE_FIRST_IRQ; ivtor = (uintptr_t) ram_vector_table; #endif } diff --git a/src/rp2_common/pico_standard_link/CMakeLists.txt b/src/rp2_common/pico_standard_link/CMakeLists.txt index a428eb69..53eaa84f 100644 --- a/src/rp2_common/pico_standard_link/CMakeLists.txt +++ b/src/rp2_common/pico_standard_link/CMakeLists.txt @@ -30,6 +30,7 @@ if (NOT TARGET pico_standard_link) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_BINARY_TYPE ${TYPE}) endfunction() + # slightly messy as we support both the preferred PICO_DEFAULT_BINARY_TYPE and the individual variables if (NOT PICO_DEFAULT_BINARY_TYPE) if (PICO_NO_FLASH) set(PICO_DEFAULT_BINARY_TYPE no_flash) @@ -40,6 +41,23 @@ if (NOT TARGET pico_standard_link) else() set(PICO_DEFAULT_BINARY_TYPE default) endif() + else() + # we must set the individual variables here, as they are used in generator expressions, + # but also for our checks below + if (PICO_DEFAULT_BINARY_TYPE STREQUAL no_flash) + set(PICO_NO_FLASH 1) + endif() + if (PICO_DEFAULT_BINARY_TYPE STREQUAL blocked_ram) + set(PICO_USE_BLOCKED_RAM 1) + endif() + if (PICO_DEFAULT_BINARY_TYPE STREQUAL copy_to_ram) + set(PICO_COPY_TO_RAM 1) + endif() + endif() + if ((PICO_NO_FLASH AND PICO_USE_BLOCKED_RAM) OR + (PICO_USE_BLOCKED_RAM AND PICO_COPY_TO_RAM) OR + (PICO_COPY_TO_RAM AND PICO_NO_FLASH)) + message(FATAL_ERROR "Conflicting binary types specified amongst PICO_DEFAULT_BINARY_TYPE, PICO_NO_FLASH, PICO_USE_BLOCKED_RAM and PICO_COPY_TO_RAM") endif() # todo only needed if not using a custom linker script diff --git a/src/rp2_common/pico_stdio_usb/BUILD.bazel b/src/rp2_common/pico_stdio_usb/BUILD.bazel index be950655..1e881714 100644 --- a/src/rp2_common/pico_stdio_usb/BUILD.bazel +++ b/src/rp2_common/pico_stdio_usb/BUILD.bazel @@ -24,6 +24,9 @@ cc_library( hdrs = ["include/tusb_config.h"], includes = ["include"], target_compatible_with = compatible_with_rp2(), + deps = [ + ":pico_stdio_usb_headers", + ], ) pico_sdk_define( @@ -43,10 +46,6 @@ cc_library( hdrs = ["include/pico/stdio_usb.h"], includes = ["include"], target_compatible_with = compatible_with_rp2(), - visibility = [ - ":__pkg__", - "//src/rp2_common/tinyusb:__pkg__", - ], deps = [ ":LIB_PICO_STDIO_USB", ":PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS", diff --git a/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h b/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h index b1cb0354..9e6575a3 100644 --- a/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h +++ b/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h @@ -44,10 +44,30 @@ // this variable is no longer set by default (one is claimed dynamically), but will be respected if specified #endif +// PICO_CONFIG: PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK, Enable/disable the use of a background task to call tud_task(), type=bool, default=1 if the application is not using tinyUSB directly, group=pico_stdio_usb +#ifndef PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE +#define PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK 1 +#else +#define PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK 0 +#endif +#endif + +// PICO_CONFIG: PICO_STDIO_USB_ENABLE_TINYUSB_INIT, Enable/disable calling tinyUSB tusb_init() during initialization, type=bool, default=1 if the application is not using tinyUSB directly, group=pico_stdio_usb +#ifndef PICO_STDIO_USB_ENABLE_TINYUSB_INIT +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE +#define PICO_STDIO_USB_ENABLE_TINYUSB_INIT 1 +#else +#define PICO_STDIO_USB_ENABLE_TINYUSB_INIT 0 +#endif +#endif + // PICO_CONFIG: PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE, Enable/disable resetting into BOOTSEL mode if the host sets the baud rate to a magic value (PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE), type=bool, default=1 if application is not using TinyUSB directly, group=pico_stdio_usb #ifndef PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE -#if !defined(LIB_TINYUSB_HOST) && !defined(LIB_TINYUSB_DEVICE) +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE #define PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE 1 +#else +#define PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE 0 #endif #endif @@ -91,8 +111,10 @@ // PICO_CONFIG: PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE, Enable/disable resetting into BOOTSEL mode via an additional VENDOR USB interface - enables picotool based reset, type=bool, default=1 if application is not using TinyUSB directly, group=pico_stdio_usb #ifndef PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE -#if !defined(LIB_TINYUSB_HOST) && !defined(LIB_TINYUSB_DEVICE) +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE #define PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE 1 +#else +#define PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE 0 #endif #endif @@ -116,6 +138,15 @@ #define PICO_STDIO_USB_RESET_RESET_TO_FLASH_DELAY_MS 100 #endif +// PICO_CONFIG: PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS, Defines the default USB descriptors needed for USB communication, type=bool, default=1 if the application is not using tinyUSB directly, group=pico_stdio_usb +#ifndef PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE +#define PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS 1 +#else +#define PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS 0 +#endif +#endif + // PICO_CONFIG: PICO_STDIO_USB_CONNECTION_WITHOUT_DTR, Disable use of DTR for connection checking meaning connection is assumed to be valid, type=bool, default=0, group=pico_stdio_usb #ifndef PICO_STDIO_USB_CONNECTION_WITHOUT_DTR #define PICO_STDIO_USB_CONNECTION_WITHOUT_DTR 0 @@ -161,6 +192,19 @@ bool stdio_usb_deinit(void); * \return true if stdio is connected over CDC */ bool stdio_usb_connected(void); + +#if PICO_STDIO_USB_SUPPORT_CHARS_AVAILABLE_CALLBACK +/*! \brief Explicitly calls the registered USB stdio chars_available_callback + * \ingroup pico_stdio_usb + * + * This method is normally called by the internal USB stdio background thread when there is new USB CDC + * data available to read. However, if the internal background thread is disabled (e.g. when the user + * directly links tinyUSB), the user will need to implement their own background thread and call this + * method directly. + */ +void stdio_usb_call_chars_available_callback(void); +#endif + #ifdef __cplusplus } #endif diff --git a/src/rp2_common/pico_stdio_usb/stdio_usb.c b/src/rp2_common/pico_stdio_usb/stdio_usb.c index 0f9e3188..61aa7089 100644 --- a/src/rp2_common/pico_stdio_usb/stdio_usb.c +++ b/src/rp2_common/pico_stdio_usb/stdio_usb.c @@ -26,8 +26,7 @@ static void (*chars_available_callback)(void*); static void *chars_available_param; #endif -// when tinyusb_device is explicitly linked we do no background tud processing -#if !LIB_TINYUSB_DEVICE +#if PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK // if this crit_sec is initialized, we are not in periodic timer mode, and must make sure // we don't either create multiple one shot timers, or miss creating one. this crit_sec // is used to protect the one_shot_timer_pending flag @@ -171,6 +170,12 @@ void stdio_usb_set_chars_available_callback(void (*fn)(void*), void *param) { chars_available_callback = fn; chars_available_param = param; } + +void stdio_usb_call_chars_available_callback(void) { + if (chars_available_callback) { + chars_available_callback(chars_available_param); + } +} #endif stdio_driver_t stdio_usb = { @@ -197,8 +202,8 @@ bool stdio_usb_init(void) { bi_decl_if_func_used(bi_program_feature("USB stdin / stdout")); #endif -#if !defined(LIB_TINYUSB_DEVICE) - // initialize TinyUSB, as user hasn't explicitly linked it +#if PICO_STDIO_USB_ENABLE_TINYUSB_INIT + // initialize TinyUSB tusb_init(); #else assert(tud_inited()); // we expect the caller to have initialized if they are using TinyUSB @@ -206,7 +211,7 @@ bool stdio_usb_init(void) { if (!mutex_is_initialized(&stdio_usb_mutex)) mutex_init(&stdio_usb_mutex); bool rc = true; -#if !LIB_TINYUSB_DEVICE +#if PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK #ifdef PICO_STDIO_USB_LOW_PRIORITY_IRQ user_irq_claim(PICO_STDIO_USB_LOW_PRIORITY_IRQ); #else @@ -265,7 +270,7 @@ bool stdio_usb_deinit(void) { sleep_ms(PICO_STDIO_USB_DEINIT_DELAY_MS); #endif -#if !LIB_TINYUSB_DEVICE +#if PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK if (irq_has_shared_handler(USBCTRL_IRQ)) { spin_lock_unclaim(spin_lock_get_num(one_shot_timer_crit_sec.spin_lock)); critical_section_deinit(&one_shot_timer_crit_sec); diff --git a/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c b/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c index 2f6e7587..b805e8fb 100644 --- a/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c +++ b/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c @@ -26,11 +26,12 @@ * THE SOFTWARE. */ -#if !defined(LIB_TINYUSB_HOST) && !defined(LIB_TINYUSB_DEVICE) - -#include "tusb.h" +#include "pico/stdio_usb.h" #include "pico/stdio_usb/reset_interface.h" #include "pico/unique_id.h" +#include "tusb.h" + +#if PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS #ifndef USBD_VID #define USBD_VID (0x2E8A) // Raspberry Pi diff --git a/src/rp2_common/pico_time_adapter/include/pico/time_adapter.h b/src/rp2_common/pico_time_adapter/include/pico/time_adapter.h index 639e9149..9392fe77 100644 --- a/src/rp2_common/pico_time_adapter/include/pico/time_adapter.h +++ b/src/rp2_common/pico_time_adapter/include/pico/time_adapter.h @@ -80,7 +80,7 @@ static inline void ta_disable_irq_handler(alarm_pool_timer_t *timer, uint alarm_ hw_clear_bits(&timer_hw_from_timer(timer)->inte, 1u << alarm_num); irq_set_enabled(irq_num, true); irq_remove_handler(irq_num, irq_handler); - hardware_alarm_unclaim(alarm_num); + timer_hardware_alarm_unclaim(timer, alarm_num); } static inline void ta_hardware_alarm_claim(alarm_pool_timer_t *timer, uint hardware_alaram_num) { diff --git a/src/rp2_common/pico_unique_id/include/pico/unique_id.h b/src/rp2_common/pico_unique_id/include/pico/unique_id.h index 367d32bf..9f91733d 100644 --- a/src/rp2_common/pico_unique_id/include/pico/unique_id.h +++ b/src/rp2_common/pico_unique_id/include/pico/unique_id.h @@ -41,6 +41,28 @@ extern "C" { #define PICO_UNIQUE_BOARD_ID_SIZE_BYTES 8 +/** + * \brief Static initialization order + * \ingroup pico_unique_id + * + * This defines the init_priority of the pico_unique_id. By default, it is 1000. The valid range is + * from 101-65535. Set it to -1 to set the priority to none, thus putting it after 65535. Changing + * this value will initialize the unique_id earlier or later in the static initialization order. + * This is most useful for C++ consumers of the pico-sdk. + * + * See https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-constructor-function-attribute + * and https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#index-init_005fpriority-variable-attribute + * + * Here is an example of C++ static initializers that will run before, and then after, pico_unique_id is loaded: + * + * [[gnu::init_priority(500)]] my_class before_instance; + * [[gnu::init_priority(2000)]] my_class after_instance; + * + */ +#ifndef PICO_UNIQUE_BOARD_ID_INIT_PRIORITY +#define PICO_UNIQUE_BOARD_ID_INIT_PRIORITY 1000 +#endif + /** * \brief Unique board identifier * \ingroup pico_unique_id diff --git a/src/rp2_common/pico_unique_id/unique_id.c b/src/rp2_common/pico_unique_id/unique_id.c index c027bf27..28204eda 100644 --- a/src/rp2_common/pico_unique_id/unique_id.c +++ b/src/rp2_common/pico_unique_id/unique_id.c @@ -12,7 +12,13 @@ static_assert(PICO_UNIQUE_BOARD_ID_SIZE_BYTES <= FLASH_UNIQUE_ID_SIZE_BYTES, "Bo static pico_unique_board_id_t retrieved_id; -static void __attribute__((constructor)) _retrieve_unique_id_on_boot(void) { +#if PICO_UNIQUE_BOARD_ID_INIT_PRIORITY == -1 +#define PICO_UNIQUE_BOARD_ID_INIT_ATTRIBUTES constructor +#else +#define PICO_UNIQUE_BOARD_ID_INIT_ATTRIBUTES constructor(PICO_UNIQUE_BOARD_ID_INIT_PRIORITY) +#endif + +static void __attribute__((PICO_UNIQUE_BOARD_ID_INIT_ATTRIBUTES)) _retrieve_unique_id_on_boot(void) { #if PICO_RP2040 #if PICO_NO_FLASH // The hardware_flash call will panic() if called directly on a NO_FLASH diff --git a/src/rp2_common/tinyusb/BUILD.bazel b/src/rp2_common/tinyusb/BUILD.bazel index 4accbb5e..fcc0405a 100644 --- a/src/rp2_common/tinyusb/BUILD.bazel +++ b/src/rp2_common/tinyusb/BUILD.bazel @@ -15,6 +15,7 @@ cc_library( includes = ["include"], target_compatible_with = compatible_with_rp2(), deps = [ + "//bazel/config:PICO_TINYUSB_CONFIG", "//src/common/pico_binary_info", "//src/common/pico_stdlib_headers", "//src/common/pico_sync", @@ -30,7 +31,6 @@ cc_library( "//src/rp2_common/pico_stdio_semihosting", "//src/rp2_common/pico_stdio_uart", "//src/rp2_common/pico_stdio_usb:pico_stdio_usb_headers", - "//src/rp2_common/pico_stdio_usb:tusb_config", "//src/rp2_common/pico_unique_id", ], ) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index c2fbe328..7d68c910 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -153,6 +153,28 @@ function(picotool_check_configurable TARGET) endif() endfunction() +# Compare 2 key files, used by picotool_check_default_keys +function(picotool_compare_keys TARGET KEY DEFAULT TYPE) + if (KEY) + execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files "${KEY}" "${PICO_SDK_PATH}/tools/example_keys/${DEFAULT}" + RESULT_VARIABLE compare_result + ) + if(compare_result EQUAL 0) + message(WARNING "${TARGET} is using a default ${TYPE} key - this must be changed before production") + endif() + endif() +endfunction() + +# Check if default signing/encryption keys are being used +function(picotool_check_default_keys TARGET) + get_target_property(picotool_sigfile ${TARGET} PICOTOOL_SIGFILE) + picotool_compare_keys(${TARGET} ${picotool_sigfile} private.pem "signing") + get_target_property(picotool_aesfile ${TARGET} PICOTOOL_AESFILE) + picotool_compare_keys(${TARGET} ${picotool_aesfile} privateaes.bin "encryption") + get_target_property(picotool_enc_sigfile ${TARGET} PICOTOOL_ENC_SIGFILE) + picotool_compare_keys(${TARGET} ${picotool_enc_sigfile} private.pem "encrypted signing") +endfunction() + # Generate pio header and include it in the build # PICO_CMAKE_CONFIG: PICO_DEFAULT_PIOASM_OUTPUT_FORMAT, Default output format used by pioasm when using pico_generate_pio_header, type=string, default=c-sdk, group=build function(pico_generate_pio_header TARGET) @@ -449,6 +471,12 @@ function(picotool_postprocess_binary TARGET) set_target_properties(${TARGET} PROPERTIES PICOTOOL_PROCESSING_CONFIGURED true ) + + # PICO_CMAKE_CONFIG: PICO_ALLOW_EXAMPLE_KEYS, Don't raise a warning when using default signing/encryption keys, type=bool, default=0, group=build + if (NOT PICO_ALLOW_EXAMPLE_KEYS) + picotool_check_default_keys(${TARGET}) + endif() + # Read target properties get_target_property(picotool_sign_output ${TARGET} PICOTOOL_SIGN_OUTPUT) if (picotool_sign_output) diff --git a/tools/build_all_headers.py b/tools/build_all_headers.py index fc047d99..a3e4f04b 100755 --- a/tools/build_all_headers.py +++ b/tools/build_all_headers.py @@ -24,11 +24,15 @@ IGNORE_DIRS.add('common/pico_usb_reset_interface') IGNORE_DIRS.add('rp2_common/cmsis') IGNORE_DIRS.add('rp2_common/pico_async_context') IGNORE_DIRS.add('rp2_common/pico_btstack') -IGNORE_DIRS.add('rp2_common/pico_cyw43_arch') +#IGNORE_DIRS.add('rp2_common/pico_cyw43_arch') IGNORE_DIRS.add('rp2_common/pico_cyw43_driver') IGNORE_DIRS.add('rp2_common/pico_lwip') IGNORE_DIRS.add('rp2_common/pico_stdio_semihosting') IGNORE_DIRS.add('rp2_common/pico_stdio_usb') +IGNORE_DIRS.add('rp2_common/pico_clib_interface') +IGNORE_DIRS.add('rp2_common/pico_mbedtls') + +SORT_HEADERS_BY_DIRECTORY = True # if False, sort by filename if len(sys.argv) != 3: print("Usage: {} top_dir output_header".format(os.path.basename(sys.argv[0]))) @@ -54,7 +58,12 @@ for root, dirs, files in os.walk(top_dir): include_dirs.add(os.path.join(root, 'include')) dirs.remove('include') -include_files = list() +include_files_by_chip = { + 'none': list(), + 'rp2040': list(), + 'rp2350': list(), +} +all_include_files = set() include_locations = dict() for d in sorted(include_dirs): for root, dirs, files in os.walk(d): @@ -62,13 +71,30 @@ for d in sorted(include_dirs): if f.endswith('.h'): include_file = os.path.relpath(os.path.join(root, f), d) include_path = os.path.relpath(d, top_dir) - if include_file in include_files: - raise Exception("Duplicate include file '{}' (found in both {} and {})".format(include_file, include_locations[include_file], include_path)) - include_files.append(include_file) + if 'rp2040/' in include_path: + include_files_by_chip['rp2040'].append(include_file) + elif 'rp2350/' in include_path: + include_files_by_chip['rp2350'].append(include_file) + else: + if include_file in include_files_by_chip['none']: + raise Exception("Duplicate include file '{}' (found in both {} and {})".format(include_file, include_locations[include_file], include_path)) + include_files_by_chip['none'].append(include_file) include_locations[include_file] = include_path + all_include_files.add(include_file) -with open(output_header, 'w') as fh: - fh.write('''/* +# figure out which includes are applicable to both chips +include_files_by_chip['both'] = [] +for f in include_files_by_chip['rp2040']: + if f in include_files_by_chip['rp2350']: + include_files_by_chip['both'].append(f) + include_locations[f] = include_locations[f].replace('rp2350/', 'rp2xxx/') +for f in include_files_by_chip['both']: + include_files_by_chip['rp2040'].remove(f) + include_files_by_chip['rp2350'].remove(f) + +if SORT_HEADERS_BY_DIRECTORY: + with open(output_header, 'w') as fh: + fh.write('''/* * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause @@ -77,11 +103,61 @@ with open(output_header, 'w') as fh: // This file is autogenerated, do not edit by hand ''') - last_location = '' - for f in include_files: - if include_locations[f] != last_location: - fh.write('\n// {}\n'.format(include_locations[f])) - fh.write('#include "{}"\n'.format(f)) - last_location = include_locations[f] - fh.write('\n') + last_location = '' + for f in include_files_by_chip['none']: + if include_locations[f] != last_location: + fh.write('\n// {}\n'.format(include_locations[f])) + fh.write('#include "{}"\n'.format(f)) + last_location = include_locations[f] + for f in include_files_by_chip['both']: + if include_locations[f] != last_location: + fh.write('\n// {}\n'.format(include_locations[f])) + fh.write('#include "{}"\n'.format(f)) + last_location = include_locations[f] + if include_files_by_chip['rp2040']: + fh.write('\n#if PICO_RP2040\n') + for f in include_files_by_chip['rp2040']: + if include_locations[f] != last_location: + fh.write('\n// {}\n'.format(include_locations[f])) + fh.write('#include "{}"\n'.format(f)) + last_location = include_locations[f] + fh.write('\n#endif\n') + if include_files_by_chip['rp2350']: + fh.write('\n#if PICO_RP2350\n') + for f in include_files_by_chip['rp2350']: + if include_locations[f] != last_location: + fh.write('\n// {}\n'.format(include_locations[f])) + fh.write('#include "{}"\n'.format(f)) + last_location = include_locations[f] + fh.write('\n#endif\n') + fh.write('\n') +else: + with open(output_header, 'w') as fh: + fh.write('''/* + * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// This file is autogenerated, do not edit by hand + +''') + last_define = None + for f in sorted(all_include_files, key=lambda x: os.path.split(x)): + if f in include_files_by_chip['rp2040']: + define = 'PICO_RP2040' + elif f in include_files_by_chip['rp2350']: + define = 'PICO_RP2350' + else: + define = None + if define != last_define: + if last_define is not None: + fh.write('#endif\n') + if define is not None: + fh.write('#if {}\n'.format(define)) + fh.write('#include "{}"\n'.format(f)) + last_define = define + if last_define is not None: + fh.write('#endif\n') + fh.write('\n') diff --git a/tools/check_board_header.py b/tools/check_board_header.py index c259c813..3bfce1c5 100755 --- a/tools/check_board_header.py +++ b/tools/check_board_header.py @@ -196,6 +196,7 @@ def read_defines_from(header_file, defines_dict): if board_header_basename == "amethyst_fpga.h": defines['PICO_RP2350'] = DefineType('PICO_RP2350', 1, 1, -1) + defines['PICO_RP2350A'] = DefineType('PICO_RP2350A', 0, 0, -1) with open(board_header) as header_fh: last_ifndef = None @@ -347,7 +348,7 @@ with open(board_header) as header_fh: raise Exception("{}:{} Include-guard #define {} is missing an #ifndef".format(board_header, lineno, name)) if value: raise Exception("{}:{} Include-guard #define {} shouldn't have a value".format(board_header, lineno, name)) - if len(defines) and not (len(defines) == 1 and defines[list(defines.keys())[0]].lineno < 0): + if any(defines[d].lineno >= 0 for d in defines): raise Exception("{}:{} Include-guard #define {} should be the first define".format(board_header, lineno, name)) if name == expected_include_guard: has_include_guard = True @@ -387,10 +388,15 @@ else: other_chip = 'RP2350' elif cmake_settings['PICO_PLATFORM'].value == "rp2350": other_chip = 'RP2040' - if 'PICO_RP2350A' in defines and defines['PICO_RP2350A'].resolved_value == 1: - chip = 'RP2350A' + if 'PICO_RP2350B' in defines: + raise Exception("{} sets #define {} {} (should probably be #define {} {})".format(board_header, 'PICO_RP2350B', defines['PICO_RP2350B'].resolved_value, 'PICO_RP2350A', 1 - defines['PICO_RP2350B'].resolved_value)) + if 'PICO_RP2350A' not in defines: + raise Exception("{} has no #define for {} (set to 1 for RP2350A, or 0 for RP2350B)".format(board_header, 'PICO_RP2350A')) else: - chip = 'RP2350B' + if defines['PICO_RP2350A'].resolved_value == 1: + chip = 'RP2350A' + else: + chip = 'RP2350B' if not board_header.endswith("amethyst_fpga.h"): if 'PICO_RP2350_A2_SUPPORTED' not in cmake_default_settings: raise Exception("{} uses chip {} but is missing a pico_cmake_set_default {} comment".format(board_header, chip, 'PICO_RP2350_A2_SUPPORTED')) diff --git a/tools/example_keys/private.pem b/tools/example_keys/private.pem new file mode 100644 index 00000000..bf777d89 --- /dev/null +++ b/tools/example_keys/private.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQACg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIAXAdiilH8wT07TESUzWPt+BY9+NcchvYU3xbnpK+CBNoAcGBSuBBAAK +oUQDQgAEYYJtMQFGW4AB94tU3u/Qir5sRcYjBYMqCa+8gxsYd9OwMS3dqWKsnVBz +dyy7bFWdJzXDMb9o20xRRd57Q9xSYw== +-----END EC PRIVATE KEY----- diff --git a/tools/example_keys/privateaes.bin b/tools/example_keys/privateaes.bin new file mode 100644 index 00000000..21a47756 Binary files /dev/null and b/tools/example_keys/privateaes.bin differ diff --git a/tools/extract_configs.py b/tools/extract_configs.py index 30705d5c..00ff3437 100755 --- a/tools/extract_configs.py +++ b/tools/extract_configs.py @@ -133,12 +133,12 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): -# Scan all .c and .h files in the specific path, recursively. +# Scan all .c and .h and .S files in the specific path, recursively. for dirpath, dirnames, filenames in os.walk(scandir): for filename in filenames: file_ext = os.path.splitext(filename)[1] - if file_ext in ('.c', '.h'): + if file_ext in ('.c', '.h', '.S'): file_path = os.path.join(dirpath, filename) applicable = "all" for chip in (*CHIP_NAMES, "host"): @@ -241,6 +241,7 @@ for applicable, all_defines in chips_all_defines.items(): for applicable, all_configs in chips_all_configs.items(): all_defines = chips_all_defines[applicable] + resolved_defines = chips_resolved_defines[applicable] for config_name, config_obj in all_configs.items(): file_path = os.path.join(scandir, config_obj['filename']) linenum = config_obj['line_number'] diff --git a/tools/pioasm/c_sdk_output.cpp b/tools/pioasm/c_sdk_output.cpp index c1730db4..d62d47c3 100644 --- a/tools/pioasm/c_sdk_output.cpp +++ b/tools/pioasm/c_sdk_output.cpp @@ -139,7 +139,7 @@ struct c_sdk_output : public output_format { const char *types[] = { "STATUS_TX_LESSTHAN", "STATUS_RX_LESSTHAN", - "STATUS_IRQ_INDEX", + "STATUS_IRQ_SET", }; if (program.mov_status_type < 0 || program.mov_status_type >= 3) { throw std::runtime_error("unknown mov_status type");