diff --git a/.github/workflows/choco_packages.config b/.github/workflows/choco_packages.config
index f7885c9fc..d443f751c 100644
--- a/.github/workflows/choco_packages.config
+++ b/.github/workflows/choco_packages.config
@@ -1,7 +1,6 @@
-
diff --git a/.github/workflows/multi-gcc.yml b/.github/workflows/multi-gcc.yml
index 886109d2e..f20062458 100644
--- a/.github/workflows/multi-gcc.yml
+++ b/.github/workflows/multi-gcc.yml
@@ -25,133 +25,399 @@ jobs:
- name: Checkout submodules
run: git submodule update --init
- - name: GCC 6.2.1 Debug
- if: always()
+ - name: Host Release
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=host; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: Host Debug
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=host; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 6.2.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-6_2-2016q4; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 6.2.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-6_2-2016q4; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 6.3.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-6-2017-q2-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 6.3.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-6-2017-q2-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 7.2.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-7-2017-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 7.2.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-7-2017-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 7.3.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-7-2018-q2-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 7.3.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-7-2018-q2-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 8.2.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-8-2018-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 8.2.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-8-2018-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 8.3.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-8-2019-q3-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 8.3.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-8-2019-q3-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 9.2.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2019-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 9.2.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2019-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 9.2.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2019-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 9.2.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2019-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 9.3.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2020-q2-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 9.3.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2020-q2-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 9.3.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2020-q2-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 9.3.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2020-q2-update; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 10.2.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10-2020-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 10.2.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10-2020-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 10.2.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10-2020-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 10.2.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10-2020-q4-major; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 10.3.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10.3-2021.10; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 10.3.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10.3-2021.10; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 10.3.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10.3-2021.10; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 10.3.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10.3-2021.10; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 11.2.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 11.2.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 11.2.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 11.2.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 11.3.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 11.3.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 11.3.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 11.3.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 12.2.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 12.2.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 12.2.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 12.2.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 12.3.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 12.3.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 12.3.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 12.3.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 13.2.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 13.2.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 13.2.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 13.2.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 13.3.1 Debug Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 13.3.1 Debug RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 13.3.1 Release Pico W
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: GCC 13.3.1 Release RP2350
+ if: ${{ !cancelled() }}
+ shell: bash
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: LLVM 14.0.0 Debug Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-6_2-2016q4 -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-14.0.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 6.2.1 Release
- if: always()
+ - name: LLVM 14.0.0 Debug RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-6_2-2016q4 -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-14.0.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 6.3.1 Debug
- if: always()
+ - name: LLVM 14.0.0 Release Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-6-2017-q2-update -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-14.0.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 6.3.1 Release
- if: always()
+ - name: LLVM 14.0.0 Release RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-6-2017-q2-update -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-14.0.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 7.2.1 Debug
- if: always()
+ - name: RISCV GCC 14.1.0 Debug RP2350 RISCV
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-7-2017-q4-major -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350-riscv -DPICO_TOOLCHAIN_PATH=/opt/riscv/riscv32-unknown-elf-gcc-14.1.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 7.2.1 Release
- if: always()
+ - name: RISCV GCC 14.1.0 Release RP2350 RISCV
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-7-2017-q4-major -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350-riscv -DPICO_TOOLCHAIN_PATH=/opt/riscv/riscv32-unknown-elf-gcc-14.1.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 7.3.1 Debug
- if: always()
+ - name: GCC 14.2.1 Debug Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-7-2018-q2-update -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 7.3.1 Release
- if: always()
+ - name: GCC 14.2.1 Debug RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-7-2018-q2-update -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 8.2.1 Debug
- if: always()
+ - name: GCC 14.2.1 Release Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-8-2018-q4-major -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 8.2.1 Release
- if: always()
+ - name: GCC 14.2.1 Release RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-8-2018-q4-major -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 8.3.1 Debug
- if: always()
+ - name: LLVM 15.0.2 Debug Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-8-2019-q3-update -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-15.0.2; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 8.3.1 Release
- if: always()
+ - name: LLVM 15.0.2 Debug RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-8-2019-q3-update -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-15.0.2; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 9.2.1 Debug
- if: always()
+ - name: LLVM 15.0.2 Release Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2019-q4-major -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-15.0.2; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 9.2.1 Release
- if: always()
+ - name: LLVM 15.0.2 Release RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2019-q4-major -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-15.0.2; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 9.3.1 Debug
- if: always()
+ - name: LLVM 16.0.0 Debug Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2020-q2-update -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-16.0.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 9.3.1 Release
- if: always()
+ - name: LLVM 16.0.0 Debug RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-9-2020-q2-update -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-16.0.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 10.2.1 Debug
- if: always()
+ - name: LLVM 16.0.0 Release Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10-2020-q4-major -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-16.0.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 10.2.1 Release
- if: always()
+ - name: LLVM 16.0.0 Release RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10-2020-q4-major -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-16.0.0; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 10.3.1 Debug
- if: always()
+ - name: LLVM 17.0.1 Debug Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10.3-2021.10 -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-17.0.1; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 10.3.1 Release
- if: always()
+ - name: LLVM 17.0.1 Debug RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-none-eabi-10.3-2021.10 -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-17.0.1; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 11.2.1 Debug
- if: always()
+ - name: LLVM 17.0.1 Release Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-17.0.1; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 11.2.1 Release
- if: always()
+ - name: LLVM 17.0.1 Release RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVMEmbeddedToolchainForArm-17.0.1; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 11.3.1 Debug
- if: always()
+ - name: LLVM 18.1.3 Debug Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVM-ET-Arm-18.1.3-Linux-x86_64; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 11.3.1 Release
- if: always()
+ - name: LLVM 18.1.3 Debug RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVM-ET-Arm-18.1.3-Linux-x86_64; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 12.2.1 Debug
- if: always()
+ - name: LLVM 18.1.3 Release Pico W
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_BOARD=pico_w -DPICO_PLATFORM=rp2040 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVM-ET-Arm-18.1.3-Linux-x86_64; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
- - name: GCC 12.2.1 Release
- if: always()
+ - name: LLVM 18.1.3 Release RP2350
+ if: ${{ !cancelled() }}
shell: bash
- run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_TOOLCHAIN_PATH=/opt/arm/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=rp2350 -DPICO_COMPILER=pico_arm_clang -DPICO_TOOLCHAIN_PATH=/opt/arm/LLVM-ET-Arm-18.1.3-Linux-x86_64; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
diff --git a/.github/workflows/scripts/generate_multi_gcc_workflow.py b/.github/workflows/scripts/generate_multi_gcc_workflow.py
index ac10b8b2c..7e36f63af 100755
--- a/.github/workflows/scripts/generate_multi_gcc_workflow.py
+++ b/.github/workflows/scripts/generate_multi_gcc_workflow.py
@@ -5,15 +5,52 @@
import subprocess
import re
-toolchain_dir = "/opt/arm"
-toolchains = os.listdir(toolchain_dir)
+toolchains = [os.path.join("/opt/arm", x) for x in os.listdir("/opt/arm")]
+toolchains += [os.path.join("/opt/riscv", x) for x in os.listdir("/opt/riscv")]
-gcc_versions = OrderedDict()
+compilers = []
+class Compiler:
+ def __init__(self, version, path, type):
+ self.version = version
+ self.path = path
+ self.type = type
+ @property
+ def gcc(self):
+ return self.type == "GCC"
+
+ @property
+ def llvm(self):
+ return self.type == "LLVM"
+
+ @property
+ def riscv(self):
+ return "RISCV" in self.type
+
+ def __repr__(self):
+ return self.version
+
+seen_versions = []
for toolchain in toolchains:
- fullpath = os.path.join(toolchain_dir, toolchain)
- gcc_path = os.path.join(fullpath, "bin/arm-none-eabi-gcc")
- version = subprocess.run([gcc_path, "--version"], capture_output=True)
+ gcc_path = os.path.join(toolchain, "bin/arm-none-eabi-gcc")
+ llvm_path = os.path.join(toolchain, "bin/clang")
+ riscv_gcc_path = os.path.join(toolchain, "bin/riscv32-unknown-elf-gcc")
+
+ type = None
+ path = None
+ if os.path.exists(gcc_path):
+ path = gcc_path
+ type = "GCC"
+ elif os.path.exists(llvm_path):
+ path = llvm_path
+ type = "LLVM"
+ elif os.path.exists(riscv_gcc_path):
+ path = riscv_gcc_path
+ type = "RISCV GCC"
+ else:
+ raise Exception("Unknown compiler type")
+
+ version = subprocess.run([path, "--version"], capture_output=True)
stdout = version.stdout.decode('utf-8')
stderr = version.stderr.decode('utf-8')
assert(len(stderr) == 0)
@@ -23,14 +60,13 @@
assert(m is not None)
version = m.group(1)
- if version in gcc_versions:
- raise Exception("Already have version {} in versions current path {}, this path {}".format(version, gcc_versions[version], fullpath))
-
- gcc_versions[version] = fullpath
+ if version in seen_versions:
+ raise Exception("Already have version {} in versions current path {}, this path {}".format(version, gcc_versions[version], path))
-# Sort by major version
-gcc_versions_sorted = OrderedDict(sorted(gcc_versions.items(), key=lambda item: int(item[0].replace(".", ""))))
+ compilers.append(Compiler(version, toolchain, type))
+ seen_versions.append(version)
+compilers_sorted = sorted(compilers, key=lambda x: int(x.version.replace(".", "")))
# Create output
output = '''
@@ -59,14 +95,55 @@
- name: Checkout submodules
run: git submodule update --init
+
+ - name: Host Release
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Release -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=host; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
+
+ - name: Host Debug
+ run: cd ${{github.workspace}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE=Debug -DPICO_NO_PICOTOOL=1 -DPICO_PLATFORM=host; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)
'''
-for gcc_version, toolchain_path in gcc_versions_sorted.items():
- for build_type in ["Debug", "Release"]:
- output += "\n"
- output += " - name: GCC {} {}\n".format(gcc_version, build_type)
- output += " if: always()\n"
- output += " shell: bash\n"
- output += " run: cd ${{{{github.workspace}}}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE={} -DPICO_TOOLCHAIN_PATH={} -DPICO_BOARD=pico_w; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)\n".format(build_type, toolchain_path)
+platforms = []
+class Platform:
+ def __init__(self, name, platform, board, minimum_gcc_version=None):
+ self.name = name
+ self.board = board
+ self.platform = platform
+ self.riscv = "riscv" in platform
+ self.minimum_gcc_version = minimum_gcc_version
+
+ def cmake_string(self, compiler):
+ opts = []
+ # Temporary while private repo
+ opts.append("-DPICO_NO_PICOTOOL=1")
+ if self.board: opts.append(f"-DPICO_BOARD={self.board}")
+ opts.append(f"-DPICO_PLATFORM={self.platform}")
+ if compiler.llvm: opts.append("-DPICO_COMPILER=pico_arm_clang")
+ opts.append(f"-DPICO_TOOLCHAIN_PATH={compiler.path}")
+ return " ".join(opts)
+
+ def compiler_valid(self, compiler):
+ if compiler.riscv != self.riscv:
+ return False
+
+ if self.minimum_gcc_version and compiler.gcc:
+ if int(compiler.version.split(".")[0]) < self.minimum_gcc_version:
+ return False
+ return True
+
+
+platforms.append(Platform("Pico W", "rp2040", "pico_w"))
+platforms.append(Platform("RP2350", "rp2350", None, 9))
+platforms.append(Platform("RP2350 RISCV", "rp2350-riscv", None))
+
+for compiler in compilers_sorted:
+ for build_type in ["Debug", "Release"]:
+ for p in platforms:
+ if not p.compiler_valid(compiler): continue
+ output += "\n"
+ output += " - name: {} {} {} {}\n".format(compiler.type, compiler.version, build_type, p.name)
+ output += " if: always()\n"
+ output += " shell: bash\n"
+ output += " run: cd ${{{{github.workspace}}}}; mkdir -p build; rm -rf build/*; cd build; cmake ../ -DPICO_SDK_TESTS_ENABLED=1 -DCMAKE_BUILD_TYPE={} {}; make --output-sync=target --no-builtin-rules --no-builtin-variables -j$(nproc)\n".format(build_type, p.cmake_string(compiler))
print(output)
diff --git a/MODULE.bazel b/MODULE.bazel
index 9cdcce3b2..f80a08a99 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -1,12 +1,12 @@
module(
name = "pico-sdk",
- version = "2.1.0",
+ version = "2.1.1",
)
bazel_dep(name = "platforms", version = "0.0.9")
bazel_dep(name = "bazel_skylib", version = "1.6.1")
bazel_dep(name = "rules_python", version = "0.36.0")
-bazel_dep(name = "picotool", version = "2.1.0")
+bazel_dep(name = "picotool", version = "2.1.1")
bazel_dep(name = "rules_cc", version = "0.0.10")
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
@@ -54,34 +54,34 @@ http_archive(
http_archive(
name = "clang_linux-x86_64",
build_file = "//bazel/toolchain:clang.BUILD",
- sha256 = "6c599d1aba568236064c340d7813324849896d5a4e2f3fd8225a8c31bfcbf884",
+ sha256 = "82302f8f0d9cb1062e60756147403c1525e965e1d7b777fab8076c74c7a5a19b",
type = "zip",
- url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/linux-amd64/+/git_revision:2b0a708f41dd6291ee744704d43febc975e3d026",
+ url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/linux-amd64/+/git_revision:910be4ff90d7d07bd4518ea03b85c0974672bf9c",
)
http_archive(
name = "clang_win-x86_64",
build_file = "//bazel/toolchain:clang.BUILD",
- sha256 = "f49ba4123ee3958f2b47289d017a5b3f1ca01f82dd7a2168c45412c18101fd13",
+ sha256 = "2e9b8ac889838754e5305b6fd73c7bba7a6ec7364f1ce8ac60268b6d3bc61e6c",
type = "zip",
# Windows doesn't like `:` in the produced filename, so replace it with `%3A`.
- url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/windows-amd64/+/git_revision:2b0a708f41dd6291ee744704d43febc975e3d026".replace("git_revision:", "git_revision%3A"),
+ url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/windows-amd64/+/git_revision:910be4ff90d7d07bd4518ea03b85c0974672bf9c".replace("git_revision:", "git_revision%3A"),
)
http_archive(
name = "clang_mac-x86_64",
build_file = "//bazel/toolchain:clang.BUILD",
- sha256 = "d3516f2eb4c12d17ae77ee84c9226fbea581d4fb806910ceac4717d5adfcf748",
+ sha256 = "d3f2ef6f391ef66141092cfdf07facd18d2587a25616e1251e6e6b13b05ab3df",
type = "zip",
- url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/mac-amd64/+/git_revision:2b0a708f41dd6291ee744704d43febc975e3d026",
+ url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/mac-amd64/+/git_revision:910be4ff90d7d07bd4518ea03b85c0974672bf9c",
)
http_archive(
name = "clang_mac-aarch64",
build_file = "//bazel/toolchain:clang.BUILD",
- sha256 = "68e551f41c7e9473063b09819f6ab8ec6e7e53677f4078189656cb14dc52984b",
+ sha256 = "61109b8464e9213ef8b9bfe55ce56298b94d4c66eaea308cf2b6556b0b85429e",
type = "zip",
- url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/mac-arm64/+/git_revision:2b0a708f41dd6291ee744704d43febc975e3d026",
+ url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/mac-arm64/+/git_revision:910be4ff90d7d07bd4518ea03b85c0974672bf9c",
)
new_git_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
@@ -90,7 +90,7 @@ new_git_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:git.bzl"
new_git_repository(
name = "tinyusb",
build_file = "//src/rp2_common/tinyusb:tinyusb.BUILD",
- commit = "5217cee5de4cd555018da90f9f1bcc87fb1c1d3a", # keep-in-sync-with-submodule: lib/tinyusb
+ commit = "86ad6e56c1700e85f1c5678607a762cfe3aa2f47", # keep-in-sync-with-submodule: lib/tinyusb
remote = "https://github.com/hathach/tinyusb.git",
)
@@ -98,7 +98,7 @@ new_git_repository(
new_git_repository(
name = "btstack",
build_file = "//src/rp2_common/pico_btstack:btstack.BUILD",
- commit = "2b49e57bd1fae85ac32ac1f41cdb7c794de335f6", # keep-in-sync-with-submodule: lib/btstack
+ commit = "501e6d2b86e6c92bfb9c390bcf55709938e25ac1", # keep-in-sync-with-submodule: lib/btstack
remote = "https://github.com/bluekitchen/btstack.git",
)
@@ -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 = "cf924bb04c8984675ca0fc2178f082e404e048c3", # keep-in-sync-with-submodule: lib/cyw43-driver
+ commit = "c1075d4bc440422cf2b2fd12c64a1f53f77660ee", # keep-in-sync-with-submodule: lib/cyw43-driver
remote = "https://github.com/georgerobotics/cyw43-driver.git",
)
diff --git a/README.md b/README.md
index 69f6c4ef3..4d24d9fa2 100644
--- a/README.md
+++ b/README.md
@@ -184,7 +184,7 @@ instructions for other platforms, and just in general, we recommend you see [Ras
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.
- Specifying `PICO_BOARD=` sets up various compiler defines (e.g. default pin numbers for UART and other hardware) and in certain
+ 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
be built without a board which provides the requisite hardware functionality.
diff --git a/bazel/toolchain/BUILD.bazel b/bazel/toolchain/BUILD.bazel
index bba5baafd..ba8d947ca 100644
--- a/bazel/toolchain/BUILD.bazel
+++ b/bazel/toolchain/BUILD.bazel
@@ -79,9 +79,11 @@ cc_args(
name = "llvm-libc_args",
actions = ["@rules_cc//cc/toolchains/actions:link_actions"],
args = [
+ "--unwindlib=none",
"-nostdlib++",
"-nostartfiles",
"-Wl,-lc++",
+ "-Wl,-lm",
],
visibility = ["//visibility:private"],
)
diff --git a/cmake/preload/toolchains/pico_arm_clang_arm.cmake b/cmake/preload/toolchains/pico_arm_clang_arm.cmake
index bf06d3410..4c7816561 100644
--- a/cmake/preload/toolchains/pico_arm_clang_arm.cmake
+++ b/cmake/preload/toolchains/pico_arm_clang_arm.cmake
@@ -1,5 +1,3 @@
-# NOTE: THIS IS A WIP ONLY PICO_ARM_GCC IS CURRENTLY SUPPORTED
-# todo there is probably a more "cmake" way of doing this going thru the standard path with our "PICO" platform
# i.e. CMakeInformation and whatnot
include(${CMAKE_CURRENT_LIST_DIR}/util/find_compiler.cmake)
diff --git a/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake b/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake
index d35bdbc19..c5199e55a 100644
--- a/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake
+++ b/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake
@@ -4,5 +4,5 @@ set(CMAKE_SYSTEM_PROCESSOR cortex-m33)
set(PICO_CLANG_RUNTIMES armv8m.main_soft_nofp 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)
include(${CMAKE_CURRENT_LIST_DIR}/util/pico_arm_clang_common.cmake)
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index 3171c5d3b..5b40ed730 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -55,11 +55,21 @@ if(PICO_BUILD_DOCS)
set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
+ if(DOXYGEN_VERSION VERSION_GREATER_EQUAL "1.9.8")
+ # see https://github.com/doxygen/doxygen/issues/10562
+ set(DOXY_API_DOCS_TAB_TYPE "topics")
+ else()
+ set(DOXY_API_DOCS_TAB_TYPE "modules")
+ endif()
+ set(doxylayout_in ${CMAKE_CURRENT_SOURCE_DIR}/DoxygenLayout.xml.in)
+ set(doxylayout ${CMAKE_CURRENT_BINARY_DIR}/DoxygenLayout.xml)
+
if (PICO_PLATFORM STREQUAL "rp2040")
set(PICO_DOXYGEN_TAG "(RP2040)")
elseif (PICO_PLATFORM STREQUAL "rp2350-arm-s" OR PICO_PLATFORM STREQUAL "rp2350-riscv")
set(PICO_DOXYGEN_TAG "(RP2350)")
endif()
+ configure_file(${doxylayout_in} ${doxylayout} @ONLY)
configure_file(${doxyfile_in} ${doxyfile} @ONLY)
add_custom_target(docs
diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in
index 916877b32..f1e62f1e7 100644
--- a/docs/Doxyfile.in
+++ b/docs/Doxyfile.in
@@ -17,7 +17,7 @@ FILE_PATTERNS = *.h \
*.md
USE_MDFILE_AS_MAINPAGE = @PROJECT_SOURCE_DIR@/docs/mainpage.md
-LAYOUT_FILE = @PROJECT_SOURCE_DIR@/docs/DoxygenLayout.xml
+LAYOUT_FILE = @PROJECT_BINARY_DIR@/docs/DoxygenLayout.xml
HTML_FOOTER = @PROJECT_SOURCE_DIR@/docs/footer.html
HTML_HEADER = @PROJECT_SOURCE_DIR@/docs/header.html
@@ -65,4 +65,4 @@ PREDEFINED = __not_in_flash_func(x)= \
DOXYGEN_GENERATION= \
@DOXY_PREDEFINED@
-ENABLED_SECTIONS = @DOXY_ENABLED_SECTIONS@
\ No newline at end of file
+ENABLED_SECTIONS = @DOXY_ENABLED_SECTIONS@
diff --git a/docs/DoxygenLayout.xml b/docs/DoxygenLayout.xml.in
similarity index 98%
rename from docs/DoxygenLayout.xml
rename to docs/DoxygenLayout.xml.in
index 07c1c980c..34dd66fcd 100644
--- a/docs/DoxygenLayout.xml
+++ b/docs/DoxygenLayout.xml.in
@@ -3,7 +3,7 @@
-
+
diff --git a/external/pico_sdk_import.cmake b/external/pico_sdk_import.cmake
index a0721d0d1..d493cc23a 100644
--- a/external/pico_sdk_import.cmake
+++ b/external/pico_sdk_import.cmake
@@ -3,6 +3,28 @@
# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()
+# Copyright 2020 (c) 2020 Raspberry Pi (Trading) Ltd.
+#
+# 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. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
+
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
@@ -40,25 +62,40 @@ if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
- # GIT_SUBMODULES_RECURSE was added in 3.17
- if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
- FetchContent_Declare(
- pico_sdk
- GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
- GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
- GIT_SUBMODULES_RECURSE FALSE
- )
- else ()
- FetchContent_Declare(
- pico_sdk
- GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
- GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
- )
- endif ()
+ FetchContent_Declare(
+ pico_sdk
+ GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
+ GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
+ )
if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
- FetchContent_Populate(pico_sdk)
+ # GIT_SUBMODULES_RECURSE was added in 3.17
+ if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
+ FetchContent_Populate(
+ pico_sdk
+ QUIET
+ GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
+ GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
+ GIT_SUBMODULES_RECURSE FALSE
+
+ SOURCE_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-src
+ BINARY_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-build
+ SUBBUILD_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-subbuild
+ )
+ else ()
+ FetchContent_Populate(
+ pico_sdk
+ QUIET
+ GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
+ GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
+
+ SOURCE_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-src
+ BINARY_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-build
+ SUBBUILD_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-subbuild
+ )
+ endif ()
+
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
diff --git a/lib/btstack b/lib/btstack
index 2b49e57bd..501e6d2b8 160000
--- a/lib/btstack
+++ b/lib/btstack
@@ -1 +1 @@
-Subproject commit 2b49e57bd1fae85ac32ac1f41cdb7c794de335f6
+Subproject commit 501e6d2b86e6c92bfb9c390bcf55709938e25ac1
diff --git a/lib/cyw43-driver b/lib/cyw43-driver
index cf924bb04..c1075d4bc 160000
--- a/lib/cyw43-driver
+++ b/lib/cyw43-driver
@@ -1 +1 @@
-Subproject commit cf924bb04c8984675ca0fc2178f082e404e048c3
+Subproject commit c1075d4bc440422cf2b2fd12c64a1f53f77660ee
diff --git a/lib/tinyusb b/lib/tinyusb
index 5217cee5d..86ad6e56c 160000
--- a/lib/tinyusb
+++ b/lib/tinyusb
@@ -1 +1 @@
-Subproject commit 5217cee5de4cd555018da90f9f1bcc87fb1c1d3a
+Subproject commit 86ad6e56c1700e85f1c5678607a762cfe3aa2f47
diff --git a/pico_sdk_version.cmake b/pico_sdk_version.cmake
index 27a215389..58d0b1483 100644
--- a/pico_sdk_version.cmake
+++ b/pico_sdk_version.cmake
@@ -6,10 +6,10 @@ set(PICO_SDK_VERSION_MAJOR 2)
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 0)
+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)
+# set(PICO_SDK_VERSION_PRE_RELEASE_ID develop)
# 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/boards/include/boards/adafruit_feather_rp2350.h b/src/boards/include/boards/adafruit_feather_rp2350.h
index 20d77478d..75aaaf902 100644
--- a/src/boards/include/boards/adafruit_feather_rp2350.h
+++ b/src/boards/include/boards/adafruit_feather_rp2350.h
@@ -16,6 +16,11 @@
#ifndef _BOARDS_ADAFRUIT_FEATHER_RP2350_H
#define _BOARDS_ADAFRUIT_FEATHER_RP2350_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_FEATHER_RP2350
diff --git a/src/boards/include/boards/seeed_xiao_rp2350.h b/src/boards/include/boards/seeed_xiao_rp2350.h
index 3390dedcc..52e163654 100644
--- a/src/boards/include/boards/seeed_xiao_rp2350.h
+++ b/src/boards/include/boards/seeed_xiao_rp2350.h
@@ -134,7 +134,7 @@
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
#ifndef PICO_FLASH_SPI_CLKDIV
-#define PICO_FLASH_SPI_CLKDIV 2
+#define PICO_FLASH_SPI_CLKDIV 4
#endif
// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024)
diff --git a/src/boards/include/boards/sparkfun_iotnode_lorawan_rp2350.h b/src/boards/include/boards/sparkfun_iotnode_lorawan_rp2350.h
new file mode 100644
index 000000000..5bea33cc4
--- /dev/null
+++ b/src/boards/include/boards/sparkfun_iotnode_lorawan_rp2350.h
@@ -0,0 +1,88 @@
+/*
+ * 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 Node LoRaWAN
+//
+// 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
+
+// For board detection
+#define SPARKFUN_IOTNODE_LORAWAN_RP2350
+
+// --- 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 18
+#endif
+#ifndef PICO_DEFAULT_UART_RX_PIN
+#define PICO_DEFAULT_UART_RX_PIN 19
+#endif
+
+// --- LED ---
+#ifndef PICO_DEFAULT_WS2812_PIN
+#define PICO_DEFAULT_WS2812_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 20
+#endif
+#ifndef PICO_DEFAULT_I2C_SCL_PIN
+#define PICO_DEFAULT_I2C_SCL_PIN 21
+#endif
+
+// --- SPI ---
+#ifndef PICO_DEFAULT_SPI
+#define PICO_DEFAULT_SPI 1
+#endif
+#ifndef PICO_DEFAULT_SPI_SCK_PIN
+#define PICO_DEFAULT_SPI_SCK_PIN 14
+#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 12
+#endif
+#ifndef PICO_DEFAULT_SPI_CSN_PIN
+#define PICO_DEFAULT_SPI_CSN_PIN 13
+#endif
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024)
+#ifndef PICO_FLASH_SIZE_BYTES
+#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
+#endif
+
+// pico_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_pico_cam_a.h b/src/boards/include/boards/waveshare_pico_cam_a.h
new file mode 100755
index 000000000..a8b3b40e8
--- /dev/null
+++ b/src/boards/include/boards/waveshare_pico_cam_a.h
@@ -0,0 +1,83 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2040
+
+#ifndef _BOARDS_WAVESHARE_PICO_CAM_A_H
+#define _BOARDS_WAVESHARE_PICO_CAM_A_H
+
+// For board detection
+#define WAVESHARE_PICO_CAM_A
+
+// --- 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
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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
+
+// --- LCD ---
+#ifndef WAVESHARE_LCD_SPI
+#define WAVESHARE_LCD_SPI 1
+#endif
+#ifndef WAVESHARE_LCD_DC_PIN
+#define WAVESHARE_LCD_DC_PIN 9
+#endif
+#ifndef WAVESHARE_LCD_CS_PIN
+#define WAVESHARE_LCD_CS_PIN 13
+#endif
+#ifndef WAVESHARE_LCD_SCLK_PIN
+#define WAVESHARE_LCD_SCLK_PIN 10
+#endif
+#ifndef WAVESHARE_LCD_TX_PIN
+#define WAVESHARE_LCD_TX_PIN 11
+#endif
+#ifndef WAVESHARE_LCD_RST_PIN
+#define WAVESHARE_LCD_RST_PIN 7
+#endif
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024)
+#ifndef PICO_FLASH_SIZE_BYTES
+#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
+#endif
+// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
+#define PICO_SMPS_MODE_PIN 23
+
+// 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/waveshare_rp2040_ble.h b/src/boards/include/boards/waveshare_rp2040_ble.h
new file mode 100755
index 000000000..8a56e9c58
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2040_ble.h
@@ -0,0 +1,83 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2040
+
+#ifndef _BOARDS_WAVESHARE_RP2040_BLE_H
+#define _BOARDS_WAVESHARE_RP2040_BLE_H
+
+// For board detection
+#define WAVESHARE_RP2040_BLE
+
+// --- 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
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (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
+
+// 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/waveshare_rp2040_eth.h b/src/boards/include/boards/waveshare_rp2040_eth.h
new file mode 100755
index 000000000..8d3912e60
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2040_eth.h
@@ -0,0 +1,83 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2040
+
+#ifndef _BOARDS_WAVESHARE_RP2040_ETH_H
+#define _BOARDS_WAVESHARE_RP2040_ETH_H
+
+// For board detection
+#define WAVESHARE_RP2040_ETH
+
+// --- 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 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 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
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (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
+
+// 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/waveshare_rp2040_geek.h b/src/boards/include/boards/waveshare_rp2040_geek.h
new file mode 100755
index 000000000..cba41cf7f
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2040_geek.h
@@ -0,0 +1,103 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2040
+
+#ifndef _BOARDS_WAVESHARE_RP2040_GEEK_H
+#define _BOARDS_WAVESHARE_RP2040_GEEK_H
+
+// For board detection
+#define WAVESHARE_RP2040_GEEK
+
+// --- UART ---
+#ifndef PICO_DEFAULT_UART
+#define PICO_DEFAULT_UART 1
+#endif
+#ifndef PICO_DEFAULT_UART_TX_PIN
+#define PICO_DEFAULT_UART_TX_PIN 4
+#endif
+#ifndef PICO_DEFAULT_UART_RX_PIN
+#define PICO_DEFAULT_UART_RX_PIN 5
+#endif
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 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 20
+#endif
+#ifndef PICO_DEFAULT_SPI_CSN_PIN
+#define PICO_DEFAULT_SPI_CSN_PIN 17
+#endif
+
+// --- LCD ---
+#ifndef WAVESHARE_LCD_SPI
+#define WAVESHARE_LCD_SPI 1
+#endif
+#ifndef WAVESHARE_LCD_DC_PIN
+#define WAVESHARE_LCD_DC_PIN 8
+#endif
+#ifndef WAVESHARE_LCD_CS_PIN
+#define WAVESHARE_LCD_CS_PIN 9
+#endif
+#ifndef WAVESHARE_LCD_SCLK_PIN
+#define WAVESHARE_LCD_SCLK_PIN 10
+#endif
+#ifndef WAVESHARE_LCD_TX_PIN
+#define WAVESHARE_LCD_TX_PIN 11
+#endif
+#ifndef WAVESHARE_LCD_RST_PIN
+#define WAVESHARE_LCD_RST_PIN 12
+#endif
+#ifndef WAVESHARE_LCD_BL_PIN
+#define WAVESHARE_LCD_BL_PIN 25
+#endif
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (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
+
+// 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/waveshare_rp2040_lcd_0.96.h b/src/boards/include/boards/waveshare_rp2040_lcd_0.96.h
index 079187059..267dc1753 100644
--- a/src/boards/include/boards/waveshare_rp2040_lcd_0.96.h
+++ b/src/boards/include/boards/waveshare_rp2040_lcd_0.96.h
@@ -59,26 +59,26 @@
#endif
// --- LCD ---
-#ifndef WAVESHARE_RP2040_LCD_SPI
-#define WAVESHARE_RP2040_LCD_SPI 1
+#ifndef WAVESHARE_LCD_SPI
+#define WAVESHARE_LCD_SPI 1
#endif
-#ifndef WAVESHARE_RP2040_LCD_DC_PIN
-#define WAVESHARE_RP2040_LCD_DC_PIN 8
+#ifndef WAVESHARE_LCD_DC_PIN
+#define WAVESHARE_LCD_DC_PIN 8
#endif
-#ifndef WAVESHARE_RP2040_LCD_CS_PIN
-#define WAVESHARE_RP2040_LCD_CS_PIN 9
+#ifndef WAVESHARE_LCD_CS_PIN
+#define WAVESHARE_LCD_CS_PIN 9
#endif
-#ifndef WAVESHARE_RP2040_LCD_SCLK_PIN
-#define WAVESHARE_RP2040_LCD_SCLK_PIN 10
+#ifndef WAVESHARE_LCD_SCLK_PIN
+#define WAVESHARE_LCD_SCLK_PIN 10
#endif
-#ifndef WAVESHARE_RP2040_LCD_TX_PIN
-#define WAVESHARE_RP2040_LCD_TX_PIN 11
+#ifndef WAVESHARE_LCD_TX_PIN
+#define WAVESHARE_LCD_TX_PIN 11
#endif
-#ifndef WAVESHARE_RP2040_LCD_RST_PIN
-#define WAVESHARE_RP2040_LCD_RST_PIN 12
+#ifndef WAVESHARE_LCD_RST_PIN
+#define WAVESHARE_LCD_RST_PIN 12
#endif
-#ifndef WAVESHARE_RP2040_LCD_BL_PIN
-#define WAVESHARE_RP2040_LCD_BL_PIN 25
+#ifndef WAVESHARE_LCD_BL_PIN
+#define WAVESHARE_LCD_BL_PIN 25
#endif
// --- FLASH ---
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 816aec2e1..f88b9ed3d 100644
--- a/src/boards/include/boards/waveshare_rp2040_lcd_1.28.h
+++ b/src/boards/include/boards/waveshare_rp2040_lcd_1.28.h
@@ -59,30 +59,30 @@
#endif
// --- LCD ---
-#ifndef WAVESHARE_RP2040_LCD_SPI
-#define WAVESHARE_RP2040_LCD_SPI 1
+#ifndef WAVESHARE_LCD_SPI
+#define WAVESHARE_LCD_SPI 1
#endif
-#ifndef WAVESHARE_RP2040_LCD_DC_PIN
-#define WAVESHARE_RP2040_LCD_DC_PIN 8
+#ifndef WAVESHARE_LCD_DC_PIN
+#define WAVESHARE_LCD_DC_PIN 8
#endif
-#ifndef WAVESHARE_RP2040_LCD_CS_PIN
-#define WAVESHARE_RP2040_LCD_CS_PIN 9
+#ifndef WAVESHARE_LCD_CS_PIN
+#define WAVESHARE_LCD_CS_PIN 9
#endif
-#ifndef WAVESHARE_RP2040_LCD_SCLK_PIN
-#define WAVESHARE_RP2040_LCD_SCLK_PIN 10
+#ifndef WAVESHARE_LCD_SCLK_PIN
+#define WAVESHARE_LCD_SCLK_PIN 10
#endif
-#ifndef WAVESHARE_RP2040_LCD_TX_PIN
-#define WAVESHARE_RP2040_LCD_TX_PIN 11
+#ifndef WAVESHARE_LCD_TX_PIN
+#define WAVESHARE_LCD_TX_PIN 11
#endif
-#ifndef WAVESHARE_RP2040_LCD_RST_PIN
-#define WAVESHARE_RP2040_LCD_RST_PIN 12
+#ifndef WAVESHARE_LCD_RST_PIN
+#define WAVESHARE_LCD_RST_PIN 12
#endif
-#ifndef WAVESHARE_RP2040_LCD_BL_PIN
-#define WAVESHARE_RP2040_LCD_BL_PIN 25
+#ifndef WAVESHARE_LCD_BL_PIN
+#define WAVESHARE_LCD_BL_PIN 25
#endif
// --- ADC ---
-#ifndef WAVESHARE_RP2040_BAT_ADC_PIN
-#define WAVESHARE_RP2040_BAT_ADC_PIN 29
+#ifndef WAVESHARE_BAT_ADC_PIN
+#define WAVESHARE_BAT_ADC_PIN 29
#endif
// --- FLASH ---
diff --git a/src/boards/include/boards/waveshare_rp2040_matrix.h b/src/boards/include/boards/waveshare_rp2040_matrix.h
new file mode 100755
index 000000000..9233a3639
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2040_matrix.h
@@ -0,0 +1,84 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2040
+
+#ifndef _BOARDS_WAVESHARE_RP2040_MATRIX_H
+#define _BOARDS_WAVESHARE_RP2040_MATRIX_H
+
+// For board detection
+#define WAVESHARE_RP2040_MATRIX
+
+// --- 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 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
+
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (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
+
+// 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/waveshare_rp2040_pizero.h b/src/boards/include/boards/waveshare_rp2040_pizero.h
new file mode 100755
index 000000000..7c598fa59
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2040_pizero.h
@@ -0,0 +1,80 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2040
+
+#ifndef _BOARDS_WAVESHARE_RP2040_PIZERO_H
+#define _BOARDS_WAVESHARE_RP2040_PIZERO_H
+
+// For board detection
+#define WAVESHARE_RP2040_PIZERO
+
+// --- 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
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 18
+#endif
+#ifndef PICO_DEFAULT_SPI_TX_PIN
+#define PICO_DEFAULT_SPI_TX_PIN 19
+#endif
+#ifndef PICO_DEFAULT_SPI_RX_PIN
+#define PICO_DEFAULT_SPI_RX_PIN 16
+#endif
+#ifndef PICO_DEFAULT_SPI_CSN_PIN
+#define PICO_DEFAULT_SPI_CSN_PIN 17
+#endif
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024)
+#ifndef PICO_FLASH_SIZE_BYTES
+#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
+#endif
+// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
+#define PICO_SMPS_MODE_PIN 23
+
+// 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/waveshare_rp2040_power_management_hat_b.h b/src/boards/include/boards/waveshare_rp2040_power_management_hat_b.h
new file mode 100755
index 000000000..8290eb022
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2040_power_management_hat_b.h
@@ -0,0 +1,80 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2040
+
+#ifndef _BOARDS_WAVESHARE_RP2040_POWER_MANAGEMENT_HAT_B_H
+#define _BOARDS_WAVESHARE_RP2040_POWER_MANAGEMENT_HAT_B_H
+
+// For board detection
+#define WAVESHARE_RP2040_POWER_MANAGEMENT_HAT_B
+
+// --- 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
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 18
+#endif
+#ifndef PICO_DEFAULT_SPI_TX_PIN
+#define PICO_DEFAULT_SPI_TX_PIN 19
+#endif
+#ifndef PICO_DEFAULT_SPI_RX_PIN
+#define PICO_DEFAULT_SPI_RX_PIN 16
+#endif
+#ifndef PICO_DEFAULT_SPI_CSN_PIN
+#define PICO_DEFAULT_SPI_CSN_PIN 17
+#endif
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (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
+
+// 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/waveshare_rp2040_tiny.h b/src/boards/include/boards/waveshare_rp2040_tiny.h
new file mode 100755
index 000000000..84f646280
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2040_tiny.h
@@ -0,0 +1,83 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2040
+
+#ifndef _BOARDS_WAVESHARE_RP2040_TINY_H
+#define _BOARDS_WAVESHARE_RP2040_TINY_H
+
+// For board detection
+#define WAVESHARE_RP2040_TINY
+
+// --- 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 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
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (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
+
+// 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/waveshare_rp2040_touch_lcd_1.28.h b/src/boards/include/boards/waveshare_rp2040_touch_lcd_1.28.h
new file mode 100755
index 000000000..35a340197
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2040_touch_lcd_1.28.h
@@ -0,0 +1,105 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2040
+
+#ifndef _BOARDS_WAVESHARE_RP2040_TOUCH_LCD_1_28_H
+#define _BOARDS_WAVESHARE_RP2040_TOUCH_LCD_1_28_H
+
+// For board detection
+#define WAVESHARE_RP2040_TOUCH_LCD_1_28
+
+// --- 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
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 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
+
+// --- LCD ---
+#ifndef WAVESHARE_LCD_SPI
+#define WAVESHARE_LCD_SPI 1
+#endif
+#ifndef WAVESHARE_LCD_DC_PIN
+#define WAVESHARE_LCD_DC_PIN 8
+#endif
+#ifndef WAVESHARE_LCD_CS_PIN
+#define WAVESHARE_LCD_CS_PIN 9
+#endif
+#ifndef WAVESHARE_LCD_SCLK_PIN
+#define WAVESHARE_LCD_SCLK_PIN 10
+#endif
+#ifndef WAVESHARE_LCD_TX_PIN
+#define WAVESHARE_LCD_TX_PIN 11
+#endif
+#ifndef WAVESHARE_LCD_RST_PIN
+#define WAVESHARE_LCD_RST_PIN 12
+#endif
+#ifndef WAVESHARE_LCD_BL_PIN
+#define WAVESHARE_LCD_BL_PIN 25
+#endif
+
+// --- ADC ---
+#ifndef WAVESHARE_BAT_ADC_PIN
+#define WAVESHARE_BAT_ADC_PIN 29
+#endif
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024)
+#ifndef PICO_FLASH_SIZE_BYTES
+#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/waveshare_rp2350_eth.h b/src/boards/include/boards/waveshare_rp2350_eth.h
new file mode 100755
index 000000000..f4aa7ee48
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_eth.h
@@ -0,0 +1,87 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_ETH_H
+#define _BOARDS_WAVESHARE_RP2350_ETH_H
+
+// For board detection
+#define WAVESHARE_RP2350_ETH
+
+// --- 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 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 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
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (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
+#ifndef PICO_RP2350_A2_SUPPORTED
+#define PICO_RP2350_A2_SUPPORTED 1
+#endif
+
+#endif
diff --git a/src/boards/include/boards/waveshare_rp2350_geek.h b/src/boards/include/boards/waveshare_rp2350_geek.h
new file mode 100755
index 000000000..ff065cbda
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_geek.h
@@ -0,0 +1,107 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_GEEK_H
+#define _BOARDS_WAVESHARE_RP2350_GEEK_H
+
+// For board detection
+#define WAVESHARE_RP2350_GEEK
+
+// --- RP2350 VARIANT ---
+#define PICO_RP2350A 1
+
+// --- UART ---
+#ifndef PICO_DEFAULT_UART
+#define PICO_DEFAULT_UART 1
+#endif
+#ifndef PICO_DEFAULT_UART_TX_PIN
+#define PICO_DEFAULT_UART_TX_PIN 4
+#endif
+#ifndef PICO_DEFAULT_UART_RX_PIN
+#define PICO_DEFAULT_UART_RX_PIN 5
+#endif
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 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 20
+#endif
+#ifndef PICO_DEFAULT_SPI_CSN_PIN
+#define PICO_DEFAULT_SPI_CSN_PIN 17
+#endif
+
+// --- LCD ---
+#ifndef WAVESHARE_LCD_SPI
+#define WAVESHARE_LCD_SPI 1
+#endif
+#ifndef WAVESHARE_LCD_DC_PIN
+#define WAVESHARE_LCD_DC_PIN 8
+#endif
+#ifndef WAVESHARE_LCD_CS_PIN
+#define WAVESHARE_LCD_CS_PIN 9
+#endif
+#ifndef WAVESHARE_LCD_SCLK_PIN
+#define WAVESHARE_LCD_SCLK_PIN 10
+#endif
+#ifndef WAVESHARE_LCD_TX_PIN
+#define WAVESHARE_LCD_TX_PIN 11
+#endif
+#ifndef WAVESHARE_LCD_RST_PIN
+#define WAVESHARE_LCD_RST_PIN 12
+#endif
+#ifndef WAVESHARE_LCD_BL_PIN
+#define WAVESHARE_LCD_BL_PIN 25
+#endif
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024)
+#ifndef PICO_FLASH_SIZE_BYTES
+#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
+#endif
+// 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
+#ifndef PICO_RP2350_A2_SUPPORTED
+#define PICO_RP2350_A2_SUPPORTED 1
+#endif
+
+#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
new file mode 100755
index 000000000..fd6c9f778
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_lcd_0.96.h
@@ -0,0 +1,107 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_LCD_0_96_H
+#define _BOARDS_WAVESHARE_RP2350_LCD_0_96_H
+
+// For board detection
+#define WAVESHARE_RP2350_LCD_0_96
+
+// --- 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
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 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
+
+// --- LCD ---
+#ifndef WAVESHARE_LCD_SPI
+#define WAVESHARE_LCD_SPI 1
+#endif
+#ifndef WAVESHARE_LCD_DC_PIN
+#define WAVESHARE_LCD_DC_PIN 8
+#endif
+#ifndef WAVESHARE_LCD_CS_PIN
+#define WAVESHARE_LCD_CS_PIN 9
+#endif
+#ifndef WAVESHARE_LCD_SCLK_PIN
+#define WAVESHARE_LCD_SCLK_PIN 10
+#endif
+#ifndef WAVESHARE_LCD_TX_PIN
+#define WAVESHARE_LCD_TX_PIN 11
+#endif
+#ifndef WAVESHARE_LCD_RST_PIN
+#define WAVESHARE_LCD_RST_PIN 12
+#endif
+#ifndef WAVESHARE_LCD_BL_PIN
+#define WAVESHARE_LCD_BL_PIN 25
+#endif
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 3
+#endif
+
+// pico_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
+#ifndef PICO_RP2350_A2_SUPPORTED
+#define PICO_RP2350_A2_SUPPORTED 1
+#endif
+
+#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
new file mode 100755
index 000000000..4d4e0e022
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_lcd_1.28.h
@@ -0,0 +1,112 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_LCD_1_28_H
+#define _BOARDS_WAVESHARE_RP2350_LCD_1_28_H
+
+// For board detection
+#define WAVESHARE_RP2350_LCD_1_28
+
+// --- 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
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 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
+
+// --- LCD ---
+#ifndef WAVESHARE_LCD_SPI
+#define WAVESHARE_LCD_SPI 1
+#endif
+#ifndef WAVESHARE_LCD_DC_PIN
+#define WAVESHARE_LCD_DC_PIN 8
+#endif
+#ifndef WAVESHARE_LCD_CS_PIN
+#define WAVESHARE_LCD_CS_PIN 9
+#endif
+#ifndef WAVESHARE_LCD_SCLK_PIN
+#define WAVESHARE_LCD_SCLK_PIN 10
+#endif
+#ifndef WAVESHARE_LCD_TX_PIN
+#define WAVESHARE_LCD_TX_PIN 11
+#endif
+#ifndef WAVESHARE_LCD_RST_PIN
+#define WAVESHARE_LCD_RST_PIN 12
+#endif
+#ifndef WAVESHARE_LCD_BL_PIN
+#define WAVESHARE_LCD_BL_PIN 25
+#endif
+
+// --- ADC ---
+#ifndef WAVESHARE_BAT_ADC_PIN
+#define WAVESHARE_BAT_ADC_PIN 29
+#endif
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 3
+#endif
+
+// pico_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
+#ifndef PICO_RP2350_A2_SUPPORTED
+#define PICO_RP2350_A2_SUPPORTED 1
+#endif
+
+#endif
diff --git a/src/boards/include/boards/waveshare_rp2350_one.h b/src/boards/include/boards/waveshare_rp2350_one.h
new file mode 100755
index 000000000..937e1b682
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_one.h
@@ -0,0 +1,87 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_ONE_H
+#define _BOARDS_WAVESHARE_RP2350_ONE_H
+
+// For board detection
+#define WAVESHARE_RP2350_ONE
+
+// --- 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 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
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (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
+#ifndef PICO_RP2350_A2_SUPPORTED
+#define PICO_RP2350_A2_SUPPORTED 1
+#endif
+
+#endif
diff --git a/src/boards/include/boards/waveshare_rp2350_plus_16mb.h b/src/boards/include/boards/waveshare_rp2350_plus_16mb.h
new file mode 100755
index 000000000..8de280b1c
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_plus_16mb.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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_PLUS_16MB_H
+#define _BOARDS_WAVESHARE_RP2350_PLUS_16MB_H
+
+// For board detection
+#define WAVESHARE_RP2350_PLUS_16MB
+
+// --- 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
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 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
+
+// --- ADC ---
+#ifndef WAVESHARE_BAT_ADC_PIN
+#define WAVESHARE_BAT_ADC_PIN 29
+#endif
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024)
+#ifndef PICO_FLASH_SIZE_BYTES
+#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
+#endif
+// 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
+#ifndef PICO_RP2350_A2_SUPPORTED
+#define PICO_RP2350_A2_SUPPORTED 1
+#endif
+
+#endif
diff --git a/src/boards/include/boards/waveshare_rp2350_plus_4mb.h b/src/boards/include/boards/waveshare_rp2350_plus_4mb.h
new file mode 100755
index 000000000..3c8b98617
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_plus_4mb.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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_PLUS_4MB_H
+#define _BOARDS_WAVESHARE_RP2350_PLUS_4MB_H
+
+// For board detection
+#define WAVESHARE_RP2350_PLUS_4MB
+
+// --- 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
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 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
+
+// --- ADC ---
+#ifndef WAVESHARE_BAT_ADC_PIN
+#define WAVESHARE_BAT_ADC_PIN 29
+#endif
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (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
+#ifndef PICO_RP2350_A2_SUPPORTED
+#define PICO_RP2350_A2_SUPPORTED 1
+#endif
+
+#endif
diff --git a/src/boards/include/boards/waveshare_rp2350_tiny.h b/src/boards/include/boards/waveshare_rp2350_tiny.h
new file mode 100755
index 000000000..23af13c0f
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_tiny.h
@@ -0,0 +1,87 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_TINY_H
+#define _BOARDS_WAVESHARE_RP2350_TINY_H
+
+// For board detection
+#define WAVESHARE_RP2350_TINY
+
+// --- 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 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
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 3
+#endif
+
+// pico_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
+#ifndef PICO_RP2350_A2_SUPPORTED
+#define PICO_RP2350_A2_SUPPORTED 1
+#endif
+
+#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
new file mode 100755
index 000000000..52eea9eb4
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_touch_lcd_1.28.h
@@ -0,0 +1,112 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_TOUCH_LCD_1_28_H
+#define _BOARDS_WAVESHARE_RP2350_TOUCH_LCD_1_28_H
+
+// For board detection
+#define WAVESHARE_RP2350_TOUCH_LCD_1_28
+
+// --- 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
+
+// no PICO_DEFAULT_WS2812_PIN
+
+// --- 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 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
+
+// --- LCD ---
+#ifndef WAVESHARE_LCD_SPI
+#define WAVESHARE_LCD_SPI 1
+#endif
+#ifndef WAVESHARE_LCD_DC_PIN
+#define WAVESHARE_LCD_DC_PIN 8
+#endif
+#ifndef WAVESHARE_LCD_CS_PIN
+#define WAVESHARE_LCD_CS_PIN 9
+#endif
+#ifndef WAVESHARE_LCD_SCLK_PIN
+#define WAVESHARE_LCD_SCLK_PIN 10
+#endif
+#ifndef WAVESHARE_LCD_TX_PIN
+#define WAVESHARE_LCD_TX_PIN 11
+#endif
+#ifndef WAVESHARE_LCD_RST_PIN
+#define WAVESHARE_LCD_RST_PIN 12
+#endif
+#ifndef WAVESHARE_LCD_BL_PIN
+#define WAVESHARE_LCD_BL_PIN 25
+#endif
+
+// --- ADC ---
+#ifndef WAVESHARE_BAT_ADC_PIN
+#define WAVESHARE_BAT_ADC_PIN 29
+#endif
+
+// --- FLASH ---
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 2
+#endif
+
+// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (16 * 1024 * 1024)
+#ifndef PICO_FLASH_SIZE_BYTES
+#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
+#endif
+// 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
+#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
new file mode 100755
index 000000000..10b5d8b91
--- /dev/null
+++ b/src/boards/include/boards/waveshare_rp2350_zero.h
@@ -0,0 +1,87 @@
+/*
+ * 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
+// -----------------------------------------------------
+
+// pico_cmake_set PICO_PLATFORM=rp2350
+
+#ifndef _BOARDS_WAVESHARE_RP2350_ZERO_H
+#define _BOARDS_WAVESHARE_RP2350_ZERO_H
+
+// For board detection
+#define WAVESHARE_RP2350_ZERO
+
+// --- 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 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
+
+// --- FLASH ---
+
+#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
+
+#ifndef PICO_FLASH_SPI_CLKDIV
+#define PICO_FLASH_SPI_CLKDIV 3
+#endif
+
+// pico_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
+#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 5cabf3cc9..00a5fffc6 100644
--- a/src/cmake/on_device.cmake
+++ b/src/cmake/on_device.cmake
@@ -37,10 +37,9 @@ function(pico_add_dis_output TARGET)
set(EXTRA_COMMAND COMMAND picotool coprodis --quiet ${output_path}$>,$,$>.dis ${output_path}$>,$,$>.dis)
endif()
endif()
-
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_OBJDUMP} -h $ > ${output_path}$>,$,$>.dis
- COMMAND ${CMAKE_OBJDUMP} -d $ >> ${output_path}$>,$,$>.dis
+ COMMAND ${CMAKE_OBJDUMP} -d ${PICO_DISASM_OBJDUMP_ARGS} $ >> ${output_path}$>,$,$>.dis
${EXTRA_COMMAND}
VERBATIM
)
diff --git a/src/common/README.md b/src/common/README.md
index 0f30a4211..5397946c4 100644
--- a/src/common/README.md
+++ b/src/common/README.md
@@ -1,3 +1,3 @@
This directory code that is common to all builds regardless of `PICO_PLATFORM`. It is a mix
of common header files, or high level functionality built entirely using `hardware_` or `pico_` libraries provided
-by the actual target `PICO_PLATFORM``
\ No newline at end of file
+by the actual target `PICO_PLATFORM`
diff --git a/src/common/boot_picobin_headers/include/boot/picobin.h b/src/common/boot_picobin_headers/include/boot/picobin.h
index 25308478b..0b65221e0 100644
--- a/src/common/boot_picobin_headers/include/boot/picobin.h
+++ b/src/common/boot_picobin_headers/include/boot/picobin.h
@@ -76,6 +76,9 @@
#define PICOBIN_IMAGE_TYPE_EXE_CPU_VARMULET _u(2)
#define PICOBIN_IMAGE_TYPE_EXE_CPU_AS_BITS(x) _PICOBIN_INDEX_TO_BITS(PICOBIN_IMAGE_TYPE_EXE_CPU, _ ## x)
+#define PICOBIN_IMAGE_TYPE_EXE_EXTRA_SECURITY_LSB _u(11)
+#define PICOBIN_IMAGE_TYPE_EXE_EXTRA_SECURITY_BITS _u(0x0800)
+
#define PICOBIN_IMAGE_TYPE_EXE_CHIP_LSB _u(12)
#define PICOBIN_IMAGE_TYPE_EXE_CHIP_BITS _u(0x7000)
#define PICOBIN_IMAGE_TYPE_EXE_CHIP_RP2040 _u(0)
diff --git a/src/common/pico_time/include/pico/time.h b/src/common/pico_time/include/pico/time.h
index 53a606bcb..771fe42d6 100644
--- a/src/common/pico_time/include/pico/time.h
+++ b/src/common/pico_time/include/pico/time.h
@@ -688,7 +688,6 @@ static inline bool cancel_alarm(alarm_id_t alarm_id) {
* \brief Return the time remaining before the next trigger of an alarm
* \ingroup alarm
*
- * @param pool the alarm_pool containing the alarm
* @param alarm_id the alarm
*
* @return >=0 the number of microseconds before the next trigger
diff --git a/src/rp2040/hardware_regs/RP2040.svd b/src/rp2040/hardware_regs/RP2040.svd
index 7ffdf3868..2bac8265d 100644
--- a/src/rp2040/hardware_regs/RP2040.svd
+++ b/src/rp2040/hardware_regs/RP2040.svd
@@ -32214,7 +32214,8 @@ SPDX-License-Identifier: BSD-3-Clause
After writing, this register must be polled until it returns all-zero. Until this point, it is unsafe to restart the channel.
[15:0]
- write-only
+ read-write
+ oneToClear
diff --git a/src/rp2040/hardware_regs/include/hardware/platform_defs.h b/src/rp2040/hardware_regs/include/hardware/platform_defs.h
index 1d23b9d12..537988846 100644
--- a/src/rp2040/hardware_regs/include/hardware/platform_defs.h
+++ b/src/rp2040/hardware_regs/include/hardware/platform_defs.h
@@ -61,6 +61,11 @@
#endif
#endif
+// PICO_CONFIG: PICO_USE_FASTEST_SUPPORTED_CLOCK, Use the fastest officially supported clock by default, type=bool, default=0, group=hardware_base
+#ifndef PICO_USE_FASTEST_SUPPORTED_CLOCK
+#define PICO_USE_FASTEST_SUPPORTED_CLOCK 0
+#endif
+
// PICO_CONFIG: SYS_CLK_HZ, System operating frequency in Hz, type=int, default=125000000, advanced=true, group=hardware_base
#ifndef SYS_CLK_HZ
#ifdef SYS_CLK_KHZ
@@ -68,9 +73,13 @@
#elif defined(SYS_CLK_MHZ)
#define SYS_CLK_HZ ((SYS_CLK_MHZ) * _u(1000000))
#else
+#if PICO_USE_FASTEST_SUPPORTED_CLOCK
+#define SYS_CLK_HZ _u(200000000)
+#else
#define SYS_CLK_HZ _u(125000000)
#endif
#endif
+#endif
// PICO_CONFIG: USB_CLK_HZ, USB clock frequency. Must be 48MHz for the USB interface to operate correctly, type=int, default=48000000, advanced=true, group=hardware_base
#ifndef USB_CLK_HZ
diff --git a/src/rp2040/hardware_structs/include/hardware/structs/busctrl.h b/src/rp2040/hardware_structs/include/hardware/structs/busctrl.h
index 65893227d..2302025e7 100644
--- a/src/rp2040/hardware_structs/include/hardware/structs/busctrl.h
+++ b/src/rp2040/hardware_structs/include/hardware/structs/busctrl.h
@@ -24,7 +24,6 @@
// BITMASK [BITRANGE] FIELDNAME (RESETVALUE) DESCRIPTION
/** \brief Bus fabric performance counters on RP2040 (used as typedef \ref bus_ctrl_perf_counter_t)
- * \ingroup hardware_busctrl
*/
typedef enum bus_ctrl_perf_counter_rp2040 {
arbiter_rom_perf_event_access = 19,
diff --git a/src/rp2040/pico_platform/include/pico/platform.h b/src/rp2040/pico_platform/include/pico/platform.h
index 47aa119a7..5c157f532 100644
--- a/src/rp2040/pico_platform/include/pico/platform.h
+++ b/src/rp2040/pico_platform/include/pico/platform.h
@@ -77,6 +77,10 @@
#ifndef __ASSEMBLER__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*! \brief No-op function for the body of tight loops
* \ingroup pico_platform
*
@@ -210,6 +214,10 @@ return a;
(__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \
(a)*(b))
+#ifdef __cplusplus
+}
+#endif
+
#endif // __ASSEMBLER__
#endif
diff --git a/src/rp2350/hardware_regs/RP2350.svd b/src/rp2350/hardware_regs/RP2350.svd
index aa2c36213..fc6479ebb 100644
--- a/src/rp2350/hardware_regs/RP2350.svd
+++ b/src/rp2350/hardware_regs/RP2350.svd
@@ -62229,7 +62229,8 @@ SPDX-License-Identifier: BSD-3-Clause
After writing, this register must be polled until it returns all-zero. Until this point, it is unsafe to restart the channel.
[15:0]
- write-only
+ read-write
+ oneToClear
diff --git a/src/rp2350/hardware_regs/include/hardware/platform_defs.h b/src/rp2350/hardware_regs/include/hardware/platform_defs.h
index bd8b68a9f..25dc1d624 100644
--- a/src/rp2350/hardware_regs/include/hardware/platform_defs.h
+++ b/src/rp2350/hardware_regs/include/hardware/platform_defs.h
@@ -89,6 +89,11 @@
#endif
#endif
+// PICO_CONFIG: PICO_USE_FASTEST_SUPPORTED_CLOCK, Use the fastest officially supported clock by default, type=bool, default=0, group=hardware_base
+#ifndef PICO_USE_FASTEST_SUPPORTED_CLOCK
+#define PICO_USE_FASTEST_SUPPORTED_CLOCK 0
+#endif
+
// PICO_CONFIG: SYS_CLK_HZ, System operating frequency in Hz, type=int, default=150000000, advanced=true, group=hardware_base
#ifndef SYS_CLK_HZ
#ifdef SYS_CLK_KHZ
diff --git a/src/rp2350/hardware_structs/include/hardware/structs/busctrl.h b/src/rp2350/hardware_structs/include/hardware/structs/busctrl.h
index 2eb83a992..b38797b25 100644
--- a/src/rp2350/hardware_structs/include/hardware/structs/busctrl.h
+++ b/src/rp2350/hardware_structs/include/hardware/structs/busctrl.h
@@ -24,7 +24,6 @@
// BITMASK [BITRANGE] FIELDNAME (RESETVALUE) DESCRIPTION
/** \brief Bus fabric performance counters on RP2350 (used as typedef \ref bus_ctrl_perf_counter_t)
- * \ingroup hardware_busctrl
*/
typedef enum bus_ctrl_perf_counter_rp2350 {
arbiter_rom_perf_event_access = 19,
diff --git a/src/rp2350/pico_platform/include/pico/platform.h b/src/rp2350/pico_platform/include/pico/platform.h
index 24fec75bb..35a6a0bd6 100644
--- a/src/rp2350/pico_platform/include/pico/platform.h
+++ b/src/rp2350/pico_platform/include/pico/platform.h
@@ -70,6 +70,10 @@
#ifndef __ASSEMBLER__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*! \brief No-op function for the body of tight loops
* \ingroup pico_platform
*
@@ -281,6 +285,10 @@ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) {
(__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \
(a)*(b))
+#ifdef __cplusplus
+}
+#endif
+
#endif // __ASSEMBLER__
#endif
diff --git a/src/rp2_common/BUILD.bazel b/src/rp2_common/BUILD.bazel
index 6ad8f2241..fe1c0c3e3 100644
--- a/src/rp2_common/BUILD.bazel
+++ b/src/rp2_common/BUILD.bazel
@@ -71,6 +71,7 @@ alias(
"//src/rp2_common/hardware_base:__pkg__",
"//src/rp2_common/hardware_irq:__pkg__",
"//src/rp2_common/hardware_pll:__pkg__",
+ "//src/rp2_common/hardware_vreg:__pkg__",
"//src/rp2_common/hardware_watchdog:__pkg__",
"//src/rp2_common/hardware_xosc:__pkg__",
"//src/rp2_common/pico_bit_ops:__pkg__",
diff --git a/src/rp2_common/cmsis/CMakeLists.txt b/src/rp2_common/cmsis/CMakeLists.txt
index fb1fea229..d0582440e 100644
--- a/src/rp2_common/cmsis/CMakeLists.txt
+++ b/src/rp2_common/cmsis/CMakeLists.txt
@@ -44,7 +44,7 @@
# message(WARNING "Non-standard vendor ${PICO_CMSIS_VENDOR} amd device ${PICO_CMSIS_DEVICE} specified, but PICO_CMSIS_PATH was not set")
#endif()
-# ... using these 3 lines instead
+# ... using this line instead
set(PICO_CMSIS_CORE_PATH ${CMAKE_CURRENT_LIST_DIR}/stub)
if (PICO_CMSIS_CORE_PATH AND PICO_CMSIS_DEVICE)
diff --git a/src/rp2_common/hardware_adc/include/hardware/adc.h b/src/rp2_common/hardware_adc/include/hardware/adc.h
index 20ab38a82..83040566f 100644
--- a/src/rp2_common/hardware_adc/include/hardware/adc.h
+++ b/src/rp2_common/hardware_adc/include/hardware/adc.h
@@ -106,7 +106,7 @@ static inline void adc_gpio_init(uint gpio) {
*
* Select an ADC input
* \if rp2040_specific
- * On RP02040 0...3 are GPIOs 26...29 respectively. Input 4 is the onboard temperature sensor.
+ * On RP2040 0...3 are GPIOs 26...29 respectively. Input 4 is the onboard temperature sensor.
* \endif
* \if rp2350_specific
* On RP2350A 0...3 are GPIOs 26...29 respectively. Input 4 is the onboard temperature sensor.
@@ -126,7 +126,7 @@ static inline void adc_select_input(uint input) {
* \return The currently selected input channel.
*
* \if rp2040_specific
- * On RP02040 0...3 are GPIOs 26...29 respectively. Input 4 is the onboard temperature sensor.
+ * On RP2040 0...3 are GPIOs 26...29 respectively. Input 4 is the onboard temperature sensor.
* \endif
*
* \if rp2350_specific
diff --git a/src/rp2_common/hardware_boot_lock/include/hardware/boot_lock.h b/src/rp2_common/hardware_boot_lock/include/hardware/boot_lock.h
index dd63ef0e8..3244afb7a 100644
--- a/src/rp2_common/hardware_boot_lock/include/hardware/boot_lock.h
+++ b/src/rp2_common/hardware_boot_lock/include/hardware/boot_lock.h
@@ -9,6 +9,10 @@
#include "pico.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK, Enable/disable assertions in the hardware_boot_lock module, type=bool, default=0, group=hardware_boot_lock
#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK
#define PARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK 0
@@ -141,4 +145,9 @@ boot_lock_t *boot_lock_init(uint lock_num);
void boot_locks_reset(void);
#endif
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
\ No newline at end of file
diff --git a/src/rp2_common/hardware_clocks/CMakeLists.txt b/src/rp2_common/hardware_clocks/CMakeLists.txt
index 87312781c..95b16c2f3 100644
--- a/src/rp2_common/hardware_clocks/CMakeLists.txt
+++ b/src/rp2_common/hardware_clocks/CMakeLists.txt
@@ -10,4 +10,8 @@ pico_mirrored_target_link_libraries(hardware_clocks INTERFACE
hardware_vreg
hardware_watchdog
hardware_xosc
-)
\ No newline at end of file
+)
+
+if (PICO_USE_FASTEST_SUPPORTED_CLOCK)
+ target_compile_definitions(hardware_clocks INTERFACE PICO_USE_FASTEST_SUPPORTED_CLOCK=1)
+endif()
\ No newline at end of file
diff --git a/src/rp2_common/hardware_clocks/clocks.c b/src/rp2_common/hardware_clocks/clocks.c
index cf1b0f610..e3a60aabe 100644
--- a/src/rp2_common/hardware_clocks/clocks.c
+++ b/src/rp2_common/hardware_clocks/clocks.c
@@ -101,8 +101,22 @@ bool clock_configure(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32
if (freq > src_freq)
return false;
- uint32_t div = (uint32_t)((((uint64_t) src_freq) << CLOCKS_CLK_GPOUT0_DIV_INT_LSB) / freq);
- uint32_t actual_freq = (uint32_t) ((((uint64_t) src_freq) << CLOCKS_CLK_GPOUT0_DIV_INT_LSB) / div);
+ uint64_t div64 =((((uint64_t) src_freq) << CLOCKS_CLK_GPOUT0_DIV_INT_LSB) / freq);
+ uint32_t div, actual_freq;
+ if (div64 >> 32) {
+ // set div to 0 for maximum clock divider
+ div = 0;
+ actual_freq = src_freq >> (32 - CLOCKS_CLK_GPOUT0_DIV_INT_LSB);
+ } else {
+ div = (uint32_t) div64;
+#if PICO_RP2040
+ // on RP2040 only clock divider of 1, or >= 2 are supported
+ if (div < (2u << CLOCKS_CLK_GPOUT0_DIV_INT_LSB)) {
+ div = (1u << CLOCKS_CLK_GPOUT0_DIV_INT_LSB);
+ }
+#endif
+ actual_freq = (uint32_t) ((((uint64_t) src_freq) << CLOCKS_CLK_GPOUT0_DIV_INT_LSB) / div);
+ }
clock_configure_internal(clock, src, auxsrc, actual_freq, div);
// Store the configured frequency
diff --git a/src/rp2_common/hardware_clocks/include/hardware/clocks.h b/src/rp2_common/hardware_clocks/include/hardware/clocks.h
index 7611f80e8..0acd5a6b6 100644
--- a/src/rp2_common/hardware_clocks/include/hardware/clocks.h
+++ b/src/rp2_common/hardware_clocks/include/hardware/clocks.h
@@ -206,6 +206,36 @@ extern "C" {
#endif
#endif // SYS_CLK_KHZ == 125000 && XOSC_KHZ == 12000 && PLL_COMMON_REFDIV == 1
+#if PICO_RP2040 && (SYS_CLK_HZ == 200 * MHZ) && (XOSC_HZ == 12 * MHZ) && (PLL_SYS_REFDIV == 1)
+// PICO_CONFIG: SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST, Should the regulator voltage be adjusted above SYS_CLK_VREG_VOLTAGE_MIN when initializing the clocks, type=bool, default=0, advanced=true, group=hardware_clocks
+#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST
+#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST 1
+#endif
+// PICO_CONFIG: SYS_CLK_VREG_VOLTAGE_MIN, minimum voltage (see VREG_VOLTAGE_x_xx) for the voltage regulator to be ensured during clock initialization if SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST is 1, type=int, advanced=true, group=hardware_clocks
+#if SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST && !defined(SYS_CLK_VREG_VOLTAGE_MIN)
+#define SYS_CLK_VREG_VOLTAGE_MIN VREG_VOLTAGE_1_15
+#endif
+// PLL settings for fast 200 MHz system clock on RP2040
+#ifndef PLL_SYS_VCO_FREQ_HZ
+#define PLL_SYS_VCO_FREQ_HZ (1200 * MHZ)
+#endif
+#ifndef PLL_SYS_POSTDIV1
+#define PLL_SYS_POSTDIV1 6
+#endif
+#ifndef PLL_SYS_POSTDIV2
+#define PLL_SYS_POSTDIV2 1
+#endif
+#else
+#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST
+#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST 0
+#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=1, 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
+
#if !defined(PLL_SYS_VCO_FREQ_HZ) || !defined(PLL_SYS_POSTDIV1) || !defined(PLL_SYS_POSTDIV2)
#error PLL_SYS_VCO_FREQ_HZ, PLL_SYS_POSTDIV1 and PLL_SYS_POSTDIV2 must all be specified when using custom clock setup
#endif
@@ -262,9 +292,21 @@ extern "C" {
typedef clock_num_t clock_handle_t;
-/*! \brief Configure the specified clock
+/*! \brief Configure the specified clock with automatic clock divisor setup
* \ingroup hardware_clocks
*
+ * This method allows both the src_frequency of the input clock source AND the desired
+ * frequency to be specified, and will set the clock divider to achieve the exact or higher frequency
+ * achievable, with the maximum being the src_freq.
+ *
+ * \if rp2350_specific
+ * Note: The RP2350 clock hardware supports divisors from 1.0->65536.0 in steps of 1/65536
+ *
+ * \endif
+ * \if rp2040_specific
+ * Note: The RP2040 clock hardware only supports divisors of exactly 1.0 or 2.0->16777216.0 in steps of 1/256
+ * \endif
+ *
* See the tables in the description for details on the possible values for clock sources.
*
* \param clock The clock to configure
@@ -272,10 +314,11 @@ typedef clock_num_t clock_handle_t;
* \param auxsrc The auxiliary clock source, which depends on which clock is being set. Can be 0
* \param src_freq Frequency of the input clock source
* \param freq Requested frequency
+ * \return true if the clock is updated, false if freq > src_freq
*/
bool clock_configure(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq);
-/*! \brief Configure the specified clock to use the undividded input source
+/*! \brief Configure the specified clock to use the undivided input source
* \ingroup hardware_clocks
*
* See the tables in the description for details on the possible values for clock sources.
@@ -287,7 +330,7 @@ bool clock_configure(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32
*/
void clock_configure_undivided(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq);
-/*! \brief Configure the specified clock to use the undividded input source
+/*! \brief Configure the specified clock to use the undivided input source
* \ingroup hardware_clocks
*
* See the tables in the description for details on the possible values for clock sources.
diff --git a/src/rp2_common/hardware_divider/include/hardware/divider.h b/src/rp2_common/hardware_divider/include/hardware/divider.h
index de8772dfd..70746da58 100644
--- a/src/rp2_common/hardware_divider/include/hardware/divider.h
+++ b/src/rp2_common/hardware_divider/include/hardware/divider.h
@@ -110,7 +110,7 @@ static inline void hw_divider_divmod_s32_start(int32_t a, int32_t b) {
sio_hw->div_sdividend = (uint32_t)a;
sio_hw->div_sdivisor = (uint32_t)b;
#else
- hw_divider_divmod_s32(a, b);
+ hw_divider_results[get_core_num()] = hw_divider_divmod_s32(a, b);
#endif
}
@@ -130,7 +130,7 @@ static inline void hw_divider_divmod_u32_start(uint32_t a, uint32_t b) {
sio_hw->div_udividend = a;
sio_hw->div_udivisor = b;
#else
- hw_divider_divmod_u32(a, b);
+ hw_divider_results[get_core_num()] = hw_divider_divmod_u32(a, b);
#endif
}
diff --git a/src/rp2_common/hardware_dma/include/hardware/dma.h b/src/rp2_common/hardware_dma/include/hardware/dma.h
index 8bb35ec1f..94b74cb7f 100644
--- a/src/rp2_common/hardware_dma/include/hardware/dma.h
+++ b/src/rp2_common/hardware_dma/include/hardware/dma.h
@@ -535,7 +535,7 @@ static inline void dma_channel_start(uint channel) {
*\endcode
*
* \if rp2350_specific
- * RP2350 only: Due to errata RP12350-E5 (see the RP2350 datasheet for further detail), it is necessary to clear the enable bit of
+ * RP2350 only: Due to errata RP2350-E5 (see the RP2350 datasheet for further detail), it is necessary to clear the enable bit of
* the aborted channel and any chained channels prior to the abort to prevent re-triggering.
* \endif
*
diff --git a/src/rp2_common/hardware_flash/flash.c b/src/rp2_common/hardware_flash/flash.c
index 902d0daf7..adae07878 100644
--- a/src/rp2_common/hardware_flash/flash.c
+++ b/src/rp2_common/hardware_flash/flash.c
@@ -288,9 +288,9 @@ void flash_get_unique_id(uint8_t *id_out) {
#if !PICO_RP2040
// This is a static symbol because the layout of FLASH_DEVINFO is liable to change from device to
// device, so fields must have getters/setters.
-static io_rw_16 * flash_devinfo_ptr(void) {
+static io_rw_16 * __no_inline_not_in_flash_func(flash_devinfo_ptr)(void) {
// Note the lookup returns a pointer to a 32-bit pointer literal in the ROM
- io_rw_16 **p = (io_rw_16 **) rom_data_lookup(ROM_DATA_FLASH_DEVINFO16_PTR);
+ io_rw_16 **p = (io_rw_16 **) rom_data_lookup_inline(ROM_DATA_FLASH_DEVINFO16_PTR);
assert(p);
return *p;
}
diff --git a/src/rp2_common/hardware_gpio/gpio.c b/src/rp2_common/hardware_gpio/gpio.c
index 9dac191d9..42dcc544a 100644
--- a/src/rp2_common/hardware_gpio/gpio.c
+++ b/src/rp2_common/hardware_gpio/gpio.c
@@ -184,16 +184,13 @@ static void _gpio_set_irq_enabled(uint gpio, uint32_t events, bool enabled, io_b
}
void gpio_set_irq_enabled(uint gpio, uint32_t events, bool enabled) {
- // either this call disables the interrupt
- // or callback should already be set (raw or using gpio_set_irq_callback)
+ // either this call disables the interrupt or callback should already be set.
// this protects against enabling the interrupt without callback set
/**
* Modification on the porting to Zephyr:
* The GPIO irq is managed by Zephyr, so there is no need to check it in the SDK.
*
- assert(!enabled
- || (raw_irq_mask[get_core_num()] & (1ull< 2
+static_assert(PIO2_BASE - PIO0_BASE == (2u << 20), "hardware layout mismatch");
+#endif
#define PIO_NUM(pio) (((uintptr_t)(pio) - PIO0_BASE) >> 20)
#endif
@@ -185,6 +188,9 @@ static_assert(PIO1_BASE - PIO0_BASE == (1u << 20), "hardware layout mismatch");
*/
#ifndef PIO_INSTANCE
static_assert(PIO1_BASE - PIO0_BASE == (1u << 20), "hardware layout mismatch");
+#if NUM_PIOS > 2
+static_assert(PIO2_BASE - PIO0_BASE == (2u << 20), "hardware layout mismatch");
+#endif
#define PIO_INSTANCE(instance) ((pio_hw_t *)(PIO0_BASE + (instance) * (1u << 20)))
#endif
@@ -214,8 +220,13 @@ static_assert(DREQ_PIO0_TX1 == DREQ_PIO0_TX0 + 1, "");
static_assert(DREQ_PIO0_TX2 == DREQ_PIO0_TX0 + 2, "");
static_assert(DREQ_PIO0_TX3 == DREQ_PIO0_TX0 + 3, "");
static_assert(DREQ_PIO0_RX0 == DREQ_PIO0_TX0 + NUM_PIO_STATE_MACHINES, "");
+static_assert(DREQ_PIO1_TX0 == DREQ_PIO0_RX0 + NUM_PIO_STATE_MACHINES, "");
static_assert(DREQ_PIO1_RX0 == DREQ_PIO1_TX0 + NUM_PIO_STATE_MACHINES, "");
-#define PIO_DREQ_NUM(pio, sm, is_tx) ((sm) + (((is_tx) ? 0 : NUM_PIO_STATE_MACHINES) + PIO_NUM(pio) * (DREQ_PIO1_TX0 - DREQ_PIO0_TX0)))
+#if NUM_PIOS > 2
+static_assert(DREQ_PIO2_TX0 == DREQ_PIO1_RX0 + NUM_PIO_STATE_MACHINES, "");
+static_assert(DREQ_PIO2_RX0 == DREQ_PIO2_TX0 + NUM_PIO_STATE_MACHINES, "");
+#endif
+#define PIO_DREQ_NUM(pio, sm, is_tx) (DREQ_PIO0_TX0 + (sm) + (((is_tx) ? 0 : NUM_PIO_STATE_MACHINES) + PIO_NUM(pio) * (DREQ_PIO1_TX0 - DREQ_PIO0_TX0)))
#endif
/**
@@ -919,7 +930,7 @@ int pio_set_gpio_base(PIO pio, uint gpio_base);
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
* \param program the program definition
* \return true if the program can be loaded;
- * false if not, e.g. if there is not suitable space in the instruction memory
+ * false if not, e.g. if there is not suitable space in the instruction memory
*/
bool pio_can_add_program(PIO pio, const pio_program_t *program);
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 c27a4c178..671145606 100644
--- a/src/rp2_common/hardware_pio/include/hardware/pio_instructions.h
+++ b/src/rp2_common/hardware_pio/include/hardware/pio_instructions.h
@@ -79,6 +79,10 @@ static inline uint _pio_major_instr_bits(uint instr) {
return instr & 0xe000u;
}
+static inline uint _pio_arg1(uint instr) {
+ return (instr >> 5) & 0x7u;
+}
+
static inline uint _pio_encode_instr_and_args(enum pio_instr_bits instr_bits, uint arg1, uint arg2) {
valid_params_if(PIO_INSTRUCTIONS, arg1 <= 0x7);
#if PARAM_ASSERTIONS_ENABLED(PIO_INSTRUCTIONS)
diff --git a/src/rp2_common/hardware_pio/pio.c b/src/rp2_common/hardware_pio/pio.c
index ed34cd815..7182cfff5 100644
--- a/src/rp2_common/hardware_pio/pio.c
+++ b/src/rp2_common/hardware_pio/pio.c
@@ -162,6 +162,15 @@ static int add_program_at_offset(PIO pio, const pio_program_t *program, uint off
if (rc != 0) return rc;
for (uint i = 0; i < program->length; ++i) {
uint16_t instr = program->instructions[i];
+#if PICO_PIO_USE_GPIO_BASE
+ if (pio_instr_bits_wait == _pio_major_instr_bits(instr) && !((_pio_arg1(instr) & 3u))) {
+ // wait GPIO will include only the 5 lower bits of the GPIO number, so if the GPIO
+ // base is 16 we need to flip bit 4 (which is equivalent to subtracting 16 from
+ // the original number 16-47 stored as 16-31 and 0-15)
+ static_assert(PIO_GPIOBASE_BITS == 16, ""); // only works for gpio base being 0 or 16
+ instr ^= (uint16_t)pio_get_gpio_base(pio);
+ }
+#endif
pio->instr_mem[offset + i] = pio_instr_bits_jmp != _pio_major_instr_bits(instr) ? instr : instr + offset;
}
uint32_t program_mask = (1u << program->length) - 1;
diff --git a/src/rp2_common/hardware_powman/include/hardware/powman.h b/src/rp2_common/hardware_powman/include/hardware/powman.h
index fce8c14cd..ea9e2758b 100644
--- a/src/rp2_common/hardware_powman/include/hardware/powman.h
+++ b/src/rp2_common/hardware_powman/include/hardware/powman.h
@@ -10,6 +10,10 @@
#include "pico.h"
#include "hardware/structs/powman.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** \file hardware/powman.h
* \defgroup hardware_powman hardware_powman
*
@@ -272,4 +276,8 @@ static inline void powman_set_debug_power_request_ignored(bool ignored) {
powman_clear_bits(&powman_hw->dbg_pwrcfg, 0);
}
+#ifdef __cplusplus
+}
+#endif
+
#endif
\ No newline at end of file
diff --git a/src/rp2_common/hardware_sync/include/hardware/sync.h b/src/rp2_common/hardware_sync/include/hardware/sync.h
index 474b27936..82b253786 100644
--- a/src/rp2_common/hardware_sync/include/hardware/sync.h
+++ b/src/rp2_common/hardware_sync/include/hardware/sync.h
@@ -198,10 +198,41 @@ __force_inline static void __mem_fence_release(void) {
//#endif
}
-/*! \brief Save and disable interrupts
+/*! \brief Explicitly disable interrupts on the calling core
* \ingroup hardware_sync
+ */
+__force_inline static uint32_t disable_interrupts(void) {
+#ifdef __riscv
+ __compiler_memory_barrier();
+ riscv_clear_csr(mstatus, 8);
+ __compiler_memory_barrier();
+#else
+ pico_default_asm_volatile ( "cpsid i" : : : "memory");
+#endif
+}
+
+/*! \brief Explicitly enable interrupts on the calling core
+ * \ingroup hardware_sync
+ */
+__force_inline static uint32_t enable_interrupts(void) {
+#ifdef __riscv
+ __compiler_memory_barrier();
+ riscv_set_csr(mstatus, 8);
+ __compiler_memory_barrier();
+#else
+ pico_default_asm_volatile ( "cpsie i" : : : "memory");
+#endif
+}
+
+/*! \brief Disable interrupts on the calling core, returning the previous interrupt state
+ * \ingroup hardware_sync
+ *
+ * This method is commonly paired with \ref restore_interrupts_from_disabled() to temporarily
+ * disable interrupts around a piece of code, without needing to care whether interrupts
+ * were previously enabled
*
- * \return The prior interrupt enable status for restoration later via restore_interrupts()
+ * \return The prior interrupt enable status for restoration later via \ref restore_interrupts_from_disabled()
+ * or \ref restore_interrupts()
*/
__force_inline static uint32_t save_and_disable_interrupts(void) {
uint32_t status;
@@ -219,7 +250,7 @@ __force_inline static uint32_t save_and_disable_interrupts(void) {
return status;
}
-/*! \brief Restore interrupts to a specified state
+/*! \brief Restore interrupts to a specified state on the calling core
* \ingroup hardware_sync
*
* \param status Previous interrupt status from save_and_disable_interrupts()
@@ -238,10 +269,10 @@ __force_inline static void restore_interrupts(uint32_t status) {
#endif
}
-/*! \brief Restore interrupts to a specified state with restricted transitions
+/*! \brief Restore interrupts to a specified state on the calling core with restricted transitions
* \ingroup hardware_sync
*
- * This method should only be used when the interrupt state is known to be disabled,
+ * This method should only be used when the current interrupt state is known to be disabled,
* e.g. when paired with \ref save_and_disable_interrupts()
*
* \param status Previous interrupt status from save_and_disable_interrupts()
diff --git a/src/rp2_common/hardware_vreg/BUILD.bazel b/src/rp2_common/hardware_vreg/BUILD.bazel
index a1d381eef..d8f092be5 100644
--- a/src/rp2_common/hardware_vreg/BUILD.bazel
+++ b/src/rp2_common/hardware_vreg/BUILD.bazel
@@ -10,7 +10,7 @@ cc_library(
target_compatible_with = compatible_with_rp2(),
deps = [
"//src/rp2_common:hardware_structs",
- "//src/rp2_common:pico_platform",
+ "//src/rp2_common:pico_platform_internal",
"//src/rp2_common/hardware_base",
],
)
diff --git a/src/rp2_common/hardware_vreg/include/hardware/vreg.h b/src/rp2_common/hardware_vreg/include/hardware/vreg.h
index ce6ad0ca6..011ba7991 100644
--- a/src/rp2_common/hardware_vreg/include/hardware/vreg.h
+++ b/src/rp2_common/hardware_vreg/include/hardware/vreg.h
@@ -82,6 +82,13 @@ enum vreg_voltage {
void vreg_set_voltage(enum vreg_voltage voltage);
+/*! \brief Get voltage
+ * \ingroup hardware_vreg
+ *
+ * \return The current voltage (from enumeration \ref vreg_voltage) of the voltage regulator
+ **/
+enum vreg_voltage vreg_get_voltage(void);
+
/*! \brief Enable use of voltages beyond the safe range of operation
* \ingroup hardware_vreg
*
diff --git a/src/rp2_common/hardware_vreg/vreg.c b/src/rp2_common/hardware_vreg/vreg.c
index 61fd08042..b5a406c06 100644
--- a/src/rp2_common/hardware_vreg/vreg.c
+++ b/src/rp2_common/hardware_vreg/vreg.c
@@ -16,7 +16,7 @@ void vreg_set_voltage(enum vreg_voltage voltage) {
VREG_AND_CHIP_RESET_VREG_VSEL_BITS
);
-#elif PICO_RP2350
+#else
hw_set_bits(&powman_hw->vreg_ctrl, POWMAN_PASSWORD_BITS | POWMAN_VREG_CTRL_UNLOCK_BITS);
@@ -32,19 +32,21 @@ void vreg_set_voltage(enum vreg_voltage voltage) {
while (powman_hw->vreg & POWMAN_VREG_UPDATE_IN_PROGRESS_BITS)
tight_loop_contents();
+#endif
+}
+
+enum vreg_voltage vreg_get_voltage(void) {
+#if PICO_RP2040
+ return (vreg_and_chip_reset_hw->vreg & VREG_AND_CHIP_RESET_VREG_VSEL_BITS) >> VREG_AND_CHIP_RESET_VREG_VSEL_LSB;
#else
- panic_unsupported();
+ return (powman_hw->vreg & POWMAN_VREG_VSEL_BITS) >> POWMAN_VREG_VSEL_LSB;
#endif
}
void vreg_disable_voltage_limit(void) {
#if PICO_RP2040
- // The voltage limit can't be disabled on RP2040 (was implemented by
- // hardwiring the LDO controls)
- return;
-#elif PICO_RP2350
- hw_set_bits(&powman_hw->vreg_ctrl, POWMAN_PASSWORD_BITS | POWMAN_VREG_CTRL_DISABLE_VOLTAGE_LIMIT_BITS);
+ // The voltage limit can't be disabled on RP2040 (was implemented by hard-wiring the LDO controls)
#else
- panic_unsupported();
+ hw_set_bits(&powman_hw->vreg_ctrl, POWMAN_PASSWORD_BITS | POWMAN_VREG_CTRL_DISABLE_VOLTAGE_LIMIT_BITS);
#endif
}
diff --git a/src/rp2_common/hardware_xip_cache/include/hardware/xip_cache.h b/src/rp2_common/hardware_xip_cache/include/hardware/xip_cache.h
index 286db8bdc..ff915eb0c 100644
--- a/src/rp2_common/hardware_xip_cache/include/hardware/xip_cache.h
+++ b/src/rp2_common/hardware_xip_cache/include/hardware/xip_cache.h
@@ -20,14 +20,14 @@
* of flash), so pointers should have XIP_BASE subtracted before passing into one of these
* functions.
*
- * \if rp2040-specific
+ * \if rp2040_specific
* The only valid cache maintenance operation on RP2040 is "invalidate", which tells the cache to
* forget everything it knows about some address. This is necessary after a programming operation,
* because the cache does not automatically know about any serial programming operations performed
* on the external flash device, and could return stale data.
* \endif
*
- * \if rp2350-specific
+ * \if rp2350_specific
* On RP2350, the three types of operation are:
*
* * Invalidate: tell the cache to forget everything it knows about some address. The next access to
@@ -124,7 +124,7 @@ void xip_cache_invalidate_all(void);
*/
void xip_cache_invalidate_range(uintptr_t start_offset, uintptr_t size_bytes);
-#if !XIP_CACHE_IS_READ_ONLY
+#if !XIP_CACHE_IS_READ_ONLY || PICO_COMBINED_DOCS
/*! \brief Clean the cache for the entire XIP address space
* \ingroup hardware_xip_cache
@@ -136,12 +136,12 @@ void xip_cache_invalidate_range(uintptr_t start_offset, uintptr_t size_bytes);
* This function is faster than calling xip_cache_clean_range() for the entire address space,
* because it iterates over cachelines instead of addresses.
*
- * \if rp2040-specific
+ * \if rp2040_specific
* On RP2040 this is a no-op, as the XIP cache is read-only. This is indicated by the
* XIP_CACHE_IS_READ_ONLY macro.
* \endif
*
- * \if rp2350-specific
+ * \if rp2350_specific
* On RP2350, due to the workaround applied for RP2350-E11, this function also effectively
* invalidates all cache lines after cleaning them. The next access to each line will miss. Avoid
* this by calling xip_cache_clean_range() which does not suffer this issue.
@@ -155,7 +155,7 @@ void xip_cache_clean_all(void);
*
* This causes the cache to write out pending write data at these offsets to the downstream memory.
*
- * \if rp2040-specific
+ * \if rp2040_specific
* On RP2040 this is a no-op, as the XIP cache is read-only. This is indicated by the
* XIP_CACHE_IS_READ_ONLY macro.
* \endif
@@ -177,7 +177,7 @@ static inline void xip_cache_clean_range(uintptr_t start_offset, uintptr_t size_
}
#endif
-#if !PICO_RP2040
+#if !PICO_RP2040 || PICO_COMBINED_DOCS
/*! \brief Pin a range of offsets within the XIP address space
* \ingroup hardware_xip_cache
diff --git a/src/rp2_common/hardware_xosc/include/hardware/xosc.h b/src/rp2_common/hardware_xosc/include/hardware/xosc.h
index 1153b9362..fe4922785 100644
--- a/src/rp2_common/hardware_xosc/include/hardware/xosc.h
+++ b/src/rp2_common/hardware_xosc/include/hardware/xosc.h
@@ -13,9 +13,9 @@
// Allow lengthening startup delay to accommodate slow-starting oscillators
-// PICO_CONFIG: PICO_XOSC_STARTUP_DELAY_MULTIPLIER, Multiplier to lengthen xosc startup delay to accommodate slow-starting oscillators, type=int, min=1, default=1, group=hardware_xosc
+// PICO_CONFIG: PICO_XOSC_STARTUP_DELAY_MULTIPLIER, Multiplier (from 1ms) for xosc startup delay to accommodate slow-starting oscillators, type=int, min=1, default=6, group=hardware_xosc
#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER
-#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 1
+#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 6
#endif
diff --git a/src/rp2_common/pico_aon_timer/BUILD.bazel b/src/rp2_common/pico_aon_timer/BUILD.bazel
index 6ceaf2e52..45ef4f3cc 100644
--- a/src/rp2_common/pico_aon_timer/BUILD.bazel
+++ b/src/rp2_common/pico_aon_timer/BUILD.bazel
@@ -6,10 +6,14 @@ cc_library(
name = "pico_aon_timer",
srcs = ["aon_timer.c"],
hdrs = ["include/pico/aon_timer.h"],
+ defines = [
+ "LIB_PICO_AON_TIMER=1",
+ ],
includes = ["include"],
target_compatible_with = compatible_with_rp2(),
deps = [
"//src/common/pico_util",
+ "//src/common/pico_time",
"//src/rp2_common:hardware_regs",
"//src/rp2_common:pico_platform",
"//src/rp2_common/hardware_irq",
diff --git a/src/rp2_common/pico_aon_timer/CMakeLists.txt b/src/rp2_common/pico_aon_timer/CMakeLists.txt
index 0d2a2d657..c1abe98f3 100644
--- a/src/rp2_common/pico_aon_timer/CMakeLists.txt
+++ b/src/rp2_common/pico_aon_timer/CMakeLists.txt
@@ -12,6 +12,7 @@ pico_mirrored_target_link_libraries(pico_aon_timer INTERFACE pico_util)
if (TARGET hardware_rtc)
pico_mirrored_target_link_libraries(pico_aon_timer INTERFACE hardware_rtc)
+ target_link_libraries(pico_aon_timer_headers INTERFACE pico_time_headers)
endif()
if (TARGET hardware_powman)
diff --git a/src/rp2_common/pico_aon_timer/aon_timer.c b/src/rp2_common/pico_aon_timer/aon_timer.c
index a4d594f63..62ef6c27a 100644
--- a/src/rp2_common/pico_aon_timer/aon_timer.c
+++ b/src/rp2_common/pico_aon_timer/aon_timer.c
@@ -13,6 +13,8 @@ static aon_timer_alarm_handler_t aon_timer_alarm_handler;
#if HAS_RP2040_RTC
#include "hardware/rtc.h"
#include "pico/util/datetime.h"
+#include "pico/time.h"
+#include "hardware/clocks.h"
#elif HAS_POWMAN_TIMER
#include "hardware/powman.h"
@@ -56,6 +58,10 @@ bool aon_timer_set_time_calendar(const struct tm *tm) {
datetime_t dt;
tm_to_datetime(tm, &dt);
rtc_set_datetime(&dt);
+
+ // Writing to the RTC will take 2 clk_rtc clock periods to arrive
+ uint rtc_freq = clock_get_hz(clk_rtc);
+ busy_wait_us(((1000000 + rtc_freq - 1) / rtc_freq) * 2);
return true;
#elif HAS_POWMAN_TIMER
struct timespec ts;
diff --git a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h
index 768c79827..b3095d8e0 100644
--- a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h
+++ b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h
@@ -239,7 +239,7 @@ aon_timer_alarm_handler_t aon_timer_enable_alarm_calendar(const struct tm *tm, a
void aon_timer_disable_alarm(void);
/**
- * \brief Disable the currently enabled AON timer alarm if any
+ * \brief Check if the AON timer is running
* \ingroup pico_aon_timer
* \return true if the AON timer is running
*/
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 3cffcbb98..9ae72b3af 100644
--- a/src/rp2_common/pico_async_context/async_context_freertos.c
+++ b/src/rp2_common/pico_async_context/async_context_freertos.c
@@ -193,7 +193,7 @@ static void handle_sync_func_call(async_context_t *context, async_when_pending_w
uint32_t async_context_freertos_execute_sync(async_context_t *self_base, uint32_t (*func)(void *param), void *param) {
async_context_freertos_t *self = (async_context_freertos_t*)self_base;
hard_assert(xSemaphoreGetMutexHolder(self->lock_mutex) != xTaskGetCurrentTaskHandle());
- sync_func_call_t call;
+ sync_func_call_t call = {0};
call.worker.do_work = handle_sync_func_call;
call.func = func;
call.param = param;
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 33f3d45c8..730d8a5a7 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
@@ -140,7 +140,7 @@ uint32_t async_context_threadsafe_background_execute_sync(async_context_t *self_
#if ASYNC_CONTEXT_THREADSAFE_BACKGROUND_MULTI_CORE
if (self_base->core_num != get_core_num()) {
hard_assert(!recursive_mutex_enter_count(&self->lock_mutex));
- sync_func_call_t call;
+ sync_func_call_t call = {0};
call.worker.do_work = handle_sync_func_call;
call.func = func;
call.param = param;
diff --git a/src/rp2_common/pico_bootrom/bootrom.c b/src/rp2_common/pico_bootrom/bootrom.c
index 344e3724c..1120f006a 100644
--- a/src/rp2_common/pico_bootrom/bootrom.c
+++ b/src/rp2_common/pico_bootrom/bootrom.c
@@ -14,25 +14,9 @@ void *rom_func_lookup(uint32_t code) {
return rom_func_lookup_inline(code);
}
-#pragma GCC diagnostic push
-// diagnostic: GCC thinks near-zero value is a null pointer member access, but it's not
-#pragma GCC diagnostic ignored "-Warray-bounds"
void *rom_data_lookup(uint32_t code) {
-#if PICO_RP2040
- rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET);
- uint16_t *data_table = (uint16_t *) rom_hword_as_ptr(BOOTROM_DATA_TABLE_OFFSET);
- return rom_table_lookup(data_table, code);
-#else
-#ifdef __riscv
- uint32_t rom_offset_adjust = rom_size_is_64k() ? 32 * 1024 : 0;
- rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET + rom_offset_adjust);
-#else
- rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET);
-#endif
- return rom_table_lookup(code, RT_FLAG_DATA);
-#endif
+ return rom_data_lookup_inline(code);
}
-#pragma GCC diagnostic pop
/// \end::table_lookup[]
bool rom_funcs_lookup(uint32_t *table, unsigned int count) {
diff --git a/src/rp2_common/pico_bootrom/include/pico/bootrom.h b/src/rp2_common/pico_bootrom/include/pico/bootrom.h
index 498d4f724..bb5b8ba2f 100644
--- a/src/rp2_common/pico_bootrom/include/pico/bootrom.h
+++ b/src/rp2_common/pico_bootrom/include/pico/bootrom.h
@@ -215,6 +215,32 @@ static __force_inline void *rom_func_lookup_inline(uint32_t code) {
}
#pragma GCC diagnostic pop
+/*!
+ * \brief Lookup a bootrom data address by its code. This method is forcibly inlined into the caller for FLASH/RAM sensitive code usage
+ * \ingroup pico_bootrom
+ * \param code the code
+ * \return a pointer to the data, or NULL if the code does not match any bootrom data
+ */
+#pragma GCC diagnostic push
+// diagnostic: GCC thinks near-zero value is a null pointer member access, but it's not
+#pragma GCC diagnostic ignored "-Warray-bounds"
+static __force_inline void *rom_data_lookup_inline(uint32_t code) {
+#if PICO_RP2040
+ rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET);
+ uint16_t *data_table = (uint16_t *) rom_hword_as_ptr(BOOTROM_DATA_TABLE_OFFSET);
+ return rom_table_lookup(data_table, code);
+#else
+#ifdef __riscv
+ uint32_t rom_offset_adjust = rom_size_is_64k() ? 32 * 1024 : 0;
+ rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET + rom_offset_adjust);
+#else
+ rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET);
+#endif
+ return rom_table_lookup(code, RT_FLAG_DATA);
+#endif
+}
+#pragma GCC diagnostic pop
+
/*!
* \brief Reboot the device into BOOTSEL mode
* \ingroup pico_bootrom
@@ -403,7 +429,7 @@ static inline void rom_flash_enter_cmd_xip(void) {
func();
}
-#if !PICO_RP2040
+#if !PICO_RP2040 || PICO_COMBINED_DOCS
#ifdef __riscv
/*!
* \brief Give the bootrom a new stack
diff --git a/src/rp2_common/pico_btstack/CMakeLists.txt b/src/rp2_common/pico_btstack/CMakeLists.txt
index c622cacf5..010cc9e39 100644
--- a/src/rp2_common/pico_btstack/CMakeLists.txt
+++ b/src/rp2_common/pico_btstack/CMakeLists.txt
@@ -107,6 +107,13 @@ if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH})
ENABLE_BLE=1
)
+ # Added in v1.6.2
+ if (EXISTS ${PICO_BTSTACK_PATH}/src/hci_event_builder.c)
+ target_sources(pico_btstack_ble INTERFACE
+ ${PICO_BTSTACK_PATH}/src/hci_event_builder.c
+ )
+ endif()
+
pico_add_library(pico_btstack_classic)
target_sources(pico_btstack_classic INTERFACE
${PICO_BTSTACK_PATH}/src/classic/a2dp.c
@@ -161,6 +168,13 @@ if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH})
ENABLE_CLASSIC=1
)
+ # Added in v1.6.2
+ if (EXISTS ${PICO_BTSTACK_PATH}/src/classic/obex_srm_client.c)
+ target_sources(pico_btstack_classic INTERFACE
+ ${PICO_BTSTACK_PATH}/src/classic/obex_srm_client.c
+ )
+ endif()
+
pico_add_library(pico_btstack_mesh)
target_sources(pico_btstack_mesh INTERFACE
${PICO_BTSTACK_PATH}/src/mesh/adv_bearer.c
diff --git a/src/rp2_common/pico_btstack/LICENSE.RP b/src/rp2_common/pico_btstack/LICENSE.RP
index 79e0080db..124c61ca8 100644
--- a/src/rp2_common/pico_btstack/LICENSE.RP
+++ b/src/rp2_common/pico_btstack/LICENSE.RP
@@ -1,6 +1,6 @@
“BlueKitchen” shall refer to BlueKitchen GmbH.
“Raspberry Pi” shall refer to Raspberry Pi Ltd.
-“Product” shall refer to Raspberry Pi hardware products Raspberry Pi Pico W or Raspberry Pi Pico WH.
+“Product” shall refer to Raspberry Pi hardware products Pico W, Pico WH, Pico 2 W, Pico 2 WH, and RM2.
“Customer” means any purchaser of a Product.
“Customer Products” means products manufactured or distributed by Customers which use or are derived from Products.
diff --git a/src/rp2_common/pico_clib_interface/include/llvm_libc/sys/time.h b/src/rp2_common/pico_clib_interface/include/llvm_libc/sys/time.h
index 3d37f1c25..c22552ac1 100644
--- a/src/rp2_common/pico_clib_interface/include/llvm_libc/sys/time.h
+++ b/src/rp2_common/pico_clib_interface/include/llvm_libc/sys/time.h
@@ -9,15 +9,7 @@
#include <__llvm-libc-common.h>
-#include
-#include
-
-typedef long suseconds_t;
-
-struct timeval {
- time_t tv_sec;
- suseconds_t tv_usec;
-};
+#include
struct timezone {
int tz_minuteswest;
diff --git a/src/rp2_common/pico_clib_interface/llvm_libc_interface.c b/src/rp2_common/pico_clib_interface/llvm_libc_interface.c
index da4281335..dfcab015e 100644
--- a/src/rp2_common/pico_clib_interface/llvm_libc_interface.c
+++ b/src/rp2_common/pico_clib_interface/llvm_libc_interface.c
@@ -5,8 +5,10 @@
*/
#include
+#include
#include
#include
+#include
#include
@@ -65,6 +67,13 @@ ssize_t __llvm_libc_stdio_write(__unused void *cookie, const char *buf, size_t s
return size;
}
+bool __llvm_libc_timespec_get_utc(struct timespec *ts) {
+ int64_t absolute_time = (int64_t)get_absolute_time();
+ ts->tv_sec = (time_t)(absolute_time / 1000000);
+ ts->tv_nsec = (long)(absolute_time % 1000000 * 1000);
+ return true;
+}
+
void __cxa_finalize(__unused void *dso) {}
void __attribute__((noreturn)) __llvm_libc_exit(__unused int status) {
diff --git a/src/rp2_common/pico_clib_interface/picolibc_interface.c b/src/rp2_common/pico_clib_interface/picolibc_interface.c
index 8f7770ab8..63d79135e 100644
--- a/src/rp2_common/pico_clib_interface/picolibc_interface.c
+++ b/src/rp2_common/pico_clib_interface/picolibc_interface.c
@@ -7,6 +7,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -39,8 +41,9 @@ static int picolibc_putc(char c, __unused FILE *file) {
static int picolibc_getc(__unused FILE *file) {
#if LIB_PICO_STDIO
return stdio_getchar();
-#endif
+#else
return -1;
+#endif
}
static int picolibc_flush(__unused FILE *file) {
diff --git a/src/rp2_common/pico_cyw43_driver/btstack_hci_transport_cyw43.c b/src/rp2_common/pico_cyw43_driver/btstack_hci_transport_cyw43.c
index ecfcf3dbe..b77ea0662 100644
--- a/src/rp2_common/pico_cyw43_driver/btstack_hci_transport_cyw43.c
+++ b/src/rp2_common/pico_cyw43_driver/btstack_hci_transport_cyw43.c
@@ -6,21 +6,35 @@
#include "pico.h"
#include "cyw43.h"
-#include "hci_transport.h"
+#include "btstack_config.h"
#include "hci.h"
+#include "hci_transport.h"
#include "pico/btstack_hci_transport_cyw43.h"
#include "pico/btstack_chipset_cyw43.h"
+// cyw43_bluetooth_hci_write and cyw43_bluetooth_hci_read require a custom 4-byte packet header in front of the actual HCI packet
+// the HCI packet type is stored in the fourth byte of the packet header
+#define CYW43_PACKET_HEADER_SIZE 4
+
// assert outgoing pre-buffer for cyw43 header is available
-#if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE < 4)
-#error HCI_OUTGOING_PRE_BUFFER_SIZE not defined or smaller than 4. Please update btstack_config.h
+#if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE < CYW43_PACKET_HEADER_SIZE)
+#error HCI_OUTGOING_PRE_BUFFER_SIZE not defined or smaller than 4 (CYW43_PACKET_HEADER_SIZE) bytes. Please update btstack_config.h
#endif
// assert outgoing packet fragments are word aligned
#if !defined(HCI_ACL_CHUNK_SIZE_ALIGNMENT) || ((HCI_ACL_CHUNK_SIZE_ALIGNMENT & 3) != 0)
-#error HCI_ACL_CHUNK_SIZE_ALIGNMENT not defined or not a multiply of 4. Please update btstack_config.h
+#error HCI_ACL_CHUNK_SIZE_ALIGNMENT not defined or not a multiple of 4. Please update btstack_config.h
#endif
+// ensure incoming pre-buffer for cyw43 header is available (defaults from btstack/src/hci.h)
+#if HCI_INCOMING_PRE_BUFFER_SIZE < CYW43_PACKET_HEADER_SIZE
+#undef HCI_INCOMING_PRE_BUFFER_SIZE
+#define HCI_INCOMING_PRE_BUFFER_SIZE CYW43_PACKET_HEADER_SIZE
+#endif
+
+// ensure buffer for cyw43_bluetooth_hci_read starts word aligned (word align pre buffer)
+#define HCI_INCOMING_PRE_BUFFER_SIZE_ALIGNED ((HCI_INCOMING_PRE_BUFFER_SIZE + 3) & ~3)
+
#define BT_DEBUG_ENABLED 0
#if BT_DEBUG_ENABLED
#define BT_DEBUG(...) CYW43_PRINTF(__VA_ARGS__)
@@ -31,9 +45,12 @@
// Callback when we have data
static void (*hci_transport_cyw43_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = NULL;
-// Incoming packet buffer - cyw43 packet header (incl packet type) + incoming pre buffer + max(acl header + acl payload, event header + event data)
+// The incoming packet buffer consist of a pre-buffer and the actual HCI packet
+// For the call to cyw43_bluetooth_hci_read, the last 4 bytes (CY43_PACKET_HEADER_SIZE) of the pre-buffer is used for the CYW43 packet header
+// After that, only the actual HCI packet is forwarded to BTstack, which expects HCI_INCOMING_PACKET_BUFFER_SIZE of pre-buffer bytes for its own use.
__attribute__((aligned(4)))
-static uint8_t hci_packet_with_pre_buffer[4 + HCI_INCOMING_PRE_BUFFER_SIZE + HCI_INCOMING_PACKET_BUFFER_SIZE ];
+static uint8_t hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE_ALIGNED + HCI_INCOMING_PACKET_BUFFER_SIZE ];
+static uint8_t * cyw43_receive_buffer = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE_ALIGNED - CYW43_PACKET_HEADER_SIZE];
static btstack_data_source_t transport_data_source;
static bool hci_transport_ready;
@@ -97,8 +114,8 @@ static int hci_transport_cyw43_can_send_now(uint8_t packet_type) {
static int hci_transport_cyw43_send_packet(uint8_t packet_type, uint8_t *packet, int size) {
// store packet type before actual data and increase size
// This relies on HCI_OUTGOING_PRE_BUFFER_SIZE being set
- uint8_t *buffer = &packet[-4];
- uint32_t buffer_size = size + 4;
+ uint8_t *buffer = &packet[-CYW43_PACKET_HEADER_SIZE];
+ uint32_t buffer_size = size + CYW43_PACKET_HEADER_SIZE;
buffer[3] = packet_type;
CYW43_THREAD_ENTER
@@ -143,10 +160,10 @@ static void hci_transport_cyw43_process(void) {
uint32_t loop_count = 0;
#endif
do {
- int err = cyw43_bluetooth_hci_read(hci_packet_with_pre_buffer, sizeof(hci_packet_with_pre_buffer), &len);
+ int err = cyw43_bluetooth_hci_read(cyw43_receive_buffer, CYW43_PACKET_HEADER_SIZE + HCI_INCOMING_PACKET_BUFFER_SIZE , &len);
BT_DEBUG("bt in len=%lu err=%d\n", len, err);
if (err == 0 && len > 0) {
- hci_transport_cyw43_packet_handler(hci_packet_with_pre_buffer[3], hci_packet_with_pre_buffer + 4, len - 4);
+ hci_transport_cyw43_packet_handler(cyw43_receive_buffer[3], &cyw43_receive_buffer[CYW43_PACKET_HEADER_SIZE], len - CYW43_PACKET_HEADER_SIZE);
has_work = true;
} else {
has_work = false;
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 bcc7284f1..787eeff5d 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
@@ -308,11 +308,13 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
dma_channel_configure(bus_data->dma_out, &out_config, &bus_data->pio->txf[bus_data->pio_sm], tx, tx_length / 4, true);
+ pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, true);
+ dma_channel_wait_for_finish_blocking(bus_data->dma_out);
+
uint32_t fdebug_tx_stall = 1u << (PIO_FDEBUG_TXSTALL_LSB + bus_data->pio_sm);
bus_data->pio->fdebug = fdebug_tx_stall;
- pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, true);
while (!(bus_data->pio->fdebug & fdebug_tx_stall)) {
- tight_loop_contents(); // todo timeout
+ tight_loop_contents();
}
__compiler_memory_barrier();
pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, false);
diff --git a/src/rp2_common/pico_cyw43_driver/cyw43_driver.c b/src/rp2_common/pico_cyw43_driver/cyw43_driver.c
index 11d2652e0..308d649d9 100644
--- a/src/rp2_common/pico_cyw43_driver/cyw43_driver.c
+++ b/src/rp2_common/pico_cyw43_driver/cyw43_driver.c
@@ -63,8 +63,8 @@ uint32_t cyw43_irq_deinit(__unused void *param) {
#ifndef NDEBUG
assert(get_core_num() == async_context_core_num(cyw43_async_context));
#endif
- gpio_remove_raw_irq_handler(CYW43_PIN_WL_HOST_WAKE, cyw43_gpio_irq_handler);
cyw43_set_irq_enabled(false);
+ gpio_remove_raw_irq_handler(CYW43_PIN_WL_HOST_WAKE, cyw43_gpio_irq_handler);
return 0;
}
diff --git a/src/rp2_common/pico_double/double_aeabi_dcp.S b/src/rp2_common/pico_double/double_aeabi_dcp.S
index 9579c70e4..8e055648d 100644
--- a/src/rp2_common/pico_double/double_aeabi_dcp.S
+++ b/src/rp2_common/pico_double/double_aeabi_dcp.S
@@ -7,7 +7,7 @@
#include "pico/asm_helper.S"
#if !HAS_DOUBLE_COPROCESSOR
-#error attempt to compile double_aeabi_rp2350 when there is no DCP
+#error attempt to compile double_aeabi_dcp when there is no DCP
#else
#include "hardware/dcp_instr.inc.S"
@@ -29,7 +29,7 @@ double_section WRAPPER_FUNC_NAME(\func)
// ============== STATE SAVE AND RESTORE ===============
-.macro saving_func type func
+.macro saving_func type func, opt_label1='-', opt_label2='-'
// Note we are usually 32-bit aligned already at this point, as most of the
// function bodies contain exactly two 16-bit instructions: bmi and bx lr.
// We want the PCMP word-aligned.
@@ -41,6 +41,12 @@ double_section WRAPPER_FUNC_NAME(\func)
push {lr} // 16-bit instruction
bl generic_save_state // 32-bit instruction
b 1f // 16-bit instruction
+.ifnc \opt_label1,'-'
+regular_func \opt_label1
+.endif
+.ifnc \opt_label2,'-'
+regular_func \opt_label2
+.endif
// This is the actual entry point:
\type\()_func \func
PCMP apsr_nzcv
@@ -128,53 +134,124 @@ saving_func wrapper sqrt
dcp_dsqrt_m r0,r1,r0,r1,r0,r1,r2,r3,r12
saving_func_return
-// todo not a real thing
-double_wrapper_section __aeabi_dclassify
-saving_func wrapper __aeabi_dclassify
-@ with correct rounding
+double_section dclassify
+saving_func regular dclassify
dcp_dclassify_m apsr_nzcv,r0,r1
saving_func_return
// ============== CONVERSION FUNCTIONS ===============
double_wrapper_section __aeabi_d2f
-saving_func wrapper __aeabi_d2f
+saving_func wrapper __aeabi_d2f double2float
@ with rounding
dcp_double2float_m r0,r0,r1
saving_func_return
double_wrapper_section __aeabi_i2d
-saving_func wrapper __aeabi_i2d
+saving_func wrapper __aeabi_i2d int2double
dcp_int2double_m r0,r1,r0
saving_func_return
double_wrapper_section __aeabi_ui2d
-saving_func wrapper __aeabi_ui2d
+saving_func wrapper __aeabi_ui2d uint2double
dcp_uint2double_m r0,r1,r0
saving_func_return
+double_section double2fix_z
+saving_func regular double2fix_z
+ ubfx r3, r1, #20, #11
+ adds r3, r2
+ beq 1f // very small; we don't care that we might make a denormal
+ asrs ip, r3, #11
+ beq 1f
+ ite pl
+ movpl r3, #0x7ff
+ movsmi r3, #0
+1:
+ bfi r1, r3, #20, #11
+ b double2int_z_entry
+
+double_section double2ufix
+saving_func regular double2ufix_z double2ufix
+double2ufix_z_entry:
+ ubfx r3, r1, #20, #11
+ adds r3, r2
+ beq 1f // very small; we don't care that we might make a denormal
+ asrs ip, r3, #11
+ beq 1f
+ ite pl
+ lsrspl r3, r1, #20 // 0x7ff
+ movsmi r3, #0
+1:
+ bfi r1, r3, #20, #11
+ b double2uint_z_entry
+
+double_section double2fix
+saving_func regular double2fix
+ ubfx r3, r1, #20, #11
+ cbz r3, 2f // 0 or denormal
+ adds r3, r2
+ beq 1f // very small; we don't care that we might make a denormal
+ asrs ip, r3, #11
+ beq 1f
+ ite pl
+ movpl r3, #0x7ff
+ movsmi r3, #0
+1:
+ bfi r1, r3, #20, #11
+ b double2int_entry
+2:
+ movs r0, #0
+saving_func_return
+
+
+double_section double2int
+saving_func regular double2int
+double2int_entry:
+ lsls r2, r1, #1
+ bcc double2int_z_entry // positive is ok for int64_z
+ lsrs r3, r2, #21
+ beq double2int_z_entry // 0 or -0 or denormal is ok for int_z
+
+ lsrs r2, #21
+ adds r2, #1
+ subs r2, r2, #0x400
+ bcc 1f // <1 means subtract 1
+ cmp r2, #31
+ bge double2int_z_entry // must be an integer or maxed out
+ lsls r3, r1, #12
+ adds r3, r3, r0, lsr #20 // r3 now has highest 32 mantissa bits
+ lsls r3, r2
+ orrs r3, r3, r0, lsl #12 // these bits are all guaranteed to be in the fraction
+ beq double2int_z_entry // integer
+1:
+ dcp_double2int_m r0,r0,r1
+ subs r0, #1
+saving_func_return
+
double_wrapper_section __aeabi_d2iz
-saving_func wrapper __aeabi_d2iz
+saving_func wrapper __aeabi_d2iz double2int_z
+double2int_z_entry:
@ with truncation towards 0
dcp_double2int_m r0,r0,r1
+ // note: this works with either saved or not saved call as it is just a `bx lr`
saving_func_return
double_wrapper_section __aeabi_d2uiz
-saving_func wrapper __aeabi_d2uiz
+saving_func wrapper __aeabi_d2uiz double2uint double2uint_z
+double2uint_z_entry:
@ with truncation towards 0
dcp_double2uint_m r0,r0,r1
saving_func_return
-// todo not a real thing
-double_wrapper_section __aeabi_d2i_r
-saving_func wrapper __aeabi_d2i_r
+double_section double2int_r
+saving_func regular double2int_r
@ with rounding
dcp_double2int_r_m r0,r0,r1
saving_func_return
-// todo not a real thing
-double_wrapper_section __aeabi_d2ui_r
-saving_func wrapper __aeabi_d2ui_r
+double_section double2uint_r
+saving_func regular double2uint_r
@ with rounding
dcp_double2uint_r_m r0,r0,r1
saving_func_return
@@ -189,7 +266,6 @@ saving_func wrapper __aeabi_dcmpun
saving_func_return
double_wrapper_section __aeabi_dcmp
-
saving_func wrapper __aeabi_cdrcmple
dcp_dcmp_m apsr_nzcv,r2,r3,r0,r1 // with arguments reversed
bvs cmp_nan
diff --git a/src/rp2_common/pico_double/double_aeabi_rp2040.S b/src/rp2_common/pico_double/double_aeabi_rp2040.S
index 284846fd9..448b28355 100644
--- a/src/rp2_common/pico_double/double_aeabi_rp2040.S
+++ b/src/rp2_common/pico_double/double_aeabi_rp2040.S
@@ -425,6 +425,7 @@ double_wrapper_section __aeabi_ui2d
double_wrapper_section __aeabi_i2d
wrapper_func __aeabi_ui2d
+regular_func uint2double
movs r1, #0
cmp r0, #0
bne 2f
@@ -432,6 +433,7 @@ wrapper_func __aeabi_ui2d
bx lr
// double FUNC_NAME(__aeabi_i2d)(int) integer to double (double precision) conversion
wrapper_func __aeabi_i2d
+regular_func int2double
asrs r1, r0, #31
eors r0, r1
subs r0, r1
@@ -506,6 +508,7 @@ regular_func double2int
// unsigned FUNC_NAME(__aeabi_d2uiz)(double) double (double precision) to unsigned C-style conversion [3]
double_wrapper_section __aeabi_d2uiz
wrapper_func __aeabi_d2uiz
+regular_func double2uint_z
regular_func double2uint
shimmable_table_tail_call SF_TABLE_FLOAT2UINT double2uint_shim
@@ -528,11 +531,13 @@ regular_func ufix642double
// double FUNC_NAME(__aeabi_l2d)(long long) long long to double (double precision) conversion
double_wrapper_section __aeabi_l2d
wrapper_func __aeabi_l2d
+regular_func int642double
shimmable_table_tail_call SF_TABLE_INT642FLOAT int642double_shim
// double FUNC_NAME(__aeabi_l2f)(long long) long long to double (double precision) conversion
double_wrapper_section __aeabi_ul2d
wrapper_func __aeabi_ul2d
+regular_func uint642double
shimmable_table_tail_call SF_TABLE_UINT642FLOAT uint642double_shim
// long long FUNC_NAME(__aeabi_d2lz)(double) double (double precision) to long long C-style conversion [3]
@@ -566,22 +571,106 @@ regular_func double2int64
// unsigned long long FUNC_NAME(__aeabi_d2ulz)(double) double to unsigned long long C-style conversion [3]
double_wrapper_section __aeabi_d2ulz
wrapper_func __aeabi_d2ulz
+regular_func double2uint64
+regular_func double2uint64_z
shimmable_table_tail_call SF_TABLE_FLOAT2UINT64 double2uint64_shim
+double_section double2fix64_z
+regular_func double2fix64_z
+ lsls r3, r1, #1
+ bcc double2fix64 // input positive is ok for fix64
+ mov ip, r2
+ asrs r2, r3, #21
+ beq 3f // input zero or denormal, so just return zero
+ adds r2, #1
+ beq double2fix64 // input infinite/nan is ok for fix64
+
+ lsrs r3, #21
+ add r3, ip
+ movs r2, #1
+ negs r2, r2
+ lsrs r2, #22
+ subs r3, r2 // r3 = modified e - 0x3ff
+
+ bcc 3f // modified input < 1.0 means result is zero
+ cmp r3, #52
+ bge 2f // modified input must be an integer or infinite
+
+ adds r3, #12
+ mov r2, r1
+ lsls r2, r2, r3 // r2 has remaining fractional mantissa bits of r1
+ bne 1f // not integer as non zero fractional bits remain
+ subs r3, #32
+ asrs r2, r3, #31
+ bics r3, r3, r2
+ movs r2, r0
+ lsls r2, r2, r3
+ bne 1f // remaining fractional bits are non-zero, so argument was not an integer
+2:
+ // integer
+ mov r2, ip
+ b double2fix64
+3: // result is zero
+ movs r0, #0
+ movs r1, #0
+ bx lr
+1:
+ push {lr}
+ mov r2, ip
+ bl double2fix64
+ movs r2, #0
+ adds r0, #1
+ adcs r1, r2
+ pop {pc}
+
double_section double2fix64
regular_func double2fix64
shimmable_table_tail_call SF_TABLE_FLOAT2FIX64 double2fix64_shim
double_section double2ufix64
regular_func double2ufix64
+regular_func double2ufix64_z
shimmable_table_tail_call SF_TABLE_FLOAT2UFIX64 double2ufix64_shim
double_section double2fix
regular_func double2fix
shimmable_table_tail_call SF_TABLE_FLOAT2FIX double2fix_shim
+double_section double2fix_z
+regular_func double2fix_z
+ lsls r3, r1, #1
+ asrs r3, #21
+ beq 2f // input is zero or denormal
+ adds r3, #1
+ beq 3f // input is infinite or nan
+
+ // extract exponent again
+ lsls r3, r1, #1
+ lsrs r3, #21
+ // adjust
+ adds r3, r2
+ ble 2f // adjusted input is zero or dedornmal or < 1
+ lsrs r3, r3, #11
+ bne 3f // adjusted input is > infinite
+
+ lsls r2, r2, #20 // align exponent adjustment offset
+ adds r1, r1, r2 // we know adjustment is safe
+ b double2int_z
+2:
+ // result is zero
+ movs r0, #0
+ bx lr
+3:
+ movs r0, #0
+ subs r0, #1
+ lsrs r0, #1
+ asrs r1, #31
+ eors r0, r1
+ bx lr
+
double_section double2ufix
regular_func double2ufix
+regular_func double2ufix_z
shimmable_table_tail_call SF_TABLE_FLOAT2UFIX double2ufix_shim
double_wrapper_section __aeabi_d2f
diff --git a/src/rp2_common/pico_double/double_conv_m33.S b/src/rp2_common/pico_double/double_conv_m33.S
index 606cbfc30..d927d73ca 100644
--- a/src/rp2_common/pico_double/double_conv_m33.S
+++ b/src/rp2_common/pico_double/double_conv_m33.S
@@ -249,7 +249,69 @@ regular_func ufix2double
movs r1,#0
bx r14
-double_wrapper_section conv_dtoi64
+double_section conv_dtoi64
+regular_func double2int64
+ lsls r3, r1, #1
+ bcc double2int64_z // input positive is ok for int64_z
+ cmp r3, #0xffe00000
+ bcs double2int64_z // input is infinite
+ lsrs r3, #21
+ beq 2f // input zero or denormal, means answer remains zero
+ sub r3, #0x3ff
+ cmp r3, #0
+ blt 1f // input is less than 1.0
+ cmp r3, #52
+ bge double2int64_z // modified input must be an integer or infinite
+ adds r3, #12
+ lsls r2, r1, r3 // r2 has remaining fractional mantissa bits of r1
+ bne 1f // not integer as non zero fractional bits remain
+ subs r3, #32
+ bics r3, r3, r3, asr #31 // map negative shift to zero
+ lsls r3, r0, r3
+ beq double2int64_z // remaining fractional bits are 0, so argument was an integer
+1:
+ push {lr}
+ bl double2int64_z
+ subs r0, #1
+ sbcs r1, r1, #0
+ pop {pc}
+2:
+ movs r0, #0
+ movs r1, #0
+ bx lr
+
+double_section conv_dtofix64
+regular_func double2fix64
+ lsls r3, r1, #1
+ bcc double2fix64_z // input positive is ok for fix64_z
+ cmp r3, #0xffe00000
+ bcs double2fix64_z // input is infinite
+ lsrs r3, #21
+ beq 2f // input zero or denormal, means answer remains zero
+ sub r3, #0x3ff
+ adds r3, r2
+ blt 1f // modified input zero or denormal, or less than 1.0
+ cmp r3, #52
+ bge double2fix64_z // modified input must be an integer or infinite
+ adds r3, #12
+ lsls ip, r1, r3 // ip has remaining fractional mantissa bits of r1
+ bne 1f // not integer as non zero fractional bits remain
+ subs r3, #32
+ bics r3, r3, r3, asr #31 // map negative shift to zero
+ lsls r3, r0, r3
+ beq double2fix64_z // remaining fractional bits are 0, so argument was an integer
+1:
+ push {lr}
+ bl double2fix64_z
+ subs r0, #1
+ sbcs r1, r1, #0
+ pop {pc}
+2:
+ movs r0, #0
+ movs r1, #0
+ bx lr
+
+double_wrapper_section conv_dtoi64_z
@ convert double to signed int64, rounding towards 0, clamping
wrapper_func __aeabi_d2lz
diff --git a/src/rp2_common/pico_double/double_fma_dcp.S b/src/rp2_common/pico_double/double_fma_dcp.S
index 30f669bd9..bb810d0fb 100644
--- a/src/rp2_common/pico_double/double_fma_dcp.S
+++ b/src/rp2_common/pico_double/double_fma_dcp.S
@@ -582,7 +582,7 @@ wrapper_func fma
saving_func_return
-double_wrapper_section __dmla
+double_section fma_fast
@ cf saving_func macro: but here we need to record the SP before the state save possibly changes it
1:
push {lr} // 16-bit instruction
@@ -592,6 +592,7 @@ double_wrapper_section __dmla
@ r0:r1 m
@ r2:r3 n
@ [r13,#0] a
+regular_func fma_fast
regular_func mla
mov r12,sp @ save the SP
PCMP apsr_nzcv @ test the engaged flag
diff --git a/src/rp2_common/pico_double/include/pico/double.h b/src/rp2_common/pico_double/include/pico/double.h
index f8c2b4dd5..6805078fb 100644
--- a/src/rp2_common/pico_double/include/pico/double.h
+++ b/src/rp2_common/pico_double/include/pico/double.h
@@ -16,59 +16,178 @@ extern "C" {
#endif
/** \file double.h
-* \defgroup pico_double pico_double
+* \defgroup pico_double pico_double
*
* \brief Optimized double-precision floating point functions
*
-* (Replacement) optimized implementations are provided of the following compiler built-ins
-* and math library functions:
+* An application can take control of the floating point routines used in the application over and above what is provided by the compiler,
+* by depending on the pico_double library. A user might want to do this:
*
-* - __aeabi_dadd, __aeabi_ddiv, __aeabi_dmul, __aeabi_drsub, __aeabi_dsub, __aeabi_cdcmpeq, __aeabi_cdrcmple, __aeabi_cdcmple, __aeabi_dcmpeq, __aeabi_dcmplt, __aeabi_dcmple, __aeabi_dcmpge, __aeabi_dcmpgt, __aeabi_dcmpun, __aeabi_i2d, __aeabi_l2d, __aeabi_ui2d, __aeabi_ul2d, __aeabi_d2iz, __aeabi_d2lz, __aeabi_d2uiz, __aeabi_d2ulz, __aeabi_d2f
-* - sqrt, cos, sin, tan, atan2, exp, log, ldexp, copysign, trunc, floor, ceil, round, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh, exp2, log2, exp10, log10, pow,, hypot, cbrt, fmod, drem, remainder, remquo, expm1, log1p, fma
-* - powint, sincos (GNU extensions)
+* 1. To use optimized software implementations provided by the RP2-series device's bootrom or the SDK
+* 2. To use optimized combined software/hardware implementations utilizing custom RP2-series hardware for acceleration
+* 3. To control the amount of C compiler/library code bloat
+* 4. To make sure no floating point is called at all
*
-* The following additional optimized functions are also provided:
+* The pico_double library comes in three main flavors:
*
-* - int2double, uint2double, int642double, uint642double, fix2double, ufix2double, fix642double, ufix642double
-* - double2fix, double2ufix, double2fix64, double2ufix64, double2int, double2uint, double2int64, double2uint64, double2int_z, double2int64_z,
-* - exp10, sincos, powint
+* 1. `pico_double_none` - all floating point operations cause a \ref panic - no double-precision floating point code is included
+* 2. `pico_double_compiler` - no custom functions are provided; all double-precision floating point is handled by the C compiler/library
+* 3. `pico_double_pico` - the smallest and fastest available for the platform, along with additional functionality (e.g. fixed point conversions) which are detailed below
*
-* On RP2350 the following additional functions are available; the _fast methods are faster but do not round correctly"
+* The user can control which version they want (e.g. **pico_double_xxx** by either setting the CMake global variable
+* `PICO_DEFAULT_DOUBLE_IMPL=xxx`, or by using the CMake function `pico_set_double_implementation( xxx)`. Note that in the absence
+* of either, pico_double_pico is used by default.
*
-* - ddiv_fast, sqrt_fast
+* \if rp2040_specific
+* On RP2040, `pico_double_pico` uses optimized hand coded implementations from the bootrom and the SDK for both
+* basic double-precision floating point operations and floating point math library functions. These implementations
+* are generally faster and smaller than those provided by the C compiler/library, though they don't support all the features of a fully compliant
+* floating point implementation; they are however usually fine for the majority of cases
+* \endif
+*
+* \if rp2350_specific
+* On RP2350, `pico_double_pico` uses RP2350 DCP instructions (double co-processor) to implement fast version of the basic
+* arithmetic functions, and provides optimized M33 implementations of trignometric and scientific functions.
+* These implementations are generally faster and smaller than those provided by the C compiler/library, though they don't support all the features of a fully compliant
+* floating point implementation; they are however usually fine for the majority of cases
+* \endif
+*
+* On Arm, (replacement) optimized implementations are provided for the following compiler built-ins
+* and math library functions when using `pico_double_pico`:
+*
+* - basic arithmetic:
+*
+* __aeabi_dadd, __aeabi_ddiv, __aeabi_dmul, __aeabi_drsub, __aeabi_dsub
+*
+* - comparison:
+*
+* __aeabi_cfcmpeq, __aeabi_cfrcmple, __aeabi_cfcmple, __aeabi_dcmpeq, __aeabi_dcmplt, __aeabi_dcmple, __aeabi_dcmpge, __aeabi_dcmpgt, __aeabi_dcmpun
+*
+* - (u)int32 <-> double:
+*
+* __aeabi_i2d, __aeabi_ui2d, __aeabi_d2iz, __aeabi_d2uiz
+*
+* - (u)int64 <-> double:
+*
+* __aeabi_l2d, __aeabi_ul2d, __aeabi_d2lz, __aeabi_d2ulz
+*
+* - double -> float:
+*
+* __aeabi_d2d
+*
+* - basic trigonometric:
+*
+* sqrt, cos, sin, tan, atan2, exp, log
+*
+* - trigonometric and scientific
+*
+* ldexp, copysign, trunc, floor, ceil, round, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh, exp2, log2, exp10, log10, pow, hypot, cbrt, fmod, drem, remainder, remquo, expm1, log1p, fma
+*
+* - GNU exetnsions:
+*
+* powint, sincos
+*
+* On Arm, the following additional optimized functions are also provided when using `pico_double_pico`:
+*
+* - Conversions to/from integer types:
+*
+* - (u)int -> double (round to nearest):
+*
+* int2double, uint2double, int642double, uint642double
+*
+* - (u)double -> int (round towards zero):
+*
+* double2int_z, double2uint_z, double2int64_z, double2uint64_z
+*
+* - (u)double -> int (round towards -infinity):
+*
+* double2int, double2uint, double2int64, double2uint64
+*
+* - Conversions to/from fixed point integers:
+*
+* - (u)fix -> double (round to nearest):
+*
+* fix2double, ufix2double, fix642double, ufix642double
+*
+* - double -> (u)fix (round towards zero):
+*
+* double2fix_z, double2ufix_z, double2fix64_z, double2ufix64_z
+*
+* - double -> (u)fix (round towards -infinity):
+*
+* double2fix, double2ufix, double2fix64, double2ufix64
+*
+* - Even faster versions of divide and square-root functions that do not round correctly:
+*
+* ddiv_fast, sqrt_fast (these do not round correctly)
+*
+* - Faster unfused multiply and accumulate:
+*
+* mla (fast fma)
+*
+* \if rp2350_specific
+* On RISC-V there is no custom double-precision floating point support, so `pico_double_pico` is equivalent to `pico_double_compiler`
+* \endif
*/
+#if !defined(__riscv) || PICO_COMBINED_DOCS
+#if PICO_COMBINED_DOCS || !LIB_PICO_DOUBLE_COMPILER
double int2double(int32_t i);
-double uint2double(uint32_t u);
+double uint2double(uint32_t i);
double int642double(int64_t i);
-double uint642double(uint64_t u);
+double uint642double(uint64_t i);
double fix2double(int32_t m, int e);
double ufix2double(uint32_t m, int e);
double fix642double(int64_t m, int e);
double ufix642double(uint64_t m, int e);
-// These methods round towards -Infinity.
-int32_t double2fix(double d, int e);
-uint32_t double2ufix(double d, int e);
-int64_t double2fix64(double d, int e);
-uint64_t double2ufix64(double d, int e);
-int32_t double2int(double d);
-uint32_t double2uint(double d);
-int64_t double2int64(double d);
-uint64_t double2uint64(double d);
+// These methods round towards 0, which IS the C way
+int32_t double2int_z(double f);
+int64_t double2int64_z(double f);
+int32_t double2uint_z(double f);
+int64_t double2uint64_z(double f);
+int32_t double2fix_z(double f, int e);
+uint32_t double2ufix_z(double f, int e);
+int64_t double2fix64_z(double f, int e);
+uint64_t double2ufix64_z(double f, int e);
-// These methods round towards 0.
-int32_t double2int_z(double d);
-int64_t double2int64_z(double d);
+// These methods round towards -Infinity - which IS NOT the C way for negative numbers;
+// as such the naming is not ideal, however is kept for backwards compatibility
+int32_t double2int(double f);
+uint32_t double2uint(double f);
+int64_t double2int64(double f);
+uint64_t double2uint64(double f);
+int32_t double2fix(double f, int e);
+uint32_t double2ufix(double f, int e);
+int64_t double2fix64(double f, int e);
+uint64_t double2ufix64(double f, int e);
+
+#endif
double exp10(double x);
void sincos(double x, double *sinx, double *cosx);
double powint(double x, int y);
-#if !PICO_RP2040
+#if !PICO_RP2040 || PICO_COMBINED_DOCS
double ddiv_fast(double n, double d);
-double sqrt_fast(double d);
-double mla(double x, double y, double z); // note this is not fused
+double sqrt_fast(double f);
+double fma_fast(double x, double y, double z); // this is not fused
+double mla(double x, double y, double z); // another name for fma_fast
+#endif
+
+#endif
+
+#if LIB_PICO_DOUBLE_COMPILER || defined(__riscv)
+// when using the compiler; we provide as many functions as we trivially can, though in the double case they are not optimal
+static inline double int2double(int32_t i) { return (double)i; }
+static inline double uint2double(uint32_t i) { return (double)i; }
+static inline double int642double(int64_t i) { return (double)i; }
+static inline double uint642double(uint64_t i) { return (double)i; }
+
+static inline int32_t double2int_z(double d) { return (int32_t)d; }
+static inline int64_t double2int64_z(double d) { return (int64_t)d; }
+static inline int32_t double2uint_z(double d) { return (uint32_t)d; }
+static inline int64_t double2uint64_z(double d) { return (uint64_t)d; }
#endif
#ifdef __cplusplus
@@ -76,4 +195,3 @@ double mla(double x, double y, double z); // note this is not fused
#endif
#endif
-
diff --git a/src/rp2_common/pico_flash/flash.c b/src/rp2_common/pico_flash/flash.c
index 6a6294a78..1dc68c7b7 100644
--- a/src/rp2_common/pico_flash/flash.c
+++ b/src/rp2_common/pico_flash/flash.c
@@ -145,7 +145,16 @@ static int default_enter_safe_zone_timeout_ms(__unused uint32_t timeout_ms) {
uint core_num = get_core_num();
// create at low priority on other core
TaskHandle_t task_handle;
+
+ // when FreeRTOS dynamic allocation is disabled (configSUPPORT_DYNAMIC_ALLOCATION == 0), the following fails
+#if configSUPPORT_DYNAMIC_ALLOCATION
if (pdPASS != xTaskCreateAffinitySet(flash_lockout_task, "flash lockout", configMINIMAL_STACK_SIZE, (void *)core_num, 0, 1u << (core_num ^ 1), &task_handle)) {
+#else
+ static StackType_t flash_lockout_stack[configMINIMAL_STACK_SIZE];
+ static StaticTask_t flash_lockout_task_tcb;
+ task_handle = xTaskCreateStaticAffinitySet(flash_lockout_task, "flash lockout", configMINIMAL_STACK_SIZE, (void *)core_num, 0, flash_lockout_stack, &flash_lockout_task_tcb, 1u << (core_num ^ 1));
+ if (task_handle == NULL) {
+#endif
return PICO_ERROR_INSUFFICIENT_RESOURCES;
}
lockout_state[core_num] = FREERTOS_LOCKOUT_LOCKER_WAITING;
@@ -216,4 +225,4 @@ static int default_exit_safe_zone_timeout_ms(__unused uint32_t timeout_ms) {
#endif
}
return PICO_OK;
-}
\ No newline at end of file
+}
diff --git a/src/rp2_common/pico_float/BUILD.bazel b/src/rp2_common/pico_float/BUILD.bazel
index f6aadca2d..8d4ab363e 100644
--- a/src/rp2_common/pico_float/BUILD.bazel
+++ b/src/rp2_common/pico_float/BUILD.bazel
@@ -2,13 +2,16 @@ load("//bazel:defs.bzl", "compatible_with_rp2", "incompatible_with_config")
package(default_visibility = ["//visibility:public"])
-_WRAP_FLOAT_AEABI_FLAGS = [
+_WRAP_FLOAT_AEABI_ARITHMETIC_FLAGS = [
"-Wl,--wrap=__aeabi_fadd",
"-Wl,--wrap=__aeabi_fdiv",
"-Wl,--wrap=__aeabi_fmul",
"-Wl,--wrap=__aeabi_frsub",
"-Wl,--wrap=__aeabi_fsub",
"-Wl,--wrap=__aeabi_cfcmpeq",
+]
+
+_WRAP_FLOAT_AEABI_CMP_FLAGS = [
"-Wl,--wrap=__aeabi_cfrcmple",
"-Wl,--wrap=__aeabi_cfcmple",
"-Wl,--wrap=__aeabi_fcmpeq",
@@ -17,15 +20,27 @@ _WRAP_FLOAT_AEABI_FLAGS = [
"-Wl,--wrap=__aeabi_fcmpge",
"-Wl,--wrap=__aeabi_fcmpgt",
"-Wl,--wrap=__aeabi_fcmpun",
+]
+
+_WRAP_FLOAT_AEABI_CONV_32_FLAGS = [
"-Wl,--wrap=__aeabi_i2f",
"-Wl,--wrap=__aeabi_l2f",
"-Wl,--wrap=__aeabi_ui2f",
"-Wl,--wrap=__aeabi_ul2f",
+]
+
+_WRAP_FLOAT_AEABI_CONV_64_FLAGS = [
"-Wl,--wrap=__aeabi_f2iz",
"-Wl,--wrap=__aeabi_f2lz",
"-Wl,--wrap=__aeabi_f2uiz",
"-Wl,--wrap=__aeabi_f2ulz",
+]
+
+_WRAP_FLOAT_AEABI_CONV_DOUBLE_FLAGS = [
"-Wl,--wrap=__aeabi_f2d",
+]
+
+_WRAP_FLOAT_SQRTF_FLAGS = [
"-Wl,--wrap=sqrtf",
]
@@ -36,13 +51,16 @@ _WRAP_FLOAT_SCI_FLAGS = [
"-Wl,--wrap=atan2f",
"-Wl,--wrap=expf",
"-Wl,--wrap=logf",
+ "-Wl,--wrap=sincosf", # gnu
+]
+
+_WRAP_FLOAT_SCI_EXTRA_FLAGS = [
"-Wl,--wrap=ldexpf",
"-Wl,--wrap=copysignf",
"-Wl,--wrap=truncf",
"-Wl,--wrap=floorf",
"-Wl,--wrap=ceilf",
"-Wl,--wrap=roundf",
- "-Wl,--wrap=sincosf", # gnu
"-Wl,--wrap=asinf",
"-Wl,--wrap=acosf",
"-Wl,--wrap=atanf",
@@ -114,30 +132,31 @@ _PICO_FLOAT_IMPLS = [
],
"compatibility": incompatible_with_config("@platforms//cpu:riscv32") + ["//bazel/constraint:rp2040"],
"extra_deps": [],
- "linkopts": _WRAP_FLOAT_AEABI_FLAGS + _WRAP_FLOAT_SCI_FLAGS,
+ "linkopts": _WRAP_FLOAT_AEABI_ARITHMETIC_FLAGS + _WRAP_FLOAT_AEABI_CMP_FLAGS + _WRAP_FLOAT_AEABI_CONV_32_FLAGS + _WRAP_FLOAT_AEABI_CONV_64_FLAGS + _WRAP_FLOAT_AEABI_CONV_DOUBLE_FLAGS + _WRAP_FLOAT_SQRTF_FLAGS + _WRAP_FLOAT_SCI_FLAGS + _WRAP_FLOAT_SCI_EXTRA_FLAGS,
},
{
"name": "dcp",
"srcs": [
"float_aeabi_dcp.S",
- "float_conv_m33.S",
+ "float_common_m33.S",
"float_math.c",
"float_sci_m33.S",
],
"compatibility": compatible_with_rp2() + incompatible_with_config("@platforms//cpu:riscv32") + incompatible_with_config("//bazel/constraint:rp2040"),
"extra_deps": ["//src/rp2_common/hardware_dcp"],
- "linkopts": _WRAP_FLOAT_SCI_FLAGS,
+ "linkopts": _WRAP_FLOAT_AEABI_ARITHMETIC_FLAGS + _WRAP_FLOAT_AEABI_CMP_FLAGS + _WRAP_FLOAT_AEABI_CONV_32_FLAGS + _WRAP_FLOAT_AEABI_CONV_64_FLAGS + _WRAP_FLOAT_AEABI_CONV_DOUBLE_FLAGS + _WRAP_FLOAT_SQRTF_FLAGS + _WRAP_FLOAT_SCI_FLAGS + _WRAP_FLOAT_SCI_EXTRA_FLAGS,
},
{
"name": "vfp",
"srcs": [
+ "float_conv32_vfp.S",
"float_sci_m33_vfp.S",
- "float_conv_m33.S",
+ "float_common_m33.S",
"float_math.c",
],
"compatibility": compatible_with_rp2() + incompatible_with_config("@platforms//cpu:riscv32") + incompatible_with_config("//bazel/constraint:rp2040"),
"extra_deps": ["//src/rp2_common/hardware_dcp"],
- "linkopts": _WRAP_FLOAT_SCI_FLAGS,
+ "linkopts": _WRAP_FLOAT_AEABI_CONV_64_FLAGS + _WRAP_FLOAT_SCI_FLAGS + _WRAP_FLOAT_SCI_EXTRA_FLAGS,
},
{
"name": "single_hazard3",
@@ -146,7 +165,7 @@ _PICO_FLOAT_IMPLS = [
],
"compatibility": compatible_with_rp2() + ["@platforms//cpu:riscv32"],
"extra_deps": ["//src/rp2_common/hardware_hazard3"],
- "linkopts": _WRAP_FLOAT_SCI_FLAGS,
+ "linkopts": _WRAP_FLOAT_SCI_EXTRA_FLAGS,
},
]
@@ -184,7 +203,7 @@ cc_library(
hdrs = ["include/pico/float.h"],
defines = ["LIB_PICO_FLOAT_PICO=0"],
includes = ["include"],
- linkopts = _WRAP_FLOAT_AEABI_FLAGS + _WRAP_FLOAT_SCI_FLAGS,
+ linkopts = _WRAP_FLOAT_AEABI_ARITHMETIC_FLAGS + _WRAP_FLOAT_AEABI_CMP_FLAGS + _WRAP_FLOAT_AEABI_CONV_32_FLAGS + _WRAP_FLOAT_AEABI_CONV_64_FLAGS + _WRAP_FLOAT_AEABI_CONV_DOUBLE_FLAGS + _WRAP_FLOAT_SQRTF_FLAGS + _WRAP_FLOAT_SCI_FLAGS + _WRAP_FLOAT_SCI_EXTRA_FLAGS,
target_compatible_with = compatible_with_rp2(),
visibility = ["//visibility:private"],
deps = [
diff --git a/src/rp2_common/pico_float/CMakeLists.txt b/src/rp2_common/pico_float/CMakeLists.txt
index 7d53274ff..f634f094d 100644
--- a/src/rp2_common/pico_float/CMakeLists.txt
+++ b/src/rp2_common/pico_float/CMakeLists.txt
@@ -18,13 +18,15 @@
$>,$,${PICO_DEFAULT_FLOAT_IMPL}>)
function(wrap_float_functions TARGET)
- cmake_parse_arguments(WRAP_FLOAT "NO_WRAP_AEABI;NO_WRAP_SCI" "" "" ${ARGN} )
- if (NOT WRAP_FLOAT_NO_WRAP_AEABI)
+ cmake_parse_arguments(WRAP_FLOAT "NO_AEABI_ARITHMETIC;NO_AEABI_CMP;NO_AEABI_CONV_32;NO_AEABI_CONV_64;NO_AEABI_CONV_DOUBLE;NO_SQRTF;NO_SCI;NO_SCI_EXTRA" "" "" ${ARGN} )
+ if (NOT WRAP_FLOAT_NO_AEABI_ARITHMETIC)
pico_wrap_function(${TARGET} __aeabi_fadd)
pico_wrap_function(${TARGET} __aeabi_fdiv)
pico_wrap_function(${TARGET} __aeabi_fmul)
pico_wrap_function(${TARGET} __aeabi_frsub)
pico_wrap_function(${TARGET} __aeabi_fsub)
+ endif()
+ if (NOT WRAP_FLOAT_NO_AEABI_CMP)
pico_wrap_function(${TARGET} __aeabi_cfcmpeq)
pico_wrap_function(${TARGET} __aeabi_cfrcmple)
pico_wrap_function(${TARGET} __aeabi_cfcmple)
@@ -34,32 +36,42 @@
pico_wrap_function(${TARGET} __aeabi_fcmpge)
pico_wrap_function(${TARGET} __aeabi_fcmpgt)
pico_wrap_function(${TARGET} __aeabi_fcmpun)
+ endif()
+ if (NOT WRAP_FLOAT_NO_AEABI_CONV_32)
pico_wrap_function(${TARGET} __aeabi_i2f)
- pico_wrap_function(${TARGET} __aeabi_l2f)
pico_wrap_function(${TARGET} __aeabi_ui2f)
- pico_wrap_function(${TARGET} __aeabi_ul2f)
pico_wrap_function(${TARGET} __aeabi_f2iz)
- pico_wrap_function(${TARGET} __aeabi_f2lz)
pico_wrap_function(${TARGET} __aeabi_f2uiz)
+ endif()
+ if (NOT WRAP_FLOAT_NO_AEABI_CONV_64)
+ pico_wrap_function(${TARGET} __aeabi_l2f)
+ pico_wrap_function(${TARGET} __aeabi_ul2f)
+ pico_wrap_function(${TARGET} __aeabi_f2lz)
pico_wrap_function(${TARGET} __aeabi_f2ulz)
+ endif()
+ if (NOT WRAP_FLOAT_NO_AEABI_CONV_DOUBLE)
pico_wrap_function(${TARGET} __aeabi_f2d)
+ endif()
+ # separate as we have a direct DCP version
+ if (NOT WRAP_FLOAT_NO_SQRTF)
pico_wrap_function(${TARGET} sqrtf)
endif()
- if (NOT WRAP_FLOAT_NO_WRAP_SCI)
+ if (NOT WRAP_FLOAT_NO_SCI)
pico_wrap_function(${TARGET} cosf)
pico_wrap_function(${TARGET} sinf)
pico_wrap_function(${TARGET} tanf)
pico_wrap_function(${TARGET} atan2f)
pico_wrap_function(${TARGET} expf)
pico_wrap_function(${TARGET} logf)
-
+ pico_wrap_function(${TARGET} sincosf) # gnu
+ endif()
+ if (NOT WRAP_FLOAT_NO_SCI_EXTRA)
pico_wrap_function(${TARGET} ldexpf)
pico_wrap_function(${TARGET} copysignf)
pico_wrap_function(${TARGET} truncf)
pico_wrap_function(${TARGET} floorf)
pico_wrap_function(${TARGET} ceilf)
pico_wrap_function(${TARGET} roundf)
- pico_wrap_function(${TARGET} sincosf) # gnu
pico_wrap_function(${TARGET} asinf)
pico_wrap_function(${TARGET} acosf)
pico_wrap_function(${TARGET} atanf)
@@ -93,7 +105,9 @@
)
target_link_libraries(pico_float_none INTERFACE pico_float_headers)
- wrap_float_functions(pico_float_none)
+ wrap_float_functions(pico_float_none) # we wrap all functions
+ # be explicit that there should be no floating point instructions
+ target_compile_options(pico_float_none INTERFACE -msoft-float)
pico_add_library(pico_float_pico)
if (PICO_RP2040)
@@ -107,21 +121,52 @@
target_link_libraries(pico_float_pico INTERFACE pico_bootrom pico_float_headers hardware_divider)
elseif(NOT PICO_RISCV)
pico_add_library(pico_float_pico_dcp)
+ # todo what functions from float_math belong in each case; should some be left to GCC on RP2350?
target_sources(pico_float_pico_dcp INTERFACE
${CMAKE_CURRENT_LIST_DIR}/float_math.c
${CMAKE_CURRENT_LIST_DIR}/float_aeabi_dcp.S
+ ${CMAKE_CURRENT_LIST_DIR}/float_common_m33.S
${CMAKE_CURRENT_LIST_DIR}/float_sci_m33.S
- ${CMAKE_CURRENT_LIST_DIR}/float_conv_m33.S
)
- wrap_float_functions(pico_float_pico_dcp NO_WRAP_AEABI)
+ # NOTE the main reason for using pico_float_pico_dcp is presumably that you
+ # don't want to use VFP at all, so turn off compiler support, otherwise, it will inline usages
+ target_compile_options(pico_float_pico_dcp INTERFACE -msoft-float)
+
+ wrap_float_functions(pico_float_pico_dcp
+ # we wrap all functions as we don't want to use VFP (or compiler versions) at all
+ #NO_AEABI_ARITHMETIC
+ #NO_AEABI_CMP
+ #NO_AEABI_CONV_32
+ #NO_AEABI_CONV_64
+ #NO_AEABI_CONV_DOUBLE
+ #NO_SQRTF
+ #NO_SCI
+ #NO_SCI_EXTRA
+ )
+
pico_add_library(pico_float_pico_vfp)
target_sources(pico_float_pico_vfp INTERFACE
${CMAKE_CURRENT_LIST_DIR}/float_math.c
+ ${CMAKE_CURRENT_LIST_DIR}/float_conv32_vfp.S
+ ${CMAKE_CURRENT_LIST_DIR}/float_common_m33.S
${CMAKE_CURRENT_LIST_DIR}/float_sci_m33_vfp.S
- ${CMAKE_CURRENT_LIST_DIR}/float_conv_m33.S
)
- wrap_float_functions(pico_float_pico_vfp NO_WRAP_AEABI)
+ wrap_float_functions(pico_float_pico_vfp
+ # for these 3, arguably compiler is probably inlining anyway, but use the cmopiler's
+ # version for explicit AEABI calls
+ NO_AEABI_ARITHMETIC
+ NO_AEABI_CMP
+ NO_AEABI_CONV_32
+ #NO_AEABI_CONV_64 # we have optimized M33 versions
+ NO_AEABI_CONV_DOUBLE
+ # we don't have an optimized vfp or m33 sqrtf available
+ NO_SQRTF
+ #NO_SCI # we have optimized VFP versions
+ #NO_SCI_EXTRA # todo - are our versions better than what GCC proides?
+ )
+
+
target_link_libraries(pico_float_pico INTERFACE
pico_float_pico_vfp)
else()
diff --git a/src/rp2_common/pico_float/float_aeabi_dcp.S b/src/rp2_common/pico_float/float_aeabi_dcp.S
index 61c240919..de170d3ef 100644
--- a/src/rp2_common/pico_float/float_aeabi_dcp.S
+++ b/src/rp2_common/pico_float/float_aeabi_dcp.S
@@ -5,15 +5,17 @@
*/
#include "pico/asm_helper.S"
-#if HAS_DOUBLE_COPROCESSOR
+
+#if !HAS_DOUBLE_COPROCESSOR
+#error attempt to compile float_aeabi_dcp when there is no DCP
+#else
+
#include "hardware/dcp_instr.inc.S"
#include "hardware/dcp_canned.inc.S"
pico_default_asm_setup
-// todo alignment
-//__pre_init __aeabi_float_init, 00020
-// factor out save/restore (there is a copy in double code)
+// todo factor out save/restore (there is a copy in double code)
.macro float_section name
#if PICO_FLOAT_IN_RAM
@@ -29,7 +31,7 @@ float_section WRAPPER_FUNC_NAME(\func)
// ============== STATE SAVE AND RESTORE ===============
-.macro saving_func func
+.macro saving_func type func, opt_label1='-', opt_label2='-'
// Note we are usually 32-bit aligned already at this point, as most of the
// function bodies contain exactly two 16-bit instructions: bmi and bx lr.
// We want the PCMP word-aligned.
@@ -41,8 +43,14 @@ float_section WRAPPER_FUNC_NAME(\func)
push {lr} // 16-bit instruction
bl generic_save_state // 32-bit instruction
b 1f // 16-bit instruction
+.ifnc \opt_label1,'-'
+regular_func \opt_label1
+.endif
+.ifnc \opt_label2,'-'
+regular_func \opt_label2
+.endif
// This is the actual entry point:
-wrapper_func \func
+\type\()_func \func
PCMP apsr_nzcv
bmi 1b
1:
@@ -82,115 +90,208 @@ generic_restore_state:
// ============== ARITHMETIC FUNCTIONS ===============
float_wrapper_section __aeabi_fadd
-saving_func __aeabi_fadd
+saving_func wrapper __aeabi_fadd
dcp_fadd_m r0,r0,r1
saving_func_return
float_wrapper_section __aeabi_fsub
-saving_func __aeabi_fsub
+saving_func wrapper __aeabi_fsub
dcp_fsub_m r0,r0,r1
saving_func_return
float_wrapper_section __aeabi_frsub
-saving_func __aeabi_frsub
+saving_func wrapper __aeabi_frsub
dcp_fsub_m r0,r1,r0
saving_func_return
float_wrapper_section __aeabi_fmul
-saving_func __aeabi_fmul
+saving_func wrapper __aeabi_fmul
dcp_fmul_m r0,r0,r1,r0,r1
saving_func_return
float_section fdiv_fast
-saving_func fdiv_fast
+saving_func regular fdiv_fast
dcp_fdiv_fast_m r0,r0,r1,r0,r1,r2
saving_func_return
float_wrapper_section __aeabi_fdiv
-saving_func __aeabi_fdiv
+saving_func wrapper __aeabi_fdiv
@ with correct rounding
dcp_fdiv_m r0,r0,r1,r0,r1,r2,r3
saving_func_return
float_section sqrtf_fast
-saving_func sqrtf_fast
+saving_func regular sqrtf_fast
dcp_fsqrt_fast_m r0,r0,r0,r1,r2,r3
saving_func_return
float_wrapper_section sqrtf
-saving_func sqrtf
+saving_func wrapper sqrtf
@ with correct rounding
dcp_fsqrt_m r0,r0,r0,r1,r2,r3
saving_func_return
-// todo not a real thing
-float_wrapper_section __aeabi_fclassify
-saving_func __aeabi_fclassify
+float_section fclassify
+saving_func regular fclassify
dcp_fclassify_m apsr_nzcv,r0
saving_func_return
// ============== CONVERSION FUNCTIONS ===============
float_wrapper_section __aeabi_f2d
-saving_func __aeabi_f2d
+saving_func wrapper __aeabi_f2d float2double
dcp_float2double_m r0,r1,r0
saving_func_return
float_wrapper_section __aeabi_i2f
-saving_func __aeabi_i2f
+saving_func wrapper __aeabi_i2f int2float
@ with rounding
dcp_int2float_m r0,r0
saving_func_return
float_wrapper_section __aeabi_ui2f
-saving_func __aeabi_ui2f
+saving_func wrapper __aeabi_ui2f uint2float
@ with rounding
dcp_uint2float_m r0,r0
saving_func_return
+float_section float2fix_z
+regular_func float2fix_z
+ ubfx r2, r0, #23, #8
+ cbz r2, 2f // input is zero or denormal
+ cmp r2, #0xff
+ beq 3f // input infinite or nan
+ adds r2, r1
+ ble 2f // modified input is denormal so zero
+ cmp r2, #0xff
+ beq 3f // modified input is infinite
+1:
+ bfi r0, r2, #23, #8
+ b float2int_z_entry
+2:
+ movs r0, #0
+ bx lr
+3:
+ mvn r1, #0x80000000
+ add r0, r1, r0, lsr#31 @ so -Inf → 0x80000000, +Inf → 0x7fffffff
+ bx lr
+
float_wrapper_section __aeabi_f2iz
-saving_func __aeabi_f2iz
+saving_func wrapper __aeabi_f2iz float2int_z
@ with truncation towards 0
+float2int_z_entry:
dcp_float2int_m r0,r0
saving_func_return
+float_section __aeabi_f2ufix
+regular_func float2ufix
+regular_func float2ufix_z
+ ubfx r2, r0, #23, #8
+ cbz r2, 2f // input is zero or denormal
+ cmp r2, #0xff
+ beq 3f // input infinite or nan
+ adds r2, r1
+ ble 2f // modified input is denormal so zero
+ cmp r2, #0xff
+ beq 3f // modified input is infinite
+1:
+ bfi r0, r2, #23, #8
+ b float2uint_z_entry
+2:
+ movs r0, #0
+ bx lr
+3:
+ mvn r0, r0, asr #31
+ bx lr
+
float_wrapper_section __aeabi_f2uiz
-saving_func __aeabi_f2uiz
+saving_func wrapper __aeabi_f2uiz float2uint_z float2uint
@ with truncation towards 0
+float2uint_z_entry:
dcp_float2uint_m r0,r0
saving_func_return
-// todo not a real thing
+float_section conv_f2fix
+saving_func regular float2fix
+ ubfx r2, r0, #23, #8
+ cbz r2, 2f // input is zero or denormal
+ cmp r2, #0xff
+ beq 3f // input infinite or nan
+ adds r2, r1
+ ble 2f // modified input is denormal so zero
+ cmp r2, #0xff
+ beq 3f // modified input is infinite
+1:
+ bfi r0, r2, #23, #8
+ b float2int_entry
+2:
+ movs r0, #0
+ bx lr
+3:
+ mvn r1, #0x80000000
+ add r0, r1, r0, lsr#31 @ so -Inf → 0x80000000, +Inf → 0x7fffffff
+ bx lr
+
+float_section float2int
+// (not a real thing - kept because we use wrapper in saving_func)
+saving_func regular float2int
+float2int_entry:
+ lsls r1, r0, #1
+ // r0 = abs(zero) => r1 = 0x00000000
+ // r0 = abs(denornaml) => r1 = 0x00xxxxxx
+ // r0 = abs(1.0f) => r1 = 0x7f000000
+ // r0 = abs(inf/nan) => r1 = 0xffxxxxxx
+ bls float2int_z_entry // input positive or zero or -zero are ok for int64_z
+ lsrs r1, #24
+ beq float2int_z_entry // input denormal is flushed to zero anyway
+ subs r1, #0x7f
+ bcc 1f // input < 1.0f means we need to subtract 1 after conversion
+ // mask off all but fractional bits
+ lsls r2, r0, r1
+ lsls r2, #9
+ beq float2int_z_entry // input is integer
+1:
+ WXFC r0, r0
+ ADD0
+ ADD1
+ NTDC
+ RDIC r0
+ subs r0, #1
+saving_func_return
+
+#if 0 // not sure these are super useful; if they are we should give them names
float_wrapper_section __aeabi_f2i_r
-saving_func __aeabi_f2i_r
+// (not a real thing - kept because we use wrapper in saving_func)
+saving_func wrapper __aeabi_f2i_r
@ with rounding
dcp_float2int_r_m r0,r0
saving_func_return
-// todo not a real thing
float_wrapper_section __aeabi_f2ui_r
-saving_func __aeabi_f2ui_r
+// (not a real thing - kept because we use wrapper in saving_func)
+saving_func wrapper __aeabi_f2ui_r
@ with rounding
dcp_float2uint_r_m r0,r0
saving_func_return
+#endif
// ============== COMPARISON FUNCTIONS ===============
float_wrapper_section __aeabi_fcmpun
-saving_func __aeabi_fcmpun
+saving_func wrapper __aeabi_fcmpun
dcp_fcmp_m r0,r0,r1
// extract unordered bit
ubfx r0, r0, #28, #1
saving_func_return
float_wrapper_section __aeabi_fcmp
-saving_func __aeabi_cfrcmple
+saving_func wrapper __aeabi_cfrcmple
dcp_fcmp_m apsr_nzcv,r1,r0 // with arguments reversed
bvs cmp_nan
saving_func_return
// these next two can be the same function in the absence of exceptions
-saving_func __aeabi_cfcmple
+saving_func wrapper __aeabi_cfcmple
dcp_fcmp_m apsr_nzcv,r0,r1
bvs cmp_nan
saving_func_return
@@ -198,7 +299,7 @@ saving_func __aeabi_cfcmple
// It is not clear from the ABI documentation whether cfcmpeq must set the C flag
// in the same way as cfcmple. If not, we could save the "bvs" below; but we
// err on the side of caution.
-saving_func __aeabi_cfcmpeq
+saving_func wrapper __aeabi_cfcmpeq
dcp_fcmp_m apsr_nzcv,r0,r1
bvs cmp_nan
saving_func_return
@@ -212,14 +313,14 @@ cmp_nan:
saving_func_return
float_wrapper_section __aeabi_fcmpeq
-saving_func __aeabi_fcmpeq
+saving_func wrapper __aeabi_fcmpeq
dcp_fcmp_m r0,r0,r1
// extract Z
ubfx r0, r0, #30, #1
saving_func_return
float_wrapper_section __aeabi_fcmplt
-saving_func __aeabi_fcmplt
+saving_func wrapper __aeabi_fcmplt
dcp_fcmp_m apsr_nzcv,r1,r0
ite hi
movhi r0,#1
@@ -227,7 +328,7 @@ saving_func __aeabi_fcmplt
saving_func_return
float_wrapper_section __aeabi_fcmple
-saving_func __aeabi_fcmple
+saving_func wrapper __aeabi_fcmple
dcp_fcmp_m apsr_nzcv,r1,r0
ite hs
movhs r0,#1
@@ -235,7 +336,7 @@ saving_func __aeabi_fcmple
saving_func_return
float_wrapper_section __aeabi_fcmpge
-saving_func __aeabi_fcmpge
+saving_func wrapper __aeabi_fcmpge
dcp_fcmp_m apsr_nzcv,r0,r1
ite hs
movhs r0,#1
@@ -243,7 +344,7 @@ saving_func __aeabi_fcmpge
saving_func_return
float_wrapper_section __aeabi_fcmpgt
-saving_func __aeabi_fcmpgt
+saving_func wrapper __aeabi_fcmpgt
dcp_fcmp_m apsr_nzcv,r0,r1
ite hi
movhi r0,#1
diff --git a/src/rp2_common/pico_float/float_aeabi_rp2040.S b/src/rp2_common/pico_float/float_aeabi_rp2040.S
index 8eb83fc22..c34f68f67 100644
--- a/src/rp2_common/pico_float/float_aeabi_rp2040.S
+++ b/src/rp2_common/pico_float/float_aeabi_rp2040.S
@@ -471,17 +471,36 @@ float_section float2int
regular_func float2int
shimmable_table_tail_call SF_TABLE_FLOAT2INT float2int_shim
+float_section float2fix_z
+regular_func float2fix_z
+ cmn r0, r0
+ bcc float2fix
+ push {lr}
+ lsls r0, #1
+ lsrs r0, #1
+ bl float2ufix_z
+ cmp r0, #0
+ bmi 1f
+ negs r0, r0
+ pop {pc}
+1:
+ movs r0, #128
+ lsls r0, #24
+ pop {pc}
+
float_section float2fix
regular_func float2fix
shimmable_table_tail_call SF_TABLE_FLOAT2FIX float2fix_shim
float_section float2ufix
regular_func float2ufix
+regular_func float2ufix_z
table_tail_call SF_TABLE_FLOAT2UFIX
// unsigned FUNC_NAME(__aeabi_f2uiz)(float) float (single precision) to unsigned C-style conversion [3]
float_wrapper_section __aeabi_f2uiz
wrapper_func __aeabi_f2uiz
+regular_func float2uint
regular_func float2uint_z
table_tail_call SF_TABLE_FLOAT2UINT
@@ -530,10 +549,11 @@ wrapper_func __aeabi_f2lz
regular_func float2int64_z
cmn r0, r0
bcc float2int64
+ movs r1, #0
+float2fix64_z_neg:
push {lr}
lsls r0, #1
lsrs r0, #1
- movs r1, #0
bl float2ufix64
cmp r1, #0
bmi 1f
@@ -553,17 +573,24 @@ regular_func float2int64
shimmable_table_tail_call SF_TABLE_FLOAT2INT64 float2int64_shim
float_section float2fix64
+regular_func float2fix64_z
+ cmn r0, r0
+ bcs float2fix64_z_neg
+ // fall thru
+
regular_func float2fix64
shimmable_table_tail_call SF_TABLE_FLOAT2FIX64 float2fix64_shim
// unsigned long long FUNC_NAME(__aeabi_f2ulz)(float) float to unsigned long long C-style conversion [3]
float_wrapper_section __aeabi_f2ulz
wrapper_func __aeabi_f2ulz
+regular_func float2uint64
regular_func float2uint64_z
shimmable_table_tail_call SF_TABLE_FLOAT2UINT64 float2uint64_shim
float_section float2ufix64
regular_func float2ufix64
+regular_func float2ufix64_z
shimmable_table_tail_call SF_TABLE_FLOAT2UFIX64 float2ufix64_shim
float_wrapper_section __aeabi_f2d
diff --git a/src/rp2_common/pico_float/float_conv_m33.S b/src/rp2_common/pico_float/float_common_m33.S
similarity index 85%
rename from src/rp2_common/pico_float/float_conv_m33.S
rename to src/rp2_common/pico_float/float_common_m33.S
index dd47a939e..491d758fb 100644
--- a/src/rp2_common/pico_float/float_conv_m33.S
+++ b/src/rp2_common/pico_float/float_common_m33.S
@@ -241,7 +241,52 @@ regular_func ufix642float
bxlo r14
b 3b
-float_wrapper_section conv_ftoi64
+float_section conv_ftoi64
+regular_func float2int64
+ lsls r1, r0, #1
+ // r0 = abs(zero) => r1 = 0x00000000
+ // r0 = abs(denornaml) => r1 = 0x00xxxxxx
+ // r0 = abs(1.0f) => r1 = 0x7f000000
+ // r0 = abs(inf/nan) => r1 = 0xffxxxxxx
+ bls float2int64_z // positive or zero or -zero are ok for int64_z
+ lsrs r1, #24
+ subs r1, #0x7f
+ bcc 1f // <1 means subtract 1
+ // mask off all but fractional bits
+ lsls r2, r0, r1
+ lsls r2, #9
+ beq float2int64_z // integer
+1:
+ push {lr}
+ bl float2int64_z
+ subs r0, #1
+ sbcs r1, r1, #0
+ pop {pc}
+
+float_section conv_ftof64
+regular_func float2fix64
+ lsls r2, r0, #1
+ // r0 = abs(zero) => r1 = 0x00000000
+ // r0 = abs(denornaml) => r1 = 0x00xxxxxx
+ // r0 = abs(1.0f) => r1 = 0x7f000000
+ // r0 = abs(inf/nan) => r1 = 0xffxxxxxx
+ bls float2fix64_z // positive or zero or -zero are ok for fix64_z
+ lsrs r2, #24
+ rsbs r3, r1, #0x7f
+ subs r2, r3
+ bcc 1f // <1 means subtract 1
+ // mask off all but fractional bits
+ lsls r2, r0, r2
+ lsls r2, #9
+ beq float2fix64_z // integer
+1:
+ push {lr}
+ bl float2fix64_z
+ subs r0, #1
+ sbcs r1, r1, #0
+ pop {pc}
+
+float_wrapper_section conv_ftoi64z
@ convert float to signed int64, rounding towards 0, clamping
wrapper_func __aeabi_f2lz
@@ -318,7 +363,7 @@ regular_func float2uint64_z
movs r1,#0 @ fall through
@ convert float in r0 to unsigned fixed point in r0:r1, clamping
regular_func float2ufix64
-//regular_func float2ufix64_z
+regular_func float2ufix64_z
subs r1,#0x96 @ remove exponent bias, compensate for mantissa length
asrs r2,r0,#23 @ sign and exponent
sub r3,r2,#1
diff --git a/src/rp2_common/pico_float/float_conv32_vfp.S b/src/rp2_common/pico_float/float_conv32_vfp.S
new file mode 100644
index 000000000..80fb5ca25
--- /dev/null
+++ b/src/rp2_common/pico_float/float_conv32_vfp.S
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if !PICO_RP2040
+#include "pico/asm_helper.S"
+
+pico_default_asm_setup
+
+.macro float_section name
+#if PICO_FLOAT_IN_RAM
+.section RAM_SECTION_NAME(\name), "ax"
+#else
+.section SECTION_NAME(\name), "ax"
+#endif
+.endm
+
+float_section int2float
+regular_func int2float
+ vmov s15, r0
+ vcvt.f32.s32 s15, s15
+ vmov r0, s15
+ bx lr
+
+float_section uint2float
+regular_func uint2float
+ vmov s15, r0
+ vcvt.f32.u32 s15, s15
+ vmov r0, s15
+ bx lr
+
+float_section float2int
+regular_func float2int
+ vmov s15, r0
+ vcvtm.s32.f32 s15, s15
+ vmov r0, s15
+ bx lr
+
+float_section float2int_z
+regular_func float2int_z
+ vmov s15, r0
+ vcvt.s32.f32 s15, s15
+ vmov r0, s15
+ bx lr
+
+float_section float2uint
+regular_func float2uint
+regular_func float2uint_z
+ vmov s15, r0
+ vcvt.u32.f32 s15, s15
+ vmov r0, s15
+ bx lr
+
+float_section float2fix_z
+regular_func float2fix_z
+ ubfx r2, r0, #23, #8
+ adds r2, r1
+ asrs r3, r2, #8
+ beq 1f
+ ite pl
+ movpl r2, #0xff
+ movmi r2, #0
+1:
+ bfi r0, r2, #23, #8
+ b float2int_z
+
+float_section float2fix
+regular_func float2fix
+ lsls r2, r0, #1
+ // r0 = abs(zero) => r1 = 0x00000000
+ // r0 = abs(denornaml) => r1 = 0x00xxxxxx
+ // r0 = abs(1.0f) => r1 = 0x7f000000
+ // r0 = abs(inf/nan) => r1 = 0xffxxxxxx
+ bls float2fix_z // input positive or zero or -zero are ok for fix_z
+ lsrs r2, #24
+ beq float2fix_z // input denormal will be flushed to zero
+ rsbs r3, r1, #0x7f
+ subs r2, r3
+ bcc 1f // iunput <1.0f means we need to subtract 1
+ // mask off all but fractional bits
+ lsls r2, r0, r2
+ lsls r2, #9
+ beq float2fix_z // input is integer
+1:
+ push {lr}
+ bl float2fix_z
+ subs r0, #1
+ sbcs r1, r1, #0
+ pop {pc}
+
+float_section float2ufix
+regular_func float2ufix
+regular_func float2ufix_z
+ ubfx r2, r0, #23, #8
+ adds r2, r1
+ asrs r3, r2, #8
+ beq 1f
+ ite pl
+ movpl r2, #0xff
+ movmi r2, #0
+1:
+ bfi r0, r2, #23, #8
+ b float2uint_z
+#endif
diff --git a/src/rp2_common/pico_float/include/pico/float.h b/src/rp2_common/pico_float/include/pico/float.h
index 6cafc83e4..ef95e1ecd 100644
--- a/src/rp2_common/pico_float/include/pico/float.h
+++ b/src/rp2_common/pico_float/include/pico/float.h
@@ -21,66 +21,294 @@ extern "C" {
*
* \brief Optimized single-precision floating point functions
*
-* (Replacement) optimized implementations are provided for the following compiler built-ins
-* and math library functions on Arm:
+* An application can take control of the floating point routines used in the application over and above what is provided by the compiler,
+* by depending on the pico_float library. A user might want to do this
*
-* - __aeabi_fadd, __aeabi_fdiv, __aeabi_fmul, __aeabi_frsub, __aeabi_fsub, __aeabi_cfcmpeq, __aeabi_cfrcmple, __aeabi_cfcmple, __aeabi_fcmpeq, __aeabi_fcmplt, __aeabi_fcmple, __aeabi_fcmpge, __aeabi_fcmpgt, __aeabi_fcmpun, __aeabi_i2f, __aeabi_l2f, __aeabi_ui2f, __aeabi_ul2f, __aeabi_f2iz, __aeabi_f2lz, __aeabi_f2uiz, __aeabi_f2ulz, __aeabi_f2d, sqrtf, cosf, sinf, tanf, atan2f, expf, logf
-* - ldexpf, copysignf, truncf, floorf, ceilf, roundf, asinf, acosf, atanf, sinhf, coshf, tanhf, asinhf, acoshf, atanhf, exp2f, log2f, exp10f, log10f, powf, hypotf, cbrtf, fmodf, dremf, remainderf, remquof, expm1f, log1pf, fmaf
-* - powintf, sincosf (GNU extensions)
+* 1. To use optimized software implementations provided by the RP2-series device's bootrom or the SDK
+* 2. To use optimized combined software/hardware implementations utilizing custom RP2-series hardware for acceleration
+* 3. To control the amount of C compiler/library code bloat
+* 4. To make sure no floating point is called at all
*
-* The following additional optimized functions are also provided:
+* The pico_float library comes in three main flavors:
*
-* - int2float, uint2float, int642float, uint642float, fix2float, ufix2float, fix642float, ufix642float
-* - float2fix, float2ufix, float2fix64, float2ufix64, float2int, float2uint, float2int64, float2uint64, float2int_z, float2int64_z, float2uint_z, float2uint64_z
-* - exp10f, sincosf, powintf
+* 1. `pico_float_none` - all floating point operations cause a \ref panic - no single-precision floating point code is included
+* 2. `pico_float_compiler` - no custom functions are provided; all single-precision floating point is handled by the C compiler/library
+* 3. `pico_float_pico` - the smallest and fastest available for the platform, along with additional functionality (e.g. fixed point conversions) which are detailed below
*
-* On RP2350 (Arm) the following additional functions are available; the _fast methods are faster but do not round correctly
+* The user can control which version they want (e.g. **pico_float_xxx** by either setting the CMake global variable
+* `PICO_DEFAULT_FLOAT_IMPL=xxx`, or by using the CMake function `pico_set_float_implementation( xxx)`. Note that in the absence
+* of either, pico_float_pico is used by default.
*
-* - float2fix64_z, fdiv_fast, fsqrt_fast,
+* \if rp2040_specific
+* On RP2040, `pico_float_pico` uses optimized hand coded implementations from the bootrom and the SDK for both
+* basic single-precision floating point operations and floating point math library functions. These implementations
+* are generally faster and smaller than those provided by the C compiler/library, though they don't support all the features of a fully compliant
+* floating point implementation; they are however usually fine for the majority of cases
+* \endif
*
-* On RP2350 RISC-V, only a small number of compiler runtime functions are overridden with faster implementations:
+* \if rp2350_specific
+* On Arm on RP2350, there are multiple options for `pico_float_pico`:
*
-* - __addsf3, __subsf3, __mulsf3
+* 1. `pico_float_pico_vfp` - this library leaves basic C single-precision floating point operations to the compiler
+* which can use inlined VFP (Arm FPU) code. Custom optimized versions of trigonometric and scientific functions are provided.
+* No DCP (RP2350 Double co-processor) instructions are used.
+* 2. `pico_float_pico_dcp` - this library prevents the compiler injecting inlined VFP code, and also implements
+* all single-precision floating point operations in optimized DCP or M33 code. This option is not quite as fast
+* as pico_float_pico_vfp, however it allows floating point operations without enabling the floating point co-processor
+* on the CPU; this can be beneficial in certain circumstances, e.g. where leaving stack in tasks or interrupts
+* for the floating point state is undesirable.
+*
+* Note: `pico_float_pico` is equivalent to `pico_float_pico_vfp` on RP2350, as this is the most sensible default
+* \endif
+*
+* On Arm, (replacement) optimized implementations are provided for the following compiler built-ins
+* and math library functions when using `_pico` variants of `pico_float`:
+*
+* - basic arithmetic: (except `pico_float_pico_vfp`)
+*
+* __aeabi_fadd, __aeabi_fdiv, __aeabi_fmul, __aeabi_frsub, __aeabi_fsub
+*
+* - comparison: (except `pico_float_pico_vfp`)
+*
+* __aeabi_cfcmpeq, __aeabi_cfrcmple, __aeabi_cfcmple, __aeabi_fcmpeq, __aeabi_fcmplt, __aeabi_fcmple, __aeabi_fcmpge, __aeabi_fcmpgt, __aeabi_fcmpun
+*
+* - (u)int32 <-> float: (except `pico_float_pico_vfp`)
+*
+* __aeabi_i2f, __aeabi_ui2f, __aeabi_f2iz, __aeabi_f2uiz
+*
+* - (u)int64 <-> float: (except `pico_float_pico_vfp`)
+*
+* __aeabi_l2f, __aeabi_ul2f, __aeabi_f2lz, __aeabi_f2ulz
+*
+* - float -> double: (except `pico_float_pico_vfp`)
+*
+* __aeabi_f2d
+*
+* - basic trigonometric:
+*
+* sqrtf, cosf, sinf, tanf, atan2f, expf, logf
+*
+* - trigonometric and scientific
+*
+* ldexpf, copysignf, truncf, floorf, ceilf, roundf, asinf, acosf, atanf, sinhf, coshf, tanhf, asinhf, acoshf, atanhf, exp2f, log2f, exp10f, log10f, powf, hypotf, cbrtf, fmodf, dremf, remainderf, remquof, expm1f, log1pf, fmaf
+*
+* - GNU exetnsions:
+*
+* powintf, sincosf
+*
+* On Arm, the following additional optimized functions are also provided (when using `_pico` variants of `pico_float`):
+*
+* - Conversions to/from integer types:
+*
+* - (u)int -> float (round to nearest):
+*
+* int2float, uint2float, int642float, uint642float
+*
+* note: on `pico_float_pico_vfp` the 32-bit functions are also provided as C macros since they map to inline VFP code
+*
+* - (u)float -> int (round towards zero):
+*
+* float2int_z, float2uint_z, float2int64_z, float2uint64_z
+*
+* note: on `pico_float_pico_vfp` the 32-bit functions are also provided as C macros since they map to inline VFP code
+*
+* - (u)float -> int (round towards -infinity):
+*
+* float2int, float2uint, float2int64, float2uint64
+*
+* - Conversions to/from fixed point integers:
+*
+* - (u)fix -> float (round to nearest):
+*
+* fix2float, ufix2float, fix642float, ufix642float
+*
+* - float -> (u)fix (round towards zero):
+*
+* float2fix_z, float2ufix_z, float2fix64_z, float2ufix64_z
+*
+* note: on `pico_float_pico_vfp` the 32-bit functions are also provided as C macros since they can map to inline VFP code
+* when the number of fractional bits is a compile time constant between 1 and 32
+*
+* - float -> (u)fix (round towards -infinity):
+*
+* float2fix, float2ufix, float2fix64, float2ufix64
+*
+* note: on `pico_float_pico_vfp` the 32-bit functions are also provided as C macros since they can map to inline VFP code
+* when the number of fractional bits is a compile time constant between 1 and 32
+*
+* - Even faster versions of divide and square-root functions that do not round correctly: (`pico_float_pico_dcp` only)
+*
+* fdiv_fast, sqrtf_fast
+*
+* \if rp2350_specific
+* On RISC-V, (replacement) optimized implementations are provided for the following compiler built-ins when using the `pico_float_pico`
+* library (note that there are no variants of this library like there are on Arm):
+*
+* - basic arithmetic:
+*
+* __addsf3, __subsf3, __mulsf3
+* \endif
*/
-
-// None of these functions are available on RISC-V:
#if !defined(__riscv) || PICO_COMBINED_DOCS
-float int2float(int32_t f);
-float uint2float(uint32_t f);
-float int642float(int64_t f);
-float uint642float(uint64_t f);
+#if PICO_COMBINED_DOCS || !LIB_PICO_FLOAT_COMPILER
+float int2float(int32_t i);
+float uint2float(uint32_t i);
+float int642float(int64_t i);
+float uint642float(uint64_t i);
float fix2float(int32_t m, int e);
float ufix2float(uint32_t m, int e);
float fix642float(int64_t m, int e);
float ufix642float(uint64_t m, int e);
-// These methods round towards -Infinity.
-int32_t float2fix(float f, int e);
-uint32_t float2ufix(float f, int e);
-int64_t float2fix64(float f, int e);
-uint64_t float2ufix64(float f, int e);
+// These methods round towards 0, which IS the C way
+int32_t float2int_z(float f);
+int64_t float2int64_z(float f);
+int32_t float2uint_z(float f);
+int64_t float2uint64_z(float f);
+int32_t float2fix_z(float f, int e);
+uint32_t float2ufix_z(float f, int e);
+int64_t float2fix64_z(float f, int e);
+uint64_t float2ufix64_z(float f, int e);
+
+// These methods round towards -Infinity - which IS NOT the C way for negative numbers;
+// as such the naming is not ideal, however is kept for backwards compatibility
int32_t float2int(float f);
uint32_t float2uint(float f);
int64_t float2int64(float f);
uint64_t float2uint64(float f);
+int32_t float2fix(float f, int e);
+uint32_t float2ufix(float f, int e);
+int64_t float2fix64(float f, int e);
+uint64_t float2ufix64(float f, int e);
-// These methods round towards 0.
-int32_t float2int_z(float f);
-int64_t float2int64_z(float f);
-int32_t float2uint_z(float f);
-int64_t float2uint64_z(float f);
+#if LIB_PICO_FLOAT_PICO_VFP
+// a bit of a hack to inline VFP fixed point conversion when exponent is constant and in range 1-32
+#define fix2float(m, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _fix2float_inline(m, e) : fix2 ## float(m, e), fix2 ## float(m, e))
+#define ufix2float(m, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _ufix2float_inline(m, e) : ufix2 ## float(m, e), ufix2 ## float(m, e))
+#define float2fix_z(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2fix_z_inline(f, e) : float2 ## fix_z(f, e), float2 ## fix_z(f, e))
+#define float2ufix_z(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2ufix_z_inline(f, e) : float2 ## ufix_z(f, e), float2 ## ufix_z(f, e))
+#define float2fix(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2fix_inline(f, e) : float2 ## fix(f, e), float2 ## fix(f, e))
+#define float2ufix(f, e) __builtin_choose_expr(__builtin_constant_p(e), (e) >= 1 && (e) <= 32 ? _float2ufix_inline(f, e) : float2 ## ufix(f, e), float2 ## ufix(f, e))
+
+#define _fix2float_inline(m, e) ({ \
+ int32_t _m = m; \
+ float f; \
+ pico_default_asm( \
+ "vmov %0, %1\n" \
+ "vcvt.f32.s32 %0, %0, %2\n" \
+ : "=t" (f) \
+ : "r" (_m), "i" (e) \
+ ); \
+ f; \
+})
+#define _ufix2float_inline(m, e) ({ \
+ uint32_t _m = m; \
+ float f; \
+ pico_default_asm( \
+ "vmov %0, %1\n" \
+ "vcvt.f32.u32 %0, %0, %2\n" \
+ : "=t" (f) \
+ : "r" (_m), "i" (e) \
+ ); \
+ f; \
+})
+#define _float2fix_z_inline(f, e) ({ \
+ int32_t _m; \
+ float _f = (f); \
+ pico_default_asm( \
+ "vcvt.s32.f32 %0, %0, %2\n" \
+ "vmov %1, %0\n" \
+ : "+t" (_f), "=r" (_m) \
+ : "i" (e) \
+ ); \
+ _m; \
+})
+#define _float2ufix_z_inline(f, e) ({ \
+ uint32_t _m; \
+ float _f = (f); \
+ pico_default_asm( \
+ "vcvt.u32.f32 %0, %0, %2\n" \
+ "vmov %1, %0\n" \
+ : "+t" (_f), "=r" (_m) \
+ : "i" (e) \
+ ); \
+ _m; \
+})
+#define _float2fix_z_inline(f, e) ({ \
+ int32_t _m; \
+ float _f = (f); \
+ pico_default_asm( \
+ "vcvt.s32.f32 %0, %0, %2\n" \
+ "vmov %1, %0\n" \
+ : "+t" (_f), "=r" (_m) \
+ : "i" (e) \
+ ); \
+ _m; \
+})
+#define _float2fix_inline(f, e) ({ \
+ union { float _f; int32_t _i; } _u; \
+ _u._f = (f); \
+ uint rc, tmp; \
+ pico_default_asm( \
+ "vcvt.s32.f32 %0, %0, %4\n" \
+ "vmov %2, %0\n" \
+ "lsls %1, #1\n" \
+ "bls 2f\n" /* positive or zero or -zero are ok with the result we have */ \
+ "lsrs %3, %1, #24\n" \
+ "subs %3, #0x7f - %c4\n" \
+ "bcc 1f\n" /* 0 < abs(f) < 1 ^ e, so need to round down */ \
+ /* mask off all but fractional bits */ \
+ "lsls %1, %3\n" \
+ "lsls %1, #8\n" \
+ "beq 2f\n" /* integers can round towards zero */ \
+ "1:\n" \
+ /* need to subtract 1 from the result to round towards -infinity... */ \
+ /* this will never cause an overflow, because to get here we must have had a non integer/infinite value which */ \
+ /* therefore cannot have been equal to INT64_MIN when rounded towards zero */ \
+ "subs %2, #1\n" \
+ "2:\n" \
+ : "+t" (_u._f), "+r" (_u._i), "=r" (rc), "=r" (tmp) \
+ : "i" (e) \
+ ); \
+ rc; \
+})
+#define _float2ufix_inline(f, e) _float2ufix_z_inline((f), (e))
+#endif
+
+#if LIB_PICO_FLOAT_PICO_VFP
+// may as well provide inline macros for VFP
+#define int2float(i) ((float)(int32_t)(i))
+#define uint2float(i) ((float)(uint32_t)(i))
+#define float2int_z(f) ((int32_t)(f))
+#define float2uint_z(f) ((uint32_t)(f))
+#endif
+
+#endif
float exp10f(float x);
void sincosf(float x, float *sinx, float *cosx);
float powintf(float x, int y);
#if !PICO_RP2040 || PICO_COMBINED_DOCS
-int64_t float2fix64_z(float f, int e);
float fdiv_fast(float n, float d);
-float fsqrt_fast(float f);
+float sqrtf_fast(float f);
+#endif
+
#endif
+#if defined(__riscv) || LIB_PICO_FLOAT_COMPILER
+// when using the compiler or RISC-V, we provide as many functions as we trivially can - these will be efficient
+// when using hard-float on Arm
+static inline float int2float(int32_t i) { return (float)i; }
+static inline float uint2float(uint32_t i) { return (float)i; }
+static inline float int642float(int64_t i) { return (float)i; }
+static inline float uint642float(uint64_t i) { return (float)i; }
+
+static inline int32_t float2int_z(float f) { return (int32_t)f; }
+static inline int64_t float2int64_z(float f) { return (int64_t)f; }
+static inline int32_t float2uint_z(float f) { return (uint32_t)f; }
+static inline int64_t float2uint64_z(float f) { return (uint64_t)f; }
#endif
#ifdef __cplusplus
diff --git a/src/rp2_common/pico_lwip/lwip_nosys.c b/src/rp2_common/pico_lwip/lwip_nosys.c
index 856affa56..9a949f6ea 100644
--- a/src/rp2_common/pico_lwip/lwip_nosys.c
+++ b/src/rp2_common/pico_lwip/lwip_nosys.c
@@ -71,4 +71,8 @@ void sys_arch_unprotect(__unused sys_prot_t pval) {
uint32_t sys_now(void) {
return to_ms_since_boot(get_absolute_time());
}
+
+__weak uint32_t sys_jiffies(void) {
+ return time_us_32();
+}
#endif
\ No newline at end of file
diff --git a/src/rp2_common/pico_lwip/tools/makefsdata.py b/src/rp2_common/pico_lwip/tools/makefsdata.py
index 88fca43a6..9ee0d88c1 100755
--- a/src/rp2_common/pico_lwip/tools/makefsdata.py
+++ b/src/rp2_common/pico_lwip/tools/makefsdata.py
@@ -23,9 +23,10 @@ def process_file(input_dir, file):
if content_type is None:
content_type = "application/octet-stream"
- # file name
- data = f"/{file.relative_to(input_dir)}\x00"
- comment = f"\"/{file.relative_to(input_dir)}\" ({len(data)} chars)"
+ # file name with posix directory separators
+ file_path_posix = file.relative_to(input_dir).as_posix()
+ data = f"/{file_path_posix}\x00"
+ comment = f"\"/{file_path_posix}\" ({len(data)} chars)"
while(len(data) % PAYLOAD_ALIGNMENT != 0):
data += "\x00"
results.append({'data': bytes(data, "utf-8"), 'comment': comment});
@@ -94,7 +95,7 @@ def process_file_list(fd, input):
fd.write(f"static const unsigned char {data_var}[] = {{\n")
for entry in results:
fd.write(f"\n /* {entry['comment']} */\n")
- byte_count = 0;
+ byte_count = 0
for b in entry['data']:
if byte_count % 16 == 0:
fd.write(" ")
diff --git a/src/rp2_common/pico_mbedtls/pico_mbedtls.c b/src/rp2_common/pico_mbedtls/pico_mbedtls.c
index 3279a42d1..853d97cdf 100644
--- a/src/rp2_common/pico_mbedtls/pico_mbedtls.c
+++ b/src/rp2_common/pico_mbedtls/pico_mbedtls.c
@@ -36,6 +36,7 @@ void mbedtls_sha256_init(__unused mbedtls_sha256_context *ctx) {
}
void mbedtls_sha256_free(__unused mbedtls_sha256_context *ctx) {
+ pico_sha256_cleanup(ctx);
}
int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) {
diff --git a/src/rp2_common/pico_multicore/include/pico/multicore.h b/src/rp2_common/pico_multicore/include/pico/multicore.h
index c452b9822..5eb49ddce 100644
--- a/src/rp2_common/pico_multicore/include/pico/multicore.h
+++ b/src/rp2_common/pico_multicore/include/pico/multicore.h
@@ -449,6 +449,13 @@ static inline uint multicore_doorbell_irq_num(uint doorbell_num) {
*/
void multicore_lockout_victim_init(void);
+/*! \brief Stop the current core being able to be a "victim" of lockout (i.e. forced to pause in a known state by the other core)
+ * \ingroup multicore_lockout
+ *
+ * This code unhooks the intercore FIFO IRQ, and the FIFO may be used for any other purpose after this.
+ */
+void multicore_lockout_victim_deinit(void);
+
/*! \brief Determine if \ref multicore_lockout_victim_init() has been called on the specified core.
* \ingroup multicore_lockout
*
diff --git a/src/rp2_common/pico_multicore/multicore.c b/src/rp2_common/pico_multicore/multicore.c
index cdbee6f49..1bf95e684 100644
--- a/src/rp2_common/pico_multicore/multicore.c
+++ b/src/rp2_common/pico_multicore/multicore.c
@@ -23,12 +23,11 @@
#endif
#endif
-// note that these are not reset by core reset, however for now, I think people resetting cores
-// and then relying on multicore_lockout for that core without re-initializing, is probably
-// something we can live with breaking.
-//
-// whilst we could clear this in core 1 reset path, that doesn't necessarily catch all,
-// and means pulling in this array even if multicore_lockout is not used.
+// Note that there is no automatic way for us to clear these flags when a particular core is reset, and yet
+// we DO ideally want to clear them, as the `multicore_lockout_victim_init()` checks the flag for the current core
+// and is a no-op if set. We DO have a new `multicore_lockout_victim_deinit()` method, which can be called in a pinch after
+// the reset before calling `multicore_lockout_victim_init()` again, so that is good. We will reset the flag
+// for core1 in `multicore_reset_core1()` though as a convenience since most people will use that to reset core 1.
static bool lockout_victim_initialized[NUM_CORES];
void multicore_fifo_push_blocking(uint32_t data) {
@@ -118,6 +117,9 @@ void multicore_reset_core1(void) {
bool enabled = pico_irq_is_enabled(irq_num);
irq_set_enabled(irq_num, false);
+ // Core 1 will be in un-initialized state
+ lockout_victim_initialized[1] = false;
+
// Bring core 1 back out of reset. It will drain its own mailbox FIFO, then push
// a 0 to our mailbox to tell us it has done this.
*power_off_clr = PSM_FRCE_OFF_PROC1_BITS;
@@ -243,6 +245,18 @@ void multicore_lockout_victim_init(void) {
lockout_victim_initialized[core_num] = true;
}
+void multicore_lockout_victim_deinit(void) {
+ uint core_num = get_core_num();
+ if (lockout_victim_initialized[core_num]) {
+ // On platforms other than RP2040, these are actually the same IRQ number
+ // (each core only sees its own IRQ, always at the same IRQ number).
+ uint fifo_irq_this_core = SIO_FIFO_IRQ_NUM(core_num);
+ irq_remove_handler(fifo_irq_this_core, multicore_lockout_handler);
+ irq_set_enabled(fifo_irq_this_core, false);
+ lockout_victim_initialized[core_num] = false;
+ }
+}
+
static bool multicore_lockout_handshake(uint32_t magic, absolute_time_t until) {
uint irq_num = SIO_FIFO_IRQ_NUM(get_core_num());
bool enabled = pico_irq_is_enabled(irq_num);
diff --git a/src/rp2_common/pico_runtime_init/BUILD.bazel b/src/rp2_common/pico_runtime_init/BUILD.bazel
index ec5c40205..8956c4e18 100644
--- a/src/rp2_common/pico_runtime_init/BUILD.bazel
+++ b/src/rp2_common/pico_runtime_init/BUILD.bazel
@@ -34,6 +34,8 @@ cc_library(
"//src/rp2_common/hardware_base",
"//src/rp2_common/hardware_clocks",
"//src/rp2_common/hardware_ticks",
+ "//src/rp2_common/hardware_timer",
+ "//src/rp2_common/hardware_vreg",
"//src/rp2_common/pico_bootrom",
"//src/rp2_common/pico_runtime",
],
diff --git a/src/rp2_common/pico_runtime_init/CMakeLists.txt b/src/rp2_common/pico_runtime_init/CMakeLists.txt
index 769e4aa11..81f6ab47f 100644
--- a/src/rp2_common/pico_runtime_init/CMakeLists.txt
+++ b/src/rp2_common/pico_runtime_init/CMakeLists.txt
@@ -13,7 +13,7 @@ pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE
)
if (TARGET hardware_clocks)
- pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE hardware_clocks)
+ pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE hardware_clocks hardware_timer hardware_vreg)
endif()
# pico/runtime_init.h includes pico/runtime.h
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 b6ca04523..b81b1311b 100644
--- a/src/rp2_common/pico_runtime_init/runtime_init_clocks.c
+++ b/src/rp2_common/pico_runtime_init/runtime_init_clocks.c
@@ -10,6 +10,8 @@
#include "hardware/clocks.h"
#include "hardware/pll.h"
#include "hardware/ticks.h"
+#include "hardware/timer.h"
+#include "hardware/vreg.h"
#include "hardware/xosc.h"
#if PICO_RP2040
#include "hardware/regs/rtc.h"
@@ -85,6 +87,15 @@ void __weak runtime_init_clocks(void) {
0,
XOSC_HZ);
+ // This must be done after we've configured CLK_REF to XOSC due to the need to time a delay
+#if SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST && defined(SYS_CLK_VREG_VOLTAGE_MIN)
+ if (vreg_get_voltage() < SYS_CLK_VREG_VOLTAGE_MIN) {
+ vreg_set_voltage(SYS_CLK_VREG_VOLTAGE_MIN);
+ // wait for voltage to settle; must use CPU cycles as TIMER is not yet clocked correctly
+ busy_wait_at_least_cycles((uint32_t)((SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US * (uint64_t)XOSC_HZ) / 1000000));
+ }
+#endif
+
/// \tag::configure_clk_sys[]
// CLK SYS = PLL SYS (usually) 125MHz / 1 = 125MHz
clock_configure_undivided(clk_sys,
diff --git a/src/rp2_common/pico_sha256/include/pico/sha256.h b/src/rp2_common/pico_sha256/include/pico/sha256.h
index 80aa5af37..ab0c81ad7 100644
--- a/src/rp2_common/pico_sha256/include/pico/sha256.h
+++ b/src/rp2_common/pico_sha256/include/pico/sha256.h
@@ -58,6 +58,16 @@ typedef struct pico_sha256_state {
size_t total_data_size;
} pico_sha256_state_t;
+/*! \brief Release the internal lock on the SHA-256 hardware
+ * \ingroup pico_sha256
+ *
+ * Release the internal lock on the SHA-256 hardware.
+ * Does nothing if the internal lock was not claimed.
+ *
+ * @param state A pointer to a pico_sha256_state_t instance
+ */
+void pico_sha256_cleanup(pico_sha256_state_t *state);
+
/*! \brief Start a SHA-256 calculation returning immediately with an error if the SHA-256 hardware is not available
* \ingroup pico_sha256
*
diff --git a/src/rp2_common/pico_sha256/sha256.c b/src/rp2_common/pico_sha256/sha256.c
index e0cc73974..91009c804 100644
--- a/src/rp2_common/pico_sha256/sha256.c
+++ b/src/rp2_common/pico_sha256/sha256.c
@@ -30,6 +30,12 @@ void __weak pico_sha256_unlock(pico_sha256_state_t *state) {
state->locked = false;
}
+void pico_sha256_cleanup(pico_sha256_state_t *state) {
+ if (state->locked) {
+ pico_sha256_unlock(state);
+ }
+}
+
int pico_sha256_try_start(pico_sha256_state_t *state, enum sha256_endianness endianness, bool use_dma) {
memset(state, 0, sizeof(*state));
if (!pico_sha256_lock(state)) return PICO_ERROR_RESOURCE_IN_USE;
diff --git a/src/rp2_common/pico_standard_binary_info/doc.h b/src/rp2_common/pico_standard_binary_info/doc.h
index e24741ec1..3245681f6 100644
--- a/src/rp2_common/pico_standard_binary_info/doc.h
+++ b/src/rp2_common/pico_standard_binary_info/doc.h
@@ -9,11 +9,11 @@
* * The program name if defined (unless `PICO_NO_BINARY_SIZE=1`). The value is `PICO_PROGRAM_NAME` or `PICO_TARGET_NAME` if the former isn't defined
* * The value of PICO_BOARD (unless `PICO_NO_BI_PICO_BOARD=1`)
* * The SDK version (unless `PICO_NO_BI_SDK_VERSION=1`)
- * * The program version string if defined (unless `PICO_NO_BI_PROGRAM_VERSION_STRING=1`). The value is `PICO_PROGRAM_VERSION_STRING``
+ * * The program version string if defined (unless `PICO_NO_BI_PROGRAM_VERSION_STRING=1`). The value is `PICO_PROGRAM_VERSION_STRING`
* * The program description if defined (unless `PICO_NO_BI_PROGRAM_DESCRIPTION=1`). The value is `PICO_PROGRAM_DESCRIPTION`
* * The program url if defined (unless `PICO_NO_BI_PROGRAM_URL=1`). The value is `PICO_PROGRAM_URL`
* * The boot stage 2 used if any (unless `PICO_NO_BI_BOOT_STAGE2_NAME=1`). The value is `PICO_BOOT_STAGE2_NAME`
- * * The program build date (unless `PICO_NO_BI_PROGRAM_BUILD_DATE=1). The value defaults to the C preprocessor value `__DATE__`, but can be overridden with `PICO_PROGRAM_BUILD_DATE`. Note you should do a clean build if you want to be sure this value is up to date.
+ * * The program build date (unless `PICO_NO_BI_PROGRAM_BUILD_DATE=1`). The value defaults to the C preprocessor value `__DATE__`, but can be overridden with `PICO_PROGRAM_BUILD_DATE`. Note you should do a clean build if you want to be sure this value is up to date.
* * The program build type (unless `PICO_NO_BI_BUILD_TYPE=1`). The value is `PICO_CMAKE_BUILD_TYPE` which comes from the CMake build - e.g. Release, Debug, RelMinSize
* * The binary size (unless `PICO_NO_BI_BINARY_SIZE=1`)
*/
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 b572998d8..b1cb0354c 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
@@ -74,8 +74,8 @@
// PICO_CONFIG: PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED, Optionally define a pin to use as bootloader activity LED when BOOTSEL mode is entered via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE), type=int, min=0, max=47 on RP2350B, 29 otherwise, group=pico_stdio_usb
// PICO_CONFIG: PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW, Whether pin to use as bootloader activity LED when BOOTSEL mode is entered via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE) is active low, type=bool, default=0, group=pico_stdio_usb
-#ifndef PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED_ACTIVE_LOW
-#define PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED_ACTIVE_LOW 0
+#ifndef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW
+#define PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW 0
#endif
// PICO_CONFIG: PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED, Whether the pin specified by PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED is fixed or can be modified by picotool over the VENDOR USB interface, type=bool, default=0, group=pico_stdio_usb
diff --git a/src/rp2_common/pico_stdio_usb/include/tusb_config.h b/src/rp2_common/pico_stdio_usb/include/tusb_config.h
index 13e0c5eb5..0b9e4306b 100644
--- a/src/rp2_common/pico_stdio_usb/include/tusb_config.h
+++ b/src/rp2_common/pico_stdio_usb/include/tusb_config.h
@@ -33,8 +33,19 @@
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE)
#define CFG_TUD_CDC (1)
-#define CFG_TUD_CDC_RX_BUFSIZE (256)
-#define CFG_TUD_CDC_TX_BUFSIZE (256)
+
+// CDC FIFO size of TX and RX
+#ifndef CFG_TUD_CDC_RX_BUFSIZE
+#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+#endif
+#ifndef CFG_TUD_CDC_TX_BUFSIZE
+#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+#endif
+
+// CDC Endpoint transfer buffer size, more is faster
+#ifndef CFG_TUD_CDC_EP_BUFSIZE
+#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+#endif
// We use a vendor specific interface but with our own driver
// Vendor driver only used for Microsoft OS 2.0 descriptor
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 59308b4b9..639e91498 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
@@ -48,15 +48,16 @@ static inline void ta_set_timeout(alarm_pool_timer_t *timer, uint alarm_num, int
// 2. If we just passed the target time, then time_til_target will be high, meaning we will
// likely not do the update, but this is OK since the caller who has the full 64 bits
// must check if the target time has passed when we return anyway to avoid races.
- if (time_til_target < time_til_alarm) {
+ // 3. We should never leave here without an alarm being armed
+ if (time_til_target < time_til_alarm || (timer_hw_from_timer(timer)->armed & (1 << alarm_num)) == 0) {
timer_hw_from_timer(timer)->alarm[alarm_num] = (uint32_t) target;
}
}
static inline bool ta_wakes_up_on_or_before(alarm_pool_timer_t *timer, uint alarm_num, int64_t target) {
- uint32_t current = timer_time_us_32(timer_hw_from_timer(timer));
- uint32_t time_til_target = (uint32_t) target - current;
- uint32_t time_til_alarm = timer_hw_from_timer(timer)->alarm[alarm_num] - current;
+ int64_t current = (int64_t)timer_time_us_64(timer_hw_from_timer(timer));
+ int64_t time_til_target = target - current;
+ uint32_t time_til_alarm = timer_hw_from_timer(timer)->alarm[alarm_num] - (uint32_t)current;
return time_til_alarm <= time_til_target;
}
@@ -75,6 +76,7 @@ static inline void ta_enable_irq_handler(alarm_pool_timer_t *timer, uint alarm_n
static inline void ta_disable_irq_handler(alarm_pool_timer_t *timer, uint alarm_num, irq_handler_t irq_handler) {
uint irq_num = timer_hardware_alarm_get_irq_num(timer, alarm_num);
+ timer_hw_from_timer(timer)->armed = 1u << alarm_num; // disarm the timer
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);
diff --git a/test/cmsis_test/cmsis_test.c b/test/cmsis_test/cmsis_test.c
index 6e9fdf62c..7c8f9baa4 100644
--- a/test/cmsis_test/cmsis_test.c
+++ b/test/cmsis_test/cmsis_test.c
@@ -35,5 +35,7 @@ int main(void) {
irq_set_enabled(DMA_IRQ_0_IRQn, true);
irq_set_pending(DMA_IRQ_0_IRQn);
puts(irq_handler_called ? "SUCCESS" : "FAILURE");
- return !(pendsv_called && irq_handler_called);
+ bool ok = pendsv_called && irq_handler_called;
+ puts(ok ? "PASSED" : "FAILED");
+ return !ok;
}
diff --git a/test/pico_divider_test/pico_divider_nesting_test.c b/test/pico_divider_test/pico_divider_nesting_test.c
index dfcdafc42..4e1915df8 100644
--- a/test/pico_divider_test/pico_divider_nesting_test.c
+++ b/test/pico_divider_test/pico_divider_nesting_test.c
@@ -47,7 +47,15 @@ bool timer_callback(repeating_timer_t *t) {
// if (fabs(fz - (fa * 11.0f + fb)) > 1e-9f) {
// FAILED();
// }
- if (fabsf(fz - fa * 11.0f) > 1e-3f) {
+ union {
+ float f;
+ uint32_t i;
+ } fi, fi2;
+ fi.f = fabsf(fz - fa * 11.0f);
+ // make a float which is close to 1ulp
+ fi2.i = fi.i & 0x7f800000u;
+ fi2.i++;
+ if (fi.f > fi2.f) {
FAILED();
}
double dz = z;
@@ -258,4 +266,3 @@ int main() {
printf("PASSED\n");
return 0;
}
-
diff --git a/test/pico_float_test/BUILD.bazel b/test/pico_float_test/BUILD.bazel
index 1efdf724d..364053300 100644
--- a/test/pico_float_test/BUILD.bazel
+++ b/test/pico_float_test/BUILD.bazel
@@ -85,3 +85,12 @@ filegroup(
name = "m33",
srcs = ["m33.c"],
)
+
+# TODO: Add these tests to the Bazel build.
+filegroup(
+ name = "unsupported_tests",
+ srcs = [
+ "custom_double_funcs_test.c",
+ "custom_float_funcs_test.c",
+ ],
+)
\ No newline at end of file
diff --git a/test/pico_float_test/CMakeLists.txt b/test/pico_float_test/CMakeLists.txt
index 971c2a6d7..93845bb36 100644
--- a/test/pico_float_test/CMakeLists.txt
+++ b/test/pico_float_test/CMakeLists.txt
@@ -79,4 +79,31 @@ else ()
target_link_libraries(m33 pico_double pico_stdlib)
pico_add_extra_outputs(m33)
endif()
+
+endif()
+
+set(FLOAT_TYPES compiler)
+set(DOUBLE_TYPES compiler)
+list(APPEND FLOAT_TYPES pico)
+list(APPEND DOUBLE_TYPES pico)
+if (PICO_RP2350)
+ if (NOT PICO_RISCV)
+ list(APPEND FLOAT_TYPES pico_vfp pico_dcp)
+ endif()
endif()
+
+foreach (FLOAT_TYPE IN LISTS FLOAT_TYPES)
+ add_executable(custom_float_funcs_test_${FLOAT_TYPE} custom_float_funcs_test.c)
+ pico_set_float_implementation(custom_float_funcs_test_${FLOAT_TYPE} ${FLOAT_TYPE})
+ target_link_libraries(custom_float_funcs_test_${FLOAT_TYPE} PRIVATE pico_stdlib)
+ pico_add_extra_outputs(custom_float_funcs_test_${FLOAT_TYPE})
+ pico_set_printf_implementation(custom_float_funcs_test_${FLOAT_TYPE} compiler)
+endforeach ()
+
+foreach (DOUBLE_TYPE IN LISTS DOUBLE_TYPES)
+ add_executable(custom_double_funcs_test_${DOUBLE_TYPE} custom_double_funcs_test.c)
+ pico_set_double_implementation(custom_double_funcs_test_${DOUBLE_TYPE} ${DOUBLE_TYPE})
+ target_link_libraries(custom_double_funcs_test_${DOUBLE_TYPE} PRIVATE pico_stdlib)
+ pico_add_extra_outputs(custom_double_funcs_test_${DOUBLE_TYPE})
+ pico_set_printf_implementation(custom_double_funcs_test_${DOUBLE_TYPE} compiler)
+endforeach ()
\ No newline at end of file
diff --git a/test/pico_float_test/custom_double_funcs_test.c b/test/pico_float_test/custom_double_funcs_test.c
new file mode 100644
index 000000000..85624d4cb
--- /dev/null
+++ b/test/pico_float_test/custom_double_funcs_test.c
@@ -0,0 +1,515 @@
+#include
+#include "pico/stdlib.h"
+#include "pico/double.h"
+#include "math.h"
+
+#if 0
+#define printf(...) ((void)0)
+#endif
+#if 0
+#define stop() return -1
+#else
+#define stop() rc=1
+#endif
+#define test_assert(x) ({ if (!(x)) { printf("Assertion failed: ");puts(#x);printf(" at " __FILE__ ":%d\n", __LINE__); stop(); } })
+#define test_checkd(x, expected, msg) ({ if ((x) != (expected)) { printf(" %s: %f != %f\n", msg, x, expected); stop(); } })
+#define test_checki(x, expected, msg) ({ if ((x) != (expected)) { printf(" %s: %d != %d\n", msg, x, expected); stop(); } })
+#define test_checku(x, expected, msg) ({ if ((uint32_t)(x) != (uint32_t)(expected)) { printf(" %s: %u != %u\n", msg, x, expected); stop(); } })
+#define test_checki64(x, expected, msg) ({ if ((x) != (expected)) { printf(" %s: %lld != %lld\n", msg, (int64_t)(x), (int64_t)(expected)); stop(); } })
+#define test_checku64(x, expected, msg) ({ if ((uint64_t)(x) != (uint64_t)(expected)) { printf(" %s: %llu != %llu\n", msg, (uint64_t)(x), (uint64_t)(expected)); stop(); } })
+
+#if !(LIB_PICO_DOUBLE_COMPILER || defined(__riscv))
+static inline double fix2double_8(int32_t m) { return fix2double(m, 8); }
+static inline double fix2double_12(int32_t m) { return fix2double(m, 12); }
+static inline double fix2double_16(int32_t m) { return fix2double(m, 16); }
+static inline double fix2double_24(int32_t m) { return fix2double(m, 24); }
+static inline double fix2double_28(int32_t m) { return fix2double(m, 28); }
+static inline double fix2double_32(int32_t m) { return fix2double(m, 32); }
+
+static inline double ufix2double_12(int32_t m) { return ufix2double(m, 12); }
+
+static inline double double2fix_12(int32_t m) { return double2fix(m, 12); }
+
+static inline double double2ufix_12(int32_t m) { return double2ufix(m, 12); }
+#endif
+
+#if 1 && (LIB_PICO_DOUBLE_COMPILER || defined(__riscv))
+#define double2int_z(f) ({ double _d = f; pico_default_asm_volatile("" : "+r" (_d)); double2 ## int_z(_d); })
+#define double2uint_z(f) ({ double _d = f; pico_default_asm_volatile("" : "+r" (_d)); double2 ## uint_z(_d); })
+#define double2int64_z(f) ({ double _d = f; pico_default_asm_volatile("" : "+r" (_d)); double2 ## int64_z(_d); })
+#define double2uint64_z(f) ({ double _d = f; pico_default_asm_volatile("" : "+r" (_d)); double2 ## uint64_z(_d); })
+#define int2double(i) ({ int32_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); int2 ## double(_i); })
+#define uint2double(i) ({ uint32_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); uint2 ## double(_i); })
+#define int642double(i) ({ int64_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); int642 ## double(_i); })
+#define uint642double(i) ({ uint64_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); uint642 ## double(_i); })
+#endif
+
+int test() {
+ int rc = 0;
+#if LIB_PICO_DOUBLE_PICO
+ printf(">>> Using PICO\n");
+#endif
+ printf("int2double\n");
+ test_checkd(int2double(0), 0.0, "int2double1");
+ test_checkd(int2double(-1), -1.0, "int2double2");
+ test_checkd(int2double(1), 1.0, "int2double3");
+ test_checkd(int2double(INT32_MAX), 2147483647.0, "int2double4");
+ test_checkd(int2double(INT32_MIN), -2147483648.0, "int2double5");
+ // these have rounding behavior on float but not double
+ test_checkd(int2double(2147483391), 2147483391.0, "int2double6");
+ test_checkd(int2double(2147483391), 2147483391.0, "int2double7");
+ test_checkd(int2double(2147483457), 2147483457.0, "int2double8");
+ test_checkd(int2double(2147483483), 2147483483.0, "int2double9");
+ test_checkd(int2double(2147483584), 2147483584.0, "int2double10");
+
+ printf("uint2double\n");
+ test_checkd(uint2double(0), 0.0, "uint2double1");
+ test_checkd(uint2double(1), 1.0, "uint2double2");
+ test_checkd(uint2double(INT32_MAX), 2147483647.0, "uint2double3");
+ // todo test correct rounding around maximum precision
+ test_checkd(uint2double(UINT32_MAX), 4294967295.0, "uint2double4");
+
+ printf("int642double\n");
+ test_checkd(int642double(0), 0.0, "int642double1");
+ test_checkd(int642double(-1), -1.0, "int642double2");
+ test_checkd(int642double(1), 1.0, "int642double3");
+ test_checkd(int642double(INT32_MAX-1), 2147483646.0, "int642double4");
+ test_checkd(int642double(INT32_MAX), 2147483647.0, "int642double5");
+ test_checkd(int642double(INT32_MAX+1ll), 2147483648.0, "int642double6");
+ test_checkd(int642double(INT32_MIN-1ll), -2147483649.0, "int642double7");
+ test_checkd(int642double(INT32_MIN), -2147483648.0, "int642double8");
+ test_checkd(int642double(INT32_MIN+1ll), -2147483647.0, "int642double9");
+ // todo test correct rounding around maximum precision
+ test_checkd(int642double(INT64_MAX), 9223372036854775807.0, "int642double10");
+ test_checkd(int642double(INT64_MIN), -9223372036854775808.0, "int642doubl11e");
+
+ printf("uint642double\n");
+ test_checkd(uint642double(0), 0.0, "uint642double1");
+ test_checkd(uint642double(1), 1.0, "uint642double2");
+ test_checkd(uint642double(INT32_MAX-1), 2147483646.0, "uint642double3");
+ test_checkd(uint642double(INT32_MAX), 2147483647.0, "uint642double4");
+ test_checkd(uint642double(INT32_MAX+1ll), 2147483648.0, "uint642double5");
+ test_checkd(uint642double(INT64_MAX), 9223372036854775807.0, "uint642double6");
+ // todo test correct rounding around maximum precision
+ test_checkd(uint642double(UINT64_MAX), 18446744073709551615.0, "uint642double7");
+
+ union {
+ uint64_t u;
+ double d;
+ } u64d;
+
+#if !(LIB_PICO_DOUBLE_COMPILER || defined(__riscv))
+ printf("fix2double\n");
+ // todo test correct rounding around maximum precision
+ test_checkd(fix2double(-3, 1), -1.5, "fix2double1");
+ test_checkd(fix2double(-3, 1), -1.5, "fix2double2");
+ test_checkd(fix2double(-3, -4), -48.0, "fix2double3");
+
+ printf("ufix2double\n");
+ // todo test correct rounding around maximum precision
+ test_checkd(ufix2double(0xa0000000, 30), 2.5, "ufix2double1");
+ test_checkd(ufix2double(3, -4), 48.0, "ufix2double2");
+
+ printf("fix64double\n");
+ // todo test correct rounding around maximum precision
+ test_checkd(fix642double(-0xa000000000ll, 38), -2.5, "fix642double1");
+ test_checkd(fix642double(-3, -34), -51539607552.0, "fix642double2");
+
+ printf("ufix642double\n");
+ // todo test correct rounding around maximum precision
+ test_checkd(ufix642double(0xa000000000ll, 38), 2.5, "ufix642double1");
+ test_checkd(ufix642double(3, -34), 51539607552.0, "fix64double2");
+
+ test_checkd(fix2double_8(128), 0.5, "fix2double_8_1");
+ test_checkd(fix2double_8(-128), -0.5, "fix2double_8_2");
+ test_checkd(fix2double_16(8192), 0.125, "fix2double_8_3");
+ test_checkd(fix2double_16(-8192), -0.125, "fix2double_8_4");
+ test_checkd(fix2double_24(3<<23), 1.5, "fix2double_8_5");
+ test_checkd(fix2double_24(-(3<<23)), -1.5, "fix2double_8_6");
+
+ printf("double2fix\n");
+ test_checki(double2fix(-0.5, 8), -0x80, "double2fix0");
+ test_checki(double2fix(3.5, 8), 0x380, "double2fix1");
+ test_checki(double2fix(-3.5, 8), -0x380, "double2fix2");
+ test_checki(double2fix(32768.0, 16), INT32_MAX, "double2fix3");
+ test_checki(double2fix(65536.0, 16), INT32_MAX, "double2fix4");
+ test_checki(double2fix(-65536.0, 16), INT32_MIN, "double2fix4b");
+ test_checki(double2fix(INFINITY, 16), INT32_MAX, "double2fix5");
+ test_checki(double2fix(-INFINITY, 16), INT32_MIN, "double2fix5b");
+ test_checki(double2fix(INFINITY, -16), INT32_MAX, "double2fix5c");
+ test_checki(double2fix(-INFINITY, -16), INT32_MIN, "double2fix5d");
+ test_checki(double2fix(3.24999, 2), 12, "double2fix6");
+ test_checki(double2fix(3.25, 2), 13, "double2fix7");
+ test_checki(double2fix(-3.24999, 2), -13, "double2fix8");
+ test_checki(double2fix(-3.25, 2), -13, "double2fix9");
+ test_checki(double2fix(-0.75, 1), -2, "double2fix10");
+ test_checki(double2fix(-3.0, -1), -2, "double2fix11"); // not very useful
+ test_checki(double2fix(0.0, 16), 0, "double2fix12");
+ test_checki(double2fix(-0.0, 16), 0, "double2fix13");
+ test_checki(double2fix(0.0, -16), 0, "double2fix14");
+ test_checki(double2fix(-0.0, -16), 0, "double2fix15");
+
+ printf("double2ufix\n");
+ test_checku(double2ufix(3.5, 8), 0x380, "double2ufix1");
+ test_checku(double2ufix(-3.5, 8), 0, "double2ufix2");
+ test_checku(double2ufix(32768.0, 16), 32768 << 16, "double2ufix3");
+ test_checku(double2ufix(65536.0, 16), UINT32_MAX, "double2ufix4");
+ test_checku(double2ufix(INFINITY, 16), UINT32_MAX, "double2ufix5");
+ test_checku(double2ufix(-INFINITY, 16), 0, "double2ufix5b");
+ test_checku(double2ufix(INFINITY, -16), UINT32_MAX, "double2ufix5c");
+ test_checku(double2ufix(-INFINITY, -16), 0, "double2ufix5d");
+ test_checku(double2ufix(3.24999, 2), 12, "double2ufix6");
+ 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, "double2ufix14");
+ test_checki(double2ufix(-0.0, -16), 0, "double2fix15");
+
+ 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(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");
+ test_checki64(double2fix64(INFINITY, -16), INT64_MAX, "double2fix645c");
+ test_checki64(double2fix64(-INFINITY, -16), INT64_MIN, "double2fix645d");
+ test_checki64(double2fix64(3.24999, 2), 12, "double2fix646");
+ test_checki64(double2fix64(3.25, 2), 13, "double2fix647");
+ test_checki64(double2fix64(-3.24999, 2), -13, "double2fix648");
+ test_checki64(double2fix64(-3.25, 2), -13, "double2fix649");
+ test_checki64(double2fix64(-3.0, -1), -2, "double2fix6410"); // not very useful
+ test_checki64(double2fix64(2147483648.0 * 2147483648.0, 16), INT64_MAX, "double2ufix6411");
+ test_checki64(double2fix64(0.0, 16), 0, "double2fix6412");
+ test_checki64(double2fix64(-0.0, 16), 0, "double2fix6413");
+ test_checki64(double2fix64(0.0, -16), 0, "double2fix6412b");
+ test_checki64(double2fix64(-0.0, -16), 0, "double2fix6413b");
+ test_checki64(double2fix64(-3.25, 40), -13ll * (1ll << 38), "double2fix6414");
+ u64d.u = 0xc00a000000000001;
+ test_checki64(double2fix64(u64d.d, 40), -13ll * (1ll << 38) - 1ll, "double2fix6414b");
+
+ u64d.u = 0xc00a000080000001;
+ test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18) - 2ll, "double2fix6415c");
+ u64d.u = 0xc00a000080000000;
+ test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18) - 1ll, "double2fix6415d");
+ u64d.u = 0xc00a000000000001;
+ test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18) - 1ll, "double2fix6415e");
+ u64d.u = 0xc00a000000000000;
+ test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18), "double2fix6415g");
+
+ u64d.u = 0xc00a000080000001;
+ test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17) - 1ll, "double2fix6415h");
+ u64d.u = 0xc00a000080000000;
+ test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17) - 1ll, "double2fix6415i");
+ u64d.u = 0xc00a000000000001;
+ test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17) - 1ll, "double2fix6415j");
+ u64d.u = 0xc00a000000000000;
+ test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17), "double2fix6415k");
+
+ printf("double2ufix64\n");
+ test_checku64(double2ufix64(3.5, 8), 0x380, "double2ufix641");
+ test_checku64(double2ufix64(-3.5, 8), 0, "double2ufix642");
+ test_checku64(double2ufix64(32768.0, 16), 32768ull << 16, "double2ufix643");
+ test_checku64(double2ufix64(65536.0, 16), 65536ull << 16, "double2ufix644");
+ test_checku64(double2ufix64(2147483648.0, 16), 2147483648ull << 16, "double2ufix644b");
+ test_checku64(double2ufix64(INFINITY, 16), UINT64_MAX, "double2ufix645");
+ test_checku64(double2ufix64(-INFINITY, 16), 0, "double2ufix645b");
+ test_checku64(double2ufix64(INFINITY, -16), UINT64_MAX, "double2ufix645c");
+ test_checku64(double2ufix64(-INFINITY, -16), 0, "double2ufix645d");
+ test_checku64(double2ufix64(3.24999, 2), 12, "double2ufix646");
+ test_checku64(double2ufix64(3.25, 2), 13, "double2ufix647");
+ test_checku64(double2ufix64(3.0, -1), 1, "double2ufix648"); // not very useful
+ test_checki64(double2ufix64(0.0, 16), 0, "double2ufix649");
+ test_checki64(double2ufix64(-0.0, 16), 0, "double2ufix6410");
+
+ printf("double2fix_z\n");
+ test_checki(double2fix_z(3.5, 8), 0x380, "double2fix_z1");
+ test_checki(double2fix_z(-3.5, 8), -0x380, "double2fix_z2");
+ test_checki(double2fix_z(32768.0, 16), INT32_MAX, "double2fix_z3");
+ test_checki(double2fix_z(65536.0, 16), INT32_MAX, "double2fix_z4");
+ test_checki(double2fix_z(INFINITY, 16), INT32_MAX, "double2fix_z5");
+ test_checki(double2fix_z(-INFINITY, 16), INT32_MIN, "double2fix_z5b");
+ test_checki(double2fix_z(INFINITY, -50), INT32_MAX, "double2fix_z5c");
+ test_checki(double2fix_z(-INFINITY, -50), INT32_MIN, "double2fix_z5d");
+ test_checki(double2fix_z(3.24999, 2), 12, "double2fix_z6");
+ test_checki(double2fix_z(3.25, 2), 13, "double2fix_z7");
+ test_checki(double2fix_z(-3.24999, 2), -12, "double2fix_z8");
+ test_checki(double2fix_z(-3.25, 2), -13, "double2fix_z9");
+ test_checki(double2fix_z(-0.75, 1), -1, "double2fix_z10");
+ test_checki(double2fix_z(-3.0, -1), -1, "double2fix_z11"); // not very useful
+ test_checki(double2fix_z(0.0, 16), 0, "double2fix_z12");
+ test_checki(double2fix_z(-0.0, 16), 0, "double2fix_z13");
+ test_checki(double2fix_z(0.0, -16), 0, "double2fix_z12b");
+ test_checki(double2fix_z(-0.0, -16), 0, "double2fix_z13b");
+
+ printf("double2ufix_z\n");
+ test_checku(double2ufix_z(3.5, 8), 0x380, "double2ufix_z1");
+ test_checku(double2ufix_z(-3.5, 8), 0, "double2ufix_z2");
+ test_checku(double2ufix_z(32768.0, 16), 32768 << 16, "double2ufix_z3");
+ test_checku(double2ufix_z(65536.0, 16), UINT32_MAX, "double2ufix_z4");
+ test_checku(double2ufix_z(INFINITY, 16), UINT32_MAX, "double2ufix_z5");
+ test_checku(double2ufix_z(-INFINITY, 16), 0, "double2ufix_z5b");
+ test_checku(double2ufix_z(INFINITY, 16), UINT32_MAX, "double2ufix_z5c");
+ test_checku(double2ufix_z(-INFINITY, 16), 0, "double2ufix_z5d");
+ 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");
+
+ printf("double2fix64_z\n");
+ test_checki64(double2fix64_z(3.5, 8), 0x380, "double2fix64_z1");
+ test_checki64(double2fix64_z(-3.5, 8), -0x380, "double2fix64_z2");
+ test_checki64(double2fix64_z(32768.0, 16), 32768ll << 16, "double2fix64_z3");
+ 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(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");
+ test_checki64(double2fix64_z(-3.25, 2), -13, "double2fix64_z9");
+ test_checki64(double2fix64_z(-3.0, -1), -1, "double2fix64_z10"); // not very useful
+ test_checki64(double2fix64_z(0.0, 16), 0, "double2fix64_z11");
+ test_checki64(double2fix64_z(-0.0, 16), 0, "double2fix64_z12");
+ test_checki64(double2fix64_z(0.0, -16), 0, "double2fix64_z13");
+ test_checki64(double2fix64_z(-0.0, -16), 0, "double2fix64_z14");
+ test_checki64(double2fix64_z(-3.25, 40), -13ll * (1ll << 38), "double2fix64_z15");
+ u64d.u = 0xc00a000000000001;
+ test_checki64(double2fix64_z(u64d.d, 40), -13ll * (1ll << 38), "double2fix64_z15b");
+
+ u64d.u = 0xc00a000080000001;
+ test_checki64(double2fix64_z(u64d.d, 20), -13ll * (1ll << 18) - 1ll, "double2fix64_z15c");
+ u64d.u = 0xc00a000080000000;
+ test_checki64(double2fix64_z(u64d.d, 20), -13ll * (1ll << 18) - 1ll, "double2fix64_z15d");
+ u64d.u = 0xc00a000000000001;
+ test_checki64(double2fix64_z(u64d.d, 20), -13ll * (1ll << 18), "double2fix64_z15e");
+ u64d.u = 0xc00a000000000000;
+ test_checki64(double2fix64_z(u64d.d, 20), -13ll * (1ll << 18), "double2fix64_z15g");
+
+ u64d.u = 0xc00a000080000001;
+ test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15h");
+ u64d.u = 0xc00a000080000000;
+ test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15i");
+ u64d.u = 0xc00a000000000001;
+ test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15j");
+ u64d.u = 0xc00a000000000000;
+ test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15k");
+
+ printf("double2ufix64_z\n");
+ test_checku64(double2ufix64_z(3.5, 8), 0x380, "double2ufix64_z1");
+ 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_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");
+ test_checku64(double2ufix64_z(-INFINITY, 16), 0, "double2ufix64_z5d");
+ test_checku64(double2ufix64_z(3.24999, 2), 12, "double2ufix64_z6");
+ test_checku64(double2ufix64_z(3.25, 2), 13, "double2ufix64_z7");
+ test_checki64(double2ufix64_z(3.0, -1), 1, "double2fuix64_z8"); // not very useful
+ test_checki64(double2ufix64_z(0.0, 16), 0, "double2ufix64_z9");
+ test_checki64(double2ufix64_z(-0.0, 16), 0, "double2ufix64_z10");
+ test_checki64(double2ufix64_z(0.0, -16), 0, "double2ufix64_z11");
+ test_checki64(double2ufix64_z(-0.0, -16), 0, "double2ufix64_z12");
+
+ printf("double2int\n");
+ test_checki(double2int(0.0), 0, "double2int1");
+ test_checki(double2int(0.25), 0, "double2int1b");
+ test_checki(double2int(0.5), 0, "double2int2");
+ test_checki(double2int(0.75), 0, "double2int2b");
+ test_checki(double2int(1.0), 1, "double2int3");
+ test_checki(double2int(-10.0), -10, "double2int3a");
+ test_checki(double2int(-0.0), 0, "double2int3b");
+ test_checki(double2int(-0.25), -1, "double2int4");
+ test_checki(double2int(-0.5), -1, "double2int4b");
+ test_checki(double2int(-0.75), -1, "double2int5");
+ test_checki(double2int(-1.0), -1, "double2int5b");
+ // todo test correct rounding around maximum precision
+ test_checki(double2int(2147483646.0), INT32_MAX-1, "double2int6");
+ test_checki(double2int(2147483647.0), INT32_MAX, "double2int6b");
+ test_checki(double2int(21474836470.0), INT32_MAX, "double2int7");
+ test_checki(double2int(-2147483648.0), INT32_MIN, "double2int8");
+ test_checki(double2int(-21474836480.0), INT32_MIN, "double2int9");
+ test_checki(double2int(-2.5), -3, "double2int10");
+ test_checki(double2int(-2.4), -3, "double2int11");
+ u64d.u = 0xc000000000000000ull;
+ test_checki(double2int(u64d.d), -2, "double2int12");
+ u64d.u = 0xc008000000000000ull;
+ test_checki(double2int(u64d.d), -3, "double2int12b");
+ u64d.u = 0xc000000000000001ull;
+ test_checki(double2int(u64d.d), -3, "double2int12c");
+ u64d.u = 0xc000000080000000ull;
+ test_checki(double2int(u64d.d), -3, "double2int12d");
+ u64d.u = 0xc000000100000000ull;
+ test_checki(double2int(u64d.d), -3, "double2int12e");
+ u64d.u = 0xc000000100000001ull;
+ test_checki(double2int(u64d.d), -3, "double2int12f");
+ test_checki(double2int(-2147483647.0), INT32_MIN+1, "double2int13");
+ test_checki(double2int(-2147483647.1), INT32_MIN, "double2int14");
+ test_checki(double2int(-2147483647.9), INT32_MIN, "double2int15");
+ test_checki(double2int(-2147483648.0), INT32_MIN, "double2int16");
+ test_checki(double2int(-2147483648.1), INT32_MIN, "double2int17");
+ test_checki(double2int(-21474836480.1), INT32_MIN, "double2int18");
+
+ printf("double2uint\n");
+ test_checku(double2uint(0.0), 0, "double2uint1");
+ test_checku(double2uint(0.25), 0, "double2uint2");
+ test_checku(double2uint(0.5), 0, "double2uint3");
+ test_checku(double2uint(0.75), 0, "double2uint4");
+ test_checku(double2uint(1.0), 1, "double2uint5");
+ test_checku(double2uint(2147483647.0), INT32_MAX, "double2uint6");
+ test_checku(double2uint(2147483648.0), INT32_MAX+1u, "double2uint7");
+ test_checku(double2uint(4294967294.5), UINT32_MAX-1, "double2uint8");
+ test_checku(double2uint(4294967295.0), UINT32_MAX, "double2uint9");
+ test_checku(double2uint(42949672950.0), UINT32_MAX, "double2uint10");
+
+ printf("double2int64\n");
+ test_checki64(double2int64(0.0), 0, "double2int641");
+ test_checki64(double2int64(0.25), 0, "double2int641b");
+ test_checki64(double2int64(0.5), 0, "double2int642");
+ test_checki64(double2int64(0.75), 0, "double2int642b");
+ test_checki64(double2int64(1.0), 1, "double2int643");
+ test_checki64(double2int64(-10.0), -10, "double2int643a");
+ test_checki64(double2int64(-0.0), 0, "double2int643b");
+ test_checki64(double2int64(-0.25), -1, "double2int644");
+ test_checki64(double2int64(-0.5), -1, "double2int644b");
+ test_checki64(double2int64(-0.75), -1, "double2int645");
+ test_checki64(double2int64(-1.0), -1, "double2int645b");
+ // todo test correct rounding around maximum precision
+ test_checki64(double2int64(2147483647.0), INT32_MAX, "double2int646");
+ test_checki64(double2int64(21474836470.0), 21474836470ll, "double2int647");
+ test_checki64(double2int64(-2147483648.0), INT32_MIN, "double2int648");
+ test_checki64(double2int64(-21474836480.0), -21474836480ll, "double2int649");
+ test_checki64(double2int64(-2.5), -3, "double2int6410");
+ test_checki64(double2int64(-2.4), -3, "double2int6411");
+ u64d.u = 0xc000000000000000ull;
+ test_checki64(double2int64(u64d.d), -2, "double2int6412");
+ u64d.u = 0xc008000000000000ull;
+ test_checki64(double2int64(u64d.d), -3, "double2int6412b");
+ u64d.u = 0xc000000000000001ull;
+ test_checki64(double2int64(u64d.d), -3, "double2int6412c");
+ u64d.u = 0xc000000080000000ull;
+ test_checki64(double2int64(u64d.d), -3, "double2int6412d");
+ u64d.u = 0xc000000100000000ull;
+ test_checki64(double2int64(u64d.d), -3, "double2int6412e");
+ u64d.u = 0xc000000100000001ull;
+ test_checki64(double2int64(u64d.d), -3, "double2int6412f");
+
+ printf("double2uint64\n");
+ test_checku64(double2uint64(0.0), 0, "double2uint641");
+ test_checku64(double2uint64(0.25), 0, "double2uint642");
+ test_checku64(double2uint64(0.5), 0, "double2uint643");
+ test_checku64(double2uint64(0.75), 0, "double2uint644");
+ test_checku64(double2uint64(1.0), 1, "double2uint645");
+ test_checku64(double2uint64(2147483647.0), INT32_MAX, "double2uint646");
+ test_checku64(double2uint64(2147483648.0), INT32_MAX+1u, "double2uint647");
+ // todo test correct rounding around maximum precision
+ test_checku64(double2uint64(4294967294.5), 4294967294ull, "double2uint648");
+ test_checku64(double2uint64(4294967295.0), 4294967295ull, "double2uint649");
+ test_checku64(double2uint64(42949672950.0), 42949672950, "double2uint6410");
+#endif
+
+ // // These methods round towards 0.
+ printf("double2int_z\n");
+ test_checki(double2int_z(0.0), 0, "double2int_z1");
+ test_checki(double2int_z(0.25), 0, "double2int_z1b");
+ test_checki(double2int_z(0.5), 0, "double2int_z2");
+ test_checki(double2int_z(0.75), 0, "double2int_z2b");
+ test_checki(double2int_z(1.0), 1, "double2int_z3");
+ test_checki(double2int_z(-10.0), -10, "double2int_z3a");
+ test_checki(double2int_z(-0.0), 0, "double2int_z3b");
+ test_checki(double2int_z(-0.25), 0, "double2int_z4");
+ test_checki(double2int_z(-0.5), 0, "double2int_z4b");
+ test_checki(double2int_z(-0.75), 0, "double2int_z5");
+ test_checki(double2int_z(-1.0), -1, "double2int_z5b");
+ // todo test correct rounding around maximum precision
+ test_checki(double2int_z(2147483647.0), INT32_MAX, "double2int_z6");
+ test_checki(double2int_z(21474836470.0), INT32_MAX, "double2int_z7");
+ test_checki(double2int_z(-2147483648.0), INT32_MIN, "double2int_z8");
+ test_checki(double2int_z(-21474836480.0), INT32_MIN, "double2int_z9");
+ test_checki(double2int_z(-2.5), -2, "double2int_z10");
+ test_checki(double2int_z(-2.4), -2, "double2int_z11");
+ u64d.u = 0xc000000000000000ull;
+ test_checki(double2int_z(u64d.d), -2, "double2int_z12");
+ u64d.u = 0xc008000000000000ull;
+ test_checki(double2int_z(u64d.d), -3, "double2int_z12b");
+ u64d.u = 0xc000000000000001ull;
+ test_checki(double2int_z(u64d.d), -2, "double2int_z12c");
+ u64d.u = 0xc000000080000000ull;
+ test_checki(double2int_z(u64d.d), -2, "double2int_z12d");
+ u64d.u = 0xc000000100000000ull;
+ test_checki(double2int_z(u64d.d), -2, "double2int_z12e");
+ u64d.u = 0xc000000100000001ull;
+ test_checki(double2int_z(u64d.d), -2, "double2int_z12f");
+
+ printf("double2int64_z\n");
+ test_checki64(double2int64_z(0.0), 0, "double2int64_z1");
+ test_checki64(double2int64_z(0.25), 0, "double2int64_z1b");
+ test_checki64(double2int64_z(0.5), 0, "double2int64_z2");
+ test_checki64(double2int64_z(0.75), 0, "double2int64_z2b");
+ test_checki64(double2int64_z(1.0), 1, "double2int64_z3");
+ test_checki64(double2int64_z(-10.0), -10, "double2int64_z3a");
+ test_checki64(double2int64_z(-0.0), 0, "double2int64_z3b");
+ test_checki64(double2int64_z(-0.25), 0, "double2int64_z4");
+ test_checki64(double2int64_z(-0.5), 0, "double2int64_z4b");
+ test_checki64(double2int64_z(-0.75), 0, "double2int64_z5");
+ test_checki64(double2int64_z(-1.0), -1, "double2int64_z5b");
+ // todo test correct rounding around maximum precision
+ test_checki64(double2int64_z(2147483647.0), 2147483647ll, "double2int64_z6");
+ test_checki64(double2int64_z(21474836470.0), 21474836470ll, "double2int64_z7");
+ test_checki64(double2int64_z(-2147483648.0), INT32_MIN, "double2int64_z8");
+ test_checki64(double2int64_z(-21474836480.0), -21474836480ll, "double2int64_z9");
+ test_checki64(double2int64_z(-2.5), -2, "double2int64_z10");
+ test_checki64(double2int64_z(-2.4), -2, "double2int64_z11");
+
+ printf("double2uint_z\n");
+ test_checku(double2uint_z(0.0), 0, "double2uint_z1");
+ test_checku(double2uint_z(0.25), 0, "double2uint_z2");
+ test_checku(double2uint_z(0.5), 0, "double2uint_z3");
+ test_checku(double2uint_z(0.75), 0, "double2uint_z4");
+ test_checku(double2uint_z(1.0), 1, "double2uint_z5");
+ test_checku(double2uint_z(2147483647.0), INT32_MAX, "double2uint_z6");
+ test_checku(double2uint_z(2147483648.0), INT32_MAX+1u, "double2uint_z7");
+ // todo test correct rounding around maximum precision
+ test_checku(double2uint_z(4294967294.5), UINT32_MAX-1u, "double2uint_z8");
+ test_checku(double2uint_z(4294967295.0), UINT32_MAX, "double2uint_z9");
+ test_checku(double2uint_z(42949672950.0), UINT32_MAX, "double2uint_z10");
+
+ printf("double2uint64_z\n");
+ test_checku64(double2uint64_z(0.0), 0, "double2uint64_z1");
+ test_checku64(double2uint64_z(0.25), 0, "double2uint64_z2");
+ test_checku64(double2uint64_z(0.5), 0, "double2uint64_z3");
+ test_checku64(double2uint64_z(0.75), 0, "double2uint64_z4");
+ test_checku64(double2uint64_z(1.0), 1, "double2uint64_z5");
+ test_checku64(double2uint64_z(2147483647.0), INT32_MAX, "double2uint64_z6");
+ test_checku64(double2uint64_z(2147483648.0), INT32_MAX+1u, "double2uint64_z7");
+ // todo test correct rounding around maximum precision
+ test_checku64(double2uint64_z(4294967294.5), 4294967294ull, "double2uint64_z8");
+ test_checku64(double2uint64_z(4294967295.0), 4294967295ull, "double2uint64_z9");
+ test_checku64(double2uint64_z(4294967296.0), 4294967296ull, "double2uint64_z9b");
+ test_checku64(double2uint64_z(42949672950.0), 42949672950ull, "double2uint64_z10");
+
+ // double exp10(double x);
+ // void sincos(double x, double *sinx, double *cosx);
+ // double powint(double x, int y);
+ return rc;
+}
+
+int main() {
+ stdio_init_all();
+ int rc = test();
+ if (rc) {
+ printf("FAILED\n");
+ } else {
+ printf("PASSED\n");
+ }
+}
diff --git a/test/pico_float_test/custom_float_funcs_test.c b/test/pico_float_test/custom_float_funcs_test.c
new file mode 100644
index 000000000..d749f778a
--- /dev/null
+++ b/test/pico_float_test/custom_float_funcs_test.c
@@ -0,0 +1,402 @@
+#include
+#include "pico/stdlib.h"
+#include "pico/float.h"
+#include "math.h"
+
+#if 0
+#define printf(...) ((void)0)
+#endif
+#if 0
+#define stop() return -1
+#else
+#define stop() rc=1
+#endif
+#define test_assert(x) ({ if (!(x)) { printf("Assertion failed: ");puts(#x);printf(" at " __FILE__ ":%d\n", __LINE__); stop(); } })
+#define test_checkf(x, expected, msg) ({ if ((x) != (expected)) { printf(" %s: %f != %f\n", msg, x, expected); stop(); } })
+#define test_checki(x, expected, msg) ({ if ((x) != (expected)) { printf(" %s: %d != %d\n", msg, x, expected); stop(); } })
+#define test_checku(x, expected, msg) ({ if ((uint32_t)(x) != (uint32_t)(expected)) { printf(" %s: %u != %u\n", msg, x, expected); stop(); } })
+#define test_checki64(x, expected, msg) ({ if ((x) != (expected)) { printf(" %s: %lld != %lld\n", msg, (int64_t)(x), (int64_t)(expected)); stop(); } })
+#define test_checku64(x, expected, msg) ({ if ((uint64_t)(x) != (uint64_t)(expected)) { printf(" %s: %llu != %llu\n", msg, (uint64_t)(x), (uint64_t)(expected)); stop(); } })
+
+#if !(LIB_PICO_FLOAT_COMPILER || defined(__riscv))
+static inline float fix2float_8(int32_t m) { return fix2float(m, 8); }
+static inline float fix2float_12(int32_t m) { return fix2float(m, 12); }
+static inline float fix2float_16(int32_t m) { return fix2float(m, 16); }
+static inline float fix2float_24(int32_t m) { return fix2float(m, 24); }
+static inline float fix2float_28(int32_t m) { return fix2float(m, 28); }
+static inline float fix2float_32(int32_t m) { return fix2float(m, 32); }
+
+static inline float ufix2float_12(int32_t m) { return ufix2float(m, 12); }
+
+static inline float float2fix_12(int32_t m) { return float2fix(m, 12); }
+
+static inline float float2ufix_12(int32_t m) { return float2ufix(m, 12); }
+#endif
+
+#if 1 && (LIB_PICO_FLOAT_COMPILER || defined(__riscv))
+#if __SOFTFP__ || defined(__riscv)
+#define FREG "+r"
+#else
+#define FREG "+t"
+#endif
+// prevent the compiler from eliding the calculations
+#define float2int_z(f) ({ float _f = f; pico_default_asm_volatile("" : FREG (_f)); float2 ## int_z(_f); })
+#define float2uint_z(f) ({ float _f = f; pico_default_asm_volatile("" : FREG (_f)); float2 ## uint_z(_f); })
+#define float2int64_z(f) ({ float _f = f; pico_default_asm_volatile("" : FREG (_f)); float2 ## int64_z(_f); })
+#define float2uint64_z(f) ({ float _f = f; pico_default_asm_volatile("" : FREG (_f)); float2 ## uint64_z(_f); })
+#define int2float(i) ({ int32_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); int2 ## float(_i); })
+#define uint2float(i) ({ uint32_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); uint2 ## float(_i); })
+#define int642float(i) ({ int64_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); int642 ## float(_i); })
+#define uint642float(i) ({ uint64_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); uint642 ## float(_i); })
+#endif
+
+#if 1 && LIB_PICO_FLOAT_VFP
+// prevet the compiler from eliding the calculations
+#undef float2int_z
+#undef float2uint_z
+#undef int2float
+#undef uint2float
+#endif
+
+int test() {
+ int rc = 0;
+#if LIB_PICO_FLOAT_PICO_DCP
+ printf(">>> Using DCP\n");
+#endif
+#if LIB_PICO_FLOAT_PICO_VFP
+ printf(">>> Using VFP\n");
+#endif
+ printf("int2float\n");
+ test_checkf(int2float(0), 0.0f, "int2float1");
+ test_checkf(int2float(-1), -1.0f, "int2float2");
+ test_checkf(int2float(1), 1.0f, "int2float3");
+ test_checkf(int2float(INT32_MAX), 2147483647.0f, "int2float4");
+ test_checkf(int2float(INT32_MIN), -2147483648.0f, "int2float5");
+ // check rounding
+ test_checkf(int2float(2147483391), 2147483392.0f, "int2float6");
+ test_checkf(int2float(2147483456), 2147483392.0f, "int2float7");
+ test_checkf(int2float(2147483457), 2147483520.0f, "int2float8");
+ test_checkf(int2float(2147483483), 2147483520.0f, "int2float9");
+ test_checkf(int2float(2147483584), 2147483648.0f, "int2float10");
+
+ printf("uint2float\n");
+ test_checkf(uint2float(0), 0.0f, "uint2float1");
+ test_checkf(uint2float(1), 1.0f, "uint2float2");
+ test_checkf(uint2float(INT32_MAX), 2147483647.0f, "uint2float3");
+ // todo test correct rounding around maximum precision
+ test_checkf(uint2float(UINT32_MAX), 4294967295.0f, "uint2float4");
+
+ printf("int642float\n");
+ test_checkf(int642float(0), 0.0f, "int642float1");
+ test_checkf(int642float(-1), -1.0f, "int642float2");
+ test_checkf(int642float(1), 1.0f, "int642float3");
+ test_checkf(int642float(INT32_MAX-1), 2147483646.0f, "int642float4"); // note equality is within 1ulp
+ test_checkf(int642float(INT32_MAX), 2147483647.0f, "int642float5"); // note equality is within 1ulp
+ test_checkf(int642float(INT32_MAX+1ll), 2147483648.0f, "int642float6");
+ test_checkf(int642float(INT32_MIN-1ll), -2147483649.0f, "int642float7"); // note equality is within 1ulp
+ test_checkf(int642float(INT32_MIN), -2147483648.0f, "int642float8");
+ test_checkf(int642float(INT32_MIN+1ll), -2147483647.0f, "int642float9"); // note equality is within 1ulp
+ // todo test correct rounding around maximum precision
+ test_checkf(int642float(INT64_MAX), 9223372036854775807.0f, "int642float10");
+ test_checkf(int642float(INT64_MIN), -9223372036854775808.0f, "int642float11");
+
+ printf("uint642float\n");
+ test_checkf(uint642float(0), 0.0f, "uint642float1");
+ test_checkf(uint642float(1), 1.0f, "uint642float2");
+ test_checkf(uint642float(INT32_MAX-1), 2147483646.0f, "uint642float3"); // note equality is within 1ulp
+ test_checkf(uint642float(INT32_MAX), 2147483647.0f, "uint642float4"); // note equality is within 1ulp
+ test_checkf(uint642float(INT32_MAX+1ll), 2147483648.0f, "uint642float5");
+ test_checkf(uint642float(INT64_MAX), 9223372036854775807.0f, "uint642float6");
+ // todo test correct rounding around maximum precision
+ test_checkf(uint642float(UINT64_MAX), 18446744073709551615.0f, "uint642float7");
+
+ union {
+ uint32_t u;
+ float f;
+ } u32f;
+
+#if !(LIB_PICO_FLOAT_COMPILER || defined(__riscv))
+ printf("fix2float\n");
+ // todo test correct rounding around maximum precision
+ test_checkf(fix2float(-3, 1), -1.5f, "fix2float1");
+ test_checkf(fix2float(-3, 1), -1.5f, "fix2float2");
+ test_checkf(fix2float(-3, -4), -48.0f, "fix2float3");
+
+ printf("ufix2float\n");
+ // todo test correct rounding around maximum precision
+ test_checkf(ufix2float(0xa0000000, 30), 2.5f, "ufix2float1");
+ test_checkf(ufix2float(3, -4), 48.0f, "ufix2float2");
+
+ printf("fix642float\n");
+ // todo test correct rounding around maximum precision
+ test_checkf(fix642float(-0xa000000000ll, 38), -2.5f, "fix6422float1");
+ test_checkf(fix642float(-3, -34), -51539607552.0f, "fix642float2");
+
+ printf("ufix642float\n");
+ // todo test correct rounding around maximum precision
+ test_checkf(ufix642float(0xa000000000ll, 38), 2.5f, "ufix642float1");
+ test_checkf(ufix642float(3, -34), 51539607552.0f, "fix64float2");
+
+ test_checkf(fix2float_8(128), 0.5f, "fix2float_8_1");
+ test_checkf(fix2float_8(-128), -0.5f, "fix2float_8_2");
+ test_checkf(fix2float_16(8192), 0.125f, "fix2float_8_3");
+ test_checkf(fix2float_16(-8192), -0.125f, "fix2float_8_4");
+ test_checkf(fix2float_24(3<<23), 1.5f, "fix2float_8_5");
+ test_checkf(fix2float_24(-(3<<23)), -1.5f, "fix2float_8_6");
+
+ printf("float2fix\n");
+ test_checki(float2fix(-0.5f, 8), -0x80, "float2fix0");
+ test_checki(float2fix(3.5f, 8), 0x380, "float2fix1");
+ test_checki(float2fix(-3.5f, 8), -0x380, "float2fix2");
+ test_checki(float2fix(32768.0f, 16), INT32_MAX, "float2fix3");
+ test_checki(float2fix(65536.0f, 16), INT32_MAX, "float2fix4");
+ test_checki(float2fix(-65536.0f, 16), INT32_MIN, "float2fix4b");
+ test_checki(float2fix(INFINITY, 16), INT32_MAX, "float2fix5");
+ test_checki(float2fix(-INFINITY, 16), INT32_MIN, "float2fix5b");
+ test_checki(float2fix(3.24999f, 2), 12, "float2fix6");
+ test_checki(float2fix(3.25f, 2), 13, "float2fix7");
+ test_checki(float2fix(-3.24999f, 2), -13, "float2fix8");
+ test_checki(float2fix(-3.25f, 2), -13, "float2fix9");
+ test_checki(float2fix(-0.75f, 1), -2, "float2fix10");
+ test_checki(float2fix(-3.0f, -1), -2, "float2fix11"); // not very useful
+ u32f.u = 0x7f012345;
+ test_checki(float2fix(u32f.f, 1), INT32_MAX, "float2fix12");
+ u32f.u = 0xff012345;
+ test_checki(float2fix(u32f.f, 1), INT32_MIN, "float2fix13");
+
+ printf("float2ufix\n");
+ test_checku(float2ufix(3.5f, 8), 0x380, "float2ufix1");
+ test_checku(float2ufix(-3.5f, 8), 0, "float2ufix2");
+ test_checku(float2ufix(32768.0f, 16), 32768 << 16, "float2ufix3");
+ test_checku(float2ufix(65536.0f, 16), UINT32_MAX, "float2ufix4");
+ test_checku(float2ufix(INFINITY, 16), UINT32_MAX, "float2ufix5");
+ test_checku(float2ufix(3.24999f, 2), 12, "float2ufix6");
+ test_checku(float2ufix(3.25f, 2), 13, "float2ufix7");
+ test_checku(float2ufix(3.0f, -1), 1, "float2ufix8"); // not very useful
+
+ printf("float2fix64\n");
+ test_checki64(float2fix64(3.5f, 8), 0x380, "float2fix641");
+ 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(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");
+ test_checki64(float2fix64(3.25f, 2), 13, "float2fix647");
+ test_checki64(float2fix64(-3.24999f, 2), -13, "float2fix648");
+ test_checki64(float2fix64(-3.25f, 2), -13, "float2fix649");
+ test_checki64(float2fix64(-3.0f, -1), -2, "float2fix6410"); // not very useful
+
+ printf("float2ufix64\n");
+ test_checku64(float2ufix64(3.5f, 8), 0x380, "float2ufix641");
+ test_checku64(float2ufix64(-3.5f, 8), 0, "float2ufix642");
+ test_checku64(float2ufix64(32768.0f, 16), 32768ull << 16, "float2ufix643");
+ test_checku64(float2ufix64(65536.0f, 16), 65536ull << 16, "float2ufix644");
+ test_checku64(float2ufix64(2147483648.0f, 16), 2147483648ull << 16, "float2ufix644b");
+ test_checku64(float2ufix64(INFINITY, 16), UINT64_MAX, "float2ufix645");
+ test_checku64(float2ufix64(3.24999f, 2), 12, "float2ufix646");
+ test_checku64(float2ufix64(3.25f, 2), 13, "float2ufix647");
+ test_checku64(float2ufix64(3.0f, -1), 1, "float2ufix648"); // not very useful
+
+ printf("float2fix_z\n");
+ test_checki(float2fix_z(3.5f, 8), 0x380, "float2fix_z1");
+ test_checki(float2fix_z(-3.5f, 8), -0x380, "float2fix_z2");
+ test_checki(float2fix_z(32768.0f, 16), INT32_MAX, "float2fix_z3");
+ test_checki(float2fix_z(65536.0f, 16), INT32_MAX, "float2fix_z4");
+ test_checki(float2fix_z(INFINITY, 16), INT32_MAX, "float2fix_z5");
+ test_checki(float2fix_z(-INFINITY, 16), INT32_MIN, "float2fix_z5b");
+ test_checki(float2fix_z(3.24999f, 2), 12, "float2fix_z6");
+ test_checki(float2fix_z(3.25f, 2), 13, "float2fix_z7");
+ test_checki(float2fix_z(-3.24999f, 2), -12, "float2fix_z8");
+ test_checki(float2fix_z(-3.25f, 2), -13, "float2fix_z9");
+ test_checki(float2fix_z(-0.75f, 1), -1, "float2fix_z10");
+ test_checki(float2fix_z(-3.0f, -1), -1, "float2fix_z11"); // not very useful
+ u32f.u = 0x7f012345;
+ test_checki(float2fix_z(u32f.f, 1), INT32_MAX, "float2fix_z12");
+ u32f.u = 0xff012345;
+ test_checki(float2fix_z(u32f.f, 1), INT32_MIN, "float2fix_z13");
+
+ printf("float2ufix_z\n");
+ test_checku(float2ufix_z(3.5f, 8), 0x380, "float2ufix_z1");
+ test_checku(float2ufix_z(-3.5f, 8), 0, "float2ufix_z2");
+ test_checku(float2ufix_z(32768.0f, 16), 32768 << 16, "float2ufix_z3");
+ test_checku(float2ufix_z(65536.0f, 16), UINT32_MAX, "float2ufix_z4");
+ test_checku(float2ufix_z(INFINITY, 16), UINT32_MAX, "float2ufix_z5");
+ test_checku(float2ufix_z(3.24999f, 2), 12, "float2ufix_z6");
+ 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");
+ u32f.u = 0xff012345;
+ test_checku(float2ufix_z(u32f.f, 1), 0, "float2fix_z10");
+
+ printf("float2fix64_z\n");
+ test_checki64(float2fix64_z(3.5f, 8), 0x380, "float2fix64_z1");
+ test_checki64(float2fix64_z(-3.5f, 8), -0x380, "float2fix64_z2");
+ test_checki64(float2fix64_z(32768.0f, 16), 32768ll << 16, "float2fix64_z3");
+ test_checki64(float2fix64_z(65536.0f, 16), 65536ll << 16, "float2fix64_z4");
+ test_checki64(float2fix64_z(65536.0f * 65536.0f * 32768.0f, 16), INT64_MAX, "float2fix64_z4b");
+ test_checki64(float2fix64_z(INFINITY, 16), INT64_MAX, "float2fix64_z5");
+ test_checki64(float2fix64_z(3.24999f, 2), 12, "float2fix64_z6");
+ test_checki64(float2fix64_z(3.25f, 2), 13, "float2fix64_z7");
+ test_checki64(float2fix64_z(-3.24999f, 2), -12, "float2fix64_z8");
+ test_checki64(float2fix64_z(-3.25f, 2), -13, "float2fix64_z9");
+ test_checki64(float2fix64_z(-3.0f, -1), -1, "float2fix64_z10"); // not very useful
+
+ printf("float2ufix64_z\n");
+ test_checku64(float2ufix64_z(3.5f, 8), 0x380, "float2ufix64_z1");
+ 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_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");
+ test_checki64(float2ufix64_z(3.0f, -1), 1, "float2fuix64_z8"); // not very useful
+
+ printf("float2int\n");
+ test_checki(float2int(0.0f), 0, "float2int1");
+ test_checki(float2int(0.25f), 0, "float2int1b");
+ test_checki(float2int(0.5f), 0, "float2int2");
+ test_checki(float2int(0.75f), 0, "float2int2b");
+ test_checki(float2int(1.0f), 1, "float2int3");
+ test_checki(float2int(-10.0f), -10, "float2int3a");
+ test_checki(float2int(-0.0f), 0, "float2int3b");
+ test_checki(float2int(-0.25f), -1, "float2int4");
+ test_checki(float2int(-0.5f), -1, "float2int4b");
+ test_checki(float2int(-0.75f), -1, "float2int5");
+ test_checki(float2int(-1.0f), -1, "float2int5b");
+ // todo test correct rounding around maximum precision
+ test_checki(float2int(2147483647.0f), INT32_MAX, "float2int6");
+ test_checki(float2int(21474836470.0f), INT32_MAX, "float2int7");
+ test_checki(float2int(-2147483648.0f), INT32_MIN, "float2int8");
+ test_checki(float2int(-21474836480.0f), INT32_MIN, "float2int9");
+ test_checki(float2int(-2.5f), -3, "float2int10");
+ test_checki(float2int(-2.4f), -3, "float2int11");
+
+ printf("float2uint\n");
+ test_checku(float2uint(0.0f), 0, "float2uint1");
+ test_checku(float2uint(0.25f), 0, "float2uint2");
+ test_checku(float2uint(0.5f), 0, "float2uint3");
+ test_checku(float2uint(0.75f), 0, "float2uint4");
+ test_checku(float2uint(1.0f), 1, "float2uint5");
+ test_checku(float2uint(2147483647.0f), INT32_MAX+1u, "float2uint6"); // note loss of precision
+ test_checku(float2uint(2147483648.0f), INT32_MAX+1u, "float2uint7");
+ test_checku(float2uint(4294967294.5f), UINT32_MAX, "float2uint8"); // note loss of precision
+ test_checku(float2uint(4294967295.0f), UINT32_MAX, "float2uint9");
+ test_checku(float2uint(42949672950.0f), UINT32_MAX, "float2uint10");
+
+ printf("float2int64\n");
+ test_checki64(float2int64(0.0f), 0, "float2int641");
+ test_checki64(float2int64(0.25f), 0, "float2int641b");
+ test_checki64(float2int64(0.5f), 0, "float2int642");
+ test_checki64(float2int64(0.75f), 0, "float2int642b");
+ test_checki64(float2int64(1.0f), 1, "float2int643");
+ test_checki64(float2int64(-10.0f), -10, "float2int643a");
+ test_checki64(float2int64(-0.0f), 0, "float2int643b");
+ test_checki64(float2int64(-0.25f), -1, "float2int644");
+ test_checki64(float2int64(-0.5f), -1, "float2int644b");
+ test_checki64(float2int64(-0.75f), -1, "float2int645");
+ test_checki64(float2int64(-1.0f), -1, "float2int645b");
+ // todo test correct rounding around maximum precision
+ test_checki64(float2int64(2147483647.0f), INT32_MAX+1ll, "float2int646");
+ test_checki64(float2int64(21474836470.0f), 21474836480ll, "float2int647"); // note loss of precision
+ test_checki64(float2int64(-2147483648.0f), INT32_MIN, "float2int648");
+ test_checki64(float2int64(-21474836480.0f), -21474836480ll, "float2int649");
+ test_checki64(float2int64(-2.5f), -3, "float2int6410");
+ test_checki64(float2int64(-2.4f), -3, "float2int6411");
+
+ printf("float2uint64\n");
+ test_checku64(float2uint64(0.0f), 0, "float2uint641");
+ test_checku64(float2uint64(0.25f), 0, "float2uint642");
+ test_checku64(float2uint64(0.5f), 0, "float2uint643");
+ test_checku64(float2uint64(0.75f), 0, "float2uint644");
+ test_checku64(float2uint64(1.0f), 1, "float2uint645");
+ test_checku64(float2uint64(2147483647.0f), INT32_MAX+1u, "float2uint646"); // note loss of precision
+ test_checku64(float2uint64(2147483648.0f), INT32_MAX+1u, "float2uint647");
+ test_checku64(float2uint64(4294967294.5f), 4294967296ull, "float2uint648"); // note loss of precision
+ test_checku64(float2uint64(4294967295.0f), 4294967296ull, "float2uint649"); // note loss of precision
+ test_checku64(float2uint64(42949672950.0f), 42949672960ull, "float2uint6410"); // note loss of precision
+#endif
+
+ // // These methods round towards 0.
+ printf("float2int_z\n");
+ test_checki(float2int_z(0.0f), 0, "float2int_z1");
+ test_checki(float2int_z(0.25f), 0, "float2int_z1b");
+ test_checki(float2int_z(0.5f), 0, "float2int_z2");
+ test_checki(float2int_z(0.75f), 0, "float2int_z2b");
+ test_checki(float2int_z(1.0f), 1, "float2int_z3");
+ test_checki(float2int_z(-10.0f), -10, "float2int_z3a");
+ test_checki(float2int_z(-0.0f), 0, "float2int_z3b");
+ test_checki(float2int_z(-0.25f), 0, "float2int_z4");
+ test_checki(float2int_z(-0.5f), 0, "float2int_z4b");
+ test_checki(float2int_z(-0.75f), 0, "float2int_z5");
+ test_checki(float2int_z(-1.0f), -1, "float2int_z5b");
+ // todo test correct rounding around maximum precision
+ test_checki(float2int_z(2147483647.0f), INT32_MAX, "float2int_z6");
+ test_checki(float2int_z(21474836470.0f), INT32_MAX, "float2int_z7");
+ test_checki(float2int_z(-2147483648.0f), INT32_MIN, "float2int_z8");
+ test_checki(float2int_z(-21474836480.0f), INT32_MIN, "float2int_z9");
+ test_checki(float2int_z(-2.5f), -2, "float2int_z10");
+ test_checki(float2int_z(-2.4f), -2, "float2int_z11");
+
+ printf("float2int64_z\n");
+ test_checki64(float2int64_z(0.0f), 0, "float2int64_z1");
+ test_checki64(float2int64_z(0.25f), 0, "float2int64_z1b");
+ test_checki64(float2int64_z(0.5f), 0, "float2int64_z2");
+ test_checki64(float2int64_z(0.75f), 0, "float2int64_z2b");
+ test_checki64(float2int64_z(1.0f), 1, "float2int64_z3");
+ test_checki64(float2int64_z(-10.0f), -10, "float2int64_z3a");
+ test_checki64(float2int64_z(-0.0f), 0, "float2int64_z3b");
+ test_checki64(float2int64_z(-0.25f), 0, "float2int64_z4");
+ test_checki64(float2int64_z(-0.5f), 0, "float2int64_z4b");
+ test_checki64(float2int64_z(-0.75f), 0, "float2int64_z5");
+ test_checki64(float2int64_z(-1.0f), -1, "float2int64_z5b");
+ test_checki64(float2int64_z(2147483647.0f), 2147483648ll, "float2int64_z6"); // note loss of precision
+ test_checki64(float2int64_z(21474836470.0f), 21474836480ll, "float2int64_z7"); // note loss of precision
+ test_checki64(float2int64_z(-2147483648.0f), INT32_MIN, "float2int64_z8");
+ test_checki64(float2int64_z(-21474836480.0f), -21474836480ll, "float2int64_z9");
+ test_checki64(float2int64_z(-2.5f), -2, "float2int64_z10");
+ test_checki64(float2int64_z(-2.4f), -2, "float2int64_z11");
+
+ printf("float2uint_z\n");
+ test_checku(float2uint_z(0.0f), 0, "float2uint_z1");
+ test_checku(float2uint_z(0.25f), 0, "float2uint_z2");
+ test_checku(float2uint_z(0.5f), 0, "float2uint_z3");
+ test_checku(float2uint_z(0.75f), 0, "float2uint_z4");
+ test_checku(float2uint_z(1.0f), 1, "float2uint_z5");
+ test_checku(float2uint_z(2147483647.0f), INT32_MAX+1u, "float2uint_z6"); // note loss of precision
+ test_checku(float2uint_z(2147483648.0f), INT32_MAX+1u, "float2uint_z7");
+ // todo test correct rounding around maximum precision
+ test_checku(float2uint_z(4294967294.5f), UINT32_MAX, "float2uint_z8"); // note loss of precision
+ test_checku(float2uint_z(4294967295.0f), UINT32_MAX, "float2uint_z9");
+ test_checku(float2uint_z(42949672950.0f), UINT32_MAX, "float2uint_z10");
+
+ printf("float2uint64_z\n");
+ test_checku64(float2uint64_z(0.0f), 0, "float2uint64_z1");
+ test_checku64(float2uint64_z(0.25f), 0, "float2uint64_z2");
+ test_checku64(float2uint64_z(0.5f), 0, "float2uint64_z3");
+ test_checku64(float2uint64_z(0.75f), 0, "float2uint64_z4");
+ test_checku64(float2uint64_z(1.0f), 1, "float2uint64_z5");
+ test_checku64(float2uint64_z(2147483647.0f), INT32_MAX+1u, "float2uint64_z6"); // note loss of precision
+ test_checku64(float2uint64_z(2147483648.0f), INT32_MAX+1u, "float2uint64_z7");
+ test_checku64(float2uint64_z(4294967294.5f), 4294967296ull, "float2uint64_z8"); // note loss of precision
+ test_checku64(float2uint64_z(4294967295.0f), 4294967296ull, "float2uint64_z9"); // note loss of precision
+ test_checku64(float2uint64_z(42949672950.0f), 42949672960ull, "float2uint64_z10"); // note loss of precision
+
+ // float exp10f(float x);
+ // void sincosf(float x, float *sinx, float *cosx);
+ // float powintf(float x, int y);
+ return rc;
+}
+
+int main() {
+ stdio_init_all();
+ int rc = test();
+ if (rc) {
+ printf("FAILED\n");
+ } else {
+ printf("PASSED\n");
+ }
+}
diff --git a/test/pico_float_test/pico_double_test.c b/test/pico_float_test/pico_double_test.c
index 3b7a8ec29..b844e15d4 100644
--- a/test/pico_float_test/pico_double_test.c
+++ b/test/pico_float_test/pico_double_test.c
@@ -365,7 +365,13 @@ int main() {
printf("EXP %10.18g\n", check_close1(exp, x));
printf("LN %10.18g\n", check_close1(log, x));
printf("POW %10.18f\n", check_close2(pow, x, x));
+#if LIB_PICO_DOUBLE_PICO && __clang_major__ == 15
+ // seem to be a compiler/linker bug here with calls to __real_trunc, so just call trunc rather than doing
+ // a closeness check - at least we will know that the call works
+ printf("TRUNC %10.18f\n", trunc(x));
+#else
printf("TRUNC %10.18f\n", check_close1(trunc, x));
+#endif
printf("LDEXP %10.18f\n", check_close2(ldexp, x, x));
// todo come pack
// printf("FMOD %10.18f\n", check_close2(fmod, x, 3.0f));
diff --git a/test/pico_time_test/BUILD.bazel b/test/pico_time_test/BUILD.bazel
index b7a437629..038738601 100644
--- a/test/pico_time_test/BUILD.bazel
+++ b/test/pico_time_test/BUILD.bazel
@@ -12,6 +12,7 @@ cc_binary(
target_compatible_with = compatible_with_rp2(),
deps = [
"//src/rp2_common/pico_stdlib",
+ "//src/rp2_common/pico_aon_timer",
"//test/pico_test",
],
)
diff --git a/test/pico_time_test/CMakeLists.txt b/test/pico_time_test/CMakeLists.txt
index d36a3da07..20a5608bd 100644
--- a/test/pico_time_test/CMakeLists.txt
+++ b/test/pico_time_test/CMakeLists.txt
@@ -4,5 +4,8 @@ if (NOT PICO_TIME_NO_ALARM_SUPPORT)
PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS=250
)
target_link_libraries(pico_time_test PRIVATE pico_test)
+ if (PICO_RP2040)
+ target_link_libraries(pico_time_test PRIVATE pico_aon_timer)
+ endif()
pico_add_extra_outputs(pico_time_test)
endif()
\ No newline at end of file
diff --git a/test/pico_time_test/pico_time_test.c b/test/pico_time_test/pico_time_test.c
index 40472df11..0fc18daae 100644
--- a/test/pico_time_test/pico_time_test.c
+++ b/test/pico_time_test/pico_time_test.c
@@ -8,8 +8,16 @@
#include
#include
#include
+#if PICO_ON_DEVICE
+#include "hardware/clocks.h"
+#endif
#include "pico/stdlib.h"
#include "pico/test.h"
+
+#if LIB_PICO_AON_TIMER
+#include "pico/aon_timer.h"
+#endif
+
// Include sys/types.h before inttypes.h to work around issue with
// certain versions of GCC and newlib which causes omission of PRIi64
#include
@@ -71,9 +79,12 @@ static bool repeating_timer_callback(struct repeating_timer *t) {
#define RESOLUTION_ALLOWANCE PICO_HARDWARE_TIMER_RESOLUTION_US
#endif
-int issue_195_test(void);
-int issue_1812_test(void);
-int issue_1953_test(void);
+static int issue_195_test(void);
+static int issue_1812_test(void);
+static int issue_1953_test(void);
+static int issue_2118_test(void);
+static int issue_2148_test(void);
+static int issue_2186_test(void);
int main() {
setup_default_uart();
@@ -246,6 +257,12 @@ int main() {
issue_1953_test();
+ issue_2118_test();
+
+ issue_2148_test();
+
+ issue_2186_test();
+
PICOTEST_END_TEST();
}
@@ -256,7 +273,7 @@ int64_t issue_195_callback(alarm_id_t id, void *user_data) {
return -ISSUE_195_TIMER_DELAY;
}
-int issue_195_test(void) {
+static int issue_195_test(void) {
PICOTEST_START_SECTION("Issue #195 race condition - without fix may hang on gcc 10.2.1 release builds");
absolute_time_t t1 = get_absolute_time();
int id = add_alarm_in_us(ISSUE_195_TIMER_DELAY, issue_195_callback, NULL, true);
@@ -275,7 +292,7 @@ int issue_195_test(void) {
}
// Setting an alarm should not swallow a sev
-int issue_1812_test(void) {
+static int issue_1812_test(void) {
PICOTEST_START_SECTION("Issue #1812 defect - Setting an alarm should not ignore a sev");
__sev(); // Make sure the call below does not ignore this
@@ -299,7 +316,7 @@ static void alarm_pool_stuck_issue_1953(uint alarm, void *data) {
hard_assert(false);
}
-int issue_1953_test(void) {
+static int issue_1953_test(void) {
PICOTEST_START_SECTION("Issue #1953 defect - Alarm can be set in the past");
int alarm = hardware_alarm_claim_unused(true);
hardware_alarm_set_callback(alarm, alarm_pool_stuck_issue_1953);
@@ -307,8 +324,8 @@ int issue_1953_test(void) {
repeating_timer_t timer1;
repeating_timer_t timer2;
- assert(add_repeating_timer_us(10, timer_callback_issue_1953, NULL, &timer1));
- assert(add_repeating_timer_us(100, timer_callback_issue_1953, NULL, &timer2));
+ hard_assert(add_repeating_timer_us(10, timer_callback_issue_1953, NULL, &timer1));
+ hard_assert(add_repeating_timer_us(100, timer_callback_issue_1953, NULL, &timer2));
int iterations = 0;
while(iterations < 100) {
@@ -325,3 +342,82 @@ int issue_1953_test(void) {
PICOTEST_END_SECTION();
return 0;
}
+
+static int counter_2118;
+static bool timer_callback_issue_2118(repeating_timer_t *rt) {
+ counter_2118++;
+ return true;
+}
+
+static int issue_2118_test(void) {
+ PICOTEST_START_SECTION("Issue #2118 defect - failure to set an alarm");
+
+#if PICO_ON_DEVICE
+ // this problem only happens when running the clock fast as it requires the time between
+ // alarm_pool_irq_handler handling an alarm and setting the next alarm to be <1us
+ set_sys_clock_hz(200 * MHZ, true);
+ setup_default_uart();
+#endif
+
+ alarm_pool_t *pool = alarm_pool_create(2, 1);
+ repeating_timer_t timer;
+ alarm_pool_add_repeating_timer_ms(pool, -20, timer_callback_issue_2118, NULL, &timer);
+
+ int iterations = 0;
+ while(iterations < 100) {
+ iterations++;
+ sleep_ms(20);
+ }
+ PICOTEST_CHECK(counter_2118 >= 100, "Repeating timer failure");
+
+ alarm_pool_destroy(pool);
+#if PICO_ON_DEVICE
+ hard_assert(timer_hw->armed == 0); // check destroying the pool unarms its timer
+ set_sys_clock_hz(SYS_CLK_HZ, true);
+ setup_default_uart();
+#endif
+
+ PICOTEST_END_SECTION();
+ return 0;
+}
+
+static int issue_2186_test(void) {
+ PICOTEST_START_SECTION("Issue #2186 defect - ta_wakes_up_on_or_before");
+
+ hard_assert(best_effort_wfe_or_timeout(get_absolute_time() - 1));
+ hard_assert(best_effort_wfe_or_timeout(get_absolute_time() - 1)); // this will lockup without the fix - wfe which never happens
+
+ PICOTEST_END_SECTION();
+ return 0;
+}
+
+static int issue_2148_test(void) {
+#if HAS_RP2040_RTC
+ PICOTEST_START_SECTION("Issue #2148 defect - get time after rtc start");
+ struct tm tm = { 0 };
+ struct tm tm_check = { 0 };
+
+ tm.tm_sec = 55;
+ tm.tm_min = 36;
+ tm.tm_hour = 20;
+ tm.tm_mday = 21;
+ tm.tm_mon = 10;
+ tm.tm_year = 124;
+ tm.tm_wday = 4;
+ tm.tm_yday = 325;
+ tm.tm_isdst = 0;
+ hard_assert(aon_timer_start_calendar(&tm));
+ hard_assert(aon_timer_get_time_calendar(&tm_check));
+
+ PICOTEST_CHECK(tm.tm_sec == tm_check.tm_sec || tm.tm_sec == tm_check.tm_sec - 1, "failed to get seconds");
+ PICOTEST_CHECK(tm.tm_min == tm_check.tm_min, "failed to get minutes");
+ PICOTEST_CHECK(tm.tm_hour == tm_check.tm_hour, "failed to get hour");
+ PICOTEST_CHECK(tm.tm_mday == tm_check.tm_mday, "failed to get day");
+ PICOTEST_CHECK(tm.tm_mon == tm_check.tm_mon, "failed to get month");
+ PICOTEST_CHECK(tm.tm_year == tm_check.tm_year, "failed to get year");
+
+ aon_timer_stop();
+ PICOTEST_END_SECTION();
+#endif
+ return 0;
+}
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index aa7dbcb00..c2fbe3281 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -101,7 +101,7 @@ endfunction()
# Check picotool is installed, or download and build it if not installed
function(pico_init_picotool)
- set(picotool_VERSION_REQUIRED 2.1.0)
+ set(picotool_VERSION_REQUIRED 2.1.1)
if (NOT TARGET picotool AND NOT DEFINED picotool_FOUND)
# Build path of local install dir
if (DEFINED ENV{PICOTOOL_FETCH_FROM_GIT_PATH} AND (NOT PICOTOOL_FETCH_FROM_GIT_PATH))
@@ -155,9 +155,10 @@ endfunction()
# Generate pio header and include it in the build
# PICO_CMAKE_CONFIG: PICO_DEFAULT_PIOASM_OUTPUT_FORMAT, Default output format used by pioasm when using pico_generate_pio_header, type=string, default=c-sdk, group=build
-function(pico_generate_pio_header TARGET PIO)
+function(pico_generate_pio_header TARGET)
pico_init_pioasm()
- cmake_parse_arguments(pico_generate_pio_header "" "OUTPUT_FORMAT;OUTPUT_DIR" "" ${ARGN} )
+ # 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} )
if (pico_generate_pio_header_OUTPUT_FORMAT)
set(OUTPUT_FORMAT "${pico_generate_pio_header_OUTPUT_FORMAT}")
@@ -173,24 +174,31 @@ function(pico_generate_pio_header TARGET PIO)
else()
set(HEADER_DIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()
- get_filename_component(PIO_NAME ${PIO} NAME)
- set(HEADER "${HEADER_DIR}/${PIO_NAME}.h")
- #message("Will generate ${HEADER}")
- get_filename_component(HEADER_GEN_TARGET ${PIO} NAME_WE)
- set(HEADER_GEN_TARGET "${TARGET}_${HEADER_GEN_TARGET}_pio_h")
- add_custom_target(${HEADER_GEN_TARGET} DEPENDS ${HEADER})
+ # Loop through each PIO file
+ foreach(PIO ${pico_generate_pio_header_UNPARSED_ARGUMENTS})
+ get_filename_component(PIO_NAME ${PIO} NAME)
+ set(HEADER "${HEADER_DIR}/${PIO_NAME}.h")
+ #message("Will generate ${HEADER}")
+ get_filename_component(HEADER_GEN_TARGET ${PIO} NAME_WE)
+ set(HEADER_GEN_TARGET "${TARGET}_${HEADER_GEN_TARGET}_pio_h")
+
+ add_custom_target(${HEADER_GEN_TARGET} DEPENDS ${HEADER})
+
+ if (PICO_PIO_VERSION)
+ set(VERSION_STRING "${PICO_PIO_VERSION}")
+ else()
+ set(VERSION_STRING "0")
+ endif()
+
+ add_custom_command(OUTPUT ${HEADER}
+ DEPENDS ${PIO}
+ COMMAND pioasm -o ${OUTPUT_FORMAT} -v ${VERSION_STRING} ${PIO} ${HEADER}
+ VERBATIM)
+
+ add_dependencies(${TARGET} ${HEADER_GEN_TARGET})
+ endforeach()
- if (PICO_PIO_VERSION)
- set(VERSION_STRING "${PICO_PIO_VERSION}")
- else()
- set(VERSION_STRING "0")
- endif()
- add_custom_command(OUTPUT ${HEADER}
- DEPENDS ${PIO}
- COMMAND pioasm -o ${OUTPUT_FORMAT} -v ${VERSION_STRING} ${PIO} ${HEADER}
- VERBATIM)
- add_dependencies(${TARGET} ${HEADER_GEN_TARGET})
get_target_property(target_type ${TARGET} TYPE)
if ("INTERFACE_LIBRARY" STREQUAL "${target_type}")
target_include_directories(${TARGET} INTERFACE ${HEADER_DIR})
diff --git a/tools/Findpicotool.cmake b/tools/Findpicotool.cmake
index e7ecbcea9..e5bfaeaac 100644
--- a/tools/Findpicotool.cmake
+++ b/tools/Findpicotool.cmake
@@ -15,10 +15,12 @@ if (NOT TARGET picotool)
endif ()
include(FetchContent)
- set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICOTOOL_FETCH_FROM_GIT_PATH)
- get_filename_component(FETCHCONTENT_BASE_DIR "${PICOTOOL_FETCH_FROM_GIT_PATH}" ABSOLUTE)
+ get_filename_component(picotool_INSTALL_DIR "${PICOTOOL_FETCH_FROM_GIT_PATH}" ABSOLUTE)
+ else ()
+ get_filename_component(picotool_INSTALL_DIR "${FETCHCONTENT_BASE_DIR}" ABSOLUTE)
endif ()
+ set(picotool_INSTALL_DIR ${picotool_INSTALL_DIR} CACHE PATH "Directory where picotool has been installed" FORCE)
set(picotool_BUILD_TARGET picotoolBuild)
set(picotool_TARGET picotool)
@@ -32,20 +34,15 @@ if (NOT TARGET picotool)
)
endif()
- FetchContent_Declare(
- picotool
- GIT_REPOSITORY https://github.com/raspberrypi/picotool.git
- GIT_TAG develop
- GIT_PROGRESS true
- )
+ message("Downloading Picotool")
+ FetchContent_Populate(picotool QUIET
+ GIT_REPOSITORY https://github.com/raspberrypi/picotool.git
+ GIT_TAG develop
- FetchContent_GetProperties(picotool)
- set(picotool_INSTALL_DIR ${FETCHCONTENT_BASE_DIR} CACHE PATH "Directory where picotool has been installed" FORCE)
- if (NOT picotool_POPULATED)
- message("Downloading Picotool")
- FetchContent_Populate(picotool)
- endif ()
- set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
+ SOURCE_DIR ${picotool_INSTALL_DIR}/picotool-src
+ BINARY_DIR ${picotool_INSTALL_DIR}/picotool-build
+ SUBBUILD_DIR ${picotool_INSTALL_DIR}/picotool-subbuild
+ )
add_custom_target(picotoolForceReconfigure
${CMAKE_COMMAND} -E touch_nocreate "${CMAKE_SOURCE_DIR}/CMakeLists.txt"
diff --git a/tools/extract_build_defines.py b/tools/extract_build_defines.py
index bbcad15af..179f084ec 100755
--- a/tools/extract_build_defines.py
+++ b/tools/extract_build_defines.py
@@ -139,7 +139,7 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum):
elif BASE_BUILD_DEFINE_RE.search(line):
m = BUILD_DEFINE_RE.match(line)
if not m:
- if line.startswith("## "):
+ 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))
diff --git a/tools/extract_cmake_configs.py b/tools/extract_cmake_configs.py
index 8fdb4504e..18884330f 100755
--- a/tools/extract_cmake_configs.py
+++ b/tools/extract_cmake_configs.py
@@ -139,7 +139,7 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum):
elif BASE_CMAKE_CONFIG_RE.search(line):
m = CMAKE_CONFIG_RE.match(line)
if not m:
- if line.startswith("## "):
+ if re.match("^\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))
diff --git a/tools/extract_configs.py b/tools/extract_configs.py
index 034866987..30705d5cb 100755
--- a/tools/extract_configs.py
+++ b/tools/extract_configs.py
@@ -158,7 +158,7 @@ def ValidateAttrs(config_name, config_attrs, file_path, linenum):
elif BASE_CONFIG_RE.search(line):
m = CONFIG_RE.match(line)
if not m:
- if line.startswith("//// "):
+ 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))
diff --git a/tools/pioasm/pio_assembler.cpp b/tools/pioasm/pio_assembler.cpp
index a427c22e4..a36854b2c 100644
--- a/tools/pioasm/pio_assembler.cpp
+++ b/tools/pioasm/pio_assembler.cpp
@@ -63,7 +63,7 @@ void program::set_pio_version(const yy::location &l, int version) {
void program::set_clock_div(const yy::location &l, float clock_div) {
if (clock_div < 1.0f || clock_div >= 65536.0f) {
- throw syntax_error(l, "clock divider must be between 1 and 65546");
+ throw syntax_error(l, "clock divider must be between 1 and 65535");
}
clock_div_int = (uint16_t)clock_div;
if (clock_div_int == 0) {
@@ -292,7 +292,7 @@ uint instruction::encode(program &program) {
}
}
// note we store the 6th bit of arg2 above the 16 bits of instruction
- return (((uint) raw.type) << 13u) | (((uint) _delay | (uint) _sideset) << 8u) | (raw.arg1 << 5u) | raw.arg2 | ((raw.arg2 >> 5) << 16);
+ return (((uint) raw.type) << 13u) | (((uint) _delay | (uint) _sideset) << 8u) | (raw.arg1 << 5u) | (raw.arg2 & 0x1fu) | ((raw.arg2 >> 5) << 16);
}
raw_encoding instruction::raw_encode(program& program) {
diff --git a/tools/pioasm/pio_disassembler.cpp b/tools/pioasm/pio_disassembler.cpp
index 2a34796d0..74d862bc6 100644
--- a/tools/pioasm/pio_disassembler.cpp
+++ b/tools/pioasm/pio_disassembler.cpp
@@ -56,7 +56,9 @@ std::string disassemble(uint inst, uint sideset_bits_including_opt, bool sideset
if (arg2 & 0x1cu) {
invalid = true;
} else if (arg2) {
- guts = "jmppin " + std::to_string(arg2 & 3u);
+ guts = "jmppin + " + std::to_string(arg2 & 3u);
+ } else {
+ guts = "jmppin";
}
break;
}
@@ -131,7 +133,7 @@ std::string disassemble(uint inst, uint sideset_bits_including_opt, bool sideset
op("mov");
std::string guts = dest + ", ";
if (operation == 1) {
- guts += "!";
+ guts += "~";
} else if (operation == 2) {
guts += "::";
}
@@ -193,6 +195,9 @@ std::string disassemble(uint inst, uint sideset_bits_including_opt, bool sideset
}
delay &= ((1u << (5 - sideset_bits_including_opt)) - 1u);
ss << std::left << std::setw(4) << (delay ? ("[" + std::to_string(delay) + "]") : "");
- return ss.str();
+ // remove trailing spaces
+ auto str = ss.str();
+ str.erase(str.find_last_not_of(' ')+1);
+ return str;
}
diff --git a/tools/pioasm/python_output.cpp b/tools/pioasm/python_output.cpp
index bcaa8d610..f4cf326bd 100644
--- a/tools/pioasm/python_output.cpp
+++ b/tools/pioasm/python_output.cpp
@@ -204,6 +204,9 @@ struct python_output : public output_format {
}
}
break;
+ default:
+ invalid = true;
+ break;
}
if (!invalid) {
guts = ((arg1 & 4u) ? "1, " : "0, ") + guts;
@@ -254,23 +257,24 @@ struct python_output : public output_format {
uint operation = arg2 >> 3u;
if (source.empty() || dest.empty() || operation == 3) {
invalid = true;
- }
- if (dest == source && (arg1 == 1 || arg2 == 2) && operation == 0) {
- op("nop");
- op_guts("");
} else {
- op("mov");
- std::string guts = dest + ", ";
- if (operation == 1) {
- guts += "invert(";
- } else if (operation == 2) {
- guts += "reverse(";
- }
- guts += source;
- if (operation == 1 || operation == 2) {
- guts += ")";
+ if (dest == source && (arg1 == 1 || arg2 == 2) && operation == 0) {
+ op("nop");
+ op_guts("");
+ } else {
+ op("mov");
+ std::string guts = dest + ", ";
+ if (operation == 1) {
+ guts += "invert(";
+ } else if (operation == 2) {
+ guts += "reverse(";
+ }
+ guts += source;
+ if (operation == 1 || operation == 2) {
+ guts += ")";
+ }
+ op_guts(guts);
}
- op_guts(guts);
}
break;
}
@@ -310,7 +314,9 @@ struct python_output : public output_format {
if (invalid) {
op("word");
ss << std::hex;
- op_guts(std::to_string(inst));
+ std::stringstream guts;
+ guts << std::hex << std::showbase << std::setfill('0') << std::setw(4) << inst;
+ op_guts(guts.str());
}
uint delay = ((uint) inst >> 8u) & 0x1f;
ss << std::left << std::setw(9);
diff --git a/tools/pioasm/test/amethyst.pio b/tools/pioasm/test/amethyst.pio
index 97422a22b..6b8160460 100644
--- a/tools/pioasm/test/amethyst.pio
+++ b/tools/pioasm/test/amethyst.pio
@@ -44,3 +44,10 @@ wait gpio 40
.pio_version 1
.mov_status txfifo < 12
.mov_status irq next set 3
+
+.program python
+.pio_version 1
+wait 0 jmppin
+wait 0 jmppin + 3
+mov x, !x
+.word 0x1234
\ No newline at end of file