Merge branch 'raspberrypi:develop' into develop

This commit is contained in:
David Dyck 2025-04-11 05:38:57 -10:00 committed by GitHub
commit 75f2822752
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
86 changed files with 1415 additions and 412 deletions

View File

@ -2,5 +2,5 @@
<packages>
<package id="gcc-arm-embedded" version="10.2.1" />
<package id="mingw" version="12.2.0" />
<package id="ninja" version="1.11.1" />
<package id="ninja" version="1.12.1" />
</packages>

View File

@ -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",

View File

@ -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 "")

View File

@ -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
* @}
*

View File

@ -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__",
],
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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__",

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -51022,5 +51022,38 @@ SPDX-License-Identifier: BSD-3-Clause
</register>
</registers>
</peripheral>
<peripheral>
<name>SPARE_IRQ</name>
<baseAddress>0x00000000</baseAddress>
<addressBlock>
<offset>0</offset>
<size>4</size>
<usage>reserved</usage>
</addressBlock>
<interrupt>
<name>SPARE_IRQ_0</name>
<value>26</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_1</name>
<value>27</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_2</name>
<value>28</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_3</name>
<value>29</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_4</name>
<value>30</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_5</name>
<value>31</value>
</interrupt>
</peripheral>
</peripherals>
</device>

View File

@ -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

View File

@ -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",

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -105846,5 +105846,40 @@ SPDX-License-Identifier: BSD-3-Clause
</register>
</registers>
</peripheral>
<peripheral>
<name>SPARE_IRQ</name>
<baseAddress>0x00000000</baseAddress>
<addressBlock>
<offset>0</offset>
<size>4</size>
<usage>reserved</usage>
</addressBlock>
<interrupt>
<name>SPARE_IRQ_0</name>
<value>46</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_1</name>
<value>47</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_2</name>
<value>48</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_3</name>
<value>49</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_4</name>
<value>50</value>
</interrupt>
<interrupt>
<name>SPARE_IRQ_5</name>
<value>51</value>
</interrupt>
</peripheral>
</peripherals>
</device>

View File

@ -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)

View File

@ -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",

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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
}

View File

@ -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
*/

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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"],

View File

@ -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__
// ----------------------------------------------------------------------------

View File

@ -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

View File

@ -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
*/

View File

@ -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

View File

@ -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);

View File

@ -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 {
/*!

View File

@ -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"],

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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"

View File

@ -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()

View File

@ -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);

View File

@ -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",
],
)

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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
*

View File

@ -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.

View File

@ -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; i<count_of(ram_vector_table); i++) {
ram_vector_table[i] = (uintptr_t)__unhandled_user_irq;
}
// note that this is not a safely overridable value, you should use override PICO_NUM_VTABLE_IRQs instead.
// keeping around as a #define though as it used to be supported
#ifdef PICO_RAM_VECTOR_TABLE_SIZE
#warning Overriding PICO_RAM_VECTOR_TABLE_SIZE is deprecated; specify PICO_NUM_VTABLE_IRQS instead
#endif
#ifndef PICO_RAM_VECTOR_TABLE_SIZE
#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + PICO_NUM_VTABLE_IRQS)
#endif
uint32_t __attribute__((section(".ram_vector_table"))) ram_vector_table[PICO_RAM_VECTOR_TABLE_SIZE];
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)
extern uint32_t __vectors;
extern uint32_t __vectors_end;
uint32_t stored_words = (uint32_t)(&__vectors_end - &__vectors);
__builtin_memcpy(ram_vector_table, &__vectors, 4 * MIN(stored_words, PICO_RAM_VECTOR_TABLE_SIZE));
for(uint i = stored_words; i<count_of(ram_vector_table); i++) {
ram_vector_table[i] = (uintptr_t)__unhandled_user_irq;
}
scb_hw->vtor = (uintptr_t) ram_vector_table;
#endif
}

View File

@ -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

View File

@ -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",

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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",
],
)

View File

@ -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)

View File

@ -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')

View File

@ -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'))

View File

@ -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-----

Binary file not shown.

View File

@ -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']

View File

@ -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");