From 20af13465c479b3ffd3885a5d21ef70164d6ce00 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Fri, 30 Aug 2024 17:26:37 -0300 Subject: [PATCH 01/45] fix(UI): Fix breaking changes and lock textual version (#214) --- README.md | 15 ++++++++------- tools/config_editor/README.md | 2 +- tools/config_editor/app.py | 8 ++++---- tools/config_editor/requirements.txt | 1 + 4 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 tools/config_editor/requirements.txt diff --git a/README.md b/README.md index 501c62887..16452f7e1 100644 --- a/README.md +++ b/README.md @@ -22,20 +22,21 @@ For more information and troubleshooting, please refer to the [UI README](tools/ To use it, follow these steps: -1. Make sure you have the required dependencies installed: +1. Make sure you have the following prerequisites: - Python 3.9 or later - - The [Textual](https://github.com/textualize/textual/) library - All the dependencies listed in the previous section -2. Execute the script `tools/config_editor/app.py` from any folder. It will automatically detect the path to the root of the repository. +2. Install the required UI packages using `pip install -r tools/config_editor/requirements.txt`. -3. Configure the compilation and ESP-IDF options as desired. +3. Execute the script `tools/config_editor/app.py` from any folder. It will automatically detect the path to the root of the repository. -4. Click on the "Compile Static Libraries" button to start the compilation process. +4. Configure the compilation and ESP-IDF options as desired. -5. The script will show the compilation output in a new screen. Note that the compilation process can take many hours, depending on the number of libraries selected and the options chosen. +5. Click on the "Compile Static Libraries" button to start the compilation process. -6. If the compilation is successful and the option to copy the libraries to the Arduino Core folder is enabled, it will already be available for use in the Arduino IDE. Otherwise, you can find the compiled libraries in the `esp32-arduino-libs` folder alongside this repository. +6. The script will show the compilation output in a new screen. Note that the compilation process can take many hours, depending on the number of libraries selected and the options chosen. + +7. If the compilation is successful and the option to copy the libraries to the Arduino Core folder is enabled, it will already be available for use in the Arduino IDE. Otherwise, you can find the compiled libraries in the `esp32-arduino-libs` folder alongside this repository. - Note that the copy operation doesn't currently support the core downloaded from the Arduino IDE Boards Manager, only the manual installation from the [`arduino-esp32`](https://github.com/espressif/arduino-esp32) repository. ### Documentation diff --git a/tools/config_editor/README.md b/tools/config_editor/README.md index 10cf8f8a0..9abd93fc7 100644 --- a/tools/config_editor/README.md +++ b/tools/config_editor/README.md @@ -6,7 +6,7 @@ It has mouse support and can be pre-configured using command line arguments. ## Requirements - Python 3.9 or later - - The "textual" library (install it using `pip install textual`) + - Install the required packages using `pip install -r requirements.txt` - The requirements from esp32-arduino-lib-builder ## Troubleshooting diff --git a/tools/config_editor/app.py b/tools/config_editor/app.py index fcba827d2..dbe24ca05 100755 --- a/tools/config_editor/app.py +++ b/tools/config_editor/app.py @@ -112,10 +112,10 @@ class ConfigEditorApp(App): ENABLE_COMMAND_PALETTE = False CSS_PATH = "style.tcss" SCREENS = { - "main": MainScreen(), - "settings": SettingsScreen(), - "compile": CompileScreen(), - "editor": EditorScreen(), + "main": MainScreen, + "settings": SettingsScreen, + "compile": CompileScreen, + "editor": EditorScreen, } def on_mount(self) -> None: diff --git a/tools/config_editor/requirements.txt b/tools/config_editor/requirements.txt new file mode 100644 index 000000000..f3cac7be0 --- /dev/null +++ b/tools/config_editor/requirements.txt @@ -0,0 +1 @@ +textual==0.79.0 From 33d92531ce4997b3a15fdbfa8c81f5a20a209d7b Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Sat, 31 Aug 2024 18:24:58 +0300 Subject: [PATCH 02/45] Update ESP32 definition in PlatformIO (#217) --- configs/pio_end.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/pio_end.txt b/configs/pio_end.txt index e7544f1dd..f942d442d 100644 --- a/configs/pio_end.txt +++ b/configs/pio_end.txt @@ -1,5 +1,5 @@ "ARDUINO_ARCH_ESP32", - "ESP32", + ("ESP32", "ESP32"), ("F_CPU", "$BOARD_F_CPU"), ("ARDUINO", 10812), ("ARDUINO_VARIANT", '\\"%s\\"' % board_config.get("build.variant").replace('"', "")), From 009e79d0b32164d5ed1d1dac95a31ae9b5699508 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Sat, 31 Aug 2024 12:26:25 -0300 Subject: [PATCH 03/45] Fix Dockerfile and test docker build in PRs (#216) * Use requirements.txt in Dockerfile * Test docker build in PRs * Optimize push workflow for PRs * Optimize docker workflow * Improve name --- .github/workflows/docker.yml | 37 ++++++++++++++++++++++++++++-------- .github/workflows/push.yml | 17 ++++++++++++++++- tools/docker/Dockerfile | 4 ++-- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 8952015a2..d6166a365 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -7,6 +7,12 @@ on: - 'release/*' tags: - 'v*.*' + pull_request: + paths: + - ".github/workflows/docker.yml" + - "tools/config_editor/requirements.txt" + - "tools/docker/Dockerfile" + - "tools/docker/entrypoint.sh" env: # Build the image for amd64 and arm64 @@ -16,8 +22,8 @@ env: jobs: docker: # Disable the job in forks - if: ${{ github.repository_owner == 'espressif' }} - + if: ${{ github.event_name == 'pull_request' || github.repository_owner == 'espressif' }} + name: Build docker image and push if needed runs-on: ubuntu-latest steps: # Depending on the branch/tag, set CLONE_BRANCH_OR_TAG variable (used in the Dockerfile @@ -29,50 +35,65 @@ jobs: run: | echo "CLONE_BRANCH_OR_TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV echo "TAG_NAME=$GITHUB_REF_NAME" >> $GITHUB_ENV + echo "URL=${{ github.server_url }}/${{ github.repository }}.git" >> $GITHUB_ENV + - name: Set variables (release branches) if: ${{ github.ref_type == 'branch' && startsWith(github.ref_name, 'release/') }} run: | echo "CLONE_BRANCH_OR_TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV echo "TAG_NAME=release-${GITHUB_REF_NAME##release/}" >> $GITHUB_ENV + echo "URL=${{ github.server_url }}/${{ github.repository }}.git" >> $GITHUB_ENV + - name: Set variables (main branch) if: ${{ github.ref_type == 'branch' && github.ref_name == 'master' }} run: | echo "CLONE_BRANCH_OR_TAG=master" >> $GITHUB_ENV echo "TAG_NAME=latest" >> $GITHUB_ENV + echo "URL=${{ github.server_url }}/${{ github.repository }}.git" >> $GITHUB_ENV + + - name: Set variables (pull requests) + if: ${{ github.event_name == 'pull_request' }} + run: | + echo "CLONE_BRANCH_OR_TAG=${{ github.event.pull_request.head.ref }}" >> $GITHUB_ENV + echo "TAG_NAME=PR_${{ github.event.number }}" >> $GITHUB_ENV + echo "URL=${{ github.server_url }}/${{ github.event.pull_request.head.repo.full_name }}.git" >> $GITHUB_ENV # Display the variables set above, just in case. - name: Check variables run: | echo "CLONE_BRANCH_OR_TAG: $CLONE_BRANCH_OR_TAG" - echo "CHECKOUT_REF: $CHECKOUT_REF" echo "TAG_NAME: $TAG_NAME" + echo "URL: $URL" - # The following steps are the standard boilerplate from - # https://github.com/marketplace/actions/build-and-push-docker-images - name: Checkout uses: actions/checkout@v4 + - name: Login to Docker Hub + if: ${{ github.event_name == 'push' }} uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Set up QEMU for multiarch builds uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Build and push uses: docker/build-push-action@v5 with: context: tools/docker - push: true + push: ${{ github.event_name == 'push' }} tags: ${{ env.DOCKERHUB_REPO }}:${{ env.TAG_NAME }} platforms: ${{ env.BUILD_PLATFORMS }} build-args: | - LIBBUILDER_CLONE_URL=${{ github.server_url }}/${{ github.repository }}.git + LIBBUILDER_CLONE_URL=${{ env.URL }} LIBBUILDER_CLONE_BRANCH_OR_TAG=${{ env.CLONE_BRANCH_OR_TAG }} - name: Update Docker Hub repository description (master branch) - if: ${{ github.ref_type == 'branch' && github.ref_name == 'master' }} + if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && github.ref_name == 'master' }} uses: peter-evans/dockerhub-description@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index c3edd52d3..649c84c81 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -5,13 +5,21 @@ on: branches: - master pull_request: + paths: + - "**" + - "!**.md" + - "!.github/workflows/cron_build.yml" + - "!.github/workflows/cron.yml" + - "!.github/workflows/docker.yml" + - "!.github/workflows/repository_dispatch.yml" + - "!tools/config_editor/**" + - "!tools/docker/**" concurrency: group: esp-idf-libs-${{github.event.pull_request.number || github.ref}} cancel-in-progress: true jobs: - build-libs: name: Build Libs for ${{ matrix.target }} runs-on: ubuntu-latest @@ -21,16 +29,20 @@ jobs: fail-fast: false steps: - uses: actions/checkout@v4 + - name: Install dependencies run: bash ./tools/prepare-ci.sh + - name: Build Libs for ${{ matrix.target }} run: bash ./build.sh -e -t ${{ matrix.target }} + - name: Upload build if: failure() uses: actions/upload-artifact@v4 with: name: build-${{ matrix.target }} path: build + - name: Upload archive uses: actions/upload-artifact@v4 with: @@ -48,17 +60,20 @@ jobs: path: dist pattern: artifacts-* merge-multiple: true + - shell: bash run: | mkdir -p out find dist -name 'arduino-esp32-libs-esp*.tar.gz' -exec tar zxvf {} -C out \; cd out/tools/esp32-arduino-libs && tar zcf ../../../dist/esp32-arduino-libs.tar.gz * && cd ../../.. cp out/package_esp32_index.template.json dist/package_esp32_index.template.json + - name: Upload full esp32-arduino-libs archive uses: actions/upload-artifact@v4 with: name: esp32-arduino-libs path: dist/esp32-arduino-libs.tar.gz + - name: Upload package_esp32_index.template.json uses: actions/upload-artifact@v4 with: diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index a46733a34..3262cbb2d 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -34,7 +34,6 @@ RUN : \ python3-setuptools \ python3-venv \ wget \ - && pip3 install --upgrade pip textual-dev \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* \ && : @@ -70,7 +69,8 @@ RUN echo LIBBUILDER_CHECKOUT_REF=$LIBBUILDER_CHECKOUT_REF LIBBUILDER_CLONE_BRANC fi && \ git checkout $LIBBUILDER_CHECKOUT_REF && \ git submodule update --init --recursive; \ - fi + fi && \ + pip3 install --upgrade -r $LIBBUILDER_PATH/tools/config_editor/requirements.txt COPY entrypoint.sh $LIBBUILDER_PATH/entrypoint.sh From 11e303c664d693a25498f7af1231f184447319b2 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 24 Sep 2024 23:08:15 +0300 Subject: [PATCH 04/45] Add P4 to targets for 5.3 --- .github/workflows/cron.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index f2053b3ad..ed2522f54 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -36,4 +36,4 @@ jobs: targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2" - idf_branch: "release/v5.3" lib_builder_branch: "release/v5.3" - targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2" + targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4" From 5d4ed02e13458b5ea83b3b8ef00747e1fec06bf2 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Thu, 26 Sep 2024 01:41:14 +0300 Subject: [PATCH 05/45] Add Matter component as part of the libs (#220) * Add Matter component as part of the libs * feat(matter): adds necessary setup * feat(matter): sdkconfig for each SoC * fix(matter): no wifi within C2 * fix(matter): replaces wrong pieces * fix(matter): forgot folder reference * feat(matter): strip matter lib.a * fix(matter): missing double quote * fix(matter): bad folder name * feat(matter): testing freertos backward compatibility * feat(matter): testing not using minimal mdns * feat(matter): disable lwip ipv6 autoconfig * feat(matter): common settings * feat(matter): revert changes * feat(matter): revert changes * feat(matter): revert changes * feat(matter): revert changes * feat(matter): no WiFi matter for H2 - thread only * feat(matter): revert changes * feat(matter): revert changes * feat(matter): no support for H2 - no WiFi * feat(matter): clean up * feat(matter): script clean up --------- Co-authored-by: SuGliger Co-authored-by: Rodrigo Garcia --- CMakeLists.txt | 5 +++++ configs/defconfig.common | 16 ++++++++++++++++ configs/defconfig.esp32c6 | 17 ----------------- configs/defconfig.esp32h2 | 17 ----------------- main/idf_component.yml | 5 +++++ tools/copy-libs.sh | 13 ++++++++++++- 6 files changed, 38 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88cede199..1b0fca085 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,3 +33,8 @@ add_custom_command( VERBATIM ) add_custom_target(mem-variant DEPENDS "mem_variant") + +################## +### ESP Matter ### +################## +idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-DCHIP_HAVE_CONFIG_H" APPEND) diff --git a/configs/defconfig.common b/configs/defconfig.common index a6b42ed64..47310528c 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -75,8 +75,14 @@ CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT=y CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT=y CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM=y +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y +CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 CONFIG_MBEDTLS_PSK_MODES=y CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y +CONFIG_MBEDTLS_ECJPAKE_C=y +CONFIG_MBEDTLS_HKDF_C=y CONFIG_MBEDTLS_CAMELLIA_C=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y # CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN is not set @@ -111,3 +117,13 @@ CONFIG_ESP_COREDUMP_STACK_SIZE=1024 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y +# +# Matter Settings +# +# Disable Matter BLE +CONFIG_ENABLE_CHIPOBLE=n +CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n +# ESP Insights +CONFIG_ENABLE_ESP_INSIGHTS_TRACE=n +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y diff --git a/configs/defconfig.esp32c6 b/configs/defconfig.esp32c6 index e2c9c33ea..7770504fc 100644 --- a/configs/defconfig.esp32c6 +++ b/configs/defconfig.esp32c6 @@ -8,23 +8,6 @@ CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 #CONFIG_ULP_COPROC_LP_CORE=y #CONFIG_ULP_COPROC_RESERVE_MEM=4096 -# -# ESP32 Arduino OpenThread Configuration -# -# lwIP -# -CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 -CONFIG_LWIP_MULTICAST_PING=y -CONFIG_LWIP_BROADCAST_PING=y -# end of lwip - -# -# mbedTLS -# -CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y -CONFIG_MBEDTLS_ECJPAKE_C=y -# end of mbedTLS - # # OpenThread # diff --git a/configs/defconfig.esp32h2 b/configs/defconfig.esp32h2 index 79a13544d..dfd36395d 100644 --- a/configs/defconfig.esp32h2 +++ b/configs/defconfig.esp32h2 @@ -4,23 +4,6 @@ CONFIG_RTC_CLK_CAL_CYCLES=576 # CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 -# -# ESP32 Arduino OpenThread Configuration -# -# lwIP -# -CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 -CONFIG_LWIP_MULTICAST_PING=y -CONFIG_LWIP_BROADCAST_PING=y -# end of lwip - -# -# mbedTLS -# -CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y -CONFIG_MBEDTLS_ECJPAKE_C=y -# end of mbedTLS - # # OpenThread # diff --git a/main/idf_component.yml b/main/idf_component.yml index 011906d27..292709d64 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -22,6 +22,11 @@ dependencies: version: ">=1.4.2" rules: - if: "target in [esp32s3]" + espressif/esp_matter: + version: "^1.3.0" + require: public + rules: + - if: "target not in [esp32c2, esp32h2]" # esp-sr: "^1.3.1" # esp32-camera: "^2.0.4" diff --git a/tools/copy-libs.sh b/tools/copy-libs.sh index 8ee2276dd..565eb4542 100755 --- a/tools/copy-libs.sh +++ b/tools/copy-libs.sh @@ -491,6 +491,17 @@ echo -n "$LD_FLAGS" > "$FLAGS_DIR/ld_flags" echo -n "$LD_SCRIPTS" > "$FLAGS_DIR/ld_scripts" echo -n "$AR_LIBS" > "$FLAGS_DIR/ld_libs" +# Matter Library adjustments +for flag_file in "c_flags" "cpp_flags" "S_flags"; do + echo "Fixing $FLAGS_DIR/$flag_file" + sed 's/\\\"-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=\\\"/-DCHIP_HAVE_CONFIG_H/' $FLAGS_DIR/$flag_file > $FLAGS_DIR/$flag_file.temp + mv $FLAGS_DIR/$flag_file.temp $FLAGS_DIR/$flag_file +done +CHIP_RESOLVE_DIR="$AR_SDK/include/espressif__esp_matter/connectedhomeip/connectedhomeip/src/lib/address_resolve" +sed 's/CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER//' $CHIP_RESOLVE_DIR/AddressResolve.h > $CHIP_RESOLVE_DIR/AddressResolve_temp.h +mv $CHIP_RESOLVE_DIR/AddressResolve_temp.h $CHIP_RESOLVE_DIR/AddressResolve.h +# End of Matter Library adjustments + # copy zigbee + zboss lib if [ -d "managed_components/espressif__esp-zigbee-lib/lib/$IDF_TARGET/" ]; then cp -r "managed_components/espressif__esp-zigbee-lib/lib/$IDF_TARGET"/* "$AR_SDK/lib/" @@ -530,7 +541,7 @@ for item; do done done -for lib in "openthread" "espressif__esp-tflite-micro" "bt"; do +for lib in "openthread" "espressif__esp-tflite-micro" "bt" "espressif__esp_matter"; do if [ -f "$AR_SDK/lib/lib$lib.a" ]; then echo "Stripping $AR_SDK/lib/lib$lib.a" "$TOOLCHAIN-strip" -g "$AR_SDK/lib/lib$lib.a" From 4ae464bbaef132f5ad9ec1b73468f2260b77d960 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Thu, 26 Sep 2024 09:39:28 -0300 Subject: [PATCH 06/45] feat(matter): removes -DESP32=ESP32 (#224) removes -DESP32=ESP32 from flags/defines --- tools/copy-libs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/copy-libs.sh b/tools/copy-libs.sh index 565eb4542..bbc89e089 100755 --- a/tools/copy-libs.sh +++ b/tools/copy-libs.sh @@ -102,7 +102,7 @@ for item in "${@:2:${#@}-5}"; do INCLUDES+="$item " fi elif [ "$prefix" = "-D" ]; then - if [[ "${item:2:7}" != "ARDUINO" ]] && [[ "$item" != "-DESP32" ]]; then #skip ARDUINO defines + if [[ "${item:2:7}" != "ARDUINO" ]] && [[ "$item" != "-DESP32=ESP32" ]]; then #skip ARDUINO defines DEFINES+="$item " fi elif [ "$prefix" = "-O" ]; then From ab03ddc44d75d8a9e6780520c7d643d8e97921ec Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 1 Oct 2024 00:22:46 +0300 Subject: [PATCH 07/45] Fix ESP-DL component build (#226) * Fix ESP-DL component build Changes in the upstream repository require some changes in the component config * For IDF 5.1 use older commit * Update idf_component.yml --- main/idf_component.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/idf_component.yml b/main/idf_component.yml index 292709d64..00682c102 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -13,7 +13,7 @@ dependencies: rules: - if: "target not in [esp32c2]" espressif/esp-dl: - version: "master" + version: "af7808ba09448ce82c704455975d4cf1e4305fd7" git: https://github.com/espressif/esp-dl.git require: public rules: From 42f7e468f8d92ae346d84bbed3c73bea1194f507 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 2 Oct 2024 14:52:06 +0300 Subject: [PATCH 08/45] Update dwc2 and TinyUSB component (#228) This Pull Request updates the Arduino TinyUSB component to support the latest upstream code. Additionally adds support for NCM and ESP32-P4 --- components/arduino_tinyusb/CMakeLists.txt | 26 +- components/arduino_tinyusb/Kconfig.projbuild | 11 + .../arduino_tinyusb/include/tusb_config.h | 5 + .../arduino_tinyusb/patches/dcd_dwc2.patch | 54 +- components/arduino_tinyusb/src/dcd_dwc2.c | 693 +++++++------ components/arduino_tinyusb/src/dcd_esp32sx.c | 965 ------------------ patches/tinyusb_dcd_esp32sx.diff | 119 --- 7 files changed, 451 insertions(+), 1422 deletions(-) rename patches/tinyusb_dcd_dwc2.diff => components/arduino_tinyusb/patches/dcd_dwc2.patch (61%) delete mode 100755 components/arduino_tinyusb/src/dcd_esp32sx.c delete mode 100644 patches/tinyusb_dcd_esp32sx.diff diff --git a/components/arduino_tinyusb/CMakeLists.txt b/components/arduino_tinyusb/CMakeLists.txt index b0227ec5a..6a2e35150 100755 --- a/components/arduino_tinyusb/CMakeLists.txt +++ b/components/arduino_tinyusb/CMakeLists.txt @@ -15,14 +15,18 @@ if(CONFIG_TINYUSB_ENABLED) "-DCFG_TUSB_DEBUG=${CONFIG_TINYUSB_DEBUG_LEVEL}" "-Wno-type-limits" # needed for the vanila tinyusb with turned off classes ) + elseif(IDF_TARGET STREQUAL "esp32p4") + set(compile_options + "-DCFG_TUSB_MCU=OPT_MCU_ESP32P4" + "-DCFG_TUSB_DEBUG=${CONFIG_TINYUSB_DEBUG_LEVEL}" + "-Wno-type-limits" # needed for the vanila tinyusb with turned off classes + ) endif() set(srcs # espressif: - #"${COMPONENT_DIR}/src/dcd_esp32sx.c" "${COMPONENT_DIR}/src/dcd_dwc2.c" # tusb: - #"${COMPONENT_DIR}/tinyusb/src/portable/espressif/esp32sx/dcd_esp32sx.c" #"{COMPONENT_DIR}/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c" "${COMPONENT_DIR}/tinyusb/src/class/cdc/cdc_device.c" "${COMPONENT_DIR}/tinyusb/src/class/hid/hid_device.c" @@ -32,6 +36,7 @@ if(CONFIG_TINYUSB_ENABLED) "${COMPONENT_DIR}/tinyusb/src/class/dfu/dfu_rt_device.c" "${COMPONENT_DIR}/tinyusb/src/class/dfu/dfu_device.c" "${COMPONENT_DIR}/tinyusb/src/class/vendor/vendor_device.c" + "${COMPONENT_DIR}/tinyusb/src/class/net/ncm_device.c" "${COMPONENT_DIR}/tinyusb/src/common/tusb_fifo.c" "${COMPONENT_DIR}/tinyusb/src/device/usbd_control.c" "${COMPONENT_DIR}/tinyusb/src/device/usbd.c" @@ -56,16 +61,15 @@ if(CONFIG_TINYUSB_ENABLED) set(requires esp_rom freertos soc) set(priv_requires arduino main) - ### tinyusb lib ### - ################### - idf_component_register(INCLUDE_DIRS ${includes_public} PRIV_INCLUDE_DIRS ${includes_private} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires}) - # add_library(${COMPONENT_TARGET} STATIC ${srcs}) - # target_include_directories( - # ${COMPONENT_TARGET} - # PUBLIC ${includes_public} - # PRIVATE ${includes_private}) + + idf_component_register( + INCLUDE_DIRS ${includes_public} + PRIV_INCLUDE_DIRS ${includes_private} + SRCS ${srcs} + REQUIRES ${requires} + PRIV_REQUIRES ${priv_requires} + ) target_compile_options(${COMPONENT_TARGET} PRIVATE ${compile_options}) - #target_link_libraries(${COMPONENT_TARGET} INTERFACE ${COMPONENT_TARGET}) else() diff --git a/components/arduino_tinyusb/Kconfig.projbuild b/components/arduino_tinyusb/Kconfig.projbuild index 50e24b6a6..1db30506f 100755 --- a/components/arduino_tinyusb/Kconfig.projbuild +++ b/components/arduino_tinyusb/Kconfig.projbuild @@ -233,6 +233,17 @@ menu "Arduino TinyUSB" endmenu + menu "NCM driver" + depends on TINYUSB_ENABLED + + config TINYUSB_NCM_ENABLED + bool "Enable USB NCM TinyUSB driver" + default y + help + Enable USB NCM TinyUSB driver. + + endmenu + config TINYUSB_DEBUG_LEVEL int "TinyUSB log level (0-3)" default 0 diff --git a/components/arduino_tinyusb/include/tusb_config.h b/components/arduino_tinyusb/include/tusb_config.h index f4acaa232..90dd7f797 100755 --- a/components/arduino_tinyusb/include/tusb_config.h +++ b/components/arduino_tinyusb/include/tusb_config.h @@ -72,6 +72,10 @@ extern "C" { # define CONFIG_TINYUSB_VENDOR_ENABLED 0 #endif +#ifndef CONFIG_TINYUSB_NCM_ENABLED +# define CONFIG_TINYUSB_NCM_ENABLED 0 +#endif + /* */ /* COMMON CONFIGURATION */ /* */ @@ -113,6 +117,7 @@ extern "C" { #define CFG_TUD_DFU_RUNTIME CONFIG_TINYUSB_DFU_RT_ENABLED #define CFG_TUD_DFU CONFIG_TINYUSB_DFU_ENABLED #define CFG_TUD_VENDOR CONFIG_TINYUSB_VENDOR_ENABLED +#define CFG_TUD_NCM CONFIG_TINYUSB_NCM_ENABLED // CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE CONFIG_TINYUSB_CDC_RX_BUFSIZE diff --git a/patches/tinyusb_dcd_dwc2.diff b/components/arduino_tinyusb/patches/dcd_dwc2.patch similarity index 61% rename from patches/tinyusb_dcd_dwc2.diff rename to components/arduino_tinyusb/patches/dcd_dwc2.patch index 23755c8fc..a57df7ef6 100644 --- a/patches/tinyusb_dcd_dwc2.diff +++ b/components/arduino_tinyusb/patches/dcd_dwc2.patch @@ -1,31 +1,29 @@ ---- a/components/arduino_tinyusb/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c 2024-06-10 22:10:55.000000000 +0300 -+++ b/components/arduino_tinyusb/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c 2024-06-10 22:20:01.000000000 +0300 -@@ -186,6 +186,18 @@ - return true; - } - -+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +--- a/components/arduino_tinyusb/src/dcd_dwc2.c 2024-10-02 12:17:40.000000000 +0300 ++++ b/components/arduino_tinyusb/src/dcd_dwc2.c 2024-10-02 12:19:48.000000000 +0300 +@@ -316,6 +316,16 @@ + //-------------------------------------------------------------------- + // Endpoint + //-------------------------------------------------------------------- ++#if defined(TUP_USBIP_DWC2_ESP32) +// Keep count of how many FIFOs are in use +static uint8_t _allocated_fifos = 1; //FIFO0 is always in use + +// Will either return an unused FIFO number, or 0 if all are used. -+static uint8_t get_free_fifo(void) -+{ ++static uint8_t get_free_fifo(void) { + if (_allocated_fifos < 5) return _allocated_fifos++; + return 0; +} +#endif -+ + static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); -@@ -205,7 +217,18 @@ +@@ -336,7 +346,18 @@ dwc2->epout[epnum].doepctl = dxepctl; dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); } else { - dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); + uint8_t fifo_num = epnum; -+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) ++#if defined(TUP_USBIP_DWC2_ESP32) + // Special Case for EP5, which is used by CDC but not actually called by the driver + // we can give it a fake FIFO + if (epnum == 5) { @@ -33,51 +31,51 @@ + } else { + fifo_num = get_free_fifo(); + } -+ TU_ASSERT(fifo_num != 0); ++ //TU_ASSERT(fifo_num != 0); +#endif + dwc2->epin[epnum].diepctl = dxepctl | (fifo_num << DIEPCTL_TXFNUM_Pos); - dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); + dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum); } } -@@ -728,6 +751,10 @@ - // reset allocated fifo IN - _allocated_fifo_words_tx = 16; +@@ -850,6 +871,10 @@ + xfer_status[n][TUSB_DIR_IN].max_size = 0; + } -+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) ++#if defined(TUP_USBIP_DWC2_ESP32) + _allocated_fifos = 1; +#endif + - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); - } -@@ -1096,6 +1123,9 @@ + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); + +@@ -1204,6 +1229,9 @@ if (int_status & GINTSTS_USBRST) { // USBRST is start of reset. dwc2->gintsts = GINTSTS_USBRST; -+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) ++#if defined(TUP_USBIP_DWC2_ESP32) + _allocated_fifos = 1; +#endif bus_reset(rhport); } -@@ -1127,7 +1157,11 @@ +@@ -1235,7 +1263,11 @@ if (int_status & GINTSTS_USBSUSP) { dwc2->gintsts = GINTSTS_USBSUSP; - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + //dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) ++#if defined(TUP_USBIP_DWC2_ESP32) + _allocated_fifos = 1; +#endif } if (int_status & GINTSTS_WKUINT) { -@@ -1144,6 +1178,9 @@ +@@ -1252,6 +1284,9 @@ if (otg_int & GOTGINT_SEDET) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) ++#if defined(TUP_USBIP_DWC2_ESP32) + _allocated_fifos = 1; +#endif } diff --git a/components/arduino_tinyusb/src/dcd_dwc2.c b/components/arduino_tinyusb/src/dcd_dwc2.c index adf018fe8..8bcc98166 100644 --- a/components/arduino_tinyusb/src/dcd_dwc2.c +++ b/components/arduino_tinyusb/src/dcd_dwc2.c @@ -31,6 +31,9 @@ #if CFG_TUD_ENABLED && defined(TUP_USBIP_DWC2) +// Debug level for DWC2 +#define DWC2_DEBUG 2 + #include "device/dcd.h" #include "dwc2_type.h" @@ -43,7 +46,7 @@ #if defined(TUP_USBIP_DWC2_STM32) #include "dwc2_stm32.h" -#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#elif defined(TUP_USBIP_DWC2_ESP32) #include "dwc2_esp32.h" #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #include "dwc2_gd32.h" @@ -57,29 +60,26 @@ #error "Unsupported MCUs" #endif -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ +enum { + DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE(_dwc2_controller) +}; // DWC2 registers -#define DWC2_REG(_port) ((dwc2_regs_t*) _dwc2_controller[_port].reg_base) +//#define DWC2_REG(_port) ((dwc2_regs_t*) _dwc2_controller[_port].reg_base) -// Debug level for DWC2 -#define DWC2_DEBUG 2 - -#ifndef dcache_clean -#define dcache_clean(_addr, _size) -#endif - -#ifndef dcache_invalidate -#define dcache_invalidate(_addr, _size) -#endif +TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { + if (rhport >= DWC2_CONTROLLER_COUNT) { + // user mis-configured, ignore and use first controller + rhport = 0; + } + return (dwc2_regs_t*) _dwc2_controller[rhport].reg_base; +} -#ifndef dcache_clean_invalidate -#define dcache_clean_invalidate(_addr, _size) -#endif +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ -static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; +static CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; typedef struct { uint8_t* buffer; @@ -93,106 +93,235 @@ static xfer_ctl_t xfer_status[DWC2_EP_MAX][2]; #define XFER_CTL_BASE(_ep, _dir) (&xfer_status[_ep][_dir]) // EP0 transfers are limited to 1 packet - larger sizes has to be split -static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type +static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type +static uint16_t _dfifo_top; // top free location in FIFO RAM -// TX FIFO RAM allocation so far in words - RX FIFO size is readily available from dwc2->grxfsiz -static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) +// Number of IN endpoints active +static uint8_t _allocated_ep_in_count; // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by static bool _sof_en; -// Calculate the RX FIFO size according to minimum recommendations from reference manual -// RxFIFO = (5 * number of control endpoints + 8) + -// ((largest USB packet used / 4) + 1 for status information) + -// (2 * number of OUT endpoints) + 1 for Global NAK -// with number of control endpoints = 1 we have -// RxFIFO = 15 + (largest USB packet used / 4) + 2 * number of OUT endpoints -// we double the largest USB packet size to be able to hold up to 2 packets -static inline uint16_t calc_grxfsiz(uint16_t max_ep_size, uint8_t ep_count) { - return 15 + 2 * (max_ep_size / 4) + 2 * ep_count; +//-------------------------------------------------------------------- +// DMA +//-------------------------------------------------------------------- + +TU_ATTR_ALWAYS_INLINE static inline bool dma_enabled(const dwc2_regs_t* dwc2) { + #if !CFG_TUD_DWC2_DMA + (void) dwc2; + return false; + #else + // Internal DMA only + return (dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA); + #endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint16_t dma_cal_epfifo_base(uint8_t rhport) { + // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per endpoint direction + const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; + return dwc2_controller->ep_fifo_size/4 - 2*dwc2_controller->ep_count; } -TU_ATTR_ALWAYS_INLINE static inline void fifo_flush_tx(dwc2_regs_t* dwc2, uint8_t epnum) { +static void dma_setup_prepare(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { + if(dwc2->epout[0].doepctl & DOEPCTL_EPENA) { + return; + } + } + + // Receive only 1 packet + dwc2->epout[0].doeptsiz = (1 << DOEPTSIZ_STUPCNT_Pos) | (1 << DOEPTSIZ_PKTCNT_Pos) | (8 << DOEPTSIZ_XFRSIZ_Pos); + dwc2->epout[0].doepdma = (uintptr_t)_setup_packet; + dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; +} + +//--------------------------------------------------------------------+ +// Data FIFO +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_tx(dwc2_regs_t* dwc2, uint8_t epnum) { // flush TX fifo and wait for it cleared dwc2->grstctl = GRSTCTL_TXFFLSH | (epnum << GRSTCTL_TXFNUM_Pos); while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} } -TU_ATTR_ALWAYS_INLINE static inline void fifo_flush_rx(dwc2_regs_t* dwc2) { +TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx(dwc2_regs_t* dwc2) { // flush RX fifo and wait for it cleared dwc2->grstctl = GRSTCTL_RXFFLSH; while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} } -static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { +/* USB Data FIFO Layout + + The FIFO is split up into + - EPInfo: for storing DMA metadata, only required when use DMA. Maximum size is called + EP_LOC_CNT = ep_fifo_size - ghwcfg3.dfifo_depth. For value less than EP_LOC_CNT, gdfifocfg must be configured before + gahbcfg.dmaen is set + - Buffer mode: 1 word per endpoint direction + - Scatter/Gather DMA: 4 words per endpoint direction + - TX FIFO: one fifo for each IN endpoint. Size is dynamic depending on packet size, starting from top with EP0 IN. + - Shared RX FIFO: a shared fifo for all OUT endpoints. Typically, can hold up to 2 packets of the largest EP size. + + We allocated TX FIFO from top to bottom (using top pointer), this to allow the RX FIFO to grow dynamically which is + possible since the free space is located between the RX and TX FIFOs. + + ---------------- ep_fifo_size + | EPInfo | + | for DMA | + |-------------|-- gdfifocfg.EPINFOBASE (max is ghwcfg3.dfifo_depth) + | IN FIFO 0 | + | control | + |-------------| + | IN FIFO 1 | + |-------------| + | . . . . | + |-------------| + | IN FIFO n | + |-------------| + | FREE | + |-------------|-- GRXFSIZ (expandable) + | OUT FIFO | + | ( Shared ) | + --------------- 0 + + According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): + - Each EP IN needs at least max packet size + - All EP OUT shared a unique OUT FIFO which uses (for Slave or Buffer DMA, Scatt/Gather DMA use different formula): + - 13 for setup packets + control words (up to 3 setup packets). + - 1 for global NAK (not required/used here). + - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" + - 2 for each used OUT endpoint + + Therefore GRXFSIZ = 13 + 1 + 2 x (Largest-EPsize/4 + 1) + 2 x EPOUTnum +*/ + +TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_grxfsiz(uint16_t largest_ep_size, uint8_t ep_count) { + return 13 + 1 + 2 * ((largest_ep_size / 4) + 1) + 2 * ep_count; +} + +static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; + const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; + uint8_t const ep_count = dwc2_controller->ep_count; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); TU_ASSERT(epnum < ep_count); uint16_t fifo_size = tu_div_ceil(packet_size, 4); - - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // In FIFO is allocated by following rules: - // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". if (dir == TUSB_DIR_OUT) { // Calculate required size of RX FIFO - uint16_t const sz = calc_grxfsiz(4 * fifo_size, ep_count); - - // If size_rx needs to be extended check if possible and if so enlarge it - if (dwc2->grxfsiz < sz) { - TU_ASSERT(sz + _allocated_fifo_words_tx <= _dwc2_controller[rhport].ep_fifo_size / 4); + uint16_t const new_sz = calc_grxfsiz(4 * fifo_size, ep_count); - // Enlarge RX FIFO - dwc2->grxfsiz = sz; + // If size_rx needs to be extended check if there is enough free space + if (dwc2->grxfsiz < new_sz) { + TU_ASSERT(new_sz <= _dfifo_top); + dwc2->grxfsiz = new_sz; // Enlarge RX FIFO } } else { - // Note if The TXFELVL is configured as half empty. In order - // to be able to write a packet at that point, the fifo must be twice the max_size. + // Check IN endpoints concurrently active limit + if(_dwc2_controller->ep_in_count) { + TU_ASSERT(_allocated_ep_in_count < _dwc2_controller->ep_in_count); + _allocated_ep_in_count++; + } + + // If The TXFELVL is configured as half empty, the fifo must be twice the max_size. if ((dwc2->gahbcfg & GAHBCFG_TXFELVL) == 0) { fifo_size *= 2; } // Check if free space is available - TU_ASSERT(_allocated_fifo_words_tx + fifo_size + dwc2->grxfsiz <= _dwc2_controller[rhport].ep_fifo_size / 4); - _allocated_fifo_words_tx += fifo_size; - TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %" PRIu32, fifo_size * 4, - _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); + TU_ASSERT(_dfifo_top >= fifo_size + dwc2->grxfsiz); + _dfifo_top -= fifo_size; + TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, _dfifo_top); - // DIEPTXF starts at FIFO #1. // Both TXFD and TXSA are in unit of 32-bit words. - dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | - (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); + if (epnum == 0) { + dwc2->dieptxf0 = (fifo_size << DIEPTXF0_TX0FD_Pos) | _dfifo_top; + } else { + // DIEPTXF starts at FIFO #1. + dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | _dfifo_top; + } } return true; } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +static void dfifo_init(uint8_t rhport) { + const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + dwc2->grxfsiz = calc_grxfsiz(CFG_TUD_ENDPOINT0_SIZE, dwc2_controller->ep_count); + + if(dma_enabled(dwc2)) { + // DMA use last DFIFO to store metadata + _dfifo_top = dma_cal_epfifo_base(rhport); + }else { + _dfifo_top = dwc2_controller->ep_fifo_size / 4; + } + + // Allocate FIFO for EP0 IN + dfifo_alloc(rhport, 0x80, CFG_TUD_ENDPOINT0_SIZE); +} + +// Read a single data packet from receive FIFO +static void dfifo_read_packet(uint8_t rhport, uint8_t* dst, uint16_t len) { + (void) rhport; + + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + volatile const uint32_t* rx_fifo = dwc2->fifo[0]; + + // Reading full available 32 bit words from fifo + uint16_t full_words = len >> 2; + while (full_words--) { + tu_unaligned_write32(dst, *rx_fifo); + dst += 4; + } + + // Read the remaining 1-3 bytes from fifo + uint8_t const bytes_rem = len & 0x03; + if (bytes_rem != 0) { + uint32_t const tmp = *rx_fifo; + dst[0] = tu_u32_byte0(tmp); + if (bytes_rem > 1) dst[1] = tu_u32_byte1(tmp); + if (bytes_rem > 2) dst[2] = tu_u32_byte2(tmp); + } +} + +// Write a single data packet to EPIN FIFO +static void dfifo_write_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const* src, uint16_t len) { + (void) rhport; + + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num]; + + // Pushing full available 32 bit words to fifo + uint16_t full_words = len >> 2; + while (full_words--) { + *tx_fifo = tu_unaligned_read32(src); + src += 4; + } + + // Write the remaining 1-3 bytes into fifo + uint8_t const bytes_rem = len & 0x03; + if (bytes_rem) { + uint32_t tmp_word = src[0]; + if (bytes_rem > 1) tmp_word |= (src[1] << 8); + if (bytes_rem > 2) tmp_word |= (src[2] << 16); + + *tx_fifo = tmp_word; + } +} + +//-------------------------------------------------------------------- +// Endpoint +//-------------------------------------------------------------------- +#if defined(TUP_USBIP_DWC2_ESP32) // Keep count of how many FIFOs are in use static uint8_t _allocated_fifos = 1; //FIFO0 is always in use // Will either return an unused FIFO number, or 0 if all are used. -static uint8_t get_free_fifo(void) -{ +static uint8_t get_free_fifo(void) { if (_allocated_fifos < 5) return _allocated_fifos++; return 0; } @@ -218,7 +347,7 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); } else { uint8_t fifo_num = epnum; -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if defined(TUP_USBIP_DWC2_ESP32) // Special Case for EP5, which is used by CDC but not actually called by the driver // we can give it a fake FIFO if (epnum == 5) { @@ -226,9 +355,10 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin } else { fifo_num = get_free_fifo(); } + //TU_ASSERT(fifo_num != 0); #endif dwc2->epin[epnum].diepctl = dxepctl | (fifo_num << DIEPCTL_TXFNUM_Pos); - dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); + dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum); } } @@ -258,7 +388,7 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { } // Flush the FIFO, and wait until we have confirmed it cleared. - fifo_flush_tx(dwc2, epnum); + dfifo_flush_tx(dwc2, epnum); } else { dwc2_epout_t* epout = dwc2->epout; @@ -294,6 +424,8 @@ static void bus_reset(uint8_t rhport) { _sof_en = false; + _allocated_ep_in_count = 1; + // clear device address dwc2->dcfg &= ~DCFG_DAD_Msk; @@ -309,79 +441,28 @@ static void bus_reset(uint8_t rhport) { } } - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); // 3. Set up interrupt mask dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // The FIFO is split up in a lower part where the RX FIFO is located and an upper part where the TX FIFOs start. - // We do this to allow the RX FIFO to grow dynamically which is possible since the free space is located - // between the RX and TX FIFOs. This is required by ISO OUT EPs which need a bigger FIFO than the standard - // configuration done below. - // - // Dynamically FIFO sizes are of interest only for ISO EPs since all others are usually not opened and closed. - // All EPs other than ISO are opened as soon as the driver starts up i.e. when the host sends a - // configure interface command. Hence, all IN EPs other the ISO will be located at the top. IN ISO EPs are usually - // opened when the host sends an additional command: setInterface. At this point in time - // the ISO EP will be located next to the free space and can change its size. In case more IN EPs change its size - // an additional memory - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): - // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN - // - // - All EP OUT shared a unique OUT FIFO which uses - // - 13 for setup packets + control words (up to 3 setup packets). - // - 1 for global NAK (not required/used here). - // - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" - // - 2 for each used OUT endpoint - // - // Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum - // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x ep_count = 47 + 2 x ep_count - // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x ep_count = 271 + 2 x ep_count - // - // NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge - // of the overall picture yet. We will use the worst scenario: largest possible + ep_count - // - // For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO - // are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to - // overwrite this. - - // EP0 out max is 64 - dwc2->grxfsiz = calc_grxfsiz(64, ep_count); - - // Setup the control endpoint 0 - _allocated_fifo_words_tx = 16; - - // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); + dfifo_init(rhport); // Fixed control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); + dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos); + xfer_status[0][TUSB_DIR_OUT].max_size = 64; xfer_status[0][TUSB_DIR_IN].max_size = 64; - dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); + if(dma_enabled(dwc2)) { + dma_setup_prepare(rhport); + } else { + dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); + } dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; } @@ -391,11 +472,11 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir); // EP0 is limited to one packet each xfer // We use multiple transaction of xfer->max_size length to get a whole transfer done if (epnum == 0) { - xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir); total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); ep0_pending[dir] -= total_bytes; } @@ -408,17 +489,31 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); - epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + if(dma_enabled(dwc2)) { + epin[epnum].diepdma = (uintptr_t)xfer->buffer; - // For ISO endpoint set correct odd/even bit for next frame. - if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); - } - // Enable fifo empty interrupt only if there are something to put in the fifo. - if (total_bytes != 0) { - dwc2->diepempmsk |= (1 << epnum); + // For ISO endpoint set correct odd/even bit for next frame. + if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); + epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + } + + epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + } else { + + epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + + // For ISO endpoint set correct odd/even bit for next frame. + if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); + epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + } + // Enable fifo empty interrupt only if there are something to put in the fifo. + if (total_bytes != 0) { + dwc2->diepempmsk |= (1 << epnum); + } } } else { dwc2_epout_t* epout = dwc2->epout; @@ -428,31 +523,24 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epout[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) | ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk); - epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; if ((epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && XFER_CTL_BASE(epnum, dir)->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); } + + if(dma_enabled(dwc2)) { + epout[epnum].doepdma = (uintptr_t)xfer->buffer; + } + + epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; } } /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -#if CFG_TUSB_DEBUG >= DWC2_DEBUG -void print_dwc2_info(dwc2_regs_t* dwc2) { - // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 - // use dwc2_info.py/md for bit-field value and comparison with other ports - volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; - TU_LOG(DWC2_DEBUG, "guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); - for (size_t i = 0; i < 5; i++) { - TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 ", ", p[i]); - } - TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 "\r\n", p[5]); -} -#endif static void reset_core(dwc2_regs_t* dwc2) { // reset core @@ -471,13 +559,10 @@ static void reset_core(dwc2_regs_t* dwc2) { static bool phy_hs_supported(dwc2_regs_t* dwc2) { (void) dwc2; -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - // note: esp32 incorrect report its hs_phy_type as utmi - return false; -#elif !TUD_OPT_HIGH_SPEED +#if !TUD_OPT_HIGH_SPEED return false; #else - return dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; + return dwc2->ghwcfg2_bm.hs_phy_type != GHWCFG2_HSPHY_NOT_SUPPORTED; #endif } @@ -488,7 +573,7 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { dwc2->gusbcfg |= GUSBCFG_PHYSEL; // MCU specific PHY init before reset - dwc2_phy_init(dwc2, HS_PHY_TYPE_NONE); + dwc2_phy_init(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); // Reset core after selecting PHY reset_core(dwc2); @@ -499,7 +584,7 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos); // MCU specific PHY update post reset - dwc2_phy_update(dwc2, HS_PHY_TYPE_NONE); + dwc2_phy_update(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); // set max speed dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos); @@ -511,7 +596,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // De-select FS PHY gusbcfg &= ~GUSBCFG_PHYSEL; - if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { + if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) { TU_LOG(DWC2_DEBUG, "Highspeed ULPI PHY init\r\n"); // Select ULPI @@ -532,7 +617,9 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); // Set 16-bit interface if supported - if (dwc2->ghwcfg4_bm.utmi_phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; + if (dwc2->ghwcfg4_bm.phy_data_width) { + gusbcfg |= GUSBCFG_PHYIF16; + } } // Apply config @@ -548,7 +635,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // - 9 if using 8-bit PHY interface // - 5 if using 16-bit PHY interface gusbcfg &= ~GUSBCFG_TRDT_Msk; - gusbcfg |= (dwc2->ghwcfg4_bm.utmi_phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; + gusbcfg |= (dwc2->ghwcfg4_bm.phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; dwc2->gusbcfg = gusbcfg; // MCU specific PHY update post reset @@ -561,17 +648,26 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347) - if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) dcfg |= DCFG_XCVRDLY; + if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) { + dcfg |= DCFG_XCVRDLY; + } dwc2->dcfg = dcfg; } static bool check_dwc2(dwc2_regs_t* dwc2) { #if CFG_TUSB_DEBUG >= DWC2_DEBUG - print_dwc2_info(dwc2); + // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 + // Run 'dwc2_info.py render-md' and check dwc2_info.md for bit-field value and comparison with other ports + volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; + TU_LOG1("guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); + for (size_t i = 0; i < 5; i++) { + TU_LOG1("0x%08" PRIX32 ", ", p[i]); + } + TU_LOG1("0x%08" PRIX32 "\r\n", p[5]); #endif - // For some reasons: GD32VF103 snpsid and all hwcfg register are always zero (skip it) + // For some reason: GD32VF103 snpsid and all hwcfg register are always zero (skip it) (void) dwc2; #if !TU_CHECK_MCU(OPT_MCU_GD32VF103) uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; @@ -587,12 +683,9 @@ void dcd_init(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled - if (!check_dwc2(dwc2)) return; + TU_ASSERT(check_dwc2(dwc2), ); dcd_disconnect(rhport); - // max number of endpoints & total_fifo_size are: - // hw_cfg2->num_dev_ep, hw_cfg2->total_fifo_size - if (phy_hs_supported(dwc2)) { phy_hs_init(dwc2); // Highspeed } else { @@ -622,8 +715,8 @@ void dcd_init(uint8_t rhport) { // (non zero-length packet), send STALL back and discard. dwc2->dcfg |= DCFG_NZLSOHSK; - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); // Clear all interrupts uint32_t int_mask = dwc2->gintsts; @@ -632,12 +725,21 @@ void dcd_init(uint8_t rhport) { dwc2->gotgint |= int_mask; // Required as part of core initialization. - dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_RXFLVLM | - GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; + dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; // Configure TX FIFO empty level for interrupt. Default is complete empty dwc2->gahbcfg |= GAHBCFG_TXFELVL; + if (dma_enabled(dwc2)) { + const uint16_t epinfo_base = dma_cal_epfifo_base(rhport); + dwc2->gdfifocfg = (epinfo_base << GDFIFOCFG_EPINFOBASE_SHIFT) | epinfo_base; + + // DMA seems to be only settable after a core reset + dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2; + }else { + dwc2->gintmsk |= GINTMSK_RXFLVLM; + } + // Enable global interrupt dwc2->gahbcfg |= GAHBCFG_GINT; @@ -689,12 +791,34 @@ void dcd_remote_wakeup(uint8_t rhport) { void dcd_connect(uint8_t rhport) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + +#ifdef TUP_USBIP_DWC2_ESP32 + usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; + conf.pad_pull_override = 0; + conf.dp_pullup = 0; + conf.dp_pulldown = 0; + conf.dm_pullup = 0; + conf.dm_pulldown = 0; + USB_WRAP.otg_conf = conf; +#endif + dwc2->dctl &= ~DCTL_SDIS; } void dcd_disconnect(uint8_t rhport) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + +#ifdef TUP_USBIP_DWC2_ESP32 + usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; + conf.pad_pull_override = 1; + conf.dp_pullup = 0; + conf.dp_pulldown = 1; + conf.dm_pullup = 0; + conf.dm_pulldown = 1; + USB_WRAP.otg_conf = conf; +#endif + dwc2->dctl |= DCTL_SDIS; } @@ -718,7 +842,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) { *------------------------------------------------------------------*/ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { - TU_ASSERT(fifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt))); + TU_ASSERT(dfifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt))); edpt_activate(rhport, desc_edpt); return true; } @@ -728,6 +852,8 @@ void dcd_edpt_close_all(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; + _allocated_ep_in_count = 1; + // Disable non-control interrupt dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); @@ -745,30 +871,25 @@ void dcd_edpt_close_all(uint8_t rhport) { xfer_status[n][TUSB_DIR_IN].max_size = 0; } - // reset allocated fifo OUT - dwc2->grxfsiz = calc_grxfsiz(64, ep_count); - // reset allocated fifo IN - _allocated_fifo_words_tx = 16; - -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if defined(TUP_USBIP_DWC2_ESP32) _allocated_fifos = 1; #endif - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); + + dfifo_init(rhport); // re-init dfifo } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { - TU_ASSERT(fifo_alloc(rhport, ep_addr, largest_packet_size)); + TU_ASSERT(dfifo_alloc(rhport, ep_addr, largest_packet_size)); return true; } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { // Disable EP to clear potential incomplete transfers edpt_disable(rhport, p_endpoint_desc->bEndpointAddress, false); - edpt_activate(rhport, p_endpoint_desc); - return true; } @@ -835,6 +956,9 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { edpt_disable(rhport, ep_addr, true); + if((tu_edpt_number(ep_addr) == 0) && dma_enabled(DWC2_REG(rhport))) { + dma_setup_prepare(rhport); + } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -855,56 +979,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { } } -/*------------------------------------------------------------------*/ - -// Read a single data packet from receive FIFO -static void read_fifo_packet(uint8_t rhport, uint8_t* dst, uint16_t len) { - (void) rhport; - - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - volatile const uint32_t* rx_fifo = dwc2->fifo[0]; - - // Reading full available 32 bit words from fifo - uint16_t full_words = len >> 2; - while (full_words--) { - tu_unaligned_write32(dst, *rx_fifo); - dst += 4; - } - - // Read the remaining 1-3 bytes from fifo - uint8_t const bytes_rem = len & 0x03; - if (bytes_rem != 0) { - uint32_t const tmp = *rx_fifo; - dst[0] = tu_u32_byte0(tmp); - if (bytes_rem > 1) dst[1] = tu_u32_byte1(tmp); - if (bytes_rem > 2) dst[2] = tu_u32_byte2(tmp); - } -} - -// Write a single data packet to EPIN FIFO -static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const* src, uint16_t len) { - (void) rhport; - - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num]; - - // Pushing full available 32 bit words to fifo - uint16_t full_words = len >> 2; - while (full_words--) { - *tx_fifo = tu_unaligned_read32(src); - src += 4; - } - - // Write the remaining 1-3 bytes into fifo - uint8_t const bytes_rem = len & 0x03; - if (bytes_rem) { - uint32_t tmp_word = src[0]; - if (bytes_rem > 1) tmp_word |= (src[1] << 8); - if (bytes_rem > 2) tmp_word |= (src[2] << 16); - - *tx_fifo = tmp_word; - } -} +//-------------------------------------------------------------------- +// Interrupt Handler +//-------------------------------------------------------------------- static void handle_rxflvl_irq(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); @@ -958,7 +1035,7 @@ static void handle_rxflvl_irq(uint8_t rhport) { tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void*) (uintptr_t) rx_fifo, bcnt); } else { // Linear buffer - read_fifo_packet(rhport, xfer->buffer, bcnt); + dfifo_read_packet(rhport, xfer->buffer, bcnt); // Increment pointer to xfer data xfer->buffer += bcnt; @@ -982,21 +1059,7 @@ static void handle_rxflvl_irq(uint8_t rhport) { // XFRC complete is additionally generated when // - setup packet is received // - complete the data stage of control write is complete - if ((epnum == 0) && (bcnt == 0) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - uint32_t doepint = epout->doepint; - - if (doepint & (DOEPINT_STPKTRX | DOEPINT_OTEPSPR)) { - // skip this "no-data" transfer complete event - // Note: STPKTRX will be clear later by setup received handler - uint32_t clear_flags = DOEPINT_XFRC; - - if (doepint & DOEPINT_OTEPSPR) clear_flags |= DOEPINT_OTEPSPR; - - epout->doepint = clear_flags; - - // TU_LOG(DWC2_DEBUG, " FIX extra transfer complete on setup/data compete\r\n"); - } - } + // It will be handled in handle_epout_irq() break; default: // Invalid @@ -1017,18 +1080,7 @@ static void handle_epout_irq(uint8_t rhport) { uint32_t const doepint = epout->doepint; - // SETUP packet Setup Phase done. - if (doepint & DOEPINT_STUP) { - uint32_t clear_flag = DOEPINT_STUP; - - // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - clear_flag |= DOEPINT_STPKTRX; - } - - epout->doepint = clear_flag; - dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); - } + TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, ); // OUT XFER complete if (epout->doepint & DOEPINT_XFRC) { @@ -1036,13 +1088,65 @@ static void handle_epout_irq(uint8_t rhport) { xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + if(dma_enabled(dwc2)) { + if (doepint & DOEPINT_STUP) { + // STPKTRX is only available for version from 3_00a + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; + } + } else if (doepint & DOEPINT_OTEPSPR) { + epout->doepint = DOEPINT_OTEPSPR; + } else { + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; + } else { + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { + // Fix packet length + uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; + xfer->total_len -= remain; + // this is ZLP, so prepare EP0 for next setup + if(n == 0 && xfer->total_len == 0) { + dma_setup_prepare(rhport); + } + + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + } } else { - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_STPKTRX; + } else { + if ((doepint & DOEPINT_OTEPSPR) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_OTEPSPR; + } + + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + } + } + + // SETUP packet Setup Phase done. + if (doepint & DOEPINT_STUP) { + epout->doepint = DOEPINT_STUP; + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; } + if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + dma_setup_prepare(rhport); + } + + dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); } } } @@ -1068,6 +1172,9 @@ static void handle_epin_irq(uint8_t rhport) { // Schedule another packet to be transmitted. edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); } else { + if((n == 0) && dma_enabled(dwc2)) { + dma_setup_prepare(rhport); + } dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); } } @@ -1097,7 +1204,7 @@ static void handle_epin_irq(uint8_t rhport) { volatile uint32_t* tx_fifo = dwc2->fifo[n]; tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*) (uintptr_t) tx_fifo, packet_size); } else { - write_fifo_packet(rhport, n, xfer->buffer, packet_size); + dfifo_write_packet(rhport, n, xfer->buffer, packet_size); // Increment pointer to xfer data xfer->buffer += packet_size; @@ -1122,7 +1229,7 @@ void dcd_int_handler(uint8_t rhport) { if (int_status & GINTSTS_USBRST) { // USBRST is start of reset. dwc2->gintsts = GINTSTS_USBRST; -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if defined(TUP_USBIP_DWC2_ESP32) _allocated_fifos = 1; #endif bus_reset(rhport); @@ -1158,7 +1265,7 @@ void dcd_int_handler(uint8_t rhport) { dwc2->gintsts = GINTSTS_USBSUSP; //dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if defined(TUP_USBIP_DWC2_ESP32) _allocated_fifos = 1; #endif } @@ -1177,7 +1284,7 @@ void dcd_int_handler(uint8_t rhport) { if (otg_int & GOTGINT_SEDET) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if defined(TUP_USBIP_DWC2_ESP32) _allocated_fifos = 1; #endif } @@ -1231,25 +1338,13 @@ void dcd_int_handler(uint8_t rhport) { // } } -#if defined(TUP_USBIP_DWC2_TEST_MODE) && CFG_TUD_TEST_MODE - -bool dcd_check_test_mode_support(test_mode_t test_selector) { - // Check if test mode selector is unsupported - if (TEST_FORCE_ENABLE < test_selector || TEST_J > test_selector) { - return false; - } - - return true; -} - -void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { - // Get port address... +#if CFG_TUD_TEST_MODE +void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Enable the test mode - dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); + dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (((uint8_t) test_selector) << DCTL_TCTL_Pos); } - -#endif /* TUP_USBIP_DWC2_TEST_MODE && CFG_TUD_TEST_MODE */ +#endif #endif diff --git a/components/arduino_tinyusb/src/dcd_esp32sx.c b/components/arduino_tinyusb/src/dcd_esp32sx.c deleted file mode 100755 index 324aad595..000000000 --- a/components/arduino_tinyusb/src/dcd_esp32sx.c +++ /dev/null @@ -1,965 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft, 2019 William D. Jones for Adafruit Industries - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * Additions Copyright (c) 2020, Espressif Systems (Shanghai) Co. Ltd. - * - * 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 "tusb_option.h" - -#if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && CFG_TUD_ENABLED) - -// Espressif -#include "freertos/xtensa_api.h" -#include "esp_intr_alloc.h" -#include "esp_log.h" -#include "soc/dport_reg.h" -#include "soc/gpio_sig_map.h" -#include "soc/usb_periph.h" -#include "soc/usb_reg.h" -#include "soc/usb_struct.h" -#include "soc/periph_defs.h" // for interrupt source -#include "soc/usb_wrap_struct.h" - -#include "device/dcd.h" - -#ifndef USB_OUT_EP_NUM -#define USB_OUT_EP_NUM ((int) (sizeof(USB0.out_ep_reg) / sizeof(USB0.out_ep_reg[0]))) -#endif - -#ifndef USB_IN_EP_NUM -#define USB_IN_EP_NUM ((int) (sizeof(USB0.in_ep_reg) / sizeof(USB0.in_ep_reg[0]))) -#endif - -// Max number of bi-directional endpoints including EP0 -// Note: ESP32S2 specs say there are only up to 5 IN active endpoints include EP0 -// We should probably prohibit enabling Endpoint IN > 4 (not done yet) -#define EP_MAX USB_OUT_EP_NUM - -// FIFO size in bytes -#define EP_FIFO_SIZE 1024 - -// Max number of IN EP FIFOs -#define EP_FIFO_NUM 5 - -typedef struct { - uint8_t *buffer; - // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API - uint16_t total_len; - uint16_t queued_len; - uint16_t max_size; - bool short_packet; - uint8_t interval; -} xfer_ctl_t; - -static const char *TAG = "TUSB:DCD"; -static intr_handle_t usb_ih; - - -static uint32_t _setup_packet[2]; - -#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] -static xfer_ctl_t xfer_status[EP_MAX][2]; - -// Keep count of how many FIFOs are in use -static uint8_t _allocated_fifos = 1; //FIFO0 is always in use - -// Will either return an unused FIFO number, or 0 if all are used. -static uint8_t get_free_fifo(void) -{ - if (_allocated_fifos < EP_FIFO_NUM) return _allocated_fifos++; - return 0; -} - -// Setup the control endpoint 0. -static void bus_reset(void) -{ - for (int ep_num = 0; ep_num < USB_OUT_EP_NUM; ep_num++) { - USB0.out_ep_reg[ep_num].doepctl |= USB_DO_SNAK0_M; // DOEPCTL0_SNAK - } - - // clear device address - USB0.dcfg &= ~USB_DEVADDR_M; - - USB0.daintmsk = USB_OUTEPMSK0_M | USB_INEPMSK0_M; - USB0.doepmsk = USB_SETUPMSK_M | USB_XFERCOMPLMSK; - USB0.diepmsk = USB_TIMEOUTMSK_M | USB_DI_XFERCOMPLMSK_M /*| USB_INTKNTXFEMPMSK_M*/; - - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO MAX | - // --------------- - // | ... | - // --------------- y + x + 16 + GRXFSIZ - // | IN FIFO 2 | - // --------------- x + 16 + GRXFSIZ - // | IN FIFO 1 | - // --------------- 16 + GRXFSIZ - // | IN FIFO 0 | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): - // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN - // - // - All EP OUT shared a unique OUT FIFO which uses - // * 10 locations in hardware for setup packets + setup control words (up to 3 setup packets). - // * 2 locations for OUT endpoint control words. - // * 16 for largest packet size of 64 bytes. ( TODO Highspeed is 512 bytes) - // * 1 location for global NAK (not required/used here). - // * It is recommended to allocate 2 times the largest packet size, therefore - // Recommended value = 10 + 1 + 2 x (16+2) = 47 --> Let's make it 52 - USB0.grstctl |= 0x10 << USB_TXFNUM_S; // fifo 0x10, - USB0.grstctl |= USB_TXFFLSH_M; // Flush fifo - USB0.grxfsiz = 52; - - // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - USB0.gnptxfsiz = (16 << USB_NPTXFDEP_S) | (USB0.grxfsiz & 0x0000ffffUL); - - // Ready to receive SETUP packet - USB0.out_ep_reg[0].doeptsiz |= USB_SUPCNT0_M; - - USB0.gintmsk |= USB_IEPINTMSK_M | USB_OEPINTMSK_M; -} - -static void enum_done_processing(void) -{ - ESP_EARLY_LOGV(TAG, "dcd_int_handler - Speed enumeration done! Sending DCD_EVENT_BUS_RESET then"); - // On current silicon on the Full Speed core, speed is fixed to Full Speed. - // However, keep for debugging and in case Low Speed is ever supported. - uint32_t enum_spd = (USB0.dsts >> USB_ENUMSPD_S) & (USB_ENUMSPD_V); - - // Maximum packet size for EP 0 is set for both directions by writing DIEPCTL - if (enum_spd == 0x03) { // Full-Speed (PHY on 48 MHz) - USB0.in_ep_reg[0].diepctl &= ~USB_D_MPS0_V; // 64 bytes - USB0.in_ep_reg[0].diepctl &= ~USB_D_STALL0_M; // clear Stall - xfer_status[0][TUSB_DIR_OUT].max_size = 64; - xfer_status[0][TUSB_DIR_IN].max_size = 64; - } else { - USB0.in_ep_reg[0].diepctl |= USB_D_MPS0_V; // 8 bytes - USB0.in_ep_reg[0].diepctl &= ~USB_D_STALL0_M; // clear Stall - xfer_status[0][TUSB_DIR_OUT].max_size = 8; - xfer_status[0][TUSB_DIR_IN].max_size = 8; - } -} - - -/*------------------------------------------------------------------*/ -/* Controller API - *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ - ESP_LOGV(TAG, "DCD init - Start"); - - bool did_persist = (USB_WRAP.date.val & (1 << 31)) != 0; - - if (did_persist) { - //Clear persistence of USB peripheral through reset - USB_WRAP.date.val = 0; - } else { - // A. Disconnect - ESP_LOGV(TAG, "DCD init - Soft DISCONNECT and Setting up"); - USB0.dctl |= USB_SFTDISCON_M; // Soft disconnect - - // B. Programming DCFG - /* If USB host misbehaves during status portion of control xfer - (non zero-length packet), send STALL back and discard. Full speed. */ - USB0.dcfg |= USB_NZSTSOUTHSHK_M | // NonZero .... STALL - (3 << 0); // dev speed: fullspeed 1.1 on 48 mhz // TODO no value in usb_reg.h (IDF-1476) - } - - USB0.gahbcfg |= USB_NPTXFEMPLVL_M | USB_GLBLLNTRMSK_M; // Global interruptions ON - USB0.gusbcfg |= USB_FORCEDEVMODE_M; // force devmode - USB0.gotgctl &= ~(USB_BVALIDOVVAL_M | USB_BVALIDOVEN_M | USB_VBVALIDOVVAL_M); //no overrides - - // C. Setting SNAKs, then connect - for (int n = 0; n < USB_OUT_EP_NUM; n++) { - USB0.out_ep_reg[n].doepctl |= USB_DO_SNAK0_M; // DOEPCTL0_SNAK - } - - if (!did_persist) { - // D. Interruption masking - USB0.gintmsk = 0; //mask all - USB0.gotgint = ~0U; //clear OTG ints - USB0.gintsts = ~0U; //clear pending ints - } - - USB0.gintmsk = USB_OTGINTMSK_M | - USB_MODEMISMSK_M | - USB_RXFLVIMSK_M | - USB_ERLYSUSPMSK_M | - USB_USBSUSPMSK_M | - USB_USBRSTMSK_M | - USB_ENUMDONEMSK_M | - USB_RESETDETMSK_M | - USB_DISCONNINTMSK_M; // host most only - if (did_persist) { - USB0.grstctl &= ~USB_TXFNUM_M; - USB0.grstctl |= 0x10 << USB_TXFNUM_S; - USB0.grstctl |= USB_TXFFLSH; - USB0.grxfsiz = 52; - - for (int n = 0; n < USB_IN_EP_NUM; n++) { - USB0.in_ep_reg[n].diepint = USB_D_XFERCOMPL0_M | USB_D_TXFEMP0_M; - USB0.in_ep_reg[n].diepctl &= ~USB_D_STALL0_M; // clear Stall - USB0.in_ep_reg[n].diepctl |= USB_D_CNAK0 | USB_D_EPENA0; // clear NAK - } - USB0.dtknqr4_fifoemptymsk &= ~(0x7F); - - USB0.gnptxfsiz = (16 << USB_NPTXFDEP_S) | (USB0.grxfsiz & 0x0000ffffUL); - - USB0.daintmsk |= USB_OUTEPMSK0_M | USB_INEPMSK0_M; - USB0.doepmsk |= USB_SETUP0 | USB_XFERCOMPLMSK; - USB0.diepmsk |= USB_TIMEOUTMSK_M | USB_DI_XFERCOMPLMSK_M;//USB_INEPNAKEFFMSK - - USB0.gintmsk |= USB_IEPINTMSK_M | USB_OEPINTMSK_M; - USB0.gotgint = ~0; //clear OTG ints - USB0.gintsts = ~0; //clear pending ints - enum_done_processing(); - dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); - tusb_control_request_t request = { - .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT }, - .bRequest = TUSB_REQ_SET_CONFIGURATION, - .wValue = 1, - .wIndex = 0, - .wLength = 0 - }; - dcd_event_setup_received(0, (uint8_t *)&request, true); - } else { - dcd_connect(rhport); - } -} - -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; - ESP_LOGV(TAG, "DCD init - Set address : %u", dev_addr); - USB0.dcfg |= ((dev_addr & USB_DEVADDR_V) << USB_DEVADDR_S); - // Response with status after changing device address - dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); -} - -void dcd_remote_wakeup(uint8_t rhport) -{ - (void)rhport; - - // set remote wakeup - USB0.dctl |= USB_RMTWKUPSIG_M; - - // enable SOF to detect bus resume - USB0.gintsts = USB_SOF_M; - USB0.gintmsk |= USB_SOFMSK_M; - - // Per specs: remote wakeup signal bit must be clear within 1-15ms - vTaskDelay(pdMS_TO_TICKS(1)); - - USB0.dctl &= ~USB_RMTWKUPSIG_M; -} - -// connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) -{ - (void) rhport; - USB0.dctl &= ~USB_SFTDISCON_M; -} - -// disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) -{ - (void) rhport; - USB0.dctl |= USB_SFTDISCON_M; -} - -void dcd_sof_enable(uint8_t rhport, bool en) -{ - (void) rhport; - (void) en; - - // TODO implement later -} - -/*------------------------------------------------------------------*/ -/* DCD Endpoint port - *------------------------------------------------------------------*/ - -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) -{ - ESP_LOGV(TAG, "DCD endpoint opened"); - (void)rhport; - - usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); - usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); - - uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - - TU_ASSERT(epnum < EP_MAX); - - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); - xfer->max_size = tu_edpt_packet_size(desc_edpt); - xfer->interval = desc_edpt->bInterval; - - if (dir == TUSB_DIR_OUT) { - out_ep[epnum].doepctl &= ~(USB_D_EPTYPE0_M | USB_D_MPS0_M); - out_ep[epnum].doepctl |= USB_USBACTEP1_M | - desc_edpt->bmAttributes.xfer << USB_EPTYPE1_S | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_DO_SETD0PID1_M : 0) | - xfer->max_size << USB_MPS1_S; - USB0.daintmsk |= (1 << (16 + epnum)); - } else { - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO MAX | - // --------------- - // | ... | - // --------------- y + x + 16 + GRXFSIZ - // | IN FIFO 2 | - // --------------- x + 16 + GRXFSIZ - // | IN FIFO 1 | - // --------------- 16 + GRXFSIZ - // | IN FIFO 0 | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // Since OUT FIFO = GRXFSIZ, FIFO 0 = 16, for simplicity, we equally allocated for the rest of endpoints - // - Size : (FIFO_SIZE/4 - GRXFSIZ - 16) / (EP_MAX-1) - // - Offset: GRXFSIZ + 16 + Size*(epnum-1) - // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". - - uint8_t fifo_num = 0; - // Special Case for EP5, which is used by CDC but not actually called by the driver - // we can give it a fake FIFO - if (epnum == 5) { - fifo_num = EP_FIFO_NUM; - } else { - fifo_num = get_free_fifo(); - } - TU_ASSERT(fifo_num != 0); - - in_ep[epnum].diepctl &= ~(USB_D_TXFNUM1_M | USB_D_EPTYPE1_M | USB_DI_SETD0PID1 | USB_D_MPS1_M); - in_ep[epnum].diepctl |= USB_D_USBACTEP1_M | - fifo_num << USB_D_TXFNUM1_S | - desc_edpt->bmAttributes.xfer << USB_D_EPTYPE1_S | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? (1 << USB_DI_SETD0PID1_S) : 0) | - xfer->max_size << 0; - - USB0.daintmsk |= (1 << (0 + epnum)); - - // Both TXFD and TXSA are in unit of 32-bit words. - // IN FIFO 0 was configured during enumeration, hence the "+ 16". - uint16_t const allocated_size = (USB0.grxfsiz & 0x0000ffff) + 16; - uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_FIFO_NUM-1); - uint32_t const fifo_offset = allocated_size + fifo_size*(fifo_num-1); - - // DIEPTXF starts at FIFO #1. - USB0.dieptxf[epnum - 1] = (fifo_size << USB_NPTXFDEP_S) | fifo_offset; - } - return true; -} - -void dcd_edpt_close_all(uint8_t rhport) -{ - (void) rhport; - - usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); - usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); - - // Disable non-control interrupt - USB0.daintmsk = USB_OUTEPMSK0_M | USB_INEPMSK0_M; - - for(uint8_t n = 1; n < EP_MAX; n++) - { - // disable OUT endpoint - out_ep[n].doepctl = 0; - xfer_status[n][TUSB_DIR_OUT].max_size = 0; - - // disable IN endpoint - in_ep[n].diepctl = 0; - xfer_status[n][TUSB_DIR_IN].max_size = 0; - } - - _allocated_fifos = 1; -} - -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ - (void)rhport; - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->buffer = buffer; - // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API - xfer->total_len = total_bytes; - xfer->queued_len = 0; - xfer->short_packet = false; - - uint16_t num_packets = (total_bytes / xfer->max_size); - uint8_t short_packet_size = total_bytes % xfer->max_size; - - // Zero-size packet is special case. - if (short_packet_size > 0 || (total_bytes == 0)) { - num_packets++; - } - - ESP_LOGV(TAG, "Transfer <-> EP%i, %s, pkgs: %i, bytes: %i", - epnum, ((dir == TUSB_DIR_IN) ? "USB0.HOST (in)" : "HOST->DEV (out)"), - num_packets, total_bytes); - - // IN and OUT endpoint xfers are interrupt-driven, we just schedule them - // here. - if (dir == TUSB_DIR_IN) { - // A full IN transfer (multiple packets, possibly) triggers XFRC. - USB0.in_ep_reg[epnum].dieptsiz = (num_packets << USB_D_PKTCNT0_S) | total_bytes; - USB0.in_ep_reg[epnum].diepctl |= USB_D_EPENA1_M | USB_D_CNAK1_M; // Enable | CNAK - - // For ISO endpoint with interval=1 set correct DATA0/DATA1 bit for next frame - if ((USB0.in_ep_reg[epnum].diepctl & USB_D_EPTYPE0_M) == (1 << USB_D_EPTYPE1_S) && xfer->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (USB0.dsts & (1u << USB_SOFFN_S)); - USB0.in_ep_reg[epnum].diepctl |= (odd_frame_now ? USB_DI_SETD0PID1 : USB_DI_SETD1PID1); - } - - // Enable fifo empty interrupt only if there are something to put in the fifo. - if(total_bytes != 0) { - USB0.dtknqr4_fifoemptymsk |= (1 << epnum); - } - } else { - // Each complete packet for OUT xfers triggers XFRC. - USB0.out_ep_reg[epnum].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S); - USB0.out_ep_reg[epnum].doepctl |= USB_EPENA0_M | USB_CNAK0_M; - - // For ISO endpoint with interval=1 set correct DATA0/DATA1 bit for next frame - if ((USB0.out_ep_reg[epnum].doepctl & USB_D_EPTYPE0_M) == (1 << USB_D_EPTYPE1_S) && xfer->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (USB0.dsts & (1u << USB_SOFFN_S)); - USB0.out_ep_reg[epnum].doepctl |= (odd_frame_now ? USB_DO_SETD0PID1 : USB_DO_SETD1PID1); - } - } - return true; -} - -#if 0 // TODO support dcd_edpt_xfer_fifo API -bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ - (void)rhport; -} -#endif - -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; - - usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); - usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - if (dir == TUSB_DIR_IN) { - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(in_ep[epnum].diepctl & USB_D_EPENA1_M)) { - in_ep[epnum].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M); - } else { - // Stop transmitting packets and NAK IN xfers. - in_ep[epnum].diepctl |= USB_DI_SNAK1_M; - // while ((in_ep[epnum].diepint & USB_DI_SNAK1_M) == 0) ; - while ((in_ep[epnum].diepint & USB_D_INEPNAKEFF1_M) == 0) ; - - // Disable the endpoint. Note that both SNAK and STALL are set here. - in_ep[epnum].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M | USB_D_EPDIS1_M); - while ((in_ep[epnum].diepint & USB_D_EPDISBLD0_M) == 0) ; - in_ep[epnum].diepint = USB_D_EPDISBLD0_M; - } - - // Flush the FIFO, and wait until we have confirmed it cleared. - uint8_t const fifo_num = ((in_ep[epnum].diepctl >> USB_D_TXFNUM1_S) & USB_D_TXFNUM1_V); - // USB0.grstctl |= (fifo_num << USB_TXFNUM_S); - // USB0.grstctl |= USB_TXFFLSH_M; - // while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ; - uint32_t rstctl_last = USB0.grstctl; - uint32_t rstctl = USB_TXFFLSH_M; - rstctl |= (fifo_num << USB_TXFNUM_S); - USB0.grstctl = rstctl; - while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ; - USB0.grstctl = rstctl_last; - // TODO: Clear grstctl::fifo_num after fifo flsh - } else { - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(out_ep[epnum].doepctl & USB_EPENA0_M)) { - out_ep[epnum].doepctl |= USB_STALL0_M; - } else { - // Asserting GONAK is required to STALL an OUT endpoint. - // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt - // anyway, and it can't be cleared by user code. If this while loop never - // finishes, we have bigger problems than just the stack. - USB0.dctl |= USB_SGOUTNAK_M; - while ((USB0.gintsts & USB_GOUTNAKEFF_M) == 0) ; - - // Ditto here- disable the endpoint. Note that only STALL and not SNAK - // is set here. - out_ep[epnum].doepctl |= (USB_STALL0_M | USB_EPDIS0_M); - while ((out_ep[epnum].doepint & USB_EPDISBLD0_M) == 0) ; - out_ep[epnum].doepint = USB_EPDISBLD0_M; - - // Allow other OUT endpoints to keep receiving. - USB0.dctl |= USB_CGOUTNAK_M; - } - } -} - -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; - - usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); - usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - if (dir == TUSB_DIR_IN) { - in_ep[epnum].diepctl &= ~USB_D_STALL1_M; - - uint8_t eptype = (in_ep[epnum].diepctl & USB_D_EPTYPE1_M) >> USB_D_EPTYPE1_S; - // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt - // and bulk endpoints. - if (eptype == 2 || eptype == 3) { - in_ep[epnum].diepctl |= USB_DI_SETD0PID1_M; - } - } else { - out_ep[epnum].doepctl &= ~USB_STALL1_M; - - uint8_t eptype = (out_ep[epnum].doepctl & USB_EPTYPE1_M) >> USB_EPTYPE1_S; - // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt - // and bulk endpoints. - if (eptype == 2 || eptype == 3) { - out_ep[epnum].doepctl |= USB_DO_SETD0PID1_M; - } - } -} - -/*------------------------------------------------------------------*/ - -static void receive_packet(xfer_ctl_t *xfer, /* usb_out_endpoint_t * out_ep, */ uint16_t xfer_size) -{ - ESP_EARLY_LOGV(TAG, "USB - receive_packet"); - volatile uint32_t *rx_fifo = USB0.fifo[0]; - - // See above TODO - // uint16_t remaining = (out_ep->DOEPTSIZ & UsbDOEPTSIZ_XFRSIZ_Msk) >> UsbDOEPTSIZ_XFRSIZ_Pos; - // xfer->queued_len = xfer->total_len - remaining; - - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t to_recv_size; - - if (remaining <= xfer->max_size) { - // Avoid buffer overflow. - to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; - } else { - // Room for full packet, choose recv_size based on what the microcontroller - // claims. - to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; - } - - // Common buffer read -#if 0 // TODO support dcd_edpt_xfer_fifo API - if (xfer->ff) - { - // Ring buffer - tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) rx_fifo, to_recv_size); - } - else -#endif - { - uint8_t to_recv_rem = to_recv_size % 4; - uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem; - - // Do not assume xfer buffer is aligned. - uint8_t *base = (xfer->buffer + xfer->queued_len); - - // This for loop always runs at least once- skip if less than 4 bytes - // to collect. - if (to_recv_size >= 4) { - for (uint16_t i = 0; i < to_recv_size_aligned; i += 4) { - uint32_t tmp = (*rx_fifo); - base[i] = tmp & 0x000000FF; - base[i + 1] = (tmp & 0x0000FF00) >> 8; - base[i + 2] = (tmp & 0x00FF0000) >> 16; - base[i + 3] = (tmp & 0xFF000000) >> 24; - } - } - - // Do not read invalid bytes from RX FIFO. - if (to_recv_rem != 0) { - uint32_t tmp = (*rx_fifo); - uint8_t *last_32b_bound = base + to_recv_size_aligned; - - last_32b_bound[0] = tmp & 0x000000FF; - if (to_recv_rem > 1) { - last_32b_bound[1] = (tmp & 0x0000FF00) >> 8; - } - if (to_recv_rem > 2) { - last_32b_bound[2] = (tmp & 0x00FF0000) >> 16; - } - } - } - - xfer->queued_len += xfer_size; - - // Per USB spec, a short OUT packet (including length 0) is always - // indicative of the end of a transfer (at least for ctl, bulk, int). - xfer->short_packet = (xfer_size < xfer->max_size); -} - -static void transmit_packet(xfer_ctl_t *xfer, volatile usb_in_endpoint_t *in_ep, uint8_t fifo_num) -{ - ESP_EARLY_LOGV(TAG, "USB - transmit_packet"); - volatile uint32_t *tx_fifo = USB0.fifo[fifo_num]; - - uint16_t remaining = (in_ep->dieptsiz & 0x7FFFFU) >> USB_D_XFERSIZE0_S; - xfer->queued_len = xfer->total_len - remaining; - - uint16_t to_xfer_size = (remaining > xfer->max_size) ? xfer->max_size : remaining; - -#if 0 // TODO support dcd_edpt_xfer_fifo API - if (xfer->ff) - { - tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) tx_fifo, to_xfer_size); - } - else -#endif - { - uint8_t to_xfer_rem = to_xfer_size % 4; - uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem; - - // Buffer might not be aligned to 32b, so we need to force alignment - // by copying to a temp var. - uint8_t *base = (xfer->buffer + xfer->queued_len); - - // This for loop always runs at least once- skip if less than 4 bytes - // to send off. - if (to_xfer_size >= 4) { - for (uint16_t i = 0; i < to_xfer_size_aligned; i += 4) { - uint32_t tmp = base[i] | (base[i + 1] << 8) | - (base[i + 2] << 16) | (base[i + 3] << 24); - (*tx_fifo) = tmp; - } - } - - // Do not read beyond end of buffer if not divisible by 4. - if (to_xfer_rem != 0) { - uint32_t tmp = 0; - uint8_t *last_32b_bound = base + to_xfer_size_aligned; - - tmp |= last_32b_bound[0]; - if (to_xfer_rem > 1) { - tmp |= (last_32b_bound[1] << 8); - } - if (to_xfer_rem > 2) { - tmp |= (last_32b_bound[2] << 16); - } - - (*tx_fifo) = tmp; - } - } -} - -static void read_rx_fifo(void) -{ - // Pop control word off FIFO (completed xfers will have 2 control words, - // we only pop one ctl word each interrupt). - uint32_t const ctl_word = USB0.grxstsp; - uint8_t const pktsts = (ctl_word & USB_PKTSTS_M) >> USB_PKTSTS_S; - uint8_t const epnum = (ctl_word & USB_CHNUM_M ) >> USB_CHNUM_S; - uint16_t const bcnt = (ctl_word & USB_BCNT_M ) >> USB_BCNT_S; - - switch (pktsts) { - case 0x01: // Global OUT NAK (Interrupt) - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX type : Global OUT NAK"); - break; - - case 0x02: { // Out packet recvd - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX type : Out packet"); - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - receive_packet(xfer, bcnt); - } - break; - - case 0x03: // Out packet done (Interrupt) - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX type : Out packet done"); - break; - - case 0x04: // Step 2: Setup transaction completed (Interrupt) - // After this event, OEPINT interrupt will occur with SETUP bit set - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX : Setup packet done"); - USB0.out_ep_reg[epnum].doeptsiz |= USB_SUPCNT0_M; - break; - - case 0x06: { // Step1: Setup data packet received - volatile uint32_t *rx_fifo = USB0.fifo[0]; - - // We can receive up to three setup packets in succession, but - // only the last one is valid. Therefore we just overwrite it - _setup_packet[0] = (*rx_fifo); - _setup_packet[1] = (*rx_fifo); - - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX : Setup packet : 0x%08x 0x%08x", _setup_packet[0], _setup_packet[1]); - } - break; - - default: // Invalid, do something here, like breakpoint? - TU_BREAKPOINT(); - break; - } -} - -static void handle_epout_ints(void) -{ - // GINTSTS will be cleared with DAINT == 0 - // DAINT for a given EP clears when DOEPINTx is cleared. - // DOEPINT will be cleared when DAINT's out bits are cleared. - for (int n = 0; n < USB_OUT_EP_NUM; n++) { - xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - - if (USB0.daint & (1 << (16 + n))) { - // SETUP packet Setup Phase done. - if ((USB0.out_ep_reg[n].doepint & USB_SETUP0_M)) { - USB0.out_ep_reg[n].doepint = USB_STUPPKTRCVD0_M | USB_SETUP0_M; // clear - dcd_event_setup_received(0, (uint8_t *)&_setup_packet[0], true); - } - - // OUT XFER complete (single packet).q - if (USB0.out_ep_reg[n].doepint & USB_XFERCOMPL0_M) { - - ESP_EARLY_LOGV(TAG, "TUSB IRQ - EP OUT - XFER complete (single packet)"); - USB0.out_ep_reg[n].doepint = USB_XFERCOMPL0_M; - - // Transfer complete if short packet or total len is transferred - if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { - xfer->short_packet = false; - dcd_event_xfer_complete(0, n, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - // Schedule another packet to be received. - USB0.out_ep_reg[n].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S); - USB0.out_ep_reg[n].doepctl |= USB_EPENA0_M | USB_CNAK0_M; - } - } - } - } -} - -static void handle_epin_ints(void) -{ - // GINTSTS will be cleared with DAINT == 0 - // DAINT for a given EP clears when DIEPINTx is cleared. - // IEPINT will be cleared when DAINT's out bits are cleared. - for (uint32_t n = 0; n < USB_IN_EP_NUM; n++) { - xfer_ctl_t *xfer = &xfer_status[n][TUSB_DIR_IN]; - - if (USB0.daint & (1 << (0 + n))) { - ESP_EARLY_LOGV(TAG, "TUSB IRQ - EP IN %u", n); - - if (USB0.in_ep_reg[n].diepint & BIT(15)) { - USB0.in_ep_reg[n].diepint = BIT(15); - ESP_EARLY_LOGE(TAG, "Unknown Condition");//todo: - bus_reset(); - } - - // IN XFER complete (entire xfer). - if (USB0.in_ep_reg[n].diepint & USB_D_XFERCOMPL0_M) { - ESP_EARLY_LOGV(TAG, "TUSB IRQ - IN XFER complete!"); - USB0.in_ep_reg[n].diepint = USB_D_XFERCOMPL0_M; - dcd_event_xfer_complete(0, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); - if (!(USB0.in_ep_reg[n].diepint & USB_D_TXFEMP0_M)) { - ESP_EARLY_LOGE(TAG, "Complete but not empty: %u/%u", xfer->queued_len, xfer->total_len);//todo: - } - } - - // XFER FIFO empty - if (USB0.in_ep_reg[n].diepint & USB_D_TXFEMP0_M) { - ESP_EARLY_LOGV(TAG, "TUSB IRQ - IN XFER FIFO empty!"); - USB0.in_ep_reg[n].diepint = USB_D_TXFEMP0_M; - transmit_packet(xfer, &USB0.in_ep_reg[n], n); - - // Turn off TXFE if all bytes are written. - if (xfer->queued_len == xfer->total_len) - { - USB0.dtknqr4_fifoemptymsk &= ~(1 << n); - } - } - - // XFER Timeout - if (USB0.in_ep_reg[n].diepint & USB_D_TIMEOUT0_M) { - // Clear interrupt or enpoint will hang. - USB0.in_ep_reg[n].diepint = USB_D_TIMEOUT0_M; - ESP_EARLY_LOGE(TAG, "XFER Timeout");//todo: - // Maybe retry? - } - } - } -} - - -static void _dcd_int_handler(void* arg) -{ - (void) arg; - uint8_t const rhport = 0; - - const uint32_t int_msk = USB0.gintmsk; - const uint32_t int_status = USB0.gintsts & int_msk; - - if (int_status & USB_USBRST_M) { - // start of reset - ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset"); - USB0.gintsts = USB_USBRST_M; - // FIFOs will be reassigned when the endpoints are reopen - _allocated_fifos = 1; - bus_reset(); - } - - if (int_status & USB_RESETDET_M) { - ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset while suspend"); - USB0.gintsts = USB_RESETDET_M; - // no need to double reset - if ((int_status & USB_USBRST_M) == 0) { - _allocated_fifos = 1; - bus_reset(); - } - } - - if (int_status & USB_ENUMDONE_M) { - // ENUMDNE detects speed of the link. For full-speed, we - // always expect the same value. This interrupt is considered - // the end of reset. - USB0.gintsts = USB_ENUMDONE_M; - enum_done_processing(); - dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); - } - - if(int_status & USB_USBSUSP_M) - { - USB0.gintsts = USB_USBSUSP_M; - //dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); - dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); - _allocated_fifos = 1; - } - - if(int_status & USB_WKUPINT_M) - { - USB0.gintsts = USB_WKUPINT_M; - dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); - } - - if (int_status & USB_OTGINT_M) - { - // OTG INT bit is read-only - ESP_EARLY_LOGV(TAG, "dcd_int_handler - disconnected"); - - uint32_t const otg_int = USB0.gotgint; - - if (otg_int & USB_SESENDDET_M) - { - dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); - _allocated_fifos = 1; - } - - USB0.gotgint = otg_int; - } - - if (int_status & USB_SOF_M) { - USB0.gintsts = USB_SOF_M; - - // Disable SOF interrupt since currently only used for remote wakeup detection - USB0.gintmsk &= ~USB_SOFMSK_M; - - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); - } - - - if (int_status & USB_RXFLVI_M) { - // RXFLVL bit is read-only - ESP_EARLY_LOGV(TAG, "dcd_int_handler - rx!"); - - // Mask out RXFLVL while reading data from FIFO - USB0.gintmsk &= ~USB_RXFLVIMSK_M; - read_rx_fifo(); - USB0.gintmsk |= USB_RXFLVIMSK_M; - } - - // OUT endpoint interrupt handling. - if (int_status & USB_OEPINT_M) { - // OEPINT is read-only - ESP_EARLY_LOGV(TAG, "dcd_int_handler - OUT endpoint!"); - handle_epout_ints(); - } - - // IN endpoint interrupt handling. - if (int_status & USB_IEPINT_M) { - // IEPINT bit read-only - ESP_EARLY_LOGV(TAG, "dcd_int_handler - IN endpoint!"); - handle_epin_ints(); - } - - // Without handling - USB0.gintsts |= USB_CURMOD_INT_M | - USB_MODEMIS_M | - USB_OTGINT_M | - USB_NPTXFEMP_M | - USB_GINNAKEFF_M | - USB_GOUTNAKEFF | - USB_ERLYSUSP_M | - USB_USBSUSP_M | - USB_ISOOUTDROP_M | - USB_EOPF_M | - USB_EPMIS_M | - USB_INCOMPISOIN_M | - USB_INCOMPIP_M | - USB_FETSUSP_M | - USB_PTXFEMP_M; -} - -void dcd_int_enable (uint8_t rhport) -{ - (void) rhport; - esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, (intr_handler_t) _dcd_int_handler, NULL, &usb_ih); -} - -void dcd_int_disable (uint8_t rhport) -{ - (void) rhport; - esp_intr_free(usb_ih); -} - -#endif // #if OPT_MCU_ESP32S2 || OPT_MCU_ESP32S3 - diff --git a/patches/tinyusb_dcd_esp32sx.diff b/patches/tinyusb_dcd_esp32sx.diff deleted file mode 100644 index 024af0ddf..000000000 --- a/patches/tinyusb_dcd_esp32sx.diff +++ /dev/null @@ -1,119 +0,0 @@ ---- a/components/arduino_tinyusb/tinyusb/src/portable/espressif/esp32sx/dcd_esp32sx.c 2024-06-10 20:45:02.000000000 +0300 -+++ b/components/arduino_tinyusb/tinyusb/src/portable/espressif/esp32sx/dcd_esp32sx.c 2024-06-10 22:25:05.000000000 +0300 -@@ -282,6 +281,7 @@ - xfer->interval = desc_edpt->bInterval; - - if (dir == TUSB_DIR_OUT) { -+ out_ep[epnum].doepctl &= ~(USB_D_EPTYPE0_M | USB_D_MPS0_M); - out_ep[epnum].doepctl |= USB_USBACTEP1_M | - desc_edpt->bmAttributes.xfer << USB_EPTYPE1_S | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_DO_SETD0PID1_M : 0) | -@@ -311,7 +311,14 @@ - // - Offset: GRXFSIZ + 16 + Size*(epnum-1) - // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". - -- uint8_t fifo_num = get_free_fifo(); -+ uint8_t fifo_num = 0; -+ // Special Case for EP5, which is used by CDC but not actually called by the driver -+ // we can give it a fake FIFO -+ if (epnum == 5) { -+ fifo_num = EP_FIFO_NUM; -+ } else { -+ fifo_num = get_free_fifo(); -+ } - TU_ASSERT(fifo_num != 0); - - in_ep[epnum].diepctl &= ~(USB_D_TXFNUM1_M | USB_D_EPTYPE1_M | USB_DI_SETD0PID1 | USB_D_MPS1_M); -@@ -442,7 +449,8 @@ - } else { - // Stop transmitting packets and NAK IN xfers. - in_ep[epnum].diepctl |= USB_DI_SNAK1_M; -- while ((in_ep[epnum].diepint & USB_DI_SNAK1_M) == 0) ; -+ // while ((in_ep[epnum].diepint & USB_DI_SNAK1_M) == 0) ; -+ while ((in_ep[epnum].diepint & USB_D_INEPNAKEFF1_M) == 0) ; - - // Disable the endpoint. Note that both SNAK and STALL are set here. - in_ep[epnum].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M | USB_D_EPDIS1_M); -@@ -452,9 +460,16 @@ - - // Flush the FIFO, and wait until we have confirmed it cleared. - uint8_t const fifo_num = ((in_ep[epnum].diepctl >> USB_D_TXFNUM1_S) & USB_D_TXFNUM1_V); -- USB0.grstctl |= (fifo_num << USB_TXFNUM_S); -- USB0.grstctl |= USB_TXFFLSH_M; -+ // USB0.grstctl |= (fifo_num << USB_TXFNUM_S); -+ // USB0.grstctl |= USB_TXFFLSH_M; -+ // while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ; -+ uint32_t rstctl_last = USB0.grstctl; -+ uint32_t rstctl = USB_TXFFLSH_M; -+ rstctl |= (fifo_num << USB_TXFNUM_S); -+ USB0.grstctl = rstctl; - while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ; -+ USB0.grstctl = rstctl_last; -+ // TODO: Clear grstctl::fifo_num after fifo flsh - } else { - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(out_ep[epnum].doepctl & USB_EPENA0_M)) { -@@ -730,11 +745,21 @@ - - if (USB0.daint & (1 << (0 + n))) { - ESP_EARLY_LOGV(TAG, "TUSB IRQ - EP IN %u", n); -+ -+ if (USB0.in_ep_reg[n].diepint & BIT(15)) { -+ USB0.in_ep_reg[n].diepint = BIT(15); -+ ESP_EARLY_LOGE(TAG, "Unknown Condition");//todo: -+ bus_reset(); -+ } -+ - // IN XFER complete (entire xfer). - if (USB0.in_ep_reg[n].diepint & USB_D_XFERCOMPL0_M) { - ESP_EARLY_LOGV(TAG, "TUSB IRQ - IN XFER complete!"); - USB0.in_ep_reg[n].diepint = USB_D_XFERCOMPL0_M; - dcd_event_xfer_complete(0, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); -+ if (!(USB0.in_ep_reg[n].diepint & USB_D_TXFEMP0_M)) { -+ ESP_EARLY_LOGE(TAG, "Complete but not empty: %u/%u", xfer->queued_len, xfer->total_len);//todo: -+ } - } - - // XFER FIFO empty -@@ -754,6 +779,7 @@ - if (USB0.in_ep_reg[n].diepint & USB_D_TIMEOUT0_M) { - // Clear interrupt or endpoint will hang. - USB0.in_ep_reg[n].diepint = USB_D_TIMEOUT0_M; -+ ESP_EARLY_LOGE(TAG, "XFER Timeout");//todo: - // Maybe retry? - } - } -@@ -781,8 +807,12 @@ - if (int_status & USB_RESETDET_M) { - ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset while suspend"); - USB0.gintsts = USB_RESETDET_M; -- bus_reset(); -- } -+ // no need to double reset -+ if ((int_status & USB_USBRST_M) == 0) { -+ _allocated_fifos = 1; -+ bus_reset(); -+ } -+ } - - if (int_status & USB_ENUMDONE_M) { - // ENUMDNE detects speed of the link. For full-speed, we -@@ -796,7 +826,9 @@ - if(int_status & USB_USBSUSP_M) - { - USB0.gintsts = USB_USBSUSP_M; -- dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); -+ //dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); -+ dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -+ _allocated_fifos = 1; - } - - if(int_status & USB_WKUPINT_M) -@@ -815,6 +847,7 @@ - if (otg_int & USB_SESENDDET_M) - { - dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -+ _allocated_fifos = 1; - } - - USB0.gotgint = otg_int; From 57f7d481ebd269b7ea3dc5576c435d4329633c46 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 2 Oct 2024 23:20:56 +0300 Subject: [PATCH 09/45] Use "release/v5.1" branch for building libs --- .github/workflows/cron.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index ed2522f54..bd5513227 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -32,7 +32,7 @@ jobs: matrix: include: - idf_branch: "release/v5.1" - lib_builder_branch: "master" + lib_builder_branch: "release/v5.1" targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2" - idf_branch: "release/v5.3" lib_builder_branch: "release/v5.3" From 9e2e6b17b99af5b677f7a09b7c208cfe9a4c6e1d Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 10 Oct 2024 12:30:42 +0300 Subject: [PATCH 10/45] Drop support for ESP-DL on Xtensa chips --- main/idf_component.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main/idf_component.yml b/main/idf_component.yml index 00682c102..714b3f0d6 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -12,12 +12,12 @@ dependencies: require: public rules: - if: "target not in [esp32c2]" - espressif/esp-dl: - version: "af7808ba09448ce82c704455975d4cf1e4305fd7" - git: https://github.com/espressif/esp-dl.git - require: public - rules: - - if: "target in [esp32s3, esp32s2, esp32]" + # espressif/esp-dl: + # version: "af7808ba09448ce82c704455975d4cf1e4305fd7" + # git: https://github.com/espressif/esp-dl.git + # require: public + # rules: + # - if: "target in [esp32s3, esp32s2, esp32]" espressif/esp-sr: version: ">=1.4.2" rules: From b6f03b6a4a4d6e3d5cf0f19a78e28aa14b0256f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:15:35 +0100 Subject: [PATCH 11/45] Add default Zigbee SDKConfig settings (#240) --- configs/defconfig.esp32c6 | 8 ++++++++ configs/defconfig.esp32h2 | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/configs/defconfig.esp32c6 b/configs/defconfig.esp32c6 index 7770504fc..c39022997 100644 --- a/configs/defconfig.esp32c6 +++ b/configs/defconfig.esp32c6 @@ -34,3 +34,11 @@ CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" # end of OpenThread + +# +# Zigbee +# +CONFIG_ZB_ENABLED=y +CONFIG_ZB_ZED=y +CONFIG_ZB_RADIO_NATIVE=y +# end of Zigbee diff --git a/configs/defconfig.esp32h2 b/configs/defconfig.esp32h2 index dfd36395d..fe4a47eb6 100644 --- a/configs/defconfig.esp32h2 +++ b/configs/defconfig.esp32h2 @@ -30,3 +30,11 @@ CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" # end of OpenThread + +# +# Zigbee +# +CONFIG_ZB_ENABLED=y +CONFIG_ZB_ZED=y +CONFIG_ZB_RADIO_NATIVE=y +# end of Zigbee From 22ce6811335c695363a37745afec36ff4f580f79 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:39:44 -0300 Subject: [PATCH 12/45] fix(libs): Allow for manual rebuilding and fix commit checking (#245) --- .github/workflows/cron.yml | 3 +- .github/workflows/cron_build.yml | 1 - tools/check-deploy-needed.sh | 29 ++++++++++++++++--- tools/config.sh | 49 ++++++++++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 9 deletions(-) diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index bd5513227..dff1fb9d3 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -12,7 +12,7 @@ on: # │ │ │ │ │ # * * * * * - cron: '0 */6 * * *' - workflow_dispatch: # For testing + workflow_dispatch: # For manually rebuilding the libraries defaults: run: @@ -21,6 +21,7 @@ defaults: jobs: build-libs: name: Build with IDF ${{ matrix.idf_branch }} + if: github.repository_owner == 'espressif' uses: ./.github/workflows/cron_build.yml with: idf_branch: ${{ matrix.idf_branch }} diff --git a/.github/workflows/cron_build.yml b/.github/workflows/cron_build.yml index f8767617c..8d13759b7 100644 --- a/.github/workflows/cron_build.yml +++ b/.github/workflows/cron_build.yml @@ -132,7 +132,6 @@ jobs: compression-level: 0 - name: Push changes - if: github.repository == 'espressif/esp32-arduino-lib-builder' env: GITHUB_TOKEN: ${{ secrets.PUSH_TOKEN }} GIT_AUTHOR_EMAIL: ${{ secrets.PUSH_EMAIL }} diff --git a/tools/check-deploy-needed.sh b/tools/check-deploy-needed.sh index 230d0bf71..e33cc169c 100755 --- a/tools/check-deploy-needed.sh +++ b/tools/check-deploy-needed.sh @@ -37,19 +37,40 @@ AR_NEW_COMMIT_MESSAGE="IDF $IDF_BRANCH $IDF_COMMIT" AR_NEW_PR_TITLE="IDF $IDF_BRANCH" LIBS_RELEASE_TAG="idf-"${IDF_BRANCH//\//_}"" -LIBS_VERSION="$LIBS_RELEASE_TAG-$IDF_COMMIT" +LIBS_VERSION_PREFIX="$LIBS_RELEASE_TAG-$IDF_COMMIT-v" +VERSION_COUNTER=1 AR_HAS_BRANCH=`github_branch_exists "$AR_REPO" "$AR_NEW_BRANCH_NAME"` if [ "$AR_HAS_BRANCH" == "1" ]; then - AR_HAS_COMMIT=`github_commit_exists "$AR_REPO" "$AR_NEW_BRANCH_NAME" "$IDF_COMMIT"` + LATEST_LIBS_IDF=`github_get_libs_idf "$AR_REPO" "$AR_NEW_BRANCH_NAME" "$AR_NEW_PR_TITLE"` else - AR_HAS_COMMIT=`github_commit_exists "$AR_REPO" "$AR_BRANCH" "$IDF_COMMIT"` + LATEST_LIBS_IDF=`github_get_libs_idf "$AR_REPO" "$AR_BRANCH" "$AR_NEW_PR_TITLE"` fi + +echo "Current IDF commit: $IDF_COMMIT" +echo "Latest IDF commit in $AR_BRANCH of $AR_REPO: $LATEST_LIBS_IDF" + +AR_HAS_COMMIT=`if [ "$LATEST_LIBS_IDF" == "$IDF_COMMIT" ]; then echo "1"; else echo "0"; fi` AR_HAS_PR=`github_pr_exists "$AR_REPO" "$AR_NEW_BRANCH_NAME"` LIBS_RELEASE_ID=`github_release_id "$AR_LIBS_REPO" "$LIBS_RELEASE_TAG"` LIBS_HAS_RELEASE=`if [ -n "$LIBS_RELEASE_ID" ]; then echo "1"; else echo "0"; fi` -LIBS_ASSET_ID=`github_release_asset_id "$AR_LIBS_REPO" "$LIBS_RELEASE_ID" "esp32-arduino-libs-$LIBS_VERSION.zip"` + +if [ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]; then + echo "Workflow dispatch event. Generating new libs." + while true; do + LIBS_ASSET_ID=`github_release_asset_id "$AR_LIBS_REPO" "$LIBS_RELEASE_ID" "esp32-arduino-libs-$LIBS_VERSION_PREFIX$VERSION_COUNTER.zip"` + if [ -n "$LIBS_ASSET_ID" ]; then + VERSION_COUNTER=$((VERSION_COUNTER+1)) + else + break + fi + done +else + LIBS_ASSET_ID=`github_release_asset_id "$AR_LIBS_REPO" "$LIBS_RELEASE_ID" "esp32-arduino-libs-$LIBS_VERSION_PREFIX$VERSION_COUNTER.zip"` +fi + +LIBS_VERSION="$LIBS_VERSION_PREFIX$VERSION_COUNTER" LIBS_HAS_ASSET=`if [ -n "$LIBS_ASSET_ID" ]; then echo "1"; else echo "0"; fi` export IDF_COMMIT diff --git a/tools/config.sh b/tools/config.sh index 2988a1517..014f4849e 100755 --- a/tools/config.sh +++ b/tools/config.sh @@ -25,7 +25,7 @@ if [ -z $IDF_TARGET ]; then fi # Owner of the target ESP32 Arduino repository -AR_USER="espressif" +AR_USER="$GITHUB_REPOSITORY_OWNER" # The full name of the repository AR_REPO="$AR_USER/arduino-esp32" @@ -99,12 +99,55 @@ if [[ "$AR_OS" == "macos" ]]; then export SSTAT="stat -f %z" fi +function github_get_libs_idf(){ # github_get_libs_idf + local repo_path="$1" + local branch_name="$2" + local message_prefix="$3" + message_prefix=$(echo $message_prefix | sed 's/[]\/$*.^|[]/\\&/g') # Escape special characters + local page=1 + local version_found="" + local libs_version="" + + while [[ "$libs_version" == "" && "$page" -le 3 ]]; do + # Get the latest commit message that matches the prefix and extract the hash from the last commit message + version_found=`curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" "https://api.github.com/repos/$repo_path/commits?sha=$branch_name&per_page=100&page=$page" | \ + jq -r --arg prefix "$message_prefix" '[ .[] | select(.commit.message | test($prefix + " [a-f0-9]{8}")) ][0] | .commit.message' | \ + grep -Eo "$message_prefix [a-f0-9]{8}" | \ + awk 'END {print $NF}'` + if [[ "$version_found" != "" && "$version_found" != "null" ]]; then + libs_version=$version_found + else + page=$((page+1)) + fi + done + + if [ ! "$libs_version" == "" ] && [ ! "$libs_version" == "null" ]; then echo $libs_version; else echo ""; fi +} + function github_commit_exists(){ #github_commit_exists local repo_path="$1" local branch_name="$2" local commit_message="$3" - local commits_found=`curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" "https://api.github.com/repos/$repo_path/commits?sha=$branch_name" | jq -r '.[].commit.message' | grep "$commit_message" | wc -l` - if [ ! "$commits_found" == "" ] && [ ! "$commits_found" == "null" ] && [ ! "$commits_found" == "0" ]; then echo $commits_found; else echo 0; fi + local page=1 + local commits_found=0 + + while [ "$page" -le 3 ]; do + local response=`curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" "https://api.github.com/repos/$repo_path/commits?sha=$branch_name&per_page=100&page=$page"` + + if [[ -z "$response" || "$response" == "[]" ]]; then + break + fi + + local commits=`echo "$response" | jq -r '.[].commit.message' | grep "$commit_message" | wc -l` + if [ "$commits" -gt 0 ]; then + commits_found=1 + break + fi + + page=$((page+1)) + done + + echo $commits_found } function github_last_commit(){ # github_last_commit From 1a2fd056d04d6fa8fdd7b31ed45d301e0079af35 Mon Sep 17 00:00:00 2001 From: TimL Date: Sun, 24 Nov 2024 02:11:57 +1100 Subject: [PATCH 13/45] Fix corrupt coredump images (#246) --- configs/defconfig.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/defconfig.common b/configs/defconfig.common index 47310528c..5bb28cad5 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -113,7 +113,7 @@ CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y CONFIG_ESP_COREDUMP_CHECKSUM_CRC32=y CONFIG_ESP_COREDUMP_MAX_TASKS_NUM=64 -CONFIG_ESP_COREDUMP_STACK_SIZE=1024 +CONFIG_ESP_COREDUMP_STACK_SIZE=0 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y From c73bc7ff6161f328b54c9a79d67f1bcc670f1b30 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Tue, 10 Dec 2024 07:47:17 -0300 Subject: [PATCH 14/45] fix(config): Add fallback value to AR_USER (#253) --- tools/config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/config.sh b/tools/config.sh index 014f4849e..37805cb48 100755 --- a/tools/config.sh +++ b/tools/config.sh @@ -25,7 +25,7 @@ if [ -z $IDF_TARGET ]; then fi # Owner of the target ESP32 Arduino repository -AR_USER="$GITHUB_REPOSITORY_OWNER" +AR_USER="${GITHUB_REPOSITORY_OWNER:-espressif}" # The full name of the repository AR_REPO="$AR_USER/arduino-esp32" From d09c8c64a862a4cfff4da574be207bf801fd5930 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 18 Dec 2024 15:57:17 +0200 Subject: [PATCH 15/45] ESP32 Arduino v3.1 libs from ESP-IDF v5.3 (#208) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(build): Changes required to build against IDF v5.3 * Use unified Xtensa toolchain * add(build): Add initial ESP32-P4 skeleton Chip is not selected by default and has only one memory and bootloader configuration. This is the minimum required to issue `build.sh -t esp32p4` which will currently fail, because Arduino support is not yet ready * feat(esp32p4): Build libs for ESP32-P4 (#221) * feat(esp32p4): Build libs for ESP32-P4 * Add target to workflows * Enable in builds * Remove bluedroid patch * Add P4 to libspi * Add P4 mem variants * Update SDK in JSON even if version did not change (#223) * Do not build matter for ESP32-P4 * Update ESP-DL configuration * Add additional DL models and use extra components only when needed * Use extra DL models only on S3 and P4 * Switch to the new ESP-DL only for ESP32-P4 * Rename old DL component and revert the name of the new * Enable TinyUSB build for ESP32P4 * Add support for HighSpeed USB in arduino_tinyusb * Update tinyusb dcd_dwc2 * Add P4 configuration for PSRAM, WDT and ESP-HOSTED * Update dcd_dwc2.c * Remove conditional inclusion of builder specified components CCACHE is very fast and it also causes issues with memory variants * Do not use ESP-DL on P4 * Update P4 PSRAM Speed to 200MHz * Fixes Matter over WiFi to disable OpenThread (#232) * Fixes Matter over WiFi to disable OpenThread * fix flag value * disables Matter Stack WiFi manager * rollback Matter WiFi Manager changes * Add define to signify that prebuilt libs are used * Enable FreeRTOS Trace Facility (#234) * Enable FreeRTOS Trace Facility * Enable more statistics * fix(docker): Add docker tag to run scripts in 5.3 branch (#236) * fix(docker): Add docker tag to run scripts in 5.3 branch * Add additional info * fix(zigbee): Unlink the zigbee libs (#242) * fix(): Move mkdir to top as its already used * Update TinyUSB DCD Source * Add missing compile source from TinyUSB * Fix path to TinyUSB dwc2_common.c * Update TinyUSB DCD * Update TinyUSB DCD * Update dcd_dwc2.c * Update dcd_dwc2.c * Update copy-libs.sh * Support rev 0 for P4 (#254) * Support rev 0 for P4 * Revert C6 slave idf target * Fix the crash for esp32 and esp32c3 (#248) * fix(trademark): Remove 3rd party trademarks from scripts (#255) * Update dcd_dwc2.c * Prepare for merging release/v5.3 into master --------- Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Co-authored-by: Rodrigo Garcia Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Co-authored-by: kvp1703 <65121235+kvp1703@users.noreply.github.com> --- .github/workflows/cron.yml | 2 +- .github/workflows/push.yml | 2 +- CMakeLists.txt | 2 + build.sh | 6 +- components/arduino_tinyusb/CMakeLists.txt | 3 +- components/arduino_tinyusb/Kconfig.projbuild | 28 +- .../arduino_tinyusb/include/tusb_config.h | 7 + .../arduino_tinyusb/patches/dcd_dwc2.patch | 55 +- components/arduino_tinyusb/src/dcd_dwc2.c | 1300 +++++++---------- configs/builds.json | 19 +- configs/defconfig.common | 6 +- configs/defconfig.esp32 | 1 + configs/defconfig.esp32c3 | 1 + configs/defconfig.esp32c6 | 3 + configs/defconfig.esp32p4 | 26 + configs/{pio_end.txt => pioarduino_end.txt} | 0 .../{pio_start.txt => pioarduino_start.txt} | 2 +- main/idf_component.yml | 51 +- patches/esp32c6_provisioning_bluedroid.diff | 12 - patches/mmu_map.diff | 24 - tools/add_sdk_json.py | 2 +- tools/config.sh | 4 +- tools/copy-libs.sh | 257 ++-- tools/docker/README.md | 10 +- tools/docker/run.ps1 | 5 +- tools/docker/run.sh | 4 +- ...manifest.py => gen_pioarduino_manifest.py} | 2 +- tools/gen_tools_json.py | 2 +- tools/install-esp-idf.sh | 2 - tools/patch-tinyusb.sh | 4 + 30 files changed, 805 insertions(+), 1037 deletions(-) create mode 100644 configs/defconfig.esp32p4 rename configs/{pio_end.txt => pioarduino_end.txt} (100%) rename configs/{pio_start.txt => pioarduino_start.txt} (96%) delete mode 100644 patches/esp32c6_provisioning_bluedroid.diff delete mode 100644 patches/mmu_map.diff rename tools/{gen_platformio_manifest.py => gen_pioarduino_manifest.py} (94%) create mode 100755 tools/patch-tinyusb.sh diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index dff1fb9d3..30285c8bb 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -36,5 +36,5 @@ jobs: lib_builder_branch: "release/v5.1" targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2" - idf_branch: "release/v5.3" - lib_builder_branch: "release/v5.3" + lib_builder_branch: "master" targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4" diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 649c84c81..95610c403 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - target: [esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2] + target: [esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2, esp32p4] fail-fast: false steps: - uses: actions/checkout@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b0fca085..1268b8e68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,8 @@ add_custom_command( ) add_custom_target(mem-variant DEPENDS "mem_variant") +idf_build_set_property(COMPILE_DEFINITIONS "-DESP32_ARDUINO_LIB_BUILDER" APPEND) + ################## ### ESP Matter ### ################## diff --git a/build.sh b/build.sh index 9bceda087..50e376c2a 100755 --- a/build.sh +++ b/build.sh @@ -305,14 +305,14 @@ if [ "$BUILD_TYPE" = "all" ]; then if [ $? -ne 0 ]; then exit 1; fi fi -# Generate PlatformIO manifest file +# Generate pioarduino manifest file if [ "$BUILD_TYPE" = "all" ]; then - echo "* Generating PlatformIO manifest file..." + echo "* Generating pioarduino manifest file..." pushd $IDF_PATH ibr=$(git describe --all 2>/dev/null) ic=$(git -C "$IDF_PATH" rev-parse --short HEAD) popd - python3 ./tools/gen_platformio_manifest.py -o "$TOOLS_JSON_OUT/" -s "$ibr" -c "$ic" + python3 ./tools/gen_pioarduino_manifest.py -o "$TOOLS_JSON_OUT/" -s "$ibr" -c "$ic" if [ $? -ne 0 ]; then exit 1; fi fi diff --git a/components/arduino_tinyusb/CMakeLists.txt b/components/arduino_tinyusb/CMakeLists.txt index 6a2e35150..fd6f5983d 100755 --- a/components/arduino_tinyusb/CMakeLists.txt +++ b/components/arduino_tinyusb/CMakeLists.txt @@ -27,7 +27,8 @@ if(CONFIG_TINYUSB_ENABLED) # espressif: "${COMPONENT_DIR}/src/dcd_dwc2.c" # tusb: - #"{COMPONENT_DIR}/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c" + #"${COMPONENT_DIR}/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c" + "${COMPONENT_DIR}/tinyusb/src/portable/synopsys/dwc2/dwc2_common.c" "${COMPONENT_DIR}/tinyusb/src/class/cdc/cdc_device.c" "${COMPONENT_DIR}/tinyusb/src/class/hid/hid_device.c" "${COMPONENT_DIR}/tinyusb/src/class/midi/midi_device.c" diff --git a/components/arduino_tinyusb/Kconfig.projbuild b/components/arduino_tinyusb/Kconfig.projbuild index 1db30506f..65d9c37be 100755 --- a/components/arduino_tinyusb/Kconfig.projbuild +++ b/components/arduino_tinyusb/Kconfig.projbuild @@ -4,7 +4,7 @@ menu "Arduino TinyUSB" config TINYUSB_ENABLED bool "Enable TinyUSB driver" default y - depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4 select FREERTOS_SUPPORT_STATIC_ALLOCATION select FREERTOS_USE_AUTHENTIC_INCLUDE_PATHS help @@ -28,14 +28,16 @@ menu "Arduino TinyUSB" config TINYUSB_CDC_RX_BUFSIZE int "CDC FIFO size of RX" - default 64 + default 64 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 512 if IDF_TARGET_ESP32P4 depends on TINYUSB_CDC_ENABLED help CDC FIFO size of RX config TINYUSB_CDC_TX_BUFSIZE int "CDC FIFO size of TX" - default 64 + default 64 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 512 if IDF_TARGET_ESP32P4 depends on TINYUSB_CDC_ENABLED help CDC FIFO size of TX @@ -86,7 +88,8 @@ menu "Arduino TinyUSB" config TINYUSB_HID_BUFSIZE int "HID Buffer size" - default 64 + default 64 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 512 if IDF_TARGET_ESP32P4 depends on TINYUSB_HID_ENABLED help HID Buffer size. Should be sufficient to hold ID (if any) + Data @@ -111,14 +114,16 @@ menu "Arduino TinyUSB" config TINYUSB_MIDI_RX_BUFSIZE int "MIDI FIFO size of RX" - default 64 + default 64 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 512 if IDF_TARGET_ESP32P4 depends on TINYUSB_MIDI_ENABLED help MIDI FIFO size of RX config TINYUSB_MIDI_TX_BUFSIZE int "MIDI FIFO size of TX" - default 64 + default 64 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 512 if IDF_TARGET_ESP32P4 depends on TINYUSB_MIDI_ENABLED help MIDI FIFO size of TX @@ -143,8 +148,9 @@ menu "Arduino TinyUSB" config TINYUSB_VIDEO_STREAMING_BUFSIZE int "VIDEO streaming endpoint size" - range 0 64 - default 64 + range 0 512 + default 64 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 512 if IDF_TARGET_ESP32P4 depends on TINYUSB_VIDEO_ENABLED help VIDEO streaming endpoint size @@ -219,14 +225,16 @@ menu "Arduino TinyUSB" config TINYUSB_VENDOR_RX_BUFSIZE int "VENDOR FIFO size of RX" - default 64 + default 64 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 512 if IDF_TARGET_ESP32P4 depends on TINYUSB_VENDOR_ENABLED help VENDOR FIFO size of RX config TINYUSB_VENDOR_TX_BUFSIZE int "VENDOR FIFO size of TX" - default 64 + default 64 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 512 if IDF_TARGET_ESP32P4 depends on TINYUSB_VENDOR_ENABLED help VENDOR FIFO size of TX diff --git a/components/arduino_tinyusb/include/tusb_config.h b/components/arduino_tinyusb/include/tusb_config.h index 90dd7f797..458c78cf1 100755 --- a/components/arduino_tinyusb/include/tusb_config.h +++ b/components/arduino_tinyusb/include/tusb_config.h @@ -100,11 +100,18 @@ extern "C" { # define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4) #endif +#if CONFIG_IDF_TARGET_ESP32P4 +#define CFG_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED +#else +#define CFG_TUD_MAX_SPEED OPT_MODE_FULL_SPEED +#endif + /* */ /* DRIVER CONFIGURATION */ /* */ #define CFG_TUD_MAINTASK_SIZE 4096 +#define CFG_TUD_ENDOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_ENDOINT0_SIZE 64 // Enabled Drivers diff --git a/components/arduino_tinyusb/patches/dcd_dwc2.patch b/components/arduino_tinyusb/patches/dcd_dwc2.patch index a57df7ef6..11c1c05c0 100644 --- a/components/arduino_tinyusb/patches/dcd_dwc2.patch +++ b/components/arduino_tinyusb/patches/dcd_dwc2.patch @@ -1,10 +1,10 @@ --- a/components/arduino_tinyusb/src/dcd_dwc2.c 2024-10-02 12:17:40.000000000 +0300 +++ b/components/arduino_tinyusb/src/dcd_dwc2.c 2024-10-02 12:19:48.000000000 +0300 -@@ -316,6 +316,16 @@ +@@ -243,6 +243,17 @@ //-------------------------------------------------------------------- // Endpoint //-------------------------------------------------------------------- -+#if defined(TUP_USBIP_DWC2_ESP32) ++#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +// Keep count of how many FIFOs are in use +static uint8_t _allocated_fifos = 1; //FIFO0 is always in use + @@ -14,16 +14,18 @@ + return 0; +} +#endif - - static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { ++ + static void edpt_activate(uint8_t rhport, const tusb_desc_endpoint_t* p_endpoint_desc) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); -@@ -336,7 +346,18 @@ - dwc2->epout[epnum].doepctl = dxepctl; - dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); - } else { -- dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); + const uint8_t epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); +@@ -266,7 +277,18 @@ + depctl.bm.set_data0_iso_even = 1; + } + if (dir == TUSB_DIR_IN) { +- depctl.bm.tx_fifo_num = epnum; ++ //depctl.bm.tx_fifo_num = epnum; + uint8_t fifo_num = epnum; -+#if defined(TUP_USBIP_DWC2_ESP32) ++#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + // Special Case for EP5, which is used by CDC but not actually called by the driver + // we can give it a fake FIFO + if (epnum == 5) { @@ -31,51 +33,50 @@ + } else { + fifo_num = get_free_fifo(); + } -+ //TU_ASSERT(fifo_num != 0); +#endif -+ dwc2->epin[epnum].diepctl = dxepctl | (fifo_num << DIEPCTL_TXFNUM_Pos); - dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum); ++ depctl.bm.tx_fifo_num = fifo_num; } - } -@@ -850,6 +871,10 @@ - xfer_status[n][TUSB_DIR_IN].max_size = 0; + + dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; +@@ -557,6 +579,10 @@ + } } -+#if defined(TUP_USBIP_DWC2_ESP32) ++#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + _allocated_fifos = 1; +#endif + dfifo_flush_tx(dwc2, 0x10); // all tx fifo dfifo_flush_rx(dwc2); -@@ -1204,6 +1229,9 @@ - if (int_status & GINTSTS_USBRST) { +@@ -997,6 +1023,9 @@ + if (gintsts & GINTSTS_USBRST) { // USBRST is start of reset. dwc2->gintsts = GINTSTS_USBRST; -+#if defined(TUP_USBIP_DWC2_ESP32) ++#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + _allocated_fifos = 1; +#endif - bus_reset(rhport); + handle_bus_reset(rhport); } -@@ -1235,7 +1263,11 @@ +@@ -1008,7 +1037,11 @@ - if (int_status & GINTSTS_USBSUSP) { + if (gintsts & GINTSTS_USBSUSP) { dwc2->gintsts = GINTSTS_USBSUSP; - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + //dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -+#if defined(TUP_USBIP_DWC2_ESP32) ++#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + _allocated_fifos = 1; +#endif } - if (int_status & GINTSTS_WKUINT) { -@@ -1252,6 +1284,9 @@ + if (gintsts & GINTSTS_WKUINT) { +@@ -1025,6 +1058,9 @@ if (otg_int & GOTGINT_SEDET) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -+#if defined(TUP_USBIP_DWC2_ESP32) ++#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + _allocated_fifos = 1; +#endif } diff --git a/components/arduino_tinyusb/src/dcd_dwc2.c b/components/arduino_tinyusb/src/dcd_dwc2.c index 8bcc98166..d6796641a 100644 --- a/components/arduino_tinyusb/src/dcd_dwc2.c +++ b/components/arduino_tinyusb/src/dcd_dwc2.c @@ -31,56 +31,25 @@ #if CFG_TUD_ENABLED && defined(TUP_USBIP_DWC2) +#if !(CFG_TUD_DWC2_SLAVE_ENABLE || CFG_TUD_DWC2_DMA_ENABLE) +#error DWC2 require either CFG_TUD_DWC2_SLAVE_ENABLE or CFG_TUD_DWC2_DMA_ENABLE to be enabled +#endif + // Debug level for DWC2 #define DWC2_DEBUG 2 #include "device/dcd.h" -#include "dwc2_type.h" - -// Following symbols must be defined by port header -// - _dwc2_controller[]: array of controllers -// - DWC2_EP_MAX: largest EP counts of all controllers -// - dwc2_phy_init/dwc2_phy_update: phy init called before and after core reset -// - dwc2_dcd_int_enable/dwc2_dcd_int_disable -// - dwc2_remote_wakeup_delay - -#if defined(TUP_USBIP_DWC2_STM32) - #include "dwc2_stm32.h" -#elif defined(TUP_USBIP_DWC2_ESP32) - #include "dwc2_esp32.h" -#elif TU_CHECK_MCU(OPT_MCU_GD32VF103) - #include "dwc2_gd32.h" -#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) - #include "dwc2_bcm.h" -#elif TU_CHECK_MCU(OPT_MCU_EFM32GG) - #include "dwc2_efm32.h" -#elif TU_CHECK_MCU(OPT_MCU_XMC4000) - #include "dwc2_xmc.h" +#include "dwc2_common.h" + +#if TU_CHECK_MCU(OPT_MCU_GD32VF103) + #define DWC2_EP_COUNT(_dwc2) DWC2_EP_MAX #else - #error "Unsupported MCUs" + #define DWC2_EP_COUNT(_dwc2) ((_dwc2)->ghwcfg2_bm.num_dev_ep + 1) #endif -enum { - DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE(_dwc2_controller) -}; - -// DWC2 registers -//#define DWC2_REG(_port) ((dwc2_regs_t*) _dwc2_controller[_port].reg_base) - -TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { - if (rhport >= DWC2_CONTROLLER_COUNT) { - // user mis-configured, ignore and use first controller - rhport = 0; - } - return (dwc2_regs_t*) _dwc2_controller[rhport].reg_base; -} - //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ - -static CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; - typedef struct { uint8_t* buffer; tu_fifo_t* ff; @@ -92,34 +61,48 @@ typedef struct { static xfer_ctl_t xfer_status[DWC2_EP_MAX][2]; #define XFER_CTL_BASE(_ep, _dir) (&xfer_status[_ep][_dir]) -// EP0 transfers are limited to 1 packet - larger sizes has to be split -static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type -static uint16_t _dfifo_top; // top free location in FIFO RAM +typedef struct { + // EP0 transfers are limited to 1 packet - larger sizes has to be split + uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type + uint16_t dfifo_top; // top free location in DFIFO in words -// Number of IN endpoints active -static uint8_t _allocated_ep_in_count; + // Number of IN endpoints active + uint8_t allocated_epin_count; -// SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by -static bool _sof_en; + // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by + bool sof_en; +} dcd_data_t; + +static dcd_data_t _dcd_data; + +CFG_TUD_MEM_SECTION static struct { + TUD_EPBUF_DEF(setup_packet, 8); +} _dcd_usbbuf; //-------------------------------------------------------------------- // DMA //-------------------------------------------------------------------- +#if CFG_TUD_MEM_DCACHE_ENABLE +bool dcd_dcache_clean(const void* addr, uint32_t data_size) { + TU_VERIFY(addr && data_size); + return dwc2_dcache_clean(addr, data_size); +} -TU_ATTR_ALWAYS_INLINE static inline bool dma_enabled(const dwc2_regs_t* dwc2) { - #if !CFG_TUD_DWC2_DMA - (void) dwc2; - return false; - #else - // Internal DMA only - return (dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA); - #endif +bool dcd_dcache_invalidate(const void* addr, uint32_t data_size) { + TU_VERIFY(addr && data_size); + return dwc2_dcache_invalidate(addr, data_size); } -TU_ATTR_ALWAYS_INLINE static inline uint16_t dma_cal_epfifo_base(uint8_t rhport) { - // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per endpoint direction - const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; - return dwc2_controller->ep_fifo_size/4 - 2*dwc2_controller->ep_count; +bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) { + TU_VERIFY(addr && data_size); + return dwc2_dcache_clean_invalidate(addr, data_size); +} +#endif + +TU_ATTR_ALWAYS_INLINE static inline bool dma_device_enabled(const dwc2_regs_t* dwc2) { + (void) dwc2; + // Internal DMA only + return CFG_TUD_DWC2_DMA_ENABLE && dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA; } static void dma_setup_prepare(uint8_t rhport) { @@ -133,7 +116,7 @@ static void dma_setup_prepare(uint8_t rhport) { // Receive only 1 packet dwc2->epout[0].doeptsiz = (1 << DOEPTSIZ_STUPCNT_Pos) | (1 << DOEPTSIZ_PKTCNT_Pos) | (8 << DOEPTSIZ_XFRSIZ_Pos); - dwc2->epout[0].doepdma = (uintptr_t)_setup_packet; + dwc2->epout[0].doepdma = (uintptr_t) _dcd_usbbuf.setup_packet; dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; } @@ -141,18 +124,8 @@ static void dma_setup_prepare(uint8_t rhport) { // Data FIFO //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_tx(dwc2_regs_t* dwc2, uint8_t epnum) { - // flush TX fifo and wait for it cleared - dwc2->grstctl = GRSTCTL_TXFFLSH | (epnum << GRSTCTL_TXFNUM_Pos); - while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} -} -TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx(dwc2_regs_t* dwc2) { - // flush RX fifo and wait for it cleared - dwc2->grstctl = GRSTCTL_RXFFLSH; - while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} -} -/* USB Data FIFO Layout +/* Device Data FIFO scheme The FIFO is split up into - EPInfo: for storing DMA metadata, only required when use DMA. Maximum size is called @@ -167,11 +140,9 @@ TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx(dwc2_regs_t* dwc2) { possible since the free space is located between the RX and TX FIFOs. ---------------- ep_fifo_size - | EPInfo | - | for DMA | + | DxEPIDMAn | |-------------|-- gdfifocfg.EPINFOBASE (max is ghwcfg3.dfifo_depth) - | IN FIFO 0 | - | control | + | IN FIFO 0 | control EP |-------------| | IN FIFO 1 | |-------------| @@ -190,133 +161,86 @@ TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx(dwc2_regs_t* dwc2) { - All EP OUT shared a unique OUT FIFO which uses (for Slave or Buffer DMA, Scatt/Gather DMA use different formula): - 13 for setup packets + control words (up to 3 setup packets). - 1 for global NAK (not required/used here). - - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" + - Largest-EPsize/4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4 + 1)" - 2 for each used OUT endpoint Therefore GRXFSIZ = 13 + 1 + 2 x (Largest-EPsize/4 + 1) + 2 x EPOUTnum */ -TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_grxfsiz(uint16_t largest_ep_size, uint8_t ep_count) { +TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_device_grxfsiz(uint16_t largest_ep_size, uint8_t ep_count) { return 13 + 1 + 2 * ((largest_ep_size / 4) + 1) + 2 * ep_count; } static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; - uint8_t const ep_count = dwc2_controller->ep_count; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + const uint8_t ep_count = dwc2_controller->ep_count; + const uint8_t epnum = tu_edpt_number(ep_addr); + const uint8_t dir = tu_edpt_dir(ep_addr); TU_ASSERT(epnum < ep_count); uint16_t fifo_size = tu_div_ceil(packet_size, 4); if (dir == TUSB_DIR_OUT) { // Calculate required size of RX FIFO - uint16_t const new_sz = calc_grxfsiz(4 * fifo_size, ep_count); + const uint16_t new_sz = calc_device_grxfsiz(4 * fifo_size, ep_count); // If size_rx needs to be extended check if there is enough free space if (dwc2->grxfsiz < new_sz) { - TU_ASSERT(new_sz <= _dfifo_top); + TU_ASSERT(new_sz <= _dcd_data.dfifo_top); dwc2->grxfsiz = new_sz; // Enlarge RX FIFO } } else { // Check IN endpoints concurrently active limit - if(_dwc2_controller->ep_in_count) { - TU_ASSERT(_allocated_ep_in_count < _dwc2_controller->ep_in_count); - _allocated_ep_in_count++; + if(dwc2_controller->ep_in_count) { + TU_ASSERT(_dcd_data.allocated_epin_count < dwc2_controller->ep_in_count); + _dcd_data.allocated_epin_count++; } // If The TXFELVL is configured as half empty, the fifo must be twice the max_size. - if ((dwc2->gahbcfg & GAHBCFG_TXFELVL) == 0) { + if ((dwc2->gahbcfg & GAHBCFG_TX_FIFO_EPMTY_LVL) == 0) { fifo_size *= 2; } // Check if free space is available - TU_ASSERT(_dfifo_top >= fifo_size + dwc2->grxfsiz); - _dfifo_top -= fifo_size; - TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, _dfifo_top); + TU_ASSERT(_dcd_data.dfifo_top >= fifo_size + dwc2->grxfsiz); + _dcd_data.dfifo_top -= fifo_size; + // TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, dfifo_top); // Both TXFD and TXSA are in unit of 32-bit words. if (epnum == 0) { - dwc2->dieptxf0 = (fifo_size << DIEPTXF0_TX0FD_Pos) | _dfifo_top; + dwc2->dieptxf0 = (fifo_size << DIEPTXF0_TX0FD_Pos) | _dcd_data.dfifo_top; } else { // DIEPTXF starts at FIFO #1. - dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | _dfifo_top; + dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | _dcd_data.dfifo_top; } } return true; } -static void dfifo_init(uint8_t rhport) { +static void dfifo_device_init(uint8_t rhport) { const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; dwc2_regs_t* dwc2 = DWC2_REG(rhport); - dwc2->grxfsiz = calc_grxfsiz(CFG_TUD_ENDPOINT0_SIZE, dwc2_controller->ep_count); + dwc2->grxfsiz = calc_device_grxfsiz(CFG_TUD_ENDPOINT0_SIZE, dwc2_controller->ep_count); - if(dma_enabled(dwc2)) { - // DMA use last DFIFO to store metadata - _dfifo_top = dma_cal_epfifo_base(rhport); - }else { - _dfifo_top = dwc2_controller->ep_fifo_size / 4; + // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per endpoint direction + const bool is_dma = dma_device_enabled(dwc2); + _dcd_data.dfifo_top = dwc2_controller->ep_fifo_size/4; + if (is_dma) { + _dcd_data.dfifo_top -= 2 * dwc2_controller->ep_count; } + dwc2->gdfifocfg = (_dcd_data.dfifo_top << GDFIFOCFG_EPINFOBASE_SHIFT) | _dcd_data.dfifo_top; // Allocate FIFO for EP0 IN dfifo_alloc(rhport, 0x80, CFG_TUD_ENDPOINT0_SIZE); } -// Read a single data packet from receive FIFO -static void dfifo_read_packet(uint8_t rhport, uint8_t* dst, uint16_t len) { - (void) rhport; - - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - volatile const uint32_t* rx_fifo = dwc2->fifo[0]; - - // Reading full available 32 bit words from fifo - uint16_t full_words = len >> 2; - while (full_words--) { - tu_unaligned_write32(dst, *rx_fifo); - dst += 4; - } - - // Read the remaining 1-3 bytes from fifo - uint8_t const bytes_rem = len & 0x03; - if (bytes_rem != 0) { - uint32_t const tmp = *rx_fifo; - dst[0] = tu_u32_byte0(tmp); - if (bytes_rem > 1) dst[1] = tu_u32_byte1(tmp); - if (bytes_rem > 2) dst[2] = tu_u32_byte2(tmp); - } -} - -// Write a single data packet to EPIN FIFO -static void dfifo_write_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const* src, uint16_t len) { - (void) rhport; - - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num]; - - // Pushing full available 32 bit words to fifo - uint16_t full_words = len >> 2; - while (full_words--) { - *tx_fifo = tu_unaligned_read32(src); - src += 4; - } - - // Write the remaining 1-3 bytes into fifo - uint8_t const bytes_rem = len & 0x03; - if (bytes_rem) { - uint32_t tmp_word = src[0]; - if (bytes_rem > 1) tmp_word |= (src[1] << 8); - if (bytes_rem > 2) tmp_word |= (src[2] << 16); - - *tx_fifo = tmp_word; - } -} //-------------------------------------------------------------------- // Endpoint //-------------------------------------------------------------------- -#if defined(TUP_USBIP_DWC2_ESP32) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) // Keep count of how many FIFOs are in use static uint8_t _allocated_fifos = 1; //FIFO0 is always in use @@ -327,27 +251,32 @@ static uint8_t get_free_fifo(void) { } #endif -static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { +static void edpt_activate(uint8_t rhport, const tusb_desc_endpoint_t* p_endpoint_desc) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + const uint8_t epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + const uint8_t dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = tu_edpt_packet_size(p_endpoint_desc); xfer->interval = p_endpoint_desc->bInterval; - // USBAEP, EPTYP, SD0PID_SEVNFRM, MPSIZ are the same for IN and OUT endpoints. - uint32_t const dxepctl = (1 << DOEPCTL_USBAEP_Pos) | - (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) | - (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << DOEPCTL_MPSIZ_Pos); - - if (dir == TUSB_DIR_OUT) { - dwc2->epout[epnum].doepctl = dxepctl; - dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); - } else { + // Endpoint control + union { + uint32_t value; + dwc2_depctl_t bm; + } depctl; + depctl.value = 0; + + depctl.bm.mps = xfer->max_size; + depctl.bm.active = 1; + depctl.bm.type = p_endpoint_desc->bmAttributes.xfer; + if (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) { + depctl.bm.set_data0_iso_even = 1; + } + if (dir == TUSB_DIR_IN) { + //depctl.bm.tx_fifo_num = epnum; uint8_t fifo_num = epnum; -#if defined(TUP_USBIP_DWC2_ESP32) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) // Special Case for EP5, which is used by CDC but not actually called by the driver // we can give it a fake FIFO if (epnum == 5) { @@ -355,46 +284,45 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin } else { fifo_num = get_free_fifo(); } - //TU_ASSERT(fifo_num != 0); #endif - dwc2->epin[epnum].diepctl = dxepctl | (fifo_num << DIEPCTL_TXFNUM_Pos); - dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum); + depctl.bm.tx_fifo_num = fifo_num; } + + dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; + dep->ctl = depctl.value; + dwc2->daintmsk |= TU_BIT(epnum + DAINT_SHIFT(dir)); } static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + const uint8_t epnum = tu_edpt_number(ep_addr); + const uint8_t dir = tu_edpt_dir(ep_addr); + dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; if (dir == TUSB_DIR_IN) { - dwc2_epin_t* epin = dwc2->epin; - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(epin[epnum].diepctl & DIEPCTL_EPENA)) { - epin[epnum].diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); + if ((epnum == 0) || !(dep->diepctl & DIEPCTL_EPENA)) { + dep->diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); } else { // Stop transmitting packets and NAK IN xfers. - epin[epnum].diepctl |= DIEPCTL_SNAK; - while ((epin[epnum].diepint & DIEPINT_INEPNE) == 0) {} + dep->diepctl |= DIEPCTL_SNAK; + while ((dep->diepint & DIEPINT_INEPNE) == 0) {} // Disable the endpoint. - epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); - while ((epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0) {} + dep->diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); + while ((dep->diepint & DIEPINT_EPDISD_Msk) == 0) {} - epin[epnum].diepint = DIEPINT_EPDISD; + dep->diepint = DIEPINT_EPDISD; } // Flush the FIFO, and wait until we have confirmed it cleared. dfifo_flush_tx(dwc2, epnum); } else { - dwc2_epout_t* epout = dwc2->epout; - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(epout[epnum].doepctl & DOEPCTL_EPENA)) { - epout[epnum].doepctl |= stall ? DOEPCTL_STALL : 0; + if ((epnum == 0) || !(dep->doepctl & DOEPCTL_EPENA)) { + dep->doepctl |= stall ? DOEPCTL_STALL : 0; } else { // Asserting GONAK is required to STALL an OUT endpoint. // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt @@ -403,11 +331,11 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { dwc2->dctl |= DCTL_SGONAK; while ((dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0) {} - // Ditto here- disable the endpoint. - epout[epnum].doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); - while ((epout[epnum].doepint & DOEPINT_EPDISD_Msk) == 0) {} + // Ditto here disable the endpoint. + dep->doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); + while ((dep->doepint & DOEPINT_EPDISD_Msk) == 0) {} - epout[epnum].doepint = DOEPINT_EPDISD; + dep->doepint = DOEPINT_EPDISD; // Allow other OUT endpoints to keep receiving. dwc2->dctl |= DCTL_CGONAK; @@ -415,343 +343,124 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { } } -// Start of Bus Reset -static void bus_reset(uint8_t rhport) { - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; - - tu_memclr(xfer_status, sizeof(xfer_status)); - - _sof_en = false; - - _allocated_ep_in_count = 1; - - // clear device address - dwc2->dcfg &= ~DCFG_DAD_Msk; - - // 1. NAK for all OUT endpoints - for (uint8_t n = 0; n < ep_count; n++) { - dwc2->epout[n].doepctl |= DOEPCTL_SNAK; - } - - // 2. Disable all IN endpoints - for (uint8_t n = 0; n < ep_count; n++) { - if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { - dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; - } - } - - dfifo_flush_tx(dwc2, 0x10); // all tx fifo - dfifo_flush_rx(dwc2); - - // 3. Set up interrupt mask - dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); - dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; - dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; - - dfifo_init(rhport); - - // Fixed control EP0 size to 64 bytes - dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); - dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos); - - xfer_status[0][TUSB_DIR_OUT].max_size = 64; - xfer_status[0][TUSB_DIR_IN].max_size = 64; - - if(dma_enabled(dwc2)) { - dma_setup_prepare(rhport); - } else { - dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); - } - - dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; -} - -static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, - uint16_t total_bytes) { - (void) rhport; - +static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uint8_t dir) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir); + dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; - // EP0 is limited to one packet each xfer - // We use multiple transaction of xfer->max_size length to get a whole transfer done + uint16_t num_packets; + uint16_t total_bytes; + + // EP0 is limited to one packet per xfer if (epnum == 0) { - total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); - ep0_pending[dir] -= total_bytes; + total_bytes = tu_min16(_dcd_data.ep0_pending[dir], xfer->max_size); + _dcd_data.ep0_pending[dir] -= total_bytes; + num_packets = 1; + } else { + total_bytes = xfer->total_len; + num_packets = tu_div_ceil(total_bytes, xfer->max_size); + if (num_packets == 0) { + num_packets = 1; // zero length packet still count as 1 + } } - // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. - if (dir == TUSB_DIR_IN) { - dwc2_epin_t* epin = dwc2->epin; - - // A full IN transfer (multiple packets, possibly) triggers XFRC. - epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | - ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); - - if(dma_enabled(dwc2)) { - epin[epnum].diepdma = (uintptr_t)xfer->buffer; - - // For ISO endpoint set correct odd/even bit for next frame. - if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); - } - - epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + // transfer size: A full OUT transfer (multiple packets, possibly) triggers XFRC. + union { + uint32_t value; + dwc2_ep_tsize_t bm; + } deptsiz; + deptsiz.value = 0; + deptsiz.bm.xfer_size = total_bytes; + deptsiz.bm.packet_count = num_packets; + + dep->tsiz = deptsiz.value; + + // control + union { + dwc2_depctl_t bm; + uint32_t value; + } depctl; + depctl.value = dep->ctl; + + depctl.bm.clear_nak = 1; + depctl.bm.enable = 1; + if (depctl.bm.type == DEPCTL_EPTYPE_ISOCHRONOUS && xfer->interval == 1) { + const uint32_t odd_now = (dwc2->dsts_bm.frame_number & 1u); + if (odd_now) { + depctl.bm.set_data0_iso_even = 1; } else { + depctl.bm.set_data1_iso_odd = 1; + } + } - epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; - - // For ISO endpoint set correct odd/even bit for next frame. - if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); - } - // Enable fifo empty interrupt only if there are something to put in the fifo. - if (total_bytes != 0) { - dwc2->diepempmsk |= (1 << epnum); - } + const bool is_dma = dma_device_enabled(dwc2); + if(is_dma) { + if (dir == TUSB_DIR_IN && total_bytes != 0) { + dcd_dcache_clean(xfer->buffer, total_bytes); } + dep->diepdma = (uintptr_t) xfer->buffer; + dep->diepctl = depctl.value; // enable endpoint } else { - dwc2_epout_t* epout = dwc2->epout; - - // A full OUT transfer (multiple packets, possibly) triggers XFRC. - epout[epnum].doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ); - epout[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) | - ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk); - - if ((epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && - XFER_CTL_BASE(epnum, dir)->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); - } + dep->diepctl = depctl.value; // enable endpoint - if(dma_enabled(dwc2)) { - epout[epnum].doepdma = (uintptr_t)xfer->buffer; + // Enable tx fifo empty interrupt only if there is data. Note must after depctl enable + if (dir == TUSB_DIR_IN && total_bytes != 0) { + dwc2->diepempmsk |= (1 << epnum); } - - epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; } } -/*------------------------------------------------------------------*/ -/* Controller API - *------------------------------------------------------------------*/ - -static void reset_core(dwc2_regs_t* dwc2) { - // reset core - dwc2->grstctl |= GRSTCTL_CSRST; - - // wait for reset bit is cleared - // TODO version 4.20a should wait for RESET DONE mask - while (dwc2->grstctl & GRSTCTL_CSRST) {} - - // wait for AHB master IDLE - while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) {} - - // wait for device mode ? -} - -static bool phy_hs_supported(dwc2_regs_t* dwc2) { - (void) dwc2; - -#if !TUD_OPT_HIGH_SPEED - return false; -#else - return dwc2->ghwcfg2_bm.hs_phy_type != GHWCFG2_HSPHY_NOT_SUPPORTED; -#endif -} - -static void phy_fs_init(dwc2_regs_t* dwc2) { - TU_LOG(DWC2_DEBUG, "Fullspeed PHY init\r\n"); - - // Select FS PHY - dwc2->gusbcfg |= GUSBCFG_PHYSEL; - - // MCU specific PHY init before reset - dwc2_phy_init(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); - - // Reset core after selecting PHY - reset_core(dwc2); - - // USB turnaround time is critical for certification where long cables and 5-Hubs are used. - // So if you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, - // these bits can be programmed to a larger value. Default is 5 - dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos); - - // MCU specific PHY update post reset - dwc2_phy_update(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); - - // set max speed - dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos); -} - -static void phy_hs_init(dwc2_regs_t* dwc2) { - uint32_t gusbcfg = dwc2->gusbcfg; - - // De-select FS PHY - gusbcfg &= ~GUSBCFG_PHYSEL; - - if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) { - TU_LOG(DWC2_DEBUG, "Highspeed ULPI PHY init\r\n"); - - // Select ULPI - gusbcfg |= GUSBCFG_ULPI_UTMI_SEL; - - // ULPI 8-bit interface, single data rate - gusbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL); +//-------------------------------------------------------------------- +// Controller API +//-------------------------------------------------------------------- +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; + dwc2_regs_t* dwc2 = DWC2_REG(rhport); - // default internal VBUS Indicator and Drive - gusbcfg &= ~(GUSBCFG_ULPIEVBUSD | GUSBCFG_ULPIEVBUSI); + tu_memclr(&_dcd_data, sizeof(_dcd_data)); - // Disable FS/LS ULPI - gusbcfg &= ~(GUSBCFG_ULPIFSLS | GUSBCFG_ULPICSM); - } else { - TU_LOG(DWC2_DEBUG, "Highspeed UTMI+ PHY init\r\n"); + // Core Initialization + const bool is_highspeed = dwc2_core_is_highspeed(dwc2, TUSB_ROLE_DEVICE); + const bool is_dma = dma_device_enabled(dwc2); + TU_ASSERT(dwc2_core_init(rhport, is_highspeed, is_dma)); - // Select UTMI+ with 8-bit interface - gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); + //------------- 7.1 Device Initialization -------------// + // Set device max speed + uint32_t dcfg = dwc2->dcfg & ~DCFG_DSPD_Msk; + if (is_highspeed) { + dcfg |= DCFG_DSPD_HS << DCFG_DSPD_Pos; - // Set 16-bit interface if supported - if (dwc2->ghwcfg4_bm.phy_data_width) { - gusbcfg |= GUSBCFG_PHYIF16; + // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required + // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347) + if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) { + dcfg |= DCFG_XCVRDLY; } + } else { + dcfg |= DCFG_DSPD_FS << DCFG_DSPD_Pos; } - // Apply config - dwc2->gusbcfg = gusbcfg; - - // mcu specific phy init - dwc2_phy_init(dwc2, dwc2->ghwcfg2_bm.hs_phy_type); - - // Reset core after selecting PHY - reset_core(dwc2); - - // Set turn-around, must after core reset otherwise it will be clear - // - 9 if using 8-bit PHY interface - // - 5 if using 16-bit PHY interface - gusbcfg &= ~GUSBCFG_TRDT_Msk; - gusbcfg |= (dwc2->ghwcfg4_bm.phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; - dwc2->gusbcfg = gusbcfg; - - // MCU specific PHY update post reset - dwc2_phy_update(dwc2, dwc2->ghwcfg2_bm.hs_phy_type); - - // Set max speed - uint32_t dcfg = dwc2->dcfg; - dcfg &= ~DCFG_DSPD_Msk; - dcfg |= DCFG_DSPD_HS << DCFG_DSPD_Pos; - - // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required - // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347) - if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) { - dcfg |= DCFG_XCVRDLY; - } - + dcfg |= DCFG_NZLSOHSK; // send STALL back and discard if host send non-zlp during control status dwc2->dcfg = dcfg; -} - -static bool check_dwc2(dwc2_regs_t* dwc2) { -#if CFG_TUSB_DEBUG >= DWC2_DEBUG - // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 - // Run 'dwc2_info.py render-md' and check dwc2_info.md for bit-field value and comparison with other ports - volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; - TU_LOG1("guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); - for (size_t i = 0; i < 5; i++) { - TU_LOG1("0x%08" PRIX32 ", ", p[i]); - } - TU_LOG1("0x%08" PRIX32 "\r\n", p[5]); -#endif - // For some reason: GD32VF103 snpsid and all hwcfg register are always zero (skip it) - (void) dwc2; -#if !TU_CHECK_MCU(OPT_MCU_GD32VF103) - uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; - TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID); -#endif - - return true; -} - -void dcd_init(uint8_t rhport) { - // Programming model begins in the last section of the chapter on the USB - // peripheral in each Reference Manual. - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - - // Check Synopsys ID register, failed if controller clock/power is not enabled - TU_ASSERT(check_dwc2(dwc2), ); dcd_disconnect(rhport); - if (phy_hs_supported(dwc2)) { - phy_hs_init(dwc2); // Highspeed - } else { - phy_fs_init(dwc2); // core does not support highspeed or hs phy is not present - } - - // Restart PHY clock - dwc2->pcgctl &= ~(PCGCTL_STOPPCLK | PCGCTL_GATEHCLK | PCGCTL_PWRCLMP | PCGCTL_RSTPDWNMODULE); - - /* Set HS/FS Timeout Calibration to 7 (max available value). - * The number of PHY clocks that the application programs in - * this field is added to the high/full speed interpacket timeout - * duration in the core to account for any additional delays - * introduced by the PHY. This can be required, because the delay - * introduced by the PHY in generating the linestate condition - * can vary from one PHY to another. - */ - dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos); - // Force device mode dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD; // Clear A override, force B Valid dwc2->gotgctl = (dwc2->gotgctl & ~GOTGCTL_AVALOEN) | GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL; - // If USB host misbehaves during status portion of control xfer - // (non zero-length packet), send STALL back and discard. - dwc2->dcfg |= DCFG_NZLSOHSK; - - dfifo_flush_tx(dwc2, 0x10); // all tx fifo - dfifo_flush_rx(dwc2); + // Enable required interrupts + dwc2->gintmsk |= GINTMSK_OTGINT | GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; - // Clear all interrupts - uint32_t int_mask = dwc2->gintsts; - dwc2->gintsts |= int_mask; - int_mask = dwc2->gotgint; - dwc2->gotgint |= int_mask; - - // Required as part of core initialization. - dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; - - // Configure TX FIFO empty level for interrupt. Default is complete empty - dwc2->gahbcfg |= GAHBCFG_TXFELVL; - - if (dma_enabled(dwc2)) { - const uint16_t epinfo_base = dma_cal_epfifo_base(rhport); - dwc2->gdfifocfg = (epinfo_base << GDFIFOCFG_EPINFOBASE_SHIFT) | epinfo_base; - - // DMA seems to be only settable after a core reset - dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2; - }else { - dwc2->gintmsk |= GINTMSK_RXFLVLM; - } - - // Enable global interrupt - dwc2->gahbcfg |= GAHBCFG_GINT; - - // make sure we are in device mode -// TU_ASSERT(!(dwc2->gintsts & GINTSTS_CMOD), ); - -// TU_LOG_HEX(DWC2_DEBUG, dwc2->gotgctl); -// TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg); -// TU_LOG_HEX(DWC2_DEBUG, dwc2->dcfg); -// TU_LOG_HEX(DWC2_DEBUG, dwc2->gahbcfg); + // TX FIFO empty level for interrupt is complete empty + uint32_t gahbcfg = dwc2->gahbcfg; + gahbcfg |= GAHBCFG_TX_FIFO_EPMTY_LVL; + gahbcfg |= GAHBCFG_GINT; // Enable global interrupt + dwc2->gahbcfg = gahbcfg; dcd_connect(rhport); + return true; } void dcd_int_enable(uint8_t rhport) { @@ -827,7 +536,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); - _sof_en = en; + _dcd_data.sof_en = en; if (en) { dwc2->gintsts = GINTSTS_SOF; @@ -852,33 +561,29 @@ void dcd_edpt_close_all(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; - _allocated_ep_in_count = 1; + _dcd_data.allocated_epin_count = 0; // Disable non-control interrupt dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); for (uint8_t n = 1; n < ep_count; n++) { - // disable OUT endpoint - if (dwc2->epout[n].doepctl & DOEPCTL_EPENA) { - dwc2->epout[n].doepctl |= DOEPCTL_SNAK | DOEPCTL_EPDIS; - } - xfer_status[n][TUSB_DIR_OUT].max_size = 0; - - // disable IN endpoint - if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { - dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; + for (uint8_t d = 0; d < 2; d++) { + dwc2_dep_t* dep = &dwc2->ep[d][n]; + if (dep->ctl & EPCTL_EPENA) { + dep->ctl |= EPCTL_SNAK | EPCTL_EPDIS; + } + xfer_status[n][1-d].max_size = 0; } - xfer_status[n][TUSB_DIR_IN].max_size = 0; } -#if defined(TUP_USBIP_DWC2_ESP32) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) _allocated_fifos = 1; #endif dfifo_flush_tx(dwc2, 0x10); // all tx fifo dfifo_flush_rx(dwc2); - dfifo_init(rhport); // re-init dfifo + dfifo_device_init(rhport); // re-init dfifo } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { @@ -904,21 +609,12 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to // EP0 can only handle one packet if (epnum == 0) { - ep0_pending[dir] = total_bytes; - - // Schedule the first transaction for EP0 transfer - edpt_schedule_packets(rhport, epnum, dir, 1, ep0_pending[dir]); - } else { - uint16_t num_packets = (total_bytes / xfer->max_size); - uint16_t const short_packet_size = total_bytes % xfer->max_size; - - // Zero-size packet is special case. - if ((short_packet_size > 0) || (total_bytes == 0)) num_packets++; - - // Schedule packets to be sent within interrupt - edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); + _dcd_data.ep0_pending[dir] = total_bytes; } + // Schedule packets to be sent within interrupt + edpt_schedule_packets(rhport, epnum, dir); + return true; } @@ -938,339 +634,410 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t xfer->ff = ff; xfer->total_len = total_bytes; - uint16_t num_packets = (total_bytes / xfer->max_size); - uint16_t const short_packet_size = total_bytes % xfer->max_size; - - // Zero-size packet is special case. - if (short_packet_size > 0 || (total_bytes == 0)) num_packets++; - // Schedule packets to be sent within interrupt - edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); + // TODO xfer fifo may only available for slave mode + edpt_schedule_packets(rhport, epnum, dir); return true; } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - edpt_disable(rhport, ep_addr, false); -} - void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); edpt_disable(rhport, ep_addr, true); - if((tu_edpt_number(ep_addr) == 0) && dma_enabled(DWC2_REG(rhport))) { + if((tu_edpt_number(ep_addr) == 0) && dma_device_enabled(dwc2)) { dma_setup_prepare(rhport); } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); + dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; // Clear stall and reset data toggle - if (dir == TUSB_DIR_IN) { - dwc2->epin[epnum].diepctl &= ~DIEPCTL_STALL; - dwc2->epin[epnum].diepctl |= DIEPCTL_SD0PID_SEVNFRM; - } else { - dwc2->epout[epnum].doepctl &= ~DOEPCTL_STALL; - dwc2->epout[epnum].doepctl |= DOEPCTL_SD0PID_SEVNFRM; - } + dep->ctl &= ~EPCTL_STALL;; + dep->ctl |= EPCTL_SD0PID_SEVNFRM; } //-------------------------------------------------------------------- // Interrupt Handler //-------------------------------------------------------------------- +// 7.4.1 Initialization on USB Reset +static void handle_bus_reset(uint8_t rhport) { + dwc2_regs_t *dwc2 = DWC2_REG(rhport); + const uint8_t ep_count = DWC2_EP_COUNT(dwc2); + + tu_memclr(xfer_status, sizeof(xfer_status)); + + _dcd_data.sof_en = false; + _dcd_data.allocated_epin_count = 0; + + // 1. NAK for all OUT endpoints + for (uint8_t n = 0; n < ep_count; n++) { + dwc2->epout[n].doepctl |= DOEPCTL_SNAK; + } + + // Disable all IN endpoints + for (uint8_t n = 0; n < ep_count; n++) { + if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { + dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; + } + } + + // 2. Set up interrupt mask for EP0 + dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); + dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; + dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; + + // 4. Set up DFIFO + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); + dfifo_device_init(rhport); + + // 5. Reset device address + dwc2->dcfg_bm.address = 0; + + // Fixed both control EP0 size to 64 bytes + dwc2->epin[0].ctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); + dwc2->epout[0].ctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos); + + xfer_status[0][TUSB_DIR_OUT].max_size = 64; + xfer_status[0][TUSB_DIR_IN].max_size = 64; + + if(dma_device_enabled(dwc2)) { + dma_setup_prepare(rhport); + } else { + dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); + } + + dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; +} + +static void handle_enum_done(uint8_t rhport) { + dwc2_regs_t *dwc2 = DWC2_REG(rhport); + tusb_speed_t speed; + switch (dwc2->dsts_bm.enum_speed) { + case DCFG_SPEED_HIGH: + speed = TUSB_SPEED_HIGH; + break; + + case DCFG_SPEED_LOW: + speed = TUSB_SPEED_LOW; + break; + + case DCFG_SPEED_FULL_30_60MHZ: + case DCFG_SPEED_FULL_48MHZ: + default: + speed = TUSB_SPEED_FULL; + break; + } + + // TODO must update GUSBCFG_TRDT according to link speed + dcd_event_bus_reset(rhport, speed, true); +} + +#if 0 +TU_ATTR_ALWAYS_INLINE static inline void print_doepint(uint32_t doepint) { + const char* str[] = { + "XFRC", "DIS", "AHBERR", "SETUP_DONE", + "ORXED", "STATUS_RX", "SETUP_B2B", "RSV7", + "OPERR", "BNA", "RSV10", "ISODROP", + "BBLERR", "NAK", "NYET", "SETUP_RX" + }; + + for(uint32_t i=0; ififo[0]; + const volatile uint32_t* rx_fifo = dwc2->fifo[0]; // Pop control word off FIFO - uint32_t const ctl_word = dwc2->grxstsp; - uint8_t const pktsts = (ctl_word & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos; - uint8_t const epnum = (ctl_word & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos; - uint16_t const bcnt = (ctl_word & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos; - - dwc2_epout_t* epout = &dwc2->epout[epnum]; - -//#if CFG_TUSB_DEBUG >= DWC2_DEBUG -// const char * pktsts_str[] = -// { -// "ASSERT", "Global NAK (ISR)", "Out Data Received", "Out Transfer Complete (ISR)", -// "Setup Complete (ISR)", "ASSERT", "Setup Data Received" -// }; -// TU_LOG_LOCATION(); -// TU_LOG(DWC2_DEBUG, " EP %02X, Byte Count %u, %s\r\n", epnum, bcnt, pktsts_str[pktsts]); -// TU_LOG(DWC2_DEBUG, " daint = %08lX, doepint = %04X\r\n", (unsigned long) dwc2->daint, (unsigned int) epout->doepint); -//#endif - - switch (pktsts) { - // Global OUT NAK: do nothing - case GRXSTS_PKTSTS_GLOBALOUTNAK: + const dwc2_grxstsp_t grxstsp_bm = dwc2->grxstsp_bm; + const uint8_t epnum = grxstsp_bm.ep_ch_num; + + dwc2_dep_t* epout = &dwc2->epout[epnum]; + + switch (grxstsp_bm.packet_status) { + case GRXSTS_PKTSTS_GLOBAL_OUT_NAK: + // Global OUT NAK: do nothing break; - case GRXSTS_PKTSTS_SETUPRX: + case GRXSTS_PKTSTS_SETUP_RX: { // Setup packet received - - // We can receive up to three setup packets in succession, but - // only the last one is valid. - _setup_packet[0] = (*rx_fifo); - _setup_packet[1] = (*rx_fifo); + uint32_t* setup = (uint32_t*)(uintptr_t) _dcd_usbbuf.setup_packet; + // We can receive up to three setup packets in succession, but only the last one is valid. + setup[0] = (*rx_fifo); + setup[1] = (*rx_fifo); break; + } - case GRXSTS_PKTSTS_SETUPDONE: - // Setup packet done (Interrupt) + case GRXSTS_PKTSTS_SETUP_DONE: + // Setup packet done: + // After popping this out, dwc2 asserts a DOEPINT_SETUP interrupt which is handled by handle_epout_irq() epout->doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); break; - case GRXSTS_PKTSTS_OUTRX: { + case GRXSTS_PKTSTS_RX_DATA: { // Out packet received + const uint16_t byte_count = grxstsp_bm.byte_count; xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - // Read packet off RxFIFO - if (xfer->ff) { - // Ring buffer - tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void*) (uintptr_t) rx_fifo, bcnt); - } else { - // Linear buffer - dfifo_read_packet(rhport, xfer->buffer, bcnt); - - // Increment pointer to xfer data - xfer->buffer += bcnt; - } + if (byte_count) { + // Read packet off RxFIFO + if (xfer->ff) { + tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void*) (uintptr_t) rx_fifo, byte_count); + } else { + dfifo_read_packet(dwc2, xfer->buffer, byte_count); + xfer->buffer += byte_count; + } - // Truncate transfer length in case of short packet - if (bcnt < xfer->max_size) { - xfer->total_len -= (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; - if (epnum == 0) { - xfer->total_len -= ep0_pending[TUSB_DIR_OUT]; - ep0_pending[TUSB_DIR_OUT] = 0; + // short packet, minus remaining bytes (xfer_size) + if (byte_count < xfer->max_size) { + xfer->total_len -= epout->tsiz_bm.xfer_size; + if (epnum == 0) { + xfer->total_len -= _dcd_data.ep0_pending[TUSB_DIR_OUT]; + _dcd_data.ep0_pending[TUSB_DIR_OUT] = 0; + } } } - } break; + } - // Out packet done (Interrupt) - case GRXSTS_PKTSTS_OUTDONE: - // Occurred on STM32L47 with dwc2 version 3.10a but not found on other version like 2.80a or 3.30a - // May (or not) be 3.10a specific feature/bug or depending on MCU configuration - // XFRC complete is additionally generated when - // - setup packet is received - // - complete the data stage of control write is complete - // It will be handled in handle_epout_irq() + case GRXSTS_PKTSTS_RX_COMPLETE: + // Out packet done + // After this entry is popped from the receive FIFO, dwc2 asserts a Transfer Completed interrupt on + // the specified OUT endpoint which will be handled by handle_epout_irq() break; - default: // Invalid - TU_BREAKPOINT(); - break; + default: break; } } -static void handle_epout_irq(uint8_t rhport) { - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; - - // DAINT for a given EP clears when DOEPINTx is cleared. - // OEPINT will be cleared when DAINT's out bits are cleared. - for (uint8_t n = 0; n < ep_count; n++) { - if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + n)) { - dwc2_epout_t* epout = &dwc2->epout[n]; - - uint32_t const doepint = epout->doepint; - - TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, ); - - // OUT XFER complete - if (epout->doepint & DOEPINT_XFRC) { - epout->doepint = DOEPINT_XFRC; - - xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - - if(dma_enabled(dwc2)) { - if (doepint & DOEPINT_STUP) { - // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; - } - } else if (doepint & DOEPINT_OTEPSPR) { - epout->doepint = DOEPINT_OTEPSPR; - } else { - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; - } else { - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); - } else { - // Fix packet length - uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; - xfer->total_len -= remain; - // this is ZLP, so prepare EP0 for next setup - if(n == 0 && xfer->total_len == 0) { - dma_setup_prepare(rhport); - } - - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); - } - } - } - } else { - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_STPKTRX; - } else { - if ((doepint & DOEPINT_OTEPSPR) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_OTEPSPR; - } - - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); - } else { - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); - } - } - } - } +static void handle_epout_slave(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepint_bm) { + if (doepint_bm.setup_phase_done) { + dcd_event_setup_received(rhport, _dcd_usbbuf.setup_packet, true); + return; + } - // SETUP packet Setup Phase done. - if (doepint & DOEPINT_STUP) { - epout->doepint = DOEPINT_STUP; - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; - } - if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - dma_setup_prepare(rhport); - } + // Normal OUT transfer complete + if (doepint_bm.xfer_complete) { + // only handle data skip if it is setup or status related + // Note: even though (xfer_complete + status_phase_rx) is for buffered DMA only, for STM32L47x (dwc2 v3.00a) they + // can is set when GRXSTS_PKTSTS_SETUP_RX is popped therefore they can bet set before/together with setup_phase_done + if (!doepint_bm.status_phase_rx && !doepint_bm.setup_packet_rx) { + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); + if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_OUT]) { + // EP0 can only handle one packet, Schedule another packet to be received. + edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT); + } else { + dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); } } } } -static void handle_epin_irq(uint8_t rhport) { +static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diepint_bm) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; - dwc2_epin_t* epin = dwc2->epin; + dwc2_dep_t* epin = &dwc2->epin[epnum]; + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); - // DAINT for a given EP clears when DIEPINTx is cleared. - // IEPINT will be cleared when DAINT's out bits are cleared. - for (uint8_t n = 0; n < ep_count; n++) { - if (dwc2->daint & TU_BIT(DAINT_IEPINT_Pos + n)) { - // IN XFER complete (entire xfer). - xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_IN); + if (diepint_bm.xfer_complete) { + if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_IN]) { + // EP0 can only handle one packet. Schedule another packet to be transmitted. + edpt_schedule_packets(rhport, epnum, TUSB_DIR_IN); + } else { + dcd_event_xfer_complete(rhport, epnum | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } - if (epin[n].diepint & DIEPINT_XFRC) { - epin[n].diepint = DIEPINT_XFRC; + // TX FIFO empty bit is read-only. It will only be cleared by hardware when written bytes is more than + // - 64 bytes or + // - Half/Empty of TX FIFO size (configured by GAHBCFG.TXFELVL) + if (diepint_bm.txfifo_empty && (dwc2->diepempmsk & (1 << epnum))) { + const uint16_t remain_packets = epin->tsiz_bm.packet_count; - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_IN]) { - // Schedule another packet to be transmitted. - edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); - } else { - if((n == 0) && dma_enabled(dwc2)) { - dma_setup_prepare(rhport); - } - dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); - } + // Process every single packet (only whole packets can be written to fifo) + for (uint16_t i = 0; i < remain_packets; i++) { + const uint16_t remain_bytes = (uint16_t) epin->tsiz_bm.xfer_size; + const uint16_t xact_bytes = tu_min16(remain_bytes, xfer->max_size); + + // Check if dtxfsts has enough space available + if (xact_bytes > ((epin->dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2)) { + break; } - // XFER FIFO empty - if ((epin[n].diepint & DIEPINT_TXFE) && (dwc2->diepempmsk & (1 << n))) { - // diepint's TXFE bit is read-only, software cannot clear it. - // It will only be cleared by hardware when written bytes is more than - // - 64 bytes or - // - Half of TX FIFO size (configured by DIEPTXF) + // Push packet to Tx-FIFO + if (xfer->ff) { + volatile uint32_t* tx_fifo = dwc2->fifo[epnum]; + tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*)(uintptr_t)tx_fifo, xact_bytes); + } else { + dfifo_write_packet(dwc2, epnum, xfer->buffer, xact_bytes); + xfer->buffer += xact_bytes; + } + } - uint16_t remaining_packets = (epin[n].dieptsiz & DIEPTSIZ_PKTCNT_Msk) >> DIEPTSIZ_PKTCNT_Pos; + // Turn off TXFE if all bytes are written. + if (epin->tsiz_bm.xfer_size == 0) { + dwc2->diepempmsk &= ~(1 << epnum); + } + } +} +#endif - // Process every single packet (only whole packets can be written to fifo) - for (uint16_t i = 0; i < remaining_packets; i++) { - uint16_t const remaining_bytes = (epin[n].dieptsiz & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos; +#if CFG_TUD_DWC2_DMA_ENABLE +static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepint_bm) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); - // Packet can not be larger than ep max size - uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size); + if (doepint_bm.setup_phase_done) { + dma_setup_prepare(rhport); + dcd_dcache_invalidate(_dcd_usbbuf.setup_packet, 8); + dcd_event_setup_received(rhport, _dcd_usbbuf.setup_packet, true); + return; + } - // It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current - // EP has to be checked if the buffer can take another WHOLE packet - if (packet_size > ((epin[n].dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2)) break; + // OUT XFER complete + if (doepint_bm.xfer_complete) { + // only handle data skip if it is setup or status related + // Normal OUT transfer complete + if (!doepint_bm.status_phase_rx && !doepint_bm.setup_packet_rx) { + if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_OUT]) { + // EP0 can only handle one packet Schedule another packet to be received. + edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT); + } else { + dwc2_dep_t* epout = &dwc2->epout[epnum]; + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - // Push packet to Tx-FIFO - if (xfer->ff) { - volatile uint32_t* tx_fifo = dwc2->fifo[n]; - tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*) (uintptr_t) tx_fifo, packet_size); - } else { - dfifo_write_packet(rhport, n, xfer->buffer, packet_size); + // determine actual received bytes + const uint16_t remain = epout->tsiz_bm.xfer_size; + xfer->total_len -= remain; - // Increment pointer to xfer data - xfer->buffer += packet_size; - } + // this is ZLP, so prepare EP0 for next setup + // TODO use status phase rx + if(epnum == 0 && xfer->total_len == 0) { + dma_setup_prepare(rhport); } - // Turn off TXFE if all bytes are written. - if (((epin[n].dieptsiz & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos) == 0) { - dwc2->diepempmsk &= ~(1 << n); + dcd_dcache_invalidate(xfer->buffer, xfer->total_len); + dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + } +} + +static void handle_epin_dma(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diepint_bm) { + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); + + if (diepint_bm.xfer_complete) { + if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_IN]) { + // EP0 can only handle one packet. Schedule another packet to be transmitted. + edpt_schedule_packets(rhport, epnum, TUSB_DIR_IN); + } else { + if(epnum == 0) { + dma_setup_prepare(rhport); + } + dcd_event_xfer_complete(rhport, epnum | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } +} +#endif + +static void handle_ep_irq(uint8_t rhport, uint8_t dir) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + const bool is_dma = dma_device_enabled(dwc2); + const uint8_t ep_count = DWC2_EP_COUNT(dwc2); + const uint8_t daint_offset = (dir == TUSB_DIR_IN) ? DAINT_IEPINT_Pos : DAINT_OEPINT_Pos; + dwc2_dep_t* ep_base = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][0]; + + // DAINT for a given EP clears when DEPINTx is cleared. + // EPINT will be cleared when DAINT bits are cleared. + for (uint8_t epnum = 0; epnum < ep_count; epnum++) { + if (dwc2->daint & TU_BIT(daint_offset + epnum)) { + dwc2_dep_t* epout = &ep_base[epnum]; + union { + uint32_t value; + dwc2_diepint_t diepint_bm; + dwc2_doepint_t doepint_bm; + } intr; + intr.value = epout->intr; + + epout->intr = intr.value; // Clear interrupt + + if (is_dma) { + #if CFG_TUD_DWC2_DMA_ENABLE + if (dir == TUSB_DIR_IN) { + handle_epin_dma(rhport, epnum, intr.diepint_bm); + } else { + handle_epout_dma(rhport, epnum, intr.doepint_bm); + } + #endif + } else { + #if CFG_TUD_DWC2_SLAVE_ENABLE + if (dir == TUSB_DIR_IN) { + handle_epin_slave(rhport, epnum, intr.diepint_bm); + } else { + handle_epout_slave(rhport, epnum, intr.doepint_bm); } + #endif } } } } +/* Interrupt Hierarchy + DIEPINT DIEPINT + \ / + \ / + DAINT + / \ + / \ + GINTSTS: OEPInt IEPInt | USBReset | EnumDone | USBSusp | WkUpInt | OTGInt | SOF | RXFLVL + + Note: when OTG_MULTI_PROC_INTRPT = 1, Device Each endpoint interrupt deachint/deachmsk/diepeachmsk/doepeachmsk + are combined to generate dedicated interrupt line for each endpoint. + */ void dcd_int_handler(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint32_t const int_mask = dwc2->gintmsk; - uint32_t const int_status = dwc2->gintsts & int_mask; + const uint32_t gintmask = dwc2->gintmsk; + const uint32_t gintsts = dwc2->gintsts & gintmask; - if (int_status & GINTSTS_USBRST) { + if (gintsts & GINTSTS_USBRST) { // USBRST is start of reset. dwc2->gintsts = GINTSTS_USBRST; -#if defined(TUP_USBIP_DWC2_ESP32) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) _allocated_fifos = 1; #endif - bus_reset(rhport); + handle_bus_reset(rhport); } - if (int_status & GINTSTS_ENUMDNE) { + if (gintsts & GINTSTS_ENUMDNE) { // ENUMDNE is the end of reset where speed of the link is detected dwc2->gintsts = GINTSTS_ENUMDNE; - - tusb_speed_t speed; - switch ((dwc2->dsts & DSTS_ENUMSPD_Msk) >> DSTS_ENUMSPD_Pos) { - case DSTS_ENUMSPD_HS: - speed = TUSB_SPEED_HIGH; - break; - - case DSTS_ENUMSPD_LS: - speed = TUSB_SPEED_LOW; - break; - - case DSTS_ENUMSPD_FS_HSPHY: - case DSTS_ENUMSPD_FS: - default: - speed = TUSB_SPEED_FULL; - break; - } - - // TODO must update GUSBCFG_TRDT according to link speed - - dcd_event_bus_reset(rhport, speed, true); + handle_enum_done(rhport); } - if (int_status & GINTSTS_USBSUSP) { + if (gintsts & GINTSTS_USBSUSP) { dwc2->gintsts = GINTSTS_USBSUSP; //dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -#if defined(TUP_USBIP_DWC2_ESP32) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) _allocated_fifos = 1; #endif } - if (int_status & GINTSTS_WKUINT) { + if (gintsts & GINTSTS_WKUINT) { dwc2->gintsts = GINTSTS_WKUINT; dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } @@ -1278,13 +1045,13 @@ void dcd_int_handler(uint8_t rhport) { // TODO check GINTSTS_DISCINT for disconnect detection // if(int_status & GINTSTS_DISCINT) - if (int_status & GINTSTS_OTGINT) { + if (gintsts & GINTSTS_OTGINT) { // OTG INT bit is read-only - uint32_t const otg_int = dwc2->gotgint; + const uint32_t otg_int = dwc2->gotgint; if (otg_int & GOTGINT_SEDET) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); -#if defined(TUP_USBIP_DWC2_ESP32) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) _allocated_fifos = 1; #endif } @@ -1292,50 +1059,43 @@ void dcd_int_handler(uint8_t rhport) { dwc2->gotgint = otg_int; } - if(int_status & GINTSTS_SOF) { + if(gintsts & GINTSTS_SOF) { dwc2->gintsts = GINTSTS_SOF; const uint32_t frame = (dwc2->dsts & DSTS_FNSOF) >> DSTS_FNSOF_Pos; // Disable SOF interrupt if SOF was not explicitly enabled since SOF was used for remote wakeup detection - if (!_sof_en) { + if (!_dcd_data.sof_en) { dwc2->gintmsk &= ~GINTMSK_SOFM; } dcd_event_sof(rhport, frame, true); } +#if CFG_TUD_DWC2_SLAVE_ENABLE // RxFIFO non-empty interrupt handling. - if (int_status & GINTSTS_RXFLVL) { + if (gintsts & GINTSTS_RXFLVL) { // RXFLVL bit is read-only + dwc2->gintmsk &= ~GINTMSK_RXFLVLM; // disable RXFLVL interrupt while reading - // Mask out RXFLVL while reading data from FIFO - dwc2->gintmsk &= ~GINTMSK_RXFLVLM; - - // Loop until all available packets were handled do { - handle_rxflvl_irq(rhport); + handle_rxflvl_irq(rhport); // read all packets } while(dwc2->gintsts & GINTSTS_RXFLVL); dwc2->gintmsk |= GINTMSK_RXFLVLM; } +#endif // OUT endpoint interrupt handling. - if (int_status & GINTSTS_OEPINT) { + if (gintsts & GINTSTS_OEPINT) { // OEPINT is read-only, clear using DOEPINTn - handle_epout_irq(rhport); + handle_ep_irq(rhport, TUSB_DIR_OUT); } // IN endpoint interrupt handling. - if (int_status & GINTSTS_IEPINT) { + if (gintsts & GINTSTS_IEPINT) { // IEPINT bit read-only, clear using DIEPINTn - handle_epin_irq(rhport); + handle_ep_irq(rhport, TUSB_DIR_IN); } - - // // Check for Incomplete isochronous IN transfer - // if(int_status & GINTSTS_IISOIXFR) { - // printf(" IISOIXFR!\r\n"); - //// TU_LOG(DWC2_DEBUG, " IISOIXFR!\r\n"); - // } } #if CFG_TUD_TEST_MODE diff --git a/configs/builds.json b/configs/builds.json index e34813cfa..ddfb8e4f8 100644 --- a/configs/builds.json +++ b/configs/builds.json @@ -4,7 +4,7 @@ "file":"libspi_flash.a", "src":"build/esp-idf/spi_flash/libspi_flash.a", "out":"lib/libspi_flash.a", - "targets":["esp32","esp32c2","esp32c3","esp32s2","esp32s3","esp32c6","esp32h2"] + "targets":["esp32","esp32c2","esp32c3","esp32s2","esp32s3","esp32c6","esp32h2","esp32p4"] }, { "file":"libesp_psram.a", @@ -44,6 +44,20 @@ } ], "targets":[ + { + "target": "esp32p4", + "features":["qio_ram"], + "idf_libs":["qio","80m"], + "bootloaders":[ + ["qio","80m"], + ["dio","80m"], + ["qio","40m"], + ["dio","40m"] + ], + "mem_variants":[ + ["dio","80m"] + ] + }, { "target": "esp32c2", "skip": 1, @@ -143,8 +157,7 @@ ["qio","80m","opi_ram"], ["dio","80m","qio_ram"], ["dio","80m","opi_ram"], - ["opi","80m","opi_ram"], - ["opi","80m","qio_ram"] + ["opi","80m","opi_ram"] ] } ] diff --git a/configs/defconfig.common b/configs/defconfig.common index 5bb28cad5..ef4620bf6 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -19,7 +19,7 @@ CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2048 CONFIG_ESP_TASK_WDT_PANIC=y -CONFIG_ESP_TIMER_TASK_STACK_SIZE=4096 +CONFIG_ESP_TIMER_TASK_STACK_SIZE=8192 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_ESP_WIFI_FTM_ENABLE=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=8 @@ -44,6 +44,10 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y # CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION is not set CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y CONFIG_HEAP_POISONING_LIGHT=y CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 CONFIG_HTTPD_WS_SUPPORT=y diff --git a/configs/defconfig.esp32 b/configs/defconfig.esp32 index 2e88a27ed..db01aeab3 100644 --- a/configs/defconfig.esp32 +++ b/configs/defconfig.esp32 @@ -19,3 +19,4 @@ CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096 diff --git a/configs/defconfig.esp32c3 b/configs/defconfig.esp32c3 index c497b562d..1baf62540 100644 --- a/configs/defconfig.esp32c3 +++ b/configs/defconfig.esp32c3 @@ -6,3 +6,4 @@ CONFIG_ESP_WIFI_11KV_SUPPORT=y CONFIG_ESP_WIFI_SCAN_CACHE=y CONFIG_ESP_WIFI_MBO_SUPPORT=y CONFIG_ESP_WIFI_11R_SUPPORT=y +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096 diff --git a/configs/defconfig.esp32c6 b/configs/defconfig.esp32c6 index c39022997..07621cf07 100644 --- a/configs/defconfig.esp32c6 +++ b/configs/defconfig.esp32c6 @@ -35,6 +35,9 @@ CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" # end of OpenThread +# Matter shall use only WiFi +CONFIG_ENABLE_MATTER_OVER_THREAD=n + # # Zigbee # diff --git a/configs/defconfig.esp32p4 b/configs/defconfig.esp32p4 new file mode 100644 index 000000000..8b04e8469 --- /dev/null +++ b/configs/defconfig.esp32p4 @@ -0,0 +1,26 @@ +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_SPEED_200M=y +# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set +CONFIG_LWIP_TCP_SACK_OUT=y + +CONFIG_SLAVE_IDF_TARGET_ESP32C6=y +CONFIG_ESP_SDIO_BUS_WIDTH=4 +CONFIG_ESP_SDIO_CLOCK_FREQ_KHZ=40000 +CONFIG_ESP_SDIO_PIN_CMD=19 +CONFIG_ESP_SDIO_PIN_CLK=18 +CONFIG_ESP_SDIO_PIN_D0=14 +CONFIG_ESP_SDIO_PIN_D1=15 +CONFIG_ESP_SDIO_PIN_D2=16 +CONFIG_ESP_SDIO_PIN_D3=17 + +# +# Chip revision +# +CONFIG_ESP32P4_REV_MIN_0=y +# CONFIG_ESP32P4_REV_MIN_1 is not set +CONFIG_ESP32P4_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 +CONFIG_ESP32P4_REV_MAX_FULL=99 +CONFIG_ESP_REV_MAX_FULL=99 +# end of Chip revision diff --git a/configs/pio_end.txt b/configs/pioarduino_end.txt similarity index 100% rename from configs/pio_end.txt rename to configs/pioarduino_end.txt diff --git a/configs/pio_start.txt b/configs/pioarduino_start.txt similarity index 96% rename from configs/pio_start.txt rename to configs/pioarduino_start.txt index a0b780dc9..c5174173d 100644 --- a/configs/pio_start.txt +++ b/configs/pioarduino_start.txt @@ -22,7 +22,7 @@ kinds of creative coding, interactive objects, spaces or physical experiences. http://arduino.cc/en/Reference/HomePage """ -# Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py +# Extends: https://github.com/pioarduino/platform-espressif32/blob/develop/builder/main.py from os.path import basename, join diff --git a/main/idf_component.yml b/main/idf_component.yml index 714b3f0d6..c6bb97f46 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -1,6 +1,6 @@ dependencies: # Required IDF version - idf: ">=5.1" + idf: ">=5.3" espressif/esp32-camera: version: "master" git: https://github.com/espressif/esp32-camera.git @@ -12,12 +12,6 @@ dependencies: require: public rules: - if: "target not in [esp32c2]" - # espressif/esp-dl: - # version: "af7808ba09448ce82c704455975d4cf1e4305fd7" - # git: https://github.com/espressif/esp-dl.git - # require: public - # rules: - # - if: "target in [esp32s3, esp32s2, esp32]" espressif/esp-sr: version: ">=1.4.2" rules: @@ -26,45 +20,4 @@ dependencies: version: "^1.3.0" require: public rules: - - if: "target not in [esp32c2, esp32h2]" - - # esp-sr: "^1.3.1" - # esp32-camera: "^2.0.4" - # esp-dl: - # git: https://github.com/espressif/esp-dl.git - # espressif/esp_rainmaker: - # path: components/esp_rainmaker - # git: https://github.com/espressif/esp-rainmaker.git - - # # Defining a dependency from the registry: - # # https://components.espressif.com/component/example/cmp - # example/cmp: "^3.3.3" # Automatically update minor releases - # - # # Other ways to define dependencies - # - # # For components maintained by Espressif only name can be used. - # # Same as `espressif/cmp` - # component: "~1.0.0" # Automatically update bugfix releases - # - # # Or in a longer form with extra parameters - # component2: - # version: ">=2.0.0" - # - # # For transient dependencies `public` flag can be set. - # # `public` flag doesn't have an effect for the `main` component. - # # All dependencies of `main` are public by default. - # public: true - # - # # For components hosted on non-default registry: - # service_url: "https://componentregistry.company.com" - # - # # For components in git repository: - # test_component: - # path: test_component - # git: ssh://git@gitlab.com/user/components.git - # - # # For test projects during component development - # # components can be used from a local directory - # # with relative or absolute path - # some_local_component: - # path: ../../projects/component + - if: "target not in [esp32c2, esp32h2, esp32p4]" diff --git a/patches/esp32c6_provisioning_bluedroid.diff b/patches/esp32c6_provisioning_bluedroid.diff deleted file mode 100644 index 98371b8aa..000000000 --- a/patches/esp32c6_provisioning_bluedroid.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/components/protocomm/src/simple_ble/simple_ble.c b/components/protocomm/src/simple_ble/simple_ble.c -index 8a4ae0f3d9..cd6421c6e5 100644 ---- a/components/protocomm/src/simple_ble/simple_ble.c -+++ b/components/protocomm/src/simple_ble/simple_ble.c -@@ -225,7 +225,7 @@ esp_err_t simple_ble_start(simple_ble_cfg_t *cfg) - #ifdef CONFIG_BTDM_CTRL_MODE_BTDM - ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); --#elif defined CONFIG_BTDM_CTRL_MODE_BLE_ONLY || CONFIG_BT_CTRL_MODE_EFF -+#elif defined CONFIG_BTDM_CTRL_MODE_BLE_ONLY || CONFIG_BT_CTRL_MODE_EFF || CONFIG_IDF_TARGET_ESP32C6 - ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); - #else - ESP_LOGE(TAG, "Configuration mismatch. Select BLE Only or BTDM mode from menuconfig"); diff --git a/patches/mmu_map.diff b/patches/mmu_map.diff deleted file mode 100644 index 3bf56005a..000000000 --- a/patches/mmu_map.diff +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/components/esp_mm/esp_mmu_map.c b/components/esp_mm/esp_mmu_map.c -index b7d927f8fe..6a8c4635f0 100644 ---- a/components/esp_mm/esp_mmu_map.c -+++ b/components/esp_mm/esp_mmu_map.c -@@ -315,6 +315,19 @@ esp_err_t esp_mmu_map_reserve_block_with_caps(size_t size, mmu_mem_caps_t caps, - s_mmu_ctx.mem_regions[found_region_id].max_slot_size -= aligned_size; - ESP_EARLY_LOGV(TAG, "found laddr is 0x%x", laddr); - -+ mem_block_t *mem_block = NULL; -+ mem_region_t *region = &s_mmu_ctx.mem_regions[found_region_id]; -+ TAILQ_FOREACH(mem_block, ®ion->mem_block_head, entries) { -+ if (mem_block == TAILQ_FIRST(®ion->mem_block_head) || mem_block == TAILQ_LAST(®ion->mem_block_head, mem_block_head_)) { -+ TAILQ_REMOVE(®ion->mem_block_head, mem_block, entries); -+ } else { -+ // probably the reservation of MMU region should be disallowed for this case - already some MMU mappings exist? -+ // assert/abort -+ ESP_EARLY_LOGE(TAG, "already some MMU mappings exist?"); -+ abort(); -+ } -+ } -+ - uint32_t vaddr = 0; - if (caps & MMU_MEM_CAP_EXEC) { - vaddr = mmu_ll_laddr_to_vaddr(laddr, MMU_VADDR_INSTRUCTION); diff --git a/tools/add_sdk_json.py b/tools/add_sdk_json.py index d2deb4a87..7b12289bb 100644 --- a/tools/add_sdk_json.py +++ b/tools/add_sdk_json.py @@ -66,7 +66,7 @@ def add_system(systems, host, url, filename, sha, size): dep_skip = False for dep in farray['packages'][0]['platforms'][0]['toolsDependencies']: if dep['name'] == tool_name: - if dep['version'] == tool_version: + if dep['version'] == tool_version and not tool_name.startswith('esp32-arduino-libs'): print('Skipping {0}. Same version {1}'.format(tool_name, tool_version)) dep_skip = True break diff --git a/tools/config.sh b/tools/config.sh index 37805cb48..89cd9856a 100755 --- a/tools/config.sh +++ b/tools/config.sh @@ -6,7 +6,7 @@ if [ -z $IDF_PATH ]; then fi if [ -z $IDF_BRANCH ]; then - IDF_BRANCH="release/v5.1" + IDF_BRANCH="release/v5.3" fi if [ -z $AR_PR_TARGET_BRANCH ]; then @@ -49,7 +49,7 @@ AR_PATCHES="$AR_ROOT/patches" AR_PLATFORM_TXT="$AR_OUT/platform.txt" AR_GEN_PART_PY="$AR_TOOLS/gen_esp32part.py" AR_SDK="$AR_TOOLS/esp32-arduino-libs/$IDF_TARGET" -PIO_SDK="FRAMEWORK_SDK_DIR, \"$IDF_TARGET\"" +PIOARDUINO_SDK="FRAMEWORK_SDK_DIR, \"$IDF_TARGET\"" TOOLS_JSON_OUT="$AR_TOOLS/esp32-arduino-libs" if [ -d "$IDF_PATH" ]; then diff --git a/tools/copy-libs.sh b/tools/copy-libs.sh index bbc89e089..21efe1a78 100755 --- a/tools/copy-libs.sh +++ b/tools/copy-libs.sh @@ -36,13 +36,20 @@ fi if [ -e "$AR_SDK/$MEMCONF" ]; then rm -rf "$AR_SDK/$MEMCONF" fi -if [ -e "$AR_SDK/platformio-build.py" ]; then - rm -rf "$AR_SDK/platformio-build.py" +if [ -e "$AR_SDK/pioarduino-build.py" ]; then + rm -rf "$AR_SDK/pioarduino-build.py" fi + mkdir -p "$AR_SDK" +mkdir -p "$AR_SDK/lib" function get_actual_path(){ - p="$PWD"; cd "$1"; r="$PWD"; cd "$p"; echo "$r"; + d="$1"; + if [ -d "$d" ]; then + p="$PWD"; cd "$d"; r="$PWD"; cd "$p"; echo "$r"; + else + echo ""; + fi } # @@ -56,6 +63,8 @@ AS_FLAGS="" INCLUDES="" DEFINES="" +EXCLUDE_LIBS=";" + LD_FLAGS="" LD_LIBS="" LD_LIB_FILES="" @@ -63,13 +72,13 @@ LD_LIBS_SEARCH="" LD_SCRIPTS="" LD_SCRIPT_DIRS="" -PIO_CC_FLAGS="" -PIO_C_FLAGS="" -PIO_CXX_FLAGS="" -PIO_AS_FLAGS="" -PIO_LD_FLAGS="" -PIO_LD_FUNCS="" -PIO_LD_SCRIPTS="" +PIOARDUINO_CC_FLAGS="" +PIOARDUINO_C_FLAGS="" +PIOARDUINO_CXX_FLAGS="" +PIOARDUINO_AS_FLAGS="" +PIOARDUINO_LD_FLAGS="" +PIOARDUINO_LD_FUNCS="" +PIOARDUINO_LD_SCRIPTS="" TOOLCHAIN_PREFIX="" if [ "$IS_XTENSA" = "y" ]; then @@ -78,6 +87,17 @@ else TOOLCHAIN="riscv32-esp-elf" fi +# copy zigbee + zboss lib +if [ -d "managed_components/espressif__esp-zigbee-lib/lib/$IDF_TARGET/" ]; then + cp -r "managed_components/espressif__esp-zigbee-lib/lib/$IDF_TARGET"/* "$AR_SDK/lib/" + EXCLUDE_LIBS+="esp_zb_api_ed;" +fi + +if [ -d "managed_components/espressif__esp-zboss-lib/lib/$IDF_TARGET/" ]; then + cp -r "managed_components/espressif__esp-zboss-lib/lib/$IDF_TARGET"/* "$AR_SDK/lib/" + EXCLUDE_LIBS+="zboss_stack.ed;zboss_port.debug;" +fi + #collect includes, defines and c-flags str=`cat build/compile_commands.json | grep arduino-lib-builder-gcc.c | grep command | cut -d':' -f2 | cut -d',' -f1` str="${str:2:${#str}-1}" #remove leading space and quotes @@ -106,7 +126,7 @@ for item in "${@:2:${#@}-5}"; do DEFINES+="$item " fi elif [ "$prefix" = "-O" ]; then - PIO_CC_FLAGS+="$item " + PIOARDUINO_CC_FLAGS+="$item " elif [[ "$item" != "-Wall" && "$item" != "-Werror=all" && "$item" != "-Wextra" ]]; then if [[ "${item:0:23}" != "-mfix-esp32-psram-cache" && "${item:0:18}" != "-fmacro-prefix-map" && "${item:0:20}" != "-fdiagnostics-color=" && "${item:0:19}" != "-fdebug-prefix-map=" ]]; then C_FLAGS+="$item " @@ -125,9 +145,9 @@ for item in "${@:2:${#@}-5}"; do if [[ "${item:0:23}" != "-mfix-esp32-psram-cache" && "${item:0:18}" != "-fmacro-prefix-map" && "${item:0:20}" != "-fdiagnostics-color=" && "${item:0:19}" != "-fdebug-prefix-map=" ]]; then AS_FLAGS+="$item " if [[ $C_FLAGS == *"$item"* ]]; then - PIO_CC_FLAGS+="$item " + PIOARDUINO_CC_FLAGS+="$item " else - PIO_AS_FLAGS+="$item " + PIOARDUINO_AS_FLAGS+="$item " fi fi fi @@ -143,8 +163,8 @@ for item in "${@:2:${#@}-5}"; do if [[ "$prefix" != "-I" && "$prefix" != "-D" && "$item" != "-Wall" && "$item" != "-Werror=all" && "$item" != "-Wextra" && "$prefix" != "-O" ]]; then if [[ "${item:0:23}" != "-mfix-esp32-psram-cache" && "${item:0:18}" != "-fmacro-prefix-map" && "${item:0:20}" != "-fdiagnostics-color=" && "${item:0:19}" != "-fdebug-prefix-map=" ]]; then CPP_FLAGS+="$item " - if [[ $PIO_CC_FLAGS != *"$item"* ]]; then - PIO_CXX_FLAGS+="$item " + if [[ $PIOARDUINO_CC_FLAGS != *"$item"* ]]; then + PIOARDUINO_CXX_FLAGS+="$item " fi fi fi @@ -152,8 +172,8 @@ done set -- $C_FLAGS for item; do - if [[ $PIO_CC_FLAGS != *"$item"* ]]; then - PIO_C_FLAGS+="$item " + if [[ $PIOARDUINO_CC_FLAGS != *"$item"* ]]; then + PIOARDUINO_C_FLAGS+="$item " fi done @@ -180,7 +200,7 @@ else fi if [ "$IDF_TARGET" = "esp32" ]; then LD_SCRIPTS+="-T esp32.rom.redefined.ld " - PIO_LD_SCRIPTS+="esp32.rom.redefined.ld " + PIOARDUINO_LD_SCRIPTS+="esp32.rom.redefined.ld " fi set -- $str for item; do @@ -200,12 +220,14 @@ for item; do add_next=1 LD_FLAGS+="$item " elif [ "${item:0:2}" = "-l" ]; then # -l[lib_name] - LD_LIBS+="$item " - exclude_libs=";m;c;gcc;stdc++;" short_name="${item:2}" - if [[ $exclude_libs != *";$short_name;"* && $LD_LIBS_SEARCH != *"lib$short_name.a"* ]]; then - LD_LIBS_SEARCH+="lib$short_name.a " - #echo "lib add: $item" + if [[ $EXCLUDE_LIBS != *";$short_name;"* ]]; then + LD_LIBS+="$item " + exclude_libs=";m;c;gcc;stdc++;" + if [[ $exclude_libs != *";$short_name;"* && $LD_LIBS_SEARCH != *"lib$short_name.a"* ]]; then + LD_LIBS_SEARCH+="lib$short_name.a " + #echo "1. lib add: $item" + fi fi elif [ "$item" = "-o" ]; then add_next=0 @@ -213,7 +235,7 @@ for item; do is_dir=0 elif [[ "${item:0:23}" != "-mfix-esp32-psram-cache" && "${item:0:18}" != "-fmacro-prefix-map" && "${item:0:19}" != "-fdebug-prefix-map=" && "${item:0:17}" != "-Wl,--start-group" && "${item:0:15}" != "-Wl,--end-group" ]]; then LD_FLAGS+="$item " - PIO_LD_FLAGS+="$item " + PIOARDUINO_LD_FLAGS+="$item " fi fi else @@ -225,10 +247,10 @@ for item; do elif [ "$is_script" = "1" ]; then is_script=0 LD_SCRIPTS+="$item " - PIO_LD_SCRIPTS+="$item " + PIOARDUINO_LD_SCRIPTS+="$item " else LD_FLAGS+="$item " - PIO_LD_FUNCS+="$item " + PIOARDUINO_LD_FUNCS+="$item " fi else if [ "${item:${#item}-2:2}" = ".a" ]; then @@ -244,30 +266,38 @@ for item; do if [[ $LD_LIB_FILES != *"$item"* ]]; then # do we already have lib with the same name? if [[ $LD_LIBS != *"-l$lname"* ]]; then - # echo "collecting lib '$lname' and file: $item" - LD_LIB_FILES+="$item " - LD_LIBS+="-l$lname " + if [[ $EXCLUDE_LIBS != *";$lname;"* ]]; then + #echo "2. collecting lib '$lname' and file: $item" + LD_LIB_FILES+="$item " + LD_LIBS+="-l$lname " + fi else # echo "!!! need to rename: '$lname'" for i in {2..9}; do n_item="${item:0:${#item}-2}_$i.a" n_name=$lname"_$i" if [ -f "$n_item" ]; then - # echo "renamed add: -l$n_name" - LD_LIBS+="-l$n_name " + if [[ $EXCLUDE_LIBS != *";$lname;"* ]]; then + #echo "3. renamed add: -l$n_name" + LD_LIBS+="-l$n_name " + fi break elif [[ $LD_LIB_FILES != *"$n_item"* && $LD_LIBS != *"-l$n_name"* ]]; then - echo "Renaming '$lname' to '$n_name': $item" - cp -f "$item" "$n_item" - LD_LIB_FILES+="$n_item " - LD_LIBS+="-l$n_name " + if [[ $EXCLUDE_LIBS != *";$lname;"* ]]; then + #echo "4. Renaming '$lname' to '$n_name': $item" + cp -f "$item" "$n_item" + LD_LIB_FILES+="$n_item " + LD_LIBS+="-l$n_name " + fi break fi done fi else - # echo "just add: -l$lname" - LD_LIBS+="-l$lname " + if [[ $EXCLUDE_LIBS != *";$lname;"* ]]; then + #echo "5. just add: -l$lname" + LD_LIBS+="-l$lname " + fi fi else echo "*** Skipping $(basename $item): size too small $lsize" @@ -288,82 +318,82 @@ done mkdir -p "$AR_SDK" -# start generation of platformio-build.py -AR_PLATFORMIO_PY="$AR_SDK/platformio-build.py" -cat configs/pio_start.txt > "$AR_PLATFORMIO_PY" +# start generation of pioarduino-build.py +AR_PIOARDUINO_PY="$AR_SDK/pioarduino-build.py" +cat configs/pioarduino_start.txt > "$AR_PIOARDUINO_PY" -echo " ASFLAGS=[" >> "$AR_PLATFORMIO_PY" +echo " ASFLAGS=[" >> "$AR_PIOARDUINO_PY" if [ "$IS_XTENSA" = "y" ]; then - echo " \"-mlongcalls\"" >> "$AR_PLATFORMIO_PY" + echo " \"-mlongcalls\"" >> "$AR_PIOARDUINO_PY" else - echo " \"-march=rv32imc\"" >> "$AR_PLATFORMIO_PY" + echo " \"-march=rv32imc\"" >> "$AR_PIOARDUINO_PY" fi -echo " ]," >> "$AR_PLATFORMIO_PY" -echo "" >> "$AR_PLATFORMIO_PY" +echo " ]," >> "$AR_PIOARDUINO_PY" +echo "" >> "$AR_PIOARDUINO_PY" -echo " ASPPFLAGS=[" >> "$AR_PLATFORMIO_PY" -set -- $PIO_AS_FLAGS +echo " ASPPFLAGS=[" >> "$AR_PIOARDUINO_PY" +set -- $PIOARDUINO_AS_FLAGS for item; do - echo " \"$item\"," >> "$AR_PLATFORMIO_PY" + echo " \"$item\"," >> "$AR_PIOARDUINO_PY" done -echo " \"-x\", \"assembler-with-cpp\"" >> "$AR_PLATFORMIO_PY" -echo " ]," >> "$AR_PLATFORMIO_PY" -echo "" >> "$AR_PLATFORMIO_PY" +echo " \"-x\", \"assembler-with-cpp\"" >> "$AR_PIOARDUINO_PY" +echo " ]," >> "$AR_PIOARDUINO_PY" +echo "" >> "$AR_PIOARDUINO_PY" -echo " CFLAGS=[" >> "$AR_PLATFORMIO_PY" -set -- $PIO_C_FLAGS +echo " CFLAGS=[" >> "$AR_PIOARDUINO_PY" +set -- $PIOARDUINO_C_FLAGS last_item="${@: -1}" for item in "${@:0:${#@}}"; do if [ "${item:0:1}" != "/" ]; then - echo " \"$item\"," >> "$AR_PLATFORMIO_PY" + echo " \"$item\"," >> "$AR_PIOARDUINO_PY" fi done -echo " \"$last_item\"" >> "$AR_PLATFORMIO_PY" -echo " ]," >> "$AR_PLATFORMIO_PY" -echo "" >> "$AR_PLATFORMIO_PY" +echo " \"$last_item\"" >> "$AR_PIOARDUINO_PY" +echo " ]," >> "$AR_PIOARDUINO_PY" +echo "" >> "$AR_PIOARDUINO_PY" -echo " CXXFLAGS=[" >> "$AR_PLATFORMIO_PY" -set -- $PIO_CXX_FLAGS +echo " CXXFLAGS=[" >> "$AR_PIOARDUINO_PY" +set -- $PIOARDUINO_CXX_FLAGS last_item="${@: -1}" for item in "${@:0:${#@}}"; do if [ "${item:0:1}" != "/" ]; then - echo " \"$item\"," >> "$AR_PLATFORMIO_PY" + echo " \"$item\"," >> "$AR_PIOARDUINO_PY" fi done -echo " \"$last_item\"" >> "$AR_PLATFORMIO_PY" -echo " ]," >> "$AR_PLATFORMIO_PY" -echo "" >> "$AR_PLATFORMIO_PY" +echo " \"$last_item\"" >> "$AR_PIOARDUINO_PY" +echo " ]," >> "$AR_PIOARDUINO_PY" +echo "" >> "$AR_PIOARDUINO_PY" -echo " CCFLAGS=[" >> "$AR_PLATFORMIO_PY" -set -- $PIO_CC_FLAGS +echo " CCFLAGS=[" >> "$AR_PIOARDUINO_PY" +set -- $PIOARDUINO_CC_FLAGS for item; do - echo " \"$item\"," >> "$AR_PLATFORMIO_PY" + echo " \"$item\"," >> "$AR_PIOARDUINO_PY" done -echo " \"-MMD\"" >> "$AR_PLATFORMIO_PY" -echo " ]," >> "$AR_PLATFORMIO_PY" -echo "" >> "$AR_PLATFORMIO_PY" +echo " \"-MMD\"" >> "$AR_PIOARDUINO_PY" +echo " ]," >> "$AR_PIOARDUINO_PY" +echo "" >> "$AR_PIOARDUINO_PY" -echo " LINKFLAGS=[" >> "$AR_PLATFORMIO_PY" -set -- $PIO_LD_FLAGS +echo " LINKFLAGS=[" >> "$AR_PIOARDUINO_PY" +set -- $PIOARDUINO_LD_FLAGS for item; do - echo " \"$item\"," >> "$AR_PLATFORMIO_PY" + echo " \"$item\"," >> "$AR_PIOARDUINO_PY" done -set -- $PIO_LD_SCRIPTS +set -- $PIOARDUINO_LD_SCRIPTS for item; do - echo " \"-T\", \"$item\"," >> "$AR_PLATFORMIO_PY" + echo " \"-T\", \"$item\"," >> "$AR_PIOARDUINO_PY" done -set -- $PIO_LD_FUNCS +set -- $PIOARDUINO_LD_FUNCS for item; do - echo " \"-u\", \"$item\"," >> "$AR_PLATFORMIO_PY" + echo " \"-u\", \"$item\"," >> "$AR_PIOARDUINO_PY" done -echo " '-Wl,-Map=\"%s\"' % join(\"\${BUILD_DIR}\", \"\${PROGNAME}.map\")" >> "$AR_PLATFORMIO_PY" +echo " '-Wl,-Map=\"%s\"' % join(\"\${BUILD_DIR}\", \"\${PROGNAME}.map\")" >> "$AR_PIOARDUINO_PY" -echo " ]," >> "$AR_PLATFORMIO_PY" -echo "" >> "$AR_PLATFORMIO_PY" +echo " ]," >> "$AR_PIOARDUINO_PY" +echo "" >> "$AR_PIOARDUINO_PY" # include dirs REL_INC="" -echo " CPPPATH=[" >> "$AR_PLATFORMIO_PY" +echo " CPPPATH=[" >> "$AR_PIOARDUINO_PY" set -- $INCLUDES @@ -391,11 +421,11 @@ for item; do out_cpath="$AR_SDK/include/$fname$out_sub" REL_INC+="-iwithprefixbefore $fname$out_sub " if [ "$out_sub" = "" ]; then - echo " join($PIO_SDK, \"include\", \"$fname\")," >> "$AR_PLATFORMIO_PY" + echo " join($PIOARDUINO_SDK, \"include\", \"$fname\")," >> "$AR_PIOARDUINO_PY" else - pio_sub="${out_sub:1}" - pio_sub=`echo $pio_sub | sed 's/\//\\", \\"/g'` - echo " join($PIO_SDK, \"include\", \"$fname\", \"$pio_sub\")," >> "$AR_PLATFORMIO_PY" + pioarduino_sub="${out_sub:1}" + pioarduino_sub=`echo $pioarduino_sub | sed 's/\//\\", \\"/g'` + echo " join($PIOARDUINO_SDK, \"include\", \"$fname\", \"$pioarduino_sub\")," >> "$AR_PIOARDUINO_PY" fi for f in `find "$item" -name '*.h'`; do rel_f=${f#*$item} @@ -422,21 +452,19 @@ for item; do fi fi done -echo " join($PIO_SDK, board_config.get(\"build.arduino.memory_type\", (board_config.get(\"build.flash_mode\", \"dio\") + \"_$OCT_PSRAM\")), \"include\")," >> "$AR_PLATFORMIO_PY" -echo " join(FRAMEWORK_DIR, \"cores\", board_config.get(\"build.core\"))" >> "$AR_PLATFORMIO_PY" -echo " ]," >> "$AR_PLATFORMIO_PY" -echo "" >> "$AR_PLATFORMIO_PY" - -mkdir -p "$AR_SDK/lib" +echo " join($PIOARDUINO_SDK, board_config.get(\"build.arduino.memory_type\", (board_config.get(\"build.flash_mode\", \"dio\") + \"_$OCT_PSRAM\")), \"include\")," >> "$AR_PIOARDUINO_PY" +echo " join(FRAMEWORK_DIR, \"cores\", board_config.get(\"build.core\"))" >> "$AR_PIOARDUINO_PY" +echo " ]," >> "$AR_PIOARDUINO_PY" +echo "" >> "$AR_PIOARDUINO_PY" AR_LIBS="$LD_LIBS" -PIO_LIBS="" +PIOARDUINO_LIBS="" set -- $LD_LIBS for item; do - if [ "$PIO_LIBS" != "" ]; then - PIO_LIBS+=", " + if [ "$PIOARDUINO_LIBS" != "" ]; then + PIOARDUINO_LIBS+=", " fi - PIO_LIBS+="\"$item\"" + PIOARDUINO_LIBS+="\"$item\"" done set -- $LD_LIB_FILES @@ -444,19 +472,19 @@ for item; do cp "$item" "$AR_SDK/lib/" done -echo " LIBPATH=[" >> "$AR_PLATFORMIO_PY" -echo " join($PIO_SDK, \"lib\")," >> "$AR_PLATFORMIO_PY" -echo " join($PIO_SDK, \"ld\")," >> "$AR_PLATFORMIO_PY" -echo " join($PIO_SDK, board_config.get(\"build.arduino.memory_type\", (board_config.get(\"build.flash_mode\", \"dio\") + \"_$OCT_PSRAM\")))" >> "$AR_PLATFORMIO_PY" -echo " ]," >> "$AR_PLATFORMIO_PY" -echo "" >> "$AR_PLATFORMIO_PY" +echo " LIBPATH=[" >> "$AR_PIOARDUINO_PY" +echo " join($PIOARDUINO_SDK, \"lib\")," >> "$AR_PIOARDUINO_PY" +echo " join($PIOARDUINO_SDK, \"ld\")," >> "$AR_PIOARDUINO_PY" +echo " join($PIOARDUINO_SDK, board_config.get(\"build.arduino.memory_type\", (board_config.get(\"build.flash_mode\", \"dio\") + \"_$OCT_PSRAM\")))" >> "$AR_PIOARDUINO_PY" +echo " ]," >> "$AR_PIOARDUINO_PY" +echo "" >> "$AR_PIOARDUINO_PY" -echo " LIBS=[" >> "$AR_PLATFORMIO_PY" -echo " $PIO_LIBS" >> "$AR_PLATFORMIO_PY" -echo " ]," >> "$AR_PLATFORMIO_PY" -echo "" >> "$AR_PLATFORMIO_PY" +echo " LIBS=[" >> "$AR_PIOARDUINO_PY" +echo " $PIOARDUINO_LIBS" >> "$AR_PIOARDUINO_PY" +echo " ]," >> "$AR_PIOARDUINO_PY" +echo "" >> "$AR_PIOARDUINO_PY" -echo " CPPDEFINES=[" >> "$AR_PLATFORMIO_PY" +echo " CPPDEFINES=[" >> "$AR_PIOARDUINO_PY" set -- $DEFINES for item; do item="${item:2}" #remove -D @@ -464,17 +492,17 @@ for item; do item=(${item//=/ }) re='^[+-]?[0-9]+([.][0-9]+)?$' if [[ ${item[1]} =~ $re ]]; then - echo " (\"${item[0]}\", ${item[1]})," >> "$AR_PLATFORMIO_PY" + echo " (\"${item[0]}\", ${item[1]})," >> "$AR_PIOARDUINO_PY" else - echo " (\"${item[0]}\", '${item[1]}')," >> "$AR_PLATFORMIO_PY" + echo " (\"${item[0]}\", '${item[1]}')," >> "$AR_PIOARDUINO_PY" fi else - echo " \"$item\"," >> "$AR_PLATFORMIO_PY" + echo " \"$item\"," >> "$AR_PIOARDUINO_PY" fi done -# end generation of platformio-build.py -cat configs/pio_end.txt >> "$AR_PLATFORMIO_PY" +# end generation of pioarduino-build.py +cat configs/pioarduino_end.txt >> "$AR_PIOARDUINO_PY" # replace double backslashes with single one DEFINES=`echo "$DEFINES" | tr -s '\'` @@ -502,15 +530,6 @@ sed 's/CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER/:/arduino-esp32 espressif/esp32-arduino-lib-builder:latest +docker run --rm -it -e "TERM=xterm-256color" -v :/arduino-esp32 espressif/esp32-arduino-lib-builder:release-v5.3 ``` The above command explained: @@ -35,18 +35,16 @@ The above command explained: - `-t`: Allocates a pseudo-TTY. - `-e "TERM=xterm-256color"`: Optional. Sets the terminal type to `xterm-256color` to display colors correctly. - `-v :/arduino-esp32`: Optional. Mounts the Arduino Core for ESP32 repository at `/arduino-esp32` inside the container. Replace `` with the path to the repository on the host machine. If not provided, the container will not copy the compiled libraries to the host machine. - - `espressif/esp32-arduino-lib-builder:latest`: The Docker image to use. + - `espressif/esp32-arduino-lib-builder:release-v5.3`: The Docker image to use. After running the above command, you will be inside the container and can build the libraries using the user interface. By default the docker container will run the user interface script. If you want to run a specific command, you can pass it as an argument to the docker run command. For example, to run a terminal inside the container, you can run: ```bash -docker run -it espressif/esp32-arduino-lib-builder:latest /bin/bash +docker run -it espressif/esp32-arduino-lib-builder:release-v5.3 /bin/bash ``` ## Documentation - - -For more information about this image and the detailed usage instructions, please refer to the Arduino Core for ESP32 documentation. +For more information about this image and the detailed usage instructions, please refer to the [Arduino Core for ESP32 documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/lib_builder.html#docker-image). diff --git a/tools/docker/run.ps1 b/tools/docker/run.ps1 index 4c49ac505..5ecb01a64 100644 --- a/tools/docker/run.ps1 +++ b/tools/docker/run.ps1 @@ -1,5 +1,8 @@ # This is an example of how to run the docker container. # This script is not part of the container, it is meant to be run on the host machine. +# Note that this file will build the release/v5.3 branch. For other branches, change the tag accordingly. +# You can check the available tags at https://hub.docker.com/r/espressif/esp32-arduino-lib-builder/tags +# As this script is unsigned, you may need to run `Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass` before running it. # Usage: .\run.ps1 # Exit on error @@ -58,4 +61,4 @@ if ($env:LIBBUILDER_GIT_SAFE_DIR) { } Write-Output "Running: docker run $($DOCKER_ARGS -join ' ') espressif/esp32-arduino-lib-builder" -docker run @($DOCKER_ARGS) espressif/esp32-arduino-lib-builder +docker run @($DOCKER_ARGS) espressif/esp32-arduino-lib-builder:release-v5.3 diff --git a/tools/docker/run.sh b/tools/docker/run.sh index 59e967363..c7f97a6f5 100755 --- a/tools/docker/run.sh +++ b/tools/docker/run.sh @@ -2,6 +2,8 @@ # This is an example of how to run the docker container. # This script is not part of the container, it is meant to be run on the host machine. +# Note that this file will build the release/v5.3 branch. For other branches, change the tag accordingly. +# You can check the available tags at https://hub.docker.com/r/espressif/esp32-arduino-lib-builder/tags # Usage: ./run.sh if ! [ -x "$(command -v docker)" ]; then @@ -31,4 +33,4 @@ if [ -n "$LIBBUILDER_GIT_SAFE_DIR" ]; then fi echo "Running: docker run ${DOCKER_ARGS[@]} espressif/esp32-arduino-lib-builder" -docker run ${DOCKER_ARGS[@]} espressif/esp32-arduino-lib-builder +docker run ${DOCKER_ARGS[@]} espressif/esp32-arduino-lib-builder:release-v5.3 diff --git a/tools/gen_platformio_manifest.py b/tools/gen_pioarduino_manifest.py similarity index 94% rename from tools/gen_platformio_manifest.py rename to tools/gen_pioarduino_manifest.py index f02218826..9d2b99c19 100644 --- a/tools/gen_platformio_manifest.py +++ b/tools/gen_pioarduino_manifest.py @@ -53,7 +53,7 @@ def main(dst_dir, version_string, commit_hash): json.dump(MANIFEST_DATA, fp, indent=2) print( - f"Generated PlatformIO manifest file '{manifest_file_path}' with '{converted_version}' version" + f"Generated pioarduino manifest file '{manifest_file_path}' with '{converted_version}' version" ) return 0 diff --git a/tools/gen_tools_json.py b/tools/gen_tools_json.py index f0fc67579..392eed508 100644 --- a/tools/gen_tools_json.py +++ b/tools/gen_tools_json.py @@ -107,7 +107,7 @@ def replace_if_xz(system): out_path = args.out_path; # settings - arduino_tools = ["xtensa-esp32-elf","xtensa-esp32s2-elf","xtensa-esp32s3-elf","xtensa-esp-elf-gdb","riscv32-esp-elf","riscv32-esp-elf-gdb","openocd-esp32"] + arduino_tools = ["xtensa-esp-elf","xtensa-esp-elf-gdb","riscv32-esp-elf","riscv32-esp-elf-gdb","openocd-esp32"] # code start farray = {"packages":[{"platforms":[{"toolsDependencies":[]}],"tools":[]}]} diff --git a/tools/install-esp-idf.sh b/tools/install-esp-idf.sh index bd3d07985..0519ae67a 100755 --- a/tools/install-esp-idf.sh +++ b/tools/install-esp-idf.sh @@ -40,9 +40,7 @@ if [ ! -x $idf_was_installed ] || [ ! -x $commit_predefined ]; then # Temporarily patch the ESP32-S2 I2C LL driver to keep the clock source cd $IDF_PATH patch -p1 -N -i $AR_PATCHES/esp32s2_i2c_ll_master_init.diff - patch -p1 -N -i $AR_PATCHES/mmu_map.diff patch -p1 -N -i $AR_PATCHES/lwip_max_tcp_pcb.diff - patch -p1 -N -i $AR_PATCHES/esp32c6_provisioning_bluedroid.diff cd - fi diff --git a/tools/patch-tinyusb.sh b/tools/patch-tinyusb.sh new file mode 100755 index 000000000..eeaa4d43b --- /dev/null +++ b/tools/patch-tinyusb.sh @@ -0,0 +1,4 @@ +#!/bin/bash +mv components/arduino_tinyusb/src/dcd_dwc2.c components/arduino_tinyusb/src/dcd_dwc2.c.prev +cp components/arduino_tinyusb/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c components/arduino_tinyusb/src/dcd_dwc2.c +patch -p1 -N -i components/arduino_tinyusb/patches/dcd_dwc2.patch From 29a5022be082ad90d3b58316c5b0de8860151901 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 18 Dec 2024 16:06:11 +0200 Subject: [PATCH 16/45] Stop building libs automatically for IDF 5.1 --- .github/workflows/cron.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 30285c8bb..8d38b2fb7 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -32,9 +32,9 @@ jobs: fail-fast: false matrix: include: - - idf_branch: "release/v5.1" - lib_builder_branch: "release/v5.1" - targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2" + # - idf_branch: "release/v5.1" + # lib_builder_branch: "release/v5.1" + # targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2" - idf_branch: "release/v5.3" lib_builder_branch: "master" targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4" From 2f061cbcb7b39f3d2d2d49eaec3a7bf2fb800a67 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Fri, 20 Dec 2024 21:09:48 -0300 Subject: [PATCH 17/45] Update defconfig.esp32c6 and defconfig.esp32h2 to disable OpenThread DNS64 (#257) * Update defconfig.esp32c6 to disable OpenThread DNS64 * Update defconfig.esp32h2 to disable OT DNS64 * Update defconfig.esp32c6 to disable OpenThread DNS64 * Update defconfig.esp32h2 to disable OT DNS64 --- configs/defconfig.esp32c6 | 6 +++++- configs/defconfig.esp32h2 | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/configs/defconfig.esp32c6 b/configs/defconfig.esp32c6 index 07621cf07..8a45b0eed 100644 --- a/configs/defconfig.esp32c6 +++ b/configs/defconfig.esp32c6 @@ -15,7 +15,11 @@ CONFIG_OPENTHREAD_ENABLED=y # Border Router disabled # CONFIG_OPENTHREAD_BORDER_ROUTER=y # CONFIG_OPENTHREAD_RADIO_SPINEL_UART=y -CONFIG_OPENTHREAD_DNS64_CLIENT=y + +# DNS64 and NAT64 will be disabled for a while +# OT IDF issue https://github.com/espressif/esp-idf/issues/15069 +# CONFIG_OPENTHREAD_DNS64_CLIENT=y + # Radio for RPC # CONFIG_OPENTHREAD_RADIO=y # CONFIG_OPENTHREAD_RADIO_NATIVE=y diff --git a/configs/defconfig.esp32h2 b/configs/defconfig.esp32h2 index fe4a47eb6..9bc304886 100644 --- a/configs/defconfig.esp32h2 +++ b/configs/defconfig.esp32h2 @@ -11,7 +11,11 @@ CONFIG_OPENTHREAD_ENABLED=y # Border Router disabled # CONFIG_OPENTHREAD_BORDER_ROUTER=y # CONFIG_OPENTHREAD_RADIO_SPINEL_UART=y -CONFIG_OPENTHREAD_DNS64_CLIENT=y + +# DNS64 and NAT64 will be disabled for a while +# OT IDF issue https://github.com/espressif/esp-idf/issues/15069 +# CONFIG_OPENTHREAD_DNS64_CLIENT=y + # Radio for RPC # CONFIG_OPENTHREAD_RADIO=y # CONFIG_OPENTHREAD_RADIO_NATIVE=y From 44fadb0eb161176b3b5ae3a44eca12635539ea6a Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 8 Jan 2025 14:09:19 +0200 Subject: [PATCH 18/45] Add IDF 5.4 to cron builds --- .github/workflows/cron.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 8d38b2fb7..889ea13d7 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -38,3 +38,6 @@ jobs: - idf_branch: "release/v5.3" lib_builder_branch: "master" targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4" + - idf_branch: "release/v5.4" + lib_builder_branch: "release/v5.4" + targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4" From b97cdf80a6e1e73cdcaef98bcdd6fd5508c6214c Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:47:02 -0300 Subject: [PATCH 19/45] fix(pioarduino): Add missing define (#261) --- configs/pioarduino_end.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/pioarduino_end.txt b/configs/pioarduino_end.txt index f942d442d..d9b5d5467 100644 --- a/configs/pioarduino_end.txt +++ b/configs/pioarduino_end.txt @@ -1,4 +1,5 @@ "ARDUINO_ARCH_ESP32", + "CHIP_HAVE_CONFIG_H", ("ESP32", "ESP32"), ("F_CPU", "$BOARD_F_CPU"), ("ARDUINO", 10812), From e68e30112ffad75e96535408dfe25bff6d2f26fb Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 21 Jan 2025 17:37:52 +0200 Subject: [PATCH 20/45] Add IDF v5.5. to cron --- .github/workflows/cron.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 889ea13d7..31c578ef7 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -41,3 +41,6 @@ jobs: - idf_branch: "release/v5.4" lib_builder_branch: "release/v5.4" targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4" + - idf_branch: "master" + lib_builder_branch: "release/v5.5" + targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4,esp32c5" From 833a7f515b95c9450473a1f5c9bb907b0e23cdb0 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Tue, 4 Feb 2025 10:59:04 -0300 Subject: [PATCH 21/45] fix(upload): Add delays and improve error checking (#265) --- tools/config.sh | 7 +++++-- tools/push-to-arduino.sh | 20 +++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/tools/config.sh b/tools/config.sh index 89cd9856a..3349e4553 100755 --- a/tools/config.sh +++ b/tools/config.sh @@ -203,8 +203,11 @@ function github_release_asset_upload(){ # github_release_asset_upload local repo_path="$1" local release_asset_id="$2" - local res=$(curl -s -k -o /dev/null -w "%{http_code}" -X DELETE -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" "https://api.github.com/repos/$repo_path/releases/assets/$release_asset_id") - if [ "$res" -eq 204 ]; then echo 1; else echo 0; fi + local res + local return_code + res=$(curl -s -k -o /dev/null -w "%{http_code}" -X DELETE -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" "https://api.github.com/repos/$repo_path/releases/assets/$release_asset_id") + return_code=$? + if [ "$res" -eq 204 ] && [ "$return_code" -eq 0 ] ; then echo 1; else echo 0; fi } diff --git a/tools/push-to-arduino.sh b/tools/push-to-arduino.sh index c4d1959d3..8b9b552a7 100755 --- a/tools/push-to-arduino.sh +++ b/tools/push-to-arduino.sh @@ -47,16 +47,22 @@ if [ $AR_HAS_COMMIT == "0" ] || [ $LIBS_HAS_ASSET == "0" ]; then fi fi + sleep 5 echo "Creating asset '$LIBS_ZIP_FILENAME'..." - mv -f "dist/esp32-arduino-libs.zip" "dist/$LIBS_ZIP_FILENAME" + LIBS_ASSET_ID=`github_release_asset_upload "$AR_LIBS_REPO" "$LIBS_RELEASE_ID" "$LIBS_ZIP_FILENAME" "dist/$LIBS_ZIP_FILENAME"` if [ -z "$LIBS_ASSET_ID" ]; then - echo "ERROR: Failed to upload asset '$LIBS_ZIP_FILENAME'" - exit 1 + echo "ERROR: Failed to upload asset '$LIBS_ZIP_FILENAME. Retrying..." + LIBS_ASSET_ID=`github_release_asset_upload "$AR_LIBS_REPO" "$LIBS_RELEASE_ID" "$LIBS_ZIP_FILENAME" "dist/$LIBS_ZIP_FILENAME"` + if [ -z "$LIBS_ASSET_ID" ]; then + echo "ERROR: Failed to upload asset '$LIBS_ZIP_FILENAME'" + exit 1 + fi fi echo "Finished uploading asset '$LIBS_ZIP_FILENAME'. Asset ID: $LIBS_ASSET_ID" + sleep 5 # Calculate the local file checksum and size local_checksum=$(sha256sum "dist/$LIBS_ZIP_FILENAME" | awk '{print $1}') @@ -108,8 +114,12 @@ if [ $AR_HAS_COMMIT == "0" ] || [ $LIBS_HAS_ASSET == "0" ]; then JSON_ASSET_ID=`github_release_asset_upload "$AR_LIBS_REPO" "$LIBS_RELEASE_ID" "$LIBS_JSON_FILENAME" "$AR_OUT/package_esp32_index.template.json"` if [ -z "$JSON_ASSET_ID" ]; then - echo "ERROR: Failed to upload asset '$LIBS_JSON_FILENAME'" - exit 1 + echo "ERROR: Failed to upload asset '$LIBS_JSON_FILENAME'. Retrying..." + JSON_ASSET_ID=`github_release_asset_upload "$AR_LIBS_REPO" "$LIBS_RELEASE_ID" "$LIBS_JSON_FILENAME" "$AR_OUT/package_esp32_index.template.json"` + if [ -z "$JSON_ASSET_ID" ]; then + echo "ERROR: Failed to upload asset '$LIBS_JSON_FILENAME'" + exit 1 + fi fi fi From ad3fb2409169c4c06f2ece49236b63e7eec7e16c Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 4 Feb 2025 23:59:06 +0200 Subject: [PATCH 22/45] fix(lcd): Enable optimizations for RGB LCD (#273) --- configs/defconfig.esp32p4 | 4 ++++ configs/defconfig.esp32s3 | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/configs/defconfig.esp32p4 b/configs/defconfig.esp32p4 index 8b04e8469..850b5fd2c 100644 --- a/configs/defconfig.esp32p4 +++ b/configs/defconfig.esp32p4 @@ -24,3 +24,7 @@ CONFIG_ESP_REV_MIN_FULL=0 CONFIG_ESP32P4_REV_MAX_FULL=99 CONFIG_ESP_REV_MAX_FULL=99 # end of Chip revision + +# RGB Display Optimizations +CONFIG_LCD_RGB_ISR_IRAM_SAFE=y +CONFIG_LCD_RGB_RESTART_IN_VSYNC=y diff --git a/configs/defconfig.esp32s3 b/configs/defconfig.esp32s3 index 2c2cba3cd..ce53e7747 100644 --- a/configs/defconfig.esp32s3 +++ b/configs/defconfig.esp32s3 @@ -17,3 +17,7 @@ CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_FSM=y # CONFIG_ULP_COPROC_TYPE_RISCV=y CONFIG_ULP_COPROC_RESERVE_MEM=512 + +# RGB Display Optimizations +CONFIG_LCD_RGB_ISR_IRAM_SAFE=y +CONFIG_LCD_RGB_RESTART_IN_VSYNC=y From 37d69cae6dd8bdbfa877528eb2f5076394b7fb6d Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 12 Feb 2025 11:19:22 +0200 Subject: [PATCH 23/45] Add support for two TinyUSB CDC devices at once (#275) --- components/arduino_tinyusb/Kconfig.projbuild | 8 ++++++++ components/arduino_tinyusb/include/tusb_config.h | 6 +++++- configs/defconfig.common | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/components/arduino_tinyusb/Kconfig.projbuild b/components/arduino_tinyusb/Kconfig.projbuild index 65d9c37be..f0a1b4dc6 100755 --- a/components/arduino_tinyusb/Kconfig.projbuild +++ b/components/arduino_tinyusb/Kconfig.projbuild @@ -42,6 +42,14 @@ menu "Arduino TinyUSB" help CDC FIFO size of TX + config TINYUSB_CDC_MAX_PORTS + int "Maximum enabled CDC ports" + range 1 2 + default 1 + depends on TINYUSB_CDC_ENABLED + help + Maximum enabled CDC ports + endmenu menu "Mass Storage (MSC) driver" diff --git a/components/arduino_tinyusb/include/tusb_config.h b/components/arduino_tinyusb/include/tusb_config.h index 458c78cf1..7802bea8f 100755 --- a/components/arduino_tinyusb/include/tusb_config.h +++ b/components/arduino_tinyusb/include/tusb_config.h @@ -115,7 +115,11 @@ extern "C" { #define CFG_TUD_ENDOINT0_SIZE 64 // Enabled Drivers -#define CFG_TUD_CDC CONFIG_TINYUSB_CDC_ENABLED +#ifdef CONFIG_TINYUSB_CDC_MAX_PORTS +#define CFG_TUD_CDC CONFIG_TINYUSB_CDC_MAX_PORTS +#else +#define CFG_TUD_CDC 0 +#endif #define CFG_TUD_MSC CONFIG_TINYUSB_MSC_ENABLED #define CFG_TUD_HID CONFIG_TINYUSB_HID_ENABLED #define CFG_TUD_MIDI CONFIG_TINYUSB_MIDI_ENABLED diff --git a/configs/defconfig.common b/configs/defconfig.common index ef4620bf6..bf5d1197f 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -131,3 +131,6 @@ CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n CONFIG_ENABLE_ESP_INSIGHTS_TRACE=n # Use compact attribute storage mode CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y + +#TinyUSB Config +CONFIG_TINYUSB_CDC_MAX_PORTS=2 From 8cea2374eec3c0c387f8c896fa69ff8777711c3a Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Thu, 13 Feb 2025 08:30:17 -0300 Subject: [PATCH 24/45] fix(docker): Bump base image (#276) * fix(docker): Bump base image * fix(docker): Fix pip install --- tools/docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 3262cbb2d..699f0bd8e 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -1,5 +1,5 @@ # To Do: Check if it is worth to use espressif/idf as base image (image size will be much bigger) -FROM ubuntu:22.04 +FROM ubuntu:latest # switch to root, let the entrypoint drop back to host user USER root @@ -70,7 +70,7 @@ RUN echo LIBBUILDER_CHECKOUT_REF=$LIBBUILDER_CHECKOUT_REF LIBBUILDER_CLONE_BRANC git checkout $LIBBUILDER_CHECKOUT_REF && \ git submodule update --init --recursive; \ fi && \ - pip3 install --upgrade -r $LIBBUILDER_PATH/tools/config_editor/requirements.txt + pip3 install --break-system-packages --upgrade -r $LIBBUILDER_PATH/tools/config_editor/requirements.txt COPY entrypoint.sh $LIBBUILDER_PATH/entrypoint.sh From 77f5effeaea8aad19cc1fd044b866cca8f163754 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 8 Jan 2025 13:27:51 +0200 Subject: [PATCH 25/45] Configure build for ESP-IDF v5.4 --- tools/config.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/config.sh b/tools/config.sh index 3349e4553..1b2941e97 100755 --- a/tools/config.sh +++ b/tools/config.sh @@ -6,11 +6,11 @@ if [ -z $IDF_PATH ]; then fi if [ -z $IDF_BRANCH ]; then - IDF_BRANCH="release/v5.3" + IDF_BRANCH="release/v5.4" fi if [ -z $AR_PR_TARGET_BRANCH ]; then - AR_PR_TARGET_BRANCH="master" + AR_PR_TARGET_BRANCH="release/v3.2.x" fi if [ -z $IDF_TARGET ]; then From 731afdf3bfa2a161aec934747b1d4f606a38255c Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 8 Jan 2025 13:28:16 +0200 Subject: [PATCH 26/45] Remove support for REV0 ESP32-P4 --- configs/defconfig.esp32p4 | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/configs/defconfig.esp32p4 b/configs/defconfig.esp32p4 index 850b5fd2c..9cc5e8392 100644 --- a/configs/defconfig.esp32p4 +++ b/configs/defconfig.esp32p4 @@ -14,17 +14,6 @@ CONFIG_ESP_SDIO_PIN_D1=15 CONFIG_ESP_SDIO_PIN_D2=16 CONFIG_ESP_SDIO_PIN_D3=17 -# -# Chip revision -# -CONFIG_ESP32P4_REV_MIN_0=y -# CONFIG_ESP32P4_REV_MIN_1 is not set -CONFIG_ESP32P4_REV_MIN_FULL=0 -CONFIG_ESP_REV_MIN_FULL=0 -CONFIG_ESP32P4_REV_MAX_FULL=99 -CONFIG_ESP_REV_MAX_FULL=99 -# end of Chip revision - # RGB Display Optimizations CONFIG_LCD_RGB_ISR_IRAM_SAFE=y CONFIG_LCD_RGB_RESTART_IN_VSYNC=y From 784cd9d2626483b40047ad172e06bf897af2b642 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 15 Jan 2025 15:50:23 +0200 Subject: [PATCH 27/45] Add temporarily the option to use toolchains with `_signed` postfix This is to fix an issue with ARM Mac toolchain for IDF v5.4 --- tools/gen_tools_json.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/gen_tools_json.py b/tools/gen_tools_json.py index 392eed508..a795285b9 100644 --- a/tools/gen_tools_json.py +++ b/tools/gen_tools_json.py @@ -27,8 +27,8 @@ def replace_if_xz(system): if not system['url'].endswith(".tar.xz"): return system - new_url = system['url'].replace(".tar.xz", ".tar.gz") - new_name = system['archiveFileName'].replace(".tar.xz", ".tar.gz") + new_url = system['url'].replace(".tar.xz", "_signed.tar.gz") + new_name = system['archiveFileName'].replace(".tar.xz", "_signed.tar.gz") new_checksum = "" new_size = 0 @@ -40,8 +40,16 @@ def replace_if_xz(system): (owner, proj, version, filename) = urlx[0] release_manifest_url = "https://github.com/%s/%s/releases/download/%s/%s-%s-checksum.sha256" % (owner, proj, version, proj, version) else: - print("No manifest match") - return system + new_url = system['url'].replace(".tar.xz", ".tar.gz") + new_name = system['archiveFileName'].replace(".tar.xz", ".tar.gz") + # parse the download url to extract all info needed for the checksum file url + urlx = re.findall("^https://github.com/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/releases/download/([a-zA-Z0-9_\-.]+)/([a-zA-Z0-9_\-.]+)$", new_url) + if urlx and len(urlx) > 0: + (owner, proj, version, filename) = urlx[0] + release_manifest_url = "https://github.com/%s/%s/releases/download/%s/%s-%s-checksum.sha256" % (owner, proj, version, proj, version) + else: + print("No manifest match") + return system # check if we have already downloaded and parsed that manifest manifest_index = 0 From cc827d83668c660ba3fa9a2329e756e5e47bb9b2 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 16 Jan 2025 17:44:36 +0200 Subject: [PATCH 28/45] Fix tools json generation --- tools/gen_tools_json.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/gen_tools_json.py b/tools/gen_tools_json.py index a795285b9..f03b73d78 100644 --- a/tools/gen_tools_json.py +++ b/tools/gen_tools_json.py @@ -27,8 +27,10 @@ def replace_if_xz(system): if not system['url'].endswith(".tar.xz"): return system - new_url = system['url'].replace(".tar.xz", "_signed.tar.gz") - new_name = system['archiveFileName'].replace(".tar.xz", "_signed.tar.gz") + new_url = system['url'].replace(".tar.xz", ".tar.gz") + new_name = system['archiveFileName'].replace(".tar.xz", ".tar.gz") + new_signed_url = system['url'].replace(".tar.xz", "_signed.tar.gz") + new_signed_name = system['archiveFileName'].replace(".tar.xz", "_signed.tar.gz") new_checksum = "" new_size = 0 @@ -40,16 +42,8 @@ def replace_if_xz(system): (owner, proj, version, filename) = urlx[0] release_manifest_url = "https://github.com/%s/%s/releases/download/%s/%s-%s-checksum.sha256" % (owner, proj, version, proj, version) else: - new_url = system['url'].replace(".tar.xz", ".tar.gz") - new_name = system['archiveFileName'].replace(".tar.xz", ".tar.gz") - # parse the download url to extract all info needed for the checksum file url - urlx = re.findall("^https://github.com/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/releases/download/([a-zA-Z0-9_\-.]+)/([a-zA-Z0-9_\-.]+)$", new_url) - if urlx and len(urlx) > 0: - (owner, proj, version, filename) = urlx[0] - release_manifest_url = "https://github.com/%s/%s/releases/download/%s/%s-%s-checksum.sha256" % (owner, proj, version, proj, version) - else: - print("No manifest match") - return system + print("No manifest match") + return system # check if we have already downloaded and parsed that manifest manifest_index = 0 @@ -84,6 +78,12 @@ def replace_if_xz(system): release_manifests.append(manifest) # find the new file in the list and get it's size and checksum + for file in release_manifests[manifest_index]['files']: + if file['name'] == new_signed_name: + print("Found a signed version of the file") + new_url = new_signed_url + new_name = new_signed_name + break for file in release_manifests[manifest_index]['files']: if file['name'] == new_name: system['url'] = new_url From 43e5553eeff8e28c296b24c41cd0823d1e4c18cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 4 Feb 2025 22:59:32 +0100 Subject: [PATCH 29/45] fix(zigbee): Exclude correct libs for 1.6.2 version (#269) --- tools/copy-libs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/copy-libs.sh b/tools/copy-libs.sh index 21efe1a78..17014e70d 100755 --- a/tools/copy-libs.sh +++ b/tools/copy-libs.sh @@ -95,7 +95,7 @@ fi if [ -d "managed_components/espressif__esp-zboss-lib/lib/$IDF_TARGET/" ]; then cp -r "managed_components/espressif__esp-zboss-lib/lib/$IDF_TARGET"/* "$AR_SDK/lib/" - EXCLUDE_LIBS+="zboss_stack.ed;zboss_port.debug;" + EXCLUDE_LIBS+="zboss_stack.ed;zboss_port.native.debug;" fi #collect includes, defines and c-flags From ffdf58bb89214802251d334cb1f9cdafadd93f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:14:11 +0100 Subject: [PATCH 30/45] fix(zigbee): Update exclude libs in script (#274) --- tools/copy-libs.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/copy-libs.sh b/tools/copy-libs.sh index 17014e70d..53e41eee5 100755 --- a/tools/copy-libs.sh +++ b/tools/copy-libs.sh @@ -90,12 +90,12 @@ fi # copy zigbee + zboss lib if [ -d "managed_components/espressif__esp-zigbee-lib/lib/$IDF_TARGET/" ]; then cp -r "managed_components/espressif__esp-zigbee-lib/lib/$IDF_TARGET"/* "$AR_SDK/lib/" - EXCLUDE_LIBS+="esp_zb_api_ed;" + EXCLUDE_LIBS+="esp_zb_api.ed;" fi if [ -d "managed_components/espressif__esp-zboss-lib/lib/$IDF_TARGET/" ]; then cp -r "managed_components/espressif__esp-zboss-lib/lib/$IDF_TARGET"/* "$AR_SDK/lib/" - EXCLUDE_LIBS+="zboss_stack.ed;zboss_port.native.debug;" + EXCLUDE_LIBS+="zboss_stack.ed;zboss_port.native;zboss_port.native.debug;" fi #collect includes, defines and c-flags From 3225f04b8efad7d11286cd27dfef60ac361bfcba Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 18 Feb 2025 11:48:43 +0200 Subject: [PATCH 31/45] Update target branches --- .github/workflows/cron.yml | 8 ++++---- tools/config.sh | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 31c578ef7..8a8f721db 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -35,11 +35,11 @@ jobs: # - idf_branch: "release/v5.1" # lib_builder_branch: "release/v5.1" # targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2" - - idf_branch: "release/v5.3" - lib_builder_branch: "master" - targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4" + # - idf_branch: "release/v5.3" + # lib_builder_branch: "master" + # targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4" - idf_branch: "release/v5.4" - lib_builder_branch: "release/v5.4" + lib_builder_branch: "master" targets: "esp32,esp32s2,esp32s3,esp32c3,esp32c6,esp32h2,esp32p4" - idf_branch: "master" lib_builder_branch: "release/v5.5" diff --git a/tools/config.sh b/tools/config.sh index 1b2941e97..79d4feef5 100755 --- a/tools/config.sh +++ b/tools/config.sh @@ -10,7 +10,7 @@ if [ -z $IDF_BRANCH ]; then fi if [ -z $AR_PR_TARGET_BRANCH ]; then - AR_PR_TARGET_BRANCH="release/v3.2.x" + AR_PR_TARGET_BRANCH="master" fi if [ -z $IDF_TARGET ]; then From 5d86a90635cc9c695913503315284fd47b4c192a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 18 Feb 2025 21:57:38 +0100 Subject: [PATCH 32/45] Delete removed Zigbee RCP mode / rename of libs --- configs/pioarduino_start.txt | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/configs/pioarduino_start.txt b/configs/pioarduino_start.txt index c5174173d..ec10a10dc 100644 --- a/configs/pioarduino_start.txt +++ b/configs/pioarduino_start.txt @@ -45,28 +45,17 @@ flatten_cppdefines = env.Flatten(env['CPPDEFINES']) if "ZIGBEE_MODE_ZCZR" in flatten_cppdefines: env.Append( LIBS=[ - "-lesp_zb_api_zczr", - "-lesp_zb_cli_command", + "-lesp_zb_api.zczr", "-lzboss_stack.zczr", - "-lzboss_port" + "-lzboss_port.native" ] ) if "ZIGBEE_MODE_ED" in flatten_cppdefines: env.Append( LIBS=[ - "-lesp_zb_api_ed", - "-lesp_zb_cli_command", + "-lesp_zb_api.ed", "-lzboss_stack.ed", - "-lzboss_port" - ] - ) -if "ZIGBEE_MODE_RCP" in flatten_cppdefines: - env.Append( - LIBS=[ - "-lesp_zb_api_rcp", - "-lesp_zb_cli_command", - "-lzboss_stack.rcp", - "-lzboss_port" + "-lzboss_port.native" ] ) From 252044546d2eb42a64401c71df580e4841ebcb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 20 Feb 2025 16:31:53 +0100 Subject: [PATCH 33/45] feat(zigbee): Enable Zigbee by default on all chips --- configs/defconfig.common | 3 +++ configs/defconfig.esp32c6 | 1 - configs/defconfig.esp32h2 | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/configs/defconfig.common b/configs/defconfig.common index bf5d1197f..2fc18a697 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -134,3 +134,6 @@ CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y #TinyUSB Config CONFIG_TINYUSB_CDC_MAX_PORTS=2 + +# Zigbee Config +CONFIG_ZB_ENABLED=y diff --git a/configs/defconfig.esp32c6 b/configs/defconfig.esp32c6 index 8a45b0eed..d0e2b7bbd 100644 --- a/configs/defconfig.esp32c6 +++ b/configs/defconfig.esp32c6 @@ -45,7 +45,6 @@ CONFIG_ENABLE_MATTER_OVER_THREAD=n # # Zigbee # -CONFIG_ZB_ENABLED=y CONFIG_ZB_ZED=y CONFIG_ZB_RADIO_NATIVE=y # end of Zigbee diff --git a/configs/defconfig.esp32h2 b/configs/defconfig.esp32h2 index 9bc304886..024120d34 100644 --- a/configs/defconfig.esp32h2 +++ b/configs/defconfig.esp32h2 @@ -38,7 +38,6 @@ CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" # # Zigbee # -CONFIG_ZB_ENABLED=y CONFIG_ZB_ZED=y CONFIG_ZB_RADIO_NATIVE=y # end of Zigbee From 4ed776080713d42e786f7179b13b8557fc67707c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 20 Feb 2025 19:09:07 +0100 Subject: [PATCH 34/45] fix(libs): Add also zcrz and remote zb libs to exclude --- tools/copy-libs.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/copy-libs.sh b/tools/copy-libs.sh index 53e41eee5..5c71c72ab 100755 --- a/tools/copy-libs.sh +++ b/tools/copy-libs.sh @@ -90,12 +90,12 @@ fi # copy zigbee + zboss lib if [ -d "managed_components/espressif__esp-zigbee-lib/lib/$IDF_TARGET/" ]; then cp -r "managed_components/espressif__esp-zigbee-lib/lib/$IDF_TARGET"/* "$AR_SDK/lib/" - EXCLUDE_LIBS+="esp_zb_api.ed;" + EXCLUDE_LIBS+="esp_zb_api.ed;esp_zb_api.zczr;" fi if [ -d "managed_components/espressif__esp-zboss-lib/lib/$IDF_TARGET/" ]; then cp -r "managed_components/espressif__esp-zboss-lib/lib/$IDF_TARGET"/* "$AR_SDK/lib/" - EXCLUDE_LIBS+="zboss_stack.ed;zboss_port.native;zboss_port.native.debug;" + EXCLUDE_LIBS+="zboss_stack.ed;zboss_stack.zczr;zboss_port.native;zboss_port.native.debug;zboss_port.remote;zboss_port.remote.debug;" fi #collect includes, defines and c-flags From 5db5d9aea007f55e4983ad74de17204649829725 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 25 Feb 2025 10:30:06 +0200 Subject: [PATCH 35/45] Update PR Title and commit messages to Arduino --- tools/check-deploy-needed.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/check-deploy-needed.sh b/tools/check-deploy-needed.sh index e33cc169c..28a95ee7e 100755 --- a/tools/check-deploy-needed.sh +++ b/tools/check-deploy-needed.sh @@ -33,8 +33,8 @@ fi # format new branch name and pr title AR_NEW_BRANCH_NAME="idf-$IDF_BRANCH" -AR_NEW_COMMIT_MESSAGE="IDF $IDF_BRANCH $IDF_COMMIT" -AR_NEW_PR_TITLE="IDF $IDF_BRANCH" +AR_NEW_COMMIT_MESSAGE="ci(libs): ESP-IDF $IDF_BRANCH $IDF_COMMIT" +AR_NEW_PR_TITLE="ci(libs): ESP-IDF $IDF_BRANCH" LIBS_RELEASE_TAG="idf-"${IDF_BRANCH//\//_}"" LIBS_VERSION_PREFIX="$LIBS_RELEASE_TAG-$IDF_COMMIT-v" From 16a6e09d397baa2fb58a34dd6abf45d9307100c4 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 26 Feb 2025 16:14:00 +0200 Subject: [PATCH 36/45] Revert "Update PR Title and commit messages to Arduino" This reverts commit 5db5d9aea007f55e4983ad74de17204649829725. --- tools/check-deploy-needed.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/check-deploy-needed.sh b/tools/check-deploy-needed.sh index 28a95ee7e..e33cc169c 100755 --- a/tools/check-deploy-needed.sh +++ b/tools/check-deploy-needed.sh @@ -33,8 +33,8 @@ fi # format new branch name and pr title AR_NEW_BRANCH_NAME="idf-$IDF_BRANCH" -AR_NEW_COMMIT_MESSAGE="ci(libs): ESP-IDF $IDF_BRANCH $IDF_COMMIT" -AR_NEW_PR_TITLE="ci(libs): ESP-IDF $IDF_BRANCH" +AR_NEW_COMMIT_MESSAGE="IDF $IDF_BRANCH $IDF_COMMIT" +AR_NEW_PR_TITLE="IDF $IDF_BRANCH" LIBS_RELEASE_TAG="idf-"${IDF_BRANCH//\//_}"" LIBS_VERSION_PREFIX="$LIBS_RELEASE_TAG-$IDF_COMMIT-v" From 206744855a44ab7332147431ddc4433c93f9c5df Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Thu, 6 Mar 2025 13:11:22 -0300 Subject: [PATCH 37/45] feat(matter): updates matter version to 1.4 --- main/idf_component.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/idf_component.yml b/main/idf_component.yml index c6bb97f46..8c574bb08 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -17,7 +17,7 @@ dependencies: rules: - if: "target in [esp32s3]" espressif/esp_matter: - version: "^1.3.0" + version: "^1.4.0" require: public rules: - if: "target not in [esp32c2, esp32h2, esp32p4]" From a401c5baa24b14515d6dcc7d0c78d0c216dc5ceb Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Fri, 7 Mar 2025 11:21:26 +0200 Subject: [PATCH 38/45] Enable I2S_ISR_IRAM_SAFE to fix bug in ESP-IDF --- configs/defconfig.common | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/defconfig.common b/configs/defconfig.common index 2fc18a697..621256ba7 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -121,6 +121,7 @@ CONFIG_ESP_COREDUMP_STACK_SIZE=0 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y +CONFIG_I2S_ISR_IRAM_SAFE=y # # Matter Settings # From fffa99e734a4505fd36d4caf94fbf5cb5f192c5c Mon Sep 17 00:00:00 2001 From: TANAKA Masayuki Date: Fri, 7 Mar 2025 18:26:53 +0900 Subject: [PATCH 39/45] fix(TinyUSB): USB HUB Subport Added, FIFO sizes(Bias Periodic OUT) It is used by USB HUB. And, Supports USB packets of 128 bytes or more. --- configs/defconfig.common | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/defconfig.common b/configs/defconfig.common index 2fc18a697..ad01918a7 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -134,6 +134,9 @@ CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y #TinyUSB Config CONFIG_TINYUSB_CDC_MAX_PORTS=2 +CONFIG_USB_HOST_HUBS_SUPPORTED=y +CONFIG_USB_HOST_HUB_MULTI_LEVEL=y +CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT=y # Zigbee Config CONFIG_ZB_ENABLED=y From 3150a1dfabec2b9fa4b5e8be71af90b4d4c05306 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 7 Mar 2025 16:58:43 +0200 Subject: [PATCH 40/45] Disable custom IP6 LwIP hook --- configs/defconfig.common | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/defconfig.common b/configs/defconfig.common index c0c91d0c4..48baf5081 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -78,7 +78,6 @@ CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT=y CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT=y -CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM=y CONFIG_LWIP_MULTICAST_PING=y CONFIG_LWIP_BROADCAST_PING=y CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 From ce6f1932b49db1aed494871df72fac97592d08b4 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Sat, 8 Mar 2025 19:18:26 -0300 Subject: [PATCH 41/45] fixes Matter 1.4 Resolve Include Macro --- tools/copy-libs.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/copy-libs.sh b/tools/copy-libs.sh index 5c71c72ab..7c302ab66 100755 --- a/tools/copy-libs.sh +++ b/tools/copy-libs.sh @@ -525,9 +525,10 @@ for flag_file in "c_flags" "cpp_flags" "S_flags"; do sed 's/\\\"-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=\\\"/-DCHIP_HAVE_CONFIG_H/' $FLAGS_DIR/$flag_file > $FLAGS_DIR/$flag_file.temp mv $FLAGS_DIR/$flag_file.temp $FLAGS_DIR/$flag_file done -CHIP_RESOLVE_DIR="$AR_SDK/include/espressif__esp_matter/connectedhomeip/connectedhomeip/src/lib/address_resolve" -sed 's/CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER//' $CHIP_RESOLVE_DIR/AddressResolve.h > $CHIP_RESOLVE_DIR/AddressResolve_temp.h -mv $CHIP_RESOLVE_DIR/AddressResolve_temp.h $CHIP_RESOLVE_DIR/AddressResolve.h +# this is not necessary for Matter 1.4, but it is for Matter 1.3 +#CHIP_RESOLVE_DIR="$AR_SDK/include/espressif__esp_matter/connectedhomeip/connectedhomeip/src/lib/address_resolve" +#sed 's/CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER//' $CHIP_RESOLVE_DIR/AddressResolve.h > $CHIP_RESOLVE_DIR/AddressResolve_temp.h +#mv $CHIP_RESOLVE_DIR/AddressResolve_temp.h $CHIP_RESOLVE_DIR/AddressResolve.h # End of Matter Library adjustments # sdkconfig From 91af3d16ec1ecef6e589bd9ca1b48b4fbe137a46 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 19 Mar 2025 17:37:46 +0200 Subject: [PATCH 42/45] Enable TLS 1.3 --- configs/defconfig.common | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/defconfig.common b/configs/defconfig.common index 48baf5081..096556a9f 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -90,6 +90,7 @@ CONFIG_MBEDTLS_CAMELLIA_C=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y # CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN is not set CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y CONFIG_OPENSSL_ASSERT_DO_NOTHING=y CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=2048 CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y From 5c05937d6ea565806dcba24258812cb8dadbe4af Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Wed, 19 Mar 2025 18:51:21 -0300 Subject: [PATCH 43/45] ci(workflows): Lock actions to commits and improve readability --- .github/workflows/cron_build.yml | 19 +++++++++++-------- .github/workflows/docker.yml | 12 ++++++------ .github/workflows/push.yml | 13 +++++++------ .github/workflows/repository_dispatch.yml | 11 ++++++++--- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/.github/workflows/cron_build.yml b/.github/workflows/cron_build.yml index 8d13759b7..fd9634928 100644 --- a/.github/workflows/cron_build.yml +++ b/.github/workflows/cron_build.yml @@ -41,7 +41,8 @@ jobs: deploy_needed: ${{ steps.check.outputs.deploy_needed }} targets_list: ${{ steps.check.outputs.targets_list }} steps: - - uses: actions/checkout@v4 + - name: Checkout ${{ inputs.lib_builder_branch }} + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ inputs.lib_builder_branch }} @@ -65,7 +66,8 @@ jobs: matrix: target: ${{ fromJson(needs.check-if-needed.outputs.targets_list) }} steps: - - uses: actions/checkout@v4 + - name: Checkout ${{ inputs.lib_builder_branch }} + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ inputs.lib_builder_branch }} @@ -88,13 +90,13 @@ jobs: - name: Upload build if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: build-${{ env.libs_branch }}-${{ matrix.target }} path: build - name: Upload library files - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: libs-${{ env.libs_branch }}-${{ matrix.target }} path: dist @@ -105,7 +107,8 @@ jobs: needs: [check-if-needed, build-libs] if: needs.check-if-needed.outputs.deploy_needed == '1' steps: - - uses: actions/checkout@v4 + - name: Checkout ${{ inputs.lib_builder_branch }} + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: ${{ inputs.lib_builder_branch }} @@ -115,7 +118,7 @@ jobs: echo "libs_branch=${branch//\//_}" >> $GITHUB_ENV - name: Download artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 with: path: dist pattern: libs-${{ env.libs_branch }}-* @@ -125,7 +128,7 @@ jobs: run: bash ./tools/combine-artifacts.sh - name: Upload full esp32-arduino-libs archive - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: esp32-arduino-libs-${{ env.libs_branch }} path: dist/esp32-arduino-libs.zip @@ -154,7 +157,7 @@ jobs: bash ./tools/push-to-arduino.sh - name: Upload package_esp32_index.template.json - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: package-esp32-index-json-${{ env.libs_branch }} path: out/package_esp32_index.template.json diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d6166a365..c89352150 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -66,23 +66,23 @@ jobs: echo "URL: $URL" - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Login to Docker Hub if: ${{ github.event_name == 'push' }} - uses: docker/login-action@v3 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up QEMU for multiarch builds - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 with: context: tools/docker push: ${{ github.event_name == 'push' }} @@ -94,7 +94,7 @@ jobs: - name: Update Docker Hub repository description (master branch) if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && github.ref_name == 'master' }} - uses: peter-evans/dockerhub-description@v4 + uses: peter-evans/dockerhub-description@e98e4d1628a5f3be2be7c231e50981aee98723ae # v4.0.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 95610c403..756ab0991 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -28,7 +28,8 @@ jobs: target: [esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2, esp32p4] fail-fast: false steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install dependencies run: bash ./tools/prepare-ci.sh @@ -38,13 +39,13 @@ jobs: - name: Upload build if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: build-${{ matrix.target }} path: build - name: Upload archive - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: artifacts-${{ matrix.target }} path: dist @@ -55,7 +56,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 with: path: dist pattern: artifacts-* @@ -69,13 +70,13 @@ jobs: cp out/package_esp32_index.template.json dist/package_esp32_index.template.json - name: Upload full esp32-arduino-libs archive - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: esp32-arduino-libs path: dist/esp32-arduino-libs.tar.gz - name: Upload package_esp32_index.template.json - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: package-esp32-index-json path: dist/package_esp32_index.template.json diff --git a/.github/workflows/repository_dispatch.yml b/.github/workflows/repository_dispatch.yml index a18412a3d..62837976b 100644 --- a/.github/workflows/repository_dispatch.yml +++ b/.github/workflows/repository_dispatch.yml @@ -7,25 +7,30 @@ jobs: name: Dispatch Event runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 + - name: Install dependencies run: bash ./tools/prepare-ci.sh + - name: Handle Event env: GITHUB_TOKEN: ${{ secrets.PUSH_TOKEN }} GIT_AUTHOR_EMAIL: ${{ secrets.PUSH_EMAIL }} GIT_COMMITTER_EMAIL: ${{ secrets.PUSH_EMAIL }} run: bash ./tools/repository_dispatch.sh + - name: Upload build if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: build path: build + - name: Upload archive - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: artifacts path: dist From c4a6b8f289dee1ea92618dfbd91d981ea2f4d1aa Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 20 Mar 2025 02:00:16 +0200 Subject: [PATCH 44/45] Revert "Enable TLS 1.3" This reverts commit 91af3d16ec1ecef6e589bd9ca1b48b4fbe137a46. --- configs/defconfig.common | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/defconfig.common b/configs/defconfig.common index 096556a9f..48baf5081 100644 --- a/configs/defconfig.common +++ b/configs/defconfig.common @@ -90,7 +90,6 @@ CONFIG_MBEDTLS_CAMELLIA_C=y CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y # CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN is not set CONFIG_MBEDTLS_SSL_PROTO_DTLS=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y CONFIG_OPENSSL_ASSERT_DO_NOTHING=y CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=2048 CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y From 2e3852231dfddc35cae7c9017713d8c95a1188b9 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Thu, 20 Mar 2025 23:25:22 -0300 Subject: [PATCH 45/45] Update CMakeLists.txt to use gnu++2a instead of 17 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1268b8e68..b79d85c0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,4 +39,4 @@ idf_build_set_property(COMPILE_DEFINITIONS "-DESP32_ARDUINO_LIB_BUILDER" APPEND) ################## ### ESP Matter ### ################## -idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-DCHIP_HAVE_CONFIG_H" APPEND) +idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++2a;-DCHIP_HAVE_CONFIG_H" APPEND)