From e2dbf2bdd19f8e125f27223b874f9f8f68eb4f4c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 Oct 2025 11:05:39 +0700 Subject: remove claude code workflow --- .github/workflows/claude.yml | 49 -------------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 .github/workflows/claude.yml (limited to '.github/workflows') diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml deleted file mode 100644 index a6ea7e396..000000000 --- a/.github/workflows/claude.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Claude Code - -on: - issue_comment: - types: [created] - pull_request_review_comment: - types: [created] - issues: - types: [opened, assigned] - pull_request_review: - types: [submitted] - -jobs: - claude: - if: | - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || - (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - issues: read - id-token: write - actions: read # Required for Claude to read CI results on PRs - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 1 - - - name: Run Claude Code - id: claude - uses: anthropics/claude-code-action@v1 - with: - anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} - - # This is an optional setting that allows Claude to read CI results on PRs - additional_permissions: | - actions: read - - # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. - # prompt: 'Update the pull request description to include a summary of changes.' - - # Optional: Add claude_args to customize behavior and configuration - # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md - # or https://docs.claude.com/en/docs/claude-code/sdk#command-line for available options - # claude_args: '--model claude-opus-4-1-20250805 --allowed-tools Bash(gh pr:*)' -- cgit v1.3.1 From f3f6046e0bbcf9b3b926ca5f0e1882d1ceb9652d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 Oct 2025 21:00:51 +0700 Subject: hil simplify skip board from previous run --- .github/workflows/build.yml | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9243c866d..16f906632 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -198,6 +198,17 @@ jobs: needs: hil-build runs-on: [self-hosted, X64, hathach, hardware-in-the-loop] steps: + - name: Get Skip Boards from previous run + if: github.run_attempt != '1' + run: | + if [ -f "${{ env.HIL_JSON }}.skip" ]; then + SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip") + else + SKIP_BOARDS="" + fi + echo "SKIP_BOARDS=$SKIP_BOARDS" + echo "SKIP_BOARDS=$SKIP_BOARDS" >> $GITHUB_ENV + - name: Clean workspace run: | echo "Cleaning up for the first run" @@ -213,25 +224,8 @@ jobs: path: cmake-build merge-multiple: true - - name: Cache skip list - uses: actions/cache@v4 - with: - path: ${{ env.HIL_JSON }}.skip - key: hil-skip-${{ github.run_id }}-${{ github.run_attempt }} - restore-keys: | - hil-skip-${{ github.run_id }}- - - name: Test on actual hardware run: | - ls cmake-build/ - - # Skip boards that passed with previous run, file is generated by hil_test.py - SKIP_BOARDS="" - if [ -f ${{ env.HIL_JSON }}.skip ]; then - SKIP_BOARDS=$(cat "${HIL_JSON}.skip") - fi - echo "SKIP_BOARDS=$SKIP_BOARDS" - python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS # --------------------------------------- -- cgit v1.3.1 From e0ee32ce6a1655de6dbb86178649c0ec878bd0d0 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 13 Oct 2025 16:46:02 +0700 Subject: fix build with west zephyr --- .github/workflows/build.yml | 4 +-- .idea/debugServers/lpc1769.xml | 13 ++++++++ .idea/debugServers/lpc55s69.xml | 13 ++++++++ .idea/debugServers/nrf52833.xml | 13 ++++++++ .idea/debugServers/nrf5340.xml | 13 ++++++++ .idea/debugServers/stm32f411.xml | 13 ++++++++ hw/bsp/nrf/family.c | 49 ++++++++++++++++------------- hw/bsp/nrf/nrfx_config/nrfx_config_common.h | 2 -- hw/bsp/zephyr_board_aliases.cmake | 2 +- 9 files changed, 95 insertions(+), 27 deletions(-) create mode 100644 .idea/debugServers/lpc1769.xml create mode 100644 .idea/debugServers/lpc55s69.xml create mode 100644 .idea/debugServers/nrf52833.xml create mode 100644 .idea/debugServers/nrf5340.xml create mode 100644 .idea/debugServers/stm32f411.xml (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16f906632..becbc5069 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -161,8 +161,8 @@ jobs: - name: Build run: | - west build -b pca10056 -d examples/device/cdc_msc/build examples/device/cdc_msc -- -DRTOS=zephyr - west build -b pca10056 -d examples/device/msc_dual_lun/build examples/device/msc_dual_lun -- -DRTOS=zephyr + west build -b nrf52840dk -d examples/device/cdc_msc/build examples/device/cdc_msc -- -DRTOS=zephyr + west build -b nrf52840dk -d examples/device/msc_dual_lun/build examples/device/msc_dual_lun -- -DRTOS=zephyr # --------------------------------------- # Hardware in the loop (HIL) diff --git a/.idea/debugServers/lpc1769.xml b/.idea/debugServers/lpc1769.xml new file mode 100644 index 000000000..4acfe6afe --- /dev/null +++ b/.idea/debugServers/lpc1769.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/lpc55s69.xml b/.idea/debugServers/lpc55s69.xml new file mode 100644 index 000000000..ceedab0af --- /dev/null +++ b/.idea/debugServers/lpc55s69.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/nrf52833.xml b/.idea/debugServers/nrf52833.xml new file mode 100644 index 000000000..09d2ae3d3 --- /dev/null +++ b/.idea/debugServers/nrf52833.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/nrf5340.xml b/.idea/debugServers/nrf5340.xml new file mode 100644 index 000000000..ac3bd59fa --- /dev/null +++ b/.idea/debugServers/nrf5340.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/stm32f411.xml b/.idea/debugServers/stm32f411.xml new file mode 100644 index 000000000..2bcdf3829 --- /dev/null +++ b/.idea/debugServers/stm32f411.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 6edeacd87..0221da083 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -66,20 +66,6 @@ #error "Example requires nrfx v3.0.0 or later" #endif -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -#if defined(NRF54H20_XXAA) -#define USBD_IRQn USBHS_IRQn -void USBHS_IRQHandler(void) { - tusb_int_handler(0, true); -} - -#else -void USBD_IRQHandler(void) { - tud_int_handler(0); -} -#endif /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM @@ -92,18 +78,37 @@ enum { USB_EVT_READY = 2 }; +// Forward USB interrupt events to TinyUSB IRQ Handler +#if defined(NRF54H20_XXAA) +#define USBD_IRQn USBHS_IRQn +void USBHS_IRQHandler(void) { + tusb_int_handler(0, true); +} + +static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(120); + +#else + #ifdef NRF5340_XXAA - #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_LFRC - #define VBUSDETECT_Msk USBREG_USBREGSTATUS_VBUSDETECT_Msk - #define OUTPUTRDY_Msk USBREG_USBREGSTATUS_OUTPUTRDY_Msk - #define GPIOTE_IRQn GPIOTE1_IRQn +#define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_LFRC +#define VBUSDETECT_Msk USBREG_USBREGSTATUS_VBUSDETECT_Msk +#define OUTPUTRDY_Msk USBREG_USBREGSTATUS_OUTPUTRDY_Msk +#define GPIOTE_IRQn GPIOTE1_IRQn #else - #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_RC - #define VBUSDETECT_Msk POWER_USBREGSTATUS_VBUSDETECT_Msk - #define OUTPUTRDY_Msk POWER_USBREGSTATUS_OUTPUTRDY_Msk +#define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_RC +#define VBUSDETECT_Msk POWER_USBREGSTATUS_VBUSDETECT_Msk +#define OUTPUTRDY_Msk POWER_USBREGSTATUS_OUTPUTRDY_Msk #endif -static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(CFG_NRFX_UARTE_INSTANCE_ID); +static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(0); + +void USBD_IRQHandler(void) { + tud_int_handler(0); +} +#endif + + + // tinyusb function that handles power event (detected, ready, removed) // We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. diff --git a/hw/bsp/nrf/nrfx_config/nrfx_config_common.h b/hw/bsp/nrf/nrfx_config/nrfx_config_common.h index 1d75e5a66..a5a29bb8e 100644 --- a/hw/bsp/nrf/nrfx_config/nrfx_config_common.h +++ b/hw/bsp/nrf/nrfx_config/nrfx_config_common.h @@ -61,7 +61,6 @@ #if defined(NRF54H20_XXAA) #define NRFX_UARTE120_ENABLED 1 -#define CFG_NRFX_UARTE_INSTANCE_ID 120 #else @@ -69,7 +68,6 @@ #define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY 7 #define NRFX_UARTE0_ENABLED 1 -#define CFG_NRFX_UARTE_INSTANCE_ID 0 #define NRFX_GPIOTE_ENABLED 1 #define NRFX_GPIOTE0_ENABLED 1 diff --git a/hw/bsp/zephyr_board_aliases.cmake b/hw/bsp/zephyr_board_aliases.cmake index b60e97ef4..a60068208 100644 --- a/hw/bsp/zephyr_board_aliases.cmake +++ b/hw/bsp/zephyr_board_aliases.cmake @@ -1,2 +1,2 @@ -set(pca10056_BOARD_ALIAS nrf52840dk/nrf52840) +set(nrf52840dk_BOARD_ALIAS nrf52840dk/nrf52840) set(stm32n657nucleo_BOARD_ALIAS nucleo_n657x0_q) -- cgit v1.3.1 From ce2dab7fb3a2572fd63e8fdf6682d95d41f59116 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Oct 2025 10:00:14 +0700 Subject: more warning fix --- .github/workflows/ci_set_matrix.py | 3 +-- hw/bsp/maxim/family.cmake | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index e53998c66..46108a847 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -34,8 +34,7 @@ family_list = { "ra": ["arm-gcc"], "rp2040": ["arm-gcc"], "rx": ["rx-gcc"], - "samd11 saml2x": ["arm-gcc", "arm-clang"], - "samd21": ["arm-gcc", "arm-clang"], + "samd11 samd2x_l2x": ["arm-gcc", "arm-clang"], "samd5x_e5x samg": ["arm-gcc", "arm-clang"], "stm32c0 stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f4": ["arm-gcc", "arm-clang", "arm-iar"], diff --git a/hw/bsp/maxim/family.cmake b/hw/bsp/maxim/family.cmake index e4b1b2c46..cbfe7c84e 100644 --- a/hw/bsp/maxim/family.cmake +++ b/hw/bsp/maxim/family.cmake @@ -186,9 +186,13 @@ function(family_configure_example TARGET RTOS) target_sources(${TARGET} PUBLIC ${TOP}/src/portable/mentor/musb/dcd_musb.c ) - target_compile_options(${TARGET} PRIVATE - -Wno-error=strict-prototypes - ) + + # warnings caused by MSDK headers + target_compile_options(${TARGET} PRIVATE -Wno-error=strict-prototypes) + if (${MAX_DEVICE} STREQUAL "max78002") + target_compile_options(${TARGET} PRIVATE -Wno-error=redundant-decls) + endif () + target_link_libraries(${TARGET} PUBLIC board_${BOARD}) # Flashing -- cgit v1.3.1 From 3ce037d62bb1fec8605af5560d1169c2841af8a1 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Oct 2025 13:38:52 +0700 Subject: add nuc to ci build --- .github/workflows/ci_set_matrix.py | 1 + 1 file changed, 1 insertion(+) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 46108a847..3789b4116 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -31,6 +31,7 @@ family_list = { "msp430": ["msp430-gcc"], "msp432e4 tm4c": ["arm-gcc"], "nrf": ["arm-gcc", "arm-clang"], + "nuc100_120 nuc121_125 nuc126 nuc505": ["arm-gcc"], "ra": ["arm-gcc"], "rp2040": ["arm-gcc"], "rx": ["rx-gcc"], -- cgit v1.3.1 From b08f672daf1efadd9c77a775332dc0b64ac22e4a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Oct 2025 17:24:55 +0700 Subject: add pvs-studio analyze to ci --- .github/workflows/build.yml | 2 +- .github/workflows/build_util.yml | 26 +++++++++++++ .github/workflows/static_analysis.yml | 43 ++++++++++++++++++++++ examples/device/cdc_msc/src/msc_disk.c | 3 +- examples/device/cdc_msc_freertos/src/msc_disk.c | 3 +- .../device/dynamic_configuration/src/msc_disk.c | 3 +- 6 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/static_analysis.yml (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index becbc5069..0495ba6a9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -219,7 +219,7 @@ jobs: uses: actions/checkout@v4 - name: Download Artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: path: cmake-build merge-multiple: true diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index a2c96f3c0..d52924efd 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -20,6 +20,10 @@ on: required: false default: false type: boolean + analyze-pvs: + required: false + default: false + type: boolean os: required: false type: string @@ -68,6 +72,28 @@ jobs: fi shell: bash + - name: PVS-Studio analyze + if: ${{ inputs.analyze-pvs }} + run: | + wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt | sudo apt-key add - + sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.pvs-studio.com/etc/viva64.list + sudo apt update + sudo apt install pvs-studio + pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} + mkdir -p sarif-reports + for build_dir in cmake-build/cmake-build-*; do + BOARD=${build_dir#cmake-build/cmake-build-} + pvs-studio-analyzer analyze -f ${build_dir}/compile_commands.json -j -o ${build_dir}/pvs-report.log --exclude-path hw/mcu/ --exclude-path lib/ + plog-converter -t sarif -o sarif-reports/${BOARD}.sarif ${build_dir}/pvs-report.log + done + + - name: PVS-Studio upload SARIF + if: ${{ inputs.analyze-pvs }} + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: sarif-reports/ + category: PVS-Studio + - name: Upload Artifacts for Hardware Testing if: ${{ inputs.upload-artifacts }} uses: actions/upload-artifact@v4 diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml new file mode 100644 index 000000000..3ace5cf99 --- /dev/null +++ b/.github/workflows/static_analysis.yml @@ -0,0 +1,43 @@ +name: Static Analysis +on: + workflow_dispatch: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened] +jobs: +# SonarQube: +# name: Build and analyze +# runs-on: ubuntu-latest +# env: +# BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed +# steps: +# - uses: actions/checkout@v4 +# with: +# fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis +# - name: Install Build Wrapper +# uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v6 +# - name: Run Build Wrapper +# run: | +# build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build --preset ${{ env.BOARD }} -t ${{ env.EXAMPLE }} +# - name: SonarQube Scan +# uses: SonarSource/sonarqube-scan-action@v6 +# env: +# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} +# with: +# args: > +# --define "sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" + PVS-Studio: + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + board: + - 'stm32h743eval' + with: + build-system: 'cmake' + toolchain: 'arm-gcc' + build-args: '-b${{ matrix.board }}' + one-per-family: true + analyze-pvs: true diff --git a/examples/device/cdc_msc/src/msc_disk.c b/examples/device/cdc_msc/src/msc_disk.c index 9a43d321e..b39f5efa1 100644 --- a/examples/device/cdc_msc/src/msc_disk.c +++ b/examples/device/cdc_msc/src/msc_disk.c @@ -45,10 +45,11 @@ enum { DISK_BLOCK_SIZE = 512 }; +static #ifdef CFG_EXAMPLE_MSC_READONLY const #endif -static uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { +uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; // sector_per_cluster = 1; reserved_sectors = 1; diff --git a/examples/device/cdc_msc_freertos/src/msc_disk.c b/examples/device/cdc_msc_freertos/src/msc_disk.c index 996be738d..29ff86281 100644 --- a/examples/device/cdc_msc_freertos/src/msc_disk.c +++ b/examples/device/cdc_msc_freertos/src/msc_disk.c @@ -76,10 +76,11 @@ enum { DISK_BLOCK_SIZE = 512 }; +static #ifdef CFG_EXAMPLE_MSC_READONLY const #endif -static uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = +uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; diff --git a/examples/device/dynamic_configuration/src/msc_disk.c b/examples/device/dynamic_configuration/src/msc_disk.c index 95bf8e45f..ab71b02d6 100644 --- a/examples/device/dynamic_configuration/src/msc_disk.c +++ b/examples/device/dynamic_configuration/src/msc_disk.c @@ -43,10 +43,11 @@ enum DISK_BLOCK_SIZE = 512 }; +static #ifdef CFG_EXAMPLE_MSC_READONLY const #endif -static uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = +uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { //------------- Block0: Boot Sector -------------// // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; -- cgit v1.3.1 From 948ba203ca8d31de3f0947bc01b5852174bc8404 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 25 Oct 2025 00:15:41 +0700 Subject: add pvs-studio analyze to ci --- .github/workflows/build_util.yml | 26 ----------------------- .github/workflows/static_analysis.yml | 39 ++++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 33 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index d52924efd..a2c96f3c0 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -20,10 +20,6 @@ on: required: false default: false type: boolean - analyze-pvs: - required: false - default: false - type: boolean os: required: false type: string @@ -72,28 +68,6 @@ jobs: fi shell: bash - - name: PVS-Studio analyze - if: ${{ inputs.analyze-pvs }} - run: | - wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt | sudo apt-key add - - sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.pvs-studio.com/etc/viva64.list - sudo apt update - sudo apt install pvs-studio - pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} - mkdir -p sarif-reports - for build_dir in cmake-build/cmake-build-*; do - BOARD=${build_dir#cmake-build/cmake-build-} - pvs-studio-analyzer analyze -f ${build_dir}/compile_commands.json -j -o ${build_dir}/pvs-report.log --exclude-path hw/mcu/ --exclude-path lib/ - plog-converter -t sarif -o sarif-reports/${BOARD}.sarif ${build_dir}/pvs-report.log - done - - - name: PVS-Studio upload SARIF - if: ${{ inputs.analyze-pvs }} - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: sarif-reports/ - category: PVS-Studio - - name: Upload Artifacts for Hardware Testing if: ${{ inputs.upload-artifacts }} uses: actions/upload-artifact@v4 diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 3ace5cf99..6541be129 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -29,15 +29,40 @@ jobs: # args: > # --define "sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" PVS-Studio: - uses: ./.github/workflows/build_util.yml + runs-on: ubuntu-latest strategy: fail-fast: false matrix: board: - 'stm32h743eval' - with: - build-system: 'cmake' - toolchain: 'arm-gcc' - build-args: '-b${{ matrix.board }}' - one-per-family: true - analyze-pvs: true + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Get Dependencies + uses: ./.github/actions/get_deps + with: + arg: -b${{ matrix.board }} + + - name: Setup Toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: 'arm-gcc' + + - name: Analyze + run: | + wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt | sudo apt-key add - + sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.pvs-studio.com/etc/viva64.list + sudo apt update + sudo apt install pvs-studio + pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} + cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel + cmake --build build + pvs-studio-analyzer analyze -f build/compile_commands.json -j --exclude-path hw/mcu/ --exclude-path lib/ + plog-converter -t sarif -o pvs.sarif PVS-Studio.log + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: pvs.sarif + category: PVS-Studio -- cgit v1.3.1 From 5e3e24337f82582103ce7e9d8498c49547cab42b Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 25 Oct 2025 12:28:20 +0700 Subject: merge codeql and pvs-studio to static_analysis.yml --- .github/workflows/codeql.yml | 1 + .github/workflows/static_analysis.yml | 119 ++++++++++++++++++++++++++++------ 2 files changed, 99 insertions(+), 21 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index dfcca6315..21ed9c223 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -41,6 +41,7 @@ jobs: # Consider using larger runners for possible analysis time improvements. runs-on: ubuntu-latest timeout-minutes: 360 + if: false permissions: actions: read contents: read diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 6541be129..f391855f5 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -6,28 +6,80 @@ on: - master pull_request: types: [opened, synchronize, reopened] + +permissions: + actions: read + contents: read + security-events: write + jobs: -# SonarQube: -# name: Build and analyze -# runs-on: ubuntu-latest -# env: -# BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed -# steps: -# - uses: actions/checkout@v4 + CodeQL: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + board: + - 'raspberry_pi_pico' + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Get Dependencies + uses: ./.github/actions/get_deps + with: + arg: -b${{ matrix.board }} + + - name: Setup Toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: 'arm-gcc' + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: 'c-cpp' + queries: security-and-quality + + - name: Build + run: | + cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel + cmake --build build + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: CodeQL + upload: always + id: step1 + +# - name: Filter out unwanted errors and warnings +# uses: advanced-security/filter-sarif@v1 # with: -# fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis -# - name: Install Build Wrapper -# uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v6 -# - name: Run Build Wrapper -# run: | -# build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build --preset ${{ env.BOARD }} -t ${{ env.EXAMPLE }} -# - name: SonarQube Scan -# uses: SonarSource/sonarqube-scan-action@v6 -# env: -# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} +# patterns: | +# -**:cpp/path-injection +# -**:cpp/world-writable-file-creation +# -**:cpp/poorly-documented-function +# -**:cpp/potentially-dangerous-function +# -**:cpp/use-of-goto +# -**:cpp/integer-multiplication-cast-to-long +# -**:cpp/comparison-with-wider-type +# -**:cpp/leap-year/* +# -**:cpp/ambiguously-signed-bit-field +# -**:cpp/suspicious-pointer-scaling +# -**:cpp/suspicious-pointer-scaling-void +# -**:cpp/unsigned-comparison-zero +# -**/third*party/** +# -**/3rd*party/** +# -**/external/** +# input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif +# output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif +# +# - name: Upload SARIF +# uses: github/codeql-action/upload-sarif@v4 # with: -# args: > -# --define "sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" +# sarif_file: ${{ steps.step1.outputs.sarif-output }} +# category: CodeQL + PVS-Studio: runs-on: ubuntu-latest strategy: @@ -49,14 +101,17 @@ jobs: with: toolchain: 'arm-gcc' - - name: Analyze + - name: Install Tools run: | wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt | sudo apt-key add - sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.pvs-studio.com/etc/viva64.list sudo apt update sudo apt install pvs-studio pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} - cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel + + - name: Analyze + run: | + cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build pvs-studio-analyzer analyze -f build/compile_commands.json -j --exclude-path hw/mcu/ --exclude-path lib/ plog-converter -t sarif -o pvs.sarif PVS-Studio.log @@ -66,3 +121,25 @@ jobs: with: sarif_file: pvs.sarif category: PVS-Studio + +# SonarQube: +# name: Build and analyze +# runs-on: ubuntu-latest +# env: +# BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed +# steps: +# - uses: actions/checkout@v4 +# with: +# fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis +# - name: Install Build Wrapper +# uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v6 +# - name: Run Build Wrapper +# run: | +# build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build --preset ${{ env.BOARD }} -t ${{ env.EXAMPLE }} +# - name: SonarQube Scan +# uses: SonarSource/sonarqube-scan-action@v6 +# env: +# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} +# with: +# args: > +# --define "sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" -- cgit v1.3.1 From 6cc445ef0f3e7b29cfe2e3d90bb3364afbc424af Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 25 Oct 2025 12:54:40 +0700 Subject: download ninja binary, apt seems take too long ~ 1 min also upload sarif as artifacts --- .github/actions/get_deps/action.yml | 5 ++++- .github/workflows/static_analysis.yml | 25 +++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) (limited to '.github/workflows') diff --git a/.github/actions/get_deps/action.yml b/.github/actions/get_deps/action.yml index ae9e7bbef..b0d6d1066 100644 --- a/.github/actions/get_deps/action.yml +++ b/.github/actions/get_deps/action.yml @@ -19,7 +19,10 @@ runs: - name: Linux dependencies if: runner.os == 'Linux' run: | - sudo apt install -y ninja-build + NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip + wget $NINJA_URL -O ninja-linux.zip + unzip ninja-linux.zip -d ninja-bin + echo >> $GITHUB_PATH "${{ github.workspace }}/ninja-bin" shell: bash - name: Get Dependencies diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index f391855f5..bbb7229df 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -50,7 +50,7 @@ jobs: with: category: CodeQL upload: always - id: step1 + id: analyze # - name: Filter out unwanted errors and warnings # uses: advanced-security/filter-sarif@v1 @@ -71,15 +71,21 @@ jobs: # -**/third*party/** # -**/3rd*party/** # -**/external/** -# input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif -# output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif +# input: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif +# output: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif # # - name: Upload SARIF # uses: github/codeql-action/upload-sarif@v4 # with: -# sarif_file: ${{ steps.step1.outputs.sarif-output }} +# sarif_file: ${{ steps.analyze.outputs.sarif-output }} # category: CodeQL + - name: Upload artifact + uses: actions/upload-artifact@v5 + with: + name: codeql-${{ matrix.board }} + path: ${{ steps.analyze.outputs.sarif-output }} + PVS-Studio: runs-on: ubuntu-latest strategy: @@ -114,14 +120,21 @@ jobs: cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build pvs-studio-analyzer analyze -f build/compile_commands.json -j --exclude-path hw/mcu/ --exclude-path lib/ - plog-converter -t sarif -o pvs.sarif PVS-Studio.log + plog-converter -t sarif -o pvs-${{ matrix.board }}.sarif PVS-Studio.log - name: Upload SARIF uses: github/codeql-action/upload-sarif@v4 with: - sarif_file: pvs.sarif + sarif_file: pvs-${{ matrix.board }}.sarif category: PVS-Studio + - name: Upload artifact + uses: actions/upload-artifact@v5 + with: + name: pvs-${{ matrix.board }} + path: pvs-${{ matrix.board }}.sarif + + # SonarQube: # name: Build and analyze # runs-on: ubuntu-latest -- cgit v1.3.1 From 531009c9a02d719d3222c89dc9d31f5967e23af3 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 25 Oct 2025 13:36:26 +0700 Subject: add SonarQube scan --- .github/workflows/static_analysis.yml | 70 +++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 24 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index bbb7229df..e5254344b 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -42,6 +42,7 @@ jobs: - name: Build run: | + mkdir -p build cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build @@ -117,10 +118,11 @@ jobs: - name: Analyze run: | + mkdir -p build cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build pvs-studio-analyzer analyze -f build/compile_commands.json -j --exclude-path hw/mcu/ --exclude-path lib/ - plog-converter -t sarif -o pvs-${{ matrix.board }}.sarif PVS-Studio.log + plog-converter -t sarif -o pvs-studio-${{ matrix.board }}.sarif PVS-Studio.log - name: Upload SARIF uses: github/codeql-action/upload-sarif@v4 @@ -131,28 +133,48 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@v5 with: - name: pvs-${{ matrix.board }} - path: pvs-${{ matrix.board }}.sarif + name: pvs-studio-${{ matrix.board }} + path: pvs-studio-${{ matrix.board }}.sarif + SonarQube: + runs-on: ubuntu-latest + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory + strategy: + fail-fast: false + matrix: + board: + - 'metro_m4_express' + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis -# SonarQube: -# name: Build and analyze -# runs-on: ubuntu-latest -# env: -# BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed -# steps: -# - uses: actions/checkout@v4 -# with: -# fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis -# - name: Install Build Wrapper -# uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v6 -# - name: Run Build Wrapper -# run: | -# build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build --preset ${{ env.BOARD }} -t ${{ env.EXAMPLE }} -# - name: SonarQube Scan -# uses: SonarSource/sonarqube-scan-action@v6 -# env: -# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} -# with: -# args: > -# --define "sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" + - name: Get Dependencies + uses: ./.github/actions/get_deps + with: + arg: -b${{ matrix.board }} + + - name: Setup Toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: 'arm-gcc' + + - name: Install Build Wrapper + uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v6 + + - name: Run Build Wrapper + run: | + cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ + + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@v6 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} + with: + # Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options + args: > + --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" -- cgit v1.3.1 From 5818db49b2de8689a07007a5e4d329b94d67ef42 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 25 Oct 2025 13:54:10 +0700 Subject: add SonarQube scan --- .github/workflows/static_analysis.yml | 5 ++--- sonar-project.properties | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 sonar-project.properties (limited to '.github/workflows') diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index e5254344b..45c5c959b 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -127,7 +127,7 @@ jobs: - name: Upload SARIF uses: github/codeql-action/upload-sarif@v4 with: - sarif_file: pvs-${{ matrix.board }}.sarif + sarif_file: pvs-studio-${{ matrix.board }}.sarif category: PVS-Studio - name: Upload artifact @@ -173,8 +173,7 @@ jobs: uses: SonarSource/sonarqube-scan-action@v6 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} with: # Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options args: > - --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" + --define sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 000000000..d797bfe6f --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,14 @@ +sonar.projectKey=hathach_tinyusb +sonar.organization=hathach + + +# This is the name and version displayed in the SonarCloud UI. +sonar.projectName=tinyusb +sonar.projectVersion=0.19.0 + + +# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. +#sonar.sources=. + +# Encoding of the source code. Default is default system encoding +#sonar.sourceEncoding=UTF-8 -- cgit v1.3.1 From d7c4bf14b464a509120ff18f94e9b02cd1c6f9fa Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 25 Oct 2025 16:30:42 +0700 Subject: add IAR CStat to static_analysis.yml --- .circleci/config2.yml | 2 + .../actions/setup_toolchain/download/action.yml | 4 +- .github/actions/setup_toolchain/toolchain.json | 2 +- .github/workflows/codeql-buildscript.sh | 6 - .github/workflows/codeql.yml | 138 --------------------- .github/workflows/fail_on_error.py | 34 ----- .github/workflows/static_analysis.yml | 55 +++++++- tools/make_release.py | 11 ++ 8 files changed, 67 insertions(+), 185 deletions(-) delete mode 100644 .github/workflows/codeql-buildscript.sh delete mode 100644 .github/workflows/codeql.yml delete mode 100755 .github/workflows/fail_on_error.py (limited to '.github/workflows') diff --git a/.circleci/config2.yml b/.circleci/config2.yml index d86a3f662..bd2a7d02a 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -34,6 +34,7 @@ commands: chmod +x toolchain.run ./toolchain.run -p ~/cache/<< parameters.toolchain >>/gnurx -y elif [[ << parameters.toolchain >> == arm-iar ]]; then + wget --progress=dot:giga https://netstorage.iar.com/FileStore/STANDARD/001/003/926/iar-lmsc-tools_1.8_amd64.deb -O ~/cache/<< parameters.toolchain >>/iar-lmsc-tools.deb wget --progress=dot:giga $toolchain_url -O ~/cache/<< parameters.toolchain >>/toolchain.deb else wget --progress=dot:giga $toolchain_url -O toolchain.tar.gz @@ -44,6 +45,7 @@ commands: # Add toolchain to PATH if [[ << parameters.toolchain >> == arm-iar ]]; then # Install IAR since we only cache deb file + sudo dpkg -i ~/cache/<< parameters.toolchain >>/iar-lmsc-tools.deb sudo dpkg --ignore-depends=libusb-1.0-0 -i ~/cache/<< parameters.toolchain >>/toolchain.deb echo "export PATH=$PATH:/opt/iar/cxarm/arm/bin" >> $BASH_ENV else diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml index ce9643010..514b38f19 100644 --- a/.github/actions/setup_toolchain/download/action.yml +++ b/.github/actions/setup_toolchain/download/action.yml @@ -29,6 +29,7 @@ runs: chmod +x toolchain.run ./toolchain.run -p ~/cache/${{ inputs.toolchain }}/gnurx -y elif [[ ${{ inputs.toolchain }} == arm-iar ]]; then + wget --progress=dot:giga https://netstorage.iar.com/FileStore/STANDARD/001/003/926/iar-lmsc-tools_1.8_amd64.deb -O ~/cache/${{ inputs.toolchain }}/iar-lmsc-tools.deb wget --progress=dot:giga ${{ inputs.toolchain_url }} -O ~/cache/${{ inputs.toolchain }}/cxarm.deb else wget --progress=dot:giga ${{ inputs.toolchain_url }} -O toolchain.tar.gz @@ -39,7 +40,8 @@ runs: - name: Setup Toolchain run: | if [[ ${{ inputs.toolchain }} == arm-iar ]]; then - sudo apt-get install -y ~/cache/${{ inputs.toolchain }}/cxarm.deb + sudo dpkg -i ~/cache/${{ inputs.toolchain }}/iar-lmsc-tools.deb + sudo apt install -y ~/cache/${{ inputs.toolchain }}/cxarm.deb echo >> $GITHUB_PATH "/opt/iar/cxarm/arm/bin" else echo >> $GITHUB_PATH `echo ~/cache/${{ inputs.toolchain }}/*/bin` diff --git a/.github/actions/setup_toolchain/toolchain.json b/.github/actions/setup_toolchain/toolchain.json index f7123ef11..8496dcad3 100644 --- a/.github/actions/setup_toolchain/toolchain.json +++ b/.github/actions/setup_toolchain/toolchain.json @@ -5,5 +5,5 @@ "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", "rx-gcc": "https://github.com/hathach/rx_device/releases/download/0.0.1/gcc-8.3.0.202411-GNURX-ELF.run", - "arm-iar": "https://netstorage.iar.com/FileStore/STANDARD/001/003/583/cxarm-9.60.4.deb" + "arm-iar": "https://netstorage.iar.com/FileStore/STANDARD/001/003/723/cxarm-9.70.1.deb" } diff --git a/.github/workflows/codeql-buildscript.sh b/.github/workflows/codeql-buildscript.sh deleted file mode 100644 index 272b55d22..000000000 --- a/.github/workflows/codeql-buildscript.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -FAMILY=stm32l4 -pip install click -python3 tools/get_deps.py $FAMILY -python3 tools/build.py -s make $FAMILY diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 21ed9c223..000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,138 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ 'master' ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/codeql.yml' - pull_request: - branches: [ 'master' ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/codeql.yml' - schedule: - - cron: '0 0 * * *' - -jobs: - analyze: - name: Analyze - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners - # Consider using larger runners for possible analysis time improvements. - runs-on: ubuntu-latest - timeout-minutes: 360 - if: false - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'c-cpp' ] - # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] - # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Toolchain - uses: ./.github/actions/setup_toolchain - with: - toolchain: 'arm-gcc' - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - queries: security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - # If this step fails, then you should remove it and run the build manually (see below) - #- name: Autobuild - # uses: github/codeql-action/autobuild@v2 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - - run: | - ./.github/workflows/codeql-buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" - upload: false - id: step1 - - # Filter out rules with low severity or high false positive rate - # Also filter out warnings in third-party code - - name: Filter out unwanted errors and warnings - uses: advanced-security/filter-sarif@v1 - with: - patterns: | - -**:cpp/path-injection - -**:cpp/world-writable-file-creation - -**:cpp/poorly-documented-function - -**:cpp/potentially-dangerous-function - -**:cpp/use-of-goto - -**:cpp/integer-multiplication-cast-to-long - -**:cpp/comparison-with-wider-type - -**:cpp/leap-year/* - -**:cpp/ambiguously-signed-bit-field - -**:cpp/suspicious-pointer-scaling - -**:cpp/suspicious-pointer-scaling-void - -**:cpp/unsigned-comparison-zero - -**/third*party/** - -**/3rd*party/** - -**/external/** - input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif - output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif - - - name: Upload SARIF - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: ${{ steps.step1.outputs.sarif-output }} - category: "/language:${{matrix.language}}" - - - name: Upload CodeQL results as an artifact - uses: actions/upload-artifact@v4 - with: - name: codeql-results - path: ${{ steps.step1.outputs.sarif-output }} - retention-days: 5 diff --git a/.github/workflows/fail_on_error.py b/.github/workflows/fail_on_error.py deleted file mode 100755 index 29791742b..000000000 --- a/.github/workflows/fail_on_error.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 - -import json -import sys - -# Return whether SARIF file contains error-level results -def codeql_sarif_contain_error(filename): - with open(filename, 'r') as f: - s = json.load(f) - - for run in s.get('runs', []): - rules_metadata = run['tool']['driver']['rules'] - if not rules_metadata: - rules_metadata = run['tool']['extensions'][0]['rules'] - - for res in run.get('results', []): - if 'ruleIndex' in res: - rule_index = res['ruleIndex'] - elif 'rule' in res and 'index' in res['rule']: - rule_index = res['rule']['index'] - else: - continue - try: - rule_level = rules_metadata[rule_index]['defaultConfiguration']['level'] - except IndexError as e: - print(e, rule_index, len(rules_metadata)) - else: - if rule_level == 'error': - return True - return False - -if __name__ == "__main__": - if codeql_sarif_contain_error(sys.argv[1]): - sys.exit(1) diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 45c5c959b..e060dfbc9 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -19,7 +19,7 @@ jobs: fail-fast: false matrix: board: - - 'raspberry_pi_pico' + - 'metro_m4_express' steps: - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -88,12 +88,13 @@ jobs: path: ${{ steps.analyze.outputs.sarif-output }} PVS-Studio: + if: github.repository_owner == 'hathach' runs-on: ubuntu-latest strategy: fail-fast: false matrix: board: - - 'stm32h743eval' + - 'raspberry_pi_pico' steps: - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -119,7 +120,7 @@ jobs: - name: Analyze run: | mkdir -p build - cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel + cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build pvs-studio-analyzer analyze -f build/compile_commands.json -j --exclude-path hw/mcu/ --exclude-path lib/ plog-converter -t sarif -o pvs-studio-${{ matrix.board }}.sarif PVS-Studio.log @@ -137,6 +138,7 @@ jobs: path: pvs-studio-${{ matrix.board }}.sarif SonarQube: + if: github.repository_owner == 'hathach' runs-on: ubuntu-latest env: BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory @@ -144,7 +146,7 @@ jobs: fail-fast: false matrix: board: - - 'metro_m4_express' + - 'stm32h743eval' steps: - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -166,7 +168,7 @@ jobs: - name: Run Build Wrapper run: | - cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=MinSizeRel + cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ - name: SonarQube Scan @@ -177,3 +179,46 @@ jobs: # Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options args: > --define sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json + + IAR-CStat: + if: github.repository_owner == 'hathach' + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + board: + - 'b_g474e_dpow1' + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Get Dependencies + uses: ./.github/actions/get_deps + with: + arg: -b${{ matrix.board }} + + - name: Setup Toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: 'arm-iar' + + - name: Run IAR C-STAT Analysis + env: + IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} + run: | + # CMake run post build to generate C-STAT SARIF report + mkdir -p build + cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DTOOLCHAIN=iar -DIAR_CSTAT=1 -DCMAKE_BUILD_TYPE=MinSizeRel + cmake --build build + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: build/cstat_sarif + category: IAR-CStat + + - name: Upload artifact + uses: actions/upload-artifact@v5 + with: + name: iar-cstat-${{ matrix.board }} + path: build/cstat_sarif diff --git a/tools/make_release.py b/tools/make_release.py index 488ad4901..0e7919f46 100755 --- a/tools/make_release.py +++ b/tools/make_release.py @@ -44,6 +44,17 @@ with open(f_library_json) as f: with open(f_library_json, 'w') as f: f.write(fdata) +################### +# sonar-project.properties +################### +f_sonar_properties = 'sonar-project.properties' +with open(f_sonar_properties) as f: + fdata = f.read() + fdata = re.sub(r'(sonar\.projectVersion=)\d+\.\d+\.\d+', rf'\1{version}', fdata) + +with open(f_sonar_properties, 'w') as f: + f.write(fdata) + ################### # docs/info/changelog.rst ################### -- cgit v1.3.1 From 42f000df8e52cfe0a46867a5e1fa5817cd58bc8a Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 25 Oct 2025 17:36:01 +0700 Subject: iar cstat require cmake at least 4.1 --- .github/workflows/static_analysis.yml | 19 +++++++++++++++---- examples/build_system/cmake/toolchain/arm_iar.cmake | 1 + hw/bsp/family_support.cmake | 8 ++++---- 3 files changed, 20 insertions(+), 8 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index e060dfbc9..0af8ac42c 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -202,23 +202,34 @@ jobs: with: toolchain: 'arm-iar' - - name: Run IAR C-STAT Analysis + - name: Install CMake 4.2 + run: | + # IAR CSTAT requires CMake >= 4.1 + wget -q https://github.com/Kitware/CMake/releases/download/v4.2.0-rc1/cmake-4.2.0-rc1-linux-x86_64.tar.gz + tar -xzf cmake-4.2.0-rc1-linux-x86_64.tar.gz + echo "${{ github.workspace }}/cmake-4.2.0-rc1-linux-x86_64/bin" >> $GITHUB_PATH + + - name: Build and run IAR C-STAT Analysis env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} run: | # CMake run post build to generate C-STAT SARIF report + cmake --version mkdir -p build - cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DTOOLCHAIN=iar -DIAR_CSTAT=1 -DCMAKE_BUILD_TYPE=MinSizeRel + cmake examples/device/cdc_msc -B build -G Ninja -DBOARD=${{ matrix.board }} -DTOOLCHAIN=iar -DIAR_CSTAT=1 -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build + # Merge sarif files for codeql upload + npm i -g @microsoft/sarif-multitool + npx @microsoft/sarif-multitool merge --merge-runs --output-file iar-cstat-${{ matrix.board }}.sarif build/cstat_sarif/*.sarif - name: Upload SARIF uses: github/codeql-action/upload-sarif@v4 with: - sarif_file: build/cstat_sarif + sarif_file: iar-cstat-${{ matrix.board }}.sarif category: IAR-CStat - name: Upload artifact uses: actions/upload-artifact@v5 with: name: iar-cstat-${{ matrix.board }} - path: build/cstat_sarif + path: iar-cstat-${{ matrix.board }}.sarif diff --git a/examples/build_system/cmake/toolchain/arm_iar.cmake b/examples/build_system/cmake/toolchain/arm_iar.cmake index 42b057020..f4c0a500e 100644 --- a/examples/build_system/cmake/toolchain/arm_iar.cmake +++ b/examples/build_system/cmake/toolchain/arm_iar.cmake @@ -19,6 +19,7 @@ find_program(CMAKE_IAR_CHECKS ichecks) find_program(CMAKE_IAR_REPORT ireport) if (IAR_CSTAT) +cmake_minimum_required(VERSION 4.1) set(CMAKE_C_ICSTAT ${CMAKE_IAR_CSTAT} --checks=${CMAKE_CURRENT_LIST_DIR}/cstat_sel_checks.txt --db=${CMAKE_BINARY_DIR}/cstat.db --sarif_dir=${CMAKE_BINARY_DIR}/cstat_sarif) endif () diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 79a9f459b..912e0f4d7 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -300,10 +300,10 @@ function(family_configure_common TARGET RTOS) COMMAND_EXPAND_LISTS ) # generate C-STAT report - add_custom_command(TARGET ${TARGET} POST_BUILD - COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/cstat_report - COMMAND ireport --db=${CMAKE_BINARY_DIR}/cstat.db --full --project ${TARGET} --output ${CMAKE_CURRENT_BINARY_DIR}/cstat_report/index.html - ) +# add_custom_command(TARGET ${TARGET} POST_BUILD +# COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/cstat_report +# COMMAND ireport --db=${CMAKE_BINARY_DIR}/cstat.db --full --project ${TARGET} --output ${CMAKE_CURRENT_BINARY_DIR}/cstat_report/index.html +# ) endif () endif () -- cgit v1.3.1 From 8865ec47814628ba1c50e52f09b7ef2fe10d463d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Oct 2025 12:09:33 +0700 Subject: update static_analysis.yml workflow --- .github/workflows/static_analysis.yml | 21 ++++++++++++++++++--- sonar-project.properties | 1 + 2 files changed, 19 insertions(+), 3 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 0af8ac42c..83eea5283 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -2,15 +2,30 @@ name: Static Analysis on: workflow_dispatch: push: - branches: - - master + branches: [ master ] + paths: + - 'src/**' + - 'examples/**' + - 'hw/bsp/**' + - '.github/workflows/static_analysis.yml' pull_request: - types: [opened, synchronize, reopened] + branches: [ master ] + paths: + - 'src/**' + - 'examples/**' + - 'hw/bsp/**' + - '.github/workflows/static_analysis.yml' permissions: actions: read contents: read security-events: write +# pull-requests: write +# checks: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: CodeQL: diff --git a/sonar-project.properties b/sonar-project.properties index d797bfe6f..5a19a234d 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -9,6 +9,7 @@ sonar.projectVersion=0.19.0 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. #sonar.sources=. +sonar.exclusions=lib/**,hw/mcu/**,test/** # Encoding of the source code. Default is default system encoding #sonar.sourceEncoding=UTF-8 -- cgit v1.3.1 From 621123b9b3709bfd1768778f5d526498549eadae Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 28 Oct 2025 00:16:40 +0700 Subject: added .pvsconfig to exclude some rules --- .PVS-Studio/.pvsconfig | 1 + .github/workflows/static_analysis.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .PVS-Studio/.pvsconfig (limited to '.github/workflows') diff --git a/.PVS-Studio/.pvsconfig b/.PVS-Studio/.pvsconfig new file mode 100644 index 000000000..b722c6d10 --- /dev/null +++ b/.PVS-Studio/.pvsconfig @@ -0,0 +1 @@ +//-V::2506,2514 diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 83eea5283..5d2a6c962 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -137,7 +137,7 @@ jobs: mkdir -p build cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build - pvs-studio-analyzer analyze -f build/compile_commands.json -j --exclude-path hw/mcu/ --exclude-path lib/ + pvs-studio-analyzer analyze -R .PVS-Studio/.pvsconfig -f build/compile_commands.json --exclude-path hw/mcu/ --exclude-path lib/ -j plog-converter -t sarif -o pvs-studio-${{ matrix.board }}.sarif PVS-Studio.log - name: Upload SARIF -- cgit v1.3.1 From 78bd6230649aee3f7731ffbce603742f31c2295e Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 28 Oct 2025 17:56:07 +0700 Subject: filter out sarif for codeql hw/mcu and lib/ --- .github/workflows/static_analysis.yml | 43 ++++++++++++----------------------- 1 file changed, 15 insertions(+), 28 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 5d2a6c962..7e74f77ce 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -65,36 +65,23 @@ jobs: uses: github/codeql-action/analyze@v4 with: category: CodeQL - upload: always + upload: false id: analyze -# - name: Filter out unwanted errors and warnings -# uses: advanced-security/filter-sarif@v1 -# with: -# patterns: | -# -**:cpp/path-injection -# -**:cpp/world-writable-file-creation -# -**:cpp/poorly-documented-function -# -**:cpp/potentially-dangerous-function -# -**:cpp/use-of-goto -# -**:cpp/integer-multiplication-cast-to-long -# -**:cpp/comparison-with-wider-type -# -**:cpp/leap-year/* -# -**:cpp/ambiguously-signed-bit-field -# -**:cpp/suspicious-pointer-scaling -# -**:cpp/suspicious-pointer-scaling-void -# -**:cpp/unsigned-comparison-zero -# -**/third*party/** -# -**/3rd*party/** -# -**/external/** -# input: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif -# output: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif -# -# - name: Upload SARIF -# uses: github/codeql-action/upload-sarif@v4 -# with: -# sarif_file: ${{ steps.analyze.outputs.sarif-output }} -# category: CodeQL + - name: Filter SARIF report + uses: advanced-security/filter-sarif@v1 + with: + patterns: | + -hw/mcu/** + -lib/** + input: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif + output: ${{ steps.analyze.outputs.sarif-output }}/cpp.sarif + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: ${{ steps.analyze.outputs.sarif-output }} + category: CodeQL - name: Upload artifact uses: actions/upload-artifact@v5 -- cgit v1.3.1 From 8e9ba218157eb1777872319ce3031ba5be6d7ccc Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 3 Nov 2025 10:46:53 +0700 Subject: fix alert using input in gh action. fix some conversion int --- .github/workflows/build_util.yml | 3 ++- src/class/audio/audio.h | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index a2c96f3c0..55901b838 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -60,8 +60,9 @@ jobs: - name: Build env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} + TOOLCHAIN: ${{ inputs.toolchain }} run: | - if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then + if [ "$TOOLCHAIN" == "esp-idf" ]; then docker run --rm -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py ${{ matrix.arg }} else python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 47d25dd81..bcfb67640 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -867,11 +867,11 @@ typedef enum { // A.2.1 - Audio Class-Audio Data Format Type I UAC2 typedef enum { - AUDIO20_DATA_FORMAT_TYPE_I_PCM = (uint32_t) (1 << 0), - AUDIO20_DATA_FORMAT_TYPE_I_PCM8 = (uint32_t) (1 << 1), - AUDIO20_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), - AUDIO20_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), - AUDIO20_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), + AUDIO20_DATA_FORMAT_TYPE_I_PCM = 1 << 0, + AUDIO20_DATA_FORMAT_TYPE_I_PCM8 = 1 << 1, + AUDIO20_DATA_FORMAT_TYPE_I_IEEE_FLOAT = 1 << 2, + AUDIO20_DATA_FORMAT_TYPE_I_ALAW = 1 << 3, + AUDIO20_DATA_FORMAT_TYPE_I_MULAW = 1 << 4, AUDIO20_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000u, } audio20_data_format_type_I_t; -- cgit v1.3.1 From 1f04fe7924e8777c1583323171c0e1cabcb29062 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 5 Nov 2025 15:31:02 +0700 Subject: added .clang-format fix more alerts disable IAR CStat since pvs-studio check is better integrated with clion --- .PVS-Studio/.pvsconfig | 13 +- .clang-format | 102 ++++++---- .github/workflows/static_analysis.yml | 3 +- README.rst | 6 +- examples/device/audio_4_channel_mic/src/main.c | 8 +- .../src/usb_descriptors.c | 8 +- examples/device/audio_test/src/main.c | 8 +- examples/device/audio_test/src/usb_descriptors.c | 8 +- .../audio_test_freertos/src/usb_descriptors.c | 8 +- examples/device/audio_test_multi_rate/src/main.c | 8 +- .../audio_test_multi_rate/src/usb_descriptors.c | 8 +- examples/device/cdc_dual_ports/src/main.c | 12 +- examples/device/cdc_msc/src/msc_disk.c | 28 ++- examples/device/cdc_uac2/src/uac2_app.c | 28 +-- examples/device/cdc_uac2/src/usb_descriptors.c | 8 +- examples/device/dfu/src/usb_descriptors.c | 8 +- examples/device/dfu_runtime/src/main.c | 4 +- examples/device/dfu_runtime/src/usb_descriptors.c | 8 +- examples/device/dynamic_configuration/src/main.c | 56 +++--- .../device/dynamic_configuration/src/msc_disk.c | 14 +- .../dynamic_configuration/src/usb_descriptors.c | 8 +- examples/device/hid_boot_interface/src/main.c | 147 +++++++------- .../hid_boot_interface/src/usb_descriptors.c | 124 ++++++------ examples/device/hid_composite/src/main.c | 211 ++++++++++----------- examples/device/mtp/src/mtp_fs_example.c | 90 +++++---- hw/bsp/family_support.cmake | 8 +- src/class/mtp/mtp.h | 14 +- src/class/mtp/mtp_device.h | 10 +- src/class/video/video.h | 10 +- src/common/tusb_common.h | 7 +- src/common/tusb_debug.h | 4 +- src/device/usbd_control.c | 6 +- src/device/usbd_pvt.h | 5 - src/tusb.c | 4 +- 34 files changed, 523 insertions(+), 471 deletions(-) (limited to '.github/workflows') diff --git a/.PVS-Studio/.pvsconfig b/.PVS-Studio/.pvsconfig index 32125c2f7..2e231c939 100644 --- a/.PVS-Studio/.pvsconfig +++ b/.PVS-Studio/.pvsconfig @@ -1,3 +1,10 @@ -//-V::2506 -//-V::2514 -//-V::2614 +//V_EXCLUDE_PATH */iar/cxarm* +//V_EXCLUDE_PATH */pico-sdk/* + +//-V::2506 MISRA. A function should have a single point of exit at the end. +//-V::2514 MISRA. Unions should not be used. +//-V:memcpy:2547 [MISRA-C-17.7] The return value of non-void function 'memcpy' should be used. +//-V:printf:2547 [MISRA-C-17.7] The return value of non-void function 'printf' should be used. +//-V::2600 [MISRA-C-21.6] The function with the 'printf' name should not be used. +//+V2614 DISABLE_LENGHT_LIMIT_CHECK:YES +//-V:memcpy:2628 Pointer arguments to the 'memcpy' function should be pointers to qualified or unqualified versions of compatible types. diff --git a/.clang-format b/.clang-format index 0fd168e5a..79a160a8d 100644 --- a/.clang-format +++ b/.clang-format @@ -1,66 +1,88 @@ -# Generated from CLion C/C++ Code Style settings +--- +Language: Cpp BasedOnStyle: LLVM -AccessModifierOffset: -2 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: None -AlignOperands: Align +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveAssignments: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false +AlignConsecutiveBitFields: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false +AlignConsecutiveDeclarations: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false +AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: true + AcrossComments: false +AlignConsecutiveShortCaseStatements: + Enabled: true + AcrossEmptyLines: true + AcrossComments: true + AlignCaseColons: false +AlignEscapedNewlines: LeftWithLastLine +AlignOperands: true +AlignTrailingComments: + Kind: Always + OverEmptyLines: 2 AllowAllArgumentsOnNextLine: false AllowAllConstructorInitializersOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: Always -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Always -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: true -AlwaysBreakAfterReturnType: None +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseExpressionOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never AlwaysBreakTemplateDeclarations: Yes BreakBeforeBraces: Custom BraceWrapping: AfterCaseLabel: false AfterClass: false - AfterControlStatement: Never + AfterControlStatement: false AfterEnum: false AfterFunction: false AfterNamespace: false + AfterStruct: false AfterUnion: false - BeforeCatch: false + AfterExternBlock: false + BeforeCatch: true BeforeElse: false - IndentBraces: false - SplitEmptyFunction: false + BeforeLambdaBody: false + BeforeWhile: false + SplitEmptyFunction: true SplitEmptyRecord: true -BreakBeforeBinaryOperators: None -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeColon -BreakInheritanceList: BeforeColon -ColumnLimit: 0 -CompactNamespaces: false -ContinuationIndentWidth: 4 + SplitEmptyNamespace: true +BracedInitializerIndentWidth: 2 +BreakConstructorInitializers: AfterColon +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 120 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +Cpp11BracedListStyle: true +IncludeCategories: + - Regex: '^<.*' + Priority: 1 + - Regex: '^".*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +InsertBraces: true IndentCaseLabels: true -IndentPPDirectives: BeforeHash -IndentWidth: 2 -KeepEmptyLinesAtTheStartOfBlocks: true +InsertNewlineAtEOF: true +MacroBlockBegin: '' +MacroBlockEnd: '' MaxEmptyLinesToKeep: 2 NamespaceIndentation: All -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PointerAlignment: Right ReflowComments: false -SpaceAfterCStyleCast: true -SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: false -SpaceBeforeAssignmentOperators: true -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements SpaceBeforeRangeBasedForLoopColon: false SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 0 SpacesInAngles: false +SpacesInConditionalStatement: false SpacesInCStyleCastParentheses: false -SpacesInContainerLiterals: true SpacesInParentheses: false -SpacesInSquareBrackets: false TabWidth: 2 -UseTab: Never +... diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 7e74f77ce..227f5e103 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -183,7 +183,8 @@ jobs: --define sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json IAR-CStat: - if: github.repository_owner == 'hathach' + #if: github.repository_owner == 'hathach' + if: false runs-on: ubuntu-latest strategy: fail-fast: false diff --git a/README.rst b/README.rst index 38ebcc8da..fcec5d613 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -|Build Status| |CircleCI Status| |Documentation Status| |Fuzzing Status| |License| +|Build Status| |CircleCI Status| |Documentation Status| |Static Analysis| |Fuzzing Status| |License| Sponsors ======== @@ -252,11 +252,13 @@ The following tools are provided freely to support the development of the TinyUS .. |Build Status| image:: https://github.com/hathach/tinyusb/actions/workflows/build.yml/badge.svg - :target: https://github.com/hathach/tinyusb/actions + :target: https://github.com/hathach/tinyusb/actions/workflows/build.yml .. |CircleCI Status| image:: https://dl.circleci.com/status-badge/img/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master.svg?style=svg :target: https://dl.circleci.com/status-badge/redirect/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master .. |Documentation Status| image:: https://readthedocs.org/projects/tinyusb/badge/?version=latest :target: https://docs.tinyusb.org/en/latest/?badge=latest +.. |Static Analysis| image:: https://github.com/hathach/tinyusb/actions/workflows/static_analysis.yml/badge.svg + :target: https://github.com/hathach/tinyusb/actions/workflows/static_analysis.yml .. |Fuzzing Status| image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/tinyusb.svg :target: https://oss-fuzz-build-logs.storage.googleapis.com/index.html#tinyusb .. |License| image:: https://img.shields.io/badge/license-MIT-brightgreen.svg diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index de9e8a06a..5767c7453 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -156,7 +156,9 @@ void tud_resume_cb(void) { void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = board_millis(); - if (start_ms == curr_ms) return;// not enough time + if (start_ms == curr_ms) { + return; // not enough time + } start_ms = curr_ms; tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX); } @@ -406,7 +408,9 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return;// not enough time + if (board_millis() - start_ms < blink_interval_ms) { + return; // not enough time + } start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c index 2f5f67f66..3bb93f67d 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c @@ -156,14 +156,18 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if ( chr_count > max_count ) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { diff --git a/examples/device/audio_test/src/main.c b/examples/device/audio_test/src/main.c index 875d0b7f0..2441eefbc 100644 --- a/examples/device/audio_test/src/main.c +++ b/examples/device/audio_test/src/main.c @@ -139,7 +139,9 @@ void tud_resume_cb(void) { void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = board_millis(); - if (start_ms == curr_ms) return;// not enough time + if (start_ms == curr_ms) { + return; // not enough time + } start_ms = curr_ms; for (size_t cnt = 0; cnt < sizeof(test_buffer_audio) / 2; cnt++) { test_buffer_audio[cnt] = startVal++; @@ -400,7 +402,9 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return;// not enough time + if (board_millis() - start_ms < blink_interval_ms) { + return; // not enough time + } start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/audio_test/src/usb_descriptors.c b/examples/device/audio_test/src/usb_descriptors.c index b6c19deba..ad161939e 100644 --- a/examples/device/audio_test/src/usb_descriptors.c +++ b/examples/device/audio_test/src/usb_descriptors.c @@ -158,14 +158,18 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { diff --git a/examples/device/audio_test_freertos/src/usb_descriptors.c b/examples/device/audio_test_freertos/src/usb_descriptors.c index b6c19deba..ad161939e 100644 --- a/examples/device/audio_test_freertos/src/usb_descriptors.c +++ b/examples/device/audio_test_freertos/src/usb_descriptors.c @@ -158,14 +158,18 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { diff --git a/examples/device/audio_test_multi_rate/src/main.c b/examples/device/audio_test_multi_rate/src/main.c index 55a649613..baeec870f 100644 --- a/examples/device/audio_test_multi_rate/src/main.c +++ b/examples/device/audio_test_multi_rate/src/main.c @@ -147,7 +147,9 @@ void tud_resume_cb(void) { void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = board_millis(); - if (start_ms == curr_ms) return;// not enough time + if (start_ms == curr_ms) { + return; // not enough time + } start_ms = curr_ms; // 16bit if (bytesPerSample == 2) { @@ -612,7 +614,9 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return;// not enough time + if (board_millis() - start_ms < blink_interval_ms) { + return; // not enough time + } start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/audio_test_multi_rate/src/usb_descriptors.c b/examples/device/audio_test_multi_rate/src/usb_descriptors.c index 1912a81e2..471eb4f2e 100644 --- a/examples/device/audio_test_multi_rate/src/usb_descriptors.c +++ b/examples/device/audio_test_multi_rate/src/usb_descriptors.c @@ -213,14 +213,18 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index 8fe003f21..5ccb06a8a 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -75,10 +75,14 @@ static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) { for (uint32_t i = 0; i < count; i++) { if (itf == 0) { // echo back 1st port as lower case - if (isupper(buf[i])) buf[i] += case_diff; + if (isupper(buf[i])) { + buf[i] += case_diff; + } } else { // echo back 2nd port as upper case - if (islower(buf[i])) buf[i] -= case_diff; + if (islower(buf[i])) { + buf[i] -= case_diff; + } } tud_cdc_n_write_char(itf, buf[i]); @@ -153,7 +157,9 @@ void led_blinking_task(void) { static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) { + return; // not enough time + } start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/cdc_msc/src/msc_disk.c b/examples/device/cdc_msc/src/msc_disk.c index 1a95f7f8b..e091c2985 100644 --- a/examples/device/cdc_msc/src/msc_disk.c +++ b/examples/device/cdc_msc/src/msc_disk.c @@ -128,9 +128,9 @@ uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t *inquiry_resp, uin const char pid[] = "Mass Storage"; const char rev[] = "1.0"; - strncpy((char*) inquiry_resp->vendor_id, vid, 8); - strncpy((char*) inquiry_resp->product_id, pid, 16); - strncpy((char*) inquiry_resp->product_rev, rev, 4); + (void) strncpy((char*) inquiry_resp->vendor_id, vid, 8); + (void) strncpy((char*) inquiry_resp->product_id, pid, 16); + (void) strncpy((char*) inquiry_resp->product_rev, rev, 4); return sizeof(scsi_inquiry_resp_t); // 36 bytes } @@ -143,8 +143,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) { // RAM disk is ready until ejected if (ejected) { // Additional Sense 3A-00 is NOT_FOUND - tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); - return false; + return tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); } return true; @@ -154,7 +153,6 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) { // Application update block count and block size void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) { (void) lun; - *block_count = DISK_BLOCK_NUM; *block_size = DISK_BLOCK_SIZE; } @@ -194,7 +192,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buff } uint8_t const *addr = msc_disk[lba] + offset; - memcpy(buffer, addr, bufsize); + (void) memcpy(buffer, addr, bufsize); return (int32_t) bufsize; } @@ -221,7 +219,7 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t * #ifndef CFG_EXAMPLE_MSC_READONLY uint8_t *addr = msc_disk[lba] + offset; - memcpy(addr, buffer, bufsize); + (void) memcpy(addr, buffer, bufsize); #else (void) lba; (void) offset; @@ -235,19 +233,17 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t * // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE // - READ10 and WRITE10 has their own callbacks int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) { + (void) lun; + (void) scsi_cmd; (void) buffer; (void) bufsize; - switch (scsi_cmd[0]) { - default: - // Set Sense = Invalid Command Operation - tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + // currently no other commands is supported - // negative means error -> tinyusb could stall and/or response with failed status - return -1; - } + // Set Sense = Invalid Command Operation + (void) tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); - return -1; + return -1; // stall/failed command request; } #endif diff --git a/examples/device/cdc_uac2/src/uac2_app.c b/examples/device/cdc_uac2/src/uac2_app.c index cb7b716e8..73a262d0c 100644 --- a/examples/device/cdc_uac2/src/uac2_app.c +++ b/examples/device/cdc_uac2/src/uac2_app.c @@ -67,7 +67,9 @@ uint8_t current_resolution; void audio_task(void) { static uint32_t start_ms = 0; uint32_t curr_ms = board_millis(); - if (start_ms == curr_ms) return;// not enough time + if (start_ms == curr_ms) { + return; // not enough time + } start_ms = curr_ms; // When new data arrived, copy data from speaker buffer, to microphone buffer // and send it over @@ -226,16 +228,15 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio20_control_r //--------------------------------------------------------------------+ // Invoked when audio class specific get request received for an entity -bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) -{ +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { audio20_control_request_t const *request = (audio20_control_request_t const *)p_request; - if (request->bEntityID == UAC2_ENTITY_CLOCK) + if (request->bEntityID == UAC2_ENTITY_CLOCK) { return tud_audio_clock_get_request(rhport, request); - if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) + } + if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) { return tud_audio_feature_unit_get_request(rhport, request); - else - { + } else { TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); } @@ -243,14 +244,15 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p } // Invoked when audio class specific set request received for an entity -bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) -{ +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) { audio20_control_request_t const *request = (audio20_control_request_t const *)p_request; - if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) + if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) { return tud_audio_feature_unit_set_request(rhport, request, buf); - if (request->bEntityID == UAC2_ENTITY_CLOCK) + } + if (request->bEntityID == UAC2_ENTITY_CLOCK) { return tud_audio_clock_set_request(rhport, request, buf); + } TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); @@ -301,7 +303,9 @@ void led_blinking_task(void) static bool led_state = false; // Blink every interval ms - if (board_millis() - start_ms < blink_interval_ms) return; + if (board_millis() - start_ms < blink_interval_ms) { + return; + } start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c index 252b602ac..e6caaa971 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.c +++ b/examples/device/cdc_uac2/src/usb_descriptors.c @@ -248,14 +248,18 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { diff --git a/examples/device/dfu/src/usb_descriptors.c b/examples/device/dfu/src/usb_descriptors.c index 14ec315ea..48c9985f3 100644 --- a/examples/device/dfu/src/usb_descriptors.c +++ b/examples/device/dfu/src/usb_descriptors.c @@ -158,14 +158,18 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { diff --git a/examples/device/dfu_runtime/src/main.c b/examples/device/dfu_runtime/src/main.c index 37cb80093..5de651bcd 100644 --- a/examples/device/dfu_runtime/src/main.c +++ b/examples/device/dfu_runtime/src/main.c @@ -132,7 +132,9 @@ void led_blinking_task(void) static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) { + return; // not enough time + } start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/dfu_runtime/src/usb_descriptors.c b/examples/device/dfu_runtime/src/usb_descriptors.c index 1d46ee252..5d5cf52cd 100644 --- a/examples/device/dfu_runtime/src/usb_descriptors.c +++ b/examples/device/dfu_runtime/src/usb_descriptors.c @@ -153,14 +153,18 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { diff --git a/examples/device/dynamic_configuration/src/main.c b/examples/device/dynamic_configuration/src/main.c index 258cfcd02..dac74bb7a 100644 --- a/examples/device/dynamic_configuration/src/main.c +++ b/examples/device/dynamic_configuration/src/main.c @@ -109,23 +109,18 @@ void tud_resume_cb(void) //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ -void cdc_task(void) -{ - if ( tud_cdc_connected() ) - { - // connected and there are data available - if ( tud_cdc_available() ) - { +void cdc_task(void) { + if (tud_cdc_connected()) { + // connected and there are data available read and echo back + if (tud_cdc_available()) { uint8_t buf[64]; - - // read and echo back uint32_t count = tud_cdc_read(buf, sizeof(buf)); - for(uint32_t i=0; i= sizeof(note_sequence)) note_pos = 0; + if (note_pos >= sizeof(note_sequence)) { + note_pos = 0; + } } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) { + return;// not enough time + } start_ms += blink_interval_ms; board_led_write(led_state); - led_state = 1 - led_state; // toggle + led_state = 1 - led_state;// toggle } diff --git a/examples/device/dynamic_configuration/src/msc_disk.c b/examples/device/dynamic_configuration/src/msc_disk.c index ab71b02d6..e95b2e197 100644 --- a/examples/device/dynamic_configuration/src/msc_disk.c +++ b/examples/device/dynamic_configuration/src/msc_disk.c @@ -177,12 +177,13 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo // Callback invoked when received READ10 command. // Copy disk's data to buffer (up to bufsize) and return number of copied bytes. -int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) -{ +int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { (void) lun; // out of ramdisk - if ( lba >= DISK_BLOCK_NUM ) return -1; + if ( lba >= DISK_BLOCK_NUM ) { + return -1; + } uint8_t const* addr = msc_disk[lba] + offset; memcpy(buffer, addr, bufsize); @@ -192,12 +193,13 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes -int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) -{ +int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { (void) lun; // out of ramdisk - if ( lba >= DISK_BLOCK_NUM ) return -1; + if ( lba >= DISK_BLOCK_NUM ) { + return -1; + } #ifndef CFG_EXAMPLE_MSC_READONLY uint8_t* addr = msc_disk[lba] + offset; diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 083279938..458b7c2a5 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -232,14 +232,18 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 for ( size_t i = 0; i < chr_count; i++ ) { diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 45712cede..44a91db67 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -23,8 +23,8 @@ * */ -#include #include +#include #include #include "bsp/board_api.h" @@ -40,10 +40,10 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, - BLINK_MOUNTED = 1000, - BLINK_SUSPENDED = 2500, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; @@ -52,21 +52,16 @@ void led_blinking_task(void); void hid_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port - tusb_rhport_init_t dev_init = { - .role = TUSB_ROLE_DEVICE, - .speed = TUSB_SPEED_AUTO - }; + tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); - while (1) - { + while (1) { tud_task(); // tinyusb device task led_blinking_task(); @@ -81,29 +76,25 @@ int main(void) //--------------------------------------------------------------------+ // Invoked when device is mounted -void tud_mount_cb(void) -{ +void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted -void tud_umount_cb(void) -{ +void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ - (void) remote_wakeup_en; +void tud_suspend_cb(bool remote_wakeup_en) { + (void)remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed -void tud_resume_cb(void) -{ +void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } @@ -113,59 +104,54 @@ void tud_resume_cb(void) // Every 10ms, we will sent 1 report for each HID profile (keyboard, mouse etc ..) // tud_hid_report_complete_cb() is used to send the next report after previous one is complete -void hid_task(void) -{ +void hid_task(void) { // Poll every 10ms - const uint32_t interval_ms = 10; - static uint32_t start_ms = 0; + const uint32_t interval_ms = 10; + static uint32_t start_ms = 0; - if ( board_millis() - start_ms < interval_ms) return; // not enough time + if (board_millis() - start_ms < interval_ms) { + return; // not enough time + } start_ms += interval_ms; uint32_t const btn = board_button_read(); - if ( tud_suspended() && btn ) - { + if (tud_suspended() && btn) { // Wake up host if we are in suspend mode // and REMOTE_WAKEUP feature is enabled by host tud_remote_wakeup(); - } - else - { + } else { // keyboard interface - if ( tud_hid_n_ready(ITF_NUM_KEYBOARD) ) - { + if (tud_hid_n_ready(ITF_NUM_KEYBOARD)) { // used to avoid send multiple consecutive zero report for keyboard static bool has_keyboard_key = false; uint8_t const report_id = 0; uint8_t const modifier = 0; - if ( btn ) - { - uint8_t keycode[6] = { 0 }; - keycode[0] = HID_KEY_ARROW_RIGHT; + if (btn) { + uint8_t keycode[6] = {0}; + keycode[0] = HID_KEY_ARROW_RIGHT; tud_hid_n_keyboard_report(ITF_NUM_KEYBOARD, report_id, modifier, keycode); has_keyboard_key = true; - }else - { + } else { // send empty key report if previously has key pressed - if (has_keyboard_key) tud_hid_n_keyboard_report(ITF_NUM_KEYBOARD, report_id, modifier, NULL); + if (has_keyboard_key) { + tud_hid_n_keyboard_report(ITF_NUM_KEYBOARD, report_id, modifier, NULL); + } has_keyboard_key = false; } } // mouse interface - if ( tud_hid_n_ready(ITF_NUM_MOUSE) ) - { - if ( btn ) - { + if (tud_hid_n_ready(ITF_NUM_MOUSE)) { + if (btn) { uint8_t const report_id = 0; uint8_t const button_mask = 0; - int8_t const vertical = 0; - int8_t const horizontal = 0; - int8_t const delta = 5; + int8_t const vertical = 0; + int8_t const horizontal = 0; + int8_t const delta = 5; tud_hid_n_mouse_report(ITF_NUM_MOUSE, report_id, button_mask, delta, delta, vertical, horizontal); } @@ -175,10 +161,9 @@ void hid_task(void) // Invoked when received SET_PROTOCOL request // protocol is either HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) -void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) -{ - (void) instance; - (void) protocol; +void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) { + (void)instance; + (void)protocol; // nothing to do since we use the same compatible boot report for both Boot and Report mode. // TODO set a indicator for user @@ -187,11 +172,10 @@ void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) -{ - (void) instance; - (void) report; - (void) len; +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, uint16_t len) { + (void)instance; + (void)report; + (void)len; // nothing to do } @@ -199,42 +183,40 @@ void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_ // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request -uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) -{ +uint16_t tud_hid_get_report_cb( + uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) { // TODO not Implemented - (void) instance; - (void) report_id; - (void) report_type; - (void) buffer; - (void) reqlen; + (void)instance; + (void)report_id; + (void)report_type; + (void)buffer; + (void)reqlen; return 0; } // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) -void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) -{ - (void) report_id; +void tud_hid_set_report_cb( + uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { + (void)report_id; // keyboard interface - if (instance == ITF_NUM_KEYBOARD) - { + if (instance == ITF_NUM_KEYBOARD) { // Set keyboard LED e.g Capslock, Numlock etc... - if (report_type == HID_REPORT_TYPE_OUTPUT) - { + if (report_type == HID_REPORT_TYPE_OUTPUT) { // bufsize should be (at least) 1 - if ( bufsize < 1 ) return; + if (bufsize < 1) { + return; + } uint8_t const kbd_leds = buffer[0]; - if (kbd_leds & KEYBOARD_LED_CAPSLOCK) - { + if (kbd_leds & KEYBOARD_LED_CAPSLOCK) { // Capslock On: disable blink, turn led on blink_interval_ms = 0; board_led_write(true); - }else - { + } else { // Caplocks Off: back to normal blink board_led_write(false); blink_interval_ms = BLINK_MOUNTED; @@ -246,16 +228,19 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_ //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ - static uint32_t start_ms = 0; - static bool led_state = false; +void led_blinking_task(void) { + static uint32_t start_ms = 0; + static bool led_state = false; // blink is disabled - if (!blink_interval_ms) return; + if (!blink_interval_ms) { + return; + } // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) { + return; // not enough time + } start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/hid_boot_interface/src/usb_descriptors.c b/examples/device/hid_boot_interface/src/usb_descriptors.c index 9b4becc85..b5c31a94a 100644 --- a/examples/device/hid_boot_interface/src/usb_descriptors.c +++ b/examples/device/hid_boot_interface/src/usb_descriptors.c @@ -33,60 +33,49 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ - PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4)) //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -static tusb_desc_device_t const desc_device = -{ - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0200, - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - - .idVendor = 0xCafe, - .idProduct = USB_PID, - .bcdDevice = 0x0100, - - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, - - .bNumConfigurations = 0x01 -}; +static tusb_desc_device_t const desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01}; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ - return (uint8_t const *) &desc_device; +uint8_t const *tud_descriptor_device_cb(void) { + return (uint8_t const *)&desc_device; } //--------------------------------------------------------------------+ // HID Report Descriptor //--------------------------------------------------------------------+ -uint8_t const desc_hid_keyboard_report[] = -{ - TUD_HID_REPORT_DESC_KEYBOARD() -}; +uint8_t const desc_hid_keyboard_report[] = {TUD_HID_REPORT_DESC_KEYBOARD()}; -uint8_t const desc_hid_mouse_report[] = -{ - TUD_HID_REPORT_DESC_MOUSE() -}; +uint8_t const desc_hid_mouse_report[] = {TUD_HID_REPORT_DESC_MOUSE()}; // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) -{ +uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance) { return (instance == 0) ? desc_hid_keyboard_report : desc_hid_mouse_report; } @@ -94,36 +83,37 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) // Configuration Descriptor //--------------------------------------------------------------------+ -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + 2*TUD_HID_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + 2 * TUD_HID_DESC_LEN) #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX - // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number - // 1 Interrupt, 2 Bulk, 3 Iso, 4 Interrupt, 5 Bulk etc ... - #define EPNUM_KEYBOARD 0x81 - #define EPNUM_MOUSE 0x84 +// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number +// 1 Interrupt, 2 Bulk, 3 Iso, 4 Interrupt, 5 Bulk etc ... +#define EPNUM_KEYBOARD 0x81 +#define EPNUM_MOUSE 0x84 #else - #define EPNUM_KEYBOARD 0x81 - #define EPNUM_MOUSE 0x82 +#define EPNUM_KEYBOARD 0x81 +#define EPNUM_MOUSE 0x82 #endif -uint8_t const desc_configuration[] = -{ +uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval - TUD_HID_DESCRIPTOR(ITF_NUM_KEYBOARD, 0, HID_ITF_PROTOCOL_KEYBOARD, sizeof(desc_hid_keyboard_report), EPNUM_KEYBOARD, CFG_TUD_HID_EP_BUFSIZE, 10), + TUD_HID_DESCRIPTOR( + ITF_NUM_KEYBOARD, 0, HID_ITF_PROTOCOL_KEYBOARD, sizeof(desc_hid_keyboard_report), EPNUM_KEYBOARD, + CFG_TUD_HID_EP_BUFSIZE, 10), // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval - TUD_HID_DESCRIPTOR(ITF_NUM_MOUSE, 0, HID_ITF_PROTOCOL_MOUSE, sizeof(desc_hid_mouse_report), EPNUM_MOUSE, CFG_TUD_HID_EP_BUFSIZE, 10) -}; + TUD_HID_DESCRIPTOR( + ITF_NUM_MOUSE, 0, HID_ITF_PROTOCOL_MOUSE, sizeof(desc_hid_mouse_report), EPNUM_MOUSE, CFG_TUD_HID_EP_BUFSIZE, + 10)}; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ - (void) index; // for multiple configurations +uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { + (void)index; // for multiple configurations return desc_configuration; } @@ -140,12 +130,11 @@ enum { }; // array of pointer to string descriptors -static char const *string_desc_arr[] = -{ - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "TinyUSB", // 1: Manufacturer - "TinyUSB Device", // 2: Product - NULL, // 3: Serials will use unique ID if possible +static char const *string_desc_arr[] = { + (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serials will use unique ID if possible }; static uint16_t _desc_str[32 + 1]; @@ -153,41 +142,44 @@ static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - (void) langid; + (void)langid; size_t chr_count; - switch ( index ) { + switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; break; - case STRID_SERIAL: - chr_count = board_usb_get_serial(_desc_str + 1, 32); - break; + case STRID_SERIAL: chr_count = board_usb_get_serial(_desc_str + 1, 32); break; default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } const char *str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) { + chr_count = max_count; + } // Convert ASCII string into UTF-16 - for ( size_t i = 0; i < chr_count; i++ ) { + for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; } // first byte is length (including header), second byte is string type - _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index 89dab0bdc..9693d564d 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -23,8 +23,8 @@ * */ -#include #include +#include #include #include "bsp/board_api.h" @@ -41,10 +41,10 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, - BLINK_MOUNTED = 1000, - BLINK_SUSPENDED = 2500, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, }; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; @@ -53,24 +53,18 @@ void led_blinking_task(void); void hid_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port - tusb_rhport_init_t dev_init = { - .role = TUSB_ROLE_DEVICE, - .speed = TUSB_SPEED_AUTO - }; + tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); board_init_after_tusb(); - while (1) - { + while (1) { tud_task(); // tinyusb device task led_blinking_task(); - hid_task(); } } @@ -80,29 +74,25 @@ int main(void) //--------------------------------------------------------------------+ // Invoked when device is mounted -void tud_mount_cb(void) -{ +void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted -void tud_umount_cb(void) -{ +void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ - (void) remote_wakeup_en; +void tud_suspend_cb(bool remote_wakeup_en) { + (void)remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed -void tud_resume_cb(void) -{ +void tud_resume_cb(void) { blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } @@ -110,138 +100,128 @@ void tud_resume_cb(void) // USB HID //--------------------------------------------------------------------+ -static void send_hid_report(uint8_t report_id, uint32_t btn) -{ +static void send_hid_report(uint8_t report_id, uint32_t btn) { // skip if hid is not ready yet - if ( !tud_hid_ready() ) return; + if (!tud_hid_ready()) { + return; + } - switch(report_id) - { - case REPORT_ID_KEYBOARD: - { + switch (report_id) { + case REPORT_ID_KEYBOARD: { // use to avoid send multiple consecutive zero report for keyboard static bool has_keyboard_key = false; - if ( btn ) - { - uint8_t keycode[6] = { 0 }; - keycode[0] = HID_KEY_A; + if (btn != 0u) { + uint8_t keycode[6] = {0}; + keycode[0] = HID_KEY_A; tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode); has_keyboard_key = true; - }else - { + } else { // send empty key report if previously has key pressed - if (has_keyboard_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL); + if (has_keyboard_key) { + tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL); + } has_keyboard_key = false; } + break; } - break; - case REPORT_ID_MOUSE: - { + case REPORT_ID_MOUSE: { int8_t const delta = 5; // no button, right + down, no scroll, no pan tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0); + break; } - break; - case REPORT_ID_CONSUMER_CONTROL: - { + case REPORT_ID_CONSUMER_CONTROL: { // use to avoid send multiple consecutive zero report static bool has_consumer_key = false; - if ( btn ) - { + if (btn != 0u) { // volume down uint16_t volume_down = HID_USAGE_CONSUMER_VOLUME_DECREMENT; tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &volume_down, 2); has_consumer_key = true; - }else - { + } else { // send empty key report (release key) if previously has key pressed uint16_t empty_key = 0; - if (has_consumer_key) tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &empty_key, 2); + if (has_consumer_key) { + tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &empty_key, 2); + } has_consumer_key = false; } + break; } - break; - case REPORT_ID_GAMEPAD: - { + case REPORT_ID_GAMEPAD: { // use to avoid send multiple consecutive zero report for keyboard static bool has_gamepad_key = false; - hid_gamepad_report_t report = - { - .x = 0, .y = 0, .z = 0, .rz = 0, .rx = 0, .ry = 0, - .hat = 0, .buttons = 0 - }; + hid_gamepad_report_t report = {.x = 0, .y = 0, .z = 0, .rz = 0, .rx = 0, .ry = 0, .hat = 0, .buttons = 0}; - if ( btn ) - { - report.hat = GAMEPAD_HAT_UP; + if (btn != 0u) { + report.hat = GAMEPAD_HAT_UP; report.buttons = GAMEPAD_BUTTON_A; tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report)); has_gamepad_key = true; - }else - { - report.hat = GAMEPAD_HAT_CENTERED; + } else { + report.hat = GAMEPAD_HAT_CENTERED; report.buttons = 0; - if (has_gamepad_key) tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report)); + if (has_gamepad_key) { + tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report)); + } has_gamepad_key = false; } + break; } - break; case REPORT_ID_STYLUS_PEN: { - static bool touch_state = false; - hid_stylus_report_t report = { - .attr = 0, - .x = 0, - .y = 0 - }; - - if (btn) { + static bool touch_state = false; + hid_stylus_report_t report = {.attr = 0, .x = 0, .y = 0}; + + if (btn != 0u) { report.attr = STYLUS_ATTR_TIP_SWITCH | STYLUS_ATTR_IN_RANGE; - report.x = 100; - report.y = 100; + report.x = 100; + report.y = 100; tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report)); touch_state = true; } else { report.attr = 0; - if (touch_state) tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report)); + if (touch_state) { + tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report)); + } touch_state = false; } + break; } - break; - default: break; + + default: break; // unknown report id } } // Every 10ms, we will sent 1 report for each HID profile (keyboard, mouse etc ..) // tud_hid_report_complete_cb() is used to send the next report after previous one is complete -void hid_task(void) -{ +void hid_task(void) { // Poll every 10ms - const uint32_t interval_ms = 10; - static uint32_t start_ms = 0; + const uint32_t interval_ms = 10; + static uint32_t start_ms = 0; - if ( board_millis() - start_ms < interval_ms) return; // not enough time + if (board_millis() - start_ms < interval_ms) { + return; // not enough time + } start_ms += interval_ms; uint32_t const btn = board_button_read(); // Remote wakeup - if ( tud_suspended() && btn ) - { + if (tud_suspended() && btn != 0u) { // Wake up host if we are in suspend mode // and REMOTE_WAKEUP feature is enabled by host tud_remote_wakeup(); - }else - { + } else { // Send the 1st of report chain, the rest will be sent by tud_hid_report_complete_cb() send_hid_report(REPORT_ID_KEYBOARD, btn); } @@ -250,15 +230,13 @@ void hid_task(void) // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) -{ - (void) instance; - (void) len; +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, uint16_t len) { + (void)instance; + (void)len; uint8_t next_report_id = report[0] + 1u; - if (next_report_id < REPORT_ID_COUNT) - { + if (next_report_id < REPORT_ID_COUNT) { send_hid_report(next_report_id, board_button_read()); } } @@ -266,41 +244,39 @@ void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_ // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request -uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) -{ +uint16_t tud_hid_get_report_cb( + uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) { // TODO not Implemented - (void) instance; - (void) report_id; - (void) report_type; - (void) buffer; - (void) reqlen; + (void)instance; + (void)report_id; + (void)report_type; + (void)buffer; + (void)reqlen; return 0; } // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) -void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) -{ - (void) instance; +void tud_hid_set_report_cb( + uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { + (void)instance; - if (report_type == HID_REPORT_TYPE_OUTPUT) - { + if (report_type == HID_REPORT_TYPE_OUTPUT) { // Set keyboard LED e.g Capslock, Numlock etc... - if (report_id == REPORT_ID_KEYBOARD) - { + if (report_id == REPORT_ID_KEYBOARD) { // bufsize should be (at least) 1 - if ( bufsize < 1 ) return; + if (bufsize < 1) { + return; + } uint8_t const kbd_leds = buffer[0]; - if (kbd_leds & KEYBOARD_LED_CAPSLOCK) - { + if ((kbd_leds & KEYBOARD_LED_CAPSLOCK) != 0u) { // Capslock On: disable blink, turn led on blink_interval_ms = 0; board_led_write(true); - }else - { + } else { // Caplocks Off: back to normal blink board_led_write(false); blink_interval_ms = BLINK_MOUNTED; @@ -312,16 +288,19 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_ //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ - static uint32_t start_ms = 0; - static bool led_state = false; +void led_blinking_task(void) { + static uint32_t start_ms = 0; + static bool led_state = false; // blink is disabled - if (!blink_interval_ms) return; + if (0u == blink_interval_ms) { + return; + } // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) { + return; // not enough time + } start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/mtp/src/mtp_fs_example.c b/examples/device/mtp/src/mtp_fs_example.c index b4772f146..1c287be4d 100644 --- a/examples/device/mtp/src/mtp_fs_example.c +++ b/examples/device/mtp/src/mtp_fs_example.c @@ -39,12 +39,15 @@ #define DEV_PROP_FRIENDLY_NAME "TinyUSB MTP" //------------- storage info -------------// -#define STORAGE_DESCRIPTRION { 'd', 'i', 's', 'k', 0 } +#define STORAGE_DESCRIPTION { 'd', 'i', 's', 'k', 0 } #define VOLUME_IDENTIFIER { 'v', 'o', 'l', 0 } -typedef MTP_STORAGE_INFO_STRUCT(TU_ARRAY_SIZE((uint16_t[]) STORAGE_DESCRIPTRION), - TU_ARRAY_SIZE(((uint16_t[])VOLUME_IDENTIFIER)) -) storage_info_t; +enum { + STORAGE_DESC_LEN = TU_ARRAY_SIZE((uint16_t[]) STORAGE_DESCRIPTION), + VOLUME_ID_LEN = TU_ARRAY_SIZE((uint16_t[])VOLUME_IDENTIFIER) +}; + +typedef MTP_STORAGE_INFO_STRUCT(STORAGE_DESC_LEN, VOLUME_ID_LEN) storage_info_t; storage_info_t storage_info = { #ifdef CFG_EXAMPLE_MTP_READONLY @@ -60,7 +63,7 @@ storage_info_t storage_info = { .free_space_in_objects = 0, // calculated at runtime .storage_description = { .count = (TU_FIELD_SIZE(storage_info_t, storage_description)-1) / sizeof(uint16_t), - .utf16 = STORAGE_DESCRIPTRION + .utf16 = STORAGE_DESCRIPTION }, .volume_identifier = { .count = (TU_FIELD_SIZE(storage_info_t, volume_identifier)-1) / sizeof(uint16_t), @@ -320,9 +323,9 @@ int32_t tud_mtp_data_complete_cb(tud_mtp_cb_data_t* cb_data) { break; } // parameter is: storage id, parent handle, new handle - mtp_container_add_uint32(resp, SUPPORTED_STORAGE_ID); - mtp_container_add_uint32(resp, f->parent); - mtp_container_add_uint32(resp, send_obj_handle); + (void) mtp_container_add_uint32(resp, SUPPORTED_STORAGE_ID); + (void) mtp_container_add_uint32(resp, f->parent); + (void) mtp_container_add_uint32(resp, send_obj_handle); resp->header->code = MTP_RESP_OK; break; } @@ -346,19 +349,22 @@ int32_t tud_mtp_response_complete_cb(tud_mtp_cb_data_t* cb_data) { //--------------------------------------------------------------------+ static int32_t fs_get_device_info(tud_mtp_cb_data_t* cb_data) { // Device info is already prepared up to playback formats. Application only need to add string fields + int32_t resp_code = 0; mtp_container_info_t* io_container = &cb_data->io_container; - mtp_container_add_cstring(io_container, DEV_INFO_MANUFACTURER); - mtp_container_add_cstring(io_container, DEV_INFO_MODEL); - mtp_container_add_cstring(io_container, DEV_INFO_VERSION); + (void) mtp_container_add_cstring(io_container, DEV_INFO_MANUFACTURER); + (void) mtp_container_add_cstring(io_container, DEV_INFO_MODEL); + (void) mtp_container_add_cstring(io_container, DEV_INFO_VERSION); enum { MAX_SERIAL_NCHARS = 32 }; uint16_t serial_utf16[MAX_SERIAL_NCHARS+1]; size_t nchars = board_usb_get_serial(serial_utf16, MAX_SERIAL_NCHARS); serial_utf16[tu_min32(nchars, MAX_SERIAL_NCHARS)] = 0; // ensure null termination - mtp_container_add_string(io_container, serial_utf16); + (void) mtp_container_add_string(io_container, serial_utf16); - tud_mtp_data_send(io_container); - return 0; + if (!tud_mtp_data_send(io_container)) { + resp_code = MTP_RESP_DEVICE_BUSY; + } + return resp_code; } static int32_t fs_open_close_session(tud_mtp_cb_data_t* cb_data) { @@ -380,7 +386,7 @@ static int32_t fs_open_close_session(tud_mtp_cb_data_t* cb_data) { static int32_t fs_get_storage_ids(tud_mtp_cb_data_t* cb_data) { mtp_container_info_t* io_container = &cb_data->io_container; uint32_t storage_ids [] = { SUPPORTED_STORAGE_ID }; - mtp_container_add_auint32(io_container, 1, storage_ids); + (void) mtp_container_add_auint32(io_container, 1, storage_ids); tud_mtp_data_send(io_container); return 0; } @@ -394,7 +400,7 @@ static int32_t fs_get_storage_info(tud_mtp_cb_data_t* cb_data) { storage_info.max_capacity_in_bytes = sizeof(README_TXT_CONTENT) + LOGO_LEN + FS_MAX_CAPACITY_BYTES; storage_info.free_space_in_objects = FS_MAX_FILE_COUNT - fs_get_file_count(); storage_info.free_space_in_bytes = storage_info.free_space_in_objects ? FS_MAX_CAPACITY_BYTES : 0; - mtp_container_add_raw(io_container, &storage_info, sizeof(storage_info)); + (void) mtp_container_add_raw(io_container, &storage_info, sizeof(storage_info)); tud_mtp_data_send(io_container); return 0; } @@ -408,14 +414,14 @@ static int32_t fs_get_device_properties(tud_mtp_cb_data_t* cb_data) { // get describing dataset mtp_device_prop_desc_header_t device_prop_header; device_prop_header.device_property_code = dev_prop_code; - switch (dev_prop_code) { + switch (dev_prop_code) { //-V2520 //-V2659 case MTP_DEV_PROP_DEVICE_FRIENDLY_NAME: device_prop_header.datatype = MTP_DATA_TYPE_STR; device_prop_header.get_set = MTP_MODE_GET; - mtp_container_add_raw(io_container, &device_prop_header, sizeof(device_prop_header)); - mtp_container_add_cstring(io_container, DEV_PROP_FRIENDLY_NAME); // factory - mtp_container_add_cstring(io_container, DEV_PROP_FRIENDLY_NAME); // current - mtp_container_add_uint8(io_container, 0); // no form + (void) mtp_container_add_raw(io_container, &device_prop_header, sizeof(device_prop_header)); + (void) mtp_container_add_cstring(io_container, DEV_PROP_FRIENDLY_NAME); // factory + (void) mtp_container_add_cstring(io_container, DEV_PROP_FRIENDLY_NAME); // current + (void) mtp_container_add_uint8(io_container, 0); // no form tud_mtp_data_send(io_container); break; @@ -424,9 +430,9 @@ static int32_t fs_get_device_properties(tud_mtp_cb_data_t* cb_data) { } } else { // get value - switch (dev_prop_code) { + switch (dev_prop_code) { //-V2520 //-V2659 case MTP_DEV_PROP_DEVICE_FRIENDLY_NAME: - mtp_container_add_cstring(io_container, DEV_PROP_FRIENDLY_NAME); + (void) mtp_container_add_cstring(io_container, DEV_PROP_FRIENDLY_NAME); tud_mtp_data_send(io_container); break; @@ -446,20 +452,20 @@ static int32_t fs_get_object_handles(tud_mtp_cb_data_t* cb_data) { const uint32_t parent_handle = command->params[2]; // folder handle, 0xFFFFFFFF is root (void)obj_format; - if (storage_id != 0xFFFFFFFF && storage_id != SUPPORTED_STORAGE_ID) { + if (storage_id != 0xFFFFFFFFu && storage_id != SUPPORTED_STORAGE_ID) { return MTP_RESP_INVALID_STORAGE_ID; } uint32_t handles[FS_MAX_FILE_COUNT] = { 0 }; - uint32_t count = 0; - for (uint8_t i = 0; i < FS_MAX_FILE_COUNT; i++) { + uint32_t count = 0u; + for (uint8_t i = 0u; i < FS_MAX_FILE_COUNT; i++) { fs_file_t* f = &fs_objects[i]; if (fs_file_exist(f) && - (parent_handle == f->parent || (parent_handle == 0xFFFFFFFF && f->parent == 0))) { - handles[count++] = i + 1; // handle is index + 1 + (parent_handle == f->parent || (parent_handle == 0xFFFFFFFFu && f->parent == 0u))) { + handles[count++] = (uint32_t) i + 1u; // handle is index + 1 } } - mtp_container_add_auint32(io_container, count, handles); + (void) mtp_container_add_auint32(io_container, count, handles); tud_mtp_data_send(io_container); return 0; @@ -490,11 +496,11 @@ static int32_t fs_get_object_info(tud_mtp_cb_data_t* cb_data) { .association_desc = 0, .sequence_number = 0 }; - mtp_container_add_raw(io_container, &obj_info_header, sizeof(obj_info_header)); - mtp_container_add_string(io_container, f->name); - mtp_container_add_cstring(io_container, FS_FIXED_DATETIME); - mtp_container_add_cstring(io_container, FS_FIXED_DATETIME); - mtp_container_add_cstring(io_container, ""); // keywords, not used + (void) mtp_container_add_raw(io_container, &obj_info_header, sizeof(obj_info_header)); + (void) mtp_container_add_string(io_container, f->name); + (void) mtp_container_add_cstring(io_container, FS_FIXED_DATETIME); + (void) mtp_container_add_cstring(io_container, FS_FIXED_DATETIME); + (void) mtp_container_add_cstring(io_container, ""); // keywords, not used tud_mtp_data_send(io_container); return 0; @@ -512,7 +518,7 @@ static int32_t fs_get_object(tud_mtp_cb_data_t* cb_data) { if (cb_data->phase == MTP_PHASE_COMMAND) { // If file contents is larger than CFG_TUD_MTP_EP_BUFSIZE, data may only partially is added here // the rest will be sent in tud_mtp_data_more_cb - mtp_container_add_raw(io_container, f->data, f->size); + (void) mtp_container_add_raw(io_container, f->data, f->size); tud_mtp_data_send(io_container); } else if (cb_data->phase == MTP_PHASE_DATA) { // continue sending remaining data: file contents offset is xferred byte minus header size @@ -522,6 +528,8 @@ static int32_t fs_get_object(tud_mtp_cb_data_t* cb_data) { memcpy(io_container->payload, f->data + offset, xact_len); tud_mtp_data_send(io_container); } + } else { + // nothing to do } return 0; @@ -537,21 +545,21 @@ static int32_t fs_send_object_info(tud_mtp_cb_data_t* cb_data) { if (!is_session_opened) { return MTP_RESP_SESSION_NOT_OPEN; } - if (storage_id != 0xFFFFFFFF && storage_id != SUPPORTED_STORAGE_ID) { + if (storage_id != 0xFFFFFFFFu && storage_id != SUPPORTED_STORAGE_ID) { return MTP_RESP_INVALID_STORAGE_ID; } if (cb_data->phase == MTP_PHASE_COMMAND) { - tud_mtp_data_receive(io_container); + (void) tud_mtp_data_receive(io_container); } else if (cb_data->phase == MTP_PHASE_DATA) { mtp_object_info_header_t* obj_info = (mtp_object_info_header_t*) io_container->payload; if (obj_info->storage_id != 0 && obj_info->storage_id != SUPPORTED_STORAGE_ID) { return MTP_RESP_INVALID_STORAGE_ID; } - if (obj_info->parent_object) { + if (obj_info->parent_object != 0) { // not root fs_file_t* parent = fs_get_file(obj_info->parent_object); - if (parent == NULL || !parent->association_type) { + if (parent == NULL || 0u == parent->association_type) { return MTP_RESP_INVALID_PARENT_OBJECT; } } @@ -575,8 +583,10 @@ static int32_t fs_send_object_info(tud_mtp_cb_data_t* cb_data) { f->size = obj_info->object_compressed_size; f->data = f_buf; uint8_t* buf = io_container->payload + sizeof(mtp_object_info_header_t); - mtp_container_get_string(buf, f->name); + (void) mtp_container_get_string(buf, f->name); // ignore date created/modified/keywords + } else { + // nothing to do } return 0; diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 16c0d48d7..c2e7bf8f2 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -301,10 +301,10 @@ function(family_configure_common TARGET RTOS) COMMAND_EXPAND_LISTS ) # generate C-STAT report -# add_custom_command(TARGET ${TARGET} POST_BUILD -# COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/cstat_report -# COMMAND ireport --db=${CMAKE_BINARY_DIR}/cstat.db --full --project ${TARGET} --output ${CMAKE_CURRENT_BINARY_DIR}/cstat_report/index.html -# ) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/cstat_report + COMMAND ireport --db=${CMAKE_BINARY_DIR}/cstat.db --full --project ${TARGET} --output ${CMAKE_CURRENT_BINARY_DIR}/cstat_report/index.html + ) endif () endif () diff --git a/src/class/mtp/mtp.h b/src/class/mtp/mtp.h index 40b6dd8b0..236cf98e0 100644 --- a/src/class/mtp/mtp.h +++ b/src/class/mtp/mtp.h @@ -799,18 +799,18 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_array(mtp_contain TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_string(mtp_container_info_t* p_container, uint16_t* utf16) { uint8_t count = 0; - while (utf16[count]) { + while (utf16[count] != 0u) { count++; } - const uint32_t added_len = 1u + 2u * count; + const uint32_t added_len = 1u + (uint32_t) count * 2u; TU_ASSERT(p_container->header->len + added_len < CFG_TUD_MTP_EP_BUFSIZE, 0); uint8_t* buf = p_container->payload + p_container->header->len - sizeof(mtp_container_header_t); *buf++ = count; p_container->header->len++; - memcpy(buf, utf16, 2 * count); - p_container->header->len += 2 * count; + memcpy(buf, utf16, 2u * (uint32_t) count); + p_container->header->len += 2u * count; return added_len; } @@ -824,7 +824,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_cstring(mtp_conta // empty string (null only): single zero byte *buf = 0; p_container->header->len++; - return 1; + return 1u; } else { *buf++ = len; p_container->header->len++; @@ -875,8 +875,8 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_add_auint32(mtp_conta // //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline uint32_t mtp_container_get_string(uint8_t* buf, uint16_t utf16[]) { - uint8_t nchars = *buf++; - memcpy(utf16, buf, 2 * nchars); + size_t nchars = *buf++; + memcpy(utf16, buf, 2u * nchars); return 1u + 2u * nchars; } diff --git a/src/class/mtp/mtp_device.h b/src/class/mtp/mtp_device.h index 397fbbbce..a33f1dc08 100644 --- a/src/class/mtp/mtp_device.h +++ b/src/class/mtp/mtp_device.h @@ -53,12 +53,14 @@ typedef struct { typedef struct { uint8_t idx; uint8_t stage; // control stage - uint32_t session_id; - const tusb_control_request_t* request; // buffer for data stage - uint8_t* buf; uint16_t bufsize; + uint8_t* buf; + + const tusb_control_request_t* request; + + uint32_t session_id; } tud_mtp_request_cb_data_t; // Number of supported operations, events, device properties, capture formats, playback formats @@ -78,7 +80,7 @@ typedef struct { /* string fields will be added using append function */ \ } -typedef MTP_DEVICE_INFO_STRUCT( +typedef MTP_DEVICE_INFO_STRUCT( //-V2586 [MISRA-C-18.7] Flexible array members should not be declared sizeof(CFG_TUD_MTP_DEVICEINFO_EXTENSIONS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_OPERATIONS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_EVENTS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_DEVICE_PROPERTIES), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_CAPTURE_FORMATS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_PLAYBACK_FORMATS) diff --git a/src/class/video/video.h b/src/class/video/video.h index f348e187b..5bdf4b840 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -219,11 +219,11 @@ typedef enum { uint8_t baInterfaceNr[_nitf]; \ } -typedef tusb_desc_video_control_header_nitf_t() tusb_desc_video_control_header_t; -typedef tusb_desc_video_control_header_nitf_t(1) tusb_desc_video_control_header_1itf_t; -typedef tusb_desc_video_control_header_nitf_t(2) tusb_desc_video_control_header_2itf_t; -typedef tusb_desc_video_control_header_nitf_t(3) tusb_desc_video_control_header_3itf_t; -typedef tusb_desc_video_control_header_nitf_t(4) tusb_desc_video_control_header_4itf_t; +typedef tusb_desc_video_control_header_nitf_t() tusb_desc_video_control_header_t; //-V2586 incorrectly detected as flexible array +typedef tusb_desc_video_control_header_nitf_t(1) tusb_desc_video_control_header_1itf_t; //-V2586 incorrectly detected as flexible array +typedef tusb_desc_video_control_header_nitf_t(2) tusb_desc_video_control_header_2itf_t; //-V2586 incorrectly detected as flexible array +typedef tusb_desc_video_control_header_nitf_t(3) tusb_desc_video_control_header_3itf_t; //-V2586 incorrectly detected as flexible array +typedef tusb_desc_video_control_header_nitf_t(4) tusb_desc_video_control_header_4itf_t; //-V2586 incorrectly detected as flexible array typedef struct TU_ATTR_PACKED { uint8_t bLength; diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 5f659eb95..7aa42a2d7 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -236,7 +236,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_round_up(uint32_t v, uint32_t f) // TODO use clz TODO remove TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_log2(uint32_t value) { uint8_t result = 0; - while (value >>= 1) { + while ((value >>= 1u) != 0u) { result++; } return result; @@ -355,7 +355,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) { } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_in_bounds(uint8_t const* p_desc, uint8_t const* desc_end) { - return (p_desc < desc_end) && (tu_desc_next(p_desc) <= desc_end); + if (p_desc >= desc_end) { + return false; + } + return tu_desc_next(p_desc) <= desc_end; } // find descriptor that match byte1 (type) diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index df4034098..a7bf3e959 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -119,7 +119,9 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 // not found return the key value in hex static char not_found[11]; - snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long) key); + if (snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long) key) <= 0) { + not_found[0] = 0; + } return not_found; } diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index c9700fd9d..2c2ff76b7 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -93,7 +93,7 @@ static bool data_stage_xact(uint8_t rhport) { if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) { ep_addr = EDPT_CTRL_IN; - if (xact_len) { + if (0u != xact_len) { TU_VERIFY(0 == tu_memcpy_s(_ctrl_epbuf.buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len)); } } @@ -159,7 +159,7 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, // invoke optional dcd hook if available dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request); - if (_ctrl_xfer.complete_cb) { + if (NULL != _ctrl_xfer.complete_cb) { // TODO refactor with usbd_driver_print_control_complete_name _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_ACK, &_ctrl_xfer.request); } @@ -185,7 +185,7 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, // invoke complete callback if set // callback can still stall control in status phase e.g out data does not make sense - if (_ctrl_xfer.complete_cb) { + if (NULL != _ctrl_xfer.complete_cb) { #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb); #endif diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 2894d3023..6e220129a 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -125,14 +125,9 @@ bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) { // Enable SOF interrupt void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en); -/*------------------------------------------------------------------*/ -/* Helper - *------------------------------------------------------------------*/ - bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in); void usbd_defer_func(osal_task_func_t func, void *param, bool in_isr); - #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); #endif diff --git a/src/tusb.c b/src/tusb.c index d52c156ab..be67eead2 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -599,7 +599,9 @@ void tu_print_mem(void const* buf, uint32_t count, uint8_t indent) { if (remain) { for (uint32_t i = 0; i < 16 - remain; i++) { tu_printf(" "); - for (int j = 0; j < 2 * size; j++) tu_printf(" "); + for (int j = 0; j < 2 * size; j++) { + tu_printf(" "); + } } } -- cgit v1.3.1 From 7f173ab5ed6a80a5fd6780779fe63fb97d2be0e9 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 8 Nov 2025 15:54:02 +0700 Subject: fix more alerts --- .PVS-Studio/.pvsconfig | 1 + .clang-format | 1 + .github/workflows/static_analysis.yml | 3 +- examples/device/cdc_uac2/src/cdc_app.c | 2 +- examples/device/net_lwip_webserver/src/arch/cc.h | 6 +- examples/host/cdc_msc_hid/src/cdc_app.c | 2 +- src/class/audio/audio_device.c | 35 +- src/class/cdc/cdc_host.c | 81 +++-- src/class/msc/msc_host.c | 5 +- src/common/tusb_debug.h | 16 +- src/common/tusb_fifo.c | 414 ++++++++++------------- src/common/tusb_fifo.h | 25 +- src/common/tusb_private.h | 21 +- src/tusb.c | 38 ++- 14 files changed, 314 insertions(+), 336 deletions(-) (limited to '.github/workflows') diff --git a/.PVS-Studio/.pvsconfig b/.PVS-Studio/.pvsconfig index d8654b077..c9e60c996 100644 --- a/.PVS-Studio/.pvsconfig +++ b/.PVS-Studio/.pvsconfig @@ -10,6 +10,7 @@ //-V::2520 [MISRA-C-16.3] Every switch-clause should be terminated by an unconditional 'break' statement //-V:memcpy:2547 [MISRA-C-17.7] The return value of non-void function 'memcpy' should be used. //-V:memmove:2547 [MISRA-C-17.7] The return value of non-void function 'memmove' should be used. +//-V:printf:2547 [MISRA-C-17.7] //-V::2584::{gintsts} dwc2 //-V::2600 [MISRA-C-21.6] The function with the 'printf' name should not be used. //+V2614 DISABLE_LENGHT_LIMIT_CHECK:YES diff --git a/.clang-format b/.clang-format index c7d769172..907dd7cdd 100644 --- a/.clang-format +++ b/.clang-format @@ -87,5 +87,6 @@ SpacesInAngles: false SpacesInConditionalStatement: false SpacesInCStyleCastParentheses: false SpacesInParentheses: false +SortIncludes: false TabWidth: 2 ... diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 227f5e103..a89cdc279 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -118,13 +118,14 @@ jobs: sudo apt update sudo apt install pvs-studio pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} + pvs-studio-analyzer --version - name: Analyze run: | mkdir -p build cmake examples -B build -G Ninja -DBOARD=${{ matrix.board }} -DCMAKE_BUILD_TYPE=MinSizeRel cmake --build build - pvs-studio-analyzer analyze -R .PVS-Studio/.pvsconfig -f build/compile_commands.json --exclude-path hw/mcu/ --exclude-path lib/ -j + pvs-studio-analyzer analyze -f build/compile_commands.json -R .PVS-Studio/.pvsconfig -j4 --security-related-issues --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser -e lib/ -e hw/mcu/ -e */iar/cxarm/ -e pico-sdk/ plog-converter -t sarif -o pvs-studio-${{ matrix.board }}.sarif PVS-Studio.log - name: Upload SARIF diff --git a/examples/device/cdc_uac2/src/cdc_app.c b/examples/device/cdc_uac2/src/cdc_app.c index e3ad8a9ac..6d18a0e69 100644 --- a/examples/device/cdc_uac2/src/cdc_app.c +++ b/examples/device/cdc_uac2/src/cdc_app.c @@ -48,7 +48,7 @@ void tud_cdc_rx_cb(uint8_t itf) { // connected() check for DTR bit // Most but not all terminal client set this when making connection if (tud_cdc_connected()) { - if (tud_cdc_available()) { + if (tud_cdc_available() > 0) { count = tud_cdc_n_read(itf, buf, sizeof(buf)); (void) count; diff --git a/examples/device/net_lwip_webserver/src/arch/cc.h b/examples/device/net_lwip_webserver/src/arch/cc.h index 9f30b91cb..c3fc12dda 100644 --- a/examples/device/net_lwip_webserver/src/arch/cc.h +++ b/examples/device/net_lwip_webserver/src/arch/cc.h @@ -29,8 +29,8 @@ * Author: Adam Dunkels * */ -#ifndef __CC_H__ -#define __CC_H__ +#ifndef CC_H__ +#define CC_H__ //#include "cpu.h" @@ -72,4 +72,4 @@ typedef int sys_prot_t; #define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0) -#endif /* __CC_H__ */ +#endif /* CC_H__ */ diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index d3daedffc..4c2c5e807 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -51,7 +51,7 @@ void cdc_app_task(void) { for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) { if (tuh_cdc_mounted(idx)) { // console --> cdc interfaces - if (count) { + if (count > 0) { tuh_cdc_write(idx, buf, count); tuh_cdc_write_flush(idx); } diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index d47d87a69..f074b7d02 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -503,7 +503,7 @@ static bool audiod_rx_xfer_isr(uint8_t rhport, audiod_function_t* audio, uint16_ #if USE_LINEAR_BUFFER_RX // Data currently is in linear buffer, copy into EP OUT FIFO - TU_VERIFY(tu_fifo_write_n(&audio->ep_out_ff, audio->lin_buf_out, n_bytes_received)); + TU_VERIFY(0 < tu_fifo_write_n(&audio->ep_out_ff, audio->lin_buf_out, n_bytes_received)); // Schedule for next receive TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); @@ -672,8 +672,12 @@ uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles) { // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1. // This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot // (audio slot = channel count samples). - if (feedback > audio->feedback.max_value) feedback = audio->feedback.max_value; - if (feedback < audio->feedback.min_value) feedback = audio->feedback.min_value; + if (feedback > audio->feedback.max_value) { + feedback = audio->feedback.max_value; + } + if (feedback < audio->feedback.min_value) { + feedback = audio->feedback.min_value; + } tud_audio_n_fb_set(func_id, feedback); @@ -714,7 +718,6 @@ void audiod_init(void) { // Initialize IN EP FIFO if required #if CFG_TUD_AUDIO_ENABLE_EP_IN - switch (i) { #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 case 0: @@ -883,9 +886,11 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint || tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) { break; } else if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const *) p_desc)->bInterfaceSubClass == AUDIO_SUBCLASS_STREAMING) { - if (_audiod_fct[i].p_desc_as == 0) { + if (_audiod_fct[i].p_desc_as == NULL) { _audiod_fct[i].p_desc_as = p_desc; } + } else { + // nothing to do } total_len += p_desc[0]; p_desc = tu_desc_next(p_desc); @@ -957,19 +962,19 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint } #if CFG_TUD_AUDIO_ENABLE_EP_IN - if (ep_in) { + if (ep_in != 0) { usbd_edpt_iso_alloc(rhport, ep_in, ep_in_size); } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT - if (ep_out) { + if (ep_out != 0) { usbd_edpt_iso_alloc(rhport, ep_out, ep_out_size); } #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - if (ep_fb) { + if (ep_fb != 0) { usbd_edpt_iso_alloc(rhport, ep_fb, 4); } #endif @@ -998,6 +1003,8 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint if (tu_unaligned_read16(p_desc + 4) == AUDIO_TERM_TYPE_USB_STREAMING) { _audiod_fct[i].bclock_id_tx = p_desc[8]; } + } else { + // nothing to do } p_desc = tu_desc_next(p_desc); } @@ -1458,6 +1465,8 @@ bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_ return audiod_control_request(rhport, request); } else if (stage == CONTROL_STAGE_DATA) { return audiod_control_complete(rhport, request); + } else { + // nothing to do } return true; @@ -1633,8 +1642,12 @@ static void audiod_fb_fifo_count_update(audiod_function_t *audio, uint16_t lvl_n feedback = audio->feedback.compute.fifo_count.nom_value - (ff_lvl - ff_thr) * rate[1]; } - if (feedback > audio->feedback.max_value) feedback = audio->feedback.max_value; - if (feedback < audio->feedback.min_value) feedback = audio->feedback.min_value; + if (feedback > audio->feedback.max_value) { + feedback = audio->feedback.max_value; + } + if (feedback < audio->feedback.min_value) { + feedback = audio->feedback.min_value; + } audio->feedback.value = feedback; } @@ -1754,7 +1767,7 @@ static bool audiod_verify_entity_exists(uint8_t itf, uint8_t entityID, uint8_t * static bool audiod_verify_itf_exists(uint8_t itf, uint8_t *func_id) { uint8_t i; for (i = 0; i < CFG_TUD_AUDIO; i++) { - if (_audiod_fct[i].p_desc) { + if (_audiod_fct[i].p_desc != NULL) { // Get pointer at beginning and end uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = _audiod_fct[i].p_desc + _audiod_fct[i].desc_length; diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 3fc6a9adf..7fdf0a7b9 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -602,7 +602,7 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding, p_cdc->requested_line.coding = *line_coding; p_cdc->user_complete_cb = complete_cb; - if (driver->set_line_coding) { + if (driver->set_line_coding != NULL) { // driver support set_line_coding request TU_VERIFY(driver->set_line_coding(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data)); @@ -611,7 +611,7 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding, } } else { // driver does not support set_line_coding and need 2 stage to set baudrate and data format separately - if (complete_cb) { + if (complete_cb != NULL) { // non-blocking TU_VERIFY(driver->set_baudrate(p_cdc, cdch_set_line_coding_stage1_baudrate_complete, user_data)); } else { @@ -619,7 +619,7 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding, xfer_result_t result = XFER_RESULT_INVALID; TU_VERIFY(driver->set_baudrate(p_cdc, NULL, (uintptr_t) &result)); - if (user_data) { + if (user_data != 0) { *((xfer_result_t *) user_data) = result; } TU_VERIFY(result == XFER_RESULT_SUCCESS); @@ -627,7 +627,7 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding, result = XFER_RESULT_INVALID; TU_VERIFY(driver->set_data_format(p_cdc, NULL, (uintptr_t) &result)); - if (user_data) { + if (user_data != 0) { *((xfer_result_t *) user_data) = result; } TU_VERIFY(result == XFER_RESULT_SUCCESS); @@ -777,6 +777,8 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d } } } + } else { + // not supported class } return false; @@ -894,7 +896,7 @@ static void cdch_internal_control_complete(tuh_xfer_t *xfer) { // Invoke application callback xfer->complete_cb = p_cdc->user_complete_cb; - if (xfer->complete_cb) { + if (xfer->complete_cb != NULL) { xfer->complete_cb(xfer); } } @@ -910,7 +912,7 @@ static void cdch_set_line_coding_stage1_baudrate_complete(tuh_xfer_t *xfer) { TU_ASSERT(driver->set_data_format(p_cdc, cdch_set_line_coding_stage2_data_format_complete, xfer->user_data),); } else { xfer->complete_cb = p_cdc->user_complete_cb; - if (xfer->complete_cb) { + if (xfer->complete_cb != NULL) { xfer->complete_cb(xfer); } } @@ -926,7 +928,7 @@ static void cdch_set_line_coding_stage2_data_format_complete(tuh_xfer_t *xfer) { } xfer->complete_cb = p_cdc->user_complete_cb; - if (xfer->complete_cb) { + if (xfer->complete_cb != NULL) { xfer->complete_cb(xfer); } } @@ -950,12 +952,12 @@ static void acm_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *x break; default: - break; + break; // unknown request } } static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_VERIFY(p_cdc->acm.capability.support_line_request); + TU_VERIFY(p_cdc->acm.capability.support_line_request != 0); const tusb_control_request_t request = { .bmRequestType_bit = { @@ -982,7 +984,7 @@ static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_t co } static bool acm_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_VERIFY(p_cdc->acm.capability.support_line_request); + TU_VERIFY(p_cdc->acm.capability.support_line_request != 0); TU_VERIFY((p_cdc->requested_line.coding.data_bits >= 5 && p_cdc->requested_line.coding.data_bits <= 8) || p_cdc->requested_line.coding.data_bits == 16); @@ -1167,10 +1169,10 @@ static bool ftdi_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete static bool ftdi_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint32_t index_value = ftdi_get_divisor(p_cdc); - TU_VERIFY(index_value); + TU_VERIFY(index_value != 0); uint16_t value = (uint16_t) index_value; uint16_t index = (uint16_t) (index_value >> 16); - if (p_cdc->ftdi.channel) { + if (p_cdc->ftdi.channel != 0) { index = (uint16_t) ((index << 8) | p_cdc->ftdi.channel); } @@ -1372,6 +1374,8 @@ static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) { divisor = 0; } else if (divisor == 0x4001) /* 1.5 */ { divisor = 1; + } else { + // nothing to do } return divisor; } @@ -1395,12 +1399,13 @@ static uint32_t ftdi_2232h_baud_base_to_divisor(uint32_t baud, uint32_t base) { divisor = 0; } else if (divisor == 0x4001) /* 1.5 */ { divisor = 1; + } else { + // nothing to do } - /* - * Set this bit to turn off a divide by 2.5 on baud rate generator + + /* Set this bit to turn off a divide by 2.5 on baud rate generator * This enables baud rates up to 12Mbaud but cannot reach below 1200 - * baud with this bit set - */ + * baud with this bit set */ divisor |= 0x00020000; return divisor; } @@ -1412,7 +1417,7 @@ static inline uint32_t ftdi_2232h_baud_to_divisor(uint32_t baud) { static inline uint32_t ftdi_get_divisor(cdch_interface_t *p_cdc) { uint32_t baud = p_cdc->requested_line.coding.bit_rate; uint32_t div_value = 0; - TU_VERIFY(baud); + TU_VERIFY(baud != 0); switch (p_cdc->ftdi.chip_type) { case FTDI_UNKNOWN: @@ -1552,7 +1557,8 @@ static void cp210x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t p_cdc->line.coding.bit_rate = p_cdc->requested_line.coding.bit_rate; break; - default: break; + default: + break; // unsupported request } } @@ -1713,7 +1719,8 @@ static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t p_cdc->line.coding.data_bits = p_cdc->requested_line.coding.data_bits; break; - default: break; + default: + break; // unsupported } break; @@ -1721,19 +1728,20 @@ static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t p_cdc->line.control_state = p_cdc->requested_line.control_state; break; - default: break; + default: + break; // unsupported request } } static bool ch34x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { const uint8_t lcr = ch34x_get_lcr(p_cdc); - TU_VERIFY(lcr); + TU_VERIFY(lcr > 0); return ch34x_write_reg(p_cdc, CH32X_REG16_LCR2_LCR, lcr, complete_cb, user_data); } static bool ch34x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { const uint16_t div_ps = ch34x_get_divisor_prescaler(p_cdc); - TU_VERIFY(div_ps); + TU_VERIFY(div_ps > 0); return ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, complete_cb, user_data); } @@ -1916,7 +1924,8 @@ static uint8_t ch34x_get_lcr(cdch_interface_t *p_cdc) { lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN; break; - default: break; + default: + break; // invalid parity } // 1.5 stop bits not supported @@ -1999,13 +2008,15 @@ static inline bool pl2303_supports_hx_status(cdch_interface_t *p_cdc, tuh_xfer_c // return pl2303_set_request(p_cdc, PL2303_BREAK_REQUEST, PL2303_BREAK_REQUEST_TYPE, state, 0, NULL, 0); //} -static inline int pl2303_clear_halt(cdch_interface_t *p_cdc, uint8_t endp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { +static inline bool +pl2303_clear_halt(cdch_interface_t *p_cdc, uint8_t endp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { /* we don't care if it wasn't halted first. in fact some devices * (like some ibmcam model 1 units) seem to expect hosts to make * this request for iso endpoints, which can't halt! */ - return pl2303_set_request(p_cdc, TUSB_REQ_CLEAR_FEATURE, PL2303_CLEAR_HALT_REQUEST_TYPE, TUSB_REQ_FEATURE_EDPT_HALT, endp, - NULL, 0, complete_cb, user_data); + return pl2303_set_request( + p_cdc, TUSB_REQ_CLEAR_FEATURE, PL2303_CLEAR_HALT_REQUEST_TYPE, TUSB_REQ_FEATURE_EDPT_HALT, endp, NULL, 0, + complete_cb, user_data); } //------------- Driver API -------------// @@ -2130,10 +2141,9 @@ static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) if (type == PL2303_TYPE_NEED_SUPPORTS_HX_STATUS) { TU_ASSERT(pl2303_supports_hx_status(p_cdc, cdch_process_set_config, CONFIG_PL2303_READ1)); break; - } else { - // no transfer triggered and continue with CONFIG_PL2303_READ1 - TU_ATTR_FALLTHROUGH; } + // no transfer triggered and continue with CONFIG_PL2303_READ1 + TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_READ1: // get supports_hx_status, type and quirks (step 2), do special read @@ -2378,10 +2388,12 @@ static pl2303_type_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step) { return PL2303_TYPE_HXN; default: - break; + break; // unknown device } break; - default: break; + + default: + break; // unknown device } TU_LOG_CDC(p_cdc, "unknown device type bcdUSB = 0x%04x", desc_dev.bcdUSB); @@ -2443,8 +2455,9 @@ static uint32_t pl2303_encode_baud_rate_divisor(uint8_t buf[PL2303_LINE_CODING_B */ baseline = 12000000 * 32; mantissa = baseline / baud; - if (mantissa == 0) + if (mantissa == 0) { mantissa = 1; /* Avoid dividing by zero if baud > 32 * 12M. */ + } exponent = 0; while (mantissa >= 512) { if (exponent < 7) { @@ -2516,7 +2529,7 @@ static bool pl2303_encode_baud_rate(cdch_interface_t *p_cdc, uint8_t buf[PL2303_ * Use direct method for supported baud rates, otherwise use divisors. * Newer chip types do not support divisor encoding. */ - if (type_data->no_divisors) { + if (type_data->no_divisors != 0) { baud_sup = baud; } else { baud_sup = pl2303_get_supported_baud_rate(baud); @@ -2524,7 +2537,7 @@ static bool pl2303_encode_baud_rate(cdch_interface_t *p_cdc, uint8_t buf[PL2303_ if (baud == baud_sup) { baud = pl2303_encode_baud_rate_direct(buf, baud); - } else if (type_data->alt_divisors) { + } else if (type_data->alt_divisors != 0) { baud = pl2303_encode_baud_rate_divisor_alt(buf, baud); } else { baud = pl2303_encode_baud_rate_divisor(buf, baud); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index ce2884f2e..daff345c5 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -123,7 +123,10 @@ bool tuh_msc_mounted(uint8_t dev_addr) { bool tuh_msc_ready(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); - return p_msc->mounted && !usbh_edpt_busy(dev_addr, p_msc->ep_in) && !usbh_edpt_busy(dev_addr, p_msc->ep_out); + TU_VERIFY(p_msc->mounted); + const bool epin_busy = usbh_edpt_busy(dev_addr, p_msc->ep_in); + const bool epout_busy = usbh_edpt_busy(dev_addr, p_msc->ep_out); + return !epin_busy && !epout_busy; } //--------------------------------------------------------------------+ diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 08117283f..e0e09f5ce 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -56,14 +56,14 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); #define tu_printf CFG_TUSB_DEBUG_PRINTF #else #include - #define tu_printf printf + #define tu_printf(...) (void) printf(__VA_ARGS__) #endif TU_ATTR_ALWAYS_INLINE static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; i= 2 diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 3b8920c01..419046b8b 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -28,7 +28,7 @@ #include "osal/osal.h" #include "tusb_fifo.h" -#define TU_FIFO_DBG 0 +#define TU_FIFO_DBG 0 // Suppress IAR warning // Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement @@ -39,13 +39,13 @@ #if OSAL_MUTEX_REQUIRED TU_ATTR_ALWAYS_INLINE static inline void _ff_lock(osal_mutex_t mutex) { - if (mutex) { + if (mutex != NULL) { osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); } } TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex) { - if (mutex) { + if (mutex != NULL) { osal_mutex_unlock(mutex); } } @@ -62,14 +62,13 @@ TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex) { * copy data to and from USB hardware FIFOs as needed for e.g. STM32s and others */ typedef enum { - TU_FIFO_COPY_INC, ///< Copy from/to an increasing source/destination address - default mode + TU_FIFO_COPY_INC, ///< Copy from/to an increasing source/destination address - default mode #ifdef TUP_MEM_CONST_ADDR TU_FIFO_COPY_CST_FULL_WORDS, ///< Copy from/to a constant source/destination address - required for e.g. STM32 to write into USB hardware FIFO #endif } tu_fifo_copy_mode_t; -bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable) -{ +bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_size, bool overwritable) { // Limit index space to 2*depth - this allows for a fast "modulo" calculation // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable // only if overflow happens once (important for unsupervised DMA applications) @@ -80,9 +79,9 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si _ff_lock(f->mutex_wr); _ff_lock(f->mutex_rd); - f->buffer = (uint8_t*) buffer; + f->buffer = (uint8_t *)buffer; f->depth = depth; - f->item_size = (uint16_t) (item_size & 0x7FFF); + f->item_size = (uint16_t)(item_size & 0x7FFF); f->overwritable = overwritable; f->rd_idx = 0; f->wr_idx = 0; @@ -101,18 +100,18 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si // Intended to be used to read from hardware USB FIFO in e.g. STM32 where all data is read from a constant address // Code adapted from dcd_synopsys.c // TODO generalize with configurable 1 byte or 4 byte each read -static void _ff_push_const_addr(uint8_t * ff_buf, const void * app_buf, uint16_t len) { - volatile const uint32_t * reg_rx = (volatile const uint32_t *) app_buf; +static void _ff_push_const_addr(uint8_t *ff_buf, const void *app_buf, uint16_t len) { + const volatile uint32_t *reg_rx = (volatile const uint32_t *)app_buf; // Reading full available 32 bit words from const app address uint16_t full_words = len >> 2; - while(full_words--) { + while (full_words--) { tu_unaligned_write32(ff_buf, *reg_rx); ff_buf += 4; } // Read the remaining 1-3 bytes from const app address - uint8_t const bytes_rem = len & 0x03; + const uint8_t bytes_rem = len & 0x03; if (bytes_rem) { uint32_t tmp32 = *reg_rx; memcpy(ff_buf, &tmp32, bytes_rem); @@ -121,18 +120,18 @@ static void _ff_push_const_addr(uint8_t * ff_buf, const void * app_buf, uint16_t // Intended to be used to write to hardware USB FIFO in e.g. STM32 // where all data is written to a constant address in full word copies -static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t len) { - volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf; +static void _ff_pull_const_addr(void *app_buf, const uint8_t *ff_buf, uint16_t len) { + volatile uint32_t *reg_tx = (volatile uint32_t *)app_buf; // Write full available 32 bit words to const address uint16_t full_words = len >> 2; - while(full_words--) { + while (full_words--) { *reg_tx = tu_unaligned_read32(ff_buf); ff_buf += 4; } // Write the remaining 1-3 bytes into const address - uint8_t const bytes_rem = len & 0x03; + const uint8_t bytes_rem = len & 0x03; if (bytes_rem) { uint32_t tmp32 = 0; memcpy(&tmp32, ff_buf, bytes_rem); @@ -143,32 +142,27 @@ static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t #endif // send one item to fifo WITHOUT updating write pointer -static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel) { +static inline void _ff_push(tu_fifo_t *f, const void *app_buf, uint16_t rel) { memcpy(f->buffer + (rel * f->item_size), app_buf, f->item_size); } // send n items to fifo WITHOUT updating write pointer -static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t wr_ptr, tu_fifo_copy_mode_t copy_mode) -{ - uint16_t const lin_count = f->depth - wr_ptr; - uint16_t const wrap_count = n - lin_count; +static void _ff_push_n(tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr, tu_fifo_copy_mode_t copy_mode) { + const uint16_t lin_count = f->depth - wr_ptr; + const uint16_t wrap_count = n - lin_count; - uint16_t lin_bytes = lin_count * f->item_size; + uint16_t lin_bytes = lin_count * f->item_size; uint16_t wrap_bytes = wrap_count * f->item_size; // current buffer of fifo - uint8_t* ff_buf = f->buffer + (wr_ptr * f->item_size); + uint8_t *ff_buf = f->buffer + (wr_ptr * f->item_size); - switch (copy_mode) - { + switch (copy_mode) { case TU_FIFO_COPY_INC: - if(n <= lin_count) - { + if (n <= lin_count) { // Linear only - memcpy(ff_buf, app_buf, n*f->item_size); - } - else - { + memcpy(ff_buf, app_buf, n * f->item_size); + } else { // Wrap around // Write data to linear part of buffer @@ -176,19 +170,17 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t // Write data wrapped around // TU_ASSERT(nWrap_bytes <= f->depth, ); - memcpy(f->buffer, ((uint8_t const*) app_buf) + lin_bytes, wrap_bytes); + memcpy(f->buffer, ((const uint8_t *)app_buf) + lin_bytes, wrap_bytes); } break; + #ifdef TUP_MEM_CONST_ADDR case TU_FIFO_COPY_CST_FULL_WORDS: // Intended for hardware buffers from which it can be read word by word only - if(n <= lin_count) - { + if (n <= lin_count) { // Linear only - _ff_push_const_addr(ff_buf, app_buf, n*f->item_size); - } - else - { + _ff_push_const_addr(ff_buf, app_buf, n * f->item_size); + } else { // Wrap around case // Write full words to linear part of buffer @@ -198,83 +190,80 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t // There could be odd 1-3 bytes before the wrap-around boundary uint8_t rem = lin_bytes & 0x03; - if (rem > 0) - { - volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf; + if (rem > 0) { + const volatile uint32_t *rx_fifo = (volatile const uint32_t *)app_buf; - uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); + uint8_t remrem = (uint8_t)tu_min16(wrap_bytes, 4 - rem); wrap_bytes -= remrem; - uint32_t tmp32 = *rx_fifo; - uint8_t * src_u8 = ((uint8_t *) &tmp32); + uint32_t tmp32 = *rx_fifo; + uint8_t *src_u8 = ((uint8_t *)&tmp32); // Write 1-3 bytes before wrapped boundary - while(rem--) *ff_buf++ = *src_u8++; + while (rem--) { + *ff_buf++ = *src_u8++; + } // Read more bytes to beginning to complete a word ff_buf = f->buffer; - while(remrem--) *ff_buf++ = *src_u8++; - } - else - { + while (remrem--) { + *ff_buf++ = *src_u8++; + } + } else { ff_buf = f->buffer; // wrap around to beginning } // Write data wrapped part - if (wrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, wrap_bytes); + if (wrap_bytes > 0) { + _ff_push_const_addr(ff_buf, app_buf, wrap_bytes); + } } break; #endif - default: break; + + default: + break; // unknown mode } } // get one item from fifo WITHOUT updating read pointer -static inline void _ff_pull(tu_fifo_t* f, void * app_buf, uint16_t rel) -{ +static inline void _ff_pull(tu_fifo_t *f, void *app_buf, uint16_t rel) { memcpy(app_buf, f->buffer + (rel * f->item_size), f->item_size); } // get n items from fifo WITHOUT updating read pointer -static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, tu_fifo_copy_mode_t copy_mode) -{ - uint16_t const lin_count = f->depth - rd_ptr; - uint16_t const wrap_count = n - lin_count; // only used if wrapped +static void _ff_pull_n(tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr, tu_fifo_copy_mode_t copy_mode) { + const uint16_t lin_count = f->depth - rd_ptr; + const uint16_t wrap_count = n - lin_count; // only used if wrapped - uint16_t lin_bytes = lin_count * f->item_size; + uint16_t lin_bytes = lin_count * f->item_size; uint16_t wrap_bytes = wrap_count * f->item_size; // current buffer of fifo - uint8_t* ff_buf = f->buffer + (rd_ptr * f->item_size); + uint8_t *ff_buf = f->buffer + (rd_ptr * f->item_size); - switch (copy_mode) - { + switch (copy_mode) { case TU_FIFO_COPY_INC: - if ( n <= lin_count ) - { + if (n <= lin_count) { // Linear only - memcpy(app_buf, ff_buf, n*f->item_size); - } - else - { + memcpy(app_buf, ff_buf, n * f->item_size); + } else { // Wrap around // Read data from linear part of buffer memcpy(app_buf, ff_buf, lin_bytes); // Read data wrapped part - memcpy((uint8_t*) app_buf + lin_bytes, f->buffer, wrap_bytes); + memcpy((uint8_t *)app_buf + lin_bytes, f->buffer, wrap_bytes); } - break; + break; + #ifdef TUP_MEM_CONST_ADDR case TU_FIFO_COPY_CST_FULL_WORDS: - if ( n <= lin_count ) - { + if (n <= lin_count) { // Linear only - _ff_pull_const_addr(app_buf, ff_buf, n*f->item_size); - } - else - { + _ff_pull_const_addr(app_buf, ff_buf, n * f->item_size); + } else { // Wrap around case // Read full words from linear part of buffer @@ -284,36 +273,41 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, // There could be odd 1-3 bytes before the wrap-around boundary uint8_t rem = lin_bytes & 0x03; - if (rem > 0) - { - volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf; + if (rem > 0) { + volatile uint32_t *reg_tx = (volatile uint32_t *)app_buf; - uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); + uint8_t remrem = (uint8_t)tu_min16(wrap_bytes, 4 - rem); wrap_bytes -= remrem; - uint32_t tmp32=0; - uint8_t * dst_u8 = (uint8_t *)&tmp32; + uint32_t tmp32 = 0; + uint8_t *dst_u8 = (uint8_t *)&tmp32; // Read 1-3 bytes before wrapped boundary - while(rem--) *dst_u8++ = *ff_buf++; + while (rem--) { + *dst_u8++ = *ff_buf++; + } // Read more bytes from beginning to complete a word ff_buf = f->buffer; - while(remrem--) *dst_u8++ = *ff_buf++; + while (remrem--) { + *dst_u8++ = *ff_buf++; + } *reg_tx = tmp32; - } - else - { + } else { ff_buf = f->buffer; // wrap around to beginning } // Read data wrapped part - if (wrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes); + if (wrap_bytes > 0) { + _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes); + } } - break; + break; #endif - default: break; + + default: + break; // unknown mode } } @@ -322,24 +316,18 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, //--------------------------------------------------------------------+ // return only the index difference and as such can be used to determine an overflow i.e overflowable count -TU_ATTR_ALWAYS_INLINE static inline -uint16_t _ff_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t _ff_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) { // In case we have non-power of two depth we need a further modification - if (wr_idx >= rd_idx) - { - return (uint16_t) (wr_idx - rd_idx); - } else - { - return (uint16_t) (2*depth - (rd_idx - wr_idx)); + if (wr_idx >= rd_idx) { + return (uint16_t)(wr_idx - rd_idx); + } else { + return (uint16_t)(2 * depth - (rd_idx - wr_idx)); } } // return remaining slot in fifo -TU_ATTR_ALWAYS_INLINE static inline -uint16_t _ff_remaining(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) -{ - uint16_t const count = _ff_count(depth, wr_idx, rd_idx); +TU_ATTR_ALWAYS_INLINE static inline uint16_t _ff_remaining(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) { + const uint16_t count = _ff_count(depth, wr_idx, rd_idx); return (depth > count) ? (depth - count) : 0; } @@ -349,16 +337,14 @@ uint16_t _ff_remaining(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) // Advance an absolute index // "absolute" index is only in the range of [0..2*depth) -static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) -{ +static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) { // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index - uint16_t new_idx = (uint16_t) (idx + offset); - if ( (idx > new_idx) || (new_idx >= 2*depth) ) - { - uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*depth-1)); - new_idx = (uint16_t) (new_idx + non_used_index_space); + uint16_t new_idx = (uint16_t)(idx + offset); + if ((idx > new_idx) || (new_idx >= 2 * depth)) { + const uint16_t non_used_index_space = (uint16_t)(UINT16_MAX - (2 * depth - 1)); + new_idx = (uint16_t)(new_idx + non_used_index_space); } return new_idx; @@ -366,14 +352,12 @@ static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) #if 0 // not used but // Backward an absolute index -static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset) -{ +static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset) { // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index uint16_t new_idx = (uint16_t) (idx - offset); - if ( (idx < new_idx) || (new_idx >= 2*depth) ) - { + if ( (idx < new_idx) || (new_idx >= 2*depth) ) { uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*depth-1)); new_idx = (uint16_t) (new_idx - non_used_index_space); } @@ -383,26 +367,22 @@ static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset) #endif // index to pointer, simply an modulo with minus. -TU_ATTR_ALWAYS_INLINE static inline -uint16_t idx2ptr(uint16_t depth, uint16_t idx) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t idx) { // Only run at most 3 times since index is limit in the range of [0..2*depth) - while ( idx >= depth ) idx -= depth; + while (idx >= depth) { + idx -= depth; + } return idx; } // Works on local copies of w // When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms // an full fifo i.e _ff_count() = depth -TU_ATTR_ALWAYS_INLINE static inline -uint16_t _ff_correct_read_index(tu_fifo_t* f, uint16_t wr_idx) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t _ff_correct_read_index(tu_fifo_t *f, uint16_t wr_idx) { uint16_t rd_idx; - if ( wr_idx >= f->depth ) - { + if (wr_idx >= f->depth) { rd_idx = wr_idx - f->depth; - }else - { + } else { rd_idx = wr_idx + f->depth; } @@ -413,16 +393,16 @@ uint16_t _ff_correct_read_index(tu_fifo_t* f, uint16_t wr_idx) // Works on local copies of w and r // Must be protected by mutexes since in case of an overflow read pointer gets modified -static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16_t rd_idx) -{ +static bool _tu_fifo_peek(tu_fifo_t *f, void *p_buffer, uint16_t wr_idx, uint16_t rd_idx) { uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); // nothing to peek - if ( cnt == 0 ) return false; + if (cnt == 0) { + return false; + } // Check overflow and correct if required - if ( cnt > f->depth ) - { + if (cnt > f->depth) { rd_idx = _ff_correct_read_index(f, wr_idx); } @@ -436,22 +416,25 @@ static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16 // Works on local copies of w and r // Must be protected by mutexes since in case of an overflow read pointer gets modified -static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx, tu_fifo_copy_mode_t copy_mode) -{ +static uint16_t _tu_fifo_peek_n( + tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx, tu_fifo_copy_mode_t copy_mode) { uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); // nothing to peek - if ( cnt == 0 ) return 0; + if (cnt == 0) { + return 0; + } // Check overflow and correct if required - if ( cnt > f->depth ) - { + if (cnt > f->depth) { rd_idx = _ff_correct_read_index(f, wr_idx); - cnt = f->depth; + cnt = f->depth; } // Check if we can read something at and after offset - if too less is available we read what remains - if ( cnt < n ) n = cnt; + if (cnt < n) { + n = cnt; + } uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); @@ -461,40 +444,36 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1 return n; } -static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu_fifo_copy_mode_t copy_mode) -{ - if ( n == 0 ) return 0; +static uint16_t _tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n, tu_fifo_copy_mode_t copy_mode) { + if (n == 0) { + return 0; + } _ff_lock(f->mutex_wr); uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; - uint8_t const* buf8 = (uint8_t const*) data; + const uint8_t *buf8 = (const uint8_t *)data; - TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ", - rd_idx, wr_idx, _ff_count(f->depth, wr_idx, rd_idx), _ff_remaining(f->depth, wr_idx, rd_idx), n); + TU_LOG( + TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ", rd_idx, wr_idx, + _ff_count(f->depth, wr_idx, rd_idx), _ff_remaining(f->depth, wr_idx, rd_idx), n); - if ( !f->overwritable ) - { + if (!f->overwritable) { // limit up to full - uint16_t const remain = _ff_remaining(f->depth, wr_idx, rd_idx); - n = tu_min16(n, remain); - } - else - { + const uint16_t remain = _ff_remaining(f->depth, wr_idx, rd_idx); + n = tu_min16(n, remain); + } else { // In over-writable mode, fifo_write() is allowed even when fifo is full. In such case, // oldest data in fifo i.e at read pointer data will be overwritten // Note: we can modify read buffer contents but we must not modify the read index itself within a write function! // Since it would end up in a race condition with read functions! - if ( n >= f->depth ) - { + if (n >= f->depth) { // Only copy last part - if ( copy_mode == TU_FIFO_COPY_INC ) - { + if (copy_mode == TU_FIFO_COPY_INC) { buf8 += (n - f->depth) * f->item_size; - }else - { + } else { // TODO should read from hw fifo to discard data, however reading an odd number could // accidentally discard data. } @@ -503,12 +482,9 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu // We start writing at the read pointer's position since we fill the whole buffer wr_idx = rd_idx; - } - else - { - uint16_t const overflowable_count = _ff_count(f->depth, wr_idx, rd_idx); - if (overflowable_count + n >= 2*f->depth) - { + } else { + const uint16_t overflowable_count = _ff_count(f->depth, wr_idx, rd_idx); + if (overflowable_count + n >= 2 * f->depth) { // Double overflowed // Index is bigger than the allowed range [0,2*depth) // re-position write index to have a full fifo after pushed @@ -518,8 +494,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu // However memmove() is expensive due to actual copying + wrapping consideration. // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory // currently deliberately not implemented --> result in incorrect data read back - }else - { + } else { // normal + single overflowed: // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read() // Therefore we just increase write index @@ -528,16 +503,11 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu } } - if (n) - { + if (n) { uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); - TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr); - // Write data _ff_push_n(f, buf8, n, wr_ptr, copy_mode); - - // Advance index f->wr_idx = advance_index(f->depth, wr_idx, n); TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\r\n", f->wr_idx); @@ -548,8 +518,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu return n; } -static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo_copy_mode_t copy_mode) -{ +static uint16_t _tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n, tu_fifo_copy_mode_t copy_mode) { _ff_lock(f->mutex_rd); // Peek the data @@ -582,8 +551,7 @@ static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo @returns Number of items in FIFO */ /******************************************************************************/ -uint16_t tu_fifo_count(tu_fifo_t* f) -{ +uint16_t tu_fifo_count(tu_fifo_t *f) { return tu_min16(_ff_count(f->depth, f->wr_idx, f->rd_idx), f->depth); } @@ -600,8 +568,7 @@ uint16_t tu_fifo_count(tu_fifo_t* f) @returns Number of items in FIFO */ /******************************************************************************/ -bool tu_fifo_empty(tu_fifo_t* f) -{ +bool tu_fifo_empty(tu_fifo_t *f) { return f->wr_idx == f->rd_idx; } @@ -618,8 +585,7 @@ bool tu_fifo_empty(tu_fifo_t* f) @returns Number of items in FIFO */ /******************************************************************************/ -bool tu_fifo_full(tu_fifo_t* f) -{ +bool tu_fifo_full(tu_fifo_t *f) { return _ff_count(f->depth, f->wr_idx, f->rd_idx) >= f->depth; } @@ -636,8 +602,7 @@ bool tu_fifo_full(tu_fifo_t* f) @returns Number of items in FIFO */ /******************************************************************************/ -uint16_t tu_fifo_remaining(tu_fifo_t* f) -{ +uint16_t tu_fifo_remaining(tu_fifo_t *f) { return _ff_remaining(f->depth, f->wr_idx, f->rd_idx); } @@ -662,14 +627,12 @@ uint16_t tu_fifo_remaining(tu_fifo_t* f) @returns True if overflow happened */ /******************************************************************************/ -bool tu_fifo_overflowed(tu_fifo_t* f) -{ +bool tu_fifo_overflowed(tu_fifo_t *f) { return _ff_count(f->depth, f->wr_idx, f->rd_idx) > f->depth; } // Only use in case tu_fifo_overflow() returned true! -void tu_fifo_correct_read_pointer(tu_fifo_t* f) -{ +void tu_fifo_correct_read_pointer(tu_fifo_t *f) { _ff_lock(f->mutex_rd); _ff_correct_read_index(f, f->wr_idx); _ff_unlock(f->mutex_rd); @@ -691,8 +654,7 @@ void tu_fifo_correct_read_pointer(tu_fifo_t* f) @returns TRUE if the queue is not empty */ /******************************************************************************/ -bool tu_fifo_read(tu_fifo_t* f, void * buffer) -{ +bool tu_fifo_read(tu_fifo_t *f, void *buffer) { _ff_lock(f->mutex_rd); // Peek the data @@ -722,8 +684,7 @@ bool tu_fifo_read(tu_fifo_t* f, void * buffer) @returns number of items read from the FIFO */ /******************************************************************************/ -uint16_t tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n) -{ +uint16_t tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n) { return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_INC); } @@ -745,8 +706,7 @@ uint16_t tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n) @returns number of items read from the FIFO */ /******************************************************************************/ -uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t* f, void * buffer, uint16_t n) -{ +uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t *f, void *buffer, uint16_t n) { return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_CST_FULL_WORDS); } #endif @@ -764,8 +724,7 @@ uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t* f, void * buffer, uint1 @returns TRUE if the queue is not empty */ /******************************************************************************/ -bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) -{ +bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer) { _ff_lock(f->mutex_rd); bool ret = _tu_fifo_peek(f, p_buffer, f->wr_idx, f->rd_idx); _ff_unlock(f->mutex_rd); @@ -787,8 +746,7 @@ bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) @returns Number of bytes written to p_buffer */ /******************************************************************************/ -uint16_t tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n) -{ +uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n) { _ff_lock(f->mutex_rd); uint16_t ret = _tu_fifo_peek_n(f, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_COPY_INC); _ff_unlock(f->mutex_rd); @@ -811,27 +769,19 @@ uint16_t tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n) FIFO will always return TRUE) */ /******************************************************************************/ -bool tu_fifo_write(tu_fifo_t* f, const void * data) -{ +bool tu_fifo_write(tu_fifo_t *f, const void *data) { _ff_lock(f->mutex_wr); - bool ret; - uint16_t const wr_idx = f->wr_idx; + bool ret; + const uint16_t wr_idx = f->wr_idx; - if ( tu_fifo_full(f) && !f->overwritable ) - { + if (tu_fifo_full(f) && !f->overwritable) { ret = false; - }else - { + } else { uint16_t wr_ptr = idx2ptr(f->depth, wr_idx); - - // Write data _ff_push(f, data, wr_ptr); - - // Advance pointer f->wr_idx = advance_index(f->depth, wr_idx, 1); - - ret = true; + ret = true; } _ff_unlock(f->mutex_wr); @@ -853,8 +803,7 @@ bool tu_fifo_write(tu_fifo_t* f, const void * data) @return Number of written elements */ /******************************************************************************/ -uint16_t tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n) -{ +uint16_t tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n) { return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_INC); } @@ -874,8 +823,7 @@ uint16_t tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n) @return Number of written elements */ /******************************************************************************/ -uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t* f, const void * data, uint16_t n) -{ +uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t *f, const void *data, uint16_t n) { return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_CST_FULL_WORDS); } #endif @@ -888,8 +836,7 @@ uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t* f, const void * data, Pointer to the FIFO buffer to manipulate */ /******************************************************************************/ -bool tu_fifo_clear(tu_fifo_t *f) -{ +bool tu_fifo_clear(tu_fifo_t *f) { _ff_lock(f->mutex_wr); _ff_lock(f->mutex_rd); @@ -943,8 +890,7 @@ bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) { Number of items the write pointer moves forward */ /******************************************************************************/ -void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n) -{ +void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n) { f->wr_idx = advance_index(f->depth, f->wr_idx, n); } @@ -964,8 +910,7 @@ void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n) Number of items the read pointer moves forward */ /******************************************************************************/ -void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) -{ +void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) { f->rd_idx = advance_index(f->depth, f->rd_idx, n); } @@ -984,8 +929,7 @@ void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) Pointer to struct which holds the desired infos */ /******************************************************************************/ -void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) -{ +void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { // Operate on temporary values in case they change in between uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; @@ -993,8 +937,7 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx); // Check overflow and correct if required - may happen in case a DMA wrote too fast - if (cnt > f->depth) - { + if (cnt > f->depth) { _ff_lock(f->mutex_rd); rd_idx = _ff_correct_read_index(f, wr_idx); _ff_unlock(f->mutex_rd); @@ -1003,8 +946,7 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) } // Check if fifo is empty - if (cnt == 0) - { + if (cnt == 0) { info->len_lin = 0; info->len_wrap = 0; info->ptr_lin = NULL; @@ -1020,17 +962,14 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) info->ptr_lin = &f->buffer[rd_ptr]; // Check if there is a wrap around necessary - if (wr_ptr > rd_ptr) - { + if (wr_ptr > rd_ptr) { // Non wrapping case - info->len_lin = cnt; + info->len_lin = cnt; info->len_wrap = 0; info->ptr_wrap = NULL; - } - else - { - info->len_lin = f->depth - rd_ptr; // Also the case if FIFO was full + } else { + info->len_lin = f->depth - rd_ptr; // Also the case if FIFO was full info->len_wrap = cnt - info->len_lin; info->ptr_wrap = f->buffer; @@ -1052,14 +991,12 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) Pointer to struct which holds the desired infos */ /******************************************************************************/ -void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) -{ +void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) { uint16_t wr_idx = f->wr_idx; uint16_t rd_idx = f->rd_idx; uint16_t remain = _ff_remaining(f->depth, wr_idx, rd_idx); - if (remain == 0) - { + if (remain == 0) { info->len_lin = 0; info->len_wrap = 0; info->ptr_lin = NULL; @@ -1074,15 +1011,12 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) // Copy pointer to buffer to start writing to info->ptr_lin = &f->buffer[wr_ptr]; - if (wr_ptr < rd_ptr) - { + if (wr_ptr < rd_ptr) { // Non wrapping case - info->len_lin = rd_ptr-wr_ptr; + info->len_lin = rd_ptr - wr_ptr; info->len_wrap = 0; info->ptr_wrap = NULL; - } - else - { + } else { info->len_lin = f->depth - wr_ptr; info->len_wrap = remain - info->len_lin; // Remaining length - n already was limited to remain or FIFO depth info->ptr_wrap = f->buffer; // Always start of buffer diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index f2a6c5469..0f4ba00d8 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -104,16 +104,16 @@ extern "C" { * | R | 1 | 2 | W | 4 | 5 | */ typedef struct { - uint8_t* buffer ; // buffer pointer - uint16_t depth ; // max items + uint8_t *buffer; // buffer pointer + uint16_t depth; // max items struct TU_ATTR_PACKED { - uint16_t item_size : 15; // size of each item - bool overwritable : 1 ; // ovwerwritable when full + uint16_t item_size : 15; // size of each item + bool overwritable : 1; // ovwerwritable when full }; - volatile uint16_t wr_idx ; // write index - volatile uint16_t rd_idx ; // read index + volatile uint16_t wr_idx; // write index + volatile uint16_t rd_idx; // read index #if OSAL_MUTEX_REQUIRED osal_mutex_t mutex_wr; @@ -129,12 +129,13 @@ typedef struct { void * ptr_wrap ; ///< wrapped part start pointer } tu_fifo_buffer_info_t; -#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable){\ - .buffer = _buffer, \ - .depth = _depth, \ - .item_size = sizeof(_type), \ - .overwritable = _overwritable, \ -} +#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ + { \ + .buffer = _buffer, \ + .depth = _depth, \ + .item_size = sizeof(_type), \ + .overwritable = _overwritable, \ + } #define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \ uint8_t _name##_buf[_depth*sizeof(_type)]; \ diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 5e1d59233..dcd5c45d6 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -40,6 +40,12 @@ extern tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM]; // Endpoint //--------------------------------------------------------------------+ +enum { + TU_EDPT_STATE_BUSY = 0x01, + TU_EDPT_STATE_STALLED = 0x02, + TU_EDPT_STATE_CLAIMED = 0x04, +}; + typedef struct TU_ATTR_PACKED { volatile uint8_t busy : 1; volatile uint8_t stalled : 1; @@ -48,8 +54,8 @@ typedef struct TU_ATTR_PACKED { typedef struct { struct TU_ATTR_PACKED { - uint8_t is_host : 1; // 1: host, 0: device - uint8_t is_mps512 : 1; // 1: 512, 0: 64 since stream is used for Bulk only + bool is_host : 1; // 1: host, 0: device + bool is_mps512 : 1; // 1: 512, 0: 64 since stream is used for Bulk only }; uint8_t ep_addr; uint16_t ep_bufsize; @@ -93,21 +99,18 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); // Open an stream for an endpoint -TU_ATTR_ALWAYS_INLINE static inline -void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { +TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { tu_fifo_clear(&s->ff); s->ep_addr = desc_ep->bEndpointAddress; - s->is_mps512 = (tu_edpt_packet_size(desc_ep) == 512) ? 1 : 0; + s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512; } -TU_ATTR_ALWAYS_INLINE static inline -void tu_edpt_stream_close(tu_edpt_stream_t* s) { +TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t* s) { s->ep_addr = 0; } // Clear fifo -TU_ATTR_ALWAYS_INLINE static inline -bool tu_edpt_stream_clear(tu_edpt_stream_t* s) { +TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_clear(tu_edpt_stream_t* s) { return tu_fifo_clear(&s->ff); } diff --git a/src/tusb.c b/src/tusb.c index be67eead2..7411f19df 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -117,11 +117,15 @@ bool tusb_inited(void) { bool ret = false; #if CFG_TUD_ENABLED - ret = ret || tud_inited(); + if (tud_inited()) { + ret = true; + } #endif #if CFG_TUH_ENABLED - ret = ret || tuh_inited(); + if (tuh_inited()) { + ret = true; + } #endif return ret; @@ -209,7 +213,8 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; // pre-check to help reducing mutex lock - TU_VERIFY((ep_state->busy == 0) && (ep_state->claimed == 0)); + TU_VERIFY(ep_state->busy == 0); + TU_VERIFY(ep_state->claimed == 0); (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); // can only claim the endpoint if it is not busy and not claimed yet. @@ -298,7 +303,7 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t const* p_desc = (uint8_t const*) desc_itf; uint16_t len = 0; - while (itf_count--) { + while ((itf_count--) > 0) { // Next on interface desc len += tu_desc_len(desc_itf); p_desc = tu_desc_next(p_desc); @@ -337,7 +342,7 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable); #if OSAL_MUTEX_REQUIRED - if (ff_buf && ff_bufsize) { + if (ff_buf != NULL && ff_bufsize > 0) { osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef); tu_fifo_config_mutex(&s->ff, is_tx ? new_mutex : NULL, is_tx ? NULL : new_mutex); } @@ -352,9 +357,13 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { (void) s; #if OSAL_MUTEX_REQUIRED - if (s->ff.mutex_wr) osal_mutex_delete(s->ff.mutex_wr); - if (s->ff.mutex_rd) osal_mutex_delete(s->ff.mutex_rd); - #endif + if (s->ff.mutex_wr) { + osal_mutex_delete(s->ff.mutex_wr); + } + if (s->ff.mutex_rd) { + osal_mutex_delete(s->ff.mutex_rd); + } +#endif return true; } @@ -403,7 +412,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_st bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; - TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (mps - 1)))); + TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (mps - 1)))); TU_VERIFY(stream_claim(hwid, s)); TU_ASSERT(stream_xfer(hwid, s, 0)); return true; @@ -411,14 +420,13 @@ bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint3 uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { // skip if no data - TU_VERIFY(tu_fifo_count(&s->ff), 0); - + TU_VERIFY(tu_fifo_count(&s->ff) > 0, 0); TU_VERIFY(stream_claim(hwid, s), 0); // Pull data from FIFO -> EP buf uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); - if (count) { + if (count > 0) { TU_ASSERT(stream_xfer(hwid, s, count), 0); return count; } else { @@ -430,7 +438,7 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { } uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { - TU_VERIFY(bufsize); // TODO support ZLP + TU_VERIFY(bufsize > 0); // TODO support ZLP if (0 == tu_fifo_depth(&s->ff)) { // no fifo for buffered @@ -453,7 +461,7 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const* buf } uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s) { - if (tu_fifo_depth(&s->ff)) { + if (tu_fifo_depth(&s->ff) > 0) { return (uint32_t) tu_fifo_remaining(&s->ff); } else { bool is_busy = true; @@ -596,7 +604,7 @@ void tu_print_mem(void const* buf, uint32_t count, uint8_t indent) { // fill up last row to 16 for printing ascii const uint32_t remain = count % 16; uint8_t nback = (uint8_t) (remain ? remain : 16); - if (remain) { + if (remain > 0) { for (uint32_t i = 0; i < 16 - remain; i++) { tu_printf(" "); for (int j = 0; j < 2 * size; j++) { -- cgit v1.3.1 From a1ae5b20ccf760282538dd81b9290527757fa9c7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 11 Nov 2025 10:27:47 +0700 Subject: update doc --- .github/workflows/static_analysis.yml | 9 +- README.rst | 56 ++++++-- docs/_static/custom.css | 3 + docs/conf.py | 8 +- docs/contributing/code_of_conduct.rst | 1 - docs/contributing/index.rst | 22 --- docs/contributing/porting.rst | 243 ---------------------------------- docs/faq.rst | 32 +---- docs/getting_started.rst | 159 ++++++++++++---------- docs/index.rst | 37 +----- docs/info/changelog.rst | 48 +++++++ docs/info/code_of_conduct.rst | 1 + docs/info/index.rst | 1 + docs/integration.rst | 93 +++++++++++++ docs/porting.rst | 243 ++++++++++++++++++++++++++++++++++ docs/reference/architecture.rst | 39 ++---- docs/reference/boards.rst | 31 +++-- docs/reference/dependencies.rst | 12 +- docs/reference/glossary.rst | 2 +- docs/troubleshooting.rst | 43 ++++-- hw/bsp/family_support.cmake | 49 +++++-- tools/gen_doc.py | 2 +- 22 files changed, 640 insertions(+), 494 deletions(-) create mode 100644 docs/_static/custom.css delete mode 100644 docs/contributing/code_of_conduct.rst delete mode 100644 docs/contributing/index.rst delete mode 100644 docs/contributing/porting.rst create mode 100644 docs/info/code_of_conduct.rst create mode 100644 docs/integration.rst create mode 100644 docs/porting.rst (limited to '.github/workflows') diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index a89cdc279..4db267517 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -90,7 +90,8 @@ jobs: path: ${{ steps.analyze.outputs.sarif-output }} PVS-Studio: - if: github.repository_owner == 'hathach' + # Only run on non-forked PR since secrets token is required + if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false runs-on: ubuntu-latest strategy: fail-fast: false @@ -141,7 +142,8 @@ jobs: path: pvs-studio-${{ matrix.board }}.sarif SonarQube: - if: github.repository_owner == 'hathach' + # Only run on non-forked PR since secrets token is required + if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false runs-on: ubuntu-latest env: BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory @@ -184,7 +186,8 @@ jobs: --define sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json IAR-CStat: - #if: github.repository_owner == 'hathach' + # Only run on non-forked PR since secrets token is required + #if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false if: false runs-on: ubuntu-latest strategy: diff --git a/README.rst b/README.rst index 2d84a2f6c..d0586f55a 100644 --- a/README.rst +++ b/README.rst @@ -1,26 +1,55 @@ +TinyUSB +======= + |Build Status| |CircleCI Status| |Documentation Status| |Static Analysis| |Fuzzing Status| |License| Sponsors -======== +-------- TinyUSB is funded by: Adafruit. Purchasing products from them helps to support this project. .. figure:: docs/assets/adafruit_logo.svg :alt: Adafruit Logo + :align: left :target: https://www.adafruit.com -TinyUSB Project -=============== +.. raw:: html + +
+ +Overview +-------- .. figure:: docs/assets/logo.svg :alt: TinyUSB + :align: left + +.. raw:: html + +
+ +TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems. It’s designed for memory safety +(no dynamic allocation) and thread safety (all interrupts deferred to non-ISR task functions). The stack emphasizes portability, +small footprint, and real-time performance across 50+ MCU families. -TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function. Check out the online `documentation `__ for more details. +Key Features +------------ + +* **Thread-safe:** USB interrupts deferred to task context +* **Memory-safe:** No dynamic allocation, all buffers static +* **Portable:** Supports 50+ MCU families +* **Comprehensive:** Includes CDC, HID, MSC, Audio, and Host support +* **RTOS-friendly:** Works with bare metal, FreeRTOS, RT-Thread, and Mynewt .. figure:: docs/assets/stack.svg :width: 500px + :align: left :alt: stackup +.. raw:: html + +
+ :: . @@ -36,7 +65,7 @@ TinyUSB is an open-source cross-platform USB Host/Device stack for embedded syst Getting started -=============== +--------------- See the `online documentation `_ for information about using TinyUSB and how it is implemented. @@ -49,7 +78,7 @@ For bugs and feature requests, please `raise an issue `_ Host Stack -========== +---------- - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) @@ -81,14 +110,14 @@ Host Stack Similar to the Device Stack, if you have a special requirement, ``usbh_app_driver_get_cb()`` can be used to write your own class driver without modifying the stack. Power Delivery Stack -==================== +-------------------- - Power Delivery 3.0 (PD3.0) with USB Type-C support (WIP) - Super early stage, only for testing purpose - Only support STM32 G4 OS Abstraction layer -==================== +-------------------- TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) events into a central queue, then processing them later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as Communication Device Class (CDC) FIFO. Therefore the stack needs to use some of the OS's basic APIs. Following OSes are already supported out of the box. @@ -98,7 +127,7 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) - **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `_ Supported CPUs -============== +-------------- +--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ | Manufacturer | Family | Device | Host | Highspeed | Driver | Note | @@ -234,7 +263,7 @@ Supported CPUs +--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ Table Legend ------------- +^^^^^^^^^^^^ ========= ========================= ✔ Supported @@ -244,7 +273,7 @@ Table Legend ========= ========================= Development Tools -================= +----------------- The following tools are provided freely to support the development of the TinyUSB project: @@ -273,6 +302,5 @@ The following tools are provided freely to support the development of the TinyUS .. _Supported Boards: docs/reference/boards.rst .. _Dependencies: docs/reference/dependencies.rst .. _Concurrency: docs/reference/concurrency.rst -.. _Contributing: docs/contributing/index.rst .. _Code of Conduct: CODE_OF_CONDUCT.rst -.. _Porting: docs/contributing/porting.rst +.. _Porting: docs/porting.rst diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 000000000..d64d26047 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,3 @@ +.clear-both { + clear: both; +} diff --git a/docs/conf.py b/docs/conf.py index 4249d41f7..cd0338413 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ from pathlib import Path # -- Project information ----------------------------------------------------- project = 'TinyUSB' -copyright = '2024, Ha Thach' +copyright = '2025, Ha Thach' author = 'Ha Thach' @@ -41,6 +41,8 @@ html_favicon = 'assets/logo.svg' html_theme_options = { 'sidebar_hide_name': True, } +html_static_path = ['_static'] +html_css_files = ['custom.css'] todo_include_todos = True @@ -52,7 +54,9 @@ def preprocess_readme(): if src.exists(): content = src.read_text() content = re.sub(r"docs/", r"", content) - content = re.sub(r".rst", r".html", content) + content = re.sub(r"\.rst\b", r".html", content) + if not content.endswith("\n"): + content += "\n" tgt.write_text(content) preprocess_readme() diff --git a/docs/contributing/code_of_conduct.rst b/docs/contributing/code_of_conduct.rst deleted file mode 100644 index fb1859c75..000000000 --- a/docs/contributing/code_of_conduct.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../CODE_OF_CONDUCT.rst \ No newline at end of file diff --git a/docs/contributing/index.rst b/docs/contributing/index.rst deleted file mode 100644 index 78933a3ca..000000000 --- a/docs/contributing/index.rst +++ /dev/null @@ -1,22 +0,0 @@ -************ -Contributing -************ - -Contributing can be highly rewarding, but it can also be frustrating at times. -It takes time to review patches, and as this is an open source project, that -sometimes can take a while. The reviewing process depends on the availability -of the maintainers, who may not be always available. Please try to be -understanding through the process. - -There a few guidelines you need to keep in mind when contributing. Please have -a look at them as that will make the contribution process easier for all -parties. - -Index -===== - -.. toctree:: - :maxdepth: 2 - - code_of_conduct - porting diff --git a/docs/contributing/porting.rst b/docs/contributing/porting.rst deleted file mode 100644 index c3076354c..000000000 --- a/docs/contributing/porting.rst +++ /dev/null @@ -1,243 +0,0 @@ - -******* -Porting -******* - -TinyUSB is designed to be a universal USB protocol stack for microcontrollers. It -handles most of the high level USB protocol and relies on the microcontroller's USB peripheral for -data transactions on different endpoints. Porting is the process of adding low-level support for -the rest of the common stack. Once the low-level is implemented, it is very easy to add USB support -for the microcontroller to other projects, especially those already using TinyUSB such as CircuitPython. - -Below are instructions on how to get the cdc_msc device example running on a new microcontroller. Doing so includes adding the common code necessary for other uses while minimizing other extra code. Whenever you see a phrase or word in ``<>`` it should be replaced. - -Register defs -------------- - -The first step to adding support is including the register definitions and startup code for the -microcontroller in TinyUSB. We write the TinyUSB implementation against these structs instead of higher level functions to keep the code small and to prevent function name collisions in linking of larger projects. For ARM microcontrollers this is the CMSIS definitions. They should be -placed in the ``hw/mcu//`` directory. - -Once this is done, create a directory in ``hw/bsp/`` for the specific board you are using to test the code (duplicating an existing board's directory is the best way to get started). The board should be a readily available development board so that others can also test. - -Build ------ - -Now that those directories are in place, we can start our iteration process to get the example building successfully. To build, run from the root of TinyUSB: - -.. code-block:: bash - - make -C examples/device/cdc_msc BOARD= - -Unless you've read ahead, this will fail miserably. Now, lets get it to fail less by updating the files in the board directory. The code in the board's directory is responsible for setting up the microcontroller's clocks and pins so that USB works. TinyUSB itself only operates on the USB peripheral. The board directory also includes information what files are needed to build the example. - -One of the first things to change is the ``-DCFG_TUSB_MCU`` C flag in the ``board.mk`` file. This is used to tell TinyUSB what platform is being built. So, add an entry to ``src/tusb_option.h`` and update the ``CFLAGS`` to match. - -Update ``board.mk``'s VENDOR and CHIP_FAMILY values when creating the directory for the struct files. Duplicate one of the other sources from ``src/portable`` into ``src/portable//`` and delete all of the implementation internals. We'll cover what everything there does later. For now, get it compiling. - -Implementation --------------- - -At this point you should get an error due to an implementation issue and hopefully the build is setup for the new MCU. You will still need to modify the ``board.mk`` to include specific ``CFLAGS``, the linker script, linker flags, source files, include directories. All file paths are relative to the top of the TinyUSB repo. - -Board Support (BSP) -^^^^^^^^^^^^^^^^^^^ - -The board support code is only used for self-contained examples and testing. It is not used when TinyUSB is part of a larger project. Its responsible for getting the MCU started and the USB peripheral clocked. It also optionally provides LED definitions that are used to blink an LED to show that the code is running. - -It is located in ``hw/bsp//board_.c``. - -``board_init()`` -~~~~~~~~~~~~~~~~ - -``board_init()`` is responsible for starting the MCU, setting up the USB clock and USB pins. It is also responsible for initializing LED pins. - -One useful clock debugging technique is to set up a PWM output at a known value such as 500hz based on the USB clock so that you can verify it is correct with a logic probe or oscilloscope. - -Setup your USB in a crystal-less mode when available. That makes the code easier to port across boards. - -``board_led_write()`` -~~~~~~~~~~~~~~~~~~~~~ - -Feel free to skip this until you want to verify your demo code is running. To implement, set the pin corresponding to the led to output a value that lights the LED when ``state`` is true. - -OS Abstraction Layer (OSAL) -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The OS Abstraction Layer is responsible for providing basic data structures for TinyUSB that may allow for concurrency when used with an RTOS. Without an RTOS it simply handles concurrency issues between the main code and interrupts. The code is almost entirely agnostic of MCU and lives in ``src/osal``. - -In RTOS configurations, ``tud_task()``/``tuh_task()`` blocks behind a synchronization structure when the event queue is empty, so that the scheduler may give the CPU to a different task. To take advantage of the library's capability to yield the CPU when there are no actionable USB device events, ensure that the ``CFG_TUSB_OS`` symbol is defined, e.g ``OPT_OS_FREERTOS`` enables the FreeRTOS scheduler to schedule other threads than that which calls ``tud_task()``/``tuh_task()``. - -Device API -^^^^^^^^^^ - -After the USB device is setup, the USB device code works by processing events on the main thread (by calling ``tud_task()``). These events are queued by the USB interrupt handler. So, there are three parts to the device low-level API: device setup, endpoint setup and interrupt processing. - -All of the code for the low-level device API is in ``src/portable///dcd_.c``. - -Device Setup -~~~~~~~~~~~~ - -``dcd_init()`` -"""""""""""""" - -Initializes the USB peripheral for device mode and enables it. -This function should enable internal D+/D- pull-up for enumeration. - -``dcd_int_enable()`` / ``dcd_int_disable()`` -"""""""""""""""""""""""""""""""""""""""""""" - -Enables or disables the USB device interrupt(s). May be used to prevent concurrency issues when mutating data structures shared between main code and the interrupt handler. - -``dcd_int_handler()`` -""""""""""""""""""""" - -Processes all the hardware generated events e.g Bus reset, new data packet from host etc ... It will be called by application in the MCU USB interrupt handler. - -``dcd_set_address()`` -""""""""""""""""""""" - -Called when the device is given a new bus address. - -If your peripheral automatically changes address during enumeration (like the nrf52) you may leave this empty and also no queue an event for the corresponding SETUP packet. - -``dcd_remote_wakeup()`` -""""""""""""""""""""""" - -Called to remote wake up host when suspended (e.g hid keyboard) - -``dcd_connect()`` / ``dcd_disconnect()`` -"""""""""""""""""""""""""""""""""""""""" - -Connect or disconnect the data-line pull-up resistor. Define only if MCU has an internal pull-up. (BSP may define for MCU without internal pull-up.) - -Special events -~~~~~~~~~~~~~~ - -You must let TinyUSB know when certain events occur so that it can continue its work. There are a few methods you can call to queue events for TinyUSB to process. - -``dcd_event_bus_signal()`` -"""""""""""""""""""""""""" - -There are a number of events that your peripheral may communicate about the state of the bus. Here is an overview of what they are. Events in **BOLD** must be provided for TinyUSB to work. - - -* **DCD_EVENT_RESET** - Triggered when the host resets the bus causing the peripheral to reset. Do any other internal reset you need from the interrupt handler such as resetting the control endpoint. -* DCD_EVENT_SOF - Signals the start of a new USB frame. - -Calls to this look like: - -.. code-block:: c - - dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); - - -The first ``0`` is the USB peripheral number. Statically saying ``0`` is common for single USB device MCUs. - -The ``true`` indicates the call is from an interrupt handler and will always be the case when porting in this way. - -``dcd_setup_received()`` -"""""""""""""""""""""""" - -SETUP packets are a special type of transaction that can occur at any time on the control endpoint, numbered ``0``. Since they are unique, most peripherals have special handling for them. Their data is always 8 bytes in length as well. - -Calls to this look like: - -.. code-block:: c - - dcd_event_setup_received(0, setup, true); - - -As before with ``dcd_event_bus_signal()`` the first argument is the USB peripheral number and the third is true to signal its being called from an interrupt handler. The middle argument is byte array of length 8 with the contents of the SETUP packet. It can be stack allocated because it is copied into the queue. - -Endpoints -~~~~~~~~~ - -Endpoints are the core of the USB data transfer process. They come in a few forms such as control, isochronous, bulk, and interrupt. We won't cover the details here except with some caveats in open below. In general, data is transferred by setting up a buffer of a given length to be transferred on a given endpoint address and then waiting for an interrupt to signal that the transfer is finished. Further details below. - -Endpoints within USB have an address which encodes both the number and direction of an endpoint. TinyUSB provides ``tu_edpt_number()`` and ``tu_edpt_dir()`` to unpack this data from the address. Here is a snippet that does it. - -.. code-block:: c - - uint8_t epnum = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - - -``dcd_edpt_open()`` -""""""""""""""""""" - -Opening an endpoint is done for all non-control endpoints once the host picks a configuration that the device should use. At this point, the endpoint should be enabled in the peripheral and configured to match the endpoint descriptor. Pay special attention to the direction of the endpoint you can get from the helper methods above. It will likely change what registers you are setting. - -Also make sure to enable endpoint specific interrupts. - -``dcd_edpt_close()`` -"""""""""""""""""""" - -Close an endpoint. his function is used for implementing alternate settings. - -After calling this, the device should not respond to any packets directed towards this endpoint. When called, this function must abort any transfers in progress through this endpoint, before returning. - -Implementation is optional. Must be called from the USB task. Interrupts could be disabled or enabled during the call. - -``dcd_edpt_xfer()`` -""""""""""""""""""" - -``dcd_edpt_xfer()`` is responsible for configuring the peripheral to send or receive data from the host. "xfer" is short for "transfer". **This is one of the core methods you must implement for TinyUSB to work (one other is the interrupt handler).** Data from the host is the OUT direction and data to the host is IN. It is used for all endpoints including the control endpoint 0. Make sure to handle the zero-length packet STATUS packet on endpoint 0 correctly. It may be a special transaction to the peripheral. - -Besides that, all other transactions are relatively straight-forward. The endpoint address provides the endpoint -number and direction which usually determines where to write the buffer info. The buffer and its length are usually -written to a specific location in memory and the peripheral is told the data is valid. (Maybe by writing a 1 to a -register or setting a counter register to 0 for OUT or length for IN.) - -The transmit buffer alignment is determined by ``CFG_TUSB_MEM_ALIGN``. - -One potential pitfall is that the buffer may be longer than the maximum endpoint size of one USB -packet. Some peripherals can handle transmitting multiple USB packets for a provided buffer (like the SAMD21). -Others (like the nRF52) may need each USB packet queued individually. To make this work you'll need to track -some state for yourself and queue up an intermediate USB packet from the interrupt handler. - -Once the transaction is going, the interrupt handler will notify TinyUSB of transfer completion. -During transmission, the IN data buffer is guaranteed to remain unchanged in memory until the ``dcd_xfer_complete()`` function is called. - -The ``dcd_edpt_xfer()`` function must never add zero-length-packets (ZLP) on its own to a transfer. If a ZLP is required, -then it must be explicitly sent by the stack calling ``dcd_edpt_xfer()``, by calling ``dcd_edpt_xfer()`` a second time with len=0. -For control transfers, this is automatically done in ``usbd_control.c``. - -At the moment, only a single buffer can be transmitted at once. There is no provision for double-buffering. new ``dcd_edpt_xfer()`` will not -be called again on the same endpoint address until the driver calls ``dcd_xfer_complete()`` (except in cases of USB resets). - -``dcd_xfer_complete()`` -""""""""""""""""""""""" - -Once a transfer completes you must call ``dcd_xfer_complete()`` from the USB interrupt handler to let TinyUSB know that a transaction has completed. Here is a sample call: - -.. code-block:: c - - dcd_event_xfer_complete(0, ep_addr, xfer->actual_len, XFER_RESULT_SUCCESS, true); - - -The arguments are: - - -* the USB peripheral number -* the endpoint address -* the actual length of the transfer. (OUT transfers may be smaller than the buffer given in ``dcd_edpt_xfer()``) -* the result of the transfer. Failure isn't handled yet. -* ``true`` to note the call is from an interrupt handler. - -``dcd_edpt_stall()`` / ``dcd_edpt_clear_stall()`` -""""""""""""""""""""""""""""""""""""""""""""""""" - -Stalling is one way an endpoint can indicate failure such as when an unsupported command is transmitted. The pair of ``dcd_edpt_stall()``, ``dcd_edpt_clear_stall()`` help manage the stall state of all endpoints. - -Woohoo! -------- - -At this point you should have everything working! 🙂 Of course, you may not write perfect code. Here are some tips and tricks for debugging. - -Use `WireShark `_ or `a Beagle `_ to sniff the USB traffic. When things aren't working its likely very early in the USB enumeration process. Figuring out where can help clue in where the issue is. For example: - - -* If the host sends a SETUP packet and its not ACKed then your USB peripheral probably isn't started correctly. -* If the peripheral is started correctly but it still didn't work, then verify your usb clock is correct. (You did output a PWM based on it right? 🙂) -* If the SETUP packet is ACKed but nothing is sent back then you interrupt handler isn't queueing the setup packet correctly. (Also, if you are using your own code instead of an example ``tud_task()`` may not be called.) If that's OK, the ``dcd_xfer_complete()`` may not be setting up the next transaction correctly. diff --git a/docs/faq.rst b/docs/faq.rst index ade51a379..a5fe09495 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -7,7 +7,7 @@ General Questions **Q: What microcontrollers does TinyUSB support?** -TinyUSB supports 30+ MCU families including STM32, RP2040, NXP (iMXRT, Kinetis, LPC), Microchip SAM, Nordic nRF5x, ESP32, and many others. See :doc:`reference/boards` for the complete list. +TinyUSB supports 50+ MCU families including STM32, RP2040, NXP (iMXRT, Kinetis, LPC), Microchip SAM, Nordic nRF5x, ESP32, and many others. See :doc:`reference/boards` for the complete list. **Q: Can I use TinyUSB in commercial projects?** @@ -178,33 +178,3 @@ ESP32-S3 has specific USB implementation challenges: - Check power supply requirements for host mode - Some features may be limited compared to other MCUs - Use ESP32-S3 specific examples and documentation - -STM32CubeIDE Integration -======================== - -**Q: How do I integrate TinyUSB with STM32CubeIDE?** - -1. In STM32CubeMX, enable USB_OTG_FS/HS under Connectivity, set to "Device_Only" mode -2. Enable the USB global interrupt in NVIC Settings -3. Add ``tusb.h`` include and call ``tusb_init()`` in main.c -4. Call ``tud_task()`` in your main loop -5. In the generated ``stm32xxx_it.c``, modify the USB IRQ handler to call ``tud_int_handler(0)`` -6. Create ``tusb_config.h`` and ``usb_descriptors.c`` files - -**Q: STM32CubeIDE generated code conflicts with TinyUSB** - -Don't use STM32's built-in USB middleware (USB Device Library) when using TinyUSB. Disable USB code generation in STM32CubeMX and let TinyUSB handle all USB functionality. - -**Q: STM32 USB interrupt handler setup** - -Replace the generated USB interrupt handler with a call to TinyUSB: - -.. code-block:: c - - void OTG_FS_IRQHandler(void) { - tud_int_handler(0); - } - -**Q: Which STM32 families work best with TinyUSB?** - -STM32F4, F7, and H7 families have the most mature TinyUSB support. STM32F0, F1, F3, L4 families are also supported but may have more limitations. Check the supported boards list for your specific variant. \ No newline at end of file diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 32c80b91c..0c3fcec80 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -2,14 +2,39 @@ Getting Started *************** -This guide will get you up and running with TinyUSB quickly. We'll start with working examples, then show you how to integrate TinyUSB into your own projects. +This guide will get you up and running with TinyUSB quickly with working examples. + +Project Structure +==================== + +TinyUSB separates example applications from board-specific hardware configurations: + +* **Example applications**: Located in `examples/ `_ directories +* **Board Support Packages (BSP)**: Located in ``hw/bsp/FAMILY/boards/BOARD_NAME/`` with hardware abstraction including pin mappings, clock settings, and linker scripts +* **Build system**: Located in `examples/build_system/ `_ which supports both Make and CMake. Though some MCU families such as espressif or rp2040 only support cmake + +For example, stm32h743eval is located in `hw/bsp/stm32h7/boards/stm32h743eval `_ where ``FAMILY=stm32h7`` and ``BOARD=stm32h743eval``. When you build with ``BOARD=stm32h743eval``, the build system automatically finds the corresponding BSP using the FAMILY. + +For guidance on integrating TinyUSB into your own firmware (configuration, descriptors, initialization, and callback workflow), see :doc:`integration`. Quick Start Examples ==================== The fastest way to understand TinyUSB is to see it working. These examples demonstrate core functionality and can be built immediately. -We'll assume you are using the stm32f407disco board. For other boards, see ``Board Support Packages`` below. +We'll assume you are using the **STM32H743 Eval board** (BOARD=stm32h743eval) under the **stm32h7** family. For other boards, see ``Board Support Packages`` below. + +Get the Code +------------ + +.. code-block:: bash + + $ git clone https://github.com/hathach/tinyusb tinyusb + $ cd tinyusb + $ python tools/get_deps.py -b stm32h743eval # or python tools/get_deps.py stm32h7 + +.. note:: + For rp2040 `pico-sdk `_ or `esp-idf `_ for Espressif targets are required; install them per vendor instructions. Simple Device Example --------------------- @@ -17,20 +42,33 @@ Simple Device Example The `cdc_msc `_ example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). **What it does:** + * Appears as a serial port that echoes back any text you send * Appears as a small USB drive with a README.TXT file * Blinks an LED to show activity -**Build and run:** +**Build and run with CMake:** + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ cmake -DBOARD=stm32h743eval -B build # add "-G Ninja" to use Ninja build + $ cmake --build build + # cmake --build build --target cdc_msc-jlink + +.. tip:: + Flashed/Debugger can be selected with --target ``-jlink``, ``-stlink`` or ``-openocd`` depending on your board. Use ``--target help`` to list all supported targets. + +**Build and run with Make:** .. code-block:: bash - $ git clone https://github.com/hathach/tinyusb tinyusb - $ cd tinyusb - $ python tools/get_deps.py stm32f4 # download dependencies, note ESP and RP2 need their SDKs, too $ cd examples/device/cdc_msc - $ cmake -DBOARD=stm32f407disco -B build # add "-G Ninja ." on Windows - $ cmake --build build # add "--target cdc_msc-jlink" for flashing using J-Link, "--target help" to list targets + $ make BOARD=stm32h743eval all + $ make BOARD=stm32h743eval flash-jlink + +.. tip:: + Flashed/Debugger can be selected with target ``flash-jlink``, ``flash-stlink`` or ``flash-openocd`` depending on your board. Connect the device to your computer and you'll see both a new serial port and a small USB drive appear. @@ -40,113 +78,91 @@ Simple Host Example The `cdc_msc_hid `_ example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. **What it does:** + * Detects and enumerates connected USB devices * Communicates with CDC devices (like USB-to-serial adapters) * Reads from MSC devices (like USB drives) * Receives input from HID devices (like keyboards and mice) -**Build and run:** +**Build and run with CMake:** .. code-block:: bash - $ # initial setup see previous example $ cd examples/host/cdc_msc_hid - $ cmake -DBOARD=stm32f407disco -B build # add "-G Ninja ." on Windows - $ cmake --build build # add "--target cdc_msc_hid-jlink" for flashing using J-Link, "--target help" to list targets - -Connect USB devices to see enumeration messages and device-specific interactions in the serial output. - -Project Structure ------------------ - -TinyUSB separates example applications from board-specific hardware configurations: - -* **Example applications**: Located in `examples/device/ `_, `examples/host/ `_, and `examples/dual/ `_ directories -* **Board Support Packages (BSP)**: Located in ``hw/bsp/FAMILY/boards/BOARD_NAME/`` with hardware abstraction including pin mappings, clock settings, and linker scripts - -For example, raspberry_pi_pico is located in `hw/bsp/rp2040/boards/raspberry_pi_pico `_ where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build with ``BOARD=raspberry_pi_pico``, the build system automatically finds the corresponding BSP using the FAMILY. - -Add TinyUSB to Your Project -============================ + $ cmake -DBOARD=stm32h743eval -B build + $ cmake --build build -Once you've seen TinyUSB working, here's how to integrate it into your own project: +**Build and run with Make:** -Integration Steps ------------------ +.. code-block:: bash -1. **Get TinyUSB**: Copy this repository or add it as a git submodule to your project at ``your_project/tinyusb`` + $ cd examples/host/cdc_msc_hid + $ make BOARD=stm32h743eval all + $ make BOARD=stm32h743eval flash-jlink -2. **Add source files**: Add all ``.c`` files from ``tinyusb/src/`` to your project +Connect USB devices to see enumeration messages and device-specific interactions in the serial output. -3. **Configure include paths**: Add ``your_project/tinyusb/src`` to your include path. Ensure your include path contains ``tusb_config.h`` +Additional Build Options +------------------------ -4. **Configure TinyUSB**: Create ``tusb_config.h`` with required macros like ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. Copy from ``examples/device/*/tusb_config.h`` as a starting point +Debug and Logging +^^^^^^^^^^^^^^^^^ -5. **Implement USB descriptors**: For device stack, implement all ``tud_descriptor_*_cb()`` callbacks +TinyUSB built-in logging can be enabled by setting `CFG_TUSB_DEBUG` which is done by passing ``LOG=level``. The higher the level, the more verbose the logging. -6. **Initialize TinyUSB**: Add ``tusb_init()`` to your initialization code +In addition to traditional hw uart as default, logging with debugger such as `Segger RTT `_ (10x faster) is also supported with `LOGGER=rtt` option. -7. **Handle interrupts**: Call ``tusb_int_handler()`` from your USB IRQ handler +.. code-block:: bash -8. **Run USB tasks**: Call ``tud_task()`` (device) or ``tuh_task()`` (host) periodically in your main loop + $ cmake -B build -DBOARD=stm32h743eval -DLOG=2 # logging level 2 with uart + $ cmake -B build -DBOARD=stm32h743eval -DLOG=2 -DLOGGER=rtt # logging level 2 with RTT -9. **Implement class callbacks**: Implement callbacks for enabled USB classes +.. code-block:: bash -Simple Integration Example --------------------------- + $ make BOARD=stm32h743eval LOG=2 all # logging level 2 with uart + $ make BOARD=stm32h743eval LOG=2 LOGGER=rtt all # logging level 2 with RTT -.. code-block:: c +RootHub Port Selection +^^^^^^^^^^^^^^^^^^^^^^ - #include "tusb.h" +Some boards support multiple usb controllers (roothub ports), by default one rh port is used as device, another as host in ``board.mk/board.cmake``. This can be overridden with option ``RHPORT_DEVICE=n`` or ``RHPORT_HOST=n`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: - int main(void) { - board_init(); // Your board initialization +.. code-block:: bash - tusb_rhport_init_t dev_init = { - .role = TUSB_ROLE_DEVICE, - .speed = TUSB_SPEED_AUTO - }; - // tud_descriptor_* callbacks omitted here - tusb_init(0, &dev_init); + $ cmake -B build -DBOARD=stm32h743eval -DRHPORT_DEVICE=1 # select roothub port 1 as device - while(1) { - tud_task(); // TinyUSB device task - your_application(); // Your application code - } - } +.. code-block:: bash - void USB_IRQHandler(void) { - tusb_int_handler(0, true); - } + $ make BOARD=stm32h743eval RHPORT_DEVICE=1 all # select roothub port 1 as device -.. note:: - Unlike many libraries, TinyUSB callbacks don't need to be explicitly registered. The stack automatically calls functions with specific names (e.g., ``tud_cdc_rx_cb()``) when events occur. Simply implement the callbacks you need. +RootHub Port Speed +^^^^^^^^^^^^^^^^^^ -.. note:: - TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`reference/glossary` for more details. +A MCU can support multiple operational speed. By default, the example build system will use the fastest supported on the board. Use option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` e.g To force operating speed -Development Tips -================ +.. code-block:: bash -**Debug builds and logging:** + $ cmake -B build -DBOARD=stm32h743eval -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. code-block:: bash - $ cmake -DBOARD=stm32f407disco -DDEBUG=1 ... # Debug build - $ cmake -DBOARD=stm32f407disco -DLOG=2 ... # Enable detailed logging + $ make BOARD=stm32h743eval RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all + -**IAR Embedded Workbench:** +IAR Embedded Workbench +---------------------- For IAR users, project connection files are available. Import `tools/iar_template.ipcf `_ or use native CMake support (IAR 9.50.1+). See `tools/iar_gen.py `_ for automated project generation. + Common Issues and Solutions -=========================== +--------------------------- **Build Errors** * **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` * **"Board 'X' not found"**: Check the available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` -* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board +* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board or ``python tools/get_deps.py -b BOARD`` **Runtime Issues** @@ -166,6 +182,7 @@ Some examples require udev permissions to access USB devices: Next Steps ========== +* Check :doc:`integration` for integrating TinyUSB into your own firmware * Check :doc:`reference/boards` for board-specific information * Explore more examples in `examples/device/ `_ and `examples/host/ `_ directories * Read :doc:`reference/usb_concepts` to understand USB fundamentals diff --git a/docs/index.rst b/docs/index.rst index ac10dbfd7..39d30a038 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,45 +1,21 @@ -TinyUSB Documentation -===================== - -TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events deferred to non-ISR task functions. - -For Developers --------------- - -TinyUSB provides a complete USB stack implementation supporting both device and host modes across a wide range of microcontrollers. The stack is designed for resource-constrained embedded systems with emphasis on code size, memory efficiency, and real-time performance. - -**Key Features:** - -* **Thread-safe design**: All USB interrupts are deferred to task context -* **Memory-safe**: No dynamic allocation, all buffers are statically allocated -* **Portable**: Supports 30+ MCU families from major vendors -* **Comprehensive**: Device classes (CDC, HID, MSC, Audio, etc.) and Host stack -* **RTOS support**: Works with bare metal, FreeRTOS, RT-Thread, and Mynewt - -**Quick Navigation:** - -* New to TinyUSB? Start with :doc:`getting_started` and :doc:`reference/glossary` -* Want to understand the design? Read :doc:`reference/architecture` and :doc:`reference/usb_concepts` -* Having issues? Check :doc:`faq` and :doc:`troubleshooting` - -Documentation Structure ------------------------ +.. include:: ../README_processed.rst .. toctree:: :maxdepth: 2 :caption: Information getting_started + integration + porting + reference/index faq troubleshooting - reference/index .. toctree:: :maxdepth: 1 :caption: Project Info info/index - contributing/index .. toctree:: :caption: External Links @@ -48,8 +24,3 @@ Documentation Structure Source Code Issue Tracker Discussions - -GitHub Project Main README -========================== - -.. include:: ../README_processed.rst diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index b4423f81e..d6bf846ed 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -20,6 +20,7 @@ API Changes ----------- - Core APIs + - Add weak callbacks with new syntax for better compiler compatibility - Add ``tusb_deinit()`` to cleanup stack - Add time functions: ``tusb_time_millis_api()`` and ``tusb_time_delay_ms_api()`` @@ -27,6 +28,7 @@ API Changes - Introduce ``xfer_isr()`` callback for ISO transfer optimization in device classes - Device APIs + - CDC: Add notification support ``tud_cdc_configure()``, ``tud_cdc_n_notify_uart_state()``, ``tud_cdc_n_notify_conn_speed_change()``, ``tud_cdc_notify_complete_cb()`` - MSC: Add ``tud_msc_inquiry2_cb()`` with bufsize parameter, update ``tud_msc_async_io_done()`` @@ -36,6 +38,7 @@ API Changes ``tud_mtp_response_send()``, ``tud_mtp_event_send()`` - Host APIs + - Core: Add ``tuh_edpt_close()``, ``tuh_address_set()``, ``tuh_descriptor_get_device_local()``, ``tuh_descriptor_get_string_langid()``, ``tuh_connected()``, ``tuh_bus_info_get()`` - Add enumeration callbacks: ``tuh_enum_descriptor_device_cb()``, @@ -50,6 +53,7 @@ Controller Driver (DCD & HCD) ----------------------------- - DWC2 + - Support DWC2 v4.30a with improved reset procedure - Fix core reset: wait for AHB idle before reset - Add STM32 DWC2 data cache support with proper alignment @@ -64,6 +68,7 @@ Controller Driver (DCD & HCD) - Refactor bitfields for better code generation - FSDEV (STM32) + - Fix AT32 compile issues after single-buffered endpoint changes - Add configurable single-buffered isochronous endpoints - Fix STM32H7 recurrent suspend ISR @@ -72,35 +77,42 @@ Controller Driver (DCD & HCD) - Improve PMA size handling for STM32U0 - EHCI + - Fix removed QHD getting reused - Fix NXP USBPHY disconnection detection - Chipidea/NXP + - Fix race condition with spinlock - Improve iMXRT support: fix build, disable BOARD_ConfigMPU, fix attach debouncing on port1 highspeed - Fix iMXRT1064 and add to HIL test pool - MAX3421E + - Use spinlock for thread safety instead of atomic flag - Implement ``hcd_edpt_close()`` - RP2040 + - Fix audio ISO transfer: reset state before notifying stack - Fix CMake RTOS cache variable - Abort transfer if active in ``iso_activate()`` - SAMD + - Add host controller driver support Device Stack ------------ - USBD Core + - Introduce ``xfer_isr()`` callback for interrupt-time transfer handling - Add ``usbd_edpt_xfer_fifo()`` stub - Revert endpoint busy/claim status if ``xfer_isr()`` defers to ``xfer_cb()`` - Audio + - Major simplification of UAC driver and alt settings management - Move ISO transfers into ``xfer_isr()`` for better performance - Remove FIFO mutex (single producer/consumer optimization) @@ -109,25 +121,30 @@ Device Stack - Update buffer macros with cache line size alignment - CDC + - Add notification support: ``CFG_TUD_CDC_NOTIFY``, ``tud_cdc_n_notify_conn_speed_change()``, ``tud_cdc_notify_complete_cb()`` - Reduce default bInterval from 16ms to 1ms for better responsiveness - Rename ``tud_cdc_configure_fifo()`` to ``tud_cdc_configure()`` and add ``tx_overwritable_if_not_connected`` option - Fix web serial robustness with major overhaul and logic cleanup - HID + - Add Usage Page and Table for Power Devices (0x84 - 0x85) - Fix HID descriptor parser variable size and 4-byte item handling - Add consumer page configurations - MIDI + - Fix MIDI interface descriptor handling after audio streaming interface - Skip RX data with all zeroes - MSC + - Add async I/O support for MSC using ``tud_msc_async_io_done()`` - Add ``tud_msc_inquiry2_cb()`` with bufsize for full inquiry response - MTP + - Add new Media Transfer Protocol (MTP) device class driver - Support MTP operations: GetDeviceInfo, SendObjectInfo, SendObject - Add MTP event support with ``tud_mtp_event_send()`` @@ -135,13 +152,16 @@ Device Stack - Add hardware-in-the-loop testing support - NCM + - Add USB NCM link state control support - Fix DHCP offer/ACK destination - USBTMC + - Add vendor-specific message support - Vendor + - Fix vendor device reset and open issues - Fix descriptor parsing for ``CFG_TUD_VENDOR > 1`` - Fix vendor FIFO argument calculation @@ -150,6 +170,7 @@ Host Stack ---------- - USBH Core + - Major enumeration improvements: - Fix enumeration racing conditions - Add proper attach debouncing with hub/rootport handling (200ms delay) @@ -173,6 +194,7 @@ Host Stack - Force removed devices in same bus info before setting address - CDC Serial Host + - Major refactor to generalize CDC serial drivers (FTDI, CP210x, CH34x, PL2303, ACM) - Add explicit ``sync()`` API with ``TU_API_SYNC()`` returning ``tusb_xfer_result_t`` - Rename ``tuh_cdc_get_local_line_coding()`` to ``tuh_cdc_get_line_coding_local()`` @@ -180,6 +202,7 @@ Host Stack - Implement ``tuh_cdc_get/set_dtr/rts()`` as inline functions - MIDI Host + - Major API changes: - Rename ``tuh_midi_stream_flush()`` to ``tuh_midi_write_flush()`` - Add ``tuh_midi_packet_read_n()`` and ``tuh_midi_packet_write_n()`` @@ -189,9 +212,11 @@ Host Stack - Add ``tuh_midi_descriptor_cb()`` and ``tuh_midi_itf_get_info()`` - MSC Host + - Continue async I/O improvements - HID Host + - Fix version string to actually show version 0.18.0 @@ -226,6 +251,7 @@ Controller Driver (DCD & HCD) ----------------------------- - DWC2 + - Add DMA support for both device and host controller - Add host driver support including: full/high speed, control/bulk/interrupt (CBI) transfer, split CBI i.e FS/LS attached via highspeed hub, hub support @@ -695,6 +721,7 @@ Controller Driver (DCD & HCD) ----------------------------- - [DWC2] Generalize synopsys dwc2 with synopsys/dwc2 which support both FS and HS phy (UTMI and ULPI) for various MCUs. + - Broadcom 28/27xx on raspberrypi SBC - Silicon Labs EFM32 - Espressif ESP32 Sx @@ -916,6 +943,7 @@ HID - Add more hid keys constant from 0x6B to 0xA4 - [Breaking] rename API + - ``HID_PROTOCOL_NONE/KEYBOARD/MOUSE`` to ``HID_ITF_PROTOCOL_NONE/KEYBOARD/MOUSE`` - ``tud_hid_boot_mode()`` to ``tud_hid_get_protocol()`` - ``tud_hid_boot_mode_cb()`` to ``tud_hid_set_protocol_cb()`` @@ -925,6 +953,7 @@ MIDI - Fix MIDI buffer overflow issue - [Breaking] rename API + - Rename ``tud_midi_read()`` to ``tud_midi_stream_read()`` - Rename ``tud_midi_write()`` to ``tud_midi_stream_write()`` - Rename ``tud_midi_receive()`` to ``tud_midi_packet_read()`` @@ -1075,15 +1104,19 @@ Device Controller Driver - Use ``dcd_event_bus_reset()`` with link speed to replace bus_signal - ESP32-S2: + - Add bus suspend and wakeup support - SAMD21: + - Fix (walkaround) samd21 setup_packet overflow by USB DMA - STM32 Synopsys: + - Rework USB FIFO allocation scheme and allow RX FIFO size reduction - Sony CXD56 + - Update Update Spresense SDK to 2.0.2 - Fix dcd issues with setup packets - Correct EP number for cdc_msc example @@ -1100,19 +1133,24 @@ USB Device **Class Driver** - CDC + - Allow to transmit data, even if the host does not support control line states i.e set DTR - HID + - change default ``CFG_TUD_HID_EP_BUFSIZE`` from 16 to 64 - MIDI + - Fix midi sysex sending bug - MSC + - Invoke only scsi complete callback after status transaction is complete. - Fix ``scsi_mode_sense6_t`` padding, which cause IAR compiler internal error. - USBTMC + - Change interrupt endpoint example size to 8 instead of 2 for better compatibility with mcu **Example** @@ -1154,6 +1192,7 @@ Device Controller Driver - Enhance STM32 Synopsys - Support bus events disconnection/suspend/resume/wakeup + - Improve transfer performance with optimizing xfer and fifo size - Support Highspeed port (OTG_HS) with both internal and external PHY - Support multiple usb ports with rhport=1 is highspeed on selected MCUs e.g H743, F23. It is possible to have OTG_HS to run on Fullspeed PHY (e.g lacking external PHY) @@ -1163,6 +1202,7 @@ Device Controller Driver - Support F105, F107 - Enhance STM32 fsdev + - Improve dcd fifo allocation - Fix ISTR race condition - Support remap USB IRQ on supported MCUs @@ -1171,6 +1211,7 @@ Device Controller Driver - Enhance NUC 505: enhance set configure behavior - Enhance SAMD + - Fix race condition with setup packet - Add SAMD11 option ``OPT_MCU_SAMD11`` - Add SAME5x option ``OPT_MCU_SAME5X`` @@ -1178,6 +1219,7 @@ Device Controller Driver - Fix SAMG control data toggle and stall race condition - Enhance nRF + - Fix hanged when ``tud_task()`` is called within critical section (disabled interrupt) - Fix disconnect bus event not submitted - Implement ISO transfer and ``dcd_edpt_close()`` @@ -1203,6 +1245,7 @@ USB Device - Improve USB Highspeed support with actual link speed detection with ``dcd_event_bus_reset()`` - Enhance class driver management + - ``usbd_driver_open()`` add max length argument, and return length of interface (0 for not supported). Return value is used for finding appropriate driver - Add application implemented class driver via ``usbd_app_driver_get_cb()`` - IAD is handled to assign driver id @@ -1219,11 +1262,13 @@ USB Device - USBTMC: fix descriptors when INT EP is disabled - CDC: + - Send zero length packet for end of data when needed - Add ``tud_cdc_tx_complete_cb()`` callback - Change ``tud_cdc_n_write_flush()`` return number of bytes forced to transfer, and flush when writing enough data to fifo - MIDI: + - Add packet interface - Add multiple jack descriptors - Fix MIDI driver for sysex @@ -1231,12 +1276,14 @@ USB Device - DFU Runtime: fix response to SET_INTERFACE and DFU_GETSTATUS request - Rename some configure macro to make it clear that those are used directly for endpoint transfer + - ``CFG_TUD_HID_BUFSIZE`` to ``CFG_TUD_HID_EP_BUFSIZE`` - ``CFG_TUD_CDC_EPSIZE`` to ``CFG_TUD_CDC_EP_BUFSIZE`` - ``CFG_TUD_MSC_BUFSIZE`` to ``CFG_TUD_MSC_EP_BUFSIZE`` - ``CFG_TUD_MIDI_EPSIZE`` to ``CFG_TUD_MIDI_EP_BUFSIZE`` - HID: + - Fix gamepad template descriptor - Add multiple HID interface API - Add extra comma to HID_REPORT_ID @@ -1258,6 +1305,7 @@ Examples - Add new ``hid_multiple_interface`` - Enhance ``net_lwip_webserver`` example + - Add multiple configuration: RNDIS for Windows, CDC-ECM for macOS (Linux will work with both) - Update lwip to STABLE-2_1_2_RELEASE for ``net_lwip_webserver`` diff --git a/docs/info/code_of_conduct.rst b/docs/info/code_of_conduct.rst new file mode 100644 index 000000000..2d70708d4 --- /dev/null +++ b/docs/info/code_of_conduct.rst @@ -0,0 +1 @@ +.. include:: ../../CODE_OF_CONDUCT.rst diff --git a/docs/info/index.rst b/docs/info/index.rst index a636f37dc..b6d30b432 100644 --- a/docs/info/index.rst +++ b/docs/info/index.rst @@ -10,3 +10,4 @@ Index changelog contributors + code_of_conduct diff --git a/docs/integration.rst b/docs/integration.rst new file mode 100644 index 000000000..3480746d0 --- /dev/null +++ b/docs/integration.rst @@ -0,0 +1,93 @@ +******************* +Integrating TinyUSB +******************* + +Once you've seen TinyUSB working in the examples, use this guide to wire the stack into your own firmware. + +Integration Steps +================= + +1. **Get TinyUSB**: Copy this repository or add it as a git submodule to your project at ``your_project/tinyusb``. +2. **Add source files**: Add every ``.c`` file from ``tinyusb/src/`` to your project build system. + +.. note:: + Only supported dcd/hcd drivers for your CPU sources under ``tinyusb/src/portable/vendor/usbip/`` are needed. Add + +3. **Configure TinyUSB**: Create ``tusb_config.h`` with macros such as ``CFG_TUSB_MCU``, ``CFG_TUSB_OS``, and class enable flags. Start from any example's ``tusb_config.h`` and tweak. +4. **Configure include paths**: Add ``your_project/tinyusb/src`` (and the folder holding ``tusb_config.h``) to your include paths. +5. **Implement USB descriptors**: For device stack, implement the ``tud_descriptor_*_cb()`` callbacks (device) or host descriptor helpers that match your product. +6. **Initialize TinyUSB**: Call ``tusb_init()`` once the clocks/peripherals are ready. Pass ``tusb_rhport_init_t`` if you need per-port settings. +7. **Handle interrupts**: From the USB ISR call ``tusb_int_handler(rhport, true)`` so the stack can process events. +8. **Run USB tasks**: Call ``tud_task()`` (device) or ``tuh_task()`` (host) regularly from the main loop, RTOS task. +9. **Implement class callbacks**: Provide the callbacks for the classes you enabled (e.g., ``tud_cdc_rx_cb()``, ``tuh_msc_mount_cb()``). + +Minimal Example +=============== + +.. code-block:: c + + #include "tusb.h" + + int main(void) { + board_init(); // Your board initialization + + // Init device stack on roothub port 0 for highspeed device + tusb_rhport_init_t dev_init = { + .role = TUSB_ROLE_DEVICE, + .speed = TUSB_SPEED_HIGH + }; + tusb_init(0, &dev_init); + + // init host stack on roothub port 1 for fullspeed host + tusb_rhport_init_t host_init = { + .role = TUSB_ROLE_DEVICE, + .speed = TUSB_SPEED_FULL + }; + tusb_init(1, &host_init); + + while (1) { + tud_task(); // device task + tuh_task(); // host task + + app_task(); // Your application logic + } + } + + void USB0_IRQHandler(void) { + // forward interrupt port 0 to TinyUSB stack + tusb_int_handler(0, true); + } + + void USB1_IRQHandler(void) { + // forward interrupt port 0 to TinyUSB stack + tusb_int_handler(1, true); + } + +.. note:: + Unlike many libraries, TinyUSB callbacks don't need to be registered. Implement functions with the prescribed names (for example ``tud_cdc_rx_cb()``) and the stack will invoke them automatically. + +.. note:: + Naming follows ``tud_*`` for device APIs and ``tuh_*`` for host APIs. Refer to :doc:`reference/glossary` for a summary of the prefixes and callback naming rules. + + +STM32CubeIDE Integration +======================== + +To integrate TinyUSB device stack with STM32CubeIDE + +1. In STM32CubeMX, enable USB_OTG_FS/HS under Connectivity, set to "Device_Only" mode +2. Enable the USB global interrupt in NVIC Settings +3. Add ``tusb.h`` include and call ``tusb_init()`` in main.c +4. Call ``tud_task()`` in your main loop +5. In the generated ``stm32xxx_it.c``, modify the USB IRQ handler to call ``tud_int_handler(0)`` + +.. code-block:: c + + void OTG_FS_IRQHandler(void) { + tud_int_handler(0); + } + +6. Create ``tusb_config.h`` and ``usb_descriptors.c`` files + +.. tip:: + STM32CubeIDE generated code conflicts with TinyUSB. Don't use STM32's built-in USB middleware (USB Device Library) when using TinyUSB. Disable USB code generation in STM32CubeMX and let TinyUSB handle all USB functionality. diff --git a/docs/porting.rst b/docs/porting.rst new file mode 100644 index 000000000..c3076354c --- /dev/null +++ b/docs/porting.rst @@ -0,0 +1,243 @@ + +******* +Porting +******* + +TinyUSB is designed to be a universal USB protocol stack for microcontrollers. It +handles most of the high level USB protocol and relies on the microcontroller's USB peripheral for +data transactions on different endpoints. Porting is the process of adding low-level support for +the rest of the common stack. Once the low-level is implemented, it is very easy to add USB support +for the microcontroller to other projects, especially those already using TinyUSB such as CircuitPython. + +Below are instructions on how to get the cdc_msc device example running on a new microcontroller. Doing so includes adding the common code necessary for other uses while minimizing other extra code. Whenever you see a phrase or word in ``<>`` it should be replaced. + +Register defs +------------- + +The first step to adding support is including the register definitions and startup code for the +microcontroller in TinyUSB. We write the TinyUSB implementation against these structs instead of higher level functions to keep the code small and to prevent function name collisions in linking of larger projects. For ARM microcontrollers this is the CMSIS definitions. They should be +placed in the ``hw/mcu//`` directory. + +Once this is done, create a directory in ``hw/bsp/`` for the specific board you are using to test the code (duplicating an existing board's directory is the best way to get started). The board should be a readily available development board so that others can also test. + +Build +----- + +Now that those directories are in place, we can start our iteration process to get the example building successfully. To build, run from the root of TinyUSB: + +.. code-block:: bash + + make -C examples/device/cdc_msc BOARD= + +Unless you've read ahead, this will fail miserably. Now, lets get it to fail less by updating the files in the board directory. The code in the board's directory is responsible for setting up the microcontroller's clocks and pins so that USB works. TinyUSB itself only operates on the USB peripheral. The board directory also includes information what files are needed to build the example. + +One of the first things to change is the ``-DCFG_TUSB_MCU`` C flag in the ``board.mk`` file. This is used to tell TinyUSB what platform is being built. So, add an entry to ``src/tusb_option.h`` and update the ``CFLAGS`` to match. + +Update ``board.mk``'s VENDOR and CHIP_FAMILY values when creating the directory for the struct files. Duplicate one of the other sources from ``src/portable`` into ``src/portable//`` and delete all of the implementation internals. We'll cover what everything there does later. For now, get it compiling. + +Implementation +-------------- + +At this point you should get an error due to an implementation issue and hopefully the build is setup for the new MCU. You will still need to modify the ``board.mk`` to include specific ``CFLAGS``, the linker script, linker flags, source files, include directories. All file paths are relative to the top of the TinyUSB repo. + +Board Support (BSP) +^^^^^^^^^^^^^^^^^^^ + +The board support code is only used for self-contained examples and testing. It is not used when TinyUSB is part of a larger project. Its responsible for getting the MCU started and the USB peripheral clocked. It also optionally provides LED definitions that are used to blink an LED to show that the code is running. + +It is located in ``hw/bsp//board_.c``. + +``board_init()`` +~~~~~~~~~~~~~~~~ + +``board_init()`` is responsible for starting the MCU, setting up the USB clock and USB pins. It is also responsible for initializing LED pins. + +One useful clock debugging technique is to set up a PWM output at a known value such as 500hz based on the USB clock so that you can verify it is correct with a logic probe or oscilloscope. + +Setup your USB in a crystal-less mode when available. That makes the code easier to port across boards. + +``board_led_write()`` +~~~~~~~~~~~~~~~~~~~~~ + +Feel free to skip this until you want to verify your demo code is running. To implement, set the pin corresponding to the led to output a value that lights the LED when ``state`` is true. + +OS Abstraction Layer (OSAL) +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The OS Abstraction Layer is responsible for providing basic data structures for TinyUSB that may allow for concurrency when used with an RTOS. Without an RTOS it simply handles concurrency issues between the main code and interrupts. The code is almost entirely agnostic of MCU and lives in ``src/osal``. + +In RTOS configurations, ``tud_task()``/``tuh_task()`` blocks behind a synchronization structure when the event queue is empty, so that the scheduler may give the CPU to a different task. To take advantage of the library's capability to yield the CPU when there are no actionable USB device events, ensure that the ``CFG_TUSB_OS`` symbol is defined, e.g ``OPT_OS_FREERTOS`` enables the FreeRTOS scheduler to schedule other threads than that which calls ``tud_task()``/``tuh_task()``. + +Device API +^^^^^^^^^^ + +After the USB device is setup, the USB device code works by processing events on the main thread (by calling ``tud_task()``). These events are queued by the USB interrupt handler. So, there are three parts to the device low-level API: device setup, endpoint setup and interrupt processing. + +All of the code for the low-level device API is in ``src/portable///dcd_.c``. + +Device Setup +~~~~~~~~~~~~ + +``dcd_init()`` +"""""""""""""" + +Initializes the USB peripheral for device mode and enables it. +This function should enable internal D+/D- pull-up for enumeration. + +``dcd_int_enable()`` / ``dcd_int_disable()`` +"""""""""""""""""""""""""""""""""""""""""""" + +Enables or disables the USB device interrupt(s). May be used to prevent concurrency issues when mutating data structures shared between main code and the interrupt handler. + +``dcd_int_handler()`` +""""""""""""""""""""" + +Processes all the hardware generated events e.g Bus reset, new data packet from host etc ... It will be called by application in the MCU USB interrupt handler. + +``dcd_set_address()`` +""""""""""""""""""""" + +Called when the device is given a new bus address. + +If your peripheral automatically changes address during enumeration (like the nrf52) you may leave this empty and also no queue an event for the corresponding SETUP packet. + +``dcd_remote_wakeup()`` +""""""""""""""""""""""" + +Called to remote wake up host when suspended (e.g hid keyboard) + +``dcd_connect()`` / ``dcd_disconnect()`` +"""""""""""""""""""""""""""""""""""""""" + +Connect or disconnect the data-line pull-up resistor. Define only if MCU has an internal pull-up. (BSP may define for MCU without internal pull-up.) + +Special events +~~~~~~~~~~~~~~ + +You must let TinyUSB know when certain events occur so that it can continue its work. There are a few methods you can call to queue events for TinyUSB to process. + +``dcd_event_bus_signal()`` +"""""""""""""""""""""""""" + +There are a number of events that your peripheral may communicate about the state of the bus. Here is an overview of what they are. Events in **BOLD** must be provided for TinyUSB to work. + + +* **DCD_EVENT_RESET** - Triggered when the host resets the bus causing the peripheral to reset. Do any other internal reset you need from the interrupt handler such as resetting the control endpoint. +* DCD_EVENT_SOF - Signals the start of a new USB frame. + +Calls to this look like: + +.. code-block:: c + + dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + + +The first ``0`` is the USB peripheral number. Statically saying ``0`` is common for single USB device MCUs. + +The ``true`` indicates the call is from an interrupt handler and will always be the case when porting in this way. + +``dcd_setup_received()`` +"""""""""""""""""""""""" + +SETUP packets are a special type of transaction that can occur at any time on the control endpoint, numbered ``0``. Since they are unique, most peripherals have special handling for them. Their data is always 8 bytes in length as well. + +Calls to this look like: + +.. code-block:: c + + dcd_event_setup_received(0, setup, true); + + +As before with ``dcd_event_bus_signal()`` the first argument is the USB peripheral number and the third is true to signal its being called from an interrupt handler. The middle argument is byte array of length 8 with the contents of the SETUP packet. It can be stack allocated because it is copied into the queue. + +Endpoints +~~~~~~~~~ + +Endpoints are the core of the USB data transfer process. They come in a few forms such as control, isochronous, bulk, and interrupt. We won't cover the details here except with some caveats in open below. In general, data is transferred by setting up a buffer of a given length to be transferred on a given endpoint address and then waiting for an interrupt to signal that the transfer is finished. Further details below. + +Endpoints within USB have an address which encodes both the number and direction of an endpoint. TinyUSB provides ``tu_edpt_number()`` and ``tu_edpt_dir()`` to unpack this data from the address. Here is a snippet that does it. + +.. code-block:: c + + uint8_t epnum = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + + +``dcd_edpt_open()`` +""""""""""""""""""" + +Opening an endpoint is done for all non-control endpoints once the host picks a configuration that the device should use. At this point, the endpoint should be enabled in the peripheral and configured to match the endpoint descriptor. Pay special attention to the direction of the endpoint you can get from the helper methods above. It will likely change what registers you are setting. + +Also make sure to enable endpoint specific interrupts. + +``dcd_edpt_close()`` +"""""""""""""""""""" + +Close an endpoint. his function is used for implementing alternate settings. + +After calling this, the device should not respond to any packets directed towards this endpoint. When called, this function must abort any transfers in progress through this endpoint, before returning. + +Implementation is optional. Must be called from the USB task. Interrupts could be disabled or enabled during the call. + +``dcd_edpt_xfer()`` +""""""""""""""""""" + +``dcd_edpt_xfer()`` is responsible for configuring the peripheral to send or receive data from the host. "xfer" is short for "transfer". **This is one of the core methods you must implement for TinyUSB to work (one other is the interrupt handler).** Data from the host is the OUT direction and data to the host is IN. It is used for all endpoints including the control endpoint 0. Make sure to handle the zero-length packet STATUS packet on endpoint 0 correctly. It may be a special transaction to the peripheral. + +Besides that, all other transactions are relatively straight-forward. The endpoint address provides the endpoint +number and direction which usually determines where to write the buffer info. The buffer and its length are usually +written to a specific location in memory and the peripheral is told the data is valid. (Maybe by writing a 1 to a +register or setting a counter register to 0 for OUT or length for IN.) + +The transmit buffer alignment is determined by ``CFG_TUSB_MEM_ALIGN``. + +One potential pitfall is that the buffer may be longer than the maximum endpoint size of one USB +packet. Some peripherals can handle transmitting multiple USB packets for a provided buffer (like the SAMD21). +Others (like the nRF52) may need each USB packet queued individually. To make this work you'll need to track +some state for yourself and queue up an intermediate USB packet from the interrupt handler. + +Once the transaction is going, the interrupt handler will notify TinyUSB of transfer completion. +During transmission, the IN data buffer is guaranteed to remain unchanged in memory until the ``dcd_xfer_complete()`` function is called. + +The ``dcd_edpt_xfer()`` function must never add zero-length-packets (ZLP) on its own to a transfer. If a ZLP is required, +then it must be explicitly sent by the stack calling ``dcd_edpt_xfer()``, by calling ``dcd_edpt_xfer()`` a second time with len=0. +For control transfers, this is automatically done in ``usbd_control.c``. + +At the moment, only a single buffer can be transmitted at once. There is no provision for double-buffering. new ``dcd_edpt_xfer()`` will not +be called again on the same endpoint address until the driver calls ``dcd_xfer_complete()`` (except in cases of USB resets). + +``dcd_xfer_complete()`` +""""""""""""""""""""""" + +Once a transfer completes you must call ``dcd_xfer_complete()`` from the USB interrupt handler to let TinyUSB know that a transaction has completed. Here is a sample call: + +.. code-block:: c + + dcd_event_xfer_complete(0, ep_addr, xfer->actual_len, XFER_RESULT_SUCCESS, true); + + +The arguments are: + + +* the USB peripheral number +* the endpoint address +* the actual length of the transfer. (OUT transfers may be smaller than the buffer given in ``dcd_edpt_xfer()``) +* the result of the transfer. Failure isn't handled yet. +* ``true`` to note the call is from an interrupt handler. + +``dcd_edpt_stall()`` / ``dcd_edpt_clear_stall()`` +""""""""""""""""""""""""""""""""""""""""""""""""" + +Stalling is one way an endpoint can indicate failure such as when an unsupported command is transmitted. The pair of ``dcd_edpt_stall()``, ``dcd_edpt_clear_stall()`` help manage the stall state of all endpoints. + +Woohoo! +------- + +At this point you should have everything working! 🙂 Of course, you may not write perfect code. Here are some tips and tricks for debugging. + +Use `WireShark `_ or `a Beagle `_ to sniff the USB traffic. When things aren't working its likely very early in the USB enumeration process. Figuring out where can help clue in where the issue is. For example: + + +* If the host sends a SETUP packet and its not ACKed then your USB peripheral probably isn't started correctly. +* If the peripheral is started correctly but it still didn't work, then verify your usb clock is correct. (You did output a PWM based on it right? 🙂) +* If the SETUP packet is ACKed but nothing is sent back then you interrupt handler isn't queueing the setup packet correctly. (Also, if you are using your own code instead of an example ``tud_task()`` may not be called.) If that's OK, the ``dcd_xfer_complete()`` may not be setting up the next transaction correctly. diff --git a/docs/reference/architecture.rst b/docs/reference/architecture.rst index 8e4c6890e..70ea17ed4 100644 --- a/docs/reference/architecture.rst +++ b/docs/reference/architecture.rst @@ -42,36 +42,23 @@ Layer Structure TinyUSB follows a layered architecture from hardware to application: -.. code-block:: none +.. figure:: ../assets/stack.svg + :width: 500px + :align: left + :alt: stackup + +.. raw:: html - ┌─────────────────────────────────────────┐ - │ Application Layer │ ← Your code - ├─────────────────────────────────────────┤ - │ USB Class Drivers │ ← CDC, HID, MSC, etc. - ├─────────────────────────────────────────┤ - │ Device/Host Stack Core │ ← USB protocol handling - ├─────────────────────────────────────────┤ - │ Hardware Abstraction (DCD/HCD) │ ← MCU-specific drivers - ├─────────────────────────────────────────┤ - │ OS Abstraction (OSAL) │ ← RTOS integration - ├─────────────────────────────────────────┤ - │ Common Utilities & FIFO │ ← Shared components - └─────────────────────────────────────────┘ +
Component Overview ------------------ -**Application Layer**: Your main application code that uses TinyUSB APIs. - -**Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. - -**Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. - -**Hardware Abstraction**: MCU-specific code that interfaces with USB peripheral hardware. - -**OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. - -**Common Utilities**: Shared code including FIFO implementations, binary helpers, and utility functions. +- **Application Layer**: Your main application code that uses TinyUSB APIs. +- **Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. +- **Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. +- **OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. +- **Device/Host Controller Driver**: drivers that interface with MCU USB peripherals. Several MCUs may share a common driver. Device Stack Architecture ========================= @@ -85,7 +72,7 @@ Core Components - MCU-specific USB device peripheral driver - Handles endpoint configuration and data transfers - Abstracts hardware differences between MCU families -- Located in ``src/portable/VENDOR/FAMILY/`` +- Located in ``src/portable/VENDOR/USBIP/`` **USB Device Core (USBD)**: - Implements USB device state machine diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index e668e2693..12da5c90b 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -107,17 +107,20 @@ olimex_emz64 Olimex PIC32-EMZ64 pic32mz http olimex_hmz144 Olimex PIC32-HMZ144 pic32mz https://www.olimex.com/Products/PIC/Development/PIC32-HMZ144/open-source-hardware cynthion_d11 Great Scott Gadgets Cynthion samd11 https://greatscottgadgets.com/cynthion/ samd11_xplained SAMD11 Xplained Pro samd11 https://www.microchip.com/en-us/development-tool/ATSAMD11-XPRO -atsamd21_xpro SAMD21 Xplained Pro samd21 https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMD21-XPRO -circuitplayground_express Adafruit Circuit Playground Express samd21 https://www.adafruit.com/product/3333 -curiosity_nano SAMD21 Curiosty Nano samd21 https://www.microchip.com/en-us/development-tool/dm320119 -cynthion_d21 Great Scott Gadgets Cynthion samd21 https://greatscottgadgets.com/cynthion/ -feather_m0_express Adafruit Feather M0 Express samd21 https://www.adafruit.com/product/3403 -itsybitsy_m0 Adafruit ItsyBitsy M0 samd21 https://www.adafruit.com/product/3727 -metro_m0_express Adafruit Metro M0 Express samd21 https://www.adafruit.com/product/3505 -qtpy Adafruit QT Py samd21 https://www.adafruit.com/product/4600 -seeeduino_xiao Seeeduino XIAO samd21 https://wiki.seeedstudio.com/Seeeduino-XIAO/ -sparkfun_samd21_mini_usb SparkFun SAMD21 Mini samd21 https://www.sparkfun.com/products/13664 -trinket_m0 Adafruit Trinket M0 samd21 https://www.adafruit.com/product/3500 +atsamd21_xpro SAMD21 Xplained Pro samd2x_l2x https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMD21-XPRO +atsaml21_xpro SAML21 Xplained Pro samd2x_l2x https://www.microchip.com/en-us/development-tool/atsaml21-xpro-b +circuitplayground_express Adafruit Circuit Playground Express samd2x_l2x https://www.adafruit.com/product/3333 +curiosity_nano SAMD21 Curiosty Nano samd2x_l2x https://www.microchip.com/en-us/development-tool/dm320119 +cynthion_d21 Great Scott Gadgets Cynthion samd2x_l2x https://greatscottgadgets.com/cynthion/ +feather_m0_express Adafruit Feather M0 Express samd2x_l2x https://www.adafruit.com/product/3403 +itsybitsy_m0 Adafruit ItsyBitsy M0 samd2x_l2x https://www.adafruit.com/product/3727 +metro_m0_express Adafruit Metro M0 Express samd2x_l2x https://www.adafruit.com/product/3505 +qtpy Adafruit QT Py samd2x_l2x https://www.adafruit.com/product/4600 +saml22_feather SAML22 Feather samd2x_l2x https://github.com/joeycastillo/Feather-Projects/tree/main/SAML22%20Feather +seeeduino_xiao Seeeduino XIAO samd2x_l2x https://wiki.seeedstudio.com/Seeeduino-XIAO/ +sensorwatch_m0 SensorWatch samd2x_l2x https://github.com/joeycastillo/Sensor-Watch +sparkfun_samd21_mini_usb SparkFun SAMD21 Mini samd2x_l2x https://www.sparkfun.com/products/13664 +trinket_m0 Adafruit Trinket M0 samd2x_l2x https://www.adafruit.com/product/3500 d5035_01 D5035-01 samd5x_e5x https://github.com/RudolphRiedel/USB_CAN-FD feather_m4_express Adafruit Feather M4 Express samd5x_e5x https://www.adafruit.com/product/3857 itsybitsy_m4 Adafruit ItsyBitsy M4 samd5x_e5x https://www.adafruit.com/product/3800 @@ -125,10 +128,9 @@ metro_m4_express Adafruit Metro M4 Express samd5x_e5x http pybadge Adafruit PyBadge samd5x_e5x https://www.adafruit.com/product/4200 pyportal Adafruit PyPortal samd5x_e5x https://www.adafruit.com/product/4116 same54_xplained SAME54 Xplained Pro samd5x_e5x https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAME54-XPRO +same70_qmtech SAME70 QMTech same7x https://www.aliexpress.com/item/1005003173783268.html +same70_xplained SAME70 Xplained same7x https://www.microchip.com/en-us/development-tool/atsame70-xpld samg55_xplained SAMG55 Xplained Pro samg https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMG55-XPRO -atsaml21_xpro SAML21 Xplained Pro saml2x https://www.microchip.com/en-us/development-tool/atsaml21-xpro-b -saml22_feather SAML22 Feather saml2x https://github.com/joeycastillo/Feather-Projects/tree/main/SAML22%20Feather -sensorwatch_m0 SensorWatch saml2x https://github.com/joeycastillo/Sensor-Watch ========================= =================================== ========== ================================================================================= ====== MindMotion @@ -295,6 +297,7 @@ stm32l052dap52 STM32 L052 DAP stm32l0 n/a stm32l0538disco STM32 L0538 Discovery stm32l0 https://www.st.com/en/evaluation-tools/32l0538discovery.html stm32l412nucleo STM32 L412 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l412kb.html stm32l476disco STM32 L476 Disco stm32l4 https://www.st.com/en/evaluation-tools/32l476gdiscovery.html +stm32l496nucleo STM32 L496 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l496ZG-P.html stm32l4p5nucleo STM32 L4P5 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l4p5zg.html stm32l4r5nucleo STM32 L4R5 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html stm32n6570dk STM32 N6570-DK stm32n6 https://www.st.com/en/evaluation-tools/stm32n6570-dk.html diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index e04cc2c2f..de1603383 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -4,9 +4,9 @@ Dependencies MCU low-level peripheral drivers and external libraries for building TinyUSB examples -======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ============================================================================================================================================================================================================================================================================================================================================================== Local Path Repo Commit Required by -======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ============================================================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s hw/mcu/analog/msdk https://github.com/analogdevicesinc/msdk.git b20b398d3e5e2007594e54a74ba3d2a2e50ddd75 maxim hw/mcu/artery/at32f402_405 https://github.com/ArteryTek/AT32F402_405_Firmware_Library.git 4424515c2663e82438654e0947695295df2abdfe at32f402_405 @@ -23,7 +23,7 @@ hw/mcu/infineon/mtb-xmclib-cat3 https://github.com/Infineon/mtb-xmclib hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git b93e856211060ae825216c6a1d6aa347ec758843 mm32 hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 11f57e578c7feea13f21c79ea0efab2630ac68c7 nrf -hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc +hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc100_120 nuc121_125 nuc126 nuc505 hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git b41cf930e65c734d8ec6de04f1d57d46787c76ae lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git 675543bcc9baa8170f868ab7ba316d418dbcf41f rp2040 @@ -80,10 +80,10 @@ hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.gi hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32n6 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c -lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git b0bbb0423b278ca632cfe1474eb227961d835fd2 ra +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c +lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 ra stm32n6 lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 tools/uf2 https://github.com/microsoft/uf2.git c594542b2faa01cc33a2b97c9fbebc38549df80a all -======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ============================================================================================================================================================================================================================================================================================================================================================== diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index 561780c53..537769c43 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -95,4 +95,4 @@ Glossary Product Identifier. 16-bit number assigned by vendor to identify specific products. USB-IF - USB Implementers Forum. Organization that maintains USB specifications and assigns VIDs. \ No newline at end of file + USB Implementers Forum. Organization that maintains USB specifications and assigns VIDs. diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index e30210d01..bb9f15166 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -15,13 +15,14 @@ Toolchain Problems The ARM GCC toolchain is not installed or not in PATH. *Solution*: + .. code-block:: bash # Ubuntu/Debian - sudo apt-get update && sudo apt-get install gcc-arm-none-eabi + $ sudo apt-get update && sudo apt-get install gcc-arm-none-eabi # macOS with Homebrew - brew install --cask gcc-arm-embedded + $ brew install --cask gcc-arm-embedded # Windows: Download from ARM website and add to PATH @@ -30,14 +31,15 @@ The ARM GCC toolchain is not installed or not in PATH. Build tools are missing. *Solution*: + .. code-block:: bash # Ubuntu/Debian - sudo apt-get install build-essential cmake + $ sudo apt-get install build-essential cmake # macOS - xcode-select --install - brew install cmake + $ xcode-select --install + $ brew install cmake Dependency Issues ----------------- @@ -47,10 +49,12 @@ Dependency Issues Dependencies for your MCU family are not downloaded. *Solution*: + .. code-block:: bash - # Download dependencies for specific family - python tools/get_deps.py stm32f4 # Replace with your family + # Download dependencies for specific board or family + $ python tools/get_deps.py -b stm32h743eval # Replace with your board + $ python tools/get_deps.py stm32f4 # Replace with your family # Or from example directory cd examples/device/cdc_msc @@ -61,14 +65,12 @@ Dependencies for your MCU family are not downloaded. Invalid board name in build command. *Diagnosis*: + .. code-block:: bash # List available boards for a family ls hw/bsp/stm32f4/boards/ - # List all supported boards - python tools/build.py -l - *Solution*: Use exact board name from the listing. Runtime Issues @@ -82,6 +84,7 @@ Device Mode Problems The most common issue - host doesn't see your USB device. *Diagnosis steps*: + 1. Check USB cable (must support data, not just power) 2. Enable logging: build with ``LOG=2`` 3. Use different USB ports/hosts @@ -99,17 +102,20 @@ The most common issue - host doesn't see your USB device. Device is detected but configuration fails. *Diagnosis*: + .. code-block:: bash # Build with logging enabled make BOARD=your_board LOG=2 all *Look for*: + - Setup request handling errors - Endpoint configuration problems - String descriptor issues *Solutions*: + - Implement all required descriptors - Check endpoint sizes match descriptors - Ensure control endpoint (EP0) handling is correct @@ -119,11 +125,13 @@ Device is detected but configuration fails. Device enumerates but data doesn't transfer correctly. *Common causes*: + - Buffer overruns in class callbacks - Incorrect endpoint usage (IN vs OUT) - Flow control issues in CDC class *Solutions*: + - Check buffer sizes in callbacks - Verify endpoint directions in descriptors - Implement proper flow control @@ -136,11 +144,13 @@ Host Mode Problems Host application doesn't see connected devices. *Hardware checks*: + - Power supply adequate for host mode - USB-A connector for host (not micro-USB) - Board supports host mode on selected port *Software checks*: + - ``tuh_task()`` called regularly - Host stack enabled in ``tusb_config.h`` - Correct root hub port configuration @@ -150,12 +160,14 @@ Host application doesn't see connected devices. Devices connect but enumeration fails. *Diagnosis*: + .. code-block:: bash # Enable host logging make BOARD=your_board LOG=2 RHPORT_HOST=1 all *Common issues*: + - Power supply insufficient during enumeration - Timing issues with slow devices - USB hub compatibility problems @@ -165,6 +177,7 @@ Devices connect but enumeration fails. Device enumerates but class-specific communication fails. *Troubleshooting*: + - Check device descriptors match expected class - Verify interface/endpoint assignments - Some devices need device-specific handling @@ -185,6 +198,7 @@ High CPU Usage **Symptoms**: MCU spending too much time in USB handling *Solutions*: + - Use efficient logging (RTT/SWO instead of UART) - Reduce log level in production builds - Optimize descriptor parsing @@ -197,11 +211,13 @@ STM32 Issues ------------ **Clock configuration problems**: + - USB requires precise 48MHz clock - HSE crystal must be configured correctly - PLL settings affect USB timing **Pin configuration**: + - USB pins need specific alternate function settings - VBUS sensing configuration - ID pin for OTG applications @@ -210,6 +226,7 @@ RP2040 Issues ------------- **PIO-USB for host mode**: + - Requires specific pin assignments - CPU overclocking may be needed for reliable operation - Timing-sensitive - avoid long interrupt disable periods @@ -218,8 +235,8 @@ ESP32 Issues ------------ **USB peripheral differences**: -- ESP32-S2/S3 have different USB capabilities -- Some variants only support device mode + +- ESP32-S2/S3/P4 have different USB capabilities - DMA configuration varies between models Advanced Debugging @@ -249,6 +266,7 @@ However, especially for diagnosis of crashes, it can still be useful. arm-none-eabi-gdb build/your_app.elf *Useful breakpoints*: + - ``dcd_int_handler()`` - USB interrupt entry - ``tud_task()`` - Main device task - Class-specific callbacks @@ -280,6 +298,7 @@ When reporting issues: 5. **Host environment**: OS version, USB port type **Resources**: + - GitHub Discussions: https://github.com/hathach/tinyusb/discussions - Issue Tracker: https://github.com/hathach/tinyusb/issues - Documentation: https://docs.tinyusb.org diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index ad68957df..23dfb9d80 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -10,6 +10,40 @@ get_filename_component(TOP ${TOP} ABSOLUTE) set(UF2CONV_PY ${TOP}/tools/uf2/utils/uf2conv.py) +function(family_resolve_board BOARD_NAME BOARD_PATH_OUT) + if ("${BOARD_NAME}" STREQUAL "") + message(FATAL_ERROR "You must set BOARD (e.g. metro_m4_express, raspberry_pi_pico). Use -DBOARD=xxx on the cmake command line.") + endif() + + file(GLOB _board_paths + LIST_DIRECTORIES true + RELATIVE ${TOP}/hw/bsp + ${TOP}/hw/bsp/*/boards/* + ) + + set(_hint_names "") + foreach(_board_path ${_board_paths}) + get_filename_component(_board_name ${_board_path} NAME) + if (_board_name STREQUAL "${BOARD_NAME}") + set(${BOARD_PATH_OUT} ${_board_path} PARENT_SCOPE) + return() + endif() + string(FIND "${_board_name}" "${BOARD_NAME}" _pos) + if (_pos EQUAL 0) + list(APPEND _hint_names ${_board_name}) + endif() + endforeach() + + if (_hint_names) + list(REMOVE_DUPLICATES _hint_names) + list(SORT _hint_names) + list(JOIN _hint_names ", " _hint_str) + message(FATAL_ERROR "BOARD '${BOARD_NAME}' not found. Boards with the same prefix:\n${_hint_str}") + else() + message(FATAL_ERROR "BOARD '${BOARD_NAME}' not found under hw/bsp/*/boards") + endif() +endfunction() + #------------------------------------------------------------- # Toolchain # Can be changed via -DTOOLCHAIN=gcc|iar or -DCMAKE_C_COMPILER= or ENV{CC}= @@ -78,21 +112,8 @@ endif () # FAMILY and BOARD #------------------------------------------------------------- if (NOT DEFINED FAMILY) - if (NOT DEFINED BOARD) - message(FATAL_ERROR "You must set a BOARD variable for the build (e.g. metro_m4_express, raspberry_pi_pico). - You can do this via -DBOARD=xxx on the cmake command line") - endif () - - # Find path contains BOARD - file(GLOB BOARD_PATH LIST_DIRECTORIES true - RELATIVE ${TOP}/hw/bsp - ${TOP}/hw/bsp/*/boards/${BOARD} - ) - if (NOT BOARD_PATH) - message(FATAL_ERROR "Could not detect FAMILY from BOARD=${BOARD}") - endif () + family_resolve_board("${BOARD}" BOARD_PATH) - # replace / with ; so that we can get the first element as FAMILY string(REPLACE "/" ";" BOARD_PATH ${BOARD_PATH}) list(GET BOARD_PATH 0 FAMILY) set(FAMILY ${FAMILY} CACHE STRING "Board family") diff --git a/tools/gen_doc.py b/tools/gen_doc.py index ab07bc116..3920531d5 100755 --- a/tools/gen_doc.py +++ b/tools/gen_doc.py @@ -23,7 +23,7 @@ def gen_deps_doc(): Dependencies ************ -MCU low-level peripheral driver and external libraries for building TinyUSB examples +MCU low-level peripheral drivers and external libraries for building TinyUSB examples {tabulate(df, headers="keys", tablefmt='rst')} """ -- cgit v1.3.1 From 9d7b401c3d98d7923ce3b53d4a129e156e4c9a97 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 19 Nov 2025 22:26:10 +0700 Subject: remove copilot-instructions.md, update and use AGENTS.md instead --- .github/copilot-instructions.md | 214 ------------------------------------- .github/workflows/ci_set_matrix.py | 3 +- AGENTS.md | 130 +++++++++++----------- 3 files changed, 67 insertions(+), 280 deletions(-) delete mode 100644 .github/copilot-instructions.md (limited to '.github/workflows') diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 9f9ab7e72..000000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,214 +0,0 @@ -# TinyUSB -TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events deferred to non-ISR task functions. - -Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. - -## Working Effectively - -### Bootstrap and Build Setup -- Install ARM GCC toolchain: `sudo apt-get update && sudo apt-get install -y gcc-arm-none-eabi` -- Fetch core dependencies: `python3 tools/get_deps.py` -- takes <1 second. NEVER CANCEL. -- For specific board families: `python3 tools/get_deps.py FAMILY_NAME` (e.g., rp2040, stm32f4) -- Dependencies are cached in `lib/` and `hw/mcu/` directories - -### Build Examples -Choose ONE of these approaches: - -**Option 1: Individual Example with CMake (RECOMMENDED)** -```bash -cd examples/device/cdc_msc -mkdir -p build && cd build -cmake -DBOARD=raspberry_pi_pico -DCMAKE_BUILD_TYPE=MinSizeRel .. -cmake --build . -j4 -``` --- takes 1-2 seconds. NEVER CANCEL. Set timeout to 5+ minutes. - -**CMake with Ninja (Alternative)** -```bash -cd examples/device/cdc_msc -mkdir build && cd build -cmake -G Ninja -DBOARD=raspberry_pi_pico .. -ninja -``` - -**Option 2: Individual Example with Make** -```bash -cd examples/device/cdc_msc -make BOARD=raspberry_pi_pico all -``` --- takes 2-3 seconds. NEVER CANCEL. Set timeout to 5+ minutes. - -**Option 3: All Examples for a Board** -```bash -python3 tools/build.py -b BOARD_NAME -``` --- takes 15-20 seconds, may have some objcopy failures that are non-critical. NEVER CANCEL. Set timeout to 30+ minutes. - -### Build Options -- **Debug build**: - - CMake: `-DCMAKE_BUILD_TYPE=Debug` - - Make: `DEBUG=1` -- **With logging**: - - CMake: `-DLOG=2` - - Make: `LOG=2` -- **With RTT logger**: - - CMake: `-DLOG=2 -DLOGGER=rtt` - - Make: `LOG=2 LOGGER=rtt` -- **RootHub port selection**: - - CMake: `-DRHPORT_DEVICE=1` - - Make: `RHPORT_DEVICE=1` -- **Port speed**: - - CMake: `-DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` - - Make: `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` - -### Flashing and Deploymen -- **Flash with JLink**:1 - - CMake: `ninja cdc_msc-jlink` - - Make: `make BOARD=raspberry_pi_pico flash-jlink` -- **Flash with OpenOCD**: - - CMake: `ninja cdc_msc-openocd` - - Make: `make BOARD=raspberry_pi_pico flash-openocd` -- **Generate UF2**: - - CMake: `ninja cdc_msc-uf2` - - Make: `make BOARD=raspberry_pi_pico all uf2` -- **List all targets** (CMake/Ninja): `ninja -t targets` - -### Unit Testing -- Install Ceedling: `sudo gem install ceedling` -- Run all unit tests: `cd test/unit-test && ceedling` or `cd test/unit-test && ceedling test:all` -- takes 4 seconds. NEVER CANCEL. Set timeout to 10+ minutes. -- Run specific test: `cd test/unit-test && ceedling test:test_fifo` -- Tests use Unity framework with CMock for mocking - -### Documentation -- Install requirements: `pip install -r docs/requirements.txt` -- Build docs: `cd docs && sphinx-build -b html . _build` -- takes 2-3 seconds. NEVER CANCEL. Set timeout to 10+ minutes. - -### Code Quality and Validation -- Format code: `clang-format -i path/to/file.c` (uses `.clang-format` config) -- Check spelling: `pip install codespell && codespell` (uses `.codespellrc` config) -- Pre-commit hooks validate unit tests and code quality automatically - -### Static Analysis with PVS-Studio -- **Analyze whole project**: - ```bash - pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser - ``` -- **Analyze specific source files**: - ```bash - pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -S path/to/file.c -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser - ``` -- **Multiple specific files**: - ```bash - pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -S src/file1.c -S src/file2.c -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser - ``` -- Requires `compile_commands.json` in the build directory (generated by CMake with `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON`) -- Use `-f` option to specify path to `compile_commands.json` -- Use `-R .PVS-Studio/.pvsconfig` to specify rule configuration file -- Use `-j12` for parallel analysis with 12 threads -- `--dump-files` saves preprocessed files for debugging -- `--misra-c-version 2023` enables MISRA C:2023 checks -- `--misra-cpp-version 2008` enables MISRA C++:2008 checks -- `--use-old-parser` uses legacy parser for compatibility -- Analysis takes ~10-30 seconds depending on project size. Set timeout to 5+ minutes. -- View results: `plog-converter -a GA:1,2 -t errorfile pvs-report.log` or open in PVS-Studio GUI - -## Validation - -### ALWAYS Run These After Making Changes -1. **Pre-commit validation** (RECOMMENDED): `pre-commit run --all-files` - - Install pre-commit: `pip install pre-commit && pre-commit install` - - Runs all quality checks, unit tests, spell checking, and formatting - - Takes 10-15 seconds. NEVER CANCEL. Set timeout to 15+ minutes. -2. **Build validation**: Build at least one example that exercises your changes - ```bash - cd examples/device/cdc_msc - make BOARD=raspberry_pi_pico all - ``` - -### Manual Testing Scenarios -- **Device examples**: Cannot be fully tested without real hardware, but must build successfully -- **Unit tests**: Exercise core stack functionality - ALL tests must pass -- **Build system**: Must be able to build examples for multiple board families - -### Board Selection for Testing -- **STM32F4**: `stm32f407disco` - no external SDK required, good for testing -- **RP2040**: `raspberry_pi_pico` - requires Pico SDK, commonly used -- **Other families**: Check `hw/bsp/FAMILY/boards/` for available boards - -## Common Tasks and Time Expectations - -### Repository Structure Quick Reference -``` -├── src/ # Core TinyUSB stack -│ ├── class/ # USB device classes (CDC, HID, MSC, Audio, etc.) -│ ├── portable/ # MCU-specific drivers (organized by vendor) -│ ├── device/ # USB device stack core -│ ├── host/ # USB host stack core -│ └── common/ # Shared utilities (FIFO, etc.) -├── examples/ # Example applications -│ ├── device/ # Device examples (cdc_msc, hid_generic, etc.) -│ ├── host/ # Host examples -│ └── dual/ # Dual-role examples -├── hw/bsp/ # Board Support Packages -│ └── FAMILY/boards/ # Board-specific configurations -├── test/unit-test/ # Unit tests using Ceedling -├── tools/ # Build and utility scripts -└── docs/ # Sphinx documentation -``` - -### Build Time Reference -- **Dependency fetch**: <1 second -- **Single example build**: 1-3 seconds -- **Unit tests**: ~4 seconds -- **Documentation build**: ~2.5 seconds -- **Full board examples**: 15-20 seconds -- **Toolchain installation**: 2-5 minutes (one-time) - -### Key Files to Know -- `tools/get_deps.py`: Manages dependencies for MCU families -- `tools/build.py`: Builds multiple examples, supports make/cmake -- `src/tusb.h`: Main TinyUSB header file -- `src/tusb_config.h`: Configuration template -- `examples/device/cdc_msc/`: Most commonly used example for testing -- `test/unit-test/project.yml`: Ceedling test configuration - -### Debugging Build Issues -- **Missing compiler**: Install `gcc-arm-none-eabi` package -- **Missing dependencies**: Run `python3 tools/get_deps.py FAMILY` -- **Board not found**: Check `hw/bsp/FAMILY/boards/` for valid board names -- **objcopy errors**: Often non-critical in full builds, try individual example builds - -### Working with USB Device Classes -- **CDC (Serial)**: `src/class/cdc/` - Virtual serial port -- **HID**: `src/class/hid/` - Human Interface Device (keyboard, mouse, etc.) -- **MSC**: `src/class/msc/` - Mass Storage Class (USB drive) -- **Audio**: `src/class/audio/` - USB Audio Class -- Each class has device (`*_device.c`) and host (`*_host.c`) implementations - -### MCU Family Support -- **STM32**: Largest support (F0, F1, F2, F3, F4, F7, G0, G4, H7, L4, U5, etc.) -- **Raspberry Pi**: RP2040, RP2350 with PIO-USB host support -- **NXP**: iMXRT, Kinetis, LPC families -- **Microchip**: SAM D/E/G/L families -- Check `hw/bsp/` for complete list and `docs/reference/boards.rst` for details - -## Code Style Guidelines - -### General Coding Standards -- Use C99 standard -- Memory-safe: no dynamic allocation -- Thread-safe: defer all interrupt events to non-ISR task functions -- 2-space indentation, no tabs -- Use snake_case for variables/functions -- Use UPPER_CASE for macros and constants -- Follow existing variable naming patterns in files you're modifying -- Include proper header comments with MIT license -- Add descriptive comments for non-obvious functions - -### Best Practices -- When including headers, group in order: C stdlib, tusb common, drivers, classes -- Always check return values from functions that can fail -- Use TU_ASSERT() for error checking with return statements -- Follow the existing code patterns in the files you're modifying - -Remember: TinyUSB is designed for embedded systems - builds are fast, tests are focused, and the codebase is optimized for resource-constrained environments. diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 3789b4116..9d0e42c2e 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -41,7 +41,8 @@ family_list = { "stm32f4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f7": ["arm-gcc", "arm-clang", "arm-iar"], "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32h7 stm32h7rs": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32h7": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32h7rs": ["arm-gcc", "arm-clang", "arm-iar"], "stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32n6": ["arm-gcc"], "stm32u0 stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"], diff --git a/AGENTS.md b/AGENTS.md index 27bc60515..d00a4b114 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,52 +1,43 @@ -# Agent Handbook +# TinyUSB Agent Instructions -## Shared TinyUSB Ground Rules +TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems, designed to be memory-safe with no +dynamic allocation and thread-safe with all interrupt events deferred to non-ISR task functions. + +Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected +information that does not match the info here. + +## Shared Ground Rules - Keep TinyUSB memory-safe: avoid dynamic allocation, defer ISR work to task context, and follow C99 with two-space indentation/no tabs. - Match file organization: core stack under `src`, MCU/BSP support in `hw/{mcu,bsp}`, examples under `examples/{device,host,dual}`, docs in `docs`, tests under `test/{unit-test,fuzz,hil}`. - Use descriptive snake_case for helpers, reserve `tud_`/`tuh_` for public APIs, `TU_` for macros, and keep headers self-contained with `#if CFG_TUSB_MCU` guards where needed. - Prefer `.clang-format` for C/C++ formatting, run `pre-commit run --all-files` before submitting, and document board/HIL coverage when applicable. - Commit in imperative mood, keep changes scoped, and supply PRs with linked issues plus test/build evidence. -## Build and Test Cheatsheet -- Fetch dependencies once with `python3 tools/get_deps.py [FAMILY]`; assets land in `lib/` and `hw/mcu/`. -- CMake (preferred): `cmake -G Ninja -DBOARD= -DCMAKE_BUILD_TYPE={MinSizeRel|Debug}` inside an example `build/` dir, then `ninja` or `cmake --build .`. -- Make (alt): `make BOARD= [DEBUG=1] [LOG=2 LOGGER=rtt] all` from the example root; add `uf2`, `flash-openocd`, or `flash-jlink` targets as needed. -- Bulk builds: `python3 tools/build.py -b ` to sweep all examples; expect occasional non-critical objcopy warnings. -- Unit tests: `cd test/unit-test && ceedling test:all` (or a specific `test_`), honor Unity/CMock fixtures under `test/support`. -- Docs: `pip install -r docs/requirements.txt` then `sphinx-build -b html . _build` from `docs/`. - -## Validation Checklist -1. `pre-commit run --all-files` after edits (install with `pip install pre-commit && pre-commit install`). -2. Build at least one representative example (e.g., `examples/device/cdc_msc`) via CMake+Ninja or Make. -3. Run unit tests relevant to touched modules; add fuzz/HIL coverage when modifying parsers or protocol state machines. - -## Copilot Agent Notes (`.github/copilot-instructions.md`) -# TinyUSB -TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events deferred to non-ISR task functions. - -Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. -### Working Effectively +## Bootstrap and Build Setup -#### Bootstrap and Build Setup - Install ARM GCC toolchain: `sudo apt-get update && sudo apt-get install -y gcc-arm-none-eabi` - Fetch core dependencies: `python3 tools/get_deps.py` -- takes <1 second. NEVER CANCEL. - For specific board families: `python3 tools/get_deps.py FAMILY_NAME` (e.g., rp2040, stm32f4) - Dependencies are cached in `lib/` and `hw/mcu/` directories -#### Build Examples +## Build Examples + Choose ONE of these approaches: **Option 1: Individual Example with CMake (RECOMMENDED)** + ```bash cd examples/device/cdc_msc mkdir -p build && cd build cmake -DBOARD=raspberry_pi_pico -DCMAKE_BUILD_TYPE=MinSizeRel .. cmake --build . -j4 ``` + -- takes 1-2 seconds. NEVER CANCEL. Set timeout to 5+ minutes. **CMake with Ninja (Alternative)** + ```bash cd examples/device/cdc_msc mkdir build && cd build @@ -55,63 +46,74 @@ ninja ``` **Option 2: Individual Example with Make** + ```bash cd examples/device/cdc_msc make BOARD=raspberry_pi_pico all ``` + -- takes 2-3 seconds. NEVER CANCEL. Set timeout to 5+ minutes. **Option 3: All Examples for a Board** + ```bash python3 tools/build.py -b BOARD_NAME ``` + -- takes 15-20 seconds, may have some objcopy failures that are non-critical. NEVER CANCEL. Set timeout to 30+ minutes. -#### Build Options +## Build Options + - **Debug build**: - - CMake: `-DCMAKE_BUILD_TYPE=Debug` - - Make: `DEBUG=1` + - CMake: `-DCMAKE_BUILD_TYPE=Debug` + - Make: `DEBUG=1` - **With logging**: - - CMake: `-DLOG=2` - - Make: `LOG=2` + - CMake: `-DLOG=2` + - Make: `LOG=2` - **With RTT logger**: - - CMake: `-DLOG=2 -DLOGGER=rtt` - - Make: `LOG=2 LOGGER=rtt` + - CMake: `-DLOG=2 -DLOGGER=rtt` + - Make: `LOG=2 LOGGER=rtt` - **RootHub port selection**: - - CMake: `-DRHPORT_DEVICE=1` - - Make: `RHPORT_DEVICE=1` + - CMake: `-DRHPORT_DEVICE=1` + - Make: `RHPORT_DEVICE=1` - **Port speed**: - - CMake: `-DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` - - Make: `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` + - CMake: `-DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` + - Make: `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` + +## Flashing and Deployment -#### Flashing and Deployment - **Flash with JLink**: - - CMake: `ninja cdc_msc-jlink` - - Make: `make BOARD=raspberry_pi_pico flash-jlink` + - CMake: `ninja cdc_msc-jlink` + - Make: `make BOARD=raspberry_pi_pico flash-jlink` - **Flash with OpenOCD**: - - CMake: `ninja cdc_msc-openocd` - - Make: `make BOARD=raspberry_pi_pico flash-openocd` + - CMake: `ninja cdc_msc-openocd` + - Make: `make BOARD=raspberry_pi_pico flash-openocd` - **Generate UF2**: - - CMake: `ninja cdc_msc-uf2` - - Make: `make BOARD=raspberry_pi_pico all uf2` + - CMake: `ninja cdc_msc-uf2` + - Make: `make BOARD=raspberry_pi_pico all uf2` - **List all targets** (CMake/Ninja): `ninja -t targets` -#### Unit Testing +## Unit Testing + - Install Ceedling: `sudo gem install ceedling` -- Run all unit tests: `cd test/unit-test && ceedling` or `cd test/unit-test && ceedling test:all` -- takes 4 seconds. NEVER CANCEL. Set timeout to 10+ minutes. +- Run all unit tests: `cd test/unit-test && ceedling` or `cd test/unit-test && ceedling test:all` -- takes 4 seconds. + NEVER CANCEL. Set timeout to 10+ minutes. - Run specific test: `cd test/unit-test && ceedling test:test_fifo` - Tests use Unity framework with CMock for mocking -#### Documentation +## Documentation + - Install requirements: `pip install -r docs/requirements.txt` - Build docs: `cd docs && sphinx-build -b html . _build` -- takes 2-3 seconds. NEVER CANCEL. Set timeout to 10+ minutes. -#### Code Quality and Validation +## Code Quality and Validation + - Format code: `clang-format -i path/to/file.c` (uses `.clang-format` config) - Check spelling: `pip install codespell && codespell` (uses `.codespellrc` config) - Pre-commit hooks validate unit tests and code quality automatically -#### Static Analysis with PVS-Studio +## Static Analysis with PVS-Studio + - **Analyze whole project**: ```bash pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser @@ -135,32 +137,40 @@ python3 tools/build.py -b BOARD_NAME - Analysis takes ~10-30 seconds depending on project size. Set timeout to 5+ minutes. - View results: `plog-converter -a GA:1,2 -t errorfile pvs-report.log` or open in PVS-Studio GUI -### Validation +## Validation Checklist + +### ALWAYS Run These After Making Changes -#### ALWAYS Run These After Making Changes 1. **Pre-commit validation** (RECOMMENDED): `pre-commit run --all-files` - - Install pre-commit: `pip install pre-commit && pre-commit install` - - Runs all quality checks, unit tests, spell checking, and formatting - - Takes 10-15 seconds. NEVER CANCEL. Set timeout to 15+ minutes. + - Install pre-commit: `pip install pre-commit && pre-commit install` + - Runs all quality checks, unit tests, spell checking, and formatting + - Takes 10-15 seconds. NEVER CANCEL. Set timeout to 15+ minutes. 2. **Build validation**: Build at least one example that exercises your changes ```bash cd examples/device/cdc_msc make BOARD=raspberry_pi_pico all ``` +3. Run unit tests relevant to touched modules; add fuzz/HIL coverage when modifying parsers or protocol state machines. -#### Manual Testing Scenarios +### Manual Testing Scenarios - **Device examples**: Cannot be fully tested without real hardware, but must build successfully - **Unit tests**: Exercise core stack functionality - ALL tests must pass - **Build system**: Must be able to build examples for multiple board families -#### Board Selection for Testing +### Board Selection for Testing - **STM32F4**: `stm32f407disco` - no external SDK required, good for testing - **RP2040**: `raspberry_pi_pico` - requires Pico SDK, commonly used - **Other families**: Check `hw/bsp/FAMILY/boards/` for available boards -### Common Tasks and Time Expectations +## Release Instructions + +1. Bump the release version variable at the top of `tools/make_release.py`. +2. Execute `python tools/make_release.py` to refresh `src/tusb_option.h`, `repository.yml`, and `library.json`. +3. Generate release notes by running `git log ..HEAD`, then add a new entry to + `docs/info/changelog.rst` that follows the existing format (heading, date, highlights, categorized bullet lists). +4. Proceed with tagging/publishing once builds and tests succeed. -#### Repository Structure Quick Reference +## Repository Structure Quick Reference ``` ├── src/ # Core TinyUSB stack │ ├── class/ # USB device classes (CDC, HID, MSC, Audio, etc.) @@ -235,13 +245,3 @@ python3 tools/build.py -b BOARD_NAME - Follow the existing code patterns in the files you're modifying Remember: TinyUSB is designed for embedded systems - builds are fast, tests are focused, and the codebase is optimized for resource-constrained environments. - -## Claude Agent Notes (`CLAUDE.md`) -- Default to CMake+Ninja for builds, but align with Make workflows when users rely on legacy scripts; provide DEBUG/LOG/LOGGER knobs consistently. -- Highlight dependency helpers (`tools/get_deps.py rp2040`) and reference core locations: `src/`, `hw/`, `examples/`, `test/`. -- Run `clang-format` on all touched files to ensure consistent formatting. -- Use `TU_ASSERT` for all fallible calls to enforce runtime checks. -- Ensure header comments retain the MIT license notice. -- Add descriptive comments for non-trivial code paths to aid maintainability. -- Release flow primer: bump `tools/make_release.py` version, run the script (updates `src/tusb_option.h`, `repository.yml`, `library.json`), refresh `docs/info/changelog.rst`, then tag. -- Testing reminders: Ceedling full or targeted runs, specify board/OS context, and ensure logging of manual hardware outcomes when available. -- cgit v1.3.1 From 7ee288bc223db393d68c7bdb09bf7c05ffd2eb03 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Sat, 29 Nov 2025 01:41:30 +0700 Subject: change armgcc setup to manual download due to issue with action (#3377) * change armgcc setup to manual download due to issue with action * build windows, macos with cmake as well --- .github/actions/setup_toolchain/action.yml | 14 ++---------- .../actions/setup_toolchain/download/action.yml | 25 +++++++++++++++++++--- .github/actions/setup_toolchain/toolchain.json | 2 ++ .github/workflows/build.yml | 12 +++++------ .idea/cmake.xml | 13 ++++++++--- tools/get_deps.py | 4 ++-- 6 files changed, 44 insertions(+), 26 deletions(-) (limited to '.github/workflows') diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml index d15a29f20..f78fe4dd3 100644 --- a/.github/actions/setup_toolchain/action.yml +++ b/.github/actions/setup_toolchain/action.yml @@ -13,12 +13,6 @@ outputs: runs: using: "composite" steps: - - name: Install ARM GCC - if: inputs.toolchain == 'arm-gcc' - uses: carlosperate/arm-none-eabi-gcc-action@v1 - with: - release: '14.2.Rel1' - - name: Pull ESP-IDF docker if: inputs.toolchain == 'esp-idf' uses: ./.github/actions/setup_toolchain/espressif @@ -26,9 +20,7 @@ runs: toolchain: ${{ inputs.toolchain }} - name: Get Toolchain URL - if: >- - inputs.toolchain != 'arm-gcc' && - inputs.toolchain != 'esp-idf' + if: inputs.toolchain != 'esp-idf' id: set-toolchain-url env: TOOLCHAIN: ${{ inputs.toolchain }} @@ -39,9 +31,7 @@ runs: shell: bash - name: Download Toolchain - if: >- - inputs.toolchain != 'arm-gcc' && - inputs.toolchain != 'esp-idf' + if: inputs.toolchain != 'esp-idf' uses: ./.github/actions/setup_toolchain/download with: toolchain: ${{ inputs.toolchain }} diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml index af7a9ad4e..5a3f66cb1 100644 --- a/.github/actions/setup_toolchain/download/action.yml +++ b/.github/actions/setup_toolchain/download/action.yml @@ -26,6 +26,7 @@ runs: TOOLCHAIN_URL: ${{ inputs.toolchain_url }} run: | mkdir -p ~/cache/${TOOLCHAIN} + FILE_EXT="${TOOLCHAIN_URL##*.}" if [[ ${TOOLCHAIN} == rx-gcc ]]; then wget --progress=dot:giga ${TOOLCHAIN_URL} -O toolchain.run @@ -34,9 +35,16 @@ runs: elif [[ ${TOOLCHAIN} == arm-iar ]]; then wget --progress=dot:giga https://netstorage.iar.com/FileStore/STANDARD/001/003/926/iar-lmsc-tools_1.8_amd64.deb -O ~/cache/${TOOLCHAIN}/iar-lmsc-tools.deb wget --progress=dot:giga ${TOOLCHAIN_URL} -O ~/cache/${TOOLCHAIN}/cxarm.deb - else + elif [[ ${FILE_EXT} == zip ]]; then + curl -L "$TOOLCHAIN_URL" -o toolchain.zip + unzip -q toolchain.zip -d ~/cache/${TOOLCHAIN} + ~/cache/${TOOLCHAIN}/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin/arm-none-eabi-gcc.exe --version + elif [[ ${FILE_EXT} == gz ]]; then wget --progress=dot:giga ${TOOLCHAIN_URL} -O toolchain.tar.gz tar -C ~/cache/${TOOLCHAIN} -xaf toolchain.tar.gz + else + echo "Unsupported toolchain file extension: ${FILE_EXT}" + exit 1 fi shell: bash @@ -47,8 +55,19 @@ runs: if [[ ${TOOLCHAIN} == arm-iar ]]; then sudo dpkg -i ~/cache/${TOOLCHAIN}/iar-lmsc-tools.deb sudo apt install -y ~/cache/${TOOLCHAIN}/cxarm.deb - echo >> $GITHUB_PATH "/opt/iar/cxarm/arm/bin" + TOOLCHAIN_PATH="/opt/iar/cxarm/arm/bin" else - echo >> $GITHUB_PATH `echo ~/cache/${TOOLCHAIN}/*/bin` + # Find the single toolchain bin directory + TOOLCHAIN_BIN_DIRS=(~/cache/${TOOLCHAIN}/*/bin) + if [[ ${#TOOLCHAIN_BIN_DIRS[@]} -ne 1 ]]; then + echo "Error: Expected exactly one toolchain bin directory, found ${#TOOLCHAIN_BIN_DIRS[@]}" + exit 1 + fi + TOOLCHAIN_PATH="${TOOLCHAIN_BIN_DIRS[0]}" + fi + # Convert to native path for Windows compatibility + if [[ "$RUNNER_OS" == "Windows" ]]; then + TOOLCHAIN_PATH=$(cygpath -w "$TOOLCHAIN_PATH") fi + echo "$TOOLCHAIN_PATH" >> $GITHUB_PATH shell: bash diff --git a/.github/actions/setup_toolchain/toolchain.json b/.github/actions/setup_toolchain/toolchain.json index 8496dcad3..ee41a5cb4 100644 --- a/.github/actions/setup_toolchain/toolchain.json +++ b/.github/actions/setup_toolchain/toolchain.json @@ -2,6 +2,8 @@ "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-19.1.1/LLVM-ET-Arm-19.1.1-Linux-x86_64.tar.xz", "arm-gcc": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz", + "arm-gcc-macos-latest": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-darwin-arm64.tar.gz", + "arm-gcc-windows-latest": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-win32-x64.zip", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", "rx-gcc": "https://github.com/hathach/rx_device/releases/download/0.0.1/gcc-8.3.0.202411-GNURX-ELF.run", diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0495ba6a9..f1b134b8a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,6 @@ on: - '.github/workflows/build_util.yml' - '.github/workflows/ci_set_matrix.py' pull_request: - branches: [ master ] paths: - 'src/**' - 'examples/**' @@ -49,7 +48,7 @@ jobs: id: set-matrix-json run: | # build matrix - MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) + MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py)/ echo "matrix=$MATRIX_JSON" echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT # hil matrix @@ -127,19 +126,20 @@ jobs: one-per-family: true # --------------------------------------- - # Build Make on Windows/MacOS + # Build Make/CMake on Windows/MacOS # --------------------------------------- - make-os: + build-os: if: github.event_name == 'pull_request' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: os: [windows-latest, macos-latest] + build-system: [ 'make', 'cmake' ] with: os: ${{ matrix.os }} - build-system: 'make' - toolchain: 'arm-gcc' + build-system: ${{ matrix.build-system }} + toolchain: 'arm-gcc-${{ matrix.os }}' build-args: '["stm32h7"]' one-per-family: true diff --git a/.idea/cmake.xml b/.idea/cmake.xml index f5e5d1f0e..677aaa662 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -56,6 +56,13 @@ + + + + + + + @@ -90,9 +97,9 @@ - - - + + + diff --git a/tools/get_deps.py b/tools/get_deps.py index 35f3b3e92..d749e4c84 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -246,7 +246,7 @@ deps_optional = { 'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x ' 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 ' 'stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 ' - 'stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba' + 'stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba ' 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg ' 'tm4c '], 'lib/CMSIS_6': ['https://github.com/ARM-software/CMSIS_6.git', @@ -343,7 +343,7 @@ def main(): for f in families: for d in deps_optional: - if d not in deps and f in deps_optional[d][2]: + if d not in deps and f in deps_optional[d][2].split(): deps.append(d) if print_only: -- cgit v1.3.1 From 3d190475ad2b71d913e059dfc6f5cc5dafe6555d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Dec 2025 00:08:45 +0700 Subject: upload metrics.json, test ci --- .github/workflows/build.yml | 374 +++++++++++++++++++-------------------- .github/workflows/build_util.yml | 9 +- examples/CMakeLists.txt | 1 + tools/get_deps.py | 2 +- 4 files changed, 197 insertions(+), 189 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f1b134b8a..7d7901c3a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -83,190 +83,190 @@ jobs: # --------------------------------------- # Build Make: only build on push with one-per-family # --------------------------------------- - make: - if: github.event_name == 'push' - needs: set-matrix - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - toolchain: - - 'aarch64-gcc' - #- 'arm-clang' - - 'arm-gcc' - - 'msp430-gcc' - - 'riscv-gcc' - - 'rx-gcc' - with: - build-system: 'make' - toolchain: ${{ matrix.toolchain }} - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} - one-per-family: true - - # --------------------------------------- - # Build IAR - # Since IAR Token secret is not passed to forked PR, only build non-forked PR with make. - # cmake is built by circle-ci. Due to IAR limit capacity, only build oe per family - # --------------------------------------- - arm-iar: - if: false # disable for now since we got reach capacity limit too often - #if: github.event_name == 'push' && github.repository_owner == 'hathach' - needs: set-matrix - uses: ./.github/workflows/build_util.yml - secrets: inherit - strategy: - fail-fast: false - matrix: - build-system: - - 'make' - with: - build-system: ${{ matrix.build-system }} - toolchain: 'arm-iar' - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['arm-iar']) }} - one-per-family: true - - # --------------------------------------- - # Build Make/CMake on Windows/MacOS - # --------------------------------------- - build-os: - if: github.event_name == 'pull_request' - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - os: [windows-latest, macos-latest] - build-system: [ 'make', 'cmake' ] - with: - os: ${{ matrix.os }} - build-system: ${{ matrix.build-system }} - toolchain: 'arm-gcc-${{ matrix.os }}' - build-args: '["stm32h7"]' - one-per-family: true - - # --------------------------------------- - # Zephyr - # --------------------------------------- - zephyr: - if: github.event_name == 'push' - runs-on: ubuntu-latest - steps: - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@v1 - with: - app-path: examples - toolchains: arm-zephyr-eabi - - - name: Build - run: | - west build -b nrf52840dk -d examples/device/cdc_msc/build examples/device/cdc_msc -- -DRTOS=zephyr - west build -b nrf52840dk -d examples/device/msc_dual_lun/build examples/device/msc_dual_lun -- -DRTOS=zephyr - - # --------------------------------------- - # Hardware in the loop (HIL) - # Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR - # --------------------------------------- - hil-build: - if: | - github.repository_owner == 'hathach' && - (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') - needs: set-matrix - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - toolchain: - - 'arm-gcc' - - 'esp-idf' - with: - build-system: 'cmake' - toolchain: ${{ matrix.toolchain }} - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.hil_json)[matrix.toolchain]) }} - one-per-family: true - upload-artifacts: true - - # --------------------------------------- - # Hardware in the loop (HIL) - # self-hosted on local VM, for attached hardware checkout HIL_JSON - # --------------------------------------- - hil-tinyusb: - if: | - github.repository_owner == 'hathach' && - (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') - needs: hil-build - runs-on: [self-hosted, X64, hathach, hardware-in-the-loop] - steps: - - name: Get Skip Boards from previous run - if: github.run_attempt != '1' - run: | - if [ -f "${{ env.HIL_JSON }}.skip" ]; then - SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip") - else - SKIP_BOARDS="" - fi - echo "SKIP_BOARDS=$SKIP_BOARDS" - echo "SKIP_BOARDS=$SKIP_BOARDS" >> $GITHUB_ENV - - - name: Clean workspace - run: | - echo "Cleaning up for the first run" - rm -rf "${{ github.workspace }}" - mkdir -p "${{ github.workspace }}" - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Download Artifacts - uses: actions/download-artifact@v5 - with: - path: cmake-build - merge-multiple: true - - - name: Test on actual hardware - run: | - python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS - - # --------------------------------------- - # Hardware in the loop (HIL) - # self-hosted by HFP, build with IAR toolchain, for attached hardware checkout test/hil/hfp.json - # Since IAR Token secret is not passed to forked PR, only build non-forked PR - # --------------------------------------- - hil-hfp: - if: | - github.repository_owner == 'hathach' && - github.event.pull_request.head.repo.fork == false && - (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') - runs-on: [self-hosted, Linux, X64, hifiphile] - env: - IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} - steps: - - name: Clean workspace - run: | - echo "Cleaning up previous run" - rm -rf "${{ github.workspace }}"3 - mkdir -p "${{ github.workspace }}" - - - name: Toolchain version - run: | - iccarm --version - - - name: Checkout TinyUSB - uses: actions/checkout@v4 - - - name: Get build boards - run: | - MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/hfp.json) - BUILD_ARGS=$(echo $MATRIX_JSON | jq -r '.["arm-gcc"] | join(" ")') - echo "BUILD_ARGS=$BUILD_ARGS" - echo "BUILD_ARGS=$BUILD_ARGS" >> $GITHUB_ENV - - - name: Get Dependencies - run: python3 tools/get_deps.py $BUILD_ARGS - - - name: Build - run: python3 tools/build.py -j 4 --toolchain iar $BUILD_ARGS - - - name: Test on actual hardware (hardware in the loop) - run: python3 test/hil/hil_test.py hfp.json +# make: +# if: github.event_name == 'push' +# needs: set-matrix +# uses: ./.github/workflows/build_util.yml +# strategy: +# fail-fast: false +# matrix: +# toolchain: +# - 'aarch64-gcc' +# #- 'arm-clang' +# - 'arm-gcc' +# - 'msp430-gcc' +# - 'riscv-gcc' +# - 'rx-gcc' +# with: +# build-system: 'make' +# toolchain: ${{ matrix.toolchain }} +# build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} +# one-per-family: true +# +# # --------------------------------------- +# # Build IAR +# # Since IAR Token secret is not passed to forked PR, only build non-forked PR with make. +# # cmake is built by circle-ci. Due to IAR limit capacity, only build oe per family +# # --------------------------------------- +# arm-iar: +# if: false # disable for now since we got reach capacity limit too often +# #if: github.event_name == 'push' && github.repository_owner == 'hathach' +# needs: set-matrix +# uses: ./.github/workflows/build_util.yml +# secrets: inherit +# strategy: +# fail-fast: false +# matrix: +# build-system: +# - 'make' +# with: +# build-system: ${{ matrix.build-system }} +# toolchain: 'arm-iar' +# build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['arm-iar']) }} +# one-per-family: true +# +# # --------------------------------------- +# # Build Make/CMake on Windows/MacOS +# # --------------------------------------- +# build-os: +# if: github.event_name == 'pull_request' +# uses: ./.github/workflows/build_util.yml +# strategy: +# fail-fast: false +# matrix: +# os: [windows-latest, macos-latest] +# build-system: [ 'make', 'cmake' ] +# with: +# os: ${{ matrix.os }} +# build-system: ${{ matrix.build-system }} +# toolchain: 'arm-gcc-${{ matrix.os }}' +# build-args: '["stm32h7"]' +# one-per-family: true +# +# # --------------------------------------- +# # Zephyr +# # --------------------------------------- +# zephyr: +# if: github.event_name == 'push' +# runs-on: ubuntu-latest +# steps: +# - name: Checkout TinyUSB +# uses: actions/checkout@v4 +# +# - name: Setup Zephyr project +# uses: zephyrproject-rtos/action-zephyr-setup@v1 +# with: +# app-path: examples +# toolchains: arm-zephyr-eabi +# +# - name: Build +# run: | +# west build -b nrf52840dk -d examples/device/cdc_msc/build examples/device/cdc_msc -- -DRTOS=zephyr +# west build -b nrf52840dk -d examples/device/msc_dual_lun/build examples/device/msc_dual_lun -- -DRTOS=zephyr +# +# # --------------------------------------- +# # Hardware in the loop (HIL) +# # Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR +# # --------------------------------------- +# hil-build: +# if: | +# github.repository_owner == 'hathach' && +# (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') +# needs: set-matrix +# uses: ./.github/workflows/build_util.yml +# strategy: +# fail-fast: false +# matrix: +# toolchain: +# - 'arm-gcc' +# - 'esp-idf' +# with: +# build-system: 'cmake' +# toolchain: ${{ matrix.toolchain }} +# build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.hil_json)[matrix.toolchain]) }} +# one-per-family: true +# upload-artifacts: true +# +# # --------------------------------------- +# # Hardware in the loop (HIL) +# # self-hosted on local VM, for attached hardware checkout HIL_JSON +# # --------------------------------------- +# hil-tinyusb: +# if: | +# github.repository_owner == 'hathach' && +# (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') +# needs: hil-build +# runs-on: [self-hosted, X64, hathach, hardware-in-the-loop] +# steps: +# - name: Get Skip Boards from previous run +# if: github.run_attempt != '1' +# run: | +# if [ -f "${{ env.HIL_JSON }}.skip" ]; then +# SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip") +# else +# SKIP_BOARDS="" +# fi +# echo "SKIP_BOARDS=$SKIP_BOARDS" +# echo "SKIP_BOARDS=$SKIP_BOARDS" >> $GITHUB_ENV +# +# - name: Clean workspace +# run: | +# echo "Cleaning up for the first run" +# rm -rf "${{ github.workspace }}" +# mkdir -p "${{ github.workspace }}" +# +# - name: Checkout TinyUSB +# uses: actions/checkout@v4 +# +# - name: Download Artifacts +# uses: actions/download-artifact@v5 +# with: +# path: cmake-build +# merge-multiple: true +# +# - name: Test on actual hardware +# run: | +# python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS +# +# # --------------------------------------- +# # Hardware in the loop (HIL) +# # self-hosted by HFP, build with IAR toolchain, for attached hardware checkout test/hil/hfp.json +# # Since IAR Token secret is not passed to forked PR, only build non-forked PR +# # --------------------------------------- +# hil-hfp: +# if: | +# github.repository_owner == 'hathach' && +# github.event.pull_request.head.repo.fork == false && +# (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') +# runs-on: [self-hosted, Linux, X64, hifiphile] +# env: +# IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} +# steps: +# - name: Clean workspace +# run: | +# echo "Cleaning up previous run" +# rm -rf "${{ github.workspace }}"3 +# mkdir -p "${{ github.workspace }}" +# +# - name: Toolchain version +# run: | +# iccarm --version +# +# - name: Checkout TinyUSB +# uses: actions/checkout@v4 +# +# - name: Get build boards +# run: | +# MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/hfp.json) +# BUILD_ARGS=$(echo $MATRIX_JSON | jq -r '.["arm-gcc"] | join(" ")') +# echo "BUILD_ARGS=$BUILD_ARGS" +# echo "BUILD_ARGS=$BUILD_ARGS" >> $GITHUB_ENV +# +# - name: Get Dependencies +# run: python3 tools/get_deps.py $BUILD_ARGS +# +# - name: Build +# run: python3 tools/build.py -j 4 --toolchain iar $BUILD_ARGS +# +# - name: Test on actual hardware (hardware in the loop) +# run: python3 test/hil/hil_test.py hfp.json diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 55901b838..848694597 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -69,11 +69,18 @@ jobs: fi shell: bash + - name: Upload Artifacts for Metrics + if: inputs.build-system == 'cmake' + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.arg }}-metrics + path: cmake-build/cmake-build-*/metrics.json + - name: Upload Artifacts for Hardware Testing if: ${{ inputs.upload-artifacts }} uses: actions/upload-artifact@v4 with: - name: ${{ matrix.arg }} + name: ${{ matrix.arg }}-binaries path: | cmake-build/cmake-build-*/*/*/*.elf cmake-build/cmake-build-*/*/*/*.bin diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d9f97d598..694681467 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -19,6 +19,7 @@ foreach (example ${EXAMPLES_LIST}) endforeach () # Post-build: run metrics.py on all map.json files +find_package(Python3 REQUIRED COMPONENTS Interpreter) add_custom_target(tinyusb_examples_metrics COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/metrics.py -f tinyusb/src -j -o ${CMAKE_BINARY_DIR}/metrics diff --git a/tools/get_deps.py b/tools/get_deps.py index 029c33607..fe2f51e01 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -15,7 +15,7 @@ deps_mandatory = { '159e31b689577dbf69cf0683bbaffbd71fa5ee10', 'all'], 'tools/linkermap': ['https://github.com/hathach/linkermap.git', - '75d9d2c9e0f83297ddbc0da899f6cc0ab21076f0', + '87f94869f9ff828812f4551138f82c3bfcaf2620', 'all'], 'tools/uf2': ['https://github.com/microsoft/uf2.git', 'c594542b2faa01cc33a2b97c9fbebc38549df80a', -- cgit v1.3.1 From ee3d3e3551f95757b85de1c2c9777a1daed8f78d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Dec 2025 09:57:49 +0700 Subject: upload metrics.json and aggregate code metrics, fine tune ci matrix run --- .github/workflows/build.yml | 26 +++++++++++++++++++++++--- .github/workflows/build_util.yml | 12 ++++++++---- .github/workflows/ci_set_matrix.py | 18 +++++------------- tools/build.py | 13 +++++++++---- tools/get_deps.py | 2 +- 5 files changed, 46 insertions(+), 25 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7d7901c3a..5e996d9d9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -57,11 +57,10 @@ jobs: echo "hil_matrix=$HIL_MATRIX_JSON" >> $GITHUB_OUTPUT # --------------------------------------- - # Build CMake: only build on push with one-per-family. + # Build CMake: only one-per-family. # Full built is done by CircleCI in PR # --------------------------------------- cmake: - if: github.event_name == 'push' needs: set-matrix uses: ./.github/workflows/build_util.yml strategy: @@ -71,7 +70,7 @@ jobs: - 'aarch64-gcc' #- 'arm-clang' - 'arm-gcc' - - 'esp-idf' + # - 'esp-idf' - 'msp430-gcc' - 'riscv-gcc' with: @@ -79,6 +78,27 @@ jobs: toolchain: ${{ matrix.toolchain }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} one-per-family: true + upload-metrics: true + + code-metrics: + needs: cmake + runs-on: ubuntu-latest + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Download Artifacts + uses: actions/download-artifact@v5 + with: + pattern: metrics-* + path: cmake-build + merge-multiple: true + + - name: Aggregate Code Metrics + run: | + tree cmake-build + python tools/get_deps.py + python tools/metrics.py -f tinyusb/src cmake-build/*/metrics.json # --------------------------------------- # Build Make: only build on push with one-per-family diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 848694597..2de0ed229 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -20,6 +20,10 @@ on: required: false default: false type: boolean + upload-metrics: + required: false + default: false + type: boolean os: required: false type: string @@ -70,17 +74,17 @@ jobs: shell: bash - name: Upload Artifacts for Metrics - if: inputs.build-system == 'cmake' + if: ${{ inputs.upload-metrics }} uses: actions/upload-artifact@v4 with: - name: ${{ matrix.arg }}-metrics + name: metrics-${{ matrix.arg }} path: cmake-build/cmake-build-*/metrics.json - name: Upload Artifacts for Hardware Testing if: ${{ inputs.upload-artifacts }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: - name: ${{ matrix.arg }}-binaries + name: binaries-${{ matrix.arg }} path: | cmake-build/cmake-build-*/*/*/*.elf cmake-build/cmake-build-*/*/*/*.bin diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 9d0e42c2e..5032c83ae 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -15,28 +15,22 @@ toolchain_list = [ # family: [supported toolchain] family_list = { - "at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437": ["arm-gcc"], - "broadcom_32bit": ["arm-gcc"], + "at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437 broadcom_32bit da1469x": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], "ch32v10x ch32v20x ch32v30x fomu gd32vf103": ["riscv-gcc"], - "da1469x": ["arm-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], "lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], - "maxim": ["arm-gcc"], - "mcx": ["arm-gcc"], - "mm32": ["arm-gcc"], + "maxim mcx mm32 msp432e4 tm4c": ["arm-gcc"], "msp430": ["msp430-gcc"], - "msp432e4 tm4c": ["arm-gcc"], "nrf": ["arm-gcc", "arm-clang"], - "nuc100_120 nuc121_125 nuc126 nuc505": ["arm-gcc"], + "nuc100_120 nuc121_125 nuc126 nuc505 xmc4000": ["arm-gcc"], "ra": ["arm-gcc"], "rp2040": ["arm-gcc"], "rx": ["rx-gcc"], - "samd11 samd2x_l2x": ["arm-gcc", "arm-clang"], - "samd5x_e5x samg": ["arm-gcc", "arm-clang"], + "samd11 samd2x_l2x samd5x_e5x samg": ["arm-gcc", "arm-clang"], "stm32c0 stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f7": ["arm-gcc", "arm-clang", "arm-iar"], @@ -45,9 +39,7 @@ family_list = { "stm32h7rs": ["arm-gcc", "arm-clang", "arm-iar"], "stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32n6": ["arm-gcc"], - "stm32u0 stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32wba": ["arm-gcc", "arm-clang"], - "xmc4000": ["arm-gcc"], + "stm32u0 stm32u5 stm32wb stm32wba": ["arm-gcc", "arm-clang", "arm-iar"], "-bespressif_s2_devkitc": ["esp-idf"], # S3, P4 will be built by hil test # "-bespressif_s3_devkitm": ["esp-idf"], diff --git a/tools/build.py b/tools/build.py index 5392a9aa4..b87af6c6a 100755 --- a/tools/build.py +++ b/tools/build.py @@ -6,8 +6,6 @@ import sys import time import subprocess import shlex -import glob -import metrics from pathlib import Path from multiprocessing import Pool @@ -26,6 +24,7 @@ build_separator = '-' * 95 build_status = [STATUS_OK, STATUS_FAILED, STATUS_SKIPPED] verbose = False +clean_build = False parallel_jobs = os.cpu_count() # ----------------------------- @@ -117,11 +116,13 @@ def cmake_board(board, build_args, build_flags_on): f'-DBOARD={board}', '-DCMAKE_BUILD_TYPE=MinSizeRel', '-DLINKERMAP_OPTION=-q -f tinyusb/src', *build_args, *build_flags]) if rcmd.returncode == 0: + if clean_build: + run_cmd(["cmake", "--build", build_dir, '--target', 'clean']) cmd = ["cmake", "--build", build_dir, '--parallel', str(parallel_jobs)] rcmd = run_cmd(cmd) if rcmd.returncode == 0: ret[0] += 1 - rcmd = run_cmd(["cmake", "--build", build_dir, '--target', 'tinyusb_examples_metrics']) + run_cmd(["cmake", "--build", build_dir, '--target', 'tinyusb_examples_metrics']) # print(rcmd.stdout.decode("utf-8")) else: ret[1] += 1 @@ -148,7 +149,8 @@ def make_one_example(example, board, make_option): if make_option: make_args += shlex.split(make_option) make_args.append("all") - # run_cmd(make_args + ["clean"]) + if clean_build: + run_cmd(make_args + ["clean"]) build_result = run_cmd(make_args) r = 0 if build_result.returncode == 0 else 1 print_build_result(board, example, r, time.monotonic() - start_time) @@ -235,11 +237,13 @@ def get_family_boards(family, one_per_family, boards): # ----------------------------- def main(): global verbose + global clean_build global parallel_jobs parser = argparse.ArgumentParser() parser.add_argument('families', nargs='*', default=[], help='Families to build') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build') + parser.add_argument('-c', '--clean', action='store_true', default=False, help='Clean before build') parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') parser.add_argument('-D', '--define-symbol', action='append', default=[], help='Define to pass to build system') @@ -257,6 +261,7 @@ def main(): build_flags_on = args.build_flags_on one_per_family = args.one_per_family verbose = args.verbose + clean_build = args.clean parallel_jobs = args.jobs build_defines.append(f'TOOLCHAIN={toolchain}') diff --git a/tools/get_deps.py b/tools/get_deps.py index fe2f51e01..9634451e2 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -15,7 +15,7 @@ deps_mandatory = { '159e31b689577dbf69cf0683bbaffbd71fa5ee10', 'all'], 'tools/linkermap': ['https://github.com/hathach/linkermap.git', - '87f94869f9ff828812f4551138f82c3bfcaf2620', + '46c3c2947db366fb66af6723709febf80d860bc1', 'all'], 'tools/uf2': ['https://github.com/microsoft/uf2.git', 'c594542b2faa01cc33a2b97c9fbebc38549df80a', -- cgit v1.3.1 From f51ca33f25841147e93c72458c927261806cdc0e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Dec 2025 11:09:41 +0700 Subject: upload metrics.json and aggregate code metrics, post metrics comment fine tune ci matrix run --- .github/workflows/build.yml | 416 ++++++++++++++++++++----------------- .github/workflows/build_util.yml | 2 +- .github/workflows/ci_set_matrix.py | 6 +- examples/CMakeLists.txt | 4 +- hw/bsp/family_support.cmake | 6 +- tools/build.py | 2 +- tools/get_deps.py | 2 +- tools/metrics.py | 254 ++++++++++++++++++++-- 8 files changed, 472 insertions(+), 220 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e996d9d9..b0b636c65 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -83,6 +83,8 @@ jobs: code-metrics: needs: cmake runs-on: ubuntu-latest + permissions: + pull-requests: write steps: - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -96,197 +98,233 @@ jobs: - name: Aggregate Code Metrics run: | - tree cmake-build python tools/get_deps.py - python tools/metrics.py -f tinyusb/src cmake-build/*/metrics.json + pip install tools/linkermap/ + python tools/metrics.py combine -j -m -f tinyusb/src cmake-build/*/metrics.json + + - name: Upload Metrics Artifact + if: github.event_name == 'push' + uses: actions/upload-artifact@v5 + with: + name: metrics-tinyusb + path: metrics.json + + - name: Download Base Branch Metrics + if: github.event_name == 'pull_request' + uses: dawidd6/action-download-artifact@v11 + with: + workflow: build.yml + branch: ${{ github.base_ref }} + name: metrics-tinyusb + path: base-metrics + continue-on-error: true + + - name: Compare with Base Branch + if: github.event_name == 'pull_request' + run: | + if [ -f base-metrics/metrics.json ]; then + python tools/metrics.py compare -f tinyusb/src base-metrics/metrics.json metrics.json + cat metrics_compare.md + else + echo "No base metrics found, skipping comparison" + cp metrics.md metrics_compare.md + fi + + - name: Post Code Metrics as PR Comment + if: github.event_name == 'pull_request' + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: code-metrics + path: metrics_compare.md + # --------------------------------------- # Build Make: only build on push with one-per-family # --------------------------------------- -# make: -# if: github.event_name == 'push' -# needs: set-matrix -# uses: ./.github/workflows/build_util.yml -# strategy: -# fail-fast: false -# matrix: -# toolchain: -# - 'aarch64-gcc' -# #- 'arm-clang' -# - 'arm-gcc' -# - 'msp430-gcc' -# - 'riscv-gcc' -# - 'rx-gcc' -# with: -# build-system: 'make' -# toolchain: ${{ matrix.toolchain }} -# build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} -# one-per-family: true -# -# # --------------------------------------- -# # Build IAR -# # Since IAR Token secret is not passed to forked PR, only build non-forked PR with make. -# # cmake is built by circle-ci. Due to IAR limit capacity, only build oe per family -# # --------------------------------------- -# arm-iar: -# if: false # disable for now since we got reach capacity limit too often -# #if: github.event_name == 'push' && github.repository_owner == 'hathach' -# needs: set-matrix -# uses: ./.github/workflows/build_util.yml -# secrets: inherit -# strategy: -# fail-fast: false -# matrix: -# build-system: -# - 'make' -# with: -# build-system: ${{ matrix.build-system }} -# toolchain: 'arm-iar' -# build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['arm-iar']) }} -# one-per-family: true -# -# # --------------------------------------- -# # Build Make/CMake on Windows/MacOS -# # --------------------------------------- -# build-os: -# if: github.event_name == 'pull_request' -# uses: ./.github/workflows/build_util.yml -# strategy: -# fail-fast: false -# matrix: -# os: [windows-latest, macos-latest] -# build-system: [ 'make', 'cmake' ] -# with: -# os: ${{ matrix.os }} -# build-system: ${{ matrix.build-system }} -# toolchain: 'arm-gcc-${{ matrix.os }}' -# build-args: '["stm32h7"]' -# one-per-family: true -# -# # --------------------------------------- -# # Zephyr -# # --------------------------------------- -# zephyr: -# if: github.event_name == 'push' -# runs-on: ubuntu-latest -# steps: -# - name: Checkout TinyUSB -# uses: actions/checkout@v4 -# -# - name: Setup Zephyr project -# uses: zephyrproject-rtos/action-zephyr-setup@v1 -# with: -# app-path: examples -# toolchains: arm-zephyr-eabi -# -# - name: Build -# run: | -# west build -b nrf52840dk -d examples/device/cdc_msc/build examples/device/cdc_msc -- -DRTOS=zephyr -# west build -b nrf52840dk -d examples/device/msc_dual_lun/build examples/device/msc_dual_lun -- -DRTOS=zephyr -# -# # --------------------------------------- -# # Hardware in the loop (HIL) -# # Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR -# # --------------------------------------- -# hil-build: -# if: | -# github.repository_owner == 'hathach' && -# (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') -# needs: set-matrix -# uses: ./.github/workflows/build_util.yml -# strategy: -# fail-fast: false -# matrix: -# toolchain: -# - 'arm-gcc' -# - 'esp-idf' -# with: -# build-system: 'cmake' -# toolchain: ${{ matrix.toolchain }} -# build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.hil_json)[matrix.toolchain]) }} -# one-per-family: true -# upload-artifacts: true -# -# # --------------------------------------- -# # Hardware in the loop (HIL) -# # self-hosted on local VM, for attached hardware checkout HIL_JSON -# # --------------------------------------- -# hil-tinyusb: -# if: | -# github.repository_owner == 'hathach' && -# (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') -# needs: hil-build -# runs-on: [self-hosted, X64, hathach, hardware-in-the-loop] -# steps: -# - name: Get Skip Boards from previous run -# if: github.run_attempt != '1' -# run: | -# if [ -f "${{ env.HIL_JSON }}.skip" ]; then -# SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip") -# else -# SKIP_BOARDS="" -# fi -# echo "SKIP_BOARDS=$SKIP_BOARDS" -# echo "SKIP_BOARDS=$SKIP_BOARDS" >> $GITHUB_ENV -# -# - name: Clean workspace -# run: | -# echo "Cleaning up for the first run" -# rm -rf "${{ github.workspace }}" -# mkdir -p "${{ github.workspace }}" -# -# - name: Checkout TinyUSB -# uses: actions/checkout@v4 -# -# - name: Download Artifacts -# uses: actions/download-artifact@v5 -# with: -# path: cmake-build -# merge-multiple: true -# -# - name: Test on actual hardware -# run: | -# python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS -# -# # --------------------------------------- -# # Hardware in the loop (HIL) -# # self-hosted by HFP, build with IAR toolchain, for attached hardware checkout test/hil/hfp.json -# # Since IAR Token secret is not passed to forked PR, only build non-forked PR -# # --------------------------------------- -# hil-hfp: -# if: | -# github.repository_owner == 'hathach' && -# github.event.pull_request.head.repo.fork == false && -# (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') -# runs-on: [self-hosted, Linux, X64, hifiphile] -# env: -# IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} -# steps: -# - name: Clean workspace -# run: | -# echo "Cleaning up previous run" -# rm -rf "${{ github.workspace }}"3 -# mkdir -p "${{ github.workspace }}" -# -# - name: Toolchain version -# run: | -# iccarm --version -# -# - name: Checkout TinyUSB -# uses: actions/checkout@v4 -# -# - name: Get build boards -# run: | -# MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/hfp.json) -# BUILD_ARGS=$(echo $MATRIX_JSON | jq -r '.["arm-gcc"] | join(" ")') -# echo "BUILD_ARGS=$BUILD_ARGS" -# echo "BUILD_ARGS=$BUILD_ARGS" >> $GITHUB_ENV -# -# - name: Get Dependencies -# run: python3 tools/get_deps.py $BUILD_ARGS -# -# - name: Build -# run: python3 tools/build.py -j 4 --toolchain iar $BUILD_ARGS -# -# - name: Test on actual hardware (hardware in the loop) -# run: python3 test/hil/hil_test.py hfp.json + make: + if: github.event_name == 'push' + needs: set-matrix + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + toolchain: + - 'aarch64-gcc' + #- 'arm-clang' + - 'arm-gcc' + - 'msp430-gcc' + - 'riscv-gcc' + - 'rx-gcc' + with: + build-system: 'make' + toolchain: ${{ matrix.toolchain }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} + one-per-family: true + + # --------------------------------------- + # Build IAR + # Since IAR Token secret is not passed to forked PR, only build non-forked PR with make. + # cmake is built by circle-ci. Due to IAR limit capacity, only build oe per family + # --------------------------------------- + arm-iar: + if: false # disable for now since we got reach capacity limit too often + #if: github.event_name == 'push' && github.repository_owner == 'hathach' + needs: set-matrix + uses: ./.github/workflows/build_util.yml + secrets: inherit + strategy: + fail-fast: false + matrix: + build-system: + - 'make' + with: + build-system: ${{ matrix.build-system }} + toolchain: 'arm-iar' + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['arm-iar']) }} + one-per-family: true + + # --------------------------------------- + # Build Make/CMake on Windows/MacOS + # --------------------------------------- + build-os: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + os: [ windows-latest, macos-latest ] + build-system: [ 'make', 'cmake' ] + with: + os: ${{ matrix.os }} + build-system: ${{ matrix.build-system }} + toolchain: 'arm-gcc-${{ matrix.os }}' + build-args: '["stm32h7"]' + one-per-family: true + + # --------------------------------------- + # Zephyr + # --------------------------------------- + zephyr: + if: github.event_name == 'push' + runs-on: ubuntu-latest + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Setup Zephyr project + uses: zephyrproject-rtos/action-zephyr-setup@v1 + with: + app-path: examples + toolchains: arm-zephyr-eabi + + - name: Build + run: | + west build -b nrf52840dk -d examples/device/cdc_msc/build examples/device/cdc_msc -- -DRTOS=zephyr + west build -b nrf52840dk -d examples/device/msc_dual_lun/build examples/device/msc_dual_lun -- -DRTOS=zephyr + + # --------------------------------------- + # Hardware in the loop (HIL) + # Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR + # --------------------------------------- + hil-build: + if: | + github.repository_owner == 'hathach' && + (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') + needs: set-matrix + uses: ./.github/workflows/build_util.yml + strategy: + fail-fast: false + matrix: + toolchain: + - 'arm-gcc' + - 'esp-idf' + with: + build-system: 'cmake' + toolchain: ${{ matrix.toolchain }} + build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.hil_json)[matrix.toolchain]) }} + one-per-family: true + upload-artifacts: true + + # --------------------------------------- + # Hardware in the loop (HIL) + # self-hosted on local VM, for attached hardware checkout HIL_JSON + # --------------------------------------- + hil-tinyusb: + if: | + github.repository_owner == 'hathach' && + (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') + needs: hil-build + runs-on: [ self-hosted, X64, hathach, hardware-in-the-loop ] + steps: + - name: Get Skip Boards from previous run + if: github.run_attempt != '1' + run: | + if [ -f "${{ env.HIL_JSON }}.skip" ]; then + SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip") + else + SKIP_BOARDS="" + fi + echo "SKIP_BOARDS=$SKIP_BOARDS" + echo "SKIP_BOARDS=$SKIP_BOARDS" >> $GITHUB_ENV + + - name: Clean workspace + run: | + echo "Cleaning up for the first run" + rm -rf "${{ github.workspace }}" + mkdir -p "${{ github.workspace }}" + + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Download Artifacts + uses: actions/download-artifact@v5 + with: + path: cmake-build + merge-multiple: true + + - name: Test on actual hardware + run: | + python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS + + # --------------------------------------- + # Hardware in the loop (HIL) + # self-hosted by HFP, build with IAR toolchain, for attached hardware checkout test/hil/hfp.json + # Since IAR Token secret is not passed to forked PR, only build non-forked PR + # --------------------------------------- + hil-hfp: + if: | + github.repository_owner == 'hathach' && + github.event.pull_request.head.repo.fork == false && + (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') + runs-on: [ self-hosted, Linux, X64, hifiphile ] + env: + IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} + steps: + - name: Clean workspace + run: | + echo "Cleaning up previous run" + rm -rf "${{ github.workspace }}"3 + mkdir -p "${{ github.workspace }}" + + - name: Toolchain version + run: | + iccarm --version + + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Get build boards + run: | + MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/hfp.json) + BUILD_ARGS=$(echo $MATRIX_JSON | jq -r '.["arm-gcc"] | join(" ")') + echo "BUILD_ARGS=$BUILD_ARGS" + echo "BUILD_ARGS=$BUILD_ARGS" >> $GITHUB_ENV + + - name: Get Dependencies + run: python3 tools/get_deps.py $BUILD_ARGS + + - name: Build + run: python3 tools/build.py -j 4 --toolchain iar $BUILD_ARGS + + - name: Test on actual hardware (hardware in the loop) + run: python3 test/hil/hil_test.py hfp.json diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 2de0ed229..36043a1d5 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -75,7 +75,7 @@ jobs: - name: Upload Artifacts for Metrics if: ${{ inputs.upload-metrics }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: metrics-${{ matrix.arg }} path: cmake-build/cmake-build-*/metrics.json diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 5032c83ae..933a8375f 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -20,8 +20,7 @@ family_list = { "ch32v10x ch32v20x ch32v30x fomu gd32vf103": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], - "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], - "lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], + "lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], "maxim mcx mm32 msp432e4 tm4c": ["arm-gcc"], "msp430": ["msp430-gcc"], @@ -36,8 +35,7 @@ family_list = { "stm32f7": ["arm-gcc", "arm-clang", "arm-iar"], "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"], "stm32h7": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32h7rs": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32h7rs stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32n6": ["arm-gcc"], "stm32u0 stm32u5 stm32wb stm32wba": ["arm-gcc", "arm-clang", "arm-iar"], "-bespressif_s2_devkitc": ["esp-idf"], diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 694681467..b34131c2b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -20,9 +20,9 @@ endforeach () # Post-build: run metrics.py on all map.json files find_package(Python3 REQUIRED COMPONENTS Interpreter) -add_custom_target(tinyusb_examples_metrics +add_custom_target(tinyusb_metrics COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/metrics.py - -f tinyusb/src -j -o ${CMAKE_BINARY_DIR}/metrics + combine -f tinyusb/src -j -o ${CMAKE_BINARY_DIR}/metrics ${MAPJSON_PATTERNS} COMMENT "Generating average code size metrics" VERBATIM diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 3ede95e3f..15d9f1eae 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -351,8 +351,10 @@ function(family_configure_common TARGET RTOS) endif () endif () - # Generate linkermap target and post build. LINKERMAP_OPTION can be set with -D to change default options - family_add_linkermap(${TARGET}) + if (NOT RTOS STREQUAL zephyr) + # Generate linkermap target and post build. LINKERMAP_OPTION can be set with -D to change default options + family_add_linkermap(${TARGET}) + endif () # run size after build # find_program(SIZE_EXE ${CMAKE_SIZE}) diff --git a/tools/build.py b/tools/build.py index b87af6c6a..e4909f45f 100755 --- a/tools/build.py +++ b/tools/build.py @@ -122,7 +122,7 @@ def cmake_board(board, build_args, build_flags_on): rcmd = run_cmd(cmd) if rcmd.returncode == 0: ret[0] += 1 - run_cmd(["cmake", "--build", build_dir, '--target', 'tinyusb_examples_metrics']) + run_cmd(["cmake", "--build", build_dir, '--target', 'tinyusb_metrics']) # print(rcmd.stdout.decode("utf-8")) else: ret[1] += 1 diff --git a/tools/get_deps.py b/tools/get_deps.py index 9634451e2..99e406ce7 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -15,7 +15,7 @@ deps_mandatory = { '159e31b689577dbf69cf0683bbaffbd71fa5ee10', 'all'], 'tools/linkermap': ['https://github.com/hathach/linkermap.git', - '46c3c2947db366fb66af6723709febf80d860bc1', + '8a8206c39d0dfd7abfa615a676b3291165fcd65c', 'all'], 'tools/uf2': ['https://github.com/microsoft/uf2.git', 'c594542b2faa01cc33a2b97c9fbebc38549df80a', diff --git a/tools/metrics.py b/tools/metrics.py index c6cd49d57..7e54531f5 100644 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -3,6 +3,7 @@ import argparse import glob +import json import sys import os @@ -39,8 +40,6 @@ def combine_maps(map_files, filters=None): Returns: all_json_data: Dictionary with mapfiles list and data from each map file """ - import json - filters = filters or [] all_json_data = {"mapfiles": [], "data": []} @@ -128,24 +127,185 @@ def compute_avg(all_json_data): return json_average -def main(argv=None): - parser = argparse.ArgumentParser(description='Calculate average size from linker map files') - parser.add_argument('files', nargs='+', help='Path to map file(s) or glob pattern(s)') - parser.add_argument('-f', '--filter', dest='filters', action='append', default=[], - help='Only include object files whose path contains this substring (can be repeated)') - parser.add_argument('-o', '--out', dest='out', default='metrics', - help='Output path basename for JSON and Markdown files (default: metrics)') - parser.add_argument('-j', '--json', dest='json_out', action='store_true', - help='Write JSON output file') - parser.add_argument('-m', '--markdown', dest='markdown_out', action='store_true', - help='Write Markdown output file') - parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', - help='Suppress summary output') - args = parser.parse_args(argv) +def compare_maps(base_file, new_file, filters=None): + """Compare two map/json files and generate difference report. + + Args: + base_file: Path to base map/json file + new_file: Path to new map/json file + filters: List of path substrings to filter object files + + Returns: + Dictionary with comparison data + """ + filters = filters or [] + + # Load both files + base_data = combine_maps([base_file], filters) + new_data = combine_maps([new_file], filters) + + if not base_data["data"] or not new_data["data"]: + return None + + base_avg = compute_avg(base_data) + new_avg = compute_avg(new_data) + + if not base_avg or not new_avg: + return None + + # Collect all sections from both + all_sections = list(base_avg["sections"]) + for s in new_avg["sections"]: + if s not in all_sections: + all_sections.append(s) + + # Build file lookup + base_files = {f["file"]: f for f in base_avg["files"]} + new_files = {f["file"]: f for f in new_avg["files"]} + + # Get all file names + all_file_names = set(base_files.keys()) | set(new_files.keys()) + + # Build comparison data + comparison = [] + for fname in sorted(all_file_names): + base_f = base_files.get(fname) + new_f = new_files.get(fname) + + row = {"file": fname, "sections": {}, "total": {}} + + for section in all_sections: + base_val = base_f["sections"].get(section, 0) if base_f else 0 + new_val = new_f["sections"].get(section, 0) if new_f else 0 + row["sections"][section] = {"base": base_val, "new": new_val, "diff": new_val - base_val} + + base_total = base_f["total"] if base_f else 0 + new_total = new_f["total"] if new_f else 0 + row["total"] = {"base": base_total, "new": new_total, "diff": new_total - base_total} + + comparison.append(row) + + return { + "base_file": base_file, + "new_file": new_file, + "sections": all_sections, + "files": comparison + } - # Expand glob patterns - map_files = expand_files(args.files) +def format_diff(base, new, diff): + """Format a diff value with percentage.""" + if base == 0 and new == 0: + return "0" + if base == 0: + return f"{new} (new)" + if new == 0: + return f"{base} ➡ 0" + if diff == 0: + return f"{base} ➡ {new}" + pct = (diff / base) * 100 + sign = "+" if diff > 0 else "" + return f"{base} ➡ {new} ({sign}{diff}, {sign}{pct:.1f}%)" + + +def get_sort_key(sort_order): + """Get sort key function based on sort order. + + Args: + sort_order: One of 'size-', 'size+', 'name-', 'name+' + + Returns: + Tuple of (key_func, reverse) + """ + if sort_order == 'size-': + return lambda x: x.get('total', 0) if isinstance(x.get('total'), int) else x['total']['new'], True + elif sort_order == 'size+': + return lambda x: x.get('total', 0) if isinstance(x.get('total'), int) else x['total']['new'], False + elif sort_order == 'name-': + return lambda x: x.get('file', ''), True + else: # name+ + return lambda x: x.get('file', ''), False + + +def write_compare_markdown(comparison, path, sort_order='size'): + """Write comparison data to markdown file.""" + sections = comparison["sections"] + + md_lines = [ + "# TinyUSB Code Size Different Report", + "", + f"**Base:** `{comparison['base_file']}`", + f"**New:** `{comparison['new_file']}`", + "", + ] + + # Build header + header = "| File |" + separator = "|:-----|" + for s in sections: + header += f" {s} |" + separator += "-----:|" + header += " Total |" + separator += "------:|" + + md_lines.append(header) + md_lines.append(separator) + + # Sort files based on sort_order + if sort_order == 'size-': + key_func = lambda x: abs(x["total"]["diff"]) + reverse = True + elif sort_order in ('size', 'size+'): + key_func = lambda x: abs(x["total"]["diff"]) + reverse = False + elif sort_order == 'name-': + key_func = lambda x: x['file'] + reverse = True + else: # name or name+ + key_func = lambda x: x['file'] + reverse = False + sorted_files = sorted(comparison["files"], key=key_func, reverse=reverse) + + sum_base = {s: 0 for s in sections} + sum_base["total"] = 0 + sum_new = {s: 0 for s in sections} + sum_new["total"] = 0 + + for f in sorted_files: + # Skip files with no changes + if f["total"]["diff"] == 0 and all(f["sections"][s]["diff"] == 0 for s in sections): + continue + + row = f"| {f['file']} |" + for s in sections: + sd = f["sections"][s] + sum_base[s] += sd["base"] + sum_new[s] += sd["new"] + row += f" {format_diff(sd['base'], sd['new'], sd['diff'])} |" + + td = f["total"] + sum_base["total"] += td["base"] + sum_new["total"] += td["new"] + row += f" {format_diff(td['base'], td['new'], td['diff'])} |" + + md_lines.append(row) + + # Add sum row + sum_row = "| **SUM** |" + for s in sections: + diff = sum_new[s] - sum_base[s] + sum_row += f" {format_diff(sum_base[s], sum_new[s], diff)} |" + total_diff = sum_new["total"] - sum_base["total"] + sum_row += f" {format_diff(sum_base['total'], sum_new['total'], total_diff)} |" + md_lines.append(sum_row) + + with open(path, "w", encoding="utf-8") as f: + f.write("\n".join(md_lines)) + + +def cmd_combine(args): + """Handle combine subcommand.""" + map_files = expand_files(args.files) all_json_data = combine_maps(map_files, args.filters) json_average = compute_avg(all_json_data) @@ -154,11 +314,65 @@ def main(argv=None): sys.exit(1) if not args.quiet: - linkermap.print_summary(json_average, False) + linkermap.print_summary(json_average, False, args.sort) if args.json_out: linkermap.write_json(json_average, args.out + '.json') if args.markdown_out: - linkermap.write_markdown(json_average, args.out + '.md') + linkermap.write_markdown(json_average, args.out + '.md', sort_opt=args.sort, + title="TinyUSB Average Code Size Metrics") + + +def cmd_compare(args): + """Handle compare subcommand.""" + comparison = compare_maps(args.base, args.new, args.filters) + + if comparison is None: + print("Failed to compare files", file=sys.stderr) + sys.exit(1) + + write_compare_markdown(comparison, args.out + '.md', args.sort) + print(f"Comparison written to {args.out}.md") + + +def main(argv=None): + parser = argparse.ArgumentParser(description='Code size metrics tool') + subparsers = parser.add_subparsers(dest='command', required=True, help='Available commands') + + # Combine subcommand + combine_parser = subparsers.add_parser('combine', help='Combine and average multiple map files') + combine_parser.add_argument('files', nargs='+', help='Path to map file(s) or glob pattern(s)') + combine_parser.add_argument('-f', '--filter', dest='filters', action='append', default=[], + help='Only include object files whose path contains this substring (can be repeated)') + combine_parser.add_argument('-o', '--out', dest='out', default='metrics', + help='Output path basename for JSON and Markdown files (default: metrics)') + combine_parser.add_argument('-j', '--json', dest='json_out', action='store_true', + help='Write JSON output file') + combine_parser.add_argument('-m', '--markdown', dest='markdown_out', action='store_true', + help='Write Markdown output file') + combine_parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', + help='Suppress summary output') + combine_parser.add_argument('-S', '--sort', dest='sort', default='name+', + choices=['size', 'size-', 'size+', 'name', 'name-', 'name+'], + help='Sort order: size/size- (descending), size+ (ascending), name/name+ (ascending), name- (descending). Default: name+') + + # Compare subcommand + compare_parser = subparsers.add_parser('compare', help='Compare two map files') + compare_parser.add_argument('base', help='Base map/json file') + compare_parser.add_argument('new', help='New map/json file') + compare_parser.add_argument('-f', '--filter', dest='filters', action='append', default=[], + help='Only include object files whose path contains this substring (can be repeated)') + compare_parser.add_argument('-o', '--out', dest='out', default='metrics_compare', + help='Output path basename for Markdown file (default: metrics_compare)') + compare_parser.add_argument('-S', '--sort', dest='sort', default='name+', + choices=['size', 'size-', 'size+', 'name', 'name-', 'name+'], + help='Sort order: size/size- (descending), size+ (ascending), name/name+ (ascending), name- (descending). Default: name+') + + args = parser.parse_args(argv) + + if args.command == 'combine': + cmd_combine(args) + elif args.command == 'compare': + cmd_compare(args) if __name__ == '__main__': -- cgit v1.3.1 From 1b6f2b90a45e172a2eb45b3dea2fa2d11382c2b0 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Dec 2025 23:10:21 +0700 Subject: clean up --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b0b636c65..77f2d573f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,7 +70,7 @@ jobs: - 'aarch64-gcc' #- 'arm-clang' - 'arm-gcc' - # - 'esp-idf' + - 'esp-idf' - 'msp430-gcc' - 'riscv-gcc' with: @@ -279,6 +279,7 @@ jobs: - name: Download Artifacts uses: actions/download-artifact@v5 with: + pattern: binaries-* path: cmake-build merge-multiple: true -- cgit v1.3.1 From e7105b1fa3ccd8200fe7fb8b0759d00afc9b07c1 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 4 Dec 2025 21:34:10 +0700 Subject: fine tune ci to build more with circleci (#3386) * fine tune ci to build more with circleci * skip make for arm-iar, esp-idf * skip make + clang for circleci since llvm-objcopy got killed due to memory issue. --- .circleci/config.yml | 51 ++++++++++-------- .circleci/config2.yml | 15 +++++- .github/workflows/build.yml | 60 +++------------------- .github/workflows/build_util.yml | 3 ++ examples/build_system/make/toolchain/gcc_common.mk | 3 ++ hw/bsp/kinetis_k/family.mk | 6 ++- hw/bsp/kinetis_kl/family.mk | 6 ++- tools/build.py | 8 +-- tools/metrics.py | 19 +++---- 9 files changed, 74 insertions(+), 97 deletions(-) (limited to '.github/workflows') diff --git a/.circleci/config.yml b/.circleci/config.yml index 580f5fe2e..d04a33959 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,25 +18,34 @@ jobs: MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) echo "MATRIX_JSON=$MATRIX_JSON" - BUILDSYSTEM_TOOLCHAIN=( - "cmake aarch64-gcc" - "cmake arm-clang" - "cmake arm-gcc" - "cmake esp-idf" - "cmake msp430-gcc" - "cmake riscv-gcc" + BUILDSYSTEM_LIST=( + "cmake" + "make" + ) + + TOOLCHAIN_LIST=( + "aarch64-gcc" + "arm-clang" + "arm-gcc" + "esp-idf" + "msp430-gcc" + "riscv-gcc" ) # only build IAR if not forked PR, since IAR token is not shared if [ -z $CIRCLE_PR_USERNAME ]; then - BUILDSYSTEM_TOOLCHAIN+=("cmake arm-iar") + TOOLCHAIN_LIST+=("arm-iar") fi gen_build_entry() { local build_system="$1" local toolchain="$2" local family="$3" - local resource_class="$4" + local build_args="" + + if [[ "$toolchain" == "arm-iar" || "$build_system" == "make" ]]; then + build_args="--one-per-family" + fi if [[ "$toolchain" == "esp-idf" ]]; then echo " - build-vm:" >> .circleci/config2.yml @@ -49,17 +58,21 @@ jobs: echo " build-system: ['$build_system']" >> .circleci/config2.yml echo " toolchain: ['$toolchain']" >> .circleci/config2.yml echo " family: $family" >> .circleci/config2.yml - echo " resource_class: ['$resource_class']" >> .circleci/config2.yml + echo " resource_class: ['large']" >> .circleci/config2.yml + echo " build-args: ['$build_args']" >> .circleci/config2.yml } - for e in "${BUILDSYSTEM_TOOLCHAIN[@]}"; do - e_arr=($e) - build_system="${e_arr[0]}" - toolchain="${e_arr[1]}" - FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"") - echo "FAMILY_${toolchain}=$FAMILY" + for build_system in "${BUILDSYSTEM_LIST[@]}"; do + for toolchain in "${TOOLCHAIN_LIST[@]}"; do + # make does not support these toolchains + if [ "$build_system" == "make" ] && { [ "$toolchain" == "arm-clang" ] || [ "$toolchain" == "arm-iar" ] || [ "$toolchain" == "esp-idf" ]; }; then + continue + fi - gen_build_entry "$build_system" "$toolchain" "$FAMILY" "large" + FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"") + echo "FAMILY_${toolchain}=$FAMILY" + gen_build_entry "$build_system" "$toolchain" "$FAMILY" + done done - continuation/continue: @@ -67,9 +80,5 @@ jobs: workflows: set-matrix: - # Only build PR here, Push will be built by github action. - when: - and: - - not: << pipeline.git.branch.is_default >> jobs: - set-matrix diff --git a/.circleci/config2.yml b/.circleci/config2.yml index 869597289..77bc4f790 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -66,6 +66,9 @@ commands: type: string family: type: string + build-args: + type: string + default: "" steps: - checkout @@ -107,7 +110,7 @@ commands: no_output_timeout: 20m command: | if [ << parameters.toolchain >> == esp-idf ]; then - docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.2 python tools/build.py << parameters.family >> + docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.2 python tools/build.py << parameters.build-args >> << parameters.family >> else # Toolchain option default is gcc if [ << parameters.toolchain >> == arm-clang ]; then @@ -121,7 +124,7 @@ commands: # circleci docker return $nproc as 36 core, limit parallel to 4 (resource-class = large) # Required for IAR, also prevent crashed/killed by docker - python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.family >> + python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> << parameters.family >> fi jobs: @@ -137,6 +140,9 @@ jobs: type: string family: type: string + build-args: + type: string + default: "" docker: - image: cimg/base:current @@ -147,6 +153,7 @@ jobs: build-system: << parameters.build-system >> toolchain: << parameters.toolchain >> family: << parameters.family >> + build-args: << parameters.build-args >> # Build using VM build-vm: @@ -160,6 +167,9 @@ jobs: type: string family: type: string + build-args: + type: string + default: "" machine: image: ubuntu-2404:current @@ -170,6 +180,7 @@ jobs: build-system: << parameters.build-system >> toolchain: << parameters.toolchain >> family: << parameters.family >> + build-args: << parameters.build-args >> workflows: build: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 77f2d573f..a1bacbc27 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,10 +56,11 @@ jobs: echo "hil_matrix=$HIL_MATRIX_JSON" echo "hil_matrix=$HIL_MATRIX_JSON" >> $GITHUB_OUTPUT - # --------------------------------------- - # Build CMake: only one-per-family. - # Full built is done by CircleCI in PR - # --------------------------------------- + # ------------------------------------------------------------------------------ + # CMake build: only one-per-family. Full built is done by CircleCI in PR + # Note: + # For Make and IAR build: will be done on CircleCI only (one-per-family too) + # ------------------------------------------------------------------------------ cmake: needs: set-matrix uses: ./.github/workflows/build_util.yml @@ -70,7 +71,7 @@ jobs: - 'aarch64-gcc' #- 'arm-clang' - 'arm-gcc' - - 'esp-idf' + #- 'esp-idf' - 'msp430-gcc' - 'riscv-gcc' with: @@ -137,52 +138,6 @@ jobs: header: code-metrics path: metrics_compare.md - - # --------------------------------------- - # Build Make: only build on push with one-per-family - # --------------------------------------- - make: - if: github.event_name == 'push' - needs: set-matrix - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - toolchain: - - 'aarch64-gcc' - #- 'arm-clang' - - 'arm-gcc' - - 'msp430-gcc' - - 'riscv-gcc' - - 'rx-gcc' - with: - build-system: 'make' - toolchain: ${{ matrix.toolchain }} - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} - one-per-family: true - - # --------------------------------------- - # Build IAR - # Since IAR Token secret is not passed to forked PR, only build non-forked PR with make. - # cmake is built by circle-ci. Due to IAR limit capacity, only build oe per family - # --------------------------------------- - arm-iar: - if: false # disable for now since we got reach capacity limit too often - #if: github.event_name == 'push' && github.repository_owner == 'hathach' - needs: set-matrix - uses: ./.github/workflows/build_util.yml - secrets: inherit - strategy: - fail-fast: false - matrix: - build-system: - - 'make' - with: - build-system: ${{ matrix.build-system }} - toolchain: 'arm-iar' - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['arm-iar']) }} - one-per-family: true - # --------------------------------------- # Build Make/CMake on Windows/MacOS # --------------------------------------- @@ -193,10 +148,9 @@ jobs: fail-fast: false matrix: os: [ windows-latest, macos-latest ] - build-system: [ 'make', 'cmake' ] with: os: ${{ matrix.os }} - build-system: ${{ matrix.build-system }} + build-system: 'cmake-make' toolchain: 'arm-gcc-${{ matrix.os }}' build-args: '["stm32h7"]' one-per-family: true diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 36043a1d5..2fc0eead0 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -68,6 +68,9 @@ jobs: run: | if [ "$TOOLCHAIN" == "esp-idf" ]; then docker run --rm -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py ${{ matrix.arg }} + elif [ "${{ inputs.build-system }}" == "cmake-make" ] || [ "${{ inputs.build-system }}" == "make-cmake" ]; then + python tools/build.py -s make ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} + python tools/build.py -s cmake ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} else python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} fi diff --git a/examples/build_system/make/toolchain/gcc_common.mk b/examples/build_system/make/toolchain/gcc_common.mk index 0cbb6774d..42fd01183 100644 --- a/examples/build_system/make/toolchain/gcc_common.mk +++ b/examples/build_system/make/toolchain/gcc_common.mk @@ -31,6 +31,9 @@ CFLAGS += \ -Wreturn-type \ -Wredundant-decls \ +CFLAGS_CLANG += \ + -Wno-error=unknown-warning-option + # -Wmissing-prototypes \ # conversion is too strict for most mcu driver, may be disable sign/int/arith-conversion # -Wconversion diff --git a/hw/bsp/kinetis_k/family.mk b/hw/bsp/kinetis_k/family.mk index e95cdb717..7a51a77d8 100644 --- a/hw/bsp/kinetis_k/family.mk +++ b/hw/bsp/kinetis_k/family.mk @@ -9,11 +9,13 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K \ LDFLAGS += \ - -nostartfiles \ - --specs=nosys.specs --specs=nano.specs \ -Wl,--defsym,__stack_size__=0x400 \ -Wl,--defsym,__heap_size__=0 +LDFLAGS_GCC += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ + SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ src/portable/nxp/khci/hcd_khci.c \ diff --git a/hw/bsp/kinetis_kl/family.mk b/hw/bsp/kinetis_kl/family.mk index 8d113aecf..aec53d486 100644 --- a/hw/bsp/kinetis_kl/family.mk +++ b/hw/bsp/kinetis_kl/family.mk @@ -9,11 +9,13 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_KL \ LDFLAGS += \ - -nostartfiles \ - -specs=nosys.specs -specs=nano.specs \ -Wl,--defsym,__stack_size__=0x400 \ -Wl,--defsym,__heap_size__=0 +LDFLAGS_GCC += \ + -nostartfiles \ + -specs=nosys.specs -specs=nano.specs \ + SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ src/portable/nxp/khci/hcd_khci.c \ diff --git a/tools/build.py b/tools/build.py index e4909f45f..c4f1558c0 100755 --- a/tools/build.py +++ b/tools/build.py @@ -142,16 +142,12 @@ def make_one_example(example, board, make_option): r = 2 else: start_time = time.monotonic() - # skip -j for circleci - if not os.getenv('CIRCLECI'): - make_option += ' -j' - make_args = ["make", "-C", f"examples/{example}", f"BOARD={board}"] + make_args = ["make", "-C", f"examples/{example}", f"BOARD={board}", '-j', str(parallel_jobs)] if make_option: make_args += shlex.split(make_option) - make_args.append("all") if clean_build: run_cmd(make_args + ["clean"]) - build_result = run_cmd(make_args) + build_result = run_cmd(make_args + ['all']) r = 0 if build_result.returncode == 0 else 1 print_build_result(board, example, r, time.monotonic() - start_time) diff --git a/tools/metrics.py b/tools/metrics.py index bb84f803e..c3b366e42 100644 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -195,17 +195,13 @@ def compare_maps(base_file, new_file, filters=None): def format_diff(base, new, diff): """Format a diff value with percentage.""" - if base == 0 and new == 0: - return "0" - if base == 0: - return f"{new} (new)" - if new == 0: - return f"{base} ➡ 0" if diff == 0: - return f"{base} ➡ {new}" + return f"{new}" + if base == 0 or new == 0: + return f"{base} ➙ {new}" pct = (diff / base) * 100 sign = "+" if diff > 0 else "" - return f"{base} ➡ {new} ({sign}{diff}, {sign}{pct:.1f}%)" + return f"{base} ➙ {new} ({sign}{diff}, {sign}{pct:.1f}%)" def get_sort_key(sort_order): @@ -232,10 +228,11 @@ def write_compare_markdown(comparison, path, sort_order='size'): sections = comparison["sections"] md_lines = [ - "# TinyUSB Code Size Different Report", + "# Size Difference Report", "", - f"**Base:** `{comparison['base_file']}`", - f"**New:** `{comparison['new_file']}`", + "Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds." + "", + "Note: If there is no change, only one value is shown.", "", ] -- cgit v1.3.1 From 93b53158f02bce9497419298ac27150eebe567d3 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 5 Dec 2025 10:21:28 +0700 Subject: Run CI build with fixed set of boards (#3389) * run cmake ci build on github with a fixed set of board to keep the size stable * Size Difference Report contain major >1% and minor <1& table --- .circleci/config.yml | 2 +- .github/workflows/build.yml | 9 ++--- .github/workflows/build_util.yml | 22 +++------- hw/bsp/rp2040/skip_ci.txt | 7 ---- tools/build.py | 62 ++++++++++++++++++++--------- tools/metrics.py | 86 ++++++++++++++++++++++++++-------------- 6 files changed, 112 insertions(+), 76 deletions(-) delete mode 100644 hw/bsp/rp2040/skip_ci.txt (limited to '.github/workflows') diff --git a/.circleci/config.yml b/.circleci/config.yml index d04a33959..42b790c83 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,7 +44,7 @@ jobs: local build_args="" if [[ "$toolchain" == "arm-iar" || "$build_system" == "make" ]]; then - build_args="--one-per-family" + build_args="--one-random" fi if [[ "$toolchain" == "esp-idf" ]]; then diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a1bacbc27..bc2fdac77 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -57,9 +57,9 @@ jobs: echo "hil_matrix=$HIL_MATRIX_JSON" >> $GITHUB_OUTPUT # ------------------------------------------------------------------------------ - # CMake build: only one-per-family. Full built is done by CircleCI in PR + # CMake build: only one board per family (first alphabetically). Full build is done by CircleCI in PR # Note: - # For Make and IAR build: will be done on CircleCI only (one-per-family too) + # For Make and IAR build: will be done on CircleCI only (one random per family as well) # ------------------------------------------------------------------------------ cmake: needs: set-matrix @@ -78,7 +78,7 @@ jobs: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} - one-per-family: true + build-options: '--one-first' upload-metrics: true code-metrics: @@ -153,7 +153,7 @@ jobs: build-system: 'cmake-make' toolchain: 'arm-gcc-${{ matrix.os }}' build-args: '["stm32h7"]' - one-per-family: true + build-options: '--one-random' # --------------------------------------- # Zephyr @@ -196,7 +196,6 @@ jobs: build-system: 'cmake' toolchain: ${{ matrix.toolchain }} build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.hil_json)[matrix.toolchain]) }} - one-per-family: true upload-artifacts: true # --------------------------------------- diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 2fc0eead0..1cbd02f1b 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -12,10 +12,10 @@ on: build-args: required: true type: string - one-per-family: + build-options: required: false - default: false - type: boolean + default: '' + type: string upload-artifacts: required: false default: false @@ -51,16 +51,6 @@ jobs: with: arg: ${{ matrix.arg }} - - name: Set build one-per-family option - id: set-one-per-family - run: | - if [[ "${{ inputs.one-per-family }}" == "true" ]]; then - BUILD_OPTION="--one-per-family" - fi - echo "build_option=$BUILD_OPTION" - echo "build_option=$BUILD_OPTION" >> $GITHUB_OUTPUT - shell: bash - - name: Build env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} @@ -69,10 +59,10 @@ jobs: if [ "$TOOLCHAIN" == "esp-idf" ]; then docker run --rm -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py ${{ matrix.arg }} elif [ "${{ inputs.build-system }}" == "cmake-make" ] || [ "${{ inputs.build-system }}" == "make-cmake" ]; then - python tools/build.py -s make ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} - python tools/build.py -s cmake ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} + python tools/build.py -s make ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} + python tools/build.py -s cmake ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} else - python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} + python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} fi shell: bash diff --git a/hw/bsp/rp2040/skip_ci.txt b/hw/bsp/rp2040/skip_ci.txt deleted file mode 100644 index fe99c9f65..000000000 --- a/hw/bsp/rp2040/skip_ci.txt +++ /dev/null @@ -1,7 +0,0 @@ -# boards in this files are skipped when running CI with this family -adafruit_feather_rp2040_usb_host -adafruit_fruit_jam -adafruit_metro_rp2350 -feather_rp2040_max3421 -pico_sdk -raspberry_pi_pico_w diff --git a/tools/build.py b/tools/build.py index c4f1558c0..87064b7a0 100755 --- a/tools/build.py +++ b/tools/build.py @@ -27,6 +27,23 @@ verbose = False clean_build = False parallel_jobs = os.cpu_count() +# CI board control lists (used when running under CI) +ci_skip_boards = { + 'rp2040': [ + 'adafruit_feather_rp2040_usb_host', + 'adafruit_fruit_jam', + 'adafruit_metro_rp2350', + 'feather_rp2040_max3421', + 'pico_sdk', + 'raspberry_pi_pico_w', + ], +} + +ci_preferred_boards = { + 'stm32h7': ['stm32h743eval'], +} + + # ----------------------------- # Helper # ----------------------------- @@ -195,35 +212,40 @@ def build_boards_list(boards, build_defines, build_system, build_flags_on): return ret -def get_family_boards(family, one_per_family, boards): +def get_family_boards(family, one_random, one_first): """Get list of boards for a family. Args: family: Family name - one_per_family: If True, return only one random board - boards: List of boards already specified via -b flag + one_random: If True, return only one random board + one_first: If True, return only the first board (alphabetical) Returns: List of board names """ - skip_ci = [] + skip_list = [] + preferred_list = [] if os.getenv('GITHUB_ACTIONS') or os.getenv('CIRCLECI'): - skip_ci_file = Path(f"hw/bsp/{family}/skip_ci.txt") - if skip_ci_file.exists(): - skip_ci = skip_ci_file.read_text().split() + skip_list = ci_skip_boards.get(family, []) + preferred_list = ci_preferred_boards.get(family, []) + all_boards = [] for entry in os.scandir(f"hw/bsp/{family}/boards"): - if entry.is_dir() and not entry.name in skip_ci: + if entry.is_dir() and entry.name not in skip_list: all_boards.append(entry.name) + if not all_boards: + print(f"No boards found for family '{family}'") + return [] all_boards.sort() - # If only-one flag is set, select one random board - if one_per_family: - for b in boards: - # skip if -b already specify one in this family - if find_family(b) == family: - return [] - all_boards = [random.choice(all_boards)] + # If only-one flags are set, honor select list first, then pick first or random + if one_first or one_random: + if preferred_list: + return [preferred_list[0]] + if one_first: + return [all_boards[0]] + if one_random: + return [random.choice(all_boards)] return all_boards @@ -244,7 +266,10 @@ def main(): parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') parser.add_argument('-D', '--define-symbol', action='append', default=[], help='Define to pass to build system') parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Build flag to pass to build system') - parser.add_argument('-1', '--one-per-family', action='store_true', default=False, help='Build only one random board inside a family') + parser.add_argument('--one-random', action='store_true', default=False, + help='Build only one random board of each specified family') + parser.add_argument('--one-first', action='store_true', default=False, + help='Build only the first board (alphabetical) of each specified family') parser.add_argument('-j', '--jobs', type=int, default=os.cpu_count(), help='Number of jobs to run in parallel') parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') args = parser.parse_args() @@ -255,7 +280,8 @@ def main(): build_system = args.build_system build_defines = args.define_symbol build_flags_on = args.build_flags_on - one_per_family = args.one_per_family + one_random = args.one_random + one_first = args.one_first verbose = args.verbose clean_build = args.clean parallel_jobs = args.jobs @@ -283,7 +309,7 @@ def main(): # get boards from families and append to boards list all_boards = list(boards) for f in all_families: - all_boards.extend(get_family_boards(f, one_per_family, boards)) + all_boards.extend(get_family_boards(f, one_random, one_first)) # build all boards result = build_boards_list(all_boards, build_defines, build_system, build_flags_on) diff --git a/tools/metrics.py b/tools/metrics.py index c3b366e42..bdc64fccc 100644 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -245,8 +245,18 @@ def write_compare_markdown(comparison, path, sort_order='size'): header += " Total |" separator += "------:|" - md_lines.append(header) - md_lines.append(separator) + def is_significant(file_row): + for s in sections: + sd = file_row["sections"][s] + diff = abs(sd["diff"]) + base = sd["base"] + if base == 0: + if diff != 0: + return True + else: + if (diff / base) * 100 > 1.0: + return True + return False # Sort files based on sort_order if sort_order == 'size-': @@ -263,38 +273,56 @@ def write_compare_markdown(comparison, path, sort_order='size'): reverse = False sorted_files = sorted(comparison["files"], key=key_func, reverse=reverse) - sum_base = {s: 0 for s in sections} - sum_base["total"] = 0 - sum_new = {s: 0 for s in sections} - sum_new["total"] = 0 - + significant = [] + minor = [] for f in sorted_files: # Skip files with no changes if f["total"]["diff"] == 0 and all(f["sections"][s]["diff"] == 0 for s in sections): continue - - row = f"| {f['file']} |" + (significant if is_significant(f) else minor).append(f) + + def render_table(title, rows): + md_lines.append(f"## {title}") + if not rows: + md_lines.append("No entries.") + md_lines.append("") + return + + md_lines.append(header) + md_lines.append(separator) + + sum_base = {s: 0 for s in sections} + sum_base["total"] = 0 + sum_new = {s: 0 for s in sections} + sum_new["total"] = 0 + + for f in rows: + row = f"| {f['file']} |" + for s in sections: + sd = f["sections"][s] + sum_base[s] += sd["base"] + sum_new[s] += sd["new"] + row += f" {format_diff(sd['base'], sd['new'], sd['diff'])} |" + + td = f["total"] + sum_base["total"] += td["base"] + sum_new["total"] += td["new"] + row += f" {format_diff(td['base'], td['new'], td['diff'])} |" + + md_lines.append(row) + + # Add sum row + sum_row = "| **SUM** |" for s in sections: - sd = f["sections"][s] - sum_base[s] += sd["base"] - sum_new[s] += sd["new"] - row += f" {format_diff(sd['base'], sd['new'], sd['diff'])} |" - - td = f["total"] - sum_base["total"] += td["base"] - sum_new["total"] += td["new"] - row += f" {format_diff(td['base'], td['new'], td['diff'])} |" - - md_lines.append(row) - - # Add sum row - sum_row = "| **SUM** |" - for s in sections: - diff = sum_new[s] - sum_base[s] - sum_row += f" {format_diff(sum_base[s], sum_new[s], diff)} |" - total_diff = sum_new["total"] - sum_base["total"] - sum_row += f" {format_diff(sum_base['total'], sum_new['total'], total_diff)} |" - md_lines.append(sum_row) + diff = sum_new[s] - sum_base[s] + sum_row += f" {format_diff(sum_base[s], sum_new[s], diff)} |" + total_diff = sum_new["total"] - sum_base["total"] + sum_row += f" {format_diff(sum_base['total'], sum_new['total'], total_diff)} |" + md_lines.append(sum_row) + md_lines.append("") + + render_table("Changes >1% in any section", significant) + render_table("Changes <1% in all sections", minor) with open(path, "w", encoding="utf-8") as f: f.write("\n".join(md_lines)) -- cgit v1.3.1 From e73dfde96dcf59e6357d833adbe49c1cf716a1b3 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 5 Dec 2025 20:12:45 +0700 Subject: also render unchange table (#3390) * also render unchange table * run metrics with circleci (full all boards build) --- .circleci/config.yml | 19 +++++++- .circleci/config2.yml | 104 +++++++++++++++++++++++++++++++++++++++++--- .github/workflows/build.yml | 12 +++-- tools/metrics.py | 11 +++-- 4 files changed, 126 insertions(+), 20 deletions(-) (limited to '.github/workflows') diff --git a/.circleci/config.yml b/.circleci/config.yml index 42b790c83..c084fc226 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,7 +9,7 @@ jobs: executor: continuation/default docker: - image: cimg/base:current - resource_class: small + resource_class: large steps: - checkout - run: @@ -52,8 +52,8 @@ jobs: else echo " - build:" >> .circleci/config2.yml fi - echo " matrix:" >> .circleci/config2.yml + echo " alias: build-${build_system}-${toolchain}" >> .circleci/config2.yml echo " parameters:" >> .circleci/config2.yml echo " build-system: ['$build_system']" >> .circleci/config2.yml echo " toolchain: ['$toolchain']" >> .circleci/config2.yml @@ -62,6 +62,9 @@ jobs: echo " build-args: ['$build_args']" >> .circleci/config2.yml } + # Collect all build aliases for code-metrics requires (cmake only, exclude esp-idf) + BUILD_ALIASES=() + for build_system in "${BUILDSYSTEM_LIST[@]}"; do for toolchain in "${TOOLCHAIN_LIST[@]}"; do # make does not support these toolchains @@ -72,9 +75,21 @@ jobs: FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"") echo "FAMILY_${toolchain}=$FAMILY" gen_build_entry "$build_system" "$toolchain" "$FAMILY" + + # Only add cmake builds: excluding esp-idf or build_args="--one-random" to metrics requirements + if [ "$build_system" == "cmake" ] && [ "$toolchain" != "esp-idf" ] && [ "$toolchain" != "arm-iar" ]; then + BUILD_ALIASES+=("build-${build_system}-${toolchain}") + fi done done + # Add code-metrics job that requires all build jobs + echo " - code-metrics:" >> .circleci/config2.yml + echo " requires:" >> .circleci/config2.yml + for alias in "${BUILD_ALIASES[@]}"; do + echo " - $alias" >> .circleci/config2.yml + done + - continuation/continue: configuration_path: .circleci/config2.yml diff --git a/.circleci/config2.yml b/.circleci/config2.yml index 77bc4f790..a39682067 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -127,6 +127,35 @@ commands: python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> << parameters.family >> fi + # Only collect and persist metrics for cmake builds (excluding esp-idf and --one-random) + - when: + condition: + and: + - equal: [ cmake, << parameters.build-system >> ] + - not: + equal: [ esp-idf, << parameters.toolchain >> ] + - not: + equal: [ arm-iar, << parameters.toolchain >> ] + steps: + - run: + name: Collect Metrics + command: | + # Create unique directory per toolchain to avoid workspace conflicts + METRICS_DIR="/tmp/metrics/<< parameters.toolchain >>" + mkdir -p "${METRICS_DIR}" + # Copy all metrics.json files + for f in cmake-build/cmake-build-*/metrics.json; do + if [ -f "$f" ]; then + BOARD_DIR=$(dirname "$f" | xargs basename) + cp "$f" "${METRICS_DIR}/${BOARD_DIR}.json" + fi + done + + - persist_to_workspace: + root: /tmp + paths: + - metrics/<< parameters.toolchain >> + jobs: # Build using docker build: @@ -146,6 +175,7 @@ jobs: docker: - image: cimg/base:current + working_directory: ~/project/tinyusb resource_class: << parameters.resource_class >> steps: @@ -173,6 +203,7 @@ jobs: machine: image: ubuntu-2404:current + working_directory: ~/project/tinyusb resource_class: << parameters.resource_class >> steps: @@ -182,20 +213,79 @@ jobs: family: << parameters.family >> build-args: << parameters.build-args >> + # Aggregate code metrics from all builds + code-metrics: + docker: + - image: cimg/python:3.12 + resource_class: large + steps: + - checkout + - attach_workspace: + at: /tmp + + - run: + name: Aggregate Code Metrics + command: | + python tools/get_deps.py + pip install tools/linkermap/ + # Combine all metrics files from all toolchain subdirectories + ls -R /tmp/metrics + if ls /tmp/metrics/*/*.json 1> /dev/null 2>&1; then + python tools/metrics.py combine -j -m -f tinyusb/src /tmp/metrics/*/*.json + else + echo "No metrics files found" + exit 1 + fi + + - store_artifacts: + path: metrics.json + destination: metrics.json + + # Compare with base master metrics on PR branches + - when: + condition: + not: + equal: [ master, << pipeline.git.branch >> ] + steps: + - run: + name: Download Base Branch Metrics + command: | + # Download metrics.json artifact from the latest successful build on master branch + mkdir -p base-metrics + # Use CircleCI API to get the latest artifact + curl -s -L "https://dl.circleci.com/api/v2/project/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/latest/artifacts?branch=master&filter=successful" \ + -H "Circle-Token: ${CIRCLE_TOKEN:-}" | \ + jq -r '.items[] | select(.path == "metrics.json") | .url' | \ + head -1 | xargs -I {} curl -s -L -o base-metrics/metrics.json {} || true + + - run: + name: Compare with Base Branch + command: | + if [ -f base-metrics/metrics.json ]; then + python tools/metrics.py compare -f tinyusb/src base-metrics/metrics.json metrics.json + cat metrics_compare.md + else + echo "No base metrics found, skipping comparison" + cp metrics.md metrics_compare.md + fi + + - store_artifacts: + path: metrics_compare.md + destination: metrics_compare.md + workflows: build: jobs: +# The jobs below are populated dynamically by config.yml set-matrix job +# Example entries that will be generated: # - build: # matrix: +# alias: build-cmake-arm-gcc # parameters: # toolchain: [ 'arm-gcc' ] # build-system: [ 'cmake' ] # family: [ 'nrf' ] # resource_class: ['large'] -# - build-vm: -# matrix: -# parameters: -# toolchain: ['esp-idf'] -# build-system: ['cmake'] -# family: ['-bespressif_kaluga_1'] -# resource_class: ['large'] +# - code-metrics: +# requires: +# - build-cmake-arm-gcc diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bc2fdac77..5017cb3cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -111,7 +111,7 @@ jobs: path: metrics.json - name: Download Base Branch Metrics - if: github.event_name == 'pull_request' + if: github.event_name != 'push' uses: dawidd6/action-download-artifact@v11 with: workflow: build.yml @@ -121,7 +121,7 @@ jobs: continue-on-error: true - name: Compare with Base Branch - if: github.event_name == 'pull_request' + if: github.event_name != 'push' run: | if [ -f base-metrics/metrics.json ]; then python tools/metrics.py compare -f tinyusb/src base-metrics/metrics.json metrics.json @@ -132,7 +132,7 @@ jobs: fi - name: Post Code Metrics as PR Comment - if: github.event_name == 'pull_request' + if: github.event_name != 'push' uses: marocchino/sticky-pull-request-comment@v2 with: header: code-metrics @@ -203,9 +203,7 @@ jobs: # self-hosted on local VM, for attached hardware checkout HIL_JSON # --------------------------------------- hil-tinyusb: - if: | - github.repository_owner == 'hathach' && - (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') + if: github.repository_owner == 'hathach' && github.event_name != 'push' needs: hil-build runs-on: [ self-hosted, X64, hathach, hardware-in-the-loop ] steps: @@ -249,7 +247,7 @@ jobs: if: | github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false && - (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') + github.event_name != 'push' runs-on: [ self-hosted, Linux, X64, hifiphile ] env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} diff --git a/tools/metrics.py b/tools/metrics.py index bdc64fccc..2794c7a2a 100644 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -275,11 +275,13 @@ def write_compare_markdown(comparison, path, sort_order='size'): significant = [] minor = [] + unchanged = [] for f in sorted_files: - # Skip files with no changes - if f["total"]["diff"] == 0 and all(f["sections"][s]["diff"] == 0 for s in sections): - continue - (significant if is_significant(f) else minor).append(f) + no_change = f["total"]["diff"] == 0 and all(f["sections"][s]["diff"] == 0 for s in sections) + if no_change: + unchanged.append(f) + else: + (significant if is_significant(f) else minor).append(f) def render_table(title, rows): md_lines.append(f"## {title}") @@ -323,6 +325,7 @@ def write_compare_markdown(comparison, path, sort_order='size'): render_table("Changes >1% in any section", significant) render_table("Changes <1% in all sections", minor) + render_table("No changes", unchanged) with open(path, "w", encoding="utf-8") as f: f.write("\n".join(md_lines)) -- cgit v1.3.1 From 919ee4b1527469e327710cff936366328f97294a Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 9 Dec 2025 20:11:18 +0700 Subject: update metrics to support bloaty csv --- .circleci/config2.yml | 1 - .github/workflows/build.yml | 3 +- .../build_system/cmake/toolchain/arm_clang.cmake | 1 - examples/build_system/cmake/toolchain/common.cmake | 41 +++--- hw/bsp/family_support.cmake | 33 ++--- src/common/tusb_compiler.h | 6 +- src/portable/synopsys/dwc2/hcd_dwc2.c | 2 +- tools/get_deps.py | 2 +- tools/metrics.py | 152 ++++++++++++--------- 9 files changed, 124 insertions(+), 117 deletions(-) (limited to '.github/workflows') diff --git a/.circleci/config2.yml b/.circleci/config2.yml index a39682067..352d0f4fa 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -227,7 +227,6 @@ jobs: name: Aggregate Code Metrics command: | python tools/get_deps.py - pip install tools/linkermap/ # Combine all metrics files from all toolchain subdirectories ls -R /tmp/metrics if ls /tmp/metrics/*/*.json 1> /dev/null 2>&1; then diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5017cb3cd..9d94a3b9b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -100,7 +100,6 @@ jobs: - name: Aggregate Code Metrics run: | python tools/get_deps.py - pip install tools/linkermap/ python tools/metrics.py combine -j -m -f tinyusb/src cmake-build/*/metrics.json - name: Upload Metrics Artifact @@ -124,7 +123,7 @@ jobs: if: github.event_name != 'push' run: | if [ -f base-metrics/metrics.json ]; then - python tools/metrics.py compare -f tinyusb/src base-metrics/metrics.json metrics.json + python tools/metrics.py compare -m -f tinyusb/src base-metrics/metrics.json metrics.json cat metrics_compare.md else echo "No base metrics found, skipping comparison" diff --git a/examples/build_system/cmake/toolchain/arm_clang.cmake b/examples/build_system/cmake/toolchain/arm_clang.cmake index dba637367..e5ca82fab 100644 --- a/examples/build_system/cmake/toolchain/arm_clang.cmake +++ b/examples/build_system/cmake/toolchain/arm_clang.cmake @@ -7,7 +7,6 @@ if (NOT DEFINED CMAKE_CXX_COMPILER) endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) -set(TOOLCHAIN_ASM_FLAGS "-x assembler-with-cpp") find_program(CMAKE_SIZE llvm-size) find_program(CMAKE_OBJCOPY llvm-objcopy) diff --git a/examples/build_system/cmake/toolchain/common.cmake b/examples/build_system/cmake/toolchain/common.cmake index 1ef04bc00..e610a349b 100644 --- a/examples/build_system/cmake/toolchain/common.cmake +++ b/examples/build_system/cmake/toolchain/common.cmake @@ -20,41 +20,32 @@ include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_CPU}.cmake) # ---------------------------------------------------------------------------- # Compile flags # ---------------------------------------------------------------------------- +set(TOOLCHAIN_C_FLAGS) +set(TOOLCHAIN_ASM_FLAGS) +set(TOOLCHAIN_EXE_LINKER_FLAGS) + if (TOOLCHAIN STREQUAL "gcc" OR TOOLCHAIN STREQUAL "clang") list(APPEND TOOLCHAIN_COMMON_FLAGS -fdata-sections -ffunction-sections # -fsingle-precision-constant # not supported by clang -fno-strict-aliasing - -g - ) - list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS - -Wl,--print-memory-usage - -Wl,--gc-sections - -Wl,--cref + -g # include debug info for bloaty ) + set(TOOLCHAIN_EXE_LINKER_FLAGS "-Wl,--print-memory-usage -Wl,--gc-sections -Wl,--cref") + + if (TOOLCHAIN STREQUAL clang) + set(TOOLCHAIN_ASM_FLAGS "-x assembler-with-cpp") + endif () elseif (TOOLCHAIN STREQUAL "iar") - list(APPEND TOOLCHAIN_COMMON_FLAGS - --debug - ) - list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS - --diag_suppress=Li065 - ) + set(TOOLCHAIN_C_FLAGS --debug) + set(TOOLCHAIN_EXE_LINKER_FLAGS --diag_suppress=Li065) endif () # join the toolchain flags into a single string list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS) -foreach (LANG IN ITEMS C CXX ASM) - set(CMAKE_${LANG}_FLAGS_INIT ${TOOLCHAIN_COMMON_FLAGS}) - # optimization flags for LOG, LOGGER ? - #set(CMAKE_${LANG}_FLAGS_RELEASE_INIT "-Os") - #set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-O0") -endforeach () - -# Assembler -if (DEFINED TOOLCHAIN_ASM_FLAGS) - set(CMAKE_ASM_FLAGS_INIT "${CMAKE_ASM_FLAGS_INIT} ${TOOLCHAIN_ASM_FLAGS}") -endif () -# Linker -list(JOIN TOOLCHAIN_EXE_LINKER_FLAGS " " CMAKE_EXE_LINKER_FLAGS_INIT) +set(CMAKE_C_FLAGS_INIT "${TOOLCHAIN_COMMON_FLAGS} ${TOOLCHAIN_C_FLAGS}") +set(CMAKE_CXX_FLAGS_INIT "${TOOLCHAIN_COMMON_FLAGS} ${TOOLCHAIN_C_FLAGS}") +set(CMAKE_ASM_FLAGS_INIT "${TOOLCHAIN_COMMON_FLAGS} ${TOOLCHAIN_ASM_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS_INIT ${TOOLCHAIN_EXE_LINKER_FLAGS}) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 62ec412e6..5eadcdaa9 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -232,7 +232,7 @@ function(family_add_bloaty TARGET) return() endif () - set(OPTION "--domain=vm -d compileunits") # add -d symbol if needed + set(OPTION "--domain=vm -d compileunits,sections,symbols") if (DEFINED BLOATY_OPTION) string(APPEND OPTION " ${BLOATY_OPTION}") endif () @@ -240,36 +240,33 @@ function(family_add_bloaty TARGET) add_custom_target(${TARGET}-bloaty DEPENDS ${TARGET} - COMMAND ${BLOATY_EXE} ${OPTION_LIST} $ > $.bloaty.txt - COMMAND cat $.bloaty.txt + COMMAND ${BLOATY_EXE} ${OPTION_LIST} $ VERBATIM) # post build - add_custom_command(TARGET ${TARGET} POST_BUILD - COMMAND ${BLOATY_EXE} ${OPTION_LIST} $ > $.bloaty.txt - COMMAND cat $.bloaty.txt - VERBATIM - ) + # add_custom_command(TARGET ${TARGET} POST_BUILD + # COMMAND ${BLOATY_EXE} --csv ${OPTION_LIST} $ > ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_bloaty.csv + # VERBATIM + # ) endfunction() # Add linkermap target (https://github.com/hathach/linkermap) function(family_add_linkermap TARGET) - set(LINKERMAP_OPTION_LIST) + set(OPTION "-j") if (DEFINED LINKERMAP_OPTION) - separate_arguments(LINKERMAP_OPTION_LIST UNIX_COMMAND ${LINKERMAP_OPTION}) + string(APPEND OPTION " ${LINKERMAP_OPTION}") endif () + separate_arguments(OPTION_LIST UNIX_COMMAND ${OPTION}) add_custom_target(${TARGET}-linkermap - COMMAND python ${LINKERMAP_PY} ${LINKERMAP_OPTION_LIST} $.map + COMMAND python ${LINKERMAP_PY} ${OPTION_LIST} $.map VERBATIM ) - # post build if bloaty not exist - if (NOT TARGET ${TARGET}-bloaty) - add_custom_command(TARGET ${TARGET} POST_BUILD - COMMAND python ${LINKERMAP_PY} ${LINKERMAP_OPTION_LIST} $.map - VERBATIM) - endif () + # post build + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND python ${LINKERMAP_PY} ${OPTION_LIST} $.map + VERBATIM) endfunction() #------------------------------------------------------------- @@ -384,7 +381,7 @@ function(family_configure_common TARGET RTOS) if (NOT RTOS STREQUAL zephyr) # Analyze size with bloaty and linkermap family_add_bloaty(${TARGET}) - family_add_linkermap(${TARGET}) # fall back to linkermap if bloaty not found + family_add_linkermap(${TARGET}) endif () # run size after build diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index c8108264f..f20834cea 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -183,11 +183,11 @@ #define TU_BSWAP32(u32) (__builtin_bswap32(u32)) #endif - #ifndef __ARMCC_VERSION // List of obsolete callback function that is renamed and should not be defined. // Put it here since only gcc support this pragma - #pragma GCC poison tud_vendor_control_request_cb - #endif + #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) + #pragma GCC poison tud_vendor_control_request_cb + #endif #elif defined(__ICCARM__) #include diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index b92448685..fc748c85f 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -821,7 +821,7 @@ static void channel_xfer_in_retry(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hci } } -#if CFG_TUSB_DEBUG +#if CFG_TUSB_DEBUG && 0 TU_ATTR_ALWAYS_INLINE static inline void print_hcint(uint32_t hcint) { const char* str[] = { "XFRC", "HALTED", "AHBERR", "STALL", diff --git a/tools/get_deps.py b/tools/get_deps.py index f11d8d51e..0d9c1a8f1 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -15,7 +15,7 @@ deps_mandatory = { '159e31b689577dbf69cf0683bbaffbd71fa5ee10', 'all'], 'tools/linkermap': ['https://github.com/hathach/linkermap.git', - '23d1c4c84c4866b84cb821fb368bb9991633871d', + '8e1f440fa15c567aceb5aa0d14f6d18c329cc67f', 'all'], 'tools/uf2': ['https://github.com/microsoft/uf2.git', 'c594542b2faa01cc33a2b97c9fbebc38549df80a', diff --git a/tools/metrics.py b/tools/metrics.py index f879a0d34..50709d5ba 100644 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Calculate average sizes using bloaty output.""" +"""Calculate average sizes from bloaty CSV or TinyUSB metrics JSON outputs.""" import argparse import csv @@ -85,7 +85,7 @@ def parse_bloaty_csv(csv_text, filters=None): def combine_files(input_files, filters=None): - """Combine multiple bloaty outputs into a single data set.""" + """Combine multiple metrics inputs (bloaty CSV or metrics JSON) into a single data set.""" filters = filters or [] all_json_data = {"file_list": [], "data": []} @@ -168,12 +168,6 @@ def compute_avg(all_json_data): continue file_accumulator[fname]["symbols"][name].append(sym.get("size", 0)) sections_map = f.get("sections") or {} - if isinstance(sections_map, list): - sections_map = { - s.get("name"): s.get("size", 0) - for s in sections_map - if isinstance(s, dict) and s.get("name") - } for sname, ssize in sections_map.items(): file_accumulator[fname]["sections"][sname].append(ssize) @@ -240,6 +234,8 @@ def compare_files(base_file, new_file, filters=None): n = new_files.get(fname, {}) b_size = b.get("size", 0) n_size = n.get("size", 0) + base_sections = b.get("sections") or {} + new_sections = n.get("sections") or {} # Symbol diffs b_syms = {s["name"]: s for s in b.get("symbols", [])} @@ -256,6 +252,14 @@ def compare_files(base_file, new_file, filters=None): "file": fname, "size": {"base": b_size, "new": n_size, "diff": n_size - b_size}, "symbols": symbols, + "sections": { + name: { + "base": base_sections.get(name, 0), + "new": new_sections.get(name, 0), + "diff": new_sections.get(name, 0) - base_sections.get(name, 0), + } + for name in sorted(set(base_sections) | set(new_sections)) + }, }) total = { @@ -299,6 +303,17 @@ def get_sort_key(sort_order): return lambda x: x.get('file', ''), False +def format_diff(base, new, diff): + """Format a diff value with percentage.""" + if diff == 0: + return f"{new}" + if base == 0 or new == 0: + return f"{base} ➙ {new}" + pct = (diff / base) * 100 + sign = "+" if diff > 0 else "" + return f"{base} ➙ {new} ({sign}{diff}, {sign}{pct:.1f}%)" + + def write_json_output(json_data, path): """Write JSON output with indentation.""" @@ -315,7 +330,7 @@ def render_combine_table(json_data, sort_order='name+'): key_func, reverse = get_sort_key(sort_order) files_sorted = sorted(files, key=key_func, reverse=reverse) - total_size = json_data.get("TOTAL") or (sum(f.get("size", 0) for f in files_sorted) or 1) + total_size = json_data.get("TOTAL") or sum(f.get("size", 0) for f in files_sorted) pct_strings = [ f"{(f.get('percent') if f.get('percent') is not None else (f.get('size', 0) / total_size * 100 if total_size else 0)):.1f}%" @@ -357,12 +372,6 @@ def render_combine_table(json_data, sort_order='name+'): parts = [f"| {f.get('file', ''):<{file_width}} |"] if section_names: sections_map = f.get("sections") or {} - if isinstance(sections_map, list): - sections_map = { - s.get("name"): s.get("size", 0) - for s in sections_map - if isinstance(s, dict) and s.get("name") - } for name in section_names: parts.append(f" {sections_map.get(name, 0):>{section_widths[name]}} |") parts.append(f" {size_val:>{size_width}} | {pct_str:>{pct_width}} |") @@ -469,6 +478,7 @@ def _build_rows(files, sort_order): "new": sd['new'], "diff": diff_val, "pct": pct_str, + "sections": f.get("sections", {}), }) return rows @@ -506,59 +516,68 @@ def render_compare_table(rows, include_sum): if not rows: return ["No entries.", ""] + # collect section columns (reverse alpha) + section_names = sorted( + {name for r in rows for name in (r.get("sections") or {})}, + reverse=True, + ) + + def fmt_abs(val_old, val_new): + diff = val_new - val_old + if diff == 0: + return f"{val_new}" + sign = "+" if diff > 0 else "" + return f"{val_old} ➙ {val_new} ({sign}{diff})" + sum_base = sum(r["base"] for r in rows) sum_new = sum(r["new"] for r in rows) total_diff = sum_new - sum_base total_pct = "n/a" if sum_base == 0 else f"{(total_diff / sum_base) * 100:+.1f}%" - base_width = max(len("base"), *(len(str(r["base"])) for r in rows)) - new_width = max(len("new"), *(len(str(r["new"])) for r in rows)) - diff_width = max(len("diff"), *(len(f"{r['diff']:+}") for r in rows)) - pct_width = max(len("% diff"), *(len(r["pct"]) for r in rows)) - name_width = max(len("file"), *(len(r["file"]) for r in rows)) - - if include_sum: - base_width = max(base_width, len(str(sum_base))) - new_width = max(new_width, len(str(sum_new))) - diff_width = max(diff_width, len(f"{total_diff:+}")) - pct_width = max(pct_width, len(total_pct)) - name_width = max(name_width, len("TOTAL")) - - header = ( - f"| {'file':<{name_width}} | " - f"{'base':>{base_width}} | " - f"{'new':>{new_width}} | " - f"{'diff':>{diff_width}} | " - f"{'% diff':>{pct_width}} |" - ) - separator = ( - f"| :{'-' * (name_width - 1)} | " - f"{'-' * base_width}:| " - f"{'-' * new_width}:| " - f"{'-' * diff_width}:| " - f"{'-' * pct_width}:|" + file_width = max(len("file"), *(len(r["file"]) for r in rows), len("TOTAL")) + size_width = max( + len("size"), + *(len(fmt_abs(r["base"], r["new"])) for r in rows), + len(fmt_abs(sum_base, sum_new)), ) + pct_width = max(len("% diff"), *(len(r["pct"]) for r in rows), len(total_pct)) + section_widths = {} + for name in section_names: + max_val_len = 0 + for r in rows: + sec_entry = (r.get("sections") or {}).get(name, {"base": 0, "new": 0}) + max_val_len = max(max_val_len, len(fmt_abs(sec_entry.get("base", 0), sec_entry.get("new", 0)))) + section_widths[name] = max(len(name), max_val_len, 1) + + header_parts = [f"| {'file':<{file_width}} |"] + sep_parts = [f"| :{'-' * (file_width - 1)} |"] + for name in section_names: + header_parts.append(f" {name:>{section_widths[name]}} |") + sep_parts.append(f" {'-' * (section_widths[name] - 1)}: |") + header_parts.append(f" {'size':>{size_width}} | {'% diff':>{pct_width}} |") + sep_parts.append(f" {'-' * (size_width - 1)}: | {'-' * (pct_width - 1)}: |") + header = "".join(header_parts) + separator = "".join(sep_parts) lines = [header, separator] for r in rows: - diff_str = f"{r['diff']:+}" - lines.append( - f"| {r['file']:<{name_width}} | " - f"{str(r['base']):>{base_width}} | " - f"{str(r['new']):>{new_width}} | " - f"{diff_str:>{diff_width}} | " - f"{r['pct']:>{pct_width}} |" - ) + parts = [f"| {r['file']:<{file_width}} |"] + sections_map = r.get("sections") or {} + for name in section_names: + sec_entry = sections_map.get(name, {"base": 0, "new": 0}) + parts.append(f" {fmt_abs(sec_entry.get('base', 0), sec_entry.get('new', 0)):>{section_widths[name]}} |") + parts.append(f" {fmt_abs(r['base'], r['new']):>{size_width}} | {r['pct']:>{pct_width}} |") + lines.append("".join(parts)) if include_sum: - lines.append( - f"| {'TOTAL':<{name_width}} | " - f"{sum_base:>{base_width}} | " - f"{sum_new:>{new_width}} | " - f"{total_diff:+{diff_width}d} | " - f"{total_pct:>{pct_width}} |" - ) + total_parts = [f"| {'TOTAL':<{file_width}} |"] + for name in section_names: + total_base = sum((r.get("sections") or {}).get(name, {}).get("base", 0) for r in rows) + total_new = sum((r.get("sections") or {}).get(name, {}).get("new", 0) for r in rows) + total_parts.append(f" {fmt_abs(total_base, total_new):>{section_widths[name]}} |") + total_parts.append(f" {fmt_abs(sum_base, sum_new):>{size_width}} | {total_pct:>{pct_width}} |") + lines.append("".join(total_parts)) return lines @@ -592,9 +611,10 @@ def cmd_compare(args): if not args.quiet: print_compare_summary(comparison, args.sort) - write_compare_markdown(comparison, args.out + '.md', args.sort) - if not args.quiet: - print(f"Comparison written to {args.out}.md") + if args.markdown_out: + write_compare_markdown(comparison, args.out + '.md', args.sort) + if not args.quiet: + print(f"Comparison written to {args.out}.md") def main(argv=None): @@ -602,9 +622,9 @@ def main(argv=None): subparsers = parser.add_subparsers(dest='command', required=True, help='Available commands') # Combine subcommand - combine_parser = subparsers.add_parser('combine', help='Combine and average multiple bloaty outputs') + combine_parser = subparsers.add_parser('combine', help='Combine and average bloaty CSV outputs or metrics JSON files') combine_parser.add_argument('files', nargs='+', - help='Path to bloaty CSV output or JSON file(s) or glob pattern(s)') + help='Path to bloaty CSV output or TinyUSB metrics JSON file(s) (including linkermap-generated) or glob pattern(s)') combine_parser.add_argument('-f', '--filter', dest='filters', action='append', default=[], help='Only include compile units whose path contains this substring (can be repeated)') combine_parser.add_argument('-o', '--out', dest='out', default='metrics', @@ -620,13 +640,15 @@ def main(argv=None): help='Sort order: size/size- (descending), size+ (ascending), name/name+ (ascending), name- (descending). Default: size-') # Compare subcommand - compare_parser = subparsers.add_parser('compare', help='Compare two bloaty outputs (CSV) or JSON inputs') - compare_parser.add_argument('base', help='Base CSV/JSON file') - compare_parser.add_argument('new', help='New CSV/JSON file') + compare_parser = subparsers.add_parser('compare', help='Compare two metrics inputs (bloaty CSV or metrics JSON)') + compare_parser.add_argument('base', help='Base CSV/metrics JSON file') + compare_parser.add_argument('new', help='New CSV/metrics JSON file') compare_parser.add_argument('-f', '--filter', dest='filters', action='append', default=[], help='Only include compile units whose path contains this substring (can be repeated)') compare_parser.add_argument('-o', '--out', dest='out', default='metrics_compare', - help='Output path basename for Markdown file (default: metrics_compare)') + help='Output path basename for Markdown/JSON files (default: metrics_compare)') + compare_parser.add_argument('-m', '--markdown', dest='markdown_out', action='store_true', + help='Write Markdown output file') compare_parser.add_argument('-S', '--sort', dest='sort', default='name+', choices=['size', 'size-', 'size+', 'name', 'name-', 'name+'], help='Sort order: size/size- (descending), size+ (ascending), name/name+ (ascending), name- (descending). Default: name+') -- cgit v1.3.1 From c7f7dc6ee1f4f56ccb86adabb2ca3f14c212e985 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Dec 2025 19:01:33 +0700 Subject: separate metric comment into its own workflow in order to work with forked PR --- .github/workflows/build.yml | 16 ++++++++++----- .github/workflows/metrics_comment.yml | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/metrics_comment.yml (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9d94a3b9b..ea7f5d74b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -130,12 +130,18 @@ jobs: cp metrics.md metrics_compare.md fi - - name: Post Code Metrics as PR Comment - if: github.event_name != 'push' - uses: marocchino/sticky-pull-request-comment@v2 + - name: Save PR number + if: github.event_name == 'pull_request' + run: echo ${{ github.event.number }} > pr_number.txt + + - name: Upload Metrics Comment Artifact + if: github.event_name == 'pull_request' + uses: actions/upload-artifact@v5 with: - header: code-metrics - path: metrics_compare.md + name: metrics-comment + path: | + metrics_compare.md + pr_number.txt # --------------------------------------- # Build Make/CMake on Windows/MacOS diff --git a/.github/workflows/metrics_comment.yml b/.github/workflows/metrics_comment.yml new file mode 100644 index 000000000..2f1b0d631 --- /dev/null +++ b/.github/workflows/metrics_comment.yml @@ -0,0 +1,38 @@ +name: Metrics Comment + +on: + workflow_run: + workflows: ["Build"] + types: + - completed + +jobs: + post-comment: + runs-on: ubuntu-latest + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + permissions: + pull-requests: write + steps: + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + name: metrics-comment + + - name: Read PR Number + id: pr_number + run: | + if [ -f pr_number.txt ]; then + echo "number=$(cat pr_number.txt)" >> $GITHUB_OUTPUT + fi + + - name: Post Code Metrics as PR Comment + if: steps.pr_number.outputs.number != '' + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: code-metrics + path: metrics_compare.md + number: ${{ steps.pr_number.outputs.number }} -- cgit v1.3.1 From d71e3c9ea61b1d2ab8e60daeb299abfdf828541e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Dec 2025 00:58:17 +0700 Subject: post pr comment anyway --- .github/workflows/build.yml | 7 +++++++ 1 file changed, 7 insertions(+) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ea7f5d74b..c062aca46 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -143,6 +143,13 @@ jobs: metrics_compare.md pr_number.txt + - name: Post Code Metrics as PR Comment + if: github.event_name != 'push' + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: code-metrics + path: metrics_compare.md + # --------------------------------------- # Build Make/CMake on Windows/MacOS # --------------------------------------- -- cgit v1.3.1 From 20b03bbc081353295f7a491038bd3efbc9c3a75a Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Sat, 13 Dec 2025 15:13:02 +0700 Subject: upload metrics.json and metrics compare to release page (#3409) * upload metrics.json and metrics compare to release page * Adjust workflow comment handling for forks --- .github/workflows/build.yml | 43 ++++++++++++++++++++++++++++------- .github/workflows/build_util.yml | 2 +- .github/workflows/metrics_comment.yml | 1 + .github/workflows/pre-commit.yml | 2 +- .github/workflows/static_analysis.yml | 8 +++---- .github/workflows/trigger.yml | 2 +- tools/metrics.py | 24 +++++++------------ 7 files changed, 51 insertions(+), 31 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c062aca46..781d3b002 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,6 +27,8 @@ on: - '.github/workflows/build.yml' - '.github/workflows/build_util.yml' - '.github/workflows/ci_set_matrix.py' + release: + types: [ published ] concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -42,7 +44,7 @@ jobs: hil_json: ${{ steps.set-matrix-json.outputs.hil_matrix }} steps: - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Generate matrix json id: set-matrix-json @@ -86,9 +88,12 @@ jobs: runs-on: ubuntu-latest permissions: pull-requests: write + contents: write steps: - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 + with: + fetch-tags: ${{ github.event_name == 'release' }} - name: Download Artifacts uses: actions/download-artifact@v5 @@ -103,14 +108,14 @@ jobs: python tools/metrics.py combine -j -m -f tinyusb/src cmake-build/*/metrics.json - name: Upload Metrics Artifact - if: github.event_name == 'push' + if: github.event_name == 'push' || github.event_name == 'release' uses: actions/upload-artifact@v5 with: name: metrics-tinyusb path: metrics.json - name: Download Base Branch Metrics - if: github.event_name != 'push' + if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' uses: dawidd6/action-download-artifact@v11 with: workflow: build.yml @@ -119,6 +124,18 @@ jobs: path: base-metrics continue-on-error: true + - name: Download Previous Release Asset + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + run: | + PREV_TAG=$(git tag --sort=-creatordate | head -n 2 | tail -n 1) + echo "Previous Release: $PREV_TAG" + echo "PREV_TAG=$PREV_TAG" >> $GITHUB_ENV + + mkdir -p base-metrics + gh release download $PREV_TAG -p metrics.json -D base-metrics || echo "No metrics.json found in $PREV_TAG release" + - name: Compare with Base Branch if: github.event_name != 'push' run: | @@ -130,6 +147,16 @@ jobs: cp metrics.md metrics_compare.md fi + - name: Upload Release Assets + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + run: | + CURR_TAG=${{ github.event.release.tag_name }} + COMPARE_FILE="metrics_compare_${CURR_TAG}-${PREV_TAG}.md" + mv metrics_compare.md $COMPARE_FILE + gh release upload $CURR_TAG metrics.json $COMPARE_FILE + - name: Save PR number if: github.event_name == 'pull_request' run: echo ${{ github.event.number }} > pr_number.txt @@ -144,7 +171,7 @@ jobs: pr_number.txt - name: Post Code Metrics as PR Comment - if: github.event_name != 'push' + if: (github.event_name == 'workflow_dispatch') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) uses: marocchino/sticky-pull-request-comment@v2 with: header: code-metrics @@ -175,7 +202,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Zephyr project uses: zephyrproject-rtos/action-zephyr-setup@v1 @@ -237,7 +264,7 @@ jobs: mkdir -p "${{ github.workspace }}" - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download Artifacts uses: actions/download-artifact@v5 @@ -275,7 +302,7 @@ jobs: iccarm --version - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Get build boards run: | diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 1cbd02f1b..540ee8b47 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -38,7 +38,7 @@ jobs: arg: ${{ fromJSON(inputs.build-args) }} steps: - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Toolchain id: setup-toolchain diff --git a/.github/workflows/metrics_comment.yml b/.github/workflows/metrics_comment.yml index 2f1b0d631..7443f7367 100644 --- a/.github/workflows/metrics_comment.yml +++ b/.github/workflows/metrics_comment.yml @@ -13,6 +13,7 @@ jobs: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' permissions: + actions: read pull-requests: write steps: - name: Download Artifacts diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index ed0efd66e..b9bfaf9b6 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -20,7 +20,7 @@ jobs: ruby-version: '3.0' - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Get Dependencies run: | diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 4db267517..a78682d7a 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -37,7 +37,7 @@ jobs: - 'metro_m4_express' steps: - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Get Dependencies uses: ./.github/actions/get_deps @@ -100,7 +100,7 @@ jobs: - 'raspberry_pi_pico' steps: - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Get Dependencies uses: ./.github/actions/get_deps @@ -154,7 +154,7 @@ jobs: - 'stm32h743eval' steps: - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis @@ -197,7 +197,7 @@ jobs: - 'b_g474e_dpow1' steps: - name: Checkout TinyUSB - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Get Dependencies uses: ./.github/actions/get_deps diff --git a/.github/workflows/trigger.yml b/.github/workflows/trigger.yml index cf40ac955..fd7c0b713 100644 --- a/.github/workflows/trigger.yml +++ b/.github/workflows/trigger.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Push to tinyusb_src run: | diff --git a/tools/metrics.py b/tools/metrics.py index 50709d5ba..6b992c8f5 100644 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -74,7 +74,6 @@ def parse_bloaty_csv(csv_text, filters=None): "file": os.path.basename(unit_path) or unit_path, "path": unit_path, "size": total_size, - "total": total_size, "symbols": symbols, "sections": sections, } @@ -146,7 +145,7 @@ def compute_avg(all_json_data): return None # Merge files with the same 'file' value and compute averages - file_accumulator = {} # key: file name, value: {"sizes": [sizes], "totals": [totals], "symbols": {name: [sizes]}, "sections": {name: [sizes]}} + file_accumulator = {} # key: file name, value: {"sizes": [sizes], "symbols": {name: [sizes]}, "sections": {name: [sizes]}} for json_data in all_json_data["data"]: for f in json_data.get("files", []): @@ -154,14 +153,12 @@ def compute_avg(all_json_data): if fname not in file_accumulator: file_accumulator[fname] = { "sizes": [], - "totals": [], "path": f.get("path"), "symbols": defaultdict(list), "sections": defaultdict(list), } - size_val = f.get("size", f.get("total", 0)) + size_val = f.get("size", 0) file_accumulator[fname]["sizes"].append(size_val) - file_accumulator[fname]["totals"].append(f.get("total", size_val)) for sym in f.get("symbols", []): name = sym.get("name") if name is None: @@ -196,9 +193,7 @@ def compute_avg(all_json_data): } ) - totals_list = [d.get("TOTAL") for d in all_json_data["data"] if isinstance(d.get("TOTAL"), (int, float))] - total_size = round(sum(totals_list) / len(totals_list)) if totals_list else ( - sum(f["size"] for f in files_average) or 1) + total_size = sum(f["size"] for f in files_average) or 1 for f in files_average: f["percent"] = (f["size"] / total_size) * 100 if total_size else 0 @@ -207,7 +202,6 @@ def compute_avg(all_json_data): json_average = { "file_list": all_json_data["file_list"], - "TOTAL": total_size, "files": files_average, } @@ -262,10 +256,12 @@ def compare_files(base_file, new_file, filters=None): }, }) + base_total = sum(f["size"] for f in base_avg["files"]) + new_total = sum(f["size"] for f in new_avg["files"]) total = { - "base": base_avg.get("TOTAL", 0), - "new": new_avg.get("TOTAL", 0), - "diff": new_avg.get("TOTAL", 0) - base_avg.get("TOTAL", 0), + "base": base_total, + "new": new_total, + "diff": new_total - base_total, } return { @@ -287,10 +283,6 @@ def get_sort_key(sort_order): """ def _size_val(entry): - if isinstance(entry.get('total'), int): - return entry.get('total', 0) - if isinstance(entry.get('total'), dict): - return entry['total'].get('new', 0) return entry.get('size', 0) if sort_order == 'size-': -- cgit v1.3.1 From e00c3d1726950fda4833c265d4df0ad9b1b97c00 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Dec 2025 16:23:55 +0700 Subject: enable ci build for hpmicro --- .github/workflows/ci_set_matrix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 933a8375f..994773f69 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -17,7 +17,7 @@ toolchain_list = [ family_list = { "at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437 broadcom_32bit da1469x": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], - "ch32v10x ch32v20x ch32v30x fomu gd32vf103": ["riscv-gcc"], + "ch32v10x ch32v20x ch32v30x fomu gd32vf103 hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], "lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], -- cgit v1.3.1 From d768735e0cacbd370bf1b8cc023caaef600b7ddc Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Tue, 16 Dec 2025 12:16:55 +0100 Subject: update ci Signed-off-by: Zixun LI --- .github/workflows/ci_set_matrix.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 933a8375f..dfe7e7780 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -21,8 +21,8 @@ family_list = { "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], "lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], - "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], - "maxim mcx mm32 msp432e4 tm4c": ["arm-gcc"], + "lpc51 lpc54 lpc55 mcx rw61x": ["arm-gcc", "arm-clang"], + "maxim mm32 msp432e4 tm4c": ["arm-gcc"], "msp430": ["msp430-gcc"], "nrf": ["arm-gcc", "arm-clang"], "nuc100_120 nuc121_125 nuc126 nuc505 xmc4000": ["arm-gcc"], -- cgit v1.3.1 From ce7b15d6f94b1f8efe917f40eb61b8c3a703d0f8 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 16 Dec 2025 21:11:13 +0100 Subject: more fixes Signed-off-by: HiFiPhile --- .github/workflows/ci_set_matrix.py | 4 ++-- README.rst | 4 ++-- hw/bsp/rw61x/family.cmake | 1 - hw/bsp/stm32h5/family.mk | 1 + 4 files changed, 5 insertions(+), 5 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index b682da1a2..c276d5253 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -21,8 +21,8 @@ family_list = { "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], "lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], - "lpc51 lpc54 lpc55 mcx rw61x": ["arm-gcc", "arm-clang"], - "maxim mm32 msp432e4 tm4c": ["arm-gcc"], + "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], + "maxim mcx mm32 msp432e4 rw61x tm4c": ["arm-gcc"], "msp430": ["msp430-gcc"], "nrf": ["arm-gcc", "arm-clang"], "nuc100_120 nuc121_125 nuc126 nuc505 xmc4000": ["arm-gcc"], diff --git a/README.rst b/README.rst index 58a9e393e..178a084ce 100644 --- a/README.rst +++ b/README.rst @@ -209,8 +209,8 @@ Supported CPUs | | +-------------------+--------+------+-----------+------------------------+--------------------+ | | | A15 | ✔ | | | ci_fs | | | +---------+-------------------+--------+------+-----------+------------------------+--------------------+ -| | RW61x | ✔ | ✔ | ✔ | ci_hs, ehci | | -+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | RW61x | ✔ | ✔ | ✔ | ci_hs, ehci | | ++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | | +--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ | Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | | diff --git a/hw/bsp/rw61x/family.cmake b/hw/bsp/rw61x/family.cmake index 8c332f96e..6782e87e3 100644 --- a/hw/bsp/rw61x/family.cmake +++ b/hw/bsp/rw61x/family.cmake @@ -82,7 +82,6 @@ function(family_configure_example TARGET RTOS) target_link_options(${TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" --specs=nosys.specs --specs=nano.specs - -nostartfiles ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${TARGET} PUBLIC diff --git a/hw/bsp/stm32h5/family.mk b/hw/bsp/stm32h5/family.mk index 89a2eddd5..e34bb513e 100644 --- a/hw/bsp/stm32h5/family.mk +++ b/hw/bsp/stm32h5/family.mk @@ -49,6 +49,7 @@ SRC_C += \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_i2c.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c INC += \ -- cgit v1.3.1 From e69494d94a680c7b5aa5310338c206921d57640b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 9 Jan 2026 10:47:50 +0700 Subject: fix pre-commit, clean up tusb_mcu.h, add at32f45x to ci build --- .github/workflows/ci_set_matrix.py | 3 ++- hw/bsp/at32f45x/at32f45x_clock.c | 2 +- hw/bsp/at32f45x/at32f45x_clock.h | 1 - hw/bsp/at32f45x/at32f45x_int.c | 1 - hw/bsp/at32f45x/at32f45x_int.h | 1 - src/common/tusb_mcu.h | 22 +--------------------- 6 files changed, 4 insertions(+), 26 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index c276d5253..237a34b9f 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -15,7 +15,8 @@ toolchain_list = [ # family: [supported toolchain] family_list = { - "at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437 broadcom_32bit da1469x": ["arm-gcc"], + "at32f45x at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437 broadcom_32bit da1469x": [ + "arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], "ch32v10x ch32v20x ch32v30x fomu gd32vf103 hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], diff --git a/hw/bsp/at32f45x/at32f45x_clock.c b/hw/bsp/at32f45x/at32f45x_clock.c index 12003cf5a..a6724e23f 100644 --- a/hw/bsp/at32f45x/at32f45x_clock.c +++ b/hw/bsp/at32f45x/at32f45x_clock.c @@ -55,7 +55,7 @@ void system_clock_config(void) /* enable pwc periph clock */ crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); - + /* config ldo voltage */ pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V3); diff --git a/hw/bsp/at32f45x/at32f45x_clock.h b/hw/bsp/at32f45x/at32f45x_clock.h index 1fd2035aa..a372a605b 100644 --- a/hw/bsp/at32f45x/at32f45x_clock.h +++ b/hw/bsp/at32f45x/at32f45x_clock.h @@ -42,4 +42,3 @@ void system_clock_config(void); #endif #endif - diff --git a/hw/bsp/at32f45x/at32f45x_int.c b/hw/bsp/at32f45x/at32f45x_int.c index 15798e381..15ff90c64 100644 --- a/hw/bsp/at32f45x/at32f45x_int.c +++ b/hw/bsp/at32f45x/at32f45x_int.c @@ -98,4 +98,3 @@ void DebugMon_Handler(void) /** * @} */ - diff --git a/hw/bsp/at32f45x/at32f45x_int.h b/hw/bsp/at32f45x/at32f45x_int.h index 64930f29e..3a2667e9d 100644 --- a/hw/bsp/at32f45x/at32f45x_int.h +++ b/hw/bsp/at32f45x/at32f45x_int.h @@ -57,4 +57,3 @@ void OTGFS1_WKUP_IRQHandler(void); #endif #endif - diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index cbdcd2dfc..5b9497b9a 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -635,17 +635,7 @@ #define TUP_USBIP_DWC2_AT32 #define TUP_DCD_ENDPOINT_MAX 4 -#elif TU_CHECK_MCU(OPT_MCU_AT32F435_437) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 - -#elif TU_CHECK_MCU(OPT_MCU_AT32F423) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 - -#elif TU_CHECK_MCU(OPT_MCU_AT32F402_405) +#elif TU_CHECK_MCU(OPT_MCU_AT32F402_405, OPT_MCU_AT32F423, OPT_MCU_AT32F425, OPT_MCU_AT32F435_437, OPT_MCU_AT32F45X) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_AT32 #define TUP_DCD_ENDPOINT_MAX 8 @@ -657,16 +647,6 @@ #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS #endif -#elif TU_CHECK_MCU(OPT_MCU_AT32F425) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 - -#elif TU_CHECK_MCU(OPT_MCU_AT32F45X) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 - //--------------------------------------------------------------------+ // HPMicro //--------------------------------------------------------------------+ -- cgit v1.3.1 From 0d28bdc27f90ab5e77576e5e28f55349b36abd24 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Jan 2026 16:33:14 +0700 Subject: minor clean up separate tud_mtp_data_send() and tud_mtp_data_receive() --- .github/workflows/ci_set_matrix.py | 3 ++- test/hil/hil_test.py | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 237a34b9f..9ab08601d 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -38,7 +38,8 @@ family_list = { "stm32h7": ["arm-gcc", "arm-clang", "arm-iar"], "stm32h7rs stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32n6": ["arm-gcc"], - "stm32u0 stm32u5 stm32wb stm32wba": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32u0 stm32wb stm32wba": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32u5": ["arm-gcc", "arm-clang", "arm-iar"], "-bespressif_s2_devkitc": ["esp-idf"], # S3, P4 will be built by hil test # "-bespressif_s3_devkitm": ["esp-idf"], diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index dfea9612f..f742bbca2 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -617,13 +617,13 @@ def test_device_mtp(board): # device tests # note don't test 2 examples with cdc or 2 msc next to each other device_tests = [ - # 'device/cdc_dual_ports', - # 'device/dfu', - # 'device/cdc_msc', - # 'device/dfu_runtime', - # 'device/cdc_msc_freertos', - # 'device/hid_boot_interface', - 'device/mtp' + 'device/cdc_dual_ports', + 'device/dfu', + 'device/cdc_msc', + 'device/dfu_runtime', + 'device/cdc_msc_freertos', + 'device/hid_boot_interface', + # 'device/mtp' ] dual_tests = [ -- cgit v1.3.1 From 9a731e03e89e5e9ba530354fdfe4829b4cc0a8cf Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Jan 2026 13:06:49 +0700 Subject: correct dual port hil assert --- .github/workflows/build.yml | 2 +- test/hil/hil_test.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 781d3b002..bb8c6d65d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -315,7 +315,7 @@ jobs: run: python3 tools/get_deps.py $BUILD_ARGS - name: Build - run: python3 tools/build.py -j 4 --toolchain iar $BUILD_ARGS + run: python3 tools/build.py --toolchain iar $BUILD_ARGS - name: Test on actual hardware (hardware in the loop) run: python3 test/hil/hil_test.py hfp.json diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index f742bbca2..b84740867 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -410,22 +410,22 @@ def test_device_cdc_dual_ports(board): sizes = [32, 64, 128, 256, 512, random.randint(2000, 5000)] def write_and_check(writer, payload): - size = len(payload) + payload_len = len(payload) for s in ser: s.reset_input_buffer() rd0 = b'' rd1 = b'' offset = 0 # Write in chunks of random 1-64 bytes (device has 64-byte buffer) - while offset < size: - chunk_size = min(random.randint(1, 64), size - offset) + while offset < payload_len: + chunk_size = min(random.randint(1, 64), payload_len - offset) ser[writer].write(payload[offset:offset + chunk_size]) ser[writer].flush() rd0 += ser[0].read(chunk_size) rd1 += ser[1].read(chunk_size) offset += chunk_size - assert rd0 == payload.lower(), f'Port0 wrong data ({size}): expected {payload.lower()[:16]}... was {rd0[:16]}' - assert rd1 == payload.upper(), f'Port1 wrong data ({size}): expected {payload.upper()[:16]}... was {rd1[:16]}' + assert rd0 == payload.lower(), f'Port0 wrong data ({payload_len}): expected {payload.lower()}... was {rd0}' + assert rd1 == payload.upper(), f'Port1 wrong data ({payload_len}): expected {payload.upper()}... was {rd1}' for size in sizes: payload0 = rand_ascii(size) -- cgit v1.3.1 From 5ad42064ea544080d47c893dafb1b41447ab9f32 Mon Sep 17 00:00:00 2001 From: Michael Rogov Papernov Date: Sat, 10 Jan 2026 17:58:41 +0000 Subject: Integrate MemBrowse --- .github/membrowse-targets.json | 662 ++++++++++++++++++++++++++++++++ .github/workflows/build.yml | 137 +++++-- .github/workflows/build_util.yml | 14 + .github/workflows/membrowse-comment.yml | 44 +++ .github/workflows/membrowse-onboard.yml | 58 +++ .github/workflows/membrowse-report.yml | 101 +++++ README.rst | 4 +- 7 files changed, 989 insertions(+), 31 deletions(-) create mode 100644 .github/membrowse-targets.json create mode 100644 .github/workflows/membrowse-comment.yml create mode 100644 .github/workflows/membrowse-onboard.yml create mode 100644 .github/workflows/membrowse-report.yml (limited to '.github/workflows') diff --git a/.github/membrowse-targets.json b/.github/membrowse-targets.json new file mode 100644 index 000000000..80dd158a8 --- /dev/null +++ b/.github/membrowse-targets.json @@ -0,0 +1,662 @@ +[ + { + "target_name": "at32f402_405-at_start_f402", + "port": "at32f402_405", + "board": "at_start_f402", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f402_405", + "build_cmd": "python3 tools/build.py -s cmake -b at_start_f402", + "elf": "cmake-build/cmake-build-at_start_f402/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/artery/at32f402_405/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F402xC_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "at32f403a_407-at32f403a_weact_blackpill", + "port": "at32f403a_407", + "board": "at32f403a_weact_blackpill", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f403a_407", + "build_cmd": "python3 tools/build.py -s cmake -b at32f403a_weact_blackpill", + "elf": "cmake-build/cmake-build-at32f403a_weact_blackpill/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/artery/at32f403a_407/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F403AxC_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "at32f413-at_start_f413", + "port": "at32f413", + "board": "at_start_f413", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f413", + "build_cmd": "python3 tools/build.py -s cmake -b at_start_f413", + "elf": "cmake-build/cmake-build-at_start_f413/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/artery/at32f413/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F413xC_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "at32f415-at_start_f415", + "port": "at32f415", + "board": "at_start_f415", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f415", + "build_cmd": "python3 tools/build.py -s cmake -b at_start_f415", + "elf": "cmake-build/cmake-build-at_start_f415/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/artery/at32f415/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F415xC_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "at32f423-at_start_f423", + "port": "at32f423", + "board": "at_start_f423", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f423", + "build_cmd": "python3 tools/build.py -s cmake -b at_start_f423", + "elf": "cmake-build/cmake-build-at_start_f423/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/artery/at32f423/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F423xC_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "at32f425-at_start_f425", + "port": "at32f425", + "board": "at_start_f425", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f425", + "build_cmd": "python3 tools/build.py -s cmake -b at_start_f425", + "elf": "cmake-build/cmake-build-at_start_f425/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/artery/at32f425/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x8_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "at32f435_437-at_start_f435", + "port": "at32f435_437", + "board": "at_start_f435", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f435_437", + "build_cmd": "python3 tools/build.py -s cmake -b at_start_f435", + "elf": "cmake-build/cmake-build-at_start_f435/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/artery/at32f435_437/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F435xM_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "broadcom_32bit-raspberrypi_zero", + "port": "broadcom_32bit", + "board": "raspberrypi_zero", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py broadcom_32bit", + "build_cmd": "python3 tools/build.py -s cmake -b raspberrypi_zero", + "elf": "cmake-build/cmake-build-raspberrypi_zero/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/broadcom/broadcom/link.ld", + "linker_vars": "" + }, + { + "target_name": "broadcom_64bit-raspberrypi_cm4", + "port": "broadcom_64bit", + "board": "raspberrypi_cm4", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.xz && tar -C $HOME/toolchain -xf toolchain.tar.xz && echo \"$HOME/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py broadcom_64bit", + "build_cmd": "python3 tools/build.py -s cmake -b raspberrypi_cm4", + "elf": "cmake-build/cmake-build-raspberrypi_cm4/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/broadcom/broadcom/link8.ld", + "linker_vars": "" + }, + { + "target_name": "ch32v10x-ch32v103r_r1_1v0", + "port": "ch32v10x", + "board": "ch32v103r_r1_1v0", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py ch32v10x", + "build_cmd": "python3 tools/build.py -s cmake -b ch32v103r_r1_1v0", + "elf": "cmake-build/cmake-build-ch32v103r_r1_1v0/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/ch32v10x/linker/ch32v10x.ld", + "linker_vars": "__FLASH_SIZE=64K __RAM_SIZE=20K" + }, + { + "target_name": "ch32v20x-ch32v203c_r0_1v0", + "port": "ch32v20x", + "board": "ch32v203c_r0_1v0", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py ch32v20x", + "build_cmd": "python3 tools/build.py -s cmake -b ch32v203c_r0_1v0", + "elf": "cmake-build/cmake-build-ch32v203c_r0_1v0/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/ch32v20x/linker/ch32v20x.ld", + "linker_vars": "__flash_size=64K __ram_size=20K" + }, + { + "target_name": "ch32v30x-ch32v307v_r1_1v0", + "port": "ch32v30x", + "board": "ch32v307v_r1_1v0", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py ch32v30x", + "build_cmd": "python3 tools/build.py -s cmake -b ch32v307v_r1_1v0", + "elf": "cmake-build/cmake-build-ch32v307v_r1_1v0/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/ch32v30x/linker/ch32v30x.ld", + "linker_vars": "__flash_size=128K __ram_size=32K" + }, + { + "target_name": "da1469x-da14695_dk_usb", + "port": "da1469x", + "board": "da14695_dk_usb", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py da1469x", + "build_cmd": "python3 tools/build.py -s cmake -b da14695_dk_usb", + "elf": "cmake-build/cmake-build-da14695_dk_usb/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/da1469x/linker/da1469x.ld", + "linker_vars": "" + }, + { + "target_name": "fomu-fomu", + "port": "fomu", + "board": "fomu", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py fomu", + "build_cmd": "python3 tools/build.py -s cmake -b fomu", + "elf": "cmake-build/cmake-build-fomu/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/fomu/fomu.ld", + "linker_vars": "" + }, + { + "target_name": "gd32vf103-sipeed_longan_nano", + "port": "gd32vf103", + "board": "sipeed_longan_nano", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py gd32vf103", + "build_cmd": "python3 tools/build.py -s cmake -b sipeed_longan_nano", + "elf": "cmake-build/cmake-build-sipeed_longan_nano/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/gd/nuclei-sdk/SoC/gd32vf103/Board/gd32vf103c_longan_nano/Source/GCC/gcc_gd32vf103xb_flashxip.ld", + "linker_vars": "__ROM_BASE=0x08000000 __ROM_SIZE=0x00020000 __RAM_BASE=0x20000000 __RAM_SIZE=0x00008000" + }, + { + "target_name": "hpmicro-hpm6750evk2", + "port": "hpmicro", + "board": "hpm6750evk2", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py hpmicro", + "build_cmd": "python3 tools/build.py -s cmake -b hpm6750evk2", + "elf": "cmake-build/cmake-build-hpm6750evk2/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/hpmicro/hpm_sdk/soc/HPM6700/HPM6750/toolchains/gcc/flash_xip.ld", + "linker_vars": "_flash_size=16M _stack_size=16K _heap_size=16K" + }, + { + "target_name": "imxrt-metro_m7_1011", + "port": "imxrt", + "board": "metro_m7_1011", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py imxrt", + "build_cmd": "python3 tools/build.py -s cmake -b metro_m7_1011", + "elf": "cmake-build/cmake-build-metro_m7_1011/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/nxp/mcux-sdk/devices/MIMXRT1011/gcc/MIMXRT1011xxxxx_flexspi_nor.ld", + "linker_vars": "" + }, + { + "target_name": "kinetis_k-frdm_k64f", + "port": "kinetis_k", + "board": "frdm_k64f", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py kinetis_k kinetis_kl", + "build_cmd": "python3 tools/build.py -s cmake -b frdm_k64f", + "elf": "cmake-build/cmake-build-frdm_k64f/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/nxp/mcux-sdk/devices/MK64F12/gcc/MK64FN1M0xxx12_flash.ld", + "linker_vars": "" + }, + { + "target_name": "kinetis_k32l2-frdm_k32l2a4s", + "port": "kinetis_k32l2", + "board": "frdm_k32l2a4s", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py kinetis_k32l2", + "build_cmd": "python3 tools/build.py -s cmake -b frdm_k32l2a4s", + "elf": "cmake-build/cmake-build-frdm_k32l2a4s/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/nxp/mcux-sdk/devices/K32L2A41A/gcc/K32L2A41xxxxA_flash.ld", + "linker_vars": "" + }, + { + "target_name": "kinetis_kl-frdm_kl25z", + "port": "kinetis_kl", + "board": "frdm_kl25z", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py kinetis_kl", + "build_cmd": "python3 tools/build.py -s cmake -b frdm_kl25z", + "elf": "cmake-build/cmake-build-frdm_kl25z/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/kinetis_kl/gcc/MKL25Z128xxx4_flash.ld", + "linker_vars": "" + }, + { + "target_name": "lpc11-lpcxpresso11u37", + "port": "lpc11", + "board": "lpcxpresso11u37", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc11", + "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso11u37", + "elf": "cmake-build/cmake-build-lpcxpresso11u37/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/lpc11/boards/lpcxpresso11u37/lpc11u37.ld", + "linker_vars": "" + }, + { + "target_name": "lpc13-lpcxpresso1347", + "port": "lpc13", + "board": "lpcxpresso1347", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc13", + "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso1347", + "elf": "cmake-build/cmake-build-lpcxpresso1347/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/lpc13/boards/lpcxpresso1347/lpc1347.ld", + "linker_vars": "" + }, + { + "target_name": "lpc15-lpcxpresso1549", + "port": "lpc15", + "board": "lpcxpresso1549", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc15", + "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso1549", + "elf": "cmake-build/cmake-build-lpcxpresso1549/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/lpc15/boards/lpcxpresso1549/lpc1549.ld", + "linker_vars": "" + }, + { + "target_name": "lpc17-lpcxpresso1769", + "port": "lpc17", + "board": "lpcxpresso1769", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc17", + "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso1769", + "elf": "cmake-build/cmake-build-lpcxpresso1769/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld", + "linker_vars": "" + }, + { + "target_name": "lpc18-lpcxpresso18s37", + "port": "lpc18", + "board": "lpcxpresso18s37", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc18", + "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso18s37", + "elf": "cmake-build/cmake-build-lpcxpresso18s37/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld", + "linker_vars": "" + }, + { + "target_name": "lpc40-ea4088_quickstart", + "port": "lpc40", + "board": "ea4088_quickstart", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc40", + "build_cmd": "python3 tools/build.py -s cmake -b ea4088_quickstart", + "elf": "cmake-build/cmake-build-ea4088_quickstart/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld", + "linker_vars": "" + }, + { + "target_name": "lpc43-ea4357", + "port": "lpc43", + "board": "ea4357", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc43", + "build_cmd": "python3 tools/build.py -s cmake -b ea4357", + "elf": "cmake-build/cmake-build-ea4357/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/lpc43/boards/ea4357/lpc4357.ld", + "linker_vars": "" + }, + { + "target_name": "lpc51-lpcxpresso51u68", + "port": "lpc51", + "board": "lpcxpresso51u68", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc51", + "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso51u68", + "elf": "cmake-build/cmake-build-lpcxpresso51u68/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC51U68/gcc/LPC51U68_flash.ld", + "linker_vars": "" + }, + { + "target_name": "lpc54-lpcxpresso54114", + "port": "lpc54", + "board": "lpcxpresso54114", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc54", + "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso54114", + "elf": "cmake-build/cmake-build-lpcxpresso54114/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC54114/gcc/LPC54114J256_cm4_flash.ld", + "linker_vars": "" + }, + { + "target_name": "lpc55-double_m33_express", + "port": "lpc55", + "board": "double_m33_express", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc55", + "build_cmd": "python3 tools/build.py -s cmake -b double_m33_express", + "elf": "cmake-build/cmake-build-double_m33_express/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/lpc55/boards/double_m33_express/LPC55S69_cm33_core0_uf2.ld", + "linker_vars": "" + }, + { + "target_name": "maxim-apard32690", + "port": "maxim", + "board": "apard32690", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py maxim", + "build_cmd": "python3 tools/build.py -s cmake -b apard32690", + "elf": "cmake-build/cmake-build-apard32690/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/maxim/linker/max32690.ld", + "linker_vars": "" + }, + { + "target_name": "mcx-frdm_mcxa153", + "port": "mcx", + "board": "frdm_mcxa153", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py mcx", + "build_cmd": "python3 tools/build.py -s cmake -b frdm_mcxa153", + "elf": "cmake-build/cmake-build-frdm_mcxa153/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/nxp/mcux-sdk/devices/MCXA153/gcc/MCXA153_flash.ld", + "linker_vars": "" + }, + { + "target_name": "mm32-mm32f327x_mb39", + "port": "mm32", + "board": "mm32f327x_mb39", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py mm32", + "build_cmd": "python3 tools/build.py -s cmake -b mm32f327x_mb39", + "elf": "cmake-build/cmake-build-mm32f327x_mb39/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld", + "linker_vars": "" + }, + { + "target_name": "msp430-msp_exp430f5529lp", + "port": "msp430", + "board": "msp_exp430f5529lp", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2 && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.bz2 && tar -C $HOME/toolchain -xf toolchain.tar.bz2 && echo \"$HOME/toolchain/msp430-gcc-9.2.0.50_linux64/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py msp430", + "build_cmd": "python3 tools/build.py -s cmake -b msp_exp430f5529lp", + "elf": "cmake-build/cmake-build-msp_exp430f5529lp/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/ti/msp430/msp430-gcc-support-files/include/msp430f5529.ld", + "linker_vars": "" + }, + { + "target_name": "msp432e4-msp_exp432e401y", + "port": "msp432e4", + "board": "msp_exp432e401y", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py msp432e4", + "build_cmd": "python3 tools/build.py -s cmake -b msp_exp432e401y", + "elf": "cmake-build/cmake-build-msp_exp432e401y/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/ti/msp432e4/Source/msp432e411y.ld", + "linker_vars": "" + }, + { + "target_name": "nrf-adafruit_clue", + "port": "nrf", + "board": "adafruit_clue", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nrf", + "build_cmd": "python3 tools/build.py -s cmake -b adafruit_clue", + "elf": "cmake-build/cmake-build-adafruit_clue/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/nrf/linker/nrf52840_xxaa.ld", + "linker_vars": "" + }, + { + "target_name": "nuc100_120-nutiny_sdk_nuc120", + "port": "nuc100_120", + "board": "nutiny_sdk_nuc120", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nuc100_120", + "build_cmd": "python3 tools/build.py -s cmake -b nutiny_sdk_nuc120", + "elf": "cmake-build/cmake-build-nutiny_sdk_nuc120/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/nuc100_120/boards/nutiny_sdk_nuc120/nuc120_flash.ld", + "linker_vars": "" + }, + { + "target_name": "nuc121_125-nutiny_sdk_nuc121", + "port": "nuc121_125", + "board": "nutiny_sdk_nuc121", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nuc121_125", + "build_cmd": "python3 tools/build.py -s cmake -b nutiny_sdk_nuc121", + "elf": "cmake-build/cmake-build-nutiny_sdk_nuc121/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/nuc121_125/boards/nutiny_sdk_nuc121/nuc121_flash.ld", + "linker_vars": "" + }, + { + "target_name": "nuc126-nutiny_nuc126v", + "port": "nuc126", + "board": "nutiny_nuc126v", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nuc126", + "build_cmd": "python3 tools/build.py -s cmake -b nutiny_nuc126v", + "elf": "cmake-build/cmake-build-nutiny_nuc126v/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/nuc126/boards/nutiny_nuc126v/nuc126_flash.ld", + "linker_vars": "" + }, + { + "target_name": "nuc505-nutiny_sdk_nuc505", + "port": "nuc505", + "board": "nutiny_sdk_nuc505", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nuc505", + "build_cmd": "python3 tools/build.py -s cmake -b nutiny_sdk_nuc505", + "elf": "cmake-build/cmake-build-nutiny_sdk_nuc505/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/nuc505/boards/nutiny_sdk_nuc505/nuc505_flashtoram.ld", + "linker_vars": "" + }, + { + "target_name": "ra-portenta_c33", + "port": "ra", + "board": "portenta_c33", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py ra", + "build_cmd": "python3 tools/build.py -s cmake -b portenta_c33", + "elf": "cmake-build/cmake-build-portenta_c33/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/ra/boards/portenta_c33/script/memory_regions.ld hw/bsp/ra/boards/portenta_c33/script/fsp.ld", + "linker_vars": "" + }, + { + "target_name": "rw61x-frdm_rw612", + "port": "rw61x", + "board": "frdm_rw612", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py rw61x", + "build_cmd": "python3 tools/build.py -s cmake -b frdm_rw612", + "elf": "cmake-build/cmake-build-frdm_rw612/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/nxp/mcux-sdk/devices/RW612/gcc/RW612_flash.ld", + "linker_vars": "" + }, + { + "target_name": "samd11-cynthion_d11", + "port": "samd11", + "board": "cynthion_d11", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py samd11", + "build_cmd": "python3 tools/build.py -s cmake -b cynthion_d11", + "elf": "cmake-build/cmake-build-cynthion_d11/device/hid_composite/hid_composite.elf", + "ld": "hw/bsp/samd11/boards/cynthion_d11/cynthion_d11.ld", + "linker_vars": "BOOTLOADER_SIZE=0x800" + }, + { + "target_name": "samd5x_e5x-d5035_01", + "port": "samd5x_e5x", + "board": "d5035_01", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py samd5x_e5x", + "build_cmd": "python3 tools/build.py -s cmake -b d5035_01", + "elf": "cmake-build/cmake-build-d5035_01/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld", + "linker_vars": "" + }, + { + "target_name": "samg-samg55_xplained", + "port": "samg", + "board": "samg55_xplained", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py samg", + "build_cmd": "python3 tools/build.py -s cmake -b samg55_xplained", + "elf": "cmake-build/cmake-build-samg55_xplained/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/samg/boards/samg55_xplained/samg55j19_flash.ld", + "linker_vars": "" + }, + { + "target_name": "stm32c0-stm32c071nucleo", + "port": "stm32c0", + "board": "stm32c071nucleo", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32c0", + "build_cmd": "python3 tools/build.py -s cmake -b stm32c071nucleo", + "elf": "cmake-build/cmake-build-stm32c071nucleo/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32f0-stm32f070rbnucleo", + "port": "stm32f0", + "board": "stm32f070rbnucleo", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f0", + "build_cmd": "python3 tools/build.py -s cmake -b stm32f070rbnucleo", + "elf": "cmake-build/cmake-build-stm32f070rbnucleo/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld", + "linker_vars": "" + }, + { + "target_name": "stm32f1-stm32f103_bluepill", + "port": "stm32f1", + "board": "stm32f103_bluepill", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f1", + "build_cmd": "python3 tools/build.py -s cmake -b stm32f103_bluepill", + "elf": "cmake-build/cmake-build-stm32f103_bluepill/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32f2-stm32f207nucleo", + "port": "stm32f2", + "board": "stm32f207nucleo", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f2", + "build_cmd": "python3 tools/build.py -s cmake -b stm32f207nucleo", + "elf": "cmake-build/cmake-build-stm32f207nucleo/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32f2/boards/stm32f207nucleo/STM32F207ZGTx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32f3-stm32f303disco", + "port": "stm32f3", + "board": "stm32f303disco", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f3", + "build_cmd": "python3 tools/build.py -s cmake -b stm32f303disco", + "elf": "cmake-build/cmake-build-stm32f303disco/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32f3/boards/stm32f303disco/STM32F303VCTx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32f4-feather_stm32f405", + "port": "stm32f4", + "board": "feather_stm32f405", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f4", + "build_cmd": "python3 tools/build.py -s cmake -b feather_stm32f405", + "elf": "cmake-build/cmake-build-feather_stm32f405/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32f7-stlinkv3mini", + "port": "stm32f7", + "board": "stlinkv3mini", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f7", + "build_cmd": "python3 tools/build.py -s cmake -b stlinkv3mini", + "elf": "cmake-build/cmake-build-stlinkv3mini/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32g0-stm32g0b1nucleo", + "port": "stm32g0", + "board": "stm32g0b1nucleo", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32g0", + "build_cmd": "python3 tools/build.py -s cmake -b stm32g0b1nucleo", + "elf": "cmake-build/cmake-build-stm32g0b1nucleo/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32g4-b_g474e_dpow1", + "port": "stm32g4", + "board": "b_g474e_dpow1", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32g4", + "build_cmd": "python3 tools/build.py -s cmake -b b_g474e_dpow1", + "elf": "cmake-build/cmake-build-b_g474e_dpow1/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32h5-stm32h503nucleo", + "port": "stm32h5", + "board": "stm32h503nucleo", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32h5", + "build_cmd": "python3 tools/build.py -s cmake -b stm32h503nucleo", + "elf": "cmake-build/cmake-build-stm32h503nucleo/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32h7-daisyseed", + "port": "stm32h7", + "board": "daisyseed", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32h7", + "build_cmd": "python3 tools/build.py -s cmake -b daisyseed", + "elf": "cmake-build/cmake-build-daisyseed/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld", + "linker_vars": "" + }, + { + "target_name": "stm32h7rs-stm32h7s3nucleo", + "port": "stm32h7rs", + "board": "stm32h7s3nucleo", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32h7rs", + "build_cmd": "python3 tools/build.py -s cmake -b stm32h7s3nucleo", + "elf": "cmake-build/cmake-build-stm32h7s3nucleo/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32h7rs/linker/stm32h7s3xx_flash.ld", + "linker_vars": "__FLASH_BEGIN=0x08000000 __FLASH_SIZE=0x00010000 __RAM_BEGIN=0x24000000 __RAM_SIZE=0x4FC00 __RAM_NONCACHEABLEBUFFER_SIZE=0x400" + }, + { + "target_name": "stm32l0-stm32l052dap52", + "port": "stm32l0", + "board": "stm32l052dap52", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32l0", + "build_cmd": "python3 tools/build.py -s cmake -b stm32l052dap52", + "elf": "cmake-build/cmake-build-stm32l052dap52/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32l4-stm32l412nucleo", + "port": "stm32l4", + "board": "stm32l412nucleo", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32l4", + "build_cmd": "python3 tools/build.py -s cmake -b stm32l412nucleo", + "elf": "cmake-build/cmake-build-stm32l412nucleo/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32n6-stm32n6570dk", + "port": "stm32n6", + "board": "stm32n6570dk", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32n6", + "build_cmd": "python3 tools/build.py -s cmake -b stm32n6570dk", + "elf": "cmake-build/cmake-build-stm32n6570dk/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32n6/boards/stm32n6570dk/STM32N657XX_AXISRAM2_fsbl.ld", + "linker_vars": "" + }, + { + "target_name": "stm32u0-stm32u083cdk", + "port": "stm32u0", + "board": "stm32u083cdk", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32u0", + "build_cmd": "python3 tools/build.py -s cmake -b stm32u083cdk", + "elf": "cmake-build/cmake-build-stm32u083cdk/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32u0/boards/stm32u083cdk/STM32U083MCTx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32u5-b_u585i_iot2a", + "port": "stm32u5", + "board": "b_u585i_iot2a", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32u5", + "build_cmd": "python3 tools/build.py -s cmake -b b_u585i_iot2a", + "elf": "cmake-build/cmake-build-b_u585i_iot2a/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld", + "linker_vars": "" + }, + { + "target_name": "stm32wb-stm32wb55nucleo", + "port": "stm32wb", + "board": "stm32wb55nucleo", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32wb", + "build_cmd": "python3 tools/build.py -s cmake -b stm32wb55nucleo", + "elf": "cmake-build/cmake-build-stm32wb55nucleo/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld", + "linker_vars": "" + }, + { + "target_name": "stm32wba-stm32wba_nucleo", + "port": "stm32wba", + "board": "stm32wba_nucleo", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32wba", + "build_cmd": "python3 tools/build.py -s cmake -b stm32wba_nucleo", + "elf": "cmake-build/cmake-build-stm32wba_nucleo/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/stm32wba/linker/STM32WBA65xx_FLASH_ns.ld", + "linker_vars": "" + }, + { + "target_name": "tm4c-ek_tm4c123gxl", + "port": "tm4c", + "board": "ek_tm4c123gxl", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py tm4c", + "build_cmd": "python3 tools/build.py -s cmake -b ek_tm4c123gxl", + "elf": "cmake-build/cmake-build-ek_tm4c123gxl/device/cdc_msc/cdc_msc.elf", + "ld": "hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld", + "linker_vars": "" + }, + { + "target_name": "xmc4000-xmc4500_relax", + "port": "xmc4000", + "board": "xmc4500_relax", + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py xmc4000", + "build_cmd": "python3 tools/build.py -s cmake -b xmc4500_relax", + "elf": "cmake-build/cmake-build-xmc4500_relax/device/cdc_msc/cdc_msc.elf", + "ld": "hw/mcu/infineon/mtb-xmclib-cat3/CMSIS/Infineon/COMPONENT_XMC4500/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld", + "linker_vars": "" + } +] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bb8c6d65d..dc5b1975e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,30 +3,8 @@ name: Build on: workflow_dispatch: push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/build.py' - - 'tools/get_deps.py' - - '.github/actions/**' - - '.github/workflows/build.yml' - - '.github/workflows/build_util.yml' - - '.github/workflows/ci_set_matrix.py' + branches: [master] pull_request: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'test/hil/**' - - 'tools/build.py' - - 'tools/get_deps.py' - - '.github/actions/**' - - '.github/workflows/build.yml' - - '.github/workflows/build_util.yml' - - '.github/workflows/ci_set_matrix.py' release: types: [ published ] concurrency: @@ -37,7 +15,44 @@ env: HIL_JSON: test/hil/tinyusb.json jobs: + # Check if code paths changed (skip builds if doc-only) + check-paths: + if: github.event_name == 'pull_request' || github.event_name == 'push' + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + code_changed: ${{ steps.filter.outputs.code }} + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 2 # Needed for push commit comparison + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + code: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'test/hil/**' + - 'tools/build.py' + - 'tools/get_deps.py' + - '.github/actions/**' + - '.github/workflows/build.yml' + - '.github/workflows/build_util.yml' + - '.github/workflows/ci_set_matrix.py' + set-matrix: + needs: [check-paths] + if: | + always() && ( + github.event_name == 'release' || + github.event_name == 'workflow_dispatch' || + needs.check-paths.outputs.code_changed == 'true' + ) runs-on: ubuntu-latest outputs: json: ${{ steps.set-matrix-json.outputs.matrix }} @@ -82,6 +97,7 @@ jobs: build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} build-options: '--one-first' upload-metrics: true + upload-artifacts: true code-metrics: needs: cmake @@ -181,7 +197,8 @@ jobs: # Build Make/CMake on Windows/MacOS # --------------------------------------- build-os: - if: github.event_name == 'pull_request' + needs: [check-paths] + if: needs.check-paths.outputs.code_changed == 'true' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -198,7 +215,8 @@ jobs: # Zephyr # --------------------------------------- zephyr: - if: github.event_name == 'push' + needs: [check-paths] + if: needs.check-paths.outputs.code_changed == 'true' runs-on: ubuntu-latest steps: - name: Checkout TinyUSB @@ -220,10 +238,10 @@ jobs: # Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR # --------------------------------------- hil-build: + needs: [check-paths, set-matrix] if: | github.repository_owner == 'hathach' && - (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') - needs: set-matrix + (github.event_name == 'workflow_dispatch' || needs.check-paths.outputs.code_changed == 'true') uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -242,8 +260,10 @@ jobs: # self-hosted on local VM, for attached hardware checkout HIL_JSON # --------------------------------------- hil-tinyusb: - if: github.repository_owner == 'hathach' && github.event_name != 'push' - needs: hil-build + needs: [check-paths, hil-build] + if: | + github.repository_owner == 'hathach' && + (github.event_name == 'release' || github.event_name == 'workflow_dispatch' || needs.check-paths.outputs.code_changed == 'true') runs-on: [ self-hosted, X64, hathach, hardware-in-the-loop ] steps: - name: Get Skip Boards from previous run @@ -283,10 +303,11 @@ jobs: # Since IAR Token secret is not passed to forked PR, only build non-forked PR # --------------------------------------- hil-hfp: + needs: [check-paths] if: | github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false && - github.event_name != 'push' + (github.event_name == 'release' || github.event_name == 'workflow_dispatch' || needs.check-paths.outputs.code_changed == 'true') runs-on: [ self-hosted, Linux, X64, hifiphile ] env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} @@ -319,3 +340,59 @@ jobs: - name: Test on actual hardware (hardware in the loop) run: python3 test/hil/hil_test.py hfp.json + + # --------------------------------------- + # Membrowse Memory Analysis + # Push: always runs (uses identical for doc-only to maintain commit chain) + # PR: only runs if code changed (doc-only PRs skip entirely) + # --------------------------------------- + membrowse: + needs: [check-paths, cmake] + if: | + always() && !cancelled() && ( + github.event_name == 'push' || + github.event_name == 'release' || + github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && needs.check-paths.outputs.code_changed == 'true') + ) + permissions: + contents: read + actions: read + uses: ./.github/workflows/membrowse-report.yml + with: + code_changed: ${{ needs.check-paths.outputs.code_changed == 'true' || github.event_name == 'release' || github.event_name == 'workflow_dispatch' }} + secrets: inherit + + membrowse-comment: + needs: [check-paths, membrowse] + if: > + always() && + github.event_name == 'pull_request' && + needs.check-paths.outputs.code_changed == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + actions: read + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Download report artifacts + id: download + uses: actions/download-artifact@v5 + with: + pattern: membrowse-report-* + path: reports + merge-multiple: true + continue-on-error: true + + - name: Save PR number + if: steps.download.outcome == 'success' + run: echo ${{ github.event.number }} > reports/pr_number.txt + + - name: Upload Membrowse Comment Artifact + if: steps.download.outcome == 'success' + uses: actions/upload-artifact@v5 + with: + name: membrowse-comment + path: reports/ diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 540ee8b47..e0fef7ce4 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -73,6 +73,19 @@ jobs: name: metrics-${{ matrix.arg }} path: cmake-build/cmake-build-*/metrics.json + - name: Copy linker scripts for artifacts + if: ${{ inputs.upload-artifacts }} + run: | + for dir in cmake-build/cmake-build-*; do + board=$(basename "$dir" | sed 's/cmake-build-//') + ld_path=$(jq -r --arg b "$board" '.[] | select(.board == $b) | .ld // empty' .github/membrowse-targets.json) + if [ -n "$ld_path" ] && [ -f "$ld_path" ]; then + mkdir -p "cmake-build/$(dirname "$ld_path")" + cp "$ld_path" "cmake-build/$ld_path" + fi + done + shell: bash + - name: Upload Artifacts for Hardware Testing if: ${{ inputs.upload-artifacts }} uses: actions/upload-artifact@v5 @@ -86,3 +99,4 @@ jobs: cmake-build/cmake-build-*/*/*/partition_table/partition-table.bin cmake-build/cmake-build-*/*/*/config.env cmake-build/cmake-build-*/*/*/flash_args + cmake-build/hw/mcu/**/*.ld diff --git a/.github/workflows/membrowse-comment.yml b/.github/workflows/membrowse-comment.yml new file mode 100644 index 000000000..a3db37360 --- /dev/null +++ b/.github/workflows/membrowse-comment.yml @@ -0,0 +1,44 @@ +name: Membrowse Comment + +on: + workflow_run: + workflows: ["Build"] + types: + - completed + +jobs: + post-comment: + runs-on: ubuntu-latest + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + permissions: + actions: read + pull-requests: write + steps: + - name: Download Artifacts + id: download + uses: actions/download-artifact@v5 + with: + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + name: membrowse-comment + path: reports + continue-on-error: true + + - name: Read PR Number + if: steps.download.outcome == 'success' + id: pr_number + run: | + if [ -f reports/pr_number.txt ]; then + echo "number=$(cat reports/pr_number.txt)" >> $GITHUB_OUTPUT + fi + + - name: Post Membrowse PR comment + if: steps.download.outcome == 'success' && steps.pr_number.outputs.number != '' + uses: membrowse/membrowse-action/comment-action@v1 + with: + json_files: 'reports/*.json' + pr_number: ${{ steps.pr_number.outputs.number }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/membrowse-onboard.yml b/.github/workflows/membrowse-onboard.yml new file mode 100644 index 000000000..a183297b2 --- /dev/null +++ b/.github/workflows/membrowse-onboard.yml @@ -0,0 +1,58 @@ +name: Onboard to Membrowse + +on: + workflow_dispatch: + inputs: + num_commits: + description: 'Number of commits to process' + required: true + default: '10' + type: string + +jobs: + load-targets: + runs-on: ubuntu-22.04 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Load target matrix + id: set-matrix + run: echo "matrix=$(jq -c '.' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT + + onboard: + needs: load-targets + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.load-targets.outputs.matrix) }} + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + fetch-depth: 0 + submodules: recursive + + - name: Install packages + run: ${{ matrix.setup_cmd }} + + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ matrix.port }}-${{ matrix.board }} + + - name: Run Membrowse Onboard Action + uses: membrowse/membrowse-action/onboard-action@v1 + with: + target_name: ${{ matrix.target_name }} + num_commits: ${{ github.event.inputs.num_commits }} + build_script: ${{ matrix.build_cmd }} + elf: ${{ matrix.elf }} + ld: ${{ matrix.ld }} + linker_vars: ${{ matrix.linker_vars }} + api_key: ${{ secrets.MEMBROWSE_API_KEY }} + api_url: ${{ vars.MEMBROWSE_API_URL }} diff --git a/.github/workflows/membrowse-report.yml b/.github/workflows/membrowse-report.yml new file mode 100644 index 000000000..aff9fe138 --- /dev/null +++ b/.github/workflows/membrowse-report.yml @@ -0,0 +1,101 @@ +name: Membrowse Memory Report + +on: + workflow_call: + inputs: + code_changed: + description: 'Whether code paths changed (true) or doc-only (false)' + type: boolean + required: true + +permissions: + contents: read + actions: read + +jobs: + load-targets: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Load target matrix + id: set-matrix + run: echo "matrix=$(jq -c '.' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT + + analyze: + needs: [load-targets] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.load-targets.outputs.matrix) }} + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + + # Download artifacts when code changed (build artifacts available) + - name: Download build artifacts + if: inputs.code_changed + id: download + uses: actions/download-artifact@v5 + with: + pattern: binaries-* + path: cmake-build + merge-multiple: true + continue-on-error: true + + - name: Restore linker scripts + if: inputs.code_changed + run: cp -r cmake-build/hw . 2>/dev/null || true + + - name: Check if ELF exists + id: check-elf + run: | + if [ -f "${{ matrix.elf }}" ]; then + echo "exists=true" >> $GITHUB_OUTPUT + else + echo "exists=false" >> $GITHUB_OUTPUT + fi + + # Run with actual ELF analysis when build artifacts available + - name: Run Membrowse Analysis + if: steps.check-elf.outputs.exists == 'true' + id: membrowse + continue-on-error: true + uses: membrowse/membrowse-action@v1 + with: + target_name: ${{ matrix.target_name }} + elf: ${{ matrix.elf }} + ld: ${{ matrix.ld }} + linker_vars: ${{ matrix.linker_vars }} + api_key: ${{ secrets.MEMBROWSE_API_KEY }} + api_url: ${{ vars.MEMBROWSE_API_URL }} + verbose: INFO + + # Run with identical=true when no ELF (doc-only push) + # Preserves the chain of commits in membrowse tracking + - name: Run Membrowse Identical Report + if: steps.check-elf.outputs.exists == 'false' + id: membrowse-identical + continue-on-error: true + uses: membrowse/membrowse-action@v1 + with: + target_name: ${{ matrix.target_name }} + identical: true + api_key: ${{ secrets.MEMBROWSE_API_KEY }} + api_url: ${{ vars.MEMBROWSE_API_URL }} + verbose: INFO + + - name: Upload report artifact + if: steps.membrowse.outcome == 'success' || steps.membrowse-identical.outcome == 'success' + uses: actions/upload-artifact@v5 + with: + name: membrowse-report-${{ matrix.target_name }} + path: ${{ steps.membrowse.outputs.report_path || steps.membrowse-identical.outputs.report_path }} diff --git a/README.rst b/README.rst index e439a3137..0eb1e84b9 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ TinyUSB ======= -|Build Status| |CircleCI Status| |Documentation Status| |Static Analysis| |Fuzzing Status| |License| +|Build Status| |CircleCI Status| |Documentation Status| |Static Analysis| |Fuzzing Status| |Membrowse| |License| Sponsors -------- @@ -293,6 +293,8 @@ The following tools are provided freely to support the development of the TinyUS :target: https://github.com/hathach/tinyusb/actions/workflows/static_analysis.yml .. |Fuzzing Status| image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/tinyusb.svg :target: https://oss-fuzz-build-logs.storage.googleapis.com/index.html#tinyusb +.. |Membrowse| image:: https://membrowse.com/badge.svg + :target: https://membrowse.com/public/hathach/tinyusb .. |License| image:: https://img.shields.io/badge/license-MIT-brightgreen.svg :target: https://opensource.org/licenses/MIT -- cgit v1.3.1 From 697fdca69d7a1df0cc63b0af47ff66459af9367a Mon Sep 17 00:00:00 2001 From: Michael Rogov Papernov Date: Sat, 24 Jan 2026 13:06:56 +0000 Subject: restructure targets file --- .github/membrowse-targets.json | 1156 +++++++++++++------------------ .github/workflows/build.yml | 4 - .github/workflows/build_util.yml | 2 +- .github/workflows/membrowse-comment.yml | 16 +- .github/workflows/membrowse-onboard.yml | 22 +- .github/workflows/membrowse-report.yml | 20 +- 6 files changed, 523 insertions(+), 697 deletions(-) (limited to '.github/workflows') diff --git a/.github/membrowse-targets.json b/.github/membrowse-targets.json index 80dd158a8..5b76f9b55 100644 --- a/.github/membrowse-targets.json +++ b/.github/membrowse-targets.json @@ -1,662 +1,494 @@ -[ - { - "target_name": "at32f402_405-at_start_f402", - "port": "at32f402_405", - "board": "at_start_f402", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f402_405", - "build_cmd": "python3 tools/build.py -s cmake -b at_start_f402", - "elf": "cmake-build/cmake-build-at_start_f402/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/artery/at32f402_405/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F402xC_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "at32f403a_407-at32f403a_weact_blackpill", - "port": "at32f403a_407", - "board": "at32f403a_weact_blackpill", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f403a_407", - "build_cmd": "python3 tools/build.py -s cmake -b at32f403a_weact_blackpill", - "elf": "cmake-build/cmake-build-at32f403a_weact_blackpill/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/artery/at32f403a_407/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F403AxC_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "at32f413-at_start_f413", - "port": "at32f413", - "board": "at_start_f413", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f413", - "build_cmd": "python3 tools/build.py -s cmake -b at_start_f413", - "elf": "cmake-build/cmake-build-at_start_f413/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/artery/at32f413/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F413xC_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "at32f415-at_start_f415", - "port": "at32f415", - "board": "at_start_f415", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f415", - "build_cmd": "python3 tools/build.py -s cmake -b at_start_f415", - "elf": "cmake-build/cmake-build-at_start_f415/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/artery/at32f415/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F415xC_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "at32f423-at_start_f423", - "port": "at32f423", - "board": "at_start_f423", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f423", - "build_cmd": "python3 tools/build.py -s cmake -b at_start_f423", - "elf": "cmake-build/cmake-build-at_start_f423/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/artery/at32f423/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F423xC_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "at32f425-at_start_f425", - "port": "at32f425", - "board": "at_start_f425", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f425", - "build_cmd": "python3 tools/build.py -s cmake -b at_start_f425", - "elf": "cmake-build/cmake-build-at_start_f425/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/artery/at32f425/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x8_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "at32f435_437-at_start_f435", - "port": "at32f435_437", - "board": "at_start_f435", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py at32f435_437", - "build_cmd": "python3 tools/build.py -s cmake -b at_start_f435", - "elf": "cmake-build/cmake-build-at_start_f435/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/artery/at32f435_437/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F435xM_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "broadcom_32bit-raspberrypi_zero", - "port": "broadcom_32bit", - "board": "raspberrypi_zero", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py broadcom_32bit", - "build_cmd": "python3 tools/build.py -s cmake -b raspberrypi_zero", - "elf": "cmake-build/cmake-build-raspberrypi_zero/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/broadcom/broadcom/link.ld", - "linker_vars": "" - }, - { - "target_name": "broadcom_64bit-raspberrypi_cm4", - "port": "broadcom_64bit", - "board": "raspberrypi_cm4", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.xz && tar -C $HOME/toolchain -xf toolchain.tar.xz && echo \"$HOME/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py broadcom_64bit", - "build_cmd": "python3 tools/build.py -s cmake -b raspberrypi_cm4", - "elf": "cmake-build/cmake-build-raspberrypi_cm4/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/broadcom/broadcom/link8.ld", - "linker_vars": "" - }, - { - "target_name": "ch32v10x-ch32v103r_r1_1v0", - "port": "ch32v10x", - "board": "ch32v103r_r1_1v0", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py ch32v10x", - "build_cmd": "python3 tools/build.py -s cmake -b ch32v103r_r1_1v0", - "elf": "cmake-build/cmake-build-ch32v103r_r1_1v0/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/ch32v10x/linker/ch32v10x.ld", - "linker_vars": "__FLASH_SIZE=64K __RAM_SIZE=20K" - }, - { - "target_name": "ch32v20x-ch32v203c_r0_1v0", - "port": "ch32v20x", - "board": "ch32v203c_r0_1v0", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py ch32v20x", - "build_cmd": "python3 tools/build.py -s cmake -b ch32v203c_r0_1v0", - "elf": "cmake-build/cmake-build-ch32v203c_r0_1v0/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/ch32v20x/linker/ch32v20x.ld", - "linker_vars": "__flash_size=64K __ram_size=20K" - }, - { - "target_name": "ch32v30x-ch32v307v_r1_1v0", - "port": "ch32v30x", - "board": "ch32v307v_r1_1v0", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py ch32v30x", - "build_cmd": "python3 tools/build.py -s cmake -b ch32v307v_r1_1v0", - "elf": "cmake-build/cmake-build-ch32v307v_r1_1v0/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/ch32v30x/linker/ch32v30x.ld", - "linker_vars": "__flash_size=128K __ram_size=32K" - }, - { - "target_name": "da1469x-da14695_dk_usb", - "port": "da1469x", - "board": "da14695_dk_usb", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py da1469x", - "build_cmd": "python3 tools/build.py -s cmake -b da14695_dk_usb", - "elf": "cmake-build/cmake-build-da14695_dk_usb/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/da1469x/linker/da1469x.ld", - "linker_vars": "" - }, - { - "target_name": "fomu-fomu", - "port": "fomu", - "board": "fomu", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py fomu", - "build_cmd": "python3 tools/build.py -s cmake -b fomu", - "elf": "cmake-build/cmake-build-fomu/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/fomu/fomu.ld", - "linker_vars": "" - }, - { - "target_name": "gd32vf103-sipeed_longan_nano", - "port": "gd32vf103", - "board": "sipeed_longan_nano", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py gd32vf103", - "build_cmd": "python3 tools/build.py -s cmake -b sipeed_longan_nano", - "elf": "cmake-build/cmake-build-sipeed_longan_nano/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/gd/nuclei-sdk/SoC/gd32vf103/Board/gd32vf103c_longan_nano/Source/GCC/gcc_gd32vf103xb_flashxip.ld", - "linker_vars": "__ROM_BASE=0x08000000 __ROM_SIZE=0x00020000 __RAM_BASE=0x20000000 __RAM_SIZE=0x00008000" - }, - { - "target_name": "hpmicro-hpm6750evk2", - "port": "hpmicro", - "board": "hpm6750evk2", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py hpmicro", - "build_cmd": "python3 tools/build.py -s cmake -b hpm6750evk2", - "elf": "cmake-build/cmake-build-hpm6750evk2/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/hpmicro/hpm_sdk/soc/HPM6700/HPM6750/toolchains/gcc/flash_xip.ld", - "linker_vars": "_flash_size=16M _stack_size=16K _heap_size=16K" - }, - { - "target_name": "imxrt-metro_m7_1011", - "port": "imxrt", - "board": "metro_m7_1011", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py imxrt", - "build_cmd": "python3 tools/build.py -s cmake -b metro_m7_1011", - "elf": "cmake-build/cmake-build-metro_m7_1011/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/nxp/mcux-sdk/devices/MIMXRT1011/gcc/MIMXRT1011xxxxx_flexspi_nor.ld", - "linker_vars": "" - }, - { - "target_name": "kinetis_k-frdm_k64f", - "port": "kinetis_k", - "board": "frdm_k64f", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py kinetis_k kinetis_kl", - "build_cmd": "python3 tools/build.py -s cmake -b frdm_k64f", - "elf": "cmake-build/cmake-build-frdm_k64f/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/nxp/mcux-sdk/devices/MK64F12/gcc/MK64FN1M0xxx12_flash.ld", - "linker_vars": "" - }, - { - "target_name": "kinetis_k32l2-frdm_k32l2a4s", - "port": "kinetis_k32l2", - "board": "frdm_k32l2a4s", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py kinetis_k32l2", - "build_cmd": "python3 tools/build.py -s cmake -b frdm_k32l2a4s", - "elf": "cmake-build/cmake-build-frdm_k32l2a4s/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/nxp/mcux-sdk/devices/K32L2A41A/gcc/K32L2A41xxxxA_flash.ld", - "linker_vars": "" - }, - { - "target_name": "kinetis_kl-frdm_kl25z", - "port": "kinetis_kl", - "board": "frdm_kl25z", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py kinetis_kl", - "build_cmd": "python3 tools/build.py -s cmake -b frdm_kl25z", - "elf": "cmake-build/cmake-build-frdm_kl25z/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/kinetis_kl/gcc/MKL25Z128xxx4_flash.ld", - "linker_vars": "" - }, - { - "target_name": "lpc11-lpcxpresso11u37", - "port": "lpc11", - "board": "lpcxpresso11u37", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc11", - "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso11u37", - "elf": "cmake-build/cmake-build-lpcxpresso11u37/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/lpc11/boards/lpcxpresso11u37/lpc11u37.ld", - "linker_vars": "" - }, - { - "target_name": "lpc13-lpcxpresso1347", - "port": "lpc13", - "board": "lpcxpresso1347", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc13", - "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso1347", - "elf": "cmake-build/cmake-build-lpcxpresso1347/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/lpc13/boards/lpcxpresso1347/lpc1347.ld", - "linker_vars": "" - }, - { - "target_name": "lpc15-lpcxpresso1549", - "port": "lpc15", - "board": "lpcxpresso1549", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc15", - "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso1549", - "elf": "cmake-build/cmake-build-lpcxpresso1549/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/lpc15/boards/lpcxpresso1549/lpc1549.ld", - "linker_vars": "" - }, - { - "target_name": "lpc17-lpcxpresso1769", - "port": "lpc17", - "board": "lpcxpresso1769", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc17", - "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso1769", - "elf": "cmake-build/cmake-build-lpcxpresso1769/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld", - "linker_vars": "" - }, - { - "target_name": "lpc18-lpcxpresso18s37", - "port": "lpc18", - "board": "lpcxpresso18s37", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc18", - "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso18s37", - "elf": "cmake-build/cmake-build-lpcxpresso18s37/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld", - "linker_vars": "" - }, - { - "target_name": "lpc40-ea4088_quickstart", - "port": "lpc40", - "board": "ea4088_quickstart", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc40", - "build_cmd": "python3 tools/build.py -s cmake -b ea4088_quickstart", - "elf": "cmake-build/cmake-build-ea4088_quickstart/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld", - "linker_vars": "" - }, - { - "target_name": "lpc43-ea4357", - "port": "lpc43", - "board": "ea4357", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc43", - "build_cmd": "python3 tools/build.py -s cmake -b ea4357", - "elf": "cmake-build/cmake-build-ea4357/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/lpc43/boards/ea4357/lpc4357.ld", - "linker_vars": "" - }, - { - "target_name": "lpc51-lpcxpresso51u68", - "port": "lpc51", - "board": "lpcxpresso51u68", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc51", - "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso51u68", - "elf": "cmake-build/cmake-build-lpcxpresso51u68/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC51U68/gcc/LPC51U68_flash.ld", - "linker_vars": "" - }, - { - "target_name": "lpc54-lpcxpresso54114", - "port": "lpc54", - "board": "lpcxpresso54114", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc54", - "build_cmd": "python3 tools/build.py -s cmake -b lpcxpresso54114", - "elf": "cmake-build/cmake-build-lpcxpresso54114/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC54114/gcc/LPC54114J256_cm4_flash.ld", - "linker_vars": "" - }, - { - "target_name": "lpc55-double_m33_express", - "port": "lpc55", - "board": "double_m33_express", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py lpc55", - "build_cmd": "python3 tools/build.py -s cmake -b double_m33_express", - "elf": "cmake-build/cmake-build-double_m33_express/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/lpc55/boards/double_m33_express/LPC55S69_cm33_core0_uf2.ld", - "linker_vars": "" - }, - { - "target_name": "maxim-apard32690", - "port": "maxim", - "board": "apard32690", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py maxim", - "build_cmd": "python3 tools/build.py -s cmake -b apard32690", - "elf": "cmake-build/cmake-build-apard32690/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/maxim/linker/max32690.ld", - "linker_vars": "" - }, - { - "target_name": "mcx-frdm_mcxa153", - "port": "mcx", - "board": "frdm_mcxa153", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py mcx", - "build_cmd": "python3 tools/build.py -s cmake -b frdm_mcxa153", - "elf": "cmake-build/cmake-build-frdm_mcxa153/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/nxp/mcux-sdk/devices/MCXA153/gcc/MCXA153_flash.ld", - "linker_vars": "" - }, - { - "target_name": "mm32-mm32f327x_mb39", - "port": "mm32", - "board": "mm32f327x_mb39", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py mm32", - "build_cmd": "python3 tools/build.py -s cmake -b mm32f327x_mb39", - "elf": "cmake-build/cmake-build-mm32f327x_mb39/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld", - "linker_vars": "" - }, - { - "target_name": "msp430-msp_exp430f5529lp", - "port": "msp430", - "board": "msp_exp430f5529lp", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2 && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.bz2 && tar -C $HOME/toolchain -xf toolchain.tar.bz2 && echo \"$HOME/toolchain/msp430-gcc-9.2.0.50_linux64/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py msp430", - "build_cmd": "python3 tools/build.py -s cmake -b msp_exp430f5529lp", - "elf": "cmake-build/cmake-build-msp_exp430f5529lp/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/ti/msp430/msp430-gcc-support-files/include/msp430f5529.ld", - "linker_vars": "" - }, - { - "target_name": "msp432e4-msp_exp432e401y", - "port": "msp432e4", - "board": "msp_exp432e401y", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py msp432e4", - "build_cmd": "python3 tools/build.py -s cmake -b msp_exp432e401y", - "elf": "cmake-build/cmake-build-msp_exp432e401y/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/ti/msp432e4/Source/msp432e411y.ld", - "linker_vars": "" - }, - { - "target_name": "nrf-adafruit_clue", - "port": "nrf", - "board": "adafruit_clue", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nrf", - "build_cmd": "python3 tools/build.py -s cmake -b adafruit_clue", - "elf": "cmake-build/cmake-build-adafruit_clue/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/nrf/linker/nrf52840_xxaa.ld", - "linker_vars": "" - }, - { - "target_name": "nuc100_120-nutiny_sdk_nuc120", - "port": "nuc100_120", - "board": "nutiny_sdk_nuc120", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nuc100_120", - "build_cmd": "python3 tools/build.py -s cmake -b nutiny_sdk_nuc120", - "elf": "cmake-build/cmake-build-nutiny_sdk_nuc120/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/nuc100_120/boards/nutiny_sdk_nuc120/nuc120_flash.ld", - "linker_vars": "" - }, - { - "target_name": "nuc121_125-nutiny_sdk_nuc121", - "port": "nuc121_125", - "board": "nutiny_sdk_nuc121", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nuc121_125", - "build_cmd": "python3 tools/build.py -s cmake -b nutiny_sdk_nuc121", - "elf": "cmake-build/cmake-build-nutiny_sdk_nuc121/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/nuc121_125/boards/nutiny_sdk_nuc121/nuc121_flash.ld", - "linker_vars": "" - }, - { - "target_name": "nuc126-nutiny_nuc126v", - "port": "nuc126", - "board": "nutiny_nuc126v", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nuc126", - "build_cmd": "python3 tools/build.py -s cmake -b nutiny_nuc126v", - "elf": "cmake-build/cmake-build-nutiny_nuc126v/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/nuc126/boards/nutiny_nuc126v/nuc126_flash.ld", - "linker_vars": "" - }, - { - "target_name": "nuc505-nutiny_sdk_nuc505", - "port": "nuc505", - "board": "nutiny_sdk_nuc505", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py nuc505", - "build_cmd": "python3 tools/build.py -s cmake -b nutiny_sdk_nuc505", - "elf": "cmake-build/cmake-build-nutiny_sdk_nuc505/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/nuc505/boards/nutiny_sdk_nuc505/nuc505_flashtoram.ld", - "linker_vars": "" - }, - { - "target_name": "ra-portenta_c33", - "port": "ra", - "board": "portenta_c33", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py ra", - "build_cmd": "python3 tools/build.py -s cmake -b portenta_c33", - "elf": "cmake-build/cmake-build-portenta_c33/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/ra/boards/portenta_c33/script/memory_regions.ld hw/bsp/ra/boards/portenta_c33/script/fsp.ld", - "linker_vars": "" - }, - { - "target_name": "rw61x-frdm_rw612", - "port": "rw61x", - "board": "frdm_rw612", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py rw61x", - "build_cmd": "python3 tools/build.py -s cmake -b frdm_rw612", - "elf": "cmake-build/cmake-build-frdm_rw612/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/nxp/mcux-sdk/devices/RW612/gcc/RW612_flash.ld", - "linker_vars": "" - }, - { - "target_name": "samd11-cynthion_d11", - "port": "samd11", - "board": "cynthion_d11", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py samd11", - "build_cmd": "python3 tools/build.py -s cmake -b cynthion_d11", - "elf": "cmake-build/cmake-build-cynthion_d11/device/hid_composite/hid_composite.elf", - "ld": "hw/bsp/samd11/boards/cynthion_d11/cynthion_d11.ld", - "linker_vars": "BOOTLOADER_SIZE=0x800" - }, - { - "target_name": "samd5x_e5x-d5035_01", - "port": "samd5x_e5x", - "board": "d5035_01", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py samd5x_e5x", - "build_cmd": "python3 tools/build.py -s cmake -b d5035_01", - "elf": "cmake-build/cmake-build-d5035_01/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld", - "linker_vars": "" - }, - { - "target_name": "samg-samg55_xplained", - "port": "samg", - "board": "samg55_xplained", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py samg", - "build_cmd": "python3 tools/build.py -s cmake -b samg55_xplained", - "elf": "cmake-build/cmake-build-samg55_xplained/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/samg/boards/samg55_xplained/samg55j19_flash.ld", - "linker_vars": "" - }, - { - "target_name": "stm32c0-stm32c071nucleo", - "port": "stm32c0", - "board": "stm32c071nucleo", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32c0", - "build_cmd": "python3 tools/build.py -s cmake -b stm32c071nucleo", - "elf": "cmake-build/cmake-build-stm32c071nucleo/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32f0-stm32f070rbnucleo", - "port": "stm32f0", - "board": "stm32f070rbnucleo", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f0", - "build_cmd": "python3 tools/build.py -s cmake -b stm32f070rbnucleo", - "elf": "cmake-build/cmake-build-stm32f070rbnucleo/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld", - "linker_vars": "" - }, - { - "target_name": "stm32f1-stm32f103_bluepill", - "port": "stm32f1", - "board": "stm32f103_bluepill", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f1", - "build_cmd": "python3 tools/build.py -s cmake -b stm32f103_bluepill", - "elf": "cmake-build/cmake-build-stm32f103_bluepill/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32f2-stm32f207nucleo", - "port": "stm32f2", - "board": "stm32f207nucleo", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f2", - "build_cmd": "python3 tools/build.py -s cmake -b stm32f207nucleo", - "elf": "cmake-build/cmake-build-stm32f207nucleo/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32f2/boards/stm32f207nucleo/STM32F207ZGTx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32f3-stm32f303disco", - "port": "stm32f3", - "board": "stm32f303disco", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f3", - "build_cmd": "python3 tools/build.py -s cmake -b stm32f303disco", - "elf": "cmake-build/cmake-build-stm32f303disco/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32f3/boards/stm32f303disco/STM32F303VCTx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32f4-feather_stm32f405", - "port": "stm32f4", - "board": "feather_stm32f405", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f4", - "build_cmd": "python3 tools/build.py -s cmake -b feather_stm32f405", - "elf": "cmake-build/cmake-build-feather_stm32f405/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32f7-stlinkv3mini", - "port": "stm32f7", - "board": "stlinkv3mini", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32f7", - "build_cmd": "python3 tools/build.py -s cmake -b stlinkv3mini", - "elf": "cmake-build/cmake-build-stlinkv3mini/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32g0-stm32g0b1nucleo", - "port": "stm32g0", - "board": "stm32g0b1nucleo", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32g0", - "build_cmd": "python3 tools/build.py -s cmake -b stm32g0b1nucleo", - "elf": "cmake-build/cmake-build-stm32g0b1nucleo/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32g4-b_g474e_dpow1", - "port": "stm32g4", - "board": "b_g474e_dpow1", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32g4", - "build_cmd": "python3 tools/build.py -s cmake -b b_g474e_dpow1", - "elf": "cmake-build/cmake-build-b_g474e_dpow1/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32h5-stm32h503nucleo", - "port": "stm32h5", - "board": "stm32h503nucleo", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32h5", - "build_cmd": "python3 tools/build.py -s cmake -b stm32h503nucleo", - "elf": "cmake-build/cmake-build-stm32h503nucleo/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32h7-daisyseed", - "port": "stm32h7", - "board": "daisyseed", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32h7", - "build_cmd": "python3 tools/build.py -s cmake -b daisyseed", - "elf": "cmake-build/cmake-build-daisyseed/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld", - "linker_vars": "" - }, - { - "target_name": "stm32h7rs-stm32h7s3nucleo", - "port": "stm32h7rs", - "board": "stm32h7s3nucleo", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32h7rs", - "build_cmd": "python3 tools/build.py -s cmake -b stm32h7s3nucleo", - "elf": "cmake-build/cmake-build-stm32h7s3nucleo/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32h7rs/linker/stm32h7s3xx_flash.ld", - "linker_vars": "__FLASH_BEGIN=0x08000000 __FLASH_SIZE=0x00010000 __RAM_BEGIN=0x24000000 __RAM_SIZE=0x4FC00 __RAM_NONCACHEABLEBUFFER_SIZE=0x400" - }, - { - "target_name": "stm32l0-stm32l052dap52", - "port": "stm32l0", - "board": "stm32l052dap52", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32l0", - "build_cmd": "python3 tools/build.py -s cmake -b stm32l052dap52", - "elf": "cmake-build/cmake-build-stm32l052dap52/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32l4-stm32l412nucleo", - "port": "stm32l4", - "board": "stm32l412nucleo", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32l4", - "build_cmd": "python3 tools/build.py -s cmake -b stm32l412nucleo", - "elf": "cmake-build/cmake-build-stm32l412nucleo/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32n6-stm32n6570dk", - "port": "stm32n6", - "board": "stm32n6570dk", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32n6", - "build_cmd": "python3 tools/build.py -s cmake -b stm32n6570dk", - "elf": "cmake-build/cmake-build-stm32n6570dk/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32n6/boards/stm32n6570dk/STM32N657XX_AXISRAM2_fsbl.ld", - "linker_vars": "" - }, - { - "target_name": "stm32u0-stm32u083cdk", - "port": "stm32u0", - "board": "stm32u083cdk", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32u0", - "build_cmd": "python3 tools/build.py -s cmake -b stm32u083cdk", - "elf": "cmake-build/cmake-build-stm32u083cdk/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32u0/boards/stm32u083cdk/STM32U083MCTx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32u5-b_u585i_iot2a", - "port": "stm32u5", - "board": "b_u585i_iot2a", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32u5", - "build_cmd": "python3 tools/build.py -s cmake -b b_u585i_iot2a", - "elf": "cmake-build/cmake-build-b_u585i_iot2a/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld", - "linker_vars": "" - }, - { - "target_name": "stm32wb-stm32wb55nucleo", - "port": "stm32wb", - "board": "stm32wb55nucleo", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32wb", - "build_cmd": "python3 tools/build.py -s cmake -b stm32wb55nucleo", - "elf": "cmake-build/cmake-build-stm32wb55nucleo/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld", - "linker_vars": "" - }, - { - "target_name": "stm32wba-stm32wba_nucleo", - "port": "stm32wba", - "board": "stm32wba_nucleo", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py stm32wba", - "build_cmd": "python3 tools/build.py -s cmake -b stm32wba_nucleo", - "elf": "cmake-build/cmake-build-stm32wba_nucleo/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/stm32wba/linker/STM32WBA65xx_FLASH_ns.ld", - "linker_vars": "" - }, - { - "target_name": "tm4c-ek_tm4c123gxl", - "port": "tm4c", - "board": "ek_tm4c123gxl", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py tm4c", - "build_cmd": "python3 tools/build.py -s cmake -b ek_tm4c123gxl", - "elf": "cmake-build/cmake-build-ek_tm4c123gxl/device/cdc_msc/cdc_msc.elf", - "ld": "hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld", - "linker_vars": "" - }, - { - "target_name": "xmc4000-xmc4500_relax", - "port": "xmc4000", - "board": "xmc4500_relax", - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH && python3 tools/get_deps.py xmc4000", - "build_cmd": "python3 tools/build.py -s cmake -b xmc4500_relax", - "elf": "cmake-build/cmake-build-xmc4500_relax/device/cdc_msc/cdc_msc.elf", - "ld": "hw/mcu/infineon/mtb-xmclib-cat3/CMSIS/Infineon/COMPONENT_XMC4500/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld", - "linker_vars": "" - } -] +{ + "templates": { + "build_cmd": "python3 tools/build.py -s cmake -b ${board}", + "elf": "cmake-build/cmake-build-${board}/device/${example}/${example}.elf", + "setup_cmd": "${toolchain.setup_cmd} && python3 tools/get_deps.py ${get_deps}", + "get_deps": "${port}" + }, + "toolchains": { + "arm-none-eabi-gcc-14": { + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH" + }, + "aarch64-none-elf-gcc-10": { + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.xz && tar -C $HOME/toolchain -xf toolchain.tar.xz && echo \"$HOME/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin\" >> $GITHUB_PATH" + }, + "riscv-none-elf-gcc-13": { + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH" + }, + "msp430-gcc-9": { + "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2 && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.bz2 && tar -C $HOME/toolchain -xf toolchain.tar.bz2 && echo \"$HOME/toolchain/msp430-gcc-9.2.0.50_linux64/bin\" >> $GITHUB_PATH" + } + }, + "targets": [ + { + "port": "at32f402_405", + "board": "at_start_f402", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/artery/at32f402_405/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F402xC_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "at32f403a_407", + "board": "at32f403a_weact_blackpill", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/artery/at32f403a_407/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F403AxC_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "at32f413", + "board": "at_start_f413", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/artery/at32f413/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F413xC_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "at32f415", + "board": "at_start_f415", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/artery/at32f415/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F415xC_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "at32f423", + "board": "at_start_f423", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/artery/at32f423/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F423xC_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "at32f425", + "board": "at_start_f425", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/artery/at32f425/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x8_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "at32f435_437", + "board": "at_start_f435", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/artery/at32f435_437/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F435xM_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "broadcom_32bit", + "board": "raspberrypi_zero", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/broadcom/broadcom/link.ld", + "example": "cdc_msc" + }, + { + "port": "broadcom_64bit", + "board": "raspberrypi_cm4", + "toolchain": "aarch64-none-elf-gcc-10", + "ld": "hw/mcu/broadcom/broadcom/link8.ld", + "example": "cdc_msc" + }, + { + "port": "ch32v10x", + "board": "ch32v103r_r1_1v0", + "toolchain": "riscv-none-elf-gcc-13", + "ld": "hw/bsp/ch32v10x/linker/ch32v10x.ld", + "linker_vars": "__FLASH_SIZE=64K __RAM_SIZE=20K", + "example": "cdc_msc" + }, + { + "port": "ch32v20x", + "board": "ch32v203c_r0_1v0", + "toolchain": "riscv-none-elf-gcc-13", + "ld": "hw/bsp/ch32v20x/linker/ch32v20x.ld", + "linker_vars": "__flash_size=64K __ram_size=20K", + "example": "cdc_msc" + }, + { + "port": "ch32v30x", + "board": "ch32v307v_r1_1v0", + "toolchain": "riscv-none-elf-gcc-13", + "ld": "hw/bsp/ch32v30x/linker/ch32v30x.ld", + "linker_vars": "__flash_size=128K __ram_size=32K", + "example": "cdc_msc" + }, + { + "port": "da1469x", + "board": "da14695_dk_usb", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/da1469x/linker/da1469x.ld", + "example": "cdc_msc" + }, + { + "port": "fomu", + "board": "fomu", + "toolchain": "riscv-none-elf-gcc-13", + "ld": "hw/bsp/fomu/fomu.ld", + "example": "cdc_msc" + }, + { + "port": "gd32vf103", + "board": "sipeed_longan_nano", + "toolchain": "riscv-none-elf-gcc-13", + "ld": "hw/mcu/gd/nuclei-sdk/SoC/gd32vf103/Board/gd32vf103c_longan_nano/Source/GCC/gcc_gd32vf103xb_flashxip.ld", + "linker_vars": "__ROM_BASE=0x08000000 __ROM_SIZE=0x00020000 __RAM_BASE=0x20000000 __RAM_SIZE=0x00008000", + "example": "cdc_msc" + }, + { + "port": "hpmicro", + "board": "hpm6750evk2", + "toolchain": "riscv-none-elf-gcc-13", + "ld": "hw/mcu/hpmicro/hpm_sdk/soc/HPM6700/HPM6750/toolchains/gcc/flash_xip.ld", + "linker_vars": "_flash_size=16M _stack_size=16K _heap_size=16K", + "example": "cdc_msc" + }, + { + "port": "imxrt", + "board": "metro_m7_1011", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/nxp/mcux-sdk/devices/MIMXRT1011/gcc/MIMXRT1011xxxxx_flexspi_nor.ld", + "example": "cdc_msc" + }, + { + "port": "kinetis_k", + "board": "frdm_k64f", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/nxp/mcux-sdk/devices/MK64F12/gcc/MK64FN1M0xxx12_flash.ld", + "get_deps": "kinetis_k kinetis_kl", + "example": "cdc_msc" + }, + { + "port": "kinetis_k32l2", + "board": "frdm_k32l2a4s", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/nxp/mcux-sdk/devices/K32L2A41A/gcc/K32L2A41xxxxA_flash.ld", + "example": "cdc_msc" + }, + { + "port": "kinetis_kl", + "board": "frdm_kl25z", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/kinetis_kl/gcc/MKL25Z128xxx4_flash.ld", + "example": "cdc_msc" + }, + { + "port": "lpc11", + "board": "lpcxpresso11u37", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/lpc11/boards/lpcxpresso11u37/lpc11u37.ld", + "example": "cdc_msc" + }, + { + "port": "lpc13", + "board": "lpcxpresso1347", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/lpc13/boards/lpcxpresso1347/lpc1347.ld", + "example": "cdc_msc" + }, + { + "port": "lpc15", + "board": "lpcxpresso1549", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/lpc15/boards/lpcxpresso1549/lpc1549.ld", + "example": "cdc_msc" + }, + { + "port": "lpc17", + "board": "lpcxpresso1769", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld", + "example": "cdc_msc" + }, + { + "port": "lpc18", + "board": "lpcxpresso18s37", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld", + "example": "cdc_msc" + }, + { + "port": "lpc40", + "board": "ea4088_quickstart", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld", + "example": "cdc_msc" + }, + { + "port": "lpc43", + "board": "ea4357", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/lpc43/boards/ea4357/lpc4357.ld", + "example": "cdc_msc" + }, + { + "port": "lpc51", + "board": "lpcxpresso51u68", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC51U68/gcc/LPC51U68_flash.ld", + "example": "cdc_msc" + }, + { + "port": "lpc54", + "board": "lpcxpresso54114", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC54114/gcc/LPC54114J256_cm4_flash.ld", + "example": "cdc_msc" + }, + { + "port": "lpc55", + "board": "double_m33_express", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/lpc55/boards/double_m33_express/LPC55S69_cm33_core0_uf2.ld", + "example": "cdc_msc" + }, + { + "port": "maxim", + "board": "apard32690", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/maxim/linker/max32690.ld", + "example": "cdc_msc" + }, + { + "port": "mcx", + "board": "frdm_mcxa153", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/nxp/mcux-sdk/devices/MCXA153/gcc/MCXA153_flash.ld", + "example": "cdc_msc" + }, + { + "port": "mm32", + "board": "mm32f327x_mb39", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld", + "example": "cdc_msc" + }, + { + "port": "msp430", + "board": "msp_exp430f5529lp", + "toolchain": "msp430-gcc-9", + "ld": "hw/mcu/ti/msp430/msp430-gcc-support-files/include/msp430f5529.ld", + "example": "cdc_msc" + }, + { + "port": "msp432e4", + "board": "msp_exp432e401y", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/ti/msp432e4/Source/msp432e411y.ld", + "example": "cdc_msc" + }, + { + "port": "nrf", + "board": "adafruit_clue", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/nrf/linker/nrf52840_xxaa.ld", + "example": "cdc_msc" + }, + { + "port": "nuc100_120", + "board": "nutiny_sdk_nuc120", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/nuc100_120/boards/nutiny_sdk_nuc120/nuc120_flash.ld", + "example": "cdc_msc" + }, + { + "port": "nuc121_125", + "board": "nutiny_sdk_nuc121", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/nuc121_125/boards/nutiny_sdk_nuc121/nuc121_flash.ld", + "example": "cdc_msc" + }, + { + "port": "nuc126", + "board": "nutiny_nuc126v", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/nuc126/boards/nutiny_nuc126v/nuc126_flash.ld", + "example": "cdc_msc" + }, + { + "port": "nuc505", + "board": "nutiny_sdk_nuc505", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/nuc505/boards/nutiny_sdk_nuc505/nuc505_flashtoram.ld", + "example": "cdc_msc" + }, + { + "port": "ra", + "board": "portenta_c33", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/ra/boards/portenta_c33/script/memory_regions.ld hw/bsp/ra/boards/portenta_c33/script/fsp.ld", + "example": "cdc_msc" + }, + { + "port": "rw61x", + "board": "frdm_rw612", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/nxp/mcux-sdk/devices/RW612/gcc/RW612_flash.ld", + "example": "cdc_msc" + }, + { + "port": "samd11", + "board": "cynthion_d11", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/samd11/boards/cynthion_d11/cynthion_d11.ld", + "linker_vars": "BOOTLOADER_SIZE=0x800", + "example": "cdc_dual_ports" + }, + { + "port": "samd5x_e5x", + "board": "d5035_01", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld", + "example": "cdc_msc" + }, + { + "port": "samg", + "board": "samg55_xplained", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/samg/boards/samg55_xplained/samg55j19_flash.ld", + "example": "cdc_msc" + }, + { + "port": "stm32c0", + "board": "stm32c071nucleo", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32f0", + "board": "stm32f070rbnucleo", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld", + "example": "cdc_msc" + }, + { + "port": "stm32f1", + "board": "stm32f103_bluepill", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32f2", + "board": "stm32f207nucleo", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32f2/boards/stm32f207nucleo/STM32F207ZGTx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32f3", + "board": "stm32f303disco", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32f3/boards/stm32f303disco/STM32F303VCTx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32f4", + "board": "feather_stm32f405", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32f7", + "board": "stlinkv3mini", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32g0", + "board": "stm32g0b1nucleo", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32g4", + "board": "b_g474e_dpow1", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32h5", + "board": "stm32h503nucleo", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32h7", + "board": "daisyseed", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld", + "example": "cdc_msc" + }, + { + "port": "stm32h7rs", + "board": "stm32h7s3nucleo", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32h7rs/linker/stm32h7s3xx_flash.ld", + "linker_vars": "__FLASH_BEGIN=0x08000000 __FLASH_SIZE=0x00010000 __RAM_BEGIN=0x24000000 __RAM_SIZE=0x4FC00 __RAM_NONCACHEABLEBUFFER_SIZE=0x400", + "example": "cdc_msc" + }, + { + "port": "stm32l0", + "board": "stm32l052dap52", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32l4", + "board": "stm32l412nucleo", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32n6", + "board": "stm32n6570dk", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32n6/boards/stm32n6570dk/STM32N657XX_AXISRAM2_fsbl.ld", + "example": "cdc_msc" + }, + { + "port": "stm32u0", + "board": "stm32u083cdk", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32u0/boards/stm32u083cdk/STM32U083MCTx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32u5", + "board": "b_u585i_iot2a", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld", + "example": "cdc_msc" + }, + { + "port": "stm32wb", + "board": "stm32wb55nucleo", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld", + "example": "cdc_msc" + }, + { + "port": "stm32wba", + "board": "stm32wba_nucleo", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/stm32wba/linker/STM32WBA65xx_FLASH_ns.ld", + "example": "cdc_msc" + }, + { + "port": "tm4c", + "board": "ek_tm4c123gxl", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld", + "example": "cdc_msc" + }, + { + "port": "xmc4000", + "board": "xmc4500_relax", + "toolchain": "arm-none-eabi-gcc-14", + "ld": "hw/mcu/infineon/mtb-xmclib-cat3/CMSIS/Infineon/COMPONENT_XMC4500/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld", + "example": "cdc_msc" + } + ] +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc5b1975e..e0c1d0a14 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -386,10 +386,6 @@ jobs: merge-multiple: true continue-on-error: true - - name: Save PR number - if: steps.download.outcome == 'success' - run: echo ${{ github.event.number }} > reports/pr_number.txt - - name: Upload Membrowse Comment Artifact if: steps.download.outcome == 'success' uses: actions/upload-artifact@v5 diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index e0fef7ce4..e62c10ca1 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -78,7 +78,7 @@ jobs: run: | for dir in cmake-build/cmake-build-*; do board=$(basename "$dir" | sed 's/cmake-build-//') - ld_path=$(jq -r --arg b "$board" '.[] | select(.board == $b) | .ld // empty' .github/membrowse-targets.json) + ld_path=$(jq -r --arg b "$board" '.targets[] | select(.board == $b) | .ld // empty' .github/membrowse-targets.json) if [ -n "$ld_path" ] && [ -f "$ld_path" ]; then mkdir -p "cmake-build/$(dirname "$ld_path")" cp "$ld_path" "cmake-build/$ld_path" diff --git a/.github/workflows/membrowse-comment.yml b/.github/workflows/membrowse-comment.yml index a3db37360..a99c9db51 100644 --- a/.github/workflows/membrowse-comment.yml +++ b/.github/workflows/membrowse-comment.yml @@ -11,11 +11,14 @@ jobs: runs-on: ubuntu-latest if: > github.event.workflow_run.event == 'pull_request' && - github.event.workflow_run.conclusion == 'success' + github.event.workflow_run.conclusion != 'cancelled' permissions: actions: read pull-requests: write steps: + - name: Checkout repository + uses: actions/checkout@v6 + - name: Download Artifacts id: download uses: actions/download-artifact@v5 @@ -26,19 +29,10 @@ jobs: path: reports continue-on-error: true - - name: Read PR Number - if: steps.download.outcome == 'success' - id: pr_number - run: | - if [ -f reports/pr_number.txt ]; then - echo "number=$(cat reports/pr_number.txt)" >> $GITHUB_OUTPUT - fi - - name: Post Membrowse PR comment - if: steps.download.outcome == 'success' && steps.pr_number.outputs.number != '' + if: steps.download.outcome == 'success' uses: membrowse/membrowse-action/comment-action@v1 with: json_files: 'reports/*.json' - pr_number: ${{ steps.pr_number.outputs.number }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/membrowse-onboard.yml b/.github/workflows/membrowse-onboard.yml index a183297b2..aa7204ffa 100644 --- a/.github/workflows/membrowse-onboard.yml +++ b/.github/workflows/membrowse-onboard.yml @@ -13,14 +13,17 @@ jobs: load-targets: runs-on: ubuntu-22.04 outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} + targets: ${{ steps.load.outputs.targets }} + toolchains: ${{ steps.load.outputs.toolchains }} steps: - name: Checkout repository uses: actions/checkout@v5 - name: Load target matrix - id: set-matrix - run: echo "matrix=$(jq -c '.' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT + id: load + run: | + echo "targets=$(jq -c '.targets' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT + echo "toolchains=$(jq -c '.toolchains' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT onboard: needs: load-targets @@ -28,7 +31,7 @@ jobs: strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.load-targets.outputs.matrix) }} + include: ${{ fromJson(needs.load-targets.outputs.targets) }} steps: - name: Checkout repository @@ -38,7 +41,8 @@ jobs: submodules: recursive - name: Install packages - run: ${{ matrix.setup_cmd }} + run: | + ${{ fromJson(needs.load-targets.outputs.toolchains)[matrix.toolchain].setup_cmd }} && python3 tools/get_deps.py ${{ matrix.get_deps || matrix.port }} - name: Setup ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -48,11 +52,11 @@ jobs: - name: Run Membrowse Onboard Action uses: membrowse/membrowse-action/onboard-action@v1 with: - target_name: ${{ matrix.target_name }} + target_name: ${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }} num_commits: ${{ github.event.inputs.num_commits }} - build_script: ${{ matrix.build_cmd }} - elf: ${{ matrix.elf }} + build_script: python3 tools/build.py -s cmake -b ${{ matrix.board }} + elf: cmake-build/cmake-build-${{ matrix.board }}/device/${{ matrix.example }}/${{ matrix.example }}.elf ld: ${{ matrix.ld }} - linker_vars: ${{ matrix.linker_vars }} + linker_vars: ${{ matrix.linker_vars || '' }} api_key: ${{ secrets.MEMBROWSE_API_KEY }} api_url: ${{ vars.MEMBROWSE_API_URL }} diff --git a/.github/workflows/membrowse-report.yml b/.github/workflows/membrowse-report.yml index aff9fe138..0667418e6 100644 --- a/.github/workflows/membrowse-report.yml +++ b/.github/workflows/membrowse-report.yml @@ -16,14 +16,14 @@ jobs: load-targets: runs-on: ubuntu-latest outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} + targets: ${{ steps.load.outputs.targets }} steps: - name: Checkout repository uses: actions/checkout@v6 - name: Load target matrix - id: set-matrix - run: echo "matrix=$(jq -c '.' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT + id: load + run: echo "targets=$(jq -c '.targets' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT analyze: needs: [load-targets] @@ -31,7 +31,7 @@ jobs: strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.load-targets.outputs.matrix) }} + include: ${{ fromJson(needs.load-targets.outputs.targets) }} steps: - name: Checkout repository @@ -58,7 +58,7 @@ jobs: - name: Check if ELF exists id: check-elf run: | - if [ -f "${{ matrix.elf }}" ]; then + if [ -f "cmake-build/cmake-build-${{ matrix.board }}/device/${{ matrix.example }}/${{ matrix.example }}.elf" ]; then echo "exists=true" >> $GITHUB_OUTPUT else echo "exists=false" >> $GITHUB_OUTPUT @@ -71,10 +71,10 @@ jobs: continue-on-error: true uses: membrowse/membrowse-action@v1 with: - target_name: ${{ matrix.target_name }} - elf: ${{ matrix.elf }} + target_name: ${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }} + elf: cmake-build/cmake-build-${{ matrix.board }}/device/${{ matrix.example }}/${{ matrix.example }}.elf ld: ${{ matrix.ld }} - linker_vars: ${{ matrix.linker_vars }} + linker_vars: ${{ matrix.linker_vars || '' }} api_key: ${{ secrets.MEMBROWSE_API_KEY }} api_url: ${{ vars.MEMBROWSE_API_URL }} verbose: INFO @@ -87,7 +87,7 @@ jobs: continue-on-error: true uses: membrowse/membrowse-action@v1 with: - target_name: ${{ matrix.target_name }} + target_name: ${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }} identical: true api_key: ${{ secrets.MEMBROWSE_API_KEY }} api_url: ${{ vars.MEMBROWSE_API_URL }} @@ -97,5 +97,5 @@ jobs: if: steps.membrowse.outcome == 'success' || steps.membrowse-identical.outcome == 'success' uses: actions/upload-artifact@v5 with: - name: membrowse-report-${{ matrix.target_name }} + name: membrowse-report-${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }} path: ${{ steps.membrowse.outputs.report_path || steps.membrowse-identical.outputs.report_path }} -- cgit v1.3.1 From b85a3967bfaf4943848900780576984b3d2167ca Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Feb 2026 11:40:13 +0700 Subject: skip zephyr and membrowse steps temporarily --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0c1d0a14..c8dca0a63 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -216,7 +216,8 @@ jobs: # --------------------------------------- zephyr: needs: [check-paths] - if: needs.check-paths.outputs.code_changed == 'true' + # skip zephyr build due to failed build, fix later + if: false && needs.check-paths.outputs.code_changed == 'true' runs-on: ubuntu-latest steps: - name: Checkout TinyUSB @@ -365,7 +366,9 @@ jobs: membrowse-comment: needs: [check-paths, membrowse] + # skip membrowse comment since it is kind of distracting if: > + false && always() && github.event_name == 'pull_request' && needs.check-paths.outputs.code_changed == 'true' -- cgit v1.3.1 From 3cef022737e4529c1ae709e4061c1530a849c07b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 6 Feb 2026 17:40:13 +0700 Subject: set folder property for flash tool targets update build.yml only build with pr and push-to-master --- .github/pull_request_template.md | 5 -- .github/workflows/build.yml | 102 +++++++++++++-------------------------- hw/bsp/family_support.cmake | 26 ++++++++++ 3 files changed, 60 insertions(+), 73 deletions(-) delete mode 100644 .github/pull_request_template.md (limited to '.github/workflows') diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index aa148eb79..000000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,5 +0,0 @@ -**Describe the PR** -A clear and concise description of what this PR solve. - -**Additional context** -If applicable, add any other context about the PR and/or screenshots here. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c8dca0a63..ded4e816c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,9 +4,33 @@ on: workflow_dispatch: push: branches: [master] + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'tools/build.py' + - 'tools/get_deps.py' + - '.github/actions/**' + - '.github/workflows/build.yml' + - '.github/workflows/build_util.yml' + - '.github/workflows/ci_set_matrix.py' pull_request: + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'test/hil/**' + - 'tools/build.py' + - 'tools/get_deps.py' + - '.github/actions/**' + - '.github/workflows/build.yml' + - '.github/workflows/build_util.yml' + - '.github/workflows/ci_set_matrix.py' release: types: [ published ] + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -15,44 +39,7 @@ env: HIL_JSON: test/hil/tinyusb.json jobs: - # Check if code paths changed (skip builds if doc-only) - check-paths: - if: github.event_name == 'pull_request' || github.event_name == 'push' - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - outputs: - code_changed: ${{ steps.filter.outputs.code }} - steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 2 # Needed for push commit comparison - - uses: dorny/paths-filter@v3 - id: filter - with: - filters: | - code: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'test/hil/**' - - 'tools/build.py' - - 'tools/get_deps.py' - - '.github/actions/**' - - '.github/workflows/build.yml' - - '.github/workflows/build_util.yml' - - '.github/workflows/ci_set_matrix.py' - set-matrix: - needs: [check-paths] - if: | - always() && ( - github.event_name == 'release' || - github.event_name == 'workflow_dispatch' || - needs.check-paths.outputs.code_changed == 'true' - ) runs-on: ubuntu-latest outputs: json: ${{ steps.set-matrix-json.outputs.matrix }} @@ -197,8 +184,6 @@ jobs: # Build Make/CMake on Windows/MacOS # --------------------------------------- build-os: - needs: [check-paths] - if: needs.check-paths.outputs.code_changed == 'true' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -215,9 +200,8 @@ jobs: # Zephyr # --------------------------------------- zephyr: - needs: [check-paths] # skip zephyr build due to failed build, fix later - if: false && needs.check-paths.outputs.code_changed == 'true' + if: false runs-on: ubuntu-latest steps: - name: Checkout TinyUSB @@ -239,10 +223,8 @@ jobs: # Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR # --------------------------------------- hil-build: - needs: [check-paths, set-matrix] - if: | - github.repository_owner == 'hathach' && - (github.event_name == 'workflow_dispatch' || needs.check-paths.outputs.code_changed == 'true') + needs: set-matrix + if: github.repository_owner == 'hathach' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -261,10 +243,7 @@ jobs: # self-hosted on local VM, for attached hardware checkout HIL_JSON # --------------------------------------- hil-tinyusb: - needs: [check-paths, hil-build] - if: | - github.repository_owner == 'hathach' && - (github.event_name == 'release' || github.event_name == 'workflow_dispatch' || needs.check-paths.outputs.code_changed == 'true') + needs: hil-build runs-on: [ self-hosted, X64, hathach, hardware-in-the-loop ] steps: - name: Get Skip Boards from previous run @@ -304,11 +283,9 @@ jobs: # Since IAR Token secret is not passed to forked PR, only build non-forked PR # --------------------------------------- hil-hfp: - needs: [check-paths] if: | github.repository_owner == 'hathach' && - github.event.pull_request.head.repo.fork == false && - (github.event_name == 'release' || github.event_name == 'workflow_dispatch' || needs.check-paths.outputs.code_changed == 'true') + !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) runs-on: [ self-hosted, Linux, X64, hifiphile ] env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} @@ -348,30 +325,19 @@ jobs: # PR: only runs if code changed (doc-only PRs skip entirely) # --------------------------------------- membrowse: - needs: [check-paths, cmake] - if: | - always() && !cancelled() && ( - github.event_name == 'push' || - github.event_name == 'release' || - github.event_name == 'workflow_dispatch' || - (github.event_name == 'pull_request' && needs.check-paths.outputs.code_changed == 'true') - ) + needs: cmake permissions: contents: read actions: read uses: ./.github/workflows/membrowse-report.yml with: - code_changed: ${{ needs.check-paths.outputs.code_changed == 'true' || github.event_name == 'release' || github.event_name == 'workflow_dispatch' }} + code_changed: true secrets: inherit membrowse-comment: - needs: [check-paths, membrowse] - # skip membrowse comment since it is kind of distracting - if: > - false && - always() && - github.event_name == 'pull_request' && - needs.check-paths.outputs.code_changed == 'true' + needs: membrowse + # skip membrowse comment since it is too verbal + if: false && github.event_name == 'pull_request' runs-on: ubuntu-latest permissions: contents: read diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index baa8422fe..ad9a4f94d 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -238,6 +238,7 @@ function(family_add_bloaty TARGET) COMMAND ${BLOATY_EXE} ${OPTION_LIST} $ VERBATIM) + set_property(TARGET ${TARGET}-bloaty PROPERTY FOLDER ${TARGET}) # post build # add_custom_command(TARGET ${TARGET} POST_BUILD # COMMAND ${BLOATY_EXE} --csv ${OPTION_LIST} $ > ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_bloaty.csv @@ -258,6 +259,8 @@ function(family_add_linkermap TARGET) VERBATIM ) + set_property(TARGET ${TARGET}-linkermap PROPERTY FOLDER ${TARGET}) + # post build add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND python ${LINKERMAP_PY} ${OPTION_LIST} $.map @@ -508,6 +511,8 @@ exit" COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} ${OPTION_LIST} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${BINARY_TARGET}.jlink VERBATIM ) + + set_property(TARGET ${NAME_TARGET}-jlink PROPERTY FOLDER ${TARGET}) endfunction() @@ -521,6 +526,8 @@ function(family_flash_stlink TARGET) DEPENDS ${TARGET} COMMAND ${STM32_PROGRAMMER_CLI} --connect port=swd --write $ --go ) + + set_property(TARGET ${TARGET}-stlink PROPERTY FOLDER ${TARGET}) endfunction() @@ -534,6 +541,8 @@ function(family_flash_stflash TARGET) DEPENDS ${TARGET} COMMAND ${ST_FLASH} write $/${TARGET}.bin 0x8000000 ) + + set_property(TARGET ${TARGET}-stflash PROPERTY FOLDER ${TARGET}) endfunction() @@ -560,6 +569,8 @@ function(family_flash_openocd TARGET) COMMAND ${OPENOCD} -c "tcl_port disabled; gdb_port disabled" ${OPTION_LIST} -c "init; halt; program $" -c reset ${OPTION_LIST2} -c exit VERBATIM ) + + set_property(TARGET ${TARGET}-openocd PROPERTY FOLDER ${TARGET}) endfunction() @@ -621,6 +632,8 @@ function(family_flash_wlink_rs TARGET) DEPENDS ${TARGET} COMMAND ${WLINK_RS} flash $ ) + + set_property(TARGET ${TARGET}-wlink-rs PROPERTY FOLDER ${TARGET}) endfunction() @@ -634,6 +647,8 @@ function(family_flash_pyocd TARGET) DEPENDS ${TARGET} COMMAND ${PYOCD} flash -t ${PYOCD_TARGET} $ ) + + set_property(TARGET ${TARGET}-pyocd PROPERTY FOLDER ${TARGET}) endfunction() @@ -643,6 +658,7 @@ function(family_flash_uf2 TARGET FAMILY_ID) DEPENDS ${TARGET} COMMAND python ${UF2CONV_PY} -f ${FAMILY_ID} --deploy $/${TARGET}.uf2 ) + set_property(TARGET ${TARGET}-uf2 PROPERTY FOLDER ${TARGET}) endfunction() @@ -657,6 +673,8 @@ function(family_flash_teensy TARGET) COMMAND ${CMAKE_OBJCOPY} -Oihex $ $/${TARGET}.hex COMMAND ${TEENSY_CLI} --mcu=${TEENSY_MCU} -w -s $/${TARGET}.hex ) + + set_property(TARGET ${TARGET}-teensy PROPERTY FOLDER ${TARGET}) endfunction() @@ -675,6 +693,8 @@ function(family_flash_nxplink TARGET) DEPENDS ${TARGET} COMMAND ${LINKSERVER_PATH} flash ${NXPLINK_DEVICE} load $ ) + + set_property(TARGET ${TARGET}-nxplink PROPERTY FOLDER ${TARGET}) endfunction() @@ -688,6 +708,8 @@ function(family_flash_dfu_util TARGET OPTION) COMMAND ${DFU_UTIL} -R -d ${DFU_UTIL_VID_PID} -a 0 -D $/${TARGET}.bin VERBATIM ) + + set_property(TARGET ${TARGET}-dfu-util PROPERTY FOLDER ${TARGET}) endfunction() function(family_flash_msp430flasher TARGET) @@ -703,6 +725,8 @@ function(family_flash_msp430flasher TARGET) COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH=${MSP430FLASHER_PARENT_DIR} ${MSP430FLASHER} -w $/${TARGET}.hex -z [VCC] ) + + set_property(TARGET ${TARGET}-msp430flasher PROPERTY FOLDER ${TARGET}) endfunction() function(family_flash_uniflash TARGET) @@ -717,6 +741,8 @@ function(family_flash_uniflash TARGET) COMMAND ${DSLITE} ${UNIFLASH_OPTION} -f $/${TARGET}.hex VERBATIM ) + + set_property(TARGET ${TARGET}-uniflash PROPERTY FOLDER ${TARGET}) endfunction() #---------------------------------- -- cgit v1.3.1 From 4632441ae7b48f1d1a32ef99e05991ea1e41f6f4 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Feb 2026 17:31:53 +0700 Subject: add back check-path job to path filter, make sure workflow always run to register commit chain with membrowse --- .github/workflows/build.yml | 61 +++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 24 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ded4e816c..b9e1b6201 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,30 +4,7 @@ on: workflow_dispatch: push: branches: [master] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/build.py' - - 'tools/get_deps.py' - - '.github/actions/**' - - '.github/workflows/build.yml' - - '.github/workflows/build_util.yml' - - '.github/workflows/ci_set_matrix.py' pull_request: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'test/hil/**' - - 'tools/build.py' - - 'tools/get_deps.py' - - '.github/actions/**' - - '.github/workflows/build.yml' - - '.github/workflows/build_util.yml' - - '.github/workflows/ci_set_matrix.py' release: types: [ published ] @@ -39,7 +16,39 @@ env: HIL_JSON: test/hil/tinyusb.json jobs: + # Check if the code changes and we need to run ci build + # Cannot use paths filter in the on-event since we want this workflow to run even no code change to register commit chain + check-paths: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + code_changed: ${{ steps.filter.outputs.code }} + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 2 # Needed for push commit comparison + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + code: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'test/hil/**' + - 'tools/build.py' + - 'tools/get_deps.py' + - '.github/actions/**' + - '.github/workflows/build.yml' + - '.github/workflows/build_util.yml' + - '.github/workflows/ci_set_matrix.py' + set-matrix: + needs: [ check-paths ] + if: needs.check-paths.outputs.code_changed == 'true' runs-on: ubuntu-latest outputs: json: ${{ steps.set-matrix-json.outputs.matrix }} @@ -184,6 +193,8 @@ jobs: # Build Make/CMake on Windows/MacOS # --------------------------------------- build-os: + needs: [ check-paths ] + if: needs.check-paths.outputs.code_changed == 'true' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -200,8 +211,9 @@ jobs: # Zephyr # --------------------------------------- zephyr: + needs: [ check-paths ] # skip zephyr build due to failed build, fix later - if: false + if: false && needs.check-paths.outputs.code_changed == 'true' runs-on: ubuntu-latest steps: - name: Checkout TinyUSB @@ -283,6 +295,7 @@ jobs: # Since IAR Token secret is not passed to forked PR, only build non-forked PR # --------------------------------------- hil-hfp: + needs: [ check-paths ] if: | github.repository_owner == 'hathach' && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) -- cgit v1.3.1 From a1a4f34e2261bb591258870870e2fd08ca60cda7 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Sat, 7 Feb 2026 18:00:11 +0700 Subject: Update .github/workflows/build.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b9e1b6201..ee03b82fa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ env: jobs: # Check if the code changes and we need to run ci build - # Cannot use paths filter in the on-event since we want this workflow to run even no code change to register commit chain + # Cannot use paths filter in the on-event since we want this workflow to run even when there are no code changes, to register the commit chain check-paths: runs-on: ubuntu-latest permissions: -- cgit v1.3.1 From 13ae5244c0daa44f3ff9bb5c85484e24ef4523c7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:18:25 +0000 Subject: Update membrowse job to run on all pushes for commit chain tracking Co-authored-by: hathach <249515+hathach@users.noreply.github.com> --- .github/workflows/build.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ee03b82fa..352875a9d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -338,13 +338,20 @@ jobs: # PR: only runs if code changed (doc-only PRs skip entirely) # --------------------------------------- membrowse: - needs: cmake + needs: [check-paths, cmake] + if: | + always() && !cancelled() && ( + github.event_name == 'push' || + github.event_name == 'release' || + github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && needs.check-paths.outputs.code_changed == 'true') + ) permissions: contents: read actions: read uses: ./.github/workflows/membrowse-report.yml with: - code_changed: true + code_changed: ${{ needs.check-paths.outputs.code_changed == 'true' || github.event_name == 'release' || github.event_name == 'workflow_dispatch' }} secrets: inherit membrowse-comment: -- cgit v1.3.1 From b66c3f75c311f1424c6d7085c7fc3ad14c544de6 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Feb 2026 12:31:24 +0700 Subject: update matrix build --- .github/workflows/ci_set_matrix.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 9ab08601d..05a48b6c9 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -15,8 +15,8 @@ toolchain_list = [ # family: [supported toolchain] family_list = { - "at32f45x at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437 broadcom_32bit da1469x": [ - "arm-gcc"], + "at32f45x at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437": ["arm-gcc"], + "broadcom_32bit da1469x": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], "ch32v10x ch32v20x ch32v30x fomu gd32vf103 hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], @@ -38,9 +38,9 @@ family_list = { "stm32h7": ["arm-gcc", "arm-clang", "arm-iar"], "stm32h7rs stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32n6": ["arm-gcc"], - "stm32u0 stm32wb stm32wba": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32u5": ["arm-gcc", "arm-clang", "arm-iar"], - "-bespressif_s2_devkitc": ["esp-idf"], + "stm32u0 stm32u5": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32wb stm32wba": ["arm-gcc", "arm-clang", "arm-iar"], + # "-bespressif_s2_devkitc": ["esp-idf"], # S3, P4 will be built by hil test # "-bespressif_s3_devkitm": ["esp-idf"], # "-bespressif_p4_function_ev": ["esp-idf"], -- cgit v1.3.1 From 39b157d22f8a82264f07cdd31396c15b7a9c9e6d Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Feb 2026 23:45:24 +0700 Subject: add membrowse-upload target and use it in ci after build --- .github/actions/get_deps/action.yml | 2 + .github/workflows/build.yml | 92 +++++++++++++++++----------------- .github/workflows/build_util.yml | 14 ++++-- .github/workflows/membrowse-report.yml | 1 - hw/bsp/family_support.cmake | 5 ++ tools/build.py | 13 +++-- 6 files changed, 73 insertions(+), 54 deletions(-) (limited to '.github/workflows') diff --git a/.github/actions/get_deps/action.yml b/.github/actions/get_deps/action.yml index a84db893b..8ea36ce78 100644 --- a/.github/actions/get_deps/action.yml +++ b/.github/actions/get_deps/action.yml @@ -22,6 +22,8 @@ runs: NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip wget $NINJA_URL -O ninja-linux.zip unzip ninja-linux.zip -d ninja-bin + pip install membrowse + #echo >> $GITHUB_PATH "$HOME/.local/bin" echo >> $GITHUB_PATH "${{ github.workspace }}/ninja-bin" shell: bash diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 352875a9d..2b0c38c4f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,7 +93,9 @@ jobs: build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} build-options: '--one-first' upload-metrics: true - upload-artifacts: true + upload-artifacts: false + upload-membrowse: true + secrets: inherit code-metrics: needs: cmake @@ -337,47 +339,47 @@ jobs: # Push: always runs (uses identical for doc-only to maintain commit chain) # PR: only runs if code changed (doc-only PRs skip entirely) # --------------------------------------- - membrowse: - needs: [check-paths, cmake] - if: | - always() && !cancelled() && ( - github.event_name == 'push' || - github.event_name == 'release' || - github.event_name == 'workflow_dispatch' || - (github.event_name == 'pull_request' && needs.check-paths.outputs.code_changed == 'true') - ) - permissions: - contents: read - actions: read - uses: ./.github/workflows/membrowse-report.yml - with: - code_changed: ${{ needs.check-paths.outputs.code_changed == 'true' || github.event_name == 'release' || github.event_name == 'workflow_dispatch' }} - secrets: inherit - - membrowse-comment: - needs: membrowse - # skip membrowse comment since it is too verbal - if: false && github.event_name == 'pull_request' - runs-on: ubuntu-latest - permissions: - contents: read - actions: read - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Download report artifacts - id: download - uses: actions/download-artifact@v5 - with: - pattern: membrowse-report-* - path: reports - merge-multiple: true - continue-on-error: true - - - name: Upload Membrowse Comment Artifact - if: steps.download.outcome == 'success' - uses: actions/upload-artifact@v5 - with: - name: membrowse-comment - path: reports/ +# membrowse: +# needs: [check-paths, cmake] +# if: | +# always() && !cancelled() && ( +# github.event_name == 'push' || +# github.event_name == 'release' || +# github.event_name == 'workflow_dispatch' || +# (github.event_name == 'pull_request' && needs.check-paths.outputs.code_changed == 'true') +# ) +# permissions: +# contents: read +# actions: read +# uses: ./.github/workflows/membrowse-report.yml +# with: +# code_changed: ${{ needs.check-paths.outputs.code_changed == 'true' || github.event_name == 'release' || github.event_name == 'workflow_dispatch' }} +# secrets: inherit +# +# membrowse-comment: +# needs: membrowse +# # skip membrowse comment since it is too verbal +# if: false && github.event_name == 'pull_request' +# runs-on: ubuntu-latest +# permissions: +# contents: read +# actions: read +# steps: +# - name: Checkout repository +# uses: actions/checkout@v6 +# +# - name: Download report artifacts +# id: download +# uses: actions/download-artifact@v5 +# with: +# pattern: membrowse-report-* +# path: reports +# merge-multiple: true +# continue-on-error: true +# +# - name: Upload Membrowse Comment Artifact +# if: steps.download.outcome == 'success' +# uses: actions/upload-artifact@v5 +# with: +# name: membrowse-comment +# path: reports/ diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index e62c10ca1..8a3dd8f91 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -24,6 +24,10 @@ on: required: false default: false type: boolean + upload-membrowse: + required: false + default: false + type: boolean os: required: false type: string @@ -54,15 +58,17 @@ jobs: - name: Build env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} + MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} + MEMBROWSE_UPLOAD_OPTION: ${{ inputs.upload-membrowse && '--membrowse-upload' || '' }} TOOLCHAIN: ${{ inputs.toolchain }} run: | if [ "$TOOLCHAIN" == "esp-idf" ]; then - docker run --rm -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py ${{ matrix.arg }} + docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py $MEMBROWSE_UPLOAD_OPTION ${{ matrix.arg }} elif [ "${{ inputs.build-system }}" == "cmake-make" ] || [ "${{ inputs.build-system }}" == "make-cmake" ]; then - python tools/build.py -s make ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} - python tools/build.py -s cmake ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} + python tools/build.py -s make $MEMBROWSE_UPLOAD_OPTION ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} + python tools/build.py -s cmake $MEMBROWSE_UPLOAD_OPTION ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} else - python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} + python tools/build.py -s ${{ inputs.build-system }} $MEMBROWSE_UPLOAD_OPTION ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} fi shell: bash diff --git a/.github/workflows/membrowse-report.yml b/.github/workflows/membrowse-report.yml index 0667418e6..f86b047df 100644 --- a/.github/workflows/membrowse-report.yml +++ b/.github/workflows/membrowse-report.yml @@ -38,7 +38,6 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 0 - submodules: recursive # Download artifacts when code changed (build artifacts available) - name: Download build artifacts diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 335b56c72..57a323c4a 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -298,6 +298,11 @@ ${MEMBROWSE_EXE} report ${OPTION} $ \"$ld_scripts\"") VERBATIM ) + if (NOT TARGET examples-membrowse-upload) + add_custom_target(examples-membrowse-upload) + endif () + add_dependencies(examples-membrowse-upload ${TARGET}-membrowse-upload) + set_property(TARGET ${TARGET}-membrowse PROPERTY FOLDER ${TARGET}) set_property(TARGET ${TARGET}-membrowse-upload PROPERTY FOLDER ${TARGET}) endif () diff --git a/tools/build.py b/tools/build.py index d22d06a0b..bc032fb91 100755 --- a/tools/build.py +++ b/tools/build.py @@ -106,7 +106,7 @@ def print_build_result(board, example, status, duration): # ----------------------------- # CMake # ----------------------------- -def cmake_board(board, build_args, build_flags_on): +def cmake_board(board, build_args, build_flags_on, membrowse_upload): ret = [0, 0, 0] start_time = time.monotonic() @@ -142,6 +142,8 @@ def cmake_board(board, build_args, build_flags_on): if rcmd.returncode == 0: ret[0] += 1 run_cmd(["cmake", "--build", build_dir, '--target', 'tinyusb_metrics']) + if membrowse_upload: + run_cmd(["cmake", "--build", build_dir, '--target', 'examples-membrowse-upload']) # print(rcmd.stdout.decode("utf-8")) else: ret[1] += 1 @@ -198,13 +200,13 @@ def make_board(board, build_args): # ----------------------------- # Build Family # ----------------------------- -def build_boards_list(boards, build_defines, build_system, build_flags_on): +def build_boards_list(boards, build_defines, build_system, build_flags_on, membrowse_upload): ret = [0, 0, 0] for b in boards: r = [0, 0, 0] if build_system == 'cmake': build_args = [f'-D{d}' for d in build_defines] - r = cmake_board(b, build_args, build_flags_on) + r = cmake_board(b, build_args, build_flags_on, membrowse_upload) elif build_system == 'make': build_args = ' '.join(f'{d}' for d in build_defines) r = make_board(b, build_args) @@ -273,6 +275,8 @@ def main(): parser.add_argument('--one-first', action='store_true', default=False, help='Build only the first board (alphabetical) of each specified family') parser.add_argument('-j', '--jobs', type=int, default=os.cpu_count(), help='Number of jobs to run in parallel') + parser.add_argument('--membrowse-upload', action='store_true', default=False, + help='Run examples-membrowse-upload target after successful CMake build') parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') args = parser.parse_args() @@ -284,6 +288,7 @@ def main(): build_flags_on = args.build_flags_on one_random = args.one_random one_first = args.one_first + membrowse_upload = args.membrowse_upload verbose = args.verbose clean_build = args.clean parallel_jobs = args.jobs @@ -314,7 +319,7 @@ def main(): all_boards.extend(get_family_boards(f, one_random, one_first)) # build all boards - result = build_boards_list(all_boards, build_defines, build_system, build_flags_on) + result = build_boards_list(all_boards, build_defines, build_system, build_flags_on, membrowse_upload) total_time = time.monotonic() - total_time print(build_separator) -- cgit v1.3.1 From dcb94d2a1224c333c4d954e3ddc82174cdfa159c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 Feb 2026 00:16:52 +0700 Subject: 1 family per job in ci_set_matrix.py --- .github/workflows/ci_set_matrix.py | 74 ++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 15 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 05a48b6c9..cd7dfa76b 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -15,32 +15,76 @@ toolchain_list = [ # family: [supported toolchain] family_list = { - "at32f45x at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437": ["arm-gcc"], - "broadcom_32bit da1469x": ["arm-gcc"], + "at32f402_405": ["arm-gcc"], + "at32f403a_407": ["arm-gcc"], + "at32f413": ["arm-gcc"], + "at32f415": ["arm-gcc"], + "at32f423": ["arm-gcc"], + "at32f425": ["arm-gcc"], + "at32f435_437": ["arm-gcc"], + "at32f45x": ["arm-gcc"], + "broadcom_32bit": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], - "ch32v10x ch32v20x ch32v30x fomu gd32vf103 hpmicro": ["riscv-gcc"], + "ch32v10x": ["riscv-gcc"], + "ch32v20x": ["riscv-gcc"], + "ch32v30x": ["riscv-gcc"], + "da1469x": ["arm-gcc"], + "fomu": ["riscv-gcc"], + "gd32vf103": ["riscv-gcc"], + "hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], - "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], - "lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], - "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], - "maxim mcx mm32 msp432e4 rw61x tm4c": ["arm-gcc"], + "kinetis_k": ["arm-gcc", "arm-clang"], + "kinetis_k32l2": ["arm-gcc", "arm-clang"], + "kinetis_kl": ["arm-gcc", "arm-clang"], + "lpc11": ["arm-gcc", "arm-clang"], + "lpc13": ["arm-gcc", "arm-clang"], + "lpc15": ["arm-gcc", "arm-clang"], + "lpc17": ["arm-gcc", "arm-clang"], + "lpc18": ["arm-gcc", "arm-clang"], + "lpc40": ["arm-gcc", "arm-clang"], + "lpc43": ["arm-gcc", "arm-clang"], + "lpc51": ["arm-gcc", "arm-clang"], + "lpc54": ["arm-gcc", "arm-clang"], + "lpc55": ["arm-gcc", "arm-clang"], + "maxim": ["arm-gcc"], + "mcx": ["arm-gcc"], + "mm32": ["arm-gcc"], "msp430": ["msp430-gcc"], + "msp432e4": ["arm-gcc"], "nrf": ["arm-gcc", "arm-clang"], - "nuc100_120 nuc121_125 nuc126 nuc505 xmc4000": ["arm-gcc"], + "nuc100_120": ["arm-gcc"], + "nuc121_125": ["arm-gcc"], + "nuc126": ["arm-gcc"], + "nuc505": ["arm-gcc"], "ra": ["arm-gcc"], "rp2040": ["arm-gcc"], + "rw61x": ["arm-gcc"], "rx": ["rx-gcc"], - "samd11 samd2x_l2x samd5x_e5x samg": ["arm-gcc", "arm-clang"], - "stm32c0 stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang", "arm-iar"], + "samd11": ["arm-gcc", "arm-clang"], + "samd2x_l2x": ["arm-gcc", "arm-clang"], + "samd5x_e5x": ["arm-gcc", "arm-clang"], + "samg": ["arm-gcc", "arm-clang"], + "stm32c0": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32f0": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32f1": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32f2": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32f3": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f7": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32g0": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32g4": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32h5": ["arm-gcc", "arm-clang", "arm-iar"], "stm32h7": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32h7rs stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32h7rs": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32l0": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32l4": ["arm-gcc", "arm-clang", "arm-iar"], "stm32n6": ["arm-gcc"], - "stm32u0 stm32u5": ["arm-gcc", "arm-clang", "arm-iar"], - "stm32wb stm32wba": ["arm-gcc", "arm-clang", "arm-iar"], - # "-bespressif_s2_devkitc": ["esp-idf"], + "stm32u0": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32u5": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32wb": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32wba": ["arm-gcc", "arm-clang", "arm-iar"], + "tm4c": ["arm-gcc"], + "xmc4000": ["arm-gcc"], # S3, P4 will be built by hil test # "-bespressif_s3_devkitm": ["esp-idf"], # "-bespressif_p4_function_ev": ["esp-idf"], -- cgit v1.3.1 From dfe7a97d342c0cca832c121cd4bd66043043bd27 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 Feb 2026 00:41:46 +0700 Subject: remove `membrowse-targets.json` as it is no longer required --- .github/membrowse-targets.json | 494 --------------------------------------- .github/workflows/build_util.yml | 13 -- 2 files changed, 507 deletions(-) delete mode 100644 .github/membrowse-targets.json (limited to '.github/workflows') diff --git a/.github/membrowse-targets.json b/.github/membrowse-targets.json deleted file mode 100644 index 05c90c74e..000000000 --- a/.github/membrowse-targets.json +++ /dev/null @@ -1,494 +0,0 @@ -{ - "templates": { - "build_cmd": "python3 tools/build.py -s cmake -b ${board}", - "elf": "cmake-build/cmake-build-${board}/device/${example}/${example}.elf", - "setup_cmd": "${toolchain.setup_cmd} && python3 tools/get_deps.py ${get_deps}", - "get_deps": "${port}" - }, - "toolchains": { - "arm-none-eabi-gcc-14": { - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin\" >> $GITHUB_PATH" - }, - "aarch64-none-elf-gcc-10": { - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.xz && tar -C $HOME/toolchain -xf toolchain.tar.xz && echo \"$HOME/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin\" >> $GITHUB_PATH" - }, - "riscv-none-elf-gcc-13": { - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.gz && tar -C $HOME/toolchain -xf toolchain.tar.gz && echo \"$HOME/toolchain/xpack-riscv-none-elf-gcc-13.2.0-2/bin\" >> $GITHUB_PATH" - }, - "msp430-gcc-9": { - "setup_cmd": "NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-linux.zip && wget -q $NINJA_URL -O ninja-linux.zip && unzip -q ninja-linux.zip -d $HOME/bin && echo \"$HOME/bin\" >> $GITHUB_PATH && TOOLCHAIN_URL=http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2 && mkdir -p $HOME/toolchain && wget -q $TOOLCHAIN_URL -O toolchain.tar.bz2 && tar -C $HOME/toolchain -xf toolchain.tar.bz2 && echo \"$HOME/toolchain/msp430-gcc-9.2.0.50_linux64/bin\" >> $GITHUB_PATH" - } - }, - "targets": [ - { - "port": "at32f402_405", - "board": "at_start_f402", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/artery/at32f402_405/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F402xC_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "at32f403a_407", - "board": "at32f403a_weact_blackpill", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/artery/at32f403a_407/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F403AxC_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "at32f413", - "board": "at_start_f413", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/artery/at32f413/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F413xC_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "at32f415", - "board": "at_start_f415", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/artery/at32f415/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F415xC_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "at32f423", - "board": "at_start_f423", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/artery/at32f423/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F423xC_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "at32f425", - "board": "at_start_f425", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/artery/at32f425/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x8_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "at32f435_437", - "board": "at_start_f435", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/artery/at32f435_437/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F435xM_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "broadcom_32bit", - "board": "raspberrypi_zero", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/broadcom/broadcom/link.ld", - "example": "cdc_msc" - }, - { - "port": "broadcom_64bit", - "board": "raspberrypi_cm4", - "toolchain": "aarch64-none-elf-gcc-10", - "ld": "hw/mcu/broadcom/broadcom/link8.ld", - "example": "cdc_msc" - }, - { - "port": "ch32v10x", - "board": "ch32v103r_r1_1v0", - "toolchain": "riscv-none-elf-gcc-13", - "ld": "hw/bsp/ch32v10x/linker/ch32v10x.ld", - "linker_vars": "__FLASH_SIZE=64K __RAM_SIZE=20K", - "example": "cdc_msc" - }, - { - "port": "ch32v20x", - "board": "ch32v203c_r0_1v0", - "toolchain": "riscv-none-elf-gcc-13", - "ld": "hw/bsp/ch32v20x/linker/ch32v20x.ld", - "linker_vars": "__flash_size=64K __ram_size=20K", - "example": "cdc_msc" - }, - { - "port": "ch32v30x", - "board": "ch32v307v_r1_1v0", - "toolchain": "riscv-none-elf-gcc-13", - "ld": "hw/bsp/ch32v30x/linker/ch32v30x.ld", - "linker_vars": "__flash_size=128K __ram_size=32K", - "example": "cdc_msc" - }, - { - "port": "da1469x", - "board": "da14695_dk_usb", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/da1469x/linker/da1469x.ld", - "example": "cdc_msc" - }, - { - "port": "fomu", - "board": "fomu", - "toolchain": "riscv-none-elf-gcc-13", - "ld": "hw/bsp/fomu/fomu.ld", - "example": "cdc_msc" - }, - { - "port": "gd32vf103", - "board": "sipeed_longan_nano", - "toolchain": "riscv-none-elf-gcc-13", - "ld": "hw/mcu/gd/nuclei-sdk/SoC/gd32vf103/Board/gd32vf103c_longan_nano/Source/GCC/gcc_gd32vf103xb_flashxip.ld", - "linker_vars": "__ROM_BASE=0x08000000 __ROM_SIZE=0x00020000 __RAM_BASE=0x20000000 __RAM_SIZE=0x00008000", - "example": "cdc_msc" - }, - { - "port": "hpmicro", - "board": "hpm6750evk2", - "toolchain": "riscv-none-elf-gcc-13", - "ld": "hw/mcu/hpmicro/hpm_sdk/soc/HPM6700/HPM6750/toolchains/gcc/flash_xip.ld", - "linker_vars": "_flash_size=16M _stack_size=16K _heap_size=16K", - "example": "cdc_msc" - }, - { - "port": "imxrt", - "board": "metro_m7_1011", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/nxp/mcux-sdk/devices/MIMXRT1011/gcc/MIMXRT1011xxxxx_flexspi_nor.ld", - "example": "cdc_msc" - }, - { - "port": "kinetis_k", - "board": "frdm_k64f", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/nxp/mcux-sdk/devices/MK64F12/gcc/MK64FN1M0xxx12_flash.ld", - "get_deps": "kinetis_k kinetis_kl", - "example": "cdc_msc" - }, - { - "port": "kinetis_k32l2", - "board": "frdm_k32l2a4s", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/nxp/mcux-sdk/devices/K32L2A41A/gcc/K32L2A41xxxxA_flash.ld", - "example": "cdc_msc" - }, - { - "port": "kinetis_kl", - "board": "frdm_kl25z", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/kinetis_kl/gcc/MKL25Z128xxx4_flash.ld", - "example": "cdc_msc" - }, - { - "port": "lpc11", - "board": "lpcxpresso11u37", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/lpc11/boards/lpcxpresso11u37/lpc11u37.ld", - "example": "cdc_msc" - }, - { - "port": "lpc13", - "board": "lpcxpresso1347", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/lpc13/boards/lpcxpresso1347/lpc1347.ld", - "example": "cdc_msc" - }, - { - "port": "lpc15", - "board": "lpcxpresso1549", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/lpc15/boards/lpcxpresso1549/lpc1549.ld", - "example": "cdc_msc" - }, - { - "port": "lpc17", - "board": "lpcxpresso1769", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld", - "example": "cdc_msc" - }, - { - "port": "lpc18", - "board": "lpcxpresso18s37", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld", - "example": "cdc_msc" - }, - { - "port": "lpc40", - "board": "ea4088_quickstart", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld", - "example": "cdc_msc" - }, - { - "port": "lpc43", - "board": "ea4357", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/lpc43/boards/ea4357/lpc4357.ld", - "example": "cdc_msc" - }, - { - "port": "lpc51", - "board": "lpcxpresso51u68", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC51U68/gcc/LPC51U68_flash.ld", - "example": "cdc_msc" - }, - { - "port": "lpc54", - "board": "lpcxpresso54114", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/nxp/mcux-sdk/devices/LPC54114/gcc/LPC54114J256_cm4_flash.ld", - "example": "cdc_msc" - }, - { - "port": "lpc55", - "board": "double_m33_express", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/lpc55/boards/double_m33_express/LPC55S69_cm33_core0_uf2.ld", - "example": "cdc_msc" - }, - { - "port": "maxim", - "board": "apard32690", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/maxim/linker/max32690.ld", - "example": "cdc_msc" - }, - { - "port": "mcx", - "board": "frdm_mcxa153", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/nxp/mcux-sdk/devices/MCXA153/gcc/MCXA153_flash.ld", - "example": "cdc_msc" - }, - { - "port": "mm32", - "board": "mm32f327x_mb39", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/mm32/boards/mm32f327x_mb39/flash.ld", - "example": "cdc_msc" - }, - { - "port": "msp430", - "board": "msp_exp430f5529lp", - "toolchain": "msp430-gcc-9", - "ld": "hw/mcu/ti/msp430/msp430-gcc-support-files/include/msp430f5529.ld", - "example": "cdc_msc" - }, - { - "port": "msp432e4", - "board": "msp_exp432e401y", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/ti/msp432e4/Source/msp432e411y.ld", - "example": "cdc_msc" - }, - { - "port": "nrf", - "board": "adafruit_clue", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/nrf/linker/nrf52840_xxaa.ld", - "example": "cdc_msc" - }, - { - "port": "nuc100_120", - "board": "nutiny_sdk_nuc120", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/nuc100_120/boards/nutiny_sdk_nuc120/nuc120_flash.ld", - "example": "cdc_msc" - }, - { - "port": "nuc121_125", - "board": "nutiny_sdk_nuc121", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/nuc121_125/boards/nutiny_sdk_nuc121/nuc121_flash.ld", - "example": "cdc_msc" - }, - { - "port": "nuc126", - "board": "nutiny_nuc126v", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/nuc126/boards/nutiny_nuc126v/nuc126_flash.ld", - "example": "cdc_msc" - }, - { - "port": "nuc505", - "board": "nutiny_sdk_nuc505", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/nuc505/boards/nutiny_sdk_nuc505/nuc505_flashtoram.ld", - "example": "cdc_msc" - }, - { - "port": "ra", - "board": "portenta_c33", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/ra/boards/portenta_c33/script/memory_regions.ld hw/bsp/ra/boards/portenta_c33/script/fsp.ld", - "example": "cdc_msc" - }, - { - "port": "rw61x", - "board": "frdm_rw612", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/nxp/mcux-sdk/devices/RW612/gcc/RW612_flash.ld", - "example": "cdc_msc" - }, - { - "port": "samd11", - "board": "cynthion_d11", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/samd11/boards/cynthion_d11/cynthion_d11.ld", - "linker_vars": "BOOTLOADER_SIZE=0x800", - "example": "cdc_dual_ports" - }, - { - "port": "samd5x_e5x", - "board": "metro_m4_express", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld", - "example": "cdc_msc" - }, - { - "port": "samg", - "board": "samg55_xplained", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/samg/boards/samg55_xplained/samg55j19_flash.ld", - "example": "cdc_msc" - }, - { - "port": "stm32c0", - "board": "stm32c071nucleo", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32f0", - "board": "stm32f070rbnucleo", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32f0/boards/stm32f070rbnucleo/stm32F070rbtx_flash.ld", - "example": "cdc_msc" - }, - { - "port": "stm32f1", - "board": "stm32f103_bluepill", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32f1/boards/stm32f103_bluepill/STM32F103X8_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32f2", - "board": "stm32f207nucleo", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32f2/boards/stm32f207nucleo/STM32F207ZGTx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32f3", - "board": "stm32f303disco", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32f3/boards/stm32f303disco/STM32F303VCTx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32f4", - "board": "feather_stm32f405", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32f4/boards/feather_stm32f405/STM32F405RGTx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32f7", - "board": "stlinkv3mini", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32f7/boards/stlinkv3mini/STM32F723xE_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32g0", - "board": "stm32g0b1nucleo", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32g4", - "board": "b_g474e_dpow1", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32h5", - "board": "stm32h503nucleo", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32h7", - "board": "stm32h743eval", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32h7/linker/stm32h743xx_flash.ld", - "example": "cdc_msc" - }, - { - "port": "stm32h7rs", - "board": "stm32h7s3nucleo", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32h7rs/linker/stm32h7s3xx_flash.ld", - "linker_vars": "__FLASH_BEGIN=0x08000000 __FLASH_SIZE=0x00010000 __RAM_BEGIN=0x24000000 __RAM_SIZE=0x4FC00 __RAM_NONCACHEABLEBUFFER_SIZE=0x400", - "example": "cdc_msc" - }, - { - "port": "stm32l0", - "board": "stm32l052dap52", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32l0/boards/stm32l052dap52/STM32L052K8Ux_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32l4", - "board": "stm32l412nucleo", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32l4/boards/stm32l412nucleo/STM32L412KBUx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32n6", - "board": "stm32n6570dk", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32n6/boards/stm32n6570dk/STM32N657XX_AXISRAM2_fsbl.ld", - "example": "cdc_msc" - }, - { - "port": "stm32u0", - "board": "stm32u083cdk", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32u0/boards/stm32u083cdk/STM32U083MCTx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32u5", - "board": "b_u585i_iot2a", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld", - "example": "cdc_msc" - }, - { - "port": "stm32wb", - "board": "stm32wb55nucleo", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32wb/boards/stm32wb55nucleo/stm32wb55xx_flash_cm4.ld", - "example": "cdc_msc" - }, - { - "port": "stm32wba", - "board": "stm32wba_nucleo", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/stm32wba/linker/STM32WBA65xx_FLASH_ns.ld", - "example": "cdc_msc" - }, - { - "port": "tm4c", - "board": "ek_tm4c123gxl", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld", - "example": "cdc_msc" - }, - { - "port": "xmc4000", - "board": "xmc4500_relax", - "toolchain": "arm-none-eabi-gcc-14", - "ld": "hw/mcu/infineon/mtb-xmclib-cat3/CMSIS/Infineon/COMPONENT_XMC4500/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld", - "example": "cdc_msc" - } - ] -} diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 8a3dd8f91..d34c41406 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -79,19 +79,6 @@ jobs: name: metrics-${{ matrix.arg }} path: cmake-build/cmake-build-*/metrics.json - - name: Copy linker scripts for artifacts - if: ${{ inputs.upload-artifacts }} - run: | - for dir in cmake-build/cmake-build-*; do - board=$(basename "$dir" | sed 's/cmake-build-//') - ld_path=$(jq -r --arg b "$board" '.targets[] | select(.board == $b) | .ld // empty' .github/membrowse-targets.json) - if [ -n "$ld_path" ] && [ -f "$ld_path" ]; then - mkdir -p "cmake-build/$(dirname "$ld_path")" - cp "$ld_path" "cmake-build/$ld_path" - fi - done - shell: bash - - name: Upload Artifacts for Hardware Testing if: ${{ inputs.upload-artifacts }} uses: actions/upload-artifact@v5 -- cgit v1.3.1 From 07a3b3b34f67b12cbbe7865923341d9746a1e8fc Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 Feb 2026 10:39:43 +0700 Subject: fetch depth 0 if membrowse-upload --- .github/workflows/build_util.yml | 2 ++ 1 file changed, 2 insertions(+) (limited to '.github/workflows') diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index d34c41406..eb3c4df89 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -43,6 +43,8 @@ jobs: steps: - name: Checkout TinyUSB uses: actions/checkout@v6 + with: + fetch-depth: ${{ !inputs.upload-membrowse && 1 || 0 }} - name: Setup Toolchain id: setup-toolchain -- cgit v1.3.1 From 2e8e33f28494307276d7a5417569461fe6584b80 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 Feb 2026 16:34:28 +0700 Subject: add build target argument to improve flexibility of build scripts and workflows membrowse-upload upload with --identical if elf file does not exist --- .github/workflows/build.yml | 23 +++++++++-------- .github/workflows/build_util.yml | 38 +++++++++++++++++++--------- hw/bsp/family_support.cmake | 54 ++++++++++++++++++++++++++++++++++------ tools/build.py | 43 +++++++++++++------------------- 4 files changed, 103 insertions(+), 55 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2b0c38c4f..412d52bb8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,8 +47,6 @@ jobs: - '.github/workflows/ci_set_matrix.py' set-matrix: - needs: [ check-paths ] - if: needs.check-paths.outputs.code_changed == 'true' runs-on: ubuntu-latest outputs: json: ${{ steps.set-matrix-json.outputs.matrix }} @@ -75,7 +73,7 @@ jobs: # For Make and IAR build: will be done on CircleCI only (one random per family as well) # ------------------------------------------------------------------------------ cmake: - needs: set-matrix + needs: [ check-paths, set-matrix ] uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -95,10 +93,12 @@ jobs: upload-metrics: true upload-artifacts: false upload-membrowse: true + code-changed: ${{ needs.check-paths.outputs.code_changed == 'true' }} secrets: inherit code-metrics: - needs: cmake + needs: [ check-paths, cmake ] + if: needs.check-paths.outputs.code_changed == true runs-on: ubuntu-latest permissions: pull-requests: write @@ -196,17 +196,18 @@ jobs: # --------------------------------------- build-os: needs: [ check-paths ] - if: needs.check-paths.outputs.code_changed == 'true' + if: needs.check-paths.outputs.code_changed == true uses: ./.github/workflows/build_util.yml strategy: fail-fast: false matrix: os: [ windows-latest, macos-latest ] + build-system: [ 'make', 'cmake' ] with: os: ${{ matrix.os }} - build-system: 'cmake-make' + build-system: ${{ matrix.build-system }} toolchain: 'arm-gcc-${{ matrix.os }}' - build-args: '["stm32h7"]' + build-args: '["stm32h7rs"]' build-options: '--one-random' # --------------------------------------- @@ -215,7 +216,8 @@ jobs: zephyr: needs: [ check-paths ] # skip zephyr build due to failed build, fix later - if: false && needs.check-paths.outputs.code_changed == 'true' + if: false + #if: needs.check-paths.outputs.code_changed == 'true' runs-on: ubuntu-latest steps: - name: Checkout TinyUSB @@ -237,8 +239,8 @@ jobs: # Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR # --------------------------------------- hil-build: - needs: set-matrix - if: github.repository_owner == 'hathach' + needs: [ check-paths, set-matrix ] + if: needs.check-paths.outputs.code_changed == true && github.repository_owner == 'hathach' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -299,6 +301,7 @@ jobs: hil-hfp: needs: [ check-paths ] if: | + needs.check-paths.outputs.code_changed == true && github.repository_owner == 'hathach' && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) runs-on: [ self-hosted, Linux, X64, hifiphile ] diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index eb3c4df89..4200c11bd 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -3,6 +3,10 @@ name: Reusable build util on: workflow_call: inputs: + os: + required: false + type: string + default: 'ubuntu-latest' build-system: required: true type: string @@ -28,10 +32,10 @@ on: required: false default: false type: boolean - os: + code-changed: required: false - type: string - default: 'ubuntu-latest' + default: false + type: boolean jobs: family: @@ -58,19 +62,29 @@ jobs: arg: ${{ matrix.arg }} - name: Build + if: ${{ inputs.code-changed }} env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} - MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} - MEMBROWSE_UPLOAD_OPTION: ${{ inputs.upload-membrowse && '--membrowse-upload' || '' }} - TOOLCHAIN: ${{ inputs.toolchain }} run: | - if [ "$TOOLCHAIN" == "esp-idf" ]; then - docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py $MEMBROWSE_UPLOAD_OPTION ${{ matrix.arg }} - elif [ "${{ inputs.build-system }}" == "cmake-make" ] || [ "${{ inputs.build-system }}" == "make-cmake" ]; then - python tools/build.py -s make $MEMBROWSE_UPLOAD_OPTION ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} - python tools/build.py -s cmake $MEMBROWSE_UPLOAD_OPTION ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} + if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then + docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py -T all ${{ matrix.arg }} else - python tools/build.py -s ${{ inputs.build-system }} $MEMBROWSE_UPLOAD_OPTION ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} ${{ matrix.arg }} + BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }}" + python tools/build.py $BUILD_PY_ARGS --target all ${{ matrix.arg }} + + if [ "${{ inputs.upload-metrics }}" = "true" ]; then + python tools/build.py $BUILD_PY_ARGS --target tinyusb_metrics ${{ matrix.arg }} + fi + fi + shell: bash + + - name: Membrowse Upload + if: inputs.toolchain != 'esp-idf' + env: + MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} + run: | + if [ "${{ inputs.upload-membrowse }}" = "true" ]; then + python tools/build.py $BUILD_PY_ARGS --target examples-membrowse-upload ${{ matrix.arg }} fi shell: bash diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 57a323c4a..fdf7b78ed 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -280,21 +280,62 @@ function(family_add_membrowse TARGET) string(APPEND OPTION " ${MEMBROWSE_OPTION}") endif () - # For Ninja generator, extract all linker scripts from Ninja commands and pass them to membrowse. + # For Ninja generator, extract all linker scripts from Ninja commands (with INCLUDE) and pass them to membrowse. if (CMAKE_GENERATOR MATCHES "Ninja") + set(TARGET_ELF_PATH "$/$") + set(MEMBROWSE_LD_SCRIPTS_CMD + "ld_scripts=\"$(${CMAKE_MAKE_PROGRAM} -C ${CMAKE_BINARY_DIR} -t commands ${TARGET} | grep -oP '(?:-Wl,--script=|-T\\s*)\\K[A-Za-z0-9_./-]+\\.ld' | xargs)\"; \ +all_ld_scripts=\"\"; \ +pending_ld_scripts=\"$ld_scripts\"; \ +while [ -n \"$pending_ld_scripts\" ]; do \ + next_pending=\"\"; \ + for script in $pending_ld_scripts; do \ + case \" $all_ld_scripts \" in *\" $script \"*) continue ;; esac; \ + all_ld_scripts=\"$all_ld_scripts $script\"; \ + script_dir=$(dirname \"$script\"); \ + include_scripts=$(grep -hoP '^\\s*INCLUDE\\s+[<\"]?\\K[^\">[:space:]]+\\.ld' \"$script\" 2>/dev/null | xargs); \ + for include_script in $include_scripts; do \ + resolved_script=\"\"; \ + if [ -f \"$include_script\" ]; then \ + resolved_script=\"$include_script\"; \ + elif [ -f \"$script_dir/$include_script\" ]; then \ + resolved_script=\"$script_dir/$include_script\"; \ + fi; \ + if [ -n \"$resolved_script\" ]; then \ + case \" $all_ld_scripts $next_pending \" in *\" $resolved_script \"*) ;; *) next_pending=\"$next_pending $resolved_script\" ;; esac; \ + fi; \ + done; \ + done; \ + pending_ld_scripts=\"$(echo \"$next_pending\" | xargs)\"; \ +done; \ +ld_scripts=\"$(echo \"$all_ld_scripts\" | xargs)\"") + set(MEMBROWSE_CMD - "ld_scripts=\"$(${CMAKE_MAKE_PROGRAM} -C ${CMAKE_BINARY_DIR} -t commands ${TARGET} | grep -oP '(?<=-Wl,--script=)[A-Za-z0-9_./-]+\\.ld' | xargs)\"; \ -${MEMBROWSE_EXE} report ${OPTION} $ \"$ld_scripts\"") + "if [ -f \"${TARGET_ELF_PATH}\" ]; then \ + ${MEMBROWSE_LD_SCRIPTS_CMD}; \ + echo ld_scripts=\"$ld_scripts\"; \ + if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ + ${MEMBROWSE_EXE} report ${OPTION} \"${TARGET_ELF_PATH}\" \"$ld_scripts\" --upload --github --target-name ${BOARD}-${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}; \ + else \ + ${MEMBROWSE_EXE} report ${OPTION} \"${TARGET_ELF_PATH}\" \"$ld_scripts\"; \ + fi; \ +else \ + if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ + ${MEMBROWSE_EXE} report ${OPTION} --identical --upload --github --target-name ${BOARD}-${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}; \ + else \ + ${MEMBROWSE_EXE} report ${OPTION} --identical; \ + fi; \ +fi") add_custom_target(${TARGET}-membrowse DEPENDS ${TARGET} - COMMAND bash -lc "${MEMBROWSE_CMD}" + COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=0 bash -lc "${MEMBROWSE_CMD}" VERBATIM ) + set_property(TARGET ${TARGET}-membrowse PROPERTY FOLDER ${TARGET}) add_custom_target(${TARGET}-membrowse-upload - DEPENDS ${TARGET} - COMMAND bash -lc "${MEMBROWSE_CMD} --upload --github --target-name ${BOARD}-${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}" + COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=1 bash -lc "${MEMBROWSE_CMD}" VERBATIM ) @@ -303,7 +344,6 @@ ${MEMBROWSE_EXE} report ${OPTION} $ \"$ld_scripts\"") endif () add_dependencies(examples-membrowse-upload ${TARGET}-membrowse-upload) - set_property(TARGET ${TARGET}-membrowse PROPERTY FOLDER ${TARGET}) set_property(TARGET ${TARGET}-membrowse-upload PROPERTY FOLDER ${TARGET}) endif () endfunction() diff --git a/tools/build.py b/tools/build.py index bc032fb91..d26028c51 100755 --- a/tools/build.py +++ b/tools/build.py @@ -98,15 +98,15 @@ def get_examples(family): return all_examples -def print_build_result(board, example, status, duration): +def print_build_result(board, build_target, status, duration): if isinstance(duration, (int, float)): duration = "{:.2f}s".format(duration) - print(build_format.format(board, example, build_status[status], duration)) + print(build_format.format(board, build_target, build_status[status], duration)) # ----------------------------- # CMake # ----------------------------- -def cmake_board(board, build_args, build_flags_on, membrowse_upload): +def cmake_board(board, build_args, build_flags_on, build_target): ret = [0, 0, 0] start_time = time.monotonic() @@ -137,26 +137,18 @@ def cmake_board(board, build_args, build_flags_on, membrowse_upload): if rcmd.returncode == 0: if clean_build: run_cmd(["cmake", "--build", build_dir, '--target', 'clean']) - cmd = ["cmake", "--build", build_dir, '--parallel', str(parallel_jobs)] + cmd = ["cmake", "--build", build_dir, '--target', build_target, '--parallel', str(parallel_jobs)] rcmd = run_cmd(cmd) - if rcmd.returncode == 0: - ret[0] += 1 - run_cmd(["cmake", "--build", build_dir, '--target', 'tinyusb_metrics']) - if membrowse_upload: - run_cmd(["cmake", "--build", build_dir, '--target', 'examples-membrowse-upload']) - # print(rcmd.stdout.decode("utf-8")) - else: - ret[1] += 1 + ret[0 if rcmd.returncode == 0 else 1] += 1 - example = 'all' - print_build_result(board, example, 0 if ret[1] == 0 else 1, time.monotonic() - start_time) + print_build_result(board, build_target, 0 if ret[1] == 0 else 1, time.monotonic() - start_time) return ret # ----------------------------- # Make # ----------------------------- -def make_one_example(example, board, make_option): +def make_one_example(example, board, make_option, build_target): # Check if board is skipped if build_utils.skip_example(example, board): print_build_result(board, example, 2, '-') @@ -168,7 +160,7 @@ def make_one_example(example, board, make_option): make_args += shlex.split(make_option) if clean_build: run_cmd(make_args + ["clean"]) - build_result = run_cmd(make_args + ['all']) + build_result = run_cmd(make_args + [build_target]) r = 0 if build_result.returncode == 0 else 1 print_build_result(board, example, r, time.monotonic() - start_time) @@ -177,7 +169,7 @@ def make_one_example(example, board, make_option): return ret -def make_board(board, build_args): +def make_board(board, build_args, build_target): print(build_separator) family = find_family(board); all_examples = get_examples(family) @@ -188,7 +180,7 @@ def make_board(board, build_args): final_status = 2 else: with Pool(processes=os.cpu_count()) as pool: - pool_args = list((map(lambda e, b=board, o=f"{build_args}": [e, b, o], all_examples))) + pool_args = list((map(lambda e, b=board, o=f"{build_args}", t=build_target: [e, b, o, t], all_examples))) r = pool.starmap(make_one_example, pool_args) # sum all element of same index (column sum) ret = list(map(sum, list(zip(*r)))) @@ -200,16 +192,16 @@ def make_board(board, build_args): # ----------------------------- # Build Family # ----------------------------- -def build_boards_list(boards, build_defines, build_system, build_flags_on, membrowse_upload): +def build_boards_list(boards, build_defines, build_system, build_flags_on, build_target): ret = [0, 0, 0] for b in boards: r = [0, 0, 0] if build_system == 'cmake': build_args = [f'-D{d}' for d in build_defines] - r = cmake_board(b, build_args, build_flags_on, membrowse_upload) + r = cmake_board(b, build_args, build_flags_on, build_target) elif build_system == 'make': build_args = ' '.join(f'{d}' for d in build_defines) - r = make_board(b, build_args) + r = make_board(b, build_args, build_target) ret[0] += r[0] ret[1] += r[1] ret[2] += r[2] @@ -275,8 +267,7 @@ def main(): parser.add_argument('--one-first', action='store_true', default=False, help='Build only the first board (alphabetical) of each specified family') parser.add_argument('-j', '--jobs', type=int, default=os.cpu_count(), help='Number of jobs to run in parallel') - parser.add_argument('--membrowse-upload', action='store_true', default=False, - help='Run examples-membrowse-upload target after successful CMake build') + parser.add_argument('-T', '--target', default='all', help='Build target to use, default is all') parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') args = parser.parse_args() @@ -288,7 +279,7 @@ def main(): build_flags_on = args.build_flags_on one_random = args.one_random one_first = args.one_first - membrowse_upload = args.membrowse_upload + build_target = args.target verbose = args.verbose clean_build = args.clean parallel_jobs = args.jobs @@ -300,7 +291,7 @@ def main(): return 1 print(build_separator) - print(build_format.format('Board', 'Example', '\033[39mResult\033[0m', 'Time')) + print(build_format.format('Board', 'Target', '\033[39mResult\033[0m', 'Time')) total_time = time.monotonic() # get all families @@ -319,7 +310,7 @@ def main(): all_boards.extend(get_family_boards(f, one_random, one_first)) # build all boards - result = build_boards_list(all_boards, build_defines, build_system, build_flags_on, membrowse_upload) + result = build_boards_list(all_boards, build_defines, build_system, build_flags_on, build_target) total_time = time.monotonic() - total_time print(build_separator) -- cgit v1.3.1 From 8c9901c31892e9213acc52538cc56c7cb24883b0 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 Feb 2026 18:17:16 +0700 Subject: correct membrowse upload step --- .github/workflows/build_util.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 4200c11bd..1a119b132 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -79,13 +79,12 @@ jobs: shell: bash - name: Membrowse Upload - if: inputs.toolchain != 'esp-idf' + if: inputs.toolchain != 'esp-idf' && inputs.upload-membrowse == true env: MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} run: | - if [ "${{ inputs.upload-membrowse }}" = "true" ]; then - python tools/build.py $BUILD_PY_ARGS --target examples-membrowse-upload ${{ matrix.arg }} - fi + BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }}" + python tools/build.py $BUILD_PY_ARGS --target examples-membrowse-upload -j 1 ${{ matrix.arg }} shell: bash - name: Upload Artifacts for Metrics -- cgit v1.3.1 From cec0ee53f60ed28d7c324f40cbebd0b677d94eb1 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 11 Feb 2026 23:06:38 +0700 Subject: make membrowse command more visible --- .github/workflows/build_util.yml | 1 + hw/bsp/family_support.cmake | 20 +++++++++----------- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 1a119b132..595129443 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -83,6 +83,7 @@ jobs: env: MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} run: | + # if code-changed is false --> there is no elf -> membrowse target upload with --indetical flag BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }}" python tools/build.py $BUILD_PY_ARGS --target examples-membrowse-upload -j 1 ${{ matrix.arg }} shell: bash diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 80ebb7bef..0130fb656 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -316,35 +316,33 @@ for symbol in $ld_symbols; do \ ld_defs=\"$ld_defs --def $symbol\"; \ done; \ ld_defs=\"$(echo \"$ld_defs\" | xargs)\"") - - set(MEMBROWSE_CMD + set(MEMBROWSE_PREPARE_CMD "if [ -f \"${TARGET_ELF_PATH}\" ]; then \ ${MEMBROWSE_LD_SCRIPTS_CMD}; \ ${MEMBROWSE_LD_DEFS_CMD}; \ - echo ld_scripts=\"$ld_scripts\"; \ - echo ld_defs=\"$ld_defs\"; \ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ - ${MEMBROWSE_EXE} report ${OPTION} \"${TARGET_ELF_PATH}\" \"$ld_scripts\" $ld_defs --upload --github --target-name ${FAMILY}/${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}; \ + MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs --upload --github --target-name ${FAMILY}/${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ else \ - ${MEMBROWSE_EXE} report ${OPTION} \"${TARGET_ELF_PATH}\" \"$ld_scripts\" $ld_defs; \ + MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs\"; \ fi; \ else \ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ - ${MEMBROWSE_EXE} report ${OPTION} --identical --upload --github --target-name ${FAMILY}/${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}; \ + MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} --identical --upload --github --target-name ${FAMILY}/${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ else \ - ${MEMBROWSE_EXE} report ${OPTION} --identical; \ + MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} --identical\"; \ fi; \ -fi") +fi; \ +echo \"$MEMBROWSE_CMD\"") add_custom_target(${TARGET}-membrowse DEPENDS ${TARGET} - COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=0 bash -lc "${MEMBROWSE_CMD}" + COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=0 bash -lc "${MEMBROWSE_PREPARE_CMD}; eval \"$MEMBROWSE_CMD\"" VERBATIM ) set_property(TARGET ${TARGET}-membrowse PROPERTY FOLDER ${TARGET}) add_custom_target(${TARGET}-membrowse-upload - COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=1 bash -lc "${MEMBROWSE_CMD}" + COMMAND ${CMAKE_COMMAND} -E env MEMBROWSE_UPLOAD=1 bash -lc "${MEMBROWSE_PREPARE_CMD}; eval \"$MEMBROWSE_CMD\"" VERBATIM ) -- cgit v1.3.1 From 4a5077a1aa78d2359f26b0c44ced025db45d77c2 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Feb 2026 00:10:18 +0700 Subject: membrowse upload continue on error --- .github/workflows/build_util.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 595129443..138673bcc 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -80,10 +80,11 @@ jobs: - name: Membrowse Upload if: inputs.toolchain != 'esp-idf' && inputs.upload-membrowse == true + continue-on-error: true # have server busy issue with membrowse env: MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} run: | - # if code-changed is false --> there is no elf -> membrowse target upload with --indetical flag + # if code-changed is false --> there is no elf -> membrowse target upload with --identical flag BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }}" python tools/build.py $BUILD_PY_ARGS --target examples-membrowse-upload -j 1 ${{ matrix.arg }} shell: bash -- cgit v1.3.1 From 39bc5cd933091c9c28b0f0bd468526d3d5d946a3 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Feb 2026 00:22:21 +0700 Subject: fix ci --- .github/workflows/build.yml | 8 ++++---- .github/workflows/build_util.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 412d52bb8..e0997c256 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -98,7 +98,7 @@ jobs: code-metrics: needs: [ check-paths, cmake ] - if: needs.check-paths.outputs.code_changed == true + if: needs.check-paths.outputs.code_changed == 'true' runs-on: ubuntu-latest permissions: pull-requests: write @@ -196,7 +196,7 @@ jobs: # --------------------------------------- build-os: needs: [ check-paths ] - if: needs.check-paths.outputs.code_changed == true + if: needs.check-paths.outputs.code_changed == 'true' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -240,7 +240,7 @@ jobs: # --------------------------------------- hil-build: needs: [ check-paths, set-matrix ] - if: needs.check-paths.outputs.code_changed == true && github.repository_owner == 'hathach' + if: needs.check-paths.outputs.code_changed == 'true' && github.repository_owner == 'hathach' uses: ./.github/workflows/build_util.yml strategy: fail-fast: false @@ -301,7 +301,7 @@ jobs: hil-hfp: needs: [ check-paths ] if: | - needs.check-paths.outputs.code_changed == true && + needs.check-paths.outputs.code_changed == 'true' && github.repository_owner == 'hathach' && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) runs-on: [ self-hosted, Linux, X64, hifiphile ] diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 138673bcc..7b1972fc9 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -34,7 +34,7 @@ on: type: boolean code-changed: required: false - default: false + default: true type: boolean jobs: -- cgit v1.3.1 From c59447faa8935124bdeebeafbcb8ba65f7fc93f0 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Feb 2026 11:30:40 +0700 Subject: clean up --- .circleci/config2.yml | 9 ++- .github/actions/get_deps/action.yml | 1 - .github/workflows/build.yml | 50 ----------------- .github/workflows/build_util.yml | 6 +- .github/workflows/membrowse-report.yml | 100 --------------------------------- .idea/cmake.xml | 1 + 6 files changed, 11 insertions(+), 156 deletions(-) delete mode 100644 .github/workflows/membrowse-report.yml (limited to '.github/workflows') diff --git a/.circleci/config2.yml b/.circleci/config2.yml index 352d0f4fa..900994a73 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -110,7 +110,7 @@ commands: no_output_timeout: 20m command: | if [ << parameters.toolchain >> == esp-idf ]; then - docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.2 python tools/build.py << parameters.build-args >> << parameters.family >> + docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.2 python tools/build.py << parameters.build-args >> --target all << parameters.family >> else # Toolchain option default is gcc if [ << parameters.toolchain >> == arm-clang ]; then @@ -124,7 +124,12 @@ commands: # circleci docker return $nproc as 36 core, limit parallel to 4 (resource-class = large) # Required for IAR, also prevent crashed/killed by docker - python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> << parameters.family >> + BUILD_PY_ARGS="-s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >>" + python tools/build.py $BUILD_PY_ARGS --target all << parameters.family >> + + if [ << parameters.build-system >> == "cmake" ]; then + python tools/build.py $BUILD_PY_ARGS --target tinyusb_metrics << parameters.family >> + fi fi # Only collect and persist metrics for cmake builds (excluding esp-idf and --one-random) diff --git a/.github/actions/get_deps/action.yml b/.github/actions/get_deps/action.yml index 8ea36ce78..bbe94f0fa 100644 --- a/.github/actions/get_deps/action.yml +++ b/.github/actions/get_deps/action.yml @@ -23,7 +23,6 @@ runs: wget $NINJA_URL -O ninja-linux.zip unzip ninja-linux.zip -d ninja-bin pip install membrowse - #echo >> $GITHUB_PATH "$HOME/.local/bin" echo >> $GITHUB_PATH "${{ github.workspace }}/ninja-bin" shell: bash diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0997c256..9d8b90f5a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -336,53 +336,3 @@ jobs: - name: Test on actual hardware (hardware in the loop) run: python3 test/hil/hil_test.py hfp.json - - # --------------------------------------- - # Membrowse Memory Analysis - # Push: always runs (uses identical for doc-only to maintain commit chain) - # PR: only runs if code changed (doc-only PRs skip entirely) - # --------------------------------------- -# membrowse: -# needs: [check-paths, cmake] -# if: | -# always() && !cancelled() && ( -# github.event_name == 'push' || -# github.event_name == 'release' || -# github.event_name == 'workflow_dispatch' || -# (github.event_name == 'pull_request' && needs.check-paths.outputs.code_changed == 'true') -# ) -# permissions: -# contents: read -# actions: read -# uses: ./.github/workflows/membrowse-report.yml -# with: -# code_changed: ${{ needs.check-paths.outputs.code_changed == 'true' || github.event_name == 'release' || github.event_name == 'workflow_dispatch' }} -# secrets: inherit -# -# membrowse-comment: -# needs: membrowse -# # skip membrowse comment since it is too verbal -# if: false && github.event_name == 'pull_request' -# runs-on: ubuntu-latest -# permissions: -# contents: read -# actions: read -# steps: -# - name: Checkout repository -# uses: actions/checkout@v6 -# -# - name: Download report artifacts -# id: download -# uses: actions/download-artifact@v5 -# with: -# pattern: membrowse-report-* -# path: reports -# merge-multiple: true -# continue-on-error: true -# -# - name: Upload Membrowse Comment Artifact -# if: steps.download.outcome == 'success' -# uses: actions/upload-artifact@v5 -# with: -# name: membrowse-comment -# path: reports/ diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 7b1972fc9..b0adec979 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -67,7 +67,7 @@ jobs: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} run: | if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then - docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py -T all ${{ matrix.arg }} + docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py --target all ${{ matrix.arg }} else BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }}" python tools/build.py $BUILD_PY_ARGS --target all ${{ matrix.arg }} @@ -90,14 +90,14 @@ jobs: shell: bash - name: Upload Artifacts for Metrics - if: ${{ inputs.upload-metrics }} + if: inputs.upload-metrics == true && inputs.code-changed == true uses: actions/upload-artifact@v5 with: name: metrics-${{ matrix.arg }} path: cmake-build/cmake-build-*/metrics.json - name: Upload Artifacts for Hardware Testing - if: ${{ inputs.upload-artifacts }} + if: inputs.upload-artifacts == true && inputs.code-changed == true uses: actions/upload-artifact@v5 with: name: binaries-${{ matrix.arg }} diff --git a/.github/workflows/membrowse-report.yml b/.github/workflows/membrowse-report.yml deleted file mode 100644 index f86b047df..000000000 --- a/.github/workflows/membrowse-report.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: Membrowse Memory Report - -on: - workflow_call: - inputs: - code_changed: - description: 'Whether code paths changed (true) or doc-only (false)' - type: boolean - required: true - -permissions: - contents: read - actions: read - -jobs: - load-targets: - runs-on: ubuntu-latest - outputs: - targets: ${{ steps.load.outputs.targets }} - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Load target matrix - id: load - run: echo "targets=$(jq -c '.targets' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT - - analyze: - needs: [load-targets] - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.load-targets.outputs.targets) }} - - steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - # Download artifacts when code changed (build artifacts available) - - name: Download build artifacts - if: inputs.code_changed - id: download - uses: actions/download-artifact@v5 - with: - pattern: binaries-* - path: cmake-build - merge-multiple: true - continue-on-error: true - - - name: Restore linker scripts - if: inputs.code_changed - run: cp -r cmake-build/hw . 2>/dev/null || true - - - name: Check if ELF exists - id: check-elf - run: | - if [ -f "cmake-build/cmake-build-${{ matrix.board }}/device/${{ matrix.example }}/${{ matrix.example }}.elf" ]; then - echo "exists=true" >> $GITHUB_OUTPUT - else - echo "exists=false" >> $GITHUB_OUTPUT - fi - - # Run with actual ELF analysis when build artifacts available - - name: Run Membrowse Analysis - if: steps.check-elf.outputs.exists == 'true' - id: membrowse - continue-on-error: true - uses: membrowse/membrowse-action@v1 - with: - target_name: ${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }} - elf: cmake-build/cmake-build-${{ matrix.board }}/device/${{ matrix.example }}/${{ matrix.example }}.elf - ld: ${{ matrix.ld }} - linker_vars: ${{ matrix.linker_vars || '' }} - api_key: ${{ secrets.MEMBROWSE_API_KEY }} - api_url: ${{ vars.MEMBROWSE_API_URL }} - verbose: INFO - - # Run with identical=true when no ELF (doc-only push) - # Preserves the chain of commits in membrowse tracking - - name: Run Membrowse Identical Report - if: steps.check-elf.outputs.exists == 'false' - id: membrowse-identical - continue-on-error: true - uses: membrowse/membrowse-action@v1 - with: - target_name: ${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }} - identical: true - api_key: ${{ secrets.MEMBROWSE_API_KEY }} - api_url: ${{ vars.MEMBROWSE_API_URL }} - verbose: INFO - - - name: Upload report artifact - if: steps.membrowse.outcome == 'success' || steps.membrowse-identical.outcome == 'success' - uses: actions/upload-artifact@v5 - with: - name: membrowse-report-${{ matrix.port }}-${{ matrix.board }}-${{ matrix.example }} - path: ${{ steps.membrowse.outputs.report_path || steps.membrowse-identical.outputs.report_path }} diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 5f9e1acd2..822a70236 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -171,6 +171,7 @@ + -- cgit v1.3.1 From 8a6012b0096cb71bb4cfaaa36813de4ac5003c18 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Feb 2026 13:32:00 +0700 Subject: refactor build scripts to support multiple build targets and improve argument handling --- .circleci/config2.yml | 7 +++--- .github/workflows/build_util.yml | 7 +++--- tools/build.py | 50 ++++++++++++++++++++-------------------- 3 files changed, 31 insertions(+), 33 deletions(-) (limited to '.github/workflows') diff --git a/.circleci/config2.yml b/.circleci/config2.yml index 900994a73..a31b0a818 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -124,12 +124,11 @@ commands: # circleci docker return $nproc as 36 core, limit parallel to 4 (resource-class = large) # Required for IAR, also prevent crashed/killed by docker - BUILD_PY_ARGS="-s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >>" - python tools/build.py $BUILD_PY_ARGS --target all << parameters.family >> - + BUILD_PY_ARGS="-s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> --target all" if [ << parameters.build-system >> == "cmake" ]; then - python tools/build.py $BUILD_PY_ARGS --target tinyusb_metrics << parameters.family >> + BUILD_PY_ARGS="$BUILD_PY_ARGS --target tinyusb_metrics" fi + python tools/build.py $BUILD_PY_ARGS << parameters.family >> fi # Only collect and persist metrics for cmake builds (excluding esp-idf and --one-random) diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index b0adec979..6863ebdf2 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -69,12 +69,11 @@ jobs: if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py --target all ${{ matrix.arg }} else - BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }}" - python tools/build.py $BUILD_PY_ARGS --target all ${{ matrix.arg }} - + BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} --target all" if [ "${{ inputs.upload-metrics }}" = "true" ]; then - python tools/build.py $BUILD_PY_ARGS --target tinyusb_metrics ${{ matrix.arg }} + BUILD_PY_ARGS="$BUILD_PY_ARGS --target tinyusb_metrics" fi + python tools/build.py $BUILD_PY_ARGS ${{ matrix.arg }} fi shell: bash diff --git a/tools/build.py b/tools/build.py index d26028c51..3c5c3c077 100755 --- a/tools/build.py +++ b/tools/build.py @@ -24,7 +24,6 @@ build_separator = '-' * 95 build_status = [STATUS_OK, STATUS_FAILED, STATUS_SKIPPED] verbose = False -clean_build = False parallel_jobs = os.cpu_count() # CI board control lists (used when running under CI) @@ -106,7 +105,7 @@ def print_build_result(board, build_target, status, duration): # ----------------------------- # CMake # ----------------------------- -def cmake_board(board, build_args, build_flags_on, build_target): +def cmake_board(board, build_args, build_flags_on, build_targets): ret = [0, 0, 0] start_time = time.monotonic() @@ -135,33 +134,36 @@ def cmake_board(board, build_args, build_flags_on, build_target): f'-DBOARD={board}', '-DCMAKE_BUILD_TYPE=MinSizeRel', '-DLINKERMAP_OPTION=-q -f tinyusb/src', *build_args, *build_flags]) if rcmd.returncode == 0: - if clean_build: - run_cmd(["cmake", "--build", build_dir, '--target', 'clean']) - cmd = ["cmake", "--build", build_dir, '--target', build_target, '--parallel', str(parallel_jobs)] - rcmd = run_cmd(cmd) + cmd = ["cmake", "--build", build_dir, '--parallel', str(parallel_jobs)] + for target in build_targets: + rcmd = run_cmd(cmd + ['--target', target]) + if rcmd.returncode != 0: + break ret[0 if rcmd.returncode == 0 else 1] += 1 - print_build_result(board, build_target, 0 if ret[1] == 0 else 1, time.monotonic() - start_time) + print_build_result(board, ','.join(build_targets), 0 if ret[1] == 0 else 1, time.monotonic() - start_time) return ret # ----------------------------- # Make # ----------------------------- -def make_one_example(example, board, make_option, build_target): +def make_one_example(example, board, make_option, build_targets): # Check if board is skipped if build_utils.skip_example(example, board): print_build_result(board, example, 2, '-') r = 2 else: start_time = time.monotonic() - make_args = ["make", "-C", f"examples/{example}", f"BOARD={board}", '-j', str(parallel_jobs)] + make_cmd = ["make", "-C", f"examples/{example}", f"BOARD={board}", '-j', str(parallel_jobs)] if make_option: - make_args += shlex.split(make_option) - if clean_build: - run_cmd(make_args + ["clean"]) - build_result = run_cmd(make_args + [build_target]) - r = 0 if build_result.returncode == 0 else 1 + make_cmd += shlex.split(make_option) + r = 0 + for target in build_targets: + build_result = run_cmd(make_cmd + [target]) + if build_result.returncode != 0: + r = 1 + break print_build_result(board, example, r, time.monotonic() - start_time) ret = [0, 0, 0] @@ -169,7 +171,7 @@ def make_one_example(example, board, make_option, build_target): return ret -def make_board(board, build_args, build_target): +def make_board(board, build_args, build_targets): print(build_separator) family = find_family(board); all_examples = get_examples(family) @@ -180,7 +182,7 @@ def make_board(board, build_args, build_target): final_status = 2 else: with Pool(processes=os.cpu_count()) as pool: - pool_args = list((map(lambda e, b=board, o=f"{build_args}", t=build_target: [e, b, o, t], all_examples))) + pool_args = list((map(lambda e, b=board, o=f"{build_args}", t=build_targets: [e, b, o, t], all_examples))) r = pool.starmap(make_one_example, pool_args) # sum all element of same index (column sum) ret = list(map(sum, list(zip(*r)))) @@ -192,16 +194,16 @@ def make_board(board, build_args, build_target): # ----------------------------- # Build Family # ----------------------------- -def build_boards_list(boards, build_defines, build_system, build_flags_on, build_target): +def build_boards_list(boards, build_defines, build_system, build_flags_on, build_targets): ret = [0, 0, 0] for b in boards: r = [0, 0, 0] if build_system == 'cmake': build_args = [f'-D{d}' for d in build_defines] - r = cmake_board(b, build_args, build_flags_on, build_target) + r = cmake_board(b, build_args, build_flags_on, build_targets) elif build_system == 'make': build_args = ' '.join(f'{d}' for d in build_defines) - r = make_board(b, build_args, build_target) + r = make_board(b, build_args, build_targets) ret[0] += r[0] ret[1] += r[1] ret[2] += r[2] @@ -251,13 +253,11 @@ def get_family_boards(family, one_random, one_first): # ----------------------------- def main(): global verbose - global clean_build global parallel_jobs parser = argparse.ArgumentParser() parser.add_argument('families', nargs='*', default=[], help='Families to build') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to build') - parser.add_argument('-c', '--clean', action='store_true', default=False, help='Clean before build') parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') parser.add_argument('-D', '--define-symbol', action='append', default=[], help='Define to pass to build system') @@ -267,7 +267,8 @@ def main(): parser.add_argument('--one-first', action='store_true', default=False, help='Build only the first board (alphabetical) of each specified family') parser.add_argument('-j', '--jobs', type=int, default=os.cpu_count(), help='Number of jobs to run in parallel') - parser.add_argument('-T', '--target', default='all', help='Build target to use, default is all') + parser.add_argument('-T', '--target', action='append', default=[], + help='Build target to use, may be specified multiple times (default: all)') parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') args = parser.parse_args() @@ -279,9 +280,8 @@ def main(): build_flags_on = args.build_flags_on one_random = args.one_random one_first = args.one_first - build_target = args.target + build_targets = args.target if args.target else ['all'] verbose = args.verbose - clean_build = args.clean parallel_jobs = args.jobs build_defines.append(f'TOOLCHAIN={toolchain}') @@ -310,7 +310,7 @@ def main(): all_boards.extend(get_family_boards(f, one_random, one_first)) # build all boards - result = build_boards_list(all_boards, build_defines, build_system, build_flags_on, build_target) + result = build_boards_list(all_boards, build_defines, build_system, build_flags_on, build_targets) total_time = time.monotonic() - total_time print(build_separator) -- cgit v1.3.1 From a6d4c6d022a3dc597c24f2e312993046345683ad Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Feb 2026 23:42:34 +0700 Subject: change membrowse target to board/target and remove redundant continue-on-error directive fix defsym can be followed by = or , --- .github/workflows/build_util.yml | 1 - hw/bsp/family_support.cmake | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 6863ebdf2..d03c9af81 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -79,7 +79,6 @@ jobs: - name: Membrowse Upload if: inputs.toolchain != 'esp-idf' && inputs.upload-membrowse == true - continue-on-error: true # have server busy issue with membrowse env: MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} run: | diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index f97518faf..699afda92 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -310,7 +310,7 @@ while [ -n \"$pending_ld_scripts\" ]; do \ done; \ ld_scripts=\"$(echo \"$all_ld_scripts\" | xargs)\"") set(MEMBROWSE_LD_DEFS_CMD - "ld_symbols=\"$(${CMAKE_MAKE_PROGRAM} -C ${CMAKE_BINARY_DIR} -t commands ${TARGET} | grep -oP '(?<=--defsym=)[^[:space:]]+' | xargs)\"; \ + "ld_symbols=\"$(${CMAKE_MAKE_PROGRAM} -C ${CMAKE_BINARY_DIR} -t commands ${TARGET} | grep -oP '(?<=--defsym[=,])[^[:space:]]+' | xargs)\"; \ ld_defs=\"\"; \ for symbol in $ld_symbols; do \ ld_defs=\"$ld_defs --def $symbol\"; \ @@ -321,13 +321,13 @@ ld_defs=\"$(echo \"$ld_defs\" | xargs)\"") ${MEMBROWSE_LD_SCRIPTS_CMD}; \ ${MEMBROWSE_LD_DEFS_CMD}; \ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ - MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs --upload --github --target-name ${FAMILY}/${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ + MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs --upload --github --target-name ${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ else \ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs\"; \ fi; \ else \ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ - MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} --identical --upload --github --target-name ${FAMILY}/${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ + MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} --identical --upload --github --target-name ${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ else \ MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} --identical\"; \ fi; \ -- cgit v1.3.1 From 80a05cfcafbaa279c3b0e71d9c26bccaffe11bc4 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Wed, 4 Mar 2026 18:08:07 +0700 Subject: "Claude PR Assistant workflow" --- .github/workflows/claude.yml | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/claude.yml (limited to '.github/workflows') diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 000000000..d300267f1 --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,50 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read # Required for Claude to read CI results on PRs + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # This is an optional setting that allows Claude to read CI results on PRs + additional_permissions: | + actions: read + + # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. + # prompt: 'Update the pull request description to include a summary of changes.' + + # Optional: Add claude_args to customize behavior and configuration + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + # claude_args: '--allowed-tools Bash(gh pr:*)' + -- cgit v1.3.1 From 8479c086796e53205c34142038c65f885c2e3e76 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Wed, 4 Mar 2026 18:08:08 +0700 Subject: "Claude Code Review workflow" --- .github/workflows/claude-code-review.yml | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/claude-code-review.yml (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 000000000..b5e8cfd4d --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,44 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize, ready_for_review, reopened] + # Optional: Only run on specific file changes + # paths: + # - "src/**/*.ts" + # - "src/**/*.tsx" + # - "src/**/*.js" + # - "src/**/*.jsx" + +jobs: + claude-review: + # Optional: Filter by PR author + # if: | + # github.event.pull_request.user.login == 'external-contributor' || + # github.event.pull_request.user.login == 'new-developer' || + # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + id: claude-review + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' + plugins: 'code-review@claude-code-plugins' + prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + -- cgit v1.3.1 From f021d5c1e1de5c1b47fcbdd6d8fb1eea70eafe61 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 4 Mar 2026 18:13:51 +0700 Subject: fix trailing newline in workflow files to pass pre-commit Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/claude-code-review.yml | 1 - .github/workflows/claude.yml | 1 - CLAUDE.md | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) create mode 120000 CLAUDE.md (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index b5e8cfd4d..25f4ad18c 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -41,4 +41,3 @@ jobs: prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md # or https://code.claude.com/docs/en/cli-reference for available options - diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index d300267f1..9471a0591 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -47,4 +47,3 @@ jobs: # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md # or https://code.claude.com/docs/en/cli-reference for available options # claude_args: '--allowed-tools Bash(gh pr:*)' - diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 000000000..47dc3e3d8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file -- cgit v1.3.1 From ce8a77083dc00423b2c1a4c7657aa7290684dea6 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Mar 2026 20:59:26 +0700 Subject: ci: fix claude-code-review for fork PRs Switch pull_request to pull_request_target so secrets and OIDC tokens are available when reviewing PRs from forks. Also add pull-requests: write permission so the action can post review comments. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/claude-code-review.yml | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 25f4ad18c..5ba2fe900 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -1,27 +1,15 @@ name: Claude Code Review on: - pull_request: + pull_request_target: types: [opened, synchronize, ready_for_review, reopened] - # Optional: Only run on specific file changes - # paths: - # - "src/**/*.ts" - # - "src/**/*.tsx" - # - "src/**/*.js" - # - "src/**/*.jsx" jobs: claude-review: - # Optional: Filter by PR author - # if: | - # github.event.pull_request.user.login == 'external-contributor' || - # github.event.pull_request.user.login == 'new-developer' || - # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' - runs-on: ubuntu-latest permissions: contents: read - pull-requests: read + pull-requests: write issues: read id-token: write -- cgit v1.3.1 From 97297fe08bf0357b447f9c735612ce5f03146a31 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Mar 2026 11:12:48 +0700 Subject: update hil test: remove unused ctypes, add fallback for skip boards --- .github/workflows/build.yml | 9 ++++++++- .github/workflows/claude-code-review.yml | 1 + test/hil/hil_test.py | 5 +---- 3 files changed, 10 insertions(+), 5 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9d8b90f5a..ab1d3611f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -291,7 +291,14 @@ jobs: - name: Test on actual hardware run: | - python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS + python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS || \ + (if [ -f "${{ env.HIL_JSON }}.skip" ]; then + SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip") + echo "Re-running with SKIP_BOARDS=$SKIP_BOARDS" + python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS + else + exit 1 + fi) # --------------------------------------- # Hardware in the loop (HIL) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 5ba2fe900..5d7efc115 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -6,6 +6,7 @@ on: jobs: claude-review: + if: false runs-on: ubuntu-latest permissions: contents: read diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index f0b24b3ff..7cffd2da8 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -47,7 +47,7 @@ from multiprocessing import Pool import fs import hashlib import ctypes -from pymtp import MTP, LIBMTP_MTPDevice, LIBMTP_RawDevice +from pymtp import MTP import string ENUM_TIMEOUT = 30 @@ -150,9 +150,6 @@ def read_disk_file(uid, lun, fname): def open_mtp_dev(uid): mtp = MTP() - # Set proper return type for LIBMTP_Open_Raw_Device (pymtp doesn't define it) - mtp.mtp.LIBMTP_Open_Raw_Device.restype = ctypes.POINTER(LIBMTP_MTPDevice) - mtp.mtp.LIBMTP_Open_Raw_Device.argtypes = [ctypes.POINTER(LIBMTP_RawDevice)] # MTP seems to take a while to enumerate timeout = 2 * ENUM_TIMEOUT while timeout > 0: -- cgit v1.3.1 From 83363afa82669e02d5ad264c4e681a63df4b1a91 Mon Sep 17 00:00:00 2001 From: Michael Rogov Papernov Date: Thu, 12 Feb 2026 14:39:12 +0000 Subject: set new membrowse comment github workflow with comment message --- .github/membrowse_pr_message.j2 | 38 +++++++++++++++++++++++++++++++++ .github/workflows/membrowse-comment.yml | 19 ++++++----------- 2 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 .github/membrowse_pr_message.j2 (limited to '.github/workflows') diff --git a/.github/membrowse_pr_message.j2 b/.github/membrowse_pr_message.j2 new file mode 100644 index 000000000..fbba1ee78 --- /dev/null +++ b/.github/membrowse_pr_message.j2 @@ -0,0 +1,38 @@ +{#- Top 10 targets with biggest memory changes + project dashboard link -#} +{% set section_columns = ['.text', '.rodata', '.data', '.bss'] -%} +{#- --- Compute per-target total absolute delta and collect changed targets --- -#} +{% set changed = [] -%} +{% for target in targets -%} +{% if target.has_changes -%} +{% set ns = namespace(total_delta=0, total_current=0) -%} +{% for region in target.regions -%} +{% set ns.total_delta = ns.total_delta + region.delta -%} +{% set ns.total_current = ns.total_current + region.used_size -%} +{% endfor -%} +{% set total_old = ns.total_current - ns.total_delta -%} +{% set pct = (ns.total_delta / total_old * 100) if total_old > 0 else 0 -%} +{% set abs_pct = (ns.total_delta | abs) if total_old == 0 else (pct | abs) -%} +{% set _ = changed.append({'target': target, 'total_current': ns.total_current, 'total_old': total_old, 'total_delta': ns.total_delta, 'pct': pct, 'abs_pct': abs_pct}) -%} +{% endif -%} +{% endfor -%} +{#- --- Sort by absolute percentage change descending and take top 10 --- -#} +{% set sorted_changed = changed | sort(attribute='abs_pct', reverse=true) -%} +{% set top10 = sorted_changed[:10] -%} +{#- --- Render --- -#} +{% if top10 %} +### Top {{ top10 | length }} targets by memory change (%) (out of {{ targets | length }} targets) {% if dashboard_url %} [View Project Dashboard →]({{ dashboard_url }}){% endif %} + +| target | .text | .rodata | .data | .bss | total | % diff | +|--------|-------|---------|-------|------|-------|--------| +{% for info in top10 -%} +{% set target = info.target -%} +{% set section_map = {} -%} +{% for section in target.sections -%} +{% set _ = section_map.update({section.name: section}) -%} +{% endfor -%} +| {% if target.comparison_url %}[{{ target.name }}]({{ target.comparison_url }}){% else %}{{ target.name }}{% endif %} | +{%- for col in section_columns %} {% if col in section_map %}{{ "{:,}".format(section_map[col].old.size) }} → {{ "{:,}".format(section_map[col].size) }} ({{ section_map[col].delta_str }}){% else %}—{% endif %} |{% endfor %} {{ "{:,}".format(info.total_old) }} → {{ "{:,}".format(info.total_current) }} ({% if info.total_delta >= 0 %}+{{ "{:,}".format(info.total_delta) }}{% else %}{{ "{:,}".format(info.total_delta) }}{% endif %}) | {% if info.total_old > 0 %}{% if info.pct >= 0 %}+{% endif %}{{ "%.1f" | format(info.pct) }}%{% else %}N/A{% endif %} | +{% endfor %} +{% else %} +No memory changes detected across {{ targets | length }} target{{ 's' if targets | length != 1 else '' }}.{% if dashboard_url %} [View Project Dashboard →]({{ dashboard_url }}){% endif %} +{% endif -%} diff --git a/.github/workflows/membrowse-comment.yml b/.github/workflows/membrowse-comment.yml index a99c9db51..368a52638 100644 --- a/.github/workflows/membrowse-comment.yml +++ b/.github/workflows/membrowse-comment.yml @@ -11,28 +11,21 @@ jobs: runs-on: ubuntu-latest if: > github.event.workflow_run.event == 'pull_request' && - github.event.workflow_run.conclusion != 'cancelled' + github.event.workflow_run.conclusion == 'success' permissions: + contents: read actions: read pull-requests: write steps: - name: Checkout repository uses: actions/checkout@v6 - - name: Download Artifacts - id: download - uses: actions/download-artifact@v5 - with: - run-id: ${{ github.event.workflow_run.id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - name: membrowse-comment - path: reports - continue-on-error: true - - name: Post Membrowse PR comment - if: steps.download.outcome == 'success' + if: ${{ secrets.MEMBROWSE_API_KEY != '' }} uses: membrowse/membrowse-action/comment-action@v1 with: - json_files: 'reports/*.json' + api_key: ${{ secrets.MEMBROWSE_API_KEY }} + commit: ${{ github.event.workflow_run.head_sha }} + comment_template: .github/membrowse_pr_message.j2 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} -- cgit v1.3.1 From b1de5229f5ff335ad6f899ca5f966a151eeb6516 Mon Sep 17 00:00:00 2001 From: Michael Rogov Papernov Date: Tue, 10 Mar 2026 21:06:39 +0000 Subject: fix secret issue in membrowse-comment --- .github/workflows/membrowse-comment.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/membrowse-comment.yml b/.github/workflows/membrowse-comment.yml index 368a52638..952d8ba37 100644 --- a/.github/workflows/membrowse-comment.yml +++ b/.github/workflows/membrowse-comment.yml @@ -9,9 +9,10 @@ on: jobs: post-comment: runs-on: ubuntu-latest + # Run the comment job even if some of the builds fail if: > github.event.workflow_run.event == 'pull_request' && - github.event.workflow_run.conclusion == 'success' + github.event.workflow_run.conclusion != 'cancelled' permissions: contents: read actions: read @@ -21,11 +22,12 @@ jobs: uses: actions/checkout@v6 - name: Post Membrowse PR comment - if: ${{ secrets.MEMBROWSE_API_KEY != '' }} + if: ${{ env.MEMBROWSE_API_KEY != '' }} uses: membrowse/membrowse-action/comment-action@v1 with: api_key: ${{ secrets.MEMBROWSE_API_KEY }} commit: ${{ github.event.workflow_run.head_sha }} comment_template: .github/membrowse_pr_message.j2 env: + MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} -- cgit v1.3.1 From 38986e392f814e17ba51f02d68f183287529fc0c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Mar 2026 13:34:07 +0700 Subject: also update metrics.json for pr --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ab1d3611f..e0ce08141 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -182,6 +182,7 @@ jobs: name: metrics-comment path: | metrics_compare.md + metrics.json pr_number.txt - name: Post Code Metrics as PR Comment -- cgit v1.3.1 From 2052111bac10fc3184b1dd9558fc1b9ab5c85ea4 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Mar 2026 15:48:49 +0700 Subject: chore(workflows): update GitHub Actions dependencies and improve membrowse error handling update AGENTS.md with metrics compare --- .github/workflows/build_util.yml | 1 + .github/workflows/cifuzz.yml | 2 +- .github/workflows/claude-code-review.yml | 2 +- .github/workflows/claude.yml | 2 +- .github/workflows/membrowse-onboard.yml | 6 ++--- .github/workflows/metrics_comment.yml | 2 +- AGENTS.md | 45 ++++++++++++++++++++++++++++++++ 7 files changed, 53 insertions(+), 7 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index d03c9af81..c9b0d36d9 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -79,6 +79,7 @@ jobs: - name: Membrowse Upload if: inputs.toolchain != 'esp-idf' && inputs.upload-membrowse == true + continue-on-error: true env: MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} run: | diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index d7f1fc066..9b3756a72 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -29,7 +29,7 @@ jobs: fuzz-seconds: 400 - name: Upload Crash - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 5d7efc115..43144bb5e 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 1 diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 9471a0591..50f449949 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -26,7 +26,7 @@ jobs: actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 1 diff --git a/.github/workflows/membrowse-onboard.yml b/.github/workflows/membrowse-onboard.yml index aa7204ffa..4b9e54cff 100644 --- a/.github/workflows/membrowse-onboard.yml +++ b/.github/workflows/membrowse-onboard.yml @@ -17,7 +17,7 @@ jobs: toolchains: ${{ steps.load.outputs.toolchains }} steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Load target matrix id: load @@ -35,7 +35,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: fetch-depth: 0 submodules: recursive @@ -45,7 +45,7 @@ jobs: ${{ fromJson(needs.load-targets.outputs.toolchains)[matrix.toolchain].setup_cmd }} && python3 tools/get_deps.py ${{ matrix.get_deps || matrix.port }} - name: Setup ccache - uses: hendrikmuhs/ccache-action@v1.2 + uses: hendrikmuhs/ccache-action@v1 with: key: ${{ matrix.port }}-${{ matrix.board }} diff --git a/.github/workflows/metrics_comment.yml b/.github/workflows/metrics_comment.yml index 7443f7367..5d250211f 100644 --- a/.github/workflows/metrics_comment.yml +++ b/.github/workflows/metrics_comment.yml @@ -17,7 +17,7 @@ jobs: pull-requests: write steps: - name: Download Artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: run-id: ${{ github.event.workflow_run.id }} github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/AGENTS.md b/AGENTS.md index bbbd7c36d..4e510b01e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -211,6 +211,51 @@ take 2-5 minutes. NEVER CANCEL. Set timeout to 20+ minutes. - Install requirements: `pip install -r docs/requirements.txt` - Build docs: `cd docs && sphinx-build -b html . _build` -- takes 2-3 seconds. NEVER CANCEL. Set timeout to 10+ minutes. +## Code Size Metrics + +Generate and compare code size metrics to evaluate the impact of changes. This is the most common workflow +when making code changes — use it to verify size impact before committing. + +**Quick single-board metrics (preferred for iterative development):** + +```bash +rm -rf cmake-build +python3 tools/build.py -b raspberry_pi_pico --target all --target tinyusb_metrics +python3 tools/metrics.py combine -j -m -f tinyusb/src cmake-build/cmake-build-*/metrics.json +``` + +This builds all examples for one board and produces `metrics.json` + `metrics.md`. Takes ~30 seconds. +NEVER CANCEL. Set timeout to 10+ minutes. + +**Comparing with master (before/after workflow):** + +1. On master: build and save baseline + ```bash + rm -rf cmake-build + python3 tools/build.py -b raspberry_pi_pico --target all --target tinyusb_metrics + python3 tools/metrics.py combine -j -m -f tinyusb/src cmake-build/cmake-build-*/metrics.json + mv metrics.json metrics_master.json + ``` +2. Switch to your branch: rebuild + ```bash + rm -rf cmake-build + python3 tools/build.py -b raspberry_pi_pico --target all --target tinyusb_metrics + python3 tools/metrics.py combine -j -m -f tinyusb/src cmake-build/cmake-build-*/metrics.json + ``` +3. Compare: `python3 tools/metrics.py compare -m -f tinyusb/src metrics_master.json metrics.json` + Produces `metrics_compare.md` showing size differences. + +**Full CI metrics (all arm-gcc families, for thorough validation):** + +```bash +rm -rf cmake-build +FAMILIES=$(python3 .github/workflows/ci_set_matrix.py | python3 -c "import sys,json; d=json.load(sys.stdin); print(' '.join(d.get('arm-gcc',[])))") +python3 tools/build.py --one-first --target all --target tinyusb_metrics $FAMILIES +python3 tools/metrics.py combine -j -m -f tinyusb/src cmake-build/cmake-build-*/metrics.json +``` + +Builds the first board of each family. Takes 2-4 minutes. NEVER CANCEL. Set timeout to 10+ minutes. + ## Code Quality and Validation - Format code: `clang-format -i path/to/file.c` (uses `.clang-format` config) -- cgit v1.3.1 From 79bbea855915048945ba2198b64bd788fbc36aad Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 12 Mar 2026 16:49:51 +0700 Subject: download metrics in case hil failed --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0ce08141..fa32abbb9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -133,6 +133,7 @@ jobs: uses: dawidd6/action-download-artifact@v11 with: workflow: build.yml + workflow_conclusion: '' branch: ${{ github.base_ref }} name: metrics-tinyusb path: base-metrics -- cgit v1.3.1 From 5794e50c377b615ba7d29484cf8575433affe0fe Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Mar 2026 11:46:53 +0700 Subject: rename and migrate kinetis_k32l to new mcux-devices --- .github/workflows/ci_set_matrix.py | 2 +- docs/reference/boards.rst | 6 +- docs/reference/dependencies.rst | 4 +- .../kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h | 170 ------- .../kinetis_k32l2/boards/frdm_k32l2a4s/board.cmake | 15 - hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.h | 96 ---- hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk | 18 - .../boards/frdm_k32l2a4s/clock_config.c | 491 --------------------- .../boards/frdm_k32l2a4s/clock_config.h | 164 ------- .../kinetis_k32l2/boards/frdm_k32l2b/board.cmake | 15 - hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h | 82 ---- hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk | 18 - .../boards/frdm_k32l2b/clock_config.c | 220 --------- .../boards/frdm_k32l2b/clock_config.h | 110 ----- hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake | 15 - hw/bsp/kinetis_k32l2/boards/kuiic/board.h | 69 --- hw/bsp/kinetis_k32l2/boards/kuiic/board.mk | 18 - hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c | 39 -- hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h | 14 - hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld | 216 --------- hw/bsp/kinetis_k32l2/family.c | 175 -------- hw/bsp/kinetis_k32l2/family.cmake | 97 ---- hw/bsp/kinetis_k32l2/family.mk | 35 -- tools/get_deps.py | 11 +- 24 files changed, 13 insertions(+), 2087 deletions(-) delete mode 100644 hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.cmake delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/board.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/board.mk delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld delete mode 100644 hw/bsp/kinetis_k32l2/family.c delete mode 100644 hw/bsp/kinetis_k32l2/family.cmake delete mode 100644 hw/bsp/kinetis_k32l2/family.mk (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index cd7dfa76b..b5c8d9544 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -34,7 +34,7 @@ family_list = { "hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k": ["arm-gcc", "arm-clang"], - "kinetis_k32l2": ["arm-gcc", "arm-clang"], + "kinetis_k32l": ["arm-gcc", "arm-clang"], "kinetis_kl": ["arm-gcc", "arm-clang"], "lpc11": ["arm-gcc", "arm-clang"], "lpc13": ["arm-gcc", "arm-clang"], diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index f6dd3cd91..eaef078d3 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -166,9 +166,9 @@ teensy_40 Teensy 4.0 imxrt ht teensy_41 Teensy 4.1 imxrt https://www.pjrc.com/store/teensy41.html frdm_k64f Freedom K64F kinetis_k https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F teensy_35 Teensy 3.5 kinetis_k https://www.pjrc.com/store/teensy35.html -frdm_k32l2a4s Freedom K32L2A4S kinetis_k32l2 https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-K32L2A4S -frdm_k32l2b Freedom K32L2B3 kinetis_k32l2 https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/nxp-freedom-development-platform-for-k32-l2b-mcus:FRDM-K32L2B3 -kuiic Kuiic kinetis_k32l2 https://github.com/nxf58843/kuiic +frdm_k32l2a4s Freedom K32L2A4S kinetis_k32l https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-K32L2A4S +frdm_k32l2b Freedom K32L2B3 kinetis_k32l https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/nxp-freedom-development-platform-for-k32-l2b-mcus:FRDM-K32L2B3 +kuiic Kuiic kinetis_k32l https://github.com/nxf58843/kuiic frdm_kl25z fomu kinetis_kl https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-kl14-kl15-kl24-kl25-mcus:FRDM-KL25Z lpcxpresso11u37 LPCXpresso11U37 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13074 lpcxpresso11u68 LPCXpresso11U68 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13058 diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index ce5f265d5..9b61e10a8 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -26,7 +26,7 @@ hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 11f57e578c7feea13f21c79ea0efab2630ac68c7 nrf hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc100_120 nuc121_125 nuc126 nuc505 hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git b41cf930e65c734d8ec6de04f1d57d46787c76ae lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 -hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt +hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_k32l kinetis_kl lpc51 lpc54 lpc55 mcx imxrt hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git 675543bcc9baa8170f868ab7ba316d418dbcf41f rp2040 hw/mcu/renesas/fsp https://github.com/renesas/fsp.git edcc97d684b6f716728a60d7a6fea049d9870bd6 ra hw/mcu/renesas/rx https://github.com/kkitayam/rx_device.git 706b4e0cf485605c32351e2f90f5698267996023 rx @@ -81,7 +81,7 @@ hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.gi hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 ra stm32n6 lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all diff --git a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h deleted file mode 100644 index 0225abe8d..000000000 --- a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * FreeRTOS Kernel V10.0.0 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. If you wish to use our Amazon - * FreeRTOS name, please do so in a fair use way that does not cause confusion. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -// skip if included from IAR assembler -#ifndef __IASMARM__ - #include "fsl_device_registers.h" -#endif - -/* Cortex M23/M33 port configuration. */ -#define configENABLE_MPU 0 -#if defined(__ARM_FP) && __ARM_FP >= 4 - #define configENABLE_FPU 1 -#else - #define configENABLE_FPU 0 -#endif -#define configENABLE_TRUSTZONE 0 -#define configMINIMAL_SECURE_STACK_SIZE (1024) - -#define configUSE_PREEMPTION 1 -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configCPU_CLOCK_HZ SystemCoreClock -#define configTICK_RATE_HZ ( 1000 ) -#define configMAX_PRIORITIES ( 5 ) -#define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) -#define configMAX_TASK_NAME_LEN 16 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configQUEUE_REGISTRY_SIZE 2 -#define configUSE_QUEUE_SETS 0 -#define configUSE_TIME_SLICING 0 -#define configUSE_NEWLIB_REENTRANT 0 -#define configENABLE_BACKWARD_COMPATIBILITY 1 -#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 - -#define configSUPPORT_STATIC_ALLOCATION 1 -#define configSUPPORT_DYNAMIC_ALLOCATION 0 - -/* Hook function related definitions. */ -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 0 -#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning -#define configCHECK_FOR_STACK_OVERFLOW 2 -#define configCHECK_HANDLER_INSTALLATION 0 - -/* Run time and task stats gathering related definitions. */ -#define configGENERATE_RUN_TIME_STATS 0 -#define configRECORD_STACK_HIGH_ADDRESS 1 -#define configUSE_TRACE_FACILITY 1 // legacy trace -#define configUSE_STATS_FORMATTING_FUNCTIONS 0 - -/* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES 2 - -/* Software timer related definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) -#define configTIMER_QUEUE_LENGTH 32 -#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE - -/* Optional functions - most linkers will remove unused functions anyway. */ -#define INCLUDE_vTaskPrioritySet 0 -#define INCLUDE_uxTaskPriorityGet 0 -#define INCLUDE_vTaskDelete 0 -#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY -#define INCLUDE_xResumeFromISR 0 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTaskGetSchedulerState 0 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 0 -#define INCLUDE_xTaskGetIdleTaskHandle 0 -#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 -#define INCLUDE_pcTaskGetTaskName 0 -#define INCLUDE_eTaskGetState 0 -#define INCLUDE_xEventGroupSetBitFromISR 0 -#define INCLUDE_xTimerPendFunctionCall 0 - -/* Define to trap errors during development. */ -// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 -#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) - #define configASSERT(_exp) \ - do {\ - if ( !(_exp) ) { \ - volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ - if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ - taskDISABLE_INTERRUPTS(); \ - __asm("BKPT #0\n"); \ - }\ - }\ - } while(0) -#else - #define configASSERT( x ) -#endif - -/* FreeRTOS hooks to NVIC vectors */ -#define xPortPendSVHandler PendSV_Handler -#define xPortSysTickHandler SysTick_Handler -#define vPortSVCHandler SVC_Handler - -//--------------------------------------------------------------------+ -// Interrupt nesting behavior configuration. -//--------------------------------------------------------------------+ - -// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header -#define configPRIO_BITS 2 - -/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ -#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(setting); -} - -/*FUNCTION********************************************************************** - * - * Function Name : CLOCK_CONFIG_FircSafeConfig - * Description : This function is used to safely configure FIRC clock. - * In default out of reset, the CPU is clocked from FIRC(IRC48M). - * Before setting FIRC, change to use SIRC as system clock, - * then configure FIRC. After FIRC is set, change back to use FIRC - * in case SIRC need to be configured. - * Param fircConfig : FIRC configuration. - * - *END**************************************************************************/ -static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig) -{ - scg_sys_clk_config_t curConfig; - const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable, - .div1 = kSCG_AsyncClkDisable, - .div3 = kSCG_AsyncClkDivBy2, - .range = kSCG_SircRangeHigh}; - scg_sys_clk_config_t sysClkSafeConfigSource = { - .divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core clock divider */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcSirc, /* System clock source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; - /* Init Sirc. */ - CLOCK_InitSirc(&scgSircConfig); - /* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */ - CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != sysClkSafeConfigSource.src); - - /* Init Firc. */ - CLOCK_InitFirc(fircConfig); - /* Change back to use FIRC as system clock source in order to configure SIRC if needed. */ - sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc; - CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != sysClkSafeConfigSource.src); -} - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ -void BOARD_InitBootClocks(void) -{ - BOARD_BootClockRUN(); -} - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockRUN -called_from_default_init: true -outputs: -- {id: Core_clock.outFreq, value: 48 MHz} -- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} -- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: OSC32KCLK.outFreq, value: 32.768 kHz} -- {id: SIRCDIV3_CLK.outFreq, value: 4 MHz} -- {id: SIRC_CLK.outFreq, value: 8 MHz} -- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} -- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} -- {id: SOSC_CLK.outFreq, value: 32.768 kHz} -- {id: Slow_clock.outFreq, value: 24 MHz} -- {id: System_clock.outFreq, value: 48 MHz} -settings: -- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} -- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} -- {id: SCG.SIRCDIV3.scale, value: '2', locked: true} -- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} -- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} -- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} -sources: -- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockRUN configuration - ******************************************************************************/ -const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN = - { - .divSlow = kSCG_SysClkDivBy2, /* Slow Clock Divider: divided by 2 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcFirc, /* Fast IRC is selected as System Clock Source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; -const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN = - { - .freq = 32768U, /* System Oscillator frequency: 32768Hz */ - .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ - .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ - .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ - .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ - }; -const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN = - { - .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ - .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDivBy2, /* Slow IRC Clock Divider 3: divided by 2 */ - .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ - }; -const scg_firc_config_t g_scgFircConfig_BOARD_BootClockRUN = - { - .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ - .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ - .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ - .trimConfig = NULL, /* Fast IRC Trim disabled */ - }; -const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockRUN = - { - .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ - .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ - .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ - .prediv = 0, /* Divided by 1 */ - .mult = 0, /* Multiply Factor is 16 */ - }; -/******************************************************************************* - * Code for BOARD_BootClockRUN configuration - ******************************************************************************/ -void BOARD_BootClockRUN(void) -{ - scg_sys_clk_config_t curConfig; - - /* Init SOSC according to board configuration. */ - CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockRUN); - /* Set the XTAL0 frequency based on board settings. */ - CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockRUN.freq); - /* Init FIRC. */ - CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockRUN); - /* Init SIRC. */ - CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockRUN); - /* Set SCG to FIRC mode. */ - CLOCK_SetRunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockRUN); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != g_sysClkConfig_BOARD_BootClockRUN.src); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; -} - -/******************************************************************************* - ********************* Configuration BOARD_BootClockHSRUN ********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockHSRUN -outputs: -- {id: CLKOUT.outFreq, value: 8 MHz} -- {id: Core_clock.outFreq, value: 96 MHz, locked: true, accuracy: '0.001'} -- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} -- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: OSC32KCLK.outFreq, value: 32.768 kHz} -- {id: PLLDIV1_CLK.outFreq, value: 96 MHz} -- {id: PLLDIV3_CLK.outFreq, value: 96 MHz} -- {id: SIRCDIV1_CLK.outFreq, value: 8 MHz} -- {id: SIRCDIV3_CLK.outFreq, value: 8 MHz} -- {id: SIRC_CLK.outFreq, value: 8 MHz} -- {id: SOSCDIV1_CLK.outFreq, value: 32.768 kHz} -- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} -- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} -- {id: SOSC_CLK.outFreq, value: 32.768 kHz} -- {id: Slow_clock.outFreq, value: 24 MHz, locked: true, accuracy: '0.001'} -- {id: System_clock.outFreq, value: 96 MHz} -settings: -- {id: SCGMode, value: SPLL} -- {id: powerMode, value: HSRUN} -- {id: CLKOUTConfig, value: 'yes'} -- {id: SCG.DIVSLOW.scale, value: '4'} -- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} -- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} -- {id: SCG.PREDIV.scale, value: '4'} -- {id: SCG.SCSSEL.sel, value: SCG.SPLL_DIV2_CLK} -- {id: SCG.SIRCDIV1.scale, value: '1', locked: true} -- {id: SCG.SIRCDIV3.scale, value: '1', locked: true} -- {id: SCG.SOSCDIV1.scale, value: '1', locked: true} -- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} -- {id: SCG.SPLLDIV1.scale, value: '1', locked: true} -- {id: SCG.SPLLDIV3.scale, value: '1', locked: true} -- {id: SCG.SPLLSRCSEL.sel, value: SCG.FIRC} -- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} -- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} -- {id: SCG_SPLLCSR_SPLLEN_CFG, value: Enabled} -sources: -- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN = - { - .divSlow = kSCG_SysClkDivBy4, /* Slow Clock Divider: divided by 4 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcSysPll, /* System PLL is selected as System Clock Source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; -const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN = - { - .freq = 32768U, /* System Oscillator frequency: 32768Hz */ - .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ - .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ - .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ - .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ - }; -const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN = - { - .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ - .div1 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 3: divided by 1 */ - .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ - }; -const scg_firc_config_t g_scgFircConfig_BOARD_BootClockHSRUN = - { - .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ - .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ - .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ - .trimConfig = NULL, /* Fast IRC Trim disabled */ - }; -const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockHSRUN = - { - .enableMode = kSCG_SysPllEnable, /* Enable SPLL clock */ - .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 3: divided by 1 */ - .src = kSCG_SysPllSrcFirc, /* System PLL clock source is Fast IRC */ - .prediv = 3, /* Divided by 4 */ - .mult = 0, /* Multiply Factor is 16 */ - }; -/******************************************************************************* - * Code for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -void BOARD_BootClockHSRUN(void) -{ - scg_sys_clk_config_t curConfig; - - /* Init SOSC according to board configuration. */ - CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockHSRUN); - /* Set the XTAL0 frequency based on board settings. */ - CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockHSRUN.freq); - /* Init FIRC. */ - CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockHSRUN); - /* Init SIRC. */ - CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockHSRUN); - /* Init SysPll. */ - CLOCK_InitSysPll(&g_scgSysPllConfig_BOARD_BootClockHSRUN); - /* Set HSRUN power mode. */ - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); - SMC_SetPowerModeHsrun(SMC); - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) - { - } - - /* Set SCG to SPLL mode. */ - CLOCK_SetHsrunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockHSRUN); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != g_sysClkConfig_BOARD_BootClockHSRUN.src); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK; - /* Set SCG CLKOUT selection. */ - CLOCK_CONFIG_SetScgOutSel(SCG_CLKOUTCNFG_SIRC); -} - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockVLPR -outputs: -- {id: Core_clock.outFreq, value: 8 MHz, locked: true, accuracy: '0.001'} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: SIRC_CLK.outFreq, value: 8 MHz} -- {id: Slow_clock.outFreq, value: 1 MHz, locked: true, accuracy: '0.001'} -- {id: System_clock.outFreq, value: 8 MHz} -settings: -- {id: SCGMode, value: SIRC} -- {id: powerMode, value: VLPR} -- {id: SCG.DIVSLOW.scale, value: '8'} -- {id: SCG.SCSSEL.sel, value: SCG.SIRC} -- {id: SCG_FIRCCSR_FIRCLPEN_CFG, value: Enabled} -sources: -- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockVLPR configuration - ******************************************************************************/ -const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR = - { - .divSlow = kSCG_SysClkDivBy8, /* Slow Clock Divider: divided by 8 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcSirc, /* Slow IRC is selected as System Clock Source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; -const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR = - { - .freq = 0U, /* System Oscillator frequency: 0Hz */ - .enableMode = SCG_SOSC_DISABLE, /* System OSC disabled */ - .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 3: Clock output is disabled */ - .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ - .workMode = kSCG_SysOscModeExt, /* Use external clock */ - }; -const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR = - { - .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ - .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 3: Clock output is disabled */ - .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ - }; -const scg_firc_config_t g_scgFircConfig_BOARD_BootClockVLPR = - { - .enableMode = kSCG_FircEnable | kSCG_FircEnableInLowPower,/* Enable FIRC clock, Enable FIRC in low power mode */ - .div1 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 3: Clock output is disabled */ - .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ - .trimConfig = NULL, /* Fast IRC Trim disabled */ - }; -const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockVLPR = - { - .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ - .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ - .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ - .prediv = 0, /* Divided by 1 */ - .mult = 0, /* Multiply Factor is 16 */ - }; -/******************************************************************************* - * Code for BOARD_BootClockVLPR configuration - ******************************************************************************/ -void BOARD_BootClockVLPR(void) -{ - /* Init FIRC. */ - CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockVLPR); - /* Init SIRC. */ - CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockVLPR); - /* Allow SMC all power modes. */ - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); - /* Set VLPR power mode. */ - SMC_SetPowerModeVlpr(SMC); - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) - { - } - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; -} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h deleted file mode 100644 index c01d5e03c..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _CLOCK_CONFIG_H_ -#define _CLOCK_CONFIG_H_ - -#include "fsl_common.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define BOARD_XTAL0_CLK_HZ 32768U /*!< Board xtal0 frequency in Hz */ - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes default configuration of clocks. - * - */ -void BOARD_InitBootClocks(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockRUN configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ - -/*! @brief SCG set for BOARD_BootClockRUN configuration. - */ -extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN; -/*! @brief System OSC set for BOARD_BootClockRUN configuration. - */ -extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN; -/*! @brief SIRC set for BOARD_BootClockRUN configuration. - */ -extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN; -/*! @brief FIRC set for BOARD_BootClockRUN configuration. - */ -extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockRUN; -extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockRUN; -/*! @brief Low Power FLL set for BOARD_BootClockRUN configuration. - */ - -/******************************************************************************* - * API for BOARD_BootClockRUN configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockRUN(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************* Configuration BOARD_BootClockHSRUN ********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKHSRUN_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ - -/*! @brief SCG set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN; -/*! @brief System OSC set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN; -/*! @brief SIRC set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN; -/*! @brief FIRC set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockHSRUN; -extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockHSRUN; -/*! @brief Low Power FLL set for BOARD_BootClockHSRUN configuration. - */ - -/******************************************************************************* - * API for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockHSRUN(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 8000000U /*!< Core clock frequency: 8000000Hz */ - -/*! @brief SCG set for BOARD_BootClockVLPR configuration. - */ -extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR; -/*! @brief System OSC set for BOARD_BootClockVLPR configuration. - */ -extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR; -/*! @brief SIRC set for BOARD_BootClockVLPR configuration. - */ -extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR; -/*! @brief FIRC set for BOARD_BootClockVLPR configuration. - */ -extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockVLPR; -extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockVLPR; -/*! @brief Low Power FLL set for BOARD_BootClockVLPR configuration. - */ - -/******************************************************************************* - * API for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockVLPR(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake deleted file mode 100644 index 2ec2acace..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake +++ /dev/null @@ -1,15 +0,0 @@ -set(MCU_VARIANT K32L2B31A) - -set(JLINK_DEVICE K32L2B31xxxxA) -set(PYOCD_TARGET K32L2B) - -set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/K32L2B31xxxxA_flash.ld) - -function(update_board TARGET) - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c - ) - target_compile_definitions(${TARGET} PUBLIC - CPU_K32L2B31VLH0A - ) -endfunction() diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h deleted file mode 100644 index 854340d6d..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -/* metadata: - name: Freedom K32L2B3 - url: https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/nxp-freedom-development-platform-for-k32-l2b-mcus:FRDM-K32L2B3 -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#include "fsl_device_registers.h" - -#define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M - -// LED -#define LED_PIN_CLOCK kCLOCK_PortD -#define LED_GPIO GPIOD -#define LED_PORT PORTD -#define LED_PIN 5 -#define LED_STATE_ON 0 - -// SW3 button1 -#define BUTTON_PIN_CLOCK kCLOCK_PortC -#define BUTTON_GPIO GPIOC -#define BUTTON_PORT PORTC -#define BUTTON_PIN 3 -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_PORT LPUART0 -#define UART_PIN_CLOCK kCLOCK_PortA -#define UART_PIN_PORT PORTA -#define UART_PIN_RX 1u -#define UART_PIN_TX 2u -#define SOPT5_LPUART0RXSRC_LPUART_RX 0x00u /*!<@brief LPUART0 Receive Data Source Select: LPUART_RX pin */ -#define SOPT5_LPUART0TXSRC_LPUART_TX 0x00u /*!<@brief LPUART0 Transmit Data Source Select: LPUART0_TX pin */ -#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk) - -static inline void BOARD_InitBootPins(void) { - /* PORTA1 (pin 23) is configured as LPUART0_RX */ - PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); - /* PORTA2 (pin 24) is configured as LPUART0_TX */ - PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); - - SIM->SOPT5 = ((SIM->SOPT5 & - /* Mask bits to zero which are setting */ - (~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK))) - /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ - | SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX) - /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ - | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX)); - - BOARD_BootClockRUN(); - SystemCoreClockUpdate(); - CLOCK_SetLpuart0Clock(1); -} - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk deleted file mode 100644 index 9cf36c500..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk +++ /dev/null @@ -1,18 +0,0 @@ -MCU = K32L2B31A - -CFLAGS += -DCPU_K32L2B31VLH0A - -# mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls - -# All source paths should be relative to the top level. -LD_FILE = $(MCU_DIR)/gcc/K32L2B31xxxxA_flash.ld - -# For flash-jlink target -JLINK_DEVICE = K32L2B31xxxxA - -# For flash-pyocd target -PYOCD_TARGET = K32L2B - -# flash using pyocd -flash: flash-pyocd diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c deleted file mode 100644 index 86eb42ef8..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ -/* - * How to setup clock using clock driver functions: - * - * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock - * and flash clock are in allowed range during clock mode switch. - * - * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. - * - * 3. Call CLOCK_SetMcgliteConfig to set MCG_Lite configuration. - * - * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. - */ - -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!GlobalInfo -product: Clocks v7.0 -processor: K32L2B31xxxxA -package_id: K32L2B31VLH0A -mcu_data: ksdk2_0 -processor_version: 9.0.0 -board: FRDM-K32L2B - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -#include "fsl_smc.h" -#include "clock_config.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ -#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ -#define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -//extern uint32_t SystemCoreClock; - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ -void BOARD_InitBootClocks(void) -{ - BOARD_BootClockRUN(); -} - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockRUN -called_from_default_init: true -outputs: -- {id: Bus_clock.outFreq, value: 24 MHz} -- {id: Core_clock.outFreq, value: 48 MHz} -- {id: Flash_clock.outFreq, value: 24 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: MCGIRCLK.outFreq, value: 8 MHz} -- {id: MCGPCLK.outFreq, value: 48 MHz} -- {id: System_clock.outFreq, value: 48 MHz} -settings: -- {id: MCGMode, value: HIRC} -- {id: MCG.CLKS.sel, value: MCG.HIRC} -- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: MCG_C2_RANGE0_CFG, value: Very_high} -- {id: MCG_MC_HIRCEN_CFG, value: Enabled} -- {id: OSC0_CR_ERCLKEN_CFG, value: Enabled} -- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} -- {id: SIM.CLKOUTSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.COPCLKSEL.sel, value: OSC.OSCERCLK} -- {id: SIM.FLEXIOSRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.LPUART0SRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.LPUART1SRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} -- {id: SIM.TPMSRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.USBSRCSEL.sel, value: MCG.MCGPCLK} -sources: -- {id: MCG.HIRC.outFreq, value: 48 MHz} -- {id: OSC.OSC.outFreq, value: 32 MHz} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockRUN configuration - ******************************************************************************/ -const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = - { - .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ - .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ - .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ - .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ - .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ - .hircEnableInNotHircMode = true, /* HIRC source is enabled */ - }; -const sim_clock_config_t simConfig_BOARD_BootClockRUN = - { - .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ - .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ - }; -const osc_config_t oscConfig_BOARD_BootClockRUN = - { - .freq = 0U, /* Oscillator frequency: 0Hz */ - .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ - .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ - .oscerConfig = - { - .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ - } - }; - -/******************************************************************************* - * Code for BOARD_BootClockRUN configuration - ******************************************************************************/ -void BOARD_BootClockRUN(void) -{ - /* Set the system clock dividers in SIM to safe value. */ - CLOCK_SetSimSafeDivs(); - /* Set MCG to HIRC mode. */ - CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); - /* Set the clock configuration in SIM module. */ - CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; -} - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockVLPR -outputs: -- {id: Bus_clock.outFreq, value: 1 MHz} -- {id: Core_clock.outFreq, value: 2 MHz} -- {id: Flash_clock.outFreq, value: 1 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: MCGIRCLK.outFreq, value: 2 MHz} -- {id: System_clock.outFreq, value: 2 MHz} -settings: -- {id: MCGMode, value: LIRC2M} -- {id: powerMode, value: VLPR} -- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: RTCCLKOUTConfig, value: 'yes'} -- {id: SIM.OUTDIV4.scale, value: '2', locked: true} -- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} -sources: -- {id: MCG.LIRC.outFreq, value: 2 MHz} -- {id: OSC.OSC.outFreq, value: 32.768 kHz} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockVLPR configuration - ******************************************************************************/ -const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR = - { - .outSrc = kMCGLITE_ClkSrcLirc, /* MCGOUTCLK source is LIRC */ - .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ - .ircs = kMCGLITE_Lirc2M, /* Slow internal reference (LIRC) 2 MHz clock selected */ - .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ - .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ - .hircEnableInNotHircMode = false, /* HIRC source is not enabled */ - }; -const sim_clock_config_t simConfig_BOARD_BootClockVLPR = - { - .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ - .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ - }; -const osc_config_t oscConfig_BOARD_BootClockVLPR = - { - .freq = 0U, /* Oscillator frequency: 0Hz */ - .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ - .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ - .oscerConfig = - { - .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ - } - }; - -/******************************************************************************* - * Code for BOARD_BootClockVLPR configuration - ******************************************************************************/ -void BOARD_BootClockVLPR(void) -{ - /* Set the system clock dividers in SIM to safe value. */ - CLOCK_SetSimSafeDivs(); - /* Set MCG to LIRC2M mode. */ - CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockVLPR); - /* Set the clock configuration in SIM module. */ - CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); - /* Set VLPR power mode. */ - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); -#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) - SMC_SetPowerModeVlpr(SMC, false); -#else - SMC_SetPowerModeVlpr(SMC); -#endif - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) - { - } - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; -} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h deleted file mode 100644 index 37328e7d8..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _CLOCK_CONFIG_H_ -#define _CLOCK_CONFIG_H_ - -#include "fsl_common.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes default configuration of clocks. - * - */ -void BOARD_InitBootClocks(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockRUN configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ - -/*! @brief MCG lite set for BOARD_BootClockRUN configuration. - */ -extern const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN; -/*! @brief SIM module set for BOARD_BootClockRUN configuration. - */ -extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; -/*! @brief OSC set for BOARD_BootClockRUN configuration. - */ -extern const osc_config_t oscConfig_BOARD_BootClockRUN; - -/******************************************************************************* - * API for BOARD_BootClockRUN configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockRUN(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 2000000U /*!< Core clock frequency: 2000000Hz */ - -/*! @brief MCG lite set for BOARD_BootClockVLPR configuration. - */ -extern const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR; -/*! @brief SIM module set for BOARD_BootClockVLPR configuration. - */ -extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; -/*! @brief OSC set for BOARD_BootClockVLPR configuration. - */ -extern const osc_config_t oscConfig_BOARD_BootClockVLPR; - -/******************************************************************************* - * API for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockVLPR(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake b/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake deleted file mode 100644 index cf14000ac..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake +++ /dev/null @@ -1,15 +0,0 @@ -set(MCU_VARIANT K32L2B31A) - -set(JLINK_DEVICE K32L2B31xxxxA) -set(PYOCD_TARGET K32L2B) - -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/kuiic.ld) - -function(update_board TARGET) - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c - ) - target_compile_definitions(${TARGET} PUBLIC - CPU_K32L2B31VLH0A - ) -endfunction() diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.h b/hw/bsp/kinetis_k32l2/boards/kuiic/board.h deleted file mode 100644 index f5895fc65..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -/* metadata: - name: Kuiic - url: https://github.com/nxf58843/kuiic -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#include "fsl_device_registers.h" - -#define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M - -// LED -#define LED_PIN_CLOCK kCLOCK_PortA -#define LED_GPIO GPIOA -#define LED_PORT PORTA -#define LED_PIN 2 -#define LED_STATE_ON 1 - -// UART -#define UART_PORT LPUART1 -#define UART_PIN_RX 3u -#define UART_PIN_TX 0u - -#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk) - -static inline void BOARD_InitBootPins(void) { - /* PORTC3 is configured as LPUART0_RX */ - PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3); - /* PORTA2 (pin 24) is configured as LPUART0_TX */ - PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); - - SIM->SOPT5 = ((SIM->SOPT5 & - /* Mask bits to zero which are setting */ - (~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK))) - /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ - | SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX) - /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ - | SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX)); - CLOCK_SetLpuart1Clock(1); -} - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk b/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk deleted file mode 100644 index 2bc5b1e34..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk +++ /dev/null @@ -1,18 +0,0 @@ -MCU = K32L2B31A - -CFLAGS += -DCPU_K32L2B31VLH0A - -# mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/kuiic.ld - -# For flash-jlink target -JLINK_DEVICE = K32L2B31xxxxA - -# For flash-pyocd target -PYOCD_TARGET = K32L2B - -# flash using pyocd -flash: flash-pyocd diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c deleted file mode 100644 index c1a6d1a8d..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "clock_config.h" -#include "fsl_clock.h" - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -// extern uint32_t SystemCoreClock; - -/******************************************************************************* - * Variables for BOARD_BootClockRUN configuration - ******************************************************************************/ -const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = { - .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ - .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ - .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ - .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ - .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ - .hircEnableInNotHircMode = true, /* HIRC source is enabled */ -}; -const sim_clock_config_t simConfig_BOARD_BootClockRUN = { - .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ - .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ -}; - -/******************************************************************************* - * Code for BOARD_BootClockRUN configuration - ******************************************************************************/ -void BOARD_BootClockRUN(void) -{ - /* Set the system clock dividers in SIM to safe value. */ - CLOCK_SetSimSafeDivs(); - /* Set MCG to HIRC mode. */ - CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); - /* Set the clock configuration in SIM module. */ - CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; -} diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h deleted file mode 100644 index 920cad98f..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef CLOCK_CONFIG_H -#define CLOCK_CONFIG_H - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */ -#define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */ -#define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */ -#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ - -void BOARD_BootClockRUN(void); - -#endif diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld b/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld deleted file mode 100644 index f478a99c7..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld +++ /dev/null @@ -1,216 +0,0 @@ -/* -** ################################################################### -** Processors: K32L2B31VFM0A -** K32L2B31VFT0A -** K32L2B31VLH0A -** K32L2B31VMP0A -** -** Compiler: GNU C Compiler -** Reference manual: K32L2B3xRM, Rev.0, July 2019 -** Version: rev. 1.0, 2019-07-30 -** Build: b190930 -** -** Abstract: -** Linker file for the GNU C Compiler -** -** Copyright 2016 Freescale Semiconductor, Inc. -** Copyright 2016-2019 NXP -** All rights reserved. -** -** SPDX-License-Identifier: BSD-3-Clause -** -** http: www.nxp.com -** mail: support@nxp.com -** -** ################################################################### -*/ - -/* Entry Point */ -ENTRY(Reset_Handler) - -HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; - -/* Specify the memory areas */ -MEMORY -{ - m_interrupts (RX) : ORIGIN = 0x00008000, LENGTH = 0x00000200 - m_flash_config (RX) : ORIGIN = 0x00008400, LENGTH = 0x00000010 - m_text (RX) : ORIGIN = 0x00008410, LENGTH = 0x00037BF0 - m_data (RW) : ORIGIN = 0x1FFFE000, LENGTH = 0x00008000 -} - -/* Define output sections */ -SECTIONS -{ - /* The startup code goes first into internal flash */ - .interrupts : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } > m_interrupts - - .flash_config : - { - . = ALIGN(4); - KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ - . = ALIGN(4); - } > m_flash_config - - /* The program code and other data goes into internal flash */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - KEEP (*(.init)) - KEEP (*(.fini)) - . = ALIGN(4); - } > m_text - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > m_text - - .ARM : - { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } > m_text - - .ctors : - { - __CTOR_LIST__ = .; - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - from the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __CTOR_END__ = .; - } > m_text - - .dtors : - { - __DTOR_LIST__ = .; - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - __DTOR_END__ = .; - } > m_text - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } > m_text - - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } > m_text - - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } > m_text - - __etext = .; /* define a global symbol at end of code */ - __DATA_ROM = .; /* Symbol is used by startup for data initialization */ - - /* reserve MTB memory at the beginning of m_data */ - .mtb : /* MTB buffer address as defined by the hardware */ - { - . = ALIGN(8); - _mtb_start = .; - KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */ - . = ALIGN(8); - _mtb_end = .; - } > m_data - - .data : AT(__DATA_ROM) - { - . = ALIGN(4); - __DATA_RAM = .; - __data_start__ = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - KEEP(*(.jcr*)) - . = ALIGN(4); - __data_end__ = .; /* define a global symbol at data end */ - } > m_data - - __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); - text_end = ORIGIN(m_text) + LENGTH(m_text); - ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") - - /* Uninitialized data section */ - .bss : - { - /* This is used by the startup in order to initialize the .bss section */ - . = ALIGN(4); - __START_BSS = .; - __bss_start__ = .; - *(.bss) - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - __END_BSS = .; - } > m_data - - .heap : - { - . = ALIGN(8); - __end__ = .; - PROVIDE(end = .); - __HeapBase = .; - . += HEAP_SIZE; - __HeapLimit = .; - __heap_limit = .; /* Add for _sbrk */ - } > m_data - - .stack : - { - . = ALIGN(8); - . += STACK_SIZE; - } > m_data - - /* Initializes stack on the end of block */ - __StackTop = ORIGIN(m_data) + LENGTH(m_data); - __StackLimit = __StackTop - STACK_SIZE; - PROVIDE(__stack = __StackTop); - - .ARM.attributes 0 : { *(.ARM.attributes) } - - ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") -} diff --git a/hw/bsp/kinetis_k32l2/family.c b/hw/bsp/kinetis_k32l2/family.c deleted file mode 100644 index ec8dc6ecf..000000000 --- a/hw/bsp/kinetis_k32l2/family.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018, hathach (tinyusb.org) - * Copyright (c) 2020, Koji Kitayama - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -/* metadata: - manufacturer: NXP -*/ - -#include "fsl_gpio.h" -#include "fsl_port.h" -#include "fsl_clock.h" -#include "fsl_lpuart.h" - -#include "clock_config.h" -#include "bsp/board_api.h" -#include "board.h" - - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB0_IRQHandler(void) { - tud_int_handler(0); -} - -void board_init(void) { - /* Enable port clocks for GPIO pins */ - CLOCK_EnableClock(kCLOCK_PortA); - CLOCK_EnableClock(kCLOCK_PortB); - CLOCK_EnableClock(kCLOCK_PortC); - CLOCK_EnableClock(kCLOCK_PortD); - CLOCK_EnableClock(kCLOCK_PortE); - - BOARD_InitBootPins(); - BOARD_BootClockRUN(); - SystemCoreClockUpdate(); - - gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0}; - GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); - PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio); - -#ifdef BUTTON_PIN - gpio_pin_config_t button_config = {kGPIO_DigitalInput, 0}; - GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); - const port_pin_config_t BUTTON_CFG = { - kPORT_PullUp, - kPORT_FastSlewRate, - kPORT_PassiveFilterDisable, -#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN - kPORT_OpenDrainDisable, -#endif - kPORT_LowDriveStrength, - kPORT_MuxAsGpio, -#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK - kPORT_UnlockRegister -#endif - }; - PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); -#endif - -#if CFG_TUSB_OS == OPT_OS_NONE - // 1ms tick timer - SysTick_Config(SystemCoreClock / 1000); -#elif CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); -#endif - - lpuart_config_t uart_config; - LPUART_GetDefaultConfig(&uart_config); - uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; - uart_config.enableTx = true; - uart_config.enableRx = true; - LPUART_Init(UART_PORT, &uart_config, UART_CLOCK_SOURCE_HZ); - - // USB - CLOCK_EnableUsbfs0Clock(USB_CLOCK_SOURCE, 48000000U); -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) { - GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); -} - -uint32_t board_button_read(void) { -#ifdef BUTTON_PIN - return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); -#else - return 0; -#endif -} - -int board_uart_read(uint8_t* buf, int len) { -#if 0 /* - Use this version if want the LED to blink during BOARD=board_test, - without having to hit a key. - */ - if( 0U != (kLPUART_RxDataRegFullFlag & LPUART_GetStatusFlags( UART_PORT )) ) - { - LPUART_ReadBlocking(UART_PORT, buf, len); - return len; - } - - return( 0 ); -#else /* Wait for 'len' characters to come in */ - - LPUART_ReadBlocking(UART_PORT, buf, len); - return len; - -#endif -} - -int board_uart_write(void const* buf, int len) { - LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -void SysTick_Handler(void) { - system_ticks++; -} - -uint32_t tusb_time_millis_api(void) { - return system_ticks; -} - -#endif - -#ifndef __ICCARM__ -// Implement _start() since we use linker flag '-nostartfiles'. -// Requires defined __STARTUP_CLEAR_BSS, -extern int main(void); - -TU_ATTR_UNUSED void _start(void) { - // called by startup code - main(); - while (1) {} -} - -#ifdef __clang__ -void _exit (int __status) { - (void) __status; - while (1) {} -} -#endif - -#endif diff --git a/hw/bsp/kinetis_k32l2/family.cmake b/hw/bsp/kinetis_k32l2/family.cmake deleted file mode 100644 index 110335ab2..000000000 --- a/hw/bsp/kinetis_k32l2/family.cmake +++ /dev/null @@ -1,97 +0,0 @@ -include_guard() - -set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) -set(CMSIS_DIR ${TOP}/lib/CMSIS_5) - -# include board specific -include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) - -# toolchain set up -set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) - -set(FAMILY_MCUS KINETIS_K32L CACHE INTERNAL "") - - -#------------------------------------ -# Startup & Linker script -#------------------------------------ -set(LD_FILE_Clang ${LD_FILE_GNU}) -set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) -set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - -#------------------------------------ -# Board Target -#------------------------------------ -function(family_add_board BOARD_TARGET) - add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/drivers/gpio/fsl_gpio.c - ${SDK_DIR}/drivers/lpuart/fsl_lpuart.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - __STARTUP_CLEAR_BSS - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers - ${SDK_DIR}/drivers/common - ${SDK_DIR}/drivers/gpio - ${SDK_DIR}/drivers/lpuart - ${SDK_DIR}/drivers/port - ${SDK_DIR}/drivers/smc - ) - - update_board(${BOARD_TARGET}) -endfunction() - -#------------------------------------ -# Functions -#------------------------------------ -function(family_configure_example TARGET RTOS) - family_configure_common(${TARGET} ${RTOS}) - family_add_tinyusb(${TARGET} OPT_MCU_KINETIS_K32L) - - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c - ${TOP}/src/portable/nxp/khci/dcd_khci.c - ${TOP}/src/portable/nxp/khci/hcd_khci.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} - ) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - --specs=nosys.specs --specs=nano.specs - -nostartfiles - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") - set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") - endif () - set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES - SKIP_LINTING ON - COMPILE_OPTIONS -w) - - # Flashing - family_flash_jlink(${TARGET}) - family_add_bin_hex(${TARGET}) - family_flash_teensy(${TARGET}) -endfunction() diff --git a/hw/bsp/kinetis_k32l2/family.mk b/hw/bsp/kinetis_k32l2/family.mk deleted file mode 100644 index e18348d4d..000000000 --- a/hw/bsp/kinetis_k32l2/family.mk +++ /dev/null @@ -1,35 +0,0 @@ -UF2_FAMILY_ID = 0x7f83e793 -SDK_DIR = hw/mcu/nxp/mcux-sdk -MCU_DIR = $(SDK_DIR)/devices/$(MCU) - -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m0plus - -CFLAGS += \ - -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K32L - -LDFLAGS_GCC += \ - -nostartfiles \ - -specs=nosys.specs -specs=nano.specs - -SRC_C += \ - src/portable/nxp/khci/dcd_khci.c \ - src/portable/nxp/khci/hcd_khci.c \ - $(MCU_DIR)/system_$(MCU).c \ - $(MCU_DIR)/drivers/fsl_clock.c \ - $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ - $(SDK_DIR)/drivers/lpuart/fsl_lpuart.c - -INC += \ - $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/$(MCU_DIR) \ - $(TOP)/$(MCU_DIR)/project_template \ - $(TOP)/$(MCU_DIR)/drivers \ - $(TOP)/$(SDK_DIR)/drivers/common \ - $(TOP)/$(SDK_DIR)/drivers/gpio \ - $(TOP)/$(SDK_DIR)/drivers/lpuart \ - $(TOP)/$(SDK_DIR)/drivers/port \ - $(TOP)/$(SDK_DIR)/drivers/smc \ - -SRC_S += $(MCU_DIR)/gcc/startup_$(MCU).S diff --git a/tools/get_deps.py b/tools/get_deps.py index 115120ef7..77c3a593a 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -63,10 +63,13 @@ deps_optional = { 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43'], 'hw/mcu/nxp/mcuxsdk-core': ['https://github.com/nxp-mcuxpresso/mcuxsdk-core', '0c5c6b16deb211110e06bde896cdff59ab213e16', - 'imxrt lpc51 lpc55 mcx'], + 'imxrt kinetis_k32l lpc51 lpc55 mcx'], 'hw/mcu/nxp/mcux-sdk': ['https://github.com/nxp-mcuxpresso/mcux-sdk', 'a1bdae309a14ec95a4f64a96d3315a4f89c397c6', - 'kinetis_k kinetis_k32l2 kinetis_kl lpc54 rw61x'], + 'kinetis_k kinetis_kl lpc54 rw61x'], + 'hw/mcu/nxp/mcux-devices-kinetis': ['https://github.com/nxp-mcuxpresso/mcux-devices-kinetis', + '98a155e666c54f396e528ec3131f27a5d5b71f76', + 'kinetis_k32l'], 'hw/mcu/nxp/mcux-devices-lpc': ['https://github.com/nxp-mcuxpresso/mcux-devices-lpc', '8096b783ec09d0d1c8629025a5f9d8e7df26e520', 'lpc51 lpc55'], @@ -267,7 +270,7 @@ deps_optional = { 'hpmicro'], 'lib/CMSIS_5': ['https://github.com/ARM-software/CMSIS_5.git', '2b7495b8535bdcb306dac29b9ded4cfb679d7e5c', - 'kinetis_k kinetis_k32l2 kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x ' + 'kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x ' 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 ' 'stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 ' 'stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba ' @@ -275,7 +278,7 @@ deps_optional = { 'tm4c '], 'lib/CMSIS_6': ['https://github.com/ARM-software/CMSIS_6.git', '6f0a58d01aa9bd2feba212097f9afe7acd991d52', - 'imxrt ra stm32n6 lpc51 lpc55 mcx'], + 'imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', 'lpc55'], -- cgit v1.3.1 From adf853643b3db80444da5c3018eb214e244fcf47 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Mar 2026 23:01:38 +0700 Subject: add ft9xx-gcc toolchain support to CI --- .circleci/config.yml | 1 + .circleci/config2.yml | 5 +++++ .github/actions/setup_toolchain/download/action.yml | 5 +++++ .github/actions/setup_toolchain/toolchain.json | 1 + .github/workflows/build.yml | 1 + .github/workflows/ci_set_matrix.py | 2 ++ 6 files changed, 15 insertions(+) (limited to '.github/workflows') diff --git a/.circleci/config.yml b/.circleci/config.yml index c084fc226..66799910d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,6 +28,7 @@ jobs: "arm-clang" "arm-gcc" "esp-idf" + "ft9xx-gcc" "msp430-gcc" "riscv-gcc" ) diff --git a/.circleci/config2.yml b/.circleci/config2.yml index bb0ac350f..4cd848131 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -33,6 +33,8 @@ commands: wget --progress=dot:giga $toolchain_url -O toolchain.run chmod +x toolchain.run ./toolchain.run -p ~/cache/<< parameters.toolchain >>/gnurx -y + elif [[ << parameters.toolchain >> == ft9xx-gcc ]]; then + wget --progress=dot:giga $toolchain_url -O ~/cache/<< parameters.toolchain >>/ft9xxtoolchain.deb elif [[ << parameters.toolchain >> == arm-iar ]]; then wget --progress=dot:giga https://netstorage.iar.com/FileStore/STANDARD/001/003/926/iar-lmsc-tools_1.8_amd64.deb -O ~/cache/<< parameters.toolchain >>/iar-lmsc-tools.deb wget --progress=dot:giga $toolchain_url -O ~/cache/<< parameters.toolchain >>/toolchain.deb @@ -48,6 +50,9 @@ commands: sudo dpkg -i ~/cache/<< parameters.toolchain >>/iar-lmsc-tools.deb sudo dpkg --ignore-depends=libusb-1.0-0 -i ~/cache/<< parameters.toolchain >>/toolchain.deb echo "export PATH=$PATH:/opt/iar/cxarm/arm/bin" >> $BASH_ENV + elif [[ << parameters.toolchain >> == ft9xx-gcc ]]; then + sudo apt install -y ~/cache/<< parameters.toolchain >>/ft9xxtoolchain.deb + echo "export PATH=$PATH:/opt/ft32/bin" >> $BASH_ENV else echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV fi diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml index 5a3f66cb1..f691b0499 100644 --- a/.github/actions/setup_toolchain/download/action.yml +++ b/.github/actions/setup_toolchain/download/action.yml @@ -32,6 +32,8 @@ runs: wget --progress=dot:giga ${TOOLCHAIN_URL} -O toolchain.run chmod +x toolchain.run ./toolchain.run -p ~/cache/${TOOLCHAIN}/gnurx -y + elif [[ ${TOOLCHAIN} == ft9xx-gcc ]]; then + wget --progress=dot:giga ${TOOLCHAIN_URL} -O ~/cache/${TOOLCHAIN}/ft9xxtoolchain.deb elif [[ ${TOOLCHAIN} == arm-iar ]]; then wget --progress=dot:giga https://netstorage.iar.com/FileStore/STANDARD/001/003/926/iar-lmsc-tools_1.8_amd64.deb -O ~/cache/${TOOLCHAIN}/iar-lmsc-tools.deb wget --progress=dot:giga ${TOOLCHAIN_URL} -O ~/cache/${TOOLCHAIN}/cxarm.deb @@ -56,6 +58,9 @@ runs: sudo dpkg -i ~/cache/${TOOLCHAIN}/iar-lmsc-tools.deb sudo apt install -y ~/cache/${TOOLCHAIN}/cxarm.deb TOOLCHAIN_PATH="/opt/iar/cxarm/arm/bin" + elif [[ ${TOOLCHAIN} == ft9xx-gcc ]]; then + sudo apt install -y ~/cache/${TOOLCHAIN}/ft9xxtoolchain.deb + TOOLCHAIN_PATH="/opt/ft32/bin" else # Find the single toolchain bin directory TOOLCHAIN_BIN_DIRS=(~/cache/${TOOLCHAIN}/*/bin) diff --git a/.github/actions/setup_toolchain/toolchain.json b/.github/actions/setup_toolchain/toolchain.json index ee41a5cb4..85c746356 100644 --- a/.github/actions/setup_toolchain/toolchain.json +++ b/.github/actions/setup_toolchain/toolchain.json @@ -2,6 +2,7 @@ "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-19.1.1/LLVM-ET-Arm-19.1.1-Linux-x86_64.tar.xz", "arm-gcc": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-linux-x64.tar.gz", + "ft9xx-gcc": "https://github.com/Bridgetek/ft32-toolchain-linux/releases/download/v2.7.6/ft9xxtoolchain_2.7.6_amd64.deb", "arm-gcc-macos-latest": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-darwin-arm64.tar.gz", "arm-gcc-windows-latest": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-win32-x64.zip", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fa32abbb9..960ccf8ee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -83,6 +83,7 @@ jobs: #- 'arm-clang' - 'arm-gcc' #- 'esp-idf' + - 'ft9xx-gcc' - 'msp430-gcc' - 'riscv-gcc' with: diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index b5c8d9544..1ea5199cf 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -8,6 +8,7 @@ toolchain_list = [ "arm-iar", "arm-gcc", "esp-idf", + "ft9xx-gcc", "msp430-gcc", "riscv-gcc", "rx-gcc" @@ -30,6 +31,7 @@ family_list = { "ch32v30x": ["riscv-gcc"], "da1469x": ["arm-gcc"], "fomu": ["riscv-gcc"], + "ft9xx": ["ft9xx-gcc"], "gd32vf103": ["riscv-gcc"], "hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], -- cgit v1.3.1 From 36400d108fc3d5aad754305d2667456321ad3412 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 14 Mar 2026 00:11:45 +0700 Subject: migrate kinetis_k32l build system to new mcux-devices paths --- .github/workflows/ci_set_matrix.py | 6 +-- .../kinetis_k32l/boards/frdm_k32l2a4s/board.cmake | 4 +- hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/board.mk | 10 ++++- hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.cmake | 4 +- hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.mk | 10 ++++- hw/bsp/kinetis_k32l/boards/kuiic/board.cmake | 2 +- hw/bsp/kinetis_k32l/boards/kuiic/board.mk | 8 +++- hw/bsp/kinetis_k32l/family.cmake | 43 +++++++++------------- hw/bsp/kinetis_k32l/family.mk | 32 ++++++++-------- 9 files changed, 64 insertions(+), 55 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 1ea5199cf..98d15c8f9 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -35,9 +35,9 @@ family_list = { "gd32vf103": ["riscv-gcc"], "hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], - "kinetis_k": ["arm-gcc", "arm-clang"], - "kinetis_k32l": ["arm-gcc", "arm-clang"], - "kinetis_kl": ["arm-gcc", "arm-clang"], + "kinetis_k": ["arm-gcc"], + "kinetis_k32l": ["arm-gcc"], + "kinetis_kl": ["arm-gcc"], "lpc11": ["arm-gcc", "arm-clang"], "lpc13": ["arm-gcc", "arm-clang"], "lpc15": ["arm-gcc", "arm-clang"], diff --git a/hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/board.cmake b/hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/board.cmake index d7cafa495..3e7a4cac6 100644 --- a/hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/board.cmake +++ b/hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/board.cmake @@ -4,7 +4,7 @@ set(MCU_CORE ${MCU_VARIANT}) set(JLINK_DEVICE K32L2A41xxxxA) set(PYOCD_TARGET K32L2A) -set(LD_FILE_GNU ${SDK_DIR}/K32L/${MCU_VARIANT}/gcc/K32L2A41xxxxA_flash.ld) +set(LD_FILE_GNU ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/gcc/K32L2A41xxxxA_flash.ld) function(update_board TARGET) target_sources(${TARGET} PUBLIC @@ -14,6 +14,6 @@ function(update_board TARGET) CPU_K32L2A41VLH1A ) target_include_directories(${TARGET} PUBLIC - ${SDK_DIR}/K32L/periph1 + ${MCUX_DEVICES}/K32L/periph1 ) endfunction() diff --git a/hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/board.mk b/hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/board.mk index fb3eb2a03..513b78d66 100644 --- a/hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/board.mk +++ b/hw/bsp/kinetis_k32l/boards/frdm_k32l2a4s/board.mk @@ -1,4 +1,4 @@ -MCU = K32L2A41A +MCU_VARIANT = K32L2A41A CFLAGS += -DCPU_K32L2A41VLH1A @@ -6,7 +6,13 @@ CFLAGS += -DCPU_K32L2A41VLH1A CFLAGS_GCC += -Wno-error=unused-parameter -Wno-error=redundant-decls -Wno-error=cast-qual # All source paths should be relative to the top level. -LD_FILE = $(MCU_DIR)/gcc/K32L2A41xxxxA_flash.ld +LD_FILE = $(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/gcc/K32L2A41xxxxA_flash.ld + +INC += \ + $(TOP)/$(MCUX_DEVICES)/K32L/periph1 + +SRC_C += \ + $(BOARD_PATH)/clock_config.c # For flash-jlink target JLINK_DEVICE = K32L2A41xxxxA diff --git a/hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.cmake b/hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.cmake index f02230063..0efb0cb3f 100644 --- a/hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.cmake +++ b/hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.cmake @@ -4,7 +4,7 @@ set(MCU_CORE ${MCU_VARIANT}) set(JLINK_DEVICE K32L2B31xxxxA) set(PYOCD_TARGET K32L2B) -set(LD_FILE_GNU ${SDK_DIR}/K32L/${MCU_VARIANT}/gcc/K32L2B31xxxxA_flash.ld) +set(LD_FILE_GNU ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/gcc/K32L2B31xxxxA_flash.ld) function(update_board TARGET) target_sources(${TARGET} PUBLIC @@ -14,6 +14,6 @@ function(update_board TARGET) CPU_K32L2B31VLH0A ) target_include_directories(${TARGET} PUBLIC - ${SDK_DIR}/K32L/periph2 + ${MCUX_DEVICES}/K32L/periph2 ) endfunction() diff --git a/hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.mk b/hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.mk index 9cf36c500..b204a142c 100644 --- a/hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.mk +++ b/hw/bsp/kinetis_k32l/boards/frdm_k32l2b/board.mk @@ -1,4 +1,4 @@ -MCU = K32L2B31A +MCU_VARIANT = K32L2B31A CFLAGS += -DCPU_K32L2B31VLH0A @@ -6,7 +6,13 @@ CFLAGS += -DCPU_K32L2B31VLH0A CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. -LD_FILE = $(MCU_DIR)/gcc/K32L2B31xxxxA_flash.ld +LD_FILE = $(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/gcc/K32L2B31xxxxA_flash.ld + +INC += \ + $(TOP)/$(MCUX_DEVICES)/K32L/periph2 + +SRC_C += \ + $(BOARD_PATH)/clock_config.c # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA diff --git a/hw/bsp/kinetis_k32l/boards/kuiic/board.cmake b/hw/bsp/kinetis_k32l/boards/kuiic/board.cmake index c99029109..506f23e51 100644 --- a/hw/bsp/kinetis_k32l/boards/kuiic/board.cmake +++ b/hw/bsp/kinetis_k32l/boards/kuiic/board.cmake @@ -14,6 +14,6 @@ function(update_board TARGET) CPU_K32L2B31VLH0A ) target_include_directories(${TARGET} PUBLIC - ${SDK_DIR}/K32L/periph2 + ${MCUX_DEVICES}/K32L/periph2 ) endfunction() diff --git a/hw/bsp/kinetis_k32l/boards/kuiic/board.mk b/hw/bsp/kinetis_k32l/boards/kuiic/board.mk index 2bc5b1e34..4dc4ff60b 100644 --- a/hw/bsp/kinetis_k32l/boards/kuiic/board.mk +++ b/hw/bsp/kinetis_k32l/boards/kuiic/board.mk @@ -1,4 +1,4 @@ -MCU = K32L2B31A +MCU_VARIANT = K32L2B31A CFLAGS += -DCPU_K32L2B31VLH0A @@ -8,6 +8,12 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/kuiic.ld +INC += \ + $(TOP)/$(MCUX_DEVICES)/K32L/periph2 + +SRC_C += \ + $(BOARD_PATH)/clock_config.c + # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA diff --git a/hw/bsp/kinetis_k32l/family.cmake b/hw/bsp/kinetis_k32l/family.cmake index 694017cb4..020695589 100644 --- a/hw/bsp/kinetis_k32l/family.cmake +++ b/hw/bsp/kinetis_k32l/family.cmake @@ -1,7 +1,7 @@ include_guard() -set(MCUX_DIR ${TOP}/hw/mcu/nxp/mcuxsdk-core) -set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-devices-kinetis) +set(MCUX_CORE ${TOP}/hw/mcu/nxp/mcuxsdk-core) +set(MCUX_DEVICES ${TOP}/hw/mcu/nxp/mcux-devices-kinetis) set(CMSIS_DIR ${TOP}/lib/CMSIS_6) # include board specific @@ -18,14 +18,11 @@ set(FAMILY_MCUS KINETIS_K32L CACHE INTERNAL "") # Startup & Linker script #------------------------------------ if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${SDK_DIR}/K32L/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) + set(LD_FILE_GNU ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) endif () -set(LD_FILE_Clang ${LD_FILE_GNU}) - if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/K32L/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) + set(STARTUP_FILE_GNU ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) endif () -set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) #------------------------------------ # Board Target @@ -33,24 +30,25 @@ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC # driver - ${MCUX_DIR}/drivers/gpio/fsl_gpio.c - ${MCUX_DIR}/drivers/lpuart/fsl_lpuart.c + ${MCUX_CORE}/drivers/gpio/fsl_gpio.c + ${MCUX_CORE}/drivers/common/fsl_common_arm.c + ${MCUX_CORE}/drivers/lpuart/fsl_lpuart.c # mcu - ${SDK_DIR}/K32L/${MCU_VARIANT}/system_${MCU_VARIANT}.c - ${SDK_DIR}/K32L/${MCU_VARIANT}/drivers/fsl_clock.c + ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/system_${MCU_VARIANT}.c + ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/drivers/fsl_clock.c ) target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMSIS_DIR}/CMSIS/Core/Include - ${MCUX_DIR}/drivers/common - ${MCUX_DIR}/drivers/gpio - ${MCUX_DIR}/drivers/lpuart - ${MCUX_DIR}/drivers/port - ${MCUX_DIR}/drivers/smc - ${SDK_DIR}/K32L/${MCU_VARIANT} - ${SDK_DIR}/K32L/${MCU_VARIANT}/drivers + ${MCUX_CORE}/drivers/common + ${MCUX_CORE}/drivers/gpio + ${MCUX_CORE}/drivers/lpuart + ${MCUX_CORE}/drivers/port + ${MCUX_CORE}/drivers/smc + ${MCUX_DEVICES}/K32L/${MCU_VARIANT} + ${MCUX_DEVICES}/K32L/${MCU_VARIANT}/drivers ) update_board(${BOARD_TARGET}) @@ -82,19 +80,12 @@ function(family_configure_example TARGET RTOS) --specs=nosys.specs --specs=nano.specs -nostartfiles ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - ) + set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) endif () - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") - set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") - endif () set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES SKIP_LINTING ON COMPILE_OPTIONS -w) diff --git a/hw/bsp/kinetis_k32l/family.mk b/hw/bsp/kinetis_k32l/family.mk index e18348d4d..2802337d3 100644 --- a/hw/bsp/kinetis_k32l/family.mk +++ b/hw/bsp/kinetis_k32l/family.mk @@ -1,9 +1,9 @@ UF2_FAMILY_ID = 0x7f83e793 -SDK_DIR = hw/mcu/nxp/mcux-sdk -MCU_DIR = $(SDK_DIR)/devices/$(MCU) include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus +MCUX_CORE = hw/mcu/nxp/mcuxsdk-core +MCUX_DEVICES = hw/mcu/nxp/mcux-devices-kinetis CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K32L @@ -15,21 +15,21 @@ LDFLAGS_GCC += \ SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ src/portable/nxp/khci/hcd_khci.c \ - $(MCU_DIR)/system_$(MCU).c \ - $(MCU_DIR)/drivers/fsl_clock.c \ - $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ - $(SDK_DIR)/drivers/lpuart/fsl_lpuart.c + $(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/system_$(MCU_VARIANT).c \ + $(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/drivers/fsl_clock.c \ + $(MCUX_CORE)/drivers/gpio/fsl_gpio.c \ + $(MCUX_CORE)/drivers/lpuart/fsl_lpuart.c \ + $(MCUX_CORE)/drivers/common/fsl_common_arm.c INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/$(MCU_DIR) \ - $(TOP)/$(MCU_DIR)/project_template \ - $(TOP)/$(MCU_DIR)/drivers \ - $(TOP)/$(SDK_DIR)/drivers/common \ - $(TOP)/$(SDK_DIR)/drivers/gpio \ - $(TOP)/$(SDK_DIR)/drivers/lpuart \ - $(TOP)/$(SDK_DIR)/drivers/port \ - $(TOP)/$(SDK_DIR)/drivers/smc \ + $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ + $(TOP)/$(MCUX_DEVICES)/K32L/$(MCU_VARIANT) \ + $(TOP)/$(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/drivers \ + $(TOP)/$(MCUX_CORE)/drivers/common \ + $(TOP)/$(MCUX_CORE)/drivers/gpio \ + $(TOP)/$(MCUX_CORE)/drivers/lpuart \ + $(TOP)/$(MCUX_CORE)/drivers/port \ + $(TOP)/$(MCUX_CORE)/drivers/smc -SRC_S += $(MCU_DIR)/gcc/startup_$(MCU).S +SRC_S += $(MCUX_DEVICES)/K32L/$(MCU_VARIANT)/gcc/startup_$(MCU_VARIANT).S -- cgit v1.3.1 From c5e3098c37cf165ffde9a304238558294e328e73 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 14 Mar 2026 11:08:52 +0700 Subject: update rx65n_target: correct pin configuration and remove unused USB interrupt definitions --- .github/workflows/ci_set_matrix.py | 1 + docs/reference/boards.rst | 2 +- docs/reference/dependencies.rst | 8 ++++---- hw/bsp/rx/boards/rx65n_target/board.cmake | 5 ----- hw/bsp/rx/boards/rx65n_target/rx65n_target.c | 2 +- hw/bsp/stm32h7/boards/stm32h747disco/board.h | 4 ++-- tools/get_deps.py | 2 +- 7 files changed, 10 insertions(+), 14 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 98d15c8f9..1d35f15dd 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -26,6 +26,7 @@ family_list = { "at32f45x": ["arm-gcc"], "broadcom_32bit": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], + "ch32f20x": ["arm-gcc"], "ch32v10x": ["riscv-gcc"], "ch32v20x": ["riscv-gcc"], "ch32v30x": ["riscv-gcc"], diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index ef53c66c1..ec91b343e 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -301,7 +301,7 @@ stm32h723nucleo STM32 H723 Nucleo stm32h7 https://www.s stm32h743eval STM32 H743 Eval stm32h7 https://www.st.com/en/evaluation-tools/stm32h743i-eval.html stm32h743nucleo STM32 H743 Nucleo stm32h7 https://www.st.com/en/evaluation-tools/nucleo-h743zi.html stm32h745disco STM32 H745 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h745i-disco.html -stm32h747disco STM32 H745 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h745i-disco.html +stm32h747disco STM32 H747 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h747i-disco.html stm32h750_weact STM32 H750 WeAct stm32h7 https://www.adafruit.com/product/5032 stm32h750bdk STM32 H750b Discovery Kit stm32h7 https://www.st.com/en/evaluation-tools/stm32h750b-dk.html waveshare_openh743i Waveshare Open H743i stm32h7 https://www.waveshare.com/openh743i-c-standard.htm diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 450ec6a25..c5b755577 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -4,9 +4,9 @@ Dependencies MCU low-level peripheral drivers and external libraries for building TinyUSB examples -======================================== ================================================================ ======================================== =================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ======================================================================================================================================================================================================================================================================================================================================== Local Path Repo Commit Required by -======================================== ================================================================ ======================================== =================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ======================================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s hw/mcu/analog/msdk https://github.com/analogdevicesinc/msdk.git b20b398d3e5e2007594e54a74ba3d2a2e50ddd75 maxim hw/mcu/artery/at32f402_405 https://github.com/ArteryTek/AT32F402_405_Firmware_Library.git 4424515c2663e82438654e0947695295df2abdfe at32f402_405 @@ -87,7 +87,7 @@ hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.gi hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg tm4c +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samg tm4c lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all @@ -95,4 +95,4 @@ lib/sct_neopixel https://github.com/gsteiert/sct_neopix lib/threadx https://github.com/eclipse-threadx/threadx.git 4b6e8100d932a3a67b34c6eb17f84f3bffb9e2ae all tools/linkermap https://github.com/hathach/linkermap.git 8e1f440fa15c567aceb5aa0d14f6d18c329cc67f all tools/uf2 https://github.com/microsoft/uf2.git c594542b2faa01cc33a2b97c9fbebc38549df80a all -======================================== ================================================================ ======================================== =================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ======================================================================================================================================================================================================================================================================================================================================== diff --git a/hw/bsp/rx/boards/rx65n_target/board.cmake b/hw/bsp/rx/boards/rx65n_target/board.cmake index e365fe8ad..c8b9286bc 100644 --- a/hw/bsp/rx/boards/rx65n_target/board.cmake +++ b/hw/bsp/rx/boards/rx65n_target/board.cmake @@ -19,9 +19,4 @@ function(update_board TARGET) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) - target_compile_definitions(${TARGET} PUBLIC - IR_USB0_USBI0=IR_PERIB_INTB185 - IER_USB0_USBI0=IER_PERIB_INTB185 - IEN_USB0_USBI0=IEN_PERIB_INTB185 - ) endfunction() diff --git a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c index dbaa9d6fe..318cd1b6d 100644 --- a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c +++ b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c @@ -116,7 +116,7 @@ void board_pin_init(void) PORTA.PCR.BIT.B4 = 1U; MPC.PA4PFS.BYTE = 0b01010; PORTA.PMR.BIT.B3 = 1U; - MPC.PA5PFS.BYTE = 0b01010; + MPC.PA3PFS.BYTE = 0b01010; /* USB VBUS -> P16 */ PORT1.PMR.BIT.B6 = 1U; diff --git a/hw/bsp/stm32h7/boards/stm32h747disco/board.h b/hw/bsp/stm32h7/boards/stm32h747disco/board.h index 0a25c89dc..1793338f8 100644 --- a/hw/bsp/stm32h7/boards/stm32h747disco/board.h +++ b/hw/bsp/stm32h7/boards/stm32h747disco/board.h @@ -25,8 +25,8 @@ */ /* metadata: - name: STM32 H745 Discovery - url: https://www.st.com/en/evaluation-tools/stm32h745i-disco.html + name: STM32 H747 Discovery + url: https://www.st.com/en/evaluation-tools/stm32h747i-disco.html */ #ifndef BOARD_H_ diff --git a/tools/get_deps.py b/tools/get_deps.py index c4ec5454e..25b85ac3b 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -274,7 +274,7 @@ deps_optional = { 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 ' 'stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 ' 'stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba ' - 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg ' + 'sam3x samd11 samd21 samd2x_l2x samd51 samd5x_e5x same5x same7x samg ' 'tm4c '], 'lib/CMSIS_6': ['https://github.com/ARM-software/CMSIS_6.git', '6f0a58d01aa9bd2feba212097f9afe7acd991d52', -- cgit v1.3.1 From 6c895e7af45107702705cc532af4abb35d2546cf Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 18 Mar 2026 00:26:18 +0700 Subject: Update several actions to latest version --- .github/actions/setup_toolchain/download/action.yml | 2 +- .github/actions/setup_toolchain/espressif/action.yml | 2 +- .github/workflows/build.yml | 6 +++--- .github/workflows/build_util.yml | 4 ++-- .github/workflows/cifuzz.yml | 2 +- .github/workflows/static_analysis.yml | 6 +++--- 6 files changed, 11 insertions(+), 11 deletions(-) (limited to '.github/workflows') diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml index f691b0499..77d3bcf19 100644 --- a/.github/actions/setup_toolchain/download/action.yml +++ b/.github/actions/setup_toolchain/download/action.yml @@ -13,7 +13,7 @@ runs: steps: - name: Cache Toolchain if: ${{ !startsWith(inputs.toolchain_url, 'https://github.com') }} - uses: actions/cache@v4 + uses: actions/cache@v5 id: cache-toolchain-download with: path: ~/cache/${{ inputs.toolchain }} diff --git a/.github/actions/setup_toolchain/espressif/action.yml b/.github/actions/setup_toolchain/espressif/action.yml index 90ef753c4..ec1ff2e91 100644 --- a/.github/actions/setup_toolchain/espressif/action.yml +++ b/.github/actions/setup_toolchain/espressif/action.yml @@ -21,7 +21,7 @@ runs: shell: bash - name: Cache Docker Image - uses: actions/cache@v4 + uses: actions/cache@v5 id: cache-toolchain-espressif with: path: ${{ env.DOCKER_ESP_IDF }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 960ccf8ee..f549bb1e4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,7 +29,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 2 # Needed for push commit comparison - - uses: dorny/paths-filter@v3 + - uses: dorny/paths-filter@v4 id: filter with: filters: | @@ -124,7 +124,7 @@ jobs: - name: Upload Metrics Artifact if: github.event_name == 'push' || github.event_name == 'release' - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: metrics-tinyusb path: metrics.json @@ -179,7 +179,7 @@ jobs: - name: Upload Metrics Comment Artifact if: github.event_name == 'pull_request' - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: metrics-comment path: | diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index c9b0d36d9..69b6f28d5 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -90,14 +90,14 @@ jobs: - name: Upload Artifacts for Metrics if: inputs.upload-metrics == true && inputs.code-changed == true - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: metrics-${{ matrix.arg }} path: cmake-build/cmake-build-*/metrics.json - name: Upload Artifacts for Hardware Testing if: inputs.upload-artifacts == true && inputs.code-changed == true - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: binaries-${{ matrix.arg }} path: | diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 9b3756a72..ff75a8ba6 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -29,7 +29,7 @@ jobs: fuzz-seconds: 400 - name: Upload Crash - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index a78682d7a..d440bf69e 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -84,7 +84,7 @@ jobs: category: CodeQL - name: Upload artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: codeql-${{ matrix.board }} path: ${{ steps.analyze.outputs.sarif-output }} @@ -136,7 +136,7 @@ jobs: category: PVS-Studio - name: Upload artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: pvs-studio-${{ matrix.board }} path: pvs-studio-${{ matrix.board }}.sarif @@ -236,7 +236,7 @@ jobs: category: IAR-CStat - name: Upload artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: iar-cstat-${{ matrix.board }} path: iar-cstat-${{ matrix.board }}.sarif -- cgit v1.3.1 From c3e5fcadadcbefcfb884f2bf6ef9af87ae9b581c Mon Sep 17 00:00:00 2001 From: alt-0191 <2223147307@qq.com> Date: Thu, 26 Feb 2026 21:13:07 +0800 Subject: ci: add ch58x to build matrix (riscv-gcc) --- .github/workflows/ci_set_matrix.py | 1 + 1 file changed, 1 insertion(+) (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 1d35f15dd..7fa3e0094 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -30,6 +30,7 @@ family_list = { "ch32v10x": ["riscv-gcc"], "ch32v20x": ["riscv-gcc"], "ch32v30x": ["riscv-gcc"], + "ch58x": ["riscv-gcc"], "da1469x": ["arm-gcc"], "fomu": ["riscv-gcc"], "ft9xx": ["ft9xx-gcc"], -- cgit v1.3.1 From ed3318f927a8cc2895344665f99a49dfc3b01461 Mon Sep 17 00:00:00 2001 From: Michael Rogov Papernov Date: Tue, 31 Mar 2026 10:33:02 +0100 Subject: dont cancel build on merge to master --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f549bb1e4..60f4c7ca1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} env: HIL_JSON: test/hil/tinyusb.json -- cgit v1.3.1 From 9a2bd7b46ca06490f96d7a7de5ff7d775ef9cfdb Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 26 Apr 2026 12:47:59 +0200 Subject: run hil_hfp on gcc build Co-authored-by: Copilot Signed-off-by: HiFiPhile --- .github/workflows/build.yml | 26 +++++++++------ test/hil/hil_ci_set_matrix.py | 75 ++++++++++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 39 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60f4c7ca1..cd71740ae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,9 +12,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} -env: - HIL_JSON: test/hil/tinyusb.json - jobs: # Check if the code changes and we need to run ci build # Cannot use paths filter in the on-event since we want this workflow to run even when there are no code changes, to register the commit chain @@ -59,11 +56,12 @@ jobs: id: set-matrix-json run: | # build matrix - MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py)/ + MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) echo "matrix=$MATRIX_JSON" echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT - # hil matrix - HIL_MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py ${{ env.HIL_JSON }}) + + # HIL matrix (merged from tinyusb + hifiphile configs) + HIL_MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/tinyusb.json test/hil/hfp.json) echo "hil_matrix=$HIL_MATRIX_JSON" echo "hil_matrix=$HIL_MATRIX_JSON" >> $GITHUB_OUTPUT @@ -239,7 +237,7 @@ jobs: # --------------------------------------- # Hardware in the loop (HIL) - # Run on PR only (hil-tinyusb), hil-hfp only run on non-forked PR + # Run on PR only (hil-tinyusb), hil-hfp-iar only run on non-forked PR # --------------------------------------- hil-build: needs: [ check-paths, set-matrix ] @@ -263,7 +261,17 @@ jobs: # --------------------------------------- hil-tinyusb: needs: hil-build - runs-on: [ self-hosted, X64, hathach, hardware-in-the-loop ] + strategy: + fail-fast: false + matrix: + include: + - runner: [ self-hosted, X64, hathach, hardware-in-the-loop ] + hil_json: test/hil/tinyusb.json + - runner: [ self-hosted, Linux, X64, hifiphile ] + hil_json: test/hil/hfp.json + runs-on: ${{ matrix.runner }} + env: + HIL_JSON: ${{ matrix.hil_json }} steps: - name: Get Skip Boards from previous run if: github.run_attempt != '1' @@ -308,7 +316,7 @@ jobs: # self-hosted by HFP, build with IAR toolchain, for attached hardware checkout test/hil/hfp.json # Since IAR Token secret is not passed to forked PR, only build non-forked PR # --------------------------------------- - hil-hfp: + hil-hfp-iar: needs: [ check-paths ] if: | needs.check-paths.outputs.code_changed == 'true' && diff --git a/test/hil/hil_ci_set_matrix.py b/test/hil/hil_ci_set_matrix.py index ecd964d87..2cce35ae2 100644 --- a/test/hil/hil_ci_set_matrix.py +++ b/test/hil/hil_ci_set_matrix.py @@ -3,45 +3,60 @@ import json import os +def _resolve_config_path(config_file): + if os.path.exists(config_file): + return config_file + + script_relative = os.path.join(os.path.dirname(__file__), config_file) + if os.path.exists(script_relative): + return script_relative + + raise FileNotFoundError(f'Config file not found: {config_file}') + + def main(): parser = argparse.ArgumentParser() - parser.add_argument('config_file', help='Configuration JSON file') + parser.add_argument('config_files', nargs='+', help='Configuration JSON file(s)') args = parser.parse_args() - config_file = args.config_file - - # if config file is not found, try to find it in the same directory as this script - if not os.path.exists(config_file): - config_file = os.path.join(os.path.dirname(__file__), config_file) - with open(config_file) as f: - config = json.load(f) - matrix = { 'arm-gcc': [], 'esp-idf': [] } - for board in config['boards']: - name = board['name'] - flasher = board['flasher'] - if flasher['name'] == 'esptool': - toolchain = 'esp-idf' - else: - toolchain = 'arm-gcc' - - build_board = f'-b {name}' - if 'build' in board: - if 'args' in board['build']: - build_board += ' ' + ' '.join(f'-D{a}' for a in board['build']['args']) - if 'flags_on' in board['build']: - for f in board['build']['flags_on']: - if f == '': - matrix[toolchain].append(build_board) - else: - matrix[toolchain].append(f'{build_board} -f1 {f.replace(" ", " -f1 ")}') + + seen = {toolchain: set() for toolchain in matrix} + + def append_build_arg(toolchain, build_arg): + if build_arg not in seen[toolchain]: + seen[toolchain].add(build_arg) + matrix[toolchain].append(build_arg) + + for config_file in args.config_files: + with open(_resolve_config_path(config_file)) as f: + config = json.load(f) + + for board in config['boards']: + name = board['name'] + flasher = board['flasher'] + if flasher['name'] == 'esptool': + toolchain = 'esp-idf' + else: + toolchain = 'arm-gcc' + + build_board = f'-b {name}' + if 'build' in board: + if 'args' in board['build']: + build_board += ' ' + ' '.join(f'-D{a}' for a in board['build']['args']) + if 'flags_on' in board['build']: + for f in board['build']['flags_on']: + if f == '': + append_build_arg(toolchain, build_board) + else: + append_build_arg(toolchain, f'{build_board} -f1 {f.replace(" ", " -f1 ")}') + else: + append_build_arg(toolchain, build_board) else: - matrix[toolchain].append(build_board) - else: - matrix[toolchain].append(build_board) + append_build_arg(toolchain, build_board) print(json.dumps(matrix)) -- cgit v1.3.1 From d11543a72260c340836aff505104e27cfdc92ccb Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 26 Apr 2026 14:10:57 +0200 Subject: change job name Co-authored-by: Copilot Signed-off-by: HiFiPhile --- .github/workflows/build.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd71740ae..b0b2d0db4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -261,13 +261,16 @@ jobs: # --------------------------------------- hil-tinyusb: needs: hil-build + name: HIL - ${{ matrix.display }} strategy: fail-fast: false matrix: include: - - runner: [ self-hosted, X64, hathach, hardware-in-the-loop ] + - display: hathach tinyusb + runner: [ self-hosted, X64, hathach, hardware-in-the-loop ] hil_json: test/hil/tinyusb.json - - runner: [ self-hosted, Linux, X64, hifiphile ] + - display: hifiphile hfp + runner: [ self-hosted, Linux, X64, hifiphile ] hil_json: test/hil/hfp.json runs-on: ${{ matrix.runner }} env: -- cgit v1.3.1 From 2c6d42771e2707f38cefc782a1defefff6a7e22d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 Apr 2026 15:43:01 +0700 Subject: clean up --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b0b2d0db4..a88b8ffba 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -261,15 +261,15 @@ jobs: # --------------------------------------- hil-tinyusb: needs: hil-build - name: HIL - ${{ matrix.display }} + name: hil-tinyusb (${{ matrix.display }}) strategy: fail-fast: false matrix: include: - - display: hathach tinyusb + - display: tinyusb.json runner: [ self-hosted, X64, hathach, hardware-in-the-loop ] hil_json: test/hil/tinyusb.json - - display: hifiphile hfp + - display: hfp.json runner: [ self-hosted, Linux, X64, hifiphile ] hil_json: test/hil/hfp.json runs-on: ${{ matrix.runner }} -- cgit v1.3.1 From c13481a4c3b0141cb00565533876806c98838c04 Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Tue, 5 May 2026 12:32:34 +0200 Subject: try to fix CI stuck Co-authored-by: Copilot Signed-off-by: Zixun LI --- .github/workflows/build.yml | 7 ++-- test/hil/hil_test.py | 86 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 74 insertions(+), 19 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a88b8ffba..a83a997c2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -326,13 +326,15 @@ jobs: github.repository_owner == 'hathach' && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) runs-on: [ self-hosted, Linux, X64, hifiphile ] + timeout-minutes: 30 env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} + PYTHONUNBUFFERED: '1' steps: - name: Clean workspace run: | echo "Cleaning up previous run" - rm -rf "${{ github.workspace }}"3 + rm -rf "${{ github.workspace }}" mkdir -p "${{ github.workspace }}" - name: Toolchain version @@ -356,4 +358,5 @@ jobs: run: python3 tools/build.py --toolchain iar $BUILD_ARGS - name: Test on actual hardware (hardware in the loop) - run: python3 test/hil/hil_test.py hfp.json + run: | + python3 test/hil/hil_test.py hfp.json diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index e98bd5da7..4d975f6c3 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -33,6 +33,7 @@ import re import sys import time import warnings +import signal # Suppress pkg_resources deprecation warning from fs module warnings.filterwarnings("ignore", message="pkg_resources is deprecated") @@ -44,6 +45,7 @@ import subprocess import json import glob from multiprocessing import Pool +from multiprocessing import TimeoutError as MpTimeoutError import fs import hashlib import ctypes @@ -62,6 +64,17 @@ board_test = {} build_dir = 'cmake-build' skip_flash = False +CMD_TIMEOUT = int(os.getenv('HIL_CMD_TIMEOUT', '180')) +POOL_TIMEOUT = int(os.getenv('HIL_POOL_TIMEOUT', '3000')) + + +def cmd_stdout_text(out): + if out is None: + return '' + if isinstance(out, bytes): + return out.decode('utf-8', errors='ignore') + return str(out) + WCH_RISCV_CONTENT = """ adapter driver wlinke adapter speed 6000 @@ -205,21 +218,54 @@ def open_printer_dev(id, vendor_str, product_str, ifnum): # ------------------------------------------------------------- # Flashing firmware # ------------------------------------------------------------- -def run_cmd(cmd, cwd=None): - r = subprocess.run(cmd, cwd=cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) +def run_cmd(cmd, cwd=None, timeout=CMD_TIMEOUT): + popen_kwargs = { + 'cwd': cwd, + 'shell': True, + 'stdout': subprocess.PIPE, + 'stderr': subprocess.STDOUT, + } + if os.name != 'nt': + popen_kwargs['preexec_fn'] = os.setsid + + p = subprocess.Popen(cmd, **popen_kwargs) + try: + out, _ = p.communicate(timeout=timeout) + r = subprocess.CompletedProcess(args=cmd, returncode=p.returncode, stdout=out) + except subprocess.TimeoutExpired as ex: + if os.name != 'nt': + try: + os.killpg(p.pid, signal.SIGKILL) + except ProcessLookupError: + pass + else: + p.kill() + out, _ = p.communicate() + timeout_out = ex.stdout or out or b'' + title = f'COMMAND TIMEOUT ({timeout}s): {cmd}' + print() + if os.getenv('CI'): + print(f"::group::{title}") + print(cmd_stdout_text(timeout_out)) + print(f"::endgroup::") + else: + print(title) + print(cmd_stdout_text(timeout_out)) + return subprocess.CompletedProcess(args=cmd, returncode=124, stdout=timeout_out) + if r.returncode != 0: title = f'COMMAND FAILED: {cmd}' print() if os.getenv('CI'): print(f"::group::{title}") - print(r.stdout.decode("utf-8")) + print(cmd_stdout_text(r.stdout)) print(f"::endgroup::") else: print(title) - print(r.stdout.decode("utf-8")) + print(cmd_stdout_text(r.stdout)) elif verbose: print(cmd) - print(r.stdout.decode("utf-8")) + print(cmd_stdout_text(r.stdout)) return r @@ -784,7 +830,7 @@ def test_device_cdc_msc_throughput(board): # Put tty in raw mode so dd sees pure binary throughput. rs = run_cmd(f'timeout 30 stty -F {tty} raw -echo') - assert rs.returncode == 0, f'stty failed: {rs.stdout.decode()}' + assert rs.returncode == 0, f'stty failed: {cmd_stdout_text(rs.stdout)}' # Payload aim: ~5 s per direction at FS (~830 kB/s), much less at HS. msc_count = 2 if is_fs else 16 # bs=1M @@ -793,20 +839,20 @@ def test_device_cdc_msc_throughput(board): tmp_file = f'/tmp/cdc_msc_tp_{uid}.bin' rw = run_cmd(f'timeout 30 dd if=/dev/zero of={tty} bs=64K count={cdc_count} 2>&1') - assert rw.returncode == 0, f'CDC dd write failed: {rw.stdout.decode()}' - cdc_w = parse_speed(rw.stdout.decode()) + assert rw.returncode == 0, f'CDC dd write failed: {cmd_stdout_text(rw.stdout)}' + cdc_w = parse_speed(cmd_stdout_text(rw.stdout)) rr = run_cmd(f'timeout 30 dd if={tty} of=/dev/null bs=64K count={cdc_count} iflag=fullblock 2>&1') - assert rr.returncode == 0, f'CDC dd read failed: {rr.stdout.decode()}' - cdc_r = parse_speed(rr.stdout.decode()) + assert rr.returncode == 0, f'CDC dd read failed: {cmd_stdout_text(rr.stdout)}' + cdc_r = parse_speed(cmd_stdout_text(rr.stdout)) rmr = run_cmd(f'dd if={dev} of={tmp_file} bs=1M count={msc_count} iflag=direct 2>&1') - assert rmr.returncode == 0, f'MSC dd read failed: {rmr.stdout.decode()}' - msc_r = parse_speed(rmr.stdout.decode()) + assert rmr.returncode == 0, f'MSC dd read failed: {cmd_stdout_text(rmr.stdout)}' + msc_r = parse_speed(cmd_stdout_text(rmr.stdout)) rmw = run_cmd(f'dd if={tmp_file} of={dev} bs=1M count={msc_count} oflag=direct 2>&1') - assert rmw.returncode == 0, f'MSC dd write failed: {rmw.stdout.decode()}' - msc_w = parse_speed(rmw.stdout.decode()) + assert rmw.returncode == 0, f'MSC dd write failed: {cmd_stdout_text(rmw.stdout)}' + msc_w = parse_speed(cmd_stdout_text(rmw.stdout)) try: os.remove(tmp_file) @@ -823,7 +869,7 @@ def test_device_dfu(board): timeout = ENUM_TIMEOUT while timeout > 0: ret = run_cmd(f'dfu-util -l') - stdout = ret.stdout.decode() + stdout = cmd_stdout_text(ret.stdout) if f'serial="{uid}"' in stdout and 'Found DFU: [cafe:4000]' in stdout: break time.sleep(1) @@ -863,7 +909,7 @@ def test_device_dfu_runtime(board): timeout = ENUM_TIMEOUT while timeout > 0: ret = run_cmd(f'dfu-util -l') - stdout = ret.stdout.decode() + stdout = cmd_stdout_text(ret.stdout) if f'serial="{uid}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout: break time.sleep(1) @@ -1456,7 +1502,13 @@ def main(): print('-' * 30) with Pool(processes=os.cpu_count()) as pool: - mret = pool.map(test_board, config_boards) + async_ret = pool.map_async(test_board, config_boards) + try: + mret = async_ret.get(timeout=POOL_TIMEOUT) + except MpTimeoutError: + pool.terminate() + pool.join() + raise RuntimeError(f'HIL worker pool timed out after {POOL_TIMEOUT}s') err_count = build_err + sum(e[1] for e in mret) # generate skip list for next re-run if failed: skip boards that fully passed, # and emit -bt BOARD:t1,t2 so each failed board only re-runs its own failed tests. -- cgit v1.3.1 From 5ea1979e290ed80430a5b65b56534373ecbdd56f Mon Sep 17 00:00:00 2001 From: HiFiPHile Date: Sun, 10 May 2026 01:47:21 +0200 Subject: add stm32c5 support Signed-off-by: HiFiPHile --- .github/workflows/ci_set_matrix.py | 1 + README.rst | 2 +- docs/reference/boards.rst | 1 + docs/reference/dependencies.rst | 4 +- .../device/cdc_msc_throughput/CMakePresets.json | 6 + examples/device/printer_to_cdc/CMakePresets.json | 6 + examples/dual/dynamic_switch/only.txt | 1 + examples/host/bare_api/only.txt | 1 + examples/host/cdc_msc_hid/only.txt | 1 + examples/host/cdc_msc_hid_freertos/only.txt | 1 + examples/host/device_info/only.txt | 1 + examples/host/midi_rx/only.txt | 1 + examples/host/msc_file_explorer/only.txt | 1 + hw/bsp/BoardPresets.json | 22 + hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h | 165 +++++ hw/bsp/stm32c5/boards/stm32c542nucleo/board.cmake | 13 + hw/bsp/stm32c5/boards/stm32c542nucleo/board.h | 83 +++ hw/bsp/stm32c5/boards/stm32c542nucleo/board.mk | 13 + hw/bsp/stm32c5/family.c | 237 +++++++ hw/bsp/stm32c5/family.cmake | 111 ++++ hw/bsp/stm32c5/family.mk | 52 ++ hw/bsp/stm32c5/stm32c5xx_hal_conf.h | 684 +++++++++++++++++++++ src/common/tusb_mcu.h | 6 + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 1 + src/portable/st/stm32_fsdev/fsdev_stm32.h | 8 +- src/tusb_option.h | 1 + tools/get_deps.py | 8 +- 27 files changed, 1427 insertions(+), 4 deletions(-) create mode 100644 examples/device/cdc_msc_throughput/CMakePresets.json create mode 100644 examples/device/printer_to_cdc/CMakePresets.json create mode 100644 hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/stm32c5/boards/stm32c542nucleo/board.cmake create mode 100644 hw/bsp/stm32c5/boards/stm32c542nucleo/board.h create mode 100644 hw/bsp/stm32c5/boards/stm32c542nucleo/board.mk create mode 100644 hw/bsp/stm32c5/family.c create mode 100644 hw/bsp/stm32c5/family.cmake create mode 100644 hw/bsp/stm32c5/family.mk create mode 100644 hw/bsp/stm32c5/stm32c5xx_hal_conf.h (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 1d35f15dd..f4d25fd37 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -68,6 +68,7 @@ family_list = { "samd5x_e5x": ["arm-gcc", "arm-clang"], "samg": ["arm-gcc", "arm-clang"], "stm32c0": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32c5": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f0": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f1": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f2": ["arm-gcc", "arm-clang", "arm-iar"], diff --git a/README.rst b/README.rst index 04998abaa..1c56a6ba0 100644 --- a/README.rst +++ b/README.rst @@ -238,7 +238,7 @@ Supported CPUs | +----+------------------------+--------+------+-----------+------------------------+--------------------+ | | F2, F4, F7, H7, H7RS | ✔ | ✔ | ✔ | dwc2 | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | C0, G0, H5, U3 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | +| | C0, C5, G0, H5, U3 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | G4 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | | +----+------------------------+--------+------+-----------+------------------------+--------------------+ diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index e61c4f98b..b0e8bffaa 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -266,6 +266,7 @@ STMicroelectronics Board Name Family URL Note =================== ================================= ========= ================================================================= ====== stm32c071nucleo STM32C071 Nucleo stm32c0 https://www.st.com/en/evaluation-tools/nucleo-c071rb.html +stm32c542nucleo STM32C542 Nucleo stm32c5 https://www.st.com/en/evaluation-tools/nucleo-c542rc.html stm32f070rbnucleo STM32 F070 Nucleo stm32f0 https://www.st.com/en/evaluation-tools/nucleo-f070rb.html stm32f072disco STM32 F072 Discovery stm32f0 https://www.st.com/en/evaluation-tools/32f072bdiscovery.html stm32f072eval STM32 F072 Eval stm32f0 https://www.st.com/en/evaluation-tools/stm32072b-eval.html diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index c5b755577..d281e912a 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -59,6 +59,7 @@ hw/mcu/st/cmsis_device_l5 https://github.com/STMicroelectronics/ hw/mcu/st/cmsis_device_n6 https://github.com/STMicroelectronics/cmsis-device-n6.git 7bcdc944fbf7cf5928d3c1d14054ca13261d33ec stm32n6 hw/mcu/st/cmsis_device_u5 https://github.com/STMicroelectronics/cmsis_device_u5.git 6e67187dec98035893692ab2923914cb5f4e0117 stm32u5 hw/mcu/st/cmsis_device_wb https://github.com/STMicroelectronics/cmsis_device_wb.git cda2cb9fc4a5232ab18efece0bb06b0b60910083 stm32wb +hw/mcu/st/stm32c5xx-dfp https://github.com/STMicroelectronics/stm32c5xx-dfp.git 6d0940882511d9430f83af9bd3da6bcb77f79239 stm32c5 hw/mcu/st/stm32-mfxstm32l152 https://github.com/STMicroelectronics/stm32-mfxstm32l152.git 7f4389efee9c6a655b55e5df3fceef5586b35f9b stm32h7 hw/mcu/st/stm32-tcpp0203 https://github.com/STMicroelectronics/stm32-tcpp0203.git 9918655bff176ac3046ccf378b5c7bbbc6a38d15 stm32h5 stm32h7rs stm32n6 hw/mcu/st/stm32c0xx_hal_driver https://github.com/STMicroelectronics/stm32c0xx_hal_driver.git c283b143bef6bdaacf64240ee6f15eb61dad6125 stm32c0 @@ -82,13 +83,14 @@ hw/mcu/st/stm32u0xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git 2c5e2568fbdb1900a13ca3b2901fdd302cac3444 stm32u5 hw/mcu/st/stm32wbaxx_hal_driver https://github.com/STMicroelectronics/stm32wbaxx_hal_driver.git 9442fbb71f855ff2e64fbf662b7726beba511a24 stm32wba hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git d60dd46996876506f1d2e9abd6b1cc110c8004cd stm32wb +hw/mcu/st/stm32c5xx-drivers https://github.com/STMicroelectronics/stm32c5xx-drivers.git 79b901285a7efeaf87c4c25db81d24cb5d8c9465 stm32c5 hw/mcu/ti https://github.com/hathach/ti_driver.git 083944907e7d08fcb1f614b47598ce45935b8da1 msp430 msp432e4 tm4c hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samg tm4c -lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx +lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx stm32c5 lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 diff --git a/examples/device/cdc_msc_throughput/CMakePresets.json b/examples/device/cdc_msc_throughput/CMakePresets.json new file mode 100644 index 000000000..5cd8971e9 --- /dev/null +++ b/examples/device/cdc_msc_throughput/CMakePresets.json @@ -0,0 +1,6 @@ +{ + "version": 6, + "include": [ + "../../../hw/bsp/BoardPresets.json" + ] +} diff --git a/examples/device/printer_to_cdc/CMakePresets.json b/examples/device/printer_to_cdc/CMakePresets.json new file mode 100644 index 000000000..5cd8971e9 --- /dev/null +++ b/examples/device/printer_to_cdc/CMakePresets.json @@ -0,0 +1,6 @@ +{ + "version": 6, + "include": [ + "../../../hw/bsp/BoardPresets.json" + ] +} diff --git a/examples/dual/dynamic_switch/only.txt b/examples/dual/dynamic_switch/only.txt index 70be49b28..e1038f9d4 100644 --- a/examples/dual/dynamic_switch/only.txt +++ b/examples/dual/dynamic_switch/only.txt @@ -2,6 +2,7 @@ family:espressif mcu:LPC43XX mcu:MIMXRT1XXX mcu:STM32C0 +mcu:STM32C5 mcu:STM32G0 mcu:STM32H5 mcu:STM32F2 diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt index 1ddfc2b5c..a2ff93be5 100644 --- a/examples/host/bare_api/only.txt +++ b/examples/host/bare_api/only.txt @@ -20,6 +20,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt index 1ddfc2b5c..a2ff93be5 100644 --- a/examples/host/cdc_msc_hid/only.txt +++ b/examples/host/cdc_msc_hid/only.txt @@ -20,6 +20,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt index 753fa7cd3..4ab8a906e 100644 --- a/examples/host/cdc_msc_hid_freertos/only.txt +++ b/examples/host/cdc_msc_hid_freertos/only.txt @@ -16,6 +16,7 @@ mcu:MSP432E4 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt index 742935dcf..4c2cb0f35 100644 --- a/examples/host/device_info/only.txt +++ b/examples/host/device_info/only.txt @@ -21,6 +21,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/midi_rx/only.txt b/examples/host/midi_rx/only.txt index c71aacd87..65ef8fac9 100644 --- a/examples/host/midi_rx/only.txt +++ b/examples/host/midi_rx/only.txt @@ -23,6 +23,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt index 1ddfc2b5c..a2ff93be5 100644 --- a/examples/host/msc_file_explorer/only.txt +++ b/examples/host/msc_file_explorer/only.txt @@ -20,6 +20,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/hw/bsp/BoardPresets.json b/hw/bsp/BoardPresets.json index 86609d075..1ff29f99d 100644 --- a/hw/bsp/BoardPresets.json +++ b/hw/bsp/BoardPresets.json @@ -626,6 +626,10 @@ "name": "stm32c071nucleo", "inherits": "default" }, + { + "name": "stm32c542nucleo", + "inherits": "default" + }, { "name": "stm32f070rbnucleo", "inherits": "default" @@ -1762,6 +1766,11 @@ "description": "Build preset for the stm32c071nucleo board", "configurePreset": "stm32c071nucleo" }, + { + "name": "stm32c542nucleo", + "description": "Build preset for the stm32c542nucleo board", + "configurePreset": "stm32c542nucleo" + }, { "name": "stm32f070rbnucleo", "description": "Build preset for the stm32f070rbnucleo board", @@ -4227,6 +4236,19 @@ } ] }, + { + "name": "stm32c542nucleo", + "steps": [ + { + "type": "configure", + "name": "stm32c542nucleo" + }, + { + "type": "build", + "name": "stm32c542nucleo" + } + ] + }, { "name": "stm32f070rbnucleo", "steps": [ diff --git a/hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..732d9a5cf --- /dev/null +++ b/hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,165 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "stm32c5xx.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 200 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ + defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<instance)) +#endif + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_DRD_FS_IRQHandler(void) { + tusb_int_handler(0, true); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +#ifdef UART_ID +static hal_uart_handle_t hUSART; +#endif + +void board_init(void) { + HAL_Init(); + board_clock_init(); + + // Enable peripheral clocks. + HAL_RCC_GPIOA_EnableClock(); + HAL_RCC_GPIOB_EnableClock(); + HAL_RCC_GPIOC_EnableClock(); + HAL_RCC_GPIOD_EnableClock(); + HAL_RCC_USB_EnableClock(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR from running before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB_DRD_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // LED + { + hal_gpio_config_t gpio_config; + gpio_config.mode = HAL_GPIO_MODE_OUTPUT; + gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW; + gpio_config.pull = HAL_GPIO_PULL_NO; + gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL; + gpio_config.init_state = HAL_GPIO_PIN_RESET; + + HAL_GPIO_Init(LED_PORT, LED_PIN, &gpio_config); + } + + // Button + { + hal_gpio_config_t gpio_config; + gpio_config.mode = HAL_GPIO_MODE_INPUT; + gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW; + gpio_config.pull = BUTTON_STATE_ACTIVE ? HAL_GPIO_PULL_DOWN : HAL_GPIO_PULL_UP; + HAL_GPIO_Init(BUTTON_PORT, BUTTON_PIN, &gpio_config); + } + +#ifdef UART_ID + UARTn_CLK_ENABLE(); + // UART + { + hal_gpio_config_t gpio_config; + gpio_config.mode = HAL_GPIO_MODE_ALTERNATE; + gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL; + gpio_config.pull = HAL_GPIO_PULL_NO; + gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW; + gpio_config.alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, UART_TX_PIN | UART_RX_PIN, &gpio_config); + } + + hal_uart_config_t uart_config; + HAL_UART_Init(&hUSART, UARTn); + uart_config.baud_rate = 115200; + uart_config.clock_prescaler = HAL_UART_PRESCALER_DIV1; + uart_config.word_length = HAL_UART_WORD_LENGTH_8_BIT; + uart_config.stop_bits = HAL_UART_STOP_BIT_1; + uart_config.parity = HAL_UART_PARITY_NONE; + uart_config.direction = HAL_UART_DIRECTION_TX_RX; + uart_config.hw_flow_ctl = HAL_UART_HW_CONTROL_NONE; + uart_config.oversampling = HAL_UART_OVERSAMPLING_16; + uart_config.one_bit_sampling = HAL_UART_ONE_BIT_SAMPLE_DISABLE; + + HAL_UART_SetConfig(&hUSART, &uart_config); + + /* Fifo configuration */ + HAL_UART_SetTxFifoThreshold(&hUSART, HAL_UART_FIFO_THRESHOLD_1_8); + HAL_UART_SetRxFifoThreshold(&hUSART, HAL_UART_FIFO_THRESHOLD_1_8); + HAL_UART_EnableFifoMode(&hUSART); + + LL_USART_Enable(UART_GET_INSTANCE(&hUSART)); +#endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + hal_gpio_pin_state_t pin_state = state ? HAL_GPIO_PIN_SET : HAL_GPIO_PIN_RESET; + HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); +} + +uint32_t board_button_read(void) { + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; + uint32_t* id32 = (uint32_t*) (uintptr_t) id; + uint8_t const len = 12; + + id32[0] = stm32_uuid[0]; + id32[1] = stm32_uuid[1]; + id32[2] = stm32_uuid[2]; + + return len; +} + +int board_uart_read(uint8_t *buf, int len) { +#ifdef UART_ID + int count = 0; + while (count < len) { + if (LL_USART_IsActiveFlag_RXNE_RXFNE(UART_GET_INSTANCE(&hUSART))) { + buf[count] = (uint8_t) UART_GET_INSTANCE(&hUSART)->RDR; + count++; + } else { + break; + } + } + return count; +#else + (void) buf; (void) len; + return -1; +#endif +} + +int board_uart_write(void const *buf, int len) { +#ifdef UART_ID + const uint8_t *p = (const uint8_t *) buf; + int count = 0; + while (count < len) { + if (LL_USART_IsActiveFlag_TXE_TXFNF(UART_GET_INSTANCE(&hUSART))) { + UART_GET_INSTANCE(&hUSART)->TDR = p[count]; + count++; + } else { + break; + } + } + return count; +#else + (void) buf; (void) len; + return 0; +#endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; + HAL_IncTick(); +} + +uint32_t tusb_time_millis_api(void) { + return system_ticks; +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +#ifndef __ICCARM__ +// Implement _start() since we use linker flag '-nostartfiles'. +extern int main(void); +TU_ATTR_UNUSED void _start(void) { + // called by startup code + main(); + while (1) {} +} +#endif + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { + +} diff --git a/hw/bsp/stm32c5/family.cmake b/hw/bsp/stm32c5/family.cmake new file mode 100644 index 000000000..5b63b1ce4 --- /dev/null +++ b/hw/bsp/stm32c5/family.cmake @@ -0,0 +1,111 @@ +include_guard() + +set(ST_FAMILY c5) +set(ST_PREFIX stm32${ST_FAMILY}xx) + +set(ST_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx-drivers) +set(ST_CMSIS ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx-dfp) +set(CMSIS_6 ${TOP}/lib/CMSIS_6) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS STM32C5 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f interface/stlink.cfg -f target/stm32c5x.cfg") + +#------------------------------------ +# Startup & Linker script +#------------------------------------ +set(STARTUP_FILE ${ST_CMSIS}/Source/startup_${MCU_VARIANT}.c) +set(LD_FILE_Clang ${LD_FILE_GNU}) + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +function(family_add_board BOARD_TARGET) + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_cortex.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_flash_itf.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_pwr.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_rcc.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_gpio.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_uart.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_dma.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_6}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_DRIVER}/hal + ${ST_DRIVER}/ll + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_options(${BOARD_TARGET} PUBLIC -Wno-redundant-decls) + endif () + + if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_definitions(${BOARD_TARGET} PUBLIC + __STACK_LIMIT=__StackLimit + __INITIAL_SP=__StackTop + ) + endif () + + update_board(${BOARD_TARGET}) +endfunction() + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + family_add_tinyusb(${TARGET} OPT_MCU_STM32C5) + + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c + ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c + ${STARTUP_FILE} + ) + target_include_directories(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") + endif () + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) + family_flash_stlink(${TARGET}) + #family_flash_openocd(${TARGET}) +endfunction() diff --git a/hw/bsp/stm32c5/family.mk b/hw/bsp/stm32c5/family.mk new file mode 100644 index 000000000..165ad4ad5 --- /dev/null +++ b/hw/bsp/stm32c5/family.mk @@ -0,0 +1,52 @@ +ST_FAMILY = c5 +ST_CMSIS = hw/mcu/st/stm32$(ST_FAMILY)xx-dfp +ST_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx-drivers + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m33 + +# -------------- +# Compiler Flags +# -------------- +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_STM32C5 \ + +# GCC Flags +CFLAGS += \ + -flto \ + +# suppress warnings caused by vendor mcu driver +CFLAGS += -Wno-error=cast-align -Wno-error=unused-parameter -Wno-error=redundant-decls + +LDFLAGS += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + +# ----------------- +# Sources & Include +# ----------------- + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \ + src/portable/st/stm32_fsdev/fsdev_common.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_CMSIS)/Source/startup_$(MCU_VARIANT).c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_flash_itf.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_pwr.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_uart.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_dma.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_DRIVER)/hal \ + $(TOP)/$(ST_DRIVER)/ll + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32c5/stm32c5xx_hal_conf.h b/hw/bsp/stm32c5/stm32c5xx_hal_conf.h new file mode 100644 index 000000000..0833fa3dd --- /dev/null +++ b/hw/bsp/stm32c5/stm32c5xx_hal_conf.h @@ -0,0 +1,684 @@ +/** + ****************************************************************************** + * @file stm32c5xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the mx_stm32c5xx_hal_drivers_license.md file + * in the same directory as the generated code. + * If no mx_stm32c5xx_hal_drivers_license.md file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32C5XX_HAL_CONF_H +#define STM32C5XX_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup HAL_Conf_How_To_Use HAL Conf How to Use + * @{ + - The STM32 HAL configuration file, stm32tnxx_hal_conf.h, is designed to customize the behaviour of the HAL modules. + - The users can utilize the provided file as-is, where all HAL modules are enabled with their default settings. + - Alternatively, users have the flexibility to customize the file based on their application's requirements. + - For example, they can enable only the necessary HAL modules or modify the predefined settings to achieve + the desired functionality. + */ + +/** + * @} + */ + +/** @defgroup HAL_Conf_Exported_Constants HAL Conf Constants + * @{ + */ + +/** @defgroup HAL_System_Configuration HAL System Configuration + * @{ + */ + +/* ########################### System Configuration ############################# */ +/** + * @brief This is the HAL system configuration section + */ +#define USE_HAL_TICK_INT_PRIORITY 15U /*!< tick interrupt priority */ +#define USE_HAL_FLASH_PREFETCH 1U /*!< Enable FLASH prefetch */ +/** + * @} + */ + +/** @defgroup HAL_MUTEX_Usage_Activation HAL MUTEX Usage Activation + * @{ + */ +/* ########################## HAL MUTEX usage activation ####################### */ +/** + * @brief Used by the HAL PPP Acquire/Release APIs when the define USE_HAL_MUTEX is set to 1 + */ +#define USE_HAL_MUTEX 0U +/** + * @} + */ + +/** @defgroup HAL_API_Parameters_Check HAL API Parameters Check + * @{ + */ +/* ########################## HAL API parameters check ##################### */ +/** + * @brief Run time parameter check activation + */ +#define USE_HAL_CHECK_PARAM 0U +#define USE_HAL_SECURE_CHECK_PARAM 0U +/** + * @} + */ + +/** @defgroup HAL_State_Transition HAL State Transition + * @{ + */ +/* ########################## State transition ################################ */ +/** + * @brief Enable protection of state transition in thread safe + */ +#define USE_HAL_CHECK_PROCESS_STATE 0U +/** + * @} + */ + +/* ########################## Peripheral configuration ######################### */ + +/** @defgroup HAL_ADC_Config HAL ADC Configuration + * @{ + */ +/* ########################## HAL_ADC Config #################################### */ +#define USE_HAL_ADC_MODULE 0U +#define USE_HAL_ADC_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U +#define USE_HAL_ADC_USER_DATA 0U +#define USE_HAL_ADC_GET_LAST_ERRORS 0U +#define USE_HAL_ADC_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_AES_Config HAL AES Configuration + * @{ + */ +/* ########################## HAL_AES Config #################################### */ +#define USE_HAL_AES_MODULE 0U +#define USE_HAL_AES_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_AES_REGISTER_CALLBACKS 0U +#define USE_HAL_AES_USER_DATA 0U +#define USE_HAL_AES_GET_LAST_ERRORS 0U +#define USE_HAL_AES_DMA 0U +#define USE_HAL_AES_ECB_CBC_ALGO 0U +#define USE_HAL_AES_CTR_ALGO 0U +#define USE_HAL_AES_GCM_GMAC_ALGO 0U +#define USE_HAL_AES_CCM_ALGO 0U +#define USE_HAL_AES_SUSPEND_RESUME 0U +/** + * @} + */ + +/** @defgroup HAL_CCB_Config HAL CCB Configuration + * @{ + */ +/* ########################## HAL_CCB Config #################################### */ +#define USE_HAL_CCB_MODULE 0U +#define USE_HAL_CCB_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_CCB_USER_DATA 0U +#define USE_HAL_CCB_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_COMP_Config HAL COMP Configuration + * @{ + */ +/* ########################## HAL_COMP Config ################################### */ +#define USE_HAL_COMP_MODULE 0U +#define USE_HAL_COMP_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U +#define USE_HAL_COMP_USER_DATA 0U +/* Use comparator with EXTI (needed to generate system wake-up event and CPU event) */ +#define USE_HAL_COMP_EXTI 0U +/* Use comparators window mode feature */ +#define USE_HAL_COMP_WINDOW_MODE 0U +/** + * @} + */ + +/** @defgroup HAL_CORDIC_Config HAL CORDIC Configuration + * @{ + */ +/* ########################## HAL_CORDIC Config ################################# */ +#define USE_HAL_CORDIC_MODULE 0U +#define USE_HAL_CORDIC_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_USER_DATA 0U +#define USE_HAL_CORDIC_GET_LAST_ERRORS 0U +#define USE_HAL_CORDIC_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_CORTEX_Config HAL CORTEX Configuration + * @{ + */ +/* ########################## HAL_CORTEX Config ################################# */ +#define USE_HAL_CORTEX_MODULE 1U +/** + * @} + */ + +/** @defgroup HAL_CRC_Config HAL CRC Configuration + * @{ + */ +/* ########################## HAL_CRC Config #################################### */ +#define USE_HAL_CRC_MODULE 0U +#define USE_HAL_CRC_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_CRC_USER_DATA 0U +/** + * @} + */ + +/** @defgroup HAL_CRS_Config HAL CRS Configuration + * @{ + */ +/* ########################## HAL_CRS Config #################################### */ +#define USE_HAL_CRS_MODULE 0U +#define USE_HAL_CRS_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_CRS_REGISTER_CALLBACKS 0U +#define USE_HAL_CRS_USER_DATA 0U +#define USE_HAL_CRS_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_DAC_Config HAL DAC Configuration + * @{ + */ +/* ########################## HAL_DAC Config #################################### */ +#define USE_HAL_DAC_MODULE 0U +#define USE_HAL_DAC_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U +#define USE_HAL_DAC_USER_DATA 0U +#define USE_HAL_DAC_GET_LAST_ERRORS 0U +#define USE_HAL_DAC_DMA 0U +#define USE_HAL_DAC_DUAL_CHANNEL 0U +/** + * @} + */ + +/** @defgroup HAL_DBGMCU_Config HAL DBGMCU Configuration + * @{ + */ +/* ########################## HAL_DBGMCU Config ################################# */ +#define USE_HAL_DBGMCU_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_DMA_Config HAL DMA Configuration + * @{ + */ +/* ########################## HAL_DMA Config #################################### */ +#define USE_HAL_DMA_MODULE 1U +#define USE_HAL_DMA_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_DMA_USER_DATA 0U +#define USE_HAL_DMA_GET_LAST_ERRORS 0U +#define USE_HAL_DMA_LINKEDLIST 0U +/** + * @} + */ + +/** @defgroup HAL_ETH_Config HAL ETH Configuration + * @{ + */ +/* ########################## HAL_ETH Config #################################### */ +#define USE_HAL_ETH_MODULE 0U +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U +#define USE_HAL_ETH_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_ETH_USER_DATA 0U +#define USE_HAL_ETH_GET_LAST_ERRORS 0U +#define USE_HAL_ETH_ATOMIC_CHANNEL_LOCK 0U +#define USE_HAL_ETH_MAX_TX_CH_NB 1U +#define USE_HAL_ETH_MAX_RX_CH_NB 1U +/** + * @} + */ + +/** @defgroup HAL_EXTI_Config HAL EXTI Configuration + * @{ + */ +/* ########################## HAL_EXTI Config ################################### */ +#define USE_HAL_EXTI_MODULE 0U +#define USE_HAL_EXTI_REGISTER_CALLBACKS 0U +#define USE_HAL_EXTI_USER_DATA 0U +/** + * @} + */ + +/** @defgroup HAL_FDCAN_Config HAL FDCAN Configuration + * @{ + */ +/* ########################## HAL_FDCAN Config ################################## */ +#define USE_HAL_FDCAN_MODULE 0U +#define USE_HAL_FDCAN_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_USER_DATA 0U +#define USE_HAL_FDCAN_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_FLASH_Config HAL FLASH Configuration + * @{ + */ +/* ########################## HAL_FLASH Config ################################## */ +#define USE_HAL_FLASH_MODULE 1U +#define USE_HAL_FLASH_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_FLASH_REGISTER_CALLBACKS 0U +#define USE_HAL_FLASH_USER_DATA 0U +#define USE_HAL_FLASH_GET_LAST_ERRORS 0U +/* Use the FLASH program by address feature */ +#define USE_HAL_FLASH_PROGRAM_BY_ADDR 0U +/* Use the FLASH erase by address feature */ +#define USE_HAL_FLASH_ERASE_BY_ADDR 0U +/* Use the FLASH erase by PAGE feature */ +#define USE_HAL_FLASH_ERASE_PAGE 0U +/* Use the FLASH bank erase feature */ +#define USE_HAL_FLASH_ERASE_BANK 0U +/* Use the FLASH mass erase feature */ +#define USE_HAL_FLASH_MASS_ERASE 0U +/* Use ECC errors handling APIs */ +#define USE_HAL_FLASH_ECC 0U +/* Use FLASH HAL API for EDATA */ +#define USE_HAL_FLASH_OB_EDATA 0U +/** + * @} + */ + +/** @defgroup HAL_GPIO_Config HAL GPIO Configuration + * @{ + */ +/* ########################## HAL_GPIO Config ################################### */ +#define USE_HAL_GPIO_MODULE 1U +#define USE_HAL_GPIO_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +/** + * @} + */ + +/** @defgroup HAL_HASH_Config HAL HASH Configuration + * @{ + */ +/* ########################## HAL_HASH Config ################################### */ +#define USE_HAL_HASH_MODULE 0U +#define USE_HAL_HASH_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U +#define USE_HAL_HASH_USER_DATA 0U +#define USE_HAL_HASH_GET_LAST_ERRORS 0U +#define USE_HAL_HASH_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_HCD_Config HAL HCD Configuration + * @{ + */ +/* ########################## HAL_HCD Config #################################### */ +#define USE_HAL_HCD_MODULE 0U +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U +#define USE_HAL_HCD_USER_DATA 0U +#define USE_HAL_HCD_GET_LAST_ERRORS 0U +#define USE_HAL_HCD_USB_DOUBLE_BUFFER 0U +#define USE_HAL_HCD_USB_EP_TYPE_ISOC 0U +#define USE_HAL_HCD_MAX_CHANNEL_NB 16U +/** + * @} + */ + +/** @defgroup HAL_I2C_Config HAL I2C Configuration + * @{ + */ +/* ########################## HAL_I2C Config #################################### */ +#define USE_HAL_I2C_MODULE 0U +#define USE_HAL_I2C_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_USER_DATA 0U +#define USE_HAL_I2C_GET_LAST_ERRORS 0U +#define USE_HAL_I2C_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_I3C_Config HAL I3C Configuration + * @{ + */ +/* ########################## HAL_I3C Config #################################### */ +#define USE_HAL_I3C_MODULE 0U +#define USE_HAL_I3C_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_I3C_REGISTER_CALLBACKS 0U +#define USE_HAL_I3C_USER_DATA 0U +#define USE_HAL_I3C_GET_LAST_ERRORS 0U +#define USE_HAL_I3C_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_I2S_Config HAL I2S Configuration + * @{ + */ +/* ########################## HAL_I2S Config #################################### */ +#define USE_HAL_I2S_MODULE 0U +#define USE_HAL_I2S_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U +#define USE_HAL_I2S_USER_DATA 0U +#define USE_HAL_I2S_GET_LAST_ERRORS 0U +#define USE_HAL_I2S_OVR_UDR_ERRORS 0U +#define USE_HAL_I2S_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_ICACHE_Config HAL ICACHE Configuration + * @{ + */ +/* ########################## HAL_ICACHE Config ################################# */ +#define USE_HAL_ICACHE_MODULE 1U +#define USE_HAL_ICACHE_REGISTER_CALLBACKS 0U +#define USE_HAL_ICACHE_USER_DATA 0U +#define USE_HAL_ICACHE_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_IWDG_Config HAL IWDG Configuration + * @{ + */ +/* ########################## HAL_IWDG Config ################################### */ +#define USE_HAL_IWDG_MODULE 0U +#define USE_HAL_IWDG_REGISTER_CALLBACKS 0U +#define USE_HAL_IWDG_USER_DATA 0U +/* IWDG time unit configuration */ +#define USE_HAL_IWDG_TIME_UNIT HAL_IWDG_TIME_UNIT_MS +/* IWDG hardware start configuration + warning: In case of starting IWDG in Hardware mode, make sure that + USE_HAL_IWDG_HARDWARE_START is aligned with OB activated set for IWDG */ +#define USE_HAL_IWDG_HARDWARE_START 0U +/* User can choose the value of the LSI frequency with the USE_HAL_IWDG_LSI_FREQ define: + - 0U : Dynamic LSI to be computed and set by the user. + - LSI_VALUE : LSI value of 32KHz. + - (LSI_VALUE / 128U): LSI value of 250Hz */ +#define USE_HAL_IWDG_LSI_FREQ LSI_VALUE +/** + * @} + */ + +/** @defgroup HAL_LPTIM_Config HAL LPTIM Configuration + * @{ + */ +/* ########################## HAL_LPTIM Config ################################## */ +#define USE_HAL_LPTIM_MODULE 0U +#define USE_HAL_LPTIM_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_USER_DATA 0U +#define USE_HAL_LPTIM_GET_LAST_ERRORS 0U +#define USE_HAL_LPTIM_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_OPAMP_Config HAL OPAMP Configuration + * @{ + */ +/* ########################## HAL_OPAMP Config ################################## */ +#define USE_HAL_OPAMP_MODULE 0U +#define USE_HAL_OPAMP_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_OPAMP_USER_DATA 0U +/** + * @} + */ + +/** @defgroup HAL_PCD_Config HAL PCD Configuration + * @{ + */ +/* ########################## HAL_PCD Config #################################### */ +#define USE_HAL_PCD_MODULE 1U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_USER_DATA 0U +#define USE_HAL_PCD_GET_LAST_ERRORS 0U +#define USE_HAL_PCD_USB_DOUBLE_BUFFER 0U +#define USE_HAL_PCD_USB_LPM 0U +#define USE_HAL_PCD_USB_BCD 0U +#define USE_HAL_PCD_USB_EP_TYPE_ISOC 0U +#define USE_HAL_PCD_MAX_ENDPOINT_NB 8U +/** + * @} + */ + +/** @defgroup HAL_PKA_Config HAL PKA Configuration + * @{ + */ +/* ########################## HAL_PKA Config #################################### */ +#define USE_HAL_PKA_MODULE 0U +#define USE_HAL_PKA_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U +#define USE_HAL_PKA_USER_DATA 0U +#define USE_HAL_PKA_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_PWR_Config HAL PWR Configuration + * @{ + */ +/* ########################## HAL_PWR Config #################################### */ +#define USE_HAL_PWR_MODULE 1U +/** + * @} + */ + +/** @defgroup HAL_RAMCFG_Config HAL RAMCFG Configuration + * @{ + */ +/* ########################## HAL_RAMCFG Config ################################# */ +#define USE_HAL_RAMCFG_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_RCC_Config HAL RCC Configuration + * @{ + */ +/* ########################## HAL_RCC Config #################################### */ +#define USE_HAL_RCC_MODULE 1U +/* Use RCC HAL API for Reset function */ +#define USE_HAL_RCC_RESET_PERIPH_CLOCK_MANAGEMENT 0U +#define USE_HAL_RCC_RESET_RTC_DOMAIN 0U +/** + * @} + */ + +/** @defgroup HAL_RNG_Config HAL RNG Configuration + * @{ + */ +/* ########################## HAL_RNG Config #################################### */ +#define USE_HAL_RNG_MODULE 0U +#define USE_HAL_RNG_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_USER_DATA 0U +#define USE_HAL_RNG_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_RTC_Config HAL RTC Configuration + * @{ + */ +/* ########################## HAL_RTC Config #################################### */ +#define USE_HAL_RTC_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_SBS_Config HAL SBS Configuration + * @{ + */ +/* ########################## HAL_SBS Config #################################### */ +#define USE_HAL_SBS_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_SMARTCARD_Config HAL SMARTCARD Configuration + * @{ + */ +/* ########################## HAL_SMARTCARD Config ############################## */ +#define USE_HAL_SMARTCARD_MODULE 0U +#define USE_HAL_SMARTCARD_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_USER_DATA 0U +#define USE_HAL_SMARTCARD_GET_LAST_ERRORS 0U +#define USE_HAL_SMARTCARD_DMA 0U +/* #################### SMARTCARD FIFO configuration ######################## */ +#define USE_HAL_SMARTCARD_FIFO 0U +/** + * @} + */ + +/** @defgroup HAL_SMBUS_Config HAL SMBUS Configuration + * @{ + */ +/* ########################## HAL_SMBUS Config ################################## */ +#define USE_HAL_SMBUS_MODULE 0U +#define USE_HAL_SMBUS_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_USER_DATA 0U +#define USE_HAL_SMBUS_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_SPI_Config HAL SPI Configuration + * @{ + */ +/* ########################## HAL_SPI Config #################################### */ +#define USE_HAL_SPI_MODULE 0U +#define USE_HAL_SPI_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_USER_DATA 0U +#define USE_HAL_SPI_GET_LAST_ERRORS 0U +#define USE_HAL_SPI_DMA 0U +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ +#define USE_HAL_SPI_CRC 0U +/** + * @} + */ + +/** @defgroup HAL_TAMP_Config HAL TAMP Configuration + * @{ + */ +/* ########################## HAL_TAMP Config ################################### */ +#define USE_HAL_TAMP_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_TIM_Config HAL TIM Configuration + * @{ + */ +/* ########################## HAL_TIM Config #################################### */ +#define USE_HAL_TIM_MODULE 0U +#define USE_HAL_TIM_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_USER_DATA 0U +#define USE_HAL_TIM_GET_LAST_ERRORS 0U +#define USE_HAL_TIM_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_UART_Config HAL UART Configuration + * @{ + */ +/* ########################## HAL_UART Config ################################### */ +#define USE_HAL_UART_MODULE 1U +#define USE_HAL_UART_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_USER_DATA 0U +#define USE_HAL_UART_GET_LAST_ERRORS 0U +#define USE_HAL_UART_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_USART_Config HAL USART Configuration + * @{ + */ +/* ########################## HAL_USART Config ################################## */ +#define USE_HAL_USART_MODULE 0U +#define USE_HAL_USART_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_USER_DATA 0U +#define USE_HAL_USART_GET_LAST_ERRORS 0U +#define USE_HAL_USART_DMA 0U +#define USE_HAL_USART_FIFO 0U +/** + * @} + */ + +/** @defgroup HAL_WWDG_Config HAL WWDG Configuration + * @{ + */ +/* ########################## HAL_WWDG Config ################################### */ +#define USE_HAL_WWDG_MODULE 0U +#define USE_HAL_WWDG_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_USER_DATA 0U +/* WWDG time unit configuration */ +#define USE_HAL_WWDG_TIME_UNIT HAL_WWDG_TIME_UNIT_MS +/* WWDG hardware start configuration + warning: In case of starting WWDG in Hardware mode, make sure that + USE_HAL_WWDG_HARDWARE_START is aligned with OB activated set for WWDG */ +#define USE_HAL_WWDG_HARDWARE_START 0U +/** + * @} + */ + +/** @defgroup HAL_XSPI_Config HAL XSPI Configuration + * @{ + */ +/* ########################## HAL_XSPI Config ################################### */ +#define USE_HAL_XSPI_MODULE 0U +#define USE_HAL_XSPI_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_XSPI_REGISTER_CALLBACKS 0U +#define USE_HAL_XSPI_USER_DATA 0U +#define USE_HAL_XSPI_GET_LAST_ERRORS 0U +#define USE_HAL_XSPI_DMA 0U +#define USE_HAL_XSPI_HYPERBUS 0U +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32C5XX_HAL_CONF_H */ diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c85ade4d0..cd9b3dc27 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -206,6 +206,12 @@ #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u +#elif TU_CHECK_MCU(OPT_MCU_STM32C5) + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD + #define CFG_TUSB_FSDEV_PMA_SIZE 2048u + #elif TU_CHECK_MCU(OPT_MCU_STM32F0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 41da3ddd0..4dfd04fb4 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -41,6 +41,7 @@ * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up * C0 2048 byte buffer; 32-bit bus; host mode + * C5 2048 byte buffer; 32-bit bus; host mode * G0 2048 byte buffer; 32-bit bus; host mode * G4 1024 byte buffer * H5 2048 byte buffer; 32-bit bus; host mode diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index 070aa00ec..74cc9d0a4 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -36,6 +36,10 @@ #include "stm32c0xx.h" #define FSDEV_HAS_SBUF_ISO 1 +#elif CFG_TUSB_MCU == OPT_MCU_STM32C5 + #include "stm32c5xx.h" + #define FSDEV_HAS_SBUF_ISO 1 + #elif CFG_TUSB_MCU == OPT_MCU_STM32F0 #include "stm32f0xx.h" #define FSDEV_HAS_SBUF_ISO 0 @@ -177,7 +181,7 @@ static const IRQn_Type fsdev_irq[] = { USB_IRQn, #elif TU_CHECK_MCU(OPT_MCU_STM32L5, OPT_MCU_STM32U3) USB_FS_IRQn, - #elif TU_CHECK_MCU(OPT_MCU_STM32C0, OPT_MCU_STM32H5, OPT_MCU_STM32U0) + #elif TU_CHECK_MCU(OPT_MCU_STM32C0, OPT_MCU_STM32C5, OPT_MCU_STM32H5, OPT_MCU_STM32U0) USB_DRD_FS_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #ifdef STM32G0B0xx @@ -276,6 +280,8 @@ TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) { #define FSDEV_STM32_CPU_MHZ 64U #elif CFG_TUSB_MCU == OPT_MCU_STM32C0 #define FSDEV_STM32_CPU_MHZ 48U +#elif CFG_TUSB_MCU == OPT_MCU_STM32C5 + #define FSDEV_STM32_CPU_MHZ 144U #endif #ifndef CFG_TUSB_FSDEV_BTABLE_FS_DELAY_COUNT diff --git a/src/tusb_option.h b/src/tusb_option.h index 154f8e2a4..83b6d3e51 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -98,6 +98,7 @@ #define OPT_MCU_STM32N6 319 ///< ST N6 #define OPT_MCU_STM32WBA 320 ///< ST WBA #define OPT_MCU_STM32U3 321 ///< ST U3 +#define OPT_MCU_STM32C5 322 ///< ST C5 // Sony #define OPT_MCU_CXD56 400 ///< SONY CXD56 diff --git a/tools/get_deps.py b/tools/get_deps.py index eb87abf6e..50497fc71 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -163,6 +163,9 @@ deps_optional = { 'hw/mcu/st/cmsis-device-wba': ['https://github.com/STMicroelectronics/cmsis-device-wba.git', '647d8522e5fd15049e9a1cc30ed19d85e5911eaf', 'stm32wba'], + 'hw/mcu/st/stm32c5xx-dfp': ['https://github.com/STMicroelectronics/stm32c5xx-dfp.git', + '6d0940882511d9430f83af9bd3da6bcb77f79239', + 'stm32c5'], 'hw/mcu/st/stm32-mfxstm32l152': ['https://github.com/STMicroelectronics/stm32-mfxstm32l152.git', '7f4389efee9c6a655b55e5df3fceef5586b35f9b', 'stm32h7'], @@ -232,6 +235,9 @@ deps_optional = { 'hw/mcu/st/stm32wbaxx_hal_driver': ['https://github.com/STMicroelectronics/stm32wbaxx_hal_driver.git', '9442fbb71f855ff2e64fbf662b7726beba511a24', 'stm32wba'], + 'hw/mcu/st/stm32c5xx-drivers': ['https://github.com/STMicroelectronics/stm32c5xx-drivers.git', + '79b901285a7efeaf87c4c25db81d24cb5d8c9465', + 'stm32c5'], 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '083944907e7d08fcb1f614b47598ce45935b8da1', 'msp430 msp432e4 tm4c'], @@ -284,7 +290,7 @@ deps_optional = { 'tm4c '], 'lib/CMSIS_6': ['https://github.com/ARM-software/CMSIS_6.git', '6f0a58d01aa9bd2feba212097f9afe7acd991d52', - 'imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx'], + 'imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx stm32c5'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', 'lpc55'], -- cgit v1.3.1 From 0a18f30a6ec8b89ad51afceaf3e80c1e1e59780a Mon Sep 17 00:00:00 2001 From: Michael Rogov Papernov Date: Tue, 12 May 2026 17:12:41 +0100 Subject: support map files --- .github/workflows/build.yml | 2 +- hw/bsp/family_support.cmake | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a83a997c2..af0191149 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,7 +9,7 @@ on: types: [ published ] concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} jobs: diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index cb8ec6cf8..2468ac43c 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -326,10 +326,12 @@ ld_defs=\"$(echo \"$ld_defs\" | xargs)\"") "if [ -f \"${TARGET_ELF_PATH}\" ]; then \ ${MEMBROWSE_LD_SCRIPTS_CMD}; \ ${MEMBROWSE_LD_DEFS_CMD}; \ + map_arg=\"\"; \ + if [ -f \"${TARGET_ELF_PATH}.map\" ]; then map_arg=\"--map-file \\\"${TARGET_ELF_PATH}.map\\\"\"; fi; \ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ - MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs --upload --github --target-name ${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ + MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs $map_arg --upload --github --target-name ${BOARD}/${TARGET} --api-key $ENV{MEMBROWSE_API_KEY}\"; \ else \ - MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs\"; \ + MEMBROWSE_CMD=\"${MEMBROWSE_EXE} report ${OPTION} \\\"${TARGET_ELF_PATH}\\\" \\\"$ld_scripts\\\" $ld_defs $map_arg\"; \ fi; \ else \ if [ \"$MEMBROWSE_UPLOAD\" = \"1\" ]; then \ -- cgit v1.3.1 From 87f9cc01cfd3134594d196210d28ee590c7a5fc3 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 1 Jun 2026 23:51:41 +0700 Subject: ci: re-enable Claude PR review and harden auth/permissions - claude-code-review.yml: re-enable (drop `if: false`); switch from pull_request_target to pull_request so fork PRs never receive the OAuth token (avoids prompt-injection token leak). Auto-review on open/synchronize/reopen/ready_for_review, skip drafts, sticky comment. - claude.yml: grant contents/pull-requests/issues write so @claude can reply and push fixes; @claude is the on-demand path for fork PRs. --- .github/workflows/claude-code-review.yml | 19 +++++++++++++++---- .github/workflows/claude.yml | 6 +++--- 2 files changed, 18 insertions(+), 7 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 43144bb5e..2f055287c 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -1,18 +1,27 @@ name: Claude Code Review on: - pull_request_target: - types: [opened, synchronize, ready_for_review, reopened] + pull_request: + # opened/reopened/ready_for_review -> first auto review + # synchronize -> auto re-review on new pushes + # + # NOTE: pull_request (not _target) means fork PRs from non-write-access + # contributors get NO token, so they are not auto-reviewed -> use @claude + # on those. Same-repo branches (yours or write-access contributors) get + # full auto-review safely. + types: [opened, synchronize, reopened, ready_for_review] jobs: claude-review: - if: false + # Skip drafts; review real PRs only + if: github.event.pull_request.draft == false runs-on: ubuntu-latest permissions: contents: read pull-requests: write issues: read id-token: write + actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository @@ -28,5 +37,7 @@ jobs: plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' plugins: 'code-review@claude-code-plugins' prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' + # Reuse one comment instead of posting a new one each push + use_sticky_comment: true + claude_args: '--max-turns 20' # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md - # or https://code.claude.com/docs/en/cli-reference for available options diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 50f449949..660edfb7b 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -19,9 +19,9 @@ jobs: (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) runs-on: ubuntu-latest permissions: - contents: read - pull-requests: read - issues: read + contents: write # allow Claude to push commits/branches when asked + pull-requests: write # allow Claude to comment on / update PRs + issues: write # allow Claude to comment on / update issues id-token: write actions: read # Required for Claude to read CI results on PRs steps: -- cgit v1.3.1 From 1ea04f7fe67bac927848e9dfd3ce2f607e7b93d7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Jun 2026 00:16:54 +0700 Subject: ci: address codex/copilot review on claude workflows - claude.yml: gate @claude on author_association (OWNER/MEMBER/COLLABORATOR) so the write-scoped token and OAuth secret are never issued for an untrusted commenter on this public repo (defense-in-depth). - claude-code-review.yml: skip fork PRs in the job condition (head.repo.full_name == github.repository) since forks get no secrets and would only fail noisily; fix the misleading token comment; pass additional_permissions: actions: read so actions: read is effective. - hil SKILL.md: reword hostname guidance, use full test/hil/* paths, and show an explicit CONFIG= assignment so the local command is runnable. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/hil/SKILL.md | 14 ++++++++------ .github/workflows/claude-code-review.yml | 17 +++++++++++------ .github/workflows/claude.yml | 15 +++++++++++---- 3 files changed, 30 insertions(+), 16 deletions(-) (limited to '.github/workflows') diff --git a/.claude/skills/hil/SKILL.md b/.claude/skills/hil/SKILL.md index c705c149c..22588eba3 100644 --- a/.claude/skills/hil/SKILL.md +++ b/.claude/skills/hil/SKILL.md @@ -5,12 +5,12 @@ description: Use when running TinyUSB Hardware-in-the-Loop (HIL) tests on physic # Hardware-in-the-Loop (HIL) Testing -Run TinyUSB HIL tests on real boards. **Run `hostname` first** — it sets the default config and whether remote mode is possible. +Run TinyUSB HIL tests on real boards. **Run `hostname` first** — it tells you which host you are on, which determines the default config and whether remote mode is possible. -| Host | Local boards | Remote (SSH → ci.lan)? | +| Host | Local config | Remote (SSH → ci.lan)? | |------|--------------|------------------------| -| `htpc` (dev PC) | `local.json` | yes (large pool, `tinyusb.json`) | -| `ci` (the rig) | `tinyusb.json` (large pool) | no — can't SSH to htpc, and boards are already local | +| `htpc` (dev PC) | `test/hil/local.json` | yes (large pool, `test/hil/tinyusb.json`) | +| `ci` (the rig) | `test/hil/tinyusb.json` (large pool) | no — can't SSH to htpc, and boards are already local | Default to **local**. Use **remote** only when on `htpc` and the user says `remote`/`ci.lan`. Never attempt remote on `ci`. @@ -27,10 +27,12 @@ If `local.json` is missing on `htpc`, ask the user to supply one (only fall back ## Local execution -Pick `$CONFIG` from `hostname`: `local.json` on `htpc`, `tinyusb.json` on `ci`. +Set `CONFIG` from `hostname` first, then run: ```bash -python3 test/hil/hil_test.py [-b BOARD_NAME] -B examples $CONFIG $EXTRA_ARGS +CONFIG=test/hil/local.json # on htpc +# CONFIG=test/hil/tinyusb.json # on ci +python3 test/hil/hil_test.py [-b BOARD_NAME] -B examples "$CONFIG" $EXTRA_ARGS ``` ## Remote execution (htpc → ci.lan only) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 2f055287c..6c8bbb03d 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -5,16 +5,18 @@ on: # opened/reopened/ready_for_review -> first auto review # synchronize -> auto re-review on new pushes # - # NOTE: pull_request (not _target) means fork PRs from non-write-access - # contributors get NO token, so they are not auto-reviewed -> use @claude - # on those. Same-repo branches (yours or write-access contributors) get - # full auto-review safely. + # NOTE: pull_request (not _target) means fork PRs get a read-only GITHUB_TOKEN + # and NO repository secrets (CLAUDE_CODE_OAUTH_TOKEN), so they cannot be + # auto-reviewed. The job condition below skips them cleanly -> use @claude on + # those. Same-repo branches (yours or write-access contributors) auto-review. types: [opened, synchronize, reopened, ready_for_review] jobs: claude-review: - # Skip drafts; review real PRs only - if: github.event.pull_request.draft == false + # Skip drafts, and skip fork PRs (no secrets -> would only fail noisily) + if: > + github.event.pull_request.draft == false && + github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest permissions: contents: read @@ -34,6 +36,9 @@ jobs: uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + # Pairs with the actions: read permission so Claude can read CI results + additional_permissions: | + actions: read plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' plugins: 'code-review@claude-code-plugins' prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 660edfb7b..dedecd349 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -12,11 +12,18 @@ on: jobs: claude: + # Only trusted actors (repo owner/member/collaborator) may summon @claude, so the + # write-scoped token and OAuth secret are never issued for an outside contributor's + # comment on this public repo. Defense-in-depth on top of the action's own check. if: | - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || - (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.review.author_association)) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association)) runs-on: ubuntu-latest permissions: contents: write # allow Claude to push commits/branches when asked -- cgit v1.3.1 From 044cd06f87117afa541d8cc743fcc9ef2bdc8089 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Jun 2026 00:24:05 +0700 Subject: ci: address second codex/copilot review round - claude.yml: drop the issues "assigned" trigger; its author_association gate keys on the issue author, not the assigner, so a maintainer assigning an outside contributor's issue would be wrongly skipped. - claude-code-review.yml: issues: read -> write so use_sticky_comment can create/update its PR comment via the issues API. - hil SKILL.md: make local/remote command blocks copy-pasteable (drop [-b BOARD_NAME] notation for concrete examples) and fix timeout (600000 ms is 10 min; use 1200000 ms for the stated 20 min). Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/hil/SKILL.md | 22 ++++++++++++++++------ .github/workflows/claude-code-review.yml | 2 +- .github/workflows/claude.yml | 5 ++++- 3 files changed, 21 insertions(+), 8 deletions(-) (limited to '.github/workflows') diff --git a/.claude/skills/hil/SKILL.md b/.claude/skills/hil/SKILL.md index 22588eba3..a7a916907 100644 --- a/.claude/skills/hil/SKILL.md +++ b/.claude/skills/hil/SKILL.md @@ -27,27 +27,37 @@ If `local.json` is missing on `htpc`, ask the user to supply one (only fall back ## Local execution -Set `CONFIG` from `hostname` first, then run: +Set `CONFIG` from `hostname` first (`test/hil/local.json` on htpc, `test/hil/tinyusb.json` on ci): ```bash -CONFIG=test/hil/local.json # on htpc -# CONFIG=test/hil/tinyusb.json # on ci -python3 test/hil/hil_test.py [-b BOARD_NAME] -B examples "$CONFIG" $EXTRA_ARGS +CONFIG=test/hil/local.json # on ci use: CONFIG=test/hil/tinyusb.json + +# All boards in the config: +python3 test/hil/hil_test.py -B examples "$CONFIG" + +# A single board (replace stm32f723disco): +python3 test/hil/hil_test.py -b stm32f723disco -B examples "$CONFIG" ``` +Append pass-through flags (`-v`, `-r 1`, â€Ļ) to either command as needed. + ## Remote execution (htpc → ci.lan only) `test/hil/hil_ci.sh` handles dir setup, scp of test scripts, rsync of firmware (`.elf`/`.bin`/`.hex`), and runs `hil_test.py` on `ci.lan` with `tinyusb.json`: ```bash -bash test/hil/hil_ci.sh [-b BOARD_NAME] [extra hil_test.py args...] +# All boards: +bash test/hil/hil_ci.sh + +# A single board, with pass-through flags: +bash test/hil/hil_ci.sh -b raspberry_pi_pico2 -t host/cdc_msc_hid -r 1 ``` Env overrides: `REMOTE`, `REMOTE_DIR`, `CONFIG`. Fails fast if the build dir/repo layout is missing. ## Timing -Runs take 2-5 min. Use a timeout â‰Ĩ 20 min (600000 ms). NEVER cancel early. +Runs take 2-5 min. Use a timeout â‰Ĩ 20 min (1200000 ms). NEVER cancel early. ## Reporting diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 6c8bbb03d..4a0e4639b 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -21,7 +21,7 @@ jobs: permissions: contents: read pull-requests: write - issues: read + issues: write # use_sticky_comment posts/updates a PR comment via the issues API id-token: write actions: read # Required for Claude to read CI results on PRs diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index dedecd349..bf7a401e4 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -6,7 +6,10 @@ on: pull_request_review_comment: types: [created] issues: - types: [opened, assigned] + # only "opened" — an issue's author_association gates the summon below; + # "assigned" would gate on the issue author, not the assigner, so a + # maintainer assigning an outsider's issue would be wrongly skipped. + types: [opened] pull_request_review: types: [submitted] -- cgit v1.3.1 From b009ddb01232192538762f21371d65a4e6d04f14 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Jun 2026 10:38:09 +0700 Subject: ci(claude): enable @claude to fix bugs and commit from comments Configure the @claude summon workflow so it can actually produce a verified fix when asked in an issue/PR comment: - use_commit_signing: bot commits show as Verified - --allowedTools Bash: lets Claude build/test to verify the fix before committing (default allowlist blocks Bash). Safe because the job `if` gate restricts this to OWNER/MEMBER/COLLABORATOR. - --max-turns 30: enough turns to investigate -> fix -> verify Auto-commit/PR is already built into claude-code-action and the required write permissions were already present, so no permission changes are needed. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/claude.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index bf7a401e4..9e7c8335f 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -50,10 +50,15 @@ jobs: additional_permissions: | actions: read - # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. - # prompt: 'Update the pull request description to include a summary of changes.' + # Sign the bot's commits so they show as "Verified". The action commits + # automatically — on a PR comment it pushes to that PR's branch; on an + # issue comment it opens a new claude/* branch + PR with the fix. + use_commit_signing: true - # Optional: Add claude_args to customize behavior and configuration - # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md - # or https://code.claude.com/docs/en/cli-reference for available options - # claude_args: '--allowed-tools Bash(gh pr:*)' + # No custom prompt: Claude performs the instructions in the @claude comment. + + # Let summoned runs actually fix bugs: allow Bash so Claude can build/test + # and verify the change before it commits, plus enough turns to investigate. + # File edits (Edit/Write) and git push are handled by the action itself. + # Safe because the job `if` gate restricts this to OWNER/MEMBER/COLLABORATOR. + claude_args: '--allowedTools Bash --max-turns 30' -- cgit v1.3.1 From 6936cc630dfc0d125337e3f4f6e9322b503df3b2 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Jun 2026 10:42:39 +0700 Subject: ci(claude): scope Bash allowlist instead of wide-open (Codex P1) Codex flagged that @claude can be summoned on a fork PR (the review workflow even directs fork PRs here), so the checked-out PR content is potentially attacker-controlled. Unrestricted Bash in this write-token + OAuth-secret job let prompt injection steer Claude into arbitrary shell/network commands. Scope Bash to the repo's actual verification commands (cmake, ninja, make, ctest, python/python3, pre-commit, clang-format, codespell, git). This blocks the injection-to-arbitrary-command path while still letting Claude build/test before committing. Building fork code itself is already done by the existing CircleCI, so that surface is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/claude.yml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 9e7c8335f..66a1098ab 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -57,8 +57,18 @@ jobs: # No custom prompt: Claude performs the instructions in the @claude comment. - # Let summoned runs actually fix bugs: allow Bash so Claude can build/test - # and verify the change before it commits, plus enough turns to investigate. - # File edits (Edit/Write) and git push are handled by the action itself. - # Safe because the job `if` gate restricts this to OWNER/MEMBER/COLLABORATOR. - claude_args: '--allowedTools Bash --max-turns 30' + # Let summoned runs actually fix bugs: allow the repo's build/test/lint + # commands so Claude can verify the change before it commits, plus enough + # turns to investigate. File edits (Edit/Write) and git push are handled + # by the action itself. + # + # Bash is scoped to a curated allowlist rather than wide-open: the job `if` + # gate trusts the *commenter*, but @claude can be summoned on a fork PR + # (claude-code-review.yml even directs fork PRs here), so the checked-out + # PR content is potentially attacker-controlled. Scoping blocks prompt + # injection from steering Claude into arbitrary shell/network commands + # while this job holds the OAuth secret + write token. Keep `bash`/`sh`/ + # `curl`/`wget`/`eval` OUT of this list. + claude_args: >- + --allowedTools "Bash(git:*),Bash(cmake:*),Bash(ninja:*),Bash(make:*),Bash(ctest:*),Bash(python3:*),Bash(python:*),Bash(pre-commit:*),Bash(clang-format:*),Bash(codespell:*)" + --max-turns 30 -- cgit v1.3.1 From 2fc46b690996f776e3b36bcaa9865e7d2a8f8c89 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Jun 2026 11:18:14 +0700 Subject: ci(claude): drop Bash allowlist entirely (Codex P1, round 2) Codex correctly noted that allowing python3/python (and really cmake/make too) is arbitrary code + network execution: a command allowlist cannot contain a prompt-injected or malicious fork PR when this job holds the OAuth secret + write token, and the review workflow directs fork PRs to @claude. The Bash allowlist was beyond the original scope (auto-commit/PR) anyway. Remove it: Claude edits files and the action commits/opens the PR, and the resulting commit is verified by the existing CircleCI matrix. Keep use_commit_signing and --max-turns 30. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/claude.yml | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 66a1098ab..66e36897c 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -57,18 +57,12 @@ jobs: # No custom prompt: Claude performs the instructions in the @claude comment. - # Let summoned runs actually fix bugs: allow the repo's build/test/lint - # commands so Claude can verify the change before it commits, plus enough - # turns to investigate. File edits (Edit/Write) and git push are handled - # by the action itself. - # - # Bash is scoped to a curated allowlist rather than wide-open: the job `if` - # gate trusts the *commenter*, but @claude can be summoned on a fork PR - # (claude-code-review.yml even directs fork PRs here), so the checked-out - # PR content is potentially attacker-controlled. Scoping blocks prompt - # injection from steering Claude into arbitrary shell/network commands - # while this job holds the OAuth secret + write token. Keep `bash`/`sh`/ - # `curl`/`wget`/`eval` OUT of this list. - claude_args: >- - --allowedTools "Bash(git:*),Bash(cmake:*),Bash(ninja:*),Bash(make:*),Bash(ctest:*),Bash(python3:*),Bash(python:*),Bash(pre-commit:*),Bash(clang-format:*),Bash(codespell:*)" - --max-turns 30 + # Deliberately NO Bash in the tool allowlist. @claude can be summoned on a + # fork PR (claude-code-review.yml even directs fork PRs here), and this job + # holds the OAuth secret + a write token. Any build/interpreter command + # (python -c, cmake/make custom targets, etc.) run against attacker- + # controlled PR content is arbitrary code + network execution, so no + # command allowlist can safely contain it. Claude still edits files and + # the action commits/opens the PR; the resulting commit is verified by the + # repo's CircleCI matrix. --max-turns gives room to investigate + fix. + claude_args: '--max-turns 30' -- cgit v1.3.1 From d585977d9275d70a75003529136dec2f3de9a875 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Jun 2026 09:05:46 +0700 Subject: ci: allow claude[bot] pushes in code review workflow Add allowed_bots: 'claude' so that when claude[bot] pushes commits the workflow skips gracefully instead of erroring. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/claude-code-review.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 4a0e4639b..97950e888 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -21,7 +21,7 @@ jobs: permissions: contents: read pull-requests: write - issues: write # use_sticky_comment posts/updates a PR comment via the issues API + issues: write # Claude posts the review comment via the issues API id-token: write actions: read # Required for Claude to read CI results on PRs @@ -36,13 +36,17 @@ jobs: uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + # Allow claude[bot]'s own pushes to be handled gracefully (skip) instead + # of erroring out the workflow + allowed_bots: 'claude' # Pairs with the actions: read permission so Claude can read CI results additional_permissions: | actions: read plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' plugins: 'code-review@claude-code-plugins' prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' - # Reuse one comment instead of posting a new one each push - use_sticky_comment: true + # TEMPORARY: expose the full Claude transcript in the Actions log for + # debugging. Revert to remove once done. + show_full_output: true claude_args: '--max-turns 20' # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md -- cgit v1.3.1 From 9a3e32bf549c5fdf6ef7931a47b8b8e2e483d856 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Jun 2026 15:15:07 +0700 Subject: ci(claude): post sticky summary comment on code review The review workflow posted nothing when a review found no issues: with use_sticky_comment unset, the only output path was inline comments, so a clean review surfaced no comment at all on the PR. Enable use_sticky_comment so a single summary comment is posted/ updated every run, making "no issues found" results visible. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/claude-code-review.yml | 3 +++ 1 file changed, 3 insertions(+) (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 97950e888..91859af9d 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -44,6 +44,9 @@ jobs: actions: read plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' plugins: 'code-review@claude-code-plugins' + # Post/update a single summary comment every run, so a clean review + # ("no issues found") is still visible instead of posting nothing. + use_sticky_comment: true prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' # TEMPORARY: expose the full Claude transcript in the Actions log for # debugging. Revert to remove once done. -- cgit v1.3.1 From 824a2d6d8567deb163ecae79bf7cccfa59159c6a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Jun 2026 12:16:13 +0700 Subject: ci(labeler): add sponsor/Adafruit tiers, owner skip, and discussion support - rename priority labels usage to Prio / Prio Top - label Adafruit members (Adafruit + Sponsor + Prio Top) and public GitHub sponsors by tier; contributors get Prio - skip sponsor/Adafruit perks for the maintainer's own issues/PRs - support discussions via the GraphQL addLabelsToLabelable mutation Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/labeler.yml | 135 +++++++++++++++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 23 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index c3cc59d0d..1fdd24bf8 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -5,6 +5,8 @@ on: types: [opened] pull_request_target: types: [opened] + discussion: + types: [created] jobs: label-priority: @@ -12,15 +14,17 @@ jobs: permissions: issues: write pull-requests: write + discussions: write steps: - - name: Label New Issue or PR + - name: Label New Issue, PR or Discussion uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - let label = ''; + let labels = []; let username = ''; let issueOrPrNumber = 0; + let discussionNodeId = ''; if (context.eventName === 'issues') { username = context.payload.issue.user.login; @@ -28,25 +32,85 @@ jobs: } else if (context.eventName === 'pull_request_target') { username = context.payload.pull_request.user.login; issueOrPrNumber = context.payload.pull_request.number; + } else if (context.eventName === 'discussion') { + username = context.payload.discussion.user.login; + discussionNodeId = context.payload.discussion.node_id; } - // Check if an Adafruit member - try { - const adafruitResponse = await github.rest.orgs.checkMembershipForUser({ - org: 'adafruit', - username: username - }); + // Maintainer is an Adafruit member; skip the Adafruit perks for their own + // issues/PRs and treat them as a plain contributor (Prio only). + const isOwner = username.toLowerCase() === 'hathach'; - if (adafruitResponse.status === 204) { - console.log('Adafruit Member'); - label = 'Prio Urgent'; + // Check if an Adafruit member: Adafruit + Sponsor + top priority + if (!isOwner) { + try { + const adafruitResponse = await github.rest.orgs.checkMembershipForUser({ + org: 'adafruit', + username: username + }); + + if (adafruitResponse.status === 204) { + console.log('Adafruit Member'); + labels = ['Adafruit', 'Sponsor', 'Prio Top']; + } + } catch (error) { + console.log('Not an Adafruit member'); + } + } + + // Check if a public GitHub Sponsor of the repo owner. + // Word ($32) tier and up get triage priority; DWORD/QWORD ($128+) go to the top. + // Private sponsorships are not visible to GITHUB_TOKEN, so only public sponsors are detected. + if (labels.length === 0) { + try { + const result = await github.graphql(` + query($sponsorable: String!, $sponsor: String!) { + user(login: $sponsorable) { + isSponsoredBy(accountLogin: $sponsor) + sponsorshipsAsMaintainer(includePrivate: false, first: 100) { + nodes { + sponsorEntity { + ... on User { login } + ... on Organization { login } + } + tier { monthlyPriceInDollars } + } + } + } + }`, { sponsorable: context.repo.owner, sponsor: username }); + + const owner = result.user; + if (owner && owner.isSponsoredBy) { + let monthly = 0; + const nodes = (owner.sponsorshipsAsMaintainer && owner.sponsorshipsAsMaintainer.nodes) || []; + for (const node of nodes) { + const login = node.sponsorEntity && node.sponsorEntity.login; + if (login && login.toLowerCase() === username.toLowerCase()) { + monthly = (node.tier && node.tier.monthlyPriceInDollars) || 0; + break; + } + } + + if (monthly >= 128) { + console.log('Sponsor (DWORD/QWORD tier)'); + labels = ['Sponsor', 'Prio Top']; + } else if (monthly >= 32) { + console.log('Sponsor (Word tier)'); + labels = ['Sponsor', 'Prio']; + } else { + console.log('Sponsor (below Word tier or tier not visible)'); + labels = ['Sponsor']; + } + } else { + console.log('Not a public sponsor'); + } + } catch (error) { + console.log('Sponsor lookup failed: ' + error.message); } - } catch (error) { - console.log('Not an Adafruit member'); } - // Check if a contributor - if (label == '') { + // Check if a contributor: prioritized in triage queue + if (labels.length === 0) { try { const collaboratorResponse = await github.rest.repos.checkCollaborator({ owner: context.repo.owner, @@ -56,18 +120,43 @@ jobs: if (collaboratorResponse.status === 204) { console.log('Contributor'); - label = 'Prio Higher'; + labels = ['Prio']; } } catch (error) { console.log('Not a contributor'); } } - if (label !== '') { - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issueOrPrNumber, - labels: [label] - }); + if (labels.length !== 0) { + if (context.eventName === 'discussion') { + // Discussions are not covered by the REST issues API; resolve the label + // names to node IDs and attach them with the GraphQL labelable mutation. + const labelIds = []; + for (const name of labels) { + const res = await github.graphql(` + query($owner: String!, $repo: String!, $name: String!) { + repository(owner: $owner, name: $repo) { + label(name: $name) { id } + } + }`, { owner: context.repo.owner, repo: context.repo.repo, name: name }); + if (res.repository.label) { + labelIds.push(res.repository.label.id); + } + } + if (labelIds.length !== 0) { + await github.graphql(` + mutation($labelableId: ID!, $labelIds: [ID!]!) { + addLabelsToLabelable(input: { labelableId: $labelableId, labelIds: $labelIds }) { + clientMutationId + } + }`, { labelableId: discussionNodeId, labelIds: labelIds }); + } + } else { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueOrPrNumber, + labels: labels + }); + } } -- cgit v1.3.1 From 5e3a56a38731e21a46c9df121530644745d55685 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Jun 2026 12:16:14 +0700 Subject: ci: add Sponsor Triage board sync workflow Cron (6h) + manual workflow that adds open issues opened by GitHub sponsors (public and private) and Adafruit org members across the adafruit org and the maintainer's repos to the private Sponsor Triage project board, setting Tier and Visibility. Logs counts only to avoid leaking private sponsor logins. Needs the SPONSOR_TOKEN PAT secret. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/sponsor-triage.yml | 164 +++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 .github/workflows/sponsor-triage.yml (limited to '.github/workflows') diff --git a/.github/workflows/sponsor-triage.yml b/.github/workflows/sponsor-triage.yml new file mode 100644 index 000000000..19c1a6105 --- /dev/null +++ b/.github/workflows/sponsor-triage.yml @@ -0,0 +1,164 @@ +name: Sponsor Triage + +# Periodically add open issues opened by sponsors (public and private) to the private "Sponsor Triage" project board +# Requires a PAT in secret SPONSOR_TOKEN with scopes: +# - project (write project items / fields) +# - read:org (search org issues, check Adafruit membership) +# - read:user / sponsors (read own sponsorships incl. private) + +on: + schedule: + - cron: '0 */6 * * *' # every 6 hours + workflow_dispatch: + +concurrency: + group: sponsor-triage + cancel-in-progress: false + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Sync sponsor issues to project board + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.SPONSOR_TOKEN }} + script: | + const PROJECT_OWNER = 'hathach'; + const PROJECT_NUMBER = 3; + // Where to look for sponsor-authored open issues. + const SEARCH_SCOPES = ['org:adafruit', 'user:hathach']; + + const tierFromMonthly = (m) => { + if (m >= 512) return 'QWORD'; + if (m >= 128) return 'DWORD'; + if (m >= 32) return 'Word'; + if (m >= 8) return 'Byte'; + if (m >= 2) return 'Bit'; + return null; + }; + + // --- 1. Resolve project id + field/option ids (by name, never hardcoded) --- + const proj = await github.graphql(` + query($owner: String!, $number: Int!) { + user(login: $owner) { + projectV2(number: $number) { + id + fields(first: 50) { + nodes { + ... on ProjectV2SingleSelectField { + id name options { id name } + } + } + } + } + } + }`, { owner: PROJECT_OWNER, number: PROJECT_NUMBER }); + + const project = proj.user.projectV2; + const fieldByName = {}; + for (const f of project.fields.nodes) { + if (f && f.name) { + fieldByName[f.name] = { id: f.id, options: {} }; + for (const o of (f.options || [])) fieldByName[f.name].options[o.name] = o.id; + } + } + const tierField = fieldByName['Tier']; + const visField = fieldByName['Visibility']; + + // --- 2. Build sponsor map: loginLower -> { tier, visibility } --- + const sponsors = new Map(); + + // 2a. GitHub Sponsors of the owner, including private ones. + let after = null; + for (let page = 0; page < 20; page++) { + const res = await github.graphql(` + query($owner: String!, $after: String) { + user(login: $owner) { + sponsorshipsAsMaintainer(includePrivate: true, first: 100, after: $after) { + pageInfo { hasNextPage endCursor } + nodes { + privacyLevel + tier { monthlyPriceInDollars } + sponsorEntity { + ... on User { login } + ... on Organization { login } + } + } + } + } + }`, { owner: PROJECT_OWNER, after }); + const conn = res.user.sponsorshipsAsMaintainer; + for (const n of conn.nodes) { + const login = n.sponsorEntity && n.sponsorEntity.login; + if (!login) continue; + const tier = tierFromMonthly((n.tier && n.tier.monthlyPriceInDollars) || 0); + const visibility = n.privacyLevel === 'PRIVATE' ? 'Private' : 'Public'; + sponsors.set(login.toLowerCase(), { login, tier, visibility }); + } + if (!conn.pageInfo.hasNextPage) break; + after = conn.pageInfo.endCursor; + } + + core.info(`Resolved ${sponsors.size} sponsor account(s).`); + if (sponsors.size === 0) return; + + // 2b. Adafruit org members get the Adafruit tier regardless of $ amount. + for (const s of sponsors.values()) { + try { + const m = await github.rest.orgs.checkMembershipForUser({ org: 'adafruit', username: s.login }); + if (m.status === 204) s.tier = 'Adafruit'; + } catch (e) { /* not an Adafruit member */ } + } + + // --- 3. Find each sponsor's open issues in the search scopes --- + const found = new Map(); // contentId -> { tier, visibility } + for (const s of sponsors.values()) { + for (const scope of SEARCH_SCOPES) { + const q = `${scope} is:open is:issue author:${s.login}`; + try { + const res = await github.graphql(` + query($q: String!) { + search(query: $q, type: ISSUE, first: 100) { + nodes { ... on Issue { id } } + } + }`, { q }); + for (const node of res.search.nodes) { + if (node && node.id && !found.has(node.id)) { + found.set(node.id, { tier: s.tier, visibility: s.visibility }); + } + } + } catch (e) { + core.warning(`Search failed for one scope: ${e.message}`); + } + } + } + core.info(`Found ${found.size} open sponsor issue(s) across scopes.`); + + // --- 4. Add to board + set Tier / Visibility (idempotent) --- + const setField = async (itemId, field, optionName) => { + if (!field || !optionName) return; + const optId = field.options[optionName]; + if (!optId) return; + await github.graphql(` + mutation($p: ID!, $i: ID!, $f: ID!, $o: String!) { + updateProjectV2ItemFieldValue(input: { + projectId: $p, itemId: $i, fieldId: $f, value: { singleSelectOptionId: $o } + }) { projectV2Item { id } } + }`, { p: project.id, i: itemId, f: field.id, o: optId }); + }; + + let added = 0; + for (const [contentId, meta] of found) { + const res = await github.graphql(` + mutation($p: ID!, $c: ID!) { + addProjectV2ItemById(input: { projectId: $p, contentId: $c }) { + item { id } + } + }`, { p: project.id, c: contentId }); + const itemId = res.addProjectV2ItemById.item.id; + await setField(itemId, tierField, meta.tier); + await setField(itemId, visField, meta.visibility); + added++; + } + core.info(`Synced ${added} item(s) to the board.`); -- cgit v1.3.1 From c86fea62e72e0b75a42245b2200763922e2baaa7 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Jun 2026 12:55:32 +0700 Subject: ci(sponsor-triage): include open PRs, not just issues Drop the is:issue qualifier so sponsor pull requests are synced to the board too (search type ISSUE already returns both). A sponsor's open PR is exactly the kind of work to prioritize reviewing. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/sponsor-triage.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/sponsor-triage.yml b/.github/workflows/sponsor-triage.yml index 19c1a6105..1e7d39028 100644 --- a/.github/workflows/sponsor-triage.yml +++ b/.github/workflows/sponsor-triage.yml @@ -1,6 +1,6 @@ name: Sponsor Triage -# Periodically add open issues opened by sponsors (public and private) to the private "Sponsor Triage" project board +# Periodically add open issues and PRs opened by sponsors (public and private) to the private "Sponsor Triage" project board # Requires a PAT in secret SPONSOR_TOKEN with scopes: # - project (write project items / fields) # - read:org (search org issues, check Adafruit membership) @@ -111,11 +111,12 @@ jobs: } catch (e) { /* not an Adafruit member */ } } - // --- 3. Find each sponsor's open issues in the search scopes --- + // --- 3. Find each sponsor's open issues and PRs in the search scopes --- + // (search type ISSUE returns both issues and pull requests) const found = new Map(); // contentId -> { tier, visibility } for (const s of sponsors.values()) { for (const scope of SEARCH_SCOPES) { - const q = `${scope} is:open is:issue author:${s.login}`; + const q = `${scope} is:open author:${s.login}`; try { const res = await github.graphql(` query($q: String!) { -- cgit v1.3.1 From 10e57012078f68752699e896478bcf3d99dc391c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Jun 2026 13:06:13 +0700 Subject: ci(sponsor-triage): select PullRequest id in search results The search drops is:issue to include PRs, but the GraphQL selection only had '... on Issue { id }', so PR nodes returned no id and were skipped. Add '... on PullRequest { id }'. (Codex/Copilot review finding.) Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/sponsor-triage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/sponsor-triage.yml b/.github/workflows/sponsor-triage.yml index 1e7d39028..728503532 100644 --- a/.github/workflows/sponsor-triage.yml +++ b/.github/workflows/sponsor-triage.yml @@ -121,7 +121,7 @@ jobs: const res = await github.graphql(` query($q: String!) { search(query: $q, type: ISSUE, first: 100) { - nodes { ... on Issue { id } } + nodes { ... on Issue { id } ... on PullRequest { id } } } }`, { q }); for (const node of res.search.nodes) { -- cgit v1.3.1 From 709b33d848e953eaacf41399a65ded1724917eb7 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 4 Jun 2026 13:55:17 +0700 Subject: ci: bump actions/github-script v7 -> v8 (Node.js 24) (#3671) Node.js 20 actions are deprecated; v8 runs on Node.js 24. Co-authored-by: Claude Opus 4.8 (1M context) --- .github/workflows/labeler.yml | 2 +- .github/workflows/sponsor-triage.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 1fdd24bf8..e860c36a3 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -17,7 +17,7 @@ jobs: discussions: write steps: - name: Label New Issue, PR or Discussion - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/sponsor-triage.yml b/.github/workflows/sponsor-triage.yml index 728503532..48b2ac7cc 100644 --- a/.github/workflows/sponsor-triage.yml +++ b/.github/workflows/sponsor-triage.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Sync sponsor issues to project board - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: github-token: ${{ secrets.SPONSOR_TOKEN }} script: | -- cgit v1.3.1 From 3d0516f439cbe2c8d69a9d8dd62f7effa935d0b2 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 4 Jun 2026 14:27:54 +0700 Subject: ci(labeler): match emoji-renamed labels (#3672) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Labels were renamed to add emojis (Adafruit 🌸, Sponsor 💖, Prio 🚩, Prio Top 🚨); update the hardcoded label names in the labeler script to match so they attach to the existing labels instead of recreating plain ones. Co-authored-by: Claude Opus 4.8 (1M context) --- .github/workflows/labeler.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index e860c36a3..87d416f58 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -51,7 +51,7 @@ jobs: if (adafruitResponse.status === 204) { console.log('Adafruit Member'); - labels = ['Adafruit', 'Sponsor', 'Prio Top']; + labels = ['Adafruit 🌸', 'Sponsor 💖', 'Prio Top 🚨']; } } catch (error) { console.log('Not an Adafruit member'); @@ -93,13 +93,13 @@ jobs: if (monthly >= 128) { console.log('Sponsor (DWORD/QWORD tier)'); - labels = ['Sponsor', 'Prio Top']; + labels = ['Sponsor 💖', 'Prio Top 🚨']; } else if (monthly >= 32) { console.log('Sponsor (Word tier)'); - labels = ['Sponsor', 'Prio']; + labels = ['Sponsor 💖', 'Prio 📌']; } else { console.log('Sponsor (below Word tier or tier not visible)'); - labels = ['Sponsor']; + labels = ['Sponsor 💖']; } } else { console.log('Not a public sponsor'); @@ -120,7 +120,7 @@ jobs: if (collaboratorResponse.status === 204) { console.log('Contributor'); - labels = ['Prio']; + labels = ['Prio 📌']; } } catch (error) { console.log('Not a contributor'); -- cgit v1.3.1 From ac32feafeb2fb0f6cc5c3010d32db319ff15ca64 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 4 Jun 2026 15:18:40 +0700 Subject: ci(labeler): auto-apply Port labels from changed driver files (#3673) * ci(labeler): auto-apply Port labels from changed driver files Add path-based labeling so a PR touching a dcd/hcd driver under src/portable/ gets the matching "Port " label automatically. --- .github/labeler.yml | 77 +++++++++++++++++++++++++++++++++++++++++++ .github/workflows/labeler.yml | 22 ++++++++++++- 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 .github/labeler.yml (limited to '.github/workflows') diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..6c7aa7e7d --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,77 @@ +# Path-based auto-labeling for USB IP / port drivers. +# Maps changed dcd/hcd files under src/portable/ to their "Port " label. +# Consumed by actions/labeler (see .github/workflows/labeler.yml -> label-port job). + +"Port DWC2": + - changed-files: + - any-glob-to-any-file: 'src/portable/synopsys/dwc2/**' + +"Port EHCI": + - changed-files: + - any-glob-to-any-file: 'src/portable/ehci/**' + +"Port OHCI": + - changed-files: + - any-glob-to-any-file: 'src/portable/ohci/**' + +"Port FSDev": + - changed-files: + - any-glob-to-any-file: 'src/portable/st/stm32_fsdev/**' + +"Port ChipIdea": + - changed-files: + - any-glob-to-any-file: 'src/portable/chipidea/**' + +"Port NXP IP3511": + - changed-files: + - any-glob-to-any-file: 'src/portable/nxp/lpc_ip3511/**' + +"Port NXP IP3516": + - changed-files: + - any-glob-to-any-file: 'src/portable/nxp/lpc_ip3516/**' + +"Port MUSB": + - changed-files: + - any-glob-to-any-file: + - 'src/portable/mentor/musb/**' + - 'src/portable/sunxi/**' + +"Port RUSB2": + - changed-files: + - any-glob-to-any-file: 'src/portable/renesas/rusb2/**' + +"Port WCH USBFS": + - changed-files: + - any-glob-to-any-file: 'src/portable/wch/*usbfs*' + +"Port WCH USBHS": + - changed-files: + - any-glob-to-any-file: 'src/portable/wch/*usbhs*' + +"Port MAX3421": + - changed-files: + - any-glob-to-any-file: 'src/portable/analog/max3421/**' + +"Port SAMD": + - changed-files: + - any-glob-to-any-file: 'src/portable/microchip/samd/**' + +"Port SAMG": + - changed-files: + - any-glob-to-any-file: 'src/portable/microchip/samg/**' + +"Port nRF": + - changed-files: + - any-glob-to-any-file: 'src/portable/nordic/nrf5x/**' + +"Port Nuvoton": + - changed-files: + - any-glob-to-any-file: 'src/portable/nuvoton/**' + +"Port RP2": + - changed-files: + - any-glob-to-any-file: 'src/portable/raspberrypi/**' + +"Port MSP430": + - changed-files: + - any-glob-to-any-file: 'src/portable/ti/msp430x5xx/**' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 87d416f58..fe09413f1 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -4,12 +4,14 @@ on: issues: types: [opened] pull_request_target: - types: [opened] + types: [opened, synchronize, reopened] discussion: types: [created] jobs: label-priority: + # Author-based priority labels: only on issue/PR/discussion creation, not on PR updates. + if: github.event_name != 'pull_request_target' || github.event.action == 'opened' runs-on: ubuntu-latest permissions: issues: write @@ -160,3 +162,21 @@ jobs: }); } } + + # Path-based Port labels: attach "Port " when a PR touches the matching + # dcd/hcd driver under src/portable/. Mapping lives in .github/labeler.yml. + label-port: + if: github.event_name == 'pull_request_target' + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + issues: write # allow auto-creating a Port label that doesn't exist yet + steps: + - uses: actions/labeler@v5 + with: + configuration-path: .github/labeler.yml + # sync-labels so a Port label is removed once a PR no longer touches + # that driver (job reruns on synchronize). Only labels listed in + # labeler.yml are managed, so author-based Prio/Sponsor labels are untouched. + sync-labels: true -- cgit v1.3.1 From ddc065dc9fd929fcc94b0993c3af4b56877b1cd6 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 4 Jun 2026 21:59:59 +0700 Subject: Remove Sponsor Triage workflow (migrated to hathach/hathach) (#3675) This personal automation now lives in the hathach/hathach repo alongside the other personal project-sync workflows; it has no place in the tinyusb library. Co-authored-by: Claude Opus 4.8 (1M context) --- .github/workflows/sponsor-triage.yml | 165 ----------------------------------- 1 file changed, 165 deletions(-) delete mode 100644 .github/workflows/sponsor-triage.yml (limited to '.github/workflows') diff --git a/.github/workflows/sponsor-triage.yml b/.github/workflows/sponsor-triage.yml deleted file mode 100644 index 48b2ac7cc..000000000 --- a/.github/workflows/sponsor-triage.yml +++ /dev/null @@ -1,165 +0,0 @@ -name: Sponsor Triage - -# Periodically add open issues and PRs opened by sponsors (public and private) to the private "Sponsor Triage" project board -# Requires a PAT in secret SPONSOR_TOKEN with scopes: -# - project (write project items / fields) -# - read:org (search org issues, check Adafruit membership) -# - read:user / sponsors (read own sponsorships incl. private) - -on: - schedule: - - cron: '0 */6 * * *' # every 6 hours - workflow_dispatch: - -concurrency: - group: sponsor-triage - cancel-in-progress: false - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - name: Sync sponsor issues to project board - uses: actions/github-script@v8 - with: - github-token: ${{ secrets.SPONSOR_TOKEN }} - script: | - const PROJECT_OWNER = 'hathach'; - const PROJECT_NUMBER = 3; - // Where to look for sponsor-authored open issues. - const SEARCH_SCOPES = ['org:adafruit', 'user:hathach']; - - const tierFromMonthly = (m) => { - if (m >= 512) return 'QWORD'; - if (m >= 128) return 'DWORD'; - if (m >= 32) return 'Word'; - if (m >= 8) return 'Byte'; - if (m >= 2) return 'Bit'; - return null; - }; - - // --- 1. Resolve project id + field/option ids (by name, never hardcoded) --- - const proj = await github.graphql(` - query($owner: String!, $number: Int!) { - user(login: $owner) { - projectV2(number: $number) { - id - fields(first: 50) { - nodes { - ... on ProjectV2SingleSelectField { - id name options { id name } - } - } - } - } - } - }`, { owner: PROJECT_OWNER, number: PROJECT_NUMBER }); - - const project = proj.user.projectV2; - const fieldByName = {}; - for (const f of project.fields.nodes) { - if (f && f.name) { - fieldByName[f.name] = { id: f.id, options: {} }; - for (const o of (f.options || [])) fieldByName[f.name].options[o.name] = o.id; - } - } - const tierField = fieldByName['Tier']; - const visField = fieldByName['Visibility']; - - // --- 2. Build sponsor map: loginLower -> { tier, visibility } --- - const sponsors = new Map(); - - // 2a. GitHub Sponsors of the owner, including private ones. - let after = null; - for (let page = 0; page < 20; page++) { - const res = await github.graphql(` - query($owner: String!, $after: String) { - user(login: $owner) { - sponsorshipsAsMaintainer(includePrivate: true, first: 100, after: $after) { - pageInfo { hasNextPage endCursor } - nodes { - privacyLevel - tier { monthlyPriceInDollars } - sponsorEntity { - ... on User { login } - ... on Organization { login } - } - } - } - } - }`, { owner: PROJECT_OWNER, after }); - const conn = res.user.sponsorshipsAsMaintainer; - for (const n of conn.nodes) { - const login = n.sponsorEntity && n.sponsorEntity.login; - if (!login) continue; - const tier = tierFromMonthly((n.tier && n.tier.monthlyPriceInDollars) || 0); - const visibility = n.privacyLevel === 'PRIVATE' ? 'Private' : 'Public'; - sponsors.set(login.toLowerCase(), { login, tier, visibility }); - } - if (!conn.pageInfo.hasNextPage) break; - after = conn.pageInfo.endCursor; - } - - core.info(`Resolved ${sponsors.size} sponsor account(s).`); - if (sponsors.size === 0) return; - - // 2b. Adafruit org members get the Adafruit tier regardless of $ amount. - for (const s of sponsors.values()) { - try { - const m = await github.rest.orgs.checkMembershipForUser({ org: 'adafruit', username: s.login }); - if (m.status === 204) s.tier = 'Adafruit'; - } catch (e) { /* not an Adafruit member */ } - } - - // --- 3. Find each sponsor's open issues and PRs in the search scopes --- - // (search type ISSUE returns both issues and pull requests) - const found = new Map(); // contentId -> { tier, visibility } - for (const s of sponsors.values()) { - for (const scope of SEARCH_SCOPES) { - const q = `${scope} is:open author:${s.login}`; - try { - const res = await github.graphql(` - query($q: String!) { - search(query: $q, type: ISSUE, first: 100) { - nodes { ... on Issue { id } ... on PullRequest { id } } - } - }`, { q }); - for (const node of res.search.nodes) { - if (node && node.id && !found.has(node.id)) { - found.set(node.id, { tier: s.tier, visibility: s.visibility }); - } - } - } catch (e) { - core.warning(`Search failed for one scope: ${e.message}`); - } - } - } - core.info(`Found ${found.size} open sponsor issue(s) across scopes.`); - - // --- 4. Add to board + set Tier / Visibility (idempotent) --- - const setField = async (itemId, field, optionName) => { - if (!field || !optionName) return; - const optId = field.options[optionName]; - if (!optId) return; - await github.graphql(` - mutation($p: ID!, $i: ID!, $f: ID!, $o: String!) { - updateProjectV2ItemFieldValue(input: { - projectId: $p, itemId: $i, fieldId: $f, value: { singleSelectOptionId: $o } - }) { projectV2Item { id } } - }`, { p: project.id, i: itemId, f: field.id, o: optId }); - }; - - let added = 0; - for (const [contentId, meta] of found) { - const res = await github.graphql(` - mutation($p: ID!, $c: ID!) { - addProjectV2ItemById(input: { projectId: $p, contentId: $c }) { - item { id } - } - }`, { p: project.id, c: contentId }); - const itemId = res.addProjectV2ItemById.item.id; - await setField(itemId, tierField, meta.tier); - await setField(itemId, visField, meta.visibility); - added++; - } - core.info(`Synced ${added} item(s) to the board.`); -- cgit v1.3.1 From 9dea2c8f397c004d3f3288bac3c0df9c842fe713 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 5 Jun 2026 14:34:27 +0700 Subject: ci: carry metrics baseline forward on no-code-change pushes (#3678) * ci: carry metrics baseline forward on no-code-change pushes The code-metrics job is gated on code_changed and only uploads the metrics-tinyusb artifact on push, so a workflow/docs-only push to master (e.g. removing an unrelated workflow) leaves the latest master Build run without a baseline. PRs download the baseline from the latest master run, so the size comparison then finds nothing and silently falls back to absolute sizes. Add a small metrics-carry-forward job that, on a non-code-change push, downloads the previous metrics-tinyusb artifact and re-publishes it, so the latest run always carries a usable baseline. Carry-forward runs re-upload too, so the baseline chains across consecutive no-code pushes (bounded by artifact retention). --- .github/workflows/build.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index af0191149..e5075f46f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -192,6 +192,36 @@ jobs: header: code-metrics path: metrics_compare.md + # --------------------------------------- + # Keep the metrics baseline available on no-code-change pushes + # The code-metrics job only runs (and uploads metrics-tinyusb) when code changed, so a + # workflow/docs-only push to master would leave the latest run without a baseline for PRs + # to compare against. Carry the previous artifact forward so the baseline is never missing. + # --------------------------------------- + metrics-carry-forward: + needs: [ check-paths ] + if: github.event_name == 'push' && needs.check-paths.outputs.code_changed != 'true' + runs-on: ubuntu-latest + steps: + - name: Download previous metrics baseline from this branch + uses: dawidd6/action-download-artifact@v11 + with: + workflow: build.yml + workflow_conclusion: '' # any conclusion, matching the PR-side baseline download + search_artifacts: true # scan back past runs that lack the artifact (e.g. earlier no-code pushes) + branch: ${{ github.ref_name }} + name: metrics-tinyusb + path: . + if_no_artifact_found: warn + continue-on-error: true # best-effort: never make a no-code push red + + - name: Re-publish baseline so the latest run keeps it + if: hashFiles('metrics.json') != '' + uses: actions/upload-artifact@v7 + with: + name: metrics-tinyusb + path: metrics.json + # --------------------------------------- # Build Make/CMake on Windows/MacOS # --------------------------------------- -- cgit v1.3.1 From 7c68545ab6bd0a2b7d4b59228d84d4c2085abae7 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 8 Jun 2026 09:42:08 +0700 Subject: ci: post auto-review findings to the PR (#3684) Add --comment so the auto-review is actually posted on the PR. --- .github/workflows/claude-code-review.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 91859af9d..71c1cb8ab 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -47,7 +47,9 @@ jobs: # Post/update a single summary comment every run, so a clean review # ("no issues found") is still visible instead of posting nothing. use_sticky_comment: true - prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' + # --comment makes the code-review command post its findings to the PR. + # Without it the command only prints the review to the Actions log. + prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }} --comment' # TEMPORARY: expose the full Claude transcript in the Actions log for # debugging. Revert to remove once done. show_full_output: true -- cgit v1.3.1 From fba8d257846ab9149f9db5443827d741492f837d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Jun 2026 16:11:13 +0700 Subject: test/hil: accumulate HIL report across re-runs; post as sticky PR comment hil_test.py persists results in a hil_report.json sidecar and regenerates hil_report.md from it. A full run starts fresh; a re-run (--skip-board / -bt, i.e. the .skip file) merges into the existing report so already-passed boards/tests are preserved while only re-run cells update. The report dir is configurable via HIL_REPORT_DIR. build.yml: each HIL rig writes the report to a workspace-sibling dir that survives the per-attempt workspace clean, and uploads it as an artifact. A new hil-report job merges the rigs' reports into one sticky PR comment (marocchino) with one table per rig. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/build.yml | 54 +++++++++++++++++++++++++++++++++++++++++ .gitignore | 1 + test/hil/hil_test.py | 59 +++++++++++++++++++++++++++++++++------------ 3 files changed, 99 insertions(+), 15 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e5075f46f..0ff29cdda 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -306,6 +306,9 @@ jobs: env: HIL_JSON: ${{ matrix.hil_json }} steps: + - name: Set HIL report dir (sibling of workspace; persists across run attempts) + run: echo "HIL_REPORT_DIR=$(dirname "$GITHUB_WORKSPACE")/hil-report" >> "$GITHUB_ENV" + - name: Get Skip Boards from previous run if: github.run_attempt != '1' run: | @@ -344,6 +347,15 @@ jobs: exit 1 fi) + - name: Upload HIL report + if: always() && github.event_name == 'pull_request' + uses: actions/upload-artifact@v7 + with: + name: hil-report-${{ matrix.display }} + path: ${{ env.HIL_REPORT_DIR }}/hil_report.md + if-no-files-found: ignore + overwrite: true + # --------------------------------------- # Hardware in the loop (HIL) # self-hosted by HFP, build with IAR toolchain, for attached hardware checkout test/hil/hfp.json @@ -390,3 +402,45 @@ jobs: - name: Test on actual hardware (hardware in the loop) run: | python3 test/hil/hil_test.py hfp.json + + # --------------------------------------- + # Combine HIL results from the rigs into a single sticky PR comment (one table per rig) + # --------------------------------------- + hil-report: + needs: hil-tinyusb + if: | + always() && + needs.hil-tinyusb.result != 'skipped' && + github.event_name == 'pull_request' && + github.repository_owner == 'hathach' && + github.event.pull_request.head.repo.fork == false + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Download HIL reports + uses: actions/download-artifact@v5 + with: + pattern: hil-report-* + path: hil-reports + + - name: Combine rig reports (one table per rig) + run: | + { + echo "## HIL test results" + echo + for d in hil-reports/hil-report-*; do + [ -d "$d" ] || continue + echo "### ${d#hil-reports/hil-report-}" + echo + cat "$d/hil_report.md" 2>/dev/null || echo "_no report produced_" + echo + done + } > hil_combined.md + cat hil_combined.md + + - name: Post HIL report as sticky PR comment + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: hil-report + path: hil_combined.md diff --git a/.gitignore b/.gitignore index ba1574558..0f3c9ce49 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ html latex hil_report.md +hil_report.json *.a *.d *.o diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 2758d093c..515c20e75 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -1694,18 +1694,17 @@ def test_board(board: Board) -> tuple[str, int, list[str], list]: return name, err_count, sorted(set(failed_tests)), rows -def generate_report(mret: list) -> str: - """Build a markdown matrix (rows = boards, columns = tests) from test_board - results. Each mret entry is (name, err, failed_tests, rows) where rows is a - list of (row_label, {example: status}). Columns are padded so the raw table - is aligned in plain text (boards left-aligned, test cells centered).""" +REPORT_MD = 'hil_report.md' +REPORT_JSON = 'hil_report.json' + + +def render_matrix(rows_all: list) -> str: + """Render rows (list of (row_label, {example: status})) as an aligned markdown + matrix: columns = tests (bare names) centered, boards left-aligned.""" canonical = device_tests + dual_tests + host_test + ['device/board_test'] - rows_all = [] # flattened (row_label, cells), preserving board/f1 order seen = set() - for _, _, _, rows in mret: - for row_label, cells in rows: - rows_all.append((row_label, cells)) - seen.update(cells) + for _, cells in rows_all: + seen.update(cells) if not seen: return 'No tests were run.' @@ -1734,6 +1733,34 @@ def generate_report(mret: list) -> str: return '\n'.join([header, sep] + body) + '\n\n' + legend +def accumulate_report(mret: list, report_dir: Path, fresh: bool) -> str: + """Merge this run's results into hil_report.json in report_dir, then (re)write + the markdown matrix to hil_report.md. `fresh` (a full run, no --skip-board/-bt) + starts a new report; otherwise a re-run accumulates so boards/tests that + already passed are preserved while re-run cells are updated. Returns the md.""" + acc = {} # ordered {row_label: {example: status}} + jpath = report_dir / REPORT_JSON + if not fresh and jpath.is_file(): + try: + for entry in json.loads(jpath.read_text()).get('rows', []): + acc[entry['board']] = dict(entry['cells']) + except (ValueError, KeyError, TypeError): + pass # corrupt/old sidecar: start fresh + + # merge this run: current cells override prior for boards/tests that ran + for _, _, _, rows in mret: + for row_label, cells in rows: + acc.setdefault(row_label, {}).update(cells) + + report_dir.mkdir(parents=True, exist_ok=True) + jpath.write_text(json.dumps({'rows': [{'board': k, 'cells': v} for k, v in acc.items()]}, + indent=2) + '\n') + + md = render_matrix(list(acc.items())) + (report_dir / REPORT_MD).write_text(md + '\n', encoding='utf-8') + return md + + def main() -> None: """ Hardware test on specified boards @@ -1823,13 +1850,15 @@ def main() -> None: elif skip_fname.exists(): skip_fname.unlink() - # board x test result matrix -> hil_report.md and stdout - report = generate_report(mret) - report_path = Path('hil_report.md') - report_path.write_text(report + '\n', encoding='utf-8') + # board x test result matrix -> hil_report.md (accumulates across re-runs) + stdout. + # A full run starts fresh; a re-run (--skip-board / -bt, i.e. the .skip file) merges + # into the existing report so already-passed boards/tests are preserved. + report_dir = Path(os.environ.get('HIL_REPORT_DIR', '.')) + fresh = not (args.skip_board or args.board_test) + report = accumulate_report(mret, report_dir, fresh) print() print(report) - print(f'\nReport written to {report_path.resolve()}') + print(f'\nReport written to {(report_dir / REPORT_MD).resolve()}') duration = time.time() - duration print() -- cgit v1.3.1 From a70c5a626b161eae1211fa47e9929de35b18bcd7 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Jun 2026 16:21:34 +0700 Subject: ci: include hil-hfp-iar (IAR) results in the HIL PR comment hil-hfp-iar runs hil_test.py on hfp.json built with IAR on its own rig. Upload its report as the hil-report-hfp-iar artifact and add the job to the hil-report combine job's needs, so the sticky comment shows a third table for the IAR rig alongside tinyusb.json and hfp.json (gcc). The combine gate now runs if either HIL job produced results. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/build.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0ff29cdda..ce94a9829 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -403,14 +403,23 @@ jobs: run: | python3 test/hil/hil_test.py hfp.json + - name: Upload HIL report + if: always() && github.event_name == 'pull_request' + uses: actions/upload-artifact@v7 + with: + name: hil-report-hfp-iar + path: hil_report.md + if-no-files-found: ignore + overwrite: true + # --------------------------------------- # Combine HIL results from the rigs into a single sticky PR comment (one table per rig) # --------------------------------------- hil-report: - needs: hil-tinyusb + needs: [ hil-tinyusb, hil-hfp-iar ] if: | always() && - needs.hil-tinyusb.result != 'skipped' && + (needs.hil-tinyusb.result != 'skipped' || needs.hil-hfp-iar.result != 'skipped') && github.event_name == 'pull_request' && github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false -- cgit v1.3.1 From 71f7ba0415764ef3dad0fe0dec49cde4d490fdc5 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Jun 2026 16:28:53 +0700 Subject: ci: demote sticky-comment report headings to h2; rename HIL report The Size Difference Report and HIL comments rendered their titles at h1, which is oversized inside a PR comment. Use h2 for both titles (with subsections demoted to h3 to keep the hierarchy), and rename the HIL comment from "HIL test results" to "Hardware-in-the-loop (HIL) Test Report" for consistency. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/build.yml | 2 +- tools/metrics.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ce94a9829..e22ba909c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -436,7 +436,7 @@ jobs: - name: Combine rig reports (one table per rig) run: | { - echo "## HIL test results" + echo "## Hardware-in-the-loop (HIL) Test Report" echo for d in hil-reports/hil-report-*; do [ -d "$d" ] || continue diff --git a/tools/metrics.py b/tools/metrics.py index f624f382f..05978b6ef 100644 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -400,7 +400,7 @@ def write_combine_markdown(json_data, path, sort_order='name+', title="TinyUSB A def write_compare_markdown(comparison, path, sort_order='size'): """Write comparison data to markdown file.""" md_lines = [ - "# Size Difference Report", + "## Size Difference Report", "", "Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.", "", @@ -415,7 +415,7 @@ def write_compare_markdown(comparison, path, sort_order='size'): md_lines.append(f"
{title}") md_lines.append("") else: - md_lines.append(f"## {title}") + md_lines.append(f"### {title}") md_lines.extend(render_compare_table(_build_rows(rows, sort_order), include_sum=True)) md_lines.append("") -- cgit v1.3.1 From 575a8fbcd0e5880791ea5f834649149a8f787d95 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Wed, 10 Jun 2026 18:04:54 +0700 Subject: Merge pull request #3690 from hathach/claude/board-test-idle-park hil: park boards with idle board_test instead of erasing flash --- .github/workflows/build_util.yml | 2 +- examples/device/board_test/src/main.c | 34 +++++++++-- hw/bsp/espressif/family.cmake | 7 +++ hw/bsp/family_support.cmake | 6 ++ test/hil/hil_test.py | 105 ++-------------------------------- 5 files changed, 48 insertions(+), 106 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 69b6f28d5..2532caebe 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -67,7 +67,7 @@ jobs: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} run: | if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then - docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py --target all ${{ matrix.arg }} + docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -e CI="$CI" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py --target all ${{ matrix.arg }} else BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} --target all" if [ "${{ inputs.upload-metrics }}" = "true" ]; then diff --git a/examples/device/board_test/src/main.c b/examples/device/board_test/src/main.c index 71e7e1da7..3d8cf9979 100644 --- a/examples/device/board_test/src/main.c +++ b/examples/device/board_test/src/main.c @@ -54,6 +54,11 @@ void tusb_time_delay_ms_api(uint32_t ms) { // //--------------------------------------------------------------------+ +// CI_BUILD (defined for all CI builds, see hw/bsp/family_support.cmake) skips the +// blink/echo loop below: after HIL tests, this firmware is flashed to park the +// board in a quiet, low-power idle state (no USB, LED, or UART activity). +#ifndef CI_BUILD + // Task parameter type: ULONG for ThreadX, void* for FreeRTOS and noos #if CFG_TUSB_OS == OPT_OS_THREADX #define RTOS_PARAM ULONG @@ -107,19 +112,37 @@ static void board_test_loop(RTOS_PARAM param) { } } +#endif // CI_BUILD + int main(void) { +#ifdef CI_BUILD + // Park the board in a quiet, low-power idle loop. board_init() is intentionally + // skipped: no clocks, peripherals, USB, LED, or UART are brought up, so the MCU + // just idles after CI flashes this over a board's previous test firmware. + while (1) { + #if defined(ESP_PLATFORM) + vTaskDelay(portMAX_DELAY); // ESP runs FreeRTOS: yield this task indefinitely + #elif defined(__ARM_ARCH) || defined(__arm__) + __asm volatile("wfe"); // Cortex-M: sleep until an event + #else + // other architectures (e.g. RISC-V): spin + #endif + } + // no return: the loop never exits (an unreachable return trips IAR's Pe111) +#else board_init(); board_led_write(true); -#if CFG_TUSB_OS == OPT_OS_FREERTOS + #if CFG_TUSB_OS == OPT_OS_FREERTOS freertos_init(); -#elif CFG_TUSB_OS == OPT_OS_THREADX + #elif CFG_TUSB_OS == OPT_OS_THREADX tx_kernel_enter(); -#else + #else board_test_loop(NULL); -#endif + #endif return 0; +#endif } #ifdef ESP_PLATFORM @@ -128,6 +151,7 @@ void app_main(void) { } #endif +#ifndef CI_BUILD //--------------------------------------------------------------------+ // FreeRTOS //--------------------------------------------------------------------+ @@ -173,3 +197,5 @@ void tx_application_define(void *first_unused_memory) { 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); } #endif + +#endif // CI_BUILD diff --git a/hw/bsp/espressif/family.cmake b/hw/bsp/espressif/family.cmake index 30d5a6ac9..b3bda4ad8 100644 --- a/hw/bsp/espressif/family.cmake +++ b/hw/bsp/espressif/family.cmake @@ -44,3 +44,10 @@ set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRE set(SDKCONFIG ${CMAKE_BINARY_DIR}/sdkconfig) include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +# CI_BUILD marks firmware built in CI (GitHub Actions sets CI). Mirrors the +# non-espressif define added in family_configure_common(); applied build-wide +# here since espressif examples return before that function runs. +if(DEFINED ENV{CI}) + idf_build_set_property(COMPILE_DEFINITIONS "CI_BUILD=1" APPEND) +endif() diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index af2716b28..1f3952205 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -454,6 +454,12 @@ function(family_configure_common TARGET RTOS) BOARD_${BOARD_UPPER} ) + # CI_BUILD marks firmware built in CI (GitHub Actions sets CI). Examples can use + # it to alter behavior under test, e.g. board_test idles to park HIL boards. + if(DEFINED ENV{CI}) + target_compile_definitions(${TARGET} PUBLIC CI_BUILD=1) + endif() + # compile define from command line if(DEFINED CFLAGS_CLI) separate_arguments(CFLAGS_CLI) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 226e97780..45bad7a45 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -40,7 +40,6 @@ import os import random import re import select -import struct import sys import time import signal @@ -514,80 +513,6 @@ def reset_lm4flash(board): return subprocess.CompletedProcess(args=['dummy'], returncode=0) -# ------------------------------------------------------------- -# Erase: wipe the first flash sector (vector table) after a board's tests so the -# MCU faults to an idle state — no USB, lower power, and faster than programming -# device/board_test. Same (board, firmware) signature as flash_*; `firmware` is -# only used to find the flash origin (jlink) or the esp flash metadata. -# ------------------------------------------------------------- -def elf_flash_origin(elf_path: str) -> int: - """Flash base address (first PT_LOAD segment physical address) of a - little-endian ELF32 firmware — i.e. where the vector table is programmed.""" - data = Path(elf_path).read_bytes() - if data[:4] != b'\x7fELF': - raise ValueError(f'not an ELF: {elf_path}') - e_phoff = struct.unpack_from(' subprocess.CompletedProcess: - flasher = board['flasher'] - origin = elf_flash_origin(f'{firmware}.elf') - script = ['halt', f'erase 0x{origin:x} 0x{origin + 4:x}', 'exit'] - f_jlink = Path(f'{board["name"]}_erase.jlink') - with f_jlink.open('w') as f: - f.writelines(f'{s}\n' for s in script) - ret = run_cmd(f'JLinkExe -USB {flasher["uid"]} {flasher["args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile {f_jlink}') - f_jlink.unlink(missing_ok=True) - return ret - - -def erase_stlink(board: Board, firmware: str) -> subprocess.CompletedProcess: - flasher = board['flasher'] - return run_cmd(f'STM32_Programmer_CLI --connect port=swd sn={flasher["uid"]} --erase 0') - - -def erase_openocd(board: Board, firmware: str) -> subprocess.CompletedProcess: - flasher = board['flasher'] - return run_cmd(f'openocd -c "tcl_port disabled" -c "gdb_port disabled" -c "adapter serial {flasher["uid"]}" ' - f'{flasher["args"]} -c "init; reset halt; flash erase_sector 0 0 0; exit"') - - -def erase_openocd_adi(board: Board, firmware: str) -> subprocess.CompletedProcess: - flasher = board['flasher'] - openocd = OPENCOD_ADI_PATH / 'src' / 'openocd' - tcl_dir = OPENCOD_ADI_PATH / 'tcl' - return run_cmd(f'{openocd} -c "adapter serial {flasher["uid"]}" -s {tcl_dir} ' - f'{flasher["args"]} -c "init; reset halt; flash erase_sector 0 0 0; exit"') - - -def erase_esptool(board: Board, firmware: str) -> subprocess.CompletedProcess: - flasher = board['flasher'] - port = get_serial_dev(flasher["uid"], None, None, 0) - fw_dir = Path(f'{firmware}.bin').parent - with (fw_dir / 'config.env').open() as f: - idf_target = json.load(f)['IDF_TARGET'] - return run_cmd(f'esptool --chip {idf_target} -p {port} {flasher["args"]} erase_region 0x0 0x4000', - cwd=str(fw_dir)) - - -def erase_lm4flash(board: Board, firmware: str) -> subprocess.CompletedProcess: - # lm4flash has no erase command, but it erases the sectors it programs — so - # writing a blank (all-0xFF) image leaves the first sector erased. - flasher = board['flasher'] - blank = Path(f'{board["name"]}_blank.bin') - blank.write_bytes(b'\xff' * 4096) - ret = run_cmd(f'lm4flash -s {flasher["uid"]} {flasher["args"]} {blank}') - blank.unlink(missing_ok=True) - return ret - - # ------------------------------------------------------------- # Tests: dual # ------------------------------------------------------------- @@ -1718,28 +1643,6 @@ def build_board(board: Board) -> tuple[str, int]: return name, failed -def disable_board(board: Board, f1: str): - """Quiesce the board after its tests so it stops drawing power / enumerating - USB: erase the first flash sector (vector table) where the flasher supports - it, otherwise flash device/board_test. Skipped when --skip-flash is set. - Returns (report_key, status) or None.""" - if skip_flash: - return None - name = board['name'] - erase_fn = globals().get(f'erase_{board["flasher"]["name"].lower()}') - fw = find_firmware(name, f1, 'device/board_test') - if erase_fn and fw is not None: - start_s = time.time() - ret = erase_fn(board, str(fw)) - status = 'pass' if ret.returncode == 0 else 'fail' - st = STATUS_OK if status == 'pass' else STATUS_FAILED - log_line(f'{name:40} {"erase (disable)":30} ... {st} in {time.time() - start_s:.1f}s') - return 'erase', status - # flasher has no erase support (or board_test not built): flash board_test - _ec, status, _ = test_example(board, f1, 'device/board_test') - return 'device/board_test', status - - def test_board(board: Board) -> tuple[str, int, list[str], list]: name = board['name'] flasher = board['flasher'] @@ -1796,10 +1699,10 @@ def test_board(board: Board) -> tuple[str, int, list[str], list]: failed_tests.append(test) rows.append((name + f1_suffix(f1), cells)) - # disable the board's usb after its tests (erase first flash sector, or flash - # board_test where the flasher can't erase); skipped when --skip-flash is set. - # This is teardown, not a test — not recorded in the report. - disable_board(board, flags_on_list[0]) + # flash board_test last to disable board's usb (skipped when --skip-flash is set); + # this is teardown/park, not a test — not recorded in the report + if not skip_flash: + test_example(board, flags_on_list[0], 'device/board_test') return name, err_count, sorted(set(failed_tests)), rows -- cgit v1.3.1 From 6f35e76667f4015ef429ace5730e20cc0037e042 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 11 Jun 2026 08:16:43 +0700 Subject: HIL: replace build.flags_on with named build variants (#3687) * test/hil: replace build.flags_on with named variant schema Boards declare build variants as `variant: [{name, flags}]` instead of `build.flags_on`. The variant `name` is the build dir (cmake-build-) and the HIL report row; `flags` is the raw CFLAGS string (-D...=1) injected via CFLAGS_CLI. No `variant` => a single build named after the board. - build.py: --build-name (dir) + --cflag= (raw CFLAGS, repeatable, =form survives the matrix's shell word-splitting); drop -f1/CFLAGS wrapping. - hil_ci_set_matrix.py: emit one build arg per variant. - hil_test.py: iterate variants; report row + build dir = variant name. - hil_ci.sh: copy all cmake-build-* dirs for -b runs. - get_deps.py: accept (ignore) --build-name/--cflag from matrix args. - tinyusb.json: migrate all 6 flags_on boards to variant. * board_test: park CI build with busy spin instead of wfe --- .github/workflows/build.yml | 10 ++++- examples/device/board_test/src/main.c | 50 ++++++++++--------------- test/hil/hfp.json | 4 ++ test/hil/hil_ci.sh | 39 +++++++++++++++++--- test/hil/hil_ci_set_matrix.py | 26 ++++++------- test/hil/hil_test.py | 69 ++++++++++++++++++----------------- test/hil/tinyusb.json | 58 ++++++++++++----------------- tools/build.py | 30 +++++++++------ tools/get_deps.py | 2 + 9 files changed, 157 insertions(+), 131 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e22ba909c..a7c7cf99a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -397,7 +397,15 @@ jobs: run: python3 tools/get_deps.py $BUILD_ARGS - name: Build - run: python3 tools/build.py --toolchain iar $BUILD_ARGS + run: | + # Each variant carries its own --build-name/--cflag, which are global to a + # single build.py invocation — so build one matrix entry at a time rather + # than joining them (joining would leak a variant's flags onto every board). + readarray -t ENTRIES < <(python test/hil/hil_ci_set_matrix.py test/hil/hfp.json | jq -r '.["arm-gcc"][]') + for entry in "${ENTRIES[@]}"; do + echo "+ tools/build.py --toolchain iar $entry" + python3 tools/build.py --toolchain iar $entry + done - name: Test on actual hardware (hardware in the loop) run: | diff --git a/examples/device/board_test/src/main.c b/examples/device/board_test/src/main.c index 3d8cf9979..96dc1bd30 100644 --- a/examples/device/board_test/src/main.c +++ b/examples/device/board_test/src/main.c @@ -57,8 +57,16 @@ void tusb_time_delay_ms_api(uint32_t ms) { // CI_BUILD (defined for all CI builds, see hw/bsp/family_support.cmake) skips the // blink/echo loop below: after HIL tests, this firmware is flashed to park the // board in a quiet, low-power idle state (no USB, LED, or UART activity). -#ifndef CI_BUILD +#ifdef CI_BUILD +int main(void) { + while (1) { + #if defined(ESP_PLATFORM) + vTaskDelay(portMAX_DELAY); + #endif + } +} +#else // Task parameter type: ULONG for ThreadX, void* for FreeRTOS and noos #if CFG_TUSB_OS == OPT_OS_THREADX #define RTOS_PARAM ULONG @@ -112,46 +120,21 @@ static void board_test_loop(RTOS_PARAM param) { } } -#endif // CI_BUILD - int main(void) { -#ifdef CI_BUILD - // Park the board in a quiet, low-power idle loop. board_init() is intentionally - // skipped: no clocks, peripherals, USB, LED, or UART are brought up, so the MCU - // just idles after CI flashes this over a board's previous test firmware. - while (1) { - #if defined(ESP_PLATFORM) - vTaskDelay(portMAX_DELAY); // ESP runs FreeRTOS: yield this task indefinitely - #elif defined(__ARM_ARCH) || defined(__arm__) - __asm volatile("wfe"); // Cortex-M: sleep until an event - #else - // other architectures (e.g. RISC-V): spin - #endif - } - // no return: the loop never exits (an unreachable return trips IAR's Pe111) -#else board_init(); board_led_write(true); - #if CFG_TUSB_OS == OPT_OS_FREERTOS +#if CFG_TUSB_OS == OPT_OS_FREERTOS freertos_init(); - #elif CFG_TUSB_OS == OPT_OS_THREADX +#elif CFG_TUSB_OS == OPT_OS_THREADX tx_kernel_enter(); - #else +#else board_test_loop(NULL); - #endif - - return 0; #endif -} -#ifdef ESP_PLATFORM -void app_main(void) { - main(); + return 0; } -#endif -#ifndef CI_BUILD //--------------------------------------------------------------------+ // FreeRTOS //--------------------------------------------------------------------+ @@ -197,5 +180,10 @@ void tx_application_define(void *first_unused_memory) { 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); } #endif - #endif // CI_BUILD + +#ifdef ESP_PLATFORM +void app_main(void) { + main(); +} +#endif diff --git a/test/hil/hfp.json b/test/hil/hfp.json index 8ba7a8f44..bb146d2fc 100644 --- a/test/hil/hfp.json +++ b/test/hil/hfp.json @@ -15,6 +15,10 @@ { "name": "stm32f746disco", "uid": "210041000C51343237303334", + "variant": [ + { "name": "stm32f746disco", "flags": "" }, + { "name": "stm32f746disco-DMA", "flags": "-DCFG_TUD_DWC2_DMA_ENABLE=1 -DCFG_TUH_DWC2_DMA_ENABLE=1" } + ], "tests": { "device": true, "host": false, "dual": false }, diff --git a/test/hil/hil_ci.sh b/test/hil/hil_ci.sh index 4f68ed067..3ec907979 100644 --- a/test/hil/hil_ci.sh +++ b/test/hil/hil_ci.sh @@ -66,14 +66,41 @@ copy_board_binaries() { } if [ -n "$BOARD" ]; then - BUILD_DIR="$ROOT_DIR/examples/cmake-build-$BOARD" - if [ ! -d "$BUILD_DIR" ]; then - echo "Error: build directory not found: $BUILD_DIR" - echo "Build first with: cd examples && cmake -DBOARD=$BOARD -G Ninja -B cmake-build-$BOARD . && cmake --build cmake-build-$BOARD" + # Copy the board's build dir plus its variant dirs. Variant names come from + # $CONFIG (they are not required to be prefixed with the board name); the + # cmake-build--* glob is kept as a fallback for ad-hoc local builds. + # Collect only dirs that actually exist, deduplicated. + declare -A SEEN_DIRS=() + BUILD_DIRS=() + add_build_dir() { + [[ -d "$1" && -z "${SEEN_DIRS[$1]:-}" ]] || return 0 + SEEN_DIRS[$1]=1 + BUILD_DIRS+=("$1") + } + shopt -s nullglob + for d in "$ROOT_DIR"/examples/cmake-build-"$BOARD" "$ROOT_DIR"/examples/cmake-build-"$BOARD"-*; do + add_build_dir "$d" + done + shopt -u nullglob + while IFS= read -r v; do + add_build_dir "$ROOT_DIR/examples/cmake-build-$v" + done < <(python3 -c ' +import json, sys +cfg = json.load(open(sys.argv[1])) +for b in cfg.get("boards", []): + if b["name"] == sys.argv[2]: + for v in b.get("variant") or []: + print(v["name"]) +' "$CONFIG" "$BOARD") + if [ ${#BUILD_DIRS[@]} -eq 0 ]; then + echo "Error: no build directory found for $BOARD under $ROOT_DIR/examples/" + echo "Build first with: cd examples && cmake --preset $BOARD && cmake --build --preset $BOARD" exit 1 fi - echo "==> Copying binaries for $BOARD" - copy_board_binaries "$BUILD_DIR" + echo "==> Copying binaries for $BOARD (${#BUILD_DIRS[@]} build dir(s))" + for d in "${BUILD_DIRS[@]}"; do + copy_board_binaries "$d" + done else echo "==> Copying all built binaries" # Use `%/` parameter expansion to strip the trailing slash from the glob — diff --git a/test/hil/hil_ci_set_matrix.py b/test/hil/hil_ci_set_matrix.py index 2cce35ae2..baa24afb1 100644 --- a/test/hil/hil_ci_set_matrix.py +++ b/test/hil/hil_ci_set_matrix.py @@ -44,19 +44,19 @@ def main(): toolchain = 'arm-gcc' build_board = f'-b {name}' - if 'build' in board: - if 'args' in board['build']: - build_board += ' ' + ' '.join(f'-D{a}' for a in board['build']['args']) - if 'flags_on' in board['build']: - for f in board['build']['flags_on']: - if f == '': - append_build_arg(toolchain, build_board) - else: - append_build_arg(toolchain, f'{build_board} -f1 {f.replace(" ", " -f1 ")}') - else: - append_build_arg(toolchain, build_board) - else: - append_build_arg(toolchain, build_board) + if 'build' in board and 'args' in board['build']: + build_board += ' ' + ' '.join(f'-D{a}' for a in board['build']['args']) + + # Each variant builds into cmake-build- with its raw CFLAGS. + # No 'variant' -> a single build named after the board. + variants = board.get('variant') or [{'name': name, 'flags': ''}] + for v in variants: + arg = build_board + if v['name'] != name: + arg += f' --build-name {v["name"]}' + for tok in v.get('flags', '').split(): + arg += f' --cflag={tok}' + append_build_arg(toolchain, arg) print(json.dumps(matrix)) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 45bad7a45..da13fcbaf 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -122,16 +122,21 @@ class TestsCfg(TypedDict, total=False): class BuildCfg(TypedDict, total=False): - flags_on: list[str] args: list[str] +class VariantCfg(TypedDict, total=False): + name: str # build dir (cmake-build-) and HIL report row + flags: str # raw CFLAGS, e.g. "-DCFG_TUD_DWC2_DMA_ENABLE=1" + + class Board(TypedDict): name: str uid: str tests: TestsCfg flasher: FlasherCfg build: NotRequired[BuildCfg] + variant: NotRequired[list[VariantCfg]] class HilConfig(TypedDict): @@ -223,7 +228,9 @@ def open_serial_dev(port: str): while timeout > 0: if os.path.exists(port): try: - ser = serial.Serial(port, baudrate=115200, timeout=5) + # write_timeout: a wedged device otherwise blocks ser.write() forever, + # hanging the worker until the pool/job timeout kills the whole run + ser = serial.Serial(port, baudrate=115200, timeout=5, write_timeout=5) break except serial.SerialException: print(f'serial {port} not reaady {timeout} sec') @@ -976,9 +983,9 @@ def test_device_cdc_msc_throughput(board): pass print(f' CDC read {cdc_r} write {cdc_w}, MSC read {msc_r} write {msc_w} ', end='') - # compact read/write speed for the report cell, e.g. "C 652k/422k M 1.1M/783k" + # compact read/write speed for the report cell, e.g. "✅ CDC 652k/422k MSC 1.1M/783k" short = lambda s: (s.split()[0].rstrip('0').rstrip('.') + s.split()[-1][0]) if ' ' in s else s - return f'C {short(cdc_r)}/{short(cdc_w)} M {short(msc_r)}/{short(msc_w)}' + return f'{REPORT_CELL["pass"]} CDC {short(cdc_r)}/{short(cdc_w)} MSC {short(msc_r)}/{short(msc_w)}' def test_device_dfu(board): @@ -1502,17 +1509,12 @@ host_test = [ ] -def f1_suffix(f1: str) -> str: - """Build dir / row-label suffix for a flags-on variant ('' for the default).""" - return '-f1_' + f1.replace(' ', '_') if f1 else '' - - -def find_firmware(name: str, f1: str, example: str): +def find_firmware(variant: str, example: str): """Locate a built example's firmware base path (no extension) under - cmake-build-[-f1_...]//. Accepts the single-config layout - (firmware directly in the example dir) or Ninja Multi-Config (a per-config - subdir like RelWithDebInfo/). Returns the base Path, or None if not built.""" - fw_dir = TINYUSB_ROOT / build_dir / f'cmake-build-{name}{f1_suffix(f1)}' / example + cmake-build-//. Accepts the single-config layout (firmware + directly in the example dir) or Ninja Multi-Config (a per-config subdir like + RelWithDebInfo/). Returns the base Path, or None if not built.""" + fw_dir = TINYUSB_ROOT / build_dir / f'cmake-build-{variant}' / example base = Path(example).name if fw_dir.is_dir(): for cand in [fw_dir / base, fw_dir / 'RelWithDebInfo' / base, @@ -1522,25 +1524,24 @@ def find_firmware(name: str, f1: str, example: str): return None -def test_example(board: Board, f1: str, example: str) -> tuple[int, str]: +def test_example(board: Board, variant: str, example: str) -> tuple[int, str]: """ Test example firmware :param board: board dict - :param f1: flags on + :param variant: build variant name = build dir (cmake-build-) and report row :param example: example name :return: (err_count, status, metric) where err_count is 0 on success/skip or 1 on failure, status is one of 'pass'/'fail'/'skip' (a missing binary counts as 'skip'), and metric is an optional string a test returns to show in its report cell instead of the pass symbol (e.g. speed) """ - name = board['name'] err_count = 0 result_status = 'fail' metric = None - test_name = f'{name + f1_suffix(f1):40} {example:30} ...' + test_name = f'{variant:40} {example:30} ...' - fw_name = find_firmware(name, f1, example) + fw_name = find_firmware(variant, example) if fw_name is None: log_line(f'{test_name} Skip (no binary)') return 0, 'skip', None @@ -1619,21 +1620,22 @@ def test_example(board: Board, f1: str, example: str) -> tuple[int, str]: def build_board(board: Board) -> tuple[str, int]: """Build firmware for this board via tools/build.py. - Honors board config's build.flags_on variants and build.args defines. - Output goes to cmake-build/cmake-build-BOARD[-f1_...]/ (tools/build.py layout).""" + Honors board config's variant list and build.args defines. + Output goes to cmake-build/cmake-build-/ (tools/build.py layout).""" name = board['name'] bcfg = cast(BuildCfg, board.get('build', {})) - flags_on_list = bcfg.get('flags_on', ['']) extra_defs = bcfg.get('args', []) + variants = board.get('variant') or [{'name': name, 'flags': ''}] failed = 0 - for f1 in flags_on_list: + for v in variants: cmd = [sys.executable, str(TINYUSB_ROOT / 'tools' / 'build.py'), '-b', name] for d in extra_defs: cmd += ['-D', d] - if f1: - for flag in f1.split(): - cmd += ['-f1', flag] + if v['name'] != name: + cmd += ['--build-name', v['name']] + for tok in v.get('flags', '').split(): + cmd += [f'--cflag={tok}'] if verbose: cmd.append('-v') print(f' + {" ".join(cmd)}') @@ -1684,25 +1686,24 @@ def test_board(board: Board) -> tuple[str, int, list[str], list]: err_count = 0 failed_tests = [] - rows = [] # list of (row_label, {example: status}) — one row per board[-f1] variant - flags_on_list = [""] - if 'build' in board and 'flags_on' in board['build']: - flags_on_list = board['build']['flags_on'] + rows = [] # list of (row_label, {example: status}) — one row per build variant + variants = board.get('variant') or [{'name': name, 'flags': ''}] - for f1 in flags_on_list: + for v in variants: + vname = v['name'] cells = {} for test in test_list: - ec, status, metric = test_example(board, f1, test) + ec, status, metric = test_example(board, vname, test) err_count += ec cells[test] = metric if metric else status if ec > 0: failed_tests.append(test) - rows.append((name + f1_suffix(f1), cells)) + rows.append((vname, cells)) # flash board_test last to disable board's usb (skipped when --skip-flash is set); # this is teardown/park, not a test — not recorded in the report if not skip_flash: - test_example(board, flags_on_list[0], 'device/board_test') + test_example(board, variants[0]['name'], 'device/board_test') return name, err_count, sorted(set(failed_tests)), rows diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index 319ee9a79..afe3c4d03 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -17,12 +17,10 @@ { "name": "espressif_p4_function_ev", "uid": "6055F9F98715", - "build": { - "flags_on": [ - "", - "CFG_TUD_DWC2_DMA_ENABLE CFG_TUH_DWC2_DMA_ENABLE" - ] - }, + "variant": [ + { "name": "espressif_p4_function_ev", "flags": "" }, + { "name": "espressif_p4_function_ev-DMA", "flags": "-DCFG_TUD_DWC2_DMA_ENABLE=1 -DCFG_TUH_DWC2_DMA_ENABLE=1" } + ], "tests": { "only": [ "device/cdc_msc_freertos", @@ -58,12 +56,10 @@ { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", - "build": { - "flags_on": [ - "", - "CFG_TUD_DWC2_DMA_ENABLE CFG_TUH_DWC2_DMA_ENABLE" - ] - }, + "variant": [ + { "name": "espressif_s3_devkitm", "flags": "" }, + { "name": "espressif_s3_devkitm-DMA", "flags": "-DCFG_TUD_DWC2_DMA_ENABLE=1 -DCFG_TUH_DWC2_DMA_ENABLE=1" } + ], "tests": { "only": [ "device/cdc_msc_freertos", @@ -226,11 +222,9 @@ { "name": "raspberry_pi_pico", "uid": "E6614C311B764A37", - "build": { - "flags_on": [ - "CFG_TUH_RPI_PIO_USB" - ] - }, + "variant": [ + { "name": "raspberry_pi_pico", "flags": "-DCFG_TUH_RPI_PIO_USB=1" } + ], "tests": { "device": true, "host": true, @@ -374,12 +368,10 @@ { "name": "stm32f723disco", "uid": "460029001951373031313335", - "build": { - "flags_on": [ - "", - "CFG_TUH_DWC2_DMA_ENABLE" - ] - }, + "variant": [ + { "name": "stm32f723disco", "flags": "" }, + { "name": "stm32f723disco-DMA", "flags": "-DCFG_TUH_DWC2_DMA_ENABLE=1" } + ], "tests": { "device": true, "host": true, @@ -410,12 +402,10 @@ { "name": "stm32h743nucleo", "uid": "110018000951383432343236", - "build": { - "flags_on": [ - "", - "CFG_TUD_DWC2_DMA_ENABLE" - ] - }, + "variant": [ + { "name": "stm32h743nucleo", "flags": "" }, + { "name": "stm32h743nucleo-DMA", "flags": "-DCFG_TUD_DWC2_DMA_ENABLE=1 -DCFG_TUH_DWC2_DMA_ENABLE=1" } + ], "tests": { "device": true, "host": false, @@ -474,12 +464,10 @@ { "name": "stm32f769disco", "uid": "21002F000F51363531383437", - "build": { - "flags_on": [ - "", - "CFG_TUD_DWC2_DMA_ENABLE" - ] - }, + "variant": [ + { "name": "stm32f769disco", "flags": "" }, + { "name": "stm32f769disco-DMA", "flags": "-DCFG_TUD_DWC2_DMA_ENABLE=1 -DCFG_TUH_DWC2_DMA_ENABLE=1" } + ], "tests": { "device": true, "host": false, diff --git a/tools/build.py b/tools/build.py index 3c5c3c077..86bc30d28 100755 --- a/tools/build.py +++ b/tools/build.py @@ -105,16 +105,14 @@ def print_build_result(board, build_target, status, duration): # ----------------------------- # CMake # ----------------------------- -def cmake_board(board, build_args, build_flags_on, build_targets): +def cmake_board(board, build_args, build_name, build_cflags, build_targets): ret = [0, 0, 0] start_time = time.monotonic() - build_dir = f'cmake-build/cmake-build-{board}' + build_dir = f'cmake-build/cmake-build-{build_name or board}' build_flags = [] - if len(build_flags_on) > 0: - cli_flags = ' '.join(f'-D{flag}=1' for flag in build_flags_on) - build_flags.append(f'-DCFLAGS_CLI={cli_flags}') - build_dir += '-f1_' + '_'.join(build_flags_on) + if build_cflags: + build_flags.append('-DCFLAGS_CLI=' + ' '.join(build_cflags)) family = find_family(board) if family == 'espressif': @@ -194,13 +192,13 @@ def make_board(board, build_args, build_targets): # ----------------------------- # Build Family # ----------------------------- -def build_boards_list(boards, build_defines, build_system, build_flags_on, build_targets): +def build_boards_list(boards, build_defines, build_system, build_name, build_cflags, build_targets): ret = [0, 0, 0] for b in boards: r = [0, 0, 0] if build_system == 'cmake': build_args = [f'-D{d}' for d in build_defines] - r = cmake_board(b, build_args, build_flags_on, build_targets) + r = cmake_board(b, build_args, build_name, build_cflags, build_targets) elif build_system == 'make': build_args = ' '.join(f'{d}' for d in build_defines) r = make_board(b, build_args, build_targets) @@ -261,7 +259,10 @@ def main(): parser.add_argument('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') parser.add_argument('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') parser.add_argument('-D', '--define-symbol', action='append', default=[], help='Define to pass to build system') - parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Build flag to pass to build system') + parser.add_argument('--build-name', default=None, + help='Override build dir name (cmake-build-); default is the board name. Used for HIL variants.') + parser.add_argument('--cflag', action='append', default=[], + help='Raw compiler flag appended to CFLAGS_CLI, e.g. --cflag=-DCFG_TUD_DWC2_DMA_ENABLE=1 (repeatable)') parser.add_argument('--one-random', action='store_true', default=False, help='Build only one random board of each specified family') parser.add_argument('--one-first', action='store_true', default=False, @@ -277,7 +278,8 @@ def main(): toolchain = args.toolchain build_system = args.build_system build_defines = args.define_symbol - build_flags_on = args.build_flags_on + build_name = args.build_name + build_cflags = args.cflag one_random = args.one_random one_first = args.one_first build_targets = args.target if args.target else ['all'] @@ -290,6 +292,12 @@ def main(): print("Please specify families or board to build") return 1 + # --build-name renames the single shared build dir, so building more than one + # board with it would clobber/mix artifacts + if build_name and (len(families) > 0 or len(boards) != 1): + print("--build-name requires exactly one board (-b) and no families") + return 1 + print(build_separator) print(build_format.format('Board', 'Target', '\033[39mResult\033[0m', 'Time')) total_time = time.monotonic() @@ -310,7 +318,7 @@ def main(): all_boards.extend(get_family_boards(f, one_random, one_first)) # build all boards - result = build_boards_list(all_boards, build_defines, build_system, build_flags_on, build_targets) + result = build_boards_list(all_boards, build_defines, build_system, build_name, build_cflags, build_targets) total_time = time.monotonic() - total_time print(build_separator) diff --git a/tools/get_deps.py b/tools/get_deps.py index eb87abf6e..abe5750f1 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -366,6 +366,8 @@ def main(): parser.add_argument('-b', '--board', action='append', default=[], help='Boards to fetch') parser.add_argument('-D', '--define', action='append', default=[], help='Have no effect') parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Have no effect') + parser.add_argument('--build-name', default=None, help='Have no effect') + parser.add_argument('--cflag', action='append', default=[], help='Have no effect') args = parser.parse_args() families = args.families -- cgit v1.3.1 From c9cfd829f6a793b227f4e52df29337f2a8530ce7 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Jun 2026 19:41:51 +0700 Subject: ci(claude-review): raise --max-turns 20 -> 50 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Claude Code Review action runs /code-review:code-review with a hard --max-turns cap. On large PRs (e.g. #3636 "add stm32c5 support", 29 files / +1689), the agent exhausts 20 turns exploring the diff before it can produce and post its review, so the SDK returns an error and the claude-review check fails red with: Reached maximum number of turns (20) Raise the cap to 50 so port-sized PRs complete and post their review. Cost scales with tokens, not the cap: a finished review pays the same whether the ceiling is 25 or 50 — the cap only bites when the agent would otherwise be force-stopped mid-run. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/claude-code-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 71c1cb8ab..94001dd8a 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -53,5 +53,5 @@ jobs: # TEMPORARY: expose the full Claude transcript in the Actions log for # debugging. Revert to remove once done. show_full_output: true - claude_args: '--max-turns 20' + claude_args: '--max-turns 50' # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md -- cgit v1.3.1 From b643e8108570b3a8d10dc446ca36954b90ac497a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Jun 2026 21:13:32 +0700 Subject: ci(claude-review): run auto review on Opus (claude-opus-4-8) The review action currently runs on the default Sonnet 4.6. On PR #3643 (musb EP0 race) it posted "No issues found" while an Opus pass on the same diff surfaced substantive questions (ISR-boundary RXRDY lifetime, regression scope of the DATA-state split). Pin the reviewer to claude-opus-4-8 for higher-signal reviews; subagents keep their cheaper default models. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/claude-code-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 94001dd8a..60cc4db4b 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -53,5 +53,5 @@ jobs: # TEMPORARY: expose the full Claude transcript in the Actions log for # debugging. Revert to remove once done. show_full_output: true - claude_args: '--max-turns 50' + claude_args: '--max-turns 50 --model claude-opus-4-8' # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md -- cgit v1.3.1 From d9f736dcf9c6b71aac470d281cd2fc05a3f7e793 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Tue, 16 Jun 2026 17:42:31 +0700 Subject: hil: enable nanoch32v203 in CI with fsdev + usbfs variants (#3707) * hil: enable nanoch32v203 in CI with fsdev + usbfs variants nanoch32v203 was parked in boards-skip; move it into the active pool now that the board is wired to the ci.lan rig. Cover both USB device IPs as build variants: - nanoch32v203-fsdev: RHPORT_DEVICE=0 (USBD / stm32 FSDev IP) - nanoch32v203-usbfs: RHPORT_DEVICE=1 (WCH USBFS IP) --- .github/workflows/build.yml | 1 + test/hil/hil_ci_set_matrix.py | 16 +++++++++++++--- test/hil/hil_test.py | 8 ++++++-- test/hil/tinyusb.json | 33 +++++++++++++++++++-------------- 4 files changed, 39 insertions(+), 19 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a7c7cf99a..3f6458285 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -278,6 +278,7 @@ jobs: matrix: toolchain: - 'arm-gcc' + - 'riscv-gcc' - 'esp-idf' with: build-system: 'cmake' diff --git a/test/hil/hil_ci_set_matrix.py b/test/hil/hil_ci_set_matrix.py index baa24afb1..13f7f1882 100644 --- a/test/hil/hil_ci_set_matrix.py +++ b/test/hil/hil_ci_set_matrix.py @@ -19,8 +19,12 @@ def main(): parser.add_argument('config_files', nargs='+', help='Configuration JSON file(s)') args = parser.parse_args() + # Toolchain buckets must match the toolchains instantiated by the hil-build + # job in .github/workflows/build.yml. Keep all keys present (even if empty) + # so `fromJSON(hil_json)[toolchain]` always resolves to a list. matrix = { 'arm-gcc': [], + 'riscv-gcc': [], 'esp-idf': [] } @@ -38,22 +42,28 @@ def main(): for board in config['boards']: name = board['name'] flasher = board['flasher'] + # esptool boards must build under esp-idf; others default to arm-gcc + # but may opt into another bucket via an explicit "toolchain" field + # (e.g. RISC-V boards like ch32v20x need "riscv-gcc"). if flasher['name'] == 'esptool': toolchain = 'esp-idf' else: - toolchain = 'arm-gcc' + toolchain = board.get('toolchain', 'arm-gcc') build_board = f'-b {name}' if 'build' in board and 'args' in board['build']: build_board += ' ' + ' '.join(f'-D{a}' for a in board['build']['args']) - # Each variant builds into cmake-build- with its raw CFLAGS. - # No 'variant' -> a single build named after the board. + # Each variant builds into cmake-build- with its own cmake + # -D defines and raw CFLAGS. No 'variant' -> a single build named after + # the board. variants = board.get('variant') or [{'name': name, 'flags': ''}] for v in variants: arg = build_board if v['name'] != name: arg += f' --build-name {v["name"]}' + for d in v.get('defines', []): + arg += f' -D{d}' for tok in v.get('flags', '').split(): arg += f' --cflag={tok}' append_build_arg(toolchain, arg) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index da13fcbaf..fb9a8205c 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -126,8 +126,9 @@ class BuildCfg(TypedDict, total=False): class VariantCfg(TypedDict, total=False): - name: str # build dir (cmake-build-) and HIL report row - flags: str # raw CFLAGS, e.g. "-DCFG_TUD_DWC2_DMA_ENABLE=1" + name: str # build dir (cmake-build-) and HIL report row + flags: str # raw CFLAGS, e.g. "-DCFG_TUD_DWC2_DMA_ENABLE=1" + defines: list[str] # cmake -D defines, e.g. ["RHPORT_DEVICE=1"] (vs flags which are compiler-only) class Board(TypedDict): @@ -137,6 +138,7 @@ class Board(TypedDict): flasher: FlasherCfg build: NotRequired[BuildCfg] variant: NotRequired[list[VariantCfg]] + toolchain: NotRequired[str] # CI build bucket override, e.g. "riscv-gcc" (consumed by hil_ci_set_matrix.py) class HilConfig(TypedDict): @@ -1634,6 +1636,8 @@ def build_board(board: Board) -> tuple[str, int]: cmd += ['-D', d] if v['name'] != name: cmd += ['--build-name', v['name']] + for d in v.get('defines', []): + cmd += ['-D', d] for tok in v.get('flags', '').split(): cmd += [f'--cflag={tok}'] if verbose: diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index afe3c4d03..ea9342c03 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -458,6 +458,25 @@ "name": "stlink", "uid": "0668FF575457657187061314" } + }, + { + "name": "nanoch32v203", + "uid": "CDAB277B0FBC03E339E339E3", + "toolchain": "riscv-gcc", + "variant": [ + {"name": "nanoch32v203-fsdev", "defines": ["RHPORT_DEVICE=0"]}, + {"name": "nanoch32v203-usbfs", "defines": ["RHPORT_DEVICE=1"]} + ], + "tests": { + "device": true, + "host": false, + "dual": false + }, + "flasher": { + "name": "openocd_wch", + "uid": "EBCA8F0670AF", + "args": "" + } } ], "boards-skip": [ @@ -478,20 +497,6 @@ "uid": "000778170924", "args": "-device stm32f769ni" } - }, - { - "name": "nanoch32v203", - "uid": "CDAB277B0FBC03E339E339E3", - "tests": { - "device": true, - "host": false, - "dual": false - }, - "flasher": { - "name": "openocd_wch", - "uid": "EBCA8F0670AF", - "args": "" - } } ] } -- cgit v1.3.1 From e7b373ede2dc1ab7322d9687bc5ca87dd156e355 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 18 Jun 2026 19:37:12 +0700 Subject: ci(review): run Claude PR review at max effort Pass --effort max to the claude CLI in the auto-review workflow so PR reviews run at maximum reasoning effort. Switch claude_args to a multi-line block scalar for readability, keeping --max-turns 50 and --model claude-opus-4-8 unchanged. Co-Authored-By: Claude Fable 5 --- .github/workflows/claude-code-review.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 60cc4db4b..59019616f 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -53,5 +53,8 @@ jobs: # TEMPORARY: expose the full Claude transcript in the Actions log for # debugging. Revert to remove once done. show_full_output: true - claude_args: '--max-turns 50 --model claude-opus-4-8' + claude_args: | + --max-turns 50 + --model claude-opus-4-8 + --effort max # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md -- cgit v1.3.1 From eda704ca1acef9691b51e17026765f497b1fffbe Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Jun 2026 15:23:08 +0700 Subject: hw/bsp+wch: rename the CH58x family to ch583 and OPT_MCU_CH58X to OPT_MCU_CH583 The BSP family and MCU option were named "ch58x"/"CH58X", but the supported part is the CH583/CH582 (and the SDK repo is openwch/ch583); CH585 is a separate MCU family, so the CH58x umbrella was misleading. Rename to the specific family: - hw/bsp/ch58x -> hw/bsp/ch583 (dir), and the BSP-local files ch58x_it.* -> ch583_it.*, system_ch58x.* -> system_ch583.* (include guards/refs updated). The vendor SDK files (CH58x_common.h, CH58x_*.c in hw/mcu/wch/ch583) keep their names. - OPT_MCU_CH58X -> OPT_MCU_CH583 in tusb_option.h, tusb_mcu.h, and the shared WCH USBFS driver (ch32_usbfs_reg.h, dcd_ch32_usbfs.c). OPT_MCU_CH582 is kept as an alias (same value), so either name selects the same code. - FAMILY_MCUS CH58X -> CH583, CFG_TUSB_MCU=OPT_MCU_CH583, mcu:CH58X -> mcu:CH583 in the example skip lists, the CI build matrix (ci_set_matrix.py), the get_deps family tag, and docs/reference/boards.rst. Board names (ch582m_evt, yd-ch582m) are unchanged. Verified: make + cmake build for ch582m_evt, and ci.lan HIL (all device examples pass). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci_set_matrix.py | 2 +- docs/reference/boards.rst | 2 +- examples/device/audio_4_channel_mic/skip.txt | 2 +- .../device/audio_4_channel_mic_freertos/skip.txt | 2 +- examples/device/audio_test/skip.txt | 2 +- examples/device/audio_test_freertos/skip.txt | 2 +- examples/device/audio_test_multi_rate/skip.txt | 2 +- examples/device/cdc_msc_freertos/skip.txt | 2 +- examples/device/cdc_uac2/skip.txt | 2 +- examples/device/dfu_runtime/skip.txt | 1 + examples/device/hid_boot_interface/skip.txt | 1 + examples/device/hid_composite/skip.txt | 1 + examples/device/hid_composite_freertos/skip.txt | 2 +- examples/device/hid_generic_inout/skip.txt | 1 + examples/device/hid_multiple_interface/skip.txt | 1 + examples/device/midi_test/skip.txt | 1 + examples/device/midi_test_freertos/skip.txt | 2 +- examples/device/uac2_headset/skip.txt | 2 +- examples/device/uac2_speaker_fb/skip.txt | 2 +- examples/device/video_capture/skip.txt | 2 +- examples/device/video_capture_2ch/skip.txt | 2 +- examples/device/webusb_serial/skip.txt | 1 + hw/bsp/ch583/boards/ch582m_evt/board.cmake | 5 + hw/bsp/ch583/boards/ch582m_evt/board.h | 61 +++++++ hw/bsp/ch583/boards/ch582m_evt/board.mk | 3 + hw/bsp/ch583/boards/yd-ch582m/board.cmake | 5 + hw/bsp/ch583/boards/yd-ch582m/board.h | 61 +++++++ hw/bsp/ch583/boards/yd-ch582m/board.mk | 3 + hw/bsp/ch583/ch583_it.c | 37 ++++ hw/bsp/ch583/ch583_it.h | 46 +++++ hw/bsp/ch583/debug_uart.c | 86 +++++++++ hw/bsp/ch583/debug_uart.h | 44 +++++ hw/bsp/ch583/family.c | 194 +++++++++++++++++++++ hw/bsp/ch583/family.cmake | 108 ++++++++++++ hw/bsp/ch583/family.mk | 59 +++++++ hw/bsp/ch583/linker/ch582.ld | 167 ++++++++++++++++++ hw/bsp/ch583/system_ch583.c | 39 +++++ hw/bsp/ch583/system_ch583.h | 43 +++++ hw/bsp/ch583/wch-riscv.cfg | 17 ++ hw/bsp/ch58x/boards/ch582m_evt/board.cmake | 5 - hw/bsp/ch58x/boards/ch582m_evt/board.h | 61 ------- hw/bsp/ch58x/boards/ch582m_evt/board.mk | 3 - hw/bsp/ch58x/boards/yd-ch582m/board.cmake | 5 - hw/bsp/ch58x/boards/yd-ch582m/board.h | 61 ------- hw/bsp/ch58x/boards/yd-ch582m/board.mk | 3 - hw/bsp/ch58x/ch58x_it.c | 37 ---- hw/bsp/ch58x/ch58x_it.h | 46 ----- hw/bsp/ch58x/debug_uart.c | 86 --------- hw/bsp/ch58x/debug_uart.h | 44 ----- hw/bsp/ch58x/family.c | 194 --------------------- hw/bsp/ch58x/family.cmake | 108 ------------ hw/bsp/ch58x/family.mk | 59 ------- hw/bsp/ch58x/linker/ch582.ld | 167 ------------------ hw/bsp/ch58x/system_ch58x.c | 39 ----- hw/bsp/ch58x/system_ch58x.h | 43 ----- hw/bsp/ch58x/wch-riscv.cfg | 17 -- src/common/tusb_mcu.h | 2 +- src/portable/wch/ch32_usbfs_reg.h | 2 +- src/portable/wch/dcd_ch32_usbfs.c | 16 +- src/tusb_option.h | 2 +- tools/get_deps.py | 2 +- 61 files changed, 1012 insertions(+), 1005 deletions(-) create mode 100644 examples/device/dfu_runtime/skip.txt create mode 100644 examples/device/hid_boot_interface/skip.txt create mode 100644 examples/device/hid_composite/skip.txt create mode 100644 examples/device/hid_generic_inout/skip.txt create mode 100644 examples/device/hid_multiple_interface/skip.txt create mode 100644 examples/device/midi_test/skip.txt create mode 100644 examples/device/webusb_serial/skip.txt create mode 100644 hw/bsp/ch583/boards/ch582m_evt/board.cmake create mode 100644 hw/bsp/ch583/boards/ch582m_evt/board.h create mode 100644 hw/bsp/ch583/boards/ch582m_evt/board.mk create mode 100644 hw/bsp/ch583/boards/yd-ch582m/board.cmake create mode 100644 hw/bsp/ch583/boards/yd-ch582m/board.h create mode 100644 hw/bsp/ch583/boards/yd-ch582m/board.mk create mode 100644 hw/bsp/ch583/ch583_it.c create mode 100644 hw/bsp/ch583/ch583_it.h create mode 100644 hw/bsp/ch583/debug_uart.c create mode 100644 hw/bsp/ch583/debug_uart.h create mode 100644 hw/bsp/ch583/family.c create mode 100644 hw/bsp/ch583/family.cmake create mode 100644 hw/bsp/ch583/family.mk create mode 100644 hw/bsp/ch583/linker/ch582.ld create mode 100644 hw/bsp/ch583/system_ch583.c create mode 100644 hw/bsp/ch583/system_ch583.h create mode 100644 hw/bsp/ch583/wch-riscv.cfg delete mode 100644 hw/bsp/ch58x/boards/ch582m_evt/board.cmake delete mode 100644 hw/bsp/ch58x/boards/ch582m_evt/board.h delete mode 100644 hw/bsp/ch58x/boards/ch582m_evt/board.mk delete mode 100644 hw/bsp/ch58x/boards/yd-ch582m/board.cmake delete mode 100644 hw/bsp/ch58x/boards/yd-ch582m/board.h delete mode 100644 hw/bsp/ch58x/boards/yd-ch582m/board.mk delete mode 100644 hw/bsp/ch58x/ch58x_it.c delete mode 100644 hw/bsp/ch58x/ch58x_it.h delete mode 100644 hw/bsp/ch58x/debug_uart.c delete mode 100644 hw/bsp/ch58x/debug_uart.h delete mode 100644 hw/bsp/ch58x/family.c delete mode 100644 hw/bsp/ch58x/family.cmake delete mode 100644 hw/bsp/ch58x/family.mk delete mode 100644 hw/bsp/ch58x/linker/ch582.ld delete mode 100644 hw/bsp/ch58x/system_ch58x.c delete mode 100644 hw/bsp/ch58x/system_ch58x.h delete mode 100644 hw/bsp/ch58x/wch-riscv.cfg (limited to '.github/workflows') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 400f319d3..dc0d3871f 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -30,7 +30,7 @@ family_list = { "ch32v10x": ["riscv-gcc"], "ch32v20x": ["riscv-gcc"], "ch32v30x": ["riscv-gcc"], - "ch58x": ["riscv-gcc"], + "ch583": ["riscv-gcc"], "da1469x": ["arm-gcc"], "fomu": ["riscv-gcc"], "ft9xx": ["ft9xx-gcc"], diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index 7ea9c228b..8a83496a4 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -370,5 +370,5 @@ ch32v203g_r0_1v0 CH32V203G-R0-1v0 ch32v20x https://github.com/openwch/ch32v20 nanoch32v203 nanoCH32V203 ch32v20x https://github.com/wuxx/nanoCH32V203 ch32v307v_r1_1v0 CH32V307V-R1-1v0 ch32v30x https://github.com/openwch/ch32v307/tree/main/SCHPCB/CH32V307V-R1-1v0 nanoch32v305 nanoCH32V305 ch32v30x https://github.com/wuxx/nanoCH32V305 -yd-ch582m yd-ch582m ch58x http://vcc-gnd.com +yd-ch582m yd-ch582m ch583 http://vcc-gnd.com ================ ================ ======== ===================================================================== ====== diff --git a/examples/device/audio_4_channel_mic/skip.txt b/examples/device/audio_4_channel_mic/skip.txt index 8c64832f7..3ca433c08 100644 --- a/examples/device/audio_4_channel_mic/skip.txt +++ b/examples/device/audio_4_channel_mic/skip.txt @@ -3,4 +3,4 @@ mcu:SAME5X mcu:SAMG family:broadcom_64bit family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index dae0a5428..1fd6b4b8a 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/audio_test/skip.txt b/examples/device/audio_test/skip.txt index 6e3082a54..42394bb11 100644 --- a/examples/device/audio_test/skip.txt +++ b/examples/device/audio_test/skip.txt @@ -2,4 +2,4 @@ mcu:SAMD11 mcu:SAME5X mcu:SAMG family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index 20deaca28..660bacd25 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/audio_test_multi_rate/skip.txt b/examples/device/audio_test_multi_rate/skip.txt index 6e3082a54..42394bb11 100644 --- a/examples/device/audio_test_multi_rate/skip.txt +++ b/examples/device/audio_test_multi_rate/skip.txt @@ -2,4 +2,4 @@ mcu:SAMD11 mcu:SAME5X mcu:SAMG family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index 197060eeb..48781de84 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/cdc_uac2/skip.txt b/examples/device/cdc_uac2/skip.txt index 4222d08c6..db1d5b80b 100644 --- a/examples/device/cdc_uac2/skip.txt +++ b/examples/device/cdc_uac2/skip.txt @@ -6,4 +6,4 @@ mcu:SAME5X mcu:SAMG board:stm32l052dap52 family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/dfu_runtime/skip.txt b/examples/device/dfu_runtime/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/dfu_runtime/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/hid_boot_interface/skip.txt b/examples/device/hid_boot_interface/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/hid_boot_interface/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/hid_composite/skip.txt b/examples/device/hid_composite/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/hid_composite/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt index fccddabcd..97d8e168b 100644 --- a/examples/device/hid_composite_freertos/skip.txt +++ b/examples/device/hid_composite_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/hid_generic_inout/skip.txt b/examples/device/hid_generic_inout/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/hid_generic_inout/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/hid_multiple_interface/skip.txt b/examples/device/hid_multiple_interface/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/hid_multiple_interface/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/midi_test/skip.txt b/examples/device/midi_test/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/midi_test/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/midi_test_freertos/skip.txt b/examples/device/midi_test_freertos/skip.txt index fccddabcd..97d8e168b 100644 --- a/examples/device/midi_test_freertos/skip.txt +++ b/examples/device/midi_test_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/uac2_headset/skip.txt b/examples/device/uac2_headset/skip.txt index 4222d08c6..db1d5b80b 100644 --- a/examples/device/uac2_headset/skip.txt +++ b/examples/device/uac2_headset/skip.txt @@ -6,4 +6,4 @@ mcu:SAME5X mcu:SAMG board:stm32l052dap52 family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/uac2_speaker_fb/skip.txt b/examples/device/uac2_speaker_fb/skip.txt index 48a484f96..0c7339c65 100644 --- a/examples/device/uac2_speaker_fb/skip.txt +++ b/examples/device/uac2_speaker_fb/skip.txt @@ -6,4 +6,4 @@ mcu:SAME5X mcu:SAMG board:stm32l052dap52 family:broadcom_64bit -mcu:CH58X +mcu:CH583 diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt index 7f000d472..5a7a1d00e 100644 --- a/examples/device/video_capture/skip.txt +++ b/examples/device/video_capture/skip.txt @@ -1,6 +1,6 @@ mcu:CH32V103 mcu:CH32V20X -mcu:CH58X +mcu:CH583 mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index 191edeb39..c37205b8c 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -5,7 +5,7 @@ mcu:GD32VF103 mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:STM32L0 family:espressif board:curiosity_nano diff --git a/examples/device/webusb_serial/skip.txt b/examples/device/webusb_serial/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/webusb_serial/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/hw/bsp/ch583/boards/ch582m_evt/board.cmake b/hw/bsp/ch583/boards/ch582m_evt/board.cmake new file mode 100644 index 000000000..4129c4550 --- /dev/null +++ b/hw/bsp/ch583/boards/ch582m_evt/board.cmake @@ -0,0 +1,5 @@ +set(LD_FLASH_SIZE 448K) +set(LD_RAM_SIZE 32K) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/ch583/boards/ch582m_evt/board.h b/hw/bsp/ch583/boards/ch582m_evt/board.h new file mode 100644 index 000000000..c3483bf17 --- /dev/null +++ b/hw/bsp/ch583/boards/ch582m_evt/board.h @@ -0,0 +1,61 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* metadata: + name: CH582M-EVT evaluation board + url: https://www.wch-ic.com/products/CH582.html +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// LED: PB4 on CH582M-EVT +#define LED_PIN GPIO_Pin_4 +#define LED_STATE_ON 0 + +// Directly reuse BOOT pin as user button +#define BUTTON_PIN GPIO_Pin_22 +#define BUTTON_STATE_ACTIVE 0 + +// UART: UART1 TX=PA9, RX=PA8 +#define CFG_BOARD_UART_BAUDRATE 115200 + +// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd; +// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later. +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif +// #ifndef BOARD_TUH_RHPORT +// #define BOARD_TUH_RHPORT 1 +// #endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch583/boards/ch582m_evt/board.mk b/hw/bsp/ch583/boards/ch582m_evt/board.mk new file mode 100644 index 000000000..a13979799 --- /dev/null +++ b/hw/bsp/ch583/boards/ch582m_evt/board.mk @@ -0,0 +1,3 @@ +LDFLAGS += \ + -Wl,--defsym=__FLASH_SIZE=448K \ + -Wl,--defsym=__RAM_SIZE=32K \ diff --git a/hw/bsp/ch583/boards/yd-ch582m/board.cmake b/hw/bsp/ch583/boards/yd-ch582m/board.cmake new file mode 100644 index 000000000..4129c4550 --- /dev/null +++ b/hw/bsp/ch583/boards/yd-ch582m/board.cmake @@ -0,0 +1,5 @@ +set(LD_FLASH_SIZE 448K) +set(LD_RAM_SIZE 32K) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/ch583/boards/yd-ch582m/board.h b/hw/bsp/ch583/boards/yd-ch582m/board.h new file mode 100644 index 000000000..0da5747bc --- /dev/null +++ b/hw/bsp/ch583/boards/yd-ch582m/board.h @@ -0,0 +1,61 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* metadata: + name: yd-ch582m from vcc-gnd studio + url: http://vcc-gnd.com/ +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// LED: PB4 on yd-ch582m board +#define LED_PIN GPIO_Pin_4 +#define LED_STATE_ON 0 + +// Directly reuse BOOT pin as user button +#define BUTTON_PIN GPIO_Pin_22 +#define BUTTON_STATE_ACTIVE 0 + +// UART: UART1 TX=PA9, RX=PA8 +#define CFG_BOARD_UART_BAUDRATE 115200 + +// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd; +// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later. +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif +// #ifndef BOARD_TUH_RHPORT +// #define BOARD_TUH_RHPORT 1 +// #endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch583/boards/yd-ch582m/board.mk b/hw/bsp/ch583/boards/yd-ch582m/board.mk new file mode 100644 index 000000000..a13979799 --- /dev/null +++ b/hw/bsp/ch583/boards/yd-ch582m/board.mk @@ -0,0 +1,3 @@ +LDFLAGS += \ + -Wl,--defsym=__FLASH_SIZE=448K \ + -Wl,--defsym=__RAM_SIZE=32K \ diff --git a/hw/bsp/ch583/ch583_it.c b/hw/bsp/ch583/ch583_it.c new file mode 100644 index 000000000..8479c537a --- /dev/null +++ b/hw/bsp/ch583/ch583_it.c @@ -0,0 +1,37 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "ch583_it.h" + +// NMI exception handler +__INTERRUPT __HIGH_CODE void NMI_Handler(void) { + while (1) {} +} + +// Hard Fault exception handler +__INTERRUPT __HIGH_CODE void HardFault_Handler(void) { + while (1) {} +} diff --git a/hw/bsp/ch583/ch583_it.h b/hw/bsp/ch583/ch583_it.h new file mode 100644 index 000000000..29d175403 --- /dev/null +++ b/hw/bsp/ch583/ch583_it.h @@ -0,0 +1,46 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef CH583_IT_H_ +#define CH583_IT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "CH58x_common.h" + +void NMI_Handler(void); +void HardFault_Handler(void); +void USB_IRQHandler(void); +// void USB2_IRQHandler(void); // host on USB2 (rhport 1) — re-add together with the host driver +void SysTick_Handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* CH583_IT_H_ */ diff --git a/hw/bsp/ch583/debug_uart.c b/hw/bsp/ch583/debug_uart.c new file mode 100644 index 000000000..850e40718 --- /dev/null +++ b/hw/bsp/ch583/debug_uart.c @@ -0,0 +1,86 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "debug_uart.h" +#include "CH58x_common.h" + +//--------------------------------------------------------------------+ +// Ring buffer based UART TX for non-blocking writes +//--------------------------------------------------------------------+ + +#define UART_RINGBUFFER_SIZE_TX 128 +#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX - 1) + +static char tx_buf[UART_RINGBUFFER_SIZE_TX]; +static uint32_t tx_produce; +static volatile uint32_t tx_consume; + +void uart_write(char c) { + uint32_t tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; + + // If the ring buffer is full, drain it here as the FIFO frees up: nothing else advances + // tx_consume between uart_write() calls, so a plain spin would deadlock on a >buffer-size burst. + while (tx_produce_next == tx_consume) { + if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) { + R8_UART1_THR = tx_buf[tx_consume]; + tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; + } + } + + // If UART TX FIFO is empty and no pending data, send directly + if ((tx_consume == tx_produce) && (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP)) { + R8_UART1_THR = c; + } else { + tx_buf[tx_produce] = c; + tx_produce = tx_produce_next; + } +} + +void uart_sync(void) { + // Wait for ring buffer to drain + while (tx_consume != tx_produce) { + if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) { + R8_UART1_THR = tx_buf[tx_consume]; + tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; + } + } + // Wait for last byte to finish transmitting + while (!(R8_UART1_LSR & RB_LSR_TX_ALL_EMP)) {} +} + +void usart_printf_init(uint32_t baudrate) { + tx_produce = 0; + tx_consume = 0; + + // Configure UART1 pins: TX=PA9, RX=PA8 + GPIOA_SetBits(GPIO_Pin_9); + GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); + GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); + + // Init UART1 with specified baud rate + UART1_DefInit(); + UART1_BaudRateCfg(baudrate); +} diff --git a/hw/bsp/ch583/debug_uart.h b/hw/bsp/ch583/debug_uart.h new file mode 100644 index 000000000..44c3e7948 --- /dev/null +++ b/hw/bsp/ch583/debug_uart.h @@ -0,0 +1,44 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef DEBUG_UART_H_ +#define DEBUG_UART_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void uart_write(char c); +void uart_sync(void); +void usart_printf_init(uint32_t baudrate); + +#ifdef __cplusplus +} +#endif + +#endif /* DEBUG_UART_H_ */ diff --git a/hw/bsp/ch583/family.c b/hw/bsp/ch583/family.c new file mode 100644 index 000000000..716e2b76b --- /dev/null +++ b/hw/bsp/ch583/family.c @@ -0,0 +1,194 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +/* metadata: + manufacturer: WCH +*/ + +// WCH SDK's DEBUG macro enables a _write() that conflicts with TinyUSB's. +// TinyUSB uses UART1 for printf via debug_uart.c, so DEBUG is not needed. +// If you need a different UART or want to keep SDK's DEBUG, modify +// debug_uart.c (TinyUSB side) or CH58x_sys.c (SDK side) to remove one _write(). +// If done, remove this #error to continue. +#ifdef DEBUG + #error "Remove the DEBUG macro from preprocessor defines to avoid " \ + "duplicate _write() between WCH SDK and TinyUSB. " \ + "TinyUSB uses UART1 by default (see debug_uart.c)." +#endif + +#include "debug_uart.h" +#include "CH58x_common.h" +#include "ch583_it.h" + +#include "bsp/board_api.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ + +// Device only: the shared dcd_ch32_usbfs.c drives USB0 (rhport 0). CH58x's second controller +// (USB2 / rhport 1) was driven by the now-removed ch58x host driver; its handler is kept +// commented out below to ease re-adding host support. +__INTERRUPT __HIGH_CODE void USB_IRQHandler(void) { + tusb_int_handler(0, true); +} + +// __INTERRUPT __HIGH_CODE void USB2_IRQHandler(void) { +// tusb_int_handler(1, true); +// } + +//--------------------------------------------------------------------+ +// SysTick +//--------------------------------------------------------------------+ + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +__INTERRUPT __HIGH_CODE void SysTick_Handler(void) { + SysTick->SR = 0; + system_ticks++; +} + +uint32_t tusb_time_millis_api(void) { + return system_ticks; +} +#endif + +//--------------------------------------------------------------------+ +// Board Init +//--------------------------------------------------------------------+ + +void board_init(void) { + // Disable interrupts during init + PFIC_DisableAllIRQ(); + + // Set system clock to PLL 60MHz (default for CH582) + SetSysClock(CLK_SOURCE_PLL_60MHz); + +#if CFG_TUSB_OS == OPT_OS_NONE + SysTick_Config(GetSysClock() / 1000); +#endif + + // UART1 init for debug output +#ifdef CFG_BOARD_UART_BAUDRATE + usart_printf_init(CFG_BOARD_UART_BAUDRATE); +#endif + + // LED +#ifdef LED_PORT_IS_A + GPIOA_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA); +#else + GPIOB_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA); +#endif + + // Button +#ifdef BUTTON_PIN + #ifdef BUTTON_PORT_IS_A + GPIOA_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU); + #else + GPIOB_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU); + #endif +#endif + + // Device only on USB0 (rhport 0): enable analog function for USB1 D+/D- and assert its D+ + // pull-up. The shared dcd_ch32_usbfs.c drives USB0; CH58x host / USB2 (rhport 1) is unsupported + // here — to re-add host, also OR in RB_PIN_USB2_IE below. + R16_PIN_ANALOG_IE |= RB_PIN_USB_IE; // | RB_PIN_USB2_IE (re-add for host on USB2) +#if CFG_TUD_ENABLED + R16_PIN_ANALOG_IE |= RB_PIN_USB_DP_PU; +#endif + + // Keep USB clock active during sleep + R8_SLP_CLK_OFF1 &= ~RB_SLP_CLK_USB; + + // Enable interrupts globally + PFIC_EnableAllIRQ(); + + board_delay(2); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { +#ifdef LED_PORT_IS_A + if (state ^ LED_STATE_ON) { + GPIOA_ResetBits(LED_PIN); + } else { + GPIOA_SetBits(LED_PIN); + } +#else + if (state ^ LED_STATE_ON) { + GPIOB_ResetBits(LED_PIN); + } else { + GPIOB_SetBits(LED_PIN); + } +#endif +} + +uint32_t board_button_read(void) { +#ifdef BUTTON_PIN + #ifdef BUTTON_PORT_IS_A + return BUTTON_STATE_ACTIVE == (GPIOA_ReadPortPin(BUTTON_PIN) ? 1 : 0); + #else + return BUTTON_STATE_ACTIVE == (GPIOB_ReadPortPin(BUTTON_PIN) ? 1 : 0); + #endif +#else + return 0; +#endif +} + +// CH58x has no memory-mapped unique-ID register (unlike ch32v10x/v20x at 0x1FFFF7E8), but the +// factory programs a unique 6-byte MAC address into FlashROM (it is a BLE part). GetMACAddress() +// reads it via the ISP ROM command FLASH_EEPROM_CMD, which is provided by libISP583.a. +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + // FLASH_EEPROM_CMD writes word-granular and requires a 4-byte-aligned buffer (CH58x_flash.c); + // size 8 matches the SDK's GET_UNIQUE_ID buffer (6 MAC bytes + 2 it pads), so the read can't + // run past the end whether it returns 6 or a full 8. + TU_ATTR_ALIGNED(4) uint8_t mac[8]; + GetMACAddress(mac); + size_t len = TU_MIN(max_len, (size_t) 6); // the 6-byte MAC is the unique part + memcpy(id, mac, len); + return len; +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + int txsize = len; + const char* bufc = (const char*) buf; + while (txsize--) { + uart_write(*bufc++); + } + uart_sync(); + return len; +} diff --git a/hw/bsp/ch583/family.cmake b/hw/bsp/ch583/family.cmake new file mode 100644 index 000000000..a379298e5 --- /dev/null +++ b/hw/bsp/ch583/family.cmake @@ -0,0 +1,108 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/wch/ch583) +set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH583 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") + +#------------------------------------ +# Startup & Linker script +#------------------------------------ +if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/ch582.ld) +endif () +set(LD_FILE_Clang ${LD_FILE_GNU}) +if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_CH583.S) +endif () +set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + +#------------------------------------ +# Board Target +#------------------------------------ +function(family_add_board BOARD_TARGET) + add_library(${BOARD_TARGET} STATIC + ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_gpio.c + ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_clk.c + ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_uart1.c + ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_sys.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch583_it.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch583.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/RVMSIS + ${SDK_SRC_DIR}/StdPeriphDriver/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_link_libraries(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/StdPeriphDriver/libISP583.a + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_USBFS=1 + FREQ_SYS=60000000 + DISK_LIB_ENABLE=0 + INT_SOFT + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -flto + -msmall-data-limit=16 + -mno-save-restore + -fmessage-length=0 + -fsigned-char + -Wno-error=strict-prototypes + ) + endif () +endfunction() + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + family_add_tinyusb(${TARGET} OPT_MCU_CH583) + + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug_uart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${TARGET} PUBLIC + -nostartfiles + --specs=nosys.specs --specs=nano.specs + -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE} + -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE} + "LINKER:--script=${LD_FILE_GNU}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for CH58x") + endif () + + set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES + SKIP_LINTING ON + COMPILE_OPTIONS -w) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) +endfunction() diff --git a/hw/bsp/ch583/family.mk b/hw/bsp/ch583/family.mk new file mode 100644 index 000000000..98d0f9337 --- /dev/null +++ b/hw/bsp/ch583/family.mk @@ -0,0 +1,59 @@ +# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable +#CROSS_COMPILE ?= riscv32-unknown-elf- + +# Toolchain from https://nucleisys.com/download.php +#CROSS_COMPILE ?= riscv-nuclei-elf- + +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +CROSS_COMPILE ?= riscv-none-elf- + +SDK_DIR = hw/mcu/wch/ch583 +SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 + +CFLAGS += \ + -flto \ + -msmall-data-limit=16 \ + -mno-save-restore \ + -fmessage-length=0 \ + -fsigned-char \ + -DCFG_TUSB_MCU=OPT_MCU_CH583 \ + -DCFG_TUD_WCH_USBIP_USBFS=1 \ + -DFREQ_SYS=60000000 \ + -DDISK_LIB_ENABLE=0 \ + -DINT_SOFT \ + -Wno-error=strict-prototypes + +LDFLAGS += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + +LIBS += $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/libISP583.a + +SRC_C += \ + src/portable/wch/dcd_ch32_usbfs.c \ + $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_gpio.c \ + $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_clk.c \ + $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_uart1.c \ + $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_sys.c \ + $(FAMILY_PATH)/debug_uart.c \ + $(FAMILY_PATH)/ch583_it.c \ + $(FAMILY_PATH)/system_ch583.c + +SRC_S += \ + $(SDK_SRC_DIR)/Startup/startup_CH583.S + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/RVMSIS \ + $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/inc + +LD_FILE ?= $(FAMILY_PATH)/linker/ch582.ld + +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/hw/bsp/ch583/linker/ch582.ld b/hw/bsp/ch583/linker/ch582.ld new file mode 100644 index 000000000..821998a49 --- /dev/null +++ b/hw/bsp/ch583/linker/ch582.ld @@ -0,0 +1,167 @@ +/* CH582 Linker Script for TinyUSB + * Based on WCH CH583 SDK Link.ld + * Supports parameterized flash/ram sizes via --defsym + */ + +/* Default sizes if not provided via --defsym */ +__flash_size = DEFINED(__FLASH_SIZE) ? __FLASH_SIZE : 448K; +__ram_size = DEFINED(__RAM_SIZE) ? __RAM_SIZE : 32K; +__stack_size = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2048; + +ENTRY( _start ) + +PROVIDE( _stack_size = __stack_size ); + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_size + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __ram_size +} + +SECTIONS +{ + .init : + { + _sinit = .; + . = ALIGN(4); + KEEP(*(SORT_NONE(.init))) + . = ALIGN(4); + _einit = .; + } >FLASH AT>FLASH + + .highcodelalign : + { + . = ALIGN(4); + PROVIDE(_highcode_lma = .); + } >FLASH AT>FLASH + + .highcode : + { + . = ALIGN(4); + PROVIDE(_highcode_vma_start = .); + *(.vector); + KEEP(*(SORT_NONE(.vector_handler))) + *(.highcode); + *(.highcode.*); + . = ALIGN(4); + PROVIDE(_highcode_vma_end = .); + } >RAM AT>FLASH + + .text : + { + . = ALIGN(4); + KEEP(*(SORT_NONE(.handle_reset))) + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.sdata2.*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH + + .fini : + { + KEEP(*(SORT_NONE(.fini))) + . = ALIGN(4); + } >FLASH AT>FLASH + + PROVIDE( _etext = . ); + PROVIDE( _eitcm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH AT>FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH AT>FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH AT>FLASH + + .ctors : + { + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >FLASH AT>FLASH + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >FLASH AT>FLASH + + .dlalign : + { + . = ALIGN(4); + PROVIDE(_data_lma = .); + } >FLASH AT>FLASH + + .data : + { + . = ALIGN(4); + PROVIDE(_data_vma = .); + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM AT>FLASH + + .bss : + { + . = ALIGN(4); + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM AT>FLASH + + PROVIDE( _end = _ebss); + PROVIDE( end = . ); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = ALIGN(4); + PROVIDE(_susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + __freertos_irq_stack_top = .; + } >RAM +} diff --git a/hw/bsp/ch583/system_ch583.c b/hw/bsp/ch583/system_ch583.c new file mode 100644 index 000000000..d3724f0ce --- /dev/null +++ b/hw/bsp/ch583/system_ch583.c @@ -0,0 +1,39 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "CH58x_common.h" +#include "system_ch583.h" + +uint32_t SystemCoreClock = FREQ_SYS; + +void SystemInit(void) { + SetSysClock(CLK_SOURCE_PLL_60MHz); + SystemCoreClock = GetSysClock(); +} + +void SystemCoreClockUpdate(void) { + SystemCoreClock = GetSysClock(); +} diff --git a/hw/bsp/ch583/system_ch583.h b/hw/bsp/ch583/system_ch583.h new file mode 100644 index 000000000..c174c9f5e --- /dev/null +++ b/hw/bsp/ch583/system_ch583.h @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef SYSTEM_CH583_H_ +#define SYSTEM_CH583_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock) + +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_CH583_H_ */ diff --git a/hw/bsp/ch583/wch-riscv.cfg b/hw/bsp/ch583/wch-riscv.cfg new file mode 100644 index 000000000..64d595d8e --- /dev/null +++ b/hw/bsp/ch583/wch-riscv.cfg @@ -0,0 +1,17 @@ +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 0x8000 -work-area-backup 1 +set _FLASHNAME $_CHIPNAME.flash + +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 + +echo "Ready for Remote Connections" diff --git a/hw/bsp/ch58x/boards/ch582m_evt/board.cmake b/hw/bsp/ch58x/boards/ch582m_evt/board.cmake deleted file mode 100644 index 4129c4550..000000000 --- a/hw/bsp/ch58x/boards/ch582m_evt/board.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(LD_FLASH_SIZE 448K) -set(LD_RAM_SIZE 32K) - -function(update_board TARGET) -endfunction() diff --git a/hw/bsp/ch58x/boards/ch582m_evt/board.h b/hw/bsp/ch58x/boards/ch582m_evt/board.h deleted file mode 100644 index c3483bf17..000000000 --- a/hw/bsp/ch58x/boards/ch582m_evt/board.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* metadata: - name: CH582M-EVT evaluation board - url: https://www.wch-ic.com/products/CH582.html -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// LED: PB4 on CH582M-EVT -#define LED_PIN GPIO_Pin_4 -#define LED_STATE_ON 0 - -// Directly reuse BOOT pin as user button -#define BUTTON_PIN GPIO_Pin_22 -#define BUTTON_STATE_ACTIVE 0 - -// UART: UART1 TX=PA9, RX=PA8 -#define CFG_BOARD_UART_BAUDRATE 115200 - -// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd; -// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later. -#ifndef BOARD_TUD_RHPORT -#define BOARD_TUD_RHPORT 0 -#endif -// #ifndef BOARD_TUH_RHPORT -// #define BOARD_TUH_RHPORT 1 -// #endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hw/bsp/ch58x/boards/ch582m_evt/board.mk b/hw/bsp/ch58x/boards/ch582m_evt/board.mk deleted file mode 100644 index a13979799..000000000 --- a/hw/bsp/ch58x/boards/ch582m_evt/board.mk +++ /dev/null @@ -1,3 +0,0 @@ -LDFLAGS += \ - -Wl,--defsym=__FLASH_SIZE=448K \ - -Wl,--defsym=__RAM_SIZE=32K \ diff --git a/hw/bsp/ch58x/boards/yd-ch582m/board.cmake b/hw/bsp/ch58x/boards/yd-ch582m/board.cmake deleted file mode 100644 index 4129c4550..000000000 --- a/hw/bsp/ch58x/boards/yd-ch582m/board.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(LD_FLASH_SIZE 448K) -set(LD_RAM_SIZE 32K) - -function(update_board TARGET) -endfunction() diff --git a/hw/bsp/ch58x/boards/yd-ch582m/board.h b/hw/bsp/ch58x/boards/yd-ch582m/board.h deleted file mode 100644 index 0da5747bc..000000000 --- a/hw/bsp/ch58x/boards/yd-ch582m/board.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* metadata: - name: yd-ch582m from vcc-gnd studio - url: http://vcc-gnd.com/ -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// LED: PB4 on yd-ch582m board -#define LED_PIN GPIO_Pin_4 -#define LED_STATE_ON 0 - -// Directly reuse BOOT pin as user button -#define BUTTON_PIN GPIO_Pin_22 -#define BUTTON_STATE_ACTIVE 0 - -// UART: UART1 TX=PA9, RX=PA8 -#define CFG_BOARD_UART_BAUDRATE 115200 - -// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd; -// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later. -#ifndef BOARD_TUD_RHPORT -#define BOARD_TUD_RHPORT 0 -#endif -// #ifndef BOARD_TUH_RHPORT -// #define BOARD_TUH_RHPORT 1 -// #endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hw/bsp/ch58x/boards/yd-ch582m/board.mk b/hw/bsp/ch58x/boards/yd-ch582m/board.mk deleted file mode 100644 index a13979799..000000000 --- a/hw/bsp/ch58x/boards/yd-ch582m/board.mk +++ /dev/null @@ -1,3 +0,0 @@ -LDFLAGS += \ - -Wl,--defsym=__FLASH_SIZE=448K \ - -Wl,--defsym=__RAM_SIZE=32K \ diff --git a/hw/bsp/ch58x/ch58x_it.c b/hw/bsp/ch58x/ch58x_it.c deleted file mode 100644 index 2211e1eda..000000000 --- a/hw/bsp/ch58x/ch58x_it.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "ch58x_it.h" - -// NMI exception handler -__INTERRUPT __HIGH_CODE void NMI_Handler(void) { - while (1) {} -} - -// Hard Fault exception handler -__INTERRUPT __HIGH_CODE void HardFault_Handler(void) { - while (1) {} -} diff --git a/hw/bsp/ch58x/ch58x_it.h b/hw/bsp/ch58x/ch58x_it.h deleted file mode 100644 index 3e050344d..000000000 --- a/hw/bsp/ch58x/ch58x_it.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef CH58X_IT_H_ -#define CH58X_IT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "CH58x_common.h" - -void NMI_Handler(void); -void HardFault_Handler(void); -void USB_IRQHandler(void); -// void USB2_IRQHandler(void); // host on USB2 (rhport 1) — re-add together with the host driver -void SysTick_Handler(void); - -#ifdef __cplusplus -} -#endif - -#endif /* CH58X_IT_H_ */ diff --git a/hw/bsp/ch58x/debug_uart.c b/hw/bsp/ch58x/debug_uart.c deleted file mode 100644 index 850e40718..000000000 --- a/hw/bsp/ch58x/debug_uart.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "debug_uart.h" -#include "CH58x_common.h" - -//--------------------------------------------------------------------+ -// Ring buffer based UART TX for non-blocking writes -//--------------------------------------------------------------------+ - -#define UART_RINGBUFFER_SIZE_TX 128 -#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX - 1) - -static char tx_buf[UART_RINGBUFFER_SIZE_TX]; -static uint32_t tx_produce; -static volatile uint32_t tx_consume; - -void uart_write(char c) { - uint32_t tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; - - // If the ring buffer is full, drain it here as the FIFO frees up: nothing else advances - // tx_consume between uart_write() calls, so a plain spin would deadlock on a >buffer-size burst. - while (tx_produce_next == tx_consume) { - if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) { - R8_UART1_THR = tx_buf[tx_consume]; - tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; - } - } - - // If UART TX FIFO is empty and no pending data, send directly - if ((tx_consume == tx_produce) && (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP)) { - R8_UART1_THR = c; - } else { - tx_buf[tx_produce] = c; - tx_produce = tx_produce_next; - } -} - -void uart_sync(void) { - // Wait for ring buffer to drain - while (tx_consume != tx_produce) { - if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) { - R8_UART1_THR = tx_buf[tx_consume]; - tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; - } - } - // Wait for last byte to finish transmitting - while (!(R8_UART1_LSR & RB_LSR_TX_ALL_EMP)) {} -} - -void usart_printf_init(uint32_t baudrate) { - tx_produce = 0; - tx_consume = 0; - - // Configure UART1 pins: TX=PA9, RX=PA8 - GPIOA_SetBits(GPIO_Pin_9); - GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); - GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); - - // Init UART1 with specified baud rate - UART1_DefInit(); - UART1_BaudRateCfg(baudrate); -} diff --git a/hw/bsp/ch58x/debug_uart.h b/hw/bsp/ch58x/debug_uart.h deleted file mode 100644 index 44c3e7948..000000000 --- a/hw/bsp/ch58x/debug_uart.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef DEBUG_UART_H_ -#define DEBUG_UART_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void uart_write(char c); -void uart_sync(void); -void usart_printf_init(uint32_t baudrate); - -#ifdef __cplusplus -} -#endif - -#endif /* DEBUG_UART_H_ */ diff --git a/hw/bsp/ch58x/family.c b/hw/bsp/ch58x/family.c deleted file mode 100644 index 64ae4a903..000000000 --- a/hw/bsp/ch58x/family.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -/* metadata: - manufacturer: WCH -*/ - -// WCH SDK's DEBUG macro enables a _write() that conflicts with TinyUSB's. -// TinyUSB uses UART1 for printf via debug_uart.c, so DEBUG is not needed. -// If you need a different UART or want to keep SDK's DEBUG, modify -// debug_uart.c (TinyUSB side) or CH58x_sys.c (SDK side) to remove one _write(). -// If done, remove this #error to continue. -#ifdef DEBUG - #error "Remove the DEBUG macro from preprocessor defines to avoid " \ - "duplicate _write() between WCH SDK and TinyUSB. " \ - "TinyUSB uses UART1 by default (see debug_uart.c)." -#endif - -#include "debug_uart.h" -#include "CH58x_common.h" -#include "ch58x_it.h" - -#include "bsp/board_api.h" -#include "board.h" - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ - -// Device only: the shared dcd_ch32_usbfs.c drives USB0 (rhport 0). CH58x's second controller -// (USB2 / rhport 1) was driven by the now-removed ch58x host driver; its handler is kept -// commented out below to ease re-adding host support. -__INTERRUPT __HIGH_CODE void USB_IRQHandler(void) { - tusb_int_handler(0, true); -} - -// __INTERRUPT __HIGH_CODE void USB2_IRQHandler(void) { -// tusb_int_handler(1, true); -// } - -//--------------------------------------------------------------------+ -// SysTick -//--------------------------------------------------------------------+ - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -__INTERRUPT __HIGH_CODE void SysTick_Handler(void) { - SysTick->SR = 0; - system_ticks++; -} - -uint32_t tusb_time_millis_api(void) { - return system_ticks; -} -#endif - -//--------------------------------------------------------------------+ -// Board Init -//--------------------------------------------------------------------+ - -void board_init(void) { - // Disable interrupts during init - PFIC_DisableAllIRQ(); - - // Set system clock to PLL 60MHz (default for CH582) - SetSysClock(CLK_SOURCE_PLL_60MHz); - -#if CFG_TUSB_OS == OPT_OS_NONE - SysTick_Config(GetSysClock() / 1000); -#endif - - // UART1 init for debug output -#ifdef CFG_BOARD_UART_BAUDRATE - usart_printf_init(CFG_BOARD_UART_BAUDRATE); -#endif - - // LED -#ifdef LED_PORT_IS_A - GPIOA_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA); -#else - GPIOB_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA); -#endif - - // Button -#ifdef BUTTON_PIN - #ifdef BUTTON_PORT_IS_A - GPIOA_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU); - #else - GPIOB_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU); - #endif -#endif - - // Device only on USB0 (rhport 0): enable analog function for USB1 D+/D- and assert its D+ - // pull-up. The shared dcd_ch32_usbfs.c drives USB0; CH58x host / USB2 (rhport 1) is unsupported - // here — to re-add host, also OR in RB_PIN_USB2_IE below. - R16_PIN_ANALOG_IE |= RB_PIN_USB_IE; // | RB_PIN_USB2_IE (re-add for host on USB2) -#if CFG_TUD_ENABLED - R16_PIN_ANALOG_IE |= RB_PIN_USB_DP_PU; -#endif - - // Keep USB clock active during sleep - R8_SLP_CLK_OFF1 &= ~RB_SLP_CLK_USB; - - // Enable interrupts globally - PFIC_EnableAllIRQ(); - - board_delay(2); -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) { -#ifdef LED_PORT_IS_A - if (state ^ LED_STATE_ON) { - GPIOA_ResetBits(LED_PIN); - } else { - GPIOA_SetBits(LED_PIN); - } -#else - if (state ^ LED_STATE_ON) { - GPIOB_ResetBits(LED_PIN); - } else { - GPIOB_SetBits(LED_PIN); - } -#endif -} - -uint32_t board_button_read(void) { -#ifdef BUTTON_PIN - #ifdef BUTTON_PORT_IS_A - return BUTTON_STATE_ACTIVE == (GPIOA_ReadPortPin(BUTTON_PIN) ? 1 : 0); - #else - return BUTTON_STATE_ACTIVE == (GPIOB_ReadPortPin(BUTTON_PIN) ? 1 : 0); - #endif -#else - return 0; -#endif -} - -// CH58x has no memory-mapped unique-ID register (unlike ch32v10x/v20x at 0x1FFFF7E8), but the -// factory programs a unique 6-byte MAC address into FlashROM (it is a BLE part). GetMACAddress() -// reads it via the ISP ROM command FLASH_EEPROM_CMD, which is provided by libISP583.a. -size_t board_get_unique_id(uint8_t id[], size_t max_len) { - // FLASH_EEPROM_CMD writes word-granular and requires a 4-byte-aligned buffer (CH58x_flash.c); - // size 8 matches the SDK's GET_UNIQUE_ID buffer (6 MAC bytes + 2 it pads), so the read can't - // run past the end whether it returns 6 or a full 8. - TU_ATTR_ALIGNED(4) uint8_t mac[8]; - GetMACAddress(mac); - size_t len = TU_MIN(max_len, (size_t) 6); // the 6-byte MAC is the unique part - memcpy(id, mac, len); - return len; -} - -int board_uart_read(uint8_t* buf, int len) { - (void) buf; - (void) len; - return 0; -} - -int board_uart_write(void const* buf, int len) { - int txsize = len; - const char* bufc = (const char*) buf; - while (txsize--) { - uart_write(*bufc++); - } - uart_sync(); - return len; -} diff --git a/hw/bsp/ch58x/family.cmake b/hw/bsp/ch58x/family.cmake deleted file mode 100644 index a52309276..000000000 --- a/hw/bsp/ch58x/family.cmake +++ /dev/null @@ -1,108 +0,0 @@ -include_guard() - -set(SDK_DIR ${TOP}/hw/mcu/wch/ch583) -set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) - -# include board specific -include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) - -# toolchain set up -set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) - -set(FAMILY_MCUS CH58X CACHE INTERNAL "") -set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") - -#------------------------------------ -# Startup & Linker script -#------------------------------------ -if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/ch582.ld) -endif () -set(LD_FILE_Clang ${LD_FILE_GNU}) -if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_CH583.S) -endif () -set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - -#------------------------------------ -# Board Target -#------------------------------------ -function(family_add_board BOARD_TARGET) - add_library(${BOARD_TARGET} STATIC - ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_gpio.c - ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_clk.c - ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_uart1.c - ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_sys.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch58x_it.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch58x.c - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_SRC_DIR}/RVMSIS - ${SDK_SRC_DIR}/StdPeriphDriver/inc - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ) - target_link_libraries(${BOARD_TARGET} PUBLIC - ${SDK_SRC_DIR}/StdPeriphDriver/libISP583.a - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - CFG_TUD_WCH_USBIP_USBFS=1 - FREQ_SYS=60000000 - DISK_LIB_ENABLE=0 - INT_SOFT - ) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_compile_options(${BOARD_TARGET} PUBLIC - -flto - -msmall-data-limit=16 - -mno-save-restore - -fmessage-length=0 - -fsigned-char - -Wno-error=strict-prototypes - ) - endif () -endfunction() - -#------------------------------------ -# Functions -#------------------------------------ -function(family_configure_example TARGET RTOS) - family_configure_common(${TARGET} ${RTOS}) - family_add_tinyusb(${TARGET} OPT_MCU_CH58X) - - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug_uart.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c - ${TOP}/src/portable/wch/dcd_ch32_usbfs.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} - ) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${TARGET} PUBLIC - -nostartfiles - --specs=nosys.specs --specs=nano.specs - -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE} - -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE} - "LINKER:--script=${LD_FILE_GNU}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - message(FATAL_ERROR "Clang is not supported for CH58x") - endif () - - set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES - SKIP_LINTING ON - COMPILE_OPTIONS -w) - - # Flashing - family_add_bin_hex(${TARGET}) - family_flash_openocd_wch(${TARGET}) -endfunction() diff --git a/hw/bsp/ch58x/family.mk b/hw/bsp/ch58x/family.mk deleted file mode 100644 index ac0443659..000000000 --- a/hw/bsp/ch58x/family.mk +++ /dev/null @@ -1,59 +0,0 @@ -# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable -#CROSS_COMPILE ?= riscv32-unknown-elf- - -# Toolchain from https://nucleisys.com/download.php -#CROSS_COMPILE ?= riscv-nuclei-elf- - -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -CROSS_COMPILE ?= riscv-none-elf- - -SDK_DIR = hw/mcu/wch/ch583 -SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC - -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= rv32imac-ilp32 - -CFLAGS += \ - -flto \ - -msmall-data-limit=16 \ - -mno-save-restore \ - -fmessage-length=0 \ - -fsigned-char \ - -DCFG_TUSB_MCU=OPT_MCU_CH58X \ - -DCFG_TUD_WCH_USBIP_USBFS=1 \ - -DFREQ_SYS=60000000 \ - -DDISK_LIB_ENABLE=0 \ - -DINT_SOFT \ - -Wno-error=strict-prototypes - -LDFLAGS += \ - -nostartfiles \ - --specs=nosys.specs --specs=nano.specs - -LIBS += $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/libISP583.a - -SRC_C += \ - src/portable/wch/dcd_ch32_usbfs.c \ - $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_gpio.c \ - $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_clk.c \ - $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_uart1.c \ - $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_sys.c \ - $(FAMILY_PATH)/debug_uart.c \ - $(FAMILY_PATH)/ch58x_it.c \ - $(FAMILY_PATH)/system_ch58x.c - -SRC_S += \ - $(SDK_SRC_DIR)/Startup/startup_CH583.S - -INC += \ - $(TOP)/$(BOARD_PATH) \ - $(TOP)/$(SDK_SRC_DIR)/RVMSIS \ - $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/inc - -LD_FILE ?= $(FAMILY_PATH)/linker/ch582.ld - -OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -flash: flash-openocd-wch - -# For freeRTOS port source -FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/hw/bsp/ch58x/linker/ch582.ld b/hw/bsp/ch58x/linker/ch582.ld deleted file mode 100644 index 821998a49..000000000 --- a/hw/bsp/ch58x/linker/ch582.ld +++ /dev/null @@ -1,167 +0,0 @@ -/* CH582 Linker Script for TinyUSB - * Based on WCH CH583 SDK Link.ld - * Supports parameterized flash/ram sizes via --defsym - */ - -/* Default sizes if not provided via --defsym */ -__flash_size = DEFINED(__FLASH_SIZE) ? __FLASH_SIZE : 448K; -__ram_size = DEFINED(__RAM_SIZE) ? __RAM_SIZE : 32K; -__stack_size = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2048; - -ENTRY( _start ) - -PROVIDE( _stack_size = __stack_size ); - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_size - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __ram_size -} - -SECTIONS -{ - .init : - { - _sinit = .; - . = ALIGN(4); - KEEP(*(SORT_NONE(.init))) - . = ALIGN(4); - _einit = .; - } >FLASH AT>FLASH - - .highcodelalign : - { - . = ALIGN(4); - PROVIDE(_highcode_lma = .); - } >FLASH AT>FLASH - - .highcode : - { - . = ALIGN(4); - PROVIDE(_highcode_vma_start = .); - *(.vector); - KEEP(*(SORT_NONE(.vector_handler))) - *(.highcode); - *(.highcode.*); - . = ALIGN(4); - PROVIDE(_highcode_vma_end = .); - } >RAM AT>FLASH - - .text : - { - . = ALIGN(4); - KEEP(*(SORT_NONE(.handle_reset))) - *(.text) - *(.text.*) - *(.rodata) - *(.rodata*) - *(.sdata2.*) - *(.glue_7) - *(.glue_7t) - *(.gnu.linkonce.t.*) - . = ALIGN(4); - } >FLASH AT>FLASH - - .fini : - { - KEEP(*(SORT_NONE(.fini))) - . = ALIGN(4); - } >FLASH AT>FLASH - - PROVIDE( _etext = . ); - PROVIDE( _eitcm = . ); - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH AT>FLASH - - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH AT>FLASH - - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH AT>FLASH - - .ctors : - { - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } >FLASH AT>FLASH - - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } >FLASH AT>FLASH - - .dlalign : - { - . = ALIGN(4); - PROVIDE(_data_lma = .); - } >FLASH AT>FLASH - - .data : - { - . = ALIGN(4); - PROVIDE(_data_vma = .); - *(.gnu.linkonce.r.*) - *(.data .data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - PROVIDE( __global_pointer$ = . + 0x800 ); - *(.sdata .sdata.*) - *(.gnu.linkonce.s.*) - . = ALIGN(8); - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) - *(.srodata .srodata.*) - . = ALIGN(4); - PROVIDE( _edata = .); - } >RAM AT>FLASH - - .bss : - { - . = ALIGN(4); - PROVIDE( _sbss = .); - *(.sbss*) - *(.gnu.linkonce.sb.*) - *(.bss*) - *(.gnu.linkonce.b.*) - *(COMMON*) - . = ALIGN(4); - PROVIDE( _ebss = .); - } >RAM AT>FLASH - - PROVIDE( _end = _ebss); - PROVIDE( end = . ); - - .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : - { - PROVIDE( _heap_end = . ); - . = ALIGN(4); - PROVIDE(_susrstack = . ); - . = . + __stack_size; - PROVIDE( _eusrstack = .); - __freertos_irq_stack_top = .; - } >RAM -} diff --git a/hw/bsp/ch58x/system_ch58x.c b/hw/bsp/ch58x/system_ch58x.c deleted file mode 100644 index 068c1a131..000000000 --- a/hw/bsp/ch58x/system_ch58x.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "CH58x_common.h" -#include "system_ch58x.h" - -uint32_t SystemCoreClock = FREQ_SYS; - -void SystemInit(void) { - SetSysClock(CLK_SOURCE_PLL_60MHz); - SystemCoreClock = GetSysClock(); -} - -void SystemCoreClockUpdate(void) { - SystemCoreClock = GetSysClock(); -} diff --git a/hw/bsp/ch58x/system_ch58x.h b/hw/bsp/ch58x/system_ch58x.h deleted file mode 100644 index e96741ee8..000000000 --- a/hw/bsp/ch58x/system_ch58x.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef SYSTEM_CH58X_H_ -#define SYSTEM_CH58X_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock) - -extern void SystemInit(void); -extern void SystemCoreClockUpdate(void); - -#ifdef __cplusplus -} -#endif - -#endif /* SYSTEM_CH58X_H_ */ diff --git a/hw/bsp/ch58x/wch-riscv.cfg b/hw/bsp/ch58x/wch-riscv.cfg deleted file mode 100644 index 64d595d8e..000000000 --- a/hw/bsp/ch58x/wch-riscv.cfg +++ /dev/null @@ -1,17 +0,0 @@ -adapter driver wlinke -adapter speed 6000 -transport select sdi - -wlink_set_address 0x00000000 -set _CHIPNAME wch_riscv -sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 - -set _TARGETNAME $_CHIPNAME.cpu - -target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME -$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 0x8000 -work-area-backup 1 -set _FLASHNAME $_CHIPNAME.flash - -flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 - -echo "Ready for Remote Connections" diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index f2a2d92a5..b5390a59d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -659,7 +659,7 @@ #define TUP_DCD_EDPT_CLOSE_API #endif -#elif TU_CHECK_MCU(OPT_MCU_CH58X) +#elif TU_CHECK_MCU(OPT_MCU_CH583) // CH582/583 USBFS: older WCH USBFS IP with a single combined per-endpoint control register // (like CH32V103), driven by the shared dcd_ch32_usbfs.c on USB0 (rhport 0). Device only: // the shared hcd_ch32_usbfs.c is CH32V20x-specific and does not support CH58x, so host / diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index 90a477b79..415a015dc 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -130,7 +130,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #define USBHD_IRQn OTG_FS_IRQn -#elif CFG_TUSB_MCU == OPT_MCU_CH58X +#elif CFG_TUSB_MCU == OPT_MCU_CH583 #include "CH58x_common.h" // CH582/583 USBFS device controller: same combined per-endpoint control register as // CH32V103 (IN response bits[1:0], OUT response bits[3:2]) but a different register map - diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 22c7a43fa..ece9cde07 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -37,7 +37,7 @@ // Struct-based EP register access (uniform layout). CH58X has a different register map and // defines EP_DMA/EP_TX_LEN/EP_CTRL itself in ch32_usbfs_reg.h. - #if CFG_TUSB_MCU == OPT_MCU_CH58X + #if CFG_TUSB_MCU == OPT_MCU_CH583 // CH58X EP registers split into a low block (EP0-4) and a high block (EP5-7). Walk from each // block's first slot by the 4-byte slot stride (pointer arithmetic off slot 0, so the unused // ternary branch's index can't trip -Warray-bounds). EP4 has no DMA register of its own (it @@ -220,7 +220,7 @@ static void update_in(uint8_t rhport, uint8_t ep, bool force) { if (xfer->valid) { if (force || xfer->len) { size_t len = TU_MIN(xfer->max_size, xfer->len); -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // Every CH58x endpoint buffer is 64 bytes. Isochronous (which would push max_size up to 1023) // is refused in dcd_edpt_iso_alloc(), but some classes (e.g. video) ignore that result, so cap // the copy here to guarantee we never write past the buffer into a neighbouring endpoint's. @@ -256,7 +256,7 @@ static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_OUT]; if (xfer->valid) { size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 len = TU_MIN(len, 64u); // cap to the 64-byte EP buffer (see update_in) #endif memcpy(xfer->buffer, ep_out_buf(ep), len); @@ -308,7 +308,7 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { // enable other endpoints but NAK everything USBOTG_FS->UEP4_1_MOD = 0xCC; USBOTG_FS->UEP2_3_MOD = 0xCC; -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // CH58X: a single mode register enables EP5/6/7 RX+TX (different bit layout than CH32). USBOTG_FS->UEP567_MOD = RB_UEP5_RX_EN | RB_UEP5_TX_EN | RB_UEP6_RX_EN | RB_UEP6_TX_EN | RB_UEP7_RX_EN | RB_UEP7_TX_EN; @@ -393,7 +393,7 @@ void dcd_int_handler(uint8_t rhport) { USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; } else if (status & USBFS_INT_FG_SUSPEND) { -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // CH58x raises this single interrupt for both suspend and resume; MIS_ST's suspend bit tells // them apart (set while suspended, clear once resumed) so tud_resume_cb() actually fires. dcd_event_t event = {.rhport = rhport, @@ -447,7 +447,7 @@ void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t *req (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // On CH58x R8_USB_DEV_AD bit 7 is a user general-purpose flag; only bits [6:0] are the address. USBOTG_FS->DEV_ADDR = (uint8_t)((USBOTG_FS->DEV_ADDR & 0x80u) | (request->wValue & 0x7Fu)); #else @@ -485,7 +485,7 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet (void)rhport; (void)ep_addr; (void)largest_packet_size; -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // No isochronous support on CH58x: its 8-bit T_LEN caps a packet at 255B and the endpoints use // plain 64-byte buffers, so accepting an iso max_size (up to 1023) would let update_in()/ // update_out() run off the end of the buffer into neighbouring ones. Refuse it outright. @@ -503,7 +503,7 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 return false; // CH58x has no isochronous support (see dcd_edpt_iso_alloc) #else return true; diff --git a/src/tusb_option.h b/src/tusb_option.h index 9170d1205..cb8e3f6bd 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -195,7 +195,7 @@ #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x #define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X #define OPT_MCU_CH32V103 2230 ///< WCH CH32V103 -#define OPT_MCU_CH58X 2240 ///< WCH CH58x +#define OPT_MCU_CH583 2240 ///< WCH CH583 #define OPT_MCU_CH582 2240 ///< alias to CH58x series #define OPT_MCU_CH583 2240 ///< alias to CH58x series diff --git a/tools/get_deps.py b/tools/get_deps.py index b31f8a0cb..ebbf9b871 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -255,7 +255,7 @@ deps_optional = { 'ch32f20x'], 'hw/mcu/wch/ch583': ['https://github.com/openwch/ch583.git', 'bd508ad7ceed48377619837051412a651952857f', - 'ch58x'], + 'ch583'], 'hw/mcu/artery/at32f403a_407': ['https://github.com/ArteryTek/AT32F403A_407_Firmware_Library.git', 'f2cb360c3d28fada76b374308b8c4c61d37a090b', 'at32f403a_407'], -- cgit v1.3.1 From 299c0a55629691f6bbded895a4be377633e815ab Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 22 Jun 2026 15:33:03 +0700 Subject: ci: post HIL report comment from workflow_run so it works on forked PRs (#3723) * ci: post HIL report comment from workflow_run so it works on forked PRs --- .github/workflows/build.yml | 47 ------------ .github/workflows/metrics_comment.yml | 39 ---------- .github/workflows/pr_comment.yml | 131 ++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 86 deletions(-) delete mode 100644 .github/workflows/metrics_comment.yml create mode 100644 .github/workflows/pr_comment.yml (limited to '.github/workflows') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3f6458285..c8c597e50 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -171,10 +171,6 @@ jobs: mv metrics_compare.md $COMPARE_FILE gh release upload $CURR_TAG metrics.json $COMPARE_FILE - - name: Save PR number - if: github.event_name == 'pull_request' - run: echo ${{ github.event.number }} > pr_number.txt - - name: Upload Metrics Comment Artifact if: github.event_name == 'pull_request' uses: actions/upload-artifact@v7 @@ -183,7 +179,6 @@ jobs: path: | metrics_compare.md metrics.json - pr_number.txt - name: Post Code Metrics as PR Comment if: (github.event_name == 'workflow_dispatch') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) @@ -420,45 +415,3 @@ jobs: path: hil_report.md if-no-files-found: ignore overwrite: true - - # --------------------------------------- - # Combine HIL results from the rigs into a single sticky PR comment (one table per rig) - # --------------------------------------- - hil-report: - needs: [ hil-tinyusb, hil-hfp-iar ] - if: | - always() && - (needs.hil-tinyusb.result != 'skipped' || needs.hil-hfp-iar.result != 'skipped') && - github.event_name == 'pull_request' && - github.repository_owner == 'hathach' && - github.event.pull_request.head.repo.fork == false - runs-on: ubuntu-latest - permissions: - pull-requests: write - steps: - - name: Download HIL reports - uses: actions/download-artifact@v5 - with: - pattern: hil-report-* - path: hil-reports - - - name: Combine rig reports (one table per rig) - run: | - { - echo "## Hardware-in-the-loop (HIL) Test Report" - echo - for d in hil-reports/hil-report-*; do - [ -d "$d" ] || continue - echo "### ${d#hil-reports/hil-report-}" - echo - cat "$d/hil_report.md" 2>/dev/null || echo "_no report produced_" - echo - done - } > hil_combined.md - cat hil_combined.md - - - name: Post HIL report as sticky PR comment - uses: marocchino/sticky-pull-request-comment@v2 - with: - header: hil-report - path: hil_combined.md diff --git a/.github/workflows/metrics_comment.yml b/.github/workflows/metrics_comment.yml deleted file mode 100644 index 5d250211f..000000000 --- a/.github/workflows/metrics_comment.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Metrics Comment - -on: - workflow_run: - workflows: ["Build"] - types: - - completed - -jobs: - post-comment: - runs-on: ubuntu-latest - if: > - github.event.workflow_run.event == 'pull_request' && - github.event.workflow_run.conclusion == 'success' - permissions: - actions: read - pull-requests: write - steps: - - name: Download Artifacts - uses: actions/download-artifact@v5 - with: - run-id: ${{ github.event.workflow_run.id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - name: metrics-comment - - - name: Read PR Number - id: pr_number - run: | - if [ -f pr_number.txt ]; then - echo "number=$(cat pr_number.txt)" >> $GITHUB_OUTPUT - fi - - - name: Post Code Metrics as PR Comment - if: steps.pr_number.outputs.number != '' - uses: marocchino/sticky-pull-request-comment@v2 - with: - header: code-metrics - path: metrics_compare.md - number: ${{ steps.pr_number.outputs.number }} diff --git a/.github/workflows/pr_comment.yml b/.github/workflows/pr_comment.yml new file mode 100644 index 000000000..4d50817b4 --- /dev/null +++ b/.github/workflows/pr_comment.yml @@ -0,0 +1,131 @@ +name: PR Comment + +on: + workflow_run: + workflows: ["Build"] + types: + - completed + +jobs: + # Resolve the PR number from trusted workflow_run metadata, NOT from build artifacts: a forked PR + # controls its own Build run and could plant any number, which the privileged jobs below would + # then post to. Same-repo PRs populate workflow_run.pull_requests; for forks it is empty, so look + # the PR up by the trusted head SHA. + pr_number: + if: github.event.workflow_run.event == 'pull_request' + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + number: ${{ steps.resolve.outputs.number }} + steps: + - name: Resolve PR number + id: resolve + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} + HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }} + PRS_JSON: ${{ toJSON(github.event.workflow_run.pull_requests) }} + run: | + # Every lookup is best-effort: on any miss the number stays empty and the comment jobs + # below simply skip (never a failed check). + # Same-repo PRs: workflow_run.pull_requests is populated. + num=$(printf '%s' "$PRS_JSON" | jq -r '.[0].number // empty') + # Fork PRs: pull_requests is empty. Find the open PR by its trusted head ref and confirm + # its head SHA matches the built commit. + if [ -z "$num" ] && [ -n "$HEAD_BRANCH" ] && [ -n "$HEAD_REPO" ]; then + num=$(gh api --method GET "repos/$REPO/pulls" \ + -f state=open -f head="${HEAD_REPO%%/*}:$HEAD_BRANCH" \ + --jq '[.[] | select(.head.sha == env.HEAD_SHA)][0].number // empty' 2>/dev/null || true) + fi + echo "number=$num" >> "$GITHUB_OUTPUT" + + metrics-comment: + needs: pr_number + if: > + github.event.workflow_run.conclusion == 'success' && + needs.pr_number.outputs.number != '' + runs-on: ubuntu-latest + permissions: + actions: read + pull-requests: write + steps: + - name: Download Artifacts + uses: actions/download-artifact@v5 + with: + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + name: metrics-comment + # Best-effort: docs-only PRs skip code-metrics, so the artifact may be absent. + continue-on-error: true + + - name: Post Code Metrics as PR Comment + if: hashFiles('metrics_compare.md') != '' + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: code-metrics + path: metrics_compare.md + number: ${{ needs.pr_number.outputs.number }} + + # --------------------------------------- + # Combine the rigs' HIL reports into one sticky PR comment (one table per rig). + # Runs here (workflow_run / base-repo context) rather than in build.yml so it also works on + # forked PRs, whose build-side GITHUB_TOKEN is read-only and cannot post comments. Posts even + # on build/HIL failure (when the report matters most); skips only on cancellation. + # --------------------------------------- + hil-comment: + needs: pr_number + if: > + github.event.workflow_run.conclusion != 'cancelled' && + needs.pr_number.outputs.number != '' + runs-on: ubuntu-latest + permissions: + actions: read + pull-requests: write + steps: + - name: Download HIL reports + uses: actions/download-artifact@v5 + with: + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + pattern: hil-report-* + path: hil-reports + continue-on-error: true + + - name: Combine rig reports (one table per rig) + id: combine + run: | + shopt -s nullglob + dirs=(hil-reports/hil-report-*) + if [ ${#dirs[@]} -eq 0 ]; then + echo "No HIL reports found" + exit 0 + fi + { + echo "## Hardware-in-the-loop (HIL) Test Report" + echo + for d in "${dirs[@]}"; do + [ -d "$d" ] || continue + echo "### ${d#hil-reports/hil-report-}" + echo + cat "$d/hil_report.md" 2>/dev/null || echo "_no report produced_" + echo + done + } > hil_combined.md + # Fork PRs can influence report content and this job posts in base-repo context, so + # neutralize @-mentions (insert a zero-width space) to prevent notification abuse. + zwsp=$(printf '\342\200\213') + sed -i -E "s/@([A-Za-z0-9_-])/@${zwsp}\1/g" hil_combined.md + cat hil_combined.md + echo "found=true" >> "$GITHUB_OUTPUT" + + - name: Post HIL report as sticky PR comment + if: steps.combine.outputs.found == 'true' + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: hil-report + path: hil_combined.md + number: ${{ needs.pr_number.outputs.number }} -- cgit v1.3.1