diff --git a/.bazelignore b/.bazelignore deleted file mode 100644 index a086fff4b..000000000 --- a/.bazelignore +++ /dev/null @@ -1,4 +0,0 @@ -# Don't accidentally pick up external CMake deps with Bazel build files. -build -# Don't treat submodules as part of this project. -lib diff --git a/.bazelrc b/.bazelrc index 96b4eca24..8eae3bc20 100644 --- a/.bazelrc +++ b/.bazelrc @@ -4,3 +4,7 @@ common --host_per_file_copt=external/.*@-w # Produce useful output when the build fails. common --verbose_failures + +# Silence warnings about old bazel_dep pins. Bazel 8 brings along newer ones, +# but we can support Bazel 7 (for now). +common --check_direct_dependencies=off diff --git a/.bazelversion b/.bazelversion index b26a34e47..8104cabd3 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -7.2.1 +8.1.0 diff --git a/.github/workflows/check_board.yml b/.github/workflows/check_board.yml new file mode 100644 index 000000000..bd0e72344 --- /dev/null +++ b/.github/workflows/check_board.yml @@ -0,0 +1,27 @@ +name: Check Board Headers + +on: + push: + paths: + - 'src/boards/include/boards/**' + - 'tools/check_board_header.py' + - 'tools/check_all_board_headers.sh' + - '.github/workflows/check_board.yml' + pull_request: + paths: + - 'src/boards/include/boards/**' + - 'tools/check_board_header.py' + - 'tools/check_all_board_headers.sh' + - '.github/workflows/check_board.yml' + +jobs: + check-board-headers: + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Check Board Headers + run: | + tools/check_all_board_headers.sh diff --git a/.github/workflows/check_configs.yml b/.github/workflows/check_configs.yml new file mode 100644 index 000000000..0d034d308 --- /dev/null +++ b/.github/workflows/check_configs.yml @@ -0,0 +1,33 @@ +name: Check Configs + +on: + push: + pull_request: + +jobs: + check-configs: + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Check Build Defines + if: always() + run: | + tools/extract_build_defines.py . + + - name: Check CMake Configs + if: always() + run: | + tools/extract_cmake_configs.py . + + - name: Check CMake Functions + if: always() + run: | + tools/extract_cmake_functions.py . + + - name: Check Configs + if: always() + run: | + tools/extract_configs.py . diff --git a/.github/workflows/choco_packages.config b/.github/workflows/choco_packages.config index d443f751c..116f47f86 100644 --- a/.github/workflows/choco_packages.config +++ b/.github/workflows/choco_packages.config @@ -2,5 +2,4 @@ - diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 28ee68bd6..75ce8324e 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@v4 - name: Checkout submodules - run: git submodule update --init + run: git submodule update --init --recursive - name: Create Build Environment # Some projects don't allow in-source building, so create a separate build directory diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml new file mode 100644 index 000000000..6196a08e4 --- /dev/null +++ b/.github/workflows/pr-check.yml @@ -0,0 +1,28 @@ +name: Make sure PRs target the develop branch + +on: + pull_request_target: + +# By default, pull_request_target gets write permissions to the repo - this prevents that +permissions: + pull-requests: write + +jobs: + check-branch: + if: github.event.pull_request.base.ref == 'master' + runs-on: ubuntu-latest + steps: + - name: Add comment + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'Please do not submit against `master`, use `develop` instead' + }) + - name: Throw error + run: | + echo "::error title=wrong-branch::Please do not submit against 'master', use 'develop' instead" + exit 1 diff --git a/MODULE.bazel b/MODULE.bazel index f80a08a99..1cc03bd1a 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,6 +1,6 @@ module( name = "pico-sdk", - version = "2.1.1", + version = "2.1.2-develop", ) bazel_dep(name = "platforms", version = "0.0.9") @@ -106,7 +106,7 @@ new_git_repository( new_git_repository( name = "cyw43-driver", build_file = "//src/rp2_common/pico_cyw43_driver:cyw43-driver.BUILD", - commit = "c1075d4bc440422cf2b2fd12c64a1f53f77660ee", # keep-in-sync-with-submodule: lib/cyw43-driver + commit = "dd7568229f3bf7a37737b9e1ef250c26efe75b23", # keep-in-sync-with-submodule: lib/cyw43-driver remote = "https://github.com/georgerobotics/cyw43-driver.git", ) @@ -114,10 +114,17 @@ new_git_repository( new_git_repository( name = "lwip", build_file = "//src/rp2_common/pico_lwip:lwip.BUILD", - commit = "0a0452b2c39bdd91e252aef045c115f88f6ca773", # keep-in-sync-with-submodule: lib/lwip + commit = "77dcd25a72509eb83f72b033d219b1d40cd8eb95", # keep-in-sync-with-submodule: lib/lwip remote = "https://github.com/lwip-tcpip/lwip.git", ) +new_git_repository( + name = "mbedtls", + build_file = "//src/rp2_common/pico_mbedtls:mbedtls.BUILD", + commit = "107ea89daaefb9867ea9121002fbbdf926780e98", # keep-in-sync-with-submodule: lib/mbedtls + remote = "https://github.com/Mbed-TLS/mbedtls.git", +) + register_toolchains( "//bazel/toolchain:linux-aarch64-rp2040", "//bazel/toolchain:linux-aarch64-rp2350", diff --git a/README.md b/README.md index 4d24d9fa2..bb89fc0bc 100644 --- a/README.md +++ b/README.md @@ -177,12 +177,11 @@ instructions for other platforms, and just in general, we recommend you see [Ras 1. Setup a CMake build directory. For example, if not using an IDE: ``` - $ mkdir build - $ cd build - $ cmake .. - ``` + $ cmake -S . -B build + ``` + > The cmake -S flag indicates the source directory, and the -B flag tells cmake the name of the output-directory to create. This doesn't have to be named "build", you can call it whatever you want. - When building for a board other than the Raspberry Pi Pico, you should pass `-DPICO_BOARD=board_name` to the `cmake` command above, e.g. `cmake -DPICO_BOARD=pico2 ..` or `cmake -DPICO_BOARD=pico_w ..` to configure the SDK and build options accordingly for that particular board. + When building for a board other than the Raspberry Pi Pico, you should pass `-DPICO_BOARD=board_name` to the `cmake` command above, e.g. `cmake -S . -B build -DPICO_BOARD=pico2` or `cmake -S . -B build -DPICO_BOARD=pico_w` to configure the SDK and build options accordingly for that particular board. Specifying `PICO_BOARD=` sets up various compiler defines (e.g. default pin numbers for UART and other hardware) and in certain cases also enables the use of additional libraries (e.g. wireless support when building for `PICO_BOARD=pico_w`) which cannot @@ -193,11 +192,32 @@ instructions for other platforms, and just in general, we recommend you see [Ras 1. Make your target from the build directory you created. ```sh - $ make hello_world + $ cmake --build build --target hello_world ``` + > The directory-name supplied to the `--build` flag needs to match the directory-name that was passed to the `-B` flag in the earlier cmake command. 1. You now have `hello_world.elf` to load via a debugger, or `hello_world.uf2` that can be installed and run on your Raspberry Pi Pico-series device via drag and drop. # RISC-V support on RP2350 See [Raspberry Pi Pico-series C/C++ SDK](https://rptl.io/pico-c-sdk) for information on setting up a build environment for RISC-V on RP2350. + +## RISC-V quick start + +The [pico-sdk-tools](https://github.com/raspberrypi/pico-sdk-tools/releases) repository contains some prebuilt versions of the RISC-V compiler. + +You can use these to get a working RISC-V compiler on Raspberry Pi OS for example. + +``` +wget https://github.com/raspberrypi/pico-sdk-tools/releases/download/v2.0.0-5/riscv-toolchain-14-aarch64-lin.tar.gz +sudo mkdir -p /opt/riscv/riscv-toolchain-14 +sudo chown $USER /opt/riscv/riscv-toolchain-14 +tar xvf riscv-toolchain-14-aarch64-lin.tar.gz -C /opt/riscv/riscv-toolchain-14 +``` + +To use the RISC-V compiler to build code you need to set a couple of environment variables and run cmake from fresh. + +``` +export PICO_TOOLCHAIN_PATH=/opt/riscv/riscv-toolchain-14/ +export PICO_PLATFORM=rp2350-riscv +``` diff --git a/REPO.bazel b/REPO.bazel new file mode 100644 index 000000000..031d5dd9d --- /dev/null +++ b/REPO.bazel @@ -0,0 +1,10 @@ +ignore_directories( + [ + # Don't accidentally pick up external CMake deps with Bazel build files. + "cmake-*", + "build", + "build-*", + # Don't treat submodules as part of this project. + "lib", + ], +) diff --git a/bazel/config/BUILD.bazel b/bazel/config/BUILD.bazel index 4e622af5c..b27cbdd54 100644 --- a/bazel/config/BUILD.bazel +++ b/bazel/config/BUILD.bazel @@ -186,6 +186,12 @@ int_flag( build_setting_default = 0, ) +# PICO_BAZEL_CONFIG: PICO_TINYUSB_CONFIG, [Bazel only] The library that provides TinyUSB config header (e.g. tusb_config.h), default=//src/rp2_common/pico_stdio_usb:tusb_config, group=build +label_flag( + name = "PICO_TINYUSB_CONFIG", + build_setting_default = "//src/rp2_common/pico_stdio_usb:tusb_config", +) + # PICO_BAZEL_CONFIG: PICO_TINYUSB_LIB, [Bazel only] The library that provides TinyUSB, default=@tinyusb//:tinyusb, group=build label_flag( name = "PICO_TINYUSB_LIB", @@ -288,3 +294,27 @@ label_flag( name = "PICO_FREERTOS_LIB", build_setting_default = "//bazel:empty_cc_lib", ) + +# PICO_BAZEL_CONFIG: PICO_MBEDTL_CONFIG, [Bazel only] The cc_library that provides mbedtls_config.h, default=//bazel:empty_cc_lib, group=pico_mbedtls +label_flag( + name = "PICO_MBEDTLS_CONFIG", + build_setting_default = "//bazel:empty_cc_lib", +) + +# PICO_BAZEL_CONFIG: PICO_COMPILATION_NO_OPT_ARGS, Makes the opt compilation mode a no-op so custom optimization arguments can be injected via the --copt flag instead, type=bool, default=0, group=build +bool_flag( + name = "PICO_COMPILATION_NO_OPT_ARGS", + build_setting_default = False, +) + +# PICO_BAZEL_CONFIG: PICO_COMPILATION_NO_DEBUG_ARGS, Makes the debug compilation mode a no-op so custom debug arguments can be injected via the --copt flag instead, type=bool, default=0, group=build +bool_flag( + name = "PICO_COMPILATION_NO_DEBUG_ARGS", + build_setting_default = False, +) + +# PICO_BAZEL_CONFIG: PICO_COMPILATION_NO_FASTBUILD_ARGS, Makes the fastbuild compilation mode a no-op so custom fastbuild arguments can be injected via the --copt flag instead, type=bool, default=0, group=build +bool_flag( + name = "PICO_COMPILATION_NO_FASTBUILD_ARGS", + build_setting_default = False, +) diff --git a/bazel/constraint/BUILD.bazel b/bazel/constraint/BUILD.bazel index a4fe918b8..acd112469 100644 --- a/bazel/constraint/BUILD.bazel +++ b/bazel/constraint/BUILD.bazel @@ -252,3 +252,24 @@ label_flag_matches( flag = "//bazel/config:PICO_FREERTOS_LIB", value = "//bazel:empty_cc_lib", ) + +label_flag_matches( + name = "pico_mbedtls_config_unset", + flag = "//bazel/config:PICO_MBEDTLS_CONFIG", + value = "//bazel:empty_cc_lib", +) + +config_setting( + name = "pico_compilation_no_opt_args_set", + flag_values = {"//bazel/config:PICO_COMPILATION_NO_OPT_ARGS": "True"}, +) + +config_setting( + name = "pico_compilation_no_debug_args_set", + flag_values = {"//bazel/config:PICO_COMPILATION_NO_DEBUG_ARGS": "True"}, +) + +config_setting( + name = "pico_compilation_no_fastbuild_args_set", + flag_values = {"//bazel/config:PICO_COMPILATION_NO_FASTBUILD_ARGS": "True"}, +) diff --git a/bazel/toolchain/BUILD.bazel b/bazel/toolchain/BUILD.bazel index ba8d947ca..dacd35389 100644 --- a/bazel/toolchain/BUILD.bazel +++ b/bazel/toolchain/BUILD.bazel @@ -89,15 +89,46 @@ cc_args( ) cc_args( - name = "opt_debug_args", + name = "debug_args", actions = [ "@rules_cc//cc/toolchains/actions:compile_actions", "@rules_cc//cc/toolchains/actions:link_actions", ], - args = [ - "-Og", # TODO: Make this configurable. - "-g3", + args = select({ + "//bazel/constraint:pico_compilation_no_debug_args_set": [], + "//conditions:default": [ + "-Og", + "-g3", + ], + }) +) + +cc_args( + name = "opt_args", + actions = [ + "@rules_cc//cc/toolchains/actions:compile_actions", + "@rules_cc//cc/toolchains/actions:link_actions", + ], + args = select({ + "//bazel/constraint:pico_compilation_no_opt_args_set": [], + "//conditions:default": [ + "-O2", + "-DNDEBUG", + ], + }) +) + +cc_args( + name = "fastbuild_args", + actions = [ + "@rules_cc//cc/toolchains/actions:compile_actions", + "@rules_cc//cc/toolchains/actions:link_actions", ], + args = select({ + "//bazel/constraint:pico_compilation_no_fastbuild_args_set": [], + # The conditions default are kept as nothing here, The bazel docs default are -gmlt -Wl,-S. + "//conditions:default": [], + }) ) configurable_toolchain_feature( @@ -132,18 +163,25 @@ configurable_toolchain_feature( linkopts = ["-Wl,-z,max-page-size=4096"], ) -# TODO: Make this shim unnecessary. -cc_args_list( - name = "all_opt_debug_args", - args = [":opt_debug_args"], -) cc_feature( - name = "override_debug", - args = [":all_opt_debug_args"], + name = "dbg", + args = [":debug_args"], overrides = "@rules_cc//cc/toolchains/features:dbg", ) +cc_feature( + name = "opt", + args = [":opt_args"], + overrides = "@rules_cc//cc/toolchains/features:opt", +) + +cc_feature( + name = "fastbuild", + args = [":fastbuild_args"], + overrides = "@rules_cc//cc/toolchains/features:fastbuild", +) + HOSTS = ( ("linux", "x86_64"), ("linux", "aarch64"), @@ -180,7 +218,9 @@ _HOST_CPU_CONSTRAINTS = { tags = ["manual"], # Don't try to build this in wildcard builds. known_features = [ "@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features", - "@pico-sdk//bazel/toolchain:override_debug", + "@pico-sdk//bazel/toolchain:dbg", + "@pico-sdk//bazel/toolchain:opt", + "@pico-sdk//bazel/toolchain:fastbuild", "@pico-sdk//bazel/toolchain:gc_sections", "@pico-sdk//bazel/toolchain:cxx_no_exceptions", "@pico-sdk//bazel/toolchain:cxx_no_rtti", @@ -189,7 +229,6 @@ _HOST_CPU_CONSTRAINTS = { ], enabled_features = [ "@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features", - "@pico-sdk//bazel/toolchain:override_debug", ] + select({ "//bazel/constraint:pico_no_gc_sections_enabled": [], "//conditions:default": [":gc_sections"], @@ -232,7 +271,9 @@ _HOST_CPU_CONSTRAINTS = { tags = ["manual"], # Don't try to build this in wildcard builds. known_features = [ "@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features", - "@pico-sdk//bazel/toolchain:override_debug", + "@pico-sdk//bazel/toolchain:dbg", + "@pico-sdk//bazel/toolchain:opt", + "@pico-sdk//bazel/toolchain:fastbuild", "@pico-sdk//bazel/toolchain:gc_sections", "@pico-sdk//bazel/toolchain:cxx_no_exceptions", "@pico-sdk//bazel/toolchain:cxx_no_rtti", @@ -241,7 +282,6 @@ _HOST_CPU_CONSTRAINTS = { ], enabled_features = [ "@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features", - "@pico-sdk//bazel/toolchain:override_debug", ] + select({ "//bazel/constraint:pico_no_gc_sections_enabled": [], "//conditions:default": [":gc_sections"], diff --git a/bazel/util/transition.bzl b/bazel/util/transition.bzl index 67f0d616e..aa943d602 100644 --- a/bazel/util/transition.bzl +++ b/bazel/util/transition.bzl @@ -114,6 +114,7 @@ kitchen_sink_test_binary = declare_transtion( attrs = { "bt_stack_config": attr.label(mandatory = True), "lwip_config": attr.label(mandatory = True), + "mbedtls_config": attr.label(mandatory = True), "enable_ble": attr.bool(default = False), "enable_bt_classic": attr.bool(default = False), # This could be shared, but we don't in order to make it clearer that @@ -127,6 +128,7 @@ kitchen_sink_test_binary = declare_transtion( "@pico-sdk//bazel/config:PICO_LWIP_CONFIG": "lwip_config", "@pico-sdk//bazel/config:PICO_BT_ENABLE_BLE": "enable_ble", "@pico-sdk//bazel/config:PICO_BT_ENABLE_CLASSIC": "enable_bt_classic", + "@pico-sdk//bazel/config:PICO_MBEDTLS_CONFIG": "mbedtls_config", }, ) diff --git a/cmake/generic_board.cmake b/cmake/generic_board.cmake index c7fdfe5a0..85f59780a 100644 --- a/cmake/generic_board.cmake +++ b/cmake/generic_board.cmake @@ -20,10 +20,22 @@ if (EXISTS ${PICO_BOARD_HEADER_FILE}) while(HEADER_FILE_CONTENTS) list(POP_FRONT HEADER_FILE_CONTENTS LINE) - if (LINE MATCHES "^[ \t\]*//[ \t\]*pico_cmake_set[ \t\]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t\]*=[ \t\]*(.*)") + # pico_board_cmake_set(var, value) + if (LINE MATCHES "^[ \t]*pico_board_cmake_set[ \t]*\\([ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*,[ \t]*(.*)[ \t]*\\)[ \t]*") set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}") - endif() - if (LINE MATCHES "^[ \t\]*//[ \t\]*pico_cmake_set_default[ \t\]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t\]*=[ \t\]*(.*)") + # pico_board_cmake_set_default(var, value) + elseif (LINE MATCHES "^[ \t]*pico_board_cmake_set_default[ \t]*\\([ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*,[ \t]*(.*)[ \t]*\\)[ \t]*") + if (NOT DEFINED "${CMAKE_MATCH_1}") + set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}") + else() + list(APPEND PICO_BOARD_CMAKE_OVERRIDES ${CMAKE_MATCH_1}) + endif() + # continue to support these for now + # // pico_cmake_set var = value + elseif (LINE MATCHES "^[ \t]*//[ \t]*pico_cmake_set[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)") + set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}") + # // pico_cmake_set_default var = value + elseif (LINE MATCHES "^[ \t]*//[ \t]*pico_cmake_set_default[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)") if (NOT DEFINED "${CMAKE_MATCH_1}") set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}") else() diff --git a/cmake/pico_pre_load_platform.cmake b/cmake/pico_pre_load_platform.cmake index df9aebdd7..ea1127574 100644 --- a/cmake/pico_pre_load_platform.cmake +++ b/cmake/pico_pre_load_platform.cmake @@ -122,7 +122,7 @@ if (PICO_PREVIOUS_PLATFORM AND NOT PICO_PREVIOUS_PLATFORM STREQUAL PICO_PLATFORM The best practice is to use separate build directories for different platforms.") endif() set(PICO_PLATFORM ${PICO_PLATFORM} CACHE STRING "PICO Build platform (e.g. rp2040, rp2350, rp2350-riscv, host)" FORCE) -set(PICO_PREVIOUS_PLATFORM ${PICO_PLATFORM} CACHE STRING "Saved PICO Build platform (e.g. rp2040, rp2350, rp2350-riscv, host)" INTERNAL) +set(PICO_PREVIOUS_PLATFORM ${PICO_PLATFORM} CACHE INTERNAL "Saved PICO Build platform (e.g. rp2040, rp2350, rp2350-riscv, host)") # PICO_CMAKE_CONFIG: PICO_CMAKE_PRELOAD_PLATFORM_FILE, Custom CMake file to use to set up the platform environment, type=string, group=build set(PICO_CMAKE_PRELOAD_PLATFORM_FILE ${PICO_CMAKE_PRELOAD_PLATFORM_FILE} CACHE INTERNAL "") diff --git a/cmake/pico_pre_load_toolchain.cmake b/cmake/pico_pre_load_toolchain.cmake index b41b386cf..8b03c5f9d 100644 --- a/cmake/pico_pre_load_toolchain.cmake +++ b/cmake/pico_pre_load_toolchain.cmake @@ -4,7 +4,7 @@ set(PICO_TOOLCHAIN_PATH "${PICO_TOOLCHAIN_PATH}" CACHE INTERNAL "") # Set a default build type if none was specified set(default_build_type "Release") -list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_PREFIX_PATH) +list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_PREFIX_PATH PICO_SDK_PATH) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Defaulting build type to '${default_build_type}' since not specified.") diff --git a/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake b/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake index c5199e55a..da42da46e 100644 --- a/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake +++ b/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake @@ -1,7 +1,7 @@ set(CMAKE_SYSTEM_PROCESSOR cortex-m33) # these are all the directories under LLVM embedded toolchain for ARM (newlib or pibolibc) and under llvm_libc -set(PICO_CLANG_RUNTIMES armv8m.main_soft_nofp armv8m.main-unknown-none-eabi) +set(PICO_CLANG_RUNTIMES armv8m.main_soft_nofp armv8m.main_soft_nofp_unaligned armv8m.main-unknown-none-eabi) set(PICO_COMMON_LANG_FLAGS "-mcpu=cortex-m33 --target=armv8m.main-none-eabi -mfloat-abi=softfp -march=armv8m.main+fp+dsp") set(PICO_DISASM_OBJDUMP_ARGS --mcpu=cortex-m33 --arch=armv8m.main+fp+dsp) diff --git a/docs/index.h b/docs/index.h index b760936c8..be52f6a0d 100644 --- a/docs/index.h +++ b/docs/index.h @@ -48,9 +48,9 @@ * \cond hardware_watchdog \defgroup hardware_watchdog hardware_watchdog \endcond * \cond hardware_xip_cache \defgroup hardware_xip_cache hardware_xip_cache \endcond * \cond hardware_xosc \defgroup hardware_xosc hardware_xosc \endcond - * \cond hardware_powman hardware_powman - * \cond hardware_hazard3 hardware_hazard3 - * \cond hardware_riscv hardware_riscv + * \cond hardware_powman \defgroup hardware_powman hardware_powman \endcond + * \cond hardware_hazard3 \defgroup hardware_hazard3 hardware_hazard3 \endcond + * \cond hardware_riscv \defgroup hardware_riscv hardware_riscv \endcond * @} * @@ -80,6 +80,7 @@ * \defgroup tinyusb_device tinyusb_device * \defgroup tinyusb_host tinyusb_host * \endcond + * \cond pico_mbedtls \defgroup pico_mbedtls pico_mbedtls \endcond * @} * * \defgroup networking Networking Libraries diff --git a/docs/mainpage.md b/docs/mainpage.md index 307fbb372..f8776e7df 100644 --- a/docs/mainpage.md +++ b/docs/mainpage.md @@ -1,28 +1,28 @@ # Raspberry Pi Pico SDK -The Raspberry Pi Pico SDK (Software Development Kit), henceforth SDK, provides the headers, libraries and build system necessary to write programs for RP-series microcontroller devices such as the Raspberry Pi Pico in C, C++ or assembly language. The SDK is designed to provide an API (Application Programming Interface) and programming environment that is familiar both to non-embedded C developers and embedded C developers alike. +The Raspberry Pi Pico Software Development Kit, hereafter **SDK**, provides the headers, libraries, and build system necessary to write programs for RP-series microcontroller devices such as the Raspberry Pi Pico in C, C++, or assembly language. The SDK is designed to provide an API (Application Programming Interface) and programming environment that's familiar both to both non-embedded and embedded C developers. -A single program runs on the device at a time with a conventional `main()` method. Standard C/C++ libraries are supported along with APIs for accessing the microcontroller's hardware, including DMA, IRQs, and the wide variety of fixed-function peripherals and PIO (Programmable IO). +A single program runs on the device at a time, with a conventional `main()` method. Standard C and C++ libraries are supported, along with APIs for accessing a microcontroller's hardware, including DMA, IRQs, and wide variety of fixed-function peripherals and PIO (Programmable IO). -Additionally the SDK provides higher-level libraries for dealing with timers, USB, synchronization and multi-core programming, along with additional high-level functionality built using PIO, such as audio. The SDK can be used to build anything from simple applications, or full-fledged runtime environments such as MicroPython, to low-level software such as the microcontroller's on-chip bootrom itself. +Additionally, the SDK provides higher-level libraries for dealing with timers, USB, synchronisation, and multi-core programming, along with high-level functionality built using PIO (such as audio). The SDK can be used to build anything from simple applications to full-fledged runtime environments such as MicroPython, or even low-level software, such as the microcontroller's on-chip boot ROM. -This documentation is generated from the SDK source tree using Doxygen. It provides basic information on the APIs used for each library, but does not provide usage information. Please refer to the Databooks for usage and more technical information. +This documentation is generated from the SDK source tree using Doxygen. It provides basic information on the APIs used for each library, but doesn't provide usage information. For more technical information and usage guidance, refer to the Raspberry Pi datasheets. ## SDK Design -The RP-series microcontroller range are powerful chips, however they are used in an embedded environment, so both RAM and program space are at premium. Additionally the trade-offs between performance and other factors (e.g. edge-case error handling, runtime vs compile-time configuration) are necessarily much more visible to the developer than they might be on other higher-level platforms. +The RP-series microcontrollers are powerful chips designed for embedded systems; these chips operate in environments with limited memory (RAM) and storage (program space). As a result, trade-offs between performance and other factors (such as edge-case error handling, runtime versus compile time configuration, and so on) are more apparent than they might be on higher-level platforms (like desktop systems). -The intention within the SDK has been for features to just work out of the box, with sensible defaults, but also to give the developer as much control and power as possible (if they want it) to fine-tune every aspect of the application they are building and the libraries used. +The SDK is designed to be both beginner-friendly and powerful for more experienced users. Its features work out-of-the-box with sensible defaults that cover most use cases. At the same time, it gives developers as much control as possible to tweak the application they're building and the libraries they use, if they choose to. ## The Build System -The SDK uses CMake to manage the build. CMake is widely supported by IDEs (Integrated Development Environments), and allows a simple specification of the build (via `CMakeLists.txt` files), from which CMake can generate a build system (for use by `make`, `ninja` or other build tools) customized for the platform and by any configuration variables the developer chooses. +The SDK uses **CMake** to manage the build process. CMake is a widely used build system for C and C++ development, and is supported by many IDEs (Integrated Development Environments). It allows developers to specify build instructions using `CMakeLists.txt` files, from which CMake can generate platform-specific build systems for tools like `make` and `ninja`. These builds can be customised for the intended platform and configuration variables defined by the developer. -Apart from being a widely-used build system for C/C++ development, CMake is fundamental to the way the SDK is structured, and how applications are configured and built. +Apart from its popularity, CMake is fundamental to how the SDK is structured, and how applications are configured and built. It enables consistent builds across platforms while providing flexibility for more complex embedded projects. -The SDK builds an executable which is bare-metal, i.e. it includes the entirety of the code needed to run on the device (other than device specific floating-point and other optimized code contained in the bootrom within the microcontroller). +The SDK builds a bare-metal executable, which is a standalone binary that includes all the code needed to run directly on a microcontroller, excluding device-specific low-level functionality, such as floating-point routines and other optimized code contained in a microcontroller's boot ROM. ## Examples -This SDK documentation contains a number of example code fragments. An index of these examples can be found [here](@ref examples_page). These examples, and any other source code included in this documentation, is Copyright © 2020 Raspberry Pi Ltd and licensed under the [3-Clause BSD](https://opensource.org/licenses/BSD-3-Clause) license. +This SDK documentation contains example code fragments. An index of these examples can be found in the [examples page](@ref examples_page). These examples, and any other source code included in this documentation, are Copyright © 2020 Raspberry Pi Ltd and licensed under the [3-Clause BSD](https://opensource.org/licenses/BSD-3-Clause) license. diff --git a/docs/weblinks_page.md b/docs/weblinks_page.md index 4f96db752..047ff7c0e 100644 --- a/docs/weblinks_page.md +++ b/docs/weblinks_page.md @@ -1,17 +1,20 @@ ## Documentation and datasheets {#weblinks_page} -The full documentation for the RP2040 and Raspberry Pi Pico board can be found at the following links - - - [RP2040 Datasheet](https://rptl.io/rp2040-datasheet) - - [Raspberry Pi Pico Datasheet](https://rptl.io/pico-datasheet) - - [RP235x Datasheet](https://rptl.io/rp2040-datasheet) - - [Raspberry Pi Pico2 Datasheet](https://rptl.io/pico-datasheet) - - [Raspberry Pi Pico W Datasheet](https://rptl.io/picow-datasheet) - - [Hardware design with RP2040](https://rptl.io/rp2040-design) - - [Raspberry Pi Pico C/C++ SDK](https://rptl.io/pico-c-sdk) - - [Raspberry Pi Pico Python SDK](https://rptl.io/pico-micropython) - - [Getting started with Raspberry Pi Pico](https://rptl.io/pico-get-started) - - [Connecting to the Internet with Raspberry Pi Pico W](https://rptl.io/picow-connect) +The full documentation for the RP2040, RP2350 and Raspberry Pi Pico-series boards can be found at the following links + + - [RP2040 Datasheet](https://rpltd.co/rp2040-datasheet) + - [Raspberry Pi Pico Datasheet](https://rpltd.co/pico-datasheet) + - [Raspberry Pi Pico W Datasheet](https://rpltd.co/picow-datasheet) + - [Hardware design with RP2040](https://rpltd.co/rp2040-design) + - [RP2350 Datasheet](https://rpltd.co/rp2350-datasheet) + - [Raspberry Pi Pico 2 Datasheet](https://rpltd.co/pico2-datasheet) + - [Raspberry Pi Pico 2 W Datasheet](https://rpltd.co/pico2w-datasheet) + - [Hardware design with RP2350](https://rpltd.co/rp2350-hardware-design) + - [RM2 Datasheet](https://rpltd.co/rm2-datasheet) + - [Raspberry Pi Pico-series C/C++ SDK](https://rpltd.co/pico-c-sdk) + - [Raspberry Pi Pico-series Python SDK](https://rpltd.co/pico-micropython) + - [Getting started with Raspberry Pi Pico-series](https://rpltd.co/pico-get-started) + - [Connecting to the Internet with Raspberry Pi Pico W-series](https://rpltd.co/picow-connect) ### Weblinks @@ -31,4 +34,9 @@ All the source code for the Raspberry Pi Pico SDK, examples and other libraries - [Pico Examples](https://github.com/raspberrypi/pico-examples) - [Pico Extras - Libraries under development](https://github.com/raspberrypi/pico-extras) - [Pico Playground - Examples that use Pico Extras](https://github.com/raspberrypi/pico-playground) - - [Pico Bootrom source code](https://github.com/raspberrypi/pico-bootrom) + - [Pico MicroPython Examples](https://github.com/raspberrypi/pico-micropython-examples) + - [RP2040 Bootrom source code](https://github.com/raspberrypi/pico-bootrom-rp2040) + - [RP2350 Bootrom source code](https://github.com/raspberrypi/pico-bootrom-rp2350) + - [Picotool](https://github.com/raspberrypi/picotool) + - [Pico VS Code extension](https://github.com/raspberrypi/pico-vscode) + - [Pico TensorFlow Lite Port](https://github.com/raspberrypi/pico-tflmicro) diff --git a/lib/cyw43-driver b/lib/cyw43-driver index c1075d4bc..dd7568229 160000 --- a/lib/cyw43-driver +++ b/lib/cyw43-driver @@ -1 +1 @@ -Subproject commit c1075d4bc440422cf2b2fd12c64a1f53f77660ee +Subproject commit dd7568229f3bf7a37737b9e1ef250c26efe75b23 diff --git a/lib/lwip b/lib/lwip index 0a0452b2c..77dcd25a7 160000 --- a/lib/lwip +++ b/lib/lwip @@ -1 +1 @@ -Subproject commit 0a0452b2c39bdd91e252aef045c115f88f6ca773 +Subproject commit 77dcd25a72509eb83f72b033d219b1d40cd8eb95 diff --git a/lib/mbedtls b/lib/mbedtls index 5a764e555..107ea89da 160000 --- a/lib/mbedtls +++ b/lib/mbedtls @@ -1 +1 @@ -Subproject commit 5a764e5555c64337ed17444410269ff21cb617b1 +Subproject commit 107ea89daaefb9867ea9121002fbbdf926780e98 diff --git a/pico_sdk_version.cmake b/pico_sdk_version.cmake index 58d0b1483..c294d325b 100644 --- a/pico_sdk_version.cmake +++ b/pico_sdk_version.cmake @@ -1,15 +1,17 @@ -# PICO_BUILD_DEFINE: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, default=Current SDK major version, group=pico_base -# PICO_CMAKE_CONFIG: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, default=Current SDK major version, group=pico_base -set(PICO_SDK_VERSION_MAJOR 2) -# PICO_BUILD_DEFINE: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, default=Current SDK minor version, group=pico_base -# PICO_CMAKE_CONFIG: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, default=Current SDK minor version, group=pico_base -set(PICO_SDK_VERSION_MINOR 1) -# PICO_BUILD_DEFINE: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, default=Current SDK revision, group=pico_base -# PICO_CMAKE_CONFIG: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, default=Current SDK revision, group=pico_base -set(PICO_SDK_VERSION_REVISION 1) -# PICO_BUILD_DEFINE: PICO_SDK_VERSION_PRE_RELEASE_ID, Optional SDK pre-release version identifier, default=Current SDK pre-release identifier, type=string, group=pico_base -# PICO_CMAKE_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, Optional SDK pre-release version identifier, default=Current SDK pre-release identifier, type=string, group=pico_base -# set(PICO_SDK_VERSION_PRE_RELEASE_ID develop) +if (NOT DEFINED PICO_SDK_VERSION_MAJOR) + # PICO_BUILD_DEFINE: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, default=Current SDK major version, group=pico_base + # PICO_CMAKE_CONFIG: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, default=Current SDK major version, group=pico_base + set(PICO_SDK_VERSION_MAJOR 2) + # PICO_BUILD_DEFINE: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, default=Current SDK minor version, group=pico_base + # PICO_CMAKE_CONFIG: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, default=Current SDK minor version, group=pico_base + set(PICO_SDK_VERSION_MINOR 1) + # PICO_BUILD_DEFINE: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, default=Current SDK revision, group=pico_base + # PICO_CMAKE_CONFIG: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, default=Current SDK revision, group=pico_base + set(PICO_SDK_VERSION_REVISION 2) + # PICO_BUILD_DEFINE: PICO_SDK_VERSION_PRE_RELEASE_ID, Optional SDK pre-release version identifier, default=Current SDK pre-release identifier, type=string, group=pico_base + # PICO_CMAKE_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, Optional SDK pre-release version identifier, default=Current SDK pre-release identifier, type=string, group=pico_base + set(PICO_SDK_VERSION_PRE_RELEASE_ID develop) +endif() # PICO_BUILD_DEFINE: PICO_SDK_VERSION_STRING, SDK version string, type=string, default=Current SDK version string, group=pico_base # PICO_CMAKE_CONFIG: PICO_SDK_VERSION_STRING, SDK version string, type=string, default=Current SDK version string, group=pico_base diff --git a/src/BUILD.bazel b/src/BUILD.bazel index 58d564ba2..a397b486507 100644 --- a/src/BUILD.bazel +++ b/src/BUILD.bazel @@ -19,6 +19,7 @@ alias( "//src/rp2_common/boot_bootrom_headers:__pkg__", "//src/rp2_common/hardware_boot_lock:__pkg__", "//src/rp2_common/pico_flash:__pkg__", + "//src/rp2_common/hardware_rcp:__pkg__", ], ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f21db2d80..65b1d8c5f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,12 +74,11 @@ endfunction() # add map file generation for the given target function(pico_add_map_output TARGET) - pico_get_runtime_output_directory(${TARGET} output_path) get_target_property(target_type ${TARGET} TYPE) if ("EXECUTABLE" STREQUAL "${target_type}") - target_link_options(${TARGET} PRIVATE "LINKER:-Map=${output_path}$>,$,$>${CMAKE_EXECUTABLE_SUFFIX}.map") + target_link_options(${TARGET} PRIVATE "LINKER:-Map=$.map") else () - target_link_options(${TARGET} INTERFACE "LINKER:-Map=${output_path}$>,$,$>${CMAKE_EXECUTABLE_SUFFIX}.map") + target_link_options(${TARGET} INTERFACE "LINKER:-Map=$.map") endif () endfunction() diff --git a/src/boards/include/boards/0xcb_helios.h b/src/boards/include/boards/0xcb_helios.h index e06c552b5..2f075c063 100644 --- a/src/boards/include/boards/0xcb_helios.h +++ b/src/boards/include/boards/0xcb_helios.h @@ -12,11 +12,11 @@ //------------------------------------------------------------------------------------------ // Board definition for the 0xCB Helios -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_0XCB_HELIOS_H #define _BOARDS_0XCB_HELIOS_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define _0XCB_HELIOS @@ -73,7 +73,7 @@ #endif // board has 16M onboard flash -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/adafruit_feather_rp2040.h b/src/boards/include/boards/adafruit_feather_rp2040.h index c9a6d618d..bbbb80182 100644 --- a/src/boards/include/boards/adafruit_feather_rp2040.h +++ b/src/boards/include/boards/adafruit_feather_rp2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_ADAFRUIT_FEATHER_RP2040_H #define _BOARDS_ADAFRUIT_FEATHER_RP2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define ADAFRUIT_FEATHER_RP2040 @@ -83,7 +83,7 @@ #define PICO_FLASH_SPI_CLKDIV 4 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/adafruit_feather_rp2040_adalogger.h b/src/boards/include/boards/adafruit_feather_rp2040_adalogger.h new file mode 100644 index 000000000..7bf8ba442 --- /dev/null +++ b/src/boards/include/boards/adafruit_feather_rp2040_adalogger.h @@ -0,0 +1,120 @@ +/* + * 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 +// ----------------------------------------------------- + +#ifndef _BOARDS_ADAFRUIT_FEATHER_RP2040_ADALOGGER_H +#define _BOARDS_ADAFRUIT_FEATHER_RP2040_ADALOGGER_H + +pico_board_cmake_set(PICO_PLATFORM, rp2040) + +// For board detection +#define ADAFRUIT_FEATHER_RP2040_ADALOGGER + +// On some samples, the xosc can take longer to stabilize than is usual +#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 +#endif + +//------------- UART -------------// +#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 + +//------------- LED -------------// +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 13 +#endif + +#ifndef PICO_DEFAULT_WS2812_PIN +#define PICO_DEFAULT_WS2812_PIN 17 +#endif + +//------------- I2C -------------// +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 1 +#endif + +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 2 +#endif + +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 3 +#endif + +//------------- SPI -------------// +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 1 +#endif + +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 15 +#endif + +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 8 +#endif + +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 14 +#endif + +//------------- SD -------------// +#ifndef PICO_SD_CARD_DETECT_PIN +#define PICO_SD_CARD_DETECT_PIN 16 +#endif + +#ifndef PICO_SD_CLK_PIN +#define PICO_SD_CLK_PIN 18 +#endif + +#ifndef PICO_SD_CMD_PIN +#define PICO_SD_CMD_PIN 19 +#endif + +#ifndef PICO_SD_DAT0_PIN +#define PICO_SD_DAT0_PIN 20 +#endif + +#ifndef PICO_SD_DAT_PIN_INCREMENT +#define PICO_SD_DAT_PIN_INCREMENT 1 +#endif + +#ifndef PICO_SD_DAT_PIN_COUNT +#define PICO_SD_DAT_PIN_COUNT 4 +#endif + +//------------- FLASH -------------// + +// Use slower generic flash access +#define PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 4 +#endif + +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) +#endif +// All boards have B1 RP2040 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif diff --git a/src/boards/include/boards/adafruit_feather_rp2040_usb_host.h b/src/boards/include/boards/adafruit_feather_rp2040_usb_host.h index 6175b9423..684f3d1f9 100644 --- a/src/boards/include/boards/adafruit_feather_rp2040_usb_host.h +++ b/src/boards/include/boards/adafruit_feather_rp2040_usb_host.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_ADAFRUIT_FEATHER_RP2040_USB_HOST_H #define _BOARDS_ADAFRUIT_FEATHER_RP2040_USB_HOST_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define ADAFRUIT_FEATHER_RP2040_USB_HOST @@ -79,7 +79,7 @@ #define PICO_FLASH_SPI_CLKDIV 4 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/adafruit_feather_rp2350.h b/src/boards/include/boards/adafruit_feather_rp2350.h index 75aaaf902..08227df8a 100644 --- a/src/boards/include/boards/adafruit_feather_rp2350.h +++ b/src/boards/include/boards/adafruit_feather_rp2350.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/adafruit_feather_rp2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_ADAFRUIT_FEATHER_RP2350_H #define _BOARDS_ADAFRUIT_FEATHER_RP2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // On some samples, the xosc can take longer to stabilize than is usual #ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER #define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 @@ -78,12 +78,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/adafruit_fruit_jam.h b/src/boards/include/boards/adafruit_fruit_jam.h new file mode 100644 index 000000000..b769862c4 --- /dev/null +++ b/src/boards/include/boards/adafruit_fruit_jam.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2025 Dan Halbert for Adafruit Industries + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- + +// This header may be included by other board headers as "boards/adafruit_fruit_jam.h" + +pico_board_cmake_set(PICO_PLATFORM, rp2350) + +#ifndef _BOARDS_ADAFRUIT_FRUIT_JAM_H +#define _BOARDS_ADAFRUIT_FRUIT_JAM_H + +// On some samples, the xosc can take longer to stabilize than is usual +#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 +#endif + +// For board detection +#define ADAFRUIT_FRUIT_JAM + +// --- RP2350 VARIANT --- +// This means RP2350B. +#define PICO_RP2350A 0 + +// --- BOARD SPECIFIC --- +// On JST PH connector. +#define ADAFRUIT_FRUIT_JAM_A0_PIN 40 + +// A1-A5 and D6-D10 are on 2x16 socket header. +#define ADAFRUIT_FRUIT_JAM_A1_PIN 41 +#define ADAFRUIT_FRUIT_JAM_A2_PIN 42 +#define ADAFRUIT_FRUIT_JAM_A3_PIN 43 +#define ADAFRUIT_FRUIT_JAM_A4_PIN 44 +#define ADAFRUIT_FRUIT_JAM_A5_PIN 45 + +#define ADAFRUIT_FRUIT_JAM_D6_PIN 6 +#define ADAFRUIT_FRUIT_JAM_D7_PIN 7 +#define ADAFRUIT_FRUIT_JAM_D8_PIN 8 +#define ADAFRUIT_FRUIT_JAM_D9_PIN 9 +#define ADAFRUIT_FRUIT_JAM_D10_PIN 10 + +// Buttons +// Boot button is also known as Button 1. +#define ADAFRUIT_FRUIT_JAM_BOOT_BUTTON_PIN 0 +#define ADAFRUIT_FRUIT_JAM_BUTTON1_PIN 0 +#define ADAFRUIT_FRUIT_JAM_BUTTON2_PIN 4 +#define ADAFRUIT_FRUIT_JAM_BUTTON3_PIN 5 + +// ESP32-C6 co-processor +#define ADAFRUIT_FRUIT_JAM_WIFI_SCK_PIN 30 +#define ADAFRUIT_FRUIT_JAM_WIFI_MOSI_PIN 31 +#define ADAFRUIT_FRUIT_JAM_WIFI_MISO_PIN 28 +#define ADAFRUIT_FRUIT_JAM_WIFI_CS_PIN 46 +#define ADAFRUIT_FRUIT_JAM_WIFI_ACK_PIN 3 +#define ADAFRUIT_FRUIT_JAM_WIFI_RESET_PIN 22 + +// HSTX header +#define ADAFRUIT_FRUIT_JAM_DVI_CKN_PIN 12 +#define ADAFRUIT_FRUIT_JAM_DVI_CKP_PIN 13 +#define ADAFRUIT_FRUIT_JAM_DVI_D0N_PIN 14 +#define ADAFRUIT_FRUIT_JAM_DVI_D0P_PIN 15 +#define ADAFRUIT_FRUIT_JAM_DVI_D1N_PIN 16 +#define ADAFRUIT_FRUIT_JAM_DVI_D1P_PIN 17 +#define ADAFRUIT_FRUIT_JAM_DVI_D2N_PIN 18 +#define ADAFRUIT_FRUIT_JAM_DVI_D2P_PIN 19 + +// Reset for ESP32-C6 and TLV320DAC3100 +#define ADAFRUIT_FRUIT_JAM_PERIPH_RESET_PIN 22 + +#define ADAFRUIT_FRUIT_JAM_I2S_ESP_IRQ_PIN 23 + +// I2S to TLV320DAC3100 +#define ADAFRUIT_FRUIT_JAM_I2S_DIN_PIN 24 +#define ADAFRUIT_FRUIT_JAM_I2S_MCLK_PIN 25 +#define ADAFRUIT_FRUIT_JAM_I2S_BCLK_PIN 26 +#define ADAFRUIT_FRUIT_JAM_I2S_WS_PIN 27 + +// SD and SDIO +#define ADAFRUIT_FRUIT_JAM_SD_SCK_PIN 34 +#define ADAFRUIT_FRUIT_JAM_SDIO_CLOCK_PIN 34 + +#define ADAFRUIT_FRUIT_JAM_SD_MOSI_PIN 35 +#define ADAFRUIT_FRUIT_JAM_SDIO_COMMAND_PIN 35 + +#define ADAFRUIT_FRUIT_JAM_SD_MISO_PIN 36 +#define ADAFRUIT_FRUIT_JAM_SDIO_DATA0_PIN 36 + +#define ADAFRUIT_FRUIT_JAM_SDIO_DATA1_PIN 37 +#define ADAFRUIT_FRUIT_JAM_SDIO_DATA2_PIN 38 + +#define ADAFRUIT_FRUIT_JAM_SD_CS_PIN 39 +#define ADAFRUIT_FRUIT_JAM_SDIO_DATA3_PIN 39 + +#define ADAFRUIT_FRUIT_JAM_SD_CARD_DETECT_PIN 33 + +#define ADAFRUIT_FRUIT_JAM_USB_HOST_DATA_PLUS_PIN 1 +#define ADAFRUIT_FRUIT_JAM_USB_HOST_DATA_MINUS_PIN 2 +#define ADAFRUIT_FRUIT_JAM_USB_HOST_5V_POWER_PIN 11 + +// --- UART --- +#ifndef PICO_DEFAULT_UART +#define PICO_DEFAULT_UART 1 +#endif + +#ifndef PICO_DEFAULT_UART_TX_PIN +#define PICO_DEFAULT_UART_TX_PIN 8 +#endif + +#ifndef PICO_DEFAULT_UART_RX_PIN +#define PICO_DEFAULT_UART_RX_PIN 9 +#endif + +// --- LED --- +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 29 +#endif + +// --- RGB (NeoPixel) LED --- +#ifndef PICO_DEFAULT_WS2812_PIN +#define PICO_DEFAULT_WS2812_PIN 32 +#endif + +// --- I2C --- +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 0 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 20 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 21 +#endif + +// --- SPI --- +// Default SPI is also the SPI for the SD card. +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 0 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN ADAFRUIT_FRUIT_JAM_SD_SCK_PIN +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN ADAFRUIT_FRUIT_JAM_SD_MOSI_PIN +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN ADAFRUIT_FRUIT_JAM_SD_MISO_PIN +#endif + +//------------- SD ------------ +#ifndef PICO_SD_CARD_DETECT_PIN +#define PICO_SD_CARD_DETECT_PIN ADAFRUIT_FRUIT_JAM_SD_CARD_DETECT_PIN +#endif + +#ifndef PICO_SD_CLK_PIN +#define PICO_SD_CLK_PIN ADAFRUIT_FRUIT_JAM_SDIO_CLOCK_PIN +#endif + +#ifndef PICO_SD_CMD_PIN +#define PICO_SD_CMD_PIN ADAFRUIT_FRUIT_JAM_SDIO_COMMAND_PIN +#endif + +#ifndef PICO_SD_DAT0_PIN +#define PICO_SD_DAT0_PIN ADAFRUIT_FRUIT_JAM_SDIO_DATA0_PIN +#endif + +#ifndef PICO_SD_DAT_PIN_INCREMENT +#define PICO_SD_DAT_PIN_INCREMENT 1 +#endif + +#ifndef PICO_SD_DAT_PIN_COUNT +#define PICO_SD_DAT_PIN_COUNT 4 +#endif + +// --- I2S AUDIO (for pico-extras/src/rp2_common/pico_audio_i2s/) + +#ifndef PICO_AUDIO_I2S_DATA_PIN +#define PICO_AUDIO_I2S_DATA_PIN ADAFRUIT_FRUIT_JAM_I2S_DIN_PIN +#endif + +#ifndef PICO_AUDIO_I2S_CLOCK_PIN_BASE +#define PICO_AUDIO_I2S_CLOCK_PIN_BASE ADAFRUIT_FRUIT_JAM_I2S_BCLK_PIN +#endif + +// --- PIO USB --- +#define PICO_DEFAULT_PIO_USB_DP_PIN ADAFRUIT_FRUIT_JAM_USB_HOST_DATA_PLUS_PIN + +// --- FLASH --- +// Winbond W25Q128 (16MB) flash +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) +#endif + +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +#endif diff --git a/src/boards/include/boards/adafruit_itsybitsy_rp2040.h b/src/boards/include/boards/adafruit_itsybitsy_rp2040.h index ee5cf9cd4..5bd06ca77 100644 --- a/src/boards/include/boards/adafruit_itsybitsy_rp2040.h +++ b/src/boards/include/boards/adafruit_itsybitsy_rp2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_ADAFRUIT_ITSYBITSY_RP2040_H #define _BOARDS_ADAFRUIT_ITSYBITSY_RP2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define ADAFRUIT_ITSYBITSY_RP2040 @@ -86,7 +86,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/adafruit_kb2040.h b/src/boards/include/boards/adafruit_kb2040.h index f63fc77e3..affb90cbb 100644 --- a/src/boards/include/boards/adafruit_kb2040.h +++ b/src/boards/include/boards/adafruit_kb2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_ADAFRUIT_KB2040_H #define _BOARDS_ADAFRUIT_KB2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define ADAFRUIT_KB2040 @@ -78,7 +78,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/adafruit_macropad_rp2040.h b/src/boards/include/boards/adafruit_macropad_rp2040.h index 672ada963..1b61d1314 100644 --- a/src/boards/include/boards/adafruit_macropad_rp2040.h +++ b/src/boards/include/boards/adafruit_macropad_rp2040.h @@ -12,11 +12,11 @@ #ifndef _BOARDS_ADAFRUIT_MACROPAD_RP2040_H #define _BOARDS_ADAFRUIT_MACROPAD_RP2040_H -// pico_cmake_set PICO_PLATFORM=rp2040 - // For board detection #define ADAFRUIT_MACROPAD_RP2040 +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // On some samples, the xosc can take longer to stabilize than is usual #ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER #define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 @@ -173,7 +173,7 @@ #define PICO_FLASH_SPI_CLKDIV 4 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/adafruit_qtpy_rp2040.h b/src/boards/include/boards/adafruit_qtpy_rp2040.h index 722d23003..60c891595 100644 --- a/src/boards/include/boards/adafruit_qtpy_rp2040.h +++ b/src/boards/include/boards/adafruit_qtpy_rp2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_ADAFRUIT_QTPY_RP2040_H #define _BOARDS_ADAFRUIT_QTPY_RP2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define ADAFRUIT_QTPY_RP2040 @@ -85,7 +85,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/adafruit_trinkey_qt2040.h b/src/boards/include/boards/adafruit_trinkey_qt2040.h index 06e294940..4af1809ce 100644 --- a/src/boards/include/boards/adafruit_trinkey_qt2040.h +++ b/src/boards/include/boards/adafruit_trinkey_qt2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_ADAFRUIT_TRINKEY_QT2040_H #define _BOARDS_ADAFRUIT_TRINKEY_QT2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define ADAFRUIT_TRINKEY_QT2040 @@ -63,7 +63,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/amethyst_fpga.h b/src/boards/include/boards/amethyst_fpga.h index ea6b9a2d4..fbe7bd25a 100644 --- a/src/boards/include/boards/amethyst_fpga.h +++ b/src/boards/include/boards/amethyst_fpga.h @@ -9,13 +9,11 @@ // 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 #define _BOARDS_AMETHYST_FPGA_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + #if !PICO_RP2350 #error "Invalid PICO_PLATFORM for amethyst_fpga.h: must be rp2350 or rp2350-riscv" #endif @@ -100,7 +98,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/archi.h b/src/boards/include/boards/archi.h index 13b7d7ea0..076cfe096 100644 --- a/src/boards/include/boards/archi.h +++ b/src/boards/include/boards/archi.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/archi.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_ARCHI_H #define _BOARDS_ARCHI_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define ARCHI @@ -104,7 +104,7 @@ #define PICO_FLASH_SPI_CLKDIV 4 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/arduino_nano_rp2040_connect.h b/src/boards/include/boards/arduino_nano_rp2040_connect.h index 9cd3035f5..57d5e0c1d 100644 --- a/src/boards/include/boards/arduino_nano_rp2040_connect.h +++ b/src/boards/include/boards/arduino_nano_rp2040_connect.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_ARDUINO_NANO_RP2040_CONNECT_H #define _BOARDS_ARDUINO_NANO_RP2040_CONNECT_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define ARDUINO_NANO_RP2040_CONNECT @@ -74,7 +74,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/cytron_maker_pi_rp2040.h b/src/boards/include/boards/cytron_maker_pi_rp2040.h index 9d2f0eb69..52be09cad 100644 --- a/src/boards/include/boards/cytron_maker_pi_rp2040.h +++ b/src/boards/include/boards/cytron_maker_pi_rp2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_CYTRON_MAKER_PI_RP2040_H #define _BOARDS_CYTRON_MAKER_PI_RP2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define CYTRON_MAKER_PI_RP2040 @@ -179,7 +179,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/datanoisetv_rp2040_dsp.h b/src/boards/include/boards/datanoisetv_rp2040_dsp.h index ae583baa4..6084efe26 100644 --- a/src/boards/include/boards/datanoisetv_rp2040_dsp.h +++ b/src/boards/include/boards/datanoisetv_rp2040_dsp.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/datanoisetv_rp2040_dsp.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_DATANOISETV_RP2040_DSP_H #define _BOARDS_DATANOISETV_RP2040_DSP_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define DATANOISETV_RP2040_DSP @@ -40,7 +40,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/datanoisetv_rp2350_dsp.h b/src/boards/include/boards/datanoisetv_rp2350_dsp.h index feb5792c0..1195e3c1e 100644 --- a/src/boards/include/boards/datanoisetv_rp2350_dsp.h +++ b/src/boards/include/boards/datanoisetv_rp2350_dsp.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/datanoisetv_rp2350_dsp.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_DATANOISETV_RP2350_DSP_H #define _BOARDS_DATANOISETV_RP2350_DSP_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define DATANOISETV_RP2350_DSP @@ -43,12 +43,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/defcon32_badge.h b/src/boards/include/boards/defcon32_badge.h index 3466fc711..ce18d6157 100644 --- a/src/boards/include/boards/defcon32_badge.h +++ b/src/boards/include/boards/defcon32_badge.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_DEFCON32_BADGE_H #define _BOARDS_DEFCON32_BADGE_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define DEFCON32_BADGE @@ -103,12 +103,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/eelectronicparts_picomini_16mb.h b/src/boards/include/boards/eelectronicparts_picomini_16mb.h new file mode 100644 index 000000000..2121628d4 --- /dev/null +++ b/src/boards/include/boards/eelectronicparts_picomini_16mb.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// +//------------------------------------------------------------------------------------------ +// Board definition for the E Electronic Parts "Pico_Mini RP2040" +// +// This header may be included by other board headers as "boards/eelectronicparts_picomini_16mb.h" + +#ifndef _BOARDS_EELECTRONICPARTS_PICOMINI_16MB_H +#define _BOARDS_EELECTRONICPARTS_PICOMINI_16MB_H + +pico_board_cmake_set(PICO_PLATFORM, rp2040) + +// 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_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +// This board comes in 2MB, 4MB, 8MB, and 16MB variants +#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) +#endif +// All boards have B1 RP2040 + +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif diff --git a/src/boards/include/boards/eelectronicparts_picomini_2mb.h b/src/boards/include/boards/eelectronicparts_picomini_2mb.h new file mode 100644 index 000000000..e10fc35ab --- /dev/null +++ b/src/boards/include/boards/eelectronicparts_picomini_2mb.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// +//------------------------------------------------------------------------------------------ +// Board definition for the E Electronic Parts "Pico_Mini RP2040" +// +// This header may be included by other board headers as "boards/eelectronicparts_picomini_2mb.h" + +#ifndef _BOARDS_EELECTRONICPARTS_PICOMINI_2MB_H +#define _BOARDS_EELECTRONICPARTS_PICOMINI_2MB_H + +pico_board_cmake_set(PICO_PLATFORM, rp2040) + +// 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_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +// This board comes in 2MB, 4MB, 8MB, and 16MB variants +#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) +#endif +// All boards have B1 RP2040 + +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif diff --git a/src/boards/include/boards/eelectronicparts_picomini_4mb.h b/src/boards/include/boards/eelectronicparts_picomini_4mb.h new file mode 100644 index 000000000..a8bc8e571 --- /dev/null +++ b/src/boards/include/boards/eelectronicparts_picomini_4mb.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// +//------------------------------------------------------------------------------------------ +// Board definition for the E Electronic Parts "Pico_Mini RP2040" +// +// This header may be included by other board headers as "boards/eelectronicparts_picomini_4mb.h" + +#ifndef _BOARDS_EELECTRONICPARTS_PICOMINI_4MB_H +#define _BOARDS_EELECTRONICPARTS_PICOMINI_4MB_H + +pico_board_cmake_set(PICO_PLATFORM, rp2040) + +// 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_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +// This board comes in 2MB, 4MB, 8MB, and 16MB variants +#define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) +#endif +// All boards have B1 RP2040 + +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif diff --git a/src/boards/include/boards/eelectronicparts_picomini_8mb.h b/src/boards/include/boards/eelectronicparts_picomini_8mb.h new file mode 100644 index 000000000..d7f19f348 --- /dev/null +++ b/src/boards/include/boards/eelectronicparts_picomini_8mb.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// +//------------------------------------------------------------------------------------------ +// Board definition for the E Electronic Parts "Pico_Mini RP2040" +// +// This header may be included by other board headers as "boards/eelectronicparts_picomini_8mb.h" + +#ifndef _BOARDS_EELECTRONICPARTS_PICOMINI_8MB_H +#define _BOARDS_EELECTRONICPARTS_PICOMINI_8MB_H + +pico_board_cmake_set(PICO_PLATFORM, rp2040) + +// 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_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +// This board comes in 2MB, 4MB, 8MB, and 16MB variants +#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) +#endif +// All boards have B1 RP2040 + +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 +#endif + +#endif diff --git a/src/boards/include/boards/eetree_gamekit_rp2040.h b/src/boards/include/boards/eetree_gamekit_rp2040.h index 3df871988..f1e72dac0 100644 --- a/src/boards/include/boards/eetree_gamekit_rp2040.h +++ b/src/boards/include/boards/eetree_gamekit_rp2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_EETREE_GAMEKIT_RP2040_H #define _BOARDS_EETREE_GAMEKIT_RP2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define EETREE_GAMEKIT_RP2040 @@ -69,7 +69,7 @@ #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/garatronic_pybstick26_rp2040.h b/src/boards/include/boards/garatronic_pybstick26_rp2040.h index d245c8209..190cefe40 100644 --- a/src/boards/include/boards/garatronic_pybstick26_rp2040.h +++ b/src/boards/include/boards/garatronic_pybstick26_rp2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_GARATRONIC_PYBSTICK26_RP2040_H #define _BOARDS_GARATRONIC_PYBSTICK26_RP2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define GARATRONIC_PYBSTICK26_RP2040 @@ -70,7 +70,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (1 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (1 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (1 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/gen4_rp2350_24.h b/src/boards/include/boards/gen4_rp2350_24.h index ec479653e..06e0bb1d0 100644 --- a/src/boards/include/boards/gen4_rp2350_24.h +++ b/src/boards/include/boards/gen4_rp2350_24.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_24_H #define _BOARDS_GEN4_RP2350_24_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_24 @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_24ct.h b/src/boards/include/boards/gen4_rp2350_24ct.h index 71b8f2e66..864a023ec 100644 --- a/src/boards/include/boards/gen4_rp2350_24ct.h +++ b/src/boards/include/boards/gen4_rp2350_24ct.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_24CT_H #define _BOARDS_GEN4_RP2350_24CT_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_24CT // CLB variants are exactly the same in operation @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_24t.h b/src/boards/include/boards/gen4_rp2350_24t.h index df086fae5..129fec9c8 100644 --- a/src/boards/include/boards/gen4_rp2350_24t.h +++ b/src/boards/include/boards/gen4_rp2350_24t.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_24T_H #define _BOARDS_GEN4_RP2350_24T_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_24T @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_28.h b/src/boards/include/boards/gen4_rp2350_28.h index b460b8780..39cef5c90 100644 --- a/src/boards/include/boards/gen4_rp2350_28.h +++ b/src/boards/include/boards/gen4_rp2350_28.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_28_H #define _BOARDS_GEN4_RP2350_28_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_28 @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_28ct.h b/src/boards/include/boards/gen4_rp2350_28ct.h index 11153e143..e581a97c4 100644 --- a/src/boards/include/boards/gen4_rp2350_28ct.h +++ b/src/boards/include/boards/gen4_rp2350_28ct.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_28CT_H #define _BOARDS_GEN4_RP2350_28CT_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_28CT // CLB variants are exactly the same in operation @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_28t.h b/src/boards/include/boards/gen4_rp2350_28t.h index c948c9eb1..a2c3af327 100644 --- a/src/boards/include/boards/gen4_rp2350_28t.h +++ b/src/boards/include/boards/gen4_rp2350_28t.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_28T_H #define _BOARDS_GEN4_RP2350_28T_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_28T @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_32.h b/src/boards/include/boards/gen4_rp2350_32.h index 896937744..2adc570ea 100644 --- a/src/boards/include/boards/gen4_rp2350_32.h +++ b/src/boards/include/boards/gen4_rp2350_32.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_32_H #define _BOARDS_GEN4_RP2350_32_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_32 @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_32ct.h b/src/boards/include/boards/gen4_rp2350_32ct.h index 0e137357e..9624c2d36 100644 --- a/src/boards/include/boards/gen4_rp2350_32ct.h +++ b/src/boards/include/boards/gen4_rp2350_32ct.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_32CT_H #define _BOARDS_GEN4_RP2350_32CT_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_32CT // CLB variants are exactly the same in operation @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_32t.h b/src/boards/include/boards/gen4_rp2350_32t.h index 6280f0d7d..a335e6233 100644 --- a/src/boards/include/boards/gen4_rp2350_32t.h +++ b/src/boards/include/boards/gen4_rp2350_32t.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_32T_H #define _BOARDS_GEN4_RP2350_32T_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_32T @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_35.h b/src/boards/include/boards/gen4_rp2350_35.h index d26f53034..2dd4eca69 100644 --- a/src/boards/include/boards/gen4_rp2350_35.h +++ b/src/boards/include/boards/gen4_rp2350_35.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_35_H #define _BOARDS_GEN4_RP2350_35_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_35 @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_35ct.h b/src/boards/include/boards/gen4_rp2350_35ct.h index 8576ac503..fbdd13d40 100644 --- a/src/boards/include/boards/gen4_rp2350_35ct.h +++ b/src/boards/include/boards/gen4_rp2350_35ct.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_35CT_H #define _BOARDS_GEN4_RP2350_35CT_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_35CT // CLB variants are exactly the same in operation @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/gen4_rp2350_35t.h b/src/boards/include/boards/gen4_rp2350_35t.h index ee8cb2385..bec4bfd39 100644 --- a/src/boards/include/boards/gen4_rp2350_35t.h +++ b/src/boards/include/boards/gen4_rp2350_35t.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_GEN4_RP2350_35T_H #define _BOARDS_GEN4_RP2350_35T_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define GEN4_RP2350_35T @@ -71,12 +71,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/hellbender_0001.h b/src/boards/include/boards/hellbender_0001.h index 9091f9124..5f9ceca13 100644 --- a/src/boards/include/boards/hellbender_0001.h +++ b/src/boards/include/boards/hellbender_0001.h @@ -12,7 +12,7 @@ #ifndef _BOARDS_HELLBENDER_0001_H #define _BOARDS_HELLBENDER_0001_H -// pico_cmake_set PICO_PLATFORM=rp2350 +pico_board_cmake_set(PICO_PLATFORM, rp2350) // For board detection #define HELLBENDER_0001 @@ -130,7 +130,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif @@ -138,9 +138,9 @@ #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 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/hellbender_2350A_devboard.h b/src/boards/include/boards/hellbender_2350A_devboard.h index 63753bcca..aa41f69b6 100644 --- a/src/boards/include/boards/hellbender_2350A_devboard.h +++ b/src/boards/include/boards/hellbender_2350A_devboard.h @@ -12,7 +12,7 @@ #ifndef _BOARDS_HELLBENDER_2350A_DEVBOARD_H #define _BOARDS_HELLBENDER_2350A_DEVBOARD_H -// pico_cmake_set PICO_PLATFORM=rp2350 +pico_board_cmake_set(PICO_PLATFORM, rp2350) // For board detection #define HELLBENDER_2350A_DEVBOARD @@ -22,16 +22,17 @@ #define HB_2350A_IMU_INT_PIN 1 #define HB_2350A_USER_QWIIC_SDA_PIN 2 #define HB_2350A_USER_QWIIC_SCL_PIN 3 -#define HB_2350A_RTC_INT_PIN 8 +#define HB_2350A_RTC_INT_PIN 22 #define HB_2350A_SDCARD_CS_PIN 9 #define HB_2350A_LORA_IO1_PIN 10 #define HB_2350A_LORA_IO3_PIN 11 -#define HB_2350A_LORA_CS_PIN 21 -#define HB_2350A_RTC_CLKIN_PIN 22 -#define HB_2350A_IMU_CLKOUT_PIN 23 +#define HB_2350A_LORA_CS_PIN 28 #define HB_2350A_LORA_BUSY_PIN 24 -#define HB_2350A_FUSB307_INT_PIN 25 #define HB_2350A_LORA_RESET_PIN 29 +#define HB_2350A_RTC_CLKIN_PIN 22 +#define HB_2350A_IMU_CLKOUT_PIN 23 +#define HB_2350A_FUSB307_INT_PIN 21 +#define HB_2350A_BQ25792_INT_PIN 8 // --- UART --- // Note, conflicts with HSTX range @@ -45,7 +46,11 @@ #define PICO_DEFAULT_UART_RX_PIN 13 #endif -// no PICO_DEFAULT_LED_PIN +// --- LED --- +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif + // no PICO_DEFAULT_WS2812_PIN // --- I2C --- @@ -72,9 +77,8 @@ #ifndef PICO_DEFAULT_SPI_RX_PIN #define PICO_DEFAULT_SPI_RX_PIN 20 #endif -#ifndef PICO_DEFAULT_SPI_CSN_PIN -#define PICO_DEFAULT_SPI_CSN_PIN 21 -#endif +// multiple devices, so this doesn't make much sense +// no PICO_DEFAULT_SPI_CSN_PIN // --- FLASH --- @@ -84,14 +88,14 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif // --- RP2350 VARIANT --- #define PICO_RP2350A 1 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/ilabs_challenger_rp2350_bconnect.h b/src/boards/include/boards/ilabs_challenger_rp2350_bconnect.h index 92d8960b8..97645a456 100644 --- a/src/boards/include/boards/ilabs_challenger_rp2350_bconnect.h +++ b/src/boards/include/boards/ilabs_challenger_rp2350_bconnect.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/ilabs_challenger_rp2350_bconnect.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_ILABS_CHALLENGER_RP2350_BCONNECT_H #define _BOARDS_ILABS_CHALLENGER_RP2350_BCONNECT_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define ILABS_CHALLENGER_RP2350_BCONNECT @@ -78,12 +78,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/ilabs_challenger_rp2350_wifi_ble.h b/src/boards/include/boards/ilabs_challenger_rp2350_wifi_ble.h index 1278209b8..b056cbcab 100644 --- a/src/boards/include/boards/ilabs_challenger_rp2350_wifi_ble.h +++ b/src/boards/include/boards/ilabs_challenger_rp2350_wifi_ble.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/ilabs_challenger_rp2350_wifi_ble.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_ILABS_CHALLENGER_RP2350_WIFI_BLE_H #define _BOARDS_ILABS_CHALLENGER_RP2350_WIFI_BLE_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define ILABS_CHALLENGER_RP2350_WIFI_BLE @@ -75,12 +75,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/ilabs_opendec02.h b/src/boards/include/boards/ilabs_opendec02.h index 197a024ec..f9b76a805 100644 --- a/src/boards/include/boards/ilabs_opendec02.h +++ b/src/boards/include/boards/ilabs_opendec02.h @@ -12,11 +12,11 @@ //------------------------------------------------------------------------------------------ // Board definition for the opendec02 open source dcc decoder // -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_ILABS_OPENDEC02_H #define _BOARDS_ILABS_OPENDEC02_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define ILABS_OPENDEC02 @@ -50,7 +50,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/machdyne_werkzeug.h b/src/boards/include/boards/machdyne_werkzeug.h index 8b45829b7..f624750cf 100644 --- a/src/boards/include/boards/machdyne_werkzeug.h +++ b/src/boards/include/boards/machdyne_werkzeug.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_MACHDYNE_WERKZEUG_H #define _BOARDS_MACHDYNE_WERKZEUG_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define MACHDYNE_WERKZEUG @@ -75,7 +75,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (1 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (1 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (1 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/melopero_perpetuo_rp2350_lora.h b/src/boards/include/boards/melopero_perpetuo_rp2350_lora.h index e86492b39..03e6568f4 100644 --- a/src/boards/include/boards/melopero_perpetuo_rp2350_lora.h +++ b/src/boards/include/boards/melopero_perpetuo_rp2350_lora.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/melopero_perpetuo_rp2350_lora.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_MELOPERO_PERPETUO_RP2350_LORA_H #define _BOARDS_MELOPERO_PERPETUO_RP2350_LORA_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define MELOPERO_PERPETUO_RP2350_LORA @@ -75,14 +75,14 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/melopero_shake_rp2040.h b/src/boards/include/boards/melopero_shake_rp2040.h index 49059c9ab..6a2f8564e 100644 --- a/src/boards/include/boards/melopero_shake_rp2040.h +++ b/src/boards/include/boards/melopero_shake_rp2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_MELOPERO_SHAKE_RP2040_H #define _BOARDS_MELOPERO_SHAKE_RP2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define MELOPERO_SHAKE_RP2040 @@ -82,7 +82,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/metrotech_xerxes_rp2040.h b/src/boards/include/boards/metrotech_xerxes_rp2040.h index a91d893ff..9998e92e3 100644 --- a/src/boards/include/boards/metrotech_xerxes_rp2040.h +++ b/src/boards/include/boards/metrotech_xerxes_rp2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_METROTECH_XERXES_RP2040_H #define _BOARDS_METROTECH_XERXES_RP2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + #define USR_SW_PIN 18 #define USR_BTN_PIN 24 #define USR_LED_PIN 25 @@ -144,7 +144,7 @@ #define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 16 #endif // !PICO_XOSC_STARTUP_DELAY_MULTIPLIER -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES /** * @brief 16MiB, Flash size in bytes diff --git a/src/boards/include/boards/net8086_usb_interposer.h b/src/boards/include/boards/net8086_usb_interposer.h index 4de560f44..09bd7724d 100644 --- a/src/boards/include/boards/net8086_usb_interposer.h +++ b/src/boards/include/boards/net8086_usb_interposer.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_NET8086_USB_INTERPOSER_H #define _BOARDS_NET8086_USB_INTERPOSER_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define NET8086_USB_INTERPOSER @@ -62,7 +62,7 @@ #define PICO_FLASH_SPI_CLKDIV 4 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/nullbits_bit_c_pro.h b/src/boards/include/boards/nullbits_bit_c_pro.h index 58bb1adc8..d9e6b3149 100644 --- a/src/boards/include/boards/nullbits_bit_c_pro.h +++ b/src/boards/include/boards/nullbits_bit_c_pro.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/nullbits_bit_c_pro.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_NULLBITS_BIT_C_PRO_H #define _BOARDS_NULLBITS_BIT_C_PRO_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define NULLBITS_BIT_C_PRO @@ -100,7 +100,7 @@ #endif // Bit-C PRO has 4MB SPI flash -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/olimex_rp2350_xl.h b/src/boards/include/boards/olimex_rp2350_xl.h new file mode 100644 index 000000000..06d249c22 --- /dev/null +++ b/src/boards/include/boards/olimex_rp2350_xl.h @@ -0,0 +1,89 @@ +/* + * 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 +// ----------------------------------------------------- + +// This header may be included by other board headers as "boards/olimex_rp2350_xl.h" + +#ifndef _BOARDS_OLIMEX_RP2350_XL_H +#define _BOARDS_OLIMEX_RP2350_XL_H + +pico_board_cmake_set(PICO_PLATFORM, rp2350) + +// Check https://github.com/OLIMEX/RP2350-PICO2-XXL + +// For board detection +#define OLIMEX_RP2350_XL + +// --- 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 0 +#endif +#ifndef PICO_DEFAULT_UART_RX_PIN +#define PICO_DEFAULT_UART_RX_PIN 1 +#endif + +// --- LED --- +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif + +// --- I2C --- +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 1 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 2 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 3 +#endif + +// --- SPI --- +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 0 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 6 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 7 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 4 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 5 +#endif + +// --- FLASH --- + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) +#endif + +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +#endif diff --git a/src/boards/include/boards/olimex_rp2350_xxl.h b/src/boards/include/boards/olimex_rp2350_xxl.h new file mode 100644 index 000000000..b9c90c95f --- /dev/null +++ b/src/boards/include/boards/olimex_rp2350_xxl.h @@ -0,0 +1,106 @@ +/* + * 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 +// ----------------------------------------------------- + +// This header may be included by other board headers as "boards/olimex_rp2350_xxl.h" + +#ifndef _BOARDS_OLIMEX_RP2350_XXL_H +#define _BOARDS_OLIMEX_RP2350_XXL_H + +pico_board_cmake_set(PICO_PLATFORM, rp2350) + +// Check https://github.com/OLIMEX/RP2350-PICO2-XXL + +// For board detection +#define OLIMEX_RP2350_XXL + +// --- 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 0 +#endif +#ifndef PICO_DEFAULT_UART_RX_PIN +#define PICO_DEFAULT_UART_RX_PIN 1 +#endif + +// --- LED --- +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif + +// --- I2C --- +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 1 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 2 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 3 +#endif + +// --- SPI --- +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 0 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 6 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 7 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 4 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 5 +#endif + +// --- XXL HAS AN SD CARD --- +#ifndef PICO_SD_CLK_PIN +#define PICO_SD_CLK_PIN 10 +#endif +#ifndef PICO_SD_CMD_PIN +#define PICO_SD_CMD_PIN 11 +#endif +#ifndef PICO_SD_DAT0_PIN +#define PICO_SD_DAT0_PIN 24 +#endif +#ifndef PICO_SD_DAT3_PIN +#define PICO_SD_DAT3_PIN 9 // DAT3 of the SD card is the chip select pin +#endif +#ifndef PICO_SD_DAT_PIN_COUNT +#define PICO_SD_DAT_PIN_COUNT 1 +#endif + +// --- FLASH --- + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) +#endif + +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +#endif diff --git a/src/boards/include/boards/phyx_rick_tny_rp2350.h b/src/boards/include/boards/phyx_rick_tny_rp2350.h index 7012ac141..c0a5a9cb9 100644 --- a/src/boards/include/boards/phyx_rick_tny_rp2350.h +++ b/src/boards/include/boards/phyx_rick_tny_rp2350.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/phyx_rick_tny_rp2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_PHYX_RICK_TNY_RP2350_H #define _BOARDS_PHYX_RICK_TNY_RP2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define PHYX_RICK_TNY_RP2350 @@ -75,12 +75,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/pi-plates_micropi.h b/src/boards/include/boards/pi-plates_micropi.h index 9c0dd62f2..3ae5c67ae 100644 --- a/src/boards/include/boards/pi-plates_micropi.h +++ b/src/boards/include/boards/pi-plates_micropi.h @@ -11,11 +11,11 @@ // Board definition for the Pi-Plates MICROPi processor board -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PI_PLATES_MICROPI_H #define _BOARDS_PI_PLATES_MICROPI_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PI_PLATES_MICROPI @@ -72,7 +72,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) //change to (16 * 1024 * 1024) on final product #endif diff --git a/src/boards/include/boards/pico.h b/src/boards/include/boards/pico.h index 800feb364..6eb8600b6 100644 --- a/src/boards/include/boards/pico.h +++ b/src/boards/include/boards/pico.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/pico.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PICO_H #define _BOARDS_PICO_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define RASPBERRYPI_PICO @@ -72,7 +72,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pico2.h b/src/boards/include/boards/pico2.h index 4dbb232d2..9998939ea 100644 --- a/src/boards/include/boards/pico2.h +++ b/src/boards/include/boards/pico2.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/pico2.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_PICO2_H #define _BOARDS_PICO2_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define RASPBERRYPI_PICO2 @@ -75,7 +75,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif @@ -93,7 +93,7 @@ #define PICO_VSYS_PIN 29 #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/pico2_w.h b/src/boards/include/boards/pico2_w.h index 42acdc4cc..32bc4a531 100644 --- a/src/boards/include/boards/pico2_w.h +++ b/src/boards/include/boards/pico2_w.h @@ -11,12 +11,12 @@ // This header may be included by other board headers as "boards/pico2_w.h" -// pico_cmake_set PICO_PLATFORM=rp2350 -// pico_cmake_set PICO_CYW43_SUPPORTED = 1 - #ifndef _BOARDS_PICO2_W_H #define _BOARDS_PICO2_W_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) +pico_board_cmake_set(PICO_CYW43_SUPPORTED, 1) + // For board detection #define RASPBERRYPI_PICO2_W @@ -74,7 +74,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif @@ -89,6 +89,12 @@ #define CYW43_WL_GPIO_LED_PIN 0 #endif +// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) +// As this is a CYW43 pin you can do this by calling cyw43_gpio_set +#ifndef CYW43_WL_GPIO_SMPS_PIN +#define CYW43_WL_GPIO_SMPS_PIN 1 +#endif + // If CYW43_WL_GPIO_VBUS_PIN is defined then a CYW43 GPIO has to be used to read VBUS. // This can be passed to cyw43_arch_gpio_get to determine if the device is battery powered. // PICO_VBUS_PIN and CYW43_WL_GPIO_VBUS_PIN should not both be defined. @@ -109,7 +115,7 @@ #define PICO_VSYS_PIN 29 #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/pico_w.h b/src/boards/include/boards/pico_w.h index 250662f1b..670cb3057 100644 --- a/src/boards/include/boards/pico_w.h +++ b/src/boards/include/boards/pico_w.h @@ -9,14 +9,14 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM = rp2040 -// pico_cmake_set PICO_CYW43_SUPPORTED = 1 - // This header may be included by other board headers as "boards/pico_w.h" #ifndef _BOARDS_PICO_W_H #define _BOARDS_PICO_W_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) +pico_board_cmake_set(PICO_CYW43_SUPPORTED, 1) + // For board detection #define RASPBERRYPI_PICO_W @@ -71,7 +71,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif @@ -94,6 +94,12 @@ #define CYW43_WL_GPIO_LED_PIN 0 #endif +// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) +// As this is a CYW43 pin you can do this by calling cyw43_gpio_set +#ifndef CYW43_WL_GPIO_SMPS_PIN +#define CYW43_WL_GPIO_SMPS_PIN 1 +#endif + // If CYW43_WL_GPIO_VBUS_PIN is defined then a CYW43 GPIO has to be used to read VBUS. // This can be passed to cyw43_arch_gpio_get to determine if the device is battery powered. // PICO_VBUS_PIN and CYW43_WL_GPIO_VBUS_PIN should not both be defined. diff --git a/src/boards/include/boards/pimoroni_badger2040.h b/src/boards/include/boards/pimoroni_badger2040.h index d05c4d4b5..d4e8a34bd 100644 --- a/src/boards/include/boards/pimoroni_badger2040.h +++ b/src/boards/include/boards/pimoroni_badger2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_BADGER2040_H #define _BOARDS_PIMORONI_BADGER2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_BADGER2040 @@ -106,7 +106,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_interstate75.h b/src/boards/include/boards/pimoroni_interstate75.h index e7baa07b2..067632c0b 100644 --- a/src/boards/include/boards/pimoroni_interstate75.h +++ b/src/boards/include/boards/pimoroni_interstate75.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_INTERSTATE75_H #define _BOARDS_PIMORONI_INTERSTATE75_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_INTERSTATE75 @@ -96,7 +96,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_keybow2040.h b/src/boards/include/boards/pimoroni_keybow2040.h index 083140294..e661b9e9d 100644 --- a/src/boards/include/boards/pimoroni_keybow2040.h +++ b/src/boards/include/boards/pimoroni_keybow2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_KEYBOW2040_H #define _BOARDS_PIMORONI_KEYBOW2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_KEYBOW2040 @@ -85,7 +85,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_motor2040.h b/src/boards/include/boards/pimoroni_motor2040.h index e183090c3..1e202f6e2 100644 --- a/src/boards/include/boards/pimoroni_motor2040.h +++ b/src/boards/include/boards/pimoroni_motor2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_MOTOR2040_H #define _BOARDS_PIMORONI_MOTOR2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_MOTOR2040 @@ -128,7 +128,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_pga2040.h b/src/boards/include/boards/pimoroni_pga2040.h index 25b9dd2b5..a33831fe5 100644 --- a/src/boards/include/boards/pimoroni_pga2040.h +++ b/src/boards/include/boards/pimoroni_pga2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_PGA2040_H #define _BOARDS_PIMORONI_PGA2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_PGA2040 @@ -69,7 +69,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_pga2350.h b/src/boards/include/boards/pimoroni_pga2350.h index f4f0a3d2a..7849444f5 100644 --- a/src/boards/include/boards/pimoroni_pga2350.h +++ b/src/boards/include/boards/pimoroni_pga2350.h @@ -11,15 +11,18 @@ // This header may be included by other board headers as "boards/pimoroni_pga2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_PIMORONI_PGA2350_H #define _BOARDS_PIMORONI_PGA2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define PIMORONI_PGA2350 #define PIMORONI_PGA2350_16MB +// --- RP2350 VARIANT --- +#define PICO_RP2350A 0 + // --- BOARD SPECIFIC --- #define PIMORONI_PGA2350_PSRAM_CS_PIN 47 @@ -76,7 +79,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif @@ -85,7 +88,7 @@ // no PICO_VBUS_PIN // no PICO_VSYS_PIN -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/pimoroni_pico_plus2_rp2350.h b/src/boards/include/boards/pimoroni_pico_plus2_rp2350.h index 34c5fb38f..6cae74b11 100644 --- a/src/boards/include/boards/pimoroni_pico_plus2_rp2350.h +++ b/src/boards/include/boards/pimoroni_pico_plus2_rp2350.h @@ -11,14 +11,17 @@ // This header may be included by other board headers as "boards/pimoroni_pico_plus2_rp2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_PIMORONI_PICO_PLUS2_RP2350_H #define _BOARDS_PIMORONI_PICO_PLUS2_RP2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // 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 @@ -83,7 +86,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif @@ -99,7 +102,7 @@ #define PICO_VSYS_PIN 43 #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/pimoroni_pico_plus2_w_rp2350.h b/src/boards/include/boards/pimoroni_pico_plus2_w_rp2350.h index ba3c0e56c..7f125aaa0 100644 --- a/src/boards/include/boards/pimoroni_pico_plus2_w_rp2350.h +++ b/src/boards/include/boards/pimoroni_pico_plus2_w_rp2350.h @@ -11,15 +11,18 @@ // This header may be included by other board headers as "boards/pimoroni_pico_plus2_w_rp2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 -// pico_cmake_set PICO_CYW43_SUPPORTED = 1 - #ifndef _BOARDS_PIMORONI_PICO_PLUS2_W_RP2350_H #define _BOARDS_PIMORONI_PICO_PLUS2_W_RP2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) +pico_board_cmake_set(PICO_CYW43_SUPPORTED, 1) + // 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 @@ -75,7 +78,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif @@ -86,7 +89,7 @@ #define PICO_VSYS_PIN 43 #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/pimoroni_picolipo_16mb.h b/src/boards/include/boards/pimoroni_picolipo_16mb.h index ad5bdf37c..d628b4422 100644 --- a/src/boards/include/boards/pimoroni_picolipo_16mb.h +++ b/src/boards/include/boards/pimoroni_picolipo_16mb.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_PICOLIPO_16MB_H #define _BOARDS_PIMORONI_PICOLIPO_16MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_PICOLIPO_16MB @@ -74,7 +74,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_picolipo_4mb.h b/src/boards/include/boards/pimoroni_picolipo_4mb.h index 981156fc3..1ea1beb91 100644 --- a/src/boards/include/boards/pimoroni_picolipo_4mb.h +++ b/src/boards/include/boards/pimoroni_picolipo_4mb.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_PICOLIPO_4MB_H #define _BOARDS_PIMORONI_PICOLIPO_4MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_PICOLIPO_4MB @@ -74,7 +74,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_picosystem.h b/src/boards/include/boards/pimoroni_picosystem.h index bacbd5734..59b8322b6 100644 --- a/src/boards/include/boards/pimoroni_picosystem.h +++ b/src/boards/include/boards/pimoroni_picosystem.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_PICOSYSTEM_H #define _BOARDS_PIMORONI_PICOSYSTEM_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_PICOSYSTEM @@ -91,7 +91,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_plasma2040.h b/src/boards/include/boards/pimoroni_plasma2040.h index c9937ef2f..d9d7db7f8 100644 --- a/src/boards/include/boards/pimoroni_plasma2040.h +++ b/src/boards/include/boards/pimoroni_plasma2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_PLASMA2040_H #define _BOARDS_PIMORONI_PLASMA2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_PLASMA2040 @@ -83,7 +83,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_plasma2350.h b/src/boards/include/boards/pimoroni_plasma2350.h index 7525a8a84..497bdbc80 100644 --- a/src/boards/include/boards/pimoroni_plasma2350.h +++ b/src/boards/include/boards/pimoroni_plasma2350.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/pimoroni_plasma2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_PIMORONI_PLASMA2350_H #define _BOARDS_PIMORONI_PLASMA2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define PIMORONI_PLASMA2350 @@ -104,12 +104,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/pimoroni_servo2040.h b/src/boards/include/boards/pimoroni_servo2040.h index 21f7049d7..55443c641 100644 --- a/src/boards/include/boards/pimoroni_servo2040.h +++ b/src/boards/include/boards/pimoroni_servo2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_SERVO2040_H #define _BOARDS_PIMORONI_SERVO2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_SERVO2040 @@ -104,7 +104,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_tiny2040.h b/src/boards/include/boards/pimoroni_tiny2040.h index 34e21f908..e38902083 100644 --- a/src/boards/include/boards/pimoroni_tiny2040.h +++ b/src/boards/include/boards/pimoroni_tiny2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_TINY2040_H #define _BOARDS_PIMORONI_TINY2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_TINY2040 #define PIMORONI_TINY2040_8MB @@ -92,7 +92,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_tiny2040_2mb.h b/src/boards/include/boards/pimoroni_tiny2040_2mb.h index 8e411cfdb..f7b24725d 100644 --- a/src/boards/include/boards/pimoroni_tiny2040_2mb.h +++ b/src/boards/include/boards/pimoroni_tiny2040_2mb.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_PIMORONI_TINY2040_2MB_H #define _BOARDS_PIMORONI_TINY2040_2MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define PIMORONI_TINY2040_2MB #define PIMORONI_TINY2040 @@ -92,7 +92,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/pimoroni_tiny2350.h b/src/boards/include/boards/pimoroni_tiny2350.h index bf00cbdb9..94e522c7e 100644 --- a/src/boards/include/boards/pimoroni_tiny2350.h +++ b/src/boards/include/boards/pimoroni_tiny2350.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/pimoroni_tiny2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_PIMORONI_TINY2350_H #define _BOARDS_PIMORONI_TINY2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define PIMORONI_TINY2350 #define PIMORONI_TINY2350_8MB @@ -84,12 +84,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/pololu_3pi_2040_robot.h b/src/boards/include/boards/pololu_3pi_2040_robot.h index 53e0db449..5479c0c83 100644 --- a/src/boards/include/boards/pololu_3pi_2040_robot.h +++ b/src/boards/include/boards/pololu_3pi_2040_robot.h @@ -9,18 +9,18 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_POLOLU_3PI_2040_ROBOT_H #define _BOARDS_POLOLU_3PI_2040_ROBOT_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define POLOLU_3PI_2040_ROBOT #define PICO_DEFAULT_LED_PIN 25 #define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 #define PICO_FLASH_SPI_CLKDIV 2 -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) // All boards have at least the B1 revision diff --git a/src/boards/include/boards/pololu_zumo_2040_robot.h b/src/boards/include/boards/pololu_zumo_2040_robot.h index 756b45a82..63abd1c24 100644 --- a/src/boards/include/boards/pololu_zumo_2040_robot.h +++ b/src/boards/include/boards/pololu_zumo_2040_robot.h @@ -9,18 +9,18 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_POLOLU_ZUMO_2040_ROBOT_H #define _BOARDS_POLOLU_ZUMO_2040_ROBOT_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define POLOLU_ZUMO_2040_ROBOT #define PICO_DEFAULT_LED_PIN 25 #define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 #define PICO_FLASH_SPI_CLKDIV 2 -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) // All boards have at least the B1 revision diff --git a/src/boards/include/boards/seeed_xiao_rp2040.h b/src/boards/include/boards/seeed_xiao_rp2040.h index efdb4cb18..a6b8f27d4 100644 --- a/src/boards/include/boards/seeed_xiao_rp2040.h +++ b/src/boards/include/boards/seeed_xiao_rp2040.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_SEEED_XIAO_RP2040_H #define _BOARDS_SEEED_XIAO_RP2040_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define SEEED_XIAO_RP2040 @@ -90,7 +90,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/seeed_xiao_rp2350.h b/src/boards/include/boards/seeed_xiao_rp2350.h index 52e163654..949d6741d 100644 --- a/src/boards/include/boards/seeed_xiao_rp2350.h +++ b/src/boards/include/boards/seeed_xiao_rp2350.h @@ -9,14 +9,17 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SEEED_XIAO_RP2350_H #define _BOARDS_SEEED_XIAO_RP2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SEEED_XIAO_RP2350 +// --- RP2350 VARIANT --- +#define PICO_RP2350A 1 + //------------- UART -------------// #ifndef PICO_DEFAULT_UART #define PICO_DEFAULT_UART 0 @@ -137,12 +140,12 @@ #define PICO_FLASH_SPI_CLKDIV 4 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/solderparty_rp2040_stamp.h b/src/boards/include/boards/solderparty_rp2040_stamp.h index af107f65a..fc95bec08 100644 --- a/src/boards/include/boards/solderparty_rp2040_stamp.h +++ b/src/boards/include/boards/solderparty_rp2040_stamp.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/solderparty_rp2040_stamp.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_SOLDERPARTY_RP2040_STAMP_H #define _BOARDS_SOLDERPARTY_RP2040_STAMP_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define SOLDERPARTY_RP2040_STAMP @@ -73,7 +73,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/solderparty_rp2040_stamp_carrier.h b/src/boards/include/boards/solderparty_rp2040_stamp_carrier.h index 811f13c46..8711d38bc 100644 --- a/src/boards/include/boards/solderparty_rp2040_stamp_carrier.h +++ b/src/boards/include/boards/solderparty_rp2040_stamp_carrier.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/solderparty_rp2040_stamp_carrier.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_SOLDERPARTY_RP2040_STAMP_CARRIER_H #define _BOARDS_SOLDERPARTY_RP2040_STAMP_CARRIER_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define SOLDERPARTY_RP2040_STAMP_CARRIER diff --git a/src/boards/include/boards/solderparty_rp2040_stamp_round_carrier.h b/src/boards/include/boards/solderparty_rp2040_stamp_round_carrier.h index 3dc0f6013..4e908c302 100644 --- a/src/boards/include/boards/solderparty_rp2040_stamp_round_carrier.h +++ b/src/boards/include/boards/solderparty_rp2040_stamp_round_carrier.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/solderparty_rp2040_stamp_round_carrier.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_SOLDERPARTY_RP2040_STAMP_ROUND_CARRIER_H #define _BOARDS_SOLDERPARTY_RP2040_STAMP_ROUND_CARRIER_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define SOLDERPARTY_RP2040_STAMP_ROUND_CARRIER diff --git a/src/boards/include/boards/solderparty_rp2350_stamp.h b/src/boards/include/boards/solderparty_rp2350_stamp.h index bb2fd7b52..9ce3930c3 100644 --- a/src/boards/include/boards/solderparty_rp2350_stamp.h +++ b/src/boards/include/boards/solderparty_rp2350_stamp.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/solderparty_rp2350_stamp.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SOLDERPARTY_RP2350_STAMP_H #define _BOARDS_SOLDERPARTY_RP2350_STAMP_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SOLDERPARTY_RP2350_STAMP @@ -73,12 +73,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/solderparty_rp2350_stamp_xl.h b/src/boards/include/boards/solderparty_rp2350_stamp_xl.h index 33233f7d6..1904d8448 100644 --- a/src/boards/include/boards/solderparty_rp2350_stamp_xl.h +++ b/src/boards/include/boards/solderparty_rp2350_stamp_xl.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/solderparty_rp2350_stamp_xl.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SOLDERPARTY_RP2350_STAMP_XL_H #define _BOARDS_SOLDERPARTY_RP2350_STAMP_XL_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SOLDERPARTY_RP2350_STAMP_XL @@ -73,12 +73,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/sparkfun_iotnode_lorawan_rp2350.h b/src/boards/include/boards/sparkfun_iotnode_lorawan_rp2350.h index 5bea33cc4..e0e329786 100644 --- a/src/boards/include/boards/sparkfun_iotnode_lorawan_rp2350.h +++ b/src/boards/include/boards/sparkfun_iotnode_lorawan_rp2350.h @@ -12,11 +12,11 @@ // // This header may be included by other board headers as "boards/sparkfun_iotnode_lorawan_rp2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SPARKFUN_IOTNODE_LORAWAN_RP2350_H #define _BOARDS_SPARKFUN_IOTNODE_LORAWAN_RP2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SPARKFUN_IOTNODE_LORAWAN_RP2350 @@ -75,12 +75,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/sparkfun_iotredboard_rp2350.h b/src/boards/include/boards/sparkfun_iotredboard_rp2350.h new file mode 100644 index 000000000..0c1d425bc --- /dev/null +++ b/src/boards/include/boards/sparkfun_iotredboard_rp2350.h @@ -0,0 +1,183 @@ +/* + * 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 IoT RedBoard - RP2350 +// +// This header may be included by other board headers as "boards/sparkfun_iotredboard_rp2350.h" + +#ifndef _BOARDS_SPARKFUN_IOTREDBOARD_RP2350_H +#define _BOARDS_SPARKFUN_IOTREDBOARD_RP2350_H + +pico_board_cmake_set(PICO_PLATFORM, rp2350) +pico_board_cmake_set(PICO_CYW43_SUPPORTED, 1) + +// For board detection +#define SPARKFUN_IOTREDBOARD_RP2350 + +// --- RP2350 VARIANT --- +#define PICO_RP2350A 0 // 1 for RP2350A, 0 for RP2350B + +// --- BOARD SPECIFIC --- +#define SPARKFUN_IOTREDBOARD_RP2350_USER_SW_PIN 39 +#define SPARKFUN_IOTREDBOARD_RP2350_PSRAM_CS_PIN 47 + + +// --- UART --- +#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 + +// --- LED --- +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif + +#ifndef PICO_DEFAULT_WS2812_PIN +#define PICO_DEFAULT_WS2812_PIN 3 +#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 22 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 23 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 20 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 21 +#endif + +// --- FLASH --- + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) +#endif + +// The IoT RedBoard has an SD Card. +#ifndef PICO_SD_CLK_PIN +#define PICO_SD_CLK_PIN 10 +#endif +#ifndef PICO_SD_CMD_PIN +#define PICO_SD_CMD_PIN 11 +#endif +#ifndef PICO_SD_DAT0_PIN +#define PICO_SD_DAT0_PIN 8 +#endif +#ifndef PICO_SD_DAT3_PIN +#define PICO_SD_DAT3_PIN 9 // DAT3 of the SD card is the chip select pin +#endif +#ifndef PICO_SD_DAT_PIN_COUNT +#define PICO_SD_DAT_PIN_COUNT 1 +#endif + +// The GPIO Pin used to monitor VSYS. Typically you would use this with ADC. +// There is an example in adc/read_vsys in pico-examples. +#ifndef PICO_VSYS_PIN +#define PICO_VSYS_PIN 46 +#endif + +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +// Bootloader activity LED in double reset mode. +#ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED +#define PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED PICO_DEFAULT_LED_PIN +#endif + +// Bootloader activity LED in USB reset mode. +#ifndef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED +#define PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED PICO_DEFAULT_LED_PIN +#endif + +// --- CYW43 --- + +#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 + +// If CYW43_WL_GPIO_VBUS_PIN is defined then a CYW43 GPIO has to be used to read VBUS. +// This can be passed to cyw43_arch_gpio_get to determine if the device is battery powered. +// PICO_VBUS_PIN and CYW43_WL_GPIO_VBUS_PIN should not both be defined. +#ifndef CYW43_WL_GPIO_VBUS_PIN +#define CYW43_WL_GPIO_VBUS_PIN 2 +#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 24u +#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 38u +#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 38u +#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 38u +#endif + +// gpio pin for the spi clock line to the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_CLOCK +#define CYW43_DEFAULT_PIN_WL_CLOCK 37u +#endif + +// gpio pin for the spi chip select to the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_CS +#define CYW43_DEFAULT_PIN_WL_CS 36u +#endif + +#endif // _BOARDS_SPARKFUN_IOTREDBOARD_RP2350_H diff --git a/src/boards/include/boards/sparkfun_micromod.h b/src/boards/include/boards/sparkfun_micromod.h index 5806bd19e..9403baa26 100644 --- a/src/boards/include/boards/sparkfun_micromod.h +++ b/src/boards/include/boards/sparkfun_micromod.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/sparkfun_micromod.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_SPARKFUN_MICROMOD_H #define _BOARDS_SPARKFUN_MICROMOD_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define SPARKFUN_MICROMOD @@ -75,7 +75,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/sparkfun_promicro.h b/src/boards/include/boards/sparkfun_promicro.h index da48c45f8..95d2da2cd 100644 --- a/src/boards/include/boards/sparkfun_promicro.h +++ b/src/boards/include/boards/sparkfun_promicro.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/sparkfun_promicro.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_SPARKFUN_PROMICRO_H #define _BOARDS_SPARKFUN_PROMICRO_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define SPARKFUN_PROMICRO @@ -75,7 +75,7 @@ #endif // board has 16M onboard flash -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/sparkfun_promicro_rp2350.h b/src/boards/include/boards/sparkfun_promicro_rp2350.h index 8709e8dca..d247e597b 100644 --- a/src/boards/include/boards/sparkfun_promicro_rp2350.h +++ b/src/boards/include/boards/sparkfun_promicro_rp2350.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/sparkfun_promicro_rp2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SPARKFUN_PROMICRO_RP2350_H #define _BOARDS_SPARKFUN_PROMICRO_RP2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SPARKFUN_PROMICRO_RP2350 @@ -73,7 +73,7 @@ #endif // board has 16M onboard flash -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif @@ -81,7 +81,7 @@ // --- RP2350 VARIANT --- #define PICO_RP2350A 1 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/sparkfun_thingplus.h b/src/boards/include/boards/sparkfun_thingplus.h index 1ed52b86c..0928387f8 100644 --- a/src/boards/include/boards/sparkfun_thingplus.h +++ b/src/boards/include/boards/sparkfun_thingplus.h @@ -14,11 +14,11 @@ // // This header may be included by other board headers as "boards/sparkfun_thingplus.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_SPARKFUN_THINGPLUS_H #define _BOARDS_SPARKFUN_THINGPLUS_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define SPARKFUN_THINGPLUS @@ -74,7 +74,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/sparkfun_thingplus_rp2350.h b/src/boards/include/boards/sparkfun_thingplus_rp2350.h index d023f943e..5b77ef324 100644 --- a/src/boards/include/boards/sparkfun_thingplus_rp2350.h +++ b/src/boards/include/boards/sparkfun_thingplus_rp2350.h @@ -12,12 +12,12 @@ // // This header may be included by other board headers as "boards/sparkfun_thingplus_rp2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 -// pico_cmake_set PICO_CYW43_SUPPORTED = 1 - #ifndef _BOARDS_SPARKFUN_THINGPLUS_RP2350_H #define _BOARDS_SPARKFUN_THINGPLUS_RP2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) +pico_board_cmake_set(PICO_CYW43_SUPPORTED, 1) + // For board detection #define SPARKFUN_THINGPLUS_RP2350 @@ -77,7 +77,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif @@ -114,7 +114,7 @@ #define CYW43_WL_GPIO_VBUS_PIN 2 #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/sparkfun_xrp_controller.h b/src/boards/include/boards/sparkfun_xrp_controller.h new file mode 100644 index 000000000..6b7099559 --- /dev/null +++ b/src/boards/include/boards/sparkfun_xrp_controller.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2024 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- +// Board definition for the SparkFun XRP Controller +// +// This header may be included by other board headers as "boards/sparkfun_xrp_controller.h" + +#ifndef _BOARDS_SPARKFUN_XRP_CONTROLLER_H +#define _BOARDS_SPARKFUN_XRP_CONTROLLER_H + +pico_board_cmake_set(PICO_PLATFORM, rp2350) +pico_board_cmake_set(PICO_CYW43_SUPPORTED, 1) + +// 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_board_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_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +// cyw43 SPI pins can't be changed at runtime +#ifndef CYW43_PIN_WL_DYNAMIC +#define CYW43_PIN_WL_DYNAMIC 0 +#endif + +// gpio pin to power up the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_REG_ON +#define CYW43_DEFAULT_PIN_WL_REG_ON 26u +#endif + +// gpio pin for spi data out to the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_DATA_OUT +#define CYW43_DEFAULT_PIN_WL_DATA_OUT 29u +#endif + +// gpio pin for spi data in from the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_DATA_IN +#define CYW43_DEFAULT_PIN_WL_DATA_IN 29u +#endif + +// gpio (irq) pin for the irq line from the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_HOST_WAKE +#define CYW43_DEFAULT_PIN_WL_HOST_WAKE 29u +#endif + +// gpio pin for the spi clock line to the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_CLOCK +#define CYW43_DEFAULT_PIN_WL_CLOCK 28u +#endif + +// gpio pin for the spi chip select to the cyw43 chip +#ifndef CYW43_DEFAULT_PIN_WL_CS +#define CYW43_DEFAULT_PIN_WL_CS 27u +#endif + +#endif diff --git a/src/boards/include/boards/switchscience_picossci2_conta_base.h b/src/boards/include/boards/switchscience_picossci2_conta_base.h index 638e47e57..6c84dd708 100644 --- a/src/boards/include/boards/switchscience_picossci2_conta_base.h +++ b/src/boards/include/boards/switchscience_picossci2_conta_base.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/switchscience_picossci2_conta_base.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SWITCHSCIENCE_PICOSSCI2_CONTA_BASE_H #define _BOARDS_SWITCHSCIENCE_PICOSSCI2_CONTA_BASE_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SWITCHSCIENCE_PICOSSCI2_CONTA_BASE @@ -74,12 +74,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/switchscience_picossci2_dev_board.h b/src/boards/include/boards/switchscience_picossci2_dev_board.h index b674362bd..6c2e86a29 100644 --- a/src/boards/include/boards/switchscience_picossci2_dev_board.h +++ b/src/boards/include/boards/switchscience_picossci2_dev_board.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/switchscience_picossci2_dev_board.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SWITCHSCIENCE_PICOSSCI2_DEV_BOARD_H #define _BOARDS_SWITCHSCIENCE_PICOSSCI2_DEV_BOARD_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SWITCHSCIENCE_PICOSSCI2_DEV_BOARD @@ -75,12 +75,12 @@ #endif // board has 4MB onboard flash -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/switchscience_picossci2_micro.h b/src/boards/include/boards/switchscience_picossci2_micro.h index e1ccf359a..e5521dc20 100644 --- a/src/boards/include/boards/switchscience_picossci2_micro.h +++ b/src/boards/include/boards/switchscience_picossci2_micro.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/switchscience_picossci2_micro.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SWITCHSCIENCE_PICOSSCI2_MICRO_H #define _BOARDS_SWITCHSCIENCE_PICOSSCI2_MICRO_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SWITCHSCIENCE_PICOSSCI2_MICRO @@ -61,12 +61,12 @@ #endif // board has 4MB onboard flash -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/switchscience_picossci2_rp2350_breakout.h b/src/boards/include/boards/switchscience_picossci2_rp2350_breakout.h index ec53d1658..7f6106129 100644 --- a/src/boards/include/boards/switchscience_picossci2_rp2350_breakout.h +++ b/src/boards/include/boards/switchscience_picossci2_rp2350_breakout.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/switchscience_picossci2_rp2350_breakout.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SWITCHSCIENCE_PICOSSCI2_RP2350_BREAKOUT_H #define _BOARDS_SWITCHSCIENCE_PICOSSCI2_RP2350_BREAKOUT_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SWITCHSCIENCE_PICOSSCI2_RP2350_BREAKOUT @@ -74,12 +74,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/switchscience_picossci2_tiny.h b/src/boards/include/boards/switchscience_picossci2_tiny.h index f422017bd..a88ef9905 100644 --- a/src/boards/include/boards/switchscience_picossci2_tiny.h +++ b/src/boards/include/boards/switchscience_picossci2_tiny.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/switchscience_picossci2_tiny.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_SWITCHSCIENCE_PICOSSCI2_TINY_H #define _BOARDS_SWITCHSCIENCE_PICOSSCI2_TINY_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define SWITCHSCIENCE_PICOSSCI2_TINY @@ -74,12 +74,12 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/tinycircuits_thumby_color_rp2350.h b/src/boards/include/boards/tinycircuits_thumby_color_rp2350.h index 58088e581..5725291c9 100644 --- a/src/boards/include/boards/tinycircuits_thumby_color_rp2350.h +++ b/src/boards/include/boards/tinycircuits_thumby_color_rp2350.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/tinycircuits_thumby_color_rp2350.h" -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_TINYCIRCUITS_THUMBY_COLOR_RP2350_H #define _BOARDS_TINYCIRCUITS_THUMBY_COLOR_RP2350_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define TINYCIRCUITS_THUMBY_COLOR_RP2350 @@ -75,7 +75,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif @@ -93,7 +93,7 @@ #define PICO_VSYS_PIN 29 #endif -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/uugear_wittypi5_hat_plus.h b/src/boards/include/boards/uugear_wittypi5_hat_plus.h new file mode 100644 index 000000000..5050d1956 --- /dev/null +++ b/src/boards/include/boards/uugear_wittypi5_hat_plus.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 Dun Cat B.V.(UUGear) + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// ----------------------------------------------------- +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES +// ----------------------------------------------------- + +// This header may be included by other board headers as "boards/uugear_wittypi5_hat_plus.h" + +#ifndef _BOARDS_UUGEAR_WITTYPI5_HAT_PLUS_H +#define _BOARDS_UUGEAR_WITTYPI5_HAT_PLUS_H + +pico_board_cmake_set(PICO_PLATFORM, rp2350) + +// For board detection +#define UUGEAR_WITTYPI5_HAT_PLUS + +// --- RP2350 VARIANT --- +#define PICO_RP2350A 1 + +// --- UART --- +#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 + +// --- LED --- +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 22 +#endif + +// --- I2C --- +#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 + +// --- FLASH --- +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 2 +#endif + +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) +#endif + +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +// Sometimes the xosc may take longer to stabilize +#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 +#endif + +#endif diff --git a/src/boards/include/boards/waveshare_pico_cam_a.h b/src/boards/include/boards/waveshare_pico_cam_a.h index a8b3b40e8..1bb1f7dd0 100755 --- a/src/boards/include/boards/waveshare_pico_cam_a.h +++ b/src/boards/include/boards/waveshare_pico_cam_a.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_PICO_CAM_A_H #define _BOARDS_WAVESHARE_PICO_CAM_A_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_PICO_CAM_A @@ -68,7 +68,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_ble.h b/src/boards/include/boards/waveshare_rp2040_ble.h index 8a56e9c58..060d2152c 100755 --- a/src/boards/include/boards/waveshare_rp2040_ble.h +++ b/src/boards/include/boards/waveshare_rp2040_ble.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_BLE_H #define _BOARDS_WAVESHARE_RP2040_BLE_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_BLE @@ -68,7 +68,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_eth.h b/src/boards/include/boards/waveshare_rp2040_eth.h index 8d3912e60..a2e955120 100755 --- a/src/boards/include/boards/waveshare_rp2040_eth.h +++ b/src/boards/include/boards/waveshare_rp2040_eth.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_ETH_H #define _BOARDS_WAVESHARE_RP2040_ETH_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_ETH @@ -68,7 +68,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_geek.h b/src/boards/include/boards/waveshare_rp2040_geek.h index cba41cf7f..50d9af18f 100755 --- a/src/boards/include/boards/waveshare_rp2040_geek.h +++ b/src/boards/include/boards/waveshare_rp2040_geek.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_GEEK_H #define _BOARDS_WAVESHARE_RP2040_GEEK_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_GEEK @@ -88,7 +88,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_lcd_0.96.h b/src/boards/include/boards/waveshare_rp2040_lcd_0.96.h index 267dc1753..024db9399 100644 --- a/src/boards/include/boards/waveshare_rp2040_lcd_0.96.h +++ b/src/boards/include/boards/waveshare_rp2040_lcd_0.96.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_LCD_0_96_H #define _BOARDS_WAVESHARE_RP2040_LCD_0_96_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_LCD_0_96 @@ -89,7 +89,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_lcd_1.28.h b/src/boards/include/boards/waveshare_rp2040_lcd_1.28.h index f88b9ed3d..c219b03a2 100644 --- a/src/boards/include/boards/waveshare_rp2040_lcd_1.28.h +++ b/src/boards/include/boards/waveshare_rp2040_lcd_1.28.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_LCD_1_28_H #define _BOARDS_WAVESHARE_RP2040_LCD_1_28_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_LCD_1_28 @@ -92,7 +92,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_matrix.h b/src/boards/include/boards/waveshare_rp2040_matrix.h index 9233a3639..0b31d7f91 100755 --- a/src/boards/include/boards/waveshare_rp2040_matrix.h +++ b/src/boards/include/boards/waveshare_rp2040_matrix.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_MATRIX_H #define _BOARDS_WAVESHARE_RP2040_MATRIX_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_MATRIX @@ -69,7 +69,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_one.h b/src/boards/include/boards/waveshare_rp2040_one.h index 389d2992d..5a48aee43 100644 --- a/src/boards/include/boards/waveshare_rp2040_one.h +++ b/src/boards/include/boards/waveshare_rp2040_one.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_ONE_H #define _BOARDS_WAVESHARE_RP2040_ONE_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_ONE @@ -68,7 +68,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_pizero.h b/src/boards/include/boards/waveshare_rp2040_pizero.h index 7c598fa59..be6b3c185 100755 --- a/src/boards/include/boards/waveshare_rp2040_pizero.h +++ b/src/boards/include/boards/waveshare_rp2040_pizero.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_PIZERO_H #define _BOARDS_WAVESHARE_RP2040_PIZERO_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_PIZERO @@ -65,7 +65,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_plus_16mb.h b/src/boards/include/boards/waveshare_rp2040_plus_16mb.h index 2d32acc9c..9471c529d 100644 --- a/src/boards/include/boards/waveshare_rp2040_plus_16mb.h +++ b/src/boards/include/boards/waveshare_rp2040_plus_16mb.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_PLUS_16MB_H #define _BOARDS_WAVESHARE_RP2040_PLUS_16MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_PLUS_16MB @@ -70,7 +70,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_plus_4mb.h b/src/boards/include/boards/waveshare_rp2040_plus_4mb.h index f5be65768..decdd19f1 100644 --- a/src/boards/include/boards/waveshare_rp2040_plus_4mb.h +++ b/src/boards/include/boards/waveshare_rp2040_plus_4mb.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_PLUS_4MB_H #define _BOARDS_WAVESHARE_RP2040_PLUS_4MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_PLUS_4MB @@ -70,7 +70,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_power_management_hat_b.h b/src/boards/include/boards/waveshare_rp2040_power_management_hat_b.h index 8290eb022..e81ef6e1b 100755 --- a/src/boards/include/boards/waveshare_rp2040_power_management_hat_b.h +++ b/src/boards/include/boards/waveshare_rp2040_power_management_hat_b.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_POWER_MANAGEMENT_HAT_B_H #define _BOARDS_WAVESHARE_RP2040_POWER_MANAGEMENT_HAT_B_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_POWER_MANAGEMENT_HAT_B @@ -65,7 +65,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_tiny.h b/src/boards/include/boards/waveshare_rp2040_tiny.h index 84f646280..6d21a5b5f 100755 --- a/src/boards/include/boards/waveshare_rp2040_tiny.h +++ b/src/boards/include/boards/waveshare_rp2040_tiny.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_TINY_H #define _BOARDS_WAVESHARE_RP2040_TINY_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_TINY @@ -68,7 +68,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_touch_lcd_1.28.h b/src/boards/include/boards/waveshare_rp2040_touch_lcd_1.28.h index 35a340197..c785e4cb0 100755 --- a/src/boards/include/boards/waveshare_rp2040_touch_lcd_1.28.h +++ b/src/boards/include/boards/waveshare_rp2040_touch_lcd_1.28.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_TOUCH_LCD_1_28_H #define _BOARDS_WAVESHARE_RP2040_TOUCH_LCD_1_28_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_TOUCH_LCD_1_28 @@ -93,7 +93,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2040_zero.h b/src/boards/include/boards/waveshare_rp2040_zero.h index 85be7c7f9..9298f474e 100644 --- a/src/boards/include/boards/waveshare_rp2040_zero.h +++ b/src/boards/include/boards/waveshare_rp2040_zero.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WAVESHARE_RP2040_ZERO_H #define _BOARDS_WAVESHARE_RP2040_ZERO_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WAVESHARE_RP2040_ZERO @@ -68,7 +68,7 @@ #define PICO_FLASH_SPI_CLKDIV 4 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/waveshare_rp2350_eth.h b/src/boards/include/boards/waveshare_rp2350_eth.h index f4aa7ee48..c90189aad 100755 --- a/src/boards/include/boards/waveshare_rp2350_eth.h +++ b/src/boards/include/boards/waveshare_rp2350_eth.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_ETH_H #define _BOARDS_WAVESHARE_RP2350_ETH_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_ETH @@ -72,14 +72,14 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/waveshare_rp2350_geek.h b/src/boards/include/boards/waveshare_rp2350_geek.h index ff065cbda..4c29348aa 100755 --- a/src/boards/include/boards/waveshare_rp2350_geek.h +++ b/src/boards/include/boards/waveshare_rp2350_geek.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_GEEK_H #define _BOARDS_WAVESHARE_RP2350_GEEK_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_GEEK @@ -92,14 +92,14 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/waveshare_rp2350_lcd_0.96.h b/src/boards/include/boards/waveshare_rp2350_lcd_0.96.h index fd6c9f778..a54bd3739 100755 --- a/src/boards/include/boards/waveshare_rp2350_lcd_0.96.h +++ b/src/boards/include/boards/waveshare_rp2350_lcd_0.96.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_LCD_0_96_H #define _BOARDS_WAVESHARE_RP2350_LCD_0_96_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_LCD_0_96 @@ -92,14 +92,14 @@ #define PICO_FLASH_SPI_CLKDIV 3 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/waveshare_rp2350_lcd_1.28.h b/src/boards/include/boards/waveshare_rp2350_lcd_1.28.h index 4d4e0e022..7c325193b 100755 --- a/src/boards/include/boards/waveshare_rp2350_lcd_1.28.h +++ b/src/boards/include/boards/waveshare_rp2350_lcd_1.28.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_LCD_1_28_H #define _BOARDS_WAVESHARE_RP2350_LCD_1_28_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_LCD_1_28 @@ -97,14 +97,14 @@ #define PICO_FLASH_SPI_CLKDIV 3 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/waveshare_rp2350_one.h b/src/boards/include/boards/waveshare_rp2350_one.h index 937e1b682..93cb5553c 100755 --- a/src/boards/include/boards/waveshare_rp2350_one.h +++ b/src/boards/include/boards/waveshare_rp2350_one.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_ONE_H #define _BOARDS_WAVESHARE_RP2350_ONE_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_ONE @@ -72,14 +72,14 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/waveshare_rp2350_plus_16mb.h b/src/boards/include/boards/waveshare_rp2350_plus_16mb.h index 8de280b1c..c674b1b74 100755 --- a/src/boards/include/boards/waveshare_rp2350_plus_16mb.h +++ b/src/boards/include/boards/waveshare_rp2350_plus_16mb.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_PLUS_16MB_H #define _BOARDS_WAVESHARE_RP2350_PLUS_16MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_PLUS_16MB @@ -74,14 +74,14 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/waveshare_rp2350_plus_4mb.h b/src/boards/include/boards/waveshare_rp2350_plus_4mb.h index 3c8b98617..0ae163f9f 100755 --- a/src/boards/include/boards/waveshare_rp2350_plus_4mb.h +++ b/src/boards/include/boards/waveshare_rp2350_plus_4mb.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_PLUS_4MB_H #define _BOARDS_WAVESHARE_RP2350_PLUS_4MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_PLUS_4MB @@ -74,14 +74,14 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/waveshare_rp2350_tiny.h b/src/boards/include/boards/waveshare_rp2350_tiny.h index 23af13c0f..d66ee2dda 100755 --- a/src/boards/include/boards/waveshare_rp2350_tiny.h +++ b/src/boards/include/boards/waveshare_rp2350_tiny.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_TINY_H #define _BOARDS_WAVESHARE_RP2350_TINY_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_TINY @@ -72,14 +72,14 @@ #define PICO_FLASH_SPI_CLKDIV 3 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/waveshare_rp2350_touch_lcd_1.28.h b/src/boards/include/boards/waveshare_rp2350_touch_lcd_1.28.h index 52eea9eb4..c8b4ce21c 100755 --- a/src/boards/include/boards/waveshare_rp2350_touch_lcd_1.28.h +++ b/src/boards/include/boards/waveshare_rp2350_touch_lcd_1.28.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_TOUCH_LCD_1_28_H #define _BOARDS_WAVESHARE_RP2350_TOUCH_LCD_1_28_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_TOUCH_LCD_1_28 @@ -96,14 +96,14 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/waveshare_rp2350_usb_a.h b/src/boards/include/boards/waveshare_rp2350_usb_a.h new file mode 100644 index 000000000..5720e71bd --- /dev/null +++ b/src/boards/include/boards/waveshare_rp2350_usb_a.h @@ -0,0 +1,101 @@ +/* + * 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 +// ----------------------------------------------------- + +#ifndef _BOARDS_WAVESHARE_RP2350_USB_A_H +#define _BOARDS_WAVESHARE_RP2350_USB_A_H + +pico_board_cmake_set(PICO_PLATFORM, rp2350) + +// For board detection +#define WAVESHARE_RP2350_USB_A + +// On some samples, the xosc can take longer to stabilize than is usual +#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 +#endif + +// --- RP2350 VARIANT --- +#define PICO_RP2350A 1 + +// --- UART --- +#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 + +// --- WS2812 --- +#ifndef PICO_DEFAULT_WS2812_PIN +#define PICO_DEFAULT_WS2812_PIN 16 +#endif + +// --- I2C --- +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 1 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 6 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 7 +#endif + +// --- SPI --- +#ifndef PICO_DEFAULT_SPI +#define PICO_DEFAULT_SPI 0 +#endif +#ifndef PICO_DEFAULT_SPI_SCK_PIN +#define PICO_DEFAULT_SPI_SCK_PIN 2 +#endif +#ifndef PICO_DEFAULT_SPI_TX_PIN +#define PICO_DEFAULT_SPI_TX_PIN 3 +#endif +#ifndef PICO_DEFAULT_SPI_RX_PIN +#define PICO_DEFAULT_SPI_RX_PIN 4 +#endif +#ifndef PICO_DEFAULT_SPI_CSN_PIN +#define PICO_DEFAULT_SPI_CSN_PIN 5 +#endif + +// --- PIO USB --- +#ifndef WAVESHARE_RP2350_USB_A_USB_DP_PIN +#define WAVESHARE_RP2350_USB_A_USB_DP_PIN 12 +#endif +#ifndef WAVESHARE_RP2350_USB_A_USB_DM_PIN +#define WAVESHARE_RP2350_USB_A_USB_DM_PIN 13 +#endif +#define PICO_DEFAULT_PIO_USB_DP_PIN WAVESHARE_RP2350_USB_A_USB_DP_PIN + +// --- FLASH --- +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + +#ifndef PICO_FLASH_SPI_CLKDIV +#define PICO_FLASH_SPI_CLKDIV 3 +#endif + +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) +#endif + +// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) +#define PICO_SMPS_MODE_PIN 23 + +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +#endif diff --git a/src/boards/include/boards/waveshare_rp2350_zero.h b/src/boards/include/boards/waveshare_rp2350_zero.h index 10b5d8b91..43a96f7c5 100755 --- a/src/boards/include/boards/waveshare_rp2350_zero.h +++ b/src/boards/include/boards/waveshare_rp2350_zero.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2350 - #ifndef _BOARDS_WAVESHARE_RP2350_ZERO_H #define _BOARDS_WAVESHARE_RP2350_ZERO_H +pico_board_cmake_set(PICO_PLATFORM, rp2350) + // For board detection #define WAVESHARE_RP2350_ZERO @@ -72,14 +72,14 @@ #define PICO_FLASH_SPI_CLKDIV 3 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1 +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) #ifndef PICO_RP2350_A2_SUPPORTED #define PICO_RP2350_A2_SUPPORTED 1 #endif diff --git a/src/boards/include/boards/weact_studio_rp2040_16mb.h b/src/boards/include/boards/weact_studio_rp2040_16mb.h index c8d3aa2ef..a27df8ef0 100644 --- a/src/boards/include/boards/weact_studio_rp2040_16mb.h +++ b/src/boards/include/boards/weact_studio_rp2040_16mb.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/weact_studio_rp2040_16mb.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WEACT_STUDIO_RP2040_16MB_H #define _BOARDS_WEACT_STUDIO_RP2040_16MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WEACT_STUDIO_RP2040_16MB @@ -75,7 +75,7 @@ #define PICO_RP2040_B0_SUPPORTED 0 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/weact_studio_rp2040_2mb.h b/src/boards/include/boards/weact_studio_rp2040_2mb.h index 4b0c00590..c1fba01f8 100644 --- a/src/boards/include/boards/weact_studio_rp2040_2mb.h +++ b/src/boards/include/boards/weact_studio_rp2040_2mb.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/weact_studio_rp2040_2mb.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WEACT_STUDIO_RP2040_2MB_H #define _BOARDS_WEACT_STUDIO_RP2040_2MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WEACT_STUDIO_RP2040_2MB @@ -75,7 +75,7 @@ #define PICO_RP2040_B0_SUPPORTED 0 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/weact_studio_rp2040_4mb.h b/src/boards/include/boards/weact_studio_rp2040_4mb.h index 405620d47..2557f1cbf 100644 --- a/src/boards/include/boards/weact_studio_rp2040_4mb.h +++ b/src/boards/include/boards/weact_studio_rp2040_4mb.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/weact_studio_rp2040_4mb.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WEACT_STUDIO_RP2040_4MB_H #define _BOARDS_WEACT_STUDIO_RP2040_4MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WEACT_STUDIO_RP2040_4MB @@ -75,7 +75,7 @@ #define PICO_RP2040_B0_SUPPORTED 0 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (4 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/weact_studio_rp2040_8mb.h b/src/boards/include/boards/weact_studio_rp2040_8mb.h index 72778c178..f90934fc3 100644 --- a/src/boards/include/boards/weact_studio_rp2040_8mb.h +++ b/src/boards/include/boards/weact_studio_rp2040_8mb.h @@ -11,11 +11,11 @@ // This header may be included by other board headers as "boards/weact_studio_rp2040_8mb.h" -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WEACT_STUDIO_RP2040_8MB_H #define _BOARDS_WEACT_STUDIO_RP2040_8MB_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WEACT_STUDIO_RP2040_8MB @@ -75,7 +75,7 @@ #define PICO_RP2040_B0_SUPPORTED 0 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (8 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (8 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/weact_studio_rp2350b_core.h b/src/boards/include/boards/weact_studio_rp2350b_core.h new file mode 100644 index 000000000..5e05e24a5 --- /dev/null +++ b/src/boards/include/boards/weact_studio_rp2350b_core.h @@ -0,0 +1,91 @@ +/* + * 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 +// ----------------------------------------------------- + +// This header may be included by other board headers as "boards/weact_studio_rp2350b_core.h" + +#ifndef _BOARDS_WEACT_STUDIO_RP2350B_CORE_H +#define _BOARDS_WEACT_STUDIO_RP2350B_CORE_H + +pico_board_cmake_set(PICO_PLATFORM, rp2350) + +// For board detection +#define WEACT_STUDIO_RP2350B_CORE + +// --- BOARD SPECIFIC --- +#define WEACT_STUDIO_RP2350B_USER_SW_PIN 23 +#define WEACT_STUDIO_RP2350B_PSRAM_CS_PIN 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 --- +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif + +// --- I2C --- +#ifndef PICO_DEFAULT_I2C +#define PICO_DEFAULT_I2C 0 +#endif +#ifndef PICO_DEFAULT_I2C_SDA_PIN +#define PICO_DEFAULT_I2C_SDA_PIN 8 +#endif +#ifndef PICO_DEFAULT_I2C_SCL_PIN +#define PICO_DEFAULT_I2C_SCL_PIN 9 +#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_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (16 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) +#endif + +// --- RP2350 VARIANT --- +// This means RP2350B. +#define PICO_RP2350A 0 + +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +#endif diff --git a/src/boards/include/boards/wiznet_w5100s_evb_pico.h b/src/boards/include/boards/wiznet_w5100s_evb_pico.h index 0640eadfb..9d33ffba7 100644 --- a/src/boards/include/boards/wiznet_w5100s_evb_pico.h +++ b/src/boards/include/boards/wiznet_w5100s_evb_pico.h @@ -9,11 +9,11 @@ // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // ----------------------------------------------------- -// pico_cmake_set PICO_PLATFORM=rp2040 - #ifndef _BOARDS_WIZNET_W5100S_EVB_PICO_H #define _BOARDS_WIZNET_W5100S_EVB_PICO_H +pico_board_cmake_set(PICO_PLATFORM, rp2040) + // For board detection #define WIZNET_W5100S_EVB_PICO @@ -89,7 +89,7 @@ #define PICO_FLASH_SPI_CLKDIV 2 #endif -// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (2 * 1024 * 1024) +pico_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) #ifndef PICO_FLASH_SIZE_BYTES #define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) #endif diff --git a/src/boards/include/boards/wiznet_w5100s_evb_pico2.h b/src/boards/include/boards/wiznet_w5100s_evb_pico2.h new file mode 100644 index 000000000..0db645455 --- /dev/null +++ b/src/boards/include/boards/wiznet_w5100s_evb_pico2.h @@ -0,0 +1,118 @@ +/* + * 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 +// ----------------------------------------------------- + +#ifndef _BOARDS_WIZNET_W5100S_EVB_PICO2_H +#define _BOARDS_WIZNET_W5100S_EVB_PICO2_H + +pico_board_cmake_set(PICO_PLATFORM, rp2350) + +// For board detection +#define WIZNET_W5100S_EVB_PICO2 + +// --- RP2350 VARIANT --- +#define PICO_RP2350A 1 + +// --- BOARD SPECIFIC --- +#ifndef W5100S_EVB_PICO2_INTN_PIN +#define W5100S_EVB_PICO2_INTN_PIN 21 +#endif + +#ifndef W5100S_EVB_PICO2_RSTN_PIN +#define W5100S_EVB_PICO2_RSTN_PIN 20 +#endif + +#ifndef W5100S_EVB_PICO2_A0_PIN +#define W5100S_EVB_PICO2_A0_PIN 26 +#endif +#ifndef W5100S_EVB_PICO2_A1_PIN +#define W5100S_EVB_PICO2_A1_PIN 27 +#endif +#ifndef W5100S_EVB_PICO2_A2_PIN +#define W5100S_EVB_PICO2_A2_PIN 28 +#endif + +// --- LED --- +#ifndef PICO_DEFAULT_LED_PIN +#define PICO_DEFAULT_LED_PIN 25 +#endif + +// --- UART --- +#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 + + +// --- I2C --- +#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_board_cmake_set_default(PICO_FLASH_SIZE_BYTES, (2 * 1024 * 1024)) +#ifndef PICO_FLASH_SIZE_BYTES +#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) +#endif +// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) +#define PICO_SMPS_MODE_PIN 23 + +// The GPIO Pin used to read VBUS to determine if the device is battery powered. +#ifndef PICO_VBUS_PIN +#define PICO_VBUS_PIN 24 +#endif + +// The GPIO Pin used to monitor VSYS. Typically you would use this with ADC. +// There is an example in adc/read_vsys in pico-examples. +#ifndef PICO_VSYS_PIN +#define PICO_VSYS_PIN 29 +#endif + +pico_board_cmake_set_default(PICO_RP2350_A2_SUPPORTED, 1) +#ifndef PICO_RP2350_A2_SUPPORTED +#define PICO_RP2350_A2_SUPPORTED 1 +#endif + +#endif diff --git a/src/cmake/on_device.cmake b/src/cmake/on_device.cmake index 00a5fffc6..69e2f3462 100644 --- a/src/cmake/on_device.cmake +++ b/src/cmake/on_device.cmake @@ -15,18 +15,38 @@ function(pico_get_runtime_output_directory TARGET output_path_name) set(${output_path_name} ${output_path} PARENT_SCOPE) endfunction() +function(pico_get_output_name TARGET output_name_var) + get_target_property(output_name ${TARGET} OUTPUT_NAME) + # Generator expressions not supported in byproducts + set(output_name_copy ${output_name}) + string(GENEX_STRIP "${output_name}" output_name) + if (NOT output_name OR (NOT output_name STREQUAL output_name_copy)) + get_target_property(output_name ${TARGET} NAME) + endif() + set(${output_name_var} ${output_name} PARENT_SCOPE) +endfunction() + +# pico_add_hex_output(TARGET) +# \brief\ Generate a hex file for the target function(pico_add_hex_output TARGET) pico_get_runtime_output_directory(${TARGET} output_path) - add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${output_path}$>,$,$>.hex VERBATIM) + pico_get_output_name(${TARGET} output_name) + add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${output_path}$>,$,$>.hex VERBATIM BYPRODUCTS "${output_path}${output_name}.hex") endfunction() +# pico_add_bin_output(TARGET) +# \brief\ Generate a bin file for the target function(pico_add_bin_output TARGET) pico_get_runtime_output_directory(${TARGET} output_path) - add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -Obinary $ ${output_path}$>,$,$>.bin VERBATIM) + pico_get_output_name(${TARGET} output_name) + add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -Obinary $ ${output_path}$>,$,$>.bin VERBATIM BYPRODUCTS "${output_path}${output_name}.bin") endfunction() +# pico_add_dis_output(TARGET) +# \brief\ Generate a disassembly file for the target function(pico_add_dis_output TARGET) pico_get_runtime_output_directory(${TARGET} output_path) + pico_get_output_name(${TARGET} output_name) # PICO_CMAKE_CONFIG: PICO_NO_COPRO_DIS, Disable disassembly listing postprocessing that disassembles RP2350 coprocessor instructions, type=bool, default=0, group=build if (NOT (PICO_NO_COPRO_DIS OR PICO_NO_PICOTOOL OR PICO_RISCV OR PICO_RP2040)) @@ -42,9 +62,14 @@ function(pico_add_dis_output TARGET) COMMAND ${CMAKE_OBJDUMP} -d ${PICO_DISASM_OBJDUMP_ARGS} $ >> ${output_path}$>,$,$>.dis ${EXTRA_COMMAND} VERBATIM + BYPRODUCTS "${output_path}${output_name}.dis" ) endfunction() +# pico_add_extra_outputs(TARGET) +# \brief_nodesc\ Perform post-build actions for the target +# +# Perform picotool processing and add disassembly, hex, bin, map, and uf2 outputs for the target function(pico_add_extra_outputs TARGET) # Disassembly will be nonsense for encrypted binaries, # so disassemble before picotool processing @@ -78,6 +103,7 @@ function(pico_add_extra_outputs TARGET) COMMAND rm -f "${PICO_SYMLINK_ELF_AS_FILENAME}" COMMAND ln -s -r $ "${PICO_SYMLINK_ELF_AS_FILENAME}" COMMENT "Symlinking from ${PICO_SYMLINK_ELF_AS_FILENAME} to ${TARGET}" + BYPRODUCTS "${PICO_SYMLINK_ELF_AS_FILENAME}" ) endif () # PICO_CMAKE_CONFIG: PICO_NO_UF2, Disable UF2 output, type=bool, default=0, group=build diff --git a/src/cmake/rp2_common.cmake b/src/cmake/rp2_common.cmake index 726bab933..d94d21f32 100644 --- a/src/cmake/rp2_common.cmake +++ b/src/cmake/rp2_common.cmake @@ -63,14 +63,14 @@ pico_add_subdirectory(rp2_common/hardware_watchdog) pico_add_subdirectory(rp2_common/hardware_xip_cache) pico_add_subdirectory(rp2_common/hardware_xosc) -if (PICO_RP2350 OR PICO_COMBINED_DOCS) +if (PICO_COMBINED_DOCS OR NOT PICO_RP2040) pico_add_subdirectory(rp2_common/hardware_powman) # Note in spite of the name this is usable on Arm as well as RISC-V: pico_add_subdirectory(rp2_common/hardware_riscv_platform_timer) pico_add_subdirectory(rp2_common/hardware_sha256) endif() -if (PICO_RP2350 OR PICO_COMBINED_DOCS) +if (PICO_COMBINED_DOCS OR NOT PICO_RP2040) pico_add_subdirectory(rp2_common/hardware_dcp) pico_add_subdirectory(rp2_common/hardware_rcp) endif() @@ -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) @@ -107,7 +108,7 @@ if (NOT PICO_BARE_METAL) pico_add_subdirectory(rp2_common/pico_printf) pico_add_subdirectory(rp2_common/pico_rand) - if (PICO_RP2350 OR PICO_COMBINED_DOCS) + if (PICO_COMBINED_DOCS OR NOT PICO_RP2040) pico_add_subdirectory(rp2_common/pico_sha256) endif() @@ -126,9 +127,9 @@ if (NOT PICO_BARE_METAL) pico_add_subdirectory(rp2_common/pico_async_context) pico_add_subdirectory(rp2_common/pico_btstack) pico_add_subdirectory(rp2_common/pico_cyw43_driver) + pico_add_subdirectory(rp2_common/pico_mbedtls) pico_add_subdirectory(rp2_common/pico_lwip) pico_add_subdirectory(rp2_common/pico_cyw43_arch) - pico_add_subdirectory(rp2_common/pico_mbedtls) pico_add_subdirectory(rp2_common/pico_time_adapter) diff --git a/src/common/boot_uf2_headers/include/boot/uf2.h b/src/common/boot_uf2_headers/include/boot/uf2.h index ffdcb90d1..279d4a131 100644 --- a/src/common/boot_uf2_headers/include/boot/uf2.h +++ b/src/common/boot_uf2_headers/include/boot/uf2.h @@ -26,13 +26,21 @@ #define UF2_FLAG_MD5_PRESENT 0x00004000u #define UF2_FLAG_EXTENSION_FLAGS_PRESENT 0x00008000u +// Extra family IDs +#define CYW43_FIRMWARE_FAMILY_ID 0xe48bff55u + +// Bootrom supported family IDs #define RP2040_FAMILY_ID 0xe48bff56u #define ABSOLUTE_FAMILY_ID 0xe48bff57u #define DATA_FAMILY_ID 0xe48bff58u #define RP2350_ARM_S_FAMILY_ID 0xe48bff59u #define RP2350_RISCV_FAMILY_ID 0xe48bff5au #define RP2350_ARM_NS_FAMILY_ID 0xe48bff5bu -#define FAMILY_ID_MAX 0xe48bff5bu +#define BOOTROM_FAMILY_ID_MIN RP2040_FAMILY_ID +#define BOOTROM_FAMILY_ID_MAX RP2350_ARM_NS_FAMILY_ID + +// Defined for backwards compatibility +#define FAMILY_ID_MAX BOOTROM_FAMILY_ID_MAX // 04 e3 57 99 #define UF2_EXTENSION_RP2_IGNORE_BLOCK 0x9957e304 diff --git a/src/common/pico_base_headers/BUILD.bazel b/src/common/pico_base_headers/BUILD.bazel index 5525c309b..c22f9ae8b 100644 --- a/src/common/pico_base_headers/BUILD.bazel +++ b/src/common/pico_base_headers/BUILD.bazel @@ -112,6 +112,7 @@ cc_library( "//src/rp2_common/hardware_watchdog:__pkg__", "//src/rp2_common/hardware_xosc:__pkg__", "//src/rp2_common/pico_crt0:__pkg__", + "//src/rp2_common/pico_platform_common:__pkg__", "//src/rp2_common/pico_printf:__pkg__", "//src/rp2_common/pico_runtime:__pkg__", "//src/rp2_common/pico_runtime_init:__pkg__", diff --git a/src/common/pico_base_headers/include/pico.h b/src/common/pico_base_headers/include/pico.h index 3b0f2f14a..2f33f19e7 100644 --- a/src/common/pico_base_headers/include/pico.h +++ b/src/common/pico_base_headers/include/pico.h @@ -26,6 +26,35 @@ #include "pico/types.h" #include "pico/version.h" +/** + * \brief A marker used in board headers to specify a CMake variable and value that should be set in the CMake build when the board header is used + * \ingroup pico_base + * + * Based on the PICO_BOARD CMake variable, the build will scan the board header for `pico_board_cmake_set(var, value)` and set these variables + * very early in the build configuration process. This allows setting CMake variables like `PICO_PLATFORM` from the board header, and thus + * affecting, for example, the choice of compiler made by the build + * + * \note use of this macro will overwrite the CMake variable if it is already set + * + * \note this macro's definition is empty as it is not intended to have any effect on actual compilation + */ +#define pico_board_cmake_set(x, y) + +/** + * \brief A marker used in board headers to specify a CMake variable and value that should be set in the CMake build when the board header is used, + * if that CMake variable has not already been set + * \ingroup pico_base + * + * Based on the PICO_BOARD CMake variable, the build will scan the board header for `pico_board_cmake_set_default(var, value)` and set these variables + * very early in the build configuration process. This allows setting CMake variables like `PICO_PLATFORM` from the board header, and thus + * affecting, for example, the choice of compiler made by the build + * + * \note use of this macro will not overwrite the CMake variable if it is already set + * + * \note this macro's definition is empty as it is not intended to have any effect on actual compilation + */ +#define pico_board_cmake_set_default(x, y) + // PICO_CONFIG: PICO_CONFIG_HEADER, Unquoted path to header include in place of the default pico/config.h which may be desirable for build systems which can't easily generate the config_autogen header, group=pico_base #ifdef PICO_CONFIG_HEADER #include __PICO_XSTRING(PICO_CONFIG_HEADER) diff --git a/src/common/pico_base_headers/include/pico/assert.h b/src/common/pico_base_headers/include/pico/assert.h index 36e25efae..cc33779a4 100644 --- a/src/common/pico_base_headers/include/pico/assert.h +++ b/src/common/pico_base_headers/include/pico/assert.h @@ -38,6 +38,16 @@ extern "C" { #ifdef NDEBUG extern void hard_assertion_failure(void); + +/*! \brief Perform a runtime assertion always (i.e. not just when NDEBUG is undefined) +* \ingroup pico_base +* +* This function is intended to provide useful information in debug builds like a normal assertion, but also +* prevent execution proceeding in other builds +* +* In debug builds this is equivalent to \ref assert, however in release builds it calls \ref hard_assertion_failure +* which, by default, just calls \ref panic with the string "Hard assert" +*/ static inline void hard_assert(bool condition, ...) { if (!condition) hard_assertion_failure(); diff --git a/src/common/pico_base_headers/include/pico/error.h b/src/common/pico_base_headers/include/pico/error.h index 9212eda81..26d0f837e 100644 --- a/src/common/pico_base_headers/include/pico/error.h +++ b/src/common/pico_base_headers/include/pico/error.h @@ -42,9 +42,9 @@ enum pico_error_codes { PICO_ERROR_UNSUPPORTED_MODIFICATION = -18, ///< Write is impossible based on previous writes; e.g. attempted to clear an OTP bit PICO_ERROR_LOCK_REQUIRED = -19, ///< A required lock is not owned PICO_ERROR_VERSION_MISMATCH = -20, ///< A version mismatch occurred (e.g. trying to run PIO version 1 code on RP2040) - PICO_ERROR_RESOURCE_IN_USE = -21 ///< The call could not proceed because requires resourcesw were unavailable + PICO_ERROR_RESOURCE_IN_USE = -21 ///< The call could not proceed because the required resources were unavailable }; #endif // !__ASSEMBLER__ -#endif \ No newline at end of file +#endif diff --git a/src/common/pico_base_headers/include/pico/types.h b/src/common/pico_base_headers/include/pico/types.h index 2e9c39642..010181eef 100644 --- a/src/common/pico_base_headers/include/pico/types.h +++ b/src/common/pico_base_headers/include/pico/types.h @@ -23,18 +23,18 @@ typedef unsigned int uint; #endif /*! \typedef absolute_time_t - \brief An opaque 64 bit timestamp in microseconds - - The type is used instead of a raw uint64_t to prevent accidentally passing relative times or times in the wrong - time units where an absolute time is required. - - note: As of SDK 2.0.0 this type defaults to being a uin64_t (i.e. no protection); it is enabled - by setting PICO_OPAQUE_ABSOLUTE_TIME_T to 1 - - \see to_us_since_boot() - \see update_us_since_boot() - \ingroup timestamp -*/ + * \brief An opaque 64 bit timestamp in microseconds + * + * The type is used instead of a raw uint64_t to prevent accidentally passing relative times or times in the wrong + * time units where an absolute time is required. + * + * note: As of SDK 2.0.0 this type defaults to being a uin64_t (i.e. no protection); it is enabled + * by setting PICO_OPAQUE_ABSOLUTE_TIME_T to 1 + * + * \see to_us_since_boot() + * \see update_us_since_boot() + * \ingroup timestamp + */ #if PICO_OPAQUE_ABSOLUTE_TIME_T typedef struct { uint64_t _private_us_since_boot; diff --git a/src/common/pico_binary_info/CMakeLists.txt b/src/common/pico_binary_info/CMakeLists.txt index d2bfd6914..5da8fb5aa 100644 --- a/src/common/pico_binary_info/CMakeLists.txt +++ b/src/common/pico_binary_info/CMakeLists.txt @@ -9,11 +9,19 @@ endif() target_link_libraries(pico_binary_info INTERFACE pico_binary_info_headers) +# pico_set_program_name(TARGET name) +# \brief\ Set the program name for the target +# +# \param\ name The program name to set function(pico_set_program_name TARGET name) # PICO_BUILD_DEFINE: PICO_PROGRAM_NAME, value passed to pico_set_program_name, type=string, group=pico_binary_info target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_NAME="${name}") endfunction() +# pico_set_program_description(TARGET description) +# \brief\ Set the program description for the target +# +# \param\ description The program description to set function(pico_set_program_description TARGET description) # since this is the command line, we will remove newlines string(REPLACE "\n" " " description ${description}) @@ -22,11 +30,19 @@ function(pico_set_program_description TARGET description) target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_DESCRIPTION="${description}") endfunction() +# pico_set_program_url(TARGET url) +# \brief\ Set the program URL for the target +# +# \param\ url The program URL to set function(pico_set_program_url TARGET url) # PICO_BUILD_DEFINE: PICO_PROGRAM_URL, value passed to pico_set_program_url, type=string, group=pico_binary_info target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_URL="${url}") endfunction() +# pico_set_program_version(TARGET version) +# \brief\ Set the program version for the target +# +# \param\ version The program version to set function(pico_set_program_version TARGET version) # PICO_BUILD_DEFINE: PICO_PROGRAM_VERSION_STRING, value passed to pico_set_program_version, type=string, group=pico_binary_info target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_VERSION_STRING="${version}") diff --git a/src/common/pico_binary_info/include/pico/binary_info/code.h b/src/common/pico_binary_info/include/pico/binary_info/code.h index 63239a963..b7fedc9ad 100644 --- a/src/common/pico_binary_info/include/pico/binary_info/code.h +++ b/src/common/pico_binary_info/include/pico/binary_info/code.h @@ -156,8 +156,8 @@ static const struct _binary_info_named_group __bi_lineno_var_name = { \ .tag = _parent_tag, \ },\ .parent_id = _parent_id, \ - .group_tag = _group_tag, \ .flags = _flags, \ + .group_tag = _group_tag, \ .group_id = _group_id, \ .label = _label \ } diff --git a/src/common/pico_sync/include/pico/critical_section.h b/src/common/pico_sync/include/pico/critical_section.h index 0e9907a9c..9874f9fff 100644 --- a/src/common/pico_sync/include/pico/critical_section.h +++ b/src/common/pico_sync/include/pico/critical_section.h @@ -7,6 +7,7 @@ #ifndef _PICO_CRITICAL_SECTION_H #define _PICO_CRITICAL_SECTION_H +#include "pico.h" #include "pico/lock_core.h" #ifdef __cplusplus @@ -58,7 +59,7 @@ void critical_section_init_with_lock_num(critical_section_t *crit_sec, uint lock * * \param crit_sec Pointer to critical_section structure */ -static inline void critical_section_enter_blocking(critical_section_t *crit_sec) { +__force_inline static void critical_section_enter_blocking(critical_section_t *crit_sec) { crit_sec->save = spin_lock_blocking(crit_sec->spin_lock); } @@ -67,7 +68,7 @@ static inline void critical_section_enter_blocking(critical_section_t *crit_sec) * * \param crit_sec Pointer to critical_section structure */ -static inline void critical_section_exit(critical_section_t *crit_sec) { +__force_inline static void critical_section_exit(critical_section_t *crit_sec) { spin_unlock(crit_sec->spin_lock, crit_sec->save); } diff --git a/src/common/pico_sync/sem.c b/src/common/pico_sync/sem.c index 904481706..8fc44580f 100644 --- a/src/common/pico_sync/sem.c +++ b/src/common/pico_sync/sem.c @@ -15,7 +15,7 @@ void sem_init(semaphore_t *sem, int16_t initial_permits, int16_t max_permits) { } int __time_critical_func(sem_available)(semaphore_t *sem) { -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) return *(volatile typeof(sem->permits) *) &sem->permits; #else static_assert(sizeof(sem->permits) == 2, ""); diff --git a/src/common/pico_time/include/pico/time.h b/src/common/pico_time/include/pico/time.h index 771fe42d6..43d5ed7a9 100644 --- a/src/common/pico_time/include/pico/time.h +++ b/src/common/pico_time/include/pico/time.h @@ -216,7 +216,7 @@ static inline bool is_nil_time(absolute_time_t t) { * \note These functions should not be called from an IRQ handler. * * \note Lower powered sleep requires use of the \link alarm_pool_get_default default alarm pool\endlink which may - * be disabled by the PICO_TIME_DEFAULT_ALARM_POOL_DISABLED #define or currently full in which case these functions + * be disabled by the PICO_TIME_DEFAULT_ALARM_POOL_DISABLED \#define or currently full in which case these functions * become busy waits instead. * * \note Whilst \a sleep_ functions are preferable to \a busy_wait functions from a power perspective, the \a busy_wait equivalent function @@ -420,7 +420,7 @@ alarm_pool_timer_t *alarm_pool_get_default_timer(void); * \param max_timers the maximum number of timers * \note For implementation reasons this is limited to PICO_PHEAP_MAX_ENTRIES which defaults to 255 * \sa alarm_pool_get_default() - * \sa hardware_claiming + * \sa hardware_claim */ static inline alarm_pool_t *alarm_pool_create(uint timer_alarm_num, uint max_timers) { return alarm_pool_create_on_timer(alarm_pool_get_default_timer(), timer_alarm_num, max_timers); @@ -443,7 +443,7 @@ alarm_pool_t *alarm_pool_create_on_timer_with_unused_hardware_alarm(alarm_pool_t * \param max_timers the maximum number of timers * \note For implementation reasons this is limited to PICO_PHEAP_MAX_ENTRIES which defaults to 255 * \sa alarm_pool_get_default() - * \sa hardware_claiming + * \sa hardware_claim */ static inline alarm_pool_t *alarm_pool_create_with_unused_hardware_alarm(uint max_timers) { return alarm_pool_create_on_timer_with_unused_hardware_alarm(alarm_pool_get_default_timer(), max_timers); diff --git a/src/common/pico_util/datetime.c b/src/common/pico_util/datetime.c index 130e2d5a6..6b59f287e 100644 --- a/src/common/pico_util/datetime.c +++ b/src/common/pico_util/datetime.c @@ -63,6 +63,7 @@ void datetime_to_tm(const datetime_t *dt, struct tm *tm) { tm->tm_hour = dt->hour; tm->tm_min = dt->min; tm->tm_sec = dt->sec; + tm->tm_isdst = -1; } void tm_to_datetime(const struct tm *tm, datetime_t *dt) { diff --git a/src/host/hardware_irq/include/hardware/irq.h b/src/host/hardware_irq/include/hardware/irq.h index 0e881b7a7..ef90ee703 100644 --- a/src/host/hardware_irq/include/hardware/irq.h +++ b/src/host/hardware_irq/include/hardware/irq.h @@ -128,7 +128,7 @@ extern "C" { typedef void (*irq_handler_t)(void); static inline void check_irq_param(__unused uint num) { - invalid_params_if(HARDWARE_IRQ, num >= NUM_IRQS); + invalid_params_if(HARDWARE_IRQ, num >= PICO_NUM_VTABLE_IRQS); } /*! \brief Set specified interrupt's priority diff --git a/src/host/hardware_irq/irq.c b/src/host/hardware_irq/irq.c index ad793c19d..db452ab12 100644 --- a/src/host/hardware_irq/irq.c +++ b/src/host/hardware_irq/irq.c @@ -96,7 +96,7 @@ void PICO_WEAK_FUNCTION_IMPL_NAME(irq_init_priorities)() { } static uint get_user_irq_claim_index(uint irq_num) { - invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= NUM_IRQS); + invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= PICO_NUM_VTABLE_IRQS); // we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31 static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today. return NUM_IRQS - irq_num - 1u; diff --git a/src/host/hardware_sync/include/hardware/sync.h b/src/host/hardware_sync/include/hardware/sync.h index ffbc08032..ae3865ae2 100644 --- a/src/host/hardware_sync/include/hardware/sync.h +++ b/src/host/hardware_sync/include/hardware/sync.h @@ -121,6 +121,10 @@ void restore_interrupts(uint32_t status); void restore_interrupts_from_disabled(uint32_t status); +void disable_interrupts(void); + +void enable_interrupts(void); + uint spin_lock_get_num(spin_lock_t *lock); spin_lock_t *spin_lock_instance(uint lock_num); diff --git a/src/host/hardware_sync/sync_core0_only.c b/src/host/hardware_sync/sync_core0_only.c index 47d0f2f5b..70964c4b0 100644 --- a/src/host/hardware_sync/sync_core0_only.c +++ b/src/host/hardware_sync/sync_core0_only.c @@ -31,6 +31,15 @@ PICO_WEAK_FUNCTION_DEF(restore_interrupts_from_disabled) void PICO_WEAK_FUNCTION_IMPL_NAME(restore_interrupts_from_disabled)(uint32_t status) { } +PICO_WEAK_FUNCTION_DEF(disable_interrupts) + +void PICO_WEAK_FUNCTION_IMPL_NAME(disable_interrupts)(void) { +} + +PICO_WEAK_FUNCTION_DEF(enable_interrupts) + +void PICO_WEAK_FUNCTION_IMPL_NAME(enable_interrupts)(void) { +} PICO_WEAK_FUNCTION_DEF(spin_lock_instance) diff --git a/src/host/pico_platform/include/pico/platform.h b/src/host/pico_platform/include/pico/platform.h index 2854ab6f7..0338354e5 100644 --- a/src/host/pico_platform/include/pico/platform.h +++ b/src/host/pico_platform/include/pico/platform.h @@ -60,6 +60,12 @@ extern void tight_loop_contents(); #define __noinline __attribute__((noinline)) #endif +#ifndef __force_inline +// don't think it is critical to inline in host mode, and this is simpler than picking the +// correct attribute incantation for always_inline on different compiler versions +#define __force_inline inline +#endif + #ifndef __aligned #define __aligned(x) __attribute__((aligned(x))) #endif diff --git a/src/rp2040/boot_stage2/CMakeLists.txt b/src/rp2040/boot_stage2/CMakeLists.txt index ba42256b7..2798b3640 100644 --- a/src/rp2040/boot_stage2/CMakeLists.txt +++ b/src/rp2040/boot_stage2/CMakeLists.txt @@ -33,7 +33,13 @@ set(PICO_BOOT_STAGE2_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "") pico_add_library(boot_stage2_headers) target_include_directories(boot_stage2_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) -# by convention the first source file name without extension is used for the binary info name +# pico_define_boot_stage2(NAME SOURCES) +# \brief\ Define a boot stage 2 target. +# +# By convention the first source file name without extension is used for the binary info name +# +# \param\ NAME The name of the boot stage 2 target +# \param\ SOURCES The source files to link into the boot stage 2 function(pico_define_boot_stage2 NAME SOURCES) add_executable(${NAME} ${SOURCES} @@ -97,7 +103,12 @@ endmacro() pico_define_boot_stage2(bs2_default ${PICO_DEFAULT_BOOT_STAGE2_FILE}) +# pico_clone_default_boot_stage2(NAME) +# \brief_nodesc\ Clone the default boot stage 2 target. +# # Create a new boot stage 2 target using the default implementation for the current build (PICO_BOARD derived) +# +# \param\ NAME The name of the new boot stage 2 target function(pico_clone_default_boot_stage2 NAME) pico_define_boot_stage2(${NAME} ${PICO_DEFAULT_BOOT_STAGE2_FILE}) endfunction() diff --git a/src/rp2040/hardware_regs/RP2040.svd b/src/rp2040/hardware_regs/RP2040.svd index 2bac8265d..50a5a93f7 100644 --- a/src/rp2040/hardware_regs/RP2040.svd +++ b/src/rp2040/hardware_regs/RP2040.svd @@ -51022,5 +51022,38 @@ SPDX-License-Identifier: BSD-3-Clause + + SPARE_IRQ + 0x00000000 + + 0 + 4 + reserved + + + SPARE_IRQ_0 + 26 + + + SPARE_IRQ_1 + 27 + + + SPARE_IRQ_2 + 28 + + + SPARE_IRQ_3 + 29 + + + SPARE_IRQ_4 + 30 + + + SPARE_IRQ_5 + 31 + + diff --git a/src/rp2040/hardware_regs/include/hardware/platform_defs.h b/src/rp2040/hardware_regs/include/hardware/platform_defs.h index 537988846..a877710d0 100644 --- a/src/rp2040/hardware_regs/include/hardware/platform_defs.h +++ b/src/rp2040/hardware_regs/include/hardware/platform_defs.h @@ -46,6 +46,15 @@ #define HAS_SIO_DIVIDER 1 #define HAS_RP2040_RTC 1 + +#ifndef FPGA_CLK_SYS_HZ +#define FPGA_CLK_SYS_HZ (48 * MHZ) +#endif + +#ifndef FPGA_CLK_REF_HZ +#define FPGA_CLK_REF_HZ (12 * MHZ) +#endif + // PICO_CONFIG: XOSC_HZ, Crystal oscillator frequency in Hz, type=int, default=12000000, advanced=true, group=hardware_base // NOTE: The system and USB clocks are generated from the frequency using two PLLs. // If you override this define, or SYS_CLK_HZ/USB_CLK_HZ below, you will *also* need to add your own adjusted PLL set-up defines to diff --git a/src/rp2040/hardware_regs/include/hardware/regs/intctrl.h b/src/rp2040/hardware_regs/include/hardware/regs/intctrl.h index 3190b413d..71c6eb90b 100644 --- a/src/rp2040/hardware_regs/include/hardware/regs/intctrl.h +++ b/src/rp2040/hardware_regs/include/hardware/regs/intctrl.h @@ -39,6 +39,12 @@ #define I2C0_IRQ 23 #define I2C1_IRQ 24 #define RTC_IRQ 25 +#define SPARE_IRQ_0 26 +#define SPARE_IRQ_1 27 +#define SPARE_IRQ_2 28 +#define SPARE_IRQ_3 29 +#define SPARE_IRQ_4 30 +#define SPARE_IRQ_5 31 #else /** * \brief Interrupt numbers on RP2040 (used as typedef \ref irq_num_t) @@ -71,6 +77,12 @@ typedef enum irq_num_rp2040 { I2C0_IRQ = 23, ///< Select I2C0's IRQ output I2C1_IRQ = 24, ///< Select I2C1's IRQ output RTC_IRQ = 25, ///< Select RTC's IRQ output + SPARE_IRQ_0 = 26, ///< Select SPARE IRQ 0 + SPARE_IRQ_1 = 27, ///< Select SPARE IRQ 1 + SPARE_IRQ_2 = 28, ///< Select SPARE IRQ 2 + SPARE_IRQ_3 = 29, ///< Select SPARE IRQ 3 + SPARE_IRQ_4 = 30, ///< Select SPARE IRQ 4 + SPARE_IRQ_5 = 31, ///< Select SPARE IRQ 5 IRQ_COUNT } irq_num_t; #endif @@ -101,6 +113,12 @@ typedef enum irq_num_rp2040 { #define isr_i2c0 isr_irq23 #define isr_i2c1 isr_irq24 #define isr_rtc isr_irq25 +#define isr_spare_0 isr_irq26 +#define isr_spare_1 isr_irq27 +#define isr_spare_2 isr_irq28 +#define isr_spare_3 isr_irq29 +#define isr_spare_4 isr_irq30 +#define isr_spare_5 isr_irq31 #endif // _INTCTRL_H diff --git a/src/rp2040/pico_platform/BUILD.bazel b/src/rp2040/pico_platform/BUILD.bazel index bc860f1f4..47b90e434 100644 --- a/src/rp2040/pico_platform/BUILD.bazel +++ b/src/rp2040/pico_platform/BUILD.bazel @@ -27,6 +27,7 @@ cc_library( deps = [ "//src/rp2040/hardware_regs", "//src/rp2040/hardware_regs:platform_defs", + "//src/rp2_common/pico_platform_common:pico_platform_common_headers", "//src/rp2_common/pico_platform_compiler", "//src/rp2_common/pico_platform_panic:pico_platform_panic_headers", "//src/rp2_common/pico_platform_sections", @@ -44,6 +45,7 @@ cc_library( "//src/rp2040/hardware_regs", "//src/rp2040/hardware_regs:platform_defs", "//src/rp2_common/hardware_base", + "//src/rp2_common/pico_platform_common", "//src/rp2_common/pico_platform_compiler", "//src/rp2_common/pico_platform_panic", "//src/rp2_common/pico_platform_sections", diff --git a/src/rp2040/pico_platform/CMakeLists.txt b/src/rp2040/pico_platform/CMakeLists.txt index f7c607a4f..9c91df3ea 100644 --- a/src/rp2040/pico_platform/CMakeLists.txt +++ b/src/rp2040/pico_platform/CMakeLists.txt @@ -17,6 +17,7 @@ if (NOT TARGET pico_platform) target_link_libraries(pico_platform_headers INTERFACE hardware_regs) pico_mirrored_target_link_libraries(pico_platform INTERFACE + pico_platform_common pico_platform_compiler pico_platform_panic pico_platform_sections diff --git a/src/rp2040/pico_platform/include/pico/platform.h b/src/rp2040/pico_platform/include/pico/platform.h index 5c157f532..437ff31f4 100644 --- a/src/rp2040/pico_platform/include/pico/platform.h +++ b/src/rp2040/pico_platform/include/pico/platform.h @@ -23,6 +23,7 @@ #include "pico/platform/compiler.h" #include "pico/platform/sections.h" #include "pico/platform/panic.h" +#include "pico/platform/common.h" #include "hardware/regs/addressmap.h" #include "hardware/regs/sio.h" @@ -66,10 +67,6 @@ #define PICO_RP2040_B2_SUPPORTED 1 #endif -#ifndef PICO_RAM_VECTOR_TABLE_SIZE -#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS) -#endif - // PICO_CONFIG: PICO_CLKDIV_ROUND_NEAREST, True if floating point clock divisors should be rounded to the nearest possible clock divisor by default rather than rounding down, type=bool, default=1, group=pico_platform #ifndef PICO_CLKDIV_ROUND_NEAREST #define PICO_CLKDIV_ROUND_NEAREST 1 @@ -80,16 +77,6 @@ #ifdef __cplusplus extern "C" { #endif - -/*! \brief No-op function for the body of tight loops - * \ingroup pico_platform - * - * No-op function intended to be called by any tight hardware polling loop. Using this ubiquitously - * makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup - * debugging might be added - */ -static __force_inline void tight_loop_contents(void) {} - /*! \brief Helper method to busy-wait for at least the given number of cycles * \ingroup pico_platform * @@ -112,17 +99,6 @@ static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) { ); } -// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime -#ifndef PICO_NO_FPGA_CHECK -#define PICO_NO_FPGA_CHECK 1 -#endif - -#if PICO_NO_FPGA_CHECK -static inline bool running_on_fpga(void) {return false;} -#else -bool running_on_fpga(void); -#endif - /*! \brief Execute a breakpoint instruction * \ingroup pico_platform */ @@ -158,9 +134,6 @@ static __force_inline uint __get_current_exception(void) { return exception; } -#define host_safe_hw_ptr(x) ((uintptr_t)(x)) -#define native_safe_hw_ptr(x) host_safe_hw_ptr(x) - /*! \brief Returns the RP2040 chip revision number * \ingroup pico_platform * @return the RP2040 chip revision number (1 for B0/B1, 2 for B2) diff --git a/src/rp2040/pico_platform/platform.c b/src/rp2040/pico_platform/platform.c index 9b0016535..5468670d6 100644 --- a/src/rp2040/pico_platform/platform.c +++ b/src/rp2040/pico_platform/platform.c @@ -6,23 +6,8 @@ #include "pico.h" #include "hardware/address_mapped.h" -#include "hardware/regs/tbman.h" #include "hardware/regs/sysinfo.h" -// Note we leave the FPGA check in by default so that we can run bug repro -// binaries coming in from the wild on the FPGA platform. It takes up around -// 48 bytes if you include all the calls, so you can pass PICO_NO_FPGA_CHECK=1 -// to remove it. The FPGA check is used to skip initialisation of hardware -// (mainly clock generators and oscillators) that aren't present on FPGA. - -#if !PICO_NO_FPGA_CHECK -// Inline stub provided in header if this code is unused (so folding can be -// done in each TU instead of relying on LTO) -bool running_on_fpga(void) { - return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS; -} -#endif - #define MANUFACTURER_RPI 0x927 #define PART_RP2 0x2 diff --git a/src/rp2350/boot_stage2/CMakeLists.txt b/src/rp2350/boot_stage2/CMakeLists.txt index e878ccc5b..fbf95b53a 100644 --- a/src/rp2350/boot_stage2/CMakeLists.txt +++ b/src/rp2350/boot_stage2/CMakeLists.txt @@ -33,7 +33,13 @@ set(PICO_BOOT_STAGE2_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "") pico_add_library(boot_stage2_headers) target_include_directories(boot_stage2_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) -# by convention the first source file name without extension is used for the binary info name +# pico_define_boot_stage2(NAME SOURCES) +# \brief\ Define a boot stage 2 target. +# +# By convention the first source file name without extension is used for the binary info name +# +# \param\ NAME The name of the boot stage 2 target +# \param\ SOURCES The source files to link into the boot stage 2 function(pico_define_boot_stage2 NAME SOURCES) add_executable(${NAME} ${SOURCES} @@ -97,7 +103,12 @@ endmacro() pico_define_boot_stage2(bs2_default ${PICO_DEFAULT_BOOT_STAGE2_FILE}) +# pico_clone_default_boot_stage2(NAME) +# \brief_nodesc\ Clone the default boot stage 2 target. +# # Create a new boot stage 2 target using the default implementation for the current build (PICO_BOARD derived) +# +# \param\ NAME The name of the new boot stage 2 target function(pico_clone_default_boot_stage2 NAME) pico_define_boot_stage2(${NAME} ${PICO_DEFAULT_BOOT_STAGE2_FILE}) endfunction() diff --git a/src/rp2350/boot_stage2/include/boot_stage2/config.h b/src/rp2350/boot_stage2/include/boot_stage2/config.h index 61f9b9b53..a73778af6 100644 --- a/src/rp2350/boot_stage2/include/boot_stage2/config.h +++ b/src/rp2350/boot_stage2/include/boot_stage2/config.h @@ -9,7 +9,7 @@ // NOTE THIS HEADER IS INCLUDED FROM ASSEMBLY -#include "pico/config.h" +#include "pico.h" // PICO_CONFIG: PICO_BUILD_BOOT_STAGE2_NAME, Name of the boot stage 2 if selected in the build system, group=boot_stage2 #ifdef PICO_BUILD_BOOT_STAGE2_NAME diff --git a/src/rp2350/hardware_regs/RP2350.svd b/src/rp2350/hardware_regs/RP2350.svd index fc6479ebb..c942b3a57 100644 --- a/src/rp2350/hardware_regs/RP2350.svd +++ b/src/rp2350/hardware_regs/RP2350.svd @@ -105846,5 +105846,40 @@ SPDX-License-Identifier: BSD-3-Clause + + + SPARE_IRQ + 0x00000000 + + 0 + 4 + reserved + + + SPARE_IRQ_0 + 46 + + + SPARE_IRQ_1 + 47 + + + SPARE_IRQ_2 + 48 + + + SPARE_IRQ_3 + 49 + + + SPARE_IRQ_4 + 50 + + + SPARE_IRQ_5 + 51 + + + diff --git a/src/rp2350/hardware_regs/include/hardware/platform_defs.h b/src/rp2350/hardware_regs/include/hardware/platform_defs.h index 25dc1d624..c919b94c1 100644 --- a/src/rp2350/hardware_regs/include/hardware/platform_defs.h +++ b/src/rp2350/hardware_regs/include/hardware/platform_defs.h @@ -73,6 +73,16 @@ #define HAS_POWMAN_TIMER 1 #define HAS_RP2350_TRNG 1 #define HAS_HSTX 1 +#define HAS_PADS_BANK0_ISOLATION 1 +#define __RISCV_PMP_CHECKED 1 + +#ifndef FPGA_CLK_SYS_HZ +#define FPGA_CLK_SYS_HZ (48 * MHZ) +#endif + +#ifndef FPGA_CLK_REF_HZ +#define FPGA_CLK_REF_HZ (12 * MHZ) +#endif // PICO_CONFIG: XOSC_HZ, Crystal oscillator frequency in Hz, type=int, default=12000000, advanced=true, group=hardware_base // NOTE: The system and USB clocks are generated from the frequency using two PLLs. diff --git a/src/rp2350/hardware_regs/include/hardware/regs/intctrl.h b/src/rp2350/hardware_regs/include/hardware/regs/intctrl.h index 96ce815e4..4db58399e 100644 --- a/src/rp2350/hardware_regs/include/hardware/regs/intctrl.h +++ b/src/rp2350/hardware_regs/include/hardware/regs/intctrl.h @@ -59,12 +59,12 @@ #define PLL_USB_IRQ 43 #define POWMAN_IRQ_POW 44 #define POWMAN_IRQ_TIMER 45 -#define SPAREIRQ_IRQ_0 46 -#define SPAREIRQ_IRQ_1 47 -#define SPAREIRQ_IRQ_2 48 -#define SPAREIRQ_IRQ_3 49 -#define SPAREIRQ_IRQ_4 50 -#define SPAREIRQ_IRQ_5 51 +#define SPARE_IRQ_0 46 +#define SPARE_IRQ_1 47 +#define SPARE_IRQ_2 48 +#define SPARE_IRQ_3 49 +#define SPARE_IRQ_4 50 +#define SPARE_IRQ_5 51 #else /** * \brief Interrupt numbers on RP2350 (used as typedef \ref irq_num_t) diff --git a/src/rp2350/pico_platform/BUILD.bazel b/src/rp2350/pico_platform/BUILD.bazel index 8b51a2dd6..b24291a2b 100644 --- a/src/rp2350/pico_platform/BUILD.bazel +++ b/src/rp2350/pico_platform/BUILD.bazel @@ -27,6 +27,7 @@ cc_library( deps = [ "//src/rp2350/hardware_regs", "//src/rp2350/hardware_regs:platform_defs", + "//src/rp2_common/pico_platform_common:pico_platform_common_headers", "//src/rp2_common/pico_platform_compiler", "//src/rp2_common/pico_platform_panic:pico_platform_panic_headers", "//src/rp2_common/pico_platform_sections", @@ -44,6 +45,7 @@ cc_library( "//src/rp2350/hardware_regs", "//src/rp2350/hardware_regs:platform_defs", "//src/rp2_common/hardware_base", + "//src/rp2_common/pico_platform_common", "//src/rp2_common/pico_platform_compiler", "//src/rp2_common/pico_platform_panic", "//src/rp2_common/pico_platform_sections", diff --git a/src/rp2350/pico_platform/CMakeLists.txt b/src/rp2350/pico_platform/CMakeLists.txt index 80a5103e3..7f875bf32 100644 --- a/src/rp2350/pico_platform/CMakeLists.txt +++ b/src/rp2350/pico_platform/CMakeLists.txt @@ -23,6 +23,7 @@ if (NOT TARGET pico_platform) hardware_regs ) pico_mirrored_target_link_libraries(pico_platform INTERFACE + pico_platform_common pico_platform_compiler pico_platform_panic pico_platform_sections diff --git a/src/rp2350/pico_platform/include/pico/platform.h b/src/rp2350/pico_platform/include/pico/platform.h index 35a6a0bd6..571efd8b8 100644 --- a/src/rp2350/pico_platform/include/pico/platform.h +++ b/src/rp2350/pico_platform/include/pico/platform.h @@ -23,13 +23,14 @@ #include "pico/platform/compiler.h" #include "pico/platform/sections.h" #include "pico/platform/panic.h" +#include "pico/platform/common.h" #include "hardware/regs/addressmap.h" #include "hardware/regs/sio.h" #ifdef __riscv #include "hardware/regs/rvcsr.h" #endif -// PICO_CONFIG: PICO_RP2350A, Whether the current board has an RP2350 in an A (30 GPIO) package, type=bool, default=Usually provided via board header, group=pico_platform +// PICO_CONFIG: PICO_RP2350A, Whether the current board has an RP2350 in an A (30 GPIO) package - set to 0 for RP2350 in a B (48 GPIO) package, type=bool, default=Usually provided via board header, group=pico_platform #if 0 // make tooling checks happy #define PICO_RP2350A 0 #endif @@ -54,10 +55,6 @@ #define PICO_NO_RAM_VECTOR_TABLE 0 #endif -#ifndef PICO_RAM_VECTOR_TABLE_SIZE -#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS) -#endif - // PICO_CONFIG: PICO_USE_STACK_GUARDS, Enable/disable stack guards, type=bool, default=0, advanced=true, group=pico_platform #ifndef PICO_USE_STACK_GUARDS #define PICO_USE_STACK_GUARDS 0 @@ -73,16 +70,6 @@ #ifdef __cplusplus extern "C" { #endif - -/*! \brief No-op function for the body of tight loops - * \ingroup pico_platform - * - * No-op function intended to be called by any tight hardware polling loop. Using this ubiquitously - * makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup - * debugging might be added - */ -static __force_inline void tight_loop_contents(void) {} - /*! \brief Helper method to busy-wait for at least the given number of cycles * \ingroup pico_platform * @@ -116,27 +103,6 @@ static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) { ); } -// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime -#ifndef PICO_NO_FPGA_CHECK -#define PICO_NO_FPGA_CHECK 1 -#endif - -// PICO_CONFIG: PICO_NO_SIM_CHECK, Remove the SIM platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime -#ifndef PICO_NO_SIM_CHECK -#define PICO_NO_SIM_CHECK 1 -#endif - -#if PICO_NO_FPGA_CHECK -static inline bool running_on_fpga(void) {return false;} -#else -bool running_on_fpga(void); -#endif -#if PICO_NO_SIM_CHECK -static inline bool running_in_sim(void) {return false;} -#else -bool running_in_sim(void); -#endif - /*! \brief Execute a breakpoint instruction * \ingroup pico_platform */ @@ -221,9 +187,6 @@ __force_inline static bool pico_processor_state_is_nonsecure(void) { #endif } -#define host_safe_hw_ptr(x) ((uintptr_t)(x)) -#define native_safe_hw_ptr(x) host_safe_hw_ptr(x) - /*! \brief Returns the RP2350 chip revision number * \ingroup pico_platform * @return the RP2350 chip revision number (1 for B0/B1, 2 for B2) diff --git a/src/rp2350/pico_platform/platform.c b/src/rp2350/pico_platform/platform.c index 97960478f..a71b8a0aa 100644 --- a/src/rp2350/pico_platform/platform.c +++ b/src/rp2350/pico_platform/platform.c @@ -6,28 +6,8 @@ #include "pico.h" #include "hardware/address_mapped.h" -#include "hardware/regs/tbman.h" #include "hardware/regs/sysinfo.h" -// Note we leave the FPGA check in by default so that we can run bug repro -// binaries coming in from the wild on the FPGA platform. It takes up around -// 48 bytes if you include all the calls, so you can pass PICO_NO_FPGA_CHECK=1 -// to remove it. The FPGA check is used to skip initialisation of hardware -// (mainly clock generators and oscillators) that aren't present on FPGA. - -#if !PICO_NO_FPGA_CHECK -// Inline stub provided in header if this code is unused (so folding can be -// done in each TU instead of relying on LTO) -bool __attribute__((weak)) running_on_fpga(void) { - return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS; -} -#endif -#if !PICO_NO_SIM_CHECK -bool __attribute__((weak)) running_in_sim(void) { - return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_HDLSIM_BITS; -} -#endif - #define MANUFACTURER_RPI 0x926 #define PART_RP4 0x4 @@ -36,9 +16,9 @@ uint8_t rp2350_chip_version(void) { uint32_t chip_id = *((io_ro_32*)(SYSINFO_BASE + SYSINFO_CHIP_ID_OFFSET)); uint32_t __unused manufacturer = chip_id & SYSINFO_CHIP_ID_MANUFACTURER_BITS; uint32_t __unused part = (chip_id & SYSINFO_CHIP_ID_PART_BITS) >> SYSINFO_CHIP_ID_PART_LSB; - assert(manufacturer == MANUFACTURER_RPI); - assert(part == PART_RP4); + assert(manufacturer == MANUFACTURER_RPI && part == PART_RP4); // 0 == A0, 1 == A1, 2 == A2 - uint version = (chip_id & SYSINFO_CHIP_ID_REVISION_BITS) >> SYSINFO_CHIP_ID_REVISION_LSB; + uint32_t version = (chip_id & SYSINFO_CHIP_ID_REVISION_BITS) >> SYSINFO_CHIP_ID_REVISION_LSB; + version = (version & 3u) | ((version & 8u) >> 1); return (uint8_t)version; } \ No newline at end of file diff --git a/src/rp2_common/boot_bootrom_headers/include/boot/bootrom_constants.h b/src/rp2_common/boot_bootrom_headers/include/boot/bootrom_constants.h index c1107f66b..e7fe6f63b 100644 --- a/src/rp2_common/boot_bootrom_headers/include/boot/bootrom_constants.h +++ b/src/rp2_common/boot_bootrom_headers/include/boot/bootrom_constants.h @@ -230,7 +230,7 @@ typedef int (*bootrom_api_callback_generic_t)(uint32_t r0, uint32_t r1, uint32_t #define PT_INFO_PARTITION_NAME 0x0080 // items are returned in order -// 3 words package_id, device_id, wafer_id +// 3 words package_id, device_id_lo, device_id_hi #define SYS_INFO_CHIP_INFO 0x0001 // 1 word: chip specific critical bits #define SYS_INFO_CRITICAL 0x0002 @@ -255,11 +255,11 @@ typedef int (*bootrom_api_callback_generic_t)(uint32_t r0, uint32_t r1, uint32_t #define BOOTROM_NS_API_get_b_partition 7 #define BOOTROM_NS_API_COUNT 8 -#define OTP_CMD_ROW_BITS 0x0000ffffu +#define OTP_CMD_ROW_BITS _u(0x0000ffff) #define OTP_CMD_ROW_LSB _u(0) -#define OTP_CMD_WRITE_BITS 0x00010000u +#define OTP_CMD_WRITE_BITS _u(0x00010000) #define OTP_CMD_WRITE_LSB _u(16) -#define OTP_CMD_ECC_BITS 0x00020000u +#define OTP_CMD_ECC_BITS _u(0x00020000) #define OTP_CMD_ECC_LSB _u(17) #ifndef __ASSEMBLER__ diff --git a/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h b/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h index 0db37f4ca..5ab49e824 100644 --- a/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h +++ b/src/rp2_common/cmsis/include/cmsis/rename_exceptions.h @@ -52,7 +52,12 @@ #if PICO_RP2350 #define isr_nmi NMI_Handler #define isr_hardfault HardFault_Handler +#define isr_memmanage MemManage_Handler +#define isr_busfault BusFault_Handler +#define isr_usagefault UsageFault_Handler +#define isr_securefault SecureFault_Handler #define isr_svcall SVC_Handler +#define isr_debugmonitor DebugMon_Handler #define isr_pendsv PendSV_Handler #define isr_systick SysTick_Handler #define isr_irq0 TIMER0_IRQ_0_Handler diff --git a/src/rp2_common/hardware_clocks/clocks.c b/src/rp2_common/hardware_clocks/clocks.c index 2d41c73d2..2bcaa5741 100644 --- a/src/rp2_common/hardware_clocks/clocks.c +++ b/src/rp2_common/hardware_clocks/clocks.c @@ -243,21 +243,8 @@ void clocks_enable_resus(resus_callback_t resus_callback) { } void clock_gpio_init_int_frac16(uint gpio, uint src, uint32_t div_int, uint16_t div_frac16) { - // Bit messy but it's as much code to loop through a lookup - // table. The sources for each gpout generators are the same - // so just call with the sources from GP0 - uint gpclk = 0; - if (gpio == 21) gpclk = clk_gpout0; - else if (gpio == 23) gpclk = clk_gpout1; - else if (gpio == 24) gpclk = clk_gpout2; - else if (gpio == 25) gpclk = clk_gpout3; -#if !PICO_RP2040 - else if (gpio == 13) gpclk = clk_gpout0; - else if (gpio == 15) gpclk = clk_gpout1; -#endif - else { - invalid_params_if(HARDWARE_CLOCKS, true); - } + // note this includes an invalid_params_if before defaulting to clk_gpout0 + uint gpclk = gpio_to_gpout_clock_handle(gpio, clk_gpout0); invalid_params_if(HARDWARE_CLOCKS, div_int >> REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_INT)); // Set up the gpclk generator @@ -283,12 +270,12 @@ static const uint8_t gpin0_src[CLK_COUNT] = { CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0, // CLK_REF CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0, // CLK_SYS CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0, // CLK_PERI -#if !PICO_RP2040 +#if HAS_HSTX CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0, // CLK_HSTX #endif CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0, // CLK_USB CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0, // CLK_ADC -#if PICO_RP2040 +#if HAS_RP2040_RTC CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0, // CLK_RTC #endif }; diff --git a/src/rp2_common/hardware_clocks/include/hardware/clocks.h b/src/rp2_common/hardware_clocks/include/hardware/clocks.h index 68f4b1a50..6aeec495b 100644 --- a/src/rp2_common/hardware_clocks/include/hardware/clocks.h +++ b/src/rp2_common/hardware_clocks/include/hardware/clocks.h @@ -231,7 +231,7 @@ extern "C" { #endif #endif // PICO_RP2040 && SYS_CLK_KHZ == 200000 && XOSC_KHZ == 12000 && PLL_COMMON_REFDIV == 1 -// PICO_CONFIG: SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US, Number of microseconds to wait after updating regulator voltage due to SYS_CLK_VREG_VOLTAGE_MIN to allow voltage to settle, type=bool, default=1000, advanced=true, group=hardware_clocks +// PICO_CONFIG: SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US, Number of microseconds to wait after updating regulator voltage due to SYS_CLK_VREG_VOLTAGE_MIN to allow voltage to settle, type=int, default=1000, advanced=true, group=hardware_clocks #ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US #define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US 1000 #endif @@ -399,7 +399,18 @@ void clocks_enable_resus(resus_callback_t resus_callback); /*! \brief Output an optionally divided clock to the specified gpio pin. * \ingroup hardware_clocks * - * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators. + * \if rp2040_specific + * On RP2040 valid GPIOs are 21, 23, 24, 25. + * These GPIOs are connected to the GPOUT0-3 clock generators. + * \endif + * \if rp2350_specific + * On RP2350 valid GPIOs are 13, 15, 21, 23, 24, 25. + * GPIOs 13 and 21 are connected to the GPOUT0 clock generator. + * GPIOs 15 and 23 are connected to the GPOUT1 clock generator. + * GPIOs 24 and 25 are connected to the GPOUT2-3 clock generators. + * \endif + * + * \param gpio The GPIO pin to output the clock to. * \param src The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator. * \param div_int The integer part of the value to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. This is in range of 1..2^24-1 on RP2040 * and 1..2^16-1 on RP2350 @@ -410,7 +421,18 @@ void clock_gpio_init_int_frac16(uint gpio, uint src, uint32_t div_int, uint16_t /*! \brief Output an optionally divided clock to the specified gpio pin. * \ingroup hardware_clocks * - * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators. + * * \if rp2040_specific + * On RP2040 valid GPIOs are 21, 23, 24, 25. + * These GPIOs are connected to the GPOUT0-3 clock generators. + * \endif + * \if rp2350_specific + * On RP2350 valid GPIOs are 13, 15, 21, 23, 24, 25. + * GPIOs 13 and 21 are connected to the GPOUT0 clock generator. + * GPIOs 15 and 23 are connected to the GPOUT1 clock generator. + * GPIOs 24 and 25 are connected to the GPOUT2-3 clock generators. + * \endif + * + * \param gpio The GPIO pin to output the clock to. * \param src The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator. * \param div_int The integer part of the value to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. This is in range of 1..2^24-1 on RP2040 * and 1..2^16-1 on RP2350 @@ -428,7 +450,18 @@ static inline void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_in /*! \brief Output an optionally divided clock to the specified gpio pin. * \ingroup hardware_clocks * - * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators. + * \if rp2040_specific + * On RP2040 valid GPIOs are 21, 23, 24, 25. + * These GPIOs are connected to the GPOUT0-3 clock generators. + * \endif + * \if rp2350_specific + * On RP2350 valid GPIOs are 13, 15, 21, 23, 24, 25. + * GPIOs 13 and 21 are connected to the GPOUT0 clock generator. + * GPIOs 15 and 23 are connected to the GPOUT1 clock generator. + * GPIOs 24 and 25 are connected to the GPOUT2-3 clock generators. + * \endif + * + * \param gpio The GPIO pin to output the clock to. * \param src The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator. * \param div The float amount to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. */ @@ -544,6 +577,42 @@ static inline bool set_sys_clock_khz(uint32_t freq_khz, bool required) { return false; } +#define GPIO_TO_GPOUT_CLOCK_HANDLE_RP2040(gpio, default_clk_handle) \ + ((gpio) == 21 ? clk_gpout0 : \ + ((gpio) == 23 ? clk_gpout1 : \ + ((gpio) == 24 ? clk_gpout2 : \ + ((gpio) == 25 ? clk_gpout3 : \ + (default_clk_handle))))) + +#define GPIO_TO_GPOUT_CLOCK_HANDLE_RP2350(gpio, default_clk_handle) \ + ((gpio) == 13 ? clk_gpout0 : \ + ((gpio) == 15 ? clk_gpout1 : \ + (GPIO_TO_GPOUT_CLOCK_HANDLE_RP2040(gpio, default_clk_handle)))) + +/** + * \def GPIO_TO_GPOUT_CLOCK_HANDLE(gpio, default_clk_handle) + * \ingroup hardware_clocks + * \hideinitializer + * \brief Returns the GPOUT clock number associated with a particular GPIO if there is one, or default_clk_handle otherwise + * + * Note this macro is intended to resolve at compile time, and does no parameter checking + */ +#ifndef GPIO_TO_GPOUT_CLOCK_HANDLE +#if PICO_RP2040 +#define GPIO_TO_GPOUT_CLOCK_HANDLE GPIO_TO_GPOUT_CLOCK_HANDLE_RP2040 +#else +#define GPIO_TO_GPOUT_CLOCK_HANDLE GPIO_TO_GPOUT_CLOCK_HANDLE_RP2350 +#endif +#endif + +/** + * \brief return the associated GPOUT clock for a given GPIO if any + * \ingroup hardware_clocks + * \return the GPOUT clock number associated with a particular GPIO or default_clk_handle otherwise + */ +static inline clock_handle_t gpio_to_gpout_clock_handle(uint gpio, clock_handle_t default_clk_handle) { + return GPIO_TO_GPOUT_CLOCK_HANDLE(gpio, ({invalid_params_if(HARDWARE_CLOCKS, true); default_clk_handle;})); +} #ifdef __cplusplus } #endif diff --git a/src/rp2_common/hardware_dma/include/hardware/dma.h b/src/rp2_common/hardware_dma/include/hardware/dma.h index 94b74cb7f..27dd92286 100644 --- a/src/rp2_common/hardware_dma/include/hardware/dma.h +++ b/src/rp2_common/hardware_dma/include/hardware/dma.h @@ -123,7 +123,7 @@ int dma_claim_unused_channel(bool required); * \param channel the dma channel * \return true if the channel is claimed, false otherwise * \see dma_channel_claim - * \see dma_channel_claim_mask + * \see dma_claim_mask */ bool dma_channel_is_claimed(uint channel); diff --git a/src/rp2_common/hardware_exception/exception.c b/src/rp2_common/hardware_exception/exception.c index d3134fbc8..52a5b64c0 100644 --- a/src/rp2_common/hardware_exception/exception.c +++ b/src/rp2_common/hardware_exception/exception.c @@ -31,12 +31,14 @@ static inline exception_handler_t *get_exception_table(void) { #endif } +#if !PICO_NO_RAM_VECTOR_TABLE static void set_raw_exception_handler_and_restore_interrupts(enum exception_number num, exception_handler_t handler, uint32_t save) { // update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness) get_exception_table()[num] = handler; __dmb(); restore_interrupts_from_disabled(save); } +#endif static inline void check_exception_param(__unused enum exception_number num) { invalid_params_if(HARDWARE_EXCEPTION, num < MIN_EXCEPTION_NUM || num > MAX_EXCEPTION_NUM); @@ -54,10 +56,12 @@ exception_handler_t exception_set_exclusive_handler(enum exception_number num, e exception_handler_t current = exception_get_vtable_handler(num); hard_assert(handler == current || exception_is_compile_time_default(current)); set_raw_exception_handler_and_restore_interrupts(num, handler, save); + return current; #else + ((void)num); + ((void)handler); panic_unsupported(); #endif - return current; } void exception_restore_handler(enum exception_number num, exception_handler_t original_handler) { @@ -66,6 +70,8 @@ void exception_restore_handler(enum exception_number num, exception_handler_t or uint32_t save = save_and_disable_interrupts(); set_raw_exception_handler_and_restore_interrupts(num, original_handler, save); #else + ((void)num); + ((void)original_handler); panic_unsupported(); #endif } diff --git a/src/rp2_common/hardware_flash/flash.c b/src/rp2_common/hardware_flash/flash.c index adae07878..fbca8de2c 100644 --- a/src/rp2_common/hardware_flash/flash.c +++ b/src/rp2_common/hardware_flash/flash.c @@ -14,6 +14,7 @@ #include "hardware/structs/qmi.h" #include "hardware/regs/otp_data.h" #endif +#include "hardware/structs/pads_qspi.h" #include "hardware/xip_cache.h" #define FLASH_BLOCK_ERASE_CMD 0xd8 @@ -71,7 +72,23 @@ static void __no_inline_not_in_flash_func(flash_enable_xip_via_boot2)(void) { #endif -#if PICO_RP2350 +//----------------------------------------------------------------------------- +// State save/restore + +// Most functions save and restore the QSPI pad state over the call. (The main +// exception is flash_start_xip() which is explicitly intended to initialise +// them). The expectation is that by the time you do any flash operations, +// you have either gone through a normal flash boot process or (in the case +// of PICO_NO_FLASH=1) you have called flash_start_xip(). Any further +// modifications to the pad state are therefore deliberate changes that we +// should preserve. +// +// Additionally, on RP2350, we save and restore the window 1 QMI configuration +// if the user has not opted into bootrom CS1 support via FLASH_DEVINFO OTP +// flags. This avoids clobbering CS1 setup (e.g. PSRAM) performed by the +// application. + +#if !PICO_RP2040 // This is specifically for saving/restoring the registers modified by RP2350 // flash_exit_xip() ROM func, not the entirety of the QMI window state. typedef struct flash_rp2350_qmi_save_state { @@ -108,9 +125,69 @@ static void __no_inline_not_in_flash_func(flash_rp2350_restore_qmi_cs1)(const fl } #endif + +typedef struct flash_hardware_save_state { +#if !PICO_RP2040 + flash_rp2350_qmi_save_state_t qmi_save; +#endif + uint32_t qspi_pads[count_of(pads_qspi_hw->io)]; +} flash_hardware_save_state_t; + +static void __no_inline_not_in_flash_func(flash_save_hardware_state)(flash_hardware_save_state_t *state) { + // Commit any pending writes to external RAM, to avoid losing them in a subsequent flush: + xip_cache_clean_all(); + for (size_t i = 0; i < count_of(pads_qspi_hw->io); ++i) { + state->qspi_pads[i] = pads_qspi_hw->io[i]; + } +#if !PICO_RP2040 + flash_rp2350_save_qmi_cs1(&state->qmi_save); +#endif +} + +static void __no_inline_not_in_flash_func(flash_restore_hardware_state)(flash_hardware_save_state_t *state) { + for (size_t i = 0; i < count_of(pads_qspi_hw->io); ++i) { + pads_qspi_hw->io[i] = state->qspi_pads[i]; + } +#if !PICO_RP2040 + // Tail call! + flash_rp2350_restore_qmi_cs1(&state->qmi_save); +#endif +} + //----------------------------------------------------------------------------- // Actual flash programming shims (work whether or not PICO_NO_FLASH==1) +void __no_inline_not_in_flash_func(flash_start_xip)(void) { + rom_connect_internal_flash_fn connect_internal_flash_func = (rom_connect_internal_flash_fn)rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH); + rom_flash_exit_xip_fn flash_exit_xip_func = (rom_flash_exit_xip_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP); + rom_flash_flush_cache_fn flash_flush_cache_func = (rom_flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); + rom_flash_enter_cmd_xip_fn flash_enter_cmd_xip_func = (rom_flash_enter_cmd_xip_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_ENTER_CMD_XIP); + assert(connect_internal_flash_func && flash_exit_xip_func && flash_flush_cache_func && flash_enter_cmd_xip_func); + // Commit any pending writes to external RAM, to avoid losing them in the subsequent flush: + xip_cache_clean_all(); +#if !PICO_RP2040 + flash_rp2350_qmi_save_state_t qmi_save; + flash_rp2350_save_qmi_cs1(&qmi_save); +#endif + + // Use ROM calls to get from ~any state to a state where low-speed flash access works: + connect_internal_flash_func(); + flash_exit_xip_func(); + flash_flush_cache_func(); + flash_enter_cmd_xip_func(); + + // If a boot2 is available then call it now. Slight limitation here is that if this is a + // NO_FLASH binary which was loaded via bootrom LOAD_MAP, we should actually have a better + // flash setup than this available via xip setup func stub left in boot RAM, but we can't + // easily detect this case to take advantage of this. + flash_init_boot2_copyout(); + flash_enable_xip_via_boot2(); + +#if !PICO_RP2040 + flash_rp2350_restore_qmi_cs1(&qmi_save); +#endif +} + void __no_inline_not_in_flash_func(flash_range_erase)(uint32_t flash_offs, size_t count) { #ifdef PICO_FLASH_SIZE_BYTES hard_assert(flash_offs + count <= PICO_FLASH_SIZE_BYTES); @@ -123,12 +200,8 @@ void __no_inline_not_in_flash_func(flash_range_erase)(uint32_t flash_offs, size_ rom_flash_flush_cache_fn flash_flush_cache_func = (rom_flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); assert(connect_internal_flash_func && flash_exit_xip_func && flash_range_erase_func && flash_flush_cache_func); flash_init_boot2_copyout(); - // Commit any pending writes to external RAM, to avoid losing them in the subsequent flush: - xip_cache_clean_all(); -#if PICO_RP2350 - flash_rp2350_qmi_save_state_t qmi_save; - flash_rp2350_save_qmi_cs1(&qmi_save); -#endif + flash_hardware_save_state_t state; + flash_save_hardware_state(&state); // No flash accesses after this point __compiler_memory_barrier(); @@ -138,9 +211,7 @@ void __no_inline_not_in_flash_func(flash_range_erase)(uint32_t flash_offs, size_ flash_range_erase_func(flash_offs, count, FLASH_BLOCK_SIZE, FLASH_BLOCK_ERASE_CMD); flash_flush_cache_func(); // Note this is needed to remove CSn IO force as well as cache flushing flash_enable_xip_via_boot2(); -#if PICO_RP2350 - flash_rp2350_restore_qmi_cs1(&qmi_save); -#endif + flash_restore_hardware_state(&state); } void __no_inline_not_in_flash_func(flash_flush_cache)(void) { @@ -160,11 +231,8 @@ void __no_inline_not_in_flash_func(flash_range_program)(uint32_t flash_offs, con rom_flash_flush_cache_fn flash_flush_cache_func = (rom_flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); assert(connect_internal_flash_func && flash_exit_xip_func && flash_range_program_func && flash_flush_cache_func); flash_init_boot2_copyout(); - xip_cache_clean_all(); -#if PICO_RP2350 - flash_rp2350_qmi_save_state_t qmi_save; - flash_rp2350_save_qmi_cs1(&qmi_save); -#endif + flash_hardware_save_state_t state; + flash_save_hardware_state(&state); __compiler_memory_barrier(); @@ -173,9 +241,8 @@ void __no_inline_not_in_flash_func(flash_range_program)(uint32_t flash_offs, con flash_range_program_func(flash_offs, data, count); flash_flush_cache_func(); // Note this is needed to remove CSn IO force as well as cache flushing flash_enable_xip_via_boot2(); -#if PICO_RP2350 - flash_rp2350_restore_qmi_cs1(&qmi_save); -#endif + + flash_restore_hardware_state(&state); } //----------------------------------------------------------------------------- @@ -208,11 +275,8 @@ void __no_inline_not_in_flash_func(flash_do_cmd)(const uint8_t *txbuf, uint8_t * rom_flash_flush_cache_fn flash_flush_cache_func = (rom_flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); assert(connect_internal_flash_func && flash_exit_xip_func && flash_flush_cache_func); flash_init_boot2_copyout(); - xip_cache_clean_all(); -#if PICO_RP2350 - flash_rp2350_qmi_save_state_t qmi_save; - flash_rp2350_save_qmi_cs1(&qmi_save); -#endif + flash_hardware_save_state_t state; + flash_save_hardware_state(&state); __compiler_memory_barrier(); connect_internal_flash_func(); @@ -260,9 +324,7 @@ void __no_inline_not_in_flash_func(flash_do_cmd)(const uint8_t *txbuf, uint8_t * flash_flush_cache_func(); flash_enable_xip_via_boot2(); -#if PICO_RP2350 - flash_rp2350_restore_qmi_cs1(&qmi_save); -#endif + flash_restore_hardware_state(&state); } #endif @@ -299,7 +361,11 @@ static void flash_devinfo_update_field(uint16_t wdata, uint16_t mask) { // Boot RAM does not support exclusives, but does support RWTYPE SET/CLR/XOR (with byte // strobes). Can't use hw_write_masked because it performs a 32-bit write. io_rw_16 *devinfo = flash_devinfo_ptr(); +#ifdef __STRICT_ANSI__ + *(io_rw_16 *)hw_xor_alias_untyped(devinfo) = (*devinfo ^ wdata) & mask; +#else *hw_xor_alias(devinfo) = (*devinfo ^ wdata) & mask; +#endif } // This is a RAM function because may be called during flash programming to enable save/restore of diff --git a/src/rp2_common/hardware_flash/include/hardware/flash.h b/src/rp2_common/hardware_flash/include/hardware/flash.h index af6343274..2bb5d5ae3 100644 --- a/src/rp2_common/hardware_flash/include/hardware/flash.h +++ b/src/rp2_common/hardware_flash/include/hardware/flash.h @@ -56,6 +56,32 @@ extern "C" { #endif +/*! \brief Initialise QSPI interface and external QSPI devices for execute-in-place + * \ingroup hardware_flash + * + * This function performs the same first-time flash setup that would normally occur over the course + * of the bootrom locating a flash binary and booting it, and that flash binary executing the SDK + * crt0. Specifically: + * + * * Initialise QSPI pads to their default states, and (non-RP2040) disable pad isolation latches + * * Issue a hardcoded sequence to attached QSPI devices to return them to a serial command state + * * Flush the XIP cache + * * Configure the QSPI interface for low-speed 03h reads + * * If this is not a PICO_NO_FLASH=1 binary: + * * (RP2040) load a boot2 stage from the first 256 bytes of RAM and execute it + * * (non-RP2040) execute an XIP setup function stored in boot RAM by either the bootrom or by crt0 + * + * This is mostly useful for initialising flash on a PICO_NO_FLASH=1 binary. (In spite of the name, + * this binary type really means "preloaded to RAM" and there may still be a flash device.) + * + * This function does not preserve the QSPI interface state or pad state. This is in contrast to + * most other functions in this library, which preserve at least the QSPI pad state. However, on + * RP2350 it does preserve the QMI window 1 configuration if you have not opted into bootrom CS1 + * support via FLASH_DEVINFO. + */ +void flash_start_xip(void); + + /*! \brief Erase areas of flash * \ingroup hardware_flash * diff --git a/src/rp2_common/hardware_gpio/gpio.c b/src/rp2_common/hardware_gpio/gpio.c index 2c4e91d40..292041a19 100644 --- a/src/rp2_common/hardware_gpio/gpio.c +++ b/src/rp2_common/hardware_gpio/gpio.c @@ -46,7 +46,7 @@ void gpio_set_function(uint gpio, gpio_function_t fn) { // Zero all fields apart from fsel; we want this IO to do what the peripheral tells it. // This doesn't affect e.g. pullup/pulldown, as these are in pad controls. io_bank0_hw->io[gpio].ctrl = fn << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB; -#if !PICO_RP2040 +#if HAS_PADS_BANK0_ISOLATION // Remove pad isolation now that the correct peripheral is in control of the pad hw_clear_bits(&pads_bank0_hw->io[gpio], PADS_BANK0_GPIO0_ISO_BITS); #endif @@ -253,11 +253,6 @@ void gpio_set_dormant_irq_enabled(uint gpio, uint32_t events, bool enabled) { _gpio_set_irq_enabled(gpio, events, enabled, irq_ctrl_base); } -void gpio_acknowledge_irq(uint gpio, uint32_t events) { - check_gpio_param(gpio); - io_bank0_hw->intr[gpio / 8] = events << (4 * (gpio % 8)); -} - #define DEBUG_PIN_MASK (((1u << PICO_DEBUG_PIN_COUNT)-1) << PICO_DEBUG_PIN_BASE) void gpio_debug_pins_init(void) { gpio_init_mask(DEBUG_PIN_MASK); diff --git a/src/rp2_common/hardware_gpio/include/hardware/gpio.h b/src/rp2_common/hardware_gpio/include/hardware/gpio.h index bd1f4b687..3894acaa8 100644 --- a/src/rp2_common/hardware_gpio/include/hardware/gpio.h +++ b/src/rp2_common/hardware_gpio/include/hardware/gpio.h @@ -204,6 +204,11 @@ enum gpio_irq_level { */ typedef void (*gpio_irq_callback_t)(uint gpio, uint32_t event_mask); +/*! \brief GPIO override modes + * \ingroup hardware_gpio + * + * \sa gpio_set_irqover, gpio_set_outover, gpio_set_inover, gpio_set_oeover + */ enum gpio_override { GPIO_OVERRIDE_NORMAL = 0, ///< peripheral signal selected via \ref gpio_set_function GPIO_OVERRIDE_INVERT = 1, ///< invert peripheral signal selected via \ref gpio_set_function @@ -565,7 +570,10 @@ static inline uint32_t gpio_get_irq_event_mask(uint gpio) { * \note For callbacks set with \ref gpio_set_irq_enabled_with_callback, or \ref gpio_set_irq_callback, this function is called automatically. * \param event_mask Bitmask of events to clear. See \ref gpio_irq_level for details. */ -void gpio_acknowledge_irq(uint gpio, uint32_t event_mask); +static inline void gpio_acknowledge_irq(uint gpio, uint32_t event_mask) { + check_gpio_param(gpio); + io_bank0_hw->intr[gpio / 8] = event_mask << (4 * (gpio % 8)); +} /*! \brief Adds a raw GPIO IRQ handler for the specified GPIOs on the current core * \ingroup hardware_gpio @@ -782,6 +790,8 @@ static inline void gpio_add_raw_irq_handler(uint gpio, irq_handler_t handler) { * * This method removes such a callback, and enables the "default" callback for the specified GPIOs. * + * \note You should always use the same gpio_mask as you used when you added the raw IRQ handler. + * * @param gpio_mask a bit mask of the GPIO numbers that will now be passed to the default callback for this core * @param handler the handler to remove from the list of GPIO IRQ handlers for this core */ diff --git a/src/rp2_common/hardware_i2c/include/hardware/i2c.h b/src/rp2_common/hardware_i2c/include/hardware/i2c.h index 604b89f98..5453752e8 100644 --- a/src/rp2_common/hardware_i2c/include/hardware/i2c.h +++ b/src/rp2_common/hardware_i2c/include/hardware/i2c.h @@ -324,10 +324,10 @@ int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t * (for example) without having to send address byte(s) repeatedly * * \param i2c Either \ref i2c0 or \ref i2c1 - * \param addr 7-bit address of device to read from - * \param dst Pointer to buffer to receive data - * \param len Length of data in bytes to receive - * \return Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged or no device present. + * \param addr 7-bit address of device to write to + * \param src Pointer to data to send + * \param len Length of data in bytes to send + * \return Number of bytes written, or PICO_ERROR_GENERIC if address not acknowledged or no device present. */ int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len); diff --git a/src/rp2_common/hardware_interp/include/hardware/interp.h b/src/rp2_common/hardware_interp/include/hardware/interp.h index 634af0f46..befe1f8ca 100644 --- a/src/rp2_common/hardware_interp/include/hardware/interp.h +++ b/src/rp2_common/hardware_interp/include/hardware/interp.h @@ -107,7 +107,7 @@ void interp_unclaim_lane(interp_hw_t *interp, uint lane); */ bool interp_lane_is_claimed(interp_hw_t *interp, uint lane); -/*! \brief Release previously claimed interpolator lanes \see interp_claim_lane_mask +/*! \brief Release previously claimed interpolator lanes, see \ref interp_claim_lane_mask * \ingroup hardware_interp * * \param interp Interpolator on which to release lanes. interp0 or interp1 diff --git a/src/rp2_common/hardware_irq/include/hardware/irq.h b/src/rp2_common/hardware_irq/include/hardware/irq.h index d671903dc..0dcc49d59 100644 --- a/src/rp2_common/hardware_irq/include/hardware/irq.h +++ b/src/rp2_common/hardware_irq/include/hardware/irq.h @@ -195,7 +195,7 @@ extern "C" { typedef void (*irq_handler_t)(void); static inline void check_irq_param(__unused uint num) { - invalid_params_if(HARDWARE_IRQ, num >= NUM_IRQS); + invalid_params_if(HARDWARE_IRQ, num >= PICO_NUM_VTABLE_IRQS); } /*! \brief Set specified interrupt's priority diff --git a/src/rp2_common/hardware_irq/irq.c b/src/rp2_common/hardware_irq/irq.c index b06db13c9..fc3d6f12c 100644 --- a/src/rp2_common/hardware_irq/irq.c +++ b/src/rp2_common/hardware_irq/irq.c @@ -15,6 +15,12 @@ PICO_RUNTIME_INIT_FUNC_PER_CORE(runtime_init_per_core_irq_priorities, PICO_RUNTIME_INIT_PER_CORE_IRQ_PRIORITIES); #endif +static_assert(IRQ_COUNT == NUM_IRQS, ""); +// "USER IRQs" use the spare irq numbers +#if NUM_USER_IRQS +static_assert(IRQ_COUNT - NUM_USER_IRQS == SPARE_IRQ_0, ""); +#endif + #if PICO_VTABLE_PER_CORE static uint8_t user_irq_claimed[NUM_CORES]; static inline uint8_t *user_irq_claimed_ptr(void) { @@ -51,13 +57,6 @@ static inline void *remove_thumb_bit(void *addr) { #endif } -static void set_raw_irq_handler_and_unlock(uint num, irq_handler_t handler, uint32_t save) { - // update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness) - get_vtable()[VTABLE_FIRST_IRQ + num] = handler; - __dmb(); - spin_unlock(spin_lock_instance(PICO_SPINLOCK_ID_IRQ), save); -} - void irq_set_enabled(uint num, bool enabled) { check_irq_param(num); // really should update irq_set_mask_enabled? @@ -76,7 +75,7 @@ bool irq_is_enabled(uint num) { } static inline void irq_set_mask_n_enabled_internal(uint n, uint32_t mask, bool enabled) { - invalid_params_if(HARDWARE_IRQ, n * 32u >= ((NUM_IRQS + 31u) & ~31u)); + invalid_params_if(HARDWARE_IRQ, n * 32u >= ((PICO_NUM_VTABLE_IRQS + 31u) & ~31u)); #if defined(__riscv) if (enabled) { hazard3_irqarray_clear(RVCSR_MEIFA_OFFSET, 2 * n, mask & 0xffffu); @@ -129,7 +128,7 @@ void irq_set_pending(uint num) { #endif } -#if !PICO_DISABLE_SHARED_IRQ_HANDLERS +#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE // limited by 8 bit relative links (and reality) static_assert(PICO_MAX_SHARED_IRQ_HANDLERS >= 1 && PICO_MAX_SHARED_IRQ_HANDLERS < 0x7f, ""); @@ -197,31 +196,38 @@ static inline bool is_shared_irq_raw_handler(irq_handler_t raw_handler) { return (uintptr_t)raw_handler - (uintptr_t)irq_handler_chain_slots < sizeof(irq_handler_chain_slots); } -bool irq_has_handler(uint irq_num) { - check_irq_param(irq_num); - irq_handler_t handler = irq_get_vtable_handler(irq_num); - return handler && handler != __unhandled_user_irq; -} - bool irq_has_shared_handler(uint irq_num) { check_irq_param(irq_num); irq_handler_t handler = irq_get_vtable_handler(irq_num); return is_shared_irq_raw_handler(handler); } -#else // PICO_DISABLE_SHARED_IRQ_HANDLERS +static void set_raw_irq_handler_and_unlock(uint num, irq_handler_t handler, uint32_t save) { + // update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness) + get_vtable()[VTABLE_FIRST_IRQ + num] = handler; + __dmb(); + spin_unlock(spin_lock_instance(PICO_SPINLOCK_ID_IRQ), save); +} + +#else // PICO_DISABLE_SHARED_IRQ_HANDLERS && PICO_NO_RAM_VECTOR_TABLE #define is_shared_irq_raw_handler(h) false bool irq_has_shared_handler(uint irq_num) { + ((void)irq_num); return false; } #endif - irq_handler_t irq_get_vtable_handler(uint num) { check_irq_param(num); return get_vtable()[VTABLE_FIRST_IRQ + num]; } +bool irq_has_handler(uint irq_num) { + check_irq_param(irq_num); + irq_handler_t handler = irq_get_vtable_handler(irq_num); + return handler && handler != __unhandled_user_irq; +} + void irq_set_exclusive_handler(uint num, irq_handler_t handler) { check_irq_param(num); #if !PICO_NO_RAM_VECTOR_TABLE @@ -231,6 +237,7 @@ void irq_set_exclusive_handler(uint num, irq_handler_t handler) { hard_assert(current == __unhandled_user_irq || current == handler); set_raw_irq_handler_and_unlock(num, handler, save); #else + ((void)handler); panic_unsupported(); #endif } @@ -252,7 +259,7 @@ irq_handler_t irq_get_exclusive_handler(uint num) { } -#if !PICO_DISABLE_SHARED_IRQ_HANDLERS +#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE #ifndef __riscv @@ -362,6 +369,8 @@ static inline int8_t get_slot_index(struct irq_handler_chain_slot *slot) { void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority) { check_irq_param(num); #if PICO_NO_RAM_VECTOR_TABLE + ((void)handler); + ((void)order_priority); panic_unsupported(); #elif PICO_DISABLE_SHARED_IRQ_HANDLERS irq_set_exclusive_handler(num, handler); @@ -455,7 +464,7 @@ void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_prior #endif // !PICO_NO_RAM_VECTOR_TABLE && !PICO_DISABLE_SHARED_IRQ_HANDLERS } -#if !PICO_DISABLE_SHARED_IRQ_HANDLERS +#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE static inline irq_handler_t handler_from_slot(struct irq_handler_chain_slot *slot) { #ifndef __riscv return slot->handler; @@ -580,6 +589,8 @@ void irq_remove_handler(uint num, irq_handler_t handler) { } set_raw_irq_handler_and_unlock(num, vtable_handler, save); #else + ((void)num); + ((void)handler); panic_unsupported(); #endif } @@ -620,7 +631,7 @@ uint irq_get_priority(uint num) { #endif } -#if !PICO_DISABLE_SHARED_IRQ_HANDLERS +#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE // used by irq_handler_chain.S to remove the last link in a handler chain after it executes // note this must be called only with the last slot in a chain (and during the exception) void irq_add_tail_to_free_list(struct irq_handler_chain_slot *slot) { @@ -664,15 +675,19 @@ __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 #endif +#if !PICO_RP2040 + // enable interrupts that might be disabled by a previous bootloader stage (guarded for RP2040 as there is no bootrom chain_image call there) + enable_interrupts(); +#endif } static uint get_user_irq_claim_index(uint irq_num) { - invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= NUM_IRQS); + invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= PICO_NUM_VTABLE_IRQS); // we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31 static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today. return NUM_IRQS - irq_num - 1u; diff --git a/src/rp2_common/hardware_pio/include/hardware/pio.h b/src/rp2_common/hardware_pio/include/hardware/pio.h index b11733092..4363608fc 100644 --- a/src/rp2_common/hardware_pio/include/hardware/pio.h +++ b/src/rp2_common/hardware_pio/include/hardware/pio.h @@ -680,7 +680,7 @@ static inline void sm_config_set_out_shift(pio_sm_config *c, bool shift_right, b * \ingroup sm_config * * \param c Pointer to the configuration structure to modify - * \param join Specifies the join type. \see enum pio_fifo_join + * \param join Specifies the join type. See \ref pio_fifo_join */ static inline void sm_config_set_fifo_join(pio_sm_config *c, enum pio_fifo_join join) { valid_params_if(HARDWARE_PIO, join == PIO_FIFO_JOIN_NONE || join == PIO_FIFO_JOIN_TX || join == PIO_FIFO_JOIN_RX @@ -720,7 +720,7 @@ static inline void sm_config_set_out_special(pio_sm_config *c, bool sticky, bool * \ingroup sm_config * * \param c Pointer to the configuration structure to modify - * \param status_sel the status operation selector. \see enum pio_mov_status_type + * \param status_sel the status operation selector. See \ref pio_mov_status_type * \param status_n parameter for the mov status operation (currently a bit count) */ static inline void sm_config_set_mov_status(pio_sm_config *c, enum pio_mov_status_type status_sel, uint status_n) { @@ -849,7 +849,7 @@ static inline uint pio_get_index(PIO pio) { * * \param pio The PIO instance; e.g. \ref pio0 or \ref pio1 * \return the PIO instance number (0, 1, ...) - * \see gpio_function + * \see gpio_function_t */ static inline uint pio_get_funcsel(PIO pio) { check_pio_param(pio); @@ -872,9 +872,25 @@ static inline PIO pio_get_instance(uint instance) { * * PIO appears as an alternate function in the GPIO muxing, just like an SPI * or UART. This function configures that multiplexing to connect a given PIO - * instance to a GPIO. Note that this is not necessary for a state machine to - * be able to read the *input* value from a GPIO, but only for it to set the - * output value or output enable. + * instance to a GPIO. It also configures the GPIO pad to pass signals in and + * out, by: + * + * * Clearing the pad output disable (OD) bit + * * Setting the pad input enable (IE) bit + * * (Non-RP2040) removing pad isolation + * + * This function achieves this low-level pad setup by calling gpio_set_function() + * internally. + * + * Note that, if your PIO program only needs the *input* from a given GPIO, + * it's not necessary to select the PIO GPIO function, because PIO input + * paths ignore the GPIO muxing. However, you must still configure the GPIO + * pad itself for input. + * + * Conversely, if using PIO for both input and output on a given pin, you must + * select the PIO GPIO function for the given PIO instance, as well as + * configuring the pad for input and output. Calling this function is + * sufficient for both the input-only and input/output case. * * \param pio The PIO instance; e.g. \ref pio0 or \ref pio1 * \param pin the GPIO pin whose function select to set @@ -948,7 +964,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 +976,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 +1014,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 +1022,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 +1045,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 +1065,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 +1435,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 +1466,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 +1998,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 +2010,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 +2022,7 @@ bool pio_claim_free_sm_and_add_program(const pio_program_t *program, PIO *pio, u * instance, then that PIO will be reconfigured so that this method can succeed * * \return true on success, false otherwise - * \see pio_remove_program_unclaim_sm + * \see pio_remove_program_and_unclaim_sm */ bool pio_claim_free_sm_and_add_program_for_gpio_range(const pio_program_t *program, PIO *pio, uint *sm, uint *offset, uint gpio_base, uint gpio_count, bool set_gpio_base); diff --git a/src/rp2_common/hardware_pio/include/hardware/pio_instructions.h b/src/rp2_common/hardware_pio/include/hardware/pio_instructions.h index 671145606..edb0ef31a 100644 --- a/src/rp2_common/hardware_pio/include/hardware/pio_instructions.h +++ b/src/rp2_common/hardware_pio/include/hardware/pio_instructions.h @@ -18,6 +18,10 @@ * parameters. * * For fuller descriptions of the instructions in question see the "RP2040 Datasheet" + * + * NOTE: These are helper functions for the raw instruction encoding, and thus + * only provide support for pins numbered 0-31. You should adjust your encoding + * according to your expected GPIO_BASE (see \ref pio_set_gpio_base) */ // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS, Enable/disable assertions in the PIO instructions, type=bool, default=0, group=pio_instructions @@ -148,7 +152,7 @@ static inline uint pio_encode_sideset(uint sideset_bit_count, uint value) { * \return the side set bits to be ORed with an instruction encoding */ static inline uint pio_encode_sideset_opt(uint sideset_bit_count, uint value) { - valid_params_if(PIO_INSTRUCTIONS, sideset_bit_count >= 1 && sideset_bit_count <= 4); + valid_params_if(PIO_INSTRUCTIONS, sideset_bit_count >= 0 && sideset_bit_count <= 4); valid_params_if(PIO_INSTRUCTIONS, value <= ((1u << sideset_bit_count) - 1)); return 0x1000u | value << (12u - sideset_bit_count); } diff --git a/src/rp2_common/hardware_powman/powman.c b/src/rp2_common/hardware_powman/powman.c index b9c556482..4af59f502 100644 --- a/src/rp2_common/hardware_powman/powman.c +++ b/src/rp2_common/hardware_powman/powman.c @@ -69,7 +69,7 @@ void powman_timer_set_1khz_tick_source_lposc_with_hz(uint32_t lposc_freq_hz) { bool was_running = powman_timer_is_running(); if (was_running) powman_timer_stop(); uint32_t lposc_freq_khz = lposc_freq_hz / 1000; - uint32_t lposc_freq_khz_frac16 = (lposc_freq_khz % 1000) * 65536 / 1000; + uint32_t lposc_freq_khz_frac16 = (lposc_freq_hz % 1000) * 65536 / 1000; powman_write(&powman_hw->lposc_freq_khz_int, lposc_freq_khz); powman_write(&powman_hw->lposc_freq_khz_frac, lposc_freq_khz_frac16); powman_set_bits(&powman_hw->timer, POWMAN_TIMER_USE_LPOSC_BITS); @@ -87,7 +87,7 @@ void powman_timer_set_1khz_tick_source_xosc_with_hz(uint32_t xosc_freq_hz) { bool was_running = powman_timer_is_running(); if (was_running) powman_timer_stop(); uint32_t xosc_freq_khz = xosc_freq_hz / 1000; - uint32_t xosc_freq_khz_frac16 = (xosc_freq_khz % 1000) * 65536 / 1000; + uint32_t xosc_freq_khz_frac16 = (xosc_freq_hz % 1000) * 65536 / 1000; powman_write(&powman_hw->xosc_freq_khz_int, xosc_freq_khz); powman_write(&powman_hw->xosc_freq_khz_frac, xosc_freq_khz_frac16); powman_set_bits(&powman_hw->timer, POWMAN_TIMER_USE_XOSC_BITS); @@ -97,12 +97,25 @@ void powman_timer_set_1khz_tick_source_xosc_with_hz(uint32_t xosc_freq_hz) { } } +#ifndef GPIO_TO_POWMAN_EXT_TIME_REF_SOURCE +#define GPIO_TO_POWMAN_EXT_TIME_REF_SOURCE(gpio, default_ext_time_ref_source) \ + ((gpio) == 12 ? 0 : \ + ((gpio) == 20 ? 1 : \ + ((gpio) == 14 ? 2 : \ + ((gpio) == 22 ? 3 : \ + (default_ext_time_ref_source))))) +#endif + +static inline uint32_t gpio_to_powman_ext_time_ref_source(uint gpio, uint32_t default_ext_time_ref_source) { + return GPIO_TO_POWMAN_EXT_TIME_REF_SOURCE(gpio, ({invalid_params_if(HARDWARE_POWMAN, true); default_ext_time_ref_source;})); +} + static void powman_timer_use_gpio(uint32_t gpio, uint32_t use, uint32_t using) { bool was_running = powman_timer_is_running(); if (was_running) powman_timer_stop(); - invalid_params_if(HARDWARE_POWMAN, !((gpio == 12) || (gpio == 14) || (gpio == 20) || (gpio == 22))); + uint32_t source = gpio_to_powman_ext_time_ref_source(gpio, 0); gpio_set_input_enabled(gpio, true); - powman_write(&powman_hw->ext_time_ref, gpio); + powman_write(&powman_hw->ext_time_ref, source); powman_set_bits(&powman_hw->timer, use); if (was_running) { powman_timer_start(); @@ -125,7 +138,7 @@ void powman_timer_disable_gpio_1hz_sync(void) { } powman_power_state powman_get_power_state(void) { - uint32_t state_reg = powman_hw->state & POWMAN_STATE_CURRENT_BITS; + uint32_t state_reg = ~powman_hw->state & POWMAN_STATE_CURRENT_BITS; // todo we should have hardware/regs/powman.h values for these static_assert(POWMAN_POWER_DOMAIN_SRAM_BANK1 == 0, ""); static_assert(POWMAN_POWER_DOMAIN_SRAM_BANK0 == 1, ""); @@ -181,19 +194,30 @@ int powman_set_power_state(powman_power_state state) { } bool powman_configure_wakeup_state(powman_power_state sleep_state, powman_power_state wakeup_state) { - // When powman wakes up it can keep the state of the sram0 and sram1 banks. Note, it can't - // explicitly - bool valid = powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_XIP_CACHE); + // Must be entering a P1 low-power state (SWCORE OFF). + bool valid = !powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SWITCHED_CORE); + // Must be waking up in a P0 state (SWCORE ON). valid &= powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SWITCHED_CORE); - valid &= powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK0) == - powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SRAM_BANK0); - valid &= powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK1) == - powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SRAM_BANK1); + powman_power_state current_state = powman_get_power_state(); + bool current_sram0 = powman_power_state_is_domain_on(current_state, POWMAN_POWER_DOMAIN_SRAM_BANK0); + bool current_sram1 = powman_power_state_is_domain_on(current_state, POWMAN_POWER_DOMAIN_SRAM_BANK1); + bool sleep_sram0 = powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK0); + bool sleep_sram1 = powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK1); + bool wakeup_sram0 = powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SRAM_BANK0); + bool wakeup_sram1 = powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SRAM_BANK1); + // Sleep state cannot turn ON SRAM0 or SRAM1 if it is OFF in the current state. + if (!current_sram0) valid &= !sleep_sram0; + if (!current_sram1) valid &= !sleep_sram1; + // Wakeup state cannot turn OFF SRAM0 or SRAM1 if it is ON in the sleep state. + if (sleep_sram0) valid &= wakeup_sram0; + if (sleep_sram1) valid &= wakeup_sram1; if (valid) { + // Prepare power sequencer to power SRAM domains on wakeup. powman_clear_bits(&powman_hw->seq_cfg, POWMAN_SEQ_CFG_HW_PWRUP_SRAM0_BITS | POWMAN_SEQ_CFG_HW_PWRUP_SRAM1_BITS); uint32_t seq_cfg_set = 0; - if (!powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK0)) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM0_BITS; - if (!powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK1)) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM1_BITS; + // Sequencer SRAM power transitions from sleep to wakeup are: OFF->ON (0), ON->ON (1) and OFF->OFF (1) + if (sleep_sram0 == wakeup_sram0) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM0_BITS; + if (sleep_sram1 == wakeup_sram1) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM1_BITS; powman_set_bits(&powman_hw->seq_cfg, seq_cfg_set); } return valid; diff --git a/src/rp2_common/hardware_rcp/BUILD.bazel b/src/rp2_common/hardware_rcp/BUILD.bazel index 750ae819e..6f8be1be3 100644 --- a/src/rp2_common/hardware_rcp/BUILD.bazel +++ b/src/rp2_common/hardware_rcp/BUILD.bazel @@ -2,6 +2,19 @@ load("//bazel:defs.bzl", "compatible_with_rp2") package(default_visibility = ["//visibility:public"]) +# Picotool needs this (transitively through +# //src/rp2_common/pico_bootrom:pico_bootrom_headers), so we can't strictly +# constrain compatibility. +cc_library( + name = "hardware_rcp_headers", + hdrs = ["include/hardware/rcp.h"], + includes = ["include"], + visibility = ["//src/rp2_common/pico_bootrom:__pkg__"], + deps = [ + "//src:pico_platform_internal", + ], +) + cc_library( name = "hardware_rcp", hdrs = ["include/hardware/rcp.h"], diff --git a/src/rp2_common/hardware_rcp/include/hardware/rcp.h b/src/rp2_common/hardware_rcp/include/hardware/rcp.h index b75f182d9..b9e144a09 100644 --- a/src/rp2_common/hardware_rcp/include/hardware/rcp.h +++ b/src/rp2_common/hardware_rcp/include/hardware/rcp.h @@ -16,8 +16,12 @@ // ---------------------------------------------------------------------------- // RCP instructions (this header is Arm-only) -#if defined(PICO_RP2350) && !defined(__riscv) +#if HAS_REDUNDANCY_COPROCESSOR +#ifdef __riscv +#error "HAS_REDUNDANCY_COPROCESSOR should be false on RISC-V" +#endif +#define rcp_is_true(x) ((x) == RCP_MASK_TRUE) #define RCP_MASK_TRUE _u(0xa500a500) #define RCP_MASK_FALSE _u(0x00c300c3) #define RCP_MASK_INTXOR _u(0x96009600) @@ -84,6 +88,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) { // Get a 32-bit canary value. `tag` must be a constant expression. #define rcp_canary_get(tag) ({ \ + static_assert(!((tag) & ~0xffu), "Tag out of range"); \ uint32_t __canary_u32; \ rcp_asm ( \ "mrc p7, #0, %0, c%c1, c%c2, #1\n" \ @@ -94,6 +99,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) { }) #define rcp_canary_get_nodelay(tag) ({ \ + static_assert(!((tag) & ~0xffu), "Tag out of range"); \ uint32_t __canary_u32; \ rcp_asm ( \ "mrc2 p7, #0, %0, c%c1, c%c2, #1\n" \ @@ -105,6 +111,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) { // Assert that canary matches result of rcp_canary_get with the same tags: #define rcp_canary_check(tag, canary) ({ \ + static_assert(!((tag) & ~0xffu), "Tag out of range"); \ rcp_asm ( \ "mcr p7, #0, %0, c%c1, c%c2, #1\n" \ : : "r" (canary), \ @@ -113,6 +120,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) { }) #define rcp_canary_check_nodelay(tag, canary) ({ \ + static_assert(!((tag) & ~0xffu), "Tag out of range"); \ rcp_asm ( \ "mcr2 p7, #0, %0, c%c1, c%c2, #1\n" \ : : "r" (canary), \ @@ -139,6 +147,9 @@ static __rcpinline uint32_t rcp_canary_status_nodelay(void) { // ---------------------------------------------------------------------------- // RCP Boolean instructions +// These instructions assert that all their arguments are valid booleans, in +// addition to any other logical conditions + // Assert b is a valid boolean (0xa500a500u or 0x00c300c3u) static __rcpinline void rcp_bvalid(uint32_t b) { rcp_asm ("mcr p7, #1, %0, c0, c0, #0\n" : : "r" (b)); @@ -306,106 +317,8 @@ static __rcpinline __attribute__((noreturn)) void rcp_panic(void) { #else // __ASSEMBLER__ #ifndef __riscv -// Assert b is a valid boolean (0xa500a500u or 0x00c300c3u) -.macro rcp_bvalid r - mcr p7, #1, \r , c0, c0, #0 -.endm - -.macro rcp_bvalid_nodelay r - mcr2 p7, #1, \r , c0, c0, #0 -.endm - -// Assert b is true (0xa500a500u) -.macro rcp_btrue r - mcr p7, #2, \r , c0, c0, #0 -.endm - -.macro rcp_btrue_nodelay r - mcr2 p7, #2, \r , c0, c0, #0 -.endm - -// Assert b is false (0x00c300c3u) -.macro rcp_bfalse r - mcr p7, #3, \r , c0, c0, #1 -.endm - -.macro rcp_bfalse_nodelay r - mcr2 p7, #3, \r , c0, c0, #1 -.endm - -// Assert b0 and b1 are both valid booleans -.macro rcp_b2valid b0, b1 - mcrr p7, #0, \b0 , \b1 , c8 -.endm - -.macro rcp_b2valid_nodelay b0, b1 - mcrr2 p7, #0, \b0 , \b1 , c8 -.endm - -// Assert b0 and b1 are both true -.macro rcp_b2and b0, b1 - mcrr p7, #1, \b0 , \b1 , c0 -.endm - -.macro rcp_b2and_nodelay b0, b1 - mcrr2 p7, #1, \b0 , \b1 , c0 -.endm - -// Assert b0 and b1 are valid, and at least one is true -.macro rcp_b2or b0, b1 - mcrr p7, #2, \b0 , \b1 , c0 -.endm - -.macro rcp_b2or_nodelay b0, b1 - mcrr2 p7, #2, \b0 , \b1 , c0 -.endm - -// Assert (b ^ mask) is a valid boolean -.macro rcp_bxorvalid b, mask - mcrr p7, #3, \b , \mask , c8 -.endm - -.macro rcp_bxorvalid_nodelay b, mask - mcrr2 p7, #3, \b , \mask , c8 -.endm - -// Assert (b ^ mask) is true -.macro rcp_bxortrue b, mask - mcrr p7, #4, \b , \mask , c0 -.endm - -.macro rcp_bxortrue_nodelay b, mask - mcrr2 p7, #4, \b , \mask , c0 -.endm - -// Assert (b ^ mask) is false -.macro rcp_bxorfalse b, mask - mcrr p7, #5, \b , \mask , c8 -.endm - -.macro rcp_bxorfalse_nodelay b, mask - mcrr2 p7, #5, \b , \mask , c8 -.endm - -// Assert (x ^ parity) == 0x96009600u -.macro rcp_ivalid x, parity - mcrr p7, #6, \x , \parity , c8 -.endm - -.macro rcp_ivalid_nodelay x, parity - mcrr2 p7, #6, \x , \parity , c8 -.endm - -// Assert x == y -.macro rcp_iequal x, y - mcrr p7, #7, \x , \y , c0 -.endm - -.macro rcp_iequal_nodelay x, y - mcrr2 p7, #7, \x , \y , c0 -.endm - -// They call this "metaprogramming" I think +// Meta-macro for evaluating assembler constant expressions and encoding as +// coprocessor register pairs: .macro rcp_switch_u8_to_ch_cl macro_name, x, args:vararg .if (\x) == 0 \macro_name c0, c0, \args @@ -924,6 +837,114 @@ static __rcpinline __attribute__((noreturn)) void rcp_panic(void) { .endif .endm +// ---------------------------------------------------------------------------- +// RCP Boolean instructions + +// Assert b is a valid boolean (0xa500a500u or 0x00c300c3u) +.macro rcp_bvalid r + mcr p7, #1, \r , c0, c0, #0 +.endm + +.macro rcp_bvalid_nodelay r + mcr2 p7, #1, \r , c0, c0, #0 +.endm + +// Assert b is true (0xa500a500u) +.macro rcp_btrue r + mcr p7, #2, \r , c0, c0, #0 +.endm + +.macro rcp_btrue_nodelay r + mcr2 p7, #2, \r , c0, c0, #0 +.endm + +// Assert b is false (0x00c300c3u) +.macro rcp_bfalse r + mcr p7, #3, \r , c0, c0, #1 +.endm + +.macro rcp_bfalse_nodelay r + mcr2 p7, #3, \r , c0, c0, #1 +.endm + +// Assert b0 and b1 are both valid booleans +.macro rcp_b2valid b0, b1 + mcrr p7, #0, \b0 , \b1 , c8 +.endm + +.macro rcp_b2valid_nodelay b0, b1 + mcrr2 p7, #0, \b0 , \b1 , c8 +.endm + +// Assert b0 and b1 are both true +.macro rcp_b2and b0, b1 + mcrr p7, #1, \b0 , \b1 , c0 +.endm + +.macro rcp_b2and_nodelay b0, b1 + mcrr2 p7, #1, \b0 , \b1 , c0 +.endm + +// Assert b0 and b1 are valid, and at least one is true +.macro rcp_b2or b0, b1 + mcrr p7, #2, \b0 , \b1 , c0 +.endm + +.macro rcp_b2or_nodelay b0, b1 + mcrr2 p7, #2, \b0 , \b1 , c0 +.endm + +// Assert (b ^ mask) is a valid boolean +.macro rcp_bxorvalid b, mask + mcrr p7, #3, \b , \mask , c8 +.endm + +.macro rcp_bxorvalid_nodelay b, mask + mcrr2 p7, #3, \b , \mask , c8 +.endm + +// Assert (b ^ mask) is true +.macro rcp_bxortrue b, mask + mcrr p7, #4, \b , \mask , c0 +.endm + +.macro rcp_bxortrue_nodelay b, mask + mcrr2 p7, #4, \b , \mask , c0 +.endm + +// Assert (b ^ mask) is false +.macro rcp_bxorfalse b, mask + mcrr p7, #5, \b , \mask , c8 +.endm + +.macro rcp_bxorfalse_nodelay b, mask + mcrr2 p7, #5, \b , \mask , c8 +.endm + +// ---------------------------------------------------------------------------- +// RCP Integer instructions + +// Assert (x ^ parity) == 0x96009600u +.macro rcp_ivalid x, parity + mcrr p7, #6, \x , \parity , c8 +.endm + +.macro rcp_ivalid_nodelay x, parity + mcrr2 p7, #6, \x , \parity , c8 +.endm + +// Assert x == y +.macro rcp_iequal x, y + mcrr p7, #7, \x , \y , c0 +.endm + +.macro rcp_iequal_nodelay x, y + mcrr2 p7, #7, \x , \y , c0 +.endm + +// ---------------------------------------------------------------------------- +// RCP Sequence count instructions + // Directly write 8-bit constant expression cnt to the sequence counter. .macro rcp_count_set_impl h, l mcr p7, #4, r0, \h , \l , #0 @@ -955,20 +976,20 @@ rcp_switch_u8_to_ch_cl rcp_count_check_impl, \cnt rcp_switch_u8_to_ch_cl rcp_count_check_nodelay_impl, \cnt .endm +// ---------------------------------------------------------------------------- +// RCP Canary instructions + // Get a 32-bit canary value. `tag` must be a constant expression. .macro rcp_canary_get_impl h, l, x mrc p7, #0, \x, \h, \l, #1 .endm - .macro rcp_canary_get x, tag rcp_switch_u8_to_ch_cl rcp_canary_get_impl \tag, \x .endm -// Get a 32-bit canary value. `tag` must be a constant expression. .macro rcp_canary_get_nodelay_impl h, l, x mrc2 p7, #0, \x, \h, \l, #1 .endm - .macro rcp_canary_get_nodelay x, tag rcp_switch_u8_to_ch_cl rcp_canary_get_nodelay_impl \tag, \x .endm @@ -977,7 +998,6 @@ rcp_switch_u8_to_ch_cl rcp_canary_get_nodelay_impl \tag, \x .macro rcp_canary_check_impl h, l, x mcr p7, #0, \x, \h, \l, #1 .endm - .macro rcp_canary_check x, tag rcp_switch_u8_to_ch_cl rcp_canary_check_impl \tag, \x .endm @@ -985,7 +1005,6 @@ rcp_switch_u8_to_ch_cl rcp_canary_check_impl \tag, \x .macro rcp_canary_check_nodelay_impl h, l, x mcr2 p7, #0, \x, \h, \l, #1 .endm - .macro rcp_canary_check_nodelay x, tag rcp_switch_u8_to_ch_cl rcp_canary_check_nodelay_impl \tag, \x .endm @@ -1001,5 +1020,7 @@ rcp_switch_u8_to_ch_cl rcp_canary_check_nodelay_impl \tag, \x #ifdef __cplusplus } #endif +#else +#define rcp_is_true(x) ((int32_t)(x) < 0) #endif #endif diff --git a/src/rp2_common/hardware_resets/include/hardware/resets.h b/src/rp2_common/hardware_resets/include/hardware/resets.h index 8baef728b..f75775717 100644 --- a/src/rp2_common/hardware_resets/include/hardware/resets.h +++ b/src/rp2_common/hardware_resets/include/hardware/resets.h @@ -23,6 +23,8 @@ * * Multiple blocks are referred to using a bitmask as follows: * + * \if rp2040_specific + * For RP2040: * Block to reset | Bit * ---------------|---- * USB | 24 @@ -41,15 +43,51 @@ * PIO 1 | 11 * PIO 0 | 10 * Pads - QSPI | 9 - * Pads - bank 0 | 8 + * Pads - Bank 0 | 8 * JTAG | 7 - * IO Bank 1 | 6 + * IO QSPI | 6 * IO Bank 0 | 5 * I2C 1 | 4 * I2C 0 | 3 * DMA | 2 * Bus Control | 1 * ADC 0 | 0 + * \endif + * + * \if rp2350_specific + * For RP2350: + * Block to reset | Bit + * ---------------|---- + * USB | 28 + * UART 1 | 27 + * UART 0 | 26 + * TRNG | 25 + * Timer 1 | 24 + * Timer 0 | 23 + * TB Manager | 22 + * SysInfo | 21 + * System Config | 20 + * SPI 1 | 19 + * SPI 0 | 18 + * SHA256 | 17 + * PWM | 16 + * PLL USB | 15 + * PLL System | 14 + * PIO 2 | 13 + * PIO 1 | 12 + * PIO 0 | 11 + * Pads - QSPI | 10 + * Pads - Bank 0 | 9 + * JTAG | 8 + * IO QSPI | 7 + * IO Bank 0 | 6 + * I2C 1 | 5 + * I2C 0 | 4 + * HSTX | 3 + * DMA | 2 + * Bus Control | 1 + * ADC 0 | 0 + * \endif * * \subsection reset_example Example * \addtogroup hardware_resets diff --git a/src/rp2_common/hardware_rtc/include/hardware/rtc.h b/src/rp2_common/hardware_rtc/include/hardware/rtc.h index 32317879c..9e05c7afb 100644 --- a/src/rp2_common/hardware_rtc/include/hardware/rtc.h +++ b/src/rp2_common/hardware_rtc/include/hardware/rtc.h @@ -8,7 +8,9 @@ #define _HARDWARE_RTC_H #include "pico.h" +#if HAS_RP2040_RTC #include "hardware/structs/rtc.h" +#endif /** \file hardware/rtc.h * \defgroup hardware_rtc hardware_rtc diff --git a/src/rp2_common/hardware_sha256/include/hardware/sha256.h b/src/rp2_common/hardware_sha256/include/hardware/sha256.h index db8fca6ff..dcbf1043d 100644 --- a/src/rp2_common/hardware_sha256/include/hardware/sha256.h +++ b/src/rp2_common/hardware_sha256/include/hardware/sha256.h @@ -122,7 +122,7 @@ static inline bool sha256_is_sum_valid(void) { * \ingroup hardware_sha256 * * After writing 64 bytes of data to the hardware, it will be unable to accept more data for a time. - * Call this to check if the hardware is ready for more data to be written. \see sha256_err_not_ready + * Call this to check if the hardware is ready for more data to be written. See \ref sha256_err_not_ready * * \return True if the hardware is ready to receive more data */ diff --git a/src/rp2_common/hardware_spi/include/hardware/spi.h b/src/rp2_common/hardware_spi/include/hardware/spi.h index cf79645da..bd83770c1 100644 --- a/src/rp2_common/hardware_spi/include/hardware/spi.h +++ b/src/rp2_common/hardware_spi/include/hardware/spi.h @@ -202,7 +202,7 @@ uint spi_set_baudrate(spi_inst_t *spi, uint baudrate); /*! \brief Get SPI baudrate * \ingroup hardware_spi * - * Get SPI baudrate which was set by \see spi_set_baudrate + * Get SPI baudrate which was set by \ref spi_set_baudrate * * \param spi SPI instance specifier, either \ref spi0 or \ref spi1 * \return The actual baudrate set diff --git a/src/rp2_common/hardware_sync/include/hardware/sync.h b/src/rp2_common/hardware_sync/include/hardware/sync.h index 82b253786..69b3e69a0 100644 --- a/src/rp2_common/hardware_sync/include/hardware/sync.h +++ b/src/rp2_common/hardware_sync/include/hardware/sync.h @@ -201,7 +201,7 @@ __force_inline static void __mem_fence_release(void) { /*! \brief Explicitly disable interrupts on the calling core * \ingroup hardware_sync */ -__force_inline static uint32_t disable_interrupts(void) { +__force_inline static void disable_interrupts(void) { #ifdef __riscv __compiler_memory_barrier(); riscv_clear_csr(mstatus, 8); @@ -214,7 +214,7 @@ __force_inline static uint32_t disable_interrupts(void) { /*! \brief Explicitly enable interrupts on the calling core * \ingroup hardware_sync */ -__force_inline static uint32_t enable_interrupts(void) { +__force_inline static void enable_interrupts(void) { #ifdef __riscv __compiler_memory_barrier(); riscv_set_csr(mstatus, 8); diff --git a/src/rp2_common/hardware_sync_spin_lock/include/hardware/sync/spin_lock.h b/src/rp2_common/hardware_sync_spin_lock/include/hardware/sync/spin_lock.h index 6885efd79..2be493d6f 100644 --- a/src/rp2_common/hardware_sync_spin_lock/include/hardware/sync/spin_lock.h +++ b/src/rp2_common/hardware_sync_spin_lock/include/hardware/sync/spin_lock.h @@ -149,7 +149,7 @@ typedef SW_SPIN_LOCK_TYPE spin_lock_t; __mem_fence_acquire(); \ }) #else -#error no SW_SPIN_TRY_LOCK available for PICO_USE_SW_SPIN_LOCK on this platform +#error no SW_SPIN_LOCK_LOCK available for PICO_USE_SW_SPIN_LOCK on this platform #endif #endif @@ -210,7 +210,7 @@ typedef SW_SPIN_LOCK_TYPE spin_lock_t; *(lock) = 0; /* write to spinlock register (release lock) */ \ }) #else -#error no SW_SPIN_TRY_LOCK available for PICO_USE_SW_SPIN_LOCK on this platform +#error no SW_SPIN_LOCK_UNLOCK available for PICO_USE_SW_SPIN_LOCK on this platform #endif #endif diff --git a/src/rp2_common/hardware_timer/include/hardware/timer.h b/src/rp2_common/hardware_timer/include/hardware/timer.h index 289a28a34..b26964083 100644 --- a/src/rp2_common/hardware_timer/include/hardware/timer.h +++ b/src/rp2_common/hardware_timer/include/hardware/timer.h @@ -351,7 +351,7 @@ typedef void (*hardware_alarm_callback_t)(uint alarm_num); * \param timer the timer instance * \param alarm_num the hardware alarm to claim * \sa hardware_alarm_claim - * \sa hardware_claiming + * \sa hardware_claim */ void timer_hardware_alarm_claim(timer_hw_t *timer, uint alarm_num); @@ -362,7 +362,7 @@ void timer_hardware_alarm_claim(timer_hw_t *timer, uint alarm_num); * * \param alarm_num the hardware alarm to claim * \sa timer_hardware_alarm_claim - * \sa hardware_claiming + * \sa hardware_claim */ void hardware_alarm_claim(uint alarm_num); @@ -375,7 +375,7 @@ void hardware_alarm_claim(uint alarm_num); * \param required if true the function will panic if none are available * \return alarm_num the hardware alarm claimed or -1 if required was false, and none are available * \sa hardware_alarm_claim_unused - * \sa hardware_claiming + * \sa hardware_claim */ int timer_hardware_alarm_claim_unused(timer_hw_t *timer, bool required); @@ -387,7 +387,7 @@ int timer_hardware_alarm_claim_unused(timer_hw_t *timer, bool required); * \param required if true the function will panic if none are available * \return alarm_num the hardware alarm claimed or -1 if required was false, and none are available * \sa timer_hardware_alarm_claim_unused - * \sa hardware_claiming + * \sa hardware_claim */ int hardware_alarm_claim_unused(bool required); @@ -397,7 +397,7 @@ int hardware_alarm_claim_unused(bool required); * \param timer the timer instance * \param alarm_num the hardware alarm to unclaim * \sa hardware_alarm_unclaim - * \sa hardware_claiming + * \sa hardware_claim */ void timer_hardware_alarm_unclaim(timer_hw_t *timer, uint alarm_num); @@ -406,7 +406,7 @@ void timer_hardware_alarm_unclaim(timer_hw_t *timer, uint alarm_num); * * \param alarm_num the hardware alarm to unclaim * \sa timer_hardware_alarm_unclaim - * \sa hardware_claiming + * \sa hardware_claim */ void hardware_alarm_unclaim(uint alarm_num); diff --git a/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h b/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h index e6adf65af..b11fd78d5 100644 --- a/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h +++ b/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h @@ -74,6 +74,13 @@ void watchdog_update(void); * \note If \ref watchdog_start_tick value does not give a 1MHz clock to the watchdog system, then the \p delay_ms * parameter will not be in milliseconds. See the datasheet for more details. * + * \if rp2040_specific + * On RP2040 the maximum delay is 8388 milliseconds, which is approximately 8.3 seconds (this is due to RP2040-E1). + * \endif + * \if rp2350_specific + * On RP2350 the maximum delay is 16777 milliseconds, which is approximately 16.7 seconds. + * \endif + * * By default the SDK assumes a 12MHz XOSC and sets the \ref watchdog_start_tick appropriately. * * This method sets a marker in the watchdog scratch register 4 that is checked by \ref watchdog_enable_caused_reboot. @@ -81,7 +88,7 @@ void watchdog_update(void); * onto the RPI-RP2), then this value will be cleared, and so \ref watchdog_enable_caused_reboot will * return false. * - * \param delay_ms Number of milliseconds before watchdog will reboot without watchdog_update being called. Maximum of 8388, which is approximately 8.3 seconds + * \param delay_ms Number of milliseconds before watchdog will reboot without watchdog_update being called * \param pause_on_debug If the watchdog should be paused when the debugger is stepping through code */ void watchdog_enable(uint32_t delay_ms, bool pause_on_debug); @@ -124,17 +131,29 @@ bool watchdog_enable_caused_reboot(void); * \brief Returns the number of microseconds before the watchdog will reboot the chip. * \ingroup hardware_watchdog * - * \if rp2040_specicifc + * \if rp2040_specific * On RP2040 this method returns the last value set instead of the remaining time due to a h/w bug. * \endif - * + * * @return The number of microseconds before the watchdog will reboot the chip. */ +uint32_t watchdog_get_time_remaining_us(void); + +/** + * \brief Returns the number of milliseconds before the watchdog will reboot the chip. + * \ingroup hardware_watchdog + * + * \if rp2040_specific + * On RP2040 this method returns the last value set instead of the remaining time due to a h/w bug. + * \endif + * + * @return The number of milliseconds before the watchdog will reboot the chip. + */ uint32_t watchdog_get_time_remaining_ms(void); // backwards compatibility with SDK < 2.0.0 static inline uint32_t watchdog_get_count(void) { - return watchdog_get_time_remaining_ms(); + return watchdog_get_time_remaining_us(); } #ifdef __cplusplus } diff --git a/src/rp2_common/hardware_watchdog/watchdog.c b/src/rp2_common/hardware_watchdog/watchdog.c index 45528ce43..c03620c14 100644 --- a/src/rp2_common/hardware_watchdog/watchdog.c +++ b/src/rp2_common/hardware_watchdog/watchdog.c @@ -28,16 +28,21 @@ void watchdog_update(void) { } // end::watchdog_update[] -uint32_t watchdog_get_time_remaining_ms(void) { - return watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS; -} - #if PICO_RP2040 -// Note, we have x2 here as the watchdog HW currently decrements twice per tick +// Note, we have x2 here as the watchdog HW currently decrements twice per tick (errata RP2040-E1) #define WATCHDOG_XFACTOR 2 #else #define WATCHDOG_XFACTOR 1 #endif + +uint32_t watchdog_get_time_remaining_us(void) { + return (watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS) / WATCHDOG_XFACTOR; +} + +uint32_t watchdog_get_time_remaining_ms(void) { + return (watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS) / (1000 * WATCHDOG_XFACTOR); +} + // tag::watchdog_enable[] // Helper function used by both watchdog_enable and watchdog_reboot void _watchdog_enable(uint32_t delay_ms, bool pause_on_debug) { @@ -60,10 +65,7 @@ void _watchdog_enable(uint32_t delay_ms, bool pause_on_debug) { if (!delay_ms) { hw_set_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_TRIGGER_BITS); } else { - load_value = delay_ms * 1000; -#if PICO_RP2040 - load_value *= 2; -#endif + load_value = delay_ms * (1000 * WATCHDOG_XFACTOR); if (load_value > WATCHDOG_LOAD_BITS) load_value = WATCHDOG_LOAD_BITS; diff --git a/src/rp2_common/pico_async_context/async_context_freertos.c b/src/rp2_common/pico_async_context/async_context_freertos.c index 9ae72b3af..f6b1a5a1a 100644 --- a/src/rp2_common/pico_async_context/async_context_freertos.c +++ b/src/rp2_common/pico_async_context/async_context_freertos.c @@ -73,6 +73,7 @@ static void async_context_task(__unused void *vself) { async_context_freertos_release_lock(&self->core); __sev(); // it is possible regular code is waiting on a WFE on the other core } while (!self->task_should_exit); + xSemaphoreGive(self->task_complete_sem); vTaskDelete(NULL); } @@ -109,19 +110,45 @@ bool async_context_freertos_init(async_context_freertos_t *self, async_context_f self->core.type = &template; self->core.flags = ASYNC_CONTEXT_FLAG_CALLBACK_FROM_NON_IRQ; self->core.core_num = get_core_num(); +#if configSUPPORT_STATIC_ALLOCATION + assert(config->task_stack); + self->lock_mutex = xSemaphoreCreateRecursiveMutexStatic(&self->lock_mutex_buf); + self->work_needed_sem = xSemaphoreCreateBinaryStatic(&self->work_needed_sem_buf); + self->task_complete_sem = xSemaphoreCreateBinaryStatic(&self->task_complete_sem_buf); + self->timer_handle = xTimerCreateStatic( "async_context_timer", // Just a text name, not used by the kernel. + portMAX_DELAY, + pdFALSE, // The timers will auto-reload themselves when they expire. + self, + timer_handler, + &self->timer_buf); + self->task_handle = xTaskCreateStatic( async_context_task, + "async_context_task", + config->task_stack_size, + self, + config->task_priority, + config->task_stack, + &self->task_buf); +#else self->lock_mutex = xSemaphoreCreateRecursiveMutex(); self->work_needed_sem = xSemaphoreCreateBinary(); + self->task_complete_sem = xSemaphoreCreateBinary(); self->timer_handle = xTimerCreate( "async_context_timer", // Just a text name, not used by the kernel. portMAX_DELAY, pdFALSE, // The timers will auto-reload themselves when they expire. self, timer_handler); +#endif if (!self->lock_mutex || !self->work_needed_sem || !self->timer_handle || +#if configSUPPORT_STATIC_ALLOCATION + !self->task_handle +#else pdPASS != xTaskCreate(async_context_task, "async_context_task", config->task_stack_size, self, - config->task_priority, &self->task_handle)) { + config->task_priority, &self->task_handle) +#endif + ) { async_context_deinit(&self->core); return false; } @@ -147,6 +174,9 @@ void async_context_freertos_deinit(async_context_t *self_base) { async_context_freertos_t *self = (async_context_freertos_t *)self_base; if (self->task_handle) { async_context_execute_sync(self_base, end_task_func, self_base); + if (self->task_complete_sem) { + xSemaphoreTake(self->task_complete_sem, portMAX_DELAY); + } } if (self->timer_handle) { xTimerDelete(self->timer_handle, 0); @@ -157,6 +187,9 @@ void async_context_freertos_deinit(async_context_t *self_base) { if (self->work_needed_sem) { vSemaphoreDelete(self->work_needed_sem); } + if (self->task_complete_sem) { + vSemaphoreDelete(self->task_complete_sem); + } memset(self, 0, sizeof(*self)); } @@ -179,6 +212,9 @@ void async_context_freertos_lock_check(__unused async_context_t *self_base) { typedef struct sync_func_call{ async_when_pending_worker_t worker; SemaphoreHandle_t sem; +#if configSUPPORT_STATIC_ALLOCATION + StaticSemaphore_t sem_buf; +#endif uint32_t (*func)(void *param); void *param; uint32_t rc; @@ -197,7 +233,11 @@ uint32_t async_context_freertos_execute_sync(async_context_t *self_base, uint32_ call.worker.do_work = handle_sync_func_call; call.func = func; call.param = param; +#if configSUPPORT_STATIC_ALLOCATION + call.sem = xSemaphoreCreateBinaryStatic(&call.sem_buf); +#else call.sem = xSemaphoreCreateBinary(); +#endif async_context_add_when_pending_worker(self_base, &call.worker); async_context_set_work_pending(self_base, &call.worker); xSemaphoreTake(call.sem, portMAX_DELAY); diff --git a/src/rp2_common/pico_async_context/async_context_threadsafe_background.c b/src/rp2_common/pico_async_context/async_context_threadsafe_background.c index 730d8a5a7..16571eba0 100644 --- a/src/rp2_common/pico_async_context/async_context_threadsafe_background.c +++ b/src/rp2_common/pico_async_context/async_context_threadsafe_background.c @@ -98,8 +98,8 @@ typedef struct sync_func_call{ static void handle_sync_func_call(async_context_t *context, async_when_pending_worker_t *worker) { sync_func_call_t *call = (sync_func_call_t *)worker; call->rc = call->func(call->param); - sem_release(&call->sem); async_context_remove_when_pending_worker(context, worker); + sem_release(&call->sem); } #endif @@ -139,7 +139,13 @@ uint32_t async_context_threadsafe_background_execute_sync(async_context_t *self_ async_context_threadsafe_background_t *self = (async_context_threadsafe_background_t*)self_base; #if ASYNC_CONTEXT_THREADSAFE_BACKGROUND_MULTI_CORE if (self_base->core_num != get_core_num()) { - hard_assert(!recursive_mutex_enter_count(&self->lock_mutex)); + // This core must not hold the lock mutex, or this cross-core execute would deadlock. It is fine if the other core holds it. + // It would be a strange set of circumstances for it to do so, hence the hard_assert + + // Note that this read of the owner is not synchronized with the other core; however we only + // care about it being set to `calling_core`, which the other core will not transition + // it either from or to. + assert(recursive_mutex_owner(&self->lock_mutex) != lock_get_caller_owner_id()); sync_func_call_t call = {0}; call.worker.do_work = handle_sync_func_call; call.func = func; diff --git a/src/rp2_common/pico_async_context/include/pico/async_context.h b/src/rp2_common/pico_async_context/include/pico/async_context.h index 6f7c4f0dc..8a19b9ca3 100644 --- a/src/rp2_common/pico_async_context/include/pico/async_context.h +++ b/src/rp2_common/pico_async_context/include/pico/async_context.h @@ -84,8 +84,8 @@ typedef struct async_context async_context_t; * A "timeout" represents some future action that must be taken at a specific time. * Its methods are called from the async_context under lock at the given time * - * \see async_context_add_worker_at - * \see async_context_add_worker_in_ms + * \see async_context_add_at_time_worker_at + * \see async_context_add_at_time_worker_in_ms */ typedef struct async_work_on_timeout { /*! @@ -119,8 +119,8 @@ typedef struct async_work_on_timeout { * to some external stimulus (usually an IRQ). * Its methods are called from the async_context under lock at the given time * - * \see async_context_add_worker_at - * \see async_context_add_worker_in_ms + * \see async_context_add_at_time_worker_at + * \see async_context_add_at_time_worker_in_ms */ typedef struct async_when_pending_worker { /*! diff --git a/src/rp2_common/pico_async_context/include/pico/async_context_freertos.h b/src/rp2_common/pico_async_context/include/pico/async_context_freertos.h index bc5131258..0120410f7 100644 --- a/src/rp2_common/pico_async_context/include/pico/async_context_freertos.h +++ b/src/rp2_common/pico_async_context/include/pico/async_context_freertos.h @@ -56,6 +56,12 @@ typedef struct async_context_freertos_config { * \brief Stack size for the async_context task */ configSTACK_DEPTH_TYPE task_stack_size; + /** + * \brief Pointer to stack memory for the async_context task. + */ +#if configSUPPORT_STATIC_ALLOCATION + StackType_t *task_stack; +#endif /** * \brief the core ID (see \ref portGET_CORE_ID()) to pin the task to. * This is only relevant in SMP mode. @@ -69,8 +75,16 @@ struct async_context_freertos { async_context_t core; SemaphoreHandle_t lock_mutex; SemaphoreHandle_t work_needed_sem; + SemaphoreHandle_t task_complete_sem; TimerHandle_t timer_handle; TaskHandle_t task_handle; +#if configSUPPORT_STATIC_ALLOCATION + StaticSemaphore_t lock_mutex_buf; + StaticSemaphore_t work_needed_sem_buf; + StaticSemaphore_t task_complete_sem_buf; + StaticTimer_t timer_buf; + StaticTask_t task_buf; +#endif uint8_t nesting; volatile bool task_should_exit; }; diff --git a/src/rp2_common/pico_bit_ops/CMakeLists.txt b/src/rp2_common/pico_bit_ops/CMakeLists.txt index a66a441f6..f3e8e1a72 100644 --- a/src/rp2_common/pico_bit_ops/CMakeLists.txt +++ b/src/rp2_common/pico_bit_ops/CMakeLists.txt @@ -19,9 +19,10 @@ if (NOT TARGET pico_bit_ops) ${CMAKE_CURRENT_LIST_DIR}/bit_ops_aeabi.S ) - target_link_libraries(pico_bit_ops_pico INTERFACE pico_bootrom pico_bit_ops_headers) + target_link_libraries(pico_bit_ops_pico INTERFACE pico_bit_ops_headers) - if (NOT PICO_RP2350) + if (PICO_RP2040) + target_link_libraries(pico_bit_ops_pico INTERFACE pico_bootrom) # gcc pico_wrap_function(pico_bit_ops_pico __clzsi2) pico_wrap_function(pico_bit_ops_pico __clzsi2) diff --git a/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S b/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S index 65a1bb4c9..88d0bc618 100644 --- a/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S +++ b/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S @@ -5,7 +5,9 @@ */ #include "pico/asm_helper.S" +#if PICO_RP2040 #include "pico/bootrom.h" +#endif #include "pico/runtime_init.h" pico_default_asm_setup diff --git a/src/rp2_common/pico_bootrom/BUILD.bazel b/src/rp2_common/pico_bootrom/BUILD.bazel index 53a24b105..1463216d3 100644 --- a/src/rp2_common/pico_bootrom/BUILD.bazel +++ b/src/rp2_common/pico_bootrom/BUILD.bazel @@ -18,6 +18,7 @@ cc_library( "//src/rp2_common/boot_bootrom_headers", "//src/rp2_common/hardware_boot_lock:hardware_boot_lock_headers", "//src/rp2_common/pico_flash:pico_flash_headers", + "//src/rp2_common/hardware_rcp:hardware_rcp_headers", ] + select({ "//bazel/constraint:host": ["//src/host/hardware_sync"], "//conditions:default": ["//src/rp2_common/hardware_sync"], diff --git a/src/rp2_common/pico_bootrom/bootrom.c b/src/rp2_common/pico_bootrom/bootrom.c index 1120f006a..766574802 100644 --- a/src/rp2_common/pico_bootrom/bootrom.c +++ b/src/rp2_common/pico_bootrom/bootrom.c @@ -7,6 +7,9 @@ #include "pico/bootrom.h" #include "boot/picoboot.h" #include "boot/picobin.h" +#if !PICO_RP2040 +#include "hardware/rcp.h" +#endif /// \tag::table_lookup[] @@ -108,4 +111,89 @@ int rom_add_flash_runtime_partition(uint32_t start_offset, uint32_t size, uint32 } return PICO_ERROR_INSUFFICIENT_RESOURCES; } + +int rom_pick_ab_partition_during_update(uint32_t *workarea_base, uint32_t workarea_size, uint partition_a_num) { +#if !PICO_RP2040 + // 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 (!rcp_is_true(IMAGE_DEF_VERIFIED(workarea_base))) { + // Chosen partition failed verification + return BOOTROM_ERROR_NOT_FOUND; + } + + if (IMAGE_DEF_TBYB_FLAGGED(workarea_base)) { + // The chosen partition is TBYB + if (tbyb_boot) { + // The boot partition is also TBYB - cannot update both, so prioritise boot partition + // Restore the erase address saved earlier + VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr; + return BOOTROM_ERROR_NOT_PERMITTED; + } else { + // Update the tbyb flash address, so that explicit_buy will clear the flag for the chosen partition + TBYB_FLAG_ADDR = + IMAGE_DEF_BASE(workarea_base) + + IMAGE_DEF_REL_BLOCK_OFFSET(workarea_base) + 4; + } + } else { + // The chosen partition is not TBYB + if (tbyb_boot && saved_erase_addr) { + // The boot partition was TBYB, and requires an erase + if (VERSION_DOWNGRADE_ERASE_ADDR) { + // But both the chosen partition requires an erase too + // As before, prioritise the boot partition, and restore it's saved erase_address + VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr; + return BOOTROM_ERROR_NOT_PERMITTED; + } else { + // The chosen partition doesn't require an erase, so we're fine + VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr; + } + } + } + + return rc; +} #endif \ No newline at end of file diff --git a/src/rp2_common/pico_bootrom/include/pico/bootrom.h b/src/rp2_common/pico_bootrom/include/pico/bootrom.h index bb5b8ba2f..4494ae1cf 100644 --- a/src/rp2_common/pico_bootrom/include/pico/bootrom.h +++ b/src/rp2_common/pico_bootrom/include/pico/bootrom.h @@ -749,10 +749,14 @@ 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_partition_during_update() 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 * \param flash_update_boot_window_base the flash update base, to pick that partition instead of the normally "better" partition + * \return >= 0 the chosen partition number out of the A/B pair */ static inline int rom_pick_ab_partition(uint8_t *workarea_base, uint32_t workarea_size, uint partition_a_num, uint32_t flash_update_boot_window_base) { rom_pick_ab_partition_fn func = (rom_pick_ab_partition_fn) rom_func_lookup_inline(ROM_FUNC_PICK_AB_PARTITION); @@ -763,6 +767,32 @@ static inline int rom_pick_ab_partition(uint8_t *workarea_base, uint32_t workare return rc; } +/*! \brief Pick A/B partition without disturbing any in progress Flash Update boot or TBYB boot + * \ingroup pico_bootrom + * + * This will perform the same function as \ref 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 \ref rom_pick_ab_partition(). + * + * This should be used instead of \ref rom_pick_ab_partition() when performing a Flash Update Boot before calling \ref rom_explicit_buy(), and can still be + * used without issue when a Flash Update Boot is not in progress. + * + * This function is necessary because if an `explicit_buy` is pending then calling `pick_ab_partition` would 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 two partitions with one `explicit_buy` call). + * + * This function 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 by \ref rom_pick_ab_partition() + * 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_partition_during_update(uint32_t *workarea_base, uint32_t workarea_size, uint partition_a_num); + /*! * \brief Get B partition * \ingroup pico_bootrom diff --git a/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c b/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c index 8028936e2..236328271 100644 --- a/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c +++ b/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c @@ -97,11 +97,11 @@ static inline bool double_tap_flag_is_set(void) { } static inline void set_double_tap_flag(void) { - hw_set_bits(&powman_hw->chip_reset, POWMAN_CHIP_RESET_DOUBLE_TAP_BITS); + hw_set_bits(&powman_hw->chip_reset, POWMAN_CHIP_RESET_DOUBLE_TAP_BITS | POWMAN_PASSWORD_BITS); } static inline void clear_double_tap_flag(void) { - hw_clear_bits(&powman_hw->chip_reset, POWMAN_CHIP_RESET_DOUBLE_TAP_BITS); + hw_clear_bits(&powman_hw->chip_reset, POWMAN_CHIP_RESET_DOUBLE_TAP_BITS | POWMAN_PASSWORD_BITS); } #endif diff --git a/src/rp2_common/pico_btstack/CMakeLists.txt b/src/rp2_common/pico_btstack/CMakeLists.txt index 010cc9e39..5fb76fcf7 100644 --- a/src/rp2_common/pico_btstack/CMakeLists.txt +++ b/src/rp2_common/pico_btstack/CMakeLists.txt @@ -1,3 +1,4 @@ +# PICO_CMAKE_CONFIG: PICO_BTSTACK_PATH, Path to an alternative version of btstack overriding the version in pico-sdk/lib/btstack. Can be passed to cmake or set in your environment, type=string, group=pico_btstack if (DEFINED ENV{PICO_BTSTACK_PATH} AND (NOT PICO_BTSTACK_PATH)) set(PICO_BTSTACK_PATH $ENV{PICO_BTSTACK_PATH}) message("Using PICO_BTSTACK_PATH from environment ('${PICO_BTSTACK_PATH}')") @@ -5,7 +6,7 @@ endif () set(BTSTACK_TEST_PATH "src/bluetooth.h") if (NOT PICO_BTSTACK_PATH) - set(PICO_BTSTACK_PATH ${PROJECT_SOURCE_DIR}/lib/btstack) + set(PICO_BTSTACK_PATH ${PICO_SDK_PATH}/lib/btstack) if (PICO_CYW43_SUPPORTED AND NOT EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) message(WARNING "btstack submodule has not been initialized; Pico W BLE support will be unavailable. hint: try 'git submodule update --init' from your SDK directory (${PICO_SDK_PATH}).") @@ -301,13 +302,22 @@ if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) pico_promote_common_scope_vars() - # Make a GATT header file from a BTstack GATT file - # Pass the target library name library type and path to the GATT input file - # To add additional directories to the gatt #import path, add them to the end of the argument list. + # pico_btstack_make_gatt_header(TARGET_LIB TARGET_TYPE GATT_FILE) + # \brief\ Make a GATT header file from a BTstack GATT file. + # + # Pass the target library name, library type, and path to the GATT input file. + # To add additional directories to the gatt import path, add them to the end of the argument list. + # + # \param\ TARGET_LIB The target library name + # \param\ TARGET_TYPE The target library type + # \param\ GATT_FILE The path to the GATT input file function(pico_btstack_make_gatt_header TARGET_LIB TARGET_TYPE GATT_FILE) find_package (Python3 REQUIRED COMPONENTS Interpreter) get_filename_component(GATT_NAME "${GATT_FILE}" NAME_WE) get_filename_component(GATT_PATH "${GATT_FILE}" PATH) + if (NOT GATT_PATH) + set(GATT_PATH "${CMAKE_CURRENT_LIST_DIR}") + endif() set(TARGET_GATT "${TARGET_LIB}_gatt_header") set(GATT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated/${TARGET_GATT}") set(GATT_HEADER "${GATT_BINARY_DIR}/${GATT_NAME}.h") diff --git a/src/rp2_common/pico_btstack/btstack_run_loop_async_context.c b/src/rp2_common/pico_btstack/btstack_run_loop_async_context.c index 9847be90d..dd66d01fc 100644 --- a/src/rp2_common/pico_btstack/btstack_run_loop_async_context.c +++ b/src/rp2_common/pico_btstack/btstack_run_loop_async_context.c @@ -129,6 +129,14 @@ const btstack_run_loop_t *btstack_run_loop_async_context_get_instance(async_cont return &btstack_run_loop_async_context; } +void btstack_run_loop_async_context_deinit(void) { + if (btstack_async_context) { + async_context_remove_at_time_worker(btstack_async_context, &btstack_timeout_worker); + async_context_remove_when_pending_worker(btstack_async_context, &btstack_processing_worker); + btstack_async_context = NULL; + } +} + static void btstack_timeout_reached(__unused async_context_t *context, __unused async_at_time_worker_t *worker) { // simply wakeup worker async_context_set_work_pending(btstack_async_context, &btstack_processing_worker); diff --git a/src/rp2_common/pico_btstack/include/pico/btstack_flash_bank.h b/src/rp2_common/pico_btstack/include/pico/btstack_flash_bank.h index 6d914f00e..d9c838c0f 100644 --- a/src/rp2_common/pico_btstack/include/pico/btstack_flash_bank.h +++ b/src/rp2_common/pico_btstack/include/pico/btstack_flash_bank.h @@ -20,16 +20,24 @@ extern "C" { #define PICO_FLASH_BANK_TOTAL_SIZE (FLASH_SECTOR_SIZE * 2u) #endif -// PICO_CONFIG: PICO_FLASH_BANK_STORAGE_OFFSET, Offset in flash of the Bluetooth flash storage, type=int, default=PICO_FLASH_SIZE_BYTES - PICO_FLASH_BANK_TOTAL_SIZE, group=pico_btstack +// PICO_CONFIG: PICO_FLASH_BANK_STORAGE_OFFSET, Offset in flash of the Bluetooth flash storage, type=int, default=PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE - PICO_FLASH_BANK_TOTAL_SIZE on RP2350 otherwise PICO_FLASH_SIZE_BYTES - PICO_FLASH_BANK_TOTAL_SIZE, group=pico_btstack #ifndef PICO_FLASH_BANK_STORAGE_OFFSET +#if PICO_RP2350 && PICO_RP2350_A2_SUPPORTED +#define PICO_FLASH_BANK_STORAGE_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE - PICO_FLASH_BANK_TOTAL_SIZE) +#else #define PICO_FLASH_BANK_STORAGE_OFFSET (PICO_FLASH_SIZE_BYTES - PICO_FLASH_BANK_TOTAL_SIZE) #endif +#endif /** * \brief Return the singleton BTstack HAL flash instance, used for non-volatile storage * \ingroup pico_btstack * - * \note By default two sectors at the end of flash are used (see \c PICO_FLASH_BANK_STORAGE_OFFSET and \c PICO_FLASH_BANK_TOTAL_SIZE) + * \note By default, two sectors near the end of flash are used. + * For RP2350 when PICO_RP2350_A2_SUPPORTED is true, two sectors that are three sectors from the end of flash are used. + * This keeps the last sector free for a workaround for chip errata RP2350-E10. See the RP2350 datasheet for more details about this. + * Otherwise, two sectors directly at the end of flash are used. + * See \c PICO_FLASH_BANK_STORAGE_OFFSET and \c PICO_FLASH_BANK_TOTAL_SIZE) */ const hal_flash_bank_t *pico_flash_bank_instance(void); diff --git a/src/rp2_common/pico_btstack/include/pico/btstack_run_loop_async_context.h b/src/rp2_common/pico_btstack/include/pico/btstack_run_loop_async_context.h index d1b09b7dc..b3a404025 100644 --- a/src/rp2_common/pico_btstack/include/pico/btstack_run_loop_async_context.h +++ b/src/rp2_common/pico_btstack/include/pico/btstack_run_loop_async_context.h @@ -23,6 +23,12 @@ extern "C" { */ const btstack_run_loop_t *btstack_run_loop_async_context_get_instance(async_context_t *context); +/** + * \brief Deinitialize the BTstack state to stop it using the async_context API + * \ingroup pico_btstack + */ +void btstack_run_loop_async_context_deinit(void); + #ifdef __cplusplus } #endif diff --git a/src/rp2_common/pico_clib_interface/newlib_interface.c b/src/rp2_common/pico_clib_interface/newlib_interface.c index 8925e5464..61adeb480 100644 --- a/src/rp2_common/pico_clib_interface/newlib_interface.c +++ b/src/rp2_common/pico_clib_interface/newlib_interface.c @@ -152,6 +152,11 @@ int __attribute__((weak)) _isatty(int fd) { return fd == STDIO_HANDLE_STDIN || fd == STDIO_HANDLE_STDOUT || fd == STDIO_HANDLE_STDERR; } +int __attribute__((weak)) _getentropy (__unused void *buffer, __unused size_t length) { + // note we don't hook this up as it isn't clear if/where it is used, and we don't particularly + // want to pull in pico_rand. the user can supply their own strong implementation if they need it! + return -1; +} // exit is not useful... no desire to pull in __call_exitprocs void exit(int status) { _exit(status); diff --git a/src/rp2_common/pico_crt0/crt0.S b/src/rp2_common/pico_crt0/crt0.S index e408b7ded..ea3b99a5a 100644 --- a/src/rp2_common/pico_crt0/crt0.S +++ b/src/rp2_common/pico_crt0/crt0.S @@ -15,6 +15,11 @@ #include "boot/picobin.h" #include "pico/bootrom.h" +// PICO_CONFIG: PICO_CRT0_NEAR_CALLS, Whether calls from crt0 into the binary are near (<16M away) - ignored for PICO_COPY_TO_RAM, default=0, type=bool, group=pico_crt0 +#ifndef PICO_CRT0_NEAR_CALLS +#define PICO_CRT0_NEAR_CALLS 0 +#endif + #ifdef NDEBUG #ifndef COLLAPSE_IRQS #define COLLAPSE_IRQS @@ -23,37 +28,56 @@ pico_default_asm_setup +// PICO_CONFIG: PICO_CRT0_NO_RESET_SECTION, Omit .reset section contents containing the startup code. This must be set if you want to replace the startup code while still keeping the rest of pico_crt0 as the reset section define here is not garbage collected, type=bool, default=0, advanced=true, group=pico_crt0 +#ifndef PICO_CRT0_NO_RESET_SECTION +#define PICO_CRT0_NO_RESET_SECTION 0 +#endif + +#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 +#if PICO_RP2040 .word isr_invalid // Reserved, should never fire .word isr_invalid // Reserved, should never fire .word isr_invalid // Reserved, should never fire .word isr_invalid // Reserved, should never fire +#else +.word isr_memmanage +.word isr_busfault +.word isr_usagefault +.word isr_securefault +#endif .word isr_invalid // Reserved, should never fire .word isr_invalid // Reserved, should never fire .word isr_invalid // Reserved, should never fire .word isr_svcall +#if PICO_RP2040 .word isr_invalid // Reserved, should never fire +#else +.word isr_debugmonitor +#endif .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 +166,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 +189,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 +204,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,20 +295,50 @@ 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 +#if !PICO_RP2040 +// since these are disabled by default, map them all to __unhandled_user_irq (will have +// a negative number +decl_isr isr_memmanage +decl_isr isr_busfault +decl_isr isr_usagefault +decl_isr isr_securefault +decl_isr isr_debugmonitor +#endif -// All unhandled USER IRQs fall through to here +// All unhandled USER IRQs fall through to here. +// Additionally, if the Armv9-M MemManage/BusFault/UsageFault/SecureFault/DebugMonitor exceptions +// are enabled, but the handlers are not defined, then unhandled_user_irq_num_in_r0 will +// also be reached, but with a negative exception number (e.g. MemManage == -12) .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 into individual BKPT instructions with label 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" @@ -310,6 +361,7 @@ binary_info_header: // ---------------------------------------------------------------------------- +#if !PICO_CRT0_NO_RESET_SECTION .section .reset, "ax" // On flash builds, the vector table comes first in the image (conventional). @@ -353,6 +405,12 @@ _entry_point: sev 1: #endif +#if !__ARM_ARCH_6M__ + // Make sure stack limit is 0 if we came in thru the debugger; we do not know what it should be + movs r0, #0 + msr msplim, r0 +#endif + ldr r0, =__vectors // Vector through our own table (SP, VTOR will not have been set up at // this point). Same path for debugger entry and bootloader entry. @@ -379,6 +437,9 @@ _enter_vtable_in_r0: .type _reset_handler,%function .thumb_func _reset_handler: + // Note if we entered thru here on core 0, then we should have gone thru bootrom, so SP (and MSPLIM) on Armv8-M + // should already be set + // Only core 0 should run the C runtime startup code; core 1 is normally // sleeping in the bootrom at this point but check to be sure (e.g. if // debugger put core 1 at the ELF entry point for some reason) @@ -441,20 +502,20 @@ bss_fill_test: bne bss_fill_loop platform_entry: // symbol for stack traces +#if PICO_CRT0_NEAR_CALLS && !PICO_COPY_TO_RAM + bl runtime_init + bl main + bl exit +#else // Use 32-bit jumps, in case these symbols are moved out of branch range // (e.g. if main is in SRAM and crt0 in flash) -#if !__ARM_ARCH_6M__ - // Make sure stack limit is 0 - the user can set it themselves - // todo probably worth adding to the EXE_DEF in the future - movs r0, #0 - msr msplim, r0 -#endif ldr r1, =runtime_init blx r1 ldr r1, =main blx r1 ldr r1, =exit blx r1 +#endif // exit should not return. If it does, hang the core. 1: // separate label because _exit can be moved out of branch range bkpt #0 @@ -474,7 +535,7 @@ data_cpy: // Note the data copy table is still included for NO_FLASH builds, even though // we skip the copy, because it is listed in binary info -.align 2 +.p2align 2 data_cpy_table: #if PICO_RP2350 && PICO_EMBED_XIP_SETUP && !PICO_NO_FLASH .word __boot2_start__ @@ -511,6 +572,7 @@ data_cpy_table: runtime_init: bx lr +#endif // PICO_CRT0_NO_RESET_SECTION // ---------------------------------------------------------------------------- // Stack/heap dummies to set size @@ -520,10 +582,16 @@ runtime_init: // // Strictly the most correct thing to do (as .stack and .heap are unreferenced) is to mark them as "a", and also KEEP, which // works correctly for both GCC and Clang, however doing so may break anyone who already has custom linker scripts without -// the KEEP. Therefore we will only add the "a" on Clang, but will also use KEEP to our own linker scripts. +// the KEEP. Therefore we add a define of PICO_CRT0_ALLOCATE_SPACERS to switch between the old and new behaviour, so anyone +// with custom linker scripts without the KEEP can set it to 0 (or update their linker script). + +// PICO_CONFIG: PICO_CRT0_ALLOCATE_SPACERS, Set spacer sections as allocatable. This makes them appear in print-memory-usage but is incompatible with linker scripts that do not KEEP the sections, type=bool, default=1, advanced=true, group=pico_crt0 +#ifndef PICO_CRT0_ALLOCATE_SPACERS +#define PICO_CRT0_ALLOCATE_SPACERS 1 +#endif .macro spacer_section name -#if PICO_ASSEMBLER_IS_CLANG +#if PICO_CRT0_ALLOCATE_SPACERS .section \name, "a" #else .section \name @@ -534,11 +602,15 @@ spacer_section .stack // align to allow for memory protection (although this alignment is pretty much ignored by linker script) .p2align 5 .equ StackSize, PICO_STACK_SIZE +.if StackSize != 0 .space StackSize +.endif spacer_section .heap .p2align 2 .equ HeapSize, PICO_HEAP_SIZE +.if HeapSize != 0 .space HeapSize +.endif #include "embedded_end_block.inc.S" diff --git a/src/rp2_common/pico_crt0/crt0_riscv.S b/src/rp2_common/pico_crt0/crt0_riscv.S index 0e89ab150..e9fc7d94c 100644 --- a/src/rp2_common/pico_crt0/crt0_riscv.S +++ b/src/rp2_common/pico_crt0/crt0_riscv.S @@ -160,64 +160,22 @@ check_irq_before_exit: addi sp, sp, 80 mret + // Default software vector table for system interrupts, routed through // mip.meip. Note this is assumed in e.g. hardware_irq to begin exactly 0x34 // words after the hardware vector table indicated by mtvec (defined above). .p2align 4 .global __soft_vector_table __soft_vector_table: -.word isr_irq0 -.word isr_irq1 -.word isr_irq2 -.word isr_irq3 -.word isr_irq4 -.word isr_irq5 -.word isr_irq6 -.word isr_irq7 -.word isr_irq8 -.word isr_irq9 -.word isr_irq10 -.word isr_irq11 -.word isr_irq12 -.word isr_irq13 -.word isr_irq14 -.word isr_irq15 -.word isr_irq16 -.word isr_irq17 -.word isr_irq18 -.word isr_irq19 -.word isr_irq20 -.word isr_irq21 -.word isr_irq22 -.word isr_irq23 -.word isr_irq24 -.word isr_irq25 -.word isr_irq26 -.word isr_irq27 -.word isr_irq28 -.word isr_irq29 -.word isr_irq30 -.word isr_irq31 -.word isr_irq32 -.word isr_irq33 -.word isr_irq34 -.word isr_irq35 -.word isr_irq36 -.word isr_irq37 -.word isr_irq38 -.word isr_irq39 -.word isr_irq40 -.word isr_irq41 -.word isr_irq42 -.word isr_irq43 -.word isr_irq44 -.word isr_irq45 -.word isr_irq46 -.word isr_irq47 -.word isr_irq48 -.word isr_irq49 -.word isr_irq50 -.word isr_irq51 +.macro vtable_irq_n n +.word isr_irq\n +.endm + +.set IRQN, 0 +.rept PICO_NUM_VTABLE_IRQS +vtable_irq_n IRQN +.set IRQN, IRQN + 1 +.endr // all default trap handlers do nothing, and we can check for them being set to our // default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end @@ -252,58 +210,23 @@ decl_isr isr_riscv_machine_exception decl_isr_bkpt isr_riscv_machine_timer decl_isr_bkpt isr_riscv_machine_soft_irq -decl_isr isr_irq0 -decl_isr isr_irq1 -decl_isr isr_irq2 -decl_isr isr_irq3 -decl_isr isr_irq4 -decl_isr isr_irq5 -decl_isr isr_irq6 -decl_isr isr_irq7 -decl_isr isr_irq8 -decl_isr isr_irq9 -decl_isr isr_irq10 -decl_isr isr_irq11 -decl_isr isr_irq12 -decl_isr isr_irq13 -decl_isr isr_irq14 -decl_isr isr_irq15 -decl_isr isr_irq16 -decl_isr isr_irq17 -decl_isr isr_irq18 -decl_isr isr_irq19 -decl_isr isr_irq20 -decl_isr isr_irq21 -decl_isr isr_irq22 -decl_isr isr_irq23 -decl_isr isr_irq24 -decl_isr isr_irq25 -decl_isr isr_irq26 -decl_isr isr_irq27 -decl_isr isr_irq28 -decl_isr isr_irq29 -decl_isr isr_irq30 -decl_isr isr_irq31 -decl_isr isr_irq32 -decl_isr isr_irq33 -decl_isr isr_irq34 -decl_isr isr_irq35 -decl_isr isr_irq36 -decl_isr isr_irq37 -decl_isr isr_irq38 -decl_isr isr_irq39 -decl_isr isr_irq40 -decl_isr isr_irq41 -decl_isr isr_irq42 -decl_isr isr_irq43 -decl_isr isr_irq44 -decl_isr isr_irq45 -decl_isr isr_irq46 -decl_isr isr_irq47 -decl_isr isr_irq48 -decl_isr isr_irq49 -decl_isr isr_irq50 -decl_isr isr_irq51 +// Declare all the ISR labels +.macro decl_isr_n n +.if \n < PICO_NUM_VTABLE_IRQS + decl_isr isr_irq\n +.elseif \n < NUM_IRQS + // We declare a strong label, so user can't override, since there is no vtable entry + .type isr_irq\n,%function + .thumb_func + isr_irq\n: +.endif +.endm + +.set IRQN, 0 +.rept PICO_NUM_VTABLE_IRQS +decl_isr_n IRQN +.set IRQN, IRQN + 1 +.endr // fall through // All unhandled USER IRQs fall through to here. Note there is no way to get diff --git a/src/rp2_common/pico_crt0/embedded_start_block.inc.S b/src/rp2_common/pico_crt0/embedded_start_block.inc.S index 8f1b622d4..4618a3a94 100644 --- a/src/rp2_common/pico_crt0/embedded_start_block.inc.S +++ b/src/rp2_common/pico_crt0/embedded_start_block.inc.S @@ -5,6 +5,21 @@ #endif #endif +#ifndef PICO_CRT0_INCLUDE_PICOBIN_VECTOR_TABLE_ITEM +// If no_flash bin, then include a vector table item +#if PICO_NO_FLASH && !PICO_RP2040 +#define PICO_CRT0_INCLUDE_PICOBIN_VECTOR_TABLE_ITEM 1 +#endif +#endif + +#ifndef PICO_CRT0_INCLUDE_PICOBIN_ENTRY_POINT_ITEM +// On RISC-V the default entry point from bootrom is the start of the binary, but +// we have our vtable at the start, so we must include an entry point +#ifdef __riscv +#define PICO_CRT0_INCLUDE_PICOBIN_ENTRY_POINT_ITEM 1 +#endif +#endif + #ifndef PICO_CRT0_INCLUDE_PICOBIN_BLOCK #define PICO_CRT0_INCLUDE_PICOBIN_BLOCK PICO_CRT0_INCLUDE_PICOBIN_IMAGE_TYPE_ITEM #endif @@ -41,7 +56,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) | \ @@ -73,9 +88,7 @@ embedded_block: .hword PICO_CRT0_VERSION_MAJOR #endif -#ifdef __riscv -// On RISC-V the default entry point from bootrom is the start of the binary, but -// we have our vtable at the start, so we must include an entry point +#if PICO_CRT0_INCLUDE_PICOBIN_ENTRY_POINT_ITEM .byte PICOBIN_BLOCK_ITEM_1BS_ENTRY_POINT .byte 0x3 // word size to next item .byte 0 // pad @@ -84,15 +97,12 @@ embedded_block: .word SRAM_END // stack pointer #endif -#ifndef PICO_RP2040 -#if PICO_NO_FLASH -// If no_flash bin, then include a vector table item +#if PICO_CRT0_INCLUDE_PICOBIN_VECTOR_TABLE_ITEM .byte PICOBIN_BLOCK_ITEM_1BS_VECTOR_TABLE .byte 0x2 .hword 0 .word __vectors #endif -#endif .byte PICOBIN_BLOCK_ITEM_2BS_LAST .hword (embedded_block_end - embedded_block - 16 ) / 4 // total size of all @@ -106,4 +116,4 @@ embedded_block: #endif .word PICOBIN_BLOCK_MARKER_END embedded_block_end: -#endif \ No newline at end of file +#endif diff --git a/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld b/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld index 89d63a9f0..44c69f3b9 100644 --- a/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld +++ b/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld @@ -33,10 +33,10 @@ ENTRY(_entry_point) SECTIONS { - /* Second stage bootloader is prepended to the image. It must be 256 bytes big - and checksummed. It is usually built by the boot_stage2 target - in the Raspberry Pi Pico SDK - */ + /* On Arm, the bootrom expects a VT at the start of the + image by default; on RISC-V, the default is to enter the image at its + lowest address, so an IMAGE_DEF item is required to specify the + nondefault entry point. */ .flash_begin : { __flash_binary_start = .; diff --git a/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld b/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld index 98088cdfc..5bedf6d21 100644 --- a/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld +++ b/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld @@ -35,7 +35,7 @@ SECTIONS /* Note unlike RP2040, we start the image with a vector table even for NO_FLASH builds. On Arm, the bootrom expects a VT at the start of the image by default; on RISC-V, the default is to enter the image at its - lowest address, so an IMAGEDEF item is required to specify the + lowest address, so an IMAGE_DEF item is required to specify the nondefault entry point. */ .text : { diff --git a/src/rp2_common/pico_cyw43_arch/cyw43_arch_freertos.c b/src/rp2_common/pico_cyw43_arch/cyw43_arch_freertos.c index 93f73ad5d..53ab62195 100644 --- a/src/rp2_common/pico_cyw43_arch/cyw43_arch_freertos.c +++ b/src/rp2_common/pico_cyw43_arch/cyw43_arch_freertos.c @@ -25,6 +25,10 @@ static async_context_freertos_t cyw43_async_context_freertos; +#if configSUPPORT_STATIC_ALLOCATION && !CYW43_NO_DEFAULT_TASK_STACK +static StackType_t cyw43_async_context_freertos_task_stack[CYW43_TASK_STACK_SIZE]; +#endif + async_context_t *cyw43_arch_init_default_async_context(void) { async_context_freertos_config_t config = async_context_freertos_default_config(); #ifdef CYW43_TASK_PRIORITY @@ -32,6 +36,9 @@ async_context_t *cyw43_arch_init_default_async_context(void) { #endif #ifdef CYW43_TASK_STACK_SIZE config.task_stack_size = CYW43_TASK_STACK_SIZE; +#endif +#if configSUPPORT_STATIC_ALLOCATION && !CYW43_NO_DEFAULT_TASK_STACK + config.task_stack = cyw43_async_context_freertos_task_stack; #endif if (async_context_freertos_init(&cyw43_async_context_freertos, &config)) return &cyw43_async_context_freertos.core; diff --git a/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h b/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h index 46aa09896..becc2fa98 100644 --- a/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h +++ b/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h @@ -59,7 +59,7 @@ extern "C" { * * As of right now, lwIP is the only supported TCP/IP stack, however the use of \c pico_cyw43_arch is intended to be independent of * the particular TCP/IP stack used (and possibly Bluetooth stack used) in the future. For this reason, the integration of lwIP - * is handled in the base (\c pico_cyw43_arch) library based on the #define \ref CYW43_LWIP used by the \c cyw43_driver. + * is handled in the base (\c pico_cyw43_arch) library based on the \#define \ref CYW43_LWIP used by the \c cyw43_driver. * * \note As of version 1.5.0 of the Raspberry Pi Pico SDK, the \c pico_cyw43_arch library no longer directly implements * the distinct behavioral abstractions. This is now handled by the more general \ref pico_async_context library. The @@ -169,7 +169,7 @@ extern "C" { * \ref cyw43_arch_init_default_async_context, however the user can specify use of their own async_context * by calling \ref cyw43_arch_set_async_context() before calling this method * - * \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes + * \return 0 if the initialization is successful, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_init(void); @@ -186,7 +186,7 @@ int cyw43_arch_init(void); * by calling \ref cyw43_arch_set_async_context() before calling this method * * \param country the country code to use (see \ref CYW43_COUNTRY_) - * \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes + * \return 0 if the initialization is successful, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_init_with_country(uint32_t country); @@ -399,7 +399,9 @@ 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 connection is successful. + * PICO_ERROR_BADAUTH is returned if the WiFi password is wrong. + * PICO_ERROR_CONNECT_FAILED is returned if the connection failed for some other reason. */ int cyw43_arch_wifi_connect_blocking(const char *ssid, const char *pw, uint32_t auth); @@ -413,7 +415,9 @@ 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 connection is successful. + * PICO_ERROR_BADAUTH is returned if the WiFi password is wrong. + * PICO_ERROR_CONNECT_FAILED is returned if the connection failed for some other reason. */ int cyw43_arch_wifi_connect_bssid_blocking(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth); @@ -427,7 +431,10 @@ 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 connection is successful. + * PICO_ERROR_TIMEOUT is returned if the timeout is reached before a successful connection. + * PICO_ERROR_BADAUTH is returned if the WiFi password is wrong. + * PICO_ERROR_CONNECT_FAILED is returned if the connection failed for some other reason. */ int cyw43_arch_wifi_connect_timeout_ms(const char *ssid, const char *pw, uint32_t auth, uint32_t timeout); @@ -442,7 +449,10 @@ 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 connection is successful. + * PICO_ERROR_TIMEOUT is returned if the timeout is reached before a successful connection. + * PICO_ERROR_BADAUTH is returned if the WiFi password is wrong. + * PICO_ERROR_CONNECT_FAILED is returned if the connection failed for some other reason. */ 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 +468,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 +485,7 @@ int cyw43_arch_wifi_connect_async(const char *ssid, const char *pw, uint32_t aut * \param auth the authorization type to use when the password is enabled. Values are \ref CYW43_AUTH_WPA_TKIP_PSK, * \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_) * - * \return 0 if the scan was started successfully, an error code otherwise \see pico_error_codes + * \return 0 if the scan was started successfully, an error code otherwise see \ref pico_error_codes */ int cyw43_arch_wifi_connect_bssid_async(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth); diff --git a/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch/arch_freertos.h b/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch/arch_freertos.h index 1ba23eff9..6944aa707 100644 --- a/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch/arch_freertos.h +++ b/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch/arch_freertos.h @@ -7,6 +7,11 @@ #ifndef _PICO_CYW43_ARCH_ARCH_FREERTOS_H #define _PICO_CYW43_ARCH_ARCH_FREERTOS_H +// PICO_CONFIG: CYW43_NO_DEFAULT_TASK_STACK, Disables the default static allocation of the CYW43 FreeRTOS task stack, type=bool, default=0, group=pico_cyw43_arch +#ifndef CYW43_NO_DEFAULT_TASK_STACK +#define CYW43_NO_DEFAULT_TASK_STACK 0 +#endif + // PICO_CONFIG: CYW43_TASK_STACK_SIZE, Stack size for the CYW43 FreeRTOS task in 4-byte words, type=int, default=1024, group=pico_cyw43_arch #ifndef CYW43_TASK_STACK_SIZE #define CYW43_TASK_STACK_SIZE 1024 diff --git a/src/rp2_common/pico_cyw43_driver/BUILD.bazel b/src/rp2_common/pico_cyw43_driver/BUILD.bazel index 23bec36a7..3810b27c2 100644 --- a/src/rp2_common/pico_cyw43_driver/BUILD.bazel +++ b/src/rp2_common/pico_cyw43_driver/BUILD.bazel @@ -83,3 +83,13 @@ pico_generate_pio_header( name = "cyw43_bus_pio", srcs = ["cyw43_bus_pio_spi.pio"], ) + +# TODO: https://github.com/raspberrypi/pico-sdk/issues/2055 Support storing +# Wi-Fi firmware in a separate partition +filegroup( + name = "pico_use_partition_firmware", + srcs = [ + "wifi_firmware.S", + "include/cyw43_partition_firmware.h", + ] +) diff --git a/src/rp2_common/pico_cyw43_driver/CMakeLists.txt b/src/rp2_common/pico_cyw43_driver/CMakeLists.txt index 289a22ab4..ddc5715e6 100644 --- a/src/rp2_common/pico_cyw43_driver/CMakeLists.txt +++ b/src/rp2_common/pico_cyw43_driver/CMakeLists.txt @@ -1,3 +1,4 @@ +# PICO_CMAKE_CONFIG: PICO_CYW43_DRIVER_PATH, Path to an alternative version of cyw43-driver overriding the version in pico-sdk/lib/cyw43-driver, type=string, group=pico_cyw43_driver if (DEFINED ENV{PICO_CYW43_DRIVER_PATH} AND (NOT PICO_CYW43_DRIVER_PATH)) set(PICO_CYW43_DRIVER_PATH $ENV{PICO_CYW43_DRIVER_PATH}) message("Using PICO_CYW43_DRIVER_PATH from environment ('${PICO_CYW43_DRIVER_PATH}')") @@ -130,16 +131,22 @@ if (EXISTS ${PICO_CYW43_DRIVER_PATH}/${CYW43_DRIVER_TEST_FILE}) ) endif() - # Set an ip address in a compile definition - # target name, target type, compile definition name to set then address in a string - # This can be used to set the following compile definitions - # CYW43_DEFAULT_IP_STA_ADDRESS - # CYW43_DEFAULT_IP_STA_GATEWAY - # CYW43_DEFAULT_IP_AP_ADDRESS - # CYW43_DEFAULT_IP_AP_GATEWAY - # CYW43_DEFAULT_IP_MASK - # CYW43_DEFAULT_IP_DNS + # pico_configure_ip4_address(TARGET_LIB TARGET_TYPE DEF_NAME IP_ADDRESS_STR) + # \brief\ Set an ip address in a compile definition + # + # This can be used to set the following compile definitions; + # CYW43_DEFAULT_IP_STA_ADDRESS; + # CYW43_DEFAULT_IP_STA_GATEWAY; + # CYW43_DEFAULT_IP_AP_ADDRESS; + # CYW43_DEFAULT_IP_AP_GATEWAY; + # CYW43_DEFAULT_IP_MASK; + # CYW43_DEFAULT_IP_DNS; # e.g. pico_configure_ip4_address(picow_tcpip_server_background PRIVATE CYW43_DEFAULT_IP_STA_ADDRESS "10.3.15.204") + # + # \param\ TARGET_LIB The target library to set the ip address for + # \param\ TARGET_TYPE The type of target library + # \param\ DEF_NAME The name of the compile definition to set + # \param\ IP_ADDRESS_STR The ip address to set function(pico_configure_ip4_address TARGET_LIB TARGET_TYPE DEF_NAME IP_ADDRESS_STR) string(REGEX MATCHALL "[0-9]+" IP_ADDRESS_LIST ${IP_ADDRESS_STR}) list(LENGTH IP_ADDRESS_LIST IP_ADDRESS_COMPONENT_COUNT) @@ -158,5 +165,100 @@ if (EXISTS ${PICO_CYW43_DRIVER_PATH}/${CYW43_DRIVER_TEST_FILE}) ) endfunction() + set(PICO_CYW43_DRIVER_CURRENT_PATH ${CMAKE_CURRENT_LIST_DIR}) + pico_register_common_scope_var(PICO_CYW43_DRIVER_CURRENT_PATH) + pico_promote_common_scope_vars() + + # pico_use_wifi_firmware_partition(TARGET [NO_EMBEDDED_PT]) + # \brief\ Use a partition for the Wi-Fi firmware + # + # This will read the CYW43 firmware from a partition with the ID 0x776966696669726d, + # instead of embedding the firmware blob in the binary. By default it will also embed + # a compatible partition table in the binary, but this can be disabled by passing the + # NO_EMBEDDED_PT argument (for example, if you need to chain into the binary, it + # can't contain a partition table). + # + # This will create additional UF2 files for the CYW43 firmware - both a regular version, + # and a TBYB version to use if you're updating it using the TBYB feature (see section + # 5.1.17 of the RP2350 datasheet). You will need to flash your chosen version to each + # new device once, after loading the partition table. For example using picotool: + # + # `picotool load TARGET.uf2`; + # `picotool reboot -u`; + # `picotool load -ux TARGET_wifi_firmware.uf2`; + # + # Then on subsequent updates, you can just flash the TARGET.uf2 file to the device. + # + # \param\ NO_EMBEDDED_PT If set, will not embed a partition table in the binary + function(pico_use_wifi_firmware_partition TARGET) + set(options NO_EMBEDDED_PT) + cmake_parse_arguments(PARSE_ARGV 1 OPTS "${options}" "" "") + if (PICO_PLATFORM STREQUAL "rp2040") + message(FATAL_ERROR "RP2040 does not support storing wi-fi firmware in partitions") + endif() + target_compile_definitions(${TARGET} PRIVATE CYW43_USE_FIRMWARE_PARTITION=1) + + if (NOT OPTS_NO_EMBEDDED_PT) + get_target_property(picotool_embed_pt ${TARGET} PICOTOOL_EMBED_PT) + if (NOT picotool_embed_pt) + pico_embed_pt_in_binary(${TARGET} ${PICO_CYW43_DRIVER_CURRENT_PATH}/wifi_pt.json) + endif() + endif() + + find_package (Python3 REQUIRED COMPONENTS Interpreter) + + # CYW43 firmware blob + add_custom_target(${TARGET}_firmware_blob DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/firmware_blob.S) + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/firmware_blob.S + COMMAND ${Python3_EXECUTABLE} ${PICO_CYW43_DRIVER_CURRENT_PATH}/cyw43_firmware.py ${PICO_CYW43_DRIVER_PATH}/firmware/wb43439A0_7_95_49_00_combined.h ${CMAKE_CURRENT_BINARY_DIR}/firmware_blob.S + ) + + # Create UF2s for regular and TBYB firmwares + add_executable(${TARGET}_wifi_firmware + ${PICO_CYW43_DRIVER_CURRENT_PATH}/wifi_firmware.S) + add_executable(${TARGET}_wifi_firmware_tbyb + ${PICO_CYW43_DRIVER_CURRENT_PATH}/wifi_firmware.S) + + add_dependencies(${TARGET}_wifi_firmware ${TARGET}_firmware_blob) + add_dependencies(${TARGET}_wifi_firmware_tbyb ${TARGET}_firmware_blob) + + target_include_directories(${TARGET}_wifi_firmware PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + target_include_directories(${TARGET}_wifi_firmware_tbyb PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + + target_compile_definitions(${TARGET}_wifi_firmware PRIVATE + NO_PICO_PLATFORM=1 + ) + target_compile_definitions(${TARGET}_wifi_firmware_tbyb PRIVATE + NO_PICO_PLATFORM=1 + PICO_CRT0_IMAGE_TYPE_TBYB=1 + ) + + target_link_options(${TARGET}_wifi_firmware PRIVATE -nostartfiles -nodefaultlibs LINKER:--script=${PICO_CYW43_DRIVER_CURRENT_PATH}/wifi_firmware.ld) + target_link_options(${TARGET}_wifi_firmware_tbyb PRIVATE -nostartfiles -nodefaultlibs LINKER:--script=${PICO_CYW43_DRIVER_CURRENT_PATH}/wifi_firmware.ld) + + target_link_libraries(${TARGET}_wifi_firmware boot_picobin_headers) + target_link_libraries(${TARGET}_wifi_firmware_tbyb boot_picobin_headers) + + get_target_property(hasSigfile ${TARGET} PICOTOOL_SIGFILE) + if (hasSigfile) + pico_sign_binary(${TARGET}_wifi_firmware ${sigfile}) + pico_sign_binary(${TARGET}_wifi_firmware_tbyb ${sigfile}) + endif() + + pico_hash_binary(${TARGET}_wifi_firmware) + pico_hash_binary(${TARGET}_wifi_firmware_tbyb) + + pico_set_uf2_family(${TARGET}_wifi_firmware cyw43-firmware) + pico_set_uf2_family(${TARGET}_wifi_firmware_tbyb cyw43-firmware) + + pico_package_uf2_output(${TARGET}_wifi_firmware 0x10000000) + pico_package_uf2_output(${TARGET}_wifi_firmware_tbyb 0x10000000) + + pico_add_extra_outputs(${TARGET}_wifi_firmware) + pico_add_extra_outputs(${TARGET}_wifi_firmware_tbyb) + + add_dependencies(${TARGET} + ${TARGET}_wifi_firmware ${TARGET}_wifi_firmware_tbyb) + endfunction() endif() diff --git a/src/rp2_common/pico_cyw43_driver/btstack_cyw43.c b/src/rp2_common/pico_cyw43_driver/btstack_cyw43.c index 75061f167..dd15835e8 100644 --- a/src/rp2_common/pico_cyw43_driver/btstack_cyw43.c +++ b/src/rp2_common/pico_cyw43_driver/btstack_cyw43.c @@ -69,6 +69,7 @@ bool btstack_cyw43_init(async_context_t *context) { void btstack_cyw43_deinit(__unused async_context_t *context) { hci_power_control(HCI_POWER_OFF); hci_close(); + btstack_run_loop_async_context_deinit(); btstack_run_loop_deinit(); btstack_memory_deinit(); } \ No newline at end of file diff --git a/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/BUILD.bazel b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/BUILD.bazel index 24e53b3f9..7ade7c787 100644 --- a/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/BUILD.bazel +++ b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/BUILD.bazel @@ -6,7 +6,7 @@ cc_library( "cybt_shared_bus.c", "cybt_shared_bus_driver.c", ], - hdrs = ["cybt_shared_bus_driver.h"], + hdrs = ["cybt_shared_bus_driver.h", "cybt_logging.h"], includes = ["."], deps = [ "@cyw43-driver//:cyw43_driver", diff --git a/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_logging.h b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_logging.h new file mode 100644 index 000000000..aad2a1e6e --- /dev/null +++ b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_logging.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CYBT_LOGGING_H +#define CYBT_LOGGING_H + +// Error messages only enabled in debug by default +#ifndef CYBT_ERROR_ENABLED +#ifndef NDEBUG +#define CYBT_ERROR_ENABLED 1 +#else +#define CYBT_ERROR_ENABLED 0 +#endif +#endif + +// Info messages only enabled in debug by default +#ifndef CYBT_INFO_ENABLED +#ifndef NDEBUG +#define CYBT_INFO_ENABLED 1 +#else +#define CYBT_INFO_ENABLED 0 +#endif +#endif + +// Debug messages disabled by default +#ifndef CYBT_DEBUG_ENABLED +#define CYBT_DEBUG_ENABLED 0 +#endif + +#ifndef cybt_error +#if CYBT_ERROR_ENABLED +#define cybt_error CYW43_WARN +#else +#define cybt_error(...) +#endif +#endif + +#ifndef cybt_info +#if CYBT_INFO_ENABLED +#define cybt_info CYW43_PRINTF +#else +#define cybt_info(...) +#endif +#endif + +#ifndef cybt_debug +#if CYBT_DEBUG_ENABLED +#define cybt_debug CYW43_PRINTF +#else +#define cybt_debug(...) +#endif +#endif + +#endif // CYBT_LOGGING_H \ No newline at end of file diff --git a/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_shared_bus.c b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_shared_bus.c index b464b3f78..f256f0e4c 100644 --- a/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_shared_bus.c +++ b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_shared_bus.c @@ -15,6 +15,7 @@ #include "cybt_shared_bus_driver.h" #include "cyw43_btfw_43439.h" +#include "cybt_logging.h" #if CYW43_USE_HEX_BTFW extern const char brcm_patch_version[]; @@ -31,16 +32,6 @@ extern const int brcm_patch_ram_length; #define BTSDIO_FWBUF_OPER_DELAY_US (250) #define BTFW_WAIT_TIME_MS (150) -#define CYBT_DEBUG 0 -#define CYBT_VDEBUG 0 - -#if CYBT_DEBUG -#define cybt_debug(format,args...) printf("%d.%d: " format, (int)cyw43_hal_ticks_ms() / 1000, (int)cyw43_hal_ticks_ms() % 1000, ## args) -#else -#define cybt_debug(format, ...) ((void)0) -#endif -#define cybt_printf(format, args...) printf("%d.%d: " format, (int)cyw43_hal_ticks_ms() / 1000, (int)cyw43_hal_ticks_ms() % 1000, ## args) - #define ROUNDUP(x, a) ((((x) + ((a) - 1)) / (a)) * (a)) #define ROUNDDN(x, a) ((x) & ~((a) - 1)) #define ISALIGNED(a, x) (((uint32_t)(a) & ((x) - 1)) == 0) @@ -119,7 +110,7 @@ int cyw43_btbus_init(cyw43_ll_t *self) { ret = cybt_fw_download_prepare(&p_write_buf, &p_hex_buf); if (CYBT_SUCCESS != ret) { - cybt_printf("Could not allocate memory\n"); + cybt_error("Could not allocate memory\n"); return ret; } @@ -127,9 +118,9 @@ int cyw43_btbus_init(cyw43_ll_t *self) { const uint8_t *fw_data_buf; uint32_t fw_data_len; #if CYW43_USE_HEX_BTFW - cybt_printf("CYW43_USE_HEX_BTFW is true\n"); + cybt_error("CYW43_USE_HEX_BTFW is true\n"); #ifndef NDEBUG - cybt_printf("BT FW download, version = %s\n", brcm_patch_version); + cybt_info("BT FW download, version = %s\n", brcm_patch_version); #endif fw_data_len = brcm_patch_ram_length; fw_data_buf = brcm_patchram_buf; @@ -147,7 +138,7 @@ int cyw43_btbus_init(cyw43_ll_t *self) { cybt_fw_download_finish(p_write_buf, p_hex_buf); if (CYBT_SUCCESS != ret) { - cybt_printf("hci_open(): FW download failed (0x%x)\n", ret); + cybt_error("hci_open(): FW download failed (0x%x)\n", ret); return CYBT_ERR_HCI_INIT_FAILED; } @@ -157,7 +148,7 @@ int cyw43_btbus_init(cyw43_ll_t *self) { if (CYBT_SUCCESS == ret) { cybt_debug("hci_open(): FW download successfully\n"); } else { - cybt_printf("hci_open(): Failed to download FW\n"); + cybt_error("hci_open(): Failed to download FW\n"); return CYBT_ERR_HCI_INIT_FAILED; } @@ -178,7 +169,7 @@ int cyw43_btbus_init(cyw43_ll_t *self) { return CYBT_SUCCESS; } -#if CYBT_VDEBUG +#if 0 static void dump_bytes(const uint8_t *bptr, uint32_t len) { unsigned int i = 0; @@ -194,6 +185,9 @@ static void dump_bytes(const uint8_t *bptr, uint32_t len) { } printf("\n"); } +#define DUMP_BYTES dump_bytes +#else +#define DUMP_BYTES(...) #endif static cybt_result_t cybt_hci_write_buf(const uint8_t *p_data, uint32_t length) { @@ -202,7 +196,7 @@ static cybt_result_t cybt_hci_write_buf(const uint8_t *p_data, uint32_t length) assert(ISALIGNED(p_data, 4)); if (!ISALIGNED(p_data, 4)) { - cybt_printf("cybt_hci_write_hdr: buffer not aligned\n"); + cybt_error("cybt_hci_write_hdr: buffer not aligned\n"); return CYBT_ERR_BADARG; } @@ -256,7 +250,7 @@ static cybt_result_t cybt_hci_read(uint8_t *p_data, uint32_t *p_length) { assert(ISALIGNED(p_data, 4)); if (!ISALIGNED(p_data, 4)) { assert(false); - cybt_printf("cybt_hci_read: buffer not aligned\n"); + cybt_error("cybt_hci_read: buffer not aligned\n"); return CYBT_ERR_BADARG; } @@ -268,9 +262,9 @@ static cybt_result_t cybt_hci_read(uint8_t *p_data, uint32_t *p_length) { cybt_debug("cybt_hci_read: bt2host_in_val=%lu bt2host_out_val=%lu fw_b2h_buf_count=%ld\n", fw_membuf_info.bt2host_in_val, fw_membuf_info.bt2host_out_val, fw_b2h_buf_count); if (fw_b2h_buf_count < available) { - cybt_printf("error: cybt_hci_read buffer overflow fw_b2h_buf_count=%ld available=%lu\n", fw_b2h_buf_count, + cybt_error("error: cybt_hci_read buffer overflow fw_b2h_buf_count=%ld available=%lu\n", fw_b2h_buf_count, available); - cybt_printf("error: cybt_hci_read bt2host_in_val=%lu bt2host_out_val=%lu\n", fw_membuf_info.bt2host_in_val, + cybt_error("error: cybt_hci_read bt2host_in_val=%lu bt2host_out_val=%lu\n", fw_membuf_info.bt2host_in_val, fw_membuf_info.bt2host_out_val); panic("cyw43 buffer overflow"); } @@ -351,9 +345,7 @@ int cyw43_btbus_write(uint8_t *buf, uint32_t size) { cybt_bus_request(); cybt_debug("cyw43_btbus_write: %d\n", cmd_len); -#if CYBT_VDEBUG - dump_bytes(buf, size); // dump header and data -#endif + DUMP_BYTES(buf, size); // dump header and data cybt_hci_write_buf(buf, size); cybt_bus_release(); @@ -372,7 +364,7 @@ static bool cybt_hci_read_packet(uint8_t *buf, uint32_t max_buf_size, uint32_t * if (bt_result != CYBT_SUCCESS) { *size = 0; - cybt_printf("cybt_hci_read_packet: error %d", bt_result); + cybt_error("cybt_hci_read_packet: error %d", bt_result); return true; } @@ -386,7 +378,7 @@ static bool cybt_hci_read_packet(uint8_t *buf, uint32_t max_buf_size, uint32_t * uint32_t hci_read_len = ((buf[2] << 16) & 0xFFFF00) | ((buf[1] << 8) & 0xFF00) | (buf[0] & 0xFF); if (hci_read_len > max_buf_size - 4) { *size = 0; - cybt_printf("cybt_hci_read_packet: too much data len %" PRId32"\n", hci_read_len); + cybt_error("cybt_hci_read_packet: too much data len %" PRId32"\n", hci_read_len); assert(false); return false; } @@ -397,7 +389,7 @@ static bool cybt_hci_read_packet(uint8_t *buf, uint32_t max_buf_size, uint32_t * bt_result = cybt_hci_read(buf + 4, &total_read_len); if (bt_result != CYBT_SUCCESS) { *size = 0; - cybt_printf("cybt_hci_read_packet: read failed\n"); + cybt_error("cybt_hci_read_packet: read failed\n"); assert(false); return false; } @@ -409,15 +401,13 @@ static bool cybt_hci_read_packet(uint8_t *buf, uint32_t max_buf_size, uint32_t * } else { assert(total_read_len > 0); *size = total_read_len + 4; - cybt_printf("cybt_hci_read_packet: failed to read all data %lu < %lu\n", total_read_len, hci_read_len); + cybt_error("cybt_hci_read_packet: failed to read all data %lu < %lu\n", total_read_len, hci_read_len); //assert(false); return true; } cybt_debug("cybt_hci_read_packet: %ld\n", *size); -#if CYBT_VDEBUG - dump_bytes(buf, *size); -#endif + DUMP_BYTES(buf, *size); return true; } diff --git a/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_shared_bus_driver.c b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_shared_bus_driver.c index 452337f99..dcfca3a15 100644 --- a/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_shared_bus_driver.c +++ b/src/rp2_common/pico_cyw43_driver/cybt_shared_bus/cybt_shared_bus_driver.c @@ -11,6 +11,7 @@ #include "cyw43_ll.h" #include "cybt_shared_bus_driver.h" +#include "cybt_logging.h" // Bluetooth register corruption occurs if both wifi and bluetooth are fully utilised. #define CYBT_CORRUPTION_TEST 1 @@ -23,23 +24,6 @@ static uint32_t last_bt_ctrl_reg; #endif -#ifndef NDEBUG -#define cybt_printf(format, args ...) printf(format,##args) -#else -#define cybt_printf(...) -#endif - -#ifndef CYBT_DEBUG -#define CYBT_DEBUG 0 -#endif - -#if CYBT_DEBUG -#include -#define cybt_debug(format, args ...) printf(format,##args) -#else -#define cybt_debug(format, ...) ((void)0) -#endif - /****************************************************************************** * Constants @@ -319,7 +303,7 @@ cybt_result_t cybt_fw_download(const uint8_t *p_bt_firmware, uint8_t version_len = *p_bt_firmware; assert(*(p_bt_firmware + version_len) == 0); #ifndef NDEBUG - cybt_printf("BT FW download, version = %s\n", p_bt_firmware + 1); + cybt_info("BT FW download, version = %s\n", p_bt_firmware + 1); #endif p_bt_firmware += version_len + 1; // skip over version p_bt_firmware += 1; // skip over record count @@ -409,7 +393,7 @@ cybt_result_t cybt_toggle_bt_intr(void) { cybt_reg_read(HOST_CTRL_REG_ADDR, ®_val); #if CYBT_CORRUPTION_TEST if ((reg_val & ~(BTSDIO_REG_SW_RDY_BITMASK | BTSDIO_REG_WAKE_BT_BITMASK | BTSDIO_REG_DATA_VALID_BITMASK)) != 0) { - cybt_printf("cybt_toggle_bt_intr read HOST_CTRL_REG_ADDR as 0x%08lx\n", reg_val); + cybt_error("cybt_toggle_bt_intr read HOST_CTRL_REG_ADDR as 0x%08lx\n", reg_val); cybt_debug_dump(); panic("cyw43 btsdio register corruption"); } @@ -485,32 +469,32 @@ void cybt_debug_dump(void) { uint32_t reg_val = 0; cybt_fw_membuf_index_t buf_index; - cybt_printf("WLAN_RAM_BASE_ADDR: 0x%08lx\n", WLAN_RAM_BASE_ADDR); - cybt_printf("H2B_BUF_ADDR: 0x%08lx\n", H2B_BUF_ADDR); - cybt_printf("B2H_BUF_ADDR: 0x%08lx\n", B2H_BUF_ADDR); + cybt_debug("WLAN_RAM_BASE_ADDR: 0x%08lx\n", WLAN_RAM_BASE_ADDR); + cybt_debug("H2B_BUF_ADDR: 0x%08lx\n", H2B_BUF_ADDR); + cybt_debug("B2H_BUF_ADDR: 0x%08lx\n", B2H_BUF_ADDR); cybt_reg_read(H2B_BUF_IN_ADDR, &buf_index.host2bt_in_val); - cybt_printf("H2B_BUF_IN_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", H2B_BUF_IN_ADDR, buf_index.host2bt_in_val, + cybt_debug("H2B_BUF_IN_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", H2B_BUF_IN_ADDR, buf_index.host2bt_in_val, last_buf_index.host2bt_in_val); cybt_reg_read(H2B_BUF_OUT_ADDR, &buf_index.host2bt_out_val); - cybt_printf("H2B_BUF_OUT_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", H2B_BUF_OUT_ADDR, buf_index.host2bt_out_val, + cybt_debug("H2B_BUF_OUT_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", H2B_BUF_OUT_ADDR, buf_index.host2bt_out_val, last_buf_index.host2bt_out_val); cybt_reg_read(B2H_BUF_IN_ADDR, &buf_index.bt2host_in_val); - cybt_printf("B2H_BUF_IN_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", B2H_BUF_IN_ADDR, buf_index.bt2host_in_val, + cybt_debug("B2H_BUF_IN_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", B2H_BUF_IN_ADDR, buf_index.bt2host_in_val, last_buf_index.bt2host_in_val); cybt_reg_read(B2H_BUF_OUT_ADDR, &buf_index.bt2host_out_val); - cybt_printf("B2H_BUF_OUT_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", B2H_BUF_OUT_ADDR, buf_index.bt2host_out_val, + cybt_debug("B2H_BUF_OUT_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", B2H_BUF_OUT_ADDR, buf_index.bt2host_out_val, last_buf_index.bt2host_out_val); cybt_reg_read(HOST_CTRL_REG_ADDR, ®_val); - cybt_printf("HOST_CTRL_REG_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", HOST_CTRL_REG_ADDR, reg_val, + cybt_debug("HOST_CTRL_REG_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", HOST_CTRL_REG_ADDR, reg_val, last_host_ctrl_reg); cybt_reg_read(BT_CTRL_REG_ADDR, ®_val); - cybt_printf("BT_CTRL_REG_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", BT_CTRL_REG_ADDR, reg_val, last_bt_ctrl_reg); + cybt_debug("BT_CTRL_REG_ADDR: 0x%08lx = 0x%08lx (last 0x%08lx)\n", BT_CTRL_REG_ADDR, reg_val, last_bt_ctrl_reg); #endif } @@ -533,7 +517,7 @@ cybt_result_t cybt_get_bt_buf_index(cybt_fw_membuf_index_t *p_buf_index) { #if CYBT_CORRUPTION_TEST if (p_buf_index->host2bt_in_val >= BTSDIO_FWBUF_SIZE || p_buf_index->host2bt_out_val >= BTSDIO_FWBUF_SIZE || p_buf_index->bt2host_in_val >= BTSDIO_FWBUF_SIZE || p_buf_index->bt2host_out_val >= BTSDIO_FWBUF_SIZE) { - cybt_printf("cybt_get_bt_buf_index invalid buffer value\n"); + cybt_error("cybt_get_bt_buf_index invalid buffer value\n"); cybt_debug_dump(); } else { memcpy((uint8_t *) &last_buf_index, (uint8_t *) p_buf_index, sizeof(cybt_fw_membuf_index_t)); @@ -567,7 +551,7 @@ static cybt_result_t cybt_reg_read(uint32_t reg_addr, uint32_t *p_value) { return CYBT_SUCCESS; } -#if CYBT_DEBUG +#if 0 static void dump_bytes(const uint8_t *bptr, uint32_t len) { unsigned int i = 0; diff --git a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c index 787eeff5d..06d5beff3 100644 --- a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c +++ b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c @@ -359,9 +359,9 @@ void cyw43_spi_gpio_setup(void) { // Reset wifi chip void cyw43_spi_reset(void) { gpio_put(CYW43_PIN_WL_REG_ON, false); // off - sleep_ms(20); + cyw43_delay_ms(20); gpio_put(CYW43_PIN_WL_REG_ON, true); // on - sleep_ms(250); + cyw43_delay_ms(250); // Setup IRQ (24) - also used for DO, DI gpio_init(CYW43_PIN_WL_HOST_WAKE); @@ -451,13 +451,6 @@ static inline int _cyw43_write_reg(cyw43_int_t *self, uint32_t fn, uint32_t reg, uint32_t buf[2]; buf[0] = make_cmd(true, true, fn, reg, size); buf[1] = val; - if (fn == BACKPLANE_FUNCTION) { - // In case of f1 overflow - self->last_size = 8; - self->last_header[0] = buf[0]; - self->last_header[1] = buf[1]; - self->last_backplane_window = self->cur_backplane_window; - } if (fn == BACKPLANE_FUNCTION) { logic_debug_set(pin_BACKPLANE_WRITE, 1); diff --git a/src/rp2_common/pico_cyw43_driver/cyw43_driver.c b/src/rp2_common/pico_cyw43_driver/cyw43_driver.c index 308d649d9..384062fc1 100644 --- a/src/rp2_common/pico_cyw43_driver/cyw43_driver.c +++ b/src/rp2_common/pico_cyw43_driver/cyw43_driver.c @@ -19,7 +19,18 @@ #define CYW43_SLEEP_CHECK_MS 50 #endif -static async_context_t *cyw43_async_context; +static async_context_t *cyw43_async_context = NULL; + +#if CYW43_USE_FIRMWARE_PARTITION + #include "pico/bootrom.h" + #include "hardware/flash.h" + #include "boot/picobin.h" + #include + + int32_t cyw43_wifi_fw_len; + int32_t cyw43_clm_len; + uintptr_t fw_data; +#endif static void cyw43_sleep_timeout_reached(async_context_t *context, async_at_time_worker_t *worker); static void cyw43_do_poll(async_context_t *context, async_when_pending_worker_t *worker); @@ -104,6 +115,87 @@ static void cyw43_sleep_timeout_reached(async_context_t *context, __unused async } bool cyw43_driver_init(async_context_t *context) { +#if CYW43_USE_FIRMWARE_PARTITION + uint32_t buffer[(16 * 4) + 1] = {}; // maximum of 16 partitions, each with maximum of 4 words returned, plus 1 + int ret = rom_get_partition_table_info(buffer, count_of(buffer), PT_INFO_PARTITION_LOCATION_AND_FLAGS | PT_INFO_PARTITION_ID); + + hard_assert(buffer[0] == (PT_INFO_PARTITION_LOCATION_AND_FLAGS | PT_INFO_PARTITION_ID)); + + if (ret > 0) { + int i = 1; + int p = 0; + int picked_p = -1; + while (i < ret) { + i++; + uint32_t flags_and_permissions = buffer[i++]; + bool has_id = (flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS); + if (has_id) { + uint64_t id = 0; + id |= buffer[i++]; + id |= ((uint64_t)(buffer[i++]) << 32ull); + if (id == CYW43_FIRMWARE_PARTITION_ID) { + picked_p = p; + break; + } + } + + p++; + } + + if (picked_p >= 0) { + #ifdef __riscv + // Increased bootrom stack is required for this function + bootrom_stack_t stack = { + .base = malloc(0x400), + .size = 0x400 + }; + rom_set_bootrom_stack(&stack); + #endif + uint32_t* workarea = malloc(0x1000); + picked_p = rom_pick_ab_partition_during_update(workarea, 0x1000, picked_p); + free(workarea); + #ifdef __riscv + // Reset bootrom stack + rom_set_bootrom_stack(&stack); + free(stack.base); + #endif + + if (picked_p < 0) { + if (picked_p == BOOTROM_ERROR_NOT_FOUND) { + CYW43_DEBUG("Chosen CYW43 firmware partition was not verified\n"); + } else if (picked_p == BOOTROM_ERROR_NOT_PERMITTED) { + CYW43_DEBUG("Too many update boots going on at once\n"); + } + return false; + } + + CYW43_DEBUG("Chosen CYW43 firmware in partition %d\n", picked_p); + int ret = rom_get_partition_table_info(buffer, count_of(buffer), PT_INFO_PARTITION_LOCATION_AND_FLAGS | PT_INFO_SINGLE_PARTITION | (picked_p << 24)); + hard_assert(buffer[0] == (PT_INFO_PARTITION_LOCATION_AND_FLAGS | PT_INFO_SINGLE_PARTITION)); + hard_assert(ret == 3); + + uint32_t location_and_permissions = buffer[1]; + uint32_t saddr = ((location_and_permissions >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB) & 0x1fffu) * FLASH_SECTOR_SIZE; + uint32_t eaddr = (((location_and_permissions >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB) & 0x1fffu) + 1) * FLASH_SECTOR_SIZE; + // Starts with metadata block + while(saddr < eaddr && *(uint32_t*)(XIP_NOCACHE_NOALLOC_NOTRANSLATE_BASE + saddr) != PICOBIN_BLOCK_MARKER_END) { + saddr += 4; + } + saddr += 4; + // Now onto data + cyw43_wifi_fw_len = *(uint32_t*)(XIP_NOCACHE_NOALLOC_NOTRANSLATE_BASE + saddr); + cyw43_clm_len = *(uint32_t*)(XIP_NOCACHE_NOALLOC_NOTRANSLATE_BASE + saddr + 4); + fw_data = XIP_NOCACHE_NOALLOC_NOTRANSLATE_BASE + saddr + 8; + } else { + CYW43_DEBUG("No CYW43 firmware partition found, so cannot get firmware from partition\n"); + return false; + } + } else { + CYW43_DEBUG("No partition table, so cannot get firmware from partition - get_partition_table_info returned %d\n", ret); + return false; + } + +#endif cyw43_init(&cyw43_state); cyw43_async_context = context; // we need the IRQ to be on the same core as the context, because we need to be able to enable/disable the IRQ @@ -114,13 +206,15 @@ bool cyw43_driver_init(async_context_t *context) { } void cyw43_driver_deinit(async_context_t *context) { - assert(context == cyw43_async_context); - async_context_remove_at_time_worker(context, &sleep_timeout_worker); - async_context_remove_when_pending_worker(context, &cyw43_poll_worker); - // the IRQ IS on the same core as the context, so must be de-initialized there - async_context_execute_sync(context, cyw43_irq_deinit, NULL); - cyw43_deinit(&cyw43_state); - cyw43_async_context = NULL; + if (cyw43_async_context != NULL) { + assert(context == cyw43_async_context); + async_context_remove_at_time_worker(context, &sleep_timeout_worker); + async_context_remove_when_pending_worker(context, &cyw43_poll_worker); + // the IRQ IS on the same core as the context, so must be de-initialized there + async_context_execute_sync(context, cyw43_irq_deinit, NULL); + cyw43_deinit(&cyw43_state); + cyw43_async_context = NULL; + } } // todo maybe add an #ifdef in cyw43_driver diff --git a/src/rp2_common/pico_cyw43_driver/cyw43_firmware.py b/src/rp2_common/pico_cyw43_driver/cyw43_firmware.py new file mode 100644 index 000000000..218ec3cd2 --- /dev/null +++ b/src/rp2_common/pico_cyw43_driver/cyw43_firmware.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2024 Raspberry Pi (Trading) Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause + +import sys +import re + +assert len(sys.argv) == 3 + +cyw43_wifi_fw_len = -1 +cyw43_clm_len = -1 + +with open(sys.argv[1], "r") as f: + data = f.read() + statements = data.split(";") + for line in statements[1].split("\n"): + if "#define CYW43_WIFI_FW_LEN" in line: + matches = re.search(r"#define\s+\S+\s+\((\S+)\)", line) + cyw43_wifi_fw_len = int(matches[1]) + elif "#define CYW43_CLM_LEN" in line: + matches = re.search(r"#define\s+\S+\s+\((\S+)\)", line) + cyw43_clm_len = int(matches[1]) + if cyw43_wifi_fw_len > 0 and cyw43_clm_len > 0: + break + data = statements[0] + bits = data.split(",") + bits[0] = bits[0].split("{")[-1] + bits[-1] = bits[-1].split("}")[0] + for i in range(len(bits)): + bits[i] = bits[i].strip() + bits[i] = bits[i].strip(',') + bits[i] = int(bits[i], base=0) + +data = ( + cyw43_wifi_fw_len.to_bytes(4, 'little', signed=True) + + cyw43_clm_len.to_bytes(4, 'little', signed=True) + + bytearray(bits) +) + +with open(sys.argv[2], "w") as f: + for b in data: + f.write(f".byte 0x{b:02x}\n") diff --git a/src/rp2_common/pico_cyw43_driver/include/cyw43_configport.h b/src/rp2_common/pico_cyw43_driver/include/cyw43_configport.h index f1c00c2fb..59b7d240e 100644 --- a/src/rp2_common/pico_cyw43_driver/include/cyw43_configport.h +++ b/src/rp2_common/pico_cyw43_driver/include/cyw43_configport.h @@ -63,12 +63,16 @@ extern "C" { #endif #ifndef CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE +#if CYW43_USE_FIRMWARE_PARTITION +#define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "cyw43_partition_firmware.h" +#else #if CYW43_ENABLE_BLUETOOTH #define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "wb43439A0_7_95_49_00_combined.h" #else #define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "w43439A0_7_95_49_00_combined.h" #endif #endif +#endif #ifndef CYW43_WIFI_NVRAM_INCLUDE_FILE #define CYW43_WIFI_NVRAM_INCLUDE_FILE "wifi_nvram_43439.h" @@ -198,9 +202,18 @@ void cyw43_post_poll_hook(void); #define cyw43_free free #endif +// PICO_CONFIG: PICO_CYW43_LOGGING_ENABLED, Enable/disable CYW43_PRINTF used for logging in cyw43 components. Has no effect if CYW43_PRINTF is defined by the user, default=1, type=bool, group=pico_cyw43_driver +#ifndef PICO_CYW43_LOGGING_ENABLED +#define PICO_CYW43_LOGGING_ENABLED 1 +#endif + +#if !defined(CYW43_PRINTF) && !PICO_CYW43_LOGGING_ENABLED +#define CYW43_PRINTF(...) (void)0 +#endif + #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif diff --git a/src/rp2_common/pico_cyw43_driver/include/cyw43_partition_firmware.h b/src/rp2_common/pico_cyw43_driver/include/cyw43_partition_firmware.h new file mode 100644 index 000000000..5df9eb5e8 --- /dev/null +++ b/src/rp2_common/pico_cyw43_driver/include/cyw43_partition_firmware.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +extern int cyw43_wifi_fw_len; +extern int cyw43_clm_len; + +#define CYW43_WIFI_FW_LEN (cyw43_wifi_fw_len) +#define CYW43_CLM_LEN (cyw43_clm_len) +extern uintptr_t fw_data; + +#include "boot/picobin.h" +#include "pico/bootrom.h" diff --git a/src/rp2_common/pico_cyw43_driver/include/pico/cyw43_driver.h b/src/rp2_common/pico_cyw43_driver/include/pico/cyw43_driver.h index 4d17c4b32..cd692963e 100644 --- a/src/rp2_common/pico_cyw43_driver/include/pico/cyw43_driver.h +++ b/src/rp2_common/pico_cyw43_driver/include/pico/cyw43_driver.h @@ -20,6 +20,14 @@ #include "cyw43_configport.h" #endif +#if CYW43_USE_FIRMWARE_PARTITION +// PICO_CONFIG: CYW43_FIRMWARE_PARTITION_ID, ID of Wi-Fi firmware partition which must match the ID used in the partition table JSON, type=int, default=0x776966696669726d, group=pico_cyw43_driver +#ifndef CYW43_FIRMWARE_PARTITION_ID +// The default 0x776966696669726d value is the ASCII encoding of "wififirm" +#define CYW43_FIRMWARE_PARTITION_ID 0x776966696669726d +#endif +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/src/rp2_common/pico_cyw43_driver/wifi_firmware.S b/src/rp2_common/pico_cyw43_driver/wifi_firmware.S new file mode 100644 index 000000000..ed398ff78 --- /dev/null +++ b/src/rp2_common/pico_cyw43_driver/wifi_firmware.S @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2024 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "boot/picobin.h" + +#if PICO_CRT0_IMAGE_TYPE_TBYB +#define CRT0_TBYB_FLAG PICOBIN_IMAGE_TYPE_EXE_TBYB_BITS +#else +#define CRT0_TBYB_FLAG 0 +#endif + +.section .wifi_fw, "a" +.global _start +_start: +.word 0 +.word 0 +.word 0 +.word 0 + +.p2align 2 +embedded_block: +.word PICOBIN_BLOCK_MARKER_START + +.byte PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE +.byte 0x1 // 1 word +.hword PICOBIN_IMAGE_TYPE_IMAGE_TYPE_AS_BITS(EXE) | \ + PICOBIN_IMAGE_TYPE_EXE_CPU_AS_BITS(RISCV) | \ + PICOBIN_IMAGE_TYPE_EXE_CHIP_AS_BITS(RP2350) | \ + CRT0_TBYB_FLAG + +// Entry point into SRAM +.byte PICOBIN_BLOCK_ITEM_1BS_ENTRY_POINT +.byte 0x3 // word size to next item +.byte 0 // pad +.byte 0 // pad +.word _start +.word 0x20082000 // stack pointer + +_lm_item: +.byte PICOBIN_BLOCK_ITEM_LOAD_MAP +.byte 7 +.byte 0 // pad +.byte 2 // 2 entries +// To sign the firmware +.word (_start - _lm_item) +.word _start +.word (firmware_end - _start) +// But clear SRAM if actually running this, so it doesn't boot +.word 0 +.word _start +.word 0x00082000 + +.byte PICOBIN_BLOCK_ITEM_2BS_LAST +.hword (embedded_block_end - embedded_block - 16 ) / 4 // total size of all +.byte 0 +.word 0 +.word PICOBIN_BLOCK_MARKER_END +embedded_block_end: + +#include "firmware_blob.S" + +firmware_end: diff --git a/src/rp2_common/pico_cyw43_driver/wifi_firmware.ld b/src/rp2_common/pico_cyw43_driver/wifi_firmware.ld new file mode 100644 index 000000000..d239ef933 --- /dev/null +++ b/src/rp2_common/pico_cyw43_driver/wifi_firmware.ld @@ -0,0 +1,14 @@ +MEMORY +{ + RAM(rx) : ORIGIN = 0x20000000, LENGTH = 512k +} + +ENTRY(_start) + +SECTIONS +{ + .wifi_fw : { + *(.wifi_fw*) + . = ALIGN(4); + } > RAM +} diff --git a/src/rp2_common/pico_cyw43_driver/wifi_pt.json b/src/rp2_common/pico_cyw43_driver/wifi_pt.json new file mode 100644 index 000000000..035a19ed8 --- /dev/null +++ b/src/rp2_common/pico_cyw43_driver/wifi_pt.json @@ -0,0 +1,52 @@ +{ + "version": [1, 0], + "unpartitioned": { + "families": ["absolute"], + "permissions": { + "secure": "rw", + "nonsecure": "rw", + "bootloader": "rw" + } + }, + "partitions": [ + { + "name": "Main", + "id": 0, + "start": 0, + "size": "3500K", + "families": ["rp2350-arm-s", "rp2350-riscv"], + "permissions": { + "secure": "rw", + "nonsecure": "rw", + "bootloader": "rw" + } + }, + { + "name": "Wi-Fi Firmware", + "id": "0x776966696669726d", + "start": "3500k", + "size": "256K", + "families": ["cyw43-firmware"], + "permissions": { + "secure": "rw", + "nonsecure": "rw", + "bootloader": "rw" + }, + "ignored_during_riscv_boot": true, + "no_reboot_on_uf2_download": true + }, + { + "start": "3500k", + "size": "256k", + "families": ["cyw43-firmware"], + "permissions": { + "secure": "rw", + "nonsecure": "rw", + "bootloader": "rw" + }, + "link": ["a", 1], + "ignored_during_riscv_boot": true, + "no_reboot_on_uf2_download": true + } + ] +} diff --git a/src/rp2_common/pico_divider/divider_hardware.S b/src/rp2_common/pico_divider/divider_hardware.S index cb3f54162..049c6f755 100644 --- a/src/rp2_common/pico_divider/divider_hardware.S +++ b/src/rp2_common/pico_divider/divider_hardware.S @@ -12,21 +12,27 @@ #warning "Building divider_hardware.S on a platform with no SIO divider hardware" #endif -// PICO_CONFIG: PICO_DIVIDER_DISABLE_INTERRUPTS, Disable interrupts around division such that divider state need not be saved/restored in exception handlers, default=0, group=pico_divider +// PICO_CONFIG: PICO_DIVIDER_DISABLE_INTERRUPTS, Disable interrupts around division such that divider state need not be saved/restored in exception handlers, default=0, type=bool, group=pico_divider +#if 0 // make tooling checks happy +#define PICO_DIVIDER_DISABLE_INTERRUPTS 0 +#endif -// PICO_CONFIG: PICO_DIVIDER_CALL_IDIV0, Whether 32 bit division by zero should call __aeabi_idiv0, default=1, group=pico_divider +// PICO_CONFIG: PICO_DIVIDER_CALL_IDIV0, Whether 32 bit division by zero should call __aeabi_idiv0, default=1, type=bool, group=pico_divider #ifndef PICO_DIVIDER_CALL_IDIV0 #define PICO_DIVIDER_CALL_IDIV0 1 #endif -// PICO_CONFIG: PICO_DIVIDER_CALL_IDIV0, Whether 64 bit division by zero should call __aeabi_ldiv0, default=1, group=pico_divider +// PICO_CONFIG: PICO_DIVIDER_CALL_LDIV0, Whether 64 bit division by zero should call __aeabi_ldiv0, default=1, type=bool, group=pico_divider #ifndef PICO_DIVIDER_CALL_LDIV0 #define PICO_DIVIDER_CALL_LDIV0 1 #endif pico_default_asm_setup -// PICO_CONFIG: PICO_DIVIDER_IN_RAM, Whether divider functions should be placed in RAM, default=0, group=pico_divider +// PICO_CONFIG: PICO_DIVIDER_IN_RAM, Whether divider functions should be placed in RAM, default=0, type=bool, group=pico_divider +#if 0 // make tooling checks happy +#define PICO_DIVIDER_IN_RAM 0 +#endif .macro div_section name #if PICO_DIVIDER_IN_RAM .section RAM_SECTION_NAME(\name), "ax" diff --git a/src/rp2_common/pico_double/double_aeabi_rp2040.S b/src/rp2_common/pico_double/double_aeabi_rp2040.S index 448b28355..6ec3d7958 100644 --- a/src/rp2_common/pico_double/double_aeabi_rp2040.S +++ b/src/rp2_common/pico_double/double_aeabi_rp2040.S @@ -649,7 +649,7 @@ regular_func double2fix_z lsrs r3, #21 // adjust adds r3, r2 - ble 2f // adjusted input is zero or dedornmal or < 1 + ble 2f // adjusted input is zero or denormal or < 1 lsrs r3, r3, #11 bne 3f // adjusted input is > infinite @@ -933,4 +933,4 @@ double_wrapper_section log wrapper_func_d1 log shimmable_table_tail_call SF_TABLE_FLN dln_shim -#endif \ No newline at end of file +#endif diff --git a/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c b/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c index 91315d193..88b7c9458 100644 --- a/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c +++ b/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c @@ -5,6 +5,7 @@ */ #include "pico.h" +#if PICO_RP2040_B0_SUPPORTED || PICO_RP2040_B1_SUPPORTED #include "pico/time.h" #include "hardware/structs/usb.h" #include "hardware/gpio.h" @@ -17,7 +18,6 @@ #define LS_K 0b10 #define LS_SE1 0b11 -#if PICO_RP2040_B0_SUPPORTED || PICO_RP2040_B1_SUPPORTED static void hw_enumeration_fix_wait_se0(void); static void hw_enumeration_fix_force_ls_j(void); static void hw_enumeration_fix_finish(void); diff --git a/src/rp2_common/pico_float/float_sci_m33_vfp.S b/src/rp2_common/pico_float/float_sci_m33_vfp.S index 86e8b2750..d105496ba 100644 --- a/src/rp2_common/pico_float/float_sci_m33_vfp.S +++ b/src/rp2_common/pico_float/float_sci_m33_vfp.S @@ -29,6 +29,7 @@ float_section WRAPPER_FUNC_NAME(\func) float_section frrcore_v +.p2align 2 // 1/2Ï€ to plenty of accuracy .long 0 @ this allows values of e down to -32 rtwopi: @@ -152,7 +153,7 @@ wrapper_func expf mov r0,#0 bx r14 -.align 3 +.p2align 3 k_exp2: .float 0.693147181 @ log2 .float 0.240226507 @ log²2/2 @@ -254,7 +255,7 @@ wrapper_func logf movlong r0,0xff800000 bx r14 -.align 3 +.p2align 3 k_log3: .float 0.5 .float 0.333333333333333 @@ -501,7 +502,7 @@ fsc_sintail: and r0,r0,#0x80000000 @ make signed zero b 22b -.align 2 +.p2align 2 2: vmul.f32 s3,s3,s9 @ ε³/3! vsub.f32 s1,s1,s3 @ ε-ε³/3! ~ sinε @@ -515,7 +516,7 @@ fsc_costail: eor r0,r0,r12,lsl#31 bx r14 -.align 3 +.p2align 3 k_sc3: .word 0x3EFFFEC1 @ ~ 1/2! with PMC .word 0x3e2aaa25 @ ~ 1/3! with PMC diff --git a/src/rp2_common/pico_lwip/BUILD.bazel b/src/rp2_common/pico_lwip/BUILD.bazel index c98ff92a2..cc5de44c8 100644 --- a/src/rp2_common/pico_lwip/BUILD.bazel +++ b/src/rp2_common/pico_lwip/BUILD.bazel @@ -131,14 +131,15 @@ alias( actual = "@lwip//:pico_lwip_tftp", ) -alias( +cc_library( name = "pico_lwip_mbedtls", - actual = "@lwip//:pico_lwip_mbedtls", + srcs = ["altcp_tls_mbedtls.c"], + deps = ["@lwip//:pico_lwip_mbedtls"], ) alias( - name = "pico_lwip_mqttt", - actual = "@lwip//:pico_lwip_mqttt", + name = "pico_lwip_mqtt", + actual = "@lwip//:pico_lwip_mqtt", ) alias( diff --git a/src/rp2_common/pico_lwip/CMakeLists.txt b/src/rp2_common/pico_lwip/CMakeLists.txt index 1a523b781..71da00176 100644 --- a/src/rp2_common/pico_lwip/CMakeLists.txt +++ b/src/rp2_common/pico_lwip/CMakeLists.txt @@ -1,3 +1,4 @@ +# PICO_CMAKE_CONFIG: PICO_LWIP_PATH, Path to an alternative version of lwip overriding the version in pico-sdk/lib/lwip. Can be passed to cmake or set in your environment, type=string, group=pico_lwip if (DEFINED ENV{PICO_LWIP_PATH} AND (NOT PICO_LWIP_PATH)) set(PICO_LWIP_PATH $ENV{PICO_LWIP_PATH}) message("Using PICO_LWIP_PATH from environment ('${PICO_LWIP_PATH}')") @@ -5,7 +6,7 @@ endif () set(LWIP_TEST_PATH "src/Filelists.cmake") if (NOT PICO_LWIP_PATH) - set(PICO_LWIP_PATH ${PROJECT_SOURCE_DIR}/lib/lwip) + set(PICO_LWIP_PATH ${PICO_SDK_PATH}/lib/lwip) if (PICO_CYW43_SUPPORTED AND NOT EXISTS ${PICO_LWIP_PATH}/${LWIP_TEST_PATH}) message(WARNING "LWIP submodule has not been initialized; Pico W wireless support will be unavailable #hint: try 'git submodule update --init' from your SDK directory (${PICO_SDK_PATH}).") @@ -234,14 +235,29 @@ if (EXISTS ${PICO_LWIP_PATH}/${LWIP_TEST_PATH}) ${PICO_LWIP_PATH}/src/apps/tftp/tftp.c ) + # Mbed TLS files pico_add_library(pico_lwip_mbedtls NOFLAG) target_sources(pico_lwip_mbedtls INTERFACE - ${PICO_LWIP_PATH}/src/apps/altcp_tls/altcp_tls_mbedtls.c ${PICO_LWIP_PATH}/src/apps/altcp_tls/altcp_tls_mbedtls_mem.c ${PICO_LWIP_PATH}/src/apps/snmp/snmpv3_mbedtls.c ) + # altcp_tls_mbedtls.c is not compatible with mbedtls 3.x so use a patched version until this is resolved + # See https://savannah.nongnu.org/patch/index.php?10448 + if (MBEDTLS_VERSION_MAJOR AND MBEDTLS_VERSION_MAJOR GREATER_EQUAL 3) + target_sources(pico_lwip_mbedtls INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/altcp_tls_mbedtls.c + ) + target_include_directories(pico_lwip_mbedtls INTERFACE + ${PICO_LWIP_PATH}/src/apps/altcp_tls + ) + else() + target_sources(pico_lwip_mbedtls INTERFACE + ${PICO_LWIP_PATH}/src/apps/altcp_tls/altcp_tls_mbedtls.c + ) + endif() + # MQTT client files pico_add_library(pico_lwip_mqtt NOFLAG) target_sources(pico_lwip_mqtt INTERFACE @@ -299,8 +315,7 @@ if (EXISTS ${PICO_LWIP_PATH}/${LWIP_TEST_PATH}) pico_mirrored_target_link_libraries(pico_lwip_freertos INTERFACE pico_async_context_base pico_lwip - pico_lwip_contrib_freertos - pico_rand) + pico_lwip_contrib_freertos) pico_add_subdirectory(tools) pico_promote_common_scope_vars() diff --git a/src/rp2_common/pico_lwip/altcp_tls_mbedtls.c b/src/rp2_common/pico_lwip/altcp_tls_mbedtls.c new file mode 100644 index 000000000..669379db9 --- /dev/null +++ b/src/rp2_common/pico_lwip/altcp_tls_mbedtls.c @@ -0,0 +1,1401 @@ +/** + * @file + * Application layered TCP/TLS connection API (to be used from TCPIP thread) + * + * This file provides a TLS layer using mbedTLS + * + * This version is currently compatible with the 2.x.x branch (current LTS). + */ + +/* + * Copyright (c) 2017 Simon Goldschmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + * Watch out: + * - 'sent' is always called with len==0 to the upper layer. This is because keeping + * track of the ratio of application data and TLS overhead would be too much. + * + * Mandatory security-related configuration: + * - ensure to add at least one strong entropy source to your mbedtls port (implement + * mbedtls_platform_entropy_poll or mbedtls_hardware_poll providing strong entropy) + * - define ALTCP_MBEDTLS_ENTROPY_PTR and ALTCP_MBEDTLS_ENTROPY_LEN to something providing + * GOOD custom entropy + * + * Missing things / @todo: + * - some unhandled/untested things might be caught by LWIP_ASSERTs... + */ + +#include "lwip/opt.h" +#include "lwip/sys.h" + +#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/apps/altcp_tls_mbedtls_opts.h" + +#if LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS + +#include "lwip/altcp.h" +#include "lwip/altcp_tls.h" +#include "lwip/priv/altcp_priv.h" + +#include "altcp_tls_mbedtls_structs.h" +#include "altcp_tls_mbedtls_mem.h" + +/* @todo: which includes are really needed? */ +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#if MBEDTLS_VERSION_MAJOR < 3 +#include "mbedtls/certs.h" +#endif +#include "mbedtls/x509.h" +#include "mbedtls/ssl.h" +#include "mbedtls/net_sockets.h" +#include "mbedtls/error.h" +#include "mbedtls/debug.h" +#include "mbedtls/platform.h" +#include "mbedtls/memory_buffer_alloc.h" +#include "mbedtls/ssl_cache.h" +#include "mbedtls/ssl_ticket.h" + +#if MBEDTLS_VERSION_MAJOR < 3 +#include "mbedtls/ssl_internal.h" /* to call mbedtls_flush_output after ERR_MEM */ +#else +int mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl); +size_t mbedtls_ssl_get_output_max_frag_len(const mbedtls_ssl_context *ssl); +#endif + +#include + +#ifndef ALTCP_MBEDTLS_ENTROPY_PTR +#define ALTCP_MBEDTLS_ENTROPY_PTR NULL +#endif +#ifndef ALTCP_MBEDTLS_ENTROPY_LEN +#define ALTCP_MBEDTLS_ENTROPY_LEN 0 +#endif +#ifndef ALTCP_MBEDTLS_RNG_FN +#define ALTCP_MBEDTLS_RNG_FN mbedtls_entropy_func +#endif + +/* Variable prototype, the actual declaration is at the end of this file + since it contains pointers to static functions declared here */ +extern const struct altcp_functions altcp_mbedtls_functions; + +/** Our global mbedTLS configuration (server-specific, not connection-specific) */ +struct altcp_tls_config { + mbedtls_ssl_config conf; + mbedtls_x509_crt *cert; + mbedtls_pk_context *pkey; + u8_t cert_count; + u8_t cert_max; + u8_t pkey_count; + u8_t pkey_max; + mbedtls_x509_crt *ca; +#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE + /** Inter-connection cache for fast connection startup */ + struct mbedtls_ssl_cache_context cache; +#endif +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && ALTCP_MBEDTLS_USE_SESSION_TICKETS + mbedtls_ssl_ticket_context ticket_ctx; +#endif +}; + +/** Entropy and random generator are shared by all mbedTLS configuration */ +struct altcp_tls_entropy_rng { + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + int ref; +}; +static struct altcp_tls_entropy_rng *altcp_tls_entropy_rng; + +static err_t altcp_mbedtls_lower_recv(void *arg, struct altcp_pcb *inner_conn, struct pbuf *p, err_t err); +static err_t altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn); +static err_t altcp_mbedtls_lower_recv_process(struct altcp_pcb *conn, altcp_mbedtls_state_t *state); +static err_t altcp_mbedtls_handle_rx_appldata(struct altcp_pcb *conn, altcp_mbedtls_state_t *state); +static int altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size); + + +static void +altcp_mbedtls_flush_output(altcp_mbedtls_state_t* state) +{ + int flushed = mbedtls_ssl_flush_output(&state->ssl_context); + if (flushed) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_flush_output failed: %d\n", flushed)); + } +} + +/* callback functions from inner/lower connection: */ + +/** Accept callback from lower connection (i.e. TCP) + * Allocate one of our structures, assign it to the new connection's 'state' and + * call the new connection's 'accepted' callback. If that succeeds, we wait + * to receive connection setup handshake bytes from the client. + */ +static err_t +altcp_mbedtls_lower_accept(void *arg, struct altcp_pcb *accepted_conn, err_t err) +{ + struct altcp_pcb *listen_conn = (struct altcp_pcb *)arg; + if (listen_conn && listen_conn->state && listen_conn->accept) { + err_t setup_err; + altcp_mbedtls_state_t *listen_state = (altcp_mbedtls_state_t *)listen_conn->state; + /* create a new altcp_conn to pass to the next 'accept' callback */ + struct altcp_pcb *new_conn = altcp_alloc(); + if (new_conn == NULL) { + return ERR_MEM; + } + setup_err = altcp_mbedtls_setup(listen_state->conf, new_conn, accepted_conn); + if (setup_err != ERR_OK) { + altcp_free(new_conn); + return setup_err; + } + return listen_conn->accept(listen_conn->arg, new_conn, err); + } + return ERR_ARG; +} + +/** Connected callback from lower connection (i.e. TCP). + * Not really implemented/tested yet... + */ +static err_t +altcp_mbedtls_lower_connected(void *arg, struct altcp_pcb *inner_conn, err_t err) +{ + struct altcp_pcb *conn = (struct altcp_pcb *)arg; + LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */ + if (conn && conn->state) { + altcp_mbedtls_state_t *state; + LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn); + /* upper connected is called when handshake is done */ + if (err != ERR_OK) { + if (conn->connected) { + return conn->connected(conn->arg, conn, err); + } + } + state = (altcp_mbedtls_state_t *)conn->state; + /* ensure overhead value is valid before first write */ + state->overhead_bytes_adjust = 0; + return altcp_mbedtls_lower_recv_process(conn, state); + } + return ERR_VAL; +} + +/* Call recved for possibly more than an u16_t */ +static void +altcp_mbedtls_lower_recved(struct altcp_pcb *inner_conn, int recvd_cnt) +{ + while (recvd_cnt > 0) { + u16_t recvd_part = (u16_t)LWIP_MIN(recvd_cnt, 0xFFFF); + altcp_recved(inner_conn, recvd_part); + recvd_cnt -= recvd_part; + } +} + +/** Recv callback from lower connection (i.e. TCP) + * This one mainly differs between connection setup/handshake (data is fed into mbedTLS only) + * and application phase (data is decoded by mbedTLS and passed on to the application). + */ +static err_t +altcp_mbedtls_lower_recv(void *arg, struct altcp_pcb *inner_conn, struct pbuf *p, err_t err) +{ + altcp_mbedtls_state_t *state; + struct altcp_pcb *conn = (struct altcp_pcb *)arg; + + LWIP_ASSERT("no err expected", err == ERR_OK); + LWIP_UNUSED_ARG(err); + + if (!conn) { + /* no connection given as arg? should not happen, but prevent pbuf/conn leaks */ + if (p != NULL) { + pbuf_free(p); + } + altcp_close(inner_conn); + return ERR_CLSD; + } + state = (altcp_mbedtls_state_t *)conn->state; + LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn); + if (!state) { + /* already closed */ + if (p != NULL) { + pbuf_free(p); + } + altcp_close(inner_conn); + return ERR_CLSD; + } + + /* handle NULL pbuf (inner connection closed) */ + if (p == NULL) { + /* remote host sent FIN, remember this (SSL state is destroyed + when both sides are closed only!) */ + if ((state->flags & (ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE | ALTCP_MBEDTLS_FLAGS_UPPER_CALLED)) == + (ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE | ALTCP_MBEDTLS_FLAGS_UPPER_CALLED)) { + /* need to notify upper layer (e.g. 'accept' called or 'connect' succeeded) */ + if ((state->rx != NULL) || (state->rx_app != NULL)) { + state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED; + /* this is a normal close (FIN) but we have unprocessed data, so delay the FIN */ + altcp_mbedtls_handle_rx_appldata(conn, state); + return ERR_OK; + } + state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSED; + if (conn->recv) { + return conn->recv(conn->arg, conn, NULL, ERR_OK); + } + } else { + /* before connection setup is done: call 'err' */ + if (conn->err) { + conn->err(conn->arg, ERR_ABRT); + } + altcp_close(conn); + } + return ERR_OK; + } + + /* If we come here, the connection is in good state (handshake phase or application data phase). + Queue up the pbuf for processing as handshake data or application data. */ + if (state->rx == NULL) { + state->rx = p; + } else { + LWIP_ASSERT("rx pbuf overflow", (int)p->tot_len + (int)p->len <= 0xFFFF); + pbuf_cat(state->rx, p); + } + return altcp_mbedtls_lower_recv_process(conn, state); +} + +static err_t +altcp_mbedtls_lower_recv_process(struct altcp_pcb *conn, altcp_mbedtls_state_t *state) +{ + if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) { + /* handle connection setup (handshake not done) */ + int ret = mbedtls_ssl_handshake(&state->ssl_context); + /* try to send data... */ + altcp_output(conn->inner_conn); + if (state->bio_bytes_read) { + /* acknowledge all bytes read */ + altcp_mbedtls_lower_recved(conn->inner_conn, state->bio_bytes_read); + state->bio_bytes_read = 0; + } + + if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + /* handshake not done, wait for more recv calls */ + LWIP_ASSERT("in this state, the rx chain should be empty", state->rx == NULL); + return ERR_OK; + } + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_handshake failed: %d\n", ret)); + /* handshake failed, connection has to be closed */ + if (conn->err) { + conn->err(conn->arg, ERR_CLSD); + } + + if (altcp_close(conn) != ERR_OK) { + altcp_abort(conn); + } + return ERR_OK; + } + /* If we come here, handshake succeeded. */ + LWIP_ASSERT("state", state->bio_bytes_read == 0); + LWIP_ASSERT("state", state->bio_bytes_appl == 0); + state->flags |= ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE; + /* issue "connect" callback" to upper connection (this can only happen for active open) */ + if (conn->connected) { + err_t err; + err = conn->connected(conn->arg, conn, ERR_OK); + if (err != ERR_OK) { + return err; + } + } + if (state->rx == NULL) { + return ERR_OK; + } + } + /* handle application data */ + return altcp_mbedtls_handle_rx_appldata(conn, state); +} + +/* Pass queued decoded rx data to application */ +static err_t +altcp_mbedtls_pass_rx_data(struct altcp_pcb *conn, altcp_mbedtls_state_t *state) +{ + err_t err; + struct pbuf *buf; + LWIP_ASSERT("conn != NULL", conn != NULL); + LWIP_ASSERT("state != NULL", state != NULL); + buf = state->rx_app; + if (buf) { + state->rx_app = NULL; + if (conn->recv) { + u16_t tot_len = buf->tot_len; + /* this needs to be increased first because the 'recved' call may come nested */ + state->rx_passed_unrecved += tot_len; + state->flags |= ALTCP_MBEDTLS_FLAGS_UPPER_CALLED; + err = conn->recv(conn->arg, conn, buf, ERR_OK); + if (err != ERR_OK) { + if (err == ERR_ABRT) { + return ERR_ABRT; + } + /* not received, leave the pbuf(s) queued (and decrease 'unrecved' again) */ + LWIP_ASSERT("state == conn->state", state == conn->state); + state->rx_app = buf; + state->rx_passed_unrecved -= tot_len; + LWIP_ASSERT("state->rx_passed_unrecved >= 0", state->rx_passed_unrecved >= 0); + if (state->rx_passed_unrecved < 0) { + state->rx_passed_unrecved = 0; + } + return err; + } + } else { + pbuf_free(buf); + } + } else if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) == + ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) { + state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSED; + if (conn->recv) { + return conn->recv(conn->arg, conn, NULL, ERR_OK); + } + } + + /* application may have close the connection */ + if (conn->state != state) { + /* return error code to ensure altcp_mbedtls_handle_rx_appldata() exits the loop */ + return ERR_ARG; + } + return ERR_OK; +} + +/* Helper function that processes rx application data stored in rx pbuf chain */ +static err_t +altcp_mbedtls_handle_rx_appldata(struct altcp_pcb *conn, altcp_mbedtls_state_t *state) +{ + int ret; + LWIP_ASSERT("state != NULL", state != NULL); + if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) { + /* handshake not done yet */ + return ERR_VAL; + } + do { + /* allocate a full-sized unchained PBUF_POOL: this is for RX! */ + struct pbuf *buf = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL); + if (buf == NULL) { + /* We're short on pbufs, try again later from 'poll' or 'recv' callbacks. + @todo: close on excessive allocation failures or leave this up to upper conn? */ + return ERR_OK; + } + + /* decrypt application data, this pulls encrypted RX data off state->rx pbuf chain */ + ret = mbedtls_ssl_read(&state->ssl_context, (unsigned char *)buf->payload, PBUF_POOL_BUFSIZE); + if (ret < 0) { + if (ret == MBEDTLS_ERR_SSL_CLIENT_RECONNECT) { + /* client is initiating a new connection using the same source port -> close connection or make handshake */ + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("new connection on same source port\n")); + LWIP_ASSERT("TODO: new connection on same source port, close this connection", 0); + } else if ((ret != MBEDTLS_ERR_SSL_WANT_READ) && (ret != MBEDTLS_ERR_SSL_WANT_WRITE)) { + if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("connection was closed gracefully\n")); + } else if (ret == MBEDTLS_ERR_NET_CONN_RESET) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("connection was reset by peer\n")); + } + pbuf_free(buf); + return ERR_OK; + } else { + pbuf_free(buf); + return ERR_OK; + } + pbuf_free(buf); + altcp_abort(conn); + return ERR_ABRT; + } else { + err_t err; + if (ret) { + LWIP_ASSERT("bogus receive length", ret <= (int)PBUF_POOL_BUFSIZE); + /* trim pool pbuf to actually decoded length */ + pbuf_realloc(buf, (u16_t)ret); + + state->bio_bytes_appl += ret; + if (mbedtls_ssl_get_bytes_avail(&state->ssl_context) == 0) { + /* Record is done, now we know the share between application and protocol bytes + and can adjust the RX window by the protocol bytes. + The rest is 'recved' by the application calling our 'recved' fn. */ + int overhead_bytes; + LWIP_ASSERT("bogus byte counts", state->bio_bytes_read > state->bio_bytes_appl); + overhead_bytes = state->bio_bytes_read - state->bio_bytes_appl; + altcp_mbedtls_lower_recved(conn->inner_conn, overhead_bytes); + state->bio_bytes_read = 0; + state->bio_bytes_appl = 0; + } + + if (state->rx_app == NULL) { + state->rx_app = buf; + } else { + pbuf_cat(state->rx_app, buf); + } + } else { + pbuf_free(buf); + buf = NULL; + } + err = altcp_mbedtls_pass_rx_data(conn, state); + if (err != ERR_OK) { + if (err == ERR_ABRT) { + /* recv callback needs to return this as the pcb is deallocated */ + return ERR_ABRT; + } + /* we hide all other errors as we retry feeding the pbuf to the app later */ + return ERR_OK; + } + } + } while (ret > 0); + return ERR_OK; +} + +/** Receive callback function called from mbedtls (set via mbedtls_ssl_set_bio) + * This function mainly copies data from pbufs and frees the pbufs after copying. + */ +static int +altcp_mbedtls_bio_recv(void *ctx, unsigned char *buf, size_t len) +{ + struct altcp_pcb *conn = (struct altcp_pcb *)ctx; + altcp_mbedtls_state_t *state; + struct pbuf *p; + u16_t ret; + u16_t copy_len; + err_t err; + + LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */ + if ((conn == NULL) || (conn->state == NULL)) { + return MBEDTLS_ERR_NET_INVALID_CONTEXT; + } + state = (altcp_mbedtls_state_t *)conn->state; + LWIP_ASSERT("state != NULL", state != NULL); + p = state->rx; + + /* @todo: return MBEDTLS_ERR_NET_CONN_RESET/MBEDTLS_ERR_NET_RECV_FAILED? */ + + if ((p == NULL) || ((p->len == 0) && (p->next == NULL))) { + if (p) { + pbuf_free(p); + } + state->rx = NULL; + if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) == + ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) { + /* close queued but not passed up yet */ + return 0; + } + return MBEDTLS_ERR_SSL_WANT_READ; + } + /* limit number of bytes again to copy from first pbuf in a chain only */ + copy_len = (u16_t)LWIP_MIN(len, p->len); + /* copy the data */ + ret = pbuf_copy_partial(p, buf, copy_len, 0); + LWIP_ASSERT("ret == copy_len", ret == copy_len); + /* hide the copied bytes from the pbuf */ + err = pbuf_remove_header(p, ret); + LWIP_ASSERT("error", err == ERR_OK); + if (p->len == 0) { + /* the first pbuf has been fully read, free it */ + state->rx = p->next; + p->next = NULL; + pbuf_free(p); + } + + state->bio_bytes_read += (int)ret; + return ret; +} + +/** Sent callback from lower connection (i.e. TCP) + * This only informs the upper layer the number of ACKed bytes. + * This now take care of TLS added bytes so application receive + * correct ACKed bytes. + */ +static err_t +altcp_mbedtls_lower_sent(void *arg, struct altcp_pcb *inner_conn, u16_t len) +{ + struct altcp_pcb *conn = (struct altcp_pcb *)arg; + LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */ + if (conn) { + int overhead; + u16_t app_len; + altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state; + LWIP_ASSERT("state", state != NULL); + LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn); + /* calculate TLS overhead part to not send it to application */ + overhead = state->overhead_bytes_adjust + state->ssl_context.out_left; + if ((unsigned)overhead > len) { + overhead = len; + } + /* remove ACKed bytes from overhead adjust counter */ + state->overhead_bytes_adjust -= len; + /* try to send more if we failed before (may increase overhead adjust counter) */ + altcp_mbedtls_flush_output(state); + /* remove calculated overhead from ACKed bytes len */ + app_len = len - (u16_t)overhead; + /* update application write counter and inform application */ + if (app_len) { + state->overhead_bytes_adjust += app_len; + if (conn->sent) + return conn->sent(conn->arg, conn, app_len); + } + } + return ERR_OK; +} + +/** Poll callback from lower connection (i.e. TCP) + * Just pass this on to the application. + * @todo: retry sending? + */ +static err_t +altcp_mbedtls_lower_poll(void *arg, struct altcp_pcb *inner_conn) +{ + struct altcp_pcb *conn = (struct altcp_pcb *)arg; + LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */ + if (conn) { + LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn); + /* check if there's unreceived rx data */ + if (conn->state) { + altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state; + /* try to send more if we failed before */ + altcp_mbedtls_flush_output(state); + if (altcp_mbedtls_handle_rx_appldata(conn, state) == ERR_ABRT) { + return ERR_ABRT; + } + } + if (conn->poll) { + return conn->poll(conn->arg, conn); + } + } + return ERR_OK; +} + +static void +altcp_mbedtls_lower_err(void *arg, err_t err) +{ + struct altcp_pcb *conn = (struct altcp_pcb *)arg; + if (conn) { + conn->inner_conn = NULL; /* already freed */ + if (conn->err) { + conn->err(conn->arg, err); + } + altcp_free(conn); + } +} + +/* setup functions */ + +static void +altcp_mbedtls_remove_callbacks(struct altcp_pcb *inner_conn) +{ + altcp_arg(inner_conn, NULL); + altcp_recv(inner_conn, NULL); + altcp_sent(inner_conn, NULL); + altcp_err(inner_conn, NULL); + altcp_poll(inner_conn, NULL, inner_conn->pollinterval); +} + +static void +altcp_mbedtls_setup_callbacks(struct altcp_pcb *conn, struct altcp_pcb *inner_conn) +{ + altcp_arg(inner_conn, conn); + altcp_recv(inner_conn, altcp_mbedtls_lower_recv); + altcp_sent(inner_conn, altcp_mbedtls_lower_sent); + altcp_err(inner_conn, altcp_mbedtls_lower_err); + /* tcp_poll is set when interval is set by application */ + /* listen is set totally different :-) */ +} + +static err_t +altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn) +{ + int ret; + struct altcp_tls_config *config = (struct altcp_tls_config *)conf; + altcp_mbedtls_state_t *state; + if (!conf) { + return ERR_ARG; + } + LWIP_ASSERT("invalid inner_conn", conn != inner_conn); + + /* allocate mbedtls context */ + state = altcp_mbedtls_alloc(conf); + if (state == NULL) { + return ERR_MEM; + } + /* initialize mbedtls context: */ + mbedtls_ssl_init(&state->ssl_context); + ret = mbedtls_ssl_setup(&state->ssl_context, &config->conf); + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_setup failed\n")); + /* @todo: convert 'ret' to err_t */ + altcp_mbedtls_free(conf, state); + return ERR_MEM; + } + /* tell mbedtls about our I/O functions */ + mbedtls_ssl_set_bio(&state->ssl_context, conn, altcp_mbedtls_bio_send, altcp_mbedtls_bio_recv, NULL); + + altcp_mbedtls_setup_callbacks(conn, inner_conn); + conn->inner_conn = inner_conn; + conn->fns = &altcp_mbedtls_functions; + conn->state = state; + return ERR_OK; +} + +struct altcp_pcb * +altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb) +{ + struct altcp_pcb *ret; + if (inner_pcb == NULL) { + return NULL; + } + ret = altcp_alloc(); + if (ret != NULL) { + if (altcp_mbedtls_setup(config, ret, inner_pcb) != ERR_OK) { + altcp_free(ret); + return NULL; + } + } + return ret; +} + +void +altcp_tls_init_session(struct altcp_tls_session *session) +{ + if (session) + mbedtls_ssl_session_init(&session->data); +} + +err_t +altcp_tls_get_session(struct altcp_pcb *conn, struct altcp_tls_session *session) +{ + if (session && conn && conn->state) { + altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state; + int ret = mbedtls_ssl_get_session(&state->ssl_context, &session->data); + return ret < 0 ? ERR_VAL : ERR_OK; + } + return ERR_ARG; +} + +err_t +altcp_tls_set_session(struct altcp_pcb *conn, struct altcp_tls_session *session) +{ + if (session && conn && conn->state) { + altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state; + int ret = -1; + if (session->data.start) + ret = mbedtls_ssl_set_session(&state->ssl_context, &session->data); + return ret < 0 ? ERR_VAL : ERR_OK; + } + return ERR_ARG; +} + +void +altcp_tls_free_session(struct altcp_tls_session *session) +{ + if (session) + mbedtls_ssl_session_free(&session->data); +} + +void * +altcp_tls_context(struct altcp_pcb *conn) +{ + if (conn && conn->state) { + altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state; + return &state->ssl_context; + } + return NULL; +} + +#if ALTCP_MBEDTLS_LIB_DEBUG != LWIP_DBG_OFF +static void +altcp_mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) +{ + LWIP_UNUSED_ARG(ctx); + LWIP_UNUSED_ARG(file); + LWIP_UNUSED_ARG(line); + LWIP_UNUSED_ARG(str); + + if (level >= ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN) { + LWIP_DEBUGF(ALTCP_MBEDTLS_LIB_DEBUG, ("%s:%04d: %s\n", file, line, str)); + } +} +#endif + +static err_t +altcp_mbedtls_ref_entropy(void) +{ + LWIP_ASSERT_CORE_LOCKED(); + + if (!altcp_tls_entropy_rng) { + altcp_tls_entropy_rng = (struct altcp_tls_entropy_rng *)altcp_mbedtls_alloc_config(sizeof(struct altcp_tls_entropy_rng)); + if (altcp_tls_entropy_rng) { + int ret; + altcp_tls_entropy_rng->ref = 1; + mbedtls_entropy_init(&altcp_tls_entropy_rng->entropy); + mbedtls_ctr_drbg_init(&altcp_tls_entropy_rng->ctr_drbg); + /* Seed the RNG, only once */ + ret = mbedtls_ctr_drbg_seed(&altcp_tls_entropy_rng->ctr_drbg, + ALTCP_MBEDTLS_RNG_FN, &altcp_tls_entropy_rng->entropy, + ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN); + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret)); + mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg); + mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy); + altcp_mbedtls_free_config(altcp_tls_entropy_rng); + altcp_tls_entropy_rng = NULL; + return ERR_ARG; + } + } else { + return ERR_MEM; + } + } else { + altcp_tls_entropy_rng->ref++; + } + return ERR_OK; +} + +static void +altcp_mbedtls_unref_entropy(void) +{ + LWIP_ASSERT_CORE_LOCKED(); + + if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref) { + altcp_tls_entropy_rng->ref--; + } +} + +/** Create new TLS configuration + * ATTENTION: Server certificate and private key have to be added outside this function! + */ +static struct altcp_tls_config * +altcp_tls_create_config(int is_server, u8_t cert_count, u8_t pkey_count, int have_ca) +{ + size_t sz; + int ret; + struct altcp_tls_config *conf; + mbedtls_x509_crt *mem; + +#if MBEDTLS_VERSION_MAJOR < 3 + if (TCP_WND < MBEDTLS_SSL_MAX_CONTENT_LEN) { +#else + if (TCP_WND < MBEDTLS_SSL_IN_CONTENT_LEN) { +#endif + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG|LWIP_DBG_LEVEL_SERIOUS, + ("altcp_tls: TCP_WND is smaller than the RX decrypion buffer, connection RX might stall!\n")); + } + + altcp_mbedtls_mem_init(); + + sz = sizeof(struct altcp_tls_config); + if (cert_count > 0) { + sz += (cert_count * sizeof(mbedtls_x509_crt)); + } + if (have_ca) { + sz += sizeof(mbedtls_x509_crt); + } + if (pkey_count > 0) { + sz += (pkey_count * sizeof(mbedtls_pk_context)); + } + + conf = (struct altcp_tls_config *)altcp_mbedtls_alloc_config(sz); + if (conf == NULL) { + return NULL; + } + conf->cert_max = cert_count; + mem = (mbedtls_x509_crt *)(conf + 1); + if (cert_count > 0) { + conf->cert = mem; + mem += cert_count; + } + if (have_ca) { + conf->ca = mem; + mem++; + } + conf->pkey_max = pkey_count; + if (pkey_count > 0) { + conf->pkey = (mbedtls_pk_context *)mem; + } + + mbedtls_ssl_config_init(&conf->conf); + + if (altcp_mbedtls_ref_entropy() != ERR_OK) { + altcp_mbedtls_free_config(conf); + return NULL; + } + + /* Setup ssl context (@todo: what's different for a client here? -> might better be done on listen/connect) */ + ret = mbedtls_ssl_config_defaults(&conf->conf, is_server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_config_defaults failed: %d\n", ret)); + altcp_mbedtls_unref_entropy(); + altcp_mbedtls_free_config(conf); + return NULL; + } + mbedtls_ssl_conf_authmode(&conf->conf, ALTCP_MBEDTLS_AUTHMODE); + + mbedtls_ssl_conf_rng(&conf->conf, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg); +#if ALTCP_MBEDTLS_LIB_DEBUG != LWIP_DBG_OFF + mbedtls_ssl_conf_dbg(&conf->conf, altcp_mbedtls_debug, stdout); +#endif +#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE + mbedtls_ssl_conf_session_cache(&conf->conf, &conf->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set); + mbedtls_ssl_cache_set_timeout(&conf->cache, ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS); + mbedtls_ssl_cache_set_max_entries(&conf->cache, ALTCP_MBEDTLS_SESSION_CACHE_SIZE); +#endif + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && ALTCP_MBEDTLS_USE_SESSION_TICKETS + mbedtls_ssl_ticket_init(&conf->ticket_ctx); + + ret = mbedtls_ssl_ticket_setup(&conf->ticket_ctx, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg, + ALTCP_MBEDTLS_SESSION_TICKET_CIPHER, ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS); + if (ret) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_ticket_setup failed: %d\n", ret)); + altcp_mbedtls_unref_entropy(); + altcp_mbedtls_free_config(conf); + return NULL; + } + + mbedtls_ssl_conf_session_tickets_cb(&conf->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse, + &conf->ticket_ctx); +#endif + + return conf; +} + +struct altcp_tls_config *altcp_tls_create_config_server(u8_t cert_count) +{ + struct altcp_tls_config *conf = altcp_tls_create_config(1, cert_count, cert_count, 0); + if (conf == NULL) { + return NULL; + } + + mbedtls_ssl_conf_ca_chain(&conf->conf, NULL, NULL); + return conf; +} + +err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config, + const u8_t *privkey, size_t privkey_len, + const u8_t *privkey_pass, size_t privkey_pass_len, + const u8_t *cert, size_t cert_len) +{ + int ret; + mbedtls_x509_crt *srvcert; + mbedtls_pk_context *pkey; + + if (config->cert_count >= config->cert_max) { + return ERR_MEM; + } + if (config->pkey_count >= config->pkey_max) { + return ERR_MEM; + } + + srvcert = config->cert + config->cert_count; + mbedtls_x509_crt_init(srvcert); + + pkey = config->pkey + config->pkey_count; + mbedtls_pk_init(pkey); + + /* Load the certificates and private key */ + ret = mbedtls_x509_crt_parse(srvcert, cert, cert_len); + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d\n", ret)); + return ERR_VAL; + } + +#if MBEDTLS_VERSION_MAJOR < 3 + ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len); +#else + ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len, NULL, NULL); +#endif + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret)); + mbedtls_x509_crt_free(srvcert); + return ERR_VAL; + } + + ret = mbedtls_ssl_conf_own_cert(&config->conf, srvcert, pkey); + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d\n", ret)); + mbedtls_x509_crt_free(srvcert); + mbedtls_pk_free(pkey); + return ERR_VAL; + } + + config->cert_count++; + config->pkey_count++; + return ERR_OK; +} + +/** Create new TLS configuration + * This is a suboptimal version that gets the encrypted private key and its password, + * as well as the server certificate. + */ +struct altcp_tls_config * +altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len, + const u8_t *privkey_pass, size_t privkey_pass_len, + const u8_t *cert, size_t cert_len) +{ + struct altcp_tls_config *conf = altcp_tls_create_config_server(1); + if (conf == NULL) { + return NULL; + } + + if (altcp_tls_config_server_add_privkey_cert(conf, privkey, privkey_len, + privkey_pass, privkey_pass_len, cert, cert_len) != ERR_OK) { + altcp_tls_free_config(conf); + return NULL; + } + + return conf; +} + +static struct altcp_tls_config * +altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth) +{ + int ret; + struct altcp_tls_config *conf = altcp_tls_create_config(0, (is_2wayauth) ? 1 : 0, (is_2wayauth) ? 1 : 0, ca != NULL); + if (conf == NULL) { + return NULL; + } + + /* Initialize the CA certificate if provided + * CA certificate is optional (to save memory) but recommended for production environment + * Without CA certificate, connection will be prone to man-in-the-middle attacks */ + if (ca) { + mbedtls_x509_crt_init(conf->ca); + ret = mbedtls_x509_crt_parse(conf->ca, ca, ca_len); + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse ca failed: %d 0x%x\n", ret, -1*ret)); + altcp_tls_free_config(conf); + return NULL; + } + + mbedtls_ssl_conf_ca_chain(&conf->conf, conf->ca, NULL); + } + return conf; +} + +struct altcp_tls_config * +altcp_tls_create_config_client(const u8_t *ca, size_t ca_len) +{ + return altcp_tls_create_config_client_common(ca, ca_len, 0); +} + +struct altcp_tls_config * +altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_t *privkey, size_t privkey_len, + const u8_t *privkey_pass, size_t privkey_pass_len, + const u8_t *cert, size_t cert_len) +{ + int ret; + struct altcp_tls_config *conf; + + if (!cert || !privkey) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("altcp_tls_create_config_client_2wayauth: certificate and priv key required\n")); + return NULL; + } + + conf = altcp_tls_create_config_client_common(ca, ca_len, 1); + if (conf == NULL) { + return NULL; + } + + /* Initialize the client certificate and corresponding private key */ + mbedtls_x509_crt_init(conf->cert); + ret = mbedtls_x509_crt_parse(conf->cert, cert, cert_len); + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse cert failed: %d 0x%x\n", ret, -1*ret)); + altcp_tls_free_config(conf); + return NULL; + } + + mbedtls_pk_init(conf->pkey); +#if MBEDTLS_VERSION_MAJOR < 3 + ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len); +#else + ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len, NULL, NULL); +#endif + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x\n", ret, -1*ret)); + altcp_tls_free_config(conf); + return NULL; + } + + ret = mbedtls_ssl_conf_own_cert(&conf->conf, conf->cert, conf->pkey); + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d 0x%x\n", ret, -1*ret)); + altcp_tls_free_config(conf); + return NULL; + } + + return conf; +} + +int +altcp_tls_configure_alpn_protocols(struct altcp_tls_config *conf, const char **protos) +{ +#if defined(MBEDTLS_SSL_ALPN) + int ret = mbedtls_ssl_conf_alpn_protocols(&conf->conf, protos); + if (ret != 0) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_alpn_protocols failed: %d\n", ret)); + } + + return ret; +#else + (void)conf; + (void)protos; + return -1; +#endif +} + +void +altcp_tls_free_config(struct altcp_tls_config *conf) +{ + if (conf->pkey) { + mbedtls_pk_free(conf->pkey); + } + if (conf->cert) { + mbedtls_x509_crt_free(conf->cert); + } + if (conf->ca) { + mbedtls_x509_crt_free(conf->ca); + } + mbedtls_ssl_config_free(&conf->conf); + altcp_mbedtls_free_config(conf); + altcp_mbedtls_unref_entropy(); +} + +void +altcp_tls_free_entropy(void) +{ + LWIP_ASSERT_CORE_LOCKED(); + + if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref == 0) { + mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg); + mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy); + altcp_mbedtls_free_config(altcp_tls_entropy_rng); + altcp_tls_entropy_rng = NULL; + } +} + +/* "virtual" functions */ +static void +altcp_mbedtls_set_poll(struct altcp_pcb *conn, u8_t interval) +{ + if (conn != NULL) { + altcp_poll(conn->inner_conn, altcp_mbedtls_lower_poll, interval); + } +} + +static void +altcp_mbedtls_recved(struct altcp_pcb *conn, u16_t len) +{ + u16_t lower_recved; + altcp_mbedtls_state_t *state; + if (conn == NULL) { + return; + } + state = (altcp_mbedtls_state_t *)conn->state; + if (state == NULL) { + return; + } + if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) { + return; + } + lower_recved = len; + if (lower_recved > state->rx_passed_unrecved) { + LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("bogus recved count (len > state->rx_passed_unrecved / %d / %d)\n", + len, state->rx_passed_unrecved)); + lower_recved = (u16_t)state->rx_passed_unrecved; + } + state->rx_passed_unrecved -= lower_recved; + + altcp_recved(conn->inner_conn, lower_recved); +} + +static err_t +altcp_mbedtls_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected) +{ + if (conn == NULL) { + return ERR_VAL; + } + conn->connected = connected; + return altcp_connect(conn->inner_conn, ipaddr, port, altcp_mbedtls_lower_connected); +} + +static struct altcp_pcb * +altcp_mbedtls_listen(struct altcp_pcb *conn, u8_t backlog, err_t *err) +{ + struct altcp_pcb *lpcb; + if (conn == NULL) { + return NULL; + } + lpcb = altcp_listen_with_backlog_and_err(conn->inner_conn, backlog, err); + if (lpcb != NULL) { + altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state; + /* Free members of the ssl context (not used on listening pcb). This + includes freeing input/output buffers, so saves ~32KByte by default */ + mbedtls_ssl_free(&state->ssl_context); + + conn->inner_conn = lpcb; + altcp_accept(lpcb, altcp_mbedtls_lower_accept); + return conn; + } + return NULL; +} + +static void +altcp_mbedtls_abort(struct altcp_pcb *conn) +{ + if (conn != NULL) { + altcp_abort(conn->inner_conn); + } +} + +static err_t +altcp_mbedtls_close(struct altcp_pcb *conn) +{ + struct altcp_pcb *inner_conn; + if (conn == NULL) { + return ERR_VAL; + } + inner_conn = conn->inner_conn; + if (inner_conn) { + err_t err; + altcp_poll_fn oldpoll = inner_conn->poll; + altcp_mbedtls_remove_callbacks(conn->inner_conn); + err = altcp_close(conn->inner_conn); + if (err != ERR_OK) { + /* not closed, set up all callbacks again */ + altcp_mbedtls_setup_callbacks(conn, inner_conn); + /* poll callback is not included in the above */ + altcp_poll(inner_conn, oldpoll, inner_conn->pollinterval); + return err; + } + conn->inner_conn = NULL; + } + altcp_free(conn); + return ERR_OK; +} + +/** Allow caller of altcp_write() to limit to negotiated chunk size + * or remaining sndbuf space of inner_conn. + */ +static u16_t +altcp_mbedtls_sndbuf(struct altcp_pcb *conn) +{ + if (conn) { + altcp_mbedtls_state_t *state; + state = (altcp_mbedtls_state_t*)conn->state; + if (!state || !(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) { + return 0; + } + if (conn->inner_conn) { + u16_t sndbuf = altcp_sndbuf(conn->inner_conn); + /* Take care of record header, IV, AuthTag */ + int ssl_expan = mbedtls_ssl_get_record_expansion(&state->ssl_context); + if (ssl_expan > 0) { + size_t ssl_added = (u16_t)LWIP_MIN(ssl_expan, 0xFFFF); + /* internal sndbuf smaller than our offset */ + if (ssl_added < sndbuf) { + size_t max_len = 0xFFFF; + size_t ret; +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + /* @todo: adjust ssl_added to real value related to negotiated cipher */ +#if MBEDTLS_VERSION_MAJOR < 3 + size_t max_frag_len = mbedtls_ssl_get_max_frag_len(&state->ssl_context); +#else + size_t max_frag_len = mbedtls_ssl_get_output_max_frag_len(&state->ssl_context); +#endif + max_len = LWIP_MIN(max_frag_len, max_len); +#endif + /* Adjust sndbuf of inner_conn with what added by SSL */ + ret = LWIP_MIN(sndbuf - ssl_added, max_len); + LWIP_ASSERT("sndbuf overflow", ret <= 0xFFFF); + return (u16_t)ret; + } + } + } + } + /* fallback: use sendbuf of the inner connection */ + return altcp_default_sndbuf(conn); +} + +/** Write data to a TLS connection. Calls into mbedTLS, which in turn calls into + * @ref altcp_mbedtls_bio_send() to send the encrypted data + */ +static err_t +altcp_mbedtls_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags) +{ + int ret; + altcp_mbedtls_state_t *state; + + LWIP_UNUSED_ARG(apiflags); + + if (conn == NULL) { + return ERR_VAL; + } + + state = (altcp_mbedtls_state_t *)conn->state; + if (state == NULL) { + /* @todo: which error? */ + return ERR_ARG; + } + if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) { + /* @todo: which error? */ + return ERR_VAL; + } + + /* HACK: if there is something left to send, try to flush it and only + allow sending more if this succeeded (this is a hack because neither + returning 0 nor MBEDTLS_ERR_SSL_WANT_WRITE worked for me) */ + if (state->ssl_context.out_left) { + altcp_mbedtls_flush_output(state); + if (state->ssl_context.out_left) { + return ERR_MEM; + } + } + ret = mbedtls_ssl_write(&state->ssl_context, (const unsigned char *)dataptr, len); + /* try to send data... */ + altcp_output(conn->inner_conn); + if (ret >= 0) { + if (ret == len) { + /* update application sent counter */ + state->overhead_bytes_adjust -= ret; + return ERR_OK; + } else { + /* @todo/@fixme: assumption: either everything sent or error */ + LWIP_ASSERT("ret <= 0", 0); + return ERR_MEM; + } + } else { + if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + /* @todo: convert error to err_t */ + return ERR_MEM; + } + LWIP_ASSERT("unhandled error", 0); + return ERR_VAL; + } +} + +/** Send callback function called from mbedtls (set via mbedtls_ssl_set_bio) + * This function is either called during handshake or when sending application + * data via @ref altcp_mbedtls_write (or altcp_write) + */ +static int +altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size) +{ + struct altcp_pcb *conn = (struct altcp_pcb *) ctx; + altcp_mbedtls_state_t *state; + int written = 0; + size_t size_left = size; + u8_t apiflags = TCP_WRITE_FLAG_COPY; + + LWIP_ASSERT("conn != NULL", conn != NULL); + if ((conn == NULL) || (conn->inner_conn == NULL)) { + return MBEDTLS_ERR_NET_INVALID_CONTEXT; + } + state = (altcp_mbedtls_state_t *)conn->state; + LWIP_ASSERT("state != NULL", state != NULL); + + while (size_left) { + u16_t write_len = (u16_t)LWIP_MIN(size_left, 0xFFFF); + err_t err = altcp_write(conn->inner_conn, (const void *)dataptr, write_len, apiflags); + if (err == ERR_OK) { + written += write_len; + size_left -= write_len; + state->overhead_bytes_adjust += write_len; + } else if (err == ERR_MEM) { + if (written) { + return written; + } + return 0; /* MBEDTLS_ERR_SSL_WANT_WRITE; */ + } else { + LWIP_ASSERT("tls_write, tcp_write: err != ERR MEM", 0); + /* @todo: return MBEDTLS_ERR_NET_CONN_RESET or MBEDTLS_ERR_NET_SEND_FAILED */ + return MBEDTLS_ERR_NET_SEND_FAILED; + } + } + return written; +} + +static u16_t +altcp_mbedtls_mss(struct altcp_pcb *conn) +{ + if (conn == NULL) { + return 0; + } + /* @todo: LWIP_MIN(mss, mbedtls_ssl_get_max_frag_len()) ? */ + return altcp_mss(conn->inner_conn); +} + +static void +altcp_mbedtls_dealloc(struct altcp_pcb *conn) +{ + /* clean up and free tls state */ + if (conn) { + altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state; + if (state) { + mbedtls_ssl_free(&state->ssl_context); + state->flags = 0; + if (state->rx) { + /* free leftover (unhandled) rx pbufs */ + pbuf_free(state->rx); + state->rx = NULL; + } + altcp_mbedtls_free(state->conf, state); + conn->state = NULL; + } + } +} + +const struct altcp_functions altcp_mbedtls_functions = { + altcp_mbedtls_set_poll, + altcp_mbedtls_recved, + altcp_default_bind, + altcp_mbedtls_connect, + altcp_mbedtls_listen, + altcp_mbedtls_abort, + altcp_mbedtls_close, + altcp_default_shutdown, + altcp_mbedtls_write, + altcp_default_output, + altcp_mbedtls_mss, + altcp_mbedtls_sndbuf, + altcp_default_sndqueuelen, + altcp_default_nagle_disable, + altcp_default_nagle_enable, + altcp_default_nagle_disabled, + altcp_default_setprio, + altcp_mbedtls_dealloc, + altcp_default_get_tcp_addrinfo, + altcp_default_get_ip, + altcp_default_get_port +#if LWIP_TCP_KEEPALIVE + , altcp_default_keepalive_disable + , altcp_default_keepalive_enable +#endif +#ifdef LWIP_DEBUG + , altcp_default_dbg_get_tcp_state +#endif +}; + +#endif /* LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS */ +#endif /* LWIP_ALTCP */ diff --git a/src/rp2_common/pico_lwip/doc.h b/src/rp2_common/pico_lwip/doc.h index 0825fabb6..bbf353387 100644 --- a/src/rp2_common/pico_lwip/doc.h +++ b/src/rp2_common/pico_lwip/doc.h @@ -44,3 +44,47 @@ * \ingroup pico_lwip * \brief lwIP compiler adapters. This is not included by default in \c \b pico_lwip in case you wish to implement your own. */ + +/** \defgroup pico_lwip_http pico_lwip_http + * \ingroup pico_lwip + * \brief LwIP HTTP client and server library + * + * This library enables you to make use of the LwIP HTTP client and server library + * + * \par LwIP HTTP server + * + * To make use of the LwIP HTTP server you need to provide the HTML that the server will return to the client. + * This is done by compiling the content directly into the executable. + * + * \par makefsdata + * + * LwIP provides a c-library tool `makefsdata` to compile your HTML into a source file for inclusion into your program. + * This is quite hard to use as you need to compile the tool as a native binary, then run the tool to generate a source file + * before compiling your code for the Pico device. + * + * \par pico_set_lwip_httpd_content + * + * To make this whole process easier, a python script `makefsdata.py` is provided to generate a source file for your HTML content. + * A CMake function `pico_set_lwip_httpd_content` takes care of running the `makefsdata.py` python script for you. + * To make use of this, specify the name of the source file as `pico_fsdata.inc` in `lwipopts.h`. + * + * \code + * #define HTTPD_FSDATA_FILE "pico_fsdata.inc" + * \endcode + * + * Then call the CMake function `pico_set_lwip_httpd_content` in your `CMakeLists.txt` to add your content to a library. + * Make sure you add this library to your executable by adding it to your target_link_libraries list. + * Here is an example from the httpd example in pico-examples. + * + * \code + * pico_add_library(pico_httpd_content NOFLAG) + * pico_set_lwip_httpd_content(pico_httpd_content INTERFACE + * ${CMAKE_CURRENT_LIST_DIR}/content/404.html + * ${CMAKE_CURRENT_LIST_DIR}/content/index.shtml + * ${CMAKE_CURRENT_LIST_DIR}/content/test.shtml + * ${CMAKE_CURRENT_LIST_DIR}/content/ledpass.shtml + * ${CMAKE_CURRENT_LIST_DIR}/content/ledfail.shtml + * ${CMAKE_CURRENT_LIST_DIR}/content/img/rpi.png + * ) + * \endcode + */ diff --git a/src/rp2_common/pico_lwip/lwip.BUILD b/src/rp2_common/pico_lwip/lwip.BUILD index c94b881c5..c76d42dc7 100644 --- a/src/rp2_common/pico_lwip/lwip.BUILD +++ b/src/rp2_common/pico_lwip/lwip.BUILD @@ -25,7 +25,15 @@ cc_library( deps = [ ":pico_lwip_headers", "@pico-sdk//bazel/config:PICO_LWIP_CONFIG", - ], + ] + # altcp_alloc.c *might* depend on mbedtls + + select({ + "@pico-sdk//bazel/constraint:pico_mbedtls_config_unset": [], + "//conditions:default": [ + "@pico-sdk//src/rp2_common/pico_mbedtls:pico_mbedtls_library", + ] + }) + , target_compatible_with = incompatible_with_config("@pico-sdk//bazel/constraint:pico_lwip_config_unset") ) @@ -138,15 +146,21 @@ cc_library( cc_library( name = "pico_lwip_mbedtls", srcs = [ - "src/apps/altcp_tls/altcp_tls_mbedtls.c", + # This source file has issues with mbedtls 3.x + # See https://savannah.nongnu.org/patch/index.php?10448 + #"src/apps/altcp_tls/altcp_tls_mbedtls.c", "src/apps/altcp_tls/altcp_tls_mbedtls_mem.c", "src/apps/snmp/snmpv3_mbedtls.c", ], - deps = [":pico_lwip_core"], + includes = ["src/apps/altcp_tls"], + deps = [ + ":pico_lwip_core", + "@pico-sdk//src/rp2_common/pico_mbedtls:pico_mbedtls_config" + ], ) cc_library( - name = "pico_lwip_mqttt", + name = "pico_lwip_mqtt", srcs = ["src/apps/mqtt/mqtt.c"], deps = [":pico_lwip_core"], ) diff --git a/src/rp2_common/pico_lwip/tools/CMakeLists.txt b/src/rp2_common/pico_lwip/tools/CMakeLists.txt index 1539ac00d..796075f39 100644 --- a/src/rp2_common/pico_lwip/tools/CMakeLists.txt +++ b/src/rp2_common/pico_lwip/tools/CMakeLists.txt @@ -1,5 +1,13 @@ -# Compile the http content into a source file "pico_fsdata.inc" in a format suitable for the lwip httpd server -# Pass the target library name library type and the list of httpd content +# pico_set_lwip_httpd_content(TARGET_LIB TARGET_TYPE HTTPD_FILES...) +# \ingroup\ pico_lwip +# \brief_nodesc\ Compile the http content into a source file for lwip. +# +# Compile the http content into a source file "pico_fsdata.inc" in a format suitable for the lwip httpd server. +# Pass the target library name, library type, and the list of httpd content files to compile. +# +# \param\ TARGET_LIB The target library name +# \param\ TARGET_TYPE The type of the target library +# \param\ HTTPD_FILES The list of httpd content files to compile function(pico_set_lwip_httpd_content TARGET_LIB TARGET_TYPE) find_package (Python3 REQUIRED COMPONENTS Interpreter) set(HTTPD_CONTENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") diff --git a/src/rp2_common/pico_lwip/tools/makefsdata.py b/src/rp2_common/pico_lwip/tools/makefsdata.py index 9ee0d88c1..e50c898c5 100755 --- a/src/rp2_common/pico_lwip/tools/makefsdata.py +++ b/src/rp2_common/pico_lwip/tools/makefsdata.py @@ -19,7 +19,7 @@ def process_file(input_dir, file): results = [] # Check content type - content_type, _ = mimetypes.guess_type(file) + content_type, content_encoding = mimetypes.guess_type(file) if content_type is None: content_type = "application/octet-stream" @@ -53,9 +53,15 @@ def process_file(input_dir, file): comment = f"\"Content-Length: {file_size}\" ({len(data)} chars)" results.append({'data': bytes(data, "utf-8"), 'comment': comment}); - # content type - data = f"Content-Type: {content_type}\r\n\r\n" - comment = f"\"Content-Type: {content_type}\" ({len(data)} chars)" + # content type and content encoding + content_type_header = f"Content-Type: {content_type}" + if content_encoding is None: + data = f"{content_type_header}\r\n\r\n" + comment = f"\"{content_type_header}\" ({len(data)} chars)" + else: + content_encoding_header = f"Content-Encoding: {content_encoding}" + data = f"{content_type_header}\r\n{content_encoding_header}\r\n\r\n" + comment = f"\"{content_type_header} {content_encoding_header}\" ({len(data)} chars)" results.append({'data': bytes(data, "utf-8"), 'comment': comment}); # file contents diff --git a/src/rp2_common/pico_mbedtls/BUILD.bazel b/src/rp2_common/pico_mbedtls/BUILD.bazel index c339941cd..843ae821e 100644 --- a/src/rp2_common/pico_mbedtls/BUILD.bazel +++ b/src/rp2_common/pico_mbedtls/BUILD.bazel @@ -2,6 +2,13 @@ load("//bazel:defs.bzl", "compatible_with_rp2") package(default_visibility = ["//visibility:public"]) +cc_library( + name = "pico_mbedtls_config", + includes = ["include"], + hdrs = ["include/pico_mbedtls_config.h"], + defines = ['MBEDTLS_CONFIG_FILE=\\"pico_mbedtls_config.h\\"'], +) + cc_library( name = "pico_mbedtls", srcs = ["pico_mbedtls.c"], @@ -9,9 +16,17 @@ cc_library( includes = ["include"], target_compatible_with = compatible_with_rp2(), deps = [ - "//bazel/config:PICO_MBEDTLS_LIB", + ":pico_mbedtls_library", + ":pico_mbedtls_config", "//src/rp2_common:pico_platform", "//src/rp2_common/pico_rand", - "//src/rp2_common/pico_sha256", - ], + ] + select({ + "//bazel/constraint:rp2350": [ "//src/rp2_common/pico_sha256" ], + "//conditions:default": [ ], + }), +) + +alias( + name = "pico_mbedtls_library", + actual = "@mbedtls//:pico_mbedtls_library", ) diff --git a/src/rp2_common/pico_mbedtls/CMakeLists.txt b/src/rp2_common/pico_mbedtls/CMakeLists.txt index 13976d6fb..608b457ea 100644 --- a/src/rp2_common/pico_mbedtls/CMakeLists.txt +++ b/src/rp2_common/pico_mbedtls/CMakeLists.txt @@ -1,3 +1,4 @@ +# PICO_CMAKE_CONFIG: PICO_MBEDTLS_PATH, Path to an alternative version of mbedtls overriding the version in pico-sdk/lib/mbedtls. Can be passed to cmake or set in your environment, type=string, group=pico_mbedtls if (DEFINED ENV{PICO_MBEDTLS_PATH} AND (NOT PICO_MBEDTLS_PATH)) set(PICO_MBEDTLS_PATH $ENV{PICO_MBEDTLS_PATH}) message("Using PICO_MBEDTLS_PATH from environment ('${PICO_MBEDTLS_PATH}')") @@ -5,7 +6,7 @@ endif() set(MBEDTLS_TEST_PATH "library/aes.c") if (NOT PICO_MBEDTLS_PATH) - set(PICO_MBEDTLS_PATH ${PROJECT_SOURCE_DIR}/lib/mbedtls) + set(PICO_MBEDTLS_PATH ${PICO_SDK_PATH}/lib/mbedtls) elseif (NOT EXISTS ${PICO_MBEDTLS_PATH}/${MBEDTLS_TEST_PATH}) message(WARNING "PICO_MBEDTLS_PATH specified but content not present.") endif() @@ -15,117 +16,168 @@ if (EXISTS ${PICO_MBEDTLS_PATH}/${MBEDTLS_TEST_PATH}) pico_register_common_scope_var(PICO_MBEDTLS_PATH) - set(src_crypto - aes.c - aesni.c - arc4.c - aria.c - asn1parse.c - asn1write.c - base64.c - bignum.c - blowfish.c - camellia.c - ccm.c - chacha20.c - chachapoly.c - cipher.c - cipher_wrap.c - constant_time.c - cmac.c - ctr_drbg.c - des.c - dhm.c - ecdh.c - ecdsa.c - ecjpake.c - ecp.c - ecp_curves.c - entropy.c - entropy_poll.c - error.c - gcm.c - havege.c - hkdf.c - hmac_drbg.c - md.c - md2.c - md4.c - md5.c - memory_buffer_alloc.c - mps_reader.c - mps_trace.c - nist_kw.c - oid.c - padlock.c - pem.c - pk.c - pk_wrap.c - pkcs12.c - pkcs5.c - pkparse.c - pkwrite.c - platform.c - platform_util.c - poly1305.c - psa_crypto.c - psa_crypto_aead.c - psa_crypto_cipher.c - psa_crypto_client.c - psa_crypto_driver_wrappers.c - psa_crypto_ecp.c - psa_crypto_hash.c - psa_crypto_mac.c - psa_crypto_rsa.c - psa_crypto_se.c - psa_crypto_slot_management.c - psa_crypto_storage.c - psa_its_file.c - ripemd160.c - rsa.c - rsa_internal.c - sha1.c - sha256.c - sha512.c - threading.c - timing.c - version.c - version_features.c - xtea.c - ) - list(TRANSFORM src_crypto PREPEND ${PICO_MBEDTLS_PATH}/library/) + # Support version 2.28.8 or 3.6.2 + if (NOT MBEDTLS_VERSION_MAJOR) + if (EXISTS ${PICO_MBEDTLS_PATH}/library/ssl_cli.c) + set(MBEDTLS_VERSION_MAJOR 2) + elseif (EXISTS ${PICO_MBEDTLS_PATH}/library/ssl_client.c) + set(MBEDTLS_VERSION_MAJOR 3) + else() + message(WARNING "Cannot determine the version of mbedtls") + endif() + pico_register_common_scope_var(MBEDTLS_VERSION_MAJOR) + endif() + + function(src_crypto_list) + set(src_crypto + aes.c + aesni.c + aria.c + asn1parse.c + asn1write.c + base64.c + bignum.c + camellia.c + ccm.c + chacha20.c + chachapoly.c + cipher.c + cipher_wrap.c + constant_time.c + cmac.c + ctr_drbg.c + des.c + dhm.c + ecdh.c + ecdsa.c + ecjpake.c + ecp.c + ecp_curves.c + entropy.c + entropy_poll.c + error.c + gcm.c + hkdf.c + hmac_drbg.c + md.c + md5.c + memory_buffer_alloc.c + mps_reader.c + mps_trace.c + nist_kw.c + oid.c + padlock.c + pem.c + pk.c + pk_wrap.c + pkcs12.c + pkcs5.c + pkparse.c + pkwrite.c + platform.c + platform_util.c + poly1305.c + psa_crypto.c + psa_crypto_aead.c + psa_crypto_cipher.c + psa_crypto_client.c + psa_crypto_ecp.c + psa_crypto_hash.c + psa_crypto_mac.c + psa_crypto_rsa.c + psa_crypto_se.c + psa_crypto_slot_management.c + psa_crypto_storage.c + psa_its_file.c + ripemd160.c + rsa.c + sha1.c + sha256.c + sha512.c + threading.c + timing.c + version.c + version_features.c + ) + if (MBEDTLS_VERSION_MAJOR EQUAL 2) + list(APPEND src_crypto + arc4.c + blowfish.c + havege.c + md2.c + md4.c + psa_crypto_driver_wrappers.c + rsa_internal.c xtea.c + ) + elseif (MBEDTLS_VERSION_MAJOR EQUAL 3) + list(APPEND src_crypto + bignum_core.c + rsa_alt_helpers.c + pk_ecc.c + ) + endif() + list(TRANSFORM src_crypto PREPEND ${PICO_MBEDTLS_PATH}/library/) + set(src_crypto ${src_crypto} PARENT_SCOPE) + endfunction() + + src_crypto_list() pico_add_library(pico_mbedtls_crypto NOFLAG) target_sources(pico_mbedtls_crypto INTERFACE ${src_crypto}) - set(src_x509 - certs.c - pkcs11.c - x509.c - x509_create.c - x509_crl.c - x509_crt.c - x509_csr.c - x509write_crt.c - x509write_csr.c - ) - list(TRANSFORM src_x509 PREPEND ${PICO_MBEDTLS_PATH}/library/) + function(src_x509_list) + set(src_x509 + x509.c + x509_create.c + x509_crl.c + x509_crt.c + x509_csr.c + x509write_crt.c + x509write_csr.c + ) + if (MBEDTLS_VERSION_MAJOR EQUAL 2) + list(APPEND src_x509 + certs.c + pkcs11.c + ) + endif() + list(TRANSFORM src_x509 PREPEND ${PICO_MBEDTLS_PATH}/library/) + set(src_x509 ${src_x509} PARENT_SCOPE) + endfunction() + + src_x509_list() pico_add_library(pico_mbedtls_x509 NOFLAG) target_sources(pico_mbedtls_x509 INTERFACE ${src_x509}) - set(src_tls - debug.c - net_sockets.c - ssl_cache.c - ssl_ciphersuites.c - ssl_cli.c - ssl_cookie.c - ssl_msg.c - ssl_srv.c - ssl_ticket.c - ssl_tls.c - ssl_tls13_keys.c - ) - list(TRANSFORM src_tls PREPEND ${PICO_MBEDTLS_PATH}/library/) + function(src_tls_list) + set(src_tls + debug.c + net_sockets.c + ssl_cache.c + ssl_ciphersuites.c + ssl_cookie.c + ssl_msg.c + ssl_ticket.c + ssl_tls.c + ssl_tls13_keys.c + ) + if (MBEDTLS_VERSION_MAJOR EQUAL 2) + list(APPEND src_tls + ssl_cli.c + ssl_srv.c + ) + elseif (MBEDTLS_VERSION_MAJOR EQUAL 3) + list(APPEND src_tls + ssl_client.c + ssl_debug_helpers_generated.c + ssl_tls12_client.c + ssl_tls12_server.c + ) + endif() + list(TRANSFORM src_tls PREPEND ${PICO_MBEDTLS_PATH}/library/) + set(src_tls ${src_tls} PARENT_SCOPE) + endfunction() + + src_tls_list() pico_add_library(pico_mbedtls_tls NOFLAG) target_sources(pico_mbedtls_tls INTERFACE ${src_tls}) @@ -134,7 +186,12 @@ if (EXISTS ${PICO_MBEDTLS_PATH}/${MBEDTLS_TEST_PATH}) if (DEFINED PICO_MBEDTLS_CONFIG_FILE) target_compile_definitions(pico_mbedtls_headers INTERFACE MBEDTLS_CONFIG_FILE="${PICO_MBEDTLS_CONFIG_FILE}") else() - target_compile_definitions(pico_mbedtls_headers INTERFACE MBEDTLS_CONFIG_FILE="mbedtls_config.h") + if (MBEDTLS_VERSION_MAJOR EQUAL 2) + target_compile_definitions(pico_mbedtls_headers INTERFACE MBEDTLS_CONFIG_FILE="mbedtls_config.h") + else() + # Avoid including mbedtls/include/mbedtls_config.h + target_compile_definitions(pico_mbedtls_headers INTERFACE MBEDTLS_CONFIG_FILE="pico_mbedtls_config.h") + endif() endif() if (TARGET pico_sha256) pico_mirrored_target_link_libraries(pico_mbedtls INTERFACE pico_sha256) @@ -143,32 +200,26 @@ if (EXISTS ${PICO_MBEDTLS_PATH}/${MBEDTLS_TEST_PATH}) target_include_directories(pico_mbedtls_headers SYSTEM INTERFACE ${PICO_MBEDTLS_PATH}/include/ ${PICO_MBEDTLS_PATH}/library/ ${CMAKE_CURRENT_LIST_DIR}/include/) function(suppress_mbedtls_warnings) + # It seems everything needs this due to mbedtls_get_unaligned_uint64 + src_crypto_list() + src_x509_list() + src_tls_list() + foreach(src_file IN LISTS src_crypto src_x509 src_tls) + set_source_files_properties( + ${src_file} + PROPERTIES + COMPILE_OPTIONS "-Wno-cast-qual" + ) + endforeach() + set_source_files_properties( - ${PICO_MBEDTLS_PATH}/library/ecdsa.c - ${PICO_MBEDTLS_PATH}/library/ecp.c - ${PICO_MBEDTLS_PATH}/library/ecp_curves.c - ${PICO_MBEDTLS_PATH}/library/pk_wrap.c - ${PICO_MBEDTLS_PATH}/library/pkparse.c - ${PICO_MBEDTLS_PATH}/library/ssl_cli.c - PROPERTIES - COMPILE_OPTIONS "-Wno-cast-qual" - ) - set_source_files_properties( - ${PICO_MBEDTLS_PATH}/library/psa_crypto_client.c - ${PICO_MBEDTLS_PATH}/library/psa_crypto_driver_wrappers.c - PROPERTIES - COMPILE_OPTIONS "-Wno-redundant-decls" - ) - set_source_files_properties( + ${PICO_MBEDTLS_PATH}/library/ssl_srvx.c ${PICO_MBEDTLS_PATH}/library/x509_crt.c - PROPERTIES - COMPILE_OPTIONS "-Wno-cast-qual;-Wno-null-dereference" - ) - set_source_files_properties( - ${PICO_MBEDTLS_PATH}/library/ssl_srv.c + ${PICO_MBEDTLS_PATH}/library/pk_ecc.c + ${PICO_MBEDTLS_PATH}/library/ssl_tls12_server.c ${PICO_MBEDTLS_PATH}/library/ssl_tls.c PROPERTIES - COMPILE_OPTIONS "-Wno-null-dereference" + COMPILE_OPTIONS "-Wno-cast-qual;-Wno-null-dereference" ) endfunction() diff --git a/src/rp2_common/pico_mbedtls/doc.h b/src/rp2_common/pico_mbedtls/doc.h new file mode 100644 index 000000000..91591fc99 --- /dev/null +++ b/src/rp2_common/pico_mbedtls/doc.h @@ -0,0 +1,11 @@ +/** + * \defgroup pico_mbedtls pico_mbedtls + * \brief pico-sdk wrapper library for mbedtls + * the documentation for which is here. + * + * Builds mbedtls for pico-sdk and implements functions to take advantage of hardware support, if enabled in mbedtls_config.h + * + * * \c \b MBEDTLS_ENTROPY_HARDWARE_ALT, implementation of a hardware entropy collector that uses \ref get_rand_64 + * * \c \b MBEDTLS_SHA256_ALT, use SHA256 hardware acceleration. Only valid if LIB_PICO_SHA256 is defined (i.e. not available for rp2040) + * + */ diff --git a/src/rp2_common/pico_mbedtls/include/pico_mbedtls_config.h b/src/rp2_common/pico_mbedtls/include/pico_mbedtls_config.h new file mode 100644 index 000000000..6c86b8e7c --- /dev/null +++ b/src/rp2_common/pico_mbedtls/include/pico_mbedtls_config.h @@ -0,0 +1,3 @@ +// Latest versions of mbedtls include mbedtls/include/mbedtls_config.h and we used to set MBEDTLS_CONFIG_FILE=mbedtls_config.h +// To maintain compatibility with this and avoid including the mbedtls version of mbedtls_config.h we include pico_mbedtls_config.h first +#include "mbedtls_config.h" \ No newline at end of file diff --git a/src/rp2_common/pico_mbedtls/mbedtls.BUILD b/src/rp2_common/pico_mbedtls/mbedtls.BUILD new file mode 100644 index 000000000..c8b856492 --- /dev/null +++ b/src/rp2_common/pico_mbedtls/mbedtls.BUILD @@ -0,0 +1,23 @@ +load("@pico-sdk//bazel:defs.bzl", "incompatible_with_config") + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "pico_mbedtls_library", + srcs = glob( + ["library/*.c"], + exclude = ["*mbedtls.c"], + ), + hdrs = glob( + include = [ + "include/**/*.h", + "library/*.h", + ], + ), + includes = ["include"], + target_compatible_with = incompatible_with_config("@pico-sdk//bazel/constraint:pico_mbedtls_config_unset"), + deps = [ + "@pico-sdk//src/rp2_common/pico_mbedtls:pico_mbedtls_config", + "@pico-sdk//bazel/config:PICO_MBEDTLS_CONFIG", + ], +) diff --git a/src/rp2_common/pico_mbedtls/pico_mbedtls.c b/src/rp2_common/pico_mbedtls/pico_mbedtls.c index 853d97cdf..b767b136f 100644 --- a/src/rp2_common/pico_mbedtls/pico_mbedtls.c +++ b/src/rp2_common/pico_mbedtls/pico_mbedtls.c @@ -8,7 +8,13 @@ #include "pico.h" #include "pico/rand.h" #include "mbedtls/sha256.h" -#include "common.h" +#include "mbedtls/version.h" + +#if MBEDTLS_VERSION_MAJOR < 3 +#define mbedtls_sha256_starts mbedtls_sha256_starts_ret +#define mbedtls_sha256_update mbedtls_sha256_update_ret +#define mbedtls_sha256_finish mbedtls_sha256_finish_ret +#endif /* Function to feed mbedtls entropy. */ int mbedtls_hardware_poll(void *data __unused, unsigned char *output, size_t len, size_t *olen) { @@ -27,7 +33,7 @@ int mbedtls_hardware_poll(void *data __unused, unsigned char *output, size_t len #error SHA256 hardware acceleration not supported #endif -// PICO_CONFIG: PICO_MBEDTLS_SHA256_ALT_USE_DMA, Whether to use DMA for writing to hardware for the mbedtls SHA-256 hardware acceleration, type=int, default=1, group=pico_stdlib +// PICO_CONFIG: PICO_MBEDTLS_SHA256_ALT_USE_DMA, Whether to use DMA for writing to hardware for the mbedtls SHA-256 hardware acceleration, type=bool, default=1, group=pico_mbedtls #ifndef PICO_MBEDTLS_SHA256_ALT_USE_DMA #define PICO_MBEDTLS_SHA256_ALT_USE_DMA 1 #endif @@ -39,17 +45,17 @@ void mbedtls_sha256_free(__unused mbedtls_sha256_context *ctx) { pico_sha256_cleanup(ctx); } -int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) { +int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224) { hard_assert(!is224); // that's annoying return pico_sha256_start_blocking(ctx, SHA256_BIG_ENDIAN, PICO_MBEDTLS_SHA256_ALT_USE_DMA); } -int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) { +int mbedtls_sha256_update(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) { pico_sha256_update_blocking(ctx, input, ilen); return 0; } -int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32]) { +int mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32]) { sha256_result_t result; pico_sha256_finish(ctx, &result); memcpy(output, result.bytes, 32); diff --git a/src/rp2_common/pico_multicore/include/pico/multicore.h b/src/rp2_common/pico_multicore/include/pico/multicore.h index 5eb49ddce..fe198aed6 100644 --- a/src/rp2_common/pico_multicore/include/pico/multicore.h +++ b/src/rp2_common/pico_multicore/include/pico/multicore.h @@ -151,7 +151,7 @@ static inline bool multicore_fifo_rvalid(void) { * * See the note in the \ref multicore_fifo section for considerations regarding use of the inter-core FIFOs * - * @return true if the FIFO has room for more data, false otherwise + * \return true if the FIFO has room for more data, false otherwise */ static inline bool multicore_fifo_wready(void) { return sio_hw->fifo_st & SIO_FIFO_ST_RDY_BITS; @@ -316,7 +316,7 @@ static inline void check_doorbell_num_param(__unused uint doorbell_num) { * * \param doorbell_num the doorbell number to claim * \param core_mask 0b01: core 0, 0b10: core 1, 0b11 both core 0 and core 1 - * \sa hardware_claiming + * \sa hardware_claim */ void multicore_doorbell_claim(uint doorbell_num, uint core_mask); @@ -328,7 +328,7 @@ void multicore_doorbell_claim(uint doorbell_num, uint core_mask); * \param core_mask 0b01: core 0, 0b10: core 1, 0b11 both core 0 and core 1 * \param required if true the function will panic if none are available * \return the doorbell number claimed or -1 if required was false, and none are available - * \sa hardware_claiming + * \sa hardware_claim */ int multicore_doorbell_claim_unused(uint core_mask, bool required); @@ -337,7 +337,7 @@ int multicore_doorbell_claim_unused(uint core_mask, bool required); * * \param doorbell_num the doorbell number to unclaim * \param core_mask 0b01: core 0, 0b10: core 1, 0b11 both core 0 and core 1 - * \sa hardware_claiming + * \sa hardware_claim */ void multicore_doorbell_unclaim(uint doorbell_num, uint core_mask); @@ -437,7 +437,7 @@ static inline uint multicore_doorbell_irq_num(uint doorbell_num) { * The core which wishes to lockout the other core calls \ref multicore_lockout_start_blocking or * \ref multicore_lockout_start_timeout_us to interrupt the other "victim" core and wait for it to be in a * "locked out" state. Once the lockout is no longer needed it calls \ref multicore_lockout_end_blocking or - * \ref multicore_lockout_end_timeout_us to release the lockout and wait for confirmation. + * \ref multicore_lockout_end_timeout_us to release the lockout. * * \note Because multicore lockout uses the intercore FIFOs, the FIFOs cannot be used for any other purpose */ @@ -491,27 +491,31 @@ void multicore_lockout_start_blocking(void); */ bool multicore_lockout_start_timeout_us(uint64_t timeout_us); -/*! \brief Release the other core from a locked out state amd wait for it to acknowledge +/*! \brief Release the other core from a locked out state * \ingroup multicore_lockout * - * \note The other core must previously have been "locked out" by calling a `multicore_lockout_start_` function - * from this core + * The other core must previously have been "locked out" by calling a `multicore_lockout_start_` function + * from this core. + * + * \note The other core will leave the lockout state if this function is called. + * The function only blocks for access to a lockout mutex, it does not wait for the other core + * to leave the lockout state. */ void multicore_lockout_end_blocking(void); -/*! \brief Release the other core from a locked out state amd wait up to a time limit for it to acknowledge +/*! \brief Release the other core from a locked out state * \ingroup multicore_lockout * * The other core must previously have been "locked out" by calling a `multicore_lockout_start_` function * from this core * - * \note be very careful using small timeout values, as a timeout here will leave the "lockout" functionality - * in a bad state. It is probably preferable to use \ref multicore_lockout_end_blocking anyway as if you have - * already waited for the victim core to enter the lockout state, then the victim core will be ready to exit - * the lockout state very quickly. + * \note The other core will leave the lockout state if this function returns true. + * The function only blocks for access to a lockout mutex, it does not wait for the other core + * to leave the lockout state. If the lockout mutex could not be acquired, the function returns + * false and no action is taken. * * \param timeout_us the timeout in microseconds - * \return true if the other core successfully exited locked out state within the timeout, false otherwise + * \return true if the other core will leave the lockout state, false otherwise */ bool multicore_lockout_end_timeout_us(uint64_t timeout_us); diff --git a/src/rp2_common/pico_multicore/multicore.c b/src/rp2_common/pico_multicore/multicore.c index f8f5660db..219f24a16 100644 --- a/src/rp2_common/pico_multicore/multicore.c +++ b/src/rp2_common/pico_multicore/multicore.c @@ -14,7 +14,7 @@ #include "hardware/structs/scb.h" #endif #include "hardware/structs/sio.h" -#include "hardware/regs/psm.h" +#include "hardware/structs/psm.h" #include "hardware/claim.h" #if !PICO_RP2040 @@ -101,8 +101,13 @@ int core1_wrapper(int (*entry)(void), void *stack_base) { void multicore_reset_core1(void) { // Use atomic aliases just in case core 1 is also manipulating some PSM state io_rw_32 *power_off = (io_rw_32 *) (PSM_BASE + PSM_FRCE_OFF_OFFSET); +#ifdef __STRICT_ANSI__ + io_rw_32 *power_off_set = hw_set_alias_untyped(power_off); + io_rw_32 *power_off_clr = hw_clear_alias_untyped(power_off); +#else io_rw_32 *power_off_set = hw_set_alias(power_off); io_rw_32 *power_off_clr = hw_clear_alias(power_off); +#endif // Hard-reset core 1. // Reading back confirms the core 1 reset is in the correct state, but also @@ -202,25 +207,27 @@ void multicore_launch_core1_raw(void (*entry)(void), uint32_t *sp, uint32_t vect irq_set_enabled(irq_num, enabled); } -#define LOCKOUT_MAGIC_START 0x73a8831eu -#define LOCKOUT_MAGIC_END (~LOCKOUT_MAGIC_START) - +// A non-zero initialisation value is used in order to reduce the chance of +// entering the lock handler on bootup due to a 0-word being present in the FIFO +static volatile uint32_t lockout_request_id = 0x73a8831eu; static mutex_t lockout_mutex; -static bool lockout_in_progress; // note this method is in RAM because lockout is used when writing to flash // it only makes inline calls static void __isr __not_in_flash_func(multicore_lockout_handler)(void) { multicore_fifo_clear_irq(); while (multicore_fifo_rvalid()) { - if (sio_hw->fifo_rd == LOCKOUT_MAGIC_START) { + uint32_t request_id = sio_hw->fifo_rd; + if (request_id == lockout_request_id) { + // valid lockout request received uint32_t save = save_and_disable_interrupts(); - multicore_fifo_push_blocking_inline(LOCKOUT_MAGIC_START); - while (multicore_fifo_pop_blocking_inline() != LOCKOUT_MAGIC_END) { - tight_loop_contents(); // not tight but endless potentially + multicore_fifo_push_blocking_inline(request_id); + // wait for the lockout to expire + while (request_id == lockout_request_id) { + // when lockout_request_id is updated, the other CPU core calls __sev + __wfe(); } restore_interrupts_from_disabled(save); - multicore_fifo_push_blocking_inline(LOCKOUT_MAGIC_END); } } } @@ -257,7 +264,7 @@ void multicore_lockout_victim_deinit(void) { } } -static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) { +static bool multicore_lockout_handshake(uint32_t request_id, absolute_time_t until) { uint irq_num = SIO_FIFO_IRQ_NUM(get_core_num()); bool enabled = irq_is_enabled(irq_num); if (enabled) irq_set_enabled(irq_num, false); @@ -267,7 +274,7 @@ static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) { if (next_timeout_us < 0) { break; } - multicore_fifo_push_timeout_us(magic, (uint64_t)next_timeout_us); + multicore_fifo_push_timeout_us(request_id, (uint64_t)next_timeout_us); next_timeout_us = absolute_time_diff_us(get_absolute_time(), until); if (next_timeout_us < 0) { break; @@ -276,7 +283,7 @@ static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) { if (!multicore_fifo_pop_timeout_us((uint64_t)next_timeout_us, &word)) { break; } - if (word == magic) { + if (word == request_id) { rc = true; } } while (!rc); @@ -284,14 +291,28 @@ static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) { return rc; } +static uint32_t update_lockout_request_id(void) { + // generate new number and then update shared variable + uint32_t new_request_id = lockout_request_id + 1; + lockout_request_id = new_request_id; + // notify other core + __sev(); + return new_request_id; +} + static bool multicore_lockout_start_block_until(absolute_time_t until) { check_lockout_mutex_init(); if (!mutex_enter_block_until(&lockout_mutex, until)) { return false; } - hard_assert(!lockout_in_progress); - bool rc = multicore_lockout_handshake(LOCKOUT_MAGIC_START, until); - lockout_in_progress = rc; + // generate a new request_id number + uint32_t request_id = update_lockout_request_id(); + // attempt to lock out + bool rc = multicore_lockout_handshake(request_id, until); + if (!rc) { + // lockout failed - cancel it + update_lockout_request_id(); + } mutex_exit(&lockout_mutex); return rc; } @@ -309,13 +330,10 @@ static bool multicore_lockout_end_block_until(absolute_time_t until) { if (!mutex_enter_block_until(&lockout_mutex, until)) { return false; } - assert(lockout_in_progress); - bool rc = multicore_lockout_handshake(LOCKOUT_MAGIC_END, until); - if (rc) { - lockout_in_progress = false; - } + // lockout finished - cancel it + update_lockout_request_id(); mutex_exit(&lockout_mutex); - return rc; + return true; } bool multicore_lockout_end_timeout_us(uint64_t timeout_us) { @@ -402,4 +420,4 @@ void multicore_doorbell_unclaim(uint doorbell_num, uint core_mask) { } -#endif \ No newline at end of file +#endif diff --git a/src/rp2_common/pico_platform_common/BUILD.bazel b/src/rp2_common/pico_platform_common/BUILD.bazel new file mode 100644 index 000000000..18a373a51 --- /dev/null +++ b/src/rp2_common/pico_platform_common/BUILD.bazel @@ -0,0 +1,25 @@ +load("//bazel:defs.bzl", "compatible_with_rp2") + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "pico_platform_common_headers", + hdrs = ["include/pico/platform/common.h"], + includes = ["include"], + visibility = [ + "//src/rp2040/pico_platform:__pkg__", + "//src/rp2350/pico_platform:__pkg__", + ], +) + +cc_library( + name = "pico_platform_common", + srcs = ["common.c"], + target_compatible_with = compatible_with_rp2(), + deps = [ + ":pico_platform_common_headers", + "//src/rp2_common:platform_defs", + "//src/rp2_common/hardware_base", + "//src/common/pico_base_headers", + ], +) diff --git a/src/rp2_common/pico_platform_common/CMakeLists.txt b/src/rp2_common/pico_platform_common/CMakeLists.txt new file mode 100644 index 000000000..8e6da4e13 --- /dev/null +++ b/src/rp2_common/pico_platform_common/CMakeLists.txt @@ -0,0 +1,8 @@ +if (NOT TARGET pico_platform_common) + pico_add_library(pico_platform_common) + target_sources(pico_platform_common INTERFACE ${CMAKE_CURRENT_LIST_DIR}/common.c) + + target_include_directories(pico_platform_common_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) + + target_link_libraries(pico_platform_common_headers INTERFACE hardware_regs) +endif() diff --git a/src/rp2_common/pico_platform_common/common.c b/src/rp2_common/pico_platform_common/common.c new file mode 100644 index 000000000..af5bf1833 --- /dev/null +++ b/src/rp2_common/pico_platform_common/common.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "pico.h" +#include "hardware/address_mapped.h" +#include "hardware/regs/tbman.h" + +// Note we leave the FPGA check in by default so that we can run bug repro +// binaries coming in from the wild on the FPGA platform. It takes up around +// 48 bytes if you include all the calls, so you can pass PICO_NO_FPGA_CHECK=1 +// to remove it. The FPGA check is used to skip initialisation of hardware +// (mainly clock generators and oscillators) that aren't present on FPGA. + +#if !PICO_NO_FPGA_CHECK +// Inline stub provided in header if this code is unused (so folding can be +// done in each TU instead of relying on LTO) +bool __attribute__((weak)) running_on_fpga(void) { + return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS; +} +#endif + +#if !PICO_NO_SIM_CHECK +bool __attribute__((weak)) running_in_sim(void) { + return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_HDLSIM_BITS; +} +#endif + diff --git a/src/rp2_common/pico_platform_common/include/pico/platform/common.h b/src/rp2_common/pico_platform_common/include/pico/platform/common.h new file mode 100644 index 000000000..c4645d6e0 --- /dev/null +++ b/src/rp2_common/pico_platform_common/include/pico/platform/common.h @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2025 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _PICO_PLATFORM_COMMON_H +#define _PICO_PLATFORM_COMMON_H + +/** \file pico/platform/common.h + * \ingroup pico_platform + * + * \brief Macros and definitions common to all rp2 platforms but not specific to any library + * + * This header may be included by assembly code + * + * Note certain library specific defines are defined here when they are interdpedent across libraries, + * but making an explicit library dependency does not make sense. + */ + +// PICO_CONFIG: PICO_MINIMAL_STORED_VECTOR_TABLE, Only store a very minimal vector table in the binary on Arm, type=bool, default=0, advanced=true, group=pico_crt0 +#ifndef PICO_MINIMAL_STORED_VECTOR_TABLE +#define PICO_MINIMAL_STORED_VECTOR_TABLE 0 +#endif + +#if PICO_MINIMAL_STORED_VECTOR_TABLE && (PICO_NO_FLASH && !defined(__riscv)) +#if PICO_NUM_VTABLE_IRQS +#warning PICO_NUM_VTABLE_IRQS is specied with PICO_MINIMAL_STORED_VECTOR_TABLE for NO_FLASH Arm binary; ignored +#undef PICO_NUM_VTABLE_IRQS +#endif +#define PICO_NUM_VTABLE_IRQS 0 +#else +// PICO_CONFIG: PICO_NUM_VTABLE_IRQS, Number of IRQ handlers in the vector table - can be lowered to save space if you aren't using some higher IRQs, type=int, default=NUM_IRQS, group=hardware_irq +#ifndef PICO_NUM_VTABLE_IRQS +#define PICO_NUM_VTABLE_IRQS NUM_IRQS +#endif +#endif + +#ifndef __ASSEMBLER__ + +// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime +#ifndef PICO_NO_FPGA_CHECK +#define PICO_NO_FPGA_CHECK 1 +#endif + +// PICO_CONFIG: PICO_NO_SIM_CHECK, Remove the SIM platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime +#ifndef PICO_NO_SIM_CHECK +#define PICO_NO_SIM_CHECK 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if PICO_NO_FPGA_CHECK +static inline bool running_on_fpga(void) {return false;} +#else +bool running_on_fpga(void); +#endif + +#if PICO_NO_SIM_CHECK +static inline bool running_in_sim(void) {return false;} +#else +bool running_in_sim(void); +#endif + +/*! \brief No-op function for the body of tight loops + * \ingroup pico_platform + * + * No-op function intended to be called by any tight hardware polling loop. Using this ubiquitously + * makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup + * debugging might be added + */ +static __force_inline void tight_loop_contents(void) {} + +#define host_safe_hw_ptr(x) ((uintptr_t)(x)) +#define native_safe_hw_ptr(x) host_safe_hw_ptr(x) + +#ifdef __cplusplus +} +#endif +#endif // __ASSEMBLER__ + + +#endif \ No newline at end of file diff --git a/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h b/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h index 486758be3..7f24008a2 100644 --- a/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h +++ b/src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h @@ -7,8 +7,8 @@ #ifndef _PICO_PLATFORM_COMPILER_H #define _PICO_PLATFORM_COMPILER_H -/** \file platform_compiler.h - * \defgroup pico_platform pico_platform +/** \file pico/platform/compiler.h + * \ingroup pico_platform * * \brief Macros and definitions (and functions when included by non assembly code) to adapt for different compilers * diff --git a/src/rp2_common/pico_printf/printf_none.S b/src/rp2_common/pico_printf/printf_none.S index 0148f265f..57cf34411 100644 --- a/src/rp2_common/pico_printf/printf_none.S +++ b/src/rp2_common/pico_printf/printf_none.S @@ -5,7 +5,6 @@ */ #include "pico/asm_helper.S" -#include "pico/bootrom/sf_table.h" pico_default_asm_setup diff --git a/src/rp2_common/pico_rand/CMakeLists.txt b/src/rp2_common/pico_rand/CMakeLists.txt index 9af7d470d..24db85c29 100644 --- a/src/rp2_common/pico_rand/CMakeLists.txt +++ b/src/rp2_common/pico_rand/CMakeLists.txt @@ -7,8 +7,13 @@ target_sources(pico_rand INTERFACE target_include_directories(pico_rand_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) pico_mirrored_target_link_libraries(pico_rand INTERFACE - pico_unique_id hardware_clocks hardware_timer hardware_sync ) + +if (TARGET pico_unique_id) + pico_mirrored_target_link_libraries(pico_rand INTERFACE + pico_unique_id + ) +endif() \ No newline at end of file diff --git a/src/rp2_common/pico_rand/include/pico/rand.h b/src/rp2_common/pico_rand/include/pico/rand.h index b0a337f24..e3bbe2df8 100644 --- a/src/rp2_common/pico_rand/include/pico/rand.h +++ b/src/rp2_common/pico_rand/include/pico/rand.h @@ -25,7 +25,7 @@ extern "C" { * The random numbers (32 to 128 bit) to be supplied are read from the PRNG which is used * to help provide a large number space. * - * The following (multiple) sources of entropy are available (of varying quality), each enabled by a #define: + * The following (multiple) sources of entropy are available (of varying quality), each enabled by a \#define: * * - The Ring Oscillator (ROSC) (\ref PICO_RAND_ENTROPY_SRC_ROSC == 1): * \ref PICO_RAND_ROSC_BIT_SAMPLE_COUNT bits are gathered from the ring oscillator "random bit" and mixed in each @@ -47,7 +47,7 @@ extern "C" { * - Time (\ref PICO_RAND_SEED_ENTROPY_SRC_TIME == 1): The 64-bit microsecond timer is mixed into the seed. * - Board Identifier (PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID == 1): The board id via \ref pico_get_unique_board_id * is mixed into the seed. - * - RAM hash (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH): The hashed contents of a + * - RAM hash (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH): The hashed contents of a * subset of RAM are mixed in. Initial RAM contents are undefined on power up, so provide a reasonable source of entropy. * By default the last 1K of RAM (which usually contains the core 0 stack) is hashed, which may also provide for differences * after each warm reset. diff --git a/src/rp2_common/pico_rand/rand.c b/src/rp2_common/pico_rand/rand.c index 794c63e4c..03b0e3d61 100644 --- a/src/rp2_common/pico_rand/rand.c +++ b/src/rp2_common/pico_rand/rand.c @@ -25,11 +25,19 @@ */ #include "pico/rand.h" +#if PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID #include "pico/unique_id.h" +#endif +#if PICO_RAND_ENTROPY_SRC_TIME #include "pico/time.h" +#endif #include "hardware/clocks.h" +#if PICO_RAND_SEED_ENTROPY_SRC_ROSC || PICO_RAND_ENTROPY_SRC_ROSC #include "hardware/structs/rosc.h" +#endif +#if PICO_RAND_SEED_ENTROPY_SRC_BUS_PERF_COUNTER || PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER #include "hardware/structs/busctrl.h" +#endif #include "hardware/sync.h" static bool rng_initialised = false; diff --git a/src/rp2_common/pico_runtime/CMakeLists.txt b/src/rp2_common/pico_runtime/CMakeLists.txt index da329e695..e190d5106 100644 --- a/src/rp2_common/pico_runtime/CMakeLists.txt +++ b/src/rp2_common/pico_runtime/CMakeLists.txt @@ -51,22 +51,27 @@ elseif (PICO_C_COMPILER_IS_CLANG) # target_link_options(pico_runtime INTERFACE "-nostdlib") endif() -# pico_minimize_runtime((INCLUDE ...) (EXCLUDE ...)) +# pico_minimize_runtime(TARGET [INCLUDE ...] [EXCLUDE ...]) +# \brief\ Minimize the runtime components for the target # # INCLUDE/EXCLUDE can contain any of the following (all defaulting to not included) # -# DEFAULT_ALARM_POOL - default alarm pool setup -# PRINTF - full printf support -# PRINTF_MINIMAL - printf support without the following -# PRINTF_FLOAT - to control float support if printf is enabled -# PRINTF_EXPONENTIAL -# PRINTF_LONG_LONG -# PRINTF_PTRDIFF_T -# FLOAT - support for single-precision floating point -# DOUBLE - support for double-precision floating point -# FPGA_CHECK - checks for FPGA which allows Raspberry Pi to run your binary on FPGA -# PANIC - default panic impl which brings in stdio -# AUTO_INIT_MUTEX - auto init mutexes; without this you get no printf mutex either - +# DEFAULT_ALARM_POOL - default alarm pool setup; +# PRINTF - full printf support; +# PRINTF_MINIMAL - printf support without the following; +# PRINTF_FLOAT - to control float support if printf is enabled; +# PRINTF_EXPONENTIAL - to control exponential support if printf is enabled; +# PRINTF_LONG_LONG - to control long long support if printf is enabled; +# PRINTF_PTRDIFF_T - to control ptrdiff_t support if printf is enabled; +# FLOAT - support for single-precision floating point; +# DOUBLE - support for double-precision floating point; +# FPGA_CHECK - checks for FPGA which allows Raspberry Pi to run your binary on FPGA; +# PANIC - default panic impl which brings in stdio; +# AUTO_INIT_MUTEX - auto init mutexes, without this you get no printf mutex either; +# CRT0_FAR_CALLS - use blx not bl for calls from crt0 to user overridable functions; +# +# \param\ INCLUDE The items to include +# \param\ EXCLUDE The items to exclude function(pico_minimize_runtime TARGET) set(ALL_ITEMS DEFAULT_ALARM_POOL @@ -144,4 +149,7 @@ function(pico_minimize_runtime TARGET) if (NOT RUNTIME_INCLUDE_FPGA_CHECK) target_compile_definitions(${TARGET} PRIVATE PICO_NO_FPGA_CHECK=1) endif() -endfunction() \ No newline at end of file + if (NOT RUNTIME_CRT0_FAR_CALLS) + target_compile_definitions(${TARGET} PRIVATE PICO_CRT0_NEAR_CALLS=1) + endif() +endfunction() diff --git a/src/rp2_common/pico_runtime/runtime.c b/src/rp2_common/pico_runtime/runtime.c index 42452e5bb..d8bae8900 100644 --- a/src/rp2_common/pico_runtime/runtime.c +++ b/src/rp2_common/pico_runtime/runtime.c @@ -8,6 +8,15 @@ #include "pico/runtime_init.h" +/*! \brief Handle a hard_assert condition failure +* \ingroup pico_runtime +* +* This weak function provides the default implementation (call \ref panic with "Hard assert") for if a \ref hard_assert +* condition fail in non debug builds. You can provide your own strong implementation to replace the default behavior +* +* \sa hard_assert +*/ + void __weak hard_assertion_failure(void) { panic("Hard assert"); } diff --git a/src/rp2_common/pico_runtime_init/CMakeLists.txt b/src/rp2_common/pico_runtime_init/CMakeLists.txt index 81f6ab47f..60d1833e0 100644 --- a/src/rp2_common/pico_runtime_init/CMakeLists.txt +++ b/src/rp2_common/pico_runtime_init/CMakeLists.txt @@ -13,7 +13,13 @@ pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE ) if (TARGET hardware_clocks) - pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE hardware_clocks hardware_timer hardware_vreg) + pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE hardware_clocks) +endif() +if (TARGET hardware_timer) + pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE hardware_timer) +endif() +if (TARGET hardware_vreg) + pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE hardware_vreg) endif() # pico/runtime_init.h includes pico/runtime.h diff --git a/src/rp2_common/pico_runtime_init/runtime_init.c b/src/rp2_common/pico_runtime_init/runtime_init.c index 2b69c8069..5e1ad04ae 100644 --- a/src/rp2_common/pico_runtime_init/runtime_init.c +++ b/src/rp2_common/pico_runtime_init/runtime_init.c @@ -152,7 +152,7 @@ void __weak runtime_init_post_clock_resets(void) { } #endif -#if !PICO_RUNTIME_SKIP_POST_CLOCK_RESETS +#if !PICO_RUNTIME_SKIP_INIT_POST_CLOCK_RESETS PICO_RUNTIME_INIT_FUNC_HW(runtime_init_post_clock_resets, PICO_RUNTIME_INIT_POST_CLOCK_RESETS); #endif @@ -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 +// 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]; -#include "hardware/structs/scb.h" void runtime_init_install_ram_vector_table(void) { // Note on RISC-V the RAM vector table is initialised during crt0 -#if !(PICO_NO_RAM_VECTOR_TABLE || PICO_NO_FLASH) && !defined(__riscv) -#if !PICO_NO_STORED_VECTOR_TABLE - __builtin_memcpy(ram_vector_table, (uint32_t *) scb_hw->vtor, sizeof(ram_vector_table)); -#else - __builtin_memcpy(ram_vector_table, (uint32_t *) scb_hw->vtor, MIN(VTABLE_FIRST_IRQ, sizeof(ram_vector_table))); - for(uint i = VTABLE_FIRST_IRQ; ivtor = (uintptr_t) ram_vector_table; #endif } diff --git a/src/rp2_common/pico_runtime_init/runtime_init_clocks.c b/src/rp2_common/pico_runtime_init/runtime_init_clocks.c index 85d473b8e..a86fe8052 100644 --- a/src/rp2_common/pico_runtime_init/runtime_init_clocks.c +++ b/src/rp2_common/pico_runtime_init/runtime_init_clocks.c @@ -41,10 +41,10 @@ void __weak runtime_init_clocks(void) { // Note: These need setting *before* the ticks are started if (running_on_fpga()) { for (uint i = 0; i < CLK_COUNT; i++) { - clock_set_reported_hz(i, 48 * MHZ); + clock_set_reported_hz(i, FPGA_CLK_SYS_HZ); } // clk_ref is 12MHz in both RP2040 and RP2350 FPGA - clock_set_reported_hz(clk_ref, 12 * MHZ); + clock_set_reported_hz(clk_ref, FPGA_CLK_REF_HZ); // RP2040 has an extra clock, the rtc #if HAS_RP2040_RTC clock_set_reported_hz(clk_rtc, RTC_CLOCK_FREQ_HZ); diff --git a/src/rp2_common/pico_runtime_init/runtime_init_stack_guard.c b/src/rp2_common/pico_runtime_init/runtime_init_stack_guard.c index 27480f2ce..964742eb2 100644 --- a/src/rp2_common/pico_runtime_init/runtime_init_stack_guard.c +++ b/src/rp2_common/pico_runtime_init/runtime_init_stack_guard.c @@ -32,7 +32,7 @@ void runtime_init_per_core_install_stack_guard(void *stack_bottom) { | 0x10000000; // XN = disable instruction fetch; no other bits means no permissions #elif defined(__riscv) - #if !PICO_RP2350 +#if !__RISCV_PMP_CHECKED #error "Check PMP configuration for new platform" #endif // RISC-V PMP, RP2350 configuration of Hazard3: 8 non-hardwired regions, diff --git a/src/rp2_common/pico_standard_link/CMakeLists.txt b/src/rp2_common/pico_standard_link/CMakeLists.txt index a428eb69d..c16968bba 100644 --- a/src/rp2_common/pico_standard_link/CMakeLists.txt +++ b/src/rp2_common/pico_standard_link/CMakeLists.txt @@ -5,6 +5,10 @@ if (NOT TARGET pico_standard_link) target_link_libraries(pico_standard_link INTERFACE boot_stage2_headers) endif() + # pico_add_link_depend(TARGET dependency) + # \brief\ Add a link time dependency to the target + # + # \param\ dependency The dependency to add function(pico_add_link_depend TARGET dependency) get_target_property(target_type ${TARGET} TYPE) if (${target_type} STREQUAL "INTERFACE_LIBRARY") @@ -21,15 +25,60 @@ if (NOT TARGET pico_standard_link) set_target_properties(${TARGET} PROPERTIES ${PROP} "${_LINK_DEPENDS}") endfunction() - # need this because cmake does not appear to have a way to override an INTERFACE variable + # pico_check_linker_script(LDSCRIPT) + # \brief_nodesc\ Check the linker script for compatibility + # + # Checks the linker script for compatibility with the current SDK version, + # and if not, raises warnings and enables workarounds to maintain + # compatibility where possible. + # + # \param\ LDSCRIPT Full path to the linker script to check + function(pico_check_linker_script TARGET LDSCRIPT) + if (EXISTS ${LDSCRIPT}) + file(READ ${LDSCRIPT} LDSCRIPT_CONTENTS) + else() + return() + endif() + + # Check if the linker script uses KEEP to keep the .stack and .heap sections + # and if not, set PICO_CRT0_ALLOCATE_SPACERS to 0 to maintain compatibility + string(FIND "${LDSCRIPT_CONTENTS}" "KEEP(*(.stack*))" KEEP_STACK_FOUND) + string(FIND "${LDSCRIPT_CONTENTS}" "KEEP(*(.heap*))" KEEP_HEAP_FOUND) + string(FIND "${LDSCRIPT_CONTENTS}" "*(.stack*)" STACK_FOUND) + string(FIND "${LDSCRIPT_CONTENTS}" "*(.heap*)" HEAP_FOUND) + set(PICO_CRT0_ALLOCATE_SPACERS TRUE) + if ((${STACK_FOUND} GREATER -1) AND NOT (${KEEP_STACK_FOUND} GREATER -1)) + message(WARNING "Linker script ${LDSCRIPT} does not KEEP the .stack section - replace `*(.stack*)` with `KEEP(*(.stack*))`") + set(PICO_CRT0_ALLOCATE_SPACERS FALSE) + endif() + if ((${HEAP_FOUND} GREATER -1) AND NOT (${KEEP_HEAP_FOUND} GREATER -1)) + message(WARNING "Linker script ${LDSCRIPT} does not KEEP the .heap section - replace `*(.heap*)` with `KEEP(*(.heap*))`") + set(PICO_CRT0_ALLOCATE_SPACERS FALSE) + endif() + if (NOT ${PICO_CRT0_ALLOCATE_SPACERS}) + message(WARNING "Linker script ${LDSCRIPT} is incompatible with certain Pico SDK >2.1.1 features; setting PICO_CRT0_ALLOCATE_SPACERS=0 as a workaround") + target_compile_definitions(${TARGET} PRIVATE PICO_CRT0_ALLOCATE_SPACERS=0) + endif() + endfunction() + + # pico_set_linker_script(TARGET LDSCRIPT) + # \brief\ Set the linker script for the target + # + # \param\ LDSCRIPT Full path to the linker script to set function(pico_set_linker_script TARGET LDSCRIPT) + pico_check_linker_script(${TARGET} ${LDSCRIPT}) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_LINKER_SCRIPT ${LDSCRIPT}) endfunction() + # pico_set_binary_type(TARGET TYPE) + # \brief\ Set the binary type for the target + # + # \param\ TYPE The binary type to set function(pico_set_binary_type TARGET TYPE) 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 +89,23 @@ if (NOT TARGET pico_standard_link) else() set(PICO_DEFAULT_BINARY_TYPE default) endif() + else() + # we must set the individual variables here, as they are used in generator expressions, + # but also for our checks below + if (PICO_DEFAULT_BINARY_TYPE STREQUAL no_flash) + set(PICO_NO_FLASH 1) + endif() + if (PICO_DEFAULT_BINARY_TYPE STREQUAL blocked_ram) + set(PICO_USE_BLOCKED_RAM 1) + endif() + if (PICO_DEFAULT_BINARY_TYPE STREQUAL copy_to_ram) + set(PICO_COPY_TO_RAM 1) + endif() + endif() + if ((PICO_NO_FLASH AND PICO_USE_BLOCKED_RAM) OR + (PICO_USE_BLOCKED_RAM AND PICO_COPY_TO_RAM) OR + (PICO_COPY_TO_RAM AND PICO_NO_FLASH)) + message(FATAL_ERROR "Conflicting binary types specified amongst PICO_DEFAULT_BINARY_TYPE, PICO_NO_FLASH, PICO_USE_BLOCKED_RAM and PICO_COPY_TO_RAM") endif() # todo only needed if not using a custom linker script diff --git a/src/rp2_common/pico_stdio/CMakeLists.txt b/src/rp2_common/pico_stdio/CMakeLists.txt index 5798b8d24..195a5b361 100644 --- a/src/rp2_common/pico_stdio/CMakeLists.txt +++ b/src/rp2_common/pico_stdio/CMakeLists.txt @@ -26,18 +26,34 @@ if (NOT TARGET pico_stdio) pico_mirrored_target_link_libraries(pico_stdio INTERFACE pico_printf) endif() + # pico_enable_stdio_uart(TARGET ENABLED) + # \brief\ Enable stdio UART for the target + # + # \param\ ENABLED Whether to enable stdio UART function(pico_enable_stdio_uart TARGET ENABLED) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_UART ${ENABLED}) endfunction() + # pico_enable_stdio_usb(TARGET ENABLED) + # \brief\ Enable stdio USB for the target + # + # \param\ ENABLED Whether to enable stdio USB function(pico_enable_stdio_usb TARGET ENABLED) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_USB ${ENABLED}) endfunction() + # pico_enable_stdio_semihosting(TARGET ENABLED) + # \brief\ Enable stdio semi-hosting for the target + # + # \param\ ENABLED Whether to enable stdio semi-hosting function(pico_enable_stdio_semihosting TARGET ENABLED) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_SEMIHOSTING ${ENABLED}) endfunction() + # pico_enable_stdio_rtt(TARGET ENABLED) + # \brief\ Enable stdio RTT for the target + # + # \param\ ENABLED Whether to enable stdio RTT function(pico_enable_stdio_rtt TARGET ENABLED) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_RTT ${ENABLED}) endfunction() diff --git a/src/rp2_common/pico_stdio/include/pico/stdio.h b/src/rp2_common/pico_stdio/include/pico/stdio.h index cba3b27c4..b9a96805f 100644 --- a/src/rp2_common/pico_stdio/include/pico/stdio.h +++ b/src/rp2_common/pico_stdio/include/pico/stdio.h @@ -159,7 +159,7 @@ static inline int puts_raw(const char *s) { */ void stdio_set_chars_available_callback(void (*fn)(void*), void *param); -/*! \brief Waits until a timeout to reard at least one character into a buffer +/*! \brief Waits until a timeout to read at least one character into a buffer * \ingroup pico_stdio * * This method returns as soon as input is available, but more characters may @@ -186,35 +186,35 @@ int stdio_get_until(char *buf, int len, absolute_time_t until); */ int stdio_put_string(const char *s, int len, bool newline, bool cr_translation); -/*! \brief stdio_getchar Alias for \ref getchar that definitely does not go thru the implementation +/*! \brief Alias for \ref getchar that definitely does not go thru the implementation * in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0 * * \ingroup pico_stdio */ int stdio_getchar(void); -/*! \brief stdio_getchar Alias for \ref putchar that definitely does not go thru the implementation +/*! \brief Alias for \ref putchar that definitely does not go thru the implementation * in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0 * * \ingroup pico_stdio */ int stdio_putchar(int); -/*! \brief stdio_getchar Alias for \ref puts that definitely does not go thru the implementation +/*! \brief Alias for \ref puts that definitely does not go thru the implementation * in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0 * * \ingroup pico_stdio */ int stdio_puts(const char *s); -/*! \brief stdio_getchar Alias for \ref vprintf that definitely does not go thru the implementation +/*! \brief Alias for \ref vprintf that definitely does not go thru the implementation * in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0 * * \ingroup pico_stdio */ int stdio_vprintf(const char *format, va_list va); -/*! \brief stdio_getchar Alias for \ref printf that definitely does not go thru the implementation +/*! \brief Alias for \ref printf that definitely does not go thru the implementation * in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0 * * \ingroup pico_stdio diff --git a/src/rp2_common/pico_stdio/stdio.c b/src/rp2_common/pico_stdio/stdio.c index d2ce14556..30131da1a 100644 --- a/src/rp2_common/pico_stdio/stdio.c +++ b/src/rp2_common/pico_stdio/stdio.c @@ -315,8 +315,8 @@ int PRIMARY_STDIO_FUNC(puts)(const char *s) { int REAL_FUNC(vprintf)(const char *format, va_list va); int PRIMARY_STDIO_FUNC(vprintf)(const char *format, va_list va) { - bool serialzed = stdout_serialize_begin(); - if (!serialzed) { + bool serialized = stdout_serialize_begin(); + if (!serialized) { #if PICO_STDIO_IGNORE_NESTED_STDOUT return 0; #endif @@ -337,7 +337,7 @@ int PRIMARY_STDIO_FUNC(vprintf)(const char *format, va_list va) { #else ret = REAL_FUNC(vprintf)(format, va); #endif - if (serialzed) { + if (serialized) { stdout_serialize_end(); } return ret; diff --git a/src/rp2_common/pico_stdio_uart/stdio_uart.c b/src/rp2_common/pico_stdio_uart/stdio_uart.c index 54cd86e01..2e2619c11 100644 --- a/src/rp2_common/pico_stdio_uart/stdio_uart.c +++ b/src/rp2_common/pico_stdio_uart/stdio_uart.c @@ -128,13 +128,13 @@ void stdio_uart_deinit_full(struct uart_inst *uart, int tx_pin, int rx_pin) { uart_instance = uart; stdio_set_driver_enabled(&stdio_uart, false); uart_deinit(uart_instance); -#if PICO_RP2040 - ((void)tx_pin); - ((void)rx_pin); -#else +#if HAS_PADS_BANK0_ISOLATION // Leave pads isolated if (tx_pin >= 0) hw_set_bits(&pads_bank0_hw->io[tx_pin], PADS_BANK0_GPIO0_ISO_BITS); if (rx_pin >= 0) hw_set_bits(&pads_bank0_hw->io[rx_pin], PADS_BANK0_GPIO0_ISO_BITS); +#else + ((void)tx_pin); + ((void)rx_pin); #endif } diff --git a/src/rp2_common/pico_stdio_usb/BUILD.bazel b/src/rp2_common/pico_stdio_usb/BUILD.bazel index be9506554..1e8817142 100644 --- a/src/rp2_common/pico_stdio_usb/BUILD.bazel +++ b/src/rp2_common/pico_stdio_usb/BUILD.bazel @@ -24,6 +24,9 @@ cc_library( hdrs = ["include/tusb_config.h"], includes = ["include"], target_compatible_with = compatible_with_rp2(), + deps = [ + ":pico_stdio_usb_headers", + ], ) pico_sdk_define( @@ -43,10 +46,6 @@ cc_library( hdrs = ["include/pico/stdio_usb.h"], includes = ["include"], target_compatible_with = compatible_with_rp2(), - visibility = [ - ":__pkg__", - "//src/rp2_common/tinyusb:__pkg__", - ], deps = [ ":LIB_PICO_STDIO_USB", ":PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS", diff --git a/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h b/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h index b1cb0354c..9e6575a30 100644 --- a/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h +++ b/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h @@ -44,10 +44,30 @@ // this variable is no longer set by default (one is claimed dynamically), but will be respected if specified #endif +// PICO_CONFIG: PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK, Enable/disable the use of a background task to call tud_task(), type=bool, default=1 if the application is not using tinyUSB directly, group=pico_stdio_usb +#ifndef PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE +#define PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK 1 +#else +#define PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK 0 +#endif +#endif + +// PICO_CONFIG: PICO_STDIO_USB_ENABLE_TINYUSB_INIT, Enable/disable calling tinyUSB tusb_init() during initialization, type=bool, default=1 if the application is not using tinyUSB directly, group=pico_stdio_usb +#ifndef PICO_STDIO_USB_ENABLE_TINYUSB_INIT +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE +#define PICO_STDIO_USB_ENABLE_TINYUSB_INIT 1 +#else +#define PICO_STDIO_USB_ENABLE_TINYUSB_INIT 0 +#endif +#endif + // PICO_CONFIG: PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE, Enable/disable resetting into BOOTSEL mode if the host sets the baud rate to a magic value (PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE), type=bool, default=1 if application is not using TinyUSB directly, group=pico_stdio_usb #ifndef PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE -#if !defined(LIB_TINYUSB_HOST) && !defined(LIB_TINYUSB_DEVICE) +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE #define PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE 1 +#else +#define PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE 0 #endif #endif @@ -91,8 +111,10 @@ // PICO_CONFIG: PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE, Enable/disable resetting into BOOTSEL mode via an additional VENDOR USB interface - enables picotool based reset, type=bool, default=1 if application is not using TinyUSB directly, group=pico_stdio_usb #ifndef PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE -#if !defined(LIB_TINYUSB_HOST) && !defined(LIB_TINYUSB_DEVICE) +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE #define PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE 1 +#else +#define PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE 0 #endif #endif @@ -116,6 +138,15 @@ #define PICO_STDIO_USB_RESET_RESET_TO_FLASH_DELAY_MS 100 #endif +// PICO_CONFIG: PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS, Defines the default USB descriptors needed for USB communication, type=bool, default=1 if the application is not using tinyUSB directly, group=pico_stdio_usb +#ifndef PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS +#if !LIB_TINYUSB_HOST && !LIB_TINYUSB_DEVICE +#define PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS 1 +#else +#define PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS 0 +#endif +#endif + // PICO_CONFIG: PICO_STDIO_USB_CONNECTION_WITHOUT_DTR, Disable use of DTR for connection checking meaning connection is assumed to be valid, type=bool, default=0, group=pico_stdio_usb #ifndef PICO_STDIO_USB_CONNECTION_WITHOUT_DTR #define PICO_STDIO_USB_CONNECTION_WITHOUT_DTR 0 @@ -161,6 +192,19 @@ bool stdio_usb_deinit(void); * \return true if stdio is connected over CDC */ bool stdio_usb_connected(void); + +#if PICO_STDIO_USB_SUPPORT_CHARS_AVAILABLE_CALLBACK +/*! \brief Explicitly calls the registered USB stdio chars_available_callback + * \ingroup pico_stdio_usb + * + * This method is normally called by the internal USB stdio background thread when there is new USB CDC + * data available to read. However, if the internal background thread is disabled (e.g. when the user + * directly links tinyUSB), the user will need to implement their own background thread and call this + * method directly. + */ +void stdio_usb_call_chars_available_callback(void); +#endif + #ifdef __cplusplus } #endif diff --git a/src/rp2_common/pico_stdio_usb/stdio_usb.c b/src/rp2_common/pico_stdio_usb/stdio_usb.c index 0f9e3188d..61aa7089b 100644 --- a/src/rp2_common/pico_stdio_usb/stdio_usb.c +++ b/src/rp2_common/pico_stdio_usb/stdio_usb.c @@ -26,8 +26,7 @@ static void (*chars_available_callback)(void*); static void *chars_available_param; #endif -// when tinyusb_device is explicitly linked we do no background tud processing -#if !LIB_TINYUSB_DEVICE +#if PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK // if this crit_sec is initialized, we are not in periodic timer mode, and must make sure // we don't either create multiple one shot timers, or miss creating one. this crit_sec // is used to protect the one_shot_timer_pending flag @@ -171,6 +170,12 @@ void stdio_usb_set_chars_available_callback(void (*fn)(void*), void *param) { chars_available_callback = fn; chars_available_param = param; } + +void stdio_usb_call_chars_available_callback(void) { + if (chars_available_callback) { + chars_available_callback(chars_available_param); + } +} #endif stdio_driver_t stdio_usb = { @@ -197,8 +202,8 @@ bool stdio_usb_init(void) { bi_decl_if_func_used(bi_program_feature("USB stdin / stdout")); #endif -#if !defined(LIB_TINYUSB_DEVICE) - // initialize TinyUSB, as user hasn't explicitly linked it +#if PICO_STDIO_USB_ENABLE_TINYUSB_INIT + // initialize TinyUSB tusb_init(); #else assert(tud_inited()); // we expect the caller to have initialized if they are using TinyUSB @@ -206,7 +211,7 @@ bool stdio_usb_init(void) { if (!mutex_is_initialized(&stdio_usb_mutex)) mutex_init(&stdio_usb_mutex); bool rc = true; -#if !LIB_TINYUSB_DEVICE +#if PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK #ifdef PICO_STDIO_USB_LOW_PRIORITY_IRQ user_irq_claim(PICO_STDIO_USB_LOW_PRIORITY_IRQ); #else @@ -265,7 +270,7 @@ bool stdio_usb_deinit(void) { sleep_ms(PICO_STDIO_USB_DEINIT_DELAY_MS); #endif -#if !LIB_TINYUSB_DEVICE +#if PICO_STDIO_USB_ENABLE_IRQ_BACKGROUND_TASK if (irq_has_shared_handler(USBCTRL_IRQ)) { spin_lock_unclaim(spin_lock_get_num(one_shot_timer_crit_sec.spin_lock)); critical_section_deinit(&one_shot_timer_crit_sec); diff --git a/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c b/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c index 2f6e75877..b805e8fb2 100644 --- a/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c +++ b/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c @@ -26,11 +26,12 @@ * THE SOFTWARE. */ -#if !defined(LIB_TINYUSB_HOST) && !defined(LIB_TINYUSB_DEVICE) - -#include "tusb.h" +#include "pico/stdio_usb.h" #include "pico/stdio_usb/reset_interface.h" #include "pico/unique_id.h" +#include "tusb.h" + +#if PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS #ifndef USBD_VID #define USBD_VID (0x2E8A) // Raspberry Pi diff --git a/src/rp2_common/pico_time_adapter/include/pico/time_adapter.h b/src/rp2_common/pico_time_adapter/include/pico/time_adapter.h index 639e91498..9392fe779 100644 --- a/src/rp2_common/pico_time_adapter/include/pico/time_adapter.h +++ b/src/rp2_common/pico_time_adapter/include/pico/time_adapter.h @@ -80,7 +80,7 @@ static inline void ta_disable_irq_handler(alarm_pool_timer_t *timer, uint alarm_ hw_clear_bits(&timer_hw_from_timer(timer)->inte, 1u << alarm_num); irq_set_enabled(irq_num, true); irq_remove_handler(irq_num, irq_handler); - hardware_alarm_unclaim(alarm_num); + timer_hardware_alarm_unclaim(timer, alarm_num); } static inline void ta_hardware_alarm_claim(alarm_pool_timer_t *timer, uint hardware_alaram_num) { diff --git a/src/rp2_common/pico_unique_id/include/pico/unique_id.h b/src/rp2_common/pico_unique_id/include/pico/unique_id.h index 367d32bff..9f91733de 100644 --- a/src/rp2_common/pico_unique_id/include/pico/unique_id.h +++ b/src/rp2_common/pico_unique_id/include/pico/unique_id.h @@ -41,6 +41,28 @@ extern "C" { #define PICO_UNIQUE_BOARD_ID_SIZE_BYTES 8 +/** + * \brief Static initialization order + * \ingroup pico_unique_id + * + * This defines the init_priority of the pico_unique_id. By default, it is 1000. The valid range is + * from 101-65535. Set it to -1 to set the priority to none, thus putting it after 65535. Changing + * this value will initialize the unique_id earlier or later in the static initialization order. + * This is most useful for C++ consumers of the pico-sdk. + * + * See https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-constructor-function-attribute + * and https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#index-init_005fpriority-variable-attribute + * + * Here is an example of C++ static initializers that will run before, and then after, pico_unique_id is loaded: + * + * [[gnu::init_priority(500)]] my_class before_instance; + * [[gnu::init_priority(2000)]] my_class after_instance; + * + */ +#ifndef PICO_UNIQUE_BOARD_ID_INIT_PRIORITY +#define PICO_UNIQUE_BOARD_ID_INIT_PRIORITY 1000 +#endif + /** * \brief Unique board identifier * \ingroup pico_unique_id diff --git a/src/rp2_common/pico_unique_id/unique_id.c b/src/rp2_common/pico_unique_id/unique_id.c index c027bf27d..28204eda0 100644 --- a/src/rp2_common/pico_unique_id/unique_id.c +++ b/src/rp2_common/pico_unique_id/unique_id.c @@ -12,7 +12,13 @@ static_assert(PICO_UNIQUE_BOARD_ID_SIZE_BYTES <= FLASH_UNIQUE_ID_SIZE_BYTES, "Bo static pico_unique_board_id_t retrieved_id; -static void __attribute__((constructor)) _retrieve_unique_id_on_boot(void) { +#if PICO_UNIQUE_BOARD_ID_INIT_PRIORITY == -1 +#define PICO_UNIQUE_BOARD_ID_INIT_ATTRIBUTES constructor +#else +#define PICO_UNIQUE_BOARD_ID_INIT_ATTRIBUTES constructor(PICO_UNIQUE_BOARD_ID_INIT_PRIORITY) +#endif + +static void __attribute__((PICO_UNIQUE_BOARD_ID_INIT_ATTRIBUTES)) _retrieve_unique_id_on_boot(void) { #if PICO_RP2040 #if PICO_NO_FLASH // The hardware_flash call will panic() if called directly on a NO_FLASH diff --git a/src/rp2_common/tinyusb/BUILD.bazel b/src/rp2_common/tinyusb/BUILD.bazel index 4accbb5ef..fcc0405a2 100644 --- a/src/rp2_common/tinyusb/BUILD.bazel +++ b/src/rp2_common/tinyusb/BUILD.bazel @@ -15,6 +15,7 @@ cc_library( includes = ["include"], target_compatible_with = compatible_with_rp2(), deps = [ + "//bazel/config:PICO_TINYUSB_CONFIG", "//src/common/pico_binary_info", "//src/common/pico_stdlib_headers", "//src/common/pico_sync", @@ -30,7 +31,6 @@ cc_library( "//src/rp2_common/pico_stdio_semihosting", "//src/rp2_common/pico_stdio_uart", "//src/rp2_common/pico_stdio_usb:pico_stdio_usb_headers", - "//src/rp2_common/pico_stdio_usb:tusb_config", "//src/rp2_common/pico_unique_id", ], ) diff --git a/src/rp2_common/tinyusb/CMakeLists.txt b/src/rp2_common/tinyusb/CMakeLists.txt index e305b36c0..e4115f896 100644 --- a/src/rp2_common/tinyusb/CMakeLists.txt +++ b/src/rp2_common/tinyusb/CMakeLists.txt @@ -1,17 +1,22 @@ +# PICO_CMAKE_CONFIG: PICO_TINYUSB_PATH, Path to an alternative version of tinyusb overriding the version in pico-sdk/lib/tinyusb. Can be passed to cmake or set in your environment, type=string, group=tinyusb_device if (DEFINED ENV{PICO_TINYUSB_PATH} AND (NOT PICO_TINYUSB_PATH)) set(PICO_TINYUSB_PATH $ENV{PICO_TINYUSB_PATH}) message("Using PICO_TINYUSB_PATH from environment ('${PICO_TINYUSB_PATH}')") endif () -set(TINYUSB_TEST_PATH "src/portable/raspberrypi/rp2040") +set(TINYUSB_TEST_PATH "hw/bsp/rp2040") if (NOT PICO_TINYUSB_PATH) - set(PICO_TINYUSB_PATH ${PROJECT_SOURCE_DIR}/lib/tinyusb) + set(PICO_TINYUSB_PATH ${PICO_SDK_PATH}/lib/tinyusb) if (NOT EXISTS ${PICO_TINYUSB_PATH}/${TINYUSB_TEST_PATH}) - message(WARNING "TinyUSB submodule has not been initialized; USB support will be unavailable + if (EXISTS "${PICO_TINYUSB_PATH}/LICENSE") + message(WARNING "TinyUSB submodule has been initialized, but does not contain ${TINYUSB_TEST_PATH}; USB support will be unavailable") + else() + message(WARNING "TinyUSB submodule has not been initialized; USB support will be unavailable hint: try 'git submodule update --init' from your SDK directory (${PICO_SDK_PATH}).") + endif() endif() elseif (NOT EXISTS ${PICO_TINYUSB_PATH}/${TINYUSB_TEST_PATH}) - message(WARNING "PICO_TINYUSB_PATH specified but content not present.") + message(WARNING "PICO_TINYUSB_PATH specified, but does not contain ${TINYUSB_TEST_PATH}; USB support will be unavailable") endif() if (EXISTS ${PICO_TINYUSB_PATH}/${TINYUSB_TEST_PATH}) @@ -34,14 +39,18 @@ if (EXISTS ${PICO_TINYUSB_PATH}/${TINYUSB_TEST_PATH}) PICO_RP2040_USB_DEVICE_UFRAME_FIX=1 ) - # unmarked version used by stdio USB - target_link_libraries(tinyusb_device_unmarked INTERFACE tinyusb_common pico_fix_rp2040_usb_device_enumeration tinyusb_device_base) + if (TARGET tinyusb_device_base) + # unmarked version used by stdio USB + target_link_libraries(tinyusb_device_unmarked INTERFACE tinyusb_common pico_fix_rp2040_usb_device_enumeration tinyusb_device_base) - pico_add_library(tinyusb_device) - target_link_libraries(tinyusb_device INTERFACE tinyusb_device_unmarked) + pico_add_library(tinyusb_device) + target_link_libraries(tinyusb_device INTERFACE tinyusb_device_unmarked) + endif() - pico_add_library(tinyusb_host) - target_link_libraries(tinyusb_host INTERFACE tinyusb_host_base tinyusb_common) + if (TARGET tinyusb_host_base) + pico_add_library(tinyusb_host) + target_link_libraries(tinyusb_host INTERFACE tinyusb_host_base tinyusb_common) + endif() pico_add_library(tinyusb_board) target_include_directories(tinyusb_board INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) diff --git a/test/cmsis_test/CMakeLists.txt b/test/cmsis_test/CMakeLists.txt index ca992eeaf..f6b095b46 100644 --- a/test/cmsis_test/CMakeLists.txt +++ b/test/cmsis_test/CMakeLists.txt @@ -1,3 +1,7 @@ +if (NOT TARGET cmsis_core) + message("Skipping cmsis_test as cmsis_core is unavailable on this platform") + return() +endif() # todo remove check if (NOT PICO_RISCV) add_executable(cmsis_test cmsis_test.c) diff --git a/test/hardware_irq_test/CMakeLists.txt b/test/hardware_irq_test/CMakeLists.txt index 90ef50a2b..f329e6172 100644 --- a/test/hardware_irq_test/CMakeLists.txt +++ b/test/hardware_irq_test/CMakeLists.txt @@ -1,3 +1,7 @@ +if (NOT TARGET hardware_dma) + message("Skipping hardware_irq_test as hardware_dma is unavailable on this platform") + return() +endif() add_executable(hardware_irq_test hardware_irq_test.c) target_link_libraries(hardware_irq_test PRIVATE pico_test hardware_irq hardware_dma) diff --git a/test/hardware_pwm_test/CMakeLists.txt b/test/hardware_pwm_test/CMakeLists.txt index c0e08a464..c26893cca 100644 --- a/test/hardware_pwm_test/CMakeLists.txt +++ b/test/hardware_pwm_test/CMakeLists.txt @@ -1,3 +1,7 @@ +if (NOT TARGET hardware_pwm) + message("Skipping hardware_pwm_test as hardware_pwm is unavailable on this platform") + return() +endif() add_executable(hardware_pwm_test hardware_pwm_test.c) target_link_libraries(hardware_pwm_test PRIVATE pico_test hardware_pwm) diff --git a/test/hardware_sync_spin_lock_test/CMakeLists.txt b/test/hardware_sync_spin_lock_test/CMakeLists.txt index 36edf813c..e81069aa8 100644 --- a/test/hardware_sync_spin_lock_test/CMakeLists.txt +++ b/test/hardware_sync_spin_lock_test/CMakeLists.txt @@ -1,3 +1,8 @@ +if (NOT TARGET pico_multicore) + message("Skipping hardware_sync_spin_lock_test as pico_multicore is unavailable on this platform") + return() +endif() + add_executable(hardware_sync_spin_lock_test hardware_sync_spin_lock_test.c) target_link_libraries(hardware_sync_spin_lock_test PRIVATE pico_test hardware_sync pico_multicore) diff --git a/test/kitchen_sink/BUILD.bazel b/test/kitchen_sink/BUILD.bazel index 1bd595c3e..3dbb8492f 100644 --- a/test/kitchen_sink/BUILD.bazel +++ b/test/kitchen_sink/BUILD.bazel @@ -1,4 +1,4 @@ -load("//bazel:defs.bzl", "compatible_with_rp2") +load("//bazel:defs.bzl", "compatible_with_rp2", "pico_generate_pio_header") load("//bazel/util:transition.bzl", "kitchen_sink_test_binary") package(default_visibility = ["//visibility:public"]) @@ -21,6 +21,11 @@ cc_library( includes = ["."], ) +pico_generate_pio_header( + name = "trivial_pio_test", + srcs = ["trivial.pio"], +) + cc_library( name = "kitchen_sink_common", testonly = True, @@ -110,6 +115,8 @@ cc_binary( ":kitchen_sink_common", "//src/rp2_common/pico_cyw43_arch:pico_cyw43_arch_lwip_poll", "//src/rp2_common/pico_btstack:pico_btstack", + "//src/rp2_common/pico_lwip:pico_lwip_mbedtls", + "//src/rp2_common/pico_mbedtls", ], ) @@ -121,6 +128,9 @@ cc_binary( deps = [ ":kitchen_sink_common", "//src/rp2_common/pico_cyw43_arch:pico_cyw43_arch_lwip_threadsafe_background", + "//src/rp2_common/pico_btstack:pico_btstack", + "//src/rp2_common/pico_lwip:pico_lwip_mbedtls", + "//src/rp2_common/pico_mbedtls", ], ) @@ -130,6 +140,7 @@ kitchen_sink_test_binary( src = ":kitchen_sink_lwip_poll_actual", bt_stack_config = ":btstack_config", lwip_config = ":lwip_config", + mbedtls_config = ":mbedtls_config", enable_ble = True, enable_bt_classic = True, target_compatible_with = compatible_with_rp2(), @@ -141,6 +152,7 @@ kitchen_sink_test_binary( src = ":kitchen_sink_lwip_background_actual", bt_stack_config = ":btstack_config", lwip_config = ":lwip_config", + mbedtls_config = ":mbedtls_config", enable_ble = True, enable_bt_classic = True, target_compatible_with = compatible_with_rp2(), diff --git a/test/kitchen_sink/CMakeLists.txt b/test/kitchen_sink/CMakeLists.txt index afc77e553..c2c88d9b3 100644 --- a/test/kitchen_sink/CMakeLists.txt +++ b/test/kitchen_sink/CMakeLists.txt @@ -2,23 +2,32 @@ add_library(kitchen_sink_libs INTERFACE) set(KITCHEN_SINK_LIBS hardware_adc + hardware_boot_lock + hardware_claim hardware_clocks + hardware_dcp hardware_divider hardware_dma hardware_exception hardware_flash hardware_gpio + hardware_hazard3 hardware_i2c hardware_interp hardware_irq hardware_pio - hardware_powman hardware_pll + hardware_powman hardware_pwm + hardware_rcp hardware_resets + hardware_riscv + hardware_riscv_platform_timer hardware_rtc + hardware_sha256 hardware_spi hardware_sync + hardware_sync_spin_lock hardware_ticks hardware_timer hardware_uart @@ -41,8 +50,12 @@ set(KITCHEN_SINK_LIBS pico_mem_ops pico_multicore pico_platform + pico_printf pico_rand + pico_runtime + pico_runtime_init pico_sha256 + pico_stdio pico_stdlib pico_sync pico_time @@ -50,16 +63,47 @@ set(KITCHEN_SINK_LIBS pico_util ) +set(KITCHEN_SINK_NO_HEADER_LIBS + hardware_dcp + pico_bootsel_via_double_reset + pico_int64_ops # currently empty, and only included by _pico variant + pico_mem_ops # currently empty, and only included by _pico variant +) + +set(KITCHEN_SINK_INCLUDES "#pragma once\n") foreach(LIB IN LISTS KITCHEN_SINK_LIBS) if (TARGET ${LIB}) target_link_libraries(kitchen_sink_libs INTERFACE ${LIB}) + string(REGEX MATCH "([a-z]+)_(.+)" HAS_MATCH ${LIB}) + if (HAS_MATCH AND NOT LIB IN_LIST KITCHEN_SINK_NO_HEADER_LIBS) + # these are few, so just hack fixing for now + if (LIB STREQUAL "pico_util") + string(APPEND KITCHEN_SINK_INCLUDES "#include \"pico/util/datetime.h\"\n") + string(APPEND KITCHEN_SINK_INCLUDES "#include \"pico/util/pheap.h\"\n") + string(APPEND KITCHEN_SINK_INCLUDES "#include \"pico/util/queue.h\"\n") + else() + if ("${CMAKE_MATCH_2}" STREQUAL "fix_rp2040_usb_device_enumeration") + set(CMAKE_MATCH_2 "fix/rp2040_usb_device_enumeration") + elseif ("${CMAKE_MATCH_2}" STREQUAL "sync_spin_lock") + set(CMAKE_MATCH_2 "sync/spin_lock") + endif() + string(APPEND KITCHEN_SINK_INCLUDES "#include \"${CMAKE_MATCH_1}/${CMAKE_MATCH_2}.h\"\n") + endif() + endif() endif() endforeach () +set(KITCHEN_SINK_INCLUDE_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kitchen_sink_includes.h") +file(GENERATE OUTPUT ${KITCHEN_SINK_INCLUDE_HEADER} CONTENT ${KITCHEN_SINK_INCLUDES}) add_library(kitchen_sink_options INTERFACE) -target_compile_options(kitchen_sink_options INTERFACE +if (NOT KITCHEN_SINK_NO_WERROR) + target_compile_options(kitchen_sink_options INTERFACE -Werror + ) +endif() + +target_compile_options(kitchen_sink_options INTERFACE -Wall -Wextra # -pedantic @@ -97,6 +141,7 @@ target_compile_definitions(kitchen_sink_libs INTERFACE PICO_FORBID_ARM_HEADERS_ON_RISCV=1 PARAM_ASSERTIONS_ENABLE_ALL=1 # want to check all the assertions for compilation warnings PICO_AUDIO_DMA_IRQ=1 + KITCHEN_SINK_INCLUDE_HEADER="${KITCHEN_SINK_INCLUDE_HEADER}" ) add_executable(kitchen_sink ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) @@ -105,6 +150,10 @@ pico_set_program_name(kitchen_sink "Wombat tentacles") pico_add_extra_outputs(kitchen_sink) target_compile_definitions(kitchen_sink PRIVATE KITCHEN_SINK_ID="regular binary") +if (TARGET hardware_pio) + pico_generate_pio_header(kitchen_sink ${CMAKE_CURRENT_LIST_DIR}/trivial.pio) +endif() + add_executable(kitchen_sink_extra_stdio ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) if (COMMAND suppress_tinyusb_warnings) # Explicitly suppress warnings in TinyUSB files which have them (this has to be done @@ -143,25 +192,27 @@ target_link_libraries(kitchen_sink_printf_none kitchen_sink_libs kitchen_sink_op pico_add_extra_outputs(kitchen_sink_printf_none) pico_set_printf_implementation(kitchen_sink_printf_none none) -add_executable(kitchen_sink_copy_to_ram ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) -pico_set_binary_type(kitchen_sink_copy_to_ram copy_to_ram) -target_link_libraries(kitchen_sink_copy_to_ram kitchen_sink_libs kitchen_sink_options) -pico_add_extra_outputs(kitchen_sink_copy_to_ram) -target_compile_definitions(kitchen_sink_copy_to_ram PRIVATE KITCHEN_SINK_ID="copy-to-ram binary") - -add_executable(kitchen_sink_no_flash ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) -pico_set_binary_type(kitchen_sink_no_flash no_flash) -target_link_libraries(kitchen_sink_no_flash kitchen_sink_libs kitchen_sink_options) -pico_add_extra_outputs(kitchen_sink_no_flash) -target_compile_definitions(kitchen_sink_no_flash PRIVATE KITCHEN_SINK_ID="no-flash binary") - -if (NOT PICO_RP2350) - # RP2350 does not have blocked ram - add_executable(kitchen_sink_blocked_ram ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) - pico_set_binary_type(kitchen_sink_blocked_ram blocked_ram) - target_link_libraries(kitchen_sink_blocked_ram kitchen_sink_libs kitchen_sink_options) - pico_add_extra_outputs(kitchen_sink_blocked_ram) - target_compile_definitions(kitchen_sink_blocked_ram PRIVATE KITCHEN_SINK_ID="blocked-ram binary") +if (NOT KITCHEN_SINK_NO_BINARY_TYPE_VARIANTS) + add_executable(kitchen_sink_copy_to_ram ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + pico_set_binary_type(kitchen_sink_copy_to_ram copy_to_ram) + target_link_libraries(kitchen_sink_copy_to_ram kitchen_sink_libs kitchen_sink_options) + pico_add_extra_outputs(kitchen_sink_copy_to_ram) + target_compile_definitions(kitchen_sink_copy_to_ram PRIVATE KITCHEN_SINK_ID="copy-to-ram binary") + + add_executable(kitchen_sink_no_flash ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + pico_set_binary_type(kitchen_sink_no_flash no_flash) + target_link_libraries(kitchen_sink_no_flash kitchen_sink_libs kitchen_sink_options) + pico_add_extra_outputs(kitchen_sink_no_flash) + target_compile_definitions(kitchen_sink_no_flash PRIVATE KITCHEN_SINK_ID="no-flash binary") + + if (PICO_RP2040) + # RP2040 has blocked ram + add_executable(kitchen_sink_blocked_ram ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + pico_set_binary_type(kitchen_sink_blocked_ram blocked_ram) + target_link_libraries(kitchen_sink_blocked_ram kitchen_sink_libs kitchen_sink_options) + pico_add_extra_outputs(kitchen_sink_blocked_ram) + target_compile_definitions(kitchen_sink_blocked_ram PRIVATE KITCHEN_SINK_ID="blocked-ram binary") + endif() endif() add_executable(kitchen_sink_cpp ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink_cpp.cpp) diff --git a/test/kitchen_sink/kitchen_sink.c b/test/kitchen_sink/kitchen_sink.c index 73417d5a5..7bc2bcd11 100644 --- a/test/kitchen_sink/kitchen_sink.c +++ b/test/kitchen_sink/kitchen_sink.c @@ -5,127 +5,18 @@ */ #include -// Include all headers to check for compiler warnings -#include "hardware/adc.h" -#include "hardware/claim.h" -#include "hardware/clocks.h" -#include "hardware/divider.h" + +#ifndef KITCHEN_SINK_INCLUDE_HEADER +// provided for backwards compatibility for non CMake build systems - just includes enough to compile #include "hardware/dma.h" -#include "hardware/exception.h" -#include "hardware/flash.h" -#include "hardware/gpio.h" -#include "hardware/i2c.h" -#include "hardware/interp.h" -#include "hardware/irq.h" -#include "hardware/pio.h" -#include "hardware/pio_instructions.h" -#include "hardware/pll.h" -#include "hardware/pwm.h" -#include "hardware/resets.h" -#if PICO_RP2040 -#include "hardware/rtc.h" -#endif -#if !PICO_RP2040 -#include "hardware/sha256.h" -#endif -#include "hardware/spi.h" -#include "hardware/sync.h" -#include "hardware/timer.h" -#include "hardware/ticks.h" -#include "hardware/uart.h" -#include "hardware/vreg.h" -#include "hardware/watchdog.h" -#include "hardware/xosc.h" -#include "pico/aon_timer.h" -#include "pico/binary_info.h" -#include "pico/bit_ops.h" -#include "pico/bootrom.h" -#if LIB_PICO_CYW43_ARCH -#include "pico/cyw43_arch.h" -#endif -#include "pico/divider.h" -// todo we should have this but right now double.h is only present with double_implementation == pico -#if PICO_RP2040 -#include "pico/double.h" -#endif -#include "pico/fix/rp2040_usb_device_enumeration.h" -#include "pico/flash.h" -// todo we should have this but right now float.h is only present with float_implementation == pico -#if PICO_RP2040 -#include "pico/float.h" -#endif -#include "pico/i2c_slave.h" -#if LIB_PICO_INT64_OPS_PICO -#include "pico/int64_ops.h" -#endif -#include "pico/malloc.h" -#include "pico/multicore.h" -#include "pico/platform.h" -#include "pico/printf.h" -#include "pico/rand.h" -#include "pico/runtime.h" -#if LIB_PICO_SHA256 -#include "pico/sha256.h" -#endif -#include "pico/stdio.h" -#include "pico/stdlib.h" #include "pico/sync.h" -#include "pico/time.h" -#include "pico/unique_id.h" -#include "pico/util/datetime.h" -#include "pico/util/pheap.h" -#include "pico/util/queue.h" - -#include "hardware/structs/adc.h" -#include "hardware/structs/busctrl.h" -#include "hardware/structs/clocks.h" -#include "hardware/structs/dma.h" -#include "hardware/structs/i2c.h" -#include "hardware/structs/interp.h" -#include "hardware/structs/io_bank0.h" -#include "hardware/structs/io_qspi.h" -#ifndef __riscv -#include "hardware/structs/mpu.h" -#include "hardware/structs/nvic.h" -#endif -#include "hardware/structs/pads_bank0.h" -#include "hardware/structs/pads_qspi.h" -#include "hardware/structs/pio.h" -#include "hardware/structs/pll.h" -#if PICO_RP2350 -#include "hardware/structs/powman.h" -#endif -#include "hardware/structs/psm.h" -#include "hardware/structs/pwm.h" -#include "hardware/structs/resets.h" -#include "hardware/structs/rosc.h" -#if PICO_RP2040 -#include "hardware/structs/rtc.h" -#endif -#ifndef __riscv -#include "hardware/structs/scb.h" -#endif -#include "hardware/structs/sio.h" -#if !PICO_RP2040 -#include "hardware/structs/sha256.h" -#endif -#include "hardware/structs/spi.h" -#if PICO_RP2040 -#include "hardware/structs/ssi.h" -#endif -#include "hardware/structs/syscfg.h" -#ifndef __riscv -#include "hardware/structs/systick.h" +#include "pico/stdlib.h" +#if LIB_PICO_BINARY_INFO +#include "pico/binary_info.h" #endif -#include "hardware/structs/timer.h" -#include "hardware/structs/uart.h" -#include "hardware/structs/usb.h" -#if PICO_RP2040 -#include "hardware/structs/vreg_and_chip_reset.h" +#else +#include KITCHEN_SINK_INCLUDE_HEADER #endif -#include "hardware/structs/watchdog.h" -#include "hardware/structs/xip_ctrl.h" -#include "hardware/structs/xosc.h" #if LIB_PICO_MBEDTLS #include "mbedtls/ssl.h" @@ -133,6 +24,7 @@ #include "lwip/altcp_tls.h" #endif +#if LIB_PICO_BINARY_INFO bi_decl(bi_block_device( BINARY_INFO_MAKE_TAG('K', 'S'), "foo", @@ -141,6 +33,7 @@ bi_decl(bi_block_device( NULL, BINARY_INFO_BLOCK_DEV_FLAG_READ | BINARY_INFO_BLOCK_DEV_FLAG_WRITE | BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN)); +#endif uint32_t *foo = (uint32_t *) 200; @@ -167,7 +60,6 @@ float __attribute__((noinline)) foox(float x, float b) { return x * b; } - int main(void) { spiggle(); diff --git a/test/kitchen_sink/lwipopts.h b/test/kitchen_sink/lwipopts.h index 58b704a1c..510a20449 100644 --- a/test/kitchen_sink/lwipopts.h +++ b/test/kitchen_sink/lwipopts.h @@ -11,4 +11,10 @@ #define LWIP_DNS 1 #define LWIP_SOCKET 0 #define LWIP_NETCONN 0 -#endif \ No newline at end of file + +// For testing mbedtls +#define LWIP_ALTCP 1 +#define LWIP_ALTCP_TLS 1 +#define LWIP_ALTCP_TLS_MBEDTLS 1 + +#endif diff --git a/test/kitchen_sink/mbedtls_config.h b/test/kitchen_sink/mbedtls_config.h index dae339567..4df2e168f 100644 --- a/test/kitchen_sink/mbedtls_config.h +++ b/test/kitchen_sink/mbedtls_config.h @@ -61,3 +61,4 @@ #define MBEDTLS_ECDSA_C #define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_PLATFORM_MS_TIME_ALT diff --git a/test/kitchen_sink/trivial.pio b/test/kitchen_sink/trivial.pio new file mode 100644 index 000000000..933f28ae4 --- /dev/null +++ b/test/kitchen_sink/trivial.pio @@ -0,0 +1,3 @@ +.program trivial + +out pins, 1 \ No newline at end of file diff --git a/test/pico_divider_test/CMakeLists.txt b/test/pico_divider_test/CMakeLists.txt index b180b9d77..94d73100e 100644 --- a/test/pico_divider_test/CMakeLists.txt +++ b/test/pico_divider_test/CMakeLists.txt @@ -1,3 +1,7 @@ +if (NOT TARGET pico_divider) + message("Skipping pico_divider_test as pico_divider is unavailable on this platform") + return() +endif() PROJECT(pico_divider_test) if (PICO_ON_DEVICE) diff --git a/test/pico_float_test/CMakeLists.txt b/test/pico_float_test/CMakeLists.txt index 93845bb36..8bf0de201 100644 --- a/test/pico_float_test/CMakeLists.txt +++ b/test/pico_float_test/CMakeLists.txt @@ -1,3 +1,8 @@ +if (NOT TARGET pico_float) + message("Skipping pico_float_test as pico_float is unavailable on this platform") + return() +endif() + PROJECT(pico_float_test) diff --git a/test/pico_float_test/custom_double_funcs_test.c b/test/pico_float_test/custom_double_funcs_test.c index 85624d4cb..e8f291f4c 100644 --- a/test/pico_float_test/custom_double_funcs_test.c +++ b/test/pico_float_test/custom_double_funcs_test.c @@ -162,16 +162,16 @@ int test() { test_checku(double2ufix(3.25, 2), 13, "double2ufix7"); test_checku(double2ufix(3.0, -1), 1, "double2ufix8"); // not very useful test_checki(double2ufix(0.0, 16), 0, "double2ufix12"); - test_checki(double2ufix(-0.0, 16), 0, "double2fix13"); + test_checki(double2ufix(-0.0, 16), 0, "double2ufix13"); test_checki(double2ufix(0.0, -16), 0, "double2ufix14"); - test_checki(double2ufix(-0.0, -16), 0, "double2fix15"); + test_checki(double2ufix(-0.0, -16), 0, "double2ufix15"); printf("double2fix64\n"); test_checki64(double2fix64(3.5, 8), 0x380, "double2fix641"); test_checki64(double2fix64(-3.5, 8), -0x380, "double2fix642"); test_checki64(double2fix64(32768.0, 16), 32768ll << 16, "double2fix643"); test_checki64(double2fix64(65536.0, 16), 65536ll << 16, "double2fix644"); - test_checki64(double2fix64(2147483648.0, 16), 2147483648ll << 16, "double2ufix644b"); + test_checki64(double2fix64(2147483648.0, 16), 2147483648ll << 16, "double2fix644b"); test_checki64(double2fix64(65536.0 * 65536.0 * 32768.0, 16), INT64_MAX, "double2fix644c"); test_checki64(double2fix64(INFINITY, 16), INT64_MAX, "double2fix645"); test_checki64(double2fix64(-INFINITY, 16), INT64_MIN, "double2fix645b"); @@ -257,10 +257,10 @@ int test() { test_checku(double2ufix_z(3.24999, 2), 12, "double2ufix_z6"); test_checku(double2ufix_z(3.25, 2), 13, "double2ufix_z7"); test_checku(double2ufix_z(3.0, -1), 1, "double2ufix_z8"); // not very useful - test_checki(double2ufix_z(0.0, 16), 0, "double2fix_z9"); - test_checki(double2ufix_z(-0.0, 16), 0, "double2fix_z10"); - test_checki(double2ufix_z(0.0, -16), 0, "double2fix_z11"); - test_checki(double2ufix_z(-0.0, -16), 0, "double2fix_z12"); + test_checki(double2ufix_z(0.0, 16), 0, "double2ufix_z9"); + test_checki(double2ufix_z(-0.0, 16), 0, "double2ufix_z10"); + test_checki(double2ufix_z(0.0, -16), 0, "double2ufix_z11"); + test_checki(double2ufix_z(-0.0, -16), 0, "double2ufix_z12"); printf("double2fix64_z\n"); test_checki64(double2fix64_z(3.5, 8), 0x380, "double2fix64_z1"); @@ -269,9 +269,9 @@ int test() { test_checki64(double2fix64_z(65536.0, 16), 65536ll << 16, "double2fix64_z4"); test_checki64(double2fix64_z(65536.0 * 65536.0 * 32768.0, 16), INT64_MAX, "double2fix64_z4b"); test_checki64(double2fix64_z(INFINITY, 16), INT64_MAX, "double2fix64_z5"); - test_checki64(double2fix64_z(-INFINITY, 16), INT64_MIN, "double2fix64_z5"); - test_checki64(double2fix64_z(INFINITY, 16), INT64_MAX, "double2fix64_z5"); - test_checki64(double2fix64_z(-INFINITY, 16), INT64_MIN, "double2fix64_z5"); + test_checki64(double2fix64_z(-INFINITY, 16), INT64_MIN, "double2fix64_z5b"); + test_checki64(double2fix64_z(INFINITY, 16), INT64_MAX, "double2fix64_z5c"); + test_checki64(double2fix64_z(-INFINITY, 16), INT64_MIN, "double2fix64_z5d"); test_checki64(double2fix64_z(3.24999, 2), 12, "double2fix64_z6"); test_checki64(double2fix64_z(3.25, 2), 13, "double2fix64_z7"); test_checki64(double2fix64_z(-3.24999, 2), -12, "double2fix64_z8"); @@ -308,7 +308,7 @@ int test() { test_checku64(double2ufix64_z(-3.5, 8), 0, "double2ufix64_z2"); test_checku64(double2ufix64_z(32768.0, 16), 32768ll << 16, "double2ufix64_z3"); test_checku64(double2ufix64_z(65536.0, 16), 65536ll << 16, "double2ufix64_z4"); - test_checki64(double2ufix64_z(65536.0 * 65536.0 * 65536.0, 16), UINT64_MAX, "double2fix64_z4b"); + test_checki64(double2ufix64_z(65536.0 * 65536.0 * 65536.0, 16), UINT64_MAX, "double2ufix64_z4b"); test_checku64(double2ufix64_z(INFINITY, 16), UINT64_MAX, "double2ufix64_z5"); test_checku64(double2ufix64_z(-INFINITY, 16), 0, "double2ufix64_z5b"); test_checku64(double2ufix64_z(INFINITY, 16), UINT64_MAX, "double2ufix64_z5c"); diff --git a/test/pico_float_test/custom_float_funcs_test.c b/test/pico_float_test/custom_float_funcs_test.c index d749f778a..570ca0543 100644 --- a/test/pico_float_test/custom_float_funcs_test.c +++ b/test/pico_float_test/custom_float_funcs_test.c @@ -179,7 +179,7 @@ int test() { test_checki64(float2fix64(-3.5f, 8), -0x380, "float2fix642"); test_checki64(float2fix64(32768.0f, 16), 32768ll << 16, "float2fix643"); test_checki64(float2fix64(65536.0f, 16), 65536ll << 16, "float2fix644"); - test_checki64(float2fix64(2147483648.0f, 16), 2147483648ll << 16, "float2ufix644b"); + test_checki64(float2fix64(2147483648.0f, 16), 2147483648ll << 16, "float2fix644b"); test_checki64(float2fix64(65536.0f * 65536.0f * 32768.0f, 16), INT64_MAX, "float2fix644c"); test_checki64(float2fix64(INFINITY, 16), INT64_MAX, "float2fix645"); test_checki64(float2fix64(3.24999f, 2), 12, "float2fix646"); @@ -227,9 +227,9 @@ int test() { test_checku(float2ufix_z(3.25f, 2), 13, "float2ufix_z7"); test_checku(float2ufix_z(3.0f, -1), 1, "float2ufix_z8"); // not very useful u32f.u = 0x7f012345; - test_checku(float2ufix_z(u32f.f, 1), UINT32_MAX, "float2fix_z9"); + test_checku(float2ufix_z(u32f.f, 1), UINT32_MAX, "float2ufix_z9"); u32f.u = 0xff012345; - test_checku(float2ufix_z(u32f.f, 1), 0, "float2fix_z10"); + test_checku(float2ufix_z(u32f.f, 1), 0, "float2ufix_z10"); printf("float2fix64_z\n"); test_checki64(float2fix64_z(3.5f, 8), 0x380, "float2fix64_z1"); @@ -249,7 +249,7 @@ int test() { test_checku64(float2ufix64_z(-3.5f, 8), 0, "float2ufix64_z2"); test_checku64(float2ufix64_z(32768.0f, 16), 32768ll << 16, "float2ufix64_z3"); test_checku64(float2ufix64_z(65536.0f, 16), 65536ll << 16, "float2ufix64_z4"); - test_checki64(float2ufix64_z(65536.0f * 65536.0f * 65536.0f, 16), UINT64_MAX, "float2fix64_z4b"); + test_checki64(float2ufix64_z(65536.0f * 65536.0f * 65536.0f, 16), UINT64_MAX, "float2ufix64_z4b"); test_checku64(float2ufix64_z(INFINITY, 16), UINT64_MAX, "float2ufix64_z5"); test_checku64(float2ufix64_z(3.24999f, 2), 12, "float2ufix64_z6"); test_checku64(float2ufix64_z(3.25f, 2), 13, "float2ufix64_z7"); diff --git a/test/pico_sha256_test/CMakeLists.txt b/test/pico_sha256_test/CMakeLists.txt index 8474f3edb..8dc6dd326 100644 --- a/test/pico_sha256_test/CMakeLists.txt +++ b/test/pico_sha256_test/CMakeLists.txt @@ -1,4 +1,5 @@ -if (NOT TARGET hardware_sha256) +if (NOT TARGET pico_sha256) + message("Skipping pico_sha256_test as pico_sha256 is unavailable on this platform") return() endif() diff --git a/test/pico_time_test/pico_time_test.c b/test/pico_time_test/pico_time_test.c index b8f4cba3c..9ed05e209 100644 --- a/test/pico_time_test/pico_time_test.c +++ b/test/pico_time_test/pico_time_test.c @@ -41,8 +41,8 @@ static struct timeout { alarm_id_t alarm_id; absolute_time_t target; absolute_time_t fired_at; - uint pool; uint fired_count; + uint8_t pool; bool cancelled; bool not_cancelled; // tried to cancel but it was done } timeouts[NUM_TIMEOUTS]; @@ -85,6 +85,7 @@ static int issue_1953_test(void); static int issue_2118_test(void); static int issue_2148_test(void); static int issue_2186_test(void); +static int issue_2374_test(void); int main() { setup_default_uart(); @@ -263,6 +264,8 @@ int main() { issue_2186_test(); + issue_2374_test(); + PICOTEST_END_TEST(); } @@ -421,3 +424,42 @@ static int issue_2148_test(void) { #endif return 0; } + +static void fill_stack(int val) { + uint8_t array[50]; + memset(array, val, sizeof(array)); +} + +// aon_timer_get_time called aon_timer_get_time_calendar which called datetime_to_tm +// which didn't initialise tm_isdst +static int issue_2374_test(void) { +#if HAS_RP2040_RTC && !__clang__ + PICOTEST_START_SECTION("Issue #2374 defect - time goes backwards"); + setenv("TZ", "PST8PDT7,M3.2.0/2,M11.1.0/02:00:00", 1); + tzset(); + + struct timespec ts = { .tv_sec = 1743055938, .tv_nsec = 0 }; + aon_timer_start(&ts); + + struct timespec ts1; + fill_stack(1); // Setting tm_isdst if it's uninitialised + hard_assert(aon_timer_get_time(&ts1)); + + sleep_ms(1000); + + struct timespec ts2; + fill_stack(0); // Setting tm_isdst if it's uninitialised + hard_assert(aon_timer_get_time(&ts2)); + + // Check time hasn't been adjusted due to dst + hard_assert(ts1.tv_sec == ts2.tv_sec - 1); + + setenv("TZ", "", 1); + tzset(); + + aon_timer_stop(); + + PICOTEST_END_SECTION(); +#endif + return 0; +} diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index c2fbe3281..5a6795ef2 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -41,6 +41,30 @@ define_property(TARGET BRIEF_DOCS "AES key for encrypting" FULL_DOCS "AES key for encrypting" ) +define_property(TARGET + PROPERTY PICOTOOL_IVFILE + INHERITED + BRIEF_DOCS "IV OTP salt for encrypting" + FULL_DOCS "IV OTP salt for encrypting" +) +define_property(TARGET + PROPERTY PICOTOOL_EMBED_DECRYPTION + INHERITED + BRIEF_DOCS "Embed decryption stage into encrypted binary" + FULL_DOCS "Embed decryption stage into encrypted binary" +) +define_property(TARGET + PROPERTY PICOTOOL_USE_MBEDTLS_DECRYPTION + INHERITED + BRIEF_DOCS "Use MbedTLS based decryption stage - this is faster, but not secure against power snooping" + FULL_DOCS "Use MbedTLS based decryption stage - this is faster, but not secure against power snooping" +) +define_property(TARGET + PROPERTY PICOTOOL_OTP_KEY_PAGE + INHERITED + BRIEF_DOCS "OTP page storing the AES key" + FULL_DOCS "OTP page storing the AES key" +) define_property(TARGET PROPERTY PICOTOOL_ENC_SIGFILE INHERITED @@ -71,6 +95,12 @@ define_property(TARGET BRIEF_DOCS "Extra arguments to pass to uf2 conversion" FULL_DOCS "Extra arguments to pass to uf2 conversion" ) +define_property(TARGET + PROPERTY PICOTOOL_LOAD_MAP + INHERITED + BRIEF_DOCS "Ensure a load map is added" + FULL_DOCS "Ensure a load map is added" +) # Check pioasm is installed, or build it if not installed function(pico_init_pioasm) @@ -139,6 +169,14 @@ function(pico_init_picotool) endif() endif() + if (TARGET picotool AND NOT DEFINED ENV{_PICOTOOL_FOUND_THIS_RUN}) + # Internal environment variable to prevent printing multiple times + set(ENV{_PICOTOOL_FOUND_THIS_RUN} 1) + + get_property(picotool_location TARGET picotool PROPERTY LOCATION) + message("Using picotool from ${picotool_location}") + endif() + if (TARGET picotool) set(picotool_FOUND 1 PARENT_SCOPE) else() @@ -153,13 +191,41 @@ function(picotool_check_configurable TARGET) endif() 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 +# 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() + +# pico_generate_pio_header(TARGET PIO_FILES... [OUTPUT_FORMAT ] [OUTPUT_DIR ]) +# \ingroup\ pico_pio +# \brief\ Generate pio header and include it in the build +# +# \param\ PIO_FILES The PIO files to generate the header for +# \param\ OUTPUT_FORMAT The output format to use for the pio header +# \param\ OUTPUT_DIR The directory to output the pio header to function(pico_generate_pio_header TARGET) pico_init_pioasm() # Note that PATH is not a valid argument but was previously ignored (and happens to be passed by pico-extras) cmake_parse_arguments(pico_generate_pio_header "" "OUTPUT_FORMAT;OUTPUT_DIR;PATH" "" ${ARGN} ) + # 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 if (pico_generate_pio_header_OUTPUT_FORMAT) set(OUTPUT_FORMAT "${pico_generate_pio_header_OUTPUT_FORMAT}") elseif(DEFINED PICO_DEFAULT_PIOASM_OUTPUT_FORMAT) @@ -207,21 +273,49 @@ function(pico_generate_pio_header TARGET) endif() endfunction() -# pico_package_uf2_output(TARGET PACKADDR) -# Package a UF2 output to be written to the PACKADDR address. This can be -# used with a no_flash binary to write the UF2 to flash when dragging & -# dropping, and it will be copied to SRAM by the bootrom before execution. -# This sets PICOTOOL_UF2_PACKAGE_ADDR to PACKADDR. -function(pico_package_uf2_output TARGET PACKADDR) +# pico_ensure_load_map(TARGET) +# \brief\ Ensure a load map is added to the target. +# This can be used to ensure a load map is present, so the bootrom knows where +# to load the binary if it's stored in a different location (e.g. a packaged +# binary). +# +# This sets the target property PICOTOOL_LOAD_MAP to true. +function(pico_ensure_load_map TARGET) picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES - PICOTOOL_UF2_PACKAGE_ADDR ${PACKADDR} + PICOTOOL_LOAD_MAP true ) endfunction() +# pico_package_uf2_output(TARGET [PACKADDR]) +# \brief\ Package a UF2 output to be written to the PACKADDR address. +# This can be used with a no_flash binary to write the UF2 to flash when dragging & +# dropping, and it will be copied to SRAM by the bootrom before execution. +# +# This sets the target property PICOTOOL_UF2_PACKAGE_ADDR to PACKADDR and calls +# pico_ensure_load_map(TARGET). +# +# \param\ PACKADDR The address to package the UF2 to, defaults to start of flash +function(pico_package_uf2_output TARGET) + picotool_check_configurable(${TARGET}) + if (ARGC EQUAL 1) + set_target_properties(${TARGET} PROPERTIES + PICOTOOL_UF2_PACKAGE_ADDR 0x10000000 + ) + else() + set_target_properties(${TARGET} PROPERTIES + PICOTOOL_UF2_PACKAGE_ADDR ${ARGV1} + ) + endif() + pico_ensure_load_map(${TARGET}) +endfunction() + # pico_set_otp_key_output_file(TARGET OTPFILE) -# Output the public key hash and other necessary rows to an otp JSON file. -# This sets PICOTOOL_OTP_FILE to OTPFILE. +# \brief\ Output the public key hash and other necessary rows to an otp JSON file. +# +# This sets the target property PICOTOOL_OTP_FILE to OTPFILE. +# +# \param\ OTPFILE The OTP file to output the public key hash and other necessary rows to function(pico_set_otp_key_output_file TARGET OTPFILE) picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES @@ -230,9 +324,12 @@ function(pico_set_otp_key_output_file TARGET OTPFILE) endfunction() # pico_load_map_clear_sram(TARGET) +# \brief_nodesc\ Adds a load map entry to clear all of SRAM +# # Adds an entry to the load map to instruct the bootrom to clear all of SRAM -# before loading the binary. This appends the `--clear` argument -# to PICOTOOL_EXTRA_PROCESS_ARGS. +# before loading the binary. +# +# This appends the `--clear` argument to the target property PICOTOOL_EXTRA_PROCESS_ARGS. function(pico_load_map_clear_sram TARGET) picotool_check_configurable(${TARGET}) # get and set, to inherit list @@ -246,11 +343,20 @@ function(pico_load_map_clear_sram TARGET) ) endfunction() -# pico_set_binary_version( [MAJOR ] [MINOR ] [ROLLBACK ] [ROLLBACK_ROWS ]) +# pico_set_binary_version(TARGET [MAJOR ] [MINOR ] [ROLLBACK ] [ROWS ]) +# \brief_nodesc\ Add a version item to the metadata block +# # Adds a version item to the metadata block, with the given major, minor and -# rollback version, along with the rollback rows. These are appended as arguments -# to PICOTOOL_EXTRA_PROCESS_ARGS if setting the rollback version, or set as compile -# definitions if only setting the major/minor versions. +# rollback version, along with the rollback rows. +# +# These are appended as arguments to the target property PICOTOOL_EXTRA_PROCESS_ARGS if setting the +# rollback version, or set as compile definitions if only setting the major/minor +# versions. +# +# \param\ MAJOR The major version to set +# \param\ MINOR The minor version to set +# \param\ ROLLBACK The rollback version to set +# \param\ ROWS The OTP rows to use for the rollback version function(pico_set_binary_version TARGET) picotool_check_configurable(${TARGET}) set(oneValueArgs MAJOR MINOR ROLLBACK) @@ -299,8 +405,11 @@ function(pico_set_binary_version TARGET) endfunction() # pico_set_uf2_family(TARGET FAMILY) -# Set the UF2 family to use when creating the UF2. -# This sets PICOTOOL_UF2_FAMILY to FAMILY. +# \brief\ Set the UF2 family to use when creating the UF2. +# +# This sets the target property PICOTOOL_UF2_FAMILY to FAMILY. +# +# \param\ FAMILY The UF2 family to use function(pico_set_uf2_family TARGET FAMILY) picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES @@ -309,11 +418,16 @@ function(pico_set_uf2_family TARGET FAMILY) endfunction() # pico_sign_binary(TARGET [SIGFILE]) -# Sign the target binary with the given PEM signature. This sets -# PICOTOOL_SIGN_OUTPUT to true, PICOTOOL_SIGFILE to SIGFILE (if specified), -# and PICOTOOL_OTP_FILE to ${TARGET}.otp.json (if not already set). To -# specify a common SIGFILE for multiple targets, the SIGFILE property can be +# \brief\ Sign the target binary with the given PEM signature. +# +# This sets the target properties PICOTOOL_SIGN_OUTPUT to true, +# PICOTOOL_SIGFILE to SIGFILE (if specified), and PICOTOOL_OTP_FILE to +# ${TARGET}.otp.json (if not already set). +# +# To specify a common SIGFILE for multiple targets, the SIGFILE property can be # set for a given scope, and then the SIGFILE argument is optional. +# +# \param\ SIGFILE The PEM signature file to use function(pico_sign_binary TARGET) picotool_check_configurable(${TARGET}) # Enforce signing through target properties @@ -339,7 +453,9 @@ function(pico_sign_binary TARGET) endfunction() # pico_hash_binary(TARGET) -# Hash the target binary. This sets PICOTOOL_HASH_OUTPUT to true. +# \brief\ Hash the target binary. +# +# This sets the target property PICOTOOL_HASH_OUTPUT to true. function(pico_hash_binary TARGET) picotool_check_configurable(${TARGET}) # Enforce hashing through target properties @@ -349,8 +465,14 @@ function(pico_hash_binary TARGET) endfunction() # pico_embed_pt_in_binary(TARGET PTFILE) +# \brief_nodesc\ Embed a partition table in the binary +# # Create the specified partition table from JSON, and embed it in the -# block loop. This sets PICOTOOL_EMBED_PT to PTFILE. +# block loop. +# +# This sets the target property PICOTOOL_EMBED_PT to PTFILE. +# +# \param\ PTFILE The partition table JSON file to use function(pico_embed_pt_in_binary TARGET PTFILE) picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES @@ -358,19 +480,78 @@ function(pico_embed_pt_in_binary TARGET PTFILE) ) endfunction() -# pico_encrypt_binary(TARGET AESFILE [SIGFILE]) +# pico_encrypt_binary(TARGET AESFILE IVFILE [SIGFILE ] [EMBED] [MBEDTLS] [OTP_KEY_PAGE ]) +# \brief_nodesc\ Encrypt the taget binary +# # Encrypt the target binary with the given AES key (should be a binary -# file containing 32 bytes of a random key), and sign the encrypted binary. -# This sets PICOTOOL_AESFILE to AESFILE, and PICOTOOL_ENC_SIGFILE to SIGFILE -# if present, else PICOTOOL_SIGFILE. -function(pico_encrypt_binary TARGET AESFILE) +# file containing 128 bytes of a random key share, or 32 bytes of a random key), +# and sign the encrypted binary. +# +# Salts the public IV with the provided IVFILE (should be a binary file +# containing 16 bytes of a random IV), to give the IV used by the encryption. +# +# This sets the target properties PICOTOOL_AESFILE to AESFILE, PICOTOOL_IVFILE to IVFILE, and +# PICOTOOL_ENC_SIGFILE to SIGFILE if specified, else PICOTOOL_SIGFILE. +# +# Optionally, use EMBED to embed a decryption stage into the encrypted binary. +# This sets the target property PICOTOOL_EMBED_DECRYPTION to TRUE. +# +# Optionally, use MBEDTLS to to use the MbedTLS based decryption stage - this +# is faster, but offers no security against power or timing sniffing attacks, +# and takes up more code size. +# This sets the target property PICOTOOL_USE_MBEDTLS_DECRYPTION to TRUE. +# +# Optionally, use OTP_KEY_PAGE to specify the OTP page storing the AES key. +# This sets the target property PICOTOOL_OTP_KEY_PAGE to OTP_KEY_PAGE. +# +# \param\ AESFILE The AES key file to use +# \param\ IVFILE The IV file to use +# \param\ SIGFILE The PEM signature file to use +# \param\ EMBED Embed a decryption stage into the encrypted binary +# \param\ MBEDTLS Use MbedTLS based decryption stage (faster, but less secure) +# \param\ OTP_KEY_PAGE The OTP page storing the AES key +function(pico_encrypt_binary TARGET AESFILE IVFILE) + set(options EMBED MBEDTLS) + set(oneValueArgs OTP_KEY_PAGE SIGFILE) + # set(multiValueArgs ) + cmake_parse_arguments(PARSE_ARGV 3 ENC "${options}" "${oneValueArgs}" "${multiValueArgs}") picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES PICOTOOL_AESFILE ${AESFILE} ) - if (ARGC EQUAL 3) + set_target_properties(${TARGET} PROPERTIES + PICOTOOL_IVFILE ${IVFILE} + ) + + if (ENC_EMBED) + set_target_properties(${TARGET} PROPERTIES + PICOTOOL_EMBED_DECRYPTION TRUE + ) + + # Embedded decryption stage only works with packaged binaries + get_target_property(uf2_package_addr ${TARGET} PICOTOOL_UF2_PACKAGE_ADDR) + if (NOT uf2_package_addr) + set_target_properties(${TARGET} PROPERTIES + PICOTOOL_UF2_PACKAGE_ADDR 0x10000000 + ) + endif() + endif() + + if (ENC_MBEDTLS) + set_target_properties(${TARGET} PROPERTIES + PICOTOOL_USE_MBEDTLS_DECRYPTION TRUE + ) + endif() + + if (ENC_OTP_KEY_PAGE) + set_target_properties(${TARGET} PROPERTIES + PICOTOOL_OTP_KEY_PAGE ${ENC_OTP_KEY_PAGE} + ) + endif() + + if (ENC_SIGFILE) set_target_properties(${TARGET} PROPERTIES - PICOTOOL_ENC_SIGFILE ${ARGV2} + PICOTOOL_ENC_SIGFILE ${ENC_SIGFILE} ) else() get_target_property(enc_sig_file ${TARGET} PICOTOOL_ENC_SIGFILE) @@ -388,6 +569,8 @@ function(pico_encrypt_binary TARGET AESFILE) endfunction() # pico_add_uf2_output(TARGET) +# \brief_nodesc\ Add a UF2 output using picotool +# # Add a UF2 output using picotool - must be called after # all required properties have been set function(pico_add_uf2_output TARGET) @@ -401,6 +584,7 @@ function(pico_add_uf2_output TARGET) else() set(output_path "") endif() + pico_get_output_name(${TARGET} output_name) get_target_property(${TARGET}_uf2_package_addr ${TARGET} PICOTOOL_UF2_PACKAGE_ADDR) if (${TARGET}_uf2_package_addr) @@ -439,7 +623,8 @@ function(pico_add_uf2_output TARGET) --family ${picotool_family} ${extra_uf2_args} COMMAND_EXPAND_LISTS - VERBATIM) + VERBATIM + BYPRODUCTS "${output_path}${output_name}.uf2") endif() endfunction() @@ -449,6 +634,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) @@ -466,7 +657,7 @@ function(picotool_postprocess_binary TARGET) if (NOT otp_file) set(otp_file "") endif() - get_target_property(uf2_package_addr ${TARGET} PICOTOOL_UF2_PACKAGE_ADDR) + get_target_property(ensure_load_map ${TARGET} PICOTOOL_LOAD_MAP) # Embed PT properties get_target_property(picotool_embed_pt ${TARGET} PICOTOOL_EMBED_PT) @@ -479,6 +670,10 @@ function(picotool_postprocess_binary TARGET) if (picotool_aesfile) pico_add_link_depend(${TARGET} ${picotool_aesfile}) endif() + get_target_property(picotool_ivfile ${TARGET} PICOTOOL_IVFILE) + if (picotool_ivfile) + pico_add_link_depend(${TARGET} ${picotool_ivfile}) + endif() get_target_property(picotool_enc_sigfile ${TARGET} PICOTOOL_ENC_SIGFILE) if (picotool_enc_sigfile) pico_add_link_depend(${TARGET} ${picotool_enc_sigfile}) @@ -495,33 +690,51 @@ function(picotool_postprocess_binary TARGET) # Embed PT if (picotool_embed_pt) add_custom_command(TARGET ${TARGET} POST_BUILD - DEPENDS ${picotool_embed_pt} COMMAND picotool partition create --quiet ${picotool_embed_pt} $ $ VERBATIM) endif() # Signing/hashing/load maps for packaging - if ( - picotool_sign_output OR + if (picotool_sign_output OR picotool_hash_output OR - uf2_package_addr OR - extra_process_args - ) - add_custom_command(TARGET ${TARGET} POST_BUILD - DEPENDS ${picotool_sigfile} - COMMAND picotool - ARGS seal - --quiet - $ $ - ${picotool_sigfile} ${otp_file} - ${picotool_args} - COMMAND_EXPAND_LISTS - VERBATIM) + ensure_load_map OR + extra_process_args) + # We don't need the extra end block, as picotool seal will add one + target_compile_definitions(${TARGET} PRIVATE PICO_CRT0_INCLUDE_PICOBIN_END_BLOCK=0) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND picotool + ARGS seal + --quiet + $ $ + ${picotool_sigfile} ${otp_file} + ${picotool_args} + COMMAND_EXPAND_LISTS + VERBATIM) endif() # Encryption - if (picotool_aesfile) + if (picotool_aesfile AND picotool_ivfile) + get_target_property(picotool_embed_decryption ${TARGET} PICOTOOL_EMBED_DECRYPTION) + if (picotool_embed_decryption) + list(APPEND picotool_encrypt_args "--embed") + endif() + + get_target_property(picotool_mbedtls_decryption ${TARGET} PICOTOOL_USE_MBEDTLS_DECRYPTION) + if (picotool_mbedtls_decryption) + list(APPEND picotool_encrypt_args "--use-mbedtls") + endif() + + get_target_property(otp_key_page ${TARGET} PICOTOOL_OTP_KEY_PAGE) + if (otp_key_page) + list(APPEND picotool_encrypt_args "--otp-key-page" ${otp_key_page}) + endif() + add_custom_command(TARGET ${TARGET} POST_BUILD - DEPENDS ${picotool_enc_sigfile} ${picotool_aesfile} - COMMAND picotool encrypt --quiet --hash --sign $ $ ${picotool_aesfile} ${picotool_enc_sigfile} + COMMAND picotool + ARGS encrypt + --quiet --hash --sign + ${picotool_encrypt_args} + $ $ + ${picotool_aesfile} ${picotool_ivfile} ${picotool_enc_sigfile} ${otp_file} + COMMAND_EXPAND_LISTS VERBATIM) if (ARGC EQUAL 2) set(${ARGV1} TRUE PARENT_SCOPE) diff --git a/tools/Findpicotool.cmake b/tools/Findpicotool.cmake index e5bfaeaac..79a8d2ed3 100644 --- a/tools/Findpicotool.cmake +++ b/tools/Findpicotool.cmake @@ -34,10 +34,20 @@ if (NOT TARGET picotool) ) endif() + if (NOT PICOTOOL_GIT_REPOSITORY_URL) + set(PICOTOOL_GIT_REPOSITORY_URL https://github.com/raspberrypi/picotool.git) + endif() + if (NOT PICOTOOL_GIT_BRANCH) + if (PICO_SDK_VERSION_PRE_RELEASE_ID) + set(PICOTOOL_GIT_BRANCH ${PICO_SDK_VERSION_PRE_RELEASE_ID}) + else() + set(PICOTOOL_GIT_BRANCH ${PICO_SDK_VERSION_STRING}) + endif() + endif() message("Downloading Picotool") FetchContent_Populate(picotool QUIET - GIT_REPOSITORY https://github.com/raspberrypi/picotool.git - GIT_TAG develop + GIT_REPOSITORY ${PICOTOOL_GIT_REPOSITORY_URL} + GIT_TAG ${PICOTOOL_GIT_BRANCH} SOURCE_DIR ${picotool_INSTALL_DIR}/picotool-src BINARY_DIR ${picotool_INSTALL_DIR}/picotool-build diff --git a/tools/Findpioasm.cmake b/tools/Findpioasm.cmake index a5a547671..11cf44fcf 100644 --- a/tools/Findpioasm.cmake +++ b/tools/Findpioasm.cmake @@ -34,6 +34,7 @@ if (NOT TARGET pioasm) "-DCMAKE_RULE_MESSAGES=OFF" # quieten the build "-DCMAKE_INSTALL_MESSAGE=NEVER" # quieten the install CMAKE_CACHE_ARGS "-DPIOASM_EXTRA_SOURCE_FILES:STRING=${PIOASM_EXTRA_SOURCE_FILES}" + "-DPIOASM_VERSION_STRING:STRING=${PICO_SDK_VERSION_STRING}" BUILD_ALWAYS 1 # force dependency checking EXCLUDE_FROM_ALL TRUE ) diff --git a/tools/build_all_headers.py b/tools/build_all_headers.py index fc047d999..a3e4f04b3 100755 --- a/tools/build_all_headers.py +++ b/tools/build_all_headers.py @@ -24,11 +24,15 @@ 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 @@ 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,69 @@ 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) + +# 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 + */ -with open(output_header, 'w') as fh: - fh.write('''/* +// This file is autogenerated, do not edit by hand + +''') + 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 @@ -77,11 +142,22 @@ // 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_define = None + for f in sorted(all_include_files, key=lambda x: os.path.split(x)): + if f in include_files_by_chip['rp2040']: + define = 'PICO_RP2040' + elif f in include_files_by_chip['rp2350']: + define = 'PICO_RP2350' + else: + define = None + if define != last_define: + if last_define is not None: + fh.write('#endif\n') + if define is not None: + fh.write('#if {}\n'.format(define)) + fh.write('#include "{}"\n'.format(f)) + last_define = define + if last_define is not None: + fh.write('#endif\n') + fh.write('\n') diff --git a/tools/check_all_board_headers.sh b/tools/check_all_board_headers.sh index bdbe3f773..290921791 100755 --- a/tools/check_all_board_headers.sh +++ b/tools/check_all_board_headers.sh @@ -1,7 +1,12 @@ #!/bin/bash + +EXIT_CODE=0 + for HEADER in src/boards/include/boards/*.h; do tools/check_board_header.py $HEADER if [[ $? -ne 0 ]]; then - break + EXIT_CODE=1 fi done + +exit $EXIT_CODE diff --git a/tools/check_board_header.py b/tools/check_board_header.py index c259c8131..5a5c84e63 100755 --- a/tools/check_board_header.py +++ b/tools/check_board_header.py @@ -20,6 +20,14 @@ from collections import namedtuple +if sys.version_info < (3, 11): + # Python <3.11 doesn't have ExceptionGroup, so define a simple one + class ExceptionGroup(Exception): + def __init__(self, message, errors): + message += "\n" + "\n".join(str(e) for e in errors) + super().__init__(message) + + # warnings off by default, because some boards use the same pin for multiple purposes show_warnings = False @@ -65,6 +73,7 @@ def list_to_string_with(lst, joiner): def read_defines_from(header_file, defines_dict): + errors = [] with open(header_file) as fh: last_ifndef = None last_ifndef_lineno = -1 @@ -75,35 +84,46 @@ def read_defines_from(header_file, defines_dict): # strip trailing comments line = re.sub(r"(?<=\S)\s*//.*$", "", line) - # look for "// pico_cmake_set BLAH_BLAH=42" - m = re.match(r"^\s*//\s*pico_cmake_set\s+(\w+)\s*=\s*(.+?)\s*$", line) + # look for "// old_comment BLAH_BLAH=42" and suggest changing it to "new_macro(BLAH_BLAH, 42)" + for (old_comment, new_macro) in ( + ('pico_cmake_set', 'pico_board_cmake_set'), + ('pico_cmake_set_default', 'pico_board_cmake_set_default') + ): + m = re.match(r"^\s*//\s*{}\s+(\w+)\s*=\s*(.+?)\s*$".format(old_comment), line) + if m: + name = m.group(1) + value = m.group(2) + errors.append(Exception("{}:{} \"// {} {}={}\" should be replaced with \"{}({}, {})\"".format(board_header, lineno, old_comment, name, value, new_macro, name, value))) + + # look for "pico_board_cmake_set(BLAH_BLAH, 42)" + m = re.match(r"^\s*pico_board_cmake_set\s*\(\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*,\s*(.*)\s*\)\s*$", line) if m: #print(m.groups()) name = m.group(1) value = m.group(2) # check all uppercase if name != name.upper(): - raise Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name)) + errors.append(Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name))) # check for multiply-defined values if name in cmake_settings: if cmake_settings[name].value != value: - raise Exception("{}:{} Conflicting values for pico_cmake_set {} ({} and {})".format(board_header, lineno, name, cmake_settings[name].value, value)) + errors.append(Exception("{}:{} Conflicting values for pico_board_cmake_set({}) ({} and {})".format(board_header, lineno, name, cmake_settings[name].value, value))) else: if show_warnings: - warnings.warn("{}:{} Multiple values for pico_cmake_set {} ({} and {})".format(board_header, lineno, name, cmake_settings[name].value, value)) + warnings.warn("{}:{} Multiple values for pico_board_cmake_set({}) ({} and {})".format(board_header, lineno, name, cmake_settings[name].value, value)) else: cmake_settings[name] = DefineType(name, value, None, lineno) continue - # look for "// pico_cmake_set_default BLAH_BLAH=42" - m = re.match(r"^\s*//\s*pico_cmake_set_default\s+(\w+)\s*=\s*(.+?)\s*$", line) + # look for "pico_board_cmake_set_default(BLAH_BLAH, 42)" + m = re.match(r"^\s*pico_board_cmake_set_default\s*\(\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*,\s*(.*)\s*\)\s*$", line) if m: #print(m.groups()) name = m.group(1) value = m.group(2) # check all uppercase if name != name.upper(): - raise Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name)) + errors.append(Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name))) if name not in cmake_default_settings: cmake_default_settings[name] = DefineType(name, value, None, lineno) continue @@ -119,7 +139,7 @@ def read_defines_from(header_file, defines_dict): if m: validity_stack.pop() continue - + if validity_stack[-1]: # look for "#include "foo.h" m = re.match(r"""^\s*#include\s+"(.+?)"\s*$""", line) @@ -129,7 +149,7 @@ def read_defines_from(header_file, defines_dict): assert include.endswith(".h") # assume that the include is also in the boards directory assert "/" not in include or include.startswith("boards/") - read_defines_from(os.path.join(os.path.dirname(board_header), os.path.basename(include)), defines) + errors.extend(read_defines_from(os.path.join(os.path.dirname(board_header), os.path.basename(include)), defines)) continue # look for "#if BLAH_BLAH" @@ -164,11 +184,11 @@ def read_defines_from(header_file, defines_dict): value = m.group(2) # check all uppercase if name != name.upper(): - raise Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name)) + errors.append(Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name))) # check that adjacent #ifndef and #define lines match up if last_ifndef_lineno + 1 == lineno: if last_ifndef != name: - raise Exception("{}:{} #ifndef {} / #define {} mismatch".format(board_header, last_ifndef_lineno, last_ifndef, name)) + errors.append(Exception("{}:{} #ifndef {} / #define {} mismatch".format(board_header, last_ifndef_lineno, last_ifndef, name))) if value: try: # most board-defines are integer values @@ -186,16 +206,20 @@ def read_defines_from(header_file, defines_dict): # check for multiply-defined values if name in defines_dict: if defines_dict[name].value != value: - raise Exception("{}:{} Conflicting definitions for {} ({} and {})".format(board_header, lineno, name, defines_dict[name].value, value)) + errors.append(Exception("{}:{} Conflicting definitions for {} ({} and {})".format(board_header, lineno, name, defines_dict[name].value, value))) else: if show_warnings: warnings.warn("{}:{} Multiple definitions for {} ({} and {})".format(board_header, lineno, name, defines_dict[name].value, value)) else: defines_dict[name] = DefineType(name, value, resolved_value, lineno) + return errors 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) + +errors = [] with open(board_header) as header_fh: last_ifndef = None @@ -208,32 +232,43 @@ def read_defines_from(header_file, defines_dict): line = re.sub(r"(?<=\S)\s*//.*$", "", line) # look for board-detection comment - if re.match("^\s*// For board detection", line): + if re.match(r"^\s*// For board detection", line): board_detection_is_next = True continue # check include-suggestion - m = re.match("^\s*// This header may be included by other board headers as \"(.+?)\"", line) + m = re.match(r"""^\s*// This header may be included by other board headers as "(.+?)"$""", line) if m: include_suggestion = m.group(1) if include_suggestion == expected_include_suggestion: has_include_suggestion = True else: - raise Exception("{}:{} Suggests including \"{}\" but file is named \"{}\"".format(board_header, lineno, include_suggestion, expected_include_suggestion)) + errors.append(Exception("{}:{} Suggests including \"{}\" but file is named \"{}\"".format(board_header, lineno, include_suggestion, expected_include_suggestion))) continue - # look for "// pico_cmake_set BLAH_BLAH=42" - m = re.match(r"^\s*//\s*pico_cmake_set\s+(\w+)\s*=\s*(.+?)\s*$", line) + # look for "// old_comment BLAH_BLAH=42" and suggest changing it to "new_macro(BLAH_BLAH, 42)" + for (old_comment, new_macro) in ( + ('pico_cmake_set', 'pico_board_cmake_set'), + ('pico_cmake_set_default', 'pico_board_cmake_set_default') + ): + m = re.match(r"^\s*//\s*{}\s+(\w+)\s*=\s*(.+?)\s*$".format(old_comment), line) + if m: + name = m.group(1) + value = m.group(2) + errors.append(Exception("{}:{} \"// {} {}={}\" should be replaced with \"{}({}, {})\"".format(board_header, lineno, old_comment, name, value, new_macro, name, value))) + + # look for "pico_board_cmake_set(BLAH_BLAH, 42)" + m = re.match(r"^\s*pico_board_cmake_set\s*\(\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*,\s*(.*)\s*\)\s*$", line) if m: #print(m.groups()) name = m.group(1) value = m.group(2) # check all uppercase if name != name.upper(): - raise Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name)) + errors.append(Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name))) # check for multiply-defined values if name in cmake_settings: - raise Exception("{}:{} Multiple values for pico_cmake_set {} ({} and {})".format(board_header, lineno, name, cmake_settings[name].value, value)) + errors.append(Exception("{}:{} Multiple values for pico_board_cmake_set({}) ({} and {})".format(board_header, lineno, name, cmake_settings[name].value, value))) else: if value: try: @@ -244,18 +279,18 @@ def read_defines_from(header_file, defines_dict): cmake_settings[name] = DefineType(name, value, None, lineno) continue - # look for "// pico_cmake_set_default BLAH_BLAH=42" - m = re.match(r"^\s*//\s*pico_cmake_set_default\s+(\w+)\s*=\s*(.+?)\s*$", line) + # look for "pico_board_cmake_set_default(BLAH_BLAH, 42)" + m = re.match(r"^\s*pico_board_cmake_set_default\s*\(\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*,\s*(.*)\s*\)\s*$", line) if m: #print(m.groups()) name = m.group(1) value = m.group(2) # check all uppercase if name != name.upper(): - raise Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name)) + errors.append(Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name))) # check for multiply-defined values if name in cmake_default_settings: - raise Exception("{}:{} Multiple values for pico_cmake_set_default {} ({} and {})".format(board_header, lineno, name, cmake_default_settings[name].value, value)) + errors.append(Exception("{}:{} Multiple values for pico_board_cmake_set_default({}) ({} and {})".format(board_header, lineno, name, cmake_default_settings[name].value, value))) else: if value: try: @@ -277,7 +312,7 @@ def read_defines_from(header_file, defines_dict): if m: validity_stack.pop() continue - + if validity_stack[-1]: # look for "#include "foo.h" m = re.match(r"""^\s*#include\s+"(.+?)"\s*$""", line) @@ -287,7 +322,7 @@ def read_defines_from(header_file, defines_dict): assert include.endswith(".h") # assume that the include is also in the boards directory assert "/" not in include or include.startswith("boards/") - read_defines_from(os.path.join(os.path.dirname(board_header), os.path.basename(include)), defines) + errors.extend(read_defines_from(os.path.join(os.path.dirname(board_header), os.path.basename(include)), defines)) continue # look for "#if BLAH_BLAH" @@ -321,11 +356,11 @@ def read_defines_from(header_file, defines_dict): value = m.group(2) # check all uppercase if name != name.upper(): - raise Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name)) + errors.append(Exception("{}:{} Expected \"{}\" to be all uppercase".format(board_header, lineno, name))) # check that adjacent #ifndef and #define lines match up if last_ifndef_lineno + 1 == lineno: if last_ifndef != name: - raise Exception("{}:{} #ifndef {} / #define {} mismatch".format(board_header, last_ifndef_lineno, last_ifndef, name)) + errors.append(Exception("{}:{} #ifndef {} / #define {} mismatch".format(board_header, last_ifndef_lineno, last_ifndef, name))) if value: try: # most board-defines are integer values @@ -344,28 +379,28 @@ def read_defines_from(header_file, defines_dict): if re.match(r"^_BOARDS_(\w+)_H$", name): # check it has an #ifndef if last_ifndef_lineno +1 != lineno: - raise Exception("{}:{} Include-guard #define {} is missing an #ifndef".format(board_header, lineno, name)) + errors.append(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): - raise Exception("{}:{} Include-guard #define {} should be the first define".format(board_header, lineno, name)) + errors.append(Exception("{}:{} Include-guard #define {} shouldn't have a value".format(board_header, lineno, name))) + if any(defines[d].lineno >= 0 for d in defines): + errors.append(Exception("{}:{} Include-guard #define {} should be the first define".format(board_header, lineno, name))) if name == expected_include_guard: has_include_guard = True else: - raise Exception("{}:{} Found include-guard #define {} but expected {}".format(board_header, lineno, name, expected_include_guard)) + errors.append(Exception("{}:{} Found include-guard #define {} but expected {}".format(board_header, lineno, name, expected_include_guard))) # check board-detection define if board_detection_is_next: board_detection_is_next = False if value: - raise Exception("{}:{} Board-detection #define {} shouldn't have a value".format(board_header, lineno, name)) + errors.append(Exception("{}:{} Board-detection #define {} shouldn't have a value".format(board_header, lineno, name))) # this is a bit messy because pico.h does "#define RASPBERRYPI_PICO" and metrotech_xerxes_rp2040.h does "#define XERXES_RP2040" if name.endswith(expected_board_detection) or expected_board_detection.endswith(name): has_board_detection = True else: - raise Exception("{}:{} Board-detection #define {} should end with {}".format(board_header, lineno, name, expected_board_detection)) + errors.append(Exception("{}:{} Board-detection #define {} should end with {}".format(board_header, lineno, name, expected_board_detection))) # check for multiply-defined values if name in defines: - raise Exception("{}:{} Multiple definitions for {} ({} and {})".format(board_header, lineno, name, defines[name].value, value)) + errors.append(Exception("{}:{} Multiple definitions for {} ({} and {})".format(board_header, lineno, name, defines[name].value, value))) else: defines[name] = DefineType(name, value, resolved_value, lineno) continue @@ -381,40 +416,54 @@ def read_defines_from(header_file, defines_dict): else: for setting in compulsory_cmake_settings: if setting not in cmake_settings: - raise Exception("{} is missing a pico_cmake_set {} comment".format(board_header, setting)) + errors.append(Exception("{} is missing a pico_board_cmake_set({}, XXX) call".format(board_header, setting))) + + # Must be raised before continuing, in case compulsory settings are missing + if errors: + raise ExceptionGroup("Errors in {}".format(board_header), errors) if cmake_settings['PICO_PLATFORM'].value == "rp2040": chip = 'RP2040' 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: + errors.append(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: + errors.append(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')) + errors.append(Exception("{} uses chip {} but is missing a pico_board_cmake_set_default({}, XXX) call".format(board_header, chip, 'PICO_RP2350_A2_SUPPORTED'))) if 'PICO_RP2350_A2_SUPPORTED' not in defines: - raise Exception("{} uses chip {} but is missing a #define {}".format(board_header, chip, 'PICO_RP2350_A2_SUPPORTED')) - if defines['PICO_RP2350_A2_SUPPORTED'].resolved_value != 1: - raise Exception("{} sets #define {} {} (should be 1)".format(board_header, chip, 'PICO_RP2350_A2_SUPPORTED', defines['PICO_RP2350_A2_SUPPORTED'].resolved_value)) + errors.append(Exception("{} uses chip {} but is missing a #define {}".format(board_header, chip, 'PICO_RP2350_A2_SUPPORTED'))) + elif defines['PICO_RP2350_A2_SUPPORTED'].resolved_value != 1: + errors.append(Exception("{} sets #define {} {} (should be 1)".format(board_header, chip, 'PICO_RP2350_A2_SUPPORTED', defines['PICO_RP2350_A2_SUPPORTED'].resolved_value))) for setting in compulsory_cmake_default_settings: if setting not in cmake_default_settings: - raise Exception("{} is missing a pico_cmake_set_default {} comment".format(board_header, setting)) + errors.append(Exception("{} is missing a pico_board_cmake_set_default({}, XXX) call".format(board_header, setting))) for setting in matching_cmake_default_settings: if setting in cmake_default_settings and setting not in defines: - raise Exception("{} has pico_cmake_set_default {} but is missing a matching #define".format(board_header, setting)) + errors.append(Exception("{} has pico_board_cmake_set_default({}, XXX) but is missing a matching #define".format(board_header, setting))) elif setting in defines and setting not in cmake_default_settings: - raise Exception("{} has #define {} but is missing a matching pico_cmake_set_default comment".format(board_header, setting)) + errors.append(Exception("{} has #define {} but is missing a matching pico_board_cmake_set_default({}, XXX) call".format(board_header, setting, setting))) elif setting in defines and setting in cmake_default_settings: if cmake_default_settings[setting].value != defines[setting].resolved_value: - raise Exception("{} has mismatched pico_cmake_set_default and #define values for {}".format(board_header, setting)) + errors.append(Exception("{} has mismatched pico_board_cmake_set_default and #define values for {}".format(board_header, setting))) for setting in compulsory_defines: if setting not in defines: - raise Exception("{} is missing a #define {}".format(board_header, setting)) + errors.append(Exception("{} is missing a #define {}".format(board_header, setting))) if chip is None: - raise Exception("Couldn't determine chip for {}".format(board_header)) + errors.append(Exception("Couldn't determine chip for {}".format(board_header))) + +# Must be raised before continuing, in case chip is not determined +if errors: + raise ExceptionGroup("Errors in {}".format(board_header), errors) + interfaces_json = chip_interfaces[chip] if not os.path.isfile(interfaces_json): raise Exception("{} doesn't exist".format(interfaces_json)) @@ -437,14 +486,14 @@ def read_defines_from(header_file, defines_dict): # check for other-chip defines if other_chip in name: - raise Exception("{}:{} Header is for {} and so shouldn't have settings for {} ({})".format(board_header, define.lineno, chip, other_chip, name)) + errors.append(Exception("{}:{} Header is for {} and so shouldn't have settings for {} ({})".format(board_header, define.lineno, chip, other_chip, name))) # check for pin-conflicts if name.endswith("_PIN"): if define.resolved_value is None: - raise Exception("{}:{} {} is set to an undefined value".format(board_header, define.lineno, name)) + errors.append(Exception("{}:{} {} is set to an undefined value".format(board_header, define.lineno, name))) elif not isinstance(define.resolved_value, int): - raise Exception("{}:{} {} resolves to a non-integer value {}".format(board_header, define.lineno, name, define.resolved_value)) + errors.append(Exception("{}:{} {} resolves to a non-integer value {}".format(board_header, define.lineno, name, define.resolved_value))) else: if define.resolved_value in pins and define.resolved_value == define.value: if show_warnings: @@ -452,7 +501,7 @@ def read_defines_from(header_file, defines_dict): pins[define.resolved_value].append(define) else: if define.resolved_value not in allowed_pins: - raise Exception("{}:{} Pin {} for {} isn't a valid pin-number".format(board_header, define.lineno, define.resolved_value, name)) + errors.append(Exception("{}:{} Pin {} for {} isn't a valid pin-number".format(board_header, define.lineno, define.resolved_value, name))) pins[define.resolved_value] = [define] # check for invalid DEFAULT mappings @@ -464,44 +513,52 @@ def read_defines_from(header_file, defines_dict): if interface == "WS2812": continue if interface not in allowed_interfaces: - raise Exception("{}:{} {} is defined but {} isn't in {}".format(board_header, define.lineno, name, interface, interfaces_json)) + errors.append(Exception("{}:{} {} is defined but {} isn't in {}".format(board_header, define.lineno, name, interface, interfaces_json))) + continue if instance_name not in defines: - raise Exception("{}:{} {} is defined but {} isn't defined".format(board_header, define.lineno, name, instance_name)) + errors.append(Exception("{}:{} {} is defined but {} isn't defined".format(board_header, define.lineno, name, instance_name))) + continue instance_define = defines[instance_name] instance_num = instance_define.resolved_value if instance_num not in allowed_interfaces[interface]["instances"]: - raise Exception("{}:{} {} is set to an invalid instance {}".format(board_header, instance_define.lineno, instance_define, instance_num)) + errors.append(Exception("{}:{} {} is set to an invalid instance {}".format(board_header, instance_define.lineno, instance_define, instance_num))) + continue interface_instance = allowed_interfaces[interface]["instances"][instance_num] if function not in interface_instance: - raise Exception("{}:{} {} is defined but {} isn't a valid function for {}".format(board_header, define.lineno, name, function, instance_define)) + errors.append(Exception("{}:{} {} is defined but {} isn't a valid function for {}".format(board_header, define.lineno, name, function, instance_define))) + continue if define.resolved_value not in interface_instance[function]: - raise Exception("{}:{} {} is set to {} which isn't a valid pin for {} on {} {}".format(board_header, define.lineno, name, define.resolved_value, function, interface, instance_num)) + errors.append(Exception("{}:{} {} is set to {} which isn't a valid pin for {} on {} {}".format(board_header, define.lineno, name, define.resolved_value, function, interface, instance_num))) # check that each used DEFAULT interface includes (at least) the expected pin-functions m = re.match("^PICO_DEFAULT_([A-Z0-9]+)$", name) if m: interface = m.group(1) if interface not in allowed_interfaces: - raise Exception("{}:{} {} is defined but {} isn't in {}".format(board_header, define.lineno, name, interface, interfaces_json)) + errors.append(Exception("{}:{} {} is defined but {} isn't in {}".format(board_header, define.lineno, name, interface, interfaces_json))) + continue if "expected_functions" in allowed_interfaces[interface]: expected_functions = allowed_interfaces[interface]["expected_functions"] if "required" in expected_functions: for function in expected_functions["required"]: expected_function_pin = "{}_{}_PIN".format(name, function) if expected_function_pin not in defines: - raise Exception("{}:{} {} is defined but {} isn't defined".format(board_header, define.lineno, name, expected_function_pin)) + errors.append(Exception("{}:{} {} is defined but {} isn't defined".format(board_header, define.lineno, name, expected_function_pin))) if "one_of" in expected_functions: expected_function_pins = list("{}_{}_PIN".format(name, function) for function in expected_functions["one_of"]) if not any(func_pin in defines for func_pin in expected_function_pins): - raise Exception("{}:{} {} is defined but none of {} are defined".format(board_header, define.lineno, name, list_to_string_with(expected_function_pins, "or"))) + errors.append(Exception("{}:{} {} is defined but none of {} are defined".format(board_header, define.lineno, name, list_to_string_with(expected_function_pins, "or")))) if not has_include_guard: - raise Exception("{} has no include-guard (expected {})".format(board_header, expected_include_guard)) + errors.append(Exception("{} has no include-guard (expected {})".format(board_header, expected_include_guard))) if not has_board_detection and expected_board_detection != "NONE": - raise Exception("{} has no board-detection #define (expected {})".format(board_header, expected_board_detection)) + errors.append(Exception("{} has no board-detection #define (expected {})".format(board_header, expected_board_detection))) # lots of headers don't have this #if not has_include_suggestion: # raise Exception("{} has no include-suggestion (expected {})".format(board_header, expected_include_suggestion)) +if errors: + raise ExceptionGroup("Errors in {}".format(board_header), errors) + # Check that #if / #ifdef / #ifndef / #else / #endif are correctly balanced assert len(validity_stack) == 1 and validity_stack[0] diff --git a/tools/compare_build_systems.py b/tools/compare_build_systems.py index badeadee1..583e51838 100755 --- a/tools/compare_build_systems.py +++ b/tools/compare_build_systems.py @@ -135,6 +135,7 @@ # Bazel configuration for 3p deps. "PICO_BTSTACK_CONFIG", "PICO_LWIP_CONFIG", + "PICO_MBEDTLS_CONFIG", "PICO_FREERTOS_LIB", "PICO_MBEDTLS_LIB", # CMake has PICO_DEFAULT_CLIB, but it's not user-facing. @@ -157,6 +158,10 @@ "PICO_BT_ENABLE_BLE", "PICO_BT_ENABLE_CLASSIC", "PICO_BT_ENABLE_MESH", + # Compilation modes remove, These allow the user to remove the defaults, with no args. See --compilation_mode cmd line option + "PICO_COMPILATION_NO_OPT_ARGS", + "PICO_COMPILATION_NO_DEBUG_ARGS", + "PICO_COMPILATION_NO_FASTBUILD_ARGS", ) diff --git a/tools/example_keys/private.pem b/tools/example_keys/private.pem new file mode 100644 index 000000000..bf777d897 --- /dev/null +++ b/tools/example_keys/private.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQACg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIAXAdiilH8wT07TESUzWPt+BY9+NcchvYU3xbnpK+CBNoAcGBSuBBAAK +oUQDQgAEYYJtMQFGW4AB94tU3u/Qir5sRcYjBYMqCa+8gxsYd9OwMS3dqWKsnVBz +dyy7bFWdJzXDMb9o20xRRd57Q9xSYw== +-----END EC PRIVATE KEY----- diff --git a/tools/example_keys/privateaes.bin b/tools/example_keys/privateaes.bin new file mode 100644 index 000000000..21a47756d Binary files /dev/null and b/tools/example_keys/privateaes.bin differ diff --git a/tools/extract_build_defines.py b/tools/extract_build_defines.py index 179f084ec..8df16ee88 100755 --- a/tools/extract_build_defines.py +++ b/tools/extract_build_defines.py @@ -24,6 +24,13 @@ from collections import defaultdict +if sys.version_info < (3, 11): + # Python <3.11 doesn't have ExceptionGroup, so define a simple one + class ExceptionGroup(Exception): + def __init__(self, message, errors): + message += "\n" + "\n".join(str(e) for e in errors) + super().__init__(message) + logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) @@ -51,11 +58,12 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): _type = config_attrs.get('type') + errors = [] # Validate attrs for key in config_attrs.keys(): if key not in ALLOWED_CONFIG_PROPERTIES: - raise Exception('{} at {}:{} has unexpected property "{}"'.format(config_name, file_path, linenum, key)) + errors.append(Exception('{} at {}:{} has unexpected property "{}"'.format(config_name, file_path, linenum, key))) if _type == 'int': _min = _max = _default = None @@ -86,13 +94,13 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): pass if _min is not None and _max is not None: if _min > _max: - raise Exception('{} at {}:{} has min {} > max {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['max'])) + errors.append(Exception('{} at {}:{} has min {} > max {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['max']))) if _min is not None and _default is not None: if _min > _default: - raise Exception('{} at {}:{} has min {} > default {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['default'])) + errors.append(Exception('{} at {}:{} has min {} > default {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['default']))) if _default is not None and _max is not None: if _default > _max: - raise Exception('{} at {}:{} has default {} > max {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['max'])) + errors.append(Exception('{} at {}:{} has default {} > max {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['max']))) elif _type == 'bool': assert 'min' not in config_attrs assert 'max' not in config_attrs @@ -111,10 +119,12 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): assert 'max' not in config_attrs _default = config_attrs.get('default', None) else: - raise Exception("Found unknown {} type {} at {}:{}".format(BASE_BUILD_DEFINE_NAME, _type, file_path, linenum)) - + errors.append(Exception("Found unknown {} type {} at {}:{}".format(BASE_BUILD_DEFINE_NAME, _type, file_path, linenum))) + + return errors +errors = [] # Scan all CMakeLists.txt and .cmake files in the specific path, recursively. @@ -135,14 +145,14 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): linenum += 1 line = line.strip() if BASE_CONFIG_RE.search(line): - raise Exception("Found {} at {}:{} ({}) which isn't expected in {} files".format(BASE_CONFIG_NAME, file_path, linenum, line, filename if filename == 'CMakeLists.txt' else file_ext)) + errors.append(Exception("Found {} at {}:{} ({}) which isn't expected in {} files".format(BASE_CONFIG_NAME, file_path, linenum, line, filename if filename == 'CMakeLists.txt' else file_ext))) elif BASE_BUILD_DEFINE_RE.search(line): m = BUILD_DEFINE_RE.match(line) if not m: if re.match(r"^\s*#\s*# ", line): logger.info("Possible misformatted {} at {}:{} ({})".format(BASE_BUILD_DEFINE_NAME, file_path, linenum, line)) else: - raise Exception("Found misformatted {} at {}:{} ({})".format(BASE_BUILD_DEFINE_NAME, file_path, linenum, line)) + errors.append(Exception("Found misformatted {} at {}:{} ({})".format(BASE_BUILD_DEFINE_NAME, file_path, linenum, line))) else: config_name = m.group(1) config_description = m.group(2) @@ -151,10 +161,10 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): _attrs = re.sub(r'(\(.+\))', lambda m: m.group(1).replace(',', '\0'), _attrs) if '=' in config_description: - raise Exception("For {} at {}:{} the description was set to '{}' - has the description field been omitted?".format(config_name, file_path, linenum, config_description)) + errors.append(Exception("For {} at {}:{} the description was set to '{}' - has the description field been omitted?".format(config_name, file_path, linenum, config_description))) all_descriptions = chips_all_descriptions[applicable] if config_description in all_descriptions: - raise Exception("Found description {} at {}:{} but it was already used at {}:{}".format(config_description, file_path, linenum, os.path.join(scandir, all_descriptions[config_description]['filename']), all_descriptions[config_description]['line_number'])) + errors.append(Exception("Found description {} at {}:{} but it was already used at {}:{}".format(config_description, file_path, linenum, os.path.join(scandir, all_descriptions[config_description]['filename']), all_descriptions[config_description]['line_number']))) else: all_descriptions[config_description] = {'config_name': config_name, 'filename': os.path.relpath(file_path, scandir), 'line_number': linenum} @@ -168,19 +178,19 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): try: k, v = (i.strip() for i in item.split('=')) except ValueError: - raise Exception('{} at {}:{} has malformed value {}'.format(config_name, file_path, linenum, item)) + errors.append(Exception('{} at {}:{} has malformed value {}'.format(config_name, file_path, linenum, item))) config_attrs[k] = v.replace('\0', ',') all_attrs.add(k) prev = item #print(file_path, config_name, config_attrs) if 'group' not in config_attrs: - raise Exception('{} at {}:{} has no group attribute'.format(config_name, file_path, linenum)) + errors.append(Exception('{} at {}:{} has no group attribute'.format(config_name, file_path, linenum))) #print(file_path, config_name, config_attrs) all_configs = chips_all_configs[applicable] if config_name in all_configs: - raise Exception("Found {} at {}:{} but it was already declared at {}:{}".format(config_name, file_path, linenum, os.path.join(scandir, all_configs[config_name]['filename']), all_configs[config_name]['line_number'])) + errors.append(Exception("Found {} at {}:{} but it was already declared at {}:{}".format(config_name, file_path, linenum, os.path.join(scandir, all_configs[config_name]['filename']), all_configs[config_name]['line_number']))) else: all_configs[config_name] = {'attrs': config_attrs, 'filename': os.path.relpath(file_path, scandir), 'line_number': linenum, 'description': config_description} @@ -194,14 +204,14 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): file_path = os.path.join(scandir, config_obj['filename']) linenum = config_obj['line_number'] - ValidateAttrs(config_name, config_obj['attrs'], file_path, linenum) + errors.extend(ValidateAttrs(config_name, config_obj['attrs'], file_path, linenum)) # All settings in "host" should also be in "all" for config_name, config_obj in chips_all_configs["host"].items(): if config_name not in chips_all_configs["all"]: file_path = os.path.join(scandir, config_obj['filename']) linenum = config_obj['line_number'] - raise Exception("Found 'host' config {} at {}:{}, but no matching non-host config found".format(config_name, file_path, linenum)) + errors.append(Exception("Found 'host' config {} at {}:{}, but no matching non-host config found".format(config_name, file_path, linenum))) # Any chip-specific settings should not be in "all" for chip in CHIP_NAMES: @@ -212,7 +222,7 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): chip_linenum = chip_config_obj['line_number'] all_file_path = os.path.join(scandir, all_config_obj['filename']) all_linenum = all_config_obj['line_number'] - raise Exception("'{}' config {} at {}:{} also found at {}:{}".format(chip, config_name, chip_file_path, chip_linenum, all_file_path, all_linenum)) + errors.append(Exception("'{}' config {} at {}:{} also found at {}:{}".format(chip, config_name, chip_file_path, chip_linenum, all_file_path, all_linenum))) def build_mismatch_exception_message(name, thing, config_obj1, value1, config_obj2, value2): obj1_filepath = os.path.join(scandir, config_obj1['filename']) @@ -232,14 +242,18 @@ def build_mismatch_exception_message(name, thing, config_obj1, value1, config_ob applicable_value = applicable_config_obj[field] other_value = other_config_obj[field] if applicable_value != other_value: - raise Exception(build_mismatch_exception_message(config_name, field, applicable_config_obj, applicable_value, other_config_obj, other_value)) + errors.append(Exception(build_mismatch_exception_message(config_name, field, applicable_config_obj, applicable_value, other_config_obj, other_value))) # Check that attributes match for attr in applicable_config_obj['attrs']: if attr != 'default': # totally fine for defaults to vary per-platform applicable_value = applicable_config_obj['attrs'][attr] other_value = other_config_obj['attrs'][attr] if applicable_value != other_value: - raise Exception(build_mismatch_exception_message(config_name, "attribute '{}'".format(attr), applicable_config_obj, applicable_value, other_config_obj, other_value)) + errors.append(Exception(build_mismatch_exception_message(config_name, "attribute '{}'".format(attr), applicable_config_obj, applicable_value, other_config_obj, other_value))) + +# Raise errors if any were found +if errors: + raise ExceptionGroup("Errors in {}".format(outfile), errors) # Sort the output alphabetically by name and then by chip output_rows = set() diff --git a/tools/extract_cmake_configs.py b/tools/extract_cmake_configs.py index 18884330f..b86df28dc 100755 --- a/tools/extract_cmake_configs.py +++ b/tools/extract_cmake_configs.py @@ -24,6 +24,13 @@ from collections import defaultdict +if sys.version_info < (3, 11): + # Python <3.11 doesn't have ExceptionGroup, so define a simple one + class ExceptionGroup(Exception): + def __init__(self, message, errors): + message += "\n" + "\n".join(str(e) for e in errors) + super().__init__(message) + logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) @@ -51,11 +58,12 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): _type = config_attrs.get('type') + errors = [] # Validate attrs for key in config_attrs.keys(): if key not in ALLOWED_CONFIG_PROPERTIES: - raise Exception('{} at {}:{} has unexpected property "{}"'.format(config_name, file_path, linenum, key)) + errors.append(Exception('{} at {}:{} has unexpected property "{}"'.format(config_name, file_path, linenum, key))) if _type == 'int': _min = _max = _default = None @@ -86,13 +94,13 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): pass if _min is not None and _max is not None: if _min > _max: - raise Exception('{} at {}:{} has min {} > max {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['max'])) + errors.append(Exception('{} at {}:{} has min {} > max {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['max']))) if _min is not None and _default is not None: if _min > _default: - raise Exception('{} at {}:{} has min {} > default {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['default'])) + errors.append(Exception('{} at {}:{} has min {} > default {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['default']))) if _default is not None and _max is not None: if _default > _max: - raise Exception('{} at {}:{} has default {} > max {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['max'])) + errors.append(Exception('{} at {}:{} has default {} > max {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['max']))) elif _type == 'bool': assert 'min' not in config_attrs assert 'max' not in config_attrs @@ -111,10 +119,11 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): assert 'max' not in config_attrs _default = config_attrs.get('default', None) else: - raise Exception("Found unknown {} type {} at {}:{}".format(BASE_CMAKE_CONFIG_NAME, _type, file_path, linenum)) - + errors.append(Exception("Found unknown {} type {} at {}:{}".format(BASE_CMAKE_CONFIG_NAME, _type, file_path, linenum))) + return errors +errors = [] # Scan all CMakeLists.txt and .cmake files in the specific path, recursively. @@ -135,14 +144,14 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): linenum += 1 line = line.strip() if BASE_CONFIG_RE.search(line): - raise Exception("Found {} at {}:{} ({}) which isn't expected in {} files".format(BASE_CONFIG_NAME, file_path, linenum, line, filename if filename == 'CMakeLists.txt' else file_ext)) + errors.append(Exception("Found {} at {}:{} ({}) which isn't expected in {} files".format(BASE_CONFIG_NAME, file_path, linenum, line, filename if filename == 'CMakeLists.txt' else file_ext))) elif BASE_CMAKE_CONFIG_RE.search(line): m = CMAKE_CONFIG_RE.match(line) if not m: - if re.match("^\s*#\s*# ", line): + if re.match(r"^\s*#\s*# ", line): logger.info("Possible misformatted {} at {}:{} ({})".format(BASE_CMAKE_CONFIG_NAME, file_path, linenum, line)) else: - raise Exception("Found misformatted {} at {}:{} ({})".format(BASE_CMAKE_CONFIG_NAME, file_path, linenum, line)) + errors.append(Exception("Found misformatted {} at {}:{} ({})".format(BASE_CMAKE_CONFIG_NAME, file_path, linenum, line))) else: config_name = m.group(1) config_description = m.group(2) @@ -151,10 +160,10 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): _attrs = re.sub(r'(\(.+\))', lambda m: m.group(1).replace(',', '\0'), _attrs) if '=' in config_description: - raise Exception("For {} at {}:{} the description was set to '{}' - has the description field been omitted?".format(config_name, file_path, linenum, config_description)) + errors.append(Exception("For {} at {}:{} the description was set to '{}' - has the description field been omitted?".format(config_name, file_path, linenum, config_description))) all_descriptions = chips_all_descriptions[applicable] if config_description in all_descriptions: - raise Exception("Found description {} at {}:{} but it was already used at {}:{}".format(config_description, file_path, linenum, os.path.join(scandir, all_descriptions[config_description]['filename']), all_descriptions[config_description]['line_number'])) + errors.append(Exception("Found description {} at {}:{} but it was already used at {}:{}".format(config_description, file_path, linenum, os.path.join(scandir, all_descriptions[config_description]['filename']), all_descriptions[config_description]['line_number']))) else: all_descriptions[config_description] = {'config_name': config_name, 'filename': os.path.relpath(file_path, scandir), 'line_number': linenum} @@ -168,19 +177,19 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): try: k, v = (i.strip() for i in item.split('=')) except ValueError: - raise Exception('{} at {}:{} has malformed value {}'.format(config_name, file_path, linenum, item)) + errors.append(Exception('{} at {}:{} has malformed value {}'.format(config_name, file_path, linenum, item))) config_attrs[k] = v.replace('\0', ',') all_attrs.add(k) prev = item #print(file_path, config_name, config_attrs) if 'group' not in config_attrs: - raise Exception('{} at {}:{} has no group attribute'.format(config_name, file_path, linenum)) + errors.append(Exception('{} at {}:{} has no group attribute'.format(config_name, file_path, linenum))) #print(file_path, config_name, config_attrs) all_configs = chips_all_configs[applicable] if config_name in all_configs: - raise Exception("Found {} at {}:{} but it was already declared at {}:{}".format(config_name, file_path, linenum, os.path.join(scandir, all_configs[config_name]['filename']), all_configs[config_name]['line_number'])) + errors.append(Exception("Found {} at {}:{} but it was already declared at {}:{}".format(config_name, file_path, linenum, os.path.join(scandir, all_configs[config_name]['filename']), all_configs[config_name]['line_number']))) else: all_configs[config_name] = {'attrs': config_attrs, 'filename': os.path.relpath(file_path, scandir), 'line_number': linenum, 'description': config_description} @@ -194,14 +203,14 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): file_path = os.path.join(scandir, config_obj['filename']) linenum = config_obj['line_number'] - ValidateAttrs(config_name, config_obj['attrs'], file_path, linenum) + errors.extend(ValidateAttrs(config_name, config_obj['attrs'], file_path, linenum)) # All settings in "host" should also be in "all" for config_name, config_obj in chips_all_configs["host"].items(): if config_name not in chips_all_configs["all"]: file_path = os.path.join(scandir, config_obj['filename']) linenum = config_obj['line_number'] - raise Exception("Found 'host' config {} at {}:{}, but no matching non-host config found".format(config_name, file_path, linenum)) + errors.append(Exception("Found 'host' config {} at {}:{}, but no matching non-host config found".format(config_name, file_path, linenum))) # Any chip-specific settings should not be in "all" for chip in CHIP_NAMES: @@ -212,7 +221,7 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): chip_linenum = chip_config_obj['line_number'] all_file_path = os.path.join(scandir, all_config_obj['filename']) all_linenum = all_config_obj['line_number'] - raise Exception("'{}' config {} at {}:{} also found at {}:{}".format(chip, config_name, chip_file_path, chip_linenum, all_file_path, all_linenum)) + errors.append(Exception("'{}' config {} at {}:{} also found at {}:{}".format(chip, config_name, chip_file_path, chip_linenum, all_file_path, all_linenum))) def build_mismatch_exception_message(name, thing, config_obj1, value1, config_obj2, value2): obj1_filepath = os.path.join(scandir, config_obj1['filename']) @@ -232,14 +241,18 @@ def build_mismatch_exception_message(name, thing, config_obj1, value1, config_ob applicable_value = applicable_config_obj[field] other_value = other_config_obj[field] if applicable_value != other_value: - raise Exception(build_mismatch_exception_message(config_name, field, applicable_config_obj, applicable_value, other_config_obj, other_value)) + errors.append(Exception(build_mismatch_exception_message(config_name, field, applicable_config_obj, applicable_value, other_config_obj, other_value))) # Check that attributes match for attr in applicable_config_obj['attrs']: if attr != 'default': # totally fine for defaults to vary per-platform applicable_value = applicable_config_obj['attrs'][attr] other_value = other_config_obj['attrs'][attr] if applicable_value != other_value: - raise Exception(build_mismatch_exception_message(config_name, "attribute '{}'".format(attr), applicable_config_obj, applicable_value, other_config_obj, other_value)) + errors.append(Exception(build_mismatch_exception_message(config_name, "attribute '{}'".format(attr), applicable_config_obj, applicable_value, other_config_obj, other_value))) + +# Raise errors if any were found +if errors: + raise ExceptionGroup("Errors in {}".format(outfile), errors) # Sort the output alphabetically by name and then by chip output_rows = set() diff --git a/tools/extract_cmake_functions.py b/tools/extract_cmake_functions.py new file mode 100755 index 000000000..48020768e --- /dev/null +++ b/tools/extract_cmake_functions.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2025 Raspberry Pi (Trading) Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# +# Script to scan the Raspberry Pi Pico SDK tree searching for CMake functions +# Outputs a tab separated file of the functions: +# name group signature brief description params +# +# Usage: +# +# tools/extract_cmake_functions.py [output file] +# +# If not specified, output file will be `pico_cmake_functions.tsv` + + +import os +import sys +import re +import csv +import logging + +if sys.version_info < (3, 11): + # Python <3.11 doesn't have ExceptionGroup, so define a simple one + class ExceptionGroup(Exception): + def __init__(self, message, errors): + message += "\n" + "\n".join(str(e) for e in errors) + super().__init__(message) + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +scandir = sys.argv[1] +outfile = sys.argv[2] if len(sys.argv) > 2 else 'pico_cmake_functions.tsv' + +CMAKE_FUNCTION_RE = re.compile(r'^\s*#(.*)((\n\s*#.*)*)\n\s*function\(([^\s]*)', re.MULTILINE) + +CMAKE_PICO_FUNCTIONS_RE = re.compile(r'^\s*function\((pico_[^\s\)]*)', re.MULTILINE) + +# Files containing internal functions that don't need to be documented publicly +skip_files = set([ + "pico_sdk_init.cmake", + "pico_utils.cmake", + "no_hardware.cmake", + "find_compiler.cmake", +]) + +skip_groups = set([ + "src", # skip the root src/CMakeLists.txt +]) + +# Other internal functions that don't need to be documented publicly +allowed_missing_functions = set([ + "pico_init_pioasm", + "pico_init_picotool", + "pico_add_platform_library", + "pico_get_runtime_output_directory", + "pico_get_output_name", + "pico_set_printf_implementation", + "pico_expand_pico_platform", +]) + +# Group descriptions +group_names_descriptions = { + 'boot_stage2': ('Boot Stage 2', 'CMake functions to create stage 2 bootloaders'), + 'pico_binary_info': ('Pico Binary Info', 'CMake functions to add binary info to the output binary'), + 'pico_btstack': ('Pico BTstack', 'CMake functions to configure the bluetooth stack'), + 'pico_lwip': ('Pico LwIP', 'CMake functions to configure LwIP'), + 'pico_cyw43_driver': ('Pico CYW43 Driver', 'CMake functions to configure the CYW43 driver'), + 'pico_runtime': ('Pico Runtime', 'CMake functions to configure the runtime environment'), + 'pico_standard_link': ('Pico Standard Link', 'CMake functions to configure the linker'), + 'pico_stdio': ('Pico Standard I/O', 'CMake functions to configure the standard I/O library'), + 'pico_pio': ('Pico PIO', 'CMake functions to generate PIO headers'), + 'other': ('Other', 'Other CMake functions'), +} + + +all_functions = {} + +for group, (brief, description) in group_names_descriptions.items(): + all_functions['_desc_{group}'.format(group=group)] = { + 'name': '_desc_{group}'.format(group=group), + 'group': group, + 'signature': '', + 'brief': brief, + 'description': description, + 'params': '', + } + +# Supported commands: +# \brief\ +# \brief_nodesc\ +# \param\ +# \ingroup\ +# +# Commands in the middle of a line are not supported +# +# The ; character at the end of a line denotes a hard line break in the description +# The \ character (outside of a command) and the # character are not supported in descriptions +def process_commands(description, name, group, signature): + brief = '' + params = [] + desc = '' + errors = [] + for line in description.split('\n'): + line = line.strip() + if line.startswith('\\'): + _, command, remainder = line.split('\\', 2) + remainder = remainder.strip() + if command == 'param': + # Parameter name and description + params.append(remainder) + elif command == 'brief': + # Brief description + brief = remainder + desc += brief + '\\n' + elif command == 'brief_nodesc': + # Brief description which should not be included in the main description + brief = remainder + elif command == 'ingroup': + # Group name override + group = remainder + else: + errors.append(Exception("{}:{} has unknown command: {}".format(group, name, command))) + elif '\\' in line: + errors.append(Exception("{}:{} has a line containing '\\': {}".format(group, name, line))) + else: + desc += line + '\\n' + # Check that there are no semicolons in the parameter descriptions, as that's the delimiter for the parameter list + if any([';' in x for x in params]): + errors.append(Exception("{}:{} has a parameter description containing ';'".format(group, name))) + # Check that all parameters are in the signature + signature_words = set(re.split(r'\W+', signature)) + for param in params: + param_name = param.split(' ', maxsplit=1)[0] + if param_name not in signature_words: + errors.append(Exception("{}:{} has a parameter {} which is not in the signature {}".format(group, name, param_name, signature))) + # Check that the brief description is not empty + if not brief: + logger.warning("{}:{} has no brief description".format(group, name)) + # Check that the group has a description + if group not in group_names_descriptions: + errors.append(Exception("{} has no group description (referenced from {})".format(group, name))) + + desc = re.sub(r'^(\\n)*(.*?)(\\n)*$', r'\2', desc) + return desc.strip(), brief, ';'.join(params), group, errors + + +def sort_functions(item): + group = item['group'] + name = item['name'] + + precedence = 5 + if name.startswith('_desc_'): + precedence = 0 + elif group == 'other': + if re.match(r'^pico_add_.*_output$', name): + precedence = 1 + elif name == 'pico_add_extra_outputs': + precedence = 2 + elif re.match(r'^pico_.*_binary$', name): + precedence = 3 + return group + str(precedence) + name + +all_errors = [] + +# Scan all CMakeLists.txt and .cmake files in the specific path, recursively. + +for dirpath, dirnames, filenames in os.walk(scandir): + for filename in filenames: + if filename in skip_files: + continue + # Default group is the directory name - can be overridden by the \ingroup\ command + group = os.path.basename(dirpath) + if group in skip_groups: + continue + if group in ['tools', 'cmake']: + group = 'other' + file_ext = os.path.splitext(filename)[1] + if filename == 'CMakeLists.txt' or file_ext == '.cmake': + file_path = os.path.join(dirpath, filename) + + with open(file_path, encoding="ISO-8859-1") as fh: + text = fh.read() + for match in CMAKE_FUNCTION_RE.finditer(text): + name = match.group(4) + signature = match.group(1).strip() + if signature.startswith(name): + description, brief, params, processed_group, errors = process_commands(match.group(2).replace('#', ''), name, group, signature) + all_errors.extend(errors) + new_dict = { + 'name': name, + 'group': processed_group, + 'signature': signature, + 'brief': brief, + 'description': description, + 'params': params + } + if all_functions.get(name): + if new_dict != all_functions[name]: + logger.warning("{}:{} has multiple different definitions - using the new one from {}".format(processed_group, name, file_path)) + all_functions[name] = new_dict + + for match in CMAKE_PICO_FUNCTIONS_RE.finditer(text): + name = match.group(1) + if name not in all_functions and name not in allowed_missing_functions: + logger.warning("{} function has no description in {}".format(name, file_path)) + +if all_errors: + raise ExceptionGroup("Errors in {}".format(outfile), all_errors) + + +with open(outfile, 'w', newline='') as csvfile: + fieldnames = ('name', 'group', 'signature', 'brief', 'description', 'params') + writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore', dialect='excel-tab') + + writer.writeheader() + for row in sorted(all_functions.values(), key=sort_functions): + writer.writerow(row) diff --git a/tools/extract_configs.py b/tools/extract_configs.py index 30705d5cb..bb2713b0d 100755 --- a/tools/extract_configs.py +++ b/tools/extract_configs.py @@ -24,6 +24,13 @@ from collections import defaultdict +if sys.version_info < (3, 11): + # Python <3.11 doesn't have ExceptionGroup, so define a simple one + class ExceptionGroup(Exception): + def __init__(self, message, errors): + message += "\n" + "\n".join(str(e) for e in errors) + super().__init__(message) + logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) @@ -53,11 +60,12 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): _type = config_attrs.get('type', 'int') + errors = [] # Validate attrs for key in config_attrs.keys(): if key not in ALLOWED_CONFIG_PROPERTIES: - raise Exception('{} at {}:{} has unexpected property "{}"'.format(config_name, file_path, linenum, key)) + errors.append(Exception('{} at {}:{} has unexpected property "{}"'.format(config_name, file_path, linenum, key))) if _type == 'int': assert 'enumvalues' not in config_attrs @@ -95,13 +103,13 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): logger.info('{} at {}:{} has non-integer default value "{}"'.format(config_name, file_path, linenum, config_attrs['default'])) if _min is not None and _max is not None: if _min > _max: - raise Exception('{} at {}:{} has min {} > max {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['max'])) + errors.append(Exception('{} at {}:{} has min {} > max {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['max']))) if _min is not None and _default is not None: if _min > _default: - raise Exception('{} at {}:{} has min {} > default {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['default'])) + errors.append(Exception('{} at {}:{} has min {} > default {}'.format(config_name, file_path, linenum, config_attrs['min'], config_attrs['default']))) if _default is not None and _max is not None: if _default > _max: - raise Exception('{} at {}:{} has default {} > max {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['max'])) + errors.append(Exception('{} at {}:{} has default {} > max {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['max']))) elif _type == 'bool': assert 'min' not in config_attrs @@ -126,19 +134,20 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): _default = config_attrs['default'] if _default is not None: if _default not in _enumvalues: - raise Exception('{} at {}:{} has default value {} which isn\'t in list of enumvalues {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['enumvalues'])) + errors.append(Exception('{} at {}:{} has default value {} which isn\'t in list of enumvalues {}'.format(config_name, file_path, linenum, config_attrs['default'], config_attrs['enumvalues']))) else: - raise Exception("Found unknown {} type {} at {}:{}".format(BASE_CONFIG_NAME, _type, file_path, linenum)) - + errors.append(Exception("Found unknown {} type {} at {}:{}".format(BASE_CONFIG_NAME, _type, file_path, linenum))) + return errors +errors = [] -# 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"): @@ -152,16 +161,16 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): linenum += 1 line = line.strip() if BASE_CMAKE_CONFIG_RE.search(line): - raise Exception("Found {} at {}:{} ({}) which isn't expected in {} files".format(BASE_CMAKE_CONFIG_NAME, file_path, linenum, line, file_ext)) + errors.append(Exception("Found {} at {}:{} ({}) which isn't expected in {} files".format(BASE_CMAKE_CONFIG_NAME, file_path, linenum, line, file_ext))) elif BASE_BUILD_DEFINE_RE.search(line): - raise Exception("Found {} at {}:{} ({}) which isn't expected in {} files".format(BASE_BUILD_DEFINE_NAME, file_path, linenum, line, file_ext)) + errors.append(Exception("Found {} at {}:{} ({}) which isn't expected in {} files".format(BASE_BUILD_DEFINE_NAME, file_path, linenum, line, file_ext))) elif BASE_CONFIG_RE.search(line): m = CONFIG_RE.match(line) if not m: if re.match(r"^\s*//\s*// ", line): logger.info("Possible misformatted {} at {}:{} ({})".format(BASE_CONFIG_NAME, file_path, linenum, line)) else: - raise Exception("Found misformatted {} at {}:{} ({})".format(BASE_CONFIG_NAME, file_path, linenum, line)) + errors.append(Exception("Found misformatted {} at {}:{} ({})".format(BASE_CONFIG_NAME, file_path, linenum, line))) else: config_name = m.group(1) config_description = m.group(2) @@ -170,10 +179,10 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): _attrs = re.sub(r'(\(.+\))', lambda m: m.group(1).replace(',', '\0'), _attrs) if '=' in config_description: - raise Exception("For {} at {}:{} the description was set to '{}' - has the description field been omitted?".format(config_name, file_path, linenum, config_description)) + errors.append(Exception("For {} at {}:{} the description was set to '{}' - has the description field been omitted?".format(config_name, file_path, linenum, config_description))) all_descriptions = chips_all_descriptions[applicable] if config_description in all_descriptions: - raise Exception("Found description {} at {}:{} but it was already used at {}:{}".format(config_description, file_path, linenum, os.path.join(scandir, all_descriptions[config_description]['filename']), all_descriptions[config_description]['line_number'])) + errors.append(Exception("Found description {} at {}:{} but it was already used at {}:{}".format(config_description, file_path, linenum, os.path.join(scandir, all_descriptions[config_description]['filename']), all_descriptions[config_description]['line_number']))) else: all_descriptions[config_description] = {'config_name': config_name, 'filename': os.path.relpath(file_path, scandir), 'line_number': linenum} @@ -187,19 +196,19 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): try: k, v = (i.strip() for i in item.split('=')) except ValueError: - raise Exception('{} at {}:{} has malformed value {}'.format(config_name, file_path, linenum, item)) + errors.append(Exception('{} at {}:{} has malformed value {}'.format(config_name, file_path, linenum, item))) config_attrs[k] = v.replace('\0', ',') all_attrs.add(k) prev = item #print(file_path, config_name, config_attrs) if 'group' not in config_attrs: - raise Exception('{} at {}:{} has no group attribute'.format(config_name, file_path, linenum)) + errors.append(Exception('{} at {}:{} has no group attribute'.format(config_name, file_path, linenum))) #print(file_path, config_name, config_attrs) all_configs = chips_all_configs[applicable] if config_name in all_configs: - raise Exception("Found {} at {}:{} but it was already declared at {}:{}".format(config_name, file_path, linenum, os.path.join(scandir, all_configs[config_name]['filename']), all_configs[config_name]['line_number'])) + errors.append(Exception("Found {} at {}:{} but it was already declared at {}:{}".format(config_name, file_path, linenum, os.path.join(scandir, all_configs[config_name]['filename']), all_configs[config_name]['line_number']))) else: all_configs[config_name] = {'attrs': config_attrs, 'filename': os.path.relpath(file_path, scandir), 'line_number': linenum, 'description': config_description} else: @@ -231,8 +240,9 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): chips_resolved_defines = defaultdict(dict) for applicable, all_defines in chips_all_defines.items(): for d in all_defines: - if d not in all_config_names and d.startswith("PICO_"): - logger.warning("Potential unmarked PICO define {}".format(d)) + for define_prefix in ('PICO', 'PARAM', 'CYW43'): + if d not in all_config_names and d.startswith(define_prefix+'_'): + logger.warning("#define {} is potentially missing a {}: entry".format(d, BASE_CONFIG_NAME)) resolved_defines = chips_resolved_defines[applicable] # resolve "nested defines" - this allows e.g. USB_DPRAM_MAX to resolve to USB_DPRAM_SIZE which is set to 4096 (which then matches the relevant PICO_CONFIG entry) for val in all_defines[d]: @@ -241,11 +251,12 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): 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'] - ValidateAttrs(config_name, config_obj['attrs'], file_path, linenum) + errors.extend(ValidateAttrs(config_name, config_obj['attrs'], file_path, linenum)) # Check that default values match up if 'default' in config_obj['attrs']: @@ -258,16 +269,16 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): # There _may_ be multiple matching defines, but arbitrarily display just one in the error message first_define_value = list(defines_obj.keys())[0] first_define_file_path, first_define_linenum = defines_obj[first_define_value] - raise Exception('Found {} at {}:{} with a default of {}, but #define says {} (at {}:{})'.format(config_name, file_path, linenum, config_default, first_define_value, first_define_file_path, first_define_linenum)) + errors.append(Exception('Found {} at {}:{} with a default of {}, but #define says {} (at {}:{})'.format(config_name, file_path, linenum, config_default, first_define_value, first_define_file_path, first_define_linenum))) else: - raise Exception('Found {} at {}:{} with a default of {}, but no matching #define found'.format(config_name, file_path, linenum, config_default)) + errors.append(Exception('Found {} at {}:{} with a default of {}, but no matching #define found'.format(config_name, file_path, linenum, config_default))) # All settings in "host" should also be in "all" for config_name, config_obj in chips_all_configs["host"].items(): if config_name not in chips_all_configs["all"]: file_path = os.path.join(scandir, config_obj['filename']) linenum = config_obj['line_number'] - raise Exception("Found 'host' config {} at {}:{}, but no matching non-host config found".format(config_name, file_path, linenum)) + errors.append(Exception("Found 'host' config {} at {}:{}, but no matching non-host config found".format(config_name, file_path, linenum))) # Any chip-specific settings should not be in "all" for chip in CHIP_NAMES: @@ -278,7 +289,7 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum): chip_linenum = chip_config_obj['line_number'] all_file_path = os.path.join(scandir, all_config_obj['filename']) all_linenum = all_config_obj['line_number'] - raise Exception("'{}' config {} at {}:{} also found at {}:{}".format(chip, config_name, chip_file_path, chip_linenum, all_file_path, all_linenum)) + errors.append(Exception("'{}' config {} at {}:{} also found at {}:{}".format(chip, config_name, chip_file_path, chip_linenum, all_file_path, all_linenum))) def build_mismatch_exception_message(name, thing, config_obj1, value1, config_obj2, value2): obj1_filepath = os.path.join(scandir, config_obj1['filename']) @@ -298,14 +309,18 @@ def build_mismatch_exception_message(name, thing, config_obj1, value1, config_ob applicable_value = applicable_config_obj[field] other_value = other_config_obj[field] if applicable_value != other_value: - raise Exception(build_mismatch_exception_message(config_name, field, applicable_config_obj, applicable_value, other_config_obj, other_value)) + errors.append(Exception(build_mismatch_exception_message(config_name, field, applicable_config_obj, applicable_value, other_config_obj, other_value))) # Check that attributes match for attr in applicable_config_obj['attrs']: if attr != 'default': # totally fine for defaults to vary per-platform applicable_value = applicable_config_obj['attrs'][attr] other_value = other_config_obj['attrs'][attr] if applicable_value != other_value: - raise Exception(build_mismatch_exception_message(config_name, "attribute '{}'".format(attr), applicable_config_obj, applicable_value, other_config_obj, other_value)) + errors.append(Exception(build_mismatch_exception_message(config_name, "attribute '{}'".format(attr), applicable_config_obj, applicable_value, other_config_obj, other_value))) + +# Raise errors if any were found +if errors: + raise ExceptionGroup("Errors in {}".format(outfile), errors) # Sort the output alphabetically by name and then by chip output_rows = set() diff --git a/tools/pioasm/BUILD.bazel b/tools/pioasm/BUILD.bazel index 266bce68a..732d5e42c 100644 --- a/tools/pioasm/BUILD.bazel +++ b/tools/pioasm/BUILD.bazel @@ -1,3 +1,5 @@ +load("@bazel_skylib//rules:expand_template.bzl", "expand_template") + package(default_visibility = ["//visibility:public"]) # TODO: No support for building the parser. @@ -19,6 +21,7 @@ cc_library( "pio_disassembler.h", "pio_enums.h", "pio_types.h", + ":version", ], copts = select({ "@rules_cc//cc/compiler:msvc-cl": ["/std:c++20"], @@ -63,6 +66,15 @@ cc_library( alwayslink = True, ) +expand_template( + name = "version", + template = "version.h.in", + substitutions = { + "${PIOASM_VERSION_STRING}": module_version() if module_version() != None else "0.0.1-WORKSPACE", + }, + out = "gen/version.h", +) + cc_binary( name = "pioasm", deps = [ diff --git a/tools/pioasm/CMakeLists.txt b/tools/pioasm/CMakeLists.txt index a7698cd81..dcca23860 100644 --- a/tools/pioasm/CMakeLists.txt +++ b/tools/pioasm/CMakeLists.txt @@ -41,7 +41,13 @@ if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND target_compile_options(pioasm PRIVATE -Wno-psabi) endif() -target_include_directories(pioasm PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/gen) +if (NOT PIOASM_VERSION_STRING) + message(FATAL_ERROR "PIOASM_VERSION_STRING must be provided when building pioasm") +endif() + +configure_file( ${CMAKE_CURRENT_LIST_DIR}/version.h.in ${CMAKE_BINARY_DIR}/version.h) + +target_include_directories(pioasm PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/gen ${CMAKE_BINARY_DIR}) if (MSVC OR (WIN32 AND NOT MINGW AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))) diff --git a/tools/pioasm/ada_output.cpp b/tools/pioasm/ada_output.cpp index c0f59a151..94197e676 100644 --- a/tools/pioasm/ada_output.cpp +++ b/tools/pioasm/ada_output.cpp @@ -13,8 +13,10 @@ #include #include +#include #include "output_format.h" #include "pio_disassembler.h" +#include "version.h" struct ada_output : public output_format { struct factory { @@ -97,7 +99,9 @@ struct ada_output : public output_format { FILE *out = open_single_output(destination); if (!out) return 1; - header(out, "This file is autogenerated by pioasm; do not edit!", 0); + std::stringstream header_string; + header_string << "This file is autogenerated by pioasm version " << PIOASM_VERSION_STRING << "; do not edit!"; + header(out, header_string.str(), 0); fprintf(out, "pragma Style_Checks (Off);\n\n"); fprintf(out, "with RP.PIO;\n\n"); diff --git a/tools/pioasm/c_sdk_output.cpp b/tools/pioasm/c_sdk_output.cpp index c1730db4c..156d3e71c 100644 --- a/tools/pioasm/c_sdk_output.cpp +++ b/tools/pioasm/c_sdk_output.cpp @@ -6,8 +6,10 @@ #include #include +#include #include "output_format.h" #include "pio_disassembler.h" +#include "version.h" struct c_sdk_output : public output_format { struct factory { @@ -66,7 +68,9 @@ struct c_sdk_output : public output_format { FILE *out = open_single_output(destination); if (!out) return 1; - header(out, "This file is autogenerated by pioasm; do not edit!"); + std::stringstream header_string; + header_string << "This file is autogenerated by pioasm version " << PIOASM_VERSION_STRING << "; do not edit!"; + header(out, header_string.str()); fprintf(out, "#pragma once\n"); fprintf(out, "\n"); @@ -139,7 +143,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"); diff --git a/tools/pioasm/go_output.cpp b/tools/pioasm/go_output.cpp index b1748d77a..10f4c5af9 100644 --- a/tools/pioasm/go_output.cpp +++ b/tools/pioasm/go_output.cpp @@ -14,8 +14,10 @@ #include #include +#include #include "output_format.h" #include "pio_disassembler.h" +#include "version.h" struct go_output : public output_format { struct factory { @@ -63,8 +65,10 @@ struct go_output : public output_format { FILE *out = open_single_output(destination); if (!out) return 1; - header(out, "Code generated by pioasm; DO NOT EDIT."); - + std::stringstream header_string; + header_string << "This file is autogenerated by pioasm version " << PIOASM_VERSION_STRING << "; do not edit!"; + header(out, header_string.str()); + // First we give priority to user's code blocks since // 1. In Go our imports always precede our code. // 2. We give users the freedom to use their own PIO implementation. diff --git a/tools/pioasm/main.cpp b/tools/pioasm/main.cpp index f5d678535..04e6f9987 100644 --- a/tools/pioasm/main.cpp +++ b/tools/pioasm/main.cpp @@ -6,6 +6,7 @@ #include #include "pio_assembler.h" +#include "version.h" #define DEFAULT_OUTPUT_FORMAT "c-sdk" @@ -24,6 +25,7 @@ void usage() { } std::cerr << " -p add a parameter to be passed to the output format generator" << std::endl; std::cerr << " -v specify the default PIO version (0 or 1)" << std::endl; + std::cerr << " --version print pioasm version information" << std::endl; std::cerr << " -?, --help print this help and exit\n"; } @@ -66,6 +68,9 @@ int main(int argc, char *argv[]) { } else if (argv[i] == std::string("-?") || argv[i] == std::string("--help")) { usage(); return 1; + } else if (argv[i] == std::string("--version")) { + std::cout << "pioasm version: " << PIOASM_VERSION_STRING << std::endl; + return 0; } else { std::cerr << "error: unknown option " << argv[i] << std::endl; res = 1; diff --git a/tools/pioasm/output_format.h b/tools/pioasm/output_format.h index 405a5ae75..d42ea73b4 100644 --- a/tools/pioasm/output_format.h +++ b/tools/pioasm/output_format.h @@ -7,6 +7,7 @@ #ifndef _OUTPUT_FORMAT_H #define _OUTPUT_FORMAT_H +#include #include #include #include @@ -120,4 +121,4 @@ struct output_format { output_format(std::string name) : name(std::move(name)) {} }; -#endif \ No newline at end of file +#endif diff --git a/tools/pioasm/pio_types.h b/tools/pioasm/pio_types.h index 9f9fb0e3e..755eb75a0 100644 --- a/tools/pioasm/pio_types.h +++ b/tools/pioasm/pio_types.h @@ -7,6 +7,7 @@ #ifndef _PIO_TYPES_H #define _PIO_TYPES_H +#include #include #include #include diff --git a/tools/pioasm/python_output.cpp b/tools/pioasm/python_output.cpp index f4cf326bd..080b90442 100644 --- a/tools/pioasm/python_output.cpp +++ b/tools/pioasm/python_output.cpp @@ -8,9 +8,9 @@ #include #include #include -#include #include "output_format.h" #include "pio_disassembler.h" +#include "version.h" struct python_output : public output_format { struct factory { @@ -61,7 +61,9 @@ struct python_output : public output_format { FILE *out = open_single_output(destination); if (!out) return 1; - header(out, "This file is autogenerated by pioasm; do not edit!"); + std::stringstream header_string; + header_string << "This file is autogenerated by pioasm version " << PIOASM_VERSION_STRING << "; do not edit!"; + header(out, header_string.str()); fprintf(out, "import rp2\n"); fprintf(out, "from machine import Pin"); diff --git a/tools/pioasm/test/amethyst.pio b/tools/pioasm/test/amethyst.pio index 6b8160460..d64f3f9f9 100644 --- a/tools/pioasm/test/amethyst.pio +++ b/tools/pioasm/test/amethyst.pio @@ -50,4 +50,23 @@ wait gpio 40 wait 0 jmppin wait 0 jmppin + 3 mov x, !x -.word 0x1234 \ No newline at end of file +.word 0x1234 + + +.program prev_next +.pio_version 1 +wait 0 irq prev 0 ; Wait for IRQ0 +irq prev clear 0 ; Clear IRQ0 +irq clear 0 ; Clear IRQ0 +wait 0 irq next 0 ; Wait for IRQ0 +irq next clear 0 ; Clear IRQ0 + +.program wee +.pio_version 1 +wait 0 gpio 15 +wait 0 gpio 31 + +.program wee2 +.pio_version 1 +wait 0 gpio 31 +wait 0 gpio 47 diff --git a/tools/pioasm/version.h.in b/tools/pioasm/version.h.in new file mode 100644 index 000000000..32a6d134a --- /dev/null +++ b/tools/pioasm/version.h.in @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// --------------------------------------- +// THIS FILE IS AUTOGENERATED; DO NOT EDIT +// --------------------------------------- + +#ifndef _PIOASM_VERSION_H +#define _PIOASM_VERSION_H + +#define PIOASM_VERSION_STRING "${PIOASM_VERSION_STRING}" + +#endif \ No newline at end of file