diff --git a/.codespellrc b/.codespellrc index 4f3b1e3beed8..b664425f9c7d 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,4 +1,4 @@ [codespell] skip = build,*.yuv,components/fatfs/src/*,alice.txt,*.rgb,components/wpa_supplicant/*,components/esp_wifi/* -ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart +ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart,wheight,ot write-changes = true diff --git a/.gitignore b/.gitignore index b8a8909c3776..f70980b703f2 100644 --- a/.gitignore +++ b/.gitignore @@ -96,6 +96,8 @@ dependencies.lock managed_components # pytest log +pytest-embedded/ +# legacy one pytest_embedded_log/ list_job*.txt size_info*.txt diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index fc321c428782..b29aceb40500 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -2,239 +2,5 @@ # # https://docs.gitlab.com/ee/user/project/code_owners.html#the-syntax-of-code-owners-files # -# If more than one rule matches a given file, the latest rule is used. -# The file should be generally kept sorted, except when it is necessary -# to use a different order due to the fact above. In that case, use -# '# sort-order-reset' comment line to reset the sort order. -# -# Recipes for a few common cases: -# -# 1. Specific directory with all its contents: -# -# /components/app_trace/ -# -# Note the trailing slash! -# -# 2. File with certain extension in any subdirectory of a certain directory: -# -# /examples/**/*.py -# -# This includes an *.py files in /examples/ directory as well. -# -# 3. Contents of a directory with a certain name, anywhere in the tree: -# -# test_*_host/ -# -# Will match everything under components/efuse/test_efuse_host/, -# components/heap/test_multi_heap_host/, components/lwip/test_afl_host/, etc. -# -# 4. Same as above, except limited to a specific place in the tree: -# -# /components/esp32*/ -# -# Matches everything under /components/esp32, /components/esp32s2, etc. -# Doesn't match /tools/some-test/components/esp32s5. -# -# 5. Specific file: -# -# /tools/tools.json -# -# 6. File with a certain name anywhere in the tree -# -# .gitignore -# - -* @esp-idf-codeowners/other - -/.* @esp-idf-codeowners/tools -/.codespellrc @esp-idf-codeowners/ci -/.github/workflows/ @esp-idf-codeowners/ci -/.gitlab-ci.yml @esp-idf-codeowners/ci -/.gitlab/ci/ @esp-idf-codeowners/ci -/.pre-commit-config.yaml @esp-idf-codeowners/ci -/.readthedocs.yml @esp-idf-codeowners/docs -/.vale.ini @esp-idf-codeowners/docs -/CMakeLists.txt @esp-idf-codeowners/build-config -/COMPATIBILITY*.md @esp-idf-codeowners/peripherals -/CONTRIBUTING.md @esp-idf-codeowners/docs -/Kconfig @esp-idf-codeowners/build-config -/README*.md @esp-idf-codeowners/docs -/SUPPORT_POLICY*.md @esp-idf-codeowners/docs -/add_path.sh @esp-idf-codeowners/tools -/conftest.py @esp-idf-codeowners/ci -/export.* @esp-idf-codeowners/tools -/install.* @esp-idf-codeowners/tools -/pytest.ini @esp-idf-codeowners/ci -/sdkconfig.rename @esp-idf-codeowners/build-config -/sonar-project.properties @esp-idf-codeowners/ci - -# sort-order-reset - -/components/app_trace/ @esp-idf-codeowners/debugging -/components/app_update/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities -/components/bootloader*/ @esp-idf-codeowners/system @esp-idf-codeowners/security -/components/bootloader_support/bootloader_flash/ @esp-idf-codeowners/peripherals -/components/bt/ @esp-idf-codeowners/bluetooth -/components/cmock/ @esp-idf-codeowners/system -/components/console/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities/console -/components/cxx/ @esp-idf-codeowners/system -/components/driver/ @esp-idf-codeowners/peripherals -/components/efuse/ @esp-idf-codeowners/system -/components/esp_adc/ @esp-idf-codeowners/peripherals -/components/esp_app_format/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities -/components/esp_bootloader_format/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities -/components/esp_coex/ @esp-idf-codeowners/wifi @esp-idf-codeowners/bluetooth @esp-idf-codeowners/ieee802154 -/components/esp_common/ @esp-idf-codeowners/system -/components/esp_driver_*/ @esp-idf-codeowners/peripherals -/components/esp_driver_sdmmc/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/storage -/components/esp_eth/ @esp-idf-codeowners/network -/components/esp_event/ @esp-idf-codeowners/system -/components/esp_gdbstub/ @esp-idf-codeowners/debugging -/components/esp_hid/ @esp-idf-codeowners/bluetooth -/components/esp_http_client/ @esp-idf-codeowners/app-utilities -/components/esp_http_server/ @esp-idf-codeowners/app-utilities -/components/esp_https_ota/ @esp-idf-codeowners/app-utilities -/components/esp_https_server/ @esp-idf-codeowners/app-utilities -/components/esp_hw_support/ @esp-idf-codeowners/system @esp-idf-codeowners/peripherals -/components/esp_hw_support/lowpower/ @esp-idf-codeowners/power-management -/components/esp_lcd/ @esp-idf-codeowners/peripherals -/components/esp_local_ctrl/ @esp-idf-codeowners/app-utilities -/components/esp_mm/ @esp-idf-codeowners/peripherals -/components/esp_netif/ @esp-idf-codeowners/network -/components/esp_netif_stack/ @esp-idf-codeowners/network -/components/esp_partition/ @esp-idf-codeowners/storage -/components/esp_phy/ @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi @esp-idf-codeowners/ieee802154 -/components/esp_pm/ @esp-idf-codeowners/power-management @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi @esp-idf-codeowners/system -/components/esp_psram/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/system -/components/esp_ringbuf/ @esp-idf-codeowners/system -/components/esp_rom/ @esp-idf-codeowners/system @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi -/components/esp_system/ @esp-idf-codeowners/system -/components/esp_timer/ @esp-idf-codeowners/system -/components/esp-tls/ @esp-idf-codeowners/app-utilities -/components/esp_vfs_*/ @esp-idf-codeowners/storage -/components/esp_vfs_console/ @esp-idf-codeowners/storage @esp-idf-codeowners/system -/components/esp_wifi/ @esp-idf-codeowners/wifi -/components/espcoredump/ @esp-idf-codeowners/debugging -/components/esptool_py/ @esp-idf-codeowners/tools -/components/fatfs/ @esp-idf-codeowners/storage -/components/freertos/ @esp-idf-codeowners/system -/components/hal/ @esp-idf-codeowners/peripherals -/components/heap/ @esp-idf-codeowners/system -/components/http_parser/ @esp-idf-codeowners/app-utilities -/components/idf_test/ @esp-idf-codeowners/ci -/components/ieee802154/ @esp-idf-codeowners/ieee802154 -/components/json/ @esp-idf-codeowners/app-utilities -/components/linux/ @esp-idf-codeowners/system -/components/log/ @esp-idf-codeowners/system -/components/lwip/ @esp-idf-codeowners/lwip -/components/mbedtls/ @esp-idf-codeowners/app-utilities/mbedtls @esp-idf-codeowners/security -/components/mqtt/ @esp-idf-codeowners/network -/components/newlib/ @esp-idf-codeowners/system @esp-idf-codeowners/toolchain -/components/nvs_flash/ @esp-idf-codeowners/storage -/components/nvs_sec_provider/ @esp-idf-codeowners/storage @esp-idf-codeowners/security -/components/openthread/ @esp-idf-codeowners/ieee802154 -/components/partition_table/ @esp-idf-codeowners/system -/components/perfmon/ @esp-idf-codeowners/debugging -/components/protobuf-c/ @esp-idf-codeowners/app-utilities -/components/protocomm/ @esp-idf-codeowners/app-utilities/provisioning -/components/pthread/ @esp-idf-codeowners/system -/components/riscv/ @esp-idf-codeowners/system -/components/sdmmc/ @esp-idf-codeowners/storage -/components/soc/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/system -/components/spi_flash/ @esp-idf-codeowners/peripherals -/components/spiffs/ @esp-idf-codeowners/storage -/components/tcp_transport/ @esp-idf-codeowners/network -/components/touch_element/ @esp-idf-codeowners/peripherals -/components/ulp/ @esp-idf-codeowners/system -/components/unity/ @esp-idf-codeowners/ci -/components/usb/ @esp-idf-codeowners/peripherals/usb -/components/vfs/ @esp-idf-codeowners/storage -/components/wear_levelling/ @esp-idf-codeowners/storage -/components/wifi_provisioning/ @esp-idf-codeowners/app-utilities/provisioning -/components/wpa_supplicant/ @esp-idf-codeowners/wifi @esp-idf-codeowners/app-utilities/mbedtls -/components/xtensa/ @esp-idf-codeowners/system - -/docs/ @esp-idf-codeowners/docs -/docs/**/api-guides/tools/ @esp-idf-codeowners/tools -/docs/en/api-guides/core_dump.rst @esp-idf-codeowners/debugging -/docs/en/api-guides/jtag-debugging/ @esp-idf-codeowners/debugging -/docs/**/api-reference/bluetooth/ @esp-idf-codeowners/bluetooth -/docs/**/api-reference/network/ @esp-idf-codeowners/network @esp-idf-codeowners/wifi -/docs/**/api-reference/peripherals/ @esp-idf-codeowners/peripherals -/docs/**/api-reference/peripherals/usb* @esp-idf-codeowners/peripherals @esp-idf-codeowners/peripherals/usb -/docs/**/api-reference/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities -/docs/**/api-reference/provisioning/ @esp-idf-codeowners/app-utilities/provisioning -/docs/**/api-reference/storage/ @esp-idf-codeowners/storage -/docs/**/api-reference/system/ @esp-idf-codeowners/system -/docs/**/security/ @esp-idf-codeowners/security -/docs/**/migration-guides/ @esp-idf-codeowners/docs @esp-idf-codeowners/all-maintainers - -/examples/README.md @esp-idf-codeowners/docs @esp-idf-codeowners/ci -/examples/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools -/examples/bluetooth/ @esp-idf-codeowners/bluetooth -/examples/build_system/ @esp-idf-codeowners/build-config -/examples/common_components/ @esp-idf-codeowners/system @esp-idf-codeowners/wifi @esp-idf-codeowners/lwip @esp-idf-codeowners/network -/examples/custom_bootloader/ @esp-idf-codeowners/system -/examples/cxx/ @esp-idf-codeowners/system -/examples/ethernet/ @esp-idf-codeowners/network -/examples/get-started/ @esp-idf-codeowners/system -/examples/ieee802154/ @esp-idf-codeowners/ieee802154 -/examples/mesh/ @esp-idf-codeowners/wifi -/examples/network/ @esp-idf-codeowners/network @esp-idf-codeowners/wifi -/examples/openthread/ @esp-idf-codeowners/ieee802154 -/examples/peripherals/ @esp-idf-codeowners/peripherals -/examples/peripherals/usb/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/peripherals/usb -/examples/phy/ @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi @esp-idf-codeowners/ieee802154 -/examples/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities -/examples/provisioning/ @esp-idf-codeowners/app-utilities/provisioning -/examples/security/ @esp-idf-codeowners/security -/examples/storage/ @esp-idf-codeowners/storage -/examples/system/ @esp-idf-codeowners/system -/examples/system/ota/ @esp-idf-codeowners/app-utilities -/examples/wifi/ @esp-idf-codeowners/wifi -/examples/zigbee/ @esp-idf-codeowners/ieee802154 - -/tools/ @esp-idf-codeowners/tools -/tools/ble/ @esp-idf-codeowners/app-utilities -/tools/catch/ @esp-idf-codeowners/ci -/tools/ci/ @esp-idf-codeowners/ci -/tools/cmake/ @esp-idf-codeowners/build-config -/tools/cmake/toolchain-*.cmake @esp-idf-codeowners/toolchain -/tools/esp_app_trace/ @esp-idf-codeowners/debugging -/tools/esp_prov/ @esp-idf-codeowners/app-utilities -/tools/gdb_panic_server.py @esp-idf-codeowners/debugging -/tools/kconfig*/ @esp-idf-codeowners/build-config -/tools/ldgen/ @esp-idf-codeowners/build-config -/tools/mass_mfg/ @esp-idf-codeowners/app-utilities -/tools/mocks/ @esp-idf-codeowners/system - -/tools/test_apps/ @esp-idf-codeowners/ci -/tools/test_apps/README.md @esp-idf-codeowners/docs @esp-idf-codeowners/ci - -## Note: owners here should be the same as the owners for the same example subdir, above -/tools/test_apps/build_system/ @esp-idf-codeowners/build-config -/tools/test_apps/configs/ @esp-idf-codeowners/system -/tools/test_apps/linux_compatible/ @esp-idf-codeowners/system -/tools/test_apps/peripherals/ @esp-idf-codeowners/peripherals -/tools/test_apps/phy/ @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi @esp-idf-codeowners/ieee802154 -/tools/test_apps/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities -/tools/test_apps/security/ @esp-idf-codeowners/security -/tools/test_apps/storage/ @esp-idf-codeowners/storage -/tools/test_apps/system/ @esp-idf-codeowners/system - -/tools/test_apps/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools - -/tools/test_build_system/ @esp-idf-codeowners/tools @esp-idf-codeowners/build-config - -/tools/tools.json @esp-idf-codeowners/tools @esp-idf-codeowners/toolchain @esp-idf-codeowners/debugging - -/tools/unit-test-app/ @esp-idf-codeowners/system @esp-idf-codeowners/tools - -# sort-order-reset - -/components/**/test_apps/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools -# ignore lists -/tools/ci/check_copyright_config.yaml @esp-idf-codeowners/all-maintainers -/tools/ci/check_copyright_ignore.txt @esp-idf-codeowners/all-maintainers -/tools/ci/mypy_ignore_list.txt @esp-idf-codeowners/tools +* @esp-idf-codeowners/all-maintainers diff --git a/.gitlab/ci/common.yml b/.gitlab/ci/common.yml index b811b9c8e4e8..912f706da41b 100644 --- a/.gitlab/ci/common.yml +++ b/.gitlab/ci/common.yml @@ -39,7 +39,7 @@ variables: GIT_FETCH_EXTRA_FLAGS: "--no-recurse-submodules --prune --prune-tags" # we're using .cache folder for caches GIT_CLEAN_FLAGS: -ffdx -e .cache/ - LATEST_GIT_TAG: v5.3-dev + LATEST_GIT_TAG: v5.3.1 SUBMODULE_FETCH_TOOL: "tools/ci/ci_fetch_submodule.py" # by default we will fetch all submodules @@ -84,7 +84,7 @@ variables: CI_PYTHON_TOOL_BRANCH: "" # Set this variable to specify the file name for the known failure cases. - KNOWN_FAILURE_CASES_FILE_NAME: "master.txt" + KNOWN_FAILURE_CASES_FILE_NAME: "5.3.txt" IDF_CI_BUILD: 1 diff --git a/.gitlab/ci/host-test.yml b/.gitlab/ci/host-test.yml index edca658bd4df..741d47ea70c2 100644 --- a/.gitlab/ci/host-test.yml +++ b/.gitlab/ci/host-test.yml @@ -133,7 +133,7 @@ test_cli_installer: script: # Tools must be downloaded for testing # We could use "idf_tools.py download all", but we don't want to install clang because of its huge size - - python3 ${IDF_PATH}/tools/idf_tools.py download required qemu-riscv32 qemu-xtensa + - python3 ${IDF_PATH}/tools/idf_tools.py download required qemu-riscv32 qemu-xtensa cmake - cd ${IDF_PATH}/tools/test_idf_tools - python3 -m pip install jsonschema - python3 ./test_idf_tools.py -v @@ -228,6 +228,8 @@ test_tools: - pytest --noconftest test_idf_qemu.py --junitxml=${IDF_PATH}/XUNIT_IDF_PY_QEMU.xml || stat=1 - cd ${IDF_PATH}/tools/test_mkdfu - pytest --noconftest test_mkdfu.py --junitxml=${IDF_PATH}/XUNIT_MKDFU.xml || stat=1 + - cd ${IDF_PATH}/tools/test_idf_size + - pytest --noconftest test_idf_size.py --junitxml=${IDF_PATH}/XUNIT_IDF_SIZE.xml || stat=1 - cd ${IDF_PATH} - shellcheck -s sh tools/detect_python.sh || stat=1 - shellcheck -s bash tools/detect_python.sh || stat=1 @@ -296,7 +298,7 @@ test_pytest_qemu: artifacts: paths: - XUNIT_RESULT.xml - - pytest_embedded_log/ + - pytest-embedded/ reports: junit: XUNIT_RESULT.xml allow_failure: true # IDFCI-1752 @@ -330,7 +332,7 @@ test_pytest_linux: artifacts: paths: - XUNIT_RESULT.xml - - pytest_embedded_log/ + - pytest-embedded/ - "**/build*/build_log.txt" reports: junit: XUNIT_RESULT.xml diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index a49c5795a900..b492bdc60c8d 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -86,6 +86,7 @@ - "tools/test_idf_py/**/*" - "tools/idf_size.py" + - "tools/test_idf_size/**/*" - "tools/tools.json" - "tools/tools_schema.json" diff --git a/.gitlab/ci/test-win.yml b/.gitlab/ci/test-win.yml index 6949dda5ad36..42e24469333d 100644 --- a/.gitlab/ci/test-win.yml +++ b/.gitlab/ci/test-win.yml @@ -31,7 +31,7 @@ test_cli_installer_win: IDF_PATH: "$CI_PROJECT_DIR" script: # Tools must be downloaded for testing - - python ${IDF_PATH}\tools\idf_tools.py download required qemu-riscv32 qemu-xtensa + - python ${IDF_PATH}\tools\idf_tools.py download required qemu-riscv32 qemu-xtensa cmake - cd ${IDF_PATH}\tools\test_idf_tools - python -m pip install jsonschema - python .\test_idf_tools.py diff --git a/.gitmodules b/.gitmodules index 19beee5d3b6a..ee3fd858e0cc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -49,12 +49,13 @@ [submodule "components/json/cJSON"] path = components/json/cJSON url = ../../DaveGamble/cJSON.git - sbom-version = 1.7.17 + sbom-version = 1.7.18 sbom-cpe = cpe:2.3:a:cjson_project:cjson:{}:*:*:*:*:*:*:* sbom-supplier = Person: Dave Gamble sbom-url = https://github.com/DaveGamble/cJSON sbom-description = Ultralightweight JSON parser in ANSI C - sbom-hash = 87d8f0961a01bf09bef98ff89bae9fdec42181ee + sbom-hash = acc76239bee01d8e9c858ae2cab296704e52d916 + sbom-cve-exclude-list = CVE-2024-31755 Resolved in v1.7.18 [submodule "components/mbedtls/mbedtls"] path = components/mbedtls/mbedtls diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3d2ffe3385cd..92c9949680b5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -103,10 +103,10 @@ repos: name: Check type annotations in python files entry: tools/ci/check_type_comments.py additional_dependencies: - - 'mypy==0.940' - - 'mypy-extensions==0.4.3' - - 'types-setuptools==57.4.14' - - 'types-PyYAML==0.1.9' + - 'mypy' + - 'mypy-extensions' + - 'types-setuptools' + - 'types-PyYAML' - 'types-requests' exclude: > (?x)^( diff --git a/Kconfig b/Kconfig index 4330006c8972..743953656aea 100644 --- a/Kconfig +++ b/Kconfig @@ -75,10 +75,6 @@ mainmenu "Espressif IoT Development Framework Configuration" string default "$IDF_INIT_VERSION" - config IDF_TARGET_LINUX - bool - default "y" if IDF_TARGET="linux" - config IDF_TARGET_ESP32 bool default "y" if IDF_TARGET="esp32" @@ -607,6 +603,27 @@ mainmenu "Espressif IoT Development Framework Configuration" default "gcc" if COMPILER_RT_LIB_GCCLIB default "" if COMPILER_RT_LIB_HOST + choice COMPILER_ORPHAN_SECTIONS + prompt "Orphan sections handling" + default COMPILER_ORPHAN_SECTIONS_PLACE + depends on !IDF_TARGET_LINUX + help + If the linker finds orphan sections, it attempts to place orphan sections after sections of the same + attribute such as code vs data, loadable vs non-loadable, etc. + That means that orphan sections could placed between sections defined in IDF linker scripts. + This could lead to corruption of the binary image. Configure the linker action here. + + config COMPILER_ORPHAN_SECTIONS_WARNING + bool "Place with warning" + help + Places orphan sections without a warning message. + + config COMPILER_ORPHAN_SECTIONS_PLACE + bool "Place silently" + help + Places orphan sections without a warning/error message. + endchoice + endmenu # Compiler Options menu "Component config" diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index 52bba6c49870..9c03ccf16fe0 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -17,6 +17,7 @@ #include "esp_image_format.h" #include "esp_secure_boot.h" #include "esp_flash_encrypt.h" +#include "spi_flash_mmap.h" #include "sdkconfig.h" #include "esp_ota_ops.h" diff --git a/components/app_update/test_apps/.build-test-rules.yml b/components/app_update/test_apps/.build-test-rules.yml index 37751ed08bf8..8c365fcc5ee9 100644 --- a/components/app_update/test_apps/.build-test-rules.yml +++ b/components/app_update/test_apps/.build-test-rules.yml @@ -2,6 +2,6 @@ components/app_update/test_apps: disable: - - if: IDF_TARGET in ["esp32c6", "esp32h2", "esp32p4", "esp32c5"] + - if: IDF_TARGET in ["esp32c6", "esp32h2", "esp32c5"] temporary: true - reason: target esp32c6, esp32h2, esp32p4, esp32c5 is not supported yet # TODO: IDF-8068, [ESP32C5] IDF-8638 + reason: target esp32c6, esp32h2 esp32c5 is not supported yet # TODO: [ESP32C5] IDF-8638 diff --git a/components/app_update/test_apps/README.md b/components/app_update/test_apps/README.md index b5be4985c575..ace56d6d1995 100644 --- a/components/app_update/test_apps/README.md +++ b/components/app_update/test_apps/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/app_update/test_apps/pytest_app_update_ut.py b/components/app_update/test_apps/pytest_app_update_ut.py index 9ff51bb993b8..594bdbf2f339 100644 --- a/components/app_update/test_apps/pytest_app_update_ut.py +++ b/components/app_update/test_apps/pytest_app_update_ut.py @@ -19,7 +19,7 @@ def run_multiple_stages(dut: Dut, test_case_num: int, stages: int) -> None: @pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32c6', 'esp32h2', 'esp32p4'], reason='c6/h2/p4 support TBD') # TODO: IDF-8959 +@pytest.mark.temp_skip_ci(targets=['esp32c6', 'esp32h2'], reason='c6/h2 support TBD') @pytest.mark.generic def test_app_update(dut: Dut) -> None: extra_data = dut.parse_test_menu() diff --git a/components/bootloader/subproject/main/ld/esp32/bootloader.ld b/components/bootloader/subproject/main/ld/esp32/bootloader.ld index 5814b3e3cb61..d5fb575ddd5e 100644 --- a/components/bootloader/subproject/main/ld/esp32/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32/bootloader.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -119,6 +119,7 @@ SECTIONS .dram0.data : ALIGN(0x10) { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -144,6 +145,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -208,12 +210,55 @@ SECTIONS */ .xt.prop 0 : { - KEEP (*(.xt.prop .gnu.linkonce.prop.*)) + KEEP (*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) } .xt.lit 0 : { - KEEP (*(.xt.lit .gnu.linkonce.p.*)) + KEEP (*(.xt.lit .xt.lit.* .gnu.linkonce.p.*)) } + .xtensa.info 0: { *(.xtensa.info) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } } diff --git a/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld index a7cd5406965d..f80441cebbec 100644 --- a/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -140,6 +140,7 @@ SECTIONS .dram0.data : { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -165,6 +166,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -218,6 +220,57 @@ SECTIONS _etext = .; } > iram_seg + .riscv.attributes 0: { *(.riscv.attributes) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + /DISCARD/ : { *(.rela.*) } } /** diff --git a/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld index a444e680a794..21f19c14fe82 100644 --- a/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -140,6 +140,7 @@ SECTIONS .dram0.data : { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -165,6 +166,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -218,6 +220,58 @@ SECTIONS _etext = .; } > iram_seg + .riscv.attributes 0: { *(.riscv.attributes) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + /DISCARD/ : { *(.rela.*) } + } diff --git a/components/bootloader/subproject/main/ld/esp32c5/beta3/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c5/beta3/bootloader.ld index 00888b788fb3..a2c0ef52ed8c 100644 --- a/components/bootloader/subproject/main/ld/esp32c5/beta3/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c5/beta3/bootloader.ld @@ -139,6 +139,7 @@ SECTIONS .dram0.data : { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -164,6 +165,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -217,6 +219,58 @@ SECTIONS _etext = .; } > iram_seg + .riscv.attributes 0: { *(.riscv.attributes) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + /DISCARD/ : { *(.rela.*) } + } diff --git a/components/bootloader/subproject/main/ld/esp32c5/mp/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c5/mp/bootloader.ld index 5b9af6783e5c..e389464825c7 100644 --- a/components/bootloader/subproject/main/ld/esp32c5/mp/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c5/mp/bootloader.ld @@ -138,6 +138,7 @@ SECTIONS .dram0.data : { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -163,6 +164,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -216,6 +218,58 @@ SECTIONS _etext = .; } > iram_seg + .riscv.attributes 0: { *(.riscv.attributes) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + /DISCARD/ : { *(.rela.*) } + } diff --git a/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld index 3fc5861d850d..a9eb54247ce5 100644 --- a/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -138,6 +138,7 @@ SECTIONS .dram0.data : { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -163,6 +164,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -216,6 +218,58 @@ SECTIONS _etext = .; } > iram_seg + .riscv.attributes 0: { *(.riscv.attributes) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + /DISCARD/ : { *(.rela.*) } + } diff --git a/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld index 08e3d45c4ade..61bdd1bc2bed 100644 --- a/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld @@ -138,6 +138,7 @@ SECTIONS .dram0.data : { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -163,6 +164,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -216,6 +218,58 @@ SECTIONS _etext = .; } > iram_seg + .riscv.attributes 0: { *(.riscv.attributes) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + /DISCARD/ : { *(.rela.*) } + } diff --git a/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld b/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld index 2c40fece3d10..9ae2a74d8c24 100644 --- a/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -138,7 +138,7 @@ SECTIONS .dram0.data : { - _data_start = ABSOLUTE(.); + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -164,6 +164,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -217,6 +218,58 @@ SECTIONS _etext = .; } > iram_seg + .riscv.attributes 0: { *(.riscv.attributes) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + /DISCARD/ : { *(.rela.*) } + } /** diff --git a/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld b/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld index 348feb2a96a7..b73ae430f40f 100644 --- a/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -131,9 +131,15 @@ SECTIONS _bss_end = ABSOLUTE(.); } > dram_seg - .dram0.data : + .dram0.bootdesc : ALIGN(0x10) { _data_start = ABSOLUTE(.); + *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ + } > dram_seg + + .dram0.data : + { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -159,6 +165,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -212,6 +219,58 @@ SECTIONS _etext = .; } > iram_seg + .riscv.attributes 0: { *(.riscv.attributes) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + /DISCARD/ : { *(.rela.*) } + } diff --git a/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld b/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld index 394f1a3e51bd..f2c4ede304d1 100644 --- a/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -108,6 +108,7 @@ SECTIONS .dram0.data : { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -133,6 +134,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -205,4 +207,48 @@ SECTIONS KEEP (*(.xt.lit .gnu.linkonce.p.*)) } + .xtensa.info 0: { *(.xtensa.info) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + } diff --git a/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld b/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld index bdebbaf98195..c0f4702a018e 100644 --- a/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -142,6 +142,7 @@ SECTIONS .dram0.data : { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -167,6 +168,7 @@ SECTIONS *(.gcc_except_table) *(.gnu.linkonce.e.*) *(.gnu.version_r) + *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; /* C++ constructor and destructor tables, properly ordered: */ @@ -239,6 +241,50 @@ SECTIONS KEEP (*(.xt.lit .gnu.linkonce.p.*)) } + .xtensa.info 0: { *(.xtensa.info) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + } /** diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index b725995b1c98..22bcf0fb69cb 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -13,6 +13,9 @@ #include "hal/efuse_ll.h" #include "hal/efuse_hal.h" +#ifndef BOOTLOADER_BUILD +#include "spi_flash_mmap.h" +#endif #include "hal/spi_flash_ll.h" #include "rom/spi_flash.h" #if CONFIG_IDF_TARGET_ESP32 diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c index 2ac9b2d0e1b1..8766a908a5b2 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c @@ -22,7 +22,7 @@ #include "hal/cache_hal.h" #include "hal/cache_ll.h" -void bootloader_flash_update_id() +void IRAM_ATTR bootloader_flash_update_id() { esp_rom_spiflash_chip_t *chip = &rom_spiflash_legacy_data->chip; chip->device_id = bootloader_read_flash_id(); diff --git a/components/bootloader_support/include/bootloader_memory_utils.h b/components/bootloader_support/include/bootloader_memory_utils.h index bb81697a89f0..adbf72a275f2 100644 --- a/components/bootloader_support/include/bootloader_memory_utils.h +++ b/components/bootloader_support/include/bootloader_memory_utils.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,7 @@ #include #include "soc/soc.h" +#include "soc/ext_mem_defs.h" #include "soc/soc_caps.h" #include "sdkconfig.h" #include "esp_attr.h" @@ -179,6 +180,31 @@ inline static bool esp_ptr_in_tcm(const void *p) { #endif //#if SOC_MEM_TCM_SUPPORTED /** End of the common section that has to be in sync with esp_memory_utils.h **/ + +/** + * @brief Check if the pointer is in PSRAM vaddr space + * + * @note This function is only used when in bootloader, where the PSRAM isn't initialised. + * This function simply check if the pointer is the in the PSRAM vaddr space. + * The PSRAM vaddr space is not always the same as the actual PSRAM vaddr range used in APP + * + * @param p pointer + * + * @return true: is in PSRAM; false: not in PSRAM + */ +__attribute__((always_inline)) +inline static bool esp_ptr_in_extram(const void *p) { + bool valid = false; +#if SOC_IRAM_PSRAM_ADDRESS_LOW + valid |= ((intptr_t)p >= SOC_IRAM_PSRAM_ADDRESS_LOW && (intptr_t)p < SOC_IRAM_PSRAM_ADDRESS_HIGH); +#endif + +#if SOC_DRAM_PSRAM_ADDRESS_LOW + valid |= ((intptr_t)p >= SOC_DRAM_PSRAM_ADDRESS_LOW && (intptr_t)p < SOC_DRAM_PSRAM_ADDRESS_HIGH); +#endif + return valid; +} + /** Don't add new functions below **/ #ifdef __cplusplus diff --git a/components/bootloader_support/include/esp_flash_encrypt.h b/components/bootloader_support/include/esp_flash_encrypt.h index 7c09593ecc9f..6e495dbce06d 100644 --- a/components/bootloader_support/include/esp_flash_encrypt.h +++ b/components/bootloader_support/include/esp_flash_encrypt.h @@ -9,9 +9,6 @@ #include "esp_attr.h" #include "esp_err.h" #include "soc/soc_caps.h" -#ifndef BOOTLOADER_BUILD -#include "spi_flash_mmap.h" -#endif #include "hal/efuse_ll.h" #include "sdkconfig.h" diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index 28178594975d..e37a5b41c389 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/components/bootloader_support/src/bootloader_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,8 +37,8 @@ esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, ui esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio_level(uint32_t num_pin, uint32_t delay_sec, bool level) { esp_rom_gpio_pad_select_gpio(num_pin); - if (GPIO_PIN_MUX_REG[num_pin]) { - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[num_pin]); + if (((1ULL << num_pin) & SOC_GPIO_VALID_GPIO_MASK) != 0) { + gpio_ll_input_enable(&GPIO, num_pin); } esp_rom_gpio_pad_pullup_only(num_pin); uint32_t tm_start = esp_log_early_timestamp(); diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index 2408d0a093ca..66ee195a3b1c 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -13,7 +13,7 @@ #include "soc/gpio_periph.h" #include "soc/gpio_sig_map.h" #include "soc/rtc.h" -#include "hal/gpio_hal.h" +#include "hal/gpio_ll.h" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/usb/cdc_acm.h" #include "esp32s2/rom/usb/usb_common.h" @@ -63,17 +63,17 @@ void bootloader_console_init(void) uart_tx_gpio != UART_NUM_0_TXD_DIRECT_GPIO_NUM || uart_rx_gpio != UART_NUM_0_RXD_DIRECT_GPIO_NUM) { // Change default UART pins back to GPIOs - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[UART_NUM_0_RXD_DIRECT_GPIO_NUM], PIN_FUNC_GPIO); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[UART_NUM_0_TXD_DIRECT_GPIO_NUM], PIN_FUNC_GPIO); + gpio_ll_func_sel(&GPIO, UART_NUM_0_RXD_DIRECT_GPIO_NUM, PIN_FUNC_GPIO); + gpio_ll_func_sel(&GPIO, UART_NUM_0_TXD_DIRECT_GPIO_NUM, PIN_FUNC_GPIO); // Route GPIO signals to/from pins const uint32_t tx_idx = UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX); const uint32_t rx_idx = UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[uart_rx_gpio], PIN_FUNC_GPIO); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]); + gpio_ll_func_sel(&GPIO, uart_rx_gpio, PIN_FUNC_GPIO); + gpio_ll_input_enable(&GPIO, uart_rx_gpio); esp_rom_gpio_pad_pullup_only(uart_rx_gpio); esp_rom_gpio_connect_out_signal(uart_tx_gpio, tx_idx, 0, 0); esp_rom_gpio_connect_in_signal(uart_rx_gpio, rx_idx, 0); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[uart_tx_gpio], PIN_FUNC_GPIO); + gpio_ll_func_sel(&GPIO, uart_tx_gpio, PIN_FUNC_GPIO); // Enable the peripheral uart_ll_enable_bus_clock(uart_num, true); uart_ll_reset_register(uart_num); diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 49a096e66c6a..6289936986c5 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -14,7 +14,6 @@ #include "bootloader_random.h" #include "bootloader_clock.h" #include "bootloader_common.h" -#include "esp_flash_encrypt.h" #include "esp_cpu.h" #include "soc/rtc.h" #include "hal/wdt_hal.h" diff --git a/components/bootloader_support/src/bootloader_mem.c b/components/bootloader_support/src/bootloader_mem.c index e329d304050e..d9f8466a1c53 100644 --- a/components/bootloader_support/src/bootloader_mem.c +++ b/components/bootloader_support/src/bootloader_mem.c @@ -16,7 +16,7 @@ #include "hal/apm_hal.h" #endif -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION // TODO: IDF-8615 Remove the workaround when APM supported on C5! +#if CONFIG_IDF_TARGET_ESP32C5 // TODO: IDF-8615 Remove the workaround when APM supported on C5! #include "soc/hp_apm_reg.h" #include "soc/lp_apm_reg.h" #include "soc/lp_apm0_reg.h" @@ -33,10 +33,12 @@ void bootloader_init_mem(void) * So, at boot disabling these filters. They will enable as per the * use case by TEE initialization code. */ +#ifdef SOC_APM_CTRL_FILTER_SUPPORTED apm_hal_apm_ctrl_filter_enable_all(false); #endif +#endif -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION // TODO: IDF-8615 Remove the workaround when APM supported on C5! +#if CONFIG_IDF_TARGET_ESP32C5 // TODO: IDF-8615 Remove the workaround when APM supported on C5! // disable apm filter REG_WRITE(LP_APM_FUNC_CTRL_REG, 0); REG_WRITE(LP_APM0_FUNC_CTRL_REG, 0); diff --git a/components/bootloader_support/src/bootloader_random_esp32c6.c b/components/bootloader_support/src/bootloader_random_esp32c6.c index 682e48544c8c..fec85a6a404d 100644 --- a/components/bootloader_support/src/bootloader_random_esp32c6.c +++ b/components/bootloader_support/src/bootloader_random_esp32c6.c @@ -53,7 +53,7 @@ void bootloader_random_enable(void) // create patterns and set them in pattern table uint32_t pattern_one = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation - uint32_t pattern_two = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here + uint32_t pattern_two = (SAR2_CHANNEL << 2) | SAR1_ATTEN; // we want channel 9 with max attenuation uint32_t pattern_table = 0 | (pattern_two << 3 * PATTERN_BIT_WIDTH) | pattern_one << 2 * PATTERN_BIT_WIDTH; REG_WRITE(APB_SARADC_SAR_PATT_TAB1_REG, pattern_table); @@ -88,9 +88,6 @@ void bootloader_random_disable(void) REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 0); REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); - // Revert PMU_RF_PWC_REG to it's initial value - CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); - // disable ADC_CTRL_CLK (SAR ADC function clock) REG_WRITE(PCR_SARADC_CLKM_CONF_REG, 0x00404000); diff --git a/components/bootloader_support/src/bootloader_random_esp32p4.c b/components/bootloader_support/src/bootloader_random_esp32p4.c index 4d0552f16a2a..df88e8d7b22f 100644 --- a/components/bootloader_support/src/bootloader_random_esp32p4.c +++ b/components/bootloader_support/src/bootloader_random_esp32p4.c @@ -9,7 +9,7 @@ #include "soc/pmu_reg.h" #include "soc/regi2c_saradc.h" #include "soc/hp_sys_clkrst_reg.h" -#include "soc/rtcadc_reg.h" +#include "soc/lp_adc_reg.h" #include "esp_private/regi2c_ctrl.h" #include "esp_rom_regi2c.h" diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index 7aad0fa5b5a5..b28aa656aa9c 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -25,6 +25,7 @@ #include "soc/rtc_periph.h" #include "soc/timer_periph.h" #include "hal/mmu_hal.h" +#include "hal/mmu_ll.h" #include "hal/cache_types.h" #include "hal/cache_ll.h" #include "hal/cache_hal.h" @@ -34,6 +35,9 @@ #include "esp_app_desc.h" #include "esp_secure_boot.h" #include "esp_flash_encrypt.h" +#ifndef BOOTLOADER_BUILD +#include "spi_flash_mmap.h" +#endif #include "esp_flash_partitions.h" #include "bootloader_flash_priv.h" #include "bootloader_random.h" @@ -43,6 +47,7 @@ #include "bootloader_sha.h" #include "bootloader_console.h" #include "bootloader_soc.h" +#include "bootloader_memory_utils.h" #include "esp_efuse.h" #include "esp_fault.h" @@ -715,10 +720,20 @@ static void unpack_load_app(const esp_image_metadata_t *data) // Find DROM & IROM addresses, to configure MMU mappings for (int i = 0; i < data->image.segment_count; i++) { const esp_image_segment_header_t *header = &data->segments[i]; + bool text_or_rodata = false; + //`SOC_DROM_LOW` and `SOC_DROM_HIGH` are the same as `SOC_IROM_LOW` and `SOC_IROM_HIGH`, reasons are in above `note` if (header->load_addr >= SOC_DROM_LOW && header->load_addr < SOC_DROM_HIGH) { + text_or_rodata = true; + } +#if SOC_MMU_PER_EXT_MEM_TARGET + if (header->load_addr >= SOC_EXTRAM_LOW && header->load_addr < SOC_EXTRAM_HIGH) { + text_or_rodata = true; + } +#endif + if (text_or_rodata) { /** - * D/I are shared, but there should not be a third segment on flash + * D/I are shared, but there should not be a third segment on flash/psram */ assert(rom_index < 2); rom_addr[rom_index] = data->segment_data[i]; @@ -785,6 +800,20 @@ static void unpack_load_app(const esp_image_metadata_t *data) } #endif //#if SOC_MMU_DI_VADDR_SHARED +//unused for esp32 +__attribute__((unused)) +static bool s_flash_seg_needs_map(uint32_t vaddr) +{ +#if SOC_MMU_PER_EXT_MEM_TARGET + //For these chips, segments on PSRAM will be mapped in app + bool is_psram = esp_ptr_in_extram((void *)vaddr); + return !is_psram; +#else + //For these chips, segments on Flash always need to be mapped + return true; +#endif +} + static void set_cache_and_start_app( uint32_t drom_addr, uint32_t drom_load_addr, @@ -822,8 +851,13 @@ static void set_cache_and_start_app( ESP_EARLY_LOGV(TAG, "after mapping rodata, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, drom_load_addr_aligned, drom_page_count * SPI_FLASH_MMU_PAGE_SIZE); #else uint32_t actual_mapped_len = 0; - mmu_hal_map_region(0, MMU_TARGET_FLASH0, drom_load_addr_aligned, drom_addr_aligned, drom_size, &actual_mapped_len); - ESP_EARLY_LOGV(TAG, "after mapping rodata, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, drom_load_addr_aligned, actual_mapped_len); + if (s_flash_seg_needs_map(drom_load_addr_aligned)) { + mmu_hal_map_region(0, MMU_TARGET_FLASH0, drom_load_addr_aligned, drom_addr_aligned, drom_size, &actual_mapped_len); + ESP_EARLY_LOGV(TAG, "after mapping rodata, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, drom_load_addr_aligned, actual_mapped_len); + } + //we use the MMU_LL_END_DROM_ENTRY_ID mmu entry as a map page for app to find the boot partition + mmu_hal_map_region(0, MMU_TARGET_FLASH0, MMU_LL_END_DROM_ENTRY_VADDR, drom_addr_aligned, CONFIG_MMU_PAGE_SIZE, &actual_mapped_len); + ESP_EARLY_LOGV(TAG, "mapped one page of the rodata, from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, drom_load_addr_aligned, actual_mapped_len); #endif //-----------------------MAP IROM-------------------------- @@ -840,8 +874,10 @@ static void set_cache_and_start_app( ESP_LOGV(TAG, "rc=%d", rc); ESP_EARLY_LOGV(TAG, "after mapping text, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", irom_addr_aligned, irom_load_addr_aligned, irom_page_count * SPI_FLASH_MMU_PAGE_SIZE); #else - mmu_hal_map_region(0, MMU_TARGET_FLASH0, irom_load_addr_aligned, irom_addr_aligned, irom_size, &actual_mapped_len); - ESP_EARLY_LOGV(TAG, "after mapping text, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", irom_addr_aligned, irom_load_addr_aligned, actual_mapped_len); + if (s_flash_seg_needs_map(irom_load_addr_aligned)) { + mmu_hal_map_region(0, MMU_TARGET_FLASH0, irom_load_addr_aligned, irom_addr_aligned, irom_size, &actual_mapped_len); + ESP_EARLY_LOGV(TAG, "after mapping text, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", irom_addr_aligned, irom_load_addr_aligned, actual_mapped_len); + } #endif //----------------------Enable corresponding buses---------------- diff --git a/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c b/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c index 544fcd1ad43c..f04a92169867 100644 --- a/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c +++ b/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,6 +29,7 @@ #include "bootloader_flash_config.h" #include "bootloader_mem.h" #include "esp_private/regi2c_ctrl.h" +#include "soc/chip_revision.h" #include "soc/regi2c_lp_bias.h" #include "soc/regi2c_bias.h" #include "bootloader_console.h" @@ -90,14 +91,14 @@ static void bootloader_super_wdt_auto_feed(void) static inline void bootloader_hardware_init(void) { // regi2c is enabled by default on ESP32P4, do nothing - - // On ESP32P4 ECO0, the default (power on reset) CPLL and SPLL frequencies are very high, lower them to avoid bias may not be enough in bootloader - // And we are fixing SPLL to be 480MHz at all runtime - // Suppose to fix the issue on ECO1, will check when chip comes back - // TODO: IDF-8939 - REGI2C_WRITE_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, 6); // lower default cpu_pll freq to 400M - REGI2C_WRITE_MASK(I2C_SYSPLL, I2C_SYSPLL_OC_DIV_7_0, 8); // lower default sys_pll freq to 480M - esp_rom_delay_us(100); + unsigned chip_version = efuse_hal_chip_revision(); + if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) { + // On ESP32P4 ECO0, the default (power on reset) CPLL and SPLL frequencies are very high, lower them to avoid bias may not be enough in bootloader + // And we are fixing SPLL to be 480MHz after app is up + REGI2C_WRITE_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, 6); // lower default cpu_pll freq to 400M + REGI2C_WRITE_MASK(I2C_SYSPLL, I2C_SYSPLL_OC_DIV_7_0, 8); // lower default sys_pll freq to 480M + esp_rom_delay_us(100); + } REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1, 10); REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 10); } @@ -170,7 +171,7 @@ esp_err_t bootloader_init(void) } #endif // !CONFIG_APP_BUILD_TYPE_RAM - // check whether a WDT reset happend + // check whether a WDT reset happened bootloader_check_wdt_reset(); // config WDT bootloader_config_wdt(); diff --git a/components/bootloader_support/src/esp32p4/bootloader_soc.c b/components/bootloader_support/src/esp32p4/bootloader_soc.c index 2411bfe28f65..f64b88c9589f 100644 --- a/components/bootloader_support/src/esp32p4/bootloader_soc.c +++ b/components/bootloader_support/src/esp32p4/bootloader_soc.c @@ -1,9 +1,12 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include "soc/lp_analog_peri_reg.h" +#include "soc/soc.h" +#include "hal/brownout_ll.h" void bootloader_ana_super_wdt_reset_config(bool enable) { @@ -12,7 +15,9 @@ void bootloader_ana_super_wdt_reset_config(bool enable) void bootloader_ana_bod_reset_config(bool enable) { - //TODO: IDF-7514 + REG_CLR_BIT(LP_ANALOG_PERI_FIB_ENABLE_REG, LP_ANALOG_PERI_LP_ANA_FIB_BOD_RST); + + brownout_ll_ana_reset_enable(enable); } void bootloader_ana_clock_glitch_reset_config(bool enable) diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 03bb2b0f1ef9..60498bab4e04 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -771,8 +771,14 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header static bool should_map(uint32_t load_addr) { - return (load_addr >= SOC_IROM_LOW && load_addr < SOC_IROM_HIGH) - || (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH); + bool is_irom = (load_addr >= SOC_IROM_LOW) && (load_addr < SOC_IROM_HIGH); + bool is_drom = (load_addr >= SOC_DROM_LOW) && (load_addr < SOC_DROM_HIGH); + bool is_psram = false; +#if SOC_MMU_PER_EXT_MEM_TARGET + is_psram = (load_addr >= SOC_EXTRAM_LOW) && (load_addr < SOC_EXTRAM_HIGH); +#endif + + return (is_irom || is_drom || is_psram); } static bool should_load(uint32_t load_addr) @@ -857,7 +863,7 @@ static esp_err_t process_appended_hash_and_sig(esp_image_metadata_t *data, uint3 // Case I: Bootloader part if (part_offset == ESP_BOOTLOADER_OFFSET) { - // For bootloader with secure boot v1, signature stays in an independant flash + // For bootloader with secure boot v1, signature stays in an independent flash // sector (offset 0x0) and does not get appended to the image. #if CONFIG_SECURE_BOOT_V2_ENABLED // Sanity check - secure boot v2 signature block starts on 4K boundary diff --git a/components/bootloader_support/src/flash_encryption/flash_encrypt.c b/components/bootloader_support/src/flash_encryption/flash_encrypt.c index c1f6352311ba..85697dbeb3b3 100644 --- a/components/bootloader_support/src/flash_encryption/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encryption/flash_encrypt.c @@ -16,10 +16,15 @@ #include "esp_log.h" #include "hal/wdt_hal.h" -#if SOC_KEY_MANAGER_SUPPORTED -#include "hal/key_mgr_hal.h" +#if SOC_KEY_MANAGER_FE_KEY_DEPLOY || CONFIG_IDF_TARGET_ESP32C5 +#if CONFIG_IDF_TARGET_ESP32C5 #include "soc/keymng_reg.h" -#endif +#include "soc/pcr_reg.h" +#else /* CONFIG_IDF_TARGET_ESP32C5 */ +#include "hal/key_mgr_ll.h" +#include "hal/mspi_timing_tuning_ll.h" +#endif /* !CONFIG_IDF_TARGET_ESP32C5 */ +#endif /* SOC_KEY_MANAGER_FE_KEY_DEPLOY */ #ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK #include "soc/sensitive_reg.h" @@ -216,11 +221,25 @@ static esp_err_t check_and_generate_encryption_keys(void) ESP_LOGI(TAG, "Using pre-loaded flash encryption key in efuse"); } -#if SOC_KEY_MANAGER_SUPPORTED +#if SOC_KEY_MANAGER_FE_KEY_DEPLOY || CONFIG_IDF_TARGET_ESP32C5 +#if CONFIG_IDF_TARGET_ESP32C5 + REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, 2); + REG_SET_BIT(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); + REG_CLR_BIT(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); +#else /* CONFIG_IDF_TARGET_ESP32C5 */ + // Enable and reset key manager + // To suppress build errors about spinlock's __DECLARE_RCC_ATOMIC_ENV + int __DECLARE_RCC_ATOMIC_ENV __attribute__ ((unused)); + key_mgr_ll_enable_bus_clock(true); + key_mgr_ll_enable_peripheral_clock(true); + key_mgr_ll_reset_register(); + while (key_mgr_ll_get_state() != ESP_KEY_MGR_STATE_IDLE) { + }; // Force Key Manager to use eFuse key for XTS-AES operation - key_mgr_hal_set_key_usage(ESP_KEY_MGR_XTS_AES_128_KEY, ESP_KEY_MGR_USE_EFUSE_KEY); -#endif - + key_mgr_ll_set_key_usage(ESP_KEY_MGR_XTS_AES_128_KEY, ESP_KEY_MGR_USE_EFUSE_KEY); + _mspi_timing_ll_reset_mspi(); +#endif /* !CONFIG_IDF_TARGET_ESP32C5 */ +#endif /* SOC_KEY_MANAGER_FE_KEY_DEPLOY */ return ESP_OK; } @@ -263,13 +282,6 @@ esp_err_t esp_flash_encrypt_contents(void) esp_partition_info_t partition_table[ESP_PARTITION_TABLE_MAX_ENTRIES]; int num_partitions; -#if CONFIG_IDF_TARGET_ESP32C5 && SOC_KEY_MANAGER_SUPPORTED - // TODO: [ESP32C5] IDF-8622 find a more proper place for these codes - REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_FLASH); - REG_SET_BIT(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); - REG_CLR_BIT(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN); -#endif - #ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK REG_WRITE(SENSITIVE_XTS_AES_KEY_UPDATE_REG, 1); #endif @@ -421,7 +433,7 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit &partition->pos, &image_data); should_encrypt = (err == ESP_OK); -#ifdef SECURE_FLASH_ENCRYPT_ONLY_IMAGE_LEN_IN_APP_PART +#ifdef CONFIG_SECURE_FLASH_ENCRYPT_ONLY_IMAGE_LEN_IN_APP_PART if (should_encrypt) { // Encrypt only the app image instead of encrypting the whole partition size = image_data.image_len; diff --git a/components/bootloader_support/test_apps/rtc_custom_section/README.md b/components/bootloader_support/test_apps/rtc_custom_section/README.md index a79fcf4c5ea7..46d16c788ce9 100644 --- a/components/bootloader_support/test_apps/rtc_custom_section/README.md +++ b/components/bootloader_support/test_apps/rtc_custom_section/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index d32a6d372cbb..24e1517aa3ed 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -117,6 +117,7 @@ if(CONFIG_BT_ENABLED) common/btc/include common/include porting/mem/ + porting/include ) list(APPEND include_dirs ${common_include_dirs}) @@ -573,30 +574,51 @@ if(CONFIG_BT_ENABLED) if(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT) + list(APPEND srcs + "porting/npl/freertos/src/npl_os_freertos.c" + "porting/mem/os_msys_init.c" + "porting/transport/src/hci_transport.c" + ) + + if(CONFIG_BT_CONTROLLER_DISABLED) list(APPEND srcs - "porting/npl/freertos/src/npl_os_freertos.c" - "porting/nimble/src/os_msys_init.c" + "host/nimble/nimble/porting/nimble/src/hal_uart.c" ) - - if(CONFIG_BT_CONTROLLER_DISABLED) + elseif(CONFIG_BT_LE_HCI_INTERFACE_USE_RAM) + if(CONFIG_BT_NIMBLE_ENABLED) list(APPEND srcs - "host/nimble/nimble/porting/nimble/src/hal_uart.c" - ) + "porting/transport/driver/vhci/hci_driver_nimble.c" + "host/nimble/nimble/nimble/transport/esp_ipc/src/hci_esp_ipc.c" + ) + else() + list(APPEND srcs + "porting/transport/driver/vhci/hci_driver_standard.c" + ) endif() - list(APPEND include_dirs - porting/include - porting/nimble/include - porting/npl/freertos/include - porting/transport/include - ) - - if(CONFIG_BT_LE_HCI_INTERFACE_USE_UART) + elseif(CONFIG_BT_LE_HCI_INTERFACE_USE_UART) list(APPEND srcs - "porting/transport/uart/hci_uart.c" - ) + "porting/transport/driver/common/hci_driver_util.c" + "porting/transport/driver/common/hci_driver_h4.c" + "porting/transport/driver/common/hci_driver_mem.c" + "porting/transport/driver/uart/hci_driver_uart_config.c" + ) + if(CONFIG_BT_LE_UART_HCI_DMA_MODE) + list(APPEND srcs + "porting/transport/driver/uart/hci_driver_uart_dma.c" + ) + else() + list(APPEND srcs + "porting/transport/driver/uart/hci_driver_uart.c" + ) endif() - endif() + endif() + list(APPEND include_dirs + porting/include + porting/npl/freertos/include + porting/transport/include + ) + endif() if(NOT (CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS OR CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS)) list(APPEND include_dirs @@ -622,7 +644,6 @@ if(CONFIG_BT_ENABLED) if(CONFIG_BT_NIMBLE_ENABLED) list(APPEND include_dirs - host/nimble/nimble/nimble/host/include host/nimble/nimble/nimble/include host/nimble/nimble/nimble/host/services/ans/include @@ -726,11 +747,12 @@ if(CONFIG_BT_ENABLED) "host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c" "host/nimble/port/src/nvs_port.c" ) + list(APPEND include_dirs - porting/include host/nimble/nimble/porting/nimble/include host/nimble/port/include host/nimble/nimble/nimble/transport/include + host/nimble/nimble/nimble/include ) if(CONFIG_BT_CONTROLLER_DISABLED) @@ -756,15 +778,15 @@ if(CONFIG_BT_ENABLED) endif() list(APPEND include_dirs + porting/include host/nimble/nimble/porting/npl/freertos/include - host/nimble/nimble/porting/nimble/include - host/nimble/nimble/nimble/include ) endif() if(CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE AND CONFIG_BT_CONTROLLER_ENABLED) list(APPEND srcs "host/nimble/esp-hci/src/esp_nimble_hci.c" + "host/nimble/nimble/nimble/transport/esp_ipc_legacy/src/hci_esp_ipc_legacy.c" ) list(APPEND include_dirs ${nimble_hci_include_dirs}) endif() diff --git a/components/bt/common/hci_log/bt_hci_log.c b/components/bt/common/hci_log/bt_hci_log.c index 1cc95a46ce22..e35bf1a7a688 100644 --- a/components/bt/common/hci_log/bt_hci_log.c +++ b/components/bt/common/hci_log/bt_hci_log.c @@ -31,8 +31,8 @@ static const char s_hex_to_char_mapping[16] = { '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; -bt_hci_log_t g_bt_hci_log_data_ctl = {0}; -bt_hci_log_t g_bt_hci_log_adv_ctl = {0}; +static bt_hci_log_t g_bt_hci_log_data_ctl = {0}; +static bt_hci_log_t g_bt_hci_log_adv_ctl = {0}; esp_err_t bt_hci_log_init(void) { @@ -98,35 +98,35 @@ static char IRAM_ATTR *bt_data_type_to_str(uint8_t data_type) { case HCI_LOG_DATA_TYPE_COMMAND: // hci cmd data - tag = "CMD"; + tag = "C"; break; case HCI_LOG_DATA_TYPE_H2C_ACL: // host to controller hci acl data - tag = "HAL"; + tag = "H"; break; case HCI_LOG_DATA_TYPE_SCO: // hci sco data - tag = "SCO"; + tag = "S"; break; case HCI_LOG_DATA_TYPE_EVENT: // hci event - tag = "EVT"; + tag = "E"; break; case HCI_LOG_DATA_TYPE_ADV: // controller adv report data - tag = "ADV"; + tag = NULL; break; case HCI_LOG_DATA_TYPE_C2H_ACL: // controller to host hci acl data - tag = "CAL"; + tag = "D"; break; case HCI_LOG_DATA_TYPE_SELF_DEFINE: // self-defining data - tag = "ST"; + tag = "S"; break; default: // unknown data type - tag = "UK"; + tag = "U"; break; } diff --git a/components/bt/controller/esp32c2/Kconfig.in b/components/bt/controller/esp32c2/Kconfig.in index 9543582b9c4c..2ce4ca02500c 100644 --- a/components/bt/controller/esp32c2/Kconfig.in +++ b/components/bt/controller/esp32c2/Kconfig.in @@ -2,15 +2,15 @@ menu "HCI Config" choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice @@ -73,12 +73,26 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 512 help - Set the size of uart task stack + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 256 + help + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 1024 + help + This configures stack size of hci transport task endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -280,6 +294,24 @@ config BT_LE_CONTROLLER_LOG_DUMP_ONLY help Only operate in dump mode +config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + +config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + config BT_LE_LOG_CTRL_BUF1_SIZE int "size of the first BLE controller LOG buffer" depends on BT_LE_CONTROLLER_LOG_ENABLED @@ -349,7 +381,6 @@ config BT_LE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y depends on !BT_NIMBLE_ENABLED - select MBEDTLS_ECP_RESTARTABLE select MBEDTLS_CMAC_C help Enable this option to choose mbedTLS instead of TinyCrypt for crypto @@ -527,3 +558,62 @@ config BT_LE_ROLE_OBSERVER_ENABLE default y help Enable observer role function. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N24 + bool "-24dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N21 + bool "-21dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N18 + bool "-18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -24 if BT_LE_DFT_TX_POWER_LEVEL_N24 + default -21 if BT_LE_DFT_TX_POWER_LEVEL_N21 + default -18 if BT_LE_DFT_TX_POWER_LEVEL_N18 + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 38ae519a56d6..9f158e84c43e 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -16,7 +16,10 @@ #include "sdkconfig.h" +#if CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port.h" +#endif // CONFIG_BT_NIMBLE_ENABLED + #include "nimble/nimble_port_freertos.h" #ifdef ESP_PLATFORM @@ -28,7 +31,7 @@ #endif #include "nimble/nimble_npl_os.h" -#include "nimble/ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" @@ -41,13 +44,8 @@ #include "soc/syscon_reg.h" #include "soc/modem_clkrst_reg.h" #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" #include "bt_osi_mem.h" -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif - #if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_private/sleep_modem.h" #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE @@ -64,6 +62,7 @@ #include "hal/efuse_ll.h" #include "soc/rtc.h" + /* Macro definition ************************************************************************ */ @@ -76,12 +75,6 @@ #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf - -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif // CONFIG_BT_BLUEDROID_ENABLED - typedef enum ble_rtc_slow_clk_src { BT_SLOW_CLK_SRC_MAIN_XTAL, BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0, @@ -105,12 +98,12 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); + void (*_rsv1)(int); + int (*_rsv2)(int, int (*)(void *arg), int (*)(void *arg, uint8_t byte), int (*)(void *arg, uint8_t byte), void *); + int (*_rsv3)(int, int32_t, uint8_t, uint8_t, int, int); + int (*_rsv4)(int); + void (*_rsv5)(int, uint8_t); + int (*_rsv6)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); void (*_osi_assert)(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2); @@ -188,16 +181,6 @@ static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status); static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); @@ -209,15 +192,248 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; - #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +enum log_out_mode { + LOG_DUMP_MEMORY, + LOG_ASYNC_OUT, + LOG_STORAGE_TO_FLASH, +}; + +bool log_is_inited = false; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY +uint8_t log_output_mode = LOG_DUMP_MEMORY; +#else +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; +#else +uint8_t log_output_mode = LOG_ASYNC_OUT; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + +void esp_bt_log_output_mode_set(uint8_t output_mode) +{ + log_output_mode = output_mode; +} + +uint8_t esp_bt_log_output_mode_get(void) +{ + return log_output_mode; +} + +esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) +{ + esp_err_t ret = ESP_OK; + interface_func_t bt_controller_log_interface; + bt_controller_log_interface = esp_bt_controller_log_interface; + bool task_create; + uint8_t buffers = 0; + + if (log_is_inited) { + return ret; + } + +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + switch (log_output_mode) { + case LOG_DUMP_MEMORY: + task_create = false; + break; + case LOG_ASYNC_OUT: + case LOG_STORAGE_TO_FLASH: + task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + if (log_output_mode == LOG_STORAGE_TO_FLASH) { + esp_bt_ctrl_log_partition_get_and_erase_first_block(); + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + break; + default: + assert(0); + } + + ret = ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); + if (ret == ESP_OK) { + log_is_inited = true; + } + + return ret; +} + +void esp_bt_ontroller_log_deinit(void) +{ + ble_log_deinit_async(); + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + assert(log_partition != NULL); + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + ble_log_async_output_dump_all(true); + stop_write = true; + esp_bt_ontroller_log_deinit(); + portEXIT_CRITICAL_SAFE(&spinlock); + + buffer = (const uint8_t *)mapped_ptr; + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + vTaskDelay(2); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + esp_rom_printf(":DUMP_END]\r\n"); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(log_output_mode); + assert(err == ESP_OK); + +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +{ + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); + } + + if (end) { + esp_rom_printf("\n"); + } + } +} + +void esp_ble_controller_log_dump_all(bool output) +{ + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + BT_ASSERT_PRINT("\r\n[DUMP_START:"); + ble_log_async_output_dump_all(output); + BT_ASSERT_PRINT(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + } +} #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* This variable tells if BLE is running */ @@ -229,7 +445,6 @@ static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #define BLE_RTC_DELAY_US (1800) - static const struct osi_coex_funcs_t s_osi_coex_funcs_ro = { ._magic = OSI_COEX_MAGIC_VALUE, ._version = OSI_COEX_VERSION, @@ -245,14 +460,6 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, @@ -299,83 +506,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) #endif // CONFIG_SW_COEXIST_ENABLE } -#ifdef CONFIG_BT_BLUEDROID_ENABLED -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -/** - * Allocates an mbuf for use by the nimble host. - */ -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -/** - * Allocates an mbuf suitable for an HCI ACL data packet. - * - * @return An empty mbuf on success; null on memory - * exhaustion. - */ -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - assert(cmd); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < CONFIG_FREERTOS_NUMBER_OF_CORES ? core_id : tskNO_AFFINITY)); @@ -405,56 +535,6 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits,uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - return rc; -} - -static int hci_uart_close_wrapper(int uart_no) -{ - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; -} - -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) -{ - //This function is nowhere to use. -} - -static int hci_uart_init_wrapper(int uart_no, void *cfg) -{ - //This function is nowhere to use. - return 0; -} - -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; -} - static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, arg, (intr_handle_t *)ret_handle_in); @@ -632,6 +712,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; ble_rtc_slow_clk_src_t rtc_clk_src; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { @@ -719,20 +800,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble rom commit:[%s]", r_ble_controller_get_rom_compile_version()); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - uint8_t buffers = 0; -#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED - buffers |= ESP_BLE_LOG_BUF_CONTROLLER; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - buffers |= ESP_BLE_LOG_BUF_HCI; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - ret = ble_log_init_async(bt_controller_log_interface, false, buffers, (uint32_t *)log_bufs_size); -#else - ret = ble_log_init_async(bt_controller_log_interface, true, buffers, (uint32_t *)log_bufs_size); -#endif // CONFIG_BT_CONTROLLER_LOG_DUMP + ret = esp_bt_controller_log_init(log_output_mode); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto controller_init_err; @@ -754,14 +822,23 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED controller_init_err: - ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED ble_controller_deinit(); modem_deint: @@ -786,10 +863,11 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED ble_controller_deinit(); @@ -1139,30 +1217,6 @@ uint8_t esp_ble_get_chip_rev_version(void) return efuse_ll_get_chip_wafer_version_minor(); } -#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) -{ - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); - } - if (end) { - esp_rom_printf("\n"); - } -} - -void esp_ble_controller_log_dump_all(bool output) -{ - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_reconfigure_wdts(5000); - BT_ASSERT_PRINT("\r\n[DUMP_START:"); - ble_log_async_output_dump_all(output); - BT_ASSERT_PRINT(":DUMP_END]\r\n"); - portEXIT_CRITICAL_SAFE(&spinlock); -} -#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - #if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) #if CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #define BLE_SM_KEY_ERR 0x17 diff --git a/components/bt/controller/esp32c2/esp_bt_cfg.h b/components/bt/controller/esp32c2/esp_bt_cfg.h index 0cb4168e0302..456ddcf9a859 100644 --- a/components/bt/controller/esp32c2/esp_bt_cfg.h +++ b/components/bt/controller/esp32c2/esp_bt_cfg.h @@ -28,7 +28,6 @@ extern "C" { #else #define BLE_LL_SCAN_PHY_NUMBER_N (1) #endif - #define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST) #define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS) #define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS) @@ -152,6 +151,20 @@ extern "C" { #else #define DEFAULT_BT_LE_ROLE_OBSERVER (0) #endif + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif #endif #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF @@ -192,8 +205,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -202,8 +213,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -232,7 +241,7 @@ extern "C" { #define RTC_FREQ_N (32000) /* in Hz */ #endif // CONFIG_XTAL_FREQ_26 -#define BLE_LL_TX_PWR_DBM_N (9) +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index e053cfdf40ee..0a461d071fbf 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -115,7 +115,7 @@ do{\ } while(0) #define OSI_FUNCS_TIME_BLOCKING 0xffffffff -#define OSI_VERSION 0x00010008 +#define OSI_VERSION 0x00010009 #define OSI_MAGIC_VALUE 0xFADEBEAD /* Types definition @@ -142,15 +142,24 @@ typedef struct { typedef void (* osi_intr_handler)(void); +typedef struct { + int source; /*!< ISR source */ + int flags; /*!< ISR alloc flag */ + void (*fn)(void *); /*!< ISR function */ + void *arg; /*!< ISR function args*/ + intr_handle_t *handle; /*!< ISR handle */ + esp_err_t ret; +} btdm_isr_alloc_t; + /* OSI function */ struct osi_funcs_t { uint32_t _magic; uint32_t _version; - void (*_interrupt_set)(int cpu_no, int intr_source, int interrupt_no, int interrpt_prio); - void (*_interrupt_clear)(int interrupt_source, int interrupt_no); - void (*_interrupt_handler_set)(int interrupt_no, intr_handler_t fn, void *arg); - void (*_interrupt_disable)(void); - void (*_interrupt_restore)(void); + int (* _interrupt_alloc)(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle); + int (* _interrupt_free)(void *handle); + void (*_interrupt_handler_set_rsv)(int interrupt_no, intr_handler_t fn, void *arg); + void (*_global_intr_disable)(void); + void (*_global_intr_restore)(void); void (*_task_yield)(void); void (*_task_yield_from_isr)(void); void *(*_semphr_create)(uint32_t max, uint32_t init); @@ -195,8 +204,8 @@ struct osi_funcs_t { uint32_t (* _coex_schm_interval_get)(void); uint8_t (* _coex_schm_curr_period_get)(void); void *(* _coex_schm_curr_phase_get)(void); - void (* _interrupt_on)(int intr_num); - void (* _interrupt_off)(int intr_num); + int (* _interrupt_enable)(void *handle); + int (* _interrupt_disable)(void *handle); void (* _esp_hw_power_down)(void); void (* _esp_hw_power_up)(void); void (* _ets_backup_dma_copy)(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_rem); @@ -277,11 +286,10 @@ extern uint32_t _bt_controller_data_end; /* Local Function Declare ********************************************************************* */ -static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio); -static void interrupt_clear_wrapper(int intr_source, int intr_num); -static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg); -static void interrupt_disable(void); -static void interrupt_restore(void); +static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle); +static int interrupt_free_wrapper(void *handle); +static void global_interrupt_disable(void); +static void global_interrupt_restore(void); static void task_yield_from_isr(void); static void *semphr_create_wrapper(uint32_t max, uint32_t init); static void semphr_delete_wrapper(void *semphr); @@ -319,8 +327,8 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static uint32_t coex_schm_interval_get_wrapper(void); static uint8_t coex_schm_curr_period_get_wrapper(void); static void * coex_schm_curr_phase_get_wrapper(void); -static void interrupt_on_wrapper(int intr_num); -static void interrupt_off_wrapper(int intr_num); +static int interrupt_enable_wrapper(void *handle); +static int interrupt_disable_wrapper(void *handle); static void btdm_hw_mac_power_up_wrapper(void); static void btdm_hw_mac_power_down_wrapper(void); static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem); @@ -341,11 +349,11 @@ static void bt_controller_deinit_internal(void); static const struct osi_funcs_t osi_funcs_ro = { ._magic = OSI_MAGIC_VALUE, ._version = OSI_VERSION, - ._interrupt_set = interrupt_set_wrapper, - ._interrupt_clear = interrupt_clear_wrapper, - ._interrupt_handler_set = interrupt_handler_set_wrapper, - ._interrupt_disable = interrupt_disable, - ._interrupt_restore = interrupt_restore, + ._interrupt_alloc = interrupt_alloc_wrapper, + ._interrupt_free = interrupt_free_wrapper, + ._interrupt_handler_set_rsv = NULL, + ._global_intr_disable = global_interrupt_disable, + ._global_intr_restore = global_interrupt_restore, ._task_yield = vPortYield, ._task_yield_from_isr = task_yield_from_isr, ._semphr_create = semphr_create_wrapper, @@ -390,8 +398,8 @@ static const struct osi_funcs_t osi_funcs_ro = { ._coex_schm_interval_get = coex_schm_interval_get_wrapper, ._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper, ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, - ._interrupt_on = interrupt_on_wrapper, - ._interrupt_off = interrupt_off_wrapper, + ._interrupt_enable = interrupt_enable_wrapper, + ._interrupt_disable = interrupt_disable_wrapper, ._esp_hw_power_down = btdm_hw_mac_power_down_wrapper, ._esp_hw_power_up = btdm_hw_mac_power_up_wrapper, ._ets_backup_dma_copy = btdm_backup_dma_copy_wrapper, @@ -478,35 +486,44 @@ static inline void esp_bt_power_domain_off(void) esp_wifi_bt_power_domain_off(); } -static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio) +static void btdm_intr_alloc(void *arg) { - esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num); -#if __riscv - esprv_int_set_priority(intr_num, intr_prio); - esprv_int_set_type(intr_num, 0); -#endif + btdm_isr_alloc_t *p = arg; + p->ret = esp_intr_alloc(p->source, p->flags, p->fn, p->arg, p->handle); } -static void interrupt_clear_wrapper(int intr_source, int intr_num) +static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle) { + btdm_isr_alloc_t p; + p.source = source; + p.flags = ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM; + p.fn = handler; + p.arg = arg; + p.handle = (intr_handle_t *)ret_handle; +#if CONFIG_FREERTOS_UNICORE + btdm_intr_alloc(&p); +#else + esp_ipc_call_blocking(cpu_id, btdm_intr_alloc, &p); +#endif + return p.ret; } -static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg) +static int interrupt_free_wrapper(void *handle) { - esp_cpu_intr_set_handler(n, fn, arg); + return esp_intr_free((intr_handle_t)handle); } -static void interrupt_on_wrapper(int intr_num) +static int interrupt_enable_wrapper(void *handle) { - esp_cpu_intr_enable(1 << intr_num); + return esp_intr_enable((intr_handle_t)handle); } -static void interrupt_off_wrapper(int intr_num) +static int interrupt_disable_wrapper(void *handle) { - esp_cpu_intr_disable(1<om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - assert(cmd); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED - static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { @@ -384,56 +284,6 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits, uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - return rc; -} - -static int hci_uart_close_wrapper(int uart_no) -{ - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; -} - -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) -{ - //This function is nowhere to use. -} - -static int hci_uart_init_wrapper(int uart_no, void *cfg) -{ - //This function is nowhere to use. - return 0; -} - -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; -} - static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { @@ -690,6 +540,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; uint32_t slow_clk_freq = 0; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); @@ -723,7 +574,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_mem; } - ble_get_npl_element_info(cfg, &npl_info); + r_ble_get_npl_element_info(cfg, &npl_info); npl_freertos_set_controller_npl_info(&npl_info); if (npl_freertos_mempool_init() != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "npl mempool init failed"); @@ -780,13 +631,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) coex_init(); #endif // CONFIG_SW_COEXIST_ENABLE - ret = ble_controller_init(cfg); - if (ret != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_init failed %d", ret); - goto modem_deint; - } - - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED interface_func_t bt_controller_log_interface; bt_controller_log_interface = esp_bt_controller_log_interface; @@ -804,11 +648,23 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif // CONFIG_BT_CONTROLLER_LOG_DUMP if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); - goto controller_init_err; + goto modem_deint; } #endif // CONFIG_BT_CONTROLLER_LOG_ENABLED + ret = esp_ble_register_bb_funcs(); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "esp_ble_register_bb_funcs failed %d", ret); + goto modem_deint; + } - esp_ble_change_rtc_freq(slow_clk_freq); + ret = r_ble_controller_init(cfg); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "r_ble_controller_init failed %d", ret); + goto modem_deint; + } + + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); + r_esp_ble_change_rtc_freq(slow_clk_freq); ble_controller_scan_duplicate_config(); @@ -825,23 +681,32 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) } ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); swap_in_place(mac, 6); - esp_ble_ll_set_public_addr(mac); + r_esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); - return ESP_OK; +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } + return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); + os_msys_deinit(); + r_ble_controller_deinit(); +modem_deint: + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -controller_init_err: r_ble_log_deinit_async(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - os_msys_deinit(); - ble_controller_deinit(); -modem_deint: esp_phy_modem_deinit(); // modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); @@ -864,6 +729,7 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); @@ -872,10 +738,11 @@ esp_err_t esp_bt_controller_deinit(void) // modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); + r_ble_controller_deinit(); + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED r_ble_log_deinit_async(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_controller_deinit(); #if CONFIG_BT_NIMBLE_ENABLED /* De-initialize default event queue */ @@ -920,7 +787,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) coex_enable(); #endif // CONFIG_SW_COEXIST_ENABLE - if (ble_controller_enable(mode) != 0) { + if (r_ble_controller_enable(mode) != 0) { ret = ESP_FAIL; goto error; } @@ -948,7 +815,7 @@ esp_err_t esp_bt_controller_disable(void) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_FAIL; } - if (ble_controller_disable() != 0) { + if (r_ble_controller_disable() != 0) { return ESP_FAIL; } #if CONFIG_SW_COEXIST_ENABLE @@ -1082,7 +949,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_DEFAULT: case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1095,7 +962,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { stat = ESP_OK; } break; @@ -1115,13 +982,13 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - if (ble_txpwr_set(power_type, handle, power_level) == 0) { + if (r_ble_txpwr_set(power_type, handle, power_level) == 0) { stat = ESP_OK; } break; @@ -1141,7 +1008,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: case ESP_BLE_PWR_TYPE_DEFAULT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_PWR_TYPE_CONN_HDL0: case ESP_BLE_PWR_TYPE_CONN_HDL1: @@ -1152,7 +1019,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); break; default: return ESP_PWR_LVL_INVALID; @@ -1174,11 +1041,11 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - tx_level = ble_txpwr_get(power_type, handle); + tx_level = r_ble_txpwr_get(power_type, handle); break; default: return ESP_PWR_LVL_INVALID; diff --git a/components/bt/controller/esp32c5/esp_bt_cfg.h b/components/bt/controller/esp32c5/esp_bt_cfg.h index b9597034fc63..b8bbfd3d4b7c 100644 --- a/components/bt/controller/esp32c5/esp_bt_cfg.h +++ b/components/bt/controller/esp32c5/esp_bt_cfg.h @@ -129,6 +129,21 @@ extern "C" { #else #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) #endif + + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif #endif #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF @@ -169,8 +184,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -179,8 +192,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ diff --git a/components/bt/controller/esp32c6/Kconfig.in b/components/bt/controller/esp32c6/Kconfig.in index 94721bbf08a5..07089db18e28 100644 --- a/components/bt/controller/esp32c6/Kconfig.in +++ b/components/bt/controller/esp32c6/Kconfig.in @@ -2,19 +2,37 @@ menu "HCI Config" choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice + choice BT_LE_UART_HCI_MODE_CHOICE + prompt "UART HCI mode" + depends on BT_LE_HCI_INTERFACE_USE_UART + default BT_LE_UART_HCI_NO_DMA_MODE + help + Specify UART HCI mode: DMA or No DMA + + config BT_LE_UART_HCI_DMA_MODE + bool "UHCI(UART with DMA)(EXPERIMENTAL)" + help + UART HCI Mode with DMA functionality. + + config BT_LE_UART_HCI_NO_DMA_MODE + bool "UART(NO DMA)" + help + UART HCI Mode without DMA functionality. + endchoice + config BT_LE_HCI_UART_PORT int "HCI UART port" depends on BT_LE_HCI_INTERFACE_USE_UART @@ -73,12 +91,40 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 512 + help + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 256 help - Set the size of uart task stack + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 1024 + help + This configures stack size of hci transport task + + config BT_LE_HCI_TRANS_RX_MEM_NUM + int "The amount of rx memory received at the same time" + depends on BT_LE_UART_HCI_DMA_MODE + default 3 + help + The amount of rx memory received at the same time + + config BT_LE_HCI_LLDESCS_POOL_NUM + int "The amount of lldecs memory for driver dma mode" + depends on BT_LE_UART_HCI_DMA_MODE + default 20 + help + The amount of lldecs memory for driver dma mode endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -296,6 +342,24 @@ config BT_LE_CONTROLLER_LOG_DUMP_ONLY help Only operate in dump mode +config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + +config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + config BT_LE_LOG_CTRL_BUF1_SIZE int "size of the first BLE controller LOG buffer" depends on BT_LE_CONTROLLER_LOG_ENABLED @@ -365,7 +429,6 @@ config BT_LE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y depends on !BT_NIMBLE_ENABLED - select MBEDTLS_ECP_RESTARTABLE select MBEDTLS_CMAC_C help Enable this option to choose mbedTLS instead of TinyCrypt for crypto @@ -576,3 +639,53 @@ config BT_LE_CCA_RSSI_THRESH default 20 help Power threshold of CCA in unit of -1 dBm. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index ed005edc70d6..2346cf0b3b83 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -15,7 +15,9 @@ #include "sdkconfig.h" +#if CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port.h" +#endif // CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port_freertos.h" #include "esp_private/esp_modem_clock.h" @@ -28,7 +30,7 @@ #endif // CONFIG_ESP_COEX_ENABLED #include "nimble/nimble_npl_os.h" -#include "nimble/ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" @@ -39,7 +41,6 @@ #include "esp_phy_init.h" #endif #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" #include "bt_osi_mem.h" #if SOC_PM_RETENTION_HAS_CLOCK_BUG @@ -50,10 +51,6 @@ #include "esp_private/sleep_modem.h" #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif // CONFIG_BT_BLUEDROID_ENABLED - #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -69,16 +66,11 @@ #define OSI_COEX_VERSION 0x00010006 #define OSI_COEX_MAGIC_VALUE 0xFADEBEAD -#define EXT_FUNC_VERSION 0x20221122 +#define EXT_FUNC_VERSION 0x20240422 #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif // CONFIG_BT_BLUEDROID_ENABLED - /* Types definition ************************************************************************ */ @@ -97,12 +89,6 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); @@ -123,7 +109,7 @@ typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); ************************************************************************ */ extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); -extern int ble_controller_init(esp_bt_controller_config_t *cfg); +extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int r_ble_log_deinit_async(void); @@ -131,12 +117,12 @@ extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); extern void r_ble_log_async_output_dump_all(bool output); extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int ble_controller_deinit(void); -extern int ble_controller_enable(uint8_t mode); -extern int ble_controller_disable(void); +extern int r_ble_controller_deinit(void); +extern int r_ble_controller_enable(uint8_t mode); +extern int r_ble_controller_disable(void); extern int esp_register_ext_funcs (struct ext_funcs_t *); extern void esp_unregister_ext_funcs (void); -extern int esp_ble_ll_set_public_addr(const uint8_t *addr); +extern int r_esp_ble_ll_set_public_addr(const uint8_t *addr); extern int esp_register_npl_funcs (struct npl_funcs_t *p_npl_func); extern void esp_unregister_npl_funcs (void); extern void npl_freertos_mempool_deinit(void); @@ -149,17 +135,19 @@ extern int os_msys_init(void); extern void os_msys_deinit(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); -extern void esp_ble_set_wakeup_overhead(uint32_t overhead); +extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ -extern void esp_ble_change_rtc_freq(uint32_t freq); +extern void r_esp_ble_change_rtc_freq(uint32_t freq); extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); extern int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); -extern int ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t handle, int power_level); -extern int ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); +extern int r_ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t handle, int power_level); +extern int r_ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle); +extern int r_ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); extern char *ble_controller_get_compile_version(void); +extern int esp_ble_register_bb_funcs(void); +extern void esp_ble_unregister_bb_funcs(void); extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; extern uint32_t _bt_controller_bss_start; @@ -177,16 +165,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); @@ -198,15 +176,215 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; - #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +enum log_out_mode { + LOG_DUMP_MEMORY, + LOG_ASYNC_OUT, + LOG_STORAGE_TO_FLASH, +}; + +bool log_is_inited = false; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY +uint8_t log_output_mode = LOG_DUMP_MEMORY; +#else +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; +#else +uint8_t log_output_mode = LOG_ASYNC_OUT; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + +void esp_bt_log_output_mode_set(uint8_t output_mode) +{ + log_output_mode = output_mode; +} + +uint8_t esp_bt_log_output_mode_get(void) +{ + return log_output_mode; +} + +esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) +{ + esp_err_t ret = ESP_OK; + interface_func_t bt_controller_log_interface; + bt_controller_log_interface = esp_bt_controller_log_interface; + bool task_create; + uint8_t buffers = 0; + + if (log_is_inited) { + return ret; + } + +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + switch (log_output_mode) { + case LOG_DUMP_MEMORY: + task_create = false; + break; + case LOG_ASYNC_OUT: + case LOG_STORAGE_TO_FLASH: + task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + if (log_output_mode == LOG_STORAGE_TO_FLASH) { + esp_bt_ctrl_log_partition_get_and_erase_first_block(); + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + break; + default: + assert(0); + } + + ret = r_ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); + if (ret == ESP_OK) { + log_is_inited = true; + } + + return ret; +} + +void esp_bt_ontroller_log_deinit(void) +{ + r_ble_log_deinit_async(); + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + r_ble_log_async_output_dump_all(true); + esp_bt_ontroller_log_deinit(); + stop_write = true; + + buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_reconfigure_wdts(5000); + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + esp_panic_handler_reconfigure_wdts(5000); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(log_output_mode); + assert(err == ESP_OK); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* This variable tells if BLE is running */ @@ -234,14 +412,6 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, @@ -286,75 +456,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) #endif // CONFIG_SW_COEXIST_ENABLE } -#ifdef CONFIG_BT_BLUEDROID_ENABLED -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - assert(cmd); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED - static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { @@ -386,56 +487,6 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits, uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - return rc; -} - -static int hci_uart_close_wrapper(int uart_no) -{ - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; -} - -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) -{ - //This function is nowhere to use. -} - -static int hci_uart_init_wrapper(int uart_no, void *cfg) -{ - //This function is nowhere to use. - return 0; -} - -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; -} - static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { @@ -551,7 +602,7 @@ static void sleep_modem_ble_mac_modem_state_deinit(void) void sleep_modem_light_sleep_overhead_set(uint32_t overhead) { - esp_ble_set_wakeup_overhead(overhead); + r_esp_ble_set_wakeup_overhead(overhead); } #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ @@ -577,6 +628,9 @@ esp_err_t controller_sleep_init(void) goto error; } #if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_BT_LE_SLEEP_ENABLE && !CONFIG_MAC_BB_PD +#error "CONFIG_MAC_BB_PD required for BLE light sleep to run properly" +#endif // CONFIG_BT_LE_SLEEP_ENABLE && !CONFIG_MAC_BB_PD /* Create a new regdma link for BLE related register restoration */ rc = sleep_modem_ble_mac_modem_state_init(1); assert(rc == 0); @@ -711,9 +765,9 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; uint32_t slow_clk_freq = 0; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_ERR_INVALID_STATE; @@ -744,7 +798,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_mem; } - ble_get_npl_element_info(cfg, &npl_info); + r_ble_get_npl_element_info(cfg, &npl_info); npl_freertos_set_controller_npl_info(&npl_info); if (npl_freertos_mempool_init() != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "npl mempool init failed"); @@ -802,33 +856,26 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif // CONFIG_SW_COEXIST_ENABLE #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - uint8_t buffers = 0; -#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED - buffers |= ESP_BLE_LOG_BUF_CONTROLLER; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - buffers |= ESP_BLE_LOG_BUF_HCI; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - ret = r_ble_log_init_async(bt_controller_log_interface, false, buffers, (uint32_t *)log_bufs_size); -#else - ret = r_ble_log_init_async(bt_controller_log_interface, true, buffers, (uint32_t *)log_bufs_size); -#endif // CONFIG_BT_CONTROLLER_LOG_DUMP + ret = esp_bt_controller_log_init(log_output_mode); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto modem_deint; } #endif // CONFIG_BT_CONTROLLER_LOG_ENABLED - ret = ble_controller_init(cfg); + ret = esp_ble_register_bb_funcs(); if (ret != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_init failed %d", ret); + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "esp_ble_register_bb_funcs failed %d", ret); + goto modem_deint; + } + + ret = r_ble_controller_init(cfg); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "r_ble_controller_init failed %d", ret); goto modem_deint; } ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); - esp_ble_change_rtc_freq(slow_clk_freq); + r_esp_ble_change_rtc_freq(slow_clk_freq); ble_controller_scan_duplicate_config(); @@ -843,23 +890,37 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "controller_sleep_init failed %d", ret); goto free_controller; } + ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); swap_in_place(mac, 6); - esp_ble_ll_set_public_addr(mac); + r_esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); - return ESP_OK; +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#if CONFIG_BT_LE_UART_HCI_DMA_MODE + hci_transport_mode = HCI_TRANSPORT_UART_UHCI; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } + return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); - ble_controller_deinit(); + r_ble_controller_deinit(); modem_deint: + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED esp_phy_modem_deinit(); modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); @@ -883,6 +944,7 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); @@ -891,9 +953,10 @@ esp_err_t esp_bt_controller_deinit(void) modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); - ble_controller_deinit(); + r_ble_controller_deinit(); + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED #if CONFIG_BT_NIMBLE_ENABLED @@ -939,7 +1002,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) coex_enable(); #endif // CONFIG_SW_COEXIST_ENABLE - if (ble_controller_enable(mode) != 0) { + if (r_ble_controller_enable(mode) != 0) { ret = ESP_FAIL; goto error; } @@ -967,7 +1030,7 @@ esp_err_t esp_bt_controller_disable(void) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_FAIL; } - if (ble_controller_disable() != 0) { + if (r_ble_controller_disable() != 0) { return ESP_FAIL; } #if CONFIG_SW_COEXIST_ENABLE @@ -1101,7 +1164,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_DEFAULT: case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1114,7 +1177,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { stat = ESP_OK; } break; @@ -1134,13 +1197,13 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - if (ble_txpwr_set(power_type, handle, power_level) == 0) { + if (r_ble_txpwr_set(power_type, handle, power_level) == 0) { stat = ESP_OK; } break; @@ -1160,7 +1223,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: case ESP_BLE_PWR_TYPE_DEFAULT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_PWR_TYPE_CONN_HDL0: case ESP_BLE_PWR_TYPE_CONN_HDL1: @@ -1171,7 +1234,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); break; default: return ESP_PWR_LVL_INVALID; @@ -1193,11 +1256,11 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - tx_level = ble_txpwr_get(power_type, handle); + tx_level = r_ble_txpwr_get(power_type, handle); break; default: return ESP_PWR_LVL_INVALID; @@ -1213,24 +1276,40 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) { - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); - } - if (end) { - esp_rom_printf("\n"); + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(1000); + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); + } + + if (end) { + esp_rom_printf("\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); } } void esp_ble_controller_log_dump_all(bool output) { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_reconfigure_wdts(5000); - BT_ASSERT_PRINT("\r\n[DUMP_START:"); - r_ble_log_async_output_dump_all(output); - BT_ASSERT_PRINT(":DUMP_END]\r\n"); - portEXIT_CRITICAL_SAFE(&spinlock); + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + BT_ASSERT_PRINT("\r\n[DUMP_START:"); + r_ble_log_async_output_dump_all(output); + BT_ASSERT_PRINT(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + } } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED diff --git a/components/bt/controller/esp32c6/esp_bt_cfg.h b/components/bt/controller/esp32c6/esp_bt_cfg.h index 9e341e322903..4e24c1861400 100644 --- a/components/bt/controller/esp32c6/esp_bt_cfg.h +++ b/components/bt/controller/esp32c6/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -129,6 +129,21 @@ extern "C" { #else #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) #endif + + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif #endif #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF @@ -169,8 +184,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -179,8 +192,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -205,7 +216,7 @@ extern "C" { #define RTC_FREQ_N (32768) /* in Hz */ -#define BLE_LL_TX_PWR_DBM_N (9) +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) diff --git a/components/bt/controller/esp32h2/Kconfig.in b/components/bt/controller/esp32h2/Kconfig.in index 9c91e4ddc3a0..d188d03230bd 100644 --- a/components/bt/controller/esp32h2/Kconfig.in +++ b/components/bt/controller/esp32h2/Kconfig.in @@ -2,19 +2,37 @@ menu "HCI Config" choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice + choice BT_LE_UART_HCI_MODE_CHOICE + prompt "UART HCI mode" + depends on BT_LE_HCI_INTERFACE_USE_UART + default BT_LE_UART_HCI_NO_DMA_MODE + help + Specify UART HCI mode: DMA or No DMA + + config BT_LE_UART_HCI_DMA_MODE + bool "UHCI(UART with DMA)(EXPERIMENTAL)" + help + UART HCI Mode with DMA functionality. + + config BT_LE_UART_HCI_NO_DMA_MODE + bool "UART(NO DMA)" + help + UART HCI Mode without DMA functionality. + endchoice + config BT_LE_HCI_UART_PORT int "HCI UART port" depends on BT_LE_HCI_INTERFACE_USE_UART @@ -73,12 +91,40 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 512 + help + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 256 help - Set the size of uart task stack + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 1024 + help + This configures stack size of hci transport task + + config BT_LE_HCI_TRANS_RX_MEM_NUM + int "The amount of rx memory received at the same time" + depends on BT_LE_UART_HCI_DMA_MODE + default 3 + help + The amount of rx memory received at the same time + + config BT_LE_HCI_LLDESCS_POOL_NUM + int "The amount of lldecs memory for driver dma mode" + depends on BT_LE_UART_HCI_DMA_MODE + default 20 + help + The amount of lldecs memory for driver dma mode endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -287,6 +333,24 @@ config BT_LE_CONTROLLER_LOG_DUMP_ONLY help Only operate in dump mode +config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + +config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + config BT_LE_LOG_CTRL_BUF1_SIZE int "size of the first BLE controller LOG buffer" depends on BT_LE_CONTROLLER_LOG_ENABLED @@ -356,7 +420,6 @@ config BT_LE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y depends on !BT_NIMBLE_ENABLED - select MBEDTLS_ECP_RESTARTABLE select MBEDTLS_CMAC_C help Enable this option to choose mbedTLS instead of TinyCrypt for crypto @@ -568,3 +631,62 @@ config BT_LE_CCA_RSSI_THRESH default 20 help Power threshold of CCA in unit of -1 dBm. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N24 + bool "-24dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N21 + bool "-21dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N18 + bool "-18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -24 if BT_LE_DFT_TX_POWER_LEVEL_N24 + default -21 if BT_LE_DFT_TX_POWER_LEVEL_N21 + default -18 if BT_LE_DFT_TX_POWER_LEVEL_N18 + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 248b2058ac03..90b7530b2a1f 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -15,7 +15,9 @@ #include "sdkconfig.h" +#if CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port.h" +#endif // CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port_freertos.h" #include "esp_private/esp_modem_clock.h" @@ -28,7 +30,7 @@ #endif // CONFIG_ESP_COEX_ENABLED #include "nimble/nimble_npl_os.h" -#include "nimble/ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" @@ -37,7 +39,6 @@ #include "esp_pm.h" #include "esp_phy_init.h" #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" #include "bt_osi_mem.h" #if CONFIG_FREERTOS_USE_TICKLESS_IDLE @@ -45,10 +46,6 @@ #include "esp_private/sleep_retention.h" #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif // CONFIG_BT_BLUEDROID_ENABLED - #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -59,19 +56,14 @@ ************************************************************************ */ #define NIMBLE_PORT_LOG_TAG "BLE_INIT" -#define OSI_COEX_VERSION 0x00010006 -#define OSI_COEX_MAGIC_VALUE 0xFADEBEAD +#define OSI_COEX_VERSION 0x00010006 +#define OSI_COEX_MAGIC_VALUE 0xFADEBEAD -#define EXT_FUNC_VERSION 0x20221122 +#define EXT_FUNC_VERSION 0x20240422 #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif // CONFIG_BT_BLUEDROID_ENABLED - /* Types definition ************************************************************************ */ @@ -90,12 +82,6 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); @@ -115,7 +101,7 @@ typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); ************************************************************************ */ extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); -extern int ble_controller_init(esp_bt_controller_config_t *cfg); +extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int r_ble_log_deinit_async(void); @@ -123,35 +109,37 @@ extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); extern void r_ble_log_async_output_dump_all(bool output); extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int ble_controller_deinit(void); -extern int ble_controller_enable(uint8_t mode); -extern int ble_controller_disable(void); +extern int r_ble_controller_deinit(void); +extern int r_ble_controller_enable(uint8_t mode); +extern int r_ble_controller_disable(void); extern int esp_register_ext_funcs (struct ext_funcs_t *); extern void esp_unregister_ext_funcs (void); -extern int esp_ble_ll_set_public_addr(const uint8_t *addr); +extern int r_esp_ble_ll_set_public_addr(const uint8_t *addr); extern int esp_register_npl_funcs (struct npl_funcs_t *p_npl_func); extern void esp_unregister_npl_funcs (void); extern void npl_freertos_mempool_deinit(void); extern uint32_t r_os_cputime_get32(void); extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks); -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE -extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); -extern void esp_ble_set_wakeup_overhead(uint32_t overhead); -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ -extern void esp_ble_change_rtc_freq(uint32_t freq); extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, void *w_arg, uint32_t us_to_enabled); extern void r_ble_rtc_wake_up_state_clr(void); extern int os_msys_init(void); extern void os_msys_deinit(void); +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); +extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead); +#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +extern void r_esp_ble_change_rtc_freq(uint32_t freq); extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); extern int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); -extern int ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t handle, int power_level); -extern int ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); +extern int r_ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t handle, int power_level); +extern int r_ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle); +extern int r_ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); extern char *ble_controller_get_compile_version(void); +extern int esp_ble_register_bb_funcs(void); +extern void esp_ble_unregister_bb_funcs(void); extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; extern uint32_t _bt_controller_bss_start; @@ -169,16 +157,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); @@ -190,15 +168,214 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; - #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +enum log_out_mode { + LOG_DUMP_MEMORY, + LOG_ASYNC_OUT, + LOG_STORAGE_TO_FLASH, +}; + +bool log_is_inited = false; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY +uint8_t log_output_mode = LOG_DUMP_MEMORY; +#else +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; +#else +uint8_t log_output_mode = LOG_ASYNC_OUT; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + +void esp_bt_log_output_mode_set(uint8_t output_mode) +{ + log_output_mode = output_mode; +} + +uint8_t esp_bt_log_output_mode_get(void) +{ + return log_output_mode; +} + +esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) +{ + esp_err_t ret = ESP_OK; + interface_func_t bt_controller_log_interface; + bt_controller_log_interface = esp_bt_controller_log_interface; + bool task_create; + uint8_t buffers = 0; + + if (log_is_inited) { + return ret; + } + +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + switch (log_output_mode) { + case LOG_DUMP_MEMORY: + task_create = false; + break; + case LOG_ASYNC_OUT: + case LOG_STORAGE_TO_FLASH: + task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + if (log_output_mode == LOG_STORAGE_TO_FLASH) { + esp_bt_ctrl_log_partition_get_and_erase_first_block(); + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + break; + default: + assert(0); + } + + ret = r_ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); + if (ret == ESP_OK) { + log_is_inited = true; + } + return ret; +} + +void esp_bt_ontroller_log_deinit(void) +{ + r_ble_log_deinit_async(); + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + r_ble_log_async_output_dump_all(true); + esp_bt_ontroller_log_deinit(); + stop_write = true; + + buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_reconfigure_wdts(5000); + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + esp_panic_handler_reconfigure_wdts(5000); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(log_output_mode); + assert(err == ESP_OK); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* This variable tells if BLE is running */ @@ -226,14 +403,6 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, @@ -278,75 +447,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) #endif // CONFIG_SW_COEXIST_ENABLE } -#ifdef CONFIG_BT_BLUEDROID_ENABLED -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - assert(cmd); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED - static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { @@ -378,56 +478,6 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits, uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - return rc; -} - -static int hci_uart_close_wrapper(int uart_no) -{ - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; -} - -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) -{ - //This function is nowhere to use. -} - -static int hci_uart_init_wrapper(int uart_no, void *cfg) -{ - //This function is nowhere to use. - return 0; -} - -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; -} - static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { @@ -538,9 +588,10 @@ static void sleep_modem_ble_mac_modem_state_deinit(void) void sleep_modem_light_sleep_overhead_set(uint32_t overhead) { - esp_ble_set_wakeup_overhead(overhead); + r_esp_ble_set_wakeup_overhead(overhead); } -#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ + esp_err_t controller_sleep_init(void) { @@ -684,6 +735,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; uint32_t slow_clk_freq = 0; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { @@ -716,7 +768,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_mem; } - ble_get_npl_element_info(cfg, &npl_info); + r_ble_get_npl_element_info(cfg, &npl_info); npl_freertos_set_controller_npl_info(&npl_info); if (npl_freertos_mempool_init() != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "npl mempool init failed"); @@ -730,10 +782,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) */ ble_npl_eventq_init(nimble_port_get_dflt_eventq()); #endif // CONFIG_BT_NIMBLE_ENABLED - /* Enable BT-related clocks */ modem_clock_module_enable(PERIPH_BT_MODULE); modem_clock_module_mac_reset(PERIPH_BT_MODULE); + /* Select slow clock source for BT momdule */ #if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); slow_clk_freq = 100000; @@ -771,36 +823,28 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #if CONFIG_SW_COEXIST_ENABLE coex_init(); #endif // CONFIG_SW_COEXIST_ENABLE + #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - uint8_t buffers = 0; -#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED - buffers |= ESP_BLE_LOG_BUF_CONTROLLER; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - buffers |= ESP_BLE_LOG_BUF_HCI; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - ret = r_ble_log_init_async(bt_controller_log_interface, false, buffers, (uint32_t *)log_bufs_size); -#else - ret = r_ble_log_init_async(bt_controller_log_interface, true, buffers, (uint32_t *)log_bufs_size); -#endif // CONFIG_BT_CONTROLLER_LOG_DUMP + ret = esp_bt_controller_log_init(log_output_mode); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto modem_deint; } #endif // CONFIG_BT_CONTROLLER_LOG_ENABLED + ret = esp_ble_register_bb_funcs(); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "esp_ble_register_bb_funcs failed %d", ret); + goto modem_deint; + } - ret = ble_controller_init(cfg); + ret = r_ble_controller_init(cfg); if (ret != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_init failed %d", ret); + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "r_ble_controller_init failed %d", ret); goto modem_deint; } ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); - - esp_ble_change_rtc_freq(slow_clk_freq); + r_esp_ble_change_rtc_freq(slow_clk_freq); ble_controller_scan_duplicate_config(); @@ -815,24 +859,36 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "controller_sleep_init failed %d", ret); goto free_controller; } - ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); swap_in_place(mac, 6); - esp_ble_ll_set_public_addr(mac); + r_esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); - return ESP_OK; +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#if CONFIG_BT_LE_UART_HCI_DMA_MODE + hci_transport_mode = HCI_TRANSPORT_UART_UHCI; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } + return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); - ble_controller_deinit(); + r_ble_controller_deinit(); modem_deint: + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); @@ -855,6 +911,7 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); @@ -862,9 +919,10 @@ esp_err_t esp_bt_controller_deinit(void) modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); - ble_controller_deinit(); + r_ble_controller_deinit(); + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED #if CONFIG_BT_NIMBLE_ENABLED @@ -910,7 +968,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) coex_enable(); #endif // CONFIG_SW_COEXIST_ENABLE - if (ble_controller_enable(mode) != 0) { + if (r_ble_controller_enable(mode) != 0) { ret = ESP_FAIL; goto error; } @@ -938,7 +996,7 @@ esp_err_t esp_bt_controller_disable(void) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_FAIL; } - if (ble_controller_disable() != 0) { + if (r_ble_controller_disable() != 0) { return ESP_FAIL; } #if CONFIG_SW_COEXIST_ENABLE @@ -1072,7 +1130,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_DEFAULT: case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1085,7 +1143,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { stat = ESP_OK; } break; @@ -1105,13 +1163,13 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - if (ble_txpwr_set(power_type, handle, power_level) == 0) { + if (r_ble_txpwr_set(power_type, handle, power_level) == 0) { stat = ESP_OK; } break; @@ -1131,7 +1189,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: case ESP_BLE_PWR_TYPE_DEFAULT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_PWR_TYPE_CONN_HDL0: case ESP_BLE_PWR_TYPE_CONN_HDL1: @@ -1142,7 +1200,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); break; default: return ESP_PWR_LVL_INVALID; @@ -1164,11 +1222,11 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - tx_level = ble_txpwr_get(power_type, handle); + tx_level = r_ble_txpwr_get(power_type, handle); break; default: return ESP_PWR_LVL_INVALID; @@ -1184,16 +1242,30 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) { - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); - } - if (end) { - esp_rom_printf("\n"); + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(1000); + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); + } + + if (end) { + esp_rom_printf("\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); } } void esp_ble_controller_log_dump_all(bool output) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#else portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; portENTER_CRITICAL_SAFE(&spinlock); @@ -1202,6 +1274,7 @@ void esp_ble_controller_log_dump_all(bool output) r_ble_log_async_output_dump_all(output); BT_ASSERT_PRINT(":DUMP_END]\r\n"); portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED diff --git a/components/bt/controller/esp32h2/esp_bt_cfg.h b/components/bt/controller/esp32h2/esp_bt_cfg.h index c0c5801af140..22a09be3adc6 100644 --- a/components/bt/controller/esp32h2/esp_bt_cfg.h +++ b/components/bt/controller/esp32h2/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -124,12 +124,26 @@ extern "C" { #else #define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (0) #endif - #if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT) #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) #else #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) #endif + + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif #endif #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF @@ -170,8 +184,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -180,8 +192,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -206,8 +216,7 @@ extern "C" { #define RTC_FREQ_N (32768) /* in Hz */ -#define BLE_LL_TX_PWR_DBM_N (9) - +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) #define RUN_QA_TEST (0) diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 44341b15e587..3bb36a79cdfa 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 44341b15e58792946cc65ed8d4483929194d182f +Subproject commit 3bb36a79cdfad65c656b9238e0d46b935775ed72 diff --git a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib index b9a902c3551e..db84a7e4539c 160000 --- a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib +++ b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib @@ -1 +1 @@ -Subproject commit b9a902c3551ef4a2032b6662a4cbb018125ddfda +Subproject commit db84a7e4539c5d9e6b8ec882b82a5de0fb8400c7 diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family index 76ed4114ee7d..bfdfe8f851c9 160000 --- a/components/bt/controller/lib_esp32c3_family +++ b/components/bt/controller/lib_esp32c3_family @@ -1 +1 @@ -Subproject commit 76ed4114ee7d081435a3c65793b4c8eb1dfaf199 +Subproject commit bfdfe8f851c99ced8316b133b0b15521917ea049 diff --git a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib index 45dda7a690af..77c67a4d06c9 160000 --- a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib +++ b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib @@ -1 +1 @@ -Subproject commit 45dda7a690af994e8e6a41cc3b029506335d169f +Subproject commit 77c67a4d06c95113a2d1766892cde59f5af744af diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index 0af472c6f958..3396205d4864 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit 0af472c6f95858e638565dad19a79fe47de1fff2 +Subproject commit 3396205d48647372568ba67e41c4e08917ef1038 diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index 70612d08d1ff..85174c19ced2 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit 70612d08d1ff94dfb5da99d6a68aa4032cd63276 +Subproject commit 85174c19ced288f48254b01957609b8423c757bf diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c index 9a12de171094..821287860850 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c @@ -96,7 +96,7 @@ esp_err_t esp_ble_mesh_deinit(esp_ble_mesh_deinit_param_t *param) } /* Take the Semaphore, wait BLE Mesh de-initialization to finish. */ - xSemaphoreTake(semaphore, portMAX_DELAY); + __ASSERT(xSemaphoreTake(semaphore, 3000 / portTICK_PERIOD_MS) == pdTRUE, "BLE Mesh deinit take semaphore failed"); /* Don't forget to delete the semaphore at the end. */ vSemaphoreDelete(semaphore); diff --git a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h index f7209d8e5fed..556565e7f220 100644 --- a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h +++ b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,7 +33,10 @@ esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp /** * @brief De-initialize BLE Mesh module. * - * @note This function shall be invoked after esp_ble_mesh_client_model_deinit(). + * @note + * 1. This function shall be invoked after esp_ble_mesh_client_model_deinit(). + * 2. This function is strictly forbidden to run in any BTC Task Context + * (e.g. registered Mesh Event Callback). * * @param[in] param: Pointer to the structure of BLE Mesh deinit parameters. * diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c index 38882680190d..67d5353be8fa 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -71,6 +71,29 @@ #include "esp_ble_mesh_provisioning_api.h" #include "esp_ble_mesh_networking_api.h" +#if CONFIG_BLE_MESH_DEINIT +static SemaphoreHandle_t deinit_comp_semaphore; +#endif + +static inline void btc_ble_mesh_prov_cb_to_app_reprocess(esp_ble_mesh_prov_cb_event_t event, + esp_ble_mesh_prov_cb_param_t *param) +{ + switch (event) { +#if CONFIG_BLE_MESH_DEINIT + case ESP_BLE_MESH_DEINIT_MESH_COMP_EVT: + assert(deinit_comp_semaphore); + /* Give the semaphore when BLE Mesh de-initialization is finished. + * @note: At nimble host, once this lock is released, it will cause + * the btc task to be deleted. + */ + xSemaphoreGive(deinit_comp_semaphore); + break; +#endif + default: + break; + } +} + static inline void btc_ble_mesh_prov_cb_to_app(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param) { @@ -79,6 +102,8 @@ static inline void btc_ble_mesh_prov_cb_to_app(esp_ble_mesh_prov_cb_event_t even if (btc_ble_mesh_cb) { btc_ble_mesh_cb(event, param); } + + btc_ble_mesh_prov_cb_to_app_reprocess(event, param); } static inline void btc_ble_mesh_model_cb_to_app(esp_ble_mesh_model_cb_event_t event, @@ -2825,8 +2850,8 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) case BTC_BLE_MESH_ACT_DEINIT_MESH: act = ESP_BLE_MESH_DEINIT_MESH_COMP_EVT; param.deinit_mesh_comp.err_code = bt_mesh_deinit((struct bt_mesh_deinit_param *)&arg->mesh_deinit.param); - /* Give the semaphore when BLE Mesh de-initialization is finished. */ - xSemaphoreGive(arg->mesh_deinit.semaphore); + /* Temporarily save the deinit semaphore and release it after the mesh deinit complete event is handled in the app layer */ + deinit_comp_semaphore = arg->mesh_deinit.semaphore; break; #endif /* CONFIG_BLE_MESH_DEINIT */ default: diff --git a/components/bt/esp_ble_mesh/common/atomic.c b/components/bt/esp_ble_mesh/common/atomic.c index 723ce7e3ac15..9c856cc33723 100644 --- a/components/bt/esp_ble_mesh/common/atomic.c +++ b/components/bt/esp_ble_mesh/common/atomic.c @@ -13,7 +13,7 @@ /* * SPDX-FileCopyrightText: 2016 Intel Corporation * SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc. - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -170,4 +170,18 @@ bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target) return ret; } +bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val) +{ + bt_mesh_atomic_lock(); + + if (*target == excepted) { + *target = new_val; + bt_mesh_atomic_unlock(); + return true; + } + + bt_mesh_atomic_unlock(); + return false; +} + #endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */ diff --git a/components/bt/esp_ble_mesh/common/include/mesh/atomic.h b/components/bt/esp_ble_mesh/common/include/mesh/atomic.h index f72834369fc5..b284974363a3 100644 --- a/components/bt/esp_ble_mesh/common/include/mesh/atomic.h +++ b/components/bt/esp_ble_mesh/common/include/mesh/atomic.h @@ -147,6 +147,33 @@ static inline bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value); #endif +/** + * @brief Atomic CAS operation. + * + * This compares the contents of @a *target + * with the contents of @a excepted. If equal, + * the operation is a read-modify-write operation + * that writes @a new_val into @a *target and return true. + * If they are not equal, the operation is a read + * and return false. + * + * @param target Address of atomic variable. + * @param excepted Value of excepted. + * @param new_val Write if target value is equal to expected one. + * + * @return + * - true: Target value updated. + * - false: Target value not updated. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val) +{ + return __atomic_compare_exchange_n(target, &excepted, &new_val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} +#else +extern bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val); +#endif + /** * @cond INTERNAL_HIDDEN */ diff --git a/components/bt/esp_ble_mesh/core/adv.c b/components/bt/esp_ble_mesh/core/adv.c index dbbda0ab147f..79932a058299 100644 --- a/components/bt/esp_ble_mesh/core/adv.c +++ b/components/bt/esp_ble_mesh/core/adv.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -335,8 +335,7 @@ static void adv_thread(void *p) } /* busy == 0 means this was canceled */ - if (BLE_MESH_ADV(*buf)->busy) { - BLE_MESH_ADV(*buf)->busy = 0U; + if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(*buf), 1, 0)) { #if !CONFIG_BLE_MESH_RELAY_ADV_BUF if (adv_send(*buf)) { BT_WARN("Failed to send adv packet"); @@ -449,7 +448,7 @@ static void bt_mesh_unref_buf(bt_mesh_msg_t *msg) if (msg->arg) { buf = (struct net_buf *)msg->arg; - BLE_MESH_ADV(buf)->busy = 0U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0); if (buf->ref > 1U) { buf->ref = 1U; } @@ -490,7 +489,7 @@ void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit, BLE_MESH_ADV(buf)->cb = cb; BLE_MESH_ADV(buf)->cb_data = cb_data; - BLE_MESH_ADV(buf)->busy = 1U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1); BLE_MESH_ADV(buf)->xmit = xmit; bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); @@ -589,7 +588,7 @@ void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit, BLE_MESH_ADV(buf)->cb = cb; BLE_MESH_ADV(buf)->cb_data = cb_data; - BLE_MESH_ADV(buf)->busy = 1U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1); BLE_MESH_ADV(buf)->xmit = xmit; msg.arg = (void *)net_buf_ref(buf); @@ -753,7 +752,7 @@ static void bt_mesh_ble_adv_send(struct net_buf *buf, const struct bt_mesh_send_ BLE_MESH_ADV(buf)->cb = cb; BLE_MESH_ADV(buf)->cb_data = cb_data; - BLE_MESH_ADV(buf)->busy = 1U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1); bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); @@ -772,7 +771,7 @@ static void ble_adv_tx_reset(struct ble_adv_tx *tx, bool unref) } bt_mesh_atomic_set(tx->flags, 0); memset(&tx->param, 0, sizeof(tx->param)); - BLE_MESH_ADV(tx->buf)->busy = 0U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0); if (unref) { net_buf_unref(tx->buf); } @@ -961,7 +960,8 @@ int bt_mesh_stop_ble_advertising(uint8_t index) /* busy 1, ref 1; busy 1, ref 2; * busy 0, ref 0; busy 0, ref 1; */ - if (BLE_MESH_ADV(tx->buf)->busy == 1U && + + if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) && tx->buf->ref == 1U) { unref = false; } diff --git a/components/bt/esp_ble_mesh/core/adv.h b/components/bt/esp_ble_mesh/core/adv.h index ab37ec3cda85..33224d78b111 100644 --- a/components/bt/esp_ble_mesh/core/adv.h +++ b/components/bt/esp_ble_mesh/core/adv.h @@ -10,6 +10,7 @@ #ifndef _ADV_H_ #define _ADV_H_ +#include "mesh/atomic.h" #include "mesh/access.h" #include "mesh/adapter.h" @@ -24,6 +25,7 @@ extern "C" { #define BLE_MESH_ADV_USER_DATA_SIZE 4 #define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf)) +#define BLE_MESH_ADV_BUSY(buf) (BLE_MESH_ADV(buf)->busy) uint16_t bt_mesh_pdu_duration(uint8_t xmit); @@ -48,8 +50,10 @@ struct bt_mesh_adv { const struct bt_mesh_send_cb *cb; void *cb_data; - uint8_t type:3, - busy:1; + uint8_t type:3; + + bt_mesh_atomic_t busy; + uint8_t xmit; }; diff --git a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c index 610d19a5b1f0..e0fc33b48448 100644 --- a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA * SPDX-FileCopyrightText: 2015-2016 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -74,7 +74,7 @@ static struct bt_mesh_conn_cb *bt_mesh_gatts_conn_cb; static tBTA_GATTS_IF bt_mesh_gatts_if; static uint8_t bt_mesh_gatts_addr[BLE_MESH_ADDR_LEN]; static uint16_t svc_handle, char_handle; -static future_t *future_mesh; +static future_t *gatts_future_mesh; /* Static Functions */ static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(uint16_t handle); @@ -561,6 +561,9 @@ static void bt_mesh_bta_gatts_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) case BTA_GATTS_REG_EVT: if (p_data->reg_oper.status == BTA_GATT_OK) { bt_mesh_gatts_if = p_data->reg_oper.server_if; + future_ready(gatts_future_mesh, FUTURE_SUCCESS); + } else { + future_ready(gatts_future_mesh, FUTURE_FAIL); } break; case BTA_GATTS_READ_EVT: { @@ -618,27 +621,27 @@ static void bt_mesh_bta_gatts_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) break; case BTA_GATTS_CREATE_EVT: svc_handle = p_data->create.service_id; - BT_DBG("svc_handle %d, future_mesh %p", svc_handle, future_mesh); - if (future_mesh != NULL) { - future_ready(future_mesh, FUTURE_SUCCESS); + BT_DBG("svc_handle %d, gatts_future_mesh %p", svc_handle, gatts_future_mesh); + if (gatts_future_mesh != NULL) { + future_ready(gatts_future_mesh, FUTURE_SUCCESS); } break; case BTA_GATTS_ADD_INCL_SRVC_EVT: svc_handle = p_data->add_result.attr_id; - if (future_mesh != NULL) { - future_ready(future_mesh, FUTURE_SUCCESS); + if (gatts_future_mesh != NULL) { + future_ready(gatts_future_mesh, FUTURE_SUCCESS); } break; case BTA_GATTS_ADD_CHAR_EVT: char_handle = p_data->add_result.attr_id; - if (future_mesh != NULL) { - future_ready(future_mesh, FUTURE_SUCCESS); + if (gatts_future_mesh != NULL) { + future_ready(gatts_future_mesh, FUTURE_SUCCESS); } break; case BTA_GATTS_ADD_CHAR_DESCR_EVT: char_handle = p_data->add_result.attr_id; - if (future_mesh != NULL) { - future_ready(future_mesh, FUTURE_SUCCESS); + if (gatts_future_mesh != NULL) { + future_ready(gatts_future_mesh, FUTURE_SUCCESS); } break; case BTA_GATTS_DELELTE_EVT: @@ -962,11 +965,11 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) if (svc->attrs[i].uuid->type == BLE_MESH_UUID_TYPE_16) { switch (BLE_MESH_UUID_16(svc->attrs[i].uuid)->val) { case BLE_MESH_UUID_GATT_PRIMARY_VAL: { - future_mesh = future_new(); + gatts_future_mesh = future_new(); bta_uuid_to_bt_mesh_uuid(&bta_uuid, (struct bt_mesh_uuid *)svc->attrs[i].user_data); BTA_GATTS_CreateService(bt_mesh_gatts_if, &bta_uuid, 0, svc->attr_count, true); - if (future_await(future_mesh) == FUTURE_FAIL) { + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add primary service"); return ESP_FAIL; } @@ -976,11 +979,11 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) break; } case BLE_MESH_UUID_GATT_SECONDARY_VAL: { - future_mesh = future_new(); + gatts_future_mesh = future_new(); bta_uuid_to_bt_mesh_uuid(&bta_uuid, (struct bt_mesh_uuid *)svc->attrs[i].user_data); BTA_GATTS_CreateService(bt_mesh_gatts_if, &bta_uuid, 0, svc->attr_count, false); - if (future_await(future_mesh) == FUTURE_FAIL) { + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add secondary service"); return ESP_FAIL; } @@ -993,11 +996,11 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) break; } case BLE_MESH_UUID_GATT_CHRC_VAL: { - future_mesh = future_new(); + gatts_future_mesh = future_new(); struct bt_mesh_gatt_char *gatts_chrc = (struct bt_mesh_gatt_char *)svc->attrs[i].user_data; bta_uuid_to_bt_mesh_uuid(&bta_uuid, gatts_chrc->uuid); BTA_GATTS_AddCharacteristic(svc_handle, &bta_uuid, bt_mesh_perm_to_bta_perm(svc->attrs[i + 1].perm), gatts_chrc->properties, NULL, NULL); - if (future_await(future_mesh) == FUTURE_FAIL) { + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add characteristic"); return ESP_FAIL; } @@ -1019,10 +1022,10 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) case BLE_MESH_UUID_ES_CONFIGURATION_VAL: case BLE_MESH_UUID_ES_MEASUREMENT_VAL: case BLE_MESH_UUID_ES_TRIGGER_SETTING_VAL: { - future_mesh = future_new(); + gatts_future_mesh = future_new(); bta_uuid_to_bt_mesh_uuid(&bta_uuid, svc->attrs[i].uuid); BTA_GATTS_AddCharDescriptor(svc_handle, bt_mesh_perm_to_bta_perm(svc->attrs[i].perm), &bta_uuid, NULL, NULL); - if (future_await(future_mesh) == FUTURE_FAIL) { + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add descriptor"); return ESP_FAIL; } @@ -1768,7 +1771,19 @@ void bt_mesh_gatt_init(void) CONFIG_BLE_MESH_GATT_PROXY_SERVER tBT_UUID gatts_app_uuid = {LEN_UUID_128, {0}}; memset(&gatts_app_uuid.uu.uuid128, BLE_MESH_GATTS_APP_UUID_BYTE, LEN_UUID_128); + + gatts_future_mesh = future_new(); + if (!gatts_future_mesh) { + BT_ERR("Mesh gatts sync lock alloc failed"); + return; + } + BTA_GATTS_AppRegister(&gatts_app_uuid, bt_mesh_bta_gatts_cb); + + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { + BT_ERR("Mesh gatts app register failed"); + return; + } #endif #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ diff --git a/components/bt/esp_ble_mesh/core/friend.c b/components/bt/esp_ble_mesh/core/friend.c index fca3cf1358a4..b1a298d5a97a 100644 --- a/components/bt/esp_ble_mesh/core/friend.c +++ b/components/bt/esp_ble_mesh/core/friend.c @@ -183,7 +183,7 @@ static void friend_clear(struct bt_mesh_friend *frnd, uint8_t reason) /* Cancel the sending if necessary */ if (frnd->pending_buf) { bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 2U, BLE_MESH_BUF_REF_EQUAL); - BLE_MESH_ADV(frnd->last)->busy = 0U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(frnd->last), 0); } else { bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 1U, BLE_MESH_BUF_REF_EQUAL); } diff --git a/components/bt/esp_ble_mesh/core/net.c b/components/bt/esp_ble_mesh/core/net.c index 2f9889669be6..d5b768c7d221 100644 --- a/components/bt/esp_ble_mesh/core/net.c +++ b/components/bt/esp_ble_mesh/core/net.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1129,23 +1129,34 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, if (((IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) || (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en())) && (bt_mesh_fixed_group_match(tx->ctx->addr) || bt_mesh_elem_find(tx->ctx->addr))) { - if (cb && cb->start) { - cb->start(0, 0, cb_data); - } + /** + * If the target address isn't a unicast address, then the callback function + * will be called by `adv task` in place of here, to avoid the callback function + * being called twice. + * See BLEMESH24-76 for more details. + */ + if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { + if (cb && cb->start) { + cb->start(0, 0, cb_data); + } - net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); + net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); - if (cb && cb->end) { - cb->end(0, cb_data); - } + if (cb && cb->end) { + cb->end(0, cb_data); + } - bt_mesh_net_local(); + bt_mesh_net_local(); + + err = 0; - err = 0; - /* If it is a group address, it still needs to be relayed */ - if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { goto done; + } else { + net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); + bt_mesh_net_local(); } + + err = 0; } if ((bearer & BLE_MESH_ADV_BEARER) && diff --git a/components/bt/esp_ble_mesh/core/prov_common.c b/components/bt/esp_ble_mesh/core/prov_common.c index 655c4712f244..bc75b447d256 100644 --- a/components/bt/esp_ble_mesh/core/prov_common.c +++ b/components/bt/esp_ble_mesh/core/prov_common.c @@ -359,7 +359,7 @@ static void free_segments(struct bt_mesh_prov_link *link) link->tx.buf[i] = NULL; bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); /* Mark as canceled */ - BLE_MESH_ADV(buf)->busy = 0U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0); net_buf_unref(buf); } } @@ -474,7 +474,7 @@ static void prov_retransmit(struct k_work *work) break; } - if (BLE_MESH_ADV(buf)->busy) { + if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(buf))) { continue; } diff --git a/components/bt/esp_ble_mesh/core/transport.c b/components/bt/esp_ble_mesh/core/transport.c index 64ac566aced5..70589706dae3 100644 --- a/components/bt/esp_ble_mesh/core/transport.c +++ b/components/bt/esp_ble_mesh/core/transport.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -310,7 +310,15 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx) { bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 3U, BLE_MESH_BUF_REF_SMALL); - BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U; + /** + * When cancelling a segment that is still in the adv sending queue, `tx->seg_pending` + * must else be decremented by one. More detailed information + * can be found in BLEMESH24-26. + */ + if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 1, 0)) { + tx->seg_pending--; + } + net_buf_unref(tx->seg[seg_idx]); tx->seg[seg_idx] = NULL; tx->nack_count--; @@ -443,7 +451,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) continue; } - if (BLE_MESH_ADV(seg)->busy) { + if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) { BT_DBG("Skipping segment that's still advertising"); continue; } diff --git a/components/bt/esp_ble_mesh/core/transport.enh.c b/components/bt/esp_ble_mesh/core/transport.enh.c index 2dc562d94b1c..a4a5130e2150 100644 --- a/components/bt/esp_ble_mesh/core/transport.enh.c +++ b/components/bt/esp_ble_mesh/core/transport.enh.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -121,22 +121,22 @@ static bt_mesh_mutex_t seg_rx_lock; static inline void bt_mesh_seg_tx_lock(void) { - bt_mesh_mutex_lock(&seg_tx_lock); + bt_mesh_r_mutex_lock(&seg_tx_lock); } static inline void bt_mesh_seg_tx_unlock(void) { - bt_mesh_mutex_unlock(&seg_tx_lock); + bt_mesh_r_mutex_unlock(&seg_tx_lock); } static inline void bt_mesh_seg_rx_lock(void) { - bt_mesh_mutex_lock(&seg_rx_lock); + bt_mesh_r_mutex_lock(&seg_rx_lock); } static inline void bt_mesh_seg_rx_unlock(void) { - bt_mesh_mutex_unlock(&seg_rx_lock); + bt_mesh_r_mutex_unlock(&seg_rx_lock); } uint8_t bt_mesh_seg_send_interval(void) @@ -350,7 +350,7 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx) */ bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 4U, BLE_MESH_BUF_REF_SMALL); - BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 0); net_buf_unref(tx->seg[seg_idx]); tx->seg[seg_idx] = NULL; @@ -498,7 +498,7 @@ static bool send_next_segment(struct seg_tx *tx, int *result) /* The segment may have already been transmitted, for example, the * Segment Retransmission timer is expired earlier. */ - if (BLE_MESH_ADV(seg)->busy) { + if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) { return false; } @@ -517,6 +517,12 @@ static bool send_next_segment(struct seg_tx *tx, int *result) net_tx.ctx->net_idx = tx->sub->net_idx; + /** + * Add one to the ref count only if the segment can be further + * processed by the network. + */ + seg = net_buf_ref(seg); + err = bt_mesh_net_send(&net_tx, seg, &seg_sent_cb, tx); if (err) { BT_ERR("Send seg %u failed (err %d)", tx->last_seg_n, err); @@ -762,7 +768,7 @@ static bool resend_unacked_seg(struct seg_tx *tx, int *result) * A is still going to be retransmitted, but at this moment we could * find that the "busy" flag of Segment A is 1. */ - if (BLE_MESH_ADV(seg)->busy) { + if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) { return false; } @@ -966,7 +972,18 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, } } - tx->seg[seg_o] = net_buf_ref(seg); + /** + * If the net buffer allocation of the subsequent + * segments of this segment message fails, it will + * cause the ref count of the previously allocated + * successful segments to not be unref, which will + * cause the net buffer leakage to occur, so it is + * necessary to wait until all the segments have been + * allocated, and then when the segment is confirmed + * that it will be network layer for further processing, + * then ref of the net buffer should be plus one. + */ + tx->seg[seg_o] = seg; BT_DBG("Seg %u/%u prepared", seg_o, tx->seg_n); } @@ -975,6 +992,11 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, * tx->seg[0] will be NULL here. */ if (tx->seg[0]) { + /** + * Add one to the ref count only if the segment can be further + * processed by the network. + */ + tx->seg[0] = net_buf_ref(tx->seg[0]); err = bt_mesh_net_send(net_tx, tx->seg[0], &seg_sent_cb, tx); if (err) { BT_ERR("Send 1st seg failed (err %d)", err); @@ -2327,8 +2349,8 @@ void bt_mesh_trans_init(void) seg_rx[i].buf.data = seg_rx[i].buf.__buf; } - bt_mesh_mutex_create(&seg_tx_lock); - bt_mesh_mutex_create(&seg_rx_lock); + bt_mesh_r_mutex_create(&seg_tx_lock); + bt_mesh_r_mutex_create(&seg_rx_lock); } #if CONFIG_BLE_MESH_DEINIT @@ -2338,7 +2360,7 @@ void bt_mesh_trans_deinit(bool erase) bt_mesh_tx_reset(); bt_mesh_rpl_reset(erase); - bt_mesh_mutex_free(&seg_tx_lock); - bt_mesh_mutex_free(&seg_rx_lock); + bt_mesh_r_mutex_free(&seg_tx_lock); + bt_mesh_r_mutex_free(&seg_rx_lock); } #endif /* CONFIG_BLE_MESH_DEINIT */ diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 58859d35f890..f66333932d34 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -85,7 +85,7 @@ config BT_A2DP_ENABLE depends on BT_CLASSIC_ENABLED default n help - Advanced Audio Distrubution Profile + Advanced Audio Distribution Profile config BT_SPP_ENABLED bool "SPP" @@ -140,7 +140,7 @@ config BT_HFP_WBS_ENABLE default y help This enables Wide Band Speech. Should disable it when SCO data path is PCM. - Otherwise there will be no data transmited via GPIOs. + Otherwise there will be no data transmitted via GPIOs. menuconfig BT_HID_ENABLED @@ -312,6 +312,17 @@ config BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE In order to reduce the pairing time, slave actively initiates connection parameters update during pairing. +config BT_BLE_SMP_ID_RESET_ENABLE + bool "Reset device identity when all bonding records are deleted" + depends on BT_BLE_SMP_ENABLE + default n + help + There are tracking risks associated with using a fixed or static IRK. + If enabled this option, Bluedroid will assign a new randomly-generated IRK + when all pairing and bonding records are deleted. This would decrease the ability + of a previously paired peer to be used to determine whether a device + with which it previously shared an IRK is within range. + config BT_STACK_NO_LOG bool "Disable BT debug logs (minimize bin size)" depends on BT_BLUEDROID_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_bluedroid_hci.c b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c index d17ab91494e9..1676ae88243d 100644 --- a/components/bt/host/bluedroid/api/esp_bluedroid_hci.c +++ b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c @@ -61,7 +61,7 @@ bool hci_host_check_send_available(void) void hci_host_send_packet(uint8_t *data, uint16_t len) { #if (BT_HCI_LOG_INCLUDED == TRUE) - bt_hci_log_record_hci_data(data[0], data, len); + bt_hci_log_record_hci_data(data[0], &data[1], len - 1); #endif #if (BT_CONTROLLER_INCLUDED == TRUE) esp_vhci_host_send_packet(data, len); diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index db513eb55154..1d2267e8bc7e 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -1014,6 +1014,25 @@ esp_err_t esp_ble_dtm_stop(void) return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_gap_set_privacy_mode(esp_ble_addr_type_t addr_type, esp_bd_addr_t addr, esp_ble_privacy_mode_t mode) +{ + btc_msg_t msg; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_PRIVACY_MODE; + + arg.set_privacy_mode.addr_type = addr_type; + memcpy(arg.set_privacy_mode.addr, addr, sizeof(esp_bd_addr_t)); + arg.set_privacy_mode.privacy_mode = mode; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + #if (BLE_50_FEATURE_SUPPORT == TRUE) esp_err_t esp_ble_gap_read_phy(esp_bd_addr_t bd_addr) diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_main.h b/components/bt/host/bluedroid/api/include/api/esp_bt_main.h index b13ae94d0eaf..a626ec655135 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_main.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_main.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -55,7 +55,10 @@ esp_bluedroid_status_t esp_bluedroid_get_status(void); esp_err_t esp_bluedroid_enable(void); /** - * @brief Disable bluetooth, must prior to esp_bluedroid_deinit(). + * @brief Disable Bluetooth, must be called prior to esp_bluedroid_deinit(). + * + * @note Before calling this API, ensure that all activities related to + * the application, such as connections, scans, etc., are properly closed. * * @return * - ESP_OK : Succeed diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 9e9a0e153d5d..3e06258835f6 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -228,6 +228,7 @@ typedef enum { ESP_GAP_BLE_SET_RPA_TIMEOUT_COMPLETE_EVT, /*!< When set the Resolvable Private Address (RPA) timeout completes, the event comes */ ESP_GAP_BLE_ADD_DEV_TO_RESOLVING_LIST_COMPLETE_EVT, /*!< when add a device to the resolving list completes, the event comes*/ ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT, /*!< When vendor hci command complete, the event comes */ + ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT, /*!< When set privacy mode complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -660,21 +661,55 @@ typedef struct { esp_bt_octet16_t oob_r; /*!< the 128 bits of randomizer value */ } esp_ble_local_oob_data_t; +/** +* @brief Definition of the authentication failed reason +*/ +typedef enum { + // Failure reason defined in Bluetooth Core Spec 5.0 Vol3, Part H, 3.5.5 + ESP_AUTH_SMP_PASSKEY_FAIL = 78, /*!< The user input of passkey failed */ + ESP_AUTH_SMP_OOB_FAIL, /*!< The OOB data is not available */ + ESP_AUTH_SMP_PAIR_AUTH_FAIL, /*!< The authentication requirements cannot be met */ + ESP_AUTH_SMP_CONFIRM_VALUE_FAIL, /*!< The confirm value does not match the calculated comparison value */ + ESP_AUTH_SMP_PAIR_NOT_SUPPORT, /*!< Pairing is not supported by the device */ + ESP_AUTH_SMP_ENC_KEY_SIZE, /*!< The resultant encryption key size is not long enough */ + ESP_AUTH_SMP_INVALID_CMD, /*!< The SMP command received is not supported by this device */ + ESP_AUTH_SMP_UNKNOWN_ERR, /*!< Pairing failed due to an unspecified reason */ + ESP_AUTH_SMP_REPEATED_ATTEMPT, /*!< Pairing or authentication procedure is disallowed */ + ESP_AUTH_SMP_INVALID_PARAMETERS, /*!< The command length is invalid or that a parameter is outside the specified range */ + ESP_AUTH_SMP_DHKEY_CHK_FAIL, /*!< The DHKey Check value received doesn’t match the one calculated by the local device */ + ESP_AUTH_SMP_NUM_COMP_FAIL, /*!< The confirm values in the numeric comparison protocol do not match */ + ESP_AUTH_SMP_BR_PARING_IN_PROGR, /*!< Pairing Request sent over the BR/EDR transport is in progress */ + ESP_AUTH_SMP_XTRANS_DERIVE_NOT_ALLOW, /*!< The BR/EDR Link Key or BLE LTK cannot be used to derive */ + + // Failure reason defined in Bluedroid Host + ESP_AUTH_SMP_INTERNAL_ERR, /*!< Internal error in pairing procedure */ + ESP_AUTH_SMP_UNKNOWN_IO, /*!< Unknown IO capability, unable to decide association model */ + ESP_AUTH_SMP_INIT_FAIL, /*!< SMP pairing initiation failed */ + ESP_AUTH_SMP_CONFIRM_FAIL, /*!< The confirm value does not match */ + ESP_AUTH_SMP_BUSY, /*!< Pending security request on going */ + ESP_AUTH_SMP_ENC_FAIL, /*!< The Controller failed to start encryption */ + ESP_AUTH_SMP_STARTED, /*!< SMP pairing process started */ + ESP_AUTH_SMP_RSP_TIMEOUT, /*!< Security Manager timeout due to no SMP command being received */ + ESP_AUTH_SMP_DIV_NOT_AVAIL, /*!< Encrypted Diversifier value not available */ + ESP_AUTH_SMP_UNSPEC_ERR, /*!< Unspecified failed reason */ + ESP_AUTH_SMP_CONN_TOUT, /*!< Pairing process failed due to connection timeout */ +} esp_ble_auth_fail_rsn_t; + /** * @brief Structure associated with ESP_AUTH_CMPL_EVT */ typedef struct { - esp_bd_addr_t bd_addr; /*!< BD address peer device. */ - bool key_present; /*!< Valid link key value in key element */ - esp_link_key key; /*!< Link key associated with peer device. */ - uint8_t key_type; /*!< The type of Link Key */ - bool success; /*!< TRUE of authentication succeeded, FALSE if failed. */ - uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */ - esp_ble_addr_type_t addr_type; /*!< Peer device address type */ - esp_bt_dev_type_t dev_type; /*!< Device type */ - esp_ble_auth_req_t auth_mode; /*!< authentication mode */ -} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */ + esp_bd_addr_t bd_addr; /*!< BD address of peer device */ + bool key_present; /*!< True if the link key value is valid; false otherwise */ + esp_link_key key; /*!< Link key associated with peer device */ + uint8_t key_type; /*!< The type of link key */ + bool success; /*!< True if authentication succeeded; false otherwise */ + esp_ble_auth_fail_rsn_t fail_reason; /*!< The HCI reason/error code for failure when success is false */ + esp_ble_addr_type_t addr_type; /*!< Peer device address type */ + esp_bt_dev_type_t dev_type; /*!< Device type */ + esp_ble_auth_req_t auth_mode; /*!< Authentication mode */ +} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */ /** * @brief union associated with ble security @@ -845,6 +880,10 @@ typedef uint8_t esp_ble_gap_adv_type_t; /// Extend advertising tx power, range: [-127, +126] dBm #define EXT_ADV_TX_PWR_NO_PREFERENCE (127) /*!< host has no preference for tx power */ + +/// max number of advertising sets to enable or disable +#define EXT_ADV_NUM_SETS_MAX (10) /*!< max evt instance num */ + /** * @brief ext adv parameters */ @@ -1030,6 +1069,11 @@ typedef struct { } esp_ble_gap_past_params_t; #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +typedef enum{ + ESP_BLE_NETWORK_PRIVACY_MODE = 0X00, /*!< Network Privacy Mode for peer device (default) */ + ESP_BLE_DEVICE_PRIVACY_MODE = 0X01, /*!< Device Privacy Mode for peer device */ +} esp_ble_privacy_mode_t; + /** * @brief Gap callback parameters union */ @@ -1250,72 +1294,86 @@ typedef union { */ struct ble_ext_adv_set_rand_addr_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate extend advertising random address set status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_set_rand_addr; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT */ struct ble_ext_adv_set_params_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate extend advertising parameters set status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_set_params; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT */ struct ble_ext_adv_data_set_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate extend advertising data set status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_data_set; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT */ struct ble_ext_adv_scan_rsp_set_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate extend advertising scan response data set status */ + uint8_t instance; /*!< extend advertising handle */ } scan_rsp_set; /*!< Event parameter of ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT */ struct ble_ext_adv_start_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate advertising start operation success status */ + uint8_t instance_num; /*!< extend advertising handle numble*/ + uint8_t instance[EXT_ADV_NUM_SETS_MAX]; /*!< extend advertising handle list*/ } ext_adv_start; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT */ struct ble_ext_adv_stop_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate advertising stop operation success status */ + uint8_t instance_num; /*!< extend advertising handle numble*/ + uint8_t instance[EXT_ADV_NUM_SETS_MAX]; /*!< extend advertising handle list*/ } ext_adv_stop; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT */ struct ble_ext_adv_set_remove_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate advertising stop operation success status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_remove; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT */ struct ble_ext_adv_set_clear_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate advertising stop operation success status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_clear; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT */ struct ble_periodic_adv_set_params_cmpl_param { esp_bt_status_t status; /*!< Indicate periodic advertisingparameters set status */ + uint8_t instance; /*!< extend advertising handle */ } peroid_adv_set_params; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT */ struct ble_periodic_adv_data_set_cmpl_param { esp_bt_status_t status; /*!< Indicate periodic advertising data set status */ + uint8_t instance; /*!< extend advertising handle */ } period_adv_data_set; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT */ struct ble_periodic_adv_start_cmpl_param { esp_bt_status_t status; /*!< Indicate periodic advertising start status */ + uint8_t instance; /*!< extend advertising handle */ } period_adv_start; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT */ struct ble_periodic_adv_stop_cmpl_param { esp_bt_status_t status; /*!< Indicate periodic advertising stop status */ + uint8_t instance; /*!< extend advertising handle */ } period_adv_stop; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT @@ -1507,6 +1565,12 @@ typedef union { uint16_t param_len; /*!< The length of parameter buffer */ uint8_t *p_param_buf; /*!< The point of parameter buffer */ } vendor_cmd_cmpl; /*!< Event parameter of ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT + */ + struct ble_set_privacy_mode_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate privacy mode set operation success status */ + } set_privacy_mode_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT */ } esp_ble_gap_cb_param_t; /** @@ -2640,6 +2704,21 @@ esp_err_t esp_ble_gap_clear_advertising(void); */ esp_err_t esp_ble_gap_vendor_command_send(esp_ble_vendor_cmd_params_t *vendor_cmd_param); +/** + * @brief This function set the privacy mode of the device in resolving list. + * + * @note This feature is not supported on ESP32. + * + * @param[in] addr_type: The address type of the peer identity address (BLE_ADDR_TYPE_PUBLIC or BLE_ADDR_TYPE_RANDOM). + * @param[in] addr: The peer identity address of the device. + * @param[in] mode: The privacy mode of the device. + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_set_privacy_mode(esp_ble_addr_type_t addr_type, esp_bd_addr_t addr, esp_ble_privacy_mode_t mode); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h index 13bf16a32815..0c274e203216 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h @@ -299,10 +299,14 @@ esp_err_t esp_ble_gattc_app_register(uint16_t app_id); /** * @brief This function is called to unregister an application - * from GATTC module. + * from the GATTC module. * * @param[in] gattc_if: Gatt client access interface. * + * @note Before calling this API, ensure that all activities + * related to the application, such as connections, scans, ADV, + * are properly closed. + * * @return * - ESP_OK: success * - other: failed @@ -608,7 +612,7 @@ esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id, * * @param[in] gattc_if: Gatt client access interface. * @param[in] conn_id : connection ID. - * @param[in] handle : characteritic handle to read. + * @param[in] handle : characteristic handle to read. * @param[in] auth_req : authenticate request type * * @return diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index d478d12e48c8..ec2ce657fd96 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5419,6 +5419,10 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data) status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE); p_data->ble_scan.p_stop_scan_cback(status); } + + // reset BLE scan link state when stop scan + btm_ble_clear_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); + btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); } } @@ -5838,6 +5842,13 @@ void bta_dm_ble_gap_add_dev_to_resolving_list(tBTA_DM_MSG *p_data) p_data->add_dev_to_resolving_list.p_add_dev_to_resolving_list_callback); } +void bta_dm_ble_gap_set_privacy_mode(tBTA_DM_MSG *p_data) +{ + APPL_TRACE_API("%s, privacy_mode = %d", __func__, p_data->ble_set_privacy_mode.privacy_mode); + BTM_BleSetPrivacyMode(p_data->ble_set_privacy_mode.addr_type, p_data->ble_set_privacy_mode.addr, + p_data->ble_set_privacy_mode.privacy_mode, p_data->ble_set_privacy_mode.p_cback); +} + #if (BLE_50_FEATURE_SUPPORT == TRUE) void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data) { diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index a965edf81ba6..a2282cd9bc6b 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2679,6 +2679,21 @@ void BTA_DmBleDtmStop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) } } +void BTA_DmBleSetPrivacyMode(uint8_t addr_type, BD_ADDR addr, uint8_t privacy_mode, tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback) +{ + tBTA_DM_API_SET_PRIVACY_MODE *p_msg; + + if ((p_msg = (tBTA_DM_API_SET_PRIVACY_MODE *)osi_malloc(sizeof(tBTA_DM_API_SET_PRIVACY_MODE))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_SET_PRIVACY_MODE_EVT; + p_msg->addr_type = addr_type; + memcpy(p_msg->addr, addr, sizeof(BD_ADDR)); + p_msg->privacy_mode = privacy_mode; + p_msg->p_cback = p_cback; + bta_sys_sendmsg(p_msg); + } +} + #endif /******************************************************************************* diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c index c6b62f3a6f77..5c7ee9bdede2 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c @@ -52,6 +52,18 @@ tBTE_APPL_CFG bte_appl_cfg = { BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE, BTM_BLE_OOB_DISABLE, }; + +void bta_dm_co_security_param_init(void) +{ + bte_appl_cfg.ble_auth_req = BTA_LE_AUTH_REQ_SC_MITM_BOND; + bte_appl_cfg.ble_io_cap = BTM_LOCAL_IO_CAPS_BLE; + bte_appl_cfg.ble_init_key = BTM_BLE_INITIATOR_KEY_SIZE; + bte_appl_cfg.ble_resp_key = BTM_BLE_RESPONDER_KEY_SIZE; + bte_appl_cfg.ble_max_key_size = BTM_BLE_MAX_KEY_SIZE; + bte_appl_cfg.ble_min_key_size = BTM_BLE_MIN_KEY_SIZE; + bte_appl_cfg.ble_accept_auth_enable = BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE; + bte_appl_cfg.oob_support = BTM_BLE_OOB_DISABLE; +}; #endif #if (defined CLASSIC_BT_INCLUDED && CLASSIC_BT_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 6242593c735e..99736d8ececb 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -234,6 +234,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_clear_adv, /* BTA_DM_API_BLE_CLEAR_ADV_EVT */ bta_dm_ble_gap_set_rpa_timeout, /* BTA_DM_API_SET_RPA_TIMEOUT_EVT */ bta_dm_ble_gap_add_dev_to_resolving_list, /* BTA_DM_API_ADD_DEV_TO_RESOLVING_LIST_EVT */ + bta_dm_ble_gap_set_privacy_mode, /* BTA_DM_API_SET_PRIVACY_MODE_EVT */ #endif }; diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index d756932a6ba4..f8548edea43d 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -225,6 +225,7 @@ enum { BTA_DM_API_BLE_CLEAR_ADV_EVT, BTA_DM_API_SET_RPA_TIMEOUT_EVT, BTA_DM_API_ADD_DEV_TO_RESOLVING_LIST_EVT, + BTA_DM_API_SET_PRIVACY_MODE_EVT, #endif BTA_DM_MAX_EVT }; @@ -950,6 +951,14 @@ typedef struct { tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback; } tBTA_DM_API_CLEAR_ADV; +typedef struct { + BT_HDR hdr; + tBLE_ADDR_TYPE addr_type; + BD_ADDR addr; + UINT8 privacy_mode; + tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback; +} tBTA_DM_API_SET_PRIVACY_MODE; + #endif /* BLE_INCLUDED */ /* data type for BTA_DM_API_REMOVE_ACL_EVT */ @@ -1355,6 +1364,7 @@ typedef union { tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start; tBTA_DM_API_BLE_DTM_STOP dtm_stop; tBTA_DM_API_CLEAR_ADV ble_clear_adv; + tBTA_DM_API_SET_PRIVACY_MODE ble_set_privacy_mode; #endif tBTA_DM_API_REMOVE_ACL remove_acl; @@ -1787,6 +1797,9 @@ extern void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data); extern void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data); extern void bta_dm_ble_update_duplicate_exceptional_list(tBTA_DM_MSG *p_data); +#if SMP_INCLUDED == TRUE +extern void bta_dm_co_security_param_init(void); +#endif #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE extern void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data); extern void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data); @@ -1802,6 +1815,7 @@ extern void bta_dm_ble_gap_dtm_stop(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_rpa_timeout(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_add_dev_to_resolving_list(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_set_privacy_mode(tBTA_DM_MSG *p_data); #if (BLE_50_FEATURE_SUPPORT == TRUE) extern void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_dtm_enhance_rx_start(tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c index b2302fa469fd..543b9b04bf41 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -63,7 +63,7 @@ static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data); static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb); -static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg); +void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg); static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda); static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested); static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data); @@ -154,7 +154,7 @@ void bta_gattc_disable(tBTA_GATTC_CB *p_cb) APPL_TRACE_DEBUG("bta_gattc_disable"); if (p_cb->state != BTA_GATTC_STATE_ENABLED) { - APPL_TRACE_ERROR("not enabled or disable in pogress"); + APPL_TRACE_ERROR("not enabled or disable in progress"); return; } @@ -227,7 +227,7 @@ void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data) if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_malloc(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) { p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT; p_buf->client_if = p_cb->cl_rcb[i].client_if; - APPL_TRACE_DEBUG("GATTC getbuf sucess.\n"); + APPL_TRACE_DEBUG("GATTC getbuf success.\n"); bta_sys_sendmsg(p_buf); status = BTA_GATT_OK; } else { @@ -841,6 +841,9 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data); } + // Please note that BTA_GATTC_CLOSE_EVT will run in the BTC task. + // because bta_gattc_deregister_cmpl did not execute as expected(this is a known issue), + // we will run it again in bta_gattc_clcb_dealloc_by_conn_id. if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) { bta_gattc_deregister_cmpl(p_clreg); } @@ -1672,7 +1675,7 @@ void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) ** Returns void ** *******************************************************************************/ -static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg) +void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg) { tBTA_GATTC_CB *p_cb = &bta_gattc_cb; tBTA_GATTC_IF client_if = p_clreg->client_if; @@ -2118,7 +2121,7 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify); } } else if (op == GATTC_OPTYPE_INDICATION) { - /* no one intersted and need ack? */ + /* no one interested and need ack? */ APPL_TRACE_DEBUG("%s no one interested, ack now", __func__); GATTC_SendHandleValueConfirm(conn_id, handle); } @@ -2235,7 +2238,7 @@ static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYP ** ** Function bta_gattc_init_clcb_conn ** -** Description Initaite a BTA CLCB connection +** Description Initiate a BTA CLCB connection ** ** Returns void ** @@ -2252,7 +2255,7 @@ void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda) return; } - /* initaite a new connection here */ + /* initiate a new connection here */ if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) { gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c index 2265e28293c5..b47a9d973345 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c @@ -160,7 +160,7 @@ UINT8 bta_gattc_num_reg_app(void) ** ** Function bta_gattc_find_clcb_by_cif ** -** Description get clcb by client interface and remote bd adddress +** Description get clcb by client interface and remote bd address ** ** Returns pointer to the clcb ** @@ -322,12 +322,18 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb) } } +extern void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg); void bta_gattc_clcb_dealloc_by_conn_id(UINT16 conn_id) { tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); if (p_clcb) { + tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb; bta_gattc_clcb_dealloc(p_clcb); + // there is a workaround: if there is no connect, we will reset it. + if (p_clreg && p_clreg->num_clcb == 0 && p_clreg->dereg_pending) { + bta_gattc_deregister_cmpl(p_clreg); + } } } @@ -517,7 +523,7 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) cmd_data->api_write.p_value = (UINT8 *)(cmd_data + 1); memcpy(cmd_data->api_write.p_value, p_data->api_write.p_value, len); } else { - APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__); + APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__); return FALSE; } } else { @@ -525,7 +531,7 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) memset(cmd_data, 0, sizeof(tBTA_GATTC_DATA)); memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA)); } else { - APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__); + APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__); return FALSE; } } @@ -919,7 +925,7 @@ BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda) ** ** Function bta_gattc_find_int_conn_clcb ** -** Description try to locate a clcb when an internal connecion event arrives. +** Description try to locate a clcb when an internal connection event arrives. ** ** Returns pointer to the clcb ** diff --git a/components/bt/host/bluedroid/bta/hd/bta_hd_act.c b/components/bt/host/bluedroid/bta/hd/bta_hd_act.c index 8f655d73fe24..220b86cf2f65 100644 --- a/components/bt/host/bluedroid/bta/hd/bta_hd_act.c +++ b/components/bt/host/bluedroid/bta/hd/bta_hd_act.c @@ -722,6 +722,26 @@ extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data) bta_sys_idle(BTA_ID_HD, 1, p_cback->addr); } +/******************************************************************************* + * + * Function bta_hd_open_failure + * + * Description + * + * Returns void + * + ******************************************************************************/ +extern void bta_hd_open_failure(tBTA_HD_DATA *p_data) +{ + tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data; + tBTA_HD cback_data = {0}; + + bdcpy(cback_data.conn.bda, p_cback->addr); + cback_data.conn.status = BTA_HD_ERROR; + cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED; + bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data); +} + /******************************************************************************* * * Function bta_hd_cback diff --git a/components/bt/host/bluedroid/bta/hd/bta_hd_main.c b/components/bt/host/bluedroid/bta/hd/bta_hd_main.c index a6a3b634c183..7faaf2d6cd31 100644 --- a/components/bt/host/bluedroid/bta/hd/bta_hd_main.c +++ b/components/bt/host/bluedroid/bta/hd/bta_hd_main.c @@ -62,6 +62,7 @@ enum { BTA_HD_VC_UNPLUG_DONE_ACT, BTA_HD_SUSPEND_ACT, BTA_HD_EXIT_SUSPEND_ACT, + BTA_HD_OPEN_FAILURE, BTA_HD_NUM_ACTIONS }; @@ -74,7 +75,7 @@ const tBTA_HD_ACTION bta_hd_action[] = { bta_hd_disconnect_act, bta_hd_add_device_act, bta_hd_remove_device_act, bta_hd_send_report_act, bta_hd_report_error_act, bta_hd_vc_unplug_act, bta_hd_open_act, bta_hd_close_act, bta_hd_intr_data_act, bta_hd_get_report_act, bta_hd_set_report_act, bta_hd_set_protocol_act, - bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act, + bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act, bta_hd_open_failure }; /* state table information */ @@ -118,7 +119,7 @@ const uint8_t bta_hd_st_idle[][BTA_HD_NUM_COLS] = { /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_ACT, BTA_HD_IDLE_ST}, /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_OPEN_ACT, BTA_HD_CONN_ST}, - /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, + /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_OPEN_FAILURE, BTA_HD_IDLE_ST}, /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, diff --git a/components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h b/components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h index 7a515970e684..48ac7ed846f4 100644 --- a/components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h +++ b/components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h @@ -164,5 +164,6 @@ extern void bta_hd_set_protocol_act(tBTA_HD_DATA *p_data); extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA *p_data); extern void bta_hd_suspend_act(tBTA_HD_DATA *p_data); extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data); +extern void bta_hd_open_failure(tBTA_HD_DATA *p_data); #endif diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index e2f4d374520b..75a819945964 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -437,6 +437,8 @@ typedef tBTM_SET_RPA_TIMEOUT_CMPL_CBACK tBTA_SET_RPA_TIMEOUT_CMPL_CBACK; typedef tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK tBTA_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK; +typedef tBTM_SET_PRIVACY_MODE_CMPL_CBACK tBTA_SET_PRIVACY_MODE_CMPL_CBACK; + typedef tBTM_CMPL_CB tBTA_CMPL_CB; typedef tBTM_VSC_CMPL tBTA_VSC_CMPL; @@ -2893,6 +2895,8 @@ extern void BTA_DmBleDtmTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t extern void BTA_DmBleDtmRxStart(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); extern void BTA_DmBleDtmStop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); +extern void BTA_DmBleSetPrivacyMode(uint8_t addr_type, BD_ADDR addr, uint8_t privacy_mode, tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback); + /******************************************************************************* ** ** Function BTA_DmBleSetStorageParams diff --git a/components/bt/host/bluedroid/btc/core/btc_main.c b/components/bt/host/bluedroid/btc/core/btc_main.c index 28f70b4b6a5d..c1c694b8a258 100644 --- a/components/bt/host/bluedroid/btc/core/btc_main.c +++ b/components/bt/host/bluedroid/btc/core/btc_main.c @@ -60,6 +60,7 @@ static void btc_init_bluetooth(void) #if (BLE_INCLUDED == TRUE) //load the ble local key which has been stored in the flash btc_dm_load_ble_local_keys(); + bta_dm_co_security_param_init(); #endif ///BLE_INCLUDED == TRUE #endif /* #if (SMP_INCLUDED) */ #if BTA_DYNAMIC_MEMORY diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 3ef4bd791690..464f032417c8 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -989,34 +989,48 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, case BTA_DM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT: msg.act = ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT; param.ext_adv_set_rand_addr.status = btc_btm_status_to_esp_status(params->set_ext_rand_addr.status); + param.ext_adv_set_rand_addr.instance = params->set_ext_rand_addr.instance; break; case BTA_DM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT; - param.ext_adv_set_rand_addr.status = btc_btm_status_to_esp_status(params->set_params.status); + param.ext_adv_set_params.status = btc_btm_status_to_esp_status(params->set_params.status); + param.ext_adv_set_params.instance = params->set_params.instance; break; } case BTA_DM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT; param.ext_adv_data_set.status = btc_btm_status_to_esp_status(params->adv_data_set.status); + param.ext_adv_data_set.instance = params->adv_data_set.instance; break; } case BTA_DM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT; param.scan_rsp_set.status = btc_btm_status_to_esp_status(params->scan_rsp_data_set.status); + param.scan_rsp_set.instance = params->scan_rsp_data_set.instance; break; } case BTA_DM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT; param.ext_adv_start.status = btc_btm_status_to_esp_status(params->adv_start.status); + for (UINT8 i = 0; i < params->adv_start.instance_num; i++) { + param.ext_adv_start.instance[i] = params->adv_start.instance[i]; + } + + param.ext_adv_start.instance_num = params->adv_start.instance_num; break; } case BTA_DM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT: msg.act = ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT; param.ext_adv_stop.status = btc_btm_status_to_esp_status(params->adv_start.status); + for (UINT8 i = 0; i < params->adv_start.instance_num; i++) { + param.ext_adv_stop.instance[i] = params->adv_start.instance[i]; + } + param.ext_adv_stop.instance_num = params->adv_start.instance_num; break; case BTA_DM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT: msg.act = ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT; param.ext_adv_remove.status = btc_btm_status_to_esp_status(params->adv_start.status); + param.ext_adv_remove.instance = params->adv_start.instance[0]; break; case BTA_DM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT: msg.act = ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT; @@ -1025,21 +1039,25 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, case BTA_DM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT; param.peroid_adv_set_params.status = btc_btm_status_to_esp_status(params->per_adv_set_params.status); + param.peroid_adv_set_params.instance = params->per_adv_set_params.instance; break; } case BTA_DM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT; param.period_adv_data_set.status = btc_btm_status_to_esp_status(params->per_adv_data_set.status); + param.period_adv_data_set.instance = params->per_adv_data_set.instance; break; } case BTA_DM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT; param.period_adv_start.status = btc_btm_status_to_esp_status(params->per_adv_start.status); + param.period_adv_start.instance = params->per_adv_start.instance; break; } case BTA_DM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT; param.period_adv_stop.status = btc_btm_status_to_esp_status(params->per_adv_stop.status); + param.period_adv_stop.instance = params->per_adv_stop.instance; break; } case BTA_DM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT: { @@ -1326,6 +1344,25 @@ static void btc_ble_vendor_hci_cmd_complete_callback(tBTA_VSC_CMPL *p_param) } } +static void btc_ble_set_privacy_mode_callback(UINT8 status) +{ + esp_ble_gap_cb_param_t param; + bt_status_t ret; + btc_msg_t msg = {0}; + + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT; + + param.set_privacy_mode_cmpl.status = btc_btm_status_to_esp_status(status); + + ret = btc_transfer_context(&msg, ¶m, sizeof(esp_ble_gap_cb_param_t), NULL, NULL); + + if (ret != BT_STATUS_SUCCESS) { + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + void btc_get_whitelist_size(uint16_t *length) { BTM_BleGetWhiteListSize(length); @@ -1504,6 +1541,13 @@ static void btc_ble_dtm_stop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) BTA_DmBleDtmStop(p_dtm_cmpl_cback); } +static void btc_ble_set_privacy_mode(uint8_t addr_type, + BD_ADDR addr, + uint8_t privacy_mode, + tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback) +{ + BTA_DmBleSetPrivacyMode(addr_type, addr, privacy_mode, p_cback); +} void btc_gap_ble_cb_handler(btc_msg_t *msg) { @@ -2354,6 +2398,10 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) arg->vendor_cmd_send.p_param_buf, btc_ble_vendor_hci_cmd_complete_callback); break; + case BTC_GAP_BLE_SET_PRIVACY_MODE: + btc_ble_set_privacy_mode(arg->set_privacy_mode.addr_type, arg->set_privacy_mode.addr, + arg->set_privacy_mode.privacy_mode, btc_ble_set_privacy_mode_callback); + break; default: break; } @@ -2364,6 +2412,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) //register connection parameter update callback void btc_gap_callback_init(void) { + BTM_BleRegiseterPktLengthChangeCallback(btc_set_pkt_length_callback); BTM_BleRegiseterConnParamCallback(btc_update_conn_param_callback); #if (BLE_50_FEATURE_SUPPORT == TRUE) BTM_BleGapRegisterCallback(btc_ble_5_gap_callback); diff --git a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c index d280f8f7ebca..0d99c030b663 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c +++ b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c @@ -261,7 +261,7 @@ static void btc_hd_deinit(void) } btc_hd_cb.service_dereg_active = FALSE; - // unresgister app will also relase the connection + // unregister app will also release the connection // and disable after receiving unregister event from lower layer if (is_hidd_app_register()) { btc_hd_unregister_app(true); @@ -844,6 +844,8 @@ void btc_hd_cb_handler(btc_msg_t *msg) // } // btc_storage_set_hidd((bt_bdaddr_t *)&p_data->conn.bda); btc_hd_cb.status = BTC_HD_CONNECTED; + } else if (p_data->conn.conn_status == BTA_HD_CONN_STATE_DISCONNECTED) { + btc_hd_cb.status = BTC_HD_DISCONNECTED; } param.open.status = p_data->conn.status; param.open.conn_status = p_data->conn.conn_status; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index d09d3c9fc59c..e540116de19f 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -105,6 +105,7 @@ typedef enum { BTC_GAP_BLE_ACT_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT, BTC_GAP_BLE_ACT_ADD_DEVICE_TO_RESOLVING_LIST, BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT, + BTC_GAP_BLE_SET_PRIVACY_MODE, } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ @@ -267,9 +268,15 @@ typedef union { uint8_t param_len; uint8_t *p_param_buf; } vendor_cmd_send; + // BTC_GAP_BLE_SET_PRIVACY_MODE + struct set_privacy_mode { + esp_ble_addr_type_t addr_type; + esp_bd_addr_t addr; + uint8_t privacy_mode; + } set_privacy_mode; } btc_ble_gap_args_t; -#if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_FEATURE_SUPPORT == TRUE) typedef union { struct read_phy_args { esp_bd_addr_t bd_addr; diff --git a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c index 5cd777c5a3ef..7c5157736a95 100644 --- a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c +++ b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c @@ -906,7 +906,6 @@ void btc_l2cap_cb_handler(btc_msg_t *msg) fixed_queue_enqueue(slot->rx.queue, p_data_buf, FIXED_QUEUE_MAX_TIMEOUT); } else { osi_free(p_data_buf); - break; } } osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); @@ -945,12 +944,11 @@ void btc_l2cap_cb_handler(btc_msg_t *msg) break; // to do disconnect } memset(p_data_buf, 0, count + sizeof(BT_HDR)); - p_data_buf->len = BTA_JvL2capRead(p_data->data_ind.handle, slot->id, p_data_buf->data, count); + p_data_buf->len = BTA_JvL2capRead(p_data->l2c_read.handle, slot->id, p_data_buf->data, count); if (p_data_buf->len > 0) { fixed_queue_enqueue(slot->rx.queue, p_data_buf, FIXED_QUEUE_MAX_TIMEOUT); } else { osi_free(p_data_buf); - break; } } osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); @@ -1060,7 +1058,7 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size) if (!enqueue_status) { BTC_TRACE_DEBUG("%s tx_len:%d, fd:%d\n", __func__, fixed_queue_length(slot->tx.queue), fd); osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); - //block untill under water level, be closed or time out + //block until under water level, be closed or time out tx_event_group_val = xEventGroupWaitBits(l2cap_local_param.tx_event_group, SLOT_WRITE_BIT(serial) | SLOT_CLOSE_BIT(serial), pdTRUE, pdFALSE, VFS_WRITE_TIMEOUT / portTICK_PERIOD_MS); diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index 81cfbaacdd3f..ee1f548db36d 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -218,7 +218,13 @@ #define UC_BT_SMP_MAX_BONDS 8 #endif -//Device Nane Maximum Length +#ifdef CONFIG_BT_BLE_SMP_ID_RESET_ENABLE +#define UC_BT_BLE_SMP_ID_RESET_ENABLE CONFIG_BT_BLE_SMP_ID_RESET_ENABLE +#else +#define UC_BT_BLE_SMP_ID_RESET_ENABLE FALSE +#endif + +//Device Name Maximum Length #ifdef CONFIG_BT_MAX_DEVICE_NAME_LEN #define UC_MAX_LOC_BD_NAME_LEN CONFIG_BT_MAX_DEVICE_NAME_LEN #else diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index 0adad84fb050..34ff48bc929e 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -290,6 +290,12 @@ #define SMP_SLAVE_CON_PARAMS_UPD_ENABLE FALSE #endif /* UC_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE */ +#if (UC_BT_BLE_SMP_ID_RESET_ENABLE) +#define BLE_SMP_ID_RESET_ENABLE TRUE +#else +#define BLE_SMP_ID_RESET_ENABLE FALSE +#endif + #ifdef UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP #define BLE_ADV_REPORT_FLOW_CONTROL (UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP && BLE_INCLUDED) #endif /* UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP */ @@ -569,7 +575,7 @@ #define BT_CLASSIC_BQB_INCLUDED FALSE #endif -/* This feature is used to eanble interleaved scan*/ +/* This feature is used to enable interleaved scan*/ #ifndef BTA_HOST_INTERLEAVE_SEARCH #define BTA_HOST_INTERLEAVE_SEARCH FALSE #endif @@ -1385,7 +1391,7 @@ #define GATT_CONFORMANCE_TESTING FALSE #endif -/* number of background connection device allowence, ideally to be the same as WL size +/* number of background connection device allowance, ideally to be the same as WL size */ #ifndef GATT_MAX_BG_CONN_DEV #define GATT_MAX_BG_CONN_DEV 8 /*MAX is 32*/ diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index 8f312e60a2df..47717803aea9 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -35,10 +35,6 @@ #include "esp_bluedroid_hci.h" #include "stack/hcimsgs.h" -#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) -#include "nimble/ble_hci_trans.h" -#endif - #if (C2H_FLOW_CONTROL_INCLUDED == TRUE) #include "l2c_int.h" #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE @@ -541,6 +537,26 @@ static void host_send_pkt_available_cb(void) hci_downstream_data_post(OSI_THREAD_MAX_TIMEOUT); } + +void bt_record_hci_data(uint8_t *data, uint16_t len) +{ +#if (BT_HCI_LOG_INCLUDED == TRUE) + if ((data[0] == DATA_TYPE_EVENT) && (data[1] == HCI_BLE_EVENT) && ((data[3] == HCI_BLE_ADV_PKT_RPT_EVT) || (data[3] == HCI_BLE_DIRECT_ADV_EVT) +#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) + || (data[3] == HCI_BLE_ADV_DISCARD_REPORT_EVT) +#endif // (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) + #if (BLE_50_FEATURE_SUPPORT == TRUE) + || (data[3] == HCI_BLE_EXT_ADV_REPORT_EVT) || (data[3] == HCI_BLE_PERIOD_ADV_REPORT_EVT) +#endif // (BLE_50_FEATURE_SUPPORT == TRUE) + )) { + bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2); + } else { + uint8_t data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]); + bt_hci_log_record_hci_data(data_type, &data[1], len - 1); + } +#endif // (BT_HCI_LOG_INCLUDED == TRUE) +} + static int host_recv_pkt_cb(uint8_t *data, uint16_t len) { //Target has packet to host, malloc new buffer for packet @@ -552,13 +568,11 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) return 0; } + bt_record_hci_data(data, len); + bool is_adv_rpt = host_recv_adv_packet(data); if (!is_adv_rpt) { -#if (BT_HCI_LOG_INCLUDED == TRUE) - uint8_t data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]); - bt_hci_log_record_hci_data(data_type, data, len); -#endif // (BT_HCI_LOG_INCLUDED == TRUE) pkt_size = BT_HDR_SIZE + len; pkt = (BT_HDR *) osi_calloc(pkt_size); if (!pkt) { @@ -572,10 +586,6 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) memcpy(pkt->data, data, len); fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT); } else { -#if (BT_HCI_LOG_INCLUDED == TRUE) - // data type is adv report - bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, data, len); -#endif // (BT_HCI_LOG_INCLUDED == TRUE) #if !BLE_ADV_REPORT_FLOW_CONTROL // drop the packets if pkt_queue length goes beyond upper limit if (pkt_queue_length(hci_hal_env.adv_rpt_q) > HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX) { @@ -608,42 +618,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) return 0; } -#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) - -int -ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg) -{ - if(esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) { - ble_hci_trans_buf_free(hci_ev); - return 0; - } - uint16_t len = hci_ev[1] + 3; - uint8_t *data = (uint8_t *)malloc(len); - assert(data != NULL); - data[0] = 0x04; - memcpy(&data[1], hci_ev, len - 1); - ble_hci_trans_buf_free(hci_ev); - host_recv_pkt_cb(data, len); - free(data); - return 0; -} - - -int -ble_hs_rx_data(struct os_mbuf *om, void *arg) -{ - uint16_t len = OS_MBUF_PKTHDR(om)->omp_len + 1; - uint8_t *data = (uint8_t *)malloc(len); - assert(data != NULL); - data[0] = 0x02; - os_mbuf_copydata(om, 0, len - 1, &data[1]); - host_recv_pkt_cb(data, len); - free(data); - os_mbuf_free_chain(om); - return 0; -} -#endif static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb = { .notify_host_send_available = host_send_pkt_available_cb, .notify_host_recv = host_recv_pkt_cb, diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index 334001fe7b97..0d1e8fd6268b 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -217,7 +217,7 @@ void BTM_BleLoadLocalKeys(UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key) break; default: - BTM_TRACE_ERROR("unknow local key type: %d", key_type); + BTM_TRACE_ERROR("unknown local key type: %d", key_type); break; } } @@ -694,7 +694,7 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR BTM_TRACE_DEBUG ("btm_find_dev_type - unknown device, BR/EDR assumed"); } } - } else { /* there is a security device record exisitng */ + } else { /* there is a security device record existing */ /* new inquiry result, overwrite device type in security device record */ if (p_inq_info) { p_dev_rec->device_type = p_inq_info->results.device_type; @@ -707,7 +707,7 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR } else if (memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) == 0) { *p_dev_type = BT_DEVICE_TYPE_BLE; *p_addr_type = p_dev_rec->ble.ble_addr_type; - } else { /* matching static adddress only */ + } else { /* matching static address only */ *p_dev_type = BT_DEVICE_TYPE_BREDR; *p_addr_type = BLE_ADDR_PUBLIC; } @@ -1061,7 +1061,7 @@ tBTM_SEC_ACTION btm_ble_determine_security_act(BOOLEAN is_originator, BD_ADDR bd ** LE link for LE COC. ** ** Parameter bdaddr: remote device address. -** psm : PSM of the LE COC sevice. +** psm : PSM of the LE COC service. ** is_originator: TRUE if outgoing connection. ** p_callback : Pointer to the callback function. ** p_ref_data : Pointer to be returned along with the callback. @@ -1078,7 +1078,7 @@ BOOLEAN btm_ble_start_sec_check(BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_originat /* If there is no application registered with this PSM do not allow connection */ if (!p_serv_rec) { - BTM_TRACE_WARNING ("%s PSM: %d no application registerd", __func__, psm); + BTM_TRACE_WARNING ("%s PSM: %d no application registered", __func__, psm); (*p_callback) (bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_MODE_UNSUPPORTED); return FALSE; } @@ -1151,7 +1151,7 @@ void btm_ble_rand_enc_complete (UINT8 *p, UINT16 op_code, tBTM_RAND_ENC_CB *p_en /* If there was a callback address for vcs complete, call it */ if (p_enc_cplt_cback && p) { - /* Pass paramters to the callback function */ + /* Pass parameters to the callback function */ STREAM_TO_UINT8(params.status, p); /* command status */ if (params.status == HCI_SUCCESS) { @@ -1208,7 +1208,7 @@ void btm_ble_increment_sign_ctr(BD_ADDR bd_addr, BOOLEAN is_local ) ** Function btm_ble_get_enc_key_type ** ** Description This function is to get the BLE key type that has been exchanged -** in betweem local device and peer device. +** in between local device and peer device. ** ** Returns p_key_type: output parameter to carry the key type value. ** @@ -1235,7 +1235,7 @@ BOOLEAN btm_ble_get_enc_key_type(BD_ADDR bd_addr, UINT8 *p_key_types) ** ** Description This function is called to read the local DIV ** -** Returns TRUE - if a valid DIV is availavle +** Returns TRUE - if a valid DIV is available *******************************************************************************/ BOOLEAN btm_get_local_div (BD_ADDR bd_addr, UINT16 *p_div) { @@ -1487,7 +1487,7 @@ void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE BTM_TRACE_DEBUG ("dev_rec sec_flags=0x%x", p_dev_rec->sec_flags); - /* currently encrpted */ + /* currently encrypted */ if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED) { if (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED) { cur_sec_level = BTM_LE_SEC_AUTHENTICATED; @@ -1691,7 +1691,7 @@ tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk) ** ** Function btm_ble_link_encrypted ** -** Description This function is called when LE link encrption status is changed. +** Description This function is called when LE link encryption status is changed. ** ** Returns void ** @@ -1949,7 +1949,7 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void *p_rec, void *p_data) ** Function btm_ble_connected ** ** Description This function is when a LE connection to the peer device is -** establsihed +** established ** ** Returns void ** @@ -2060,7 +2060,7 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced) peer_addr_type = bda_type; match = btm_identity_addr_to_random_pseudo (bda, &bda_type, FALSE); - /* possiblly receive connection complete with resolvable random on + /* possibly receive connection complete with resolvable random on slave role while the device has been paired */ /* It will cause that scanner doesn't send scan request to advertiser @@ -2143,6 +2143,16 @@ void btm_ble_create_ll_conn_complete (UINT8 status) if (status != HCI_SUCCESS) { btm_ble_set_conn_st(BLE_CONN_IDLE); btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status); + if(l2cb.is_ble_connecting) { + /* see L2CA_CancelBleConnectReq() */ + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(l2cb.ble_connecting_bda, BT_TRANSPORT_LE); + /* Do not remove lcb if an LE link is already up as a peripheral */ + if (p_lcb != NULL && + !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_ACL_IS_CONNECTED(l2cb.ble_connecting_bda))) { + p_lcb->disc_reason = L2CAP_CONN_CANCEL; + l2cu_release_lcb (p_lcb); + } + } } } @@ -2300,7 +2310,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) ** Function BTM_BleDataSignature ** ** Description This function is called to sign the data using AES128 CMAC -** algorith. +** algorithm. ** ** Parameter bd_addr: target device the data to be signed for. ** p_text: singing data @@ -2308,7 +2318,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) ** signature: output parameter where data signature is going to ** be stored. ** -** Returns TRUE if signing sucessul, otherwise FALSE. +** Returns TRUE if signing successful, otherwise FALSE. ** *******************************************************************************/ #if (SMP_INCLUDED == TRUE) @@ -2491,7 +2501,7 @@ BOOLEAN BTM_BleSecurityProcedureIsRunning(BD_ADDR bd_addr) ** Function BTM_BleGetSupportedKeySize ** ** Description This function gets the maximum encryption key size in bytes -** the local device can suport. +** the local device can support. ** record. ** ** Returns the key size or 0 if the size can't be retrieved. diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 04ad4804bdbc..f595e3e6efbf 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -340,8 +340,8 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr) } end: - cb_params.status = status; - + cb_params.set_ext_rand_addr.status = status; + cb_params.set_ext_rand_addr.instance = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, &cb_params); return status; @@ -420,7 +420,8 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr); } } - cb_params.status = status; + cb_params.set_params.status = status; + cb_params.set_params.instance = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params); return status; @@ -471,7 +472,14 @@ tBTM_STATUS BTM_BleConfigExtendedAdvDataRaw(BOOLEAN is_scan_rsp, UINT8 instance, } while (rem_len); end: - cb_params.status = status; + if (is_scan_rsp) { + cb_params.scan_rsp_data_set.status = status; + cb_params.scan_rsp_data_set.instance = instance; + } else { + cb_params.adv_data_set.status = status; + cb_params.adv_data_set.instance = instance; + } + BTM_ExtBleCallbackTrigger(is_scan_rsp ? BTM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT, &cb_params); return status; @@ -574,7 +582,12 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ } } - cb_params.status = status; + cb_params.adv_start.status = status; + cb_params.adv_start.instance_num = num; + for (uint8_t i = 0; i < num; i++) { + cb_params.adv_start.instance[i] = ext_adv[i].instance; + } + BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT, &cb_params); return status; @@ -629,7 +642,9 @@ tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance) end: - cb_params.status = status; + cb_params.adv_start.status = status; + cb_params.adv_start.instance_num = 1; + cb_params.adv_start.instance[0] = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT, &cb_params); @@ -655,7 +670,7 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void) } } - cb_params.status = status; + cb_params.adv_start.status = status; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT, &cb_params); @@ -693,7 +708,8 @@ tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Pa end: - cb_params.status = status; + cb_params.per_adv_set_params.status = status; + cb_params.per_adv_set_params.instance = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params); @@ -747,7 +763,9 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data } while(rem_len); end: - cb_params.status = status; + cb_params.per_adv_data_set.status = status; + cb_params.per_adv_data_set.instance = instance; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, &cb_params); return status; @@ -771,8 +789,13 @@ tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, UINT8 enable) } end: - - cb_params.status = status; + if (enable) { + cb_params.per_adv_start.status = status; + cb_params.per_adv_start.instance = instance; + } else { + cb_params.per_adv_stop.status = status; + cb_params.per_adv_stop.instance = instance; + } BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT, &cb_params); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 3de3f7c10459..165a7893840e 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -70,7 +70,7 @@ static tBTM_BLE_VSC_CB *cmn_ble_gap_vsc_cb_ptr; static tBTM_BLE_CTRL_FEATURES_CBACK *p_ctrl_le_feature_rd_cmpl_cback = NULL; #endif -tBTM_CallbackFunc conn_param_update_cb; +tBTM_CallbackFunc conn_callback_func; /******************************************************************************* ** Local functions *******************************************************************************/ @@ -309,7 +309,21 @@ void btm_ble_sem_free(void) *******************************************************************************/ void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb) { - conn_param_update_cb.update_conn_param_cb = update_conn_param_cb; + conn_callback_func.update_conn_param_cb = update_conn_param_cb; +} + +/******************************************************************************* +** +** Function BTM_BleRegiseterPktLengthChangeCallback +** +** Description Registers a callback function for packet length changes. +** +** Returns void +** +*******************************************************************************/ +void BTM_BleRegiseterPktLengthChangeCallback(tBTM_SET_PKT_DATA_LENGTH_CBACK *ptk_len_chane_cb) +{ + conn_callback_func.set_pkt_data_length_cb = ptk_len_chane_cb; } /******************************************************************************* @@ -374,6 +388,12 @@ void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy) &p_cb->adv_addr_type); } + uint8_t null_addr[BD_ADDR_LEN] = {0}; + if ((p_cb->evt_type == 0x01 || p_cb->evt_type == 0x04) && memcmp(p_addr_ptr, null_addr, BD_ADDR_LEN) == 0) { + /* directed advertising */ + return; + } + btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_SLOW_INT), (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : @@ -3989,6 +4009,9 @@ static void btm_ble_stop_discover(void) if(btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE)) { osi_sem_take(&scan_enable_sem, OSI_SEM_MAX_TIMEOUT); } + /* reset status */ + btm_ble_clear_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); + btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); } if (p_scan_cb) { @@ -4727,6 +4750,17 @@ BOOLEAN BTM_BleAddDevToResolvingList(BD_ADDR addr, return TRUE; } +BOOLEAN BTM_BleSetPrivacyMode(UINT8 addr_type, BD_ADDR bd_addr, UINT8 privacy_mode, tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_callback) +{ + if (btsnd_hcic_ble_set_privacy_mode(addr_type, bd_addr, privacy_mode) != TRUE) { + BTM_TRACE_ERROR("LE SetPrivacyMode Mode=%d: error", privacy_mode); + return FALSE; + } + + btm_cb.devcb.p_set_privacy_mode_cmpl_cb = p_callback; + return TRUE; +} + bool btm_ble_adv_pkt_ready(void) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c index 4c8ff6520707..9ddf746ae9b1 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c @@ -330,7 +330,7 @@ void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len) BTM_TRACE_DEBUG("%s status = %d", __func__, status); if (!btm_ble_deq_resolving_pending(pseudo_bda)) { - BTM_TRACE_ERROR("%s no pending resolving list operation", __func__); + BTM_TRACE_DEBUG("%s no pending resolving list operation", __func__); return; } @@ -454,6 +454,34 @@ void btm_ble_set_rpa_timeout_complete(UINT8 *p, UINT16 evt_len) } +/******************************************************************************* +** +** Function btm_ble_set_privacy_mode_complete +** +** Description This function is called when the LE Set Privacy Mode command completes. +** +** Parameters p: Pointer to the command complete event data. +** evt_len: Length of the event data. +** +** Returns void +** +*******************************************************************************/ +void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len) +{ + UINT8 status; + + // Extract the status of the command completion from the event data + STREAM_TO_UINT8(status, p); + + BTM_TRACE_DEBUG("%s status = 0x%x", __func__, status); + + tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_cb = btm_cb.devcb.p_set_privacy_mode_cmpl_cb; + + if (p_cb) { + (*p_cb)(status); + } +} + /******************************************************************************* VSC that implement controller based privacy ********************************************************************************/ @@ -1119,6 +1147,9 @@ void btm_ble_add_default_entry_to_resolving_list(void) BD_ADDR peer_addr = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; BT_OCTET16 peer_irk = {0x0}; + // Remove the existing entry in resolving list When resetting the device identity + btsnd_hcic_ble_rm_device_resolving_list(BLE_ADDR_PUBLIC, peer_addr); + btsnd_hcic_ble_add_device_resolving_list (BLE_ADDR_PUBLIC, peer_addr, peer_irk, btm_cb.devcb.id_keys.irk); } #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_dev.c b/components/bt/host/bluedroid/stack/btm/btm_dev.c index f9e3ed2bd4c9..169dcc14494a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_dev.c +++ b/components/bt/host/bluedroid/stack/btm/btm_dev.c @@ -179,20 +179,31 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, *******************************************************************************/ BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport) { - tBTM_SEC_DEV_REC *p_dev_rec; if (BTM_IsAclConnectionUp(bd_addr, transport)) { BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active\n", __func__); return FALSE; } + if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL) { /* Tell controller to get rid of the link key, if it has one stored */ BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL); - btm_sec_free_dev(p_dev_rec, transport); + btm_sec_free_dev(p_dev_rec, transport); } +#if (BLE_SMP_ID_RESET_ENABLE == TRUE) + /* + * There are tracking risks associated with using a fixed or static IRK. + * A best-practices approach, when all pairing and bonding records are deleted, + * assign a new randomly-generated IRK. + */ + if (list_is_empty(btm_cb.p_sec_dev_rec_list)) { + btm_ble_reset_id(); + } +#endif + return TRUE; } @@ -640,7 +651,7 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) tBTM_SEC_DEV_REC *p_dev_rec = NULL; tBTM_SEC_DEV_REC *p_oldest = NULL; list_node_t *p_node = NULL; - UINT32 ot = 0xFFFFFFFF; + UINT32 old_ts = 0xFFFFFFFF; /* First look for the non-paired devices for the oldest entry */ for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { @@ -650,13 +661,13 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) continue; /* Device is paired so skip it */ } - if (p_dev_rec->timestamp < ot) { + if (p_dev_rec->timestamp < old_ts) { p_oldest = p_dev_rec; - ot = p_dev_rec->timestamp; + old_ts = p_dev_rec->timestamp; } } - if (ot != 0xFFFFFFFF) { + if (old_ts != 0xFFFFFFFF) { return (p_oldest); } @@ -666,9 +677,9 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) continue; } - if (p_dev_rec->timestamp < ot) { + if (p_dev_rec->timestamp < old_ts) { p_oldest = p_dev_rec; - ot = p_dev_rec->timestamp; + old_ts = p_dev_rec->timestamp; } } return (p_oldest); diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index dd42cefcac09..0f8888fb1bd1 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -497,6 +497,7 @@ void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask); void btm_ble_resolving_list_init(UINT8 max_irk_list_sz); void btm_ble_resolving_list_cleanup(void); void btm_ble_add_default_entry_to_resolving_list(void); +void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len); #endif void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst); diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index f8ed2d86bec3..3d01a5c2d487 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -237,6 +237,9 @@ tBTM_SET_RPA_TIMEOUT_CMPL_CBACK *p_ble_set_rpa_timeout_cmpl_cb; /* Callback fun ble set rpa timeout is completed */ tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *p_add_dev_to_resolving_list_cmpl_cb; + +tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_set_privacy_mode_cmpl_cb; + tBTM_CMPL_CB *p_le_test_cmd_cmpl_cb; /* Callback function to be called when LE test mode command has been sent successfully */ @@ -970,9 +973,11 @@ typedef struct { typedef struct{ //connection parameters update callback tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb; + // setting packet data length callback + tBTM_SET_PKT_DATA_LENGTH_CBACK *set_pkt_data_length_cb; }tBTM_CallbackFunc; -extern tBTM_CallbackFunc conn_param_update_cb; +extern tBTM_CallbackFunc conn_callback_func; /* security action for L2CAP COC channels */ #define BTM_SEC_OK 1 #define BTM_SEC_ENCRYPT 2 /* encrypt the link with current key */ diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 43ec8b1b7f07..9da6b9d7a92d 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1100,6 +1100,10 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l case HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT: btm_ble_set_rpa_timeout_complete(p, evt_len); break; + case HCI_BLE_SET_PRIVACY_MODE: + btm_ble_set_privacy_mode_complete(p, evt_len); + break; +#endif // #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) #if (BLE_50_FEATURE_SUPPORT == TRUE) case HCI_BLE_SET_EXT_ADV_PARAM: case HCI_BLE_SET_EXT_ADV_DATA: @@ -1139,7 +1143,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) -#endif #endif /* (BLE_INCLUDED == TRUE) */ default: { @@ -1252,6 +1255,9 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context) static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_cmd, void *p_vsc_status_cback) { + if (status != HCI_SUCCESS){ + HCI_TRACE_WARNING("%s,opcode:0x%04x,status:0x%02x", __func__, opcode,status); + } BD_ADDR bd_addr; UINT16 handle; #if BTM_SCO_INCLUDED == TRUE @@ -1373,6 +1379,9 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c break; #if BLE_INCLUDED == TRUE +#if (BLE_50_FEATURE_SUPPORT == TRUE) + case HCI_BLE_EXT_CREATE_CONN: +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) case HCI_BLE_CREATE_LL_CONN: btm_ble_create_ll_conn_complete(status); break; @@ -1465,7 +1474,6 @@ static void btu_hcif_command_status_evt(uint8_t status, BT_HDR *command, void *c hack->context = context; event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK; - if (btu_task_post(SIG_BTU_HCI_MSG, event, OSI_THREAD_MAX_TIMEOUT) == false) { osi_free(event); } diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 0f6408f0826e..52a2b2dc09ef 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1909,4 +1909,28 @@ UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + +UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_SET_PRIVACY_MODE)) == NULL) { + return (FALSE); + } + + pp = (UINT8 *)(p + 1); + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_PRIVACY_MODE; + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PRIVACY_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PRIVACY_MODE); + + UINT8_TO_STREAM(pp, addr_type); + BDADDR_TO_STREAM(pp, addr); + UINT8_TO_STREAM(pp, privacy_mode); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} #endif diff --git a/components/bt/host/bluedroid/stack/hid/hidd_conn.c b/components/bt/host/bluedroid/stack/hid/hidd_conn.c index 3b44402eed1b..5a8e36ee599c 100644 --- a/components/bt/host/bluedroid/stack/hid/hidd_conn.c +++ b/components/bt/host/bluedroid/stack/hid/hidd_conn.c @@ -231,7 +231,7 @@ static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result) tHID_CONN *p_hcon = &hd_cb.device.conn; HIDD_TRACE_EVENT("%s: cid=%04x result=%d, conn_state=%d", __func__, cid, result, p_hcon->conn_state); if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) || @@ -243,10 +243,12 @@ static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result) } if (result != L2CAP_CONN_OK) { HIDD_TRACE_WARNING("%s: connection failed, now disconnect", __func__); - if (cid == p_hcon->ctrl_cid) + if (cid == p_hcon->ctrl_cid) { p_hcon->ctrl_cid = 0; - else + } else { p_hcon->intr_cid = 0; + } + hidd_conn_disconnect(); hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_L2CAP_CONN_FAIL | (uint32_t)result, NULL); return; @@ -278,7 +280,7 @@ static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO *p_cfg) HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid); p_hcon = &hd_cb.device.conn; if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_DEV_MTU_SIZE)) @@ -297,7 +299,8 @@ static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO *p_cfg) // update flags if (cid == p_hcon->ctrl_cid) { p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE; - if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) { + if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE) && + (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) { p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; if ((p_hcon->intr_cid = L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) { p_hcon->conn_state = HID_CONN_STATE_UNUSED; @@ -330,7 +333,7 @@ static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO *p_cfg) HIDD_TRACE_EVENT("%s: cid=%04x pcfg->result=%d", __func__, cid, p_cfg->result); p_hcon = &hd_cb.device.conn; if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if (p_hcon->intr_cid == cid && p_cfg->result == L2CAP_CFG_UNACCEPTABLE_PARAMS && p_cfg->qos_present) { @@ -357,7 +360,8 @@ static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO *p_cfg) // update flags if (cid == p_hcon->ctrl_cid) { p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE; - if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE)) { + if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE) && + (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) { p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; if ((p_hcon->intr_cid = L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) { p_hcon->conn_state = HID_CONN_STATE_UNUSED; @@ -389,11 +393,14 @@ static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed) HIDD_TRACE_EVENT("%s: cid=%04x ack_needed=%d", __func__, cid, ack_needed); p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } - if (ack_needed) + + if (ack_needed) { L2CA_DisconnectRsp(cid); + } + if (cid == p_hcon->ctrl_cid) { p_hcon->ctrl_cid = 0; p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_CTRL; @@ -417,7 +424,7 @@ static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed) * * Function hidd_l2cif_disconnect_cfm * - * Description Handles L2CAP disconection response + * Description Handles L2CAP disconnection response * * Returns void * @@ -428,7 +435,7 @@ static void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result) HIDD_TRACE_EVENT("%s: cid=%04x result=%d", __func__, cid, result); p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if (cid == p_hcon->ctrl_cid) { @@ -465,7 +472,7 @@ static void hidd_l2cif_cong_ind(uint16_t cid, bool congested) HIDD_TRACE_EVENT("%s: cid=%04x congested=%d", __func__, cid, congested); p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if (congested) { @@ -492,7 +499,7 @@ static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR *p_msg) HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid); p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); osi_free(p_msg); return; } @@ -645,7 +652,7 @@ tHID_STATUS hidd_conn_initiate(void) p_dev->conn.ctrl_cid = 0; p_dev->conn.intr_cid = 0; p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL; - p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG; + p_dev->conn.conn_flags |= HID_CONN_FLAGS_IS_ORIG; BTM_SetOutService(p_dev->addr, BTM_SEC_SERVICE_HIDD_SEC_CTRL, HIDD_SEC_CHN); /* Check if L2CAP started the connection process */ if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq(HID_PSM_CONTROL, p_dev->addr)) == 0) { diff --git a/components/bt/host/bluedroid/stack/hid/hidh_api.c b/components/bt/host/bluedroid/stack/hid/hidh_api.c index bacc5a016af3..ec072845ea68 100644 --- a/components/bt/host/bluedroid/stack/hid/hidh_api.c +++ b/components/bt/host/bluedroid/stack/hid/hidh_api.c @@ -379,7 +379,6 @@ tHID_STATUS HID_HostAddDev ( BD_ADDR addr, UINT16 attr_mask, UINT8 *handle ) if (!hh_cb.devices[i].in_use) { hh_cb.devices[i].in_use = TRUE; hh_cb.devices[i].delay_remove = FALSE; - hh_cb.devices[i].is_orig = FALSE; memcpy( hh_cb.devices[i].addr, addr, sizeof( BD_ADDR ) ) ; hh_cb.devices[i].state = HID_DEV_NO_CONN; hh_cb.devices[i].conn_tries = 0 ; @@ -487,7 +486,6 @@ tHID_STATUS HID_HostOpenDev ( UINT8 dev_handle ) } hh_cb.devices[dev_handle].conn_tries = 1; - hh_cb.devices[dev_handle].is_orig = TRUE; return hidh_conn_initiate( dev_handle ); } @@ -666,7 +664,7 @@ BOOLEAN HID_HostConnectOrig(UINT8 dev_handle) break; } - ret = hh_cb.devices[dev_handle].is_orig; + ret = hidh_conn_is_orig(dev_handle); } while (0); return ret; diff --git a/components/bt/host/bluedroid/stack/hid/hidh_conn.c b/components/bt/host/bluedroid/stack/hid/hidh_conn.c index 801f087cc5af..f9d4a47b6312 100644 --- a/components/bt/host/bluedroid/stack/hid/hidh_conn.c +++ b/components/bt/host/bluedroid/stack/hid/hidh_conn.c @@ -457,8 +457,8 @@ static void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) if (l2cap_cid == p_hcon->ctrl_cid) { p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE; - if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && - (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) { + if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE) && + (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) { /* Connect interrupt channel */ p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */ if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0) { @@ -528,8 +528,8 @@ static void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) if (l2cap_cid == p_hcon->ctrl_cid) { p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE; - if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && - (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE)) { + if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE) && + (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) { /* Connect interrupt channel */ p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */ if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0) { @@ -968,7 +968,7 @@ tHID_STATUS hidh_conn_initiate (UINT8 dhandle) p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */ /* We are the originator of this connection */ - p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG; + p_dev->conn.conn_flags |= HID_CONN_FLAGS_IS_ORIG; if (p_dev->attr_mask & HID_SEC_REQUIRED) { service_id = BTM_SEC_SERVICE_HIDH_SEC_CTRL; @@ -989,6 +989,20 @@ tHID_STATUS hidh_conn_initiate (UINT8 dhandle) return ( HID_SUCCESS ); } +/******************************************************************************* +** +** Function hidh_conn_is_orig +** +** Description This function check if we are the originator of this connection +** +** Returns BOOLEAN +** +*******************************************************************************/ +BOOLEAN hidh_conn_is_orig(UINT8 dhandle) +{ + tHID_HOST_DEV_CTB *p_dev = &hh_cb.devices[dhandle]; + return (p_dev->conn.conn_flags & HID_CONN_FLAGS_IS_ORIG); +} /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/hid/include/hid_int.h b/components/bt/host/bluedroid/stack/hid/include/hid_int.h index 865aadf966bb..beaca21e72c5 100644 --- a/components/bt/host/bluedroid/stack/hid/include/hid_int.h +++ b/components/bt/host/bluedroid/stack/hid/include/hid_int.h @@ -35,7 +35,6 @@ enum { HID_DEV_NO_CONN, HID_DEV_CONNECTED }; typedef struct per_device_ctb { BOOLEAN in_use; BOOLEAN delay_remove; - BOOLEAN is_orig; BD_ADDR addr; /* BD-Addr of the host device */ UINT16 attr_mask; /* 0x01- virtual_cable; 0x02- normally_connectable; 0x03- reconn_initiate; 0x04- sdp_disable; */ @@ -66,6 +65,7 @@ extern tHID_STATUS hidh_conn_reg (void); extern void hidh_conn_dereg( void ); extern tHID_STATUS hidh_conn_disconnect (UINT8 dhandle); extern tHID_STATUS hidh_conn_initiate (UINT8 dhandle); +extern BOOLEAN hidh_conn_is_orig(UINT8 dhandle); extern void hidh_proc_repage_timeout (TIMER_LIST_ENT *p_tle); #ifdef __cplusplus extern "C" { diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index bf431ce6cd2a..1b3096428497 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -1006,6 +1006,8 @@ typedef void (tBTM_START_STOP_ADV_CMPL_CBACK) (UINT8 status); typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info); typedef void (tBTM_CLEAR_ADV_CMPL_CBACK) (UINT8 status); +typedef void (tBTM_SET_PRIVACY_MODE_CMPL_CBACK) (tBTM_STATUS status); + #if (BLE_50_FEATURE_SUPPORT == TRUE) #define BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT 1 #define BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT 2 @@ -1048,7 +1050,8 @@ typedef void (tBTM_CLEAR_ADV_CMPL_CBACK) (UINT8 status); #define BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT 38 #define BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT 39 #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) -#define BTM_BLE_5_GAP_UNKNOWN_EVT 40 +#define BTM_BLE_GAP_SET_PRIVACY_MODE_COMPLETE_EVT 40 +#define BTM_BLE_5_GAP_UNKNOWN_EVT 41 typedef UINT8 tBTM_BLE_5_GAP_EVENT; #define BTM_BLE_EXT_ADV_DATA_COMPLETE 0x00 @@ -1097,46 +1100,58 @@ typedef struct { typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_SET_PERF_PHY_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_SET_RAND_ADDR_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_SET_PARAMS_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_DATA_SET_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_SCAN_RSP_DATA_SET_CMPL; typedef struct { UINT8 status; + UINT8 instance_num; + UINT8 instance[10]; } tBTM_BLE_EXT_ADV_START_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_STOP_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_SET_PARAMS_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_DATA_SET_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_START_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_STOP_CMPL; typedef struct { @@ -1366,6 +1381,7 @@ extern "C" { ** *******************************************************************************/ void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb); +void BTM_BleRegiseterPktLengthChangeCallback(tBTM_SET_PKT_DATA_LENGTH_CBACK *ptk_len_chane_cb); /******************************************************************************* ** @@ -2689,6 +2705,25 @@ BOOLEAN BTM_BleAddDevToResolvingList(BD_ADDR addr, uint8_t irk[], tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *p_add_dev_to_resolving_list_callback); +/******************************************************************************* +** +** Function BTM_BleSetPrivacyMode +** +** Description This function is called to set the privacy mode of device in resolving list +** +** Parameters addr_type - The address type of the device in resolving list (public or random). +** addr - The address of the device in resolving list. +** privacy_mode - The privacy mode (network or device) of the device. +** p_callback - Callback function to be called when the operation is completed. +** +** Returns TRUE if the operation was successful, otherwise FALSE. +** +*******************************************************************************/ +BOOLEAN BTM_BleSetPrivacyMode(UINT8 addr_type, + BD_ADDR bd_addr, + UINT8 privacy_mode, + tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_callback); + /* #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 2f6ce5b767d2..21b148817399 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -384,8 +384,8 @@ #define HCI_BLE_RD_TRANSMIT_POWER (0x004B | HCI_GRP_BLE_CMDS) #define HCI_BLE_RD_RF_PATH_COMPENSATION (0x004C | HCI_GRP_BLE_CMDS) #define HCI_BLE_WR_RF_PATH_COMPENSATION (0x004D | HCI_GRP_BLE_CMDS) -#define HCI_BLE_SET_PRIVACY_MODE (0x004E | HCI_GRP_BLE_CMDS) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#define HCI_BLE_SET_PRIVACY_MODE (0x004E | HCI_GRP_BLE_CMDS) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE (0x0059 | HCI_GRP_BLE_CMDS) #define HCI_BLE_PERIOD_ADV_SYNC_TRANS (0x005A | HCI_GRP_BLE_CMDS) @@ -1134,18 +1134,18 @@ typedef UINT8 tHCI_STATUS; #define HCI_MIN_INQ_LAP 0x9E8B00 #define HCI_MAX_INQ_LAP 0x9E8B3F -/* HCI role defenitions */ +/* HCI role definitions */ #define HCI_ROLE_MASTER 0x00 #define HCI_ROLE_SLAVE 0x01 #define HCI_ROLE_UNKNOWN 0xff -/* HCI mode defenitions */ +/* HCI mode definitions */ #define HCI_MODE_ACTIVE 0x00 #define HCI_MODE_HOLD 0x01 #define HCI_MODE_SNIFF 0x02 #define HCI_MODE_PARK 0x03 -/* HCI Flow Control Mode defenitions */ +/* HCI Flow Control Mode definitions */ #define HCI_PACKET_BASED_FC_MODE 0x00 #define HCI_BLOCK_BASED_FC_MODE 0x01 @@ -1414,7 +1414,7 @@ typedef UINT8 tHCI_STATUS; /* Define an invalid value for a handle */ #define HCI_INVALID_HANDLE 0xFFFF -/* Define max ammount of data in the HCI command */ +/* Define max amount of data in the HCI command */ #define HCI_COMMAND_SIZE 255 /* Define the preamble length for all HCI Commands. diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index b7d64edd991a..951e5b703a7f 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -758,6 +758,7 @@ void btsnd_hcic_vendor_spec_cmd (BT_HDR *buffer, UINT16 opcode, #define HCIC_PARAM_SIZE_BLE_WRITE_EXTENDED_SCAN_PARAM 11 #define HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL 2 #define HCIC_PARAM_SIZE_BLE_CLEAR_ADV 0 +#define HCIC_PARAM_SIZE_SET_PRIVACY_MODE 8 #if (BLE_50_FEATURE_SUPPORT == TRUE) #define HCIC_PARAM_SIZE_BLE_READ_PHY 2 #define HCIC_PARAM_SIZE_BLE_SET_DEF_PHY 3 @@ -1041,6 +1042,8 @@ UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_ #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode); + #define HCIC_PARAM_SIZE_WRITE_AUTHENT_PAYLOAD_TOUT 4 #define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_HANDLE_OFF 0 diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 4e6c8534ec5f..956a4b7fb2cb 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -175,14 +175,14 @@ BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_in L2CAP_TRACE_ERROR("There are two connection parameter requests that are being updated, please try later "); } - if ((need_cb == TRUE) && (conn_param_update_cb.update_conn_param_cb != NULL)) { + if ((need_cb == TRUE) && (conn_callback_func.update_conn_param_cb != NULL)) { tBTM_LE_UPDATE_CONN_PRAMS update_param; update_param.max_conn_int = max_int; update_param.min_conn_int = min_int; update_param.conn_int = p_lcb->current_used_conn_interval; update_param.slave_latency = p_lcb->current_used_conn_latency; update_param.supervision_tout = p_lcb->current_used_conn_timeout; - (conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); + (conn_callback_func.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); return (status == HCI_SUCCESS); } @@ -287,7 +287,7 @@ UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr) ** ** Function l2cble_notify_le_connection ** -** Description This function notifiy the l2cap connection to the app layer +** Description This function notify the l2cap connection to the app layer ** ** Returns none ** @@ -647,7 +647,7 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_in p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL; btu_stop_timer(&p_lcb->upda_con_timer); - if (conn_param_update_cb.update_conn_param_cb != NULL) { + if (conn_callback_func.update_conn_param_cb != NULL) { l2c_send_update_conn_params_cb(p_lcb, status); } @@ -686,7 +686,7 @@ void l2cble_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handl btu_stop_timer (&p_lcb->upda_con_timer); - if (conn_param_update_cb.update_conn_param_cb != NULL) { + if (conn_callback_func.update_conn_param_cb != NULL) { l2c_send_update_conn_params_cb(p_lcb, status); } if ((p_lcb->conn_update_mask & L2C_BLE_UPDATE_PARAM_FULL) != 0){ @@ -868,7 +868,7 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) ** ** Function l2cble_init_direct_conn ** -** Description This function is to initate a direct connection +** Description This function is to initiate a direct connection ** ** Returns TRUE connection initiated, FALSE otherwise. ** @@ -894,7 +894,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) /* There can be only one BLE connection request outstanding at a time */ if (p_dev_rec == NULL) { - L2CAP_TRACE_WARNING ("unknown device, can not initate connection"); + L2CAP_TRACE_WARNING ("unknown device, can not initiate connection"); return (FALSE); } @@ -947,7 +947,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) if (!btm_ble_topology_check(BTM_BLE_STATE_INIT)) { l2cu_release_lcb (p_lcb); - L2CAP_TRACE_ERROR("initate direct connection fail, topology limitation"); + L2CAP_TRACE_ERROR("initiate direct connection fail, topology limitation"); return FALSE; } uint32_t link_timeout = L2CAP_BLE_LINK_CONNECT_TOUT; @@ -981,7 +981,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) BLE_CE_LEN_MIN, /* UINT16 min_len */ BLE_CE_LEN_MIN)) { /* UINT16 max_len */ l2cu_release_lcb (p_lcb); - L2CAP_TRACE_ERROR("initate direct connection fail, no resources"); + L2CAP_TRACE_ERROR("initiate direct connection fail, no resources"); return (FALSE); } else { p_lcb->link_state = LST_CONNECTING; @@ -1033,7 +1033,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) btm_ble_set_conn_st (BLE_DIR_CONN); if(!btsnd_hcic_ble_create_ext_conn(&aux_conn)) { l2cu_release_lcb (p_lcb); - L2CAP_TRACE_ERROR("initate Aux connection failed, no resources"); + L2CAP_TRACE_ERROR("initiate Aux connection failed, no resources"); } #else L2CAP_TRACE_ERROR("BLE 5.0 not support!\n"); @@ -1324,15 +1324,18 @@ void l2cble_process_data_length_change_event(UINT16 handle, UINT16 tx_data_len, if(p_acl) { p_acl->data_length_params = data_length_params; if (p_acl->p_set_pkt_data_cback) { + // Only when the corresponding API is called will the callback be registered (*p_acl->p_set_pkt_data_cback)(BTM_SUCCESS, &data_length_params); + } else { + // If the callback is not registered,using global callback + (*conn_callback_func.set_pkt_data_length_cb)(BTM_SUCCESS, &data_length_params); } - p_acl->data_len_updating = false; if(p_acl->data_len_waiting) { p_acl->data_len_waiting = false; p_acl->p_set_pkt_data_cback = p_acl->p_set_data_len_cback_waiting; p_acl->p_set_data_len_cback_waiting = NULL; - // if value is same, triger callback directly + // if value is same, trigger callback directly if(p_acl->tx_len_waiting == p_acl->data_length_params.tx_len) { if(p_acl->p_set_pkt_data_cback) { (*p_acl->p_set_pkt_data_cback)(BTM_SUCCESS, &p_acl->data_length_params); @@ -1396,7 +1399,7 @@ void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid, *******************************************************************************/ void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status) { - if(conn_param_update_cb.update_conn_param_cb != NULL){ + if(conn_callback_func.update_conn_param_cb != NULL){ tBTM_LE_UPDATE_CONN_PRAMS update_param; //if myself update the connection parameters if (p_lcb->updating_param_flag){ @@ -1412,7 +1415,7 @@ void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status) update_param.slave_latency = p_lcb->current_used_conn_latency; update_param.supervision_tout = p_lcb->current_used_conn_timeout; - (conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); + (conn_callback_func.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); } } diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index ac5a288f2a66..5bb08e5ac705 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -164,6 +164,16 @@ config BT_NIMBLE_NVS_PERSIST help Enable this flag to make bonding persistent across device reboots +config BT_NIMBLE_SMP_ID_RESET + bool "Reset device identity when all bonding records are deleted" + default n + help + There are tracking risks associated with using a fixed or static IRK. + If enabled this option, Bluedroid will assign a new randomly-generated IRK + when all pairing and bonding records are deleted. This would decrease the ability + of a previously paired peer to be used to determine whether a device + with which it previously shared an IRK is within range. + menuconfig BT_NIMBLE_SECURITY_ENABLE bool "Enable BLE SM feature" depends on BT_NIMBLE_ENABLED @@ -498,7 +508,6 @@ config BT_NIMBLE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y depends on BT_NIMBLE_ENABLED - select MBEDTLS_ECP_RESTARTABLE select MBEDTLS_CMAC_C help Enable this option to choose mbedTLS instead of TinyCrypt for crypto @@ -597,7 +606,7 @@ if BT_NIMBLE_EXT_ADV Enable this option to start periodic advertisement. config BT_NIMBLE_PERIODIC_ADV_SYNC_TRANSFER - bool "Enable Transer Sync Events" + bool "Enable Transfer Sync Events" depends on BT_NIMBLE_ENABLE_PERIODIC_ADV default y help @@ -666,7 +675,7 @@ config BT_NIMBLE_GATT_CACHING_MAX_DSCS depends on BT_NIMBLE_GATT_CACHING default 64 help - Set this option to set the upper limit on number of discriptors per connection to be cached. + Set this option to set the upper limit on number of descriptors per connection to be cached. config BT_NIMBLE_WHITELIST_SIZE int "BLE white list size" @@ -907,7 +916,6 @@ config BT_NIMBLE_OPTIMIZE_MULTI_CONN config BT_NIMBLE_ENC_ADV_DATA bool "Encrypted Advertising Data" - depends on SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV help This option is used to enable encrypted advertising data. diff --git a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c index 8dbe78c36aee..49d976865e7c 100644 --- a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c +++ b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c @@ -63,6 +63,13 @@ void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, ble_hci_rx_acl_hs_arg = acl_arg; } +void esp_vhci_host_send_packet_wrapper(uint8_t *data, uint16_t len) +{ +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_data(data[0], &data[1], len - 1); +#endif + esp_vhci_host_send_packet(data, len); +} int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) { @@ -77,10 +84,7 @@ int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) } if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { -#if (BT_HCI_LOG_INCLUDED == TRUE) - bt_hci_log_record_hci_data(cmd[0], cmd, len); -#endif - esp_vhci_host_send_packet(cmd, len); + esp_vhci_host_send_packet_wrapper(cmd, len); } else { rc = BLE_HS_ETIMEOUT_HCI; } @@ -117,10 +121,7 @@ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) len += OS_MBUF_PKTLEN(om); if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { -#if (BT_HCI_LOG_INCLUDED == TRUE) - bt_hci_log_record_hci_data(data[0], data, len); -#endif - esp_vhci_host_send_packet(data, len); + esp_vhci_host_send_packet_wrapper(data, len); } else { rc = BLE_HS_ETIMEOUT_HCI; } @@ -178,7 +179,6 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len) OS_EXIT_CRITICAL(sr); } - /* * @brief: BT controller callback function, used to notify the upper layer that * controller is ready to receive command @@ -190,11 +190,26 @@ static void controller_rcv_pkt_ready(void) } } +void bt_record_hci_data(uint8_t *data, uint16_t len) +{ +#if (BT_HCI_LOG_INCLUDED == TRUE) + if ((data[0] == BLE_HCI_UART_H4_EVT) && (data[1] == BLE_HCI_EVCODE_LE_META) && ((data[3] == BLE_HCI_LE_SUBEV_ADV_RPT) || (data[3] == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT) + || (data[3] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT) || (data[3] == BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT))) { + bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2); + } else { + uint8_t data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]); + bt_hci_log_record_hci_data(data_type, &data[1], len - 1); + } +#endif // (BT_HCI_LOG_INCLUDED == TRUE) +} + /* * @brief: BT controller callback function, to transfer data packet to the host */ static int host_rcv_pkt(uint8_t *data, uint16_t len) { + bt_record_hci_data(data, len); + if(!ble_hs_enabled_state) { /* If host is not enabled, drop the packet */ ESP_LOGE(TAG, "Host not enabled. Dropping the packet!"); @@ -223,18 +238,12 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) /* Allocate LE Advertising Report Event from lo pool only */ if ((data[1] == BLE_HCI_EVCODE_LE_META) && (data[3] == BLE_HCI_LE_SUBEV_ADV_RPT || data[3] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { -#if (BT_HCI_LOG_INCLUDED == TRUE) - bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, data, len); -#endif evbuf = ble_transport_alloc_evt(1); /* Skip advertising report if we're out of memory */ if (!evbuf) { return 0; } } else { -#if (BT_HCI_LOG_INCLUDED == TRUE) - bt_hci_log_record_hci_data(data[0], data, len); -#endif evbuf = ble_transport_alloc_evt(0); assert(evbuf != NULL); } @@ -245,9 +254,6 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) rc = ble_hci_trans_ll_evt_tx(evbuf); assert(rc == 0); } else if (data[0] == BLE_HCI_UART_H4_ACL) { -#if (BT_HCI_LOG_INCLUDED == TRUE) - bt_hci_log_record_hci_data(HCI_LOG_DATA_TYPE_C2H_ACL, data, len); -#endif ble_hci_rx_acl(data + 1, len - 1); } return 0; @@ -282,10 +288,6 @@ esp_err_t esp_nimble_hci_init(void) goto err; } -#if (BT_HCI_LOG_INCLUDED == TRUE) - bt_hci_log_init(); -#endif // (BT_HCI_LOG_INCLUDED == TRUE) - xSemaphoreGive(vhci_send_sem); #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) @@ -313,10 +315,6 @@ esp_err_t esp_nimble_hci_deinit(void) ble_buf_free(); -#if (BT_HCI_LOG_INCLUDED == TRUE) - bt_hci_log_deinit(); -#endif // (BT_HCI_LOG_INCLUDED == TRUE) - #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) ble_adv_list_deinit(); #endif diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index cc997ecc33ff..2cf7edde6386 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit cc997ecc33fff506baa0629f784bad75be4f16fc +Subproject commit 2cf7edde63866f5663bbcdfb8776cf29c0809456 diff --git a/components/bt/host/nimble/port/include/esp_nimble_cfg.h b/components/bt/host/nimble/port/include/esp_nimble_cfg.h index d2fa3338866f..9370be89b81d 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -234,7 +234,7 @@ #endif #ifndef MYNEWT_VAL_BLE_VERSION -#define MYNEWT_VAL_BLE_VERSION (50) +#define MYNEWT_VAL_BLE_VERSION (54) #endif #ifndef MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS @@ -892,6 +892,14 @@ #define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0) #endif +#ifndef MYNEWT_VAL_BLE_SMP_ID_RESET +#ifdef CONFIG_BT_NIMBLE_SMP_ID_RESET +#define MYNEWT_VAL_BLE_SMP_ID_RESET CONFIG_BT_NIMBLE_SMP_ID_RESET +#else +#define MYNEWT_VAL_BLE_SMP_ID_RESET (0) +#endif +#endif + #ifndef MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS #define MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS (CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS) #endif diff --git a/components/bt/include/esp32/include/esp_bt.h b/components/bt/include/esp32/include/esp_bt.h index b31ce276f58a..16b2898e7d74 100644 --- a/components/bt/include/esp32/include/esp_bt.h +++ b/components/bt/include/esp32/include/esp_bt.h @@ -50,32 +50,38 @@ extern "C" { #endif //CONFIG_BT_ENABLED -#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x20240315 +/** +* @brief Internal use only +* +* @note Please do not modify this value. +*/ +#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x20240722 /** - * @brief Bluetooth mode for controller enable/disable + * @brief Bluetooth Controller mode */ typedef enum { - ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not running */ - ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */ - ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Run Classic BT mode */ - ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */ + ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not operating. */ + ESP_BT_MODE_BLE = 0x01, /*!< Bluetooth is operating in BLE mode. */ + ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Bluetooth is operating in Classic Bluetooth mode. */ + ESP_BT_MODE_BTDM = 0x03, /*!< Bluetooth is operating in Dual mode. */ } esp_bt_mode_t; /** - * @brief BLE sleep clock accuracy(SCA), values for ble_sca field in esp_bt_controller_config_t, - * currently only ESP_BLE_SCA_500PPM and ESP_BLE_SCA_250PPM are supported + * @brief BLE sleep clock accuracy (SCA) + * + * @note Currently only ESP_BLE_SCA_500PPM and ESP_BLE_SCA_250PPM are supported. */ -enum { - ESP_BLE_SCA_500PPM = 0, /*!< BLE SCA at 500ppm */ - ESP_BLE_SCA_250PPM, /*!< BLE SCA at 250ppm */ - ESP_BLE_SCA_150PPM, /*!< BLE SCA at 150ppm */ - ESP_BLE_SCA_100PPM, /*!< BLE SCA at 100ppm */ - ESP_BLE_SCA_75PPM, /*!< BLE SCA at 75ppm */ - ESP_BLE_SCA_50PPM, /*!< BLE SCA at 50ppm */ - ESP_BLE_SCA_30PPM, /*!< BLE SCA at 30ppm */ - ESP_BLE_SCA_20PPM, /*!< BLE SCA at 20ppm */ -}; +typedef enum { + ESP_BLE_SCA_500PPM = 0, /*!< BLE SCA at 500 ppm */ + ESP_BLE_SCA_250PPM, /*!< BLE SCA at 250 ppm */ + ESP_BLE_SCA_150PPM, /*!< BLE SCA at 150 ppm */ + ESP_BLE_SCA_100PPM, /*!< BLE SCA at 100 ppm */ + ESP_BLE_SCA_75PPM, /*!< BLE SCA at 75 ppm */ + ESP_BLE_SCA_50PPM, /*!< BLE SCA at 50 ppm */ + ESP_BLE_SCA_30PPM, /*!< BLE SCA at 30 ppm */ + ESP_BLE_SCA_20PPM, /*!< BLE SCA at 20 ppm */ +} esp_ble_sca_t; #ifdef CONFIG_BT_ENABLED /* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE, @@ -172,7 +178,9 @@ the adv packet will be discarded until the memory is restored. */ #else #define BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX 0 #endif - +/** +* @brief Default Bluetooth Controller configuration +*/ #define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \ .controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \ .controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \ @@ -194,6 +202,7 @@ the adv packet will be discarded until the memory is restored. */ .ble_sca = CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF, \ .pcm_role = CONFIG_BTDM_CTRL_PCM_ROLE_EFF, \ .pcm_polar = CONFIG_BTDM_CTRL_PCM_POLAR_EFF, \ + .pcm_fsyncshp = 0, \ .hli = BTDM_CTRL_HLI, \ .dup_list_refresh_period = SCAN_DUPL_CACHE_REFRESH_PERIOD, \ .ble_scan_backoff = BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX, \ @@ -201,105 +210,112 @@ the adv packet will be discarded until the memory is restored. */ } #else +/** +* @brief Default Bluetooth Controller configuration +*/ #define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; ESP_STATIC_ASSERT(0, "please enable bluetooth in menuconfig to use esp_bt.h"); #endif /** - * @brief Controller config options, depend on config mask. - * Config mask indicate which functions enabled, this means - * some options or parameters of some functions enabled by config mask. + * @brief Bluetooth Controller config options + * @note + * 1. For parameters configurable in menuconfig, please refer to menuconfig for details on range and default values. + * 2. It is not recommended to modify the default values of `controller_task_stack_size`, `controller_task_prio`. */ typedef struct { - /* - * Following parameters can be configured runtime, when call esp_bt_controller_init() - */ - uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */ - uint8_t controller_task_prio; /*!< Bluetooth controller task priority */ - uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */ - uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */ - uint8_t scan_duplicate_mode; /*!< scan duplicate mode */ - uint8_t scan_duplicate_type; /*!< scan duplicate type */ - uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */ - uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */ - uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */ - uint32_t controller_debug_flag; /*!< Controller debug log flag */ - uint8_t mode; /*!< Controller mode: BR/EDR, BLE or Dual Mode */ - uint8_t ble_max_conn; /*!< BLE maximum connection numbers */ - uint8_t bt_max_acl_conn; /*!< BR/EDR maximum ACL connection numbers */ - uint8_t bt_sco_datapath; /*!< SCO data path, i.e. HCI or PCM module */ - bool auto_latency; /*!< BLE auto latency, used to enhance classic BT performance */ - bool bt_legacy_auth_vs_evt; /*!< BR/EDR Legacy auth complete event required to protect from BIAS attack */ - /* - * Following parameters can not be configured runtime when call esp_bt_controller_init() - * It will be overwrite with a constant value which in menuconfig or from a macro. - * So, do not modify the value when esp_bt_controller_init() - */ - uint8_t bt_max_sync_conn; /*!< BR/EDR maximum ACL connection numbers. Effective in menuconfig */ - uint8_t ble_sca; /*!< BLE low power crystal accuracy index */ - uint8_t pcm_role; /*!< PCM role (master & slave)*/ - uint8_t pcm_polar; /*!< PCM polar trig (falling clk edge & rising clk edge) */ - bool hli; /*!< Using high level interrupt or not */ - uint16_t dup_list_refresh_period; /*!< Duplicate scan list refresh period */ - bool ble_scan_backoff; /*!< BLE scan backoff */ + uint16_t controller_task_stack_size; /*!< Bluetooth Controller task stack size in bytes */ + uint8_t controller_task_prio; /*!< Bluetooth Controller task priority */ + uint8_t hci_uart_no; /*!< Indicates UART number if using UART1/2 as HCI I/O interface. Configurable in menuconfig */ + uint32_t hci_uart_baudrate; /*!< Indicates UART baudrate if using UART1/2 as HCI I/O interface. Configurable in menuconfig */ + uint8_t scan_duplicate_mode; /*!< Scan duplicate filtering mode. Configurable in menuconfig */ + uint8_t scan_duplicate_type; /*!< Scan duplicate filtering type. Configurable in menuconfig */ + uint16_t normal_adv_size; /*!< Maximum number of devices in scan duplicate filtering list. Configurable in menuconfig */ + uint16_t mesh_adv_size; /*!< Maximum number of Mesh ADV packets in scan duplicate filtering list. Configurable in menuconfig */ + uint16_t send_adv_reserved_size; /*!< Controller minimum memory value in bytes. Internal use only */ + uint32_t controller_debug_flag; /*!< Controller debug log flag. Internal use only */ + uint8_t mode; /*!< Controller mode: + + 1: BLE mode + + 2: Classic Bluetooth mode + + 3: Dual mode + + Others: Invalid + + Configurable in menuconfig + */ + uint8_t ble_max_conn; /*!< Maximum number of BLE connections. Configurable in menuconfig */ + uint8_t bt_max_acl_conn; /*!< Maximum number of BR/EDR ACL connections. Configurable in menuconfig */ + uint8_t bt_sco_datapath; /*!< SCO data path, i.e. HCI or PCM module. Configurable in menuconfig */ + bool auto_latency; /*!< True if BLE auto latency is enabled, used to enhance Classic Bluetooth performance; false otherwise. Configurable in menuconfig */ + bool bt_legacy_auth_vs_evt; /*!< True if BR/EDR Legacy Authentication Vendor Specific Event is enabled, which is required to protect from BIAS attack; false otherwise. Configurable in menuconfig */ + uint8_t bt_max_sync_conn; /*!< Maximum number of BR/EDR synchronous connections. Configurable in menuconfig */ + uint8_t ble_sca; /*!< BLE low power crystal accuracy index. Configurable in menuconfig */ + uint8_t pcm_role; /*!< PCM role (master & slave). Configurable in menuconfig */ + uint8_t pcm_polar; /*!< PCM polar trig (falling clk edge & rising clk edge). Configurable in menuconfig */ + uint8_t pcm_fsyncshp; /*!< Physical shape of the PCM Frame Synchronization signal (stereo mode & mono mode). Configurable in menuconfig */ + bool hli; /*!< True if using high level interrupt; false otherwise. Configurable in menuconfig */ + uint16_t dup_list_refresh_period; /*!< Scan duplicate filtering list refresh period in seconds. Configurable in menuconfig */ + bool ble_scan_backoff; /*!< True if BLE scan backoff is enabled; false otherwise. Configurable in menuconfig */ uint32_t magic; /*!< Magic number */ } esp_bt_controller_config_t; /** - * @brief Bluetooth controller enable/disable/initialised/de-initialised status + * @brief Bluetooth Controller status */ typedef enum { - ESP_BT_CONTROLLER_STATUS_IDLE = 0, - ESP_BT_CONTROLLER_STATUS_INITED, - ESP_BT_CONTROLLER_STATUS_ENABLED, - ESP_BT_CONTROLLER_STATUS_NUM, + ESP_BT_CONTROLLER_STATUS_IDLE = 0, /*!< The Controller is not initialized or has been de-initialized.*/ + ESP_BT_CONTROLLER_STATUS_INITED, /*!< The Controller has been initialized, but not enabled or has been disabled. */ + ESP_BT_CONTROLLER_STATUS_ENABLED, /*!< The Controller has been initialized and enabled. */ + ESP_BT_CONTROLLER_STATUS_NUM, /*!< Number of Controller statuses */ } esp_bt_controller_status_t; /** - * @brief BLE tx power type - * ESP_BLE_PWR_TYPE_CONN_HDL0-8: for each connection, and only be set after connection completed. - * when disconnect, the correspond TX power is not effected. - * ESP_BLE_PWR_TYPE_ADV : for advertising/scan response. - * ESP_BLE_PWR_TYPE_SCAN : for scan. - * ESP_BLE_PWR_TYPE_DEFAULT : if each connection's TX power is not set, it will use this default value. - * if neither in scan mode nor in adv mode, it will use this default value. - * If none of power type is set, system will use ESP_PWR_LVL_P3 as default for ADV/SCAN/CONN0-9. + * @brief BLE TX power type + * @note + * 1. The connection TX power can only be set after the connection is established. + * After disconnecting, the corresponding TX power will not be affected. + * 2. `ESP_BLE_PWR_TYPE_DEFAULT` can be used to set the TX power for power types that have not been set before. + * It will not affect the TX power values which have been set for the following CONN0-8/ADV/SCAN power types. + * 3. If none of power type is set, the system will use `ESP_PWR_LVL_P3` as default for all power types. */ typedef enum { - ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, /*!< For connection handle 0 */ - ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, /*!< For connection handle 1 */ - ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, /*!< For connection handle 2 */ - ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, /*!< For connection handle 3 */ - ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, /*!< For connection handle 4 */ - ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, /*!< For connection handle 5 */ - ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, /*!< For connection handle 6 */ - ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, /*!< For connection handle 7 */ - ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, /*!< For connection handle 8 */ - ESP_BLE_PWR_TYPE_ADV = 9, /*!< For advertising */ - ESP_BLE_PWR_TYPE_SCAN = 10, /*!< For scan */ - ESP_BLE_PWR_TYPE_DEFAULT = 11, /*!< For default, if not set other, it will use default value */ - ESP_BLE_PWR_TYPE_NUM = 12, /*!< TYPE numbers */ + ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, /*!< TX power for connection handle 0 */ + ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, /*!< TX power for connection handle 1 */ + ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, /*!< TX power for connection handle 2 */ + ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, /*!< TX power for connection handle 3 */ + ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, /*!< TX power for connection handle 4 */ + ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, /*!< TX power for connection handle 5 */ + ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, /*!< TX power for connection handle 6 */ + ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, /*!< TX power for connection handle 7 */ + ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, /*!< TX power for connection handle 8 */ + ESP_BLE_PWR_TYPE_ADV = 9, /*!< TX power for advertising */ + ESP_BLE_PWR_TYPE_SCAN = 10, /*!< TX power for scan */ + ESP_BLE_PWR_TYPE_DEFAULT = 11, /*!< Default TX power type, which can be used to set the TX power for power types that have not been set before.*/ + ESP_BLE_PWR_TYPE_NUM = 12, /*!< Number of types */ } esp_ble_power_type_t; /** - * @brief Bluetooth TX power level(index), it's just a index corresponding to power(dbm). + * @brief Bluetooth TX power level (index). Each index corresponds to a specific power value in dBm. */ typedef enum { - ESP_PWR_LVL_N12 = 0, /*!< Corresponding to -12dbm */ - ESP_PWR_LVL_N9 = 1, /*!< Corresponding to -9dbm */ - ESP_PWR_LVL_N6 = 2, /*!< Corresponding to -6dbm */ - ESP_PWR_LVL_N3 = 3, /*!< Corresponding to -3dbm */ - ESP_PWR_LVL_N0 = 4, /*!< Corresponding to 0dbm */ - ESP_PWR_LVL_P3 = 5, /*!< Corresponding to +3dbm */ - ESP_PWR_LVL_P6 = 6, /*!< Corresponding to +6dbm */ - ESP_PWR_LVL_P9 = 7, /*!< Corresponding to +9dbm */ - ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12, /*!< Backward compatibility! Setting to -14dbm will actually result to -12dbm */ - ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9, /*!< Backward compatibility! Setting to -11dbm will actually result to -9dbm */ - ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6, /*!< Backward compatibility! Setting to -8dbm will actually result to -6dbm */ - ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3, /*!< Backward compatibility! Setting to -5dbm will actually result to -3dbm */ - ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0, /*!< Backward compatibility! Setting to -2dbm will actually result to 0dbm */ - ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3, /*!< Backward compatibility! Setting to +1dbm will actually result to +3dbm */ - ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6, /*!< Backward compatibility! Setting to +4dbm will actually result to +6dbm */ - ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9, /*!< Backward compatibility! Setting to +7dbm will actually result to +9dbm */ + ESP_PWR_LVL_N12 = 0, /*!< Corresponding to -12 dBm */ + ESP_PWR_LVL_N9 = 1, /*!< Corresponding to -9 dBm */ + ESP_PWR_LVL_N6 = 2, /*!< Corresponding to -6 dBm */ + ESP_PWR_LVL_N3 = 3, /*!< Corresponding to -3 dBm */ + ESP_PWR_LVL_N0 = 4, /*!< Corresponding to 0 dBm */ + ESP_PWR_LVL_P3 = 5, /*!< Corresponding to +3 dBm */ + ESP_PWR_LVL_P6 = 6, /*!< Corresponding to +6 dBm */ + ESP_PWR_LVL_P9 = 7, /*!< Corresponding to +9 dBm */ + ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12, /*!< Backward compatibility! Setting to -14 dBm will actually result in -12 dBm */ + ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9, /*!< Backward compatibility! Setting to -11 dBm will actually result in -9 dBm */ + ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6, /*!< Backward compatibility! Setting to -8 dBm will actually result in -6 dBm */ + ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3, /*!< Backward compatibility! Setting to -5 dBm will actually result in -3 dBm */ + ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0, /*!< Backward compatibility! Setting to -2 dBm will actually result in 0 dBm */ + ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3, /*!< Backward compatibility! Setting to +1 dBm will actually result in +3 dBm */ + ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6, /*!< Backward compatibility! Setting to +4 dBm will actually result in +6 dBm */ + ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9, /*!< Backward compatibility! Setting to +7 dBm will actually result in +9 dBm */ } esp_power_level_t; /** @@ -312,243 +328,312 @@ typedef enum { /** * @brief Set BLE TX power - * Connection Tx power should only be set after connection created. - * @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc - * @param power_level: Power level(index) corresponding to absolute value(dbm) - * @return ESP_OK - success, other - failed + * + * @note Connection TX power should only be set after the connection is established. + * + * @param[in] power_type The type of TX power. It could be Advertising, Connection, Default, etc. + * @param[in] power_level Power level (index) corresponding to the absolute value (dBm) + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_ARG: Invalid argument */ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level); /** * @brief Get BLE TX power - * Connection Tx power should only be get after connection created. - * @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc - * @return >= 0 - Power level, < 0 - Invalid + * + * @note Connection TX power should only be retrieved after the connection is established. + * + * @param[in] power_type The type of TX power. It could be Advertising/Connection/Default and etc. + * + * @return + * - Power level + * */ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type); /** * @brief Set BR/EDR TX power - * BR/EDR power control will use the power in range of minimum value and maximum value. - * The power level will effect the global BR/EDR TX power, such inquire, page, connection and so on. - * Please call the function after esp_bt_controller_enable and before any function which cause RF do TX. - * So you can call the function before doing discovery, profile init and so on. - * For example, if you want BR/EDR use the new TX power to do inquire, you should call - * this function before inquire. Another word, If call this function when BR/EDR is in inquire(ING), - * please do inquire again after call this function. - * Default minimum power level is ESP_PWR_LVL_N0, and maximum power level is ESP_PWR_LVL_P3. - * @param min_power_level: The minimum power level - * @param max_power_level: The maximum power level - * @return ESP_OK - success, other - failed + * + * BR/EDR power control will use the power within the range of minimum value and maximum value. + * The power level will affect the global BR/EDR TX power for operations such as inquiry, page, and connection. + * + * @note + * 1. Please call this function after `esp_bt_controller_enable()` and before any functions that cause RF transmission, + * such as performing discovery, profile initialization, and so on. + * 2. For BR/EDR to use the new TX power for inquiry, call this function before starting an inquiry. + * If BR/EDR is already inquiring, restart the inquiry after calling this function. + * + * @param[in] min_power_level The minimum power level. The default value is `ESP_PWR_LVL_N0`. + * @param[in] max_power_level The maximum power level. The default value is `ESP_PWR_LVL_P3`. + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_ARG: Invalid argument + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_level_t max_power_level); /** * @brief Get BR/EDR TX power - * If the argument is not NULL, then store the corresponding value. - * @param min_power_level: The minimum power level - * @param max_power_level: The maximum power level - * @return ESP_OK - success, other - failed + * + * The corresponding power levels will be stored into the arguments. + * + * @param[out] min_power_level Pointer to store the minimum power level + * @param[out] max_power_level The maximum power level + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_ARG: Invalid argument */ esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_level_t *max_power_level); /** * @brief Set default SCO data path - * Should be called after controller is enabled, and before (e)SCO link is established - * @param data_path: SCO data path - * @return ESP_OK - success, other - failed + * + * @note This function should be called after the Controller is enabled, and before (e)SCO link is established. + * + * @param[in] data_path SCO data path + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path); /** - * @brief Initialize BT controller to allocate task and other resource. - * This function should be called only once, before any other BT functions are called. - * @param cfg: Initial configuration of BT controller. Different from previous version, there's a mode and some - * connection configuration in "cfg" to configure controller work mode and allocate the resource which is needed. - * @return ESP_OK - success, other - failed + * @brief Initialize the Bluetooth Controller to allocate tasks and other resources + * + * @note This function should be called only once, before any other Bluetooth functions. + * + * @param[in] cfg Initial Bluetooth Controller configuration + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); /** - * @brief De-initialize BT controller to free resource and delete task. - * You should stop advertising and scanning, as well as - * disconnect all existing connections before de-initializing BT controller. + * @brief De-initialize Bluetooth Controller to free resources and delete tasks * - * This function should be called only once, after any other BT functions are called. - * @return ESP_OK - success, other - failed + * @note + * 1. You should stop advertising and scanning, and disconnect all existing connections before de-initializing Bluetooth Controller. + * 2. This function should be called only once, after any other Bluetooth functions. + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_ARG: Invalid argument + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NO_MEM: Out of memory */ esp_err_t esp_bt_controller_deinit(void); /** - * @brief Enable BT controller. - * Due to a known issue, you cannot call esp_bt_controller_enable() a second time - * to change the controller mode dynamically. To change controller mode, call - * esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode. - * @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. This mode must be - * equal as the mode in "cfg" of esp_bt_controller_init(). - * @return ESP_OK - success, other - failed + * @brief Enable Bluetooth Controller + * + * @note + * 1. Bluetooth Controller cannot be enabled in `ESP_BT_CONTROLLER_STATUS_IDLE` status. It has to be initialized first. + * 2. Due to a known issue, you cannot call `esp_bt_controller_enable()` for the second time + * to change the Controller mode dynamically. To change the Controller mode, call + * `esp_bt_controller_disable()` and then call `esp_bt_controller_enable()` with the new mode. + * + * @param[in] mode The Bluetooth Controller mode (BLE/Classic Bluetooth/BTDM) to enable + * + * For API compatibility, retain this argument. This mode must match the mode specified in the `cfg` of `esp_bt_controller_init()`. + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); /** - * @brief Disable BT controller - * @return ESP_OK - success, other - failed + * @brief Disable Bluetooth Controller + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bt_controller_disable(void); /** - * @brief Get BT controller is initialised/de-initialised/enabled/disabled - * @return status value + * @brief Get Bluetooth Controller status + * + * @return + * - ESP_BT_CONTROLLER_STATUS_IDLE: The Controller is not initialized or has been de-initialized. + * - ESP_BT_CONTROLLER_STATUS_INITED: The Controller has been initialized, but not enabled or has been disabled. + * - ESP_BT_CONTROLLER_STATUS_ENABLED: The Controller has been initialized and enabled. */ esp_bt_controller_status_t esp_bt_controller_get_status(void); -/** @brief esp_vhci_host_callback - * used for vhci call host function to notify what host need to do +/** + * @brief Vendor HCI (VHCI) callback functions to notify the Host on the next operation */ typedef struct esp_vhci_host_callback { - void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */ - int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/ + void (*notify_host_send_available)(void); /*!< Callback to notify the Host that the Controller is ready to receive the packet */ + int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< Callback to notify the Host that the Controller has a packet to send */ } esp_vhci_host_callback_t; -/** @brief esp_vhci_host_check_send_available - * used for check actively if the host can send packet to controller or not. - * @return true for ready to send, false means cannot send packet +/** + * @brief Check whether the Controller is ready to receive the packet + * + *If the return value is True, the Host can send the packet to the Controller. + * + * @note This function should be called before each `esp_vhci_host_send_packet()`. + * + * @return + * True if the Controller is ready to receive packets; false otherwise */ bool esp_vhci_host_check_send_available(void); -/** @brief esp_vhci_host_send_packet - * host send packet to controller +/** + * @brief Send the packet to the Controller * - * Should not call this function from within a critical section - * or when the scheduler is suspended. + * @note + * 1. This function shall not be called within a critical section or when the scheduler is suspended. + * 2. This function should be called only if `esp_vhci_host_check_send_available()` returns True. * - * @param data the packet point - * @param len the packet length + * @param[in] data Pointer to the packet data + * @param[in] len The packet length */ void esp_vhci_host_send_packet(uint8_t *data, uint16_t len); -/** @brief esp_vhci_host_register_callback - * register the vhci reference callback - * struct defined by vhci_host_callback structure. - * @param callback esp_vhci_host_callback type variable - * @return ESP_OK - success, ESP_FAIL - failed +/** + * @brief Register the VHCI callback funations defined in `esp_vhci_host_callback` structure. + * + * @param[in] callback `esp_vhci_host_callback` type variable + * + * @return + * - ESP_OK: Success + * - ESP_FAIL: Failure */ esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback); -/** @brief esp_bt_controller_mem_release - * release the controller memory as per the mode +/** + * @brief Release the Controller memory as per the mode * - * This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes. + * This function releases the BSS, data and other sections of the Controller to heap. The total size is about 70 KB. * - * esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init() - * or after esp_bt_controller_deinit(). + * @note + * 1. This function is optional and should be called only if you want to free up memory for other components. + * 2. This function should only be called when the controller is in `ESP_BT_CONTROLLER_STATUS_IDLE` status. + * 3. Once Bluetooth Controller memory is released, the process cannot be reversed. This means you cannot use the Bluetooth Controller mode that you have released using this function. + * 4. If your firmware will upgrade the Bluetooth Controller mode later (such as switching from BLE to Classic Bluetooth or from disabled to enabled), then do not call this function. * - * Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth - * mode which you have released by this function. + * If you never intend to use Bluetooth in a current boot-up cycle, calling `esp_bt_controller_mem_release(ESP_BT_MODE_BTDM)` could release the BSS and data consumed by both Classic Bluetooth and BLE Controller to heap. * - * If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) - * then do not call this function. + * If you intend to use BLE only, calling `esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)` could release the BSS and data consumed by Classic Bluetooth Controller. You can then continue using BLE. * - * If the app calls esp_bt_controller_enable(ESP_BT_MODE_BLE) to use BLE only then it is safe to call - * esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialization time to free unused BT Classic memory. + * If you intend to use Classic Bluetooth only, calling `esp_bt_controller_mem_release(ESP_BT_MODE_BLE)` could release the BSS and data consumed by BLE Controller. You can then continue using Classic Bluetooth. * - * If the mode is ESP_BT_MODE_BTDM, then it may be useful to call API esp_bt_mem_release(ESP_BT_MODE_BTDM) instead, - * which internally calls esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) and additionally releases the BSS and data - * consumed by the BT/BLE host stack to heap. For more details about usage please refer to the documentation of - * esp_bt_mem_release() function + * @param[in] mode The Bluetooth Controller mode * - * @param mode : the mode want to release memory - * @return ESP_OK - success, other - failed + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NOT_FOUND: Requested resource not found */ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode); -/** @brief esp_bt_mem_release - * release controller memory and BSS and data section of the BT/BLE host stack as per the mode +/** + * @brief Release the Controller memory, BSS and data section of the Classic Bluetooth/BLE Host stack as per the mode * - * This function first releases controller memory by internally calling esp_bt_controller_mem_release(). - * Additionally, if the mode is set to ESP_BT_MODE_BTDM, it also releases the BSS and data consumed by the BT/BLE host stack to heap + * @note + * 1. This function is optional and should be called only if you want to free up memory for other components. + * 2. This function should only be called when the controller is in `ESP_BT_CONTROLLER_STATUS_IDLE` status. + * 3. Once Bluetooth Controller memory is released, the process cannot be reversed. This means you cannot use the Bluetooth Controller mode that you have released using this function. + * 4. If your firmware will upgrade the Bluetooth Controller mode later (such as switching from BLE to Classic Bluetooth or from disabled to enabled), then do not call this function. * - * Note that once BT memory is released, the process cannot be reversed. It means you cannot use the bluetooth - * mode which you have released by this function. + * This function first releases Controller memory by internally calling `esp_bt_controller_mem_release()`, then releases Host memory. * - * If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) - * then do not call this function. + * If you never intend to use Bluetooth in a current boot-up cycle, calling `esp_bt_mem_release(ESP_BT_MODE_BTDM)` could release the BSS and data consumed by both Classic Bluetooth and BLE stack to heap. * - * If you never intend to use bluetooth in a current boot-up cycle, you can call esp_bt_mem_release(ESP_BT_MODE_BTDM) - * before esp_bt_controller_init or after esp_bt_controller_deinit. + * If you intend to use BLE only, calling `esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT)` could release the BSS and data consumed by Classic Bluetooth. You can then continue using BLE. * - * For example, if a user only uses bluetooth for setting the WiFi configuration, and does not use bluetooth in the rest of the product operation". - * In such cases, after receiving the WiFi configuration, you can disable/deinit bluetooth and release its memory. + * If you intend to use Classic Bluetooth only, calling `esp_bt_mem_release(ESP_BT_MODE_BLE)` could release the BSS and data consumed by BLE. You can then continue using Classic Bluetooth. + * + * For example, if you only use Bluetooth for setting the Wi-Fi configuration, and do not use Bluetooth in the rest of the product operation, + * after receiving the Wi-Fi configuration, you can disable/de-init Bluetooth and release its memory. * Below is the sequence of APIs to be called for such scenarios: * - * esp_bluedroid_disable(); - * esp_bluedroid_deinit(); - * esp_bt_controller_disable(); - * esp_bt_controller_deinit(); - * esp_bt_mem_release(ESP_BT_MODE_BTDM); + * esp_bluedroid_disable(); + * esp_bluedroid_deinit(); + * esp_bt_controller_disable(); + * esp_bt_controller_deinit(); + * esp_bt_mem_release(ESP_BT_MODE_BTDM); + * + * @param[in] mode The Bluetooth Controller mode * - * @note In case of NimBLE host, to release BSS and data memory to heap, the mode needs to be - * set to ESP_BT_MODE_BTDM as controller is dual mode. - * @param mode : the mode whose memory is to be released - * @return ESP_OK - success, other - failed + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NOT_FOUND: Requested resource not found */ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode); /** - * @brief enable bluetooth to enter modem sleep + * @brief Enable Bluetooth modem sleep * - * Note that this function shall not be invoked before esp_bt_controller_enable() + * There are currently two options for Bluetooth modem sleep: ORIG mode and EVED mode. The latter is intended for BLE only. + * The modem sleep mode could be configured in menuconfig. * - * There are currently two options for bluetooth modem sleep, one is ORIG mode, and another is EVED Mode. EVED Mode is intended for BLE only. + * In ORIG mode, if there is no event to process, the Bluetooth Controller will periodically switch off some components and pause operation, then wake up according to the scheduled interval and resume work. + * It can also wakeup earlier upon external request using function `esp_bt_controller_wakeup_request()`. * - * For ORIG mode: - * Bluetooth modem sleep is enabled in controller start up by default if CONFIG_CTRL_BTDM_MODEM_SLEEP is set and "ORIG mode" is selected. In ORIG modem sleep mode, bluetooth controller will switch off some components and pause to work every now and then, if there is no event to process; and wakeup according to the scheduled interval and resume the work. It can also wakeup earlier upon external request using function "esp_bt_controller_wakeup_request". + * @note This function shall not be invoked before `esp_bt_controller_enable()`. * * @return - * - ESP_OK : success - * - other : failed + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NOT_SUPPORTED: Operation or feature not supported */ esp_err_t esp_bt_sleep_enable(void); /** - * @brief disable bluetooth modem sleep - * - * Note that this function shall not be invoked before esp_bt_controller_enable() + * @brief Disable Bluetooth modem sleep * - * If esp_bt_sleep_disable() is called, bluetooth controller will not be allowed to enter modem sleep; - * - * If ORIG modem sleep mode is in use, if this function is called, bluetooth controller may not immediately wake up if it is dormant then. - * In this case, esp_bt_controller_wakeup_request() can be used to shorten the time for wakeup. + * @note + * 1. Bluetooth Controller will not be allowed to enter modem sleep after calling this function. + * 2. In ORIG modem sleep mode, calling this function may not immediately wake up the Controller if it is currently dormant. + * In this case, `esp_bt_controller_wakeup_request()` can be used to shorten the wake-up time. + * 3. This function shall not be invoked before `esp_bt_controller_enable()`. * * @return - * - ESP_OK : success - * - other : failed + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NOT_SUPPORTED: Operation or feature not supported */ esp_err_t esp_bt_sleep_disable(void); /** - * @brief Manually clear scan duplicate list - * - * Note that scan duplicate list will be automatically cleared when the maximum amount of device in the filter is reached - * the amount of device in the filter can be configured in menuconfig. + * @brief Manually clear the scan duplicate list * - * @note This function name is incorrectly spelled, it will be fixed in release 5.x version. + * @note + * 1. This function name is incorrectly spelled, it will be fixed in release 5.x version. + * 2. The scan duplicate list will be automatically cleared when the maximum amount of devices in the filter is reached. + * The amount of devices in the filter can be configured in menuconfig. * * @return - * - ESP_OK : success - * - other : failed + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_ble_scan_dupilcate_list_flush(void); /** - * @brief bt Wi-Fi power domain power on - */ + * @brief Power on Bluetooth Wi-Fi power domain + * + * @note This function is not recommended to use due to potential risk. +*/ void esp_wifi_bt_power_domain_on(void); /** - * @brief bt Wi-Fi power domain power off - */ + * @brief Power off Bluetooth Wi-Fi power domain + * + * @note This function is not recommended to use due to potential risk. +*/ void esp_wifi_bt_power_domain_off(void); #ifdef __cplusplus diff --git a/components/bt/include/esp32c2/include/esp_bt.h b/components/bt/include/esp32c2/include/esp_bt.h index ee1bede7e4de..c73d4cb9243e 100644 --- a/components/bt/include/esp32c2/include/esp_bt.h +++ b/components/bt/include/esp32c2/include/esp_bt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -262,13 +262,6 @@ typedef struct { .controller_run_cpu = 0, \ .enable_qa_test = RUN_QA_TEST, \ .enable_bqb_test = RUN_BQB_TEST, \ - .enable_uart_hci = HCI_UART_EN, \ - .ble_hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \ - .ble_hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \ - .ble_hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \ - .ble_hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \ - .ble_hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \ - .ble_hci_uart_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \ .enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \ .cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \ .sleep_en = NIMBLE_SLEEP_ENABLE, \ diff --git a/components/bt/include/esp32c5/include/esp_bt.h b/components/bt/include/esp32c5/include/esp_bt.h index 1a7cd6468516..37a70c2a40fa 100644 --- a/components/bt/include/esp32c5/include/esp_bt.h +++ b/components/bt/include/esp32c5/include/esp_bt.h @@ -155,7 +155,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20231124 +#define CONFIG_VERSION 0x20240422 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -196,13 +196,6 @@ typedef struct { uint8_t controller_run_cpu; /*!< CPU core on which the controller runs */ uint8_t enable_qa_test; /*!< Enable quality assurance (QA) testing */ uint8_t enable_bqb_test; /*!< Enable Bluetooth Qualification Test (BQB) testing */ - uint8_t enable_uart_hci; /*!< Enable UART HCI (Host Controller Interface) */ - uint8_t ble_hci_uart_port; /*!< UART port number for Bluetooth HCI */ - uint32_t ble_hci_uart_baud; /*!< Baud rate for Bluetooth HCI UART */ - uint8_t ble_hci_uart_data_bits; /*!< Number of data bits for Bluetooth HCI UART */ - uint8_t ble_hci_uart_stop_bits; /*!< Number of stop bits for Bluetooth HCI UART */ - uint8_t ble_hci_uart_flow_ctrl; /*!< Flow control settings for Bluetooth HCI UART */ - uint8_t ble_hci_uart_uart_parity; /*!< Parity settings for Bluetooth HCI UART */ uint8_t enable_tx_cca; /*!< Enable Transmit Clear Channel Assessment (TX CCA) */ uint8_t cca_rssi_thresh; /*!< RSSI threshold for Transmit Clear Channel Assessment (CCA) */ uint8_t sleep_en; /*!< Enable sleep mode */ @@ -252,13 +245,6 @@ typedef struct { .controller_run_cpu = 0, \ .enable_qa_test = RUN_QA_TEST, \ .enable_bqb_test = RUN_BQB_TEST, \ - .enable_uart_hci = HCI_UART_EN, \ - .ble_hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \ - .ble_hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \ - .ble_hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \ - .ble_hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \ - .ble_hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \ - .ble_hci_uart_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \ .enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \ .cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \ .sleep_en = NIMBLE_SLEEP_ENABLE, \ diff --git a/components/bt/include/esp32c6/include/esp_bt.h b/components/bt/include/esp32c6/include/esp_bt.h index 210ead42da97..ea272287228d 100644 --- a/components/bt/include/esp32c6/include/esp_bt.h +++ b/components/bt/include/esp32c6/include/esp_bt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -155,7 +155,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20231124 +#define CONFIG_VERSION 0x20240422 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -196,13 +196,6 @@ typedef struct { uint8_t controller_run_cpu; /*!< CPU core on which the controller runs */ uint8_t enable_qa_test; /*!< Enable quality assurance (QA) testing */ uint8_t enable_bqb_test; /*!< Enable Bluetooth Qualification Test (BQB) testing */ - uint8_t enable_uart_hci; /*!< Enable UART HCI (Host Controller Interface) */ - uint8_t ble_hci_uart_port; /*!< UART port number for Bluetooth HCI */ - uint32_t ble_hci_uart_baud; /*!< Baud rate for Bluetooth HCI UART */ - uint8_t ble_hci_uart_data_bits; /*!< Number of data bits for Bluetooth HCI UART */ - uint8_t ble_hci_uart_stop_bits; /*!< Number of stop bits for Bluetooth HCI UART */ - uint8_t ble_hci_uart_flow_ctrl; /*!< Flow control settings for Bluetooth HCI UART */ - uint8_t ble_hci_uart_uart_parity; /*!< Parity settings for Bluetooth HCI UART */ uint8_t enable_tx_cca; /*!< Enable Transmit Clear Channel Assessment (TX CCA) */ uint8_t cca_rssi_thresh; /*!< RSSI threshold for Transmit Clear Channel Assessment (CCA) */ uint8_t sleep_en; /*!< Enable sleep mode */ @@ -253,13 +246,6 @@ typedef struct { .controller_run_cpu = 0, \ .enable_qa_test = RUN_QA_TEST, \ .enable_bqb_test = RUN_BQB_TEST, \ - .enable_uart_hci = HCI_UART_EN, \ - .ble_hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \ - .ble_hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \ - .ble_hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \ - .ble_hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \ - .ble_hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \ - .ble_hci_uart_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \ .enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \ .cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \ .sleep_en = NIMBLE_SLEEP_ENABLE, \ diff --git a/components/bt/include/esp32h2/include/esp_bt.h b/components/bt/include/esp32h2/include/esp_bt.h index a1c7aed8ee29..bbecb64072fb 100644 --- a/components/bt/include/esp32h2/include/esp_bt.h +++ b/components/bt/include/esp32h2/include/esp_bt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -160,7 +160,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20231124 +#define CONFIG_VERSION 0x20240422 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -201,13 +201,6 @@ typedef struct { uint8_t controller_run_cpu; /*!< CPU number on which the Bluetooth controller task runs */ uint8_t enable_qa_test; /*!< Enable for QA test */ uint8_t enable_bqb_test; /*!< Enable for BQB test */ - uint8_t enable_uart_hci; /*!< Enable UART for HCI (Host Controller Interface) */ - uint8_t ble_hci_uart_port; /*!< Port of UART for HCI */ - uint32_t ble_hci_uart_baud; /*!< Baudrate of UART for HCI */ - uint8_t ble_hci_uart_data_bits; /*!< Data bits of UART for HCI */ - uint8_t ble_hci_uart_stop_bits; /*!< Stop bits of UART for HCI */ - uint8_t ble_hci_uart_flow_ctrl; /*!< Flow control of UART for HCI */ - uint8_t ble_hci_uart_uart_parity; /*!< UART parity */ uint8_t enable_tx_cca; /*!< Enable Clear Channel Assessment (CCA) when transmitting */ uint8_t cca_rssi_thresh; /*!< RSSI threshold for CCA */ uint8_t sleep_en; /*!< Enable sleep functionality */ @@ -258,13 +251,6 @@ typedef struct { .controller_run_cpu = 0, \ .enable_qa_test = RUN_QA_TEST, \ .enable_bqb_test = RUN_BQB_TEST, \ - .enable_uart_hci = HCI_UART_EN, \ - .ble_hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \ - .ble_hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \ - .ble_hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \ - .ble_hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \ - .ble_hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \ - .ble_hci_uart_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \ .enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \ .cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \ .sleep_en = NIMBLE_SLEEP_ENABLE, \ diff --git a/components/bt/include/esp32h4/include/esp_bt_cfg.h b/components/bt/include/esp32h4/include/esp_bt_cfg.h index 768a0c6ccec0..1f8caaeca8b7 100644 --- a/components/bt/include/esp32h4/include/esp_bt_cfg.h +++ b/components/bt/include/esp32h4/include/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -116,6 +116,20 @@ extern "C" { #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8) #endif + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif #endif #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF @@ -156,8 +170,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -166,8 +178,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ diff --git a/components/bt/porting/nimble/include/nimble/ble_hci_trans.h b/components/bt/porting/include/ble_hci_trans.h similarity index 93% rename from components/bt/porting/nimble/include/nimble/ble_hci_trans.h rename to components/bt/porting/include/ble_hci_trans.h index 5bbf92246014..05267b6be77e 100644 --- a/components/bt/porting/nimble/include/nimble/ble_hci_trans.h +++ b/components/bt/porting/include/ble_hci_trans.h @@ -1,20 +1,7 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 */ #ifndef H_HCI_TRANSPORT_ diff --git a/components/bt/porting/mem/bt_osi_mem.h b/components/bt/porting/include/bt_osi_mem.h similarity index 100% rename from components/bt/porting/mem/bt_osi_mem.h rename to components/bt/porting/include/bt_osi_mem.h diff --git a/components/bt/porting/nimble/include/os/endian.h b/components/bt/porting/include/os/endian.h similarity index 100% rename from components/bt/porting/nimble/include/os/endian.h rename to components/bt/porting/include/os/endian.h diff --git a/components/bt/porting/nimble/include/os/os.h b/components/bt/porting/include/os/os.h similarity index 100% rename from components/bt/porting/nimble/include/os/os.h rename to components/bt/porting/include/os/os.h diff --git a/components/bt/porting/nimble/include/os/os_error.h b/components/bt/porting/include/os/os_error.h similarity index 100% rename from components/bt/porting/nimble/include/os/os_error.h rename to components/bt/porting/include/os/os_error.h diff --git a/components/bt/porting/nimble/include/os/os_mbuf.h b/components/bt/porting/include/os/os_mbuf.h similarity index 99% rename from components/bt/porting/nimble/include/os/os_mbuf.h rename to components/bt/porting/include/os/os_mbuf.h index e6fd6b907e60..c6ea6b6e85df 100644 --- a/components/bt/porting/nimble/include/os/os_mbuf.h +++ b/components/bt/porting/include/os/os_mbuf.h @@ -65,7 +65,7 @@ struct os_mbuf_pool { /** - * A packet header structure that preceeds the mbuf packet headers. + * A packet header structure that proceeds the mbuf packet headers. */ struct os_mbuf_pkthdr { /** @@ -89,7 +89,7 @@ struct os_mbuf { */ uint8_t *om_data; /** - * Flags associated with this buffer, see OS_MBUF_F_* defintions + * Flags associated with this buffer, see OS_MBUF_F_* definitions */ uint8_t om_flags; /** diff --git a/components/bt/porting/nimble/include/os/os_mempool.h b/components/bt/porting/include/os/os_mempool.h similarity index 100% rename from components/bt/porting/nimble/include/os/os_mempool.h rename to components/bt/porting/include/os/os_mempool.h diff --git a/components/bt/porting/nimble/include/os/queue.h b/components/bt/porting/include/os/queue.h similarity index 81% rename from components/bt/porting/nimble/include/os/queue.h rename to components/bt/porting/include/os/queue.h index c184a394edbf..868f9abfa4fc 100644 --- a/components/bt/porting/nimble/include/os/queue.h +++ b/components/bt/porting/include/os/queue.h @@ -1,33 +1,27 @@ /* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. + * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF) * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * SPDX-License-Identifier: Apache-2.0 * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $ + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ #ifndef _QUEUE_H_ diff --git a/components/bt/porting/nimble/include/os/util.h b/components/bt/porting/include/os/util.h similarity index 100% rename from components/bt/porting/nimble/include/os/util.h rename to components/bt/porting/include/os/util.h diff --git a/components/bt/porting/nimble/src/os_msys_init.c b/components/bt/porting/mem/os_msys_init.c similarity index 96% rename from components/bt/porting/nimble/src/os_msys_init.c rename to components/bt/porting/mem/os_msys_init.c index bf4f4145166e..1a121e6d0b50 100644 --- a/components/bt/porting/nimble/src/os_msys_init.c +++ b/components/bt/porting/mem/os_msys_init.c @@ -82,12 +82,12 @@ static struct os_mempool os_msys_init_2_mempool; #endif #if CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER -extern int esp_ble_msys_init(uint16_t msys_size1, uint16_t msys_size2, uint16_t msys_cnt1, uint16_t msys_cnt2, uint8_t from_heap); -extern void esp_ble_msys_deinit(void); +extern int r_esp_ble_msys_init(uint16_t msys_size1, uint16_t msys_size2, uint16_t msys_cnt1, uint16_t msys_cnt2, uint8_t from_heap); +extern void r_esp_ble_msys_deinit(void); int os_msys_init(void) { - return esp_ble_msys_init(SYSINIT_MSYS_1_MEMBLOCK_SIZE, + return r_esp_ble_msys_init(SYSINIT_MSYS_1_MEMBLOCK_SIZE, SYSINIT_MSYS_2_MEMBLOCK_SIZE, OS_MSYS_1_BLOCK_COUNT, OS_MSYS_2_BLOCK_COUNT, @@ -96,7 +96,7 @@ int os_msys_init(void) void os_msys_deinit(void) { - esp_ble_msys_deinit(); + r_esp_ble_msys_deinit(); } #else // CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER diff --git a/components/bt/porting/nimble/include/nimble/ble.h b/components/bt/porting/nimble/include/nimble/ble.h deleted file mode 100644 index f037d3565b83..000000000000 --- a/components/bt/porting/nimble/include/nimble/ble.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF) - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef H_BLE_ -#define H_BLE_ - -#include -#include -#include "syscfg/syscfg.h" -#include "os/os.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* The number of advertising instances */ -#define BLE_ADV_INSTANCES (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) + 1) - -/* BLE encryption block definitions */ -#define BLE_ENC_BLOCK_SIZE (16) - -/* 4 byte header + 251 byte payload. */ -#define BLE_ACL_MAX_PKT_SIZE 255 - -struct ble_encryption_block -{ - uint8_t key[BLE_ENC_BLOCK_SIZE]; - uint8_t plain_text[BLE_ENC_BLOCK_SIZE]; - uint8_t cipher_text[BLE_ENC_BLOCK_SIZE]; -}; - -/* - * BLE MBUF structure: - * - * The BLE mbuf structure is as follows. Note that this structure applies to - * the packet header mbuf (not mbufs that are part of a "packet chain"): - * struct os_mbuf (16) - * struct os_mbuf_pkthdr (8) - * struct ble_mbuf_hdr (8) - * Data buffer (payload size, in bytes) - * - * The BLE mbuf header contains the following: - * flags: bitfield with the following values - * 0x01: Set if there was a match on the whitelist - * 0x02: Set if a connect request was transmitted upon receiving pdu - * 0x04: Set the first time we transmit the PDU (used to detect retry). - * channel: The logical BLE channel PHY channel # (0 - 39) - * crcok: flag denoting CRC check passed (1) or failed (0). - * rssi: RSSI, in dBm. - */ -struct ble_mbuf_hdr_rxinfo -{ - uint16_t flags; - uint8_t channel; - uint8_t handle; - int8_t rssi; - /* XXX: we could just use single phy_mode field */ - int8_t phy; - uint8_t phy_mode; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - int8_t rpa_index; -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - void *user_data; -#endif -}; - -/* - * Flag definitions for rxinfo - * - * Note: it's ok to have symbols with the same values as long as they cannot be - * set for the same PDU (e.g. one use by scanner, other one used by - * connection) - */ -#define BLE_MBUF_HDR_F_CONN_CREDIT (0x8000) -#define BLE_MBUF_HDR_F_IGNORED (0x8000) -#define BLE_MBUF_HDR_F_SCAN_REQ_TXD (0x4000) -#define BLE_MBUF_HDR_F_INITA_RESOLVED (0x2000) -#define BLE_MBUF_HDR_F_TARGETA_RESOLVED (0x2000) -#define BLE_MBUF_HDR_F_EXT_ADV_SEC (0x1000) -#define BLE_MBUF_HDR_F_EXT_ADV (0x0800) -#define BLE_MBUF_HDR_F_RESOLVED (0x0400) -#define BLE_MBUF_HDR_F_AUX_PTR_WAIT (0x0200) -#define BLE_MBUF_HDR_F_AUX_INVALID (0x0100) -#define BLE_MBUF_HDR_F_CRC_OK (0x0080) -#define BLE_MBUF_HDR_F_DEVMATCH (0x0040) -#define BLE_MBUF_HDR_F_MIC_FAILURE (0x0020) -#define BLE_MBUF_HDR_F_SCAN_RSP_TXD (0x0010) -#define BLE_MBUF_HDR_F_SCAN_RSP_RXD (0x0008) -#define BLE_MBUF_HDR_F_RXSTATE_MASK (0x0007) - -/* Transmit info. NOTE: no flags defined */ -struct ble_mbuf_hdr_txinfo -{ - uint8_t flags; - uint8_t reserve0; - uint8_t pyld_len; - uint8_t hdr_byte; - uint16_t offset; -}; - -struct ble_mbuf_hdr -{ - union { - struct ble_mbuf_hdr_rxinfo rxinfo; - struct ble_mbuf_hdr_txinfo txinfo; - }; - uint32_t beg_cputime; - uint32_t rem_usecs; -}; - -#define BLE_MBUF_HDR_IGNORED(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_IGNORED)) - -#define BLE_MBUF_HDR_SCAN_REQ_TXD(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_REQ_TXD)) - -#define BLE_MBUF_HDR_EXT_ADV_SEC(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_EXT_ADV_SEC)) - -#define BLE_MBUF_HDR_EXT_ADV(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_EXT_ADV)) - -#define BLE_MBUF_HDR_DEVMATCH(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_DEVMATCH)) - -#define BLE_MBUF_HDR_SCAN_RSP_RXD(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_RXD)) - -#define BLE_MBUF_HDR_AUX_INVALID(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_AUX_INVALID)) - -#define BLE_MBUF_HDR_WAIT_AUX(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT)) - -#define BLE_MBUF_HDR_CRC_OK(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_CRC_OK)) - -#define BLE_MBUF_HDR_MIC_FAILURE(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_MIC_FAILURE)) - -#define BLE_MBUF_HDR_RESOLVED(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_RESOLVED)) - -#define BLE_MBUF_HDR_INITA_RESOLVED(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_INITA_RESOLVED)) - -#define BLE_MBUF_HDR_TARGETA_RESOLVED(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_TARGETA_RESOLVED)) - -#define BLE_MBUF_HDR_RX_STATE(hdr) \ - ((uint8_t)((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_RXSTATE_MASK)) - -#define BLE_MBUF_HDR_PTR(om) \ - (struct ble_mbuf_hdr *)((uint8_t *)om + sizeof(struct os_mbuf) + \ - sizeof(struct os_mbuf_pkthdr)) - -/* BLE mbuf overhead per packet header mbuf */ -#define BLE_MBUF_PKTHDR_OVERHEAD \ - (sizeof(struct os_mbuf_pkthdr) + sizeof(struct ble_mbuf_hdr)) - -#define BLE_MBUF_MEMBLOCK_OVERHEAD \ - (sizeof(struct os_mbuf) + BLE_MBUF_PKTHDR_OVERHEAD) - -/* Length of host user header. Only contains the peer's connection handle. */ -#define BLE_MBUF_HS_HDR_LEN (2) - -#define BLE_DEV_ADDR_LEN (6) -extern uint8_t g_dev_addr[BLE_DEV_ADDR_LEN]; -extern uint8_t g_random_addr[BLE_DEV_ADDR_LEN]; - -/* BLE Error Codes (Core v4.2 Vol 2 part D) */ -enum ble_error_codes -{ - /* An "error" code of 0x0 means success */ - BLE_ERR_SUCCESS = 0x00, - BLE_ERR_UNKNOWN_HCI_CMD = 0x01, - BLE_ERR_UNK_CONN_ID = 0x02, - BLE_ERR_HW_FAIL = 0x03, - BLE_ERR_PAGE_TMO = 0x04, - BLE_ERR_AUTH_FAIL = 0x05, - BLE_ERR_PINKEY_MISSING = 0x06, - BLE_ERR_MEM_CAPACITY = 0x07, - BLE_ERR_CONN_SPVN_TMO = 0x08, - BLE_ERR_CONN_LIMIT = 0x09, - BLE_ERR_SYNCH_CONN_LIMIT = 0x0a, - BLE_ERR_ACL_CONN_EXISTS = 0x0b, - BLE_ERR_CMD_DISALLOWED = 0x0c, - BLE_ERR_CONN_REJ_RESOURCES = 0x0d, - BLE_ERR_CONN_REJ_SECURITY = 0x0e, - BLE_ERR_CONN_REJ_BD_ADDR = 0x0f, - BLE_ERR_CONN_ACCEPT_TMO = 0x10, - BLE_ERR_UNSUPPORTED = 0x11, - BLE_ERR_INV_HCI_CMD_PARMS = 0x12, - BLE_ERR_REM_USER_CONN_TERM = 0x13, - BLE_ERR_RD_CONN_TERM_RESRCS = 0x14, - BLE_ERR_RD_CONN_TERM_PWROFF = 0x15, - BLE_ERR_CONN_TERM_LOCAL = 0x16, - BLE_ERR_REPEATED_ATTEMPTS = 0x17, - BLE_ERR_NO_PAIRING = 0x18, - BLE_ERR_UNK_LMP = 0x19, - BLE_ERR_UNSUPP_REM_FEATURE = 0x1a, - BLE_ERR_SCO_OFFSET = 0x1b, - BLE_ERR_SCO_ITVL = 0x1c, - BLE_ERR_SCO_AIR_MODE = 0x1d, - BLE_ERR_INV_LMP_LL_PARM = 0x1e, - BLE_ERR_UNSPECIFIED = 0x1f, - BLE_ERR_UNSUPP_LMP_LL_PARM = 0x20, - BLE_ERR_NO_ROLE_CHANGE = 0x21, - BLE_ERR_LMP_LL_RSP_TMO = 0x22, - BLE_ERR_LMP_COLLISION = 0x23, - BLE_ERR_LMP_PDU = 0x24, - BLE_ERR_ENCRYPTION_MODE = 0x25, - BLE_ERR_LINK_KEY_CHANGE = 0x26, - BLE_ERR_UNSUPP_QOS = 0x27, - BLE_ERR_INSTANT_PASSED = 0x28, - BLE_ERR_UNIT_KEY_PAIRING = 0x29, - BLE_ERR_DIFF_TRANS_COLL = 0x2a, - /* BLE_ERR_RESERVED = 0x2b */ - BLE_ERR_QOS_PARM = 0x2c, - BLE_ERR_QOS_REJECTED = 0x2d, - BLE_ERR_CHAN_CLASS = 0x2e, - BLE_ERR_INSUFFICIENT_SEC = 0x2f, - BLE_ERR_PARM_OUT_OF_RANGE = 0x30, - /* BLE_ERR_RESERVED = 0x31 */ - BLE_ERR_PENDING_ROLE_SW = 0x32, - /* BLE_ERR_RESERVED = 0x33 */ - BLE_ERR_RESERVED_SLOT = 0x34, - BLE_ERR_ROLE_SW_FAIL = 0x35, - BLE_ERR_INQ_RSP_TOO_BIG = 0x36, - BLE_ERR_SEC_SIMPLE_PAIR = 0x37, - BLE_ERR_HOST_BUSY_PAIR = 0x38, - BLE_ERR_CONN_REJ_CHANNEL = 0x39, - BLE_ERR_CTLR_BUSY = 0x3a, - BLE_ERR_CONN_PARMS = 0x3b, - BLE_ERR_DIR_ADV_TMO = 0x3c, - BLE_ERR_CONN_TERM_MIC = 0x3d, - BLE_ERR_CONN_ESTABLISHMENT = 0x3e, - BLE_ERR_MAC_CONN_FAIL = 0x3f, - BLE_ERR_COARSE_CLK_ADJ = 0x40, - BLE_ERR_TYPE0_SUBMAP_NDEF = 0x41, - BLE_ERR_UNK_ADV_INDENT = 0x42, - BLE_ERR_LIMIT_REACHED = 0x43, - BLE_ERR_OPERATION_CANCELLED = 0x44, - BLE_ERR_PACKET_TOO_LONG = 0x45, - BLE_ERR_MAX = 0xff -}; - -/* HW error codes */ -#define BLE_HW_ERR_DO_NOT_USE (0) /* XXX: reserve this one for now */ -#define BLE_HW_ERR_HCI_SYNC_LOSS (1) - -/* Own Bluetooth Device address type */ -#define BLE_OWN_ADDR_PUBLIC (0x00) -#define BLE_OWN_ADDR_RANDOM (0x01) -#define BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT (0x02) -#define BLE_OWN_ADDR_RPA_RANDOM_DEFAULT (0x03) - -/* Bluetooth Device address type */ -#define BLE_ADDR_PUBLIC (0x00) -#define BLE_ADDR_RANDOM (0x01) -#define BLE_ADDR_PUBLIC_ID (0x02) -#define BLE_ADDR_RANDOM_ID (0x03) - -#define BLE_ADDR_ANY (&(ble_addr_t) { 0, {0, 0, 0, 0, 0, 0} }) - -#define BLE_ADDR_IS_RPA(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ - ((addr)->val[5] & 0xc0) == 0x40) -#define BLE_ADDR_IS_NRPA(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ - ((addr)->val[5] & 0xc0) == 0x00) -#define BLE_ADDR_IS_STATIC(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ - ((addr)->val[5] & 0xc0) == 0xc0) - -typedef struct { - uint8_t type; - uint8_t val[6]; -} ble_addr_t; - - -static inline int ble_addr_cmp(const ble_addr_t *a, const ble_addr_t *b) -{ - int type_diff; - - type_diff = a->type - b->type; - if (type_diff != 0) { - return type_diff; - } - - return memcmp(a->val, b->val, sizeof(a->val)); -} - -#ifdef __cplusplus -} -#endif - -#endif /* H_BLE_ */ diff --git a/components/bt/porting/nimble/include/nimble/nimble_opt.h b/components/bt/porting/nimble/include/nimble/nimble_opt.h deleted file mode 100644 index f0e988b27b0a..000000000000 --- a/components/bt/porting/nimble/include/nimble/nimble_opt.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef H_NIMBLE_OPT_ -#define H_NIMBLE_OPT_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Include automatically-generated settings. */ -#include "nimble/nimble_opt_auto.h" - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/components/bt/porting/nimble/include/nimble/nimble_opt_auto.h b/components/bt/porting/nimble/include/nimble/nimble_opt_auto.h deleted file mode 100644 index c4baec843bee..000000000000 --- a/components/bt/porting/nimble/include/nimble/nimble_opt_auto.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF) - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef H_NIMBLE_OPT_AUTO_ -#define H_NIMBLE_OPT_AUTO_ - -#include "syscfg/syscfg.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*** - * Automatic options. - * - * These settings are generated automatically from the user-specified syscfg - * settings. - */ - -#undef NIMBLE_BLE_ADVERTISE -#define NIMBLE_BLE_ADVERTISE \ - (MYNEWT_VAL(BLE_ROLE_BROADCASTER) || MYNEWT_VAL(BLE_ROLE_PERIPHERAL)) - -#undef NIMBLE_BLE_SCAN -#define NIMBLE_BLE_SCAN \ - (MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER)) - -#undef NIMBLE_BLE_CONNECT -#define NIMBLE_BLE_CONNECT \ - (MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_PERIPHERAL)) - - -/** Supported client ATT commands. */ - -#undef NIMBLE_BLE_ATT_CLT_FIND_INFO -#define NIMBLE_BLE_ATT_CLT_FIND_INFO \ - (MYNEWT_VAL(BLE_GATT_DISC_ALL_DSCS)) - -#undef NIMBLE_BLE_ATT_CLT_FIND_TYPE -#define NIMBLE_BLE_ATT_CLT_FIND_TYPE \ - (MYNEWT_VAL(BLE_GATT_DISC_SVC_UUID)) - -#undef NIMBLE_BLE_ATT_CLT_READ_TYPE -#define NIMBLE_BLE_ATT_CLT_READ_TYPE \ - (MYNEWT_VAL(BLE_GATT_FIND_INC_SVCS) || \ - MYNEWT_VAL(BLE_GATT_DISC_ALL_CHRS) || \ - MYNEWT_VAL(BLE_GATT_DISC_CHRS_UUID) || \ - MYNEWT_VAL(BLE_GATT_READ_UUID)) - -#undef NIMBLE_BLE_ATT_CLT_READ -#define NIMBLE_BLE_ATT_CLT_READ \ - (MYNEWT_VAL(BLE_GATT_READ) || \ - MYNEWT_VAL(BLE_GATT_READ_LONG) || \ - MYNEWT_VAL(BLE_GATT_FIND_INC_SVCS)) - -#undef NIMBLE_BLE_ATT_CLT_READ_BLOB -#define NIMBLE_BLE_ATT_CLT_READ_BLOB \ - (MYNEWT_VAL(BLE_GATT_READ_LONG)) - -#undef NIMBLE_BLE_ATT_CLT_READ_MULT -#define NIMBLE_BLE_ATT_CLT_READ_MULT \ - (MYNEWT_VAL(BLE_GATT_READ_MULT)) - -#undef NIMBLE_BLE_ATT_CLT_READ_MULT_VAR -#define NIMBLE_BLE_ATT_CLT_READ_MULT_VAR \ - (MYNEWT_VAL(BLE_GATT_READ_MULT_VAR)) - -#undef NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE -#define NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE \ - (MYNEWT_VAL(BLE_GATT_DISC_ALL_SVCS)) - -#undef NIMBLE_BLE_ATT_CLT_WRITE -#define NIMBLE_BLE_ATT_CLT_WRITE \ - (MYNEWT_VAL(BLE_GATT_WRITE)) - -#undef NIMBLE_BLE_ATT_CLT_SIGNED_WRITE -#define NIMBLE_BLE_ATT_CLT_SIGNED_WRITE \ - (MYNEWT_VAL(BLE_GATT_SIGNED_WRITE)) - -#undef NIMBLE_BLE_ATT_CLT_WRITE_NO_RSP -#define NIMBLE_BLE_ATT_CLT_WRITE_NO_RSP \ - (MYNEWT_VAL(BLE_GATT_WRITE_NO_RSP)) - -#undef NIMBLE_BLE_ATT_CLT_PREP_WRITE -#define NIMBLE_BLE_ATT_CLT_PREP_WRITE \ - (MYNEWT_VAL(BLE_GATT_WRITE_LONG)) - -#undef NIMBLE_BLE_ATT_CLT_EXEC_WRITE -#define NIMBLE_BLE_ATT_CLT_EXEC_WRITE \ - (MYNEWT_VAL(BLE_GATT_WRITE_LONG)) - -#undef NIMBLE_BLE_ATT_CLT_NOTIFY -#define NIMBLE_BLE_ATT_CLT_NOTIFY \ - (MYNEWT_VAL(BLE_GATT_NOTIFY)) - -#undef NIMBLE_BLE_ATT_CLT_INDICATE -#define NIMBLE_BLE_ATT_CLT_INDICATE \ - (MYNEWT_VAL(BLE_GATT_INDICATE)) - -/** Security manager settings. */ - -#undef NIMBLE_BLE_SM -#define NIMBLE_BLE_SM (MYNEWT_VAL(BLE_SM_LEGACY) || MYNEWT_VAL(BLE_SM_SC)) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/components/bt/porting/nimble/include/nimble/nimble_port.h b/components/bt/porting/nimble/include/nimble/nimble_port.h deleted file mode 100644 index 0035fee6c344..000000000000 --- a/components/bt/porting/nimble/include/nimble/nimble_port.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef _NIMBLE_PORT_H -#define _NIMBLE_PORT_H - -#include "sdkconfig.h" -#include "esp_err.h" -#include "nimble/nimble_npl.h" - -#define NIMBLE_CORE (CONFIG_BT_NIMBLE_PINNED_TO_CORE < CONFIG_FREERTOS_NUMBER_OF_CORES ? CONFIG_BT_NIMBLE_PINNED_TO_CORE : tskNO_AFFINITY) - -#define NIMBLE_HS_STACK_SIZE CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE - -#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED -#define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** -* @brief nimble_port_init - Initialize controller and NimBLE host stack -* -* @return esp_err_t - ESP_OK ( if success) -* Error code in case of failure -*/ -esp_err_t nimble_port_init(void); - -/** -* @brief nimble_port_deinit - Deinitialize controller and NimBLE host stack -* -* @return esp_err_t - ESP_OK ( if success) -* Error code in case of failure -*/ -esp_err_t nimble_port_deinit(void); - -void nimble_port_run(void); -int nimble_port_stop(void); - -/** - * @brief esp_nimble_init - Initialize the NimBLE host stack - * - * @return esp_err_t - */ -esp_err_t esp_nimble_init(void); - -/** - * @brief esp_nimble_deinit - Deinitialize the NimBLE host stack - * - * @return esp_err_t - */ -esp_err_t esp_nimble_deinit(void); - -struct ble_npl_eventq *nimble_port_get_dflt_eventq(void); - - -#ifdef __cplusplus -} -#endif - -#endif /* _NIMBLE_PORT_H */ diff --git a/components/bt/porting/nimble/include/nimble/nimble_npl.h b/components/bt/porting/npl/freertos/include/nimble/nimble_npl.h similarity index 83% rename from components/bt/porting/nimble/include/nimble/nimble_npl.h rename to components/bt/porting/npl/freertos/include/nimble/nimble_npl.h index c11a2972dfd8..c9482044b749 100644 --- a/components/bt/porting/nimble/include/nimble/nimble_npl.h +++ b/components/bt/porting/npl/freertos/include/nimble/nimble_npl.h @@ -1,20 +1,7 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * SPDX-License-Identifier: Apache-2.0 */ #ifndef _NIMBLE_NPL_H_ diff --git a/components/bt/porting/npl/freertos/src/npl_os_freertos.c b/components/bt/porting/npl/freertos/src/npl_os_freertos.c index c93a2224d779..29e2567d553d 100644 --- a/components/bt/porting/npl/freertos/src/npl_os_freertos.c +++ b/components/bt/porting/npl/freertos/src/npl_os_freertos.c @@ -1,9 +1,7 @@ /* - * SPDX-FileCopyrightText: 2019-2023 The Apache Software Foundation (ASF) + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2019-2024 Espressif Systems (Shanghai) CO LTD */ #include @@ -18,7 +16,6 @@ #include "freertos/timers.h" #include "freertos/portable.h" #include "nimble/npl_freertos.h" -#include "nimble/nimble_port.h" #include "os/os_mempool.h" #include "esp_log.h" @@ -481,32 +478,32 @@ IRAM_ATTR npl_freertos_mutex_release(struct ble_npl_mutex *mu) ble_npl_error_t npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens) { - struct ble_npl_sem_freertos *semaphor = NULL; + struct ble_npl_sem_freertos *semaphore = NULL; #if OS_MEM_ALLOC if (!os_memblock_from(&ble_freertos_sem_pool,sem->sem)) { sem->sem = os_memblock_get(&ble_freertos_sem_pool); - semaphor = (struct ble_npl_sem_freertos *)sem->sem; + semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - memset(semaphor, 0, sizeof(*semaphor)); - semaphor->handle = xSemaphoreCreateCounting(128, tokens); - BLE_LL_ASSERT(semaphor->handle); + memset(semaphore, 0, sizeof(*semaphore)); + semaphore->handle = xSemaphoreCreateCounting(128, tokens); + BLE_LL_ASSERT(semaphore->handle); } #else if(!sem->sem) { sem->sem = malloc(sizeof(struct ble_npl_sem_freertos)); - semaphor = (struct ble_npl_sem_freertos *)sem->sem; + semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - memset(semaphor, 0, sizeof(*semaphor)); - semaphor->handle = xSemaphoreCreateCounting(128, tokens); - BLE_LL_ASSERT(semaphor->handle); + memset(semaphore, 0, sizeof(*semaphore)); + semaphore->handle = xSemaphoreCreateCounting(128, tokens); + BLE_LL_ASSERT(semaphore->handle); } #endif @@ -516,19 +513,19 @@ npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens) ble_npl_error_t npl_freertos_sem_deinit(struct ble_npl_sem *sem) { - struct ble_npl_sem_freertos *semaphor = (struct ble_npl_sem_freertos *)sem->sem; + struct ble_npl_sem_freertos *semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - BLE_LL_ASSERT(semaphor->handle); - vSemaphoreDelete(semaphor->handle); + BLE_LL_ASSERT(semaphore->handle); + vSemaphoreDelete(semaphore->handle); #if OS_MEM_ALLOC - os_memblock_put(&ble_freertos_sem_pool,semaphor); + os_memblock_put(&ble_freertos_sem_pool,semaphore); #else - free((void *)semaphor); + free((void *)semaphore); #endif sem->sem = NULL; @@ -540,22 +537,22 @@ IRAM_ATTR npl_freertos_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout) { BaseType_t woken; BaseType_t ret; - struct ble_npl_sem_freertos *semaphor = (struct ble_npl_sem_freertos *)sem->sem; + struct ble_npl_sem_freertos *semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - BLE_LL_ASSERT(semaphor->handle); + BLE_LL_ASSERT(semaphore->handle); if (in_isr()) { BLE_LL_ASSERT(timeout == 0); - ret = xSemaphoreTakeFromISR(semaphor->handle, &woken); + ret = xSemaphoreTakeFromISR(semaphore->handle, &woken); if( woken == pdTRUE ) { portYIELD_FROM_ISR(); } } else { - ret = xSemaphoreTake(semaphor->handle, timeout); + ret = xSemaphoreTake(semaphore->handle, timeout); } return ret == pdPASS ? BLE_NPL_OK : BLE_NPL_TIMEOUT; @@ -566,21 +563,21 @@ IRAM_ATTR npl_freertos_sem_release(struct ble_npl_sem *sem) { BaseType_t ret; BaseType_t woken; - struct ble_npl_sem_freertos *semaphor = (struct ble_npl_sem_freertos *)sem->sem; + struct ble_npl_sem_freertos *semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - BLE_LL_ASSERT(semaphor->handle); + BLE_LL_ASSERT(semaphore->handle); if (in_isr()) { - ret = xSemaphoreGiveFromISR(semaphor->handle, &woken); + ret = xSemaphoreGiveFromISR(semaphore->handle, &woken); if( woken == pdTRUE ) { portYIELD_FROM_ISR(); } } else { - ret = xSemaphoreGive(semaphor->handle); + ret = xSemaphoreGive(semaphore->handle); } BLE_LL_ASSERT(ret == pdPASS); @@ -773,8 +770,8 @@ npl_freertos_callout_deinit(struct ble_npl_callout *co) uint16_t IRAM_ATTR npl_freertos_sem_get_count(struct ble_npl_sem *sem) { - struct ble_npl_sem_freertos *semaphor = (struct ble_npl_sem_freertos *)sem->sem; - return uxSemaphoreGetCount(semaphor->handle); + struct ble_npl_sem_freertos *semaphore = (struct ble_npl_sem_freertos *)sem->sem; + return uxSemaphoreGetCount(semaphore->handle); } diff --git a/components/bt/porting/transport/driver/common/hci_driver_h4.c b/components/bt/porting/transport/driver/common/hci_driver_h4.c new file mode 100644 index 000000000000..c31b71164e6c --- /dev/null +++ b/components/bt/porting/transport/driver/common/hci_driver_h4.c @@ -0,0 +1,356 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#include +#include "common/hci_driver_h4.h" + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#define HCI_H4_SM_W4_PKT_TYPE 0 +#define HCI_H4_SM_W4_HEADER 1 +#define HCI_H4_SM_W4_PAYLOAD 2 +#define HCI_H4_SM_COMPLETED 3 + +struct hci_h4_input_buffer { + const uint8_t *buf; + uint16_t len; +}; + +static int +hci_h4_frame_start(struct hci_h4_sm *rxs, uint8_t pkt_type) +{ + rxs->pkt_type = pkt_type; + rxs->len = 0; + rxs->exp_len = 0; + + switch (rxs->pkt_type) { + case HCI_H4_CMD: + rxs->min_len = 3; + break; + case HCI_H4_ACL: + case HCI_H4_ISO: + rxs->min_len = 4; + break; + case HCI_H4_EVT: + rxs->min_len = 2; + break; + default: + /* !TODO: Sync loss. Need to wait for reset. */ + return -1; + } + + return 0; +} + +static int +hci_h4_ib_consume(struct hci_h4_input_buffer *ib, uint16_t len) +{ + assert(ib->len >= len); + + ib->buf += len; + ib->len -= len; + + return len; +} + +static int +hci_h4_ib_pull_min_len(struct hci_h4_sm *rxs, + struct hci_h4_input_buffer *ib) +{ + uint16_t len; + + len = min(ib->len, rxs->min_len - rxs->len); + memcpy(&rxs->hdr[rxs->len], ib->buf, len); + + rxs->len += len; + hci_h4_ib_consume(ib, len); + + + return rxs->len != rxs->min_len; +} + +static int +hci_h4_sm_w4_header(struct hci_h4_sm *h4sm, struct hci_h4_input_buffer *ib) +{ + int rc; + + rc = hci_h4_ib_pull_min_len(h4sm, ib); + if (rc) { + /* need more data */ + return 1; + } + + switch (h4sm->pkt_type) { + case HCI_H4_CMD: + assert(h4sm->allocs && h4sm->allocs->cmd); + h4sm->buf = h4sm->allocs->cmd(); + if (!h4sm->buf) { + return -1; + } + + memcpy(h4sm->buf, h4sm->hdr, h4sm->len); + h4sm->exp_len = h4sm->hdr[2] + 3; + + break; + case HCI_H4_ACL: + assert(h4sm->allocs && h4sm->allocs->acl); + h4sm->om = h4sm->allocs->acl(); + if (!h4sm->om) { + return -1; + } + + os_mbuf_append(h4sm->om, h4sm->hdr, h4sm->len); + h4sm->exp_len = get_le16(&h4sm->hdr[2]) + 4; + break; +#if !CONFIG_BT_CONTROLLER_ENABLED + case HCI_H4_EVT: + if (h4sm->hdr[0] == BLE_HCI_EVCODE_LE_META) { + /* For LE Meta event we need 3 bytes to parse header */ + h4sm->min_len = 3; + rc = hci_h4_ib_pull_min_len(h4sm, ib); + if (rc) { + /* need more data */ + return 1; + } + } + + assert(h4sm->allocs && h4sm->allocs->evt); + + /* We can drop legacy advertising events if there's no free buffer in + * discardable pool. + */ + if (h4sm->hdr[2] == BLE_HCI_LE_SUBEV_ADV_RPT) { + h4sm->buf = h4sm->allocs->evt(1); + } else { + h4sm->buf = h4sm->allocs->evt(0); + if (!h4sm->buf) { + return -1; + } + } + + if (h4sm->buf) { + memcpy(h4sm->buf, h4sm->hdr, h4sm->len); + } + + h4sm->exp_len = h4sm->hdr[1] + 2; + break; +#endif // !CONFIG_BT_CONTROLLER_ENABLED + case HCI_H4_ISO: + assert(h4sm->allocs && h4sm->allocs->iso); + h4sm->om = h4sm->allocs->iso(); + if (!h4sm->om) { + return -1; + } + + os_mbuf_append(h4sm->om, h4sm->hdr, h4sm->len); + h4sm->exp_len = (get_le16(&h4sm->hdr[2]) & 0x7fff) + 4; + break; + default: + assert(0); + break; + } + + return 0; +} + +static int +hci_h4_sm_w4_payload(struct hci_h4_sm *h4sm, + struct hci_h4_input_buffer *ib) +{ + uint16_t mbuf_len; + uint16_t len; + int rc; + + len = min(ib->len, h4sm->exp_len - h4sm->len); + + + switch (h4sm->pkt_type) { + case HCI_H4_CMD: + case HCI_H4_EVT: + if (h4sm->buf) { + memcpy(&h4sm->buf[h4sm->len], ib->buf, len); + } + break; + case HCI_H4_ACL: + case HCI_H4_ISO: + assert(h4sm->om); + + mbuf_len = OS_MBUF_PKTLEN(h4sm->om); + rc = os_mbuf_append(h4sm->om, ib->buf, len); + if (rc) { + /* Some data may already be appended so need to adjust h4sm only by + * the size of appended data. + */ + len = OS_MBUF_PKTLEN(h4sm->om) - mbuf_len; + h4sm->len += len; + hci_h4_ib_consume(ib, len); + + return -1; + } + break; + default: + assert(0); + break; + } + + h4sm->len += len; + hci_h4_ib_consume(ib, len); + + /* return 1 if need more data */ + return h4sm->len != h4sm->exp_len; +} + +static void +hci_h4_sm_completed(struct hci_h4_sm *h4sm) +{ + int rc; + + switch (h4sm->pkt_type) { +#if CONFIG_BT_CONTROLLER_ENABLED + case HCI_H4_CMD: + if (h4sm->buf) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->buf); + assert(rc == 0); + h4sm->buf = NULL; + } + break; + case HCI_H4_ACL: + case HCI_H4_ISO: + if (h4sm->om) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->om); + assert(rc == 0); + h4sm->om = NULL; + } + break; +#else + case HCI_H4_CMD: + case HCI_H4_EVT: + if (h4sm->buf) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->buf); + if (rc != 0) { + ble_transport_free(h4sm->buf); + } + h4sm->buf = NULL; + } + break; + case HCI_H4_ACL: + case HCI_H4_ISO: + if (h4sm->om) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->om); + if (rc != 0) { + os_mbuf_free_chain(h4sm->om); + } + h4sm->om = NULL; + } + break; +#endif // CONFIG_BT_CONTROLLER_ENABLED + default: + assert(0); + break; + } +} + +int +hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len) +{ + struct hci_h4_input_buffer ib = { + .buf = buf, + .len = len, + }; + + int rc = 0; + while (ib.len && (rc >= 0)) { + rc = 0; + switch (h4sm->state) { + case HCI_H4_SM_W4_PKT_TYPE: + if (hci_h4_frame_start(h4sm, ib.buf[0]) < 0) { + return -1; + } + + hci_h4_ib_consume(&ib, 1); + h4sm->state = HCI_H4_SM_W4_HEADER; + /* no break */ + case HCI_H4_SM_W4_HEADER: + rc = hci_h4_sm_w4_header(h4sm, &ib); + assert(rc >= 0); + if (rc) { + break; + } + h4sm->state = HCI_H4_SM_W4_PAYLOAD; + /* no break */ + case HCI_H4_SM_W4_PAYLOAD: + rc = hci_h4_sm_w4_payload(h4sm, &ib); + assert(rc >= 0); + if (rc) { + break; + } + h4sm->state = HCI_H4_SM_COMPLETED; + /* no break */ + case HCI_H4_SM_COMPLETED: + hci_h4_sm_completed(h4sm); + h4sm->state = HCI_H4_SM_W4_PKT_TYPE; + break; + default: + return -1; + } + } + + /* Calculate consumed bytes + * + * Note: we should always consume some bytes unless there is an oom error. + * It's also possible that we have an oom error but already consumed some + * data, in such case just return success and error will be returned on next + * pass. + */ + len = len - ib.len; + if (len == 0) { + assert(rc < 0); + return -1; + } + + return len; +} + +void +hci_h4_sm_init(struct hci_h4_sm *h4sm, const struct hci_h4_allocators *allocs, + hci_h4_frame_cb *frame_cb) +{ + memset(h4sm, 0, sizeof(*h4sm)); + h4sm->allocs = allocs; + h4sm->frame_cb = frame_cb; +} diff --git a/components/bt/porting/transport/driver/common/hci_driver_mem.c b/components/bt/porting/transport/driver/common/hci_driver_mem.c new file mode 100644 index 000000000000..acfdf793f675 --- /dev/null +++ b/components/bt/porting/transport/driver/common/hci_driver_mem.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "common/hci_driver_mem.h" +#include "common/hci_driver_h4.h" +#include "esp_hci_internal.h" + +void * +hci_driver_mem_cmd_alloc(void) +{ + return r_ble_hci_trans_buf_alloc(ESP_HCI_INTERNAL_BUF_CMD); +} + +void * +hci_driver_mem_evt_alloc(int discardable) +{ + /* The controller shouldn't invoke this. */ + assert(0); + return NULL; +} + +struct os_mbuf * +hci_driver_mem_acl_alloc(void) +{ + return os_msys_get_pkthdr(0, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); +} + +struct os_mbuf * +hci_driver_mem_acl_len_alloc(uint32_t len) +{ + return os_msys_get_pkthdr(len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); +} + +struct os_mbuf * +hci_driver_mem_iso_alloc(void) +{ + return os_msys_get_pkthdr(0, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); +} + +struct os_mbuf * +hci_driver_mem_iso_len_alloc(uint32_t len) +{ + return os_msys_get_pkthdr(len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); +} + +const struct hci_h4_allocators s_hci_driver_mem_alloc = { + .cmd = hci_driver_mem_cmd_alloc, + .evt = hci_driver_mem_evt_alloc, + .acl = hci_driver_mem_acl_alloc, + .iso = hci_driver_mem_iso_alloc, +}; diff --git a/components/bt/porting/transport/driver/common/hci_driver_util.c b/components/bt/porting/transport/driver/common/hci_driver_util.c new file mode 100644 index 000000000000..30fe8d13c468 --- /dev/null +++ b/components/bt/porting/transport/driver/common/hci_driver_util.c @@ -0,0 +1,225 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_log.h" +#include "os/os.h" +#include "os/os_mempool.h" +#include "esp_hci_driver.h" +#include "esp_hci_internal.h" +#include "common/hci_driver_util.h" + +#define TAG "HCI_UTIL" +#define HCI_DRIVER_UTIL_TX_POOL_NUM \ + (CONFIG_BT_LE_ACL_BUF_COUNT + CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT + CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT) + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/** + * @brief Structure representing HCI TX data. + */ +typedef struct hci_driver_util_tx_entry { + hci_driver_data_type_t data_type; ///< Type of the HCI TX data. + uint8_t *data; ///< Pointer to the TX data. + uint32_t length; ///< Length of the TX data. + STAILQ_ENTRY(hci_driver_util_tx_entry) next; ///< Next element in the linked list. +} hci_driver_util_tx_entry_t; + +/* The list for hci_driver_util_tx_entry */ +STAILQ_HEAD(hci_driver_util_tx_list, hci_driver_util_tx_entry); + +typedef struct { + struct hci_driver_util_tx_list tx_head; + struct hci_driver_util_tx_entry *cur_tx_entry; + uint32_t cur_tx_off; + struct os_mempool *tx_entry_pool; + uint8_t *tx_entry_mem; +} hci_driver_util_env_t; + +static hci_driver_util_env_t s_hci_driver_util_env; + +static void +hci_driver_util_memory_deinit(void) +{ + if (s_hci_driver_util_env.tx_entry_pool) { + free(s_hci_driver_util_env.tx_entry_pool); + s_hci_driver_util_env.tx_entry_pool = NULL; + } + if (s_hci_driver_util_env.tx_entry_mem) { + free(s_hci_driver_util_env.tx_entry_mem); + s_hci_driver_util_env.tx_entry_mem = NULL; + } +} + +static int +hci_driver_util_memory_init(void) +{ + int rc; + + s_hci_driver_util_env.tx_entry_pool = (struct os_mempool *)malloc(sizeof(struct os_mempool)); + if (!s_hci_driver_util_env.tx_entry_pool) { + ESP_LOGE(TAG, "No memory for tx pool"); + goto init_err; + } + + s_hci_driver_util_env.tx_entry_mem = malloc(OS_MEMPOOL_SIZE(HCI_DRIVER_UTIL_TX_POOL_NUM, + sizeof(hci_driver_util_tx_entry_t)) * sizeof(os_membuf_t)); + if (!s_hci_driver_util_env.tx_entry_mem) { + ESP_LOGE(TAG, "No memory for tx pool buffer"); + goto init_err; + } + + rc = os_mempool_init(s_hci_driver_util_env.tx_entry_pool, HCI_DRIVER_UTIL_TX_POOL_NUM, + sizeof(hci_driver_util_tx_entry_t), s_hci_driver_util_env.tx_entry_mem, + "hci_tx_entry_pool"); + if (rc) { + ESP_LOGE(TAG, "Failed to initialize tx pool"); + goto init_err; + } + + return 0; + +init_err: + hci_driver_util_memory_deinit(); + return -1; +} + +void +hci_driver_util_tx_list_enqueue(hci_driver_data_type_t type, uint8_t *data, uint32_t len) +{ + os_sr_t sr; + hci_driver_util_tx_entry_t *tx_entry; + + tx_entry = os_memblock_get(s_hci_driver_util_env.tx_entry_pool); + assert(tx_entry != NULL); + tx_entry->data_type = type; + tx_entry->data = data; + tx_entry->length = len; + /* If the txbuf is command status event or command complete event, we should send firstly. + * The tx list maybe used in the controller task and hci task. Therefore, enter critical area. + */ + if ((type == HCI_DRIVER_TYPE_EVT) && ((data[0] == 0x0E) || (data[0] == 0x0F))) { + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_HEAD(&s_hci_driver_util_env.tx_head, tx_entry, next); + OS_EXIT_CRITICAL(sr); + } else { + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&s_hci_driver_util_env.tx_head, tx_entry, next); + OS_EXIT_CRITICAL(sr); + } +} + +uint32_t +hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_frame) +{ + os_sr_t sr; + uint32_t tx_len; + uint32_t data_len; + uint16_t out_off; + struct os_mbuf *om; + hci_driver_util_tx_entry_t *tx_entry; + + /* Check if there is any remaining data that hasn't been sent completely. If it has been completed, + * free the corresponding memory. Therefore, the HCI TX entry needs to be sent one by one; multiple + * entries cannot be sent together. + */ + tx_len = 0; + tx_entry = s_hci_driver_util_env.cur_tx_entry; + if (tx_entry) { + data_len = tx_entry->length; + if (tx_entry->data_type == HCI_DRIVER_TYPE_ACL) { + om = (struct os_mbuf *)tx_entry->data; + if (s_hci_driver_util_env.cur_tx_off >= data_len) { + os_mbuf_free_chain(om); + } else { + om = os_mbuf_off(om, s_hci_driver_util_env.cur_tx_off, &out_off); + tx_len = min(max_tx_len, om->om_len - out_off); + *tx_data = (void *)&om->om_data[out_off]; + } + } else if (tx_entry->data_type == HCI_DRIVER_TYPE_EVT) { + if (s_hci_driver_util_env.cur_tx_off >= data_len) { + r_ble_hci_trans_buf_free(tx_entry->data); + } else { + tx_len = min(max_tx_len, data_len - s_hci_driver_util_env.cur_tx_off); + *tx_data = &tx_entry->data[s_hci_driver_util_env.cur_tx_off]; + } + } else { + assert(0); + } + /* If this is the last frame, inform the invoker not to call this API until the current data + * has been completely sent. + */ + if (tx_len) { + s_hci_driver_util_env.cur_tx_off += tx_len; + + if (s_hci_driver_util_env.cur_tx_off >= data_len) { + *last_frame = true; + } else { + *last_frame = false; + } + } else { + os_memblock_put(s_hci_driver_util_env.tx_entry_pool, (void *)tx_entry); + s_hci_driver_util_env.cur_tx_entry = NULL; + } + } + + /* Find a new entry. */ + if (!tx_len && !STAILQ_EMPTY(&s_hci_driver_util_env.tx_head)) { + OS_ENTER_CRITICAL(sr); + tx_entry = STAILQ_FIRST(&s_hci_driver_util_env.tx_head); + STAILQ_REMOVE_HEAD(&s_hci_driver_util_env.tx_head, next); + OS_EXIT_CRITICAL(sr); + + *tx_data = &tx_entry->data_type; + s_hci_driver_util_env.cur_tx_entry = tx_entry; + s_hci_driver_util_env.cur_tx_off = 0; + tx_len = 1; + *last_frame = false; + } + + return tx_len; +} + +int +hci_driver_util_init(void) +{ + memset(&s_hci_driver_util_env, 0, sizeof(hci_driver_util_env_t)); + + if (hci_driver_util_memory_init()) { + return -1; + } + + STAILQ_INIT(&s_hci_driver_util_env.tx_head); + + return 0; +} + +void +hci_driver_util_deinit(void) +{ + hci_driver_util_tx_entry_t *tx_entry; + hci_driver_util_tx_entry_t *next_entry; + + /* Free all of controller buffers which haven't been sent yet. The whole mempool will be freed. + * Therefore, it's unnecessary to put the tx_entry into mempool. + */ + tx_entry = STAILQ_FIRST(&s_hci_driver_util_env.tx_head); + while (tx_entry) { + next_entry = STAILQ_NEXT(tx_entry, next); + if (tx_entry->data_type == HCI_DRIVER_TYPE_ACL) { + os_mbuf_free_chain((struct os_mbuf *)tx_entry->data); + } else if (tx_entry->data_type == HCI_DRIVER_TYPE_EVT) { + r_ble_hci_trans_buf_free(tx_entry->data); + } + tx_entry = next_entry; + } + + hci_driver_util_memory_deinit(); + + memset(&s_hci_driver_util_env, 0, sizeof(hci_driver_util_env_t)); +} diff --git a/components/bt/porting/transport/driver/uart/hci_driver_uart.c b/components/bt/porting/transport/driver/uart/hci_driver_uart.c new file mode 100644 index 000000000000..6ac2a462fa1b --- /dev/null +++ b/components/bt/porting/transport/driver/uart/hci_driver_uart.c @@ -0,0 +1,222 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "esp_log.h" +#include "driver/uart.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "common/hci_driver_h4.h" +#include "common/hci_driver_util.h" +#include "common/hci_driver_mem.h" +#include "hci_driver_uart.h" + +static const char *TAG = "hci_uart"; + +#define CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN (256) + +typedef struct { + TaskHandle_t tx_task_handler; + TaskHandle_t rx_task_handler; + hci_driver_uart_params_config_t *hci_uart_params; + SemaphoreHandle_t tx_sem; + QueueHandle_t rx_event_queue; + uint8_t *rx_data; + struct hci_h4_sm *h4_sm; + hci_driver_forward_fn *forward_cb; +} hci_driver_uart_env_t; + +static hci_driver_uart_env_t s_hci_driver_uart_env; +static struct hci_h4_sm s_hci_driver_uart_h4_sm; +static uint8_t s_hci_driver_uart_rx_data[CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN]; +static hci_driver_uart_params_config_t hci_driver_uart_params = BT_HCI_DRIVER_UART_CONFIG_DEFAULT(); + +static int +hci_driver_uart_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + /* By now, this layer is only used by controller. */ + assert(dir == HCI_DRIVER_DIR_C2H); + ESP_LOGD(TAG, "controller tx len:%d\n", length); + + hci_driver_util_tx_list_enqueue(data_type, data, length); + xSemaphoreGive(s_hci_driver_uart_env.tx_sem); + + return 0; +} + +static int +hci_driver_uart_h4_frame_cb(uint8_t pkt_type, void *data) +{ + hci_driver_forward_fn *forward_cb; + + forward_cb = s_hci_driver_uart_env.forward_cb; + if (!forward_cb) { + return -1; + } + ESP_LOGD(TAG, "h4 frame\n"); + return forward_cb(pkt_type, data, 0, HCI_DRIVER_DIR_H2C); +} + +static void +hci_driver_uart_tx_task(void *p) +{ + void *data; + bool last_frame; + uint32_t tx_len; + uart_port_t port; + + port = s_hci_driver_uart_env.hci_uart_params->hci_uart_port; + while (true) { + xSemaphoreTake(s_hci_driver_uart_env.tx_sem, portMAX_DELAY); + while (true) { + tx_len = hci_driver_util_tx_list_dequeue(0xffffff, &data, &last_frame); + if (tx_len == 0) { + break; + } + ESP_LOGD(TAG, "uart tx"); + ESP_LOG_BUFFER_HEXDUMP(TAG, data, tx_len, ESP_LOG_DEBUG); + uart_write_bytes(port, data, tx_len); + } + } +} + +static void +hci_driver_uart_rx_task(void *p) +{ + void *data; + int read_len; + int ret; + uart_port_t port; + uart_event_t uart_event; + + port = s_hci_driver_uart_env.hci_uart_params->hci_uart_port; + while (true) { + xQueueReceive(s_hci_driver_uart_env.rx_event_queue, &uart_event, portMAX_DELAY); + data = s_hci_driver_uart_env.rx_data; + while (true) { + read_len = uart_read_bytes(port, data, CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN, 0); + if (read_len == 0) { + break; + } + ESP_LOGD(TAG, "uart rx"); + ESP_LOG_BUFFER_HEXDUMP(TAG, data, read_len, ESP_LOG_DEBUG); + ret = hci_h4_sm_rx(s_hci_driver_uart_env.h4_sm, data, read_len); + if (ret < 0) { + r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR); + } + } + } +} + +static int +hci_driver_uart_task_create(void) +{ + /* !TODO: Set the core id by menuconfig */ + xTaskCreatePinnedToCore(hci_driver_uart_tx_task, "hci_driver_uart_tx_task", + CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE, NULL, + ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_env.tx_task_handler, + 0); + assert(s_hci_driver_uart_env.tx_task_handler); + + xTaskCreatePinnedToCore(hci_driver_uart_rx_task, "hci_driver_uart_rx_task", + CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE, NULL, + ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_env.rx_task_handler, + 0); + assert(s_hci_driver_uart_env.rx_task_handler); + + ESP_LOGI(TAG, "hci transport task create successfully, prio:%d, stack size: %ld", + ESP_TASK_BT_CONTROLLER_PRIO, CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE); + + return 0; +} + +static void +hci_driver_uart_deinit(void) +{ + if (s_hci_driver_uart_env.tx_task_handler) { + vTaskDelete(s_hci_driver_uart_env.tx_task_handler); + s_hci_driver_uart_env.tx_task_handler = NULL; + } + + if (s_hci_driver_uart_env.rx_task_handler) { + vTaskDelete(s_hci_driver_uart_env.rx_task_handler); + s_hci_driver_uart_env.rx_task_handler = NULL; + } + + ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_env.hci_uart_params->hci_uart_port)); + + if (!s_hci_driver_uart_env.tx_sem) { + vSemaphoreDelete(s_hci_driver_uart_env.tx_sem); + } + + hci_driver_util_deinit(); + memset(&s_hci_driver_uart_env, 0, sizeof(hci_driver_uart_env_t)); +} + +static int +hci_driver_uart_init(hci_driver_forward_fn *cb) +{ + int rc; + memset(&s_hci_driver_uart_env, 0, sizeof(hci_driver_uart_env_t)); + + s_hci_driver_uart_env.h4_sm = &s_hci_driver_uart_h4_sm; + hci_h4_sm_init(s_hci_driver_uart_env.h4_sm, &s_hci_driver_mem_alloc, hci_driver_uart_h4_frame_cb); + + rc = hci_driver_util_init(); + if (rc) { + goto error; + } + + s_hci_driver_uart_env.tx_sem = xSemaphoreCreateBinary(); + if (!s_hci_driver_uart_env.tx_sem) { + goto error; + } + + s_hci_driver_uart_env.rx_data = s_hci_driver_uart_rx_data; + s_hci_driver_uart_env.forward_cb = cb; + s_hci_driver_uart_env.hci_uart_params = &hci_driver_uart_params; + hci_driver_uart_config(&hci_driver_uart_params); + /* Currently, the queue size is set to 1. It will be considered as semaphore. */ + ESP_ERROR_CHECK(uart_driver_install(s_hci_driver_uart_env.hci_uart_params->hci_uart_port, + CONFIG_BT_LE_HCI_UART_RX_BUFFER_SIZE, + CONFIG_BT_LE_HCI_UART_TX_BUFFER_SIZE, + 1, &s_hci_driver_uart_env.rx_event_queue, + 0)); + + rc = hci_driver_uart_task_create(); + if (rc) { + goto error; + } + + return 0; + +error: + hci_driver_uart_deinit(); + return rc; +} + +int +hci_driver_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin) +{ + hci_driver_uart_params_config_t *uart_param = s_hci_driver_uart_env.hci_uart_params; + uart_param->hci_uart_tx_pin = tx_pin; + uart_param->hci_uart_rx_pin = rx_pin; + uart_param->hci_uart_rts_pin = rts_pin; + uart_param->hci_uart_cts_pin = cts_pin; + return hci_driver_uart_config(uart_param); +} + +hci_driver_ops_t hci_driver_uart_ops = { + .hci_driver_tx = hci_driver_uart_tx, + .hci_driver_init = hci_driver_uart_init, + .hci_driver_deinit = hci_driver_uart_deinit, +}; diff --git a/components/bt/porting/transport/driver/uart/hci_driver_uart.h b/components/bt/porting/transport/driver/uart/hci_driver_uart.h new file mode 100644 index 000000000000..8b5f5eb8560c --- /dev/null +++ b/components/bt/porting/transport/driver/uart/hci_driver_uart.h @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include "driver/uart.h" +#include "os/os_mbuf.h" +#include "esp_bt.h" +#include "esp_hci_transport.h" + +/** + * @brief UART configuration parameters for the HCI driver + */ +typedef struct hci_driver_uart_params_config +{ + uint8_t hci_uart_port; /*!< Port of UART for HCI */ + uint8_t hci_uart_data_bits; /*!< Data bits of UART for HCI */ + uint8_t hci_uart_stop_bits; /*!< Stop bits of UART for HCI */ + uint8_t hci_uart_flow_ctrl; /*!< Flow control of UART for HCI */ + uint8_t hci_uart_parity; /*!< UART parity */ + uint8_t hci_uart_driver_mode; /*!< UART driver mode */ + uint32_t hci_uart_baud; /*!< Baudrate of UART for HCI */ + int hci_uart_tx_pin; /*!< Tx Pin number of UART for HCI */ + int hci_uart_rx_pin; /*!< Rx Pin number of UART for HCI */ + int hci_uart_rts_pin; /*!< RTS Pin number of UART for HCI */ + int hci_uart_cts_pin; /*!< CTS Pin number of UART for HCI */ +} hci_driver_uart_params_config_t; + +#define BT_HCI_DRIVER_UART_CONFIG_DEFAULT() { \ + .hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \ + .hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \ + .hci_uart_tx_pin = DEFAULT_BT_LE_HCI_UART_TX_PIN , \ + .hci_uart_rx_pin = DEFAULT_BT_LE_HCI_UART_RX_PIN, \ + .hci_uart_cts_pin = DEFAULT_BT_LE_HCI_UART_CTS_PIN, \ + .hci_uart_rts_pin = DEFAULT_BT_LE_HCI_UART_RTS_PIN, \ + .hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \ + .hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \ + .hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \ + .hci_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \ +} + +/** + * @brief Configures the HCI driver UART parameters. + * This function sets up the UART interface according to the specified configuration parameters. + * + * @param uart_config A pointer to a structure containing the UART configuration parameters. + * The structure should include details such as baud rate, parity, stop bits, and flow control. + * Ensure that the uart_config structure is correctly initialized before calling this function. + * + * @return int Returns 0 on success, or a non-zero error code on failure. + * + * @note This function should be called before any UART communication is initiated. + */ +int hci_driver_uart_config(hci_driver_uart_params_config_t *uart_config); + +#if CONFIG_BT_LE_UART_HCI_DMA_MODE +/** + * @brief Reconfigure the UART pins for the HCI driver. + * + * This function changes the UART pin configuration for the HCI driver. + * + * @param tx_pin The pin number for the UART TX (transmit) line. + * @param rx_pin The pin number for the UART RX (receive) line. + * @param cts_pin The pin number for the UART CTS (clear to send) line. + * @param rts_pin The pin number for the UART RTS (request to send) line. + * + * @return int Returns 0 on success, or a negative error code on failure. + */ +int hci_driver_uart_dma_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin); +#define hci_uart_reconfig_pin hci_driver_uart_dma_reconfig_pin +#else +/** + * @brief Reconfigure the UART pins for the HCI driver. + * + * This function changes the UART pin configuration for the HCI driver. + * + * @param tx_pin The pin number for the UART TX (transmit) line. + * @param rx_pin The pin number for the UART RX (receive) line. + * @param cts_pin The pin number for the UART CTS (clear to send) line. + * @param rts_pin The pin number for the UART RTS (request to send) line. + * + * @return int Returns 0 on success, or a negative error code on failure. + */ +int hci_driver_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin); +#define hci_uart_reconfig_pin hci_driver_uart_reconfig_pin +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE + +#ifdef __cplusplus +} +#endif diff --git a/components/bt/porting/transport/driver/uart/hci_driver_uart_config.c b/components/bt/porting/transport/driver/uart/hci_driver_uart_config.c new file mode 100644 index 000000000000..aae33634647e --- /dev/null +++ b/components/bt/porting/transport/driver/uart/hci_driver_uart_config.c @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_log.h" +#include "driver/uart.h" +#include "hci_driver_uart.h" + + +static const char *TAG = "hci_uart_config"; +static uart_config_t s_uart_cfg; + +int hci_driver_uart_config(hci_driver_uart_params_config_t *uart_config) +{ + uart_config_t *uart_cfg; + uart_cfg = &s_uart_cfg; + uart_cfg->baud_rate = uart_config->hci_uart_baud; + uart_cfg->data_bits = uart_config->hci_uart_data_bits; + uart_cfg->stop_bits = uart_config->hci_uart_stop_bits; + uart_cfg->parity = uart_config->hci_uart_parity; + uart_cfg->flow_ctrl = uart_config->hci_uart_flow_ctrl; + uart_cfg->source_clk= UART_SCLK_DEFAULT; + uart_cfg->rx_flow_ctrl_thresh = UART_HW_FIFO_LEN(uart_config->hci_uart_port) - 1; + + + ESP_LOGI(TAG,"set uart pin tx:%d, rx:%d.\n", uart_config->hci_uart_tx_pin, uart_config->hci_uart_rx_pin); + ESP_LOGI(TAG,"set rts:%d, cts:%d.\n", uart_config->hci_uart_rts_pin, uart_config->hci_uart_cts_pin); + ESP_LOGI(TAG,"set baud_rate:%d.\n", uart_config->hci_uart_baud); + ESP_LOGI(TAG,"set flow_ctrl:%d.\n", uart_config->hci_uart_flow_ctrl); + + ESP_ERROR_CHECK(uart_driver_delete(uart_config->hci_uart_port)); + ESP_ERROR_CHECK(uart_param_config(uart_config->hci_uart_port, uart_cfg)); + ESP_ERROR_CHECK(uart_set_pin(uart_config->hci_uart_port, uart_config->hci_uart_tx_pin, uart_config->hci_uart_rx_pin, + uart_config->hci_uart_rts_pin, uart_config->hci_uart_cts_pin)); + return 0; +} diff --git a/components/bt/porting/transport/driver/uart/hci_driver_uart_dma.c b/components/bt/porting/transport/driver/uart/hci_driver_uart_dma.c new file mode 100644 index 000000000000..3111a7cea3c3 --- /dev/null +++ b/components/bt/porting/transport/driver/uart/hci_driver_uart_dma.c @@ -0,0 +1,671 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "esp_log.h" +#include "driver/uart.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "common/hci_driver_h4.h" +#include "common/hci_driver_util.h" +#include "common/hci_driver_mem.h" +#include "hci_driver_uart.h" + +#include "ble_hci_trans.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/gdma.h" +#include "hal/uhci_ll.h" + +/* + * UART DMA Desc struct + * + * -------------------------------------------------------------- + * | own | EoF | sub_sof | 5'b0 | length [11:0] | size [11:0] | + * -------------------------------------------------------------- + * | buf_ptr [31:0] | + * -------------------------------------------------------------- + * | next_desc_ptr [31:0] | + * -------------------------------------------------------------- + */ + +/* this bitfield is start from the LSB!!! */ +typedef struct uhci_lldesc_s { + volatile uint32_t size : 12, + length: 12, + offset: 5, /* h/w reserved 5bit, s/w use it as offset in buffer */ + sosf : 1, /* start of sub-frame */ + eof : 1, /* end of frame */ + owner : 1; /* hw or sw */ + volatile const uint8_t *buf; /* point to buffer data */ + union { + volatile uint32_t empty; + STAILQ_ENTRY(uhci_lldesc_s) qe; /* pointing to the next desc */ + }; +} uhci_lldesc_t; + +/** + * @brief Enumeration of HCI transport transmission states. + */ +typedef enum { + HCI_TRANS_TX_IDLE, ///< HCI Transport TX is in idle state. + HCI_TRANS_TX_START, ///< HCI Transport TX is starting transmission. + HCI_TRANS_TX_END, ///< HCI Transport TX has completed transmission. +} hci_trans_tx_state_t; + +typedef struct { + TaskHandle_t task_handler; + hci_driver_uart_params_config_t *hci_uart_params; + SemaphoreHandle_t process_sem; + struct hci_h4_sm *h4_sm; + hci_driver_forward_fn *forward_cb; + struct os_mempool *hci_rx_data_pool; /*!< Init a memory pool for rx_data cache */ + uint8_t *hci_rx_data_buffer; + struct os_mempool *hci_rxinfo_pool; /*!< Init a memory pool for rxinfo cache */ + os_membuf_t *hci_rxinfo_buffer; + volatile bool rxinfo_mem_exhausted; /*!< Indicate rxinfo memory does not exist */ + volatile bool is_continue_rx; /*!< Continue to rx */ + volatile hci_trans_tx_state_t hci_tx_state; /*!< HCI Tx State */ + struct os_mempool lldesc_mem_pool;/*!< Init a memory pool for uhci_lldesc_t */ + uhci_lldesc_t *lldesc_mem; +} hci_driver_uart_dma_env_t; + +#define ESP_BT_HCI_TL_STATUS_OK (0) /*!< HCI_TL Tx/Rx operation status OK */ +/* The number of lldescs pool */ +#define HCI_LLDESCS_POOL_NUM (CONFIG_BT_LE_HCI_LLDESCS_POOL_NUM) +/* Default block size for HCI RX data */ +#define HCI_RX_DATA_BLOCK_SIZE (DEFAULT_BT_LE_ACL_BUF_SIZE + BLE_HCI_TRANS_CMD_SZ) +#define HCI_RX_DATA_POOL_NUM (CONFIG_BT_LE_HCI_TRANS_RX_MEM_NUM) +#define HCI_RX_INFO_POOL_NUM (CONFIG_BT_LE_HCI_TRANS_RX_MEM_NUM + 1) + +/** + * @brief callback function for HCI Transport Layer send/receive operations + */ +typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status); + +struct uart_txrxchannel { + esp_bt_hci_tl_callback_t callback; + void *arg; + uhci_lldesc_t *link_head; +}; + +struct uart_env_tag { + struct uart_txrxchannel tx; + struct uart_txrxchannel rx; +}; + +typedef struct hci_message { + void *ptr; ///< Pointer to the message data. + uint32_t length; ///< Length of the message data. + STAILQ_ENTRY(hci_message) next; ///< Next element in the linked list. +} hci_message_t; + +static void hci_driver_uart_dma_recv_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg); +int hci_driver_uart_dma_rx_start(uint8_t *rx_data, uint32_t length); +int hci_driver_uart_dma_tx_start(esp_bt_hci_tl_callback_t callback, void *arg); + +static const char *TAG = "uart_dma"; +static hci_driver_uart_dma_env_t s_hci_driver_uart_dma_env; +static struct hci_h4_sm s_hci_driver_uart_h4_sm; +static hci_driver_uart_params_config_t hci_driver_uart_dma_params = BT_HCI_DRIVER_UART_CONFIG_DEFAULT(); + +/* The list for hci_rx_data */ +STAILQ_HEAD(g_hci_rxinfo_list, hci_message); + +DRAM_ATTR struct g_hci_rxinfo_list g_hci_rxinfo_head; +static DRAM_ATTR struct uart_env_tag uart_env; +static volatile uhci_dev_t *s_uhci_hw = &UHCI0; +static DRAM_ATTR gdma_channel_handle_t s_rx_channel; +static DRAM_ATTR gdma_channel_handle_t s_tx_channel; + +static int hci_driver_uart_dma_memory_deinit(void) +{ + + if (s_hci_driver_uart_dma_env.hci_rxinfo_buffer) { + free(s_hci_driver_uart_dma_env.hci_rxinfo_buffer); + s_hci_driver_uart_dma_env.hci_rxinfo_buffer = NULL; + } + + if (s_hci_driver_uart_dma_env.hci_rxinfo_pool) { + free(s_hci_driver_uart_dma_env.hci_rxinfo_pool); + s_hci_driver_uart_dma_env.hci_rxinfo_pool = NULL; + } + + if (s_hci_driver_uart_dma_env.hci_rx_data_buffer) { + free(s_hci_driver_uart_dma_env.hci_rx_data_buffer); + s_hci_driver_uart_dma_env.hci_rx_data_buffer = NULL; + } + + if (s_hci_driver_uart_dma_env.hci_rx_data_pool) { + free(s_hci_driver_uart_dma_env.hci_rx_data_pool); + s_hci_driver_uart_dma_env.hci_rx_data_pool = NULL; + } + + if (s_hci_driver_uart_dma_env.lldesc_mem) { + free(s_hci_driver_uart_dma_env.lldesc_mem); + s_hci_driver_uart_dma_env.lldesc_mem = NULL; + } + + return 0; +} + +static int hci_driver_uart_dma_memory_init(void) +{ + int rc = 0; + + s_hci_driver_uart_dma_env.lldesc_mem = malloc(OS_MEMPOOL_SIZE(HCI_LLDESCS_POOL_NUM, + sizeof (uhci_lldesc_t)) * sizeof(os_membuf_t)); + if (!s_hci_driver_uart_dma_env.lldesc_mem) { + return -1; + } + + rc = os_mempool_init(&s_hci_driver_uart_dma_env.lldesc_mem_pool, HCI_LLDESCS_POOL_NUM, + sizeof (uhci_lldesc_t), s_hci_driver_uart_dma_env.lldesc_mem, "hci_lldesc_pool"); + if (rc) { + goto init_err; + } + + s_hci_driver_uart_dma_env.hci_rx_data_pool = (struct os_mempool *)malloc(sizeof(struct os_mempool)); + if (!s_hci_driver_uart_dma_env.hci_rx_data_pool) { + goto init_err; + } + + memset(s_hci_driver_uart_dma_env.hci_rx_data_pool, 0, sizeof(struct os_mempool)); + s_hci_driver_uart_dma_env.hci_rx_data_buffer = malloc(OS_MEMPOOL_SIZE(HCI_RX_DATA_POOL_NUM, + HCI_RX_DATA_BLOCK_SIZE) * sizeof(os_membuf_t)); + if (!s_hci_driver_uart_dma_env.hci_rx_data_buffer) { + goto init_err; + } + + memset(s_hci_driver_uart_dma_env.hci_rx_data_buffer, 0, OS_MEMPOOL_SIZE(HCI_RX_DATA_POOL_NUM, + HCI_RX_DATA_BLOCK_SIZE) * sizeof(os_membuf_t)); + rc = os_mempool_init(s_hci_driver_uart_dma_env.hci_rx_data_pool, HCI_RX_DATA_POOL_NUM, + HCI_RX_DATA_BLOCK_SIZE, s_hci_driver_uart_dma_env.hci_rx_data_buffer, + "hci_rx_data_pool"); + if (rc) { + goto init_err; + } + + + /* Malloc hci rxinfo pool */ + s_hci_driver_uart_dma_env.hci_rxinfo_pool = (struct os_mempool *)malloc(sizeof(struct os_mempool)); + if (!s_hci_driver_uart_dma_env.hci_rxinfo_pool) { + goto init_err; + } + + memset(s_hci_driver_uart_dma_env.hci_rxinfo_pool, 0, sizeof(struct os_mempool)); + s_hci_driver_uart_dma_env.hci_rxinfo_buffer = malloc(OS_MEMPOOL_SIZE(HCI_RX_INFO_POOL_NUM, + sizeof(hci_message_t)) * sizeof(os_membuf_t)); + if (!s_hci_driver_uart_dma_env.hci_rxinfo_buffer) { + goto init_err; + } + + memset(s_hci_driver_uart_dma_env.hci_rxinfo_buffer, 0, OS_MEMPOOL_SIZE(HCI_RX_INFO_POOL_NUM, + sizeof(hci_message_t)) * sizeof(os_membuf_t)); + rc = os_mempool_init(s_hci_driver_uart_dma_env.hci_rxinfo_pool, HCI_RX_INFO_POOL_NUM, + sizeof(hci_message_t), s_hci_driver_uart_dma_env.hci_rxinfo_buffer, + "hci_rxinfo_pool"); + if (rc) { + goto init_err; + } + + return rc; +init_err: + hci_driver_uart_dma_memory_deinit(); + return rc; +} + +static IRAM_ATTR bool hci_uart_tl_rx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + esp_bt_hci_tl_callback_t callback = uart_env.rx.callback; + void *arg = uart_env.rx.arg; + assert(dma_chan == s_rx_channel); + assert(uart_env.rx.callback != NULL); + // clear callback pointer + uart_env.rx.callback = NULL; + uart_env.rx.arg = NULL; + // call handler + callback(arg, ESP_BT_HCI_TL_STATUS_OK); + return true; +} + +static IRAM_ATTR bool hci_uart_tl_tx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + esp_bt_hci_tl_callback_t callback = uart_env.tx.callback; + assert(dma_chan == s_tx_channel); + assert(uart_env.tx.callback != NULL); + // clear callback pointer + uart_env.tx.callback = NULL; + // call handler + callback(uart_env.tx.arg, ESP_BT_HCI_TL_STATUS_OK); + uart_env.tx.arg = NULL; + return true; +} + +uint8_t * IRAM_ATTR hci_driver_uart_dma_rxdata_memory_get(void) +{ + uint8_t *rx_data; + rx_data = os_memblock_get(s_hci_driver_uart_dma_env.hci_rx_data_pool); + return rx_data; +} + +hci_message_t * IRAM_ATTR hci_driver_uart_dma_rxinfo_memory_get(void) +{ + hci_message_t *rx_info; + rx_info = os_memblock_get(s_hci_driver_uart_dma_env.hci_rxinfo_pool); + return rx_info; +} + +void IRAM_ATTR hci_driver_uart_dma_cache_rxinfo(hci_message_t *hci_rxinfo) +{ + os_sr_t sr; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&g_hci_rxinfo_head, hci_rxinfo, next); + OS_EXIT_CRITICAL(sr); +} + +void IRAM_ATTR hci_driver_uart_dma_continue_rx_enable(bool enable) +{ + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + s_hci_driver_uart_dma_env.is_continue_rx = enable; + OS_EXIT_CRITICAL(sr); +} + +void IRAM_ATTR hci_driver_uart_dma_rxinfo_mem_exhausted_set(bool is_exhausted) +{ + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + s_hci_driver_uart_dma_env.rxinfo_mem_exhausted = is_exhausted; + OS_EXIT_CRITICAL(sr); +} + +void IRAM_ATTR hci_driver_uart_dma_recv_callback(void *arg, uint8_t status) +{ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + hci_message_t *hci_rxinfo; + uint8_t *rx_data; + + if (s_hci_driver_uart_dma_env.rxinfo_mem_exhausted) { + ESP_LOGE(TAG, "Will lost rx data, need adjust rxinfo memory count\n"); + assert(0); + } + + hci_rxinfo = hci_driver_uart_dma_rxinfo_memory_get(); + if (!hci_rxinfo) { + ESP_LOGW(TAG, "set rxinfo mem exhausted flag\n"); + hci_driver_uart_dma_rxinfo_mem_exhausted_set(true); + xSemaphoreGiveFromISR(s_hci_driver_uart_dma_env.process_sem, &xHigherPriorityTaskWoken); + return; + } + + hci_rxinfo->ptr = (void *)uart_env.rx.link_head->buf; + hci_rxinfo->length = uart_env.rx.link_head->length; + hci_driver_uart_dma_cache_rxinfo(hci_rxinfo); + xSemaphoreGiveFromISR(s_hci_driver_uart_dma_env.process_sem, &xHigherPriorityTaskWoken); + rx_data = hci_driver_uart_dma_rxdata_memory_get(); + if (!rx_data) { + hci_driver_uart_dma_continue_rx_enable(true); + }else { + hci_driver_uart_dma_rx_start(rx_data, HCI_RX_DATA_BLOCK_SIZE); + } +} + +void IRAM_ATTR hci_driver_uart_dma_txstate_set(hci_trans_tx_state_t tx_state) +{ + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + s_hci_driver_uart_dma_env.hci_tx_state = tx_state; + OS_EXIT_CRITICAL(sr); +} + +void IRAM_ATTR hci_driver_uart_dma_send_callback(void *arg, uint8_t status) +{ + uhci_lldesc_t *lldesc_head; + uhci_lldesc_t *lldesc_nxt; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + lldesc_head = uart_env.tx.link_head; + while (lldesc_head) { + lldesc_nxt = lldesc_head->qe.stqe_next; + os_memblock_put(&s_hci_driver_uart_dma_env.lldesc_mem_pool, lldesc_head); + lldesc_head = lldesc_nxt; + } + + uart_env.tx.link_head = NULL; + hci_driver_uart_dma_txstate_set(HCI_TRANS_TX_IDLE); + xSemaphoreGiveFromISR(s_hci_driver_uart_dma_env.process_sem, &xHigherPriorityTaskWoken); +} + +static IRAM_ATTR void hci_driver_uart_dma_recv_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg) +{ + uhci_lldesc_t *lldesc_head; + assert(buf != NULL); + assert(size != 0); + assert(callback != NULL); + uart_env.rx.callback = callback; + uart_env.rx.arg = arg; + lldesc_head = uart_env.rx.link_head; + + while (lldesc_head) { + os_memblock_put(&s_hci_driver_uart_dma_env.lldesc_mem_pool, lldesc_head), + lldesc_head = lldesc_head->qe.stqe_next; + } + + uart_env.rx.link_head = NULL; + lldesc_head = os_memblock_get(&s_hci_driver_uart_dma_env.lldesc_mem_pool); + assert(lldesc_head); + memset(lldesc_head, 0, sizeof(uhci_lldesc_t)); + lldesc_head->buf = buf; + lldesc_head->size = size; + lldesc_head->eof = 0; + s_uhci_hw->pkt_thres.pkt_thrs = size; + uart_env.rx.link_head = lldesc_head; + gdma_start(s_rx_channel, (intptr_t)(uart_env.rx.link_head)); +} + +int IRAM_ATTR hci_driver_uart_dma_rx_start(uint8_t *rx_data, uint32_t length) +{ + hci_driver_uart_dma_recv_async(rx_data, length, hci_driver_uart_dma_recv_callback, NULL); + return 0; +} + +int hci_driver_uart_dma_tx_start(esp_bt_hci_tl_callback_t callback, void *arg) +{ + void *data; + bool last_frame; + bool head_is_setted; + uint32_t tx_len; + uhci_lldesc_t *lldesc_data; + uhci_lldesc_t *lldesc_head; + uhci_lldesc_t *lldesc_tail; + + lldesc_head = NULL; + lldesc_tail = NULL; + head_is_setted = false; + last_frame = false; + while (true) { + tx_len = hci_driver_util_tx_list_dequeue(0xffffff, &data, &last_frame); + if (!tx_len) { + break; + } + + lldesc_data = os_memblock_get(&s_hci_driver_uart_dma_env.lldesc_mem_pool); + /* According to the current processing logic, It should not be empty */ + assert(lldesc_data); + memset(lldesc_data, 0, sizeof(uhci_lldesc_t)); + lldesc_data->length = tx_len; + lldesc_data->buf = data; + lldesc_data->eof = 0; + if (!head_is_setted) { + lldesc_head = lldesc_data; + head_is_setted = true; + } else { + lldesc_tail->qe.stqe_next = lldesc_data; + } + + lldesc_tail = lldesc_data; + if (last_frame) { + break; + } + } + + if (lldesc_head) { + lldesc_tail->eof = 1; + uart_env.tx.link_head = lldesc_head; + uart_env.tx.callback = callback; + uart_env.tx.arg = arg; + /* The DMA interrupt may have been triggered before setting the tx_state, + * So we set it first. + */ + hci_driver_uart_dma_txstate_set(HCI_TRANS_TX_START); + gdma_start(s_tx_channel, (intptr_t)(uart_env.tx.link_head)); + return 0; + } else { + return -1; + } +} + +static void hci_driver_uart_dma_install(void) +{ + periph_module_enable(PERIPH_UHCI0_MODULE); + periph_module_reset(PERIPH_UHCI0_MODULE); + // install DMA driver + gdma_channel_alloc_config_t tx_channel_config = { + .flags.reserve_sibling = 1, + .direction = GDMA_CHANNEL_DIRECTION_TX, + }; + + ESP_ERROR_CHECK(gdma_new_channel(&tx_channel_config, &s_tx_channel)); + gdma_channel_alloc_config_t rx_channel_config = { + .direction = GDMA_CHANNEL_DIRECTION_RX, + .sibling_chan = s_tx_channel, + }; + + ESP_ERROR_CHECK(gdma_new_channel(&rx_channel_config, &s_rx_channel)); + gdma_connect(s_tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0)); + gdma_connect(s_rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0)); + gdma_strategy_config_t strategy_config = { + .auto_update_desc = false, + .owner_check = false + }; + + gdma_apply_strategy(s_tx_channel, &strategy_config); + gdma_apply_strategy(s_rx_channel, &strategy_config); + gdma_rx_event_callbacks_t rx_cbs = { + .on_recv_eof = hci_uart_tl_rx_eof_callback + }; + + gdma_register_rx_event_callbacks(s_rx_channel, &rx_cbs, NULL); + gdma_tx_event_callbacks_t tx_cbs = { + .on_trans_eof = hci_uart_tl_tx_eof_callback + }; + + gdma_register_tx_event_callbacks(s_tx_channel, &tx_cbs, NULL); + // configure UHCI + uhci_ll_init((uhci_dev_t *)s_uhci_hw); + // uhci_ll_set_eof_mode((uhci_dev_t *)s_uhci_hw, UHCI_RX_LEN_EOF); + uhci_ll_set_eof_mode((uhci_dev_t *)s_uhci_hw, UHCI_RX_IDLE_EOF); + // disable software flow control + s_uhci_hw->escape_conf.val = 0; + uhci_ll_attach_uart_port((uhci_dev_t *)s_uhci_hw, s_hci_driver_uart_dma_env.hci_uart_params->hci_uart_port); +} + +static int +hci_driver_uart_dma_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + /* By now, this layer is only used by controller. */ + assert(dir == HCI_DRIVER_DIR_C2H); + ESP_LOGD(TAG, "dma tx:"); + ESP_LOG_BUFFER_HEXDUMP(TAG, data, length, ESP_LOG_DEBUG); + + hci_driver_util_tx_list_enqueue(data_type, data, length); + xSemaphoreGive(s_hci_driver_uart_dma_env.process_sem); + return 0; +} + +static int +hci_driver_uart_dma_h4_frame_cb(uint8_t pkt_type, void *data) +{ + hci_driver_forward_fn *forward_cb; + forward_cb = s_hci_driver_uart_dma_env.forward_cb; + if (!forward_cb) { + return -1; + } + ESP_LOGD(TAG, "h4 frame\n"); + return forward_cb(pkt_type, data, 0, HCI_DRIVER_DIR_H2C); +} + +static void +hci_driver_uart_dma_process_task(void *p) +{ + hci_message_t *rxinfo_container; + os_sr_t sr; + int ret; + uint8_t* rx_data; + uint32_t rx_len; + + while (true) { + xSemaphoreTake(s_hci_driver_uart_dma_env.process_sem, portMAX_DELAY); + ESP_LOGD(TAG, "task run:%d\n",s_hci_driver_uart_dma_env.hci_tx_state); + /* Process Tx data */ + if (s_hci_driver_uart_dma_env.hci_tx_state == HCI_TRANS_TX_IDLE) { + hci_driver_uart_dma_tx_start(hci_driver_uart_dma_send_callback, (void*)&uart_env); + } + + if (s_hci_driver_uart_dma_env.rxinfo_mem_exhausted) { + rx_data = (void *)uart_env.rx.link_head->buf; + rx_len = uart_env.rx.link_head->length; + ESP_LOGD(TAG, "rxinfo exhausted:"); + ESP_LOG_BUFFER_HEXDUMP(TAG, rx_data, rx_len, ESP_LOG_DEBUG); + ret = hci_h4_sm_rx(s_hci_driver_uart_dma_env.h4_sm, rx_data, rx_len); + hci_driver_uart_dma_rx_start(rx_data, HCI_RX_DATA_BLOCK_SIZE); + hci_driver_uart_dma_rxinfo_mem_exhausted_set(false); + if (ret < 0) { + ESP_LOGW(TAG, "parse rx data error!\n"); + r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR); + } + } + + while (!STAILQ_EMPTY(&g_hci_rxinfo_head)) { + OS_ENTER_CRITICAL(sr); + rxinfo_container = STAILQ_FIRST(&g_hci_rxinfo_head); + STAILQ_REMOVE_HEAD(&g_hci_rxinfo_head, next); + OS_EXIT_CRITICAL(sr); + + rx_data = rxinfo_container->ptr; + rx_len = rxinfo_container->length; + ESP_LOGD(TAG, "uart rx"); + ESP_LOG_BUFFER_HEXDUMP(TAG, rx_data, rx_len, ESP_LOG_DEBUG); + ret = hci_h4_sm_rx(s_hci_driver_uart_dma_env.h4_sm, rx_data, rx_len); + if (ret < 0) { + ESP_LOGW(TAG, "parse rx data error!\n"); + r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR); + } + + os_memblock_put(s_hci_driver_uart_dma_env.hci_rxinfo_pool, rxinfo_container); + /* No need to enter CRITICAL */ + if (s_hci_driver_uart_dma_env.is_continue_rx) { + /* We should set continux rx flag first, RX interrupted may happened when rx start soon */ + hci_driver_uart_dma_continue_rx_enable(false); + hci_driver_uart_dma_rx_start(rx_data, HCI_RX_DATA_BLOCK_SIZE); + } else { + os_memblock_put(s_hci_driver_uart_dma_env.hci_rx_data_pool, rx_data); + } + } + } +} + +static int +hci_driver_uart_dma_task_create(void) +{ + /* !TODO: Set the core id by menuconfig */ + xTaskCreatePinnedToCore(hci_driver_uart_dma_process_task, "hci_driver_uart_dma_process_task", + CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE, NULL, + ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_dma_env.task_handler, + 0); + assert(s_hci_driver_uart_dma_env.task_handler); + + ESP_LOGI(TAG, "hci transport task create successfully, prio:%d, stack size: %ld", + ESP_TASK_BT_CONTROLLER_PRIO, CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE); + + return 0; +} + + +static void +hci_driver_uart_dma_deinit(void) +{ + if (s_hci_driver_uart_dma_env.task_handler) { + vTaskDelete(s_hci_driver_uart_dma_env.task_handler); + s_hci_driver_uart_dma_env.task_handler = NULL; + } + + ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_dma_env.hci_uart_params->hci_uart_port)); + hci_driver_uart_dma_memory_deinit(); + if (!s_hci_driver_uart_dma_env.process_sem) { + vSemaphoreDelete(s_hci_driver_uart_dma_env.process_sem); + } + + hci_driver_util_deinit(); + memset(&s_hci_driver_uart_dma_env, 0, sizeof(hci_driver_uart_dma_env_t)); +} + + +static int +hci_driver_uart_dma_init(hci_driver_forward_fn *cb) +{ + int rc; + + memset(&s_hci_driver_uart_dma_env, 0, sizeof(hci_driver_uart_dma_env_t)); + + s_hci_driver_uart_dma_env.h4_sm = &s_hci_driver_uart_h4_sm; + hci_h4_sm_init(s_hci_driver_uart_dma_env.h4_sm, &s_hci_driver_mem_alloc, hci_driver_uart_dma_h4_frame_cb); + + rc = hci_driver_util_init(); + if (rc) { + goto error; + } + + s_hci_driver_uart_dma_env.process_sem = xSemaphoreCreateBinary(); + if (!s_hci_driver_uart_dma_env.process_sem) { + goto error; + } + + rc = hci_driver_uart_dma_memory_init(); + if (rc) { + goto error; + } + + s_hci_driver_uart_dma_env.forward_cb = cb; + s_hci_driver_uart_dma_env.hci_uart_params = &hci_driver_uart_dma_params; + hci_driver_uart_config(&hci_driver_uart_dma_params); + + ESP_LOGI(TAG, "uart attach uhci!"); + hci_driver_uart_dma_install(); + + STAILQ_INIT(&g_hci_rxinfo_head); + + rc = hci_driver_uart_dma_task_create(); + if (rc) { + goto error; + } + + s_hci_driver_uart_dma_env.hci_tx_state = HCI_TRANS_TX_IDLE; + s_hci_driver_uart_dma_env.rxinfo_mem_exhausted = false; + s_hci_driver_uart_dma_env.is_continue_rx = false; + hci_driver_uart_dma_rx_start(os_memblock_get(s_hci_driver_uart_dma_env.hci_rx_data_pool), + HCI_RX_DATA_BLOCK_SIZE); + return 0; + +error: + hci_driver_uart_dma_deinit(); + return rc; +} + +int +hci_driver_uart_dma_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin) +{ + hci_driver_uart_params_config_t *uart_param = s_hci_driver_uart_dma_env.hci_uart_params; + uart_param->hci_uart_tx_pin = tx_pin; + uart_param->hci_uart_rx_pin = rx_pin; + uart_param->hci_uart_rts_pin = rts_pin; + uart_param->hci_uart_cts_pin = cts_pin; + return hci_driver_uart_config(uart_param); +} + + +hci_driver_ops_t hci_driver_uart_dma_ops = { + .hci_driver_tx = hci_driver_uart_dma_tx, + .hci_driver_init = hci_driver_uart_dma_init, + .hci_driver_deinit = hci_driver_uart_dma_deinit, +}; diff --git a/components/bt/porting/transport/driver/vhci/hci_driver_nimble.c b/components/bt/porting/transport/driver/vhci/hci_driver_nimble.c new file mode 100644 index 000000000000..9a117eb88a5f --- /dev/null +++ b/components/bt/porting/transport/driver/vhci/hci_driver_nimble.c @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_hci_internal.h" +#include "esp_hci_driver.h" + +typedef struct { + hci_driver_forward_fn *forward_cb; +} hci_driver_vhci_env_t; + +static hci_driver_vhci_env_t s_hci_driver_vhci_env; + +static int +hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data) +{ + /* The length is contained in the data. */ + return s_hci_driver_vhci_env.forward_cb(data_type, data, 0, HCI_DRIVER_DIR_C2H); +} + +static int +hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + return s_hci_driver_vhci_env.forward_cb(data_type, data, length, HCI_DRIVER_DIR_H2C); +} + +static int +hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + int rc; + + if (dir == HCI_DRIVER_DIR_C2H) { + rc = hci_driver_vhci_controller_tx(data_type, data); + } else { + rc = hci_driver_vhci_host_tx(data_type, data, length); + } + return rc; +} + +static int +hci_driver_vhci_init(hci_driver_forward_fn *cb) +{ + s_hci_driver_vhci_env.forward_cb = cb; + return 0; +} + +static void +hci_driver_vhci_deinit(void) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); +} + +hci_driver_ops_t hci_driver_vhci_ops = { + .hci_driver_tx = hci_driver_vhci_tx, + .hci_driver_init = hci_driver_vhci_init, + .hci_driver_deinit = hci_driver_vhci_deinit, +}; diff --git a/components/bt/porting/transport/driver/vhci/hci_driver_standard.c b/components/bt/porting/transport/driver/vhci/hci_driver_standard.c new file mode 100644 index 000000000000..2cdab4359e53 --- /dev/null +++ b/components/bt/porting/transport/driver/vhci/hci_driver_standard.c @@ -0,0 +1,149 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "os/os_mbuf.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "esp_hci_driver.h" +#include "esp_bt.h" + +typedef struct { + hci_driver_forward_fn *forward_cb; + const esp_vhci_host_callback_t *host_recv_cb; +} hci_driver_vhci_env_t; + +static hci_driver_vhci_env_t s_hci_driver_vhci_env; + +static int +hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + int rc; + uint16_t buf_len = 0; + uint8_t *buf = NULL; + struct os_mbuf *om; + + if (data_type == HCI_DRIVER_TYPE_ACL) { + om = (struct os_mbuf *)data; + buf_len = length + 1; + buf = malloc(buf_len); + /* TODO: If there is no memory, should handle it in the controller. */ + assert(buf); + buf[0] = HCI_DRIVER_TYPE_ACL; + os_mbuf_copydata(om, 0, length, &buf[1]); + os_mbuf_free_chain(om); + } else if (data_type == HCI_DRIVER_TYPE_EVT) { + buf_len = length + 1; + buf = malloc(buf_len); + /* TODO: If there is no memory, should handle it in the controller. */ + assert(buf != NULL); + buf[0] = HCI_DRIVER_TYPE_EVT; + memcpy(&buf[1], data, length); + r_ble_hci_trans_buf_free(data); + } + + rc = s_hci_driver_vhci_env.forward_cb(data_type, buf, buf_len, HCI_DRIVER_DIR_C2H); + free(buf); + + return rc; +} + +static int +hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + uint8_t *cmd; + struct os_mbuf *om; + + if (data_type == HCI_DRIVER_TYPE_ACL) { + om = os_msys_get_pkthdr(length, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); + assert(om); + assert(os_mbuf_append(om, &data[1], length - 1) == 0); + data = (uint8_t *)om; + } else if (data_type == HCI_DRIVER_TYPE_CMD) { + cmd = r_ble_hci_trans_buf_alloc(ESP_HCI_INTERNAL_BUF_CMD); + assert(cmd); + memcpy(cmd, data + 1, length - 1); + data = cmd; + } + + return s_hci_driver_vhci_env.forward_cb(data_type, data, length, HCI_DRIVER_DIR_H2C); +} + +static int +hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + int rc; + + if (dir == HCI_DRIVER_DIR_C2H) { + rc = hci_driver_vhci_controller_tx(data_type, data, length); + } else { + rc = hci_driver_vhci_host_tx(data_type, data, length); + } + return rc; +} + +static int +hci_driver_vhci_init(hci_driver_forward_fn *cb) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); + s_hci_driver_vhci_env.forward_cb = cb; + return 0; +} + +static void +hci_driver_vhci_deinit(void) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); +} + +hci_driver_ops_t hci_driver_vhci_ops = { + .hci_driver_tx = hci_driver_vhci_tx, + .hci_driver_init = hci_driver_vhci_init, + .hci_driver_deinit = hci_driver_vhci_deinit, +}; + +/* Special APIs declared in the `esp_bt.h'. */ +static int +hci_driver_vhci_host_recv_cb(hci_trans_pkt_ind_t type, uint8_t *data, uint16_t len) +{ + static const esp_vhci_host_callback_t *host_recv_cb; + + host_recv_cb = s_hci_driver_vhci_env.host_recv_cb; + if (host_recv_cb) { + return host_recv_cb->notify_host_recv(data, len); + } + + return -1; +} + +esp_err_t +esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) +{ + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + return ESP_FAIL; + } + + s_hci_driver_vhci_env.host_recv_cb = callback; + if(hci_transport_host_callback_register(hci_driver_vhci_host_recv_cb)) { + s_hci_driver_vhci_env.host_recv_cb = NULL; + return ESP_FAIL; + } + + return ESP_OK; +} + +void +esp_vhci_host_send_packet(uint8_t *data, uint16_t len) +{ + hci_driver_vhci_tx(data[0], data, len, HCI_DRIVER_DIR_H2C); +} + +bool +esp_vhci_host_check_send_available(void) +{ + return true; +} diff --git a/components/bt/porting/transport/driver/vhci/hci_driver_tamplete.c b/components/bt/porting/transport/driver/vhci/hci_driver_tamplete.c new file mode 100644 index 000000000000..63feb934dadd --- /dev/null +++ b/components/bt/porting/transport/driver/vhci/hci_driver_tamplete.c @@ -0,0 +1,133 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "os/os_mbuf.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "esp_hci_driver.h" + +typedef struct { + hci_driver_forward_fn *forward_cb; +} hci_driver_vhci_env_t; + +static hci_driver_vhci_env_t s_hci_driver_vhci_env; + +static int +hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + int rc; + uint16_t len = 0; + uint8_t *buf = NULL; + struct os_mbuf *om; + + if (data_type == HCI_DRIVER_TYPE_ACL) { + /* The ACL data will be packaged as structure of `os_mbuf`. + * 1. Allocate a buffer suitable for the host. Use the following method to copy the data + * from the os_mbuf to the newly allocated memory. + * ```c + * buf = malloc(length); + * os_mbuf_copydata(om, 0, length, buf); + * ``` + * 2. Free the controller's os_mbuf + * ```c + * os_mbuf_free_chain(om); + * ``` + */ + } else if (data_type == HCI_DRIVER_TYPE_EVT) { + /* The event data will be packaged as an array. + * 1. Allocate a buffer suitable for the host. Use the following method to copy the data + * from the controller buffer to the newly allocated memory. + * ```c + * buf = malloc(length); + * memcpy(buf, data, length); + * ``` + * 2. Free the controller's buffer. + * ```c + * r_ble_hci_trans_buf_free(data); + * ``` + */ + } else { + assert(0); + } + + rc = s_hci_driver_vhci_env.forward_cb(data_type, buf, len, HCI_DRIVER_DIR_C2H); + free(buf); + + return rc; +} + +static int +hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + uint8_t *hci_data; + struct os_mbuf *om; + + if (data_type == HCI_DRIVER_TYPE_ACL) { + /* The ACL data needs to be packaged as structure of `os_mbuf`. + * 1. Get an os_mbuf in the following way. + * ```c + * om = os_msys_get_pkthdr(length, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); + * ``` + * 2. Copy the host's data into this os_mbuf using the following method. + * ```c + * assert(os_mbuf_append(om, data, length) == 0); + * hci_data = (uint8_t *)om; + * ``` + * 3. Free the host's buffer if needed. + */ + } else if (data_type == HCI_DRIVER_TYPE_CMD) { + /* The COMMAND data needs to be packaged as an array. + * 1. Get a command buffer from the controller. + * ```c + * hci_data = r_ble_hci_trans_buf_alloc(ESP_HCI_INTERNAL_BUF_CMD); + * ``` + * 2. Copy the host's data into this buffer. + * ```c + * memcpy(hci_data, data, length); + * ``` + * 3. Free the host's buffer if needed. + */ + } else { + assert(0); + } + + return s_hci_driver_vhci_env.forward_cb(data_type, hci_data, length, HCI_DRIVER_DIR_H2C); +} + +static int +hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + int rc; + + if (dir == HCI_DRIVER_DIR_C2H) { + rc = hci_driver_vhci_controller_tx(data_type, data, length); + } else { + rc = hci_driver_vhci_host_tx(data_type, data, length); + } + return rc; +} + +static int +hci_driver_vhci_init(hci_driver_forward_fn *cb) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); + s_hci_driver_vhci_env.forward_cb = cb; + return 0; +} + +static void +hci_driver_vhci_deinit(void) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); +} + +hci_driver_ops_t hci_driver_vhci_ops = { + .hci_driver_tx = hci_driver_vhci_tx, + .hci_driver_init = hci_driver_vhci_init, + .hci_driver_deinit = hci_driver_vhci_deinit, +}; diff --git a/components/bt/porting/transport/include/common/hci_driver_h4.h b/components/bt/porting/transport/include/common/hci_driver_h4.h new file mode 100644 index 000000000000..32d2dd8ba6c6 --- /dev/null +++ b/components/bt/porting/transport/include/common/hci_driver_h4.h @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _HCI_H4_H_ +#define _HCI_H4_H_ + +#include + +#define HCI_H4_NONE 0x00 +#define HCI_H4_CMD 0x01 +#define HCI_H4_ACL 0x02 +#define HCI_H4_EVT 0x04 +#define HCI_H4_ISO 0x05 + +typedef void *(hci_h4_alloc_cmd)(void); +typedef void *(hci_h4_alloc_evt)(int); +typedef struct os_mbuf *(hci_h4_alloc_acl)(void); +typedef struct os_mbuf *(hci_h4_alloc_iso)(void); + +struct hci_h4_allocators { + hci_h4_alloc_cmd *cmd; + hci_h4_alloc_acl *acl; + hci_h4_alloc_evt *evt; + hci_h4_alloc_iso *iso; +}; + +extern const struct hci_h4_allocators hci_h4_allocs_from_ll; +extern const struct hci_h4_allocators hci_h4_allocs_from_hs; + +typedef int (hci_h4_frame_cb)(uint8_t pkt_type, void *data); + +struct hci_h4_sm { + uint8_t state; + uint8_t pkt_type; + uint8_t min_len; + uint16_t len; + uint16_t exp_len; + uint8_t hdr[4]; + union { + uint8_t *buf; + struct os_mbuf *om; + }; + + const struct hci_h4_allocators *allocs; + hci_h4_frame_cb *frame_cb; +}; + +void hci_h4_sm_init(struct hci_h4_sm *h4sm, + const struct hci_h4_allocators *allocs, + hci_h4_frame_cb *frame_cb); + +int hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len); + +#endif /* _HCI_H4_H_ */ diff --git a/components/bt/porting/transport/include/common/hci_driver_mem.h b/components/bt/porting/transport/include/common/hci_driver_mem.h new file mode 100644 index 000000000000..769b18369ebf --- /dev/null +++ b/components/bt/porting/transport/include/common/hci_driver_mem.h @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _H_HCI_DRIVER_MEM_ +#define _H_HCI_DRIVER_MEM_ +#include +#include "os/os_mbuf.h" + +void *hci_driver_mem_cmd_alloc(void); + +void *hci_driver_mem_evt_alloc(int discardable); + +struct os_mbuf *hci_driver_mem_acl_alloc(void); + +struct os_mbuf *hci_driver_mem_acl_len_alloc(uint32_t len); + +struct os_mbuf *hci_driver_mem_iso_alloc(void); + +struct os_mbuf *hci_driver_mem_iso_len_alloc(uint32_t len); + +extern const struct hci_h4_allocators s_hci_driver_mem_alloc; + +#endif // _H_HCI_DRIVER_MEM_ diff --git a/components/bt/porting/transport/include/common/hci_driver_util.h b/components/bt/porting/transport/include/common/hci_driver_util.h new file mode 100644 index 000000000000..05b7abd50235 --- /dev/null +++ b/components/bt/porting/transport/include/common/hci_driver_util.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _H_HCI_DRIVER_UTIL_ +#define _H_HCI_DRIVER_UTIL_ +#include + +int hci_driver_util_init(void); + +void hci_driver_util_deinit(void); + +void hci_driver_util_tx_list_enqueue(hci_driver_data_type_t type, uint8_t *data, uint32_t len); + +uint32_t hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_frame); + +#endif // _H_HCI_DRIVER_UTIL_ diff --git a/components/bt/porting/transport/include/esp_hci_driver.h b/components/bt/porting/transport/include/esp_hci_driver.h new file mode 100644 index 000000000000..09102edff833 --- /dev/null +++ b/components/bt/porting/transport/include/esp_hci_driver.h @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_ESP_HCI_DRIVER_ +#define H_ESP_HCI_DRIVER_ +#include + +/** + * @brief Enumeration of HCI transport direction. + */ +typedef enum { + HCI_DRIVER_DIR_C2H = 0x00, ///< From controller to host. + HCI_DRIVER_DIR_H2C, ///< From host to controller. +} hci_driver_direction_t; + +typedef enum { + HCI_DRIVER_TYPE_CMD = 0x01, ///< HCI Command Indicator. + HCI_DRIVER_TYPE_ACL, ///< HCI ACL Data Indicator. + HCI_DRIVER_TYPE_SYNC, ///< HCI Synchronous Data Indicator. + HCI_DRIVER_TYPE_EVT, ///< HCI Event Indicator. + HCI_DRIVER_TYPE_ISO, ///< HCI Isochronous Data Indicator. + HCI_DRIVER_TYPE_VENDOR, ///< HCI Vendor data Indicator. +} hci_driver_data_type_t; + +typedef int hci_driver_forward_fn(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir); + +/** + * @brief Structure of HCI driver operations. + */ +typedef struct hci_driver_ops { + int (*hci_driver_tx)(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir); + int (*hci_driver_init)(hci_driver_forward_fn *cb); + void (*hci_driver_deinit)(void); +} hci_driver_ops_t; + + +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM +extern hci_driver_ops_t hci_driver_vhci_ops; +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + +#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART +extern hci_driver_ops_t hci_driver_uart_ops; +#if CONFIG_BT_LE_UART_HCI_DMA_MODE +extern hci_driver_ops_t hci_driver_uart_dma_ops; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART + +#endif // H_ESP_HCI_DRIVER_ diff --git a/components/bt/porting/transport/include/esp_hci_internal.h b/components/bt/porting/transport/include/esp_hci_internal.h new file mode 100644 index 000000000000..2b1c33530826 --- /dev/null +++ b/components/bt/porting/transport/include/esp_hci_internal.h @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_ESP_HCI_INTERNAL_ +#define H_ESP_HCI_INTERNAL_ + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include "os/os_mbuf.h" + + +/* The leadingspace in user info header for ACL data */ +#define ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE (4) + +#define ESP_HCI_INTERNAL_BUF_CMD (3) + +/** + * @brief Define the HCI hardware error code for synchronization loss. + * This error code is used to indicate a loss of synchronization between the controller and the host. + */ +#define ESP_HCI_SYNC_LOSS_ERR (0x1) +/** Callback function types; executed when HCI packets are received. */ +typedef int esp_hci_internal_rx_cmd_fn(uint8_t *cmd, void *arg); +typedef int esp_hci_internal_rx_acl_fn(struct os_mbuf *om, void *arg); + +/** + * Configures the HCI transport to operate with a host. The transport will + * execute specified callbacks upon receiving HCI packets from the controller. + * + * @param evt_cb The callback to execute upon receiving an HCI + * event. + * @param evt_arg Optional argument to pass to the event + * callback. + * @param acl_cb The callback to execute upon receiving ACL + * data. + * @param acl_arg Optional argument to pass to the ACL + * callback. + */ +void r_ble_hci_trans_cfg_hs(esp_hci_internal_rx_cmd_fn *evt_cb, void *evt_arg, + esp_hci_internal_rx_acl_fn *acl_cb, void *acl_arg); +/** + * Sends ACL data from host to controller. + * + * @param om The ACL data packet to send. + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int r_ble_hci_trans_hs_acl_tx(struct os_mbuf *om); + +/** + * Sends an HCI command from the host to the controller. + * + * @param cmd The HCI command to send. This buffer must be + * allocated via ble_hci_trans_buf_alloc(). + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int r_ble_hci_trans_hs_cmd_tx(uint8_t *cmd); + +/** + * Allocates a flat buffer of the specified type. + * + * @param type The type of buffer to allocate; one of the + * BLE_HCI_TRANS_BUF_[...] constants. + * + * @return The allocated buffer on success; + * NULL on buffer exhaustion. + */ +uint8_t * r_ble_hci_trans_buf_alloc(int type); + +/** + * Frees the specified flat buffer. The buffer must have been allocated via + * ble_hci_trans_buf_alloc(). + * + * @param buf The buffer to free. + */ +void r_ble_hci_trans_buf_free(uint8_t *buf); + +/** + * Configures a callback to get executed whenever an ACL data packet is freed. + * The function is called immediately before the free occurs. + * + * @param cb The callback to configure. + * @param arg An optional argument to pass to the callback. + * + * @return 0 on success; + * BLE_ERR_UNSUPPORTED if the transport does not + * support this operation. + */ +int r_ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg); + +/** + * @brief Handle an HCI hardware error event. + * This function processes a hardware error code and generates the appropriate HCI hardware error event. + * + * @param hw_err The hardware error code that needs to be processed. The specific meaning of the error code + * depends on the implementation and the hardware. + * + * @return int Returns 0 on success, or a non-zero error code on failure. + * + * @note This function should be called whenever a hardware error is detected in the HCI Layer. + */ +int r_ble_ll_hci_ev_hw_err(uint8_t hw_err); + +//!TODO: Check what this API is used for +int r_ble_hci_trans_reset(void); + +//!TODO: Should we initialize the hci layer in IDF ? +void esp_ble_hci_trans_init(uint8_t); + +#ifdef __cplusplus +} +#endif +#endif /* H_ESP_HCI_INTERNAL_ */ diff --git a/components/bt/porting/transport/include/esp_hci_transport.h b/components/bt/porting/transport/include/esp_hci_transport.h new file mode 100644 index 000000000000..044ebfdfb808 --- /dev/null +++ b/components/bt/porting/transport/include/esp_hci_transport.h @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_ESP_HCI_TRANSPORT_ +#define H_ESP_HCI_TRANSPORT_ + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include "os/os_mbuf.h" +#include "esp_hci_driver.h" + +/** + * @brief Enumeration of HCI packet indicators + */ +typedef enum { + HCI_CMD_IND = 0x01, /*!< HCI Command Indicator */ + HCI_ACL_IND, /*!< HCI ACL Data Indicator */ + HCI_SYNC_IND, /*!< HCI Synchronous Data Indicator */ + HCI_EVT_IND, /*!< HCI Event Indicator */ + HCI_ISO_IND, /*!< HCI Isochronous Data Indicator */ + HCI_VENDOR_IND, /*!< HCI Vendor data Indicator */ +} hci_trans_pkt_ind_t; + +/** + * @brief Enumeration of HCI Transport Mode + */ +typedef enum { + HCI_TRANSPORT_VHCI, /*!< VHCI Transport Mode */ + HCI_TRANSPORT_UART_NO_DMA, /*!< UART_NO_DMA Transport Mode */ + HCI_TRANSPORT_UART_UHCI, /*!< UART_UHCI Transport Mode */ + HCI_TRANSPORT_SDIO, /*!< SDIO Transport Mode */ + HCI_TRANSPORT_USB, /*!< USB Transport Mode */ +} hci_trans_mode_t; + +typedef int hci_transport_host_recv_fn(hci_trans_pkt_ind_t type, uint8_t *data, uint16_t len); + +/** + * @brief Initialize the HCI transport layer. + * It should be called before using any other functions in the transport layer. + * + * @param hci_transport_mode The mode in which the HCI transport should operate. + * + * @return int Returns 0 on success, or a non-zero error code on failure. + */ +int hci_transport_init(uint8_t hci_transport_mode); + +/** + * @brief Deinitialize the HCI transport layer for releasing any allocated resources. + */ +void hci_transport_deinit(void); + +/** + * @brief Set the host's HCI callback which will be invoked when receiving ACL/Events from controller. + * @param callback hci_transport_host_recv_fn type variable + * @return int 0 on success, non-zero error code on failure. + */ +int hci_transport_host_callback_register(hci_transport_host_recv_fn *callback); + +/** + * @brief Called to send HCI commands form host to controller. + * @param data Point to the commands data + * @param length Length of data + * @return int 0 on success, non-zero error code on failure. + */ +int hci_transport_host_cmd_tx(uint8_t *data, uint32_t length); + +/** + * @brief Called to send HCI ACL form host to controller. + * @param data Point to the ACL data + * @param length Length of data + * @return int 0 on success, non-zero error code on failure. + */ +int hci_transport_host_acl_tx(uint8_t *data, uint32_t length); + +#ifdef __cplusplus +} +#endif +#endif /* H_ESP_HCI_TRANSPORT_ */ diff --git a/components/bt/porting/transport/include/hci_uart.h b/components/bt/porting/transport/include/hci_uart.h deleted file mode 100644 index 02bc91b4033c..000000000000 --- a/components/bt/porting/transport/include/hci_uart.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "driver/uart.h" - -/** - * Function prototype for UART driver to ask for more data to send. - * Returns -1 if no more data is available for TX. - * Driver must call this with interrupts disabled. - */ -typedef int (*hci_uart_tx_char)(void *arg); - -/** - * Function prototype for UART driver to report that transmission is - * complete. This should be called when transmission of last byte is - * finished. - * Driver must call this with interrupts disabled. - */ -typedef void (*hci_uart_tx_done)(void *arg); - -/** - * Function prototype for UART driver to report incoming byte of data. - * Returns -1 if data was dropped. - * Driver must call this with interrupts disabled. - */ -typedef int (*hci_uart_rx_char)(void *arg, uint8_t byte); - - -/** - * Initializes given uart. Mapping of logical UART number to physical - * UART/GPIO pins is in BSP. - */ -int hci_uart_init_cbs(int uart, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); - - -/** - * Applies given configuration to UART. - * - * @param port_num The UART number to configure - * @param speed The baudrate in bps to configure - * @param databits The number of databits to send per byte - * @param stopbits The number of stop bits to send - * @param parity The UART parity - * @param flow_ctl Flow control settings on the UART - * - * @return 0 on success, non-zero error code on failure - */ -int hci_uart_config(int port_num, int32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); - -/** - * Close UART port. Can call hal_uart_config() with different settings after - * calling this. - * - * @param port_num The UART number to close - */ -int hci_uart_close(int port_num); - -/** - * More data queued for transmission. UART driver will start asking for that - * data. - * - * @param port_num The UART number to start TX on - */ -void hci_uart_start_tx(int port_num); - -/** - * Upper layers have consumed some data, and are now ready to receive more. - * This is meaningful after uart_rx_char callback has returned -1 telling - * that no more data can be accepted. - * - * @param port_num The UART number to begin RX on - */ -void hci_uart_start_rx(int port_num); - -/** - * @brief reconfig hci uart pin - * - * @param tx_pin The Tx pin - * @param rx_pin The Rx pin - * @param cts_pin The CTS pin - * @param rts_pin The RTS pin - * @return int 0 on success, non-zero error code on failure - */ -int hci_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin); - -#ifdef __cplusplus -} -#endif diff --git a/components/bt/porting/transport/src/hci_transport.c b/components/bt/porting/transport/src/hci_transport.c new file mode 100644 index 000000000000..29c2e0013119 --- /dev/null +++ b/components/bt/porting/transport/src/hci_transport.c @@ -0,0 +1,177 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_log.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "esp_bt.h" + +typedef struct hci_transport_env +{ + hci_transport_host_recv_fn *host_recv_cb; + hci_driver_ops_t *driver_ops; +} hci_transport_env_t; + +static hci_transport_env_t s_hci_transport_env; + +/* Functions for packets Rx. */ +static int +hci_transport_controller_packet_rx(hci_driver_data_type_t data_type, uint8_t *data) +{ + if (data_type == HCI_DRIVER_TYPE_CMD) { + r_ble_hci_trans_hs_cmd_tx(data); + } + + if (data_type == HCI_DRIVER_TYPE_ACL) { + r_ble_hci_trans_hs_acl_tx((struct os_mbuf *) data); + } + return 0; +} + +static int +hci_transport_host_packet_rx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + if (!s_hci_transport_env.host_recv_cb) { + return -1; + } + return s_hci_transport_env.host_recv_cb((hci_trans_pkt_ind_t)data_type, data, length); +} + +static int +hci_transport_packet_rx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + int rc; + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + return -1; + } + + if (dir == HCI_DRIVER_DIR_C2H) { + rc = hci_transport_host_packet_rx(data_type, data, length); + } else { + rc = hci_transport_controller_packet_rx(data_type, data); + } + + return rc; +} + +/* Functions for controller Tx. */ +static int +hci_transport_controller_tx_dummy(void *data, void *arg) +{ + return -1; +} + +static int +hci_transport_controller_evt_tx(uint8_t *hci_ev, void *arg) +{ + uint32_t len; + + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + r_ble_hci_trans_buf_free(hci_ev); + return -1; + } + + len = hci_ev[1] + 2; + return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_EVT, hci_ev, len, + HCI_DRIVER_DIR_C2H); +} + +static int +hci_transport_controller_acl_tx(struct os_mbuf *om, void *arg) +{ + uint16_t len; + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + os_mbuf_free_chain(om); + return -1; + } + + len = OS_MBUF_PKTHDR(om)->omp_len; + return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_ACL, (uint8_t *)om, len, + HCI_DRIVER_DIR_C2H); +} + +/* Functions for host Tx. */ +int +hci_transport_host_cmd_tx(uint8_t *data, uint32_t length) +{ + return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_CMD, data, length, + HCI_DRIVER_DIR_H2C); +} + +int +hci_transport_host_acl_tx(uint8_t *data, uint32_t length) +{ + return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_ACL, data, length, + HCI_DRIVER_DIR_H2C); +} + +int +hci_transport_host_callback_register(hci_transport_host_recv_fn *callback) +{ + s_hci_transport_env.host_recv_cb = callback; + return 0; +} + +int +hci_transport_init(uint8_t hci_transport_mode) +{ + int rc; + hci_driver_ops_t *ops; + + memset(&s_hci_transport_env, 0, sizeof(hci_transport_env_t)); + + switch(hci_transport_mode) { +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + case HCI_TRANSPORT_VHCI: + ops = &hci_driver_vhci_ops; + break; +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM +#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART +#if CONFIG_BT_LE_UART_HCI_DMA_MODE + case HCI_TRANSPORT_UART_UHCI: + ops = &hci_driver_uart_dma_ops; + break; +#else + case HCI_TRANSPORT_UART_NO_DMA: + ops = &hci_driver_uart_ops; + break; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART + default: + assert(0); + } + + rc = ops->hci_driver_init(hci_transport_packet_rx); + if (rc) { + goto error; + } + + s_hci_transport_env.driver_ops = ops; + r_ble_hci_trans_cfg_hs(hci_transport_controller_evt_tx, NULL, hci_transport_controller_acl_tx, NULL); + + return 0; + +error: + hci_transport_deinit(); + return rc; +} + +void +hci_transport_deinit(void) +{ + hci_driver_ops_t *ops; + + r_ble_hci_trans_cfg_hs((esp_hci_internal_rx_cmd_fn *)hci_transport_controller_tx_dummy, NULL, + (esp_hci_internal_rx_acl_fn *)hci_transport_controller_tx_dummy, NULL); + + ops = s_hci_transport_env.driver_ops; + if (ops) { + ops->hci_driver_deinit(); + } + memset(&s_hci_transport_env, 0, sizeof(hci_transport_env_t)); +} diff --git a/components/bt/porting/transport/uart/hci_uart.c b/components/bt/porting/transport/uart/hci_uart.c deleted file mode 100644 index c202e0a50412..000000000000 --- a/components/bt/porting/transport/uart/hci_uart.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "driver/uart.h" -#include "hci_uart.h" -#include "esp_log.h" -#include "esp_attr.h" - -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static const char *TAG = "hci_uart"; - -#define BUF_SIZE (1024) -#define RD_BUF_SIZE (BUF_SIZE) - -#define HCI_UART_TX_PIN CONFIG_BT_LE_HCI_UART_TX_PIN -#define HCI_UART_RX_PIN CONFIG_BT_LE_HCI_UART_RX_PIN - - -#ifdef CONFIG_BT_LE_HCI_UART_FLOWCTRL -#define HCI_UART_FLOWCTRL UART_HW_FLOWCTRL_CTS_RTS -#define HCI_UART_RTS_PIN CONFIG_BT_LE_HCI_UART_RTS_PIN -#define HCI_UART_CTS_PIN CONFIG_BT_LE_HCI_UART_CTS_PIN -#else -#define HCI_UART_FLOWCTRL UART_HW_FLOWCTRL_DISABLE -#define HCI_UART_RTS_PIN (-1) -#define HCI_UART_CTS_PIN (-1) -#endif - - -typedef struct { - bool uart_opened; - uart_port_t port; - uart_config_t cfg; - QueueHandle_t evt_queue; - TaskHandle_t rx_task_handler; - hci_uart_tx_char tx_char; - hci_uart_tx_done tx_done; - hci_uart_rx_char rx_char; - void *u_func_arg; - -} hci_uart_t; - -static hci_uart_t hci_uart; - -static void IRAM_ATTR hci_uart_rx_task(void *pvParameters) -{ - uart_event_t event; - uint8_t *dtmp = (uint8_t *) malloc(RD_BUF_SIZE); - while (hci_uart.uart_opened) { - //Waiting for UART event. - if (xQueueReceive(hci_uart.evt_queue, (void * )&event, (TickType_t)portMAX_DELAY)) { - bzero(dtmp, RD_BUF_SIZE); - ESP_LOGD(TAG, "uart[%d] event:", hci_uart.port); - switch (event.type) { - //Event of UART receving data - /*We'd better handler data event fast, there would be much more data events than - other types of events. If we take too much time on data event, the queue might - be full.*/ - case UART_DATA: - // ESP_LOGI(TAG, "[UART DATA]: %d", event.size); - uart_read_bytes(hci_uart.port, dtmp, event.size, portMAX_DELAY); - for (int i = 0 ; i < event.size; i++) { - hci_uart.rx_char(hci_uart.u_func_arg, dtmp[i]); - } - break; - //Event of HW FIFO overflow detected - case UART_FIFO_OVF: - ESP_LOGI(TAG, "hw fifo overflow"); - // If fifo overflow happened, you should consider adding flow control for your application. - // The ISR has already reset the rx FIFO, - uart_flush_input(hci_uart.port); - xQueueReset(hci_uart.evt_queue); - break; - //Event of UART ring buffer full - case UART_BUFFER_FULL: - ESP_LOGI(TAG, "ring buffer full"); - // If buffer full happened, you should consider encreasing your buffer size - uart_flush_input(hci_uart.port); - xQueueReset(hci_uart.evt_queue); - break; - //Event of UART RX break detected - case UART_BREAK: - ESP_LOGI(TAG, "uart rx break"); - break; - //Event of UART parity check error - case UART_PARITY_ERR: - ESP_LOGI(TAG, "uart parity error"); - break; - //Event of UART frame error - case UART_FRAME_ERR: - ESP_LOGI(TAG, "uart frame error"); - break; - //Others - default: - ESP_LOGI(TAG, "uart event type: %d", event.type); - break; - } - } - } - free(dtmp); - dtmp = NULL; - hci_uart.rx_task_handler = NULL; - vTaskDelete(NULL); -} - -int hci_uart_config(int port_num, int32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl) -{ - uart_config_t uart_cfg = { - .baud_rate = baud_rate, - .data_bits = data_bits, - .parity = parity, - .stop_bits = stop_bits, - .flow_ctrl = HCI_UART_FLOWCTRL, - .source_clk = UART_SCLK_DEFAULT, - .rx_flow_ctrl_thresh = UART_HW_FIFO_LEN(port_num) - 1, - }; - hci_uart.port = port_num; - hci_uart.cfg = uart_cfg; - - int intr_alloc_flags = 0; - intr_alloc_flags = ESP_INTR_FLAG_IRAM; - - printf("set uart pin tx:%d, rx:%d.\n", HCI_UART_TX_PIN, HCI_UART_RX_PIN); - printf("set rts:%d, cts:%d.\n", HCI_UART_RTS_PIN, HCI_UART_CTS_PIN); - printf("set baud_rate:%d.\n", baud_rate); - - ESP_ERROR_CHECK(uart_driver_delete(port_num)); - ESP_ERROR_CHECK(uart_driver_install(port_num, BUF_SIZE * 2, BUF_SIZE * 2, 20, &hci_uart.evt_queue, intr_alloc_flags)); - ESP_ERROR_CHECK(uart_param_config(port_num, &hci_uart.cfg)); - ESP_ERROR_CHECK(uart_set_pin(port_num, HCI_UART_TX_PIN, HCI_UART_RX_PIN, HCI_UART_RTS_PIN, HCI_UART_CTS_PIN)); - - hci_uart.uart_opened = true; - - //Create a task to handler UART event from ISR - xTaskCreate(hci_uart_rx_task, "hci_uart_rx_task", 2048, NULL, 12, &hci_uart.rx_task_handler); - return 0; -} - -void IRAM_ATTR hci_uart_start_tx(int port_num) -{ - int data; - uint8_t u8_data = 0; - while (1) { - data = hci_uart.tx_char(hci_uart.u_func_arg); - if (data >= 0) { - u8_data = data; - uart_write_bytes(port_num, (char *)&u8_data, 1); - } else { - break; - } - } - if (hci_uart.tx_done) { - hci_uart.tx_done(hci_uart.u_func_arg); - } -} - -int hci_uart_init_cbs(int port_num, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - hci_uart.tx_char = tx_func; - hci_uart.rx_char = rx_func; - hci_uart.tx_done = tx_done; - hci_uart.u_func_arg = arg; - return 0; -} - -int hci_uart_close(int port_num) -{ - uart_event_t uart_event; - uart_event.type = UART_BREAK; - hci_uart.uart_opened = false; - // Stop uart rx task - if (hci_uart.rx_task_handler != NULL) { - xQueueSend(hci_uart.evt_queue, (void *)&uart_event, 1000); - ESP_LOGW(TAG, "Waiting for uart task finish..."); - } - while (hci_uart.rx_task_handler != NULL); - - uart_driver_delete(port_num); - ESP_LOGI(TAG, "hci uart close success."); - return 0; -} - -int hci_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin) -{ - int port_num = hci_uart.port; - int32_t baud_rate = hci_uart.cfg.baud_rate; - uint8_t data_bits = hci_uart.cfg.data_bits; - uint8_t stop_bits = hci_uart.cfg.stop_bits; - uart_parity_t parity = hci_uart.cfg.parity; - uart_hw_flowcontrol_t flow_ctl = hci_uart.cfg.flow_ctrl; - hci_uart_close(port_num); - hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - ESP_ERROR_CHECK(uart_set_pin(port_num, tx_pin, rx_pin, rts_pin, cts_pin)); - return 0; -} -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART diff --git a/components/console/argtable3/sbom.yml b/components/console/argtable3/sbom.yml new file mode 100644 index 000000000000..1e40eb87dcab --- /dev/null +++ b/components/console/argtable3/sbom.yml @@ -0,0 +1,5 @@ +name: 'argtable3' +version: '3.2.2' +supplier: 'Organization: Espressif Systems (Shanghai) CO LTD' +originator: 'Organization: Argtable.org and individual contributors' +description: An open source ANSI C library that parses GNU-style command-line options. diff --git a/components/console/linenoise/linenoise.c b/components/console/linenoise/linenoise.c index b4e8409af90a..e585ab7e89c6 100644 --- a/components/console/linenoise/linenoise.c +++ b/components/console/linenoise/linenoise.c @@ -1091,9 +1091,9 @@ int linenoiseProbe(void) { if (cb < 0) { continue; } - if (read_bytes == 0 && c != '\x1b') { - /* invalid response */ - break; + if (read_bytes == 0 && c != ESC) { + /* invalid response, try again until the timeout triggers */ + continue; } read_bytes += cb; } diff --git a/components/cxx/CMakeLists.txt b/components/cxx/CMakeLists.txt index 228414599cd2..a14aa9b148df 100644 --- a/components/cxx/CMakeLists.txt +++ b/components/cxx/CMakeLists.txt @@ -39,7 +39,9 @@ if(NOT CONFIG_CXX_EXCEPTIONS) _Unwind_Resume_or_Rethrow _Unwind_Backtrace __cxa_call_unexpected - __gxx_personality_v0) + __gxx_personality_v0 + __cxa_throw + __cxa_allocate_exception) foreach(wrap ${WRAP_FUNCTIONS}) target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}") diff --git a/components/cxx/cxx_exception_stubs.cpp b/components/cxx/cxx_exception_stubs.cpp index 827d40dd814b..7e794755c072 100644 --- a/components/cxx/cxx_exception_stubs.cpp +++ b/components/cxx/cxx_exception_stubs.cpp @@ -178,4 +178,16 @@ extern "C" _Unwind_Reason_Code __wrap___gxx_personality_v0(int version, return abort_return<_Unwind_Reason_Code>(); } +// Reduces binary size since the linker will drop some code due to --gc-sections. +extern "C" void __wrap___cxa_allocate_exception(void) +{ + abort(); +} + +// Reduces binary size since the linker will drop some code due to --gc-sections. +extern "C" void __wrap___cxa_throw(void) +{ + abort(); +} + #endif // CONFIG_COMPILER_CXX_EXCEPTIONS diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 9abd8e64c964..e350e1a72f74 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -73,9 +73,11 @@ endif() # Touch Sensor related source files if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED) - list(APPEND srcs "touch_sensor/touch_sensor_common.c" - "touch_sensor/${target}/touch_sensor.c") - list(APPEND includes "touch_sensor/${target}/include") + if(CONFIG_SOC_TOUCH_SENSOR_VERSION LESS 3) + list(APPEND srcs "touch_sensor/touch_sensor_common.c" + "touch_sensor/${target}/touch_sensor.c") + list(APPEND includes "touch_sensor/${target}/include") + endif() endif() # TWAI related source files diff --git a/components/driver/Kconfig b/components/driver/Kconfig index ceda88e3ba87..68634c78f924 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -63,6 +63,17 @@ menu "Driver Configurations" endmenu # Legacy ADC Calibration Configuration endmenu # Legacy ADC Driver Configuration + menu "Legacy DAC Driver Configurations" + depends on SOC_DAC_SUPPORTED + config DAC_SUPPRESS_DEPRECATE_WARN + bool "Suppress legacy driver deprecated warning" + default n + help + Whether to suppress the deprecation warnings when using legacy dac driver (driver/dac.h). + If you want to continue using the legacy driver, and don't want to see related deprecation warnings, + you can enable this option. + endmenu # Legacy DAC Driver Configurations + menu "Legacy MCPWM Driver Configurations" depends on SOC_MCPWM_SUPPORTED config MCPWM_SUPPRESS_DEPRECATE_WARN @@ -97,4 +108,48 @@ menu "Driver Configurations" you can enable this option. endmenu # Legacy RMT Driver Configurations + menu "Legacy I2S Driver Configurations" + depends on SOC_I2S_SUPPORTED + config I2S_SUPPRESS_DEPRECATE_WARN + bool "Suppress legacy driver deprecated warning" + default n + help + Whether to suppress the deprecation warnings when using legacy i2s driver (driver/i2s.h). + If you want to continue using the legacy driver, and don't want to see related deprecation warnings, + you can enable this option. + endmenu # Legacy I2S Driver Configurationss + + menu "Legacy PCNT Driver Configurations" + depends on SOC_PCNT_SUPPORTED + config PCNT_SUPPRESS_DEPRECATE_WARN + bool "Suppress legacy driver deprecated warning" + default n + help + whether to suppress the deprecation warnings when using legacy PCNT driver (driver/pcnt.h). + If you want to continue using the legacy driver, and don't want to see related deprecation warnings, + you can enable this option. + endmenu # Legacy PCNT Driver Configurationss + + menu "Legacy SDM Driver Configurations" + depends on SOC_SDM_SUPPORTED + config SDM_SUPPRESS_DEPRECATE_WARN + bool "Suppress legacy driver deprecated warning" + default n + help + whether to suppress the deprecation warnings when using legacy SDM driver (driver/sigmadelta.h). + If you want to continue using the legacy driver, and don't want to see related deprecation warnings, + you can enable this option. + endmenu # Legacy SDM Driver Configurationss + + menu "Legacy Temperature Sensor Driver Configurations" + depends on SOC_TEMP_SENSOR_SUPPORTED + config TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN + bool "Suppress legacy driver deprecated warning" + default n + help + whether to suppress the deprecation warnings when using legacy temperature sensor driver + (driver/temp_sensor.h). If you want to continue using the legacy driver, + and don't want to see related deprecation warnings, you can enable this option. + endmenu # Legacy Temperature Sensor Driver Configurationss + endmenu # Driver configurations diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index dd3e9f3a7279..04eb8c9024f7 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/components/driver/deprecated/adc_dma_legacy.c @@ -57,7 +57,7 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi #define INTERNAL_BUF_NUM 5 -#if SOC_AHB_GDMA_VERSION == 1 +#if SOC_AHB_GDMA_SUPPORTED #define ADC_GDMA_HOST 0 #define ADC_DMA_INTR_MASK GDMA_LL_EVENT_RX_SUC_EOF #define ADC_DMA_INTR_MASK GDMA_LL_EVENT_RX_SUC_EOF @@ -434,7 +434,10 @@ esp_err_t adc_digi_start(void) return ESP_ERR_INVALID_STATE; } //reset ADC digital part to reset ADC sampling EOF counter - periph_module_reset(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_reset_register(); + } + sar_periph_ctrl_adc_continuous_power_acquire(); //reset flags s_adc_digi_ctx->ringbuf_overflow_flag = 0; diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index 87e66e56a8d1..76277ac5e5f5 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -70,7 +70,7 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi #define FSM_ENTER() RTC_ENTER_CRITICAL() #define FSM_EXIT() RTC_EXIT_CRITICAL() -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4 //prevent ADC1 being used by I2S dma and other tasks at the same time. static _lock_t adc1_dma_lock; #define SARADC1_ACQUIRE() _lock_acquire( &adc1_dma_lock ) @@ -172,7 +172,7 @@ static void adc_rtc_chan_init(adc_unit_t adc_unit) esp_err_t adc_common_gpio_init(adc_unit_t adc_unit, adc_channel_t channel) { ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(adc_unit), ESP_ERR_INVALID_ARG, ADC_TAG, "invalid channel"); - +#if ADC_LL_RTC_GPIO_SUPPORTED gpio_num_t gpio_num = 0; //If called with `ADC_UNIT_BOTH (ADC_UNIT_1 | ADC_UNIT_2)`, both if blocks will be run if (adc_unit == ADC_UNIT_1) { @@ -188,7 +188,7 @@ esp_err_t adc_common_gpio_init(adc_unit_t adc_unit, adc_channel_t channel) ESP_RETURN_ON_ERROR(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED), ADC_TAG, "rtc_gpio_set_direction fail"); ESP_RETURN_ON_ERROR(rtc_gpio_pulldown_dis(gpio_num), ADC_TAG, "rtc_gpio_pulldown_dis fail"); ESP_RETURN_ON_ERROR(rtc_gpio_pullup_dis(gpio_num), ADC_TAG, "rtc_gpio_pullup_dis fail"); - +#endif return ESP_OK; } @@ -571,7 +571,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * #endif adc_oneshot_ll_set_output_bits(ADC_UNIT_2, bitwidth); -#if CONFIG_IDF_TARGET_ESP32 +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32P4 adc_ll_set_controller(ADC_UNIT_2, ADC_LL_CTRL_RTC);// set controller #else adc_ll_set_controller(ADC_UNIT_2, ADC_LL_CTRL_ARB);// set controller diff --git a/components/driver/deprecated/driver/adc_types_legacy.h b/components/driver/deprecated/driver/adc_types_legacy.h index 8ea32f9d47c4..9186b9c24577 100644 --- a/components/driver/deprecated/driver/adc_types_legacy.h +++ b/components/driver/deprecated/driver/adc_types_legacy.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -81,6 +81,18 @@ typedef enum { ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO6 */ ADC1_CHANNEL_MAX, } adc1_channel_t; +#elif CONFIG_IDF_TARGET_ESP32P4 +typedef enum { + ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO16 */ + ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO17 */ + ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO18 */ + ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO19 */ + ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO20 */ + ADC1_CHANNEL_5, /*!< ADC1 channel 5 is GPIO21 */ + ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO22 */ + ADC1_CHANNEL_7, /*!< ADC1 channel 7 is GPIO23 */ + ADC1_CHANNEL_MAX, +} adc1_channel_t; #endif // CONFIG_IDF_TARGET_* #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 @@ -103,6 +115,17 @@ typedef enum { ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO5 */ ADC2_CHANNEL_MAX, } adc2_channel_t; + +#elif CONFIG_IDF_TARGET_ESP32P4 +typedef enum { + ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO49 */ + ADC2_CHANNEL_1, /*!< ADC2 channel 1 is GPIO50 */ + ADC2_CHANNEL_2, /*!< ADC2 channel 2 is GPIO51 */ + ADC2_CHANNEL_3, /*!< ADC2 channel 3 is GPIO52 */ + ADC2_CHANNEL_4, /*!< ADC2 channel 4 is GPIO53 */ + ADC2_CHANNEL_5, /*!< ADC2 channel 5 is GPIO54 */ + ADC2_CHANNEL_MAX, +} adc2_channel_t; #endif #if SOC_ADC_DMA_SUPPORTED diff --git a/components/driver/deprecated/driver/rmt.h b/components/driver/deprecated/driver/rmt.h index c99bde31bedd..e162b147aa87 100644 --- a/components/driver/deprecated/driver/rmt.h +++ b/components/driver/deprecated/driver/rmt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -152,10 +152,10 @@ esp_err_t rmt_set_tx_carrier(rmt_channel_t channel, bool carrier_en, uint16_t hi esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en); /** -* @brief Get RMT memory low power mode. +* @brief Check if the RMT memory is force powered down * -* @param channel RMT channel -* @param pd_en Pointer to accept RMT memory low power mode. +* @param channel RMT channel (actually this function is configured for all channels) +* @param pd_en Pointer to accept the result * * @return * - ESP_ERR_INVALID_ARG Parameter error diff --git a/components/driver/deprecated/i2s_legacy.c b/components/driver/deprecated/i2s_legacy.c index d36b2e2945c7..352e1f03f9ed 100644 --- a/components/driver/deprecated/i2s_legacy.c +++ b/components/driver/deprecated/i2s_legacy.c @@ -61,7 +61,6 @@ #include "esp_pm.h" #include "esp_efuse.h" #include "esp_rom_gpio.h" -#include "esp_dma_utils.h" #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #include "esp_cache.h" @@ -348,14 +347,22 @@ static esp_err_t i2s_dma_intr_init(i2s_port_t i2s_num, int intr_flag) gdma_trigger_t trig = {.periph = GDMA_TRIG_PERIPH_I2S}; switch (i2s_num) { +#if SOC_I2S_NUM > 2 + case I2S_NUM_2: + trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S2; + break; +#endif #if SOC_I2S_NUM > 1 case I2S_NUM_1: trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S1; break; #endif - default: + case I2S_NUM_0: trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S0; break; + default: + ESP_LOGE(TAG, "Unsupported I2S port number"); + return ESP_ERR_NOT_SUPPORTED; } /* Set GDMA config */ @@ -572,22 +579,17 @@ static esp_err_t i2s_alloc_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj) ESP_GOTO_ON_FALSE(dma_obj, ESP_ERR_INVALID_ARG, err, TAG, "I2S DMA object can't be NULL"); uint32_t buf_cnt = p_i2s[i2s_num]->dma_desc_num; - size_t desc_size = 0; for (int cnt = 0; cnt < buf_cnt; cnt++) { /* Allocate DMA buffer */ - esp_dma_mem_info_t dma_mem_info = { - .extra_heap_caps = MALLOC_CAP_INTERNAL, - .dma_alignment_bytes = 4, - }; - //TODO: IDF-9636 - esp_dma_capable_calloc(1, sizeof(char) * dma_obj->buf_size, &dma_mem_info, (void **)&dma_obj->buf[cnt], NULL); + dma_obj->buf[cnt] = heap_caps_aligned_calloc(4, 1, sizeof(char) * dma_obj->buf_size, + MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ESP_GOTO_ON_FALSE(dma_obj->buf[cnt], ESP_ERR_NO_MEM, err, TAG, "Error malloc dma buffer"); #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE esp_cache_msync(dma_obj->buf[cnt], dma_obj->buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); #endif /* Allocate DMA descriptor */ - esp_dma_capable_calloc(1, sizeof(lldesc_t), &dma_mem_info, (void **)&dma_obj->desc[cnt], &desc_size); + dma_obj->desc[cnt] = heap_caps_aligned_calloc(4, 1, sizeof(lldesc_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ESP_GOTO_ON_FALSE(dma_obj->desc[cnt], ESP_ERR_NO_MEM, err, TAG, "Error malloc dma description entry"); } /* DMA descriptor must be initialize after all descriptor has been created, otherwise they can't be linked together as a chain */ @@ -603,7 +605,7 @@ static esp_err_t i2s_alloc_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj) /* Link to the next descriptor */ dma_obj->desc[cnt]->empty = (uint32_t)((cnt < (buf_cnt - 1)) ? (dma_obj->desc[cnt + 1]) : dma_obj->desc[0]); #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - esp_cache_msync(dma_obj->desc[cnt], desc_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + esp_cache_msync(dma_obj->desc[cnt], sizeof(lldesc_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); #endif } if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { diff --git a/components/driver/deprecated/rmt_legacy.c b/components/driver/deprecated/rmt_legacy.c index 16d120725b4f..4269c8fa56d2 100644 --- a/components/driver/deprecated/rmt_legacy.c +++ b/components/driver/deprecated/rmt_legacy.c @@ -142,6 +142,7 @@ static void rmt_module_enable(void) rmt_ll_enable_bus_clock(0, true); rmt_ll_reset_register(0); } + rmt_ll_mem_power_by_pmu(rmt_contex.hal.regs); rmt_contex.rmt_module_enabled = true; } RMT_EXIT_CRITICAL(); @@ -152,6 +153,7 @@ static void rmt_module_disable(void) { RMT_ENTER_CRITICAL(); if (rmt_contex.rmt_module_enabled == true) { + rmt_ll_mem_force_power_off(rmt_contex.hal.regs); RMT_RCC_ATOMIC() { rmt_ll_enable_bus_clock(0, false); } @@ -251,7 +253,11 @@ esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en) { ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); RMT_ENTER_CRITICAL(); - rmt_ll_power_down_mem(rmt_contex.hal.regs, pd_en); + if (pd_en) { + rmt_ll_mem_force_power_off(rmt_contex.hal.regs); + } else { + rmt_ll_mem_power_by_pmu(rmt_contex.hal.regs); + } RMT_EXIT_CRITICAL(); return ESP_OK; } @@ -260,7 +266,7 @@ esp_err_t rmt_get_mem_pd(rmt_channel_t channel, bool *pd_en) { ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); RMT_ENTER_CRITICAL(); - *pd_en = rmt_ll_is_mem_powered_down(rmt_contex.hal.regs); + *pd_en = rmt_ll_is_mem_force_powered_down(rmt_contex.hal.regs); RMT_EXIT_CRITICAL(); return ESP_OK; } diff --git a/components/driver/i2c/i2c.c b/components/driver/i2c/i2c.c index 591177dda891..eb315a4ec49d 100644 --- a/components/driver/i2c/i2c.c +++ b/components/driver/i2c/i2c.c @@ -280,7 +280,7 @@ static void i2c_hw_enable(i2c_port_t i2c_num) static esp_err_t i2c_sleep_retention_init(void *arg) { i2c_port_t i2c_num = *(i2c_port_t *)arg; - esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[i2c_num].link_list, i2c_regs_retention[i2c_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(i2c_num)); + esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[i2c_num].link_list, i2c_regs_retention[i2c_num].link_num, REGDMA_LINK_PRI_I2C, I2C_SLEEP_RETENTION_MODULE(i2c_num)); ESP_RETURN_ON_ERROR(ret, I2C_TAG, "failed to allocate mem for sleep retention"); return ret; } diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 4e30f5c6eca9..ec02d7d63d5b 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -17,6 +17,10 @@ components/driver/test_apps/i2s_test_apps/legacy_i2s_driver: components/driver/test_apps/legacy_adc_driver: disable: - if: SOC_ADC_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: lack of runners, TODO IDF-9573 depends_components: - efuse - esp_driver_i2s @@ -50,6 +54,9 @@ components/driver/test_apps/legacy_mcpwm_driver: components/driver/test_apps/legacy_pcnt_driver: disable: - if: SOC_PCNT_SUPPORTED != 1 + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: build failed. track in IDFCI-2204 depends_filepatterns: - components/driver/deprecated/**/*pcnt* @@ -74,10 +81,6 @@ components/driver/test_apps/legacy_sigma_delta_driver: components/driver/test_apps/legacy_timer_driver: disable: - if: SOC_GPTIMER_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8962 depends_filepatterns: - components/driver/deprecated/**/*timer* diff --git a/components/driver/test_apps/legacy_adc_driver/README.md b/components/driver/test_apps/legacy_adc_driver/README.md index a8b7833fa30d..bf47d80ec649 100644 --- a/components/driver/test_apps/legacy_adc_driver/README.md +++ b/components/driver/test_apps/legacy_adc_driver/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c index 196c56764a21..e09a741b1858 100644 --- a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c +++ b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -67,6 +67,13 @@ #define ADC_TEST_HIGH_VAL 3390 #define ADC_TEST_HIGH_THRESH 200 +#elif CONFIG_IDF_TARGET_ESP32P4 +#define ADC_TEST_LOW_VAL 3100 +#define ADC_TEST_LOW_THRESH 200 + +#define ADC_TEST_HIGH_VAL 4095 +#define ADC_TEST_HIGH_THRESH 200 + #endif //ADC Channels diff --git a/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py b/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py index 6bc3b838d66d..dd7ce7097fc2 100644 --- a/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py +++ b/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut diff --git a/components/driver/test_apps/legacy_timer_driver/README.md b/components/driver/test_apps/legacy_timer_driver/README.md index bf47d80ec649..3a502b1f86f4 100644 --- a/components/driver/test_apps/legacy_timer_driver/README.md +++ b/components/driver/test_apps/legacy_timer_driver/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_timer_driver/main/test_legacy_timer.c b/components/driver/test_apps/legacy_timer_driver/main/test_legacy_timer.c index 60c448ac41e7..77c1eb508066 100644 --- a/components/driver/test_apps/legacy_timer_driver/main/test_legacy_timer.c +++ b/components/driver/test_apps/legacy_timer_driver/main/test_legacy_timer.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -62,7 +62,6 @@ static bool test_timer_group_isr_cb(void *arg) const timer_group_t timer_group = info->timer_group; const timer_idx_t timer_idx = info->timer_idx; uint64_t timer_val; - double time; uint64_t alarm_value; timer_event_t evt; alarm_flag = true; @@ -70,13 +69,11 @@ static bool test_timer_group_isr_cb(void *arg) timer_group_clr_intr_status_in_isr(timer_group, timer_idx); esp_rom_printf("This is TG%d timer[%d] reload-timer alarm!\n", timer_group, timer_idx); timer_get_counter_value(timer_group, timer_idx, &timer_val); - timer_get_counter_time_sec(timer_group, timer_idx, &time); evt.type = TIMER_AUTORELOAD_EN; } else { timer_group_clr_intr_status_in_isr(timer_group, timer_idx); esp_rom_printf("This is TG%d timer[%d] count-up-timer alarm!\n", timer_group, timer_idx); timer_get_counter_value(timer_group, timer_idx, &timer_val); - timer_get_counter_time_sec(timer_group, timer_idx, &time); timer_get_alarm_value(timer_group, timer_idx, &alarm_value); timer_set_counter_value(timer_group, timer_idx, 0); evt.type = TIMER_AUTORELOAD_DIS; @@ -363,7 +360,7 @@ TEST_CASE("Timer_read_counter_value", "[hw_timer]") timer_config_t config = { .clk_src = TIMER_SRC_CLK_DEFAULT, .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, + .alarm_en = TIMER_ALARM_DIS, .auto_reload = TIMER_AUTORELOAD_EN, .counter_dir = TIMER_COUNT_UP, .counter_en = TIMER_START, @@ -469,7 +466,7 @@ TEST_CASE("Timer_counter_direction", "[hw_timer]") timer_config_t config = { .clk_src = TIMER_SRC_CLK_DEFAULT, .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, + .alarm_en = TIMER_ALARM_DIS, .auto_reload = TIMER_AUTORELOAD_EN, .counter_dir = TIMER_COUNT_UP, .counter_en = TIMER_START, @@ -508,7 +505,7 @@ TEST_CASE("Timer_divider", "[hw_timer]") timer_config_t config = { .clk_src = TIMER_SRC_CLK_DEFAULT, .divider = clk_src_hz / TEST_TIMER_RESOLUTION_HZ, - .alarm_en = TIMER_ALARM_EN, + .alarm_en = TIMER_ALARM_DIS, .auto_reload = TIMER_AUTORELOAD_EN, .counter_dir = TIMER_COUNT_UP, .counter_en = TIMER_START, diff --git a/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py b/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py index 43c6726f6895..726f05adc7c3 100644 --- a/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py +++ b/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py @@ -1,11 +1,9 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8962 @pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', [ diff --git a/components/driver/touch_sensor/esp32s2/touch_sensor.c b/components/driver/touch_sensor/esp32s2/touch_sensor.c index 67fce6d464c3..42ed7c6291d0 100644 --- a/components/driver/touch_sensor/esp32s2/touch_sensor.c +++ b/components/driver/touch_sensor/esp32s2/touch_sensor.c @@ -10,6 +10,7 @@ #include "esp_log.h" #include "sys/lock.h" #include "soc/soc_pins.h" +#include "soc/rtc_cntl_reg.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/timers.h" diff --git a/components/driver/touch_sensor/esp32s3/touch_sensor.c b/components/driver/touch_sensor/esp32s3/touch_sensor.c index e1b86db319e7..d749996017b1 100644 --- a/components/driver/touch_sensor/esp32s3/touch_sensor.c +++ b/components/driver/touch_sensor/esp32s3/touch_sensor.c @@ -10,6 +10,7 @@ #include "esp_log.h" #include "sys/lock.h" #include "soc/soc_pins.h" +#include "soc/rtc_cntl_reg.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/timers.h" diff --git a/components/driver/touch_sensor/include/driver/touch_pad.h b/components/driver/touch_sensor/include/driver/touch_pad.h index 3730eb386da0..5de1a4121c7e 100644 --- a/components/driver/touch_sensor/include/driver/touch_pad.h +++ b/components/driver/touch_sensor/include/driver/touch_pad.h @@ -8,6 +8,6 @@ #include "soc/soc_caps.h" -#if SOC_TOUCH_SENSOR_SUPPORTED +#if SOC_TOUCH_SENSOR_SUPPORTED && SOC_TOUCH_SENSOR_VERSION < 3 #include "driver/touch_sensor.h" #endif diff --git a/components/driver/twai/include/driver/twai.h b/components/driver/twai/include/driver/twai.h index fe1bd8abb21b..78bc71106a7a 100644 --- a/components/driver/twai/include/driver/twai.h +++ b/components/driver/twai/include/driver/twai.h @@ -18,7 +18,9 @@ extern "C" { #endif /* -------------------- Default initializers and flags ---------------------- */ + /** @cond */ //Doxy command to hide preprocessor definitions from docs + /** * @brief Initializer macro for general configuration structure. * diff --git a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c index 0d48b1fd4e3a..aa8a464ef9f8 100644 --- a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c +++ b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c @@ -288,7 +288,7 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 || #endif -#if SOC_ECDSA_SUPPORTED +#if SOC_EFUSE_ECDSA_KEY purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY || #endif purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY)) { @@ -303,7 +303,7 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 || #endif //#ifdef SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS -#if SOC_ECDSA_SUPPORTED +#if SOC_EFUSE_ECDSA_KEY purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY || #endif #if SOC_KEY_MANAGER_SUPPORTED diff --git a/components/efuse/test_apps/README.md b/components/efuse/test_apps/README.md index c75201fb88f7..351f5fdebc72 100644 --- a/components/efuse/test_apps/README.md +++ b/components/efuse/test_apps/README.md @@ -1,3 +1,3 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/efuse/test_apps/main/with_key_purposes/test_efuse_keys.c b/components/efuse/test_apps/main/with_key_purposes/test_efuse_keys.c index 13452f0989e8..f6a49cfa8299 100644 --- a/components/efuse/test_apps/main/with_key_purposes/test_efuse_keys.c +++ b/components/efuse/test_apps/main/with_key_purposes/test_efuse_keys.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,7 +63,7 @@ TEST_CASE("Test efuse API blocks burning XTS and ECDSA keys into BLOCK9", "[efus purpose = ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2; TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_write_key(EFUSE_BLK9, purpose, &key, sizeof(key))); #endif -#if SOC_ECDSA_SUPPORTED +#if SOC_EFUSE_ECDSA_KEY purpose = ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY; TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_efuse_write_key(EFUSE_BLK9, purpose, &key, sizeof(key))); #endif @@ -90,7 +90,7 @@ static esp_err_t s_check_key(esp_efuse_block_t num_key, void* wr_key) purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 || #endif -#if SOC_ECDSA_SUPPORTED +#if SOC_EFUSE_ECDSA_KEY purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY || #endif purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL || @@ -169,7 +169,7 @@ TEST_CASE("Test esp_efuse_write_key for virt mode", "[efuse]") purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 || #endif //#ifdef SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS -#if SOC_ECDSA_SUPPORTED +#if SOC_EFUSE_ECDSA_KEY purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY || #endif purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY)) { @@ -204,7 +204,7 @@ TEST_CASE("Test 1 esp_efuse_write_key for FPGA", "[efuse]") esp_efuse_purpose_t purpose [] = { ESP_EFUSE_KEY_PURPOSE_USER, -#if SOC_ECDSA_SUPPORTED +#if SOC_EFUSE_ECDSA_KEY ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY, #else ESP_EFUSE_KEY_PURPOSE_RESERVED, diff --git a/components/esp-tls/CMakeLists.txt b/components/esp-tls/CMakeLists.txt index 10c16fcb87c5..3809b6473b69 100644 --- a/components/esp-tls/CMakeLists.txt +++ b/components/esp-tls/CMakeLists.txt @@ -1,4 +1,4 @@ -set(srcs esp_tls.c esp-tls-crypto/esp_tls_crypto.c esp_tls_error_capture.c) +set(srcs esp_tls.c esp-tls-crypto/esp_tls_crypto.c esp_tls_error_capture.c esp_tls_platform_port.c) if(CONFIG_ESP_TLS_USING_MBEDTLS) list(APPEND srcs "esp_tls_mbedtls.c") @@ -9,7 +9,7 @@ if(CONFIG_ESP_TLS_USING_WOLFSSL) "esp_tls_wolfssl.c") endif() -set(priv_req http_parser) +set(priv_req http_parser esp_timer) if(NOT ${IDF_TARGET} STREQUAL "linux") list(APPEND priv_req lwip) endif() @@ -17,7 +17,7 @@ endif() idf_component_register(SRCS "${srcs}" INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} esp-tls-crypto PRIV_INCLUDE_DIRS "private_include" - # mbedtls is public requirements becasue esp_tls.h + # mbedtls is public requirements because esp_tls.h # includes mbedtls header files. REQUIRES mbedtls PRIV_REQUIRES ${priv_req}) diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index 483ca2947206..a23eb27e8e83 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -16,6 +16,7 @@ #include "sdkconfig.h" #include "esp_tls.h" #include "esp_tls_private.h" +#include "esp_tls_platform_port.h" #include "esp_tls_error_capture_internal.h" #include #include @@ -537,9 +538,8 @@ int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp if (!cfg || !tls || !hostname || hostlen < 0) { return -1; } - struct timeval time = {}; - gettimeofday(&time, NULL); - uint32_t start_time_ms = (time.tv_sec * 1000) + (time.tv_usec / 1000); + uint64_t start_time_us; + start_time_us = esp_tls_get_platform_time(); while (1) { int ret = esp_tls_low_level_conn(hostname, hostlen, port, cfg, tls); if (ret == 1) { @@ -548,10 +548,8 @@ int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp ESP_LOGE(TAG, "Failed to open new connection"); return -1; } else if (ret == 0 && cfg->timeout_ms >= 0) { - gettimeofday(&time, NULL); - uint32_t current_time_ms = (time.tv_sec * 1000) + (time.tv_usec / 1000); - uint32_t elapsed_time_ms = current_time_ms - start_time_ms; - if (elapsed_time_ms >= cfg->timeout_ms) { + uint64_t elapsed_time_us = esp_tls_get_platform_time() - start_time_us; + if ((elapsed_time_us / 1000) >= cfg->timeout_ms) { ESP_LOGW(TAG, "Failed to open new connection in specified timeout"); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, ESP_ERR_ESP_TLS_CONNECTION_TIMEOUT); return 0; diff --git a/components/esp-tls/esp_tls_platform_port.c b/components/esp-tls/esp_tls_platform_port.c new file mode 100644 index 000000000000..410f14cc56ef --- /dev/null +++ b/components/esp-tls/esp_tls_platform_port.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#if CONFIG_IDF_TARGET_LINUX +#include +#include +#else +#include "esp_timer.h" +#endif + +uint64_t esp_tls_get_platform_time(void) +{ +#if CONFIG_IDF_TARGET_LINUX + // Use gettimeofday for Linux/MacOS, Ideally esp_timer should be used but it is not implemented for Linux/MacOS. + struct timeval time = {}; + gettimeofday(&time, NULL); + uint64_t curr_time = ((uint64_t)time.tv_sec * 1000000) + (time.tv_usec); + return curr_time; +#else + // For all other esp targets use esp_timer + return esp_timer_get_time(); +#endif +} diff --git a/components/esp-tls/private_include/esp_tls_platform_port.h b/components/esp-tls/private_include/esp_tls_platform_port.h new file mode 100644 index 000000000000..44bc0f3d3bbe --- /dev/null +++ b/components/esp-tls/private_include/esp_tls_platform_port.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// This file contains APIs which have different implementation across different targets e.g., Linux, ESP. + +#pragma once + +#include + +/* @brief + * + * Behaviour + * Linux: + * Returns the system time (64 bit) using gettimeofday in microseconds. This shall get changed if someone changes the system time using settimeofday + * ESP targets: + * Returns the time (64 bit) since boot obtained using esp_timer_get_time() in microseconds + * @return + * time uint64_t bit time value + * + */ +uint64_t esp_tls_get_platform_time(void); diff --git a/components/esp_adc/CMakeLists.txt b/components/esp_adc/CMakeLists.txt index 633c9549597e..92a4d9304a90 100644 --- a/components/esp_adc/CMakeLists.txt +++ b/components/esp_adc/CMakeLists.txt @@ -53,5 +53,5 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} - PRIV_REQUIRES driver esp_driver_gpio efuse esp_pm esp_ringbuf + PRIV_REQUIRES driver esp_driver_gpio efuse esp_pm esp_ringbuf esp_mm LDFRAGMENTS linker.lf) diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 6a13fb2911b8..381ad55f8d19 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -37,6 +37,10 @@ #include "adc_continuous_internal.h" #include "esp_private/adc_dma.h" #include "adc_dma_internal.h" +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#include "esp_cache.h" +#include "esp_private/esp_cache_private.h" +#endif static const char *ADC_TAG = "adc_continuous"; @@ -66,6 +70,12 @@ static IRAM_ATTR bool adc_dma_intr(adc_continuous_ctx_t *adc_digi_ctx) if (status != ADC_HAL_DMA_DESC_VALID) { break; } +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + else { + esp_err_t msync_ret = esp_cache_msync((void *)finished_buffer, finished_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(msync_ret == ESP_OK); + } +#endif ret = xRingbufferSendFromISR(adc_digi_ctx->ringbuf_hdl, finished_buffer, finished_size, &taskAwoken); need_yield |= (taskAwoken == pdTRUE); @@ -108,7 +118,10 @@ static IRAM_ATTR bool adc_dma_intr(adc_continuous_ctx_t *adc_digi_ctx) } } } - +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + esp_err_t msync_ret = esp_cache_msync((void *)(adc_digi_ctx->hal.rx_desc), adc_digi_ctx->adc_desc_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(msync_ret == ESP_OK); +#endif return need_yield; } @@ -178,7 +191,7 @@ esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_confi } //malloc internal buffer used by DMA - adc_ctx->rx_dma_buf = heap_caps_calloc(1, hdl_config->conv_frame_size * INTERNAL_BUF_NUM, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + adc_ctx->rx_dma_buf = heap_caps_calloc(INTERNAL_BUF_NUM, hdl_config->conv_frame_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT); if (!adc_ctx->rx_dma_buf) { ret = ESP_ERR_NO_MEM; goto cleanup; @@ -187,7 +200,7 @@ esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_confi //malloc dma descriptor uint32_t dma_desc_num_per_frame = (hdl_config->conv_frame_size + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; uint32_t dma_desc_max_num = dma_desc_num_per_frame * INTERNAL_BUF_NUM; - adc_ctx->hal.rx_desc = heap_caps_calloc(1, (sizeof(dma_descriptor_t)) * dma_desc_max_num, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + adc_ctx->hal.rx_desc = heap_caps_aligned_calloc(ADC_DMA_DESC_ALIGN, dma_desc_max_num, sizeof(dma_descriptor_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT); if (!adc_ctx->hal.rx_desc) { ret = ESP_ERR_NO_MEM; goto cleanup; @@ -245,7 +258,9 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle) ESP_RETURN_ON_FALSE(handle->fsm == ADC_FSM_INIT, ESP_ERR_INVALID_STATE, ADC_TAG, "ADC continuous mode isn't in the init state, it's started already"); //reset ADC digital part to reset ADC sampling EOF counter - periph_module_reset(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_reset_register(); + } if (handle->pm_lock) { ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(handle->pm_lock), ADC_TAG, "acquire pm_lock failed"); @@ -295,6 +310,10 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle) adc_dma_reset(handle->adc_dma); adc_hal_digi_reset(); adc_hal_digi_dma_link(&handle->hal, handle->rx_dma_buf); +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + esp_err_t ret = esp_cache_msync(handle->hal.rx_desc, handle->adc_desc_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + assert(ret == ESP_OK); +#endif adc_dma_start(handle->adc_dma, handle->hal.rx_desc); adc_hal_digi_connect(true); @@ -526,12 +545,12 @@ esp_err_t adc_continuous_flush_pool(adc_continuous_handle_t handle) return ESP_OK; } -esp_err_t adc_continuous_io_to_channel(int io_num, adc_unit_t * const unit_id, adc_channel_t * const channel) +esp_err_t adc_continuous_io_to_channel(int io_num, adc_unit_t *const unit_id, adc_channel_t *const channel) { return adc_io_to_channel(io_num, unit_id, channel); } -esp_err_t adc_continuous_channel_to_io(adc_unit_t unit_id, adc_channel_t channel, int * const io_num) +esp_err_t adc_continuous_channel_to_io(adc_unit_t unit_id, adc_channel_t channel, int *const io_num) { return adc_channel_to_io(unit_id, channel, io_num); } diff --git a/components/esp_adc/adc_continuous_internal.h b/components/esp_adc/adc_continuous_internal.h index 03ae5d970a2d..a2fb28dfac60 100644 --- a/components/esp_adc/adc_continuous_internal.h +++ b/components/esp_adc/adc_continuous_internal.h @@ -99,6 +99,7 @@ struct adc_continuous_ctx_t { #if SOC_ADC_MONITOR_SUPPORTED adc_monitor_t *adc_monitor[SOC_ADC_DIGI_MONITOR_NUM]; // adc monitor context #endif + size_t adc_desc_size; adc_dma_t adc_dma; adc_dma_intr_func_t adc_intr_func; }; diff --git a/components/esp_adc/adc_dma_internal.h b/components/esp_adc/adc_dma_internal.h index 5cdc73e2bae0..747ea7d5cc41 100644 --- a/components/esp_adc/adc_dma_internal.h +++ b/components/esp_adc/adc_dma_internal.h @@ -32,6 +32,8 @@ typedef struct { intr_handle_t dma_intr_hdl; } adc_dma_t; +#define ADC_DMA_DESC_ALIGN 4 + #ifdef __cplusplus } #endif diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index 80f2711489f2..0691e22f1ad3 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -115,7 +115,6 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a }; adc_oneshot_hal_init(&(unit->hal), &config); -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED //To enable the APB_SARADC periph if needed _lock_acquire(&s_ctx.mutex); s_ctx.apb_periph_ref_cnts++; @@ -123,12 +122,13 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a adc_apb_periph_claim(); } _lock_release(&s_ctx.mutex); -#endif if (init_config->ulp_mode == ADC_ULP_MODE_DISABLE) { sar_periph_ctrl_adc_oneshot_power_acquire(); } else { +#if !CONFIG_IDF_TARGET_ESP32P4 // # TODO: IDF-7528, IDF-7529 esp_sleep_enable_adc_tsens_monitor(true); +#endif } ESP_LOGD(TAG, "new adc unit%"PRId32" is created", unit->unit_id); @@ -229,7 +229,9 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle) if (ulp_mode == ADC_ULP_MODE_DISABLE) { sar_periph_ctrl_adc_oneshot_power_release(); } else { +#if !CONFIG_IDF_TARGET_ESP32P4 // # TODO: IDF-7528, IDF-7529 esp_sleep_enable_adc_tsens_monitor(false); +#endif } #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED @@ -262,7 +264,7 @@ static esp_err_t s_adc_io_init(adc_unit_t unit, adc_channel_t channel) { ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(unit), ESP_ERR_INVALID_ARG, TAG, "invalid channel"); -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED +#if !ADC_LL_RTC_GPIO_SUPPORTED uint32_t io_num = ADC_GET_IO_NUM(unit, channel); gpio_config_t cfg = { diff --git a/components/esp_adc/test_apps/.build-test-rules.yml b/components/esp_adc/test_apps/.build-test-rules.yml index aa97546c7d49..6a284fa6d2c8 100644 --- a/components/esp_adc/test_apps/.build-test-rules.yml +++ b/components/esp_adc/test_apps/.build-test-rules.yml @@ -4,6 +4,10 @@ components/esp_adc/test_apps/adc: disable: - if: SOC_ADC_SUPPORTED != 1 - if: CONFIG_NAME == "gdma_iram_safe" and IDF_TARGET in ["esp32", "esp32s2", "esp32c2"] + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: not runners for ESP32P4 ADC # TODO: IDF-9573 depends_components: - esp_adc - esp_driver_gpio diff --git a/components/esp_adc/test_apps/adc/README.md b/components/esp_adc/test_apps/adc/README.md index a8b7833fa30d..bf47d80ec649 100644 --- a/components/esp_adc/test_apps/adc/README.md +++ b/components/esp_adc/test_apps/adc/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_adc/test_apps/adc/main/test_common_adc.c b/components/esp_adc/test_apps/adc/main/test_common_adc.c index 7cf974c43f56..2636803588d1 100644 --- a/components/esp_adc/test_apps/adc/main/test_common_adc.c +++ b/components/esp_adc/test_apps/adc/main/test_common_adc.c @@ -13,6 +13,7 @@ #include "driver/rtc_io.h" #include "soc/adc_periph.h" #include "test_common_adc.h" +#include "hal/adc_ll.h" __attribute__((unused)) static const char *TAG = "TEST_ADC"; @@ -98,7 +99,7 @@ void test_adc_set_io_level(adc_unit_t unit, adc_channel_t channel, bool level) { TEST_ASSERT(channel < SOC_ADC_CHANNEL_NUM(unit) && "invalid channel"); -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED +#if !ADC_LL_RTC_GPIO_SUPPORTED uint32_t io_num = ADC_GET_IO_NUM(unit, channel); TEST_ESP_OK(gpio_set_pull_mode(io_num, (level ? GPIO_PULLUP_ONLY : GPIO_PULLDOWN_ONLY))); #else diff --git a/components/esp_adc/test_apps/adc/main/test_common_adc.h b/components/esp_adc/test_apps/adc/main/test_common_adc.h index 5228713af93e..1d28c66e4ee1 100644 --- a/components/esp_adc/test_apps/adc/main/test_common_adc.h +++ b/components/esp_adc/test_apps/adc/main/test_common_adc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -86,6 +86,14 @@ extern "C" { #define ADC_TEST_HIGH_VAL 3390 #define ADC_TEST_HIGH_VAL_DMA 4081 #define ADC_TEST_HIGH_THRESH 200 + +#elif CONFIG_IDF_TARGET_ESP32P4 +#define ADC_TEST_LOW_VAL 3100 +#define ADC_TEST_LOW_THRESH 200 + +#define ADC_TEST_HIGH_VAL 4095 +#define ADC_TEST_HIGH_VAL_DMA 4095 +#define ADC_TEST_HIGH_THRESH 200 #endif /*--------------------------------------------------------------- diff --git a/components/esp_coex/Kconfig b/components/esp_coex/Kconfig index fb982aeb0e60..d35ee7be78f2 100644 --- a/components/esp_coex/Kconfig +++ b/components/esp_coex/Kconfig @@ -32,5 +32,12 @@ menu "Wireless Coexistence" This function depends on BT-off because currently we do not support external coex and internal coex simultaneously. + config ESP_COEX_POWER_MANAGEMENT + bool "Support power management under coexistence" + default n + depends on (ESP_COEX_SW_COEXIST_ENABLE) + help + If enabled, coexist power management will be enabled. endif + endmenu # Wireless Coexistence diff --git a/components/esp_coex/include/private/esp_coexist_internal.h b/components/esp_coex/include/private/esp_coexist_internal.h index 7aee0c053338..20cea8a437b4 100644 --- a/components/esp_coex/include/private/esp_coexist_internal.h +++ b/components/esp_coex/include/private/esp_coexist_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -313,7 +313,7 @@ esp_err_t esp_coex_adapter_register(coex_adapter_funcs_t *funcs); #if CONFIG_EXTERNAL_COEX_ENABLE /** - * @brief Set external coexistence advanced informations, like working mode. + * @brief Set external coexistence advanced information, like working mode. * * @param out_pti1 This parameter no longer works, will be deprecated and later removed in future releases. * @param out_pti2 This parameter no longer works, will be deprecated and later removed in future releases. @@ -365,6 +365,25 @@ void esp_coex_external_set_txline(bool en); #endif /*SOC_EXTERNAL_COEX_LEADER_TX_LINE*/ #endif /*External Coex*/ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT +/** + * @brief Set coexist scheme flexible period + * + * @param period flexible period + * + * @return + * - ESP_OK: succeed + */ +int coex_schm_flexible_period_set(uint8_t period); + +/** + * @brief Get coexist scheme flexible period + * + * @return Coexist scheme flexible period + */ +uint8_t coex_schm_flexible_period_get(void); +#endif + /** * @brief Check the MD5 values of the coexistence adapter header files in IDF and WiFi library * diff --git a/components/esp_coex/lib b/components/esp_coex/lib index 87eecbdf1392..d99dfd1883a1 160000 --- a/components/esp_coex/lib +++ b/components/esp_coex/lib @@ -1 +1 @@ -Subproject commit 87eecbdf1392d5b4304c4c8e7a26056fa5df294f +Subproject commit d99dfd1883a1468b8986362a1382a4f46e918b60 diff --git a/components/esp_common/include/esp_idf_version.h b/components/esp_common/include/esp_idf_version.h index 4cb488257a4f..d3e010a20ead 100644 --- a/components/esp_common/include/esp_idf_version.h +++ b/components/esp_common/include/esp_idf_version.h @@ -15,7 +15,7 @@ extern "C" { /** Minor version number (x.X.x) */ #define ESP_IDF_VERSION_MINOR 3 /** Patch version number (x.x.X) */ -#define ESP_IDF_VERSION_PATCH 0 +#define ESP_IDF_VERSION_PATCH 1 /** * Macro to convert IDF version number into an integer diff --git a/components/esp_common/test_apps/.build-test-rules.yml b/components/esp_common/test_apps/.build-test-rules.yml index 7b18cd897dbe..04fd48936f06 100644 --- a/components/esp_common/test_apps/.build-test-rules.yml +++ b/components/esp_common/test_apps/.build-test-rules.yml @@ -3,6 +3,3 @@ components/esp_common/test_apps/esp_common: disable: - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 - - if: CONFIG_NAME == "psram" and IDF_TARGET in ["esp32p4"] - temporary: true - reason: esp32p4 is not supported yet # TODO: IDF-7557 diff --git a/components/esp_common/test_apps/esp_common/pytest_esp_common.py b/components/esp_common/test_apps/esp_common/pytest_esp_common.py index 983220995f67..1a31480cc2f6 100644 --- a/components/esp_common/test_apps/esp_common/pytest_esp_common.py +++ b/components/esp_common/test_apps/esp_common/pytest_esp_common.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -51,6 +50,7 @@ def run_multiple_stages(dut: Dut, test_case_num: int, stages: int) -> None: @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -89,3 +89,17 @@ def test_esp_attr_xip_psram_esp32s2(dut: Dut) -> None: ) def test_esp_attr_xip_psram_esp32s3(dut: Dut) -> None: dut.run_all_single_board_cases() + + +# psram attr tests with xip_psram +@pytest.mark.esp32p4 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'xip_psram_esp32p4' + ], + indirect=True, +) +def test_esp_attr_xip_psram_esp32p4(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_common/test_apps/esp_common/sdkconfig.xip_psram_esp32p4 b/components/esp_common/test_apps/esp_common/sdkconfig.xip_psram_esp32p4 new file mode 100644 index 000000000000..706f080ca94a --- /dev/null +++ b/components/esp_common/test_apps/esp_common/sdkconfig.xip_psram_esp32p4 @@ -0,0 +1,6 @@ +# For XiP PSRAM EXT_RAM_BSS_ATTR + +CONFIG_IDF_TARGET="esp32p4" +CONFIG_SPIRAM=y +CONFIG_SPIRAM_XIP_FROM_PSRAM=y +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y diff --git a/components/esp_driver_cam/CMakeLists.txt b/components/esp_driver_cam/CMakeLists.txt index b6a0c4dee408..e0a06e358668 100644 --- a/components/esp_driver_cam/CMakeLists.txt +++ b/components/esp_driver_cam/CMakeLists.txt @@ -1,13 +1,36 @@ -set(srcs "esp_cam_ctlr.c") +idf_build_get_property(target IDF_TARGET) -set(include "include" "interface") +set(srcs "esp_cam_ctlr.c" "dvp_share_ctrl.c") + +set(includes "include" "interface") + +set(requires "esp_driver_isp") + +set(priv_requires "esp_driver_gpio") if(CONFIG_SOC_MIPI_CSI_SUPPORTED) list(APPEND srcs "csi/src/esp_cam_ctlr_csi.c") - list(APPEND include "csi/include") + list(APPEND includes "csi/include") +endif() + +if(CONFIG_SOC_ISP_DVP_SUPPORTED) + list(APPEND srcs "isp_dvp/src/esp_cam_ctlr_isp_dvp.c") + list(APPEND includes "isp_dvp/include") +endif() + +if(NOT ${target} STREQUAL "linux") + list(APPEND requires esp_mm) +endif() + +if(CONFIG_SOC_LCDCAM_CAM_SUPPORTED) + list(APPEND srcs "dvp/src/esp_cam_ctlr_dvp_gdma.c" "dvp/src/esp_cam_ctlr_dvp_cam.c") + list(APPEND includes "dvp/include") + list(APPEND priv_include_dirs "dvp/private_include") endif() idf_component_register(SRCS ${srcs} - INCLUDE_DIRS ${include} - PRIV_REQUIRES esp_mm + INCLUDE_DIRS ${includes} + PRIV_INCLUDE_DIRS ${priv_include_dirs} + REQUIRES ${requires} + PRIV_REQUIRES ${priv_requires} ) diff --git a/components/esp_driver_cam/Kconfig b/components/esp_driver_cam/Kconfig index f7b3ceaa6b85..ca1fac319a39 100644 --- a/components/esp_driver_cam/Kconfig +++ b/components/esp_driver_cam/Kconfig @@ -1,11 +1,40 @@ -menu "ESP Camera Controller Configurations" - depends on SOC_MIPI_CSI_SUPPORTED +menu "ESP-Driver:Camera Controller Configurations" - config MIPI_CSI_ISR_IRAM_SAFE + depends on SOC_MIPI_CSI_SUPPORTED || SOC_LCDCAM_CAM_SUPPORTED + + config CAM_CTLR_MIPI_CSI_ISR_IRAM_SAFE bool "CSI ISR IRAM-Safe" + depends on SOC_MIPI_CSI_SUPPORTED default n + select DW_GDMA_ISR_IRAM_SAFE + select DW_GDMA_CTRL_FUNC_IN_IRAM + select DW_GDMA_SETTER_FUNC_IN_IRAM + select DW_GDMA_GETTER_FUNC_IN_IRAM help Ensure the CSI driver ISR is IRAM-Safe. When enabled, the ISR handler will be available when the cache is disabled. + config CAM_CTLR_ISP_DVP_ISR_IRAM_SAFE # IDF-10093 + bool "ISP_DVP ISR IRAM-Safe" + default n + select DW_GDMA_ISR_IRAM_SAFE + select DW_GDMA_CTRL_FUNC_IN_IRAM + select DW_GDMA_SETTER_FUNC_IN_IRAM + select DW_GDMA_GETTER_FUNC_IN_IRAM + help + Ensure the ISP_DVP driver ISR is IRAM-Safe. When enabled, the ISR handler + will be available when the cache is disabled. + + config CAM_CTLR_DVP_CAM_ISR_IRAM_SAFE + bool "DVP ISR IRAM-Safe" + depends on SOC_LCDCAM_CAM_SUPPORTED + default n + select DW_GDMA_ISR_IRAM_SAFE + select DW_GDMA_CTRL_FUNC_IN_IRAM + select DW_GDMA_SETTER_FUNC_IN_IRAM + select DW_GDMA_GETTER_FUNC_IN_IRAM + help + Ensure the DVP driver ISR is IRAM-Safe. When enabled, the ISR handler + will be available when the cache is disabled. + endmenu # ESP Camera Controller Configurations diff --git a/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h b/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h index fa63b5fc048f..18eed2e00cce 100644 --- a/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h +++ b/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h @@ -15,11 +15,6 @@ extern "C" { #endif -/** - * @brief ESP CAM controller max timeout value - */ -#define ESP_CAM_CTLR_MAX_DELAY UINT32_MAX - /** * @brief ESP CAM CSI controller configurations */ @@ -30,8 +25,8 @@ typedef struct { uint32_t v_res; ///< Input vertical resolution, i.e. the number of lines in a frame uint8_t data_lane_num; ///< Data lane num int lane_bit_rate_mbps; ///< Lane bit rate in Mbps - mipi_csi_color_t input_data_color_type; ///< Input color type - mipi_csi_color_t output_data_color_type; ///< Output color type + cam_ctlr_color_t input_data_color_type; ///< Input color type + cam_ctlr_color_t output_data_color_type; ///< Output color type int queue_items; ///< Queue items struct { uint32_t byte_swap_en : 1; ///< Enable byte swap diff --git a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c index 1136273da0d3..ebfcdb3fcccd 100644 --- a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c +++ b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c @@ -24,7 +24,7 @@ #include "esp_private/esp_cache_private.h" #include "esp_cache.h" -#if CONFIG_MIPI_CSI_ISR_IRAM_SAFE +#if CONFIG_CAM_CTLR_MIPI_CSI_ISR_IRAM_SAFE #define CSI_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #else #define CSI_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT @@ -66,7 +66,6 @@ static esp_err_t s_csi_claim_controller(csi_controller_t *controller) mipi_csi_ll_enable_host_bus_clock(i, 1); mipi_csi_ll_reset_host_clock(i); } - _lock_release(&s_platform.mutex); break; } } @@ -295,12 +294,12 @@ static esp_err_t s_csi_ctlr_get_buffer_length(esp_cam_ctlr_handle_t handle, size return ESP_OK; } -static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data) +IRAM_ATTR static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data) { bool need_yield = false; BaseType_t high_task_woken = pdFALSE; csi_controller_t *ctlr = (csi_controller_t *)user_data; - bool use_backup = false; + bool has_new_trans = false; dw_gdma_block_transfer_config_t csi_dma_transfer_config = {}; csi_dma_transfer_config = (dw_gdma_block_transfer_config_t) { @@ -324,28 +323,26 @@ static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_ if (ctlr->cbs.on_get_new_trans) { need_yield = ctlr->cbs.on_get_new_trans(&(ctlr->base), &new_trans, ctlr->cbs_user_data); - if (!(new_trans.buffer) || new_trans.buflen < ctlr->fb_size_in_bytes) { - use_backup = true; - } else { + if (new_trans.buffer && new_trans.buflen >= ctlr->fb_size_in_bytes) { csi_dma_transfer_config.dst.addr = (uint32_t)(new_trans.buffer); + has_new_trans = true; } } else if (xQueueReceiveFromISR(ctlr->trans_que, &new_trans, &high_task_woken) == pdTRUE) { - if (!(new_trans.buffer) || new_trans.buflen < ctlr->fb_size_in_bytes) { - use_backup = true; - } else { + if (new_trans.buffer && new_trans.buflen >= ctlr->fb_size_in_bytes) { csi_dma_transfer_config.dst.addr = (uint32_t)(new_trans.buffer); + has_new_trans = true; } - } else if (!ctlr->bk_buffer_dis) { - use_backup = true; } - if (use_backup) { - new_trans.buffer = ctlr->backup_buffer; - new_trans.buflen = ctlr->fb_size_in_bytes; - ESP_EARLY_LOGD(TAG, "no new buffer or no long enough new buffer, use driver internal buffer"); - csi_dma_transfer_config.dst.addr = (uint32_t)ctlr->backup_buffer; - } else { - assert(false && "no new buffer, and no driver internal buffer"); + if (!has_new_trans) { + if (!ctlr->bk_buffer_dis) { + new_trans.buffer = ctlr->backup_buffer; + new_trans.buflen = ctlr->fb_size_in_bytes; + ESP_EARLY_LOGD(TAG, "no new buffer or no long enough new buffer, use driver internal buffer"); + csi_dma_transfer_config.dst.addr = (uint32_t)ctlr->backup_buffer; + } else { + assert(false && "no new buffer, and no driver internal buffer"); + } } ESP_EARLY_LOGD(TAG, "new_trans.buffer: %p, new_trans.buflen: %d", new_trans.buffer, new_trans.buflen); @@ -353,7 +350,7 @@ static bool csi_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_ dw_gdma_channel_enable_ctrl(chan, true); if ((ctlr->trans.buffer != ctlr->backup_buffer) || ctlr->bk_buffer_exposed) { - esp_err_t ret = esp_cache_msync((void *)(ctlr->trans.buffer), ctlr->trans.received_size, ESP_CACHE_MSYNC_FLAG_INVALIDATE); + esp_err_t ret = esp_cache_msync((void *)(ctlr->trans.buffer), ctlr->trans.received_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); assert(ret == ESP_OK); assert(ctlr->cbs.on_trans_finished); if (ctlr->cbs.on_trans_finished) { @@ -376,7 +373,7 @@ esp_err_t s_register_event_callbacks(esp_cam_ctlr_handle_t handle, const esp_cam csi_controller_t *ctlr = __containerof(handle, csi_controller_t, base); ESP_RETURN_ON_FALSE(ctlr->csi_fsm == CSI_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "driver starts already, not allow cbs register"); -#if CONFIG_MIPI_CSI_ISR_IRAM_SAFE +#if CONFIG_CAM_CTLR_MIPI_CSI_ISR_IRAM_SAFE if (cbs->on_get_new_trans) { ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_get_new_trans), ESP_ERR_INVALID_ARG, TAG, "on_get_new_trans callback not in IRAM"); } @@ -409,7 +406,7 @@ esp_err_t s_csi_ctlr_disable(esp_cam_ctlr_handle_t handle) { ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); csi_controller_t *ctlr = __containerof(handle, csi_controller_t, base); - ESP_RETURN_ON_FALSE(ctlr->csi_fsm == CSI_FSM_ENABLED, ESP_ERR_INVALID_STATE, TAG, "processor isn't in init state"); + ESP_RETURN_ON_FALSE(ctlr->csi_fsm == CSI_FSM_ENABLED, ESP_ERR_INVALID_STATE, TAG, "processor isn't in enable state"); portENTER_CRITICAL(&ctlr->spinlock); ctlr->csi_fsm = CSI_FSM_INIT; @@ -426,14 +423,22 @@ esp_err_t s_ctlr_csi_start(esp_cam_ctlr_handle_t handle) ESP_RETURN_ON_FALSE(ctlr->cbs.on_trans_finished, ESP_ERR_INVALID_STATE, TAG, "no on_trans_finished callback registered"); esp_cam_ctlr_trans_t trans = {}; + bool has_new_trans = false; + if (ctlr->cbs.on_get_new_trans) { ctlr->cbs.on_get_new_trans(handle, &trans, ctlr->cbs_user_data); - ESP_RETURN_ON_FALSE(trans.buffer, ESP_ERR_INVALID_STATE, TAG, "no ready transaction, cannot start"); - } else if (!ctlr->bk_buffer_dis) { - trans.buffer = ctlr->backup_buffer; - trans.buflen = ctlr->fb_size_in_bytes; - } else { - ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "no ready transaction, and no backup buffer"); + if (trans.buffer) { + has_new_trans = true; + } + } + + if (!has_new_trans) { + if (!ctlr->bk_buffer_dis) { + trans.buffer = ctlr->backup_buffer; + trans.buflen = ctlr->fb_size_in_bytes; + } else { + ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "no ready transaction, and no backup buffer"); + } } ESP_LOGD(TAG, "trans.buffer: %p, trans.buflen: %d", trans.buffer, trans.buflen); @@ -481,7 +486,7 @@ esp_err_t s_ctlr_csi_stop(esp_cam_ctlr_handle_t handle) ESP_RETURN_ON_ERROR(dw_gdma_channel_enable_ctrl(ctlr->dma_chan, false), TAG, "failed to disable dwgdma"); portENTER_CRITICAL(&ctlr->spinlock); - ctlr->csi_fsm = CSI_FSM_INIT; + ctlr->csi_fsm = CSI_FSM_ENABLED; portEXIT_CRITICAL(&ctlr->spinlock); return ESP_OK; diff --git a/components/esp_driver_cam/dvp/include/esp_cam_ctlr_dvp.h b/components/esp_driver_cam/dvp/include/esp_cam_ctlr_dvp.h new file mode 100644 index 000000000000..01cd362a90d1 --- /dev/null +++ b/components/esp_driver_cam/dvp/include/esp_cam_ctlr_dvp.h @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" +#include "soc/gpio_num.h" +#include "hal/cam_types.h" +#include "esp_cam_ctlr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief ESP CAM DVP pins configuration + */ +typedef struct esp_cam_ctlr_dvp_pin_config { + cam_ctlr_data_width_t data_width; /*!< Number of data lines */ + gpio_num_t data_io[CAM_DVP_DATA_SIG_NUM]; /*!< DVP data pin number */ + gpio_num_t vsync_io; /*!< DVP V-Sync pin number */ + gpio_num_t de_io; /*!< DVP DE pin number */ + gpio_num_t pclk_io; /*!< DVP PCLK input pin number, clock is from camera sensor */ + gpio_num_t xclk_io; /*!< DVP output clock pin number, if using external XTAL, set xclk_io = GPIO_NUM_NC */ +} esp_cam_ctlr_dvp_pin_config_t; + +/** + * @brief ESP CAM DVP controller configurations + */ +typedef struct esp_cam_ctlr_dvp_config { + int ctlr_id; /*!< DVP controller ID */ + cam_clock_source_t clk_src; /*!< DVP clock source */ + uint32_t h_res; /*!< Input horizontal resolution, i.e. the number of pixels in a line */ + uint32_t v_res; /*!< Input vertical resolution, i.e. the number of lines in a frame */ + cam_ctlr_color_t input_data_color_type; /*!< Input pixel format */ + struct { + uint32_t byte_swap_en : 1; /*!< Enable byte swap */ + uint32_t bk_buffer_dis : 1; /*!< Disable backup buffer */ + uint32_t pin_dont_init : 1; /*!< Don't initialize DVP pins if users have called "esp_cam_ctlr_dvp_init" before */ + uint32_t pic_format_jpeg : 1; /*!< Input picture format is JPEG, if set this flag and "input_data_color_type" will be ignored */ + }; /*!< Boolean Flags */ + + uint32_t dma_burst_size; /*!< DVP DMA burst transmission block size, set to 0 means to disable the data burst, + other value must be power of 2, e.g., 4/8/16/32/64/128 */ + + const esp_cam_ctlr_dvp_pin_config_t *pin; /*!< DVP pin configuration, this will be ignored by "esp_cam_new_dvp_ctlr" if "pin_dont_init" is set */ +} esp_cam_ctlr_dvp_config_t; + +/** + * @brief New ESP CAM DVP controller + * + * @param config DVP controller configurations + * @param ret_handle Returned CAM controller handle + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG: Invalid argument + * - ESP_ERR_NO_MEM: Out of memory + * - ESP_ERR_NOT_SUPPORTED: Currently not support modes or types + * - ESP_ERR_NOT_FOUND: CSI is registered already + */ +esp_err_t esp_cam_new_dvp_ctlr(const esp_cam_ctlr_dvp_config_t *config, esp_cam_ctlr_handle_t *ret_handle); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_cam/dvp/include/esp_private/esp_cam_dvp.h b/components/esp_driver_cam/dvp/include/esp_private/esp_cam_dvp.h new file mode 100644 index 000000000000..032c81617930 --- /dev/null +++ b/components/esp_driver_cam/dvp/include/esp_private/esp_cam_dvp.h @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_cam_ctlr_dvp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief ESP CAM DVP initialzie clock and GPIO. + * + * @param ctlr_id CAM DVP controller ID + * @param clk_src CAM DVP clock source + * @param pin CAM DVP pin configuration + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const esp_cam_ctlr_dvp_pin_config_t *pin); + +/** + * @brief ESP CAM DVP output hardware clock + * + * @param ctlr_id CAM DVP controller ID + * @param clk_src CAM DVP clock source + * @param xclk_freq CAM DVP output clock frequency in HZ + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_output_clock(int ctlr_id, cam_clock_source_t clk_src, uint32_t xclk_freq); + +/** + * @brief ESP CAM DVP de-initialzie. + * + * @param ctlr_id DVP controller ID + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_deinit(int ctlr_id); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_cam/dvp/private_include/esp_cam_ctlr_dvp_cam.h b/components/esp_driver_cam/dvp/private_include/esp_cam_ctlr_dvp_cam.h new file mode 100644 index 000000000000..5c9b311ee1a4 --- /dev/null +++ b/components/esp_driver_cam/dvp/private_include/esp_cam_ctlr_dvp_cam.h @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "esp_cam_ctlr_interface.h" +#include "hal/cam_hal.h" +#include "esp_cam_ctlr_dvp_dma.h" +#include "esp_cam_ctlr_dvp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief DVP CAM finite state machine + */ +typedef enum esp_cam_ctlr_dvp_cam_fsm { + ESP_CAM_CTLR_DVP_CAM_FSM_INIT = 1, /*!< DVP CAM initialization state, and next state is "enabled" */ + ESP_CAM_CTLR_DVP_CAM_FSM_ENABLED, /*!< DVP CAM enabled state, and next state is "init" or "started" */ + ESP_CAM_CTLR_DVP_CAM_FSM_STARTED, /*!< DVP CAM started state, and next state is "init" or "enabled" */ +} esp_cam_ctlr_dvp_cam_fsm_t; + +/** + * @brief DVP CAM object data + */ +typedef struct esp_cam_ctlr_dvp_cam { + esp_cam_ctlr_t base; /*!< Camera controller base object data */ + esp_cam_ctlr_evt_cbs_t cbs; /*!< Camera controller callback functions */ + void *cbs_user_data; /*!< Camera controller callback private data */ + + int ctlr_id; /*!< DVP CAM port ID */ + cam_ctlr_color_t input_data_color_type; /*!< DVP CAM input pixel format */ + struct { + uint32_t bk_buffer_dis : 1; /*!< Disable backup buffer */ + uint32_t pin_dont_init : 1; /*!< Don't initialize DVP pins if users have called "esp_cam_ctlr_dvp_init" before */ + uint32_t pic_format_jpeg : 1; /*!< Input picture format is JPEG, if set this flag and "input_data_color_type" will be ignored */ + }; /*!< Boolean Flags */ + + cam_hal_context_t hal; /*!< DVP CAM HAL object data */ + esp_cam_ctlr_dvp_dma_t dma; /*!< DVP CAM DMA object data */ + size_t fb_size_in_bytes; /*!< DVP CAM frame buffer maximum size in byte */ + esp_cam_ctlr_dvp_cam_fsm_t dvp_fsm; /*!< DVP CAM finite state machine */ + uint8_t *cur_buf; /*!< DVP CAM current buffer which is receiving stream */ + uint8_t *backup_buffer; /*!< DVP CAM backup buffer */ + bool bk_buffer_exposed; /*!< status of if back_buffer is exposed to users */ + portMUX_TYPE spinlock; /*!< DVP CAM spinlock */ +} esp_cam_ctlr_dvp_cam_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_cam/dvp/private_include/esp_cam_ctlr_dvp_dma.h b/components/esp_driver_cam/dvp/private_include/esp_cam_ctlr_dvp_dma.h new file mode 100644 index 000000000000..0846d6ccd66e --- /dev/null +++ b/components/esp_driver_cam/dvp/private_include/esp_cam_ctlr_dvp_dma.h @@ -0,0 +1,104 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "hal/dma_types.h" +#include "esp_private/gdma.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_CAM_CTLR_DVP_DMA_DESC_BUFFER_MAX_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED + +/** + * @brief DVP DMA description object + */ +typedef dma_descriptor_align8_t esp_cam_ctlr_dvp_dma_desc_t; + +/** + * @brief DVP DMA object + */ +typedef struct esp_cam_ctlr_dvp_dma { + gdma_channel_handle_t dma_chan; /*!< DVP DMA channel handle */ + size_t size; /*!< DVP DMA buffer size */ + esp_cam_ctlr_dvp_dma_desc_t *desc; /*!< DVP DMA description buffer */ + size_t desc_count; /*!< DVP DMA description count */ + size_t desc_size; /*!< DVP DMA description buffer size in byte */ +} esp_cam_ctlr_dvp_dma_t; + +/** + * @brief Initialize DVP DMA object + * + * @param dma DVP DMA object pointer + * @param burst_size DVP DMA burst transmission block size + * @param size DVP DMA buffer size + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_dma_init(esp_cam_ctlr_dvp_dma_t *dma, uint32_t burst_size, size_t size); + +/** + * @brief De-initialize DVP DMA object + * + * @param dma DVP DMA object pointer + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_dma_deinit(esp_cam_ctlr_dvp_dma_t *dma); + +/** + * @brief Set DVP DMA descriptor address and start engine + * + * @param dma DVP DMA object pointer + * @param buffer DVP DMA buffer pointer + * @param size DVP DMA buffer size + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_dma_start(esp_cam_ctlr_dvp_dma_t *dma, uint8_t *buffer, size_t size); + +/** + * @brief Stop DVP DMA engine + * + * @param dma DVP DMA object pointer + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_dma_stop(esp_cam_ctlr_dvp_dma_t *dma); + +/** + * @brief Reset DVP DMA FIFO and internal finite state machine + * + * @param dma DVP DMA object pointer + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_dma_reset(esp_cam_ctlr_dvp_dma_t *dma); + +/** + * @brief Get DMA received data size + * + * @param dma DVP DMA object pointer + * + * @return DMA received data size + */ +size_t esp_cam_ctlr_dvp_dma_get_recv_size(esp_cam_ctlr_dvp_dma_t *dma); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c new file mode 100644 index 000000000000..992ea773cc83 --- /dev/null +++ b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c @@ -0,0 +1,762 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "hal/gpio_ll.h" +#include "hal/cam_ll.h" +#include "hal/color_hal.h" +#include "driver/gpio.h" +#include "esp_cache.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/esp_cache_private.h" +#include "esp_private/gpio.h" +#include "esp_heap_caps.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_clk_tree.h" +#include "soc/cam_periph.h" +#include "esp_cam_ctlr_dvp_cam.h" +#include "esp_private/esp_cam_dvp.h" +#include "../../dvp_share_ctrl.h" + +#ifdef CONFIG_CAM_CTLR_DVP_CAM_ISR_IRAM_SAFE +#define CAM_DVP_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#else +#define CAM_DVP_MEM_ALLOC_CAPS (MALLOC_CAP_DEFAULT) +#endif + +#define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) + +#define DVP_CAM_CONFIG_INPUT_PIN(pin, sig, inv) \ +{ \ + ret = esp_cam_ctlr_dvp_config_input_gpio(pin, sig, inv); \ + if (ret != ESP_OK) { \ + ESP_LOGE(TAG, "failed to configure pin=%d sig=%d", \ + pin, sig); \ + return ret; \ + } \ +} + +typedef struct dvp_platform { + _lock_t mutex; + esp_cam_ctlr_dvp_cam_t *ctlrs[CAP_DVP_PERIPH_NUM]; +} dvp_platform_t; + +static dvp_platform_t s_platform; +static const char *TAG = "dvp_cam"; + +/** + * @brief Claim DVP controller + * + * @param ctlr_id DVP controller ID + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t s_dvp_claim_ctlr(int ctlr_id, esp_cam_ctlr_dvp_cam_t *ctlr) +{ + esp_err_t ret = ESP_ERR_NOT_FOUND; + + _lock_acquire(&s_platform.mutex); + if (!s_platform.ctlrs[ctlr_id]) { + s_platform.ctlrs[ctlr_id] = ctlr; + ret = ESP_OK; + } + _lock_release(&s_platform.mutex); + + return ret; +} + +/** + * @brief Declaim DVP controller + * + * @param ctlr_id DVP controller ID + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t s_dvp_declaim_ctlr(int ctlr_id) +{ + esp_err_t ret = ESP_ERR_NOT_FOUND; + + _lock_acquire(&s_platform.mutex); + if (s_platform.ctlrs[ctlr_id]) { + s_platform.ctlrs[ctlr_id] = NULL; + ret = ESP_OK; + } + _lock_release(&s_platform.mutex); + + return ret; +} + +/** + * @brief CAM DVP initialzie input GPIO pin. + * + * @param pin DVP pin number + * @param signal DVP pin mapping signal + * @param inv true: DVP pin is inverted, false: DVP pin is not inverted + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_dvp_config_input_gpio(int pin, int signal, bool inv) +{ + esp_err_t ret; + + gpio_func_sel(pin, PIN_FUNC_GPIO); + ret = gpio_set_direction(pin, GPIO_MODE_INPUT); + if (ret != ESP_OK) { + return ret; + } + ret = gpio_set_pull_mode(pin, GPIO_FLOATING); + if (ret != ESP_OK) { + return ret; + } + esp_rom_gpio_connect_in_signal(pin, signal, inv); + + return ESP_OK; +} + +/** + * @brief CAM DVP start receiving frame. + * + * @param ctlr CAM DVP controller + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static IRAM_ATTR esp_err_t esp_cam_ctlr_dvp_start_trans(esp_cam_ctlr_dvp_cam_t *ctlr) +{ + bool buffer_ready = false; + esp_cam_ctlr_trans_t trans; + + if (ctlr->cur_buf) { + ctlr->cur_buf = NULL; + cam_hal_stop_streaming(&ctlr->hal); + ESP_RETURN_ON_ERROR_ISR(esp_cam_ctlr_dvp_dma_stop(&ctlr->dma), TAG, "failed to stop DMA"); + } + + if (ctlr->cbs.on_get_new_trans && ctlr->cbs.on_get_new_trans(&(ctlr->base), &trans, ctlr->cbs_user_data)) { + buffer_ready = true; + } else if (!ctlr->bk_buffer_dis) { + trans.buffer = ctlr->backup_buffer; + trans.buflen = ctlr->fb_size_in_bytes; + buffer_ready = true; + } + + if (!buffer_ready) { + assert(false && "no new buffer, and no driver internal buffer"); + } + + ESP_RETURN_ON_ERROR_ISR(esp_cam_ctlr_dvp_dma_reset(&ctlr->dma), TAG, "failed to reset DMA"); + ESP_RETURN_ON_ERROR_ISR(esp_cam_ctlr_dvp_dma_start(&ctlr->dma, trans.buffer, ctlr->fb_size_in_bytes), TAG, "failed to start DMA"); + + cam_hal_start_streaming(&ctlr->hal); + + ctlr->cur_buf = trans.buffer; + + return ESP_OK; +} + +/** + * @brief Check JPEG file and return JPEG frame actual size + * + * @param buffer JPEG buffer pointer + * @param size JPEG buffer size + * + * @return JPEG frame actual size if success or 0 if not JPEG header or tail TAG is found + */ +static uint32_t IRAM_ATTR esp_cam_ctlr_dvp_get_jpeg_size(const uint8_t *buffer, uint32_t size) +{ + /* Check JPEG header TAG: ff:d8 */ + + if (buffer[0] != 0xff || buffer[1] != 0xd8) { + return 0; + } + + for (uint32_t off = size - 2; off > 2; off--) { + /* Check JPEG tail TAG: ff:d9 */ + + if (buffer[off] == 0xff && buffer[off + 1] == 0xd9) { + return off + 2; + } + } + + return 0; +} + +/** + * @brief CAM DVP get actually received data size in byte + * + * @param ctlr CAM DVP controller + * @param rx_buffer CAM DVP receive buffer + * @param dma_recv_size CAM DVP DMA receive buffer size + * + * @return Received data size if success or 0 if failed + */ +static uint32_t IRAM_ATTR esp_cam_ctlr_dvp_get_recved_size(esp_cam_ctlr_dvp_cam_t *ctlr, uint8_t *rx_buffer, uint32_t dma_recv_size) +{ + esp_err_t ret; + uint32_t recv_buffer_size; + + if (ctlr->pic_format_jpeg) { + recv_buffer_size = ALIGN_UP_BY(MIN(dma_recv_size, ctlr->fb_size_in_bytes), 64); + } else { + recv_buffer_size = ctlr->fb_size_in_bytes; + } + + ret = esp_cache_msync(rx_buffer, recv_buffer_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(ret == ESP_OK); + + if (ctlr->pic_format_jpeg) { + recv_buffer_size = esp_cam_ctlr_dvp_get_jpeg_size(rx_buffer, dma_recv_size); + } + + return recv_buffer_size; +} + +/** + * @brief CAM DVP calculate frame receive buffer size. + * + * @param config CAM DVP controller configurations + * @param p_size CAM DVP frame receive buffer size buffer pointer + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_dvp_cam_get_frame_size(const esp_cam_ctlr_dvp_config_t *config, size_t *p_size) +{ + esp_err_t ret = ESP_OK; + + if (config->pic_format_jpeg) { + *p_size = config->h_res * config->v_res; + } else { + color_space_pixel_format_t pixel_format = { + .color_type_id = config->input_data_color_type + }; + uint32_t depth = color_hal_pixel_format_get_bit_depth(pixel_format); + if (!depth) { + return ESP_ERR_INVALID_ARG; + } + + *p_size = config->h_res * config->v_res * depth / 8; + } + + return ret; +} + +/** + * @brief CAM DVP receive frame done interrupt callback function. + * + * @param dma_chan DMA channel + * @param event_data DMA event data + * @param user_data DMA interrupt callback user data + * + * @return + * - true: trigger task switch + * - false: don't trigger task switch + */ +static IRAM_ATTR bool esp_cam_ctlr_recv_frame_done_isr(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + bool need_switch = false; + esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)user_data; + size_t dma_recv_size = esp_cam_ctlr_dvp_dma_get_recv_size(&ctlr->dma); + esp_cam_ctlr_trans_t trans = { + .buffer = ctlr->cur_buf, + }; + + esp_cam_ctlr_dvp_start_trans(ctlr); + + if ((trans.buffer != ctlr->backup_buffer) || ctlr->bk_buffer_exposed) { + trans.buflen = ctlr->fb_size_in_bytes; + trans.received_size = esp_cam_ctlr_dvp_get_recved_size(ctlr, trans.buffer, dma_recv_size); + need_switch = ctlr->cbs.on_trans_finished(&ctlr->base, &trans, ctlr->cbs_user_data); + } + + return need_switch; +} + +/** + * @brief ESP CAM DVP initialzie clock and GPIO. + * + * @param ctlr_id CAM DVP controller ID + * @param clk_src CAM DVP clock source + * @param pin CAM DVP pin configuration + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const esp_cam_ctlr_dvp_pin_config_t *pin) +{ + esp_err_t ret; + + ESP_RETURN_ON_FALSE(ctlr_id < CAP_DVP_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid argument: ctlr_id >= %d", CAP_DVP_PERIPH_NUM); + ESP_RETURN_ON_FALSE(pin->data_width == CAM_CTLR_DATA_WIDTH_8, ESP_ERR_INVALID_ARG, TAG, "invalid argument: data_width != CAM_CTLR_DATA_WIDTH_8"); + ESP_RETURN_ON_FALSE(pin, ESP_ERR_INVALID_ARG, TAG, "invalid argument: pin is null"); + + DVP_CAM_CONFIG_INPUT_PIN(pin->vsync_io, cam_periph_signals.buses[ctlr_id].vsync_sig, true); + DVP_CAM_CONFIG_INPUT_PIN(pin->de_io, cam_periph_signals.buses[ctlr_id].de_sig, false); + DVP_CAM_CONFIG_INPUT_PIN(pin->pclk_io, cam_periph_signals.buses[ctlr_id].pclk_sig, false); + for (int i = 0; i < pin->data_width; i++) { + DVP_CAM_CONFIG_INPUT_PIN(pin->data_io[i], cam_periph_signals.buses[ctlr_id].data_sigs[i], false); + } + + /* If using external XTAL, don't initialize xclock pin */ + + if (pin->xclk_io != GPIO_NUM_NC) { + gpio_func_sel(pin->xclk_io, PIN_FUNC_GPIO); + ret = gpio_set_direction(pin->xclk_io, GPIO_MODE_OUTPUT); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to configure pin=%d", pin->xclk_io); + return ret; + } + esp_rom_gpio_connect_out_signal(pin->xclk_io, cam_periph_signals.buses[ctlr_id].clk_sig, false, false); + } + + PERIPH_RCC_ACQUIRE_ATOMIC(cam_periph_signals.buses[ctlr_id].module, ref_count) { + if (ref_count == 0) { + cam_ll_enable_bus_clock(ctlr_id, true); + cam_ll_reset_register(ctlr_id); + } + } + + PERIPH_RCC_ATOMIC() { + cam_ll_enable_clk(ctlr_id, true); + cam_ll_select_clk_src(ctlr_id, clk_src); + }; + + return ESP_OK; +} + +/** + * @brief ESP CAM DVP output hardware clock + * + * @param ctlr_id CAM DVP controller ID + * @param clk_src CAM DVP clock source + * @param xclk_freq CAM DVP output clock frequency in HZ + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_output_clock(int ctlr_id, cam_clock_source_t clk_src, uint32_t xclk_freq) +{ + esp_err_t ret = ESP_ERR_INVALID_ARG; + uint32_t src_clk_hz; + + ESP_RETURN_ON_FALSE(ctlr_id < CAP_DVP_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid argument: ctlr_id >= %d", CAP_DVP_PERIPH_NUM); + ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz), + TAG, "failed to get clock source frequency"); + + ESP_LOGD(TAG, "DVP clock source frequency %" PRIu32 "Hz", src_clk_hz); + + if ((src_clk_hz % xclk_freq) == 0) { + PERIPH_RCC_ATOMIC() { + cam_ll_set_group_clock_coeff(ctlr_id, src_clk_hz / xclk_freq, 0, 0); + }; + + ret = ESP_OK; + } + + return ret; +} + +/** + * @brief ESP CAM DVP de-initialzie. + * + * @param ctlr_id DVP controller ID + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_deinit(int ctlr_id) +{ + ESP_RETURN_ON_FALSE(ctlr_id < CAP_DVP_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid argument: ctlr_id >= %d", CAP_DVP_PERIPH_NUM); + + PERIPH_RCC_ATOMIC() { + cam_ll_enable_clk(ctlr_id, false); + }; + + PERIPH_RCC_ACQUIRE_ATOMIC(cam_periph_signals.buses[ctlr_id].module, ref_count) { + if (ref_count == 0) { + cam_ll_reset_register(ctlr_id); + cam_ll_enable_bus_clock(ctlr_id, false); + } + } + + return ESP_OK; +} + +/** + * @brief Enable CAM DVP camera controller + * + * @param handle ESP CAM controller handle + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_dvp_cam_enable(esp_cam_ctlr_handle_t handle) +{ + esp_err_t ret = ESP_ERR_INVALID_STATE; + esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)handle; + + ESP_RETURN_ON_FALSE(ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: handle is null"); + + portENTER_CRITICAL(&ctlr->spinlock); + if (ctlr->dvp_fsm == ESP_CAM_CTLR_DVP_CAM_FSM_INIT) { + ctlr->dvp_fsm = ESP_CAM_CTLR_DVP_CAM_FSM_ENABLED; + ret = ESP_OK; + } + portEXIT_CRITICAL(&ctlr->spinlock); + + return ret; +} + +/** + * @brief Disable CAM DVP camera controller + * + * @param handle ESP CAM controller handle + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_dvp_cam_disable(esp_cam_ctlr_handle_t handle) +{ + esp_err_t ret = ESP_ERR_INVALID_STATE; + esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)handle; + + ESP_RETURN_ON_FALSE(ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: handle is null"); + + portENTER_CRITICAL(&ctlr->spinlock); + if (ctlr->dvp_fsm == ESP_CAM_CTLR_DVP_CAM_FSM_ENABLED) { + ctlr->dvp_fsm = ESP_CAM_CTLR_DVP_CAM_FSM_INIT; + ret = ESP_OK; + } + portEXIT_CRITICAL(&ctlr->spinlock); + + return ret; +} + +/** + * @brief Start CAM DVP camera controller + * + * @param handle ESP CAM controller handle + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_dvp_cam_start(esp_cam_ctlr_handle_t handle) +{ + bool start = false; + esp_err_t ret = ESP_ERR_INVALID_STATE; + esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)handle; + + ESP_RETURN_ON_FALSE(ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: handle is null"); + + portENTER_CRITICAL(&ctlr->spinlock); + if (ctlr->dvp_fsm == ESP_CAM_CTLR_DVP_CAM_FSM_ENABLED) { + ctlr->cur_buf = NULL; + ctlr->dvp_fsm = ESP_CAM_CTLR_DVP_CAM_FSM_STARTED; + start = true; + } + portEXIT_CRITICAL(&ctlr->spinlock); + + if (start) { + ret = esp_cam_ctlr_dvp_start_trans(ctlr); + } + + return ret; +} + +/** + * @brief Stop CAM DVP camera controller + * + * @param handle ESP CAM controller handle + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_dvp_cam_stop(esp_cam_ctlr_handle_t handle) +{ + esp_err_t ret = ESP_ERR_INVALID_STATE; + esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)handle; + + ESP_RETURN_ON_FALSE(ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: handle is null"); + + portENTER_CRITICAL(&ctlr->spinlock); + if (ctlr->dvp_fsm == ESP_CAM_CTLR_DVP_CAM_FSM_STARTED) { + cam_hal_stop_streaming(&ctlr->hal); + esp_cam_ctlr_dvp_dma_stop(&ctlr->dma); + ctlr->dvp_fsm = ESP_CAM_CTLR_DVP_CAM_FSM_ENABLED; + ret = ESP_OK; + } + portEXIT_CRITICAL(&ctlr->spinlock); + + return ret; +} + +/** + * @brief Delete CAM DVP camera controller + * + * @param handle ESP CAM controller handle + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_dvp_cam_del(esp_cam_ctlr_handle_t handle) +{ + esp_err_t ret = ESP_ERR_INVALID_STATE; + esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)handle; + + ESP_RETURN_ON_FALSE(ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: handle is null"); + + if (ctlr->dvp_fsm == ESP_CAM_CTLR_DVP_CAM_FSM_INIT) { + esp_cam_ctlr_dvp_dma_stop(&ctlr->dma); + cam_hal_stop_streaming(&ctlr->hal); + + esp_cam_ctlr_dvp_dma_deinit(&ctlr->dma); + + if (!ctlr->pin_dont_init) { + esp_cam_ctlr_dvp_deinit(ctlr->ctlr_id); + } + + cam_hal_deinit(&ctlr->hal); + + if (!ctlr->bk_buffer_dis) { + heap_caps_free(ctlr->backup_buffer); + } + + s_dvp_declaim_ctlr(ctlr->ctlr_id); + + heap_caps_free(ctlr); + + dvp_shared_ctrl_declaim_io_signals(); + + ret = ESP_OK; + } + + return ret; +} + +/** + * @brief Register CAM DVP camera controller event callbacks + * + * @param handle ESP CAM controller handle + * @param cbs ESP CAM controller event callbacks + * @param user_data ESP CAM controller event user data + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_dvp_cam_register_event_callbacks(esp_cam_ctlr_handle_t handle, const esp_cam_ctlr_evt_cbs_t *cbs, void *user_data) +{ + esp_err_t ret = ESP_ERR_INVALID_STATE; + esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)handle; + + ESP_RETURN_ON_FALSE(handle && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument: handle or cbs is null"); + ESP_RETURN_ON_FALSE(cbs->on_trans_finished, ESP_ERR_INVALID_ARG, TAG, "invalid argument: on_trans_finished is null"); + ESP_RETURN_ON_FALSE(cbs->on_get_new_trans || !ctlr->bk_buffer_dis, ESP_ERR_INVALID_ARG, TAG, "invalid argument: on_get_new_trans is null"); + +#if CONFIG_CAM_CTLR_DVP_CAM_ISR_IRAM_SAFE + if (cbs->on_get_new_trans) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_get_new_trans), ESP_ERR_INVALID_ARG, TAG, "on_get_new_trans callback not in IRAM"); + } + if (cbs->on_trans_finished) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_trans_finished), ESP_ERR_INVALID_ARG, TAG, "on_trans_finished callback not in IRAM"); + } +#endif + + portENTER_CRITICAL(&ctlr->spinlock); + if (ctlr->dvp_fsm == ESP_CAM_CTLR_DVP_CAM_FSM_INIT) { + ctlr->cbs.on_get_new_trans = cbs->on_get_new_trans; + ctlr->cbs.on_trans_finished = cbs->on_trans_finished; + ctlr->cbs_user_data = user_data; + ret = ESP_OK; + } + portEXIT_CRITICAL(&ctlr->spinlock); + + return ret; +} + +/** + * @brief Get AM DVP camera controller backup buffer pointer + * + * @param handle ESP CAM controller handle + * @param fb_num Backup buffer pointer storage buffer number + * @param fb0 Backup buffer pointer storage buffer + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_dvp_cam_get_internal_buffer(esp_cam_ctlr_handle_t handle, uint32_t fb_num, const void **fb0, ...) +{ + esp_err_t ret = ESP_ERR_INVALID_STATE; + esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)handle; + + ESP_RETURN_ON_FALSE(ctlr->backup_buffer, ESP_ERR_INVALID_STATE, TAG, "back_buffer is not available"); + ESP_RETURN_ON_FALSE(fb_num && fb_num <= 1, ESP_ERR_INVALID_ARG, TAG, "invalid frame buffer number"); + + portENTER_CRITICAL(&ctlr->spinlock); + if (ctlr->dvp_fsm == ESP_CAM_CTLR_DVP_CAM_FSM_INIT) { + va_list args; + const void **fb_itor = fb0; + + va_start(args, fb0); + for (uint32_t i = 0; i < fb_num; i++) { + if (fb_itor) { + *fb_itor = ctlr->backup_buffer; + fb_itor = va_arg(args, const void **); + } + } + va_end(args); + + ctlr->bk_buffer_exposed = true; + ret = ESP_OK; + } + portEXIT_CRITICAL(&ctlr->spinlock); + + return ret; +} + +/** + * @brief Get CAM DVP camera controller frame buffer length + * + * @param handle ESP CAM controller handle + * @param ret_fb_len The size of each frame buffer in bytes + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static esp_err_t esp_cam_ctlr_get_dvp_cam_frame_buffer_len(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len) +{ + esp_err_t ret = ESP_ERR_INVALID_STATE; + esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)handle; + + ESP_RETURN_ON_FALSE(ctlr && ret_fb_len, ESP_ERR_INVALID_ARG, TAG, "invalid argument: handle or ret_fb_len is null"); + + portENTER_CRITICAL(&ctlr->spinlock); + if (ctlr->dvp_fsm == ESP_CAM_CTLR_DVP_CAM_FSM_INIT) { + *ret_fb_len = ctlr->fb_size_in_bytes; + ret = ESP_OK; + } + portEXIT_CRITICAL(&ctlr->spinlock); + + return ret; +} + +/** + * @brief New ESP CAM DVP controller + * + * @param config DVP controller configurations + * @param ret_handle Returned CAM controller handle + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG: Invalid argument + * - ESP_ERR_NO_MEM: Out of memory + * - ESP_ERR_NOT_SUPPORTED: Currently not support modes or types + * - ESP_ERR_NOT_FOUND: CSI is registered already + */ +esp_err_t esp_cam_new_dvp_ctlr(const esp_cam_ctlr_dvp_config_t *config, esp_cam_ctlr_handle_t *ret_handle) +{ + esp_err_t ret; + size_t fb_size_in_bytes; + size_t alignment_size; + + ESP_RETURN_ON_FALSE(config && ret_handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: config or ret_handle is null"); + ESP_RETURN_ON_FALSE(config->ctlr_id < CAP_DVP_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid argument: ctlr_id >= %d", CAP_DVP_PERIPH_NUM); + ESP_RETURN_ON_FALSE(config->pin_dont_init || config->pin, ESP_ERR_INVALID_ARG, TAG, "invalid argument: pin_dont_init is unset and pin is null"); + ESP_RETURN_ON_ERROR(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &alignment_size), TAG, "failed to get cache alignment"); + ESP_RETURN_ON_ERROR(esp_cam_ctlr_dvp_cam_get_frame_size(config, &fb_size_in_bytes), TAG, "invalid argument: input frame pixel format is not supported"); + ESP_RETURN_ON_ERROR(dvp_shared_ctrl_claim_io_signals(), TAG, "failed to claim io signals"); + + esp_cam_ctlr_dvp_cam_t *ctlr = heap_caps_calloc(1, sizeof(esp_cam_ctlr_dvp_cam_t), CAM_DVP_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(ctlr, ESP_ERR_NO_MEM, fail0, TAG, "no mem for CAM DVP controller context"); + + ESP_GOTO_ON_ERROR(s_dvp_claim_ctlr(config->ctlr_id, ctlr), fail1, TAG, "no available DVP controller"); + + ESP_LOGD(TAG, "alignment: 0x%x\n", alignment_size); + fb_size_in_bytes = ALIGN_UP_BY(fb_size_in_bytes, alignment_size); + if (!config->bk_buffer_dis) { + ctlr->backup_buffer = heap_caps_aligned_alloc(alignment_size, fb_size_in_bytes, MALLOC_CAP_SPIRAM); + ESP_GOTO_ON_FALSE(ctlr->backup_buffer, ESP_ERR_NO_MEM, fail2, TAG, "no mem for DVP backup buffer"); + } + + ESP_GOTO_ON_ERROR(esp_cam_ctlr_dvp_dma_init(&ctlr->dma, config->dma_burst_size, fb_size_in_bytes), + fail3, TAG, "failed to initialize DVP DMA"); + + gdma_rx_event_callbacks_t cbs = { + .on_recv_eof = esp_cam_ctlr_recv_frame_done_isr + }; + + ESP_GOTO_ON_ERROR(gdma_register_rx_event_callbacks(ctlr->dma.dma_chan, &cbs, ctlr), + fail4, TAG, "failed to register DMA event callbacks"); + + /* Initialize DVP controller */ + + cam_hal_config_t cam_hal_config = { + .port = config->ctlr_id, + .byte_swap_en = config->byte_swap_en, + }; + cam_hal_init(&ctlr->hal, &cam_hal_config); + + if (!config->pin_dont_init) { + ESP_GOTO_ON_ERROR(esp_cam_ctlr_dvp_init(config->ctlr_id, config->clk_src, config->pin), + fail5, TAG, "failed to initialize clock and GPIO"); + } + + ctlr->ctlr_id = config->ctlr_id; + ctlr->fb_size_in_bytes = fb_size_in_bytes; + ctlr->dvp_fsm = ESP_CAM_CTLR_DVP_CAM_FSM_INIT; + ctlr->input_data_color_type = config->input_data_color_type; + ctlr->pic_format_jpeg = config->pic_format_jpeg; + ctlr->bk_buffer_dis = config->bk_buffer_dis; + ctlr->pin_dont_init = config->pin_dont_init; + ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; + + ctlr->base.del = esp_cam_ctlr_dvp_cam_del; + ctlr->base.enable = esp_cam_ctlr_dvp_cam_enable; + ctlr->base.start = esp_cam_ctlr_dvp_cam_start; + ctlr->base.stop = esp_cam_ctlr_dvp_cam_stop; + ctlr->base.disable = esp_cam_ctlr_dvp_cam_disable; + ctlr->base.register_event_callbacks = esp_cam_ctlr_dvp_cam_register_event_callbacks; + ctlr->base.get_internal_buffer = esp_cam_ctlr_dvp_cam_get_internal_buffer; + ctlr->base.get_buffer_len = esp_cam_ctlr_get_dvp_cam_frame_buffer_len; + + *ret_handle = &ctlr->base; + + return ESP_OK; + +fail5: + cam_hal_deinit(&ctlr->hal); +fail4: + esp_cam_ctlr_dvp_dma_deinit(&ctlr->dma); +fail3: + if (!config->bk_buffer_dis) { + heap_caps_free(ctlr->backup_buffer); + } +fail2: + s_dvp_declaim_ctlr(config->ctlr_id); +fail1: + heap_caps_free(ctlr); +fail0: + dvp_shared_ctrl_declaim_io_signals(); + return ret; +} diff --git a/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_gdma.c b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_gdma.c new file mode 100644 index 000000000000..4e428b25052c --- /dev/null +++ b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_gdma.c @@ -0,0 +1,202 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_heap_caps.h" +#include "esp_check.h" +#include "esp_cache.h" +#include "esp_private/esp_cache_private.h" +#include "esp_cam_ctlr_dvp_dma.h" + +#define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) + +static const char *TAG = "dvp_gdma"; + +/** + * @brief Configure DMA description + * + * @param dma DVP DMA object pointer + * + * @return + * - ESP_OK on success + * - Others if failed + */ +static void IRAM_ATTR esp_cam_ctlr_dvp_config_dma_desc(esp_cam_ctlr_dvp_dma_desc_t *desc, uint8_t *buffer, uint32_t size) +{ + size_t n = 0; + + while (size) { + uint32_t node_size = MIN(size, ESP_CAM_CTLR_DVP_DMA_DESC_BUFFER_MAX_SIZE); + + desc[n].dw0.size = node_size; + desc[n].dw0.length = 0; + desc[n].dw0.err_eof = 0; + desc[n].dw0.suc_eof = 0; + desc[n].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + desc[n].buffer = (uint8_t *)buffer; + desc[n].next = &desc[n + 1]; + + size -= node_size; + buffer += node_size; + n++; + } + + desc[n - 1].next = NULL; +} + +/** + * @brief Initialize DVP DMA object + * + * @param dma DVP DMA object pointer + * @param burst_size DVP DMA burst transmission block size + * @param size DVP DMA buffer size + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_dma_init(esp_cam_ctlr_dvp_dma_t *dma, uint32_t burst_size, size_t size) +{ + esp_err_t ret = ESP_OK; + size_t alignment_size; + + gdma_channel_alloc_config_t rx_alloc_config = { + .direction = GDMA_CHANNEL_DIRECTION_RX, + }; + + ESP_RETURN_ON_ERROR(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &alignment_size), TAG, "failed to get cache alignment"); + + ESP_RETURN_ON_ERROR(gdma_new_axi_channel(&rx_alloc_config, &dma->dma_chan), TAG, "new channel failed"); + + ESP_GOTO_ON_ERROR(gdma_connect(dma->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_CAM, 0)), fail0, TAG, "connect failed"); + + gdma_strategy_config_t strategy_config = { + .auto_update_desc = false, + .owner_check = true + }; + + ESP_GOTO_ON_ERROR(gdma_apply_strategy(dma->dma_chan, &strategy_config), fail1, TAG, "apply strategy failed"); + // set DMA transfer ability + gdma_transfer_config_t transfer_config = { + .max_data_burst_size = burst_size, + .access_ext_mem = true, + }; + ESP_GOTO_ON_ERROR(gdma_config_transfer(dma->dma_chan, &transfer_config), fail1, TAG, "set trans ability failed"); + + dma->desc_count = size / ESP_CAM_CTLR_DVP_DMA_DESC_BUFFER_MAX_SIZE; + if (size % ESP_CAM_CTLR_DVP_DMA_DESC_BUFFER_MAX_SIZE) { + dma->desc_count++; + } + dma->size = size; + + ESP_LOGD(TAG, "alignment: 0x%x\n", alignment_size); + dma->desc_size = ALIGN_UP_BY(dma->desc_count * sizeof(esp_cam_ctlr_dvp_dma_desc_t), alignment_size); + + dma->desc = heap_caps_aligned_alloc(alignment_size, dma->desc_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + ESP_GOTO_ON_FALSE(dma->desc, ESP_ERR_NO_MEM, fail1, TAG, "no mem for DVP DMA descriptor"); + + return ESP_OK; + +fail1: + gdma_disconnect(dma->dma_chan); +fail0: + gdma_del_channel(dma->dma_chan); + return ret; +} + +/** + * @brief De-initialize DVP DMA object + * + * @param dma DVP DMA object pointer + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t esp_cam_ctlr_dvp_dma_deinit(esp_cam_ctlr_dvp_dma_t *dma) +{ + ESP_RETURN_ON_ERROR(gdma_disconnect(dma->dma_chan), TAG, "disconnect dma channel failed"); + ESP_RETURN_ON_ERROR(gdma_del_channel(dma->dma_chan), TAG, "delete dma channel failed"); + + heap_caps_free(dma->desc); + + return ESP_OK; +} + +/** + * @brief Set DVP DMA descriptor address and start engine + * + * @param dma DVP DMA object pointer + * @param buffer DVP DMA buffer pointer + * @param size DVP DMA buffer size + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t IRAM_ATTR esp_cam_ctlr_dvp_dma_start(esp_cam_ctlr_dvp_dma_t *dma, uint8_t *buffer, size_t size) +{ + esp_err_t ret; + + ESP_RETURN_ON_FALSE_ISR(dma, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE_ISR(dma->size >= size, ESP_ERR_INVALID_ARG, TAG, "input buffer size is out of range"); + + esp_cam_ctlr_dvp_config_dma_desc(dma->desc, buffer, size); + + ret = esp_cache_msync(dma->desc, dma->desc_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE); + assert(ret == ESP_OK); + + return gdma_start(dma->dma_chan, (intptr_t)dma->desc); +} + +/** + * @brief Stop DVP DMA engine + * + * @param dma DVP DMA object pointer + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t IRAM_ATTR esp_cam_ctlr_dvp_dma_stop(esp_cam_ctlr_dvp_dma_t *dma) +{ + return gdma_stop(dma->dma_chan); +} + +/** + * @brief Reset DVP DMA FIFO and internal finite state machine + * + * @param dma DVP DMA object pointer + * + * @return + * - ESP_OK on success + * - Others if failed + */ +esp_err_t IRAM_ATTR esp_cam_ctlr_dvp_dma_reset(esp_cam_ctlr_dvp_dma_t *dma) +{ + return gdma_reset(dma->dma_chan); +} + +/** + * @brief Get DMA received data size + * + * @param dma DVP DMA object pointer + * + * @return DMA received data size + */ +size_t IRAM_ATTR esp_cam_ctlr_dvp_dma_get_recv_size(esp_cam_ctlr_dvp_dma_t *dma) +{ + size_t recv_size = 0; + + for (int i = 0; i < dma->desc_count; i++) { + recv_size += dma->desc[i].dw0.length; + if (dma->desc[i].dw0.suc_eof) { + break; + } + } + + return recv_size; +} diff --git a/components/esp_driver_cam/dvp_share_ctrl.c b/components/esp_driver_cam/dvp_share_ctrl.c new file mode 100644 index 000000000000..60d080e6d407 --- /dev/null +++ b/components/esp_driver_cam/dvp_share_ctrl.c @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_err.h" +#include "freertos/FreeRTOS.h" + +bool dvp_signal_used; +static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED; + +esp_err_t dvp_shared_ctrl_claim_io_signals(void) +{ + esp_err_t ret = ESP_ERR_NOT_FOUND; + portENTER_CRITICAL(&s_spinlock); + if (!dvp_signal_used) { + dvp_signal_used = true; + ret = ESP_OK; + } + portEXIT_CRITICAL(&s_spinlock); + + return ret; +} + +esp_err_t dvp_shared_ctrl_declaim_io_signals(void) +{ + portENTER_CRITICAL(&s_spinlock); + dvp_signal_used = false; + portEXIT_CRITICAL(&s_spinlock); + + return ESP_OK; +} diff --git a/components/esp_driver_cam/dvp_share_ctrl.h b/components/esp_driver_cam/dvp_share_ctrl.h new file mode 100644 index 000000000000..3f321fc7eba5 --- /dev/null +++ b/components/esp_driver_cam/dvp_share_ctrl.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Claim DVP IO signal usage + */ +esp_err_t dvp_shared_ctrl_claim_io_signals(void); + +/** + * @brief Declaim DVP IO signal usage + */ +esp_err_t dvp_shared_ctrl_declaim_io_signals(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_cam/esp_cam_ctlr.c b/components/esp_driver_cam/esp_cam_ctlr.c index 51a1b3c3088e..a2a4e2e9d0d9 100644 --- a/components/esp_driver_cam/esp_cam_ctlr.c +++ b/components/esp_driver_cam/esp_cam_ctlr.c @@ -84,7 +84,7 @@ esp_err_t esp_cam_ctlr_get_frame_buffer_len(esp_cam_ctlr_handle_t handle, size_t return handle->get_buffer_len(handle, ret_fb_len); } -esp_err_t esp_cam_del_ctlr(esp_cam_ctlr_handle_t handle) +esp_err_t esp_cam_ctlr_del(esp_cam_ctlr_handle_t handle) { ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); ESP_RETURN_ON_FALSE(handle->del, ESP_ERR_NOT_SUPPORTED, TAG, "controller driver function not supported"); diff --git a/components/esp_driver_cam/include/esp_cam_ctlr.h b/components/esp_driver_cam/include/esp_cam_ctlr.h index 3c7cbe2ae175..6365ad6b7384 100644 --- a/components/esp_driver_cam/include/esp_cam_ctlr.h +++ b/components/esp_driver_cam/include/esp_cam_ctlr.h @@ -87,7 +87,7 @@ esp_err_t esp_cam_ctlr_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_ * - ESP_ERR_INVALID_ARG: Invalid argument * - ESP_ERR_INVALID_STATE: Invalid state */ -esp_err_t esp_cam_del_ctlr(esp_cam_ctlr_handle_t handle); +esp_err_t esp_cam_ctlr_del(esp_cam_ctlr_handle_t handle); /** * @brief Register ESP CAM controller event callbacks diff --git a/components/esp_driver_cam/include/esp_cam_ctlr_types.h b/components/esp_driver_cam/include/esp_cam_ctlr_types.h index c215d2199665..5dae1bc5db02 100644 --- a/components/esp_driver_cam/include/esp_cam_ctlr_types.h +++ b/components/esp_driver_cam/include/esp_cam_ctlr_types.h @@ -14,6 +14,11 @@ extern "C" { #endif +/** + * @brief ESP CAM controller max timeout value + */ +#define ESP_CAM_CTLR_MAX_DELAY UINT32_MAX + /** * @brief ESP CAM controller handle */ diff --git a/components/esp_driver_cam/isp_dvp/include/esp_cam_ctlr_isp_dvp.h b/components/esp_driver_cam/isp_dvp/include/esp_cam_ctlr_isp_dvp.h new file mode 100644 index 000000000000..a0cbbc9ca7dd --- /dev/null +++ b/components/esp_driver_cam/isp_dvp/include/esp_cam_ctlr_isp_dvp.h @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "esp_err.h" +#include "driver/isp_types.h" +#include "hal/cam_ctlr_types.h" +#include "esp_cam_ctlr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief ESP CAM ISP DVP controller configurations + */ +typedef struct { + cam_ctlr_data_width_t data_width; ///< Number of data lines + int data_io[ISP_DVP_DATA_SIG_NUM]; ///< ISP DVP data-in IO numbers + int pclk_io; ///< ISP DVP pclk IO numbers + int hsync_io; ///< ISP DVP hsync IO numbers + int vsync_io; ///< ISP DVP vsync IO numbers + int de_io; ///< ISP DVP de IO numbers + struct { + uint32_t pclk_invert: 1; ///< The pclk is inverted + uint32_t hsync_invert: 1; ///< The hsync signal is inverted + uint32_t vsync_invert: 1; ///< The vsync signal is inverted + uint32_t de_invert: 1; ///< The de signal is inverted + } io_flags; ///< ISP DVP IO flags + int queue_items; ///< Queue items + struct { + uint32_t byte_swap_en : 1; ///< Enable byte swap + uint32_t bk_buffer_dis : 1; ///< Disable backup buffer + }; +} esp_cam_ctlr_isp_dvp_cfg_t; + +/** + * @brief New ESP CAM ISP DVP controller + * + * @param[in] ctlr_config ISP DVP controller configurations + * @param[out] ret_handle Returned ESP CAM controller handle + * + * @return + * - ESP_OK + * - ESP_ERR_INVALID_ARG: Invalid argument + * - ESP_ERR_NO_MEM: Out of memory + * - ESP_ERR_NOT_SUPPORTED: Currently not support modes or types + * - ESP_ERR_NOT_FOUND: ISP DVP is registered already + */ +esp_err_t esp_cam_new_isp_dvp_ctlr(isp_proc_handle_t isp_proc, const esp_cam_ctlr_isp_dvp_cfg_t *ctlr_config, esp_cam_ctlr_handle_t *ret_handle); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_cam/isp_dvp/src/esp_cam_ctlr_isp_dvp.c b/components/esp_driver_cam/isp_dvp/src/esp_cam_ctlr_isp_dvp.c new file mode 100644 index 000000000000..10446d3749c2 --- /dev/null +++ b/components/esp_driver_cam/isp_dvp/src/esp_cam_ctlr_isp_dvp.c @@ -0,0 +1,568 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/idf_additions.h" +#include "driver/isp_types.h" +#include "driver/gpio.h" +#include "hal/isp_hal.h" +#include "hal/gpio_hal.h" +#include "hal/isp_ll.h" +#include "hal/mipi_csi_brg_ll.h" +#include "hal/mipi_csi_ll.h" +#include "hal/color_hal.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/isp_private.h" +#include "esp_private/esp_cache_private.h" +#include "esp_private/mipi_csi_share_hw_ctrl.h" +#include "esp_private/dw_gdma.h" +#include "esp_cam_ctlr_types.h" +#include "esp_cam_ctlr_interface.h" +#include "esp_cache.h" +#include "esp_cam_ctlr_isp_dvp.h" +#include "../../dvp_share_ctrl.h" + +#if CONFIG_CAM_CTLR_ISP_DVP_ISR_IRAM_SAFE +#define ISP_DVP_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#else +#define ISP_DVP_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT +#endif + +typedef struct isp_dvp_controller_t { + int id; //dvp id + isp_fsm_t fsm; //finite state machine + portMUX_TYPE spinlock; //spinlock + isp_processor_t *isp_proc; //isp processor + int in_bpp; //input data type, bit per pixel + int out_bpp; //output data type, bit per pixel + size_t fb_size_in_bytes; //Frame buffer size, in bytes + esp_cam_ctlr_trans_t trans; //Saved done transaction to be given out to callers + void *backup_buffer; //backup buffer to make csi bridge can work to avoid wrong state + bool bk_buffer_exposed; //status of if back_buffer is exposed to users + bool bk_buffer_dis; //allow to not malloc backup_buffer + QueueHandle_t trans_que; //transaction queue + esp_cam_ctlr_evt_cbs_t cbs; //user callbacks + void *cbs_user_data; //callback userdata + dw_gdma_channel_handle_t dma_chan; //dwgdma channel handle + size_t dvp_transfer_size; //csi transfer size for dwgdma + bool isr_installed; //is isr installed + esp_cam_ctlr_t base; +} isp_dvp_controller_t; + +typedef struct isp_dvp_ctx_t { + _lock_t mutex; + isp_dvp_controller_t *dvp_ctlr[SOC_ISP_DVP_CTLR_NUMS]; +} isp_dvp_ctx_t; + +static const char *TAG = "ISP_DVP"; +static isp_dvp_ctx_t s_ctx; + +static esp_err_t s_isp_io_init(isp_dvp_controller_t *dvp_ctlr, const esp_cam_ctlr_isp_dvp_cfg_t *ctlr_config); +static esp_err_t s_isp_claim_dvp_controller(isp_proc_handle_t isp_proc, isp_dvp_controller_t *dvp_ctlr); +static esp_err_t s_isp_declaim_dvp_controller(isp_dvp_controller_t *dvp_ctlr); +static esp_err_t s_isp_del_dvp_controller(esp_cam_ctlr_handle_t handle); +static esp_err_t s_isp_dvp_get_frame_buffer(esp_cam_ctlr_handle_t handle, uint32_t fb_num, const void **fb0, ...); +static esp_err_t s_isp_dvp_get_frame_buffer_length(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len); +static esp_err_t s_isp_dvp_register_event_callbacks(esp_cam_ctlr_handle_t handle, const esp_cam_ctlr_evt_cbs_t *cbs, void *user_data); +static esp_err_t s_isp_dvp_enable(esp_cam_ctlr_handle_t handle); +static esp_err_t s_isp_dvp_disable(esp_cam_ctlr_handle_t handle); +static esp_err_t s_isp_dvp_start(esp_cam_ctlr_handle_t handle); +static esp_err_t s_isp_dvp_stop(esp_cam_ctlr_handle_t handle); +static esp_err_t s_isp_dvp_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms); +static bool s_dvp_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data); + +esp_err_t esp_cam_new_isp_dvp_ctlr(isp_proc_handle_t isp_proc, const esp_cam_ctlr_isp_dvp_cfg_t *ctlr_config, esp_cam_ctlr_handle_t *ret_handle) +{ + esp_err_t ret = ESP_FAIL; + ESP_RETURN_ON_FALSE(isp_proc && ctlr_config && ret_handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + + isp_dvp_controller_t *dvp_ctlr = heap_caps_calloc(1, sizeof(isp_dvp_controller_t), ISP_DVP_MEM_ALLOC_CAPS); + ESP_RETURN_ON_FALSE(dvp_ctlr, ESP_ERR_NO_MEM, TAG, "no mem for isp dvp controller"); + + dvp_ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; + dvp_ctlr->isp_proc = isp_proc; + +#if SOC_ISP_SHARE_CSI_BRG + ESP_GOTO_ON_ERROR(mipi_csi_brg_claim(MIPI_CSI_BRG_USER_ISP_DVP, &isp_proc->csi_brg_id), err, TAG, "csi bridge is in use already"); +#endif + //claim an DVP controller + ESP_GOTO_ON_ERROR(s_isp_claim_dvp_controller(isp_proc, dvp_ctlr), err, TAG, "no available controller"); + ESP_GOTO_ON_ERROR(dvp_shared_ctrl_claim_io_signals(), err, TAG, "failed to claim io signals"); + ESP_GOTO_ON_ERROR(s_isp_io_init(dvp_ctlr, ctlr_config), err, TAG, "io init fail"); + + dvp_ctlr->trans_que = xQueueCreateWithCaps(ctlr_config->queue_items, sizeof(esp_cam_ctlr_trans_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + ESP_GOTO_ON_FALSE(dvp_ctlr->trans_que, ESP_ERR_NO_MEM, err, TAG, "no memory for transaction queue"); + //in color type + int in_bits_per_pixel = color_hal_pixel_format_get_bit_depth(isp_proc->in_color_format); + dvp_ctlr->in_bpp = in_bits_per_pixel; + ESP_LOGD(TAG, "dvp_ctlr->in_bpp: 0d %d", dvp_ctlr->in_bpp); + + //out color type + int out_bits_per_pixel = color_hal_pixel_format_get_bit_depth(isp_proc->out_color_format); + dvp_ctlr->out_bpp = out_bits_per_pixel; + ESP_LOGD(TAG, "dvp_ctlr->out_bpp: 0d %d", dvp_ctlr->out_bpp); + + // Note: Width * Height * BitsPerPixel must be divisible by 8 + int fb_size_in_bits = isp_proc->v_res * isp_proc->h_res * out_bits_per_pixel; + ESP_GOTO_ON_FALSE((fb_size_in_bits % 8 == 0), ESP_ERR_INVALID_ARG, err, TAG, "framesize not 8bit aligned"); + dvp_ctlr->fb_size_in_bytes = fb_size_in_bits / 8; + ESP_LOGD(TAG, "dvp_ctlr->fb_size_in_bytes=%d", dvp_ctlr->fb_size_in_bytes); + + dvp_ctlr->bk_buffer_dis = ctlr_config->bk_buffer_dis; + if (!dvp_ctlr->bk_buffer_dis) { + size_t dma_alignment = 4; + size_t cache_alignment = 1; + ESP_GOTO_ON_ERROR(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &cache_alignment), err, TAG, "failed to get cache alignment"); + size_t alignment = MAX(cache_alignment, dma_alignment); + ESP_LOGD(TAG, "alignment: 0x%x\n", alignment); + + dvp_ctlr->backup_buffer = heap_caps_aligned_alloc(alignment, dvp_ctlr->fb_size_in_bytes, MALLOC_CAP_SPIRAM); + ESP_GOTO_ON_FALSE(dvp_ctlr->backup_buffer, ESP_ERR_NO_MEM, err, TAG, "no mem for backup buffer"); + ESP_LOGD(TAG, "dvp_ctlr->backup_buffer: %p\n", dvp_ctlr->backup_buffer); + esp_cache_msync((void *)(dvp_ctlr->backup_buffer), dvp_ctlr->fb_size_in_bytes, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + } + + bool valid_format = isp_ll_dvp_set_data_type(isp_proc->hal.hw, isp_proc->in_color_format); + ESP_GOTO_ON_FALSE(valid_format, ESP_ERR_INVALID_ARG, err, TAG, "invalid dvp color space config"); + if (ctlr_config->io_flags.pclk_invert) { + isp_ll_cam_enable_pclk_invert(isp_proc->hal.hw, true); + } + if (ctlr_config->io_flags.hsync_invert) { + isp_ll_cam_enable_hsync_invert(isp_proc->hal.hw, true); + } + if (ctlr_config->io_flags.vsync_invert) { + isp_ll_cam_enable_vsync_invert(isp_proc->hal.hw, true); + } + if (ctlr_config->io_flags.de_invert) { + isp_ll_cam_enable_de_invert(isp_proc->hal.hw, true); + } + isp_ll_dvp_cam_reset(isp_proc->hal.hw); + + // configure DW_GDMA for ISP DVP + dw_gdma_channel_alloc_config_t dvp_dma_alloc_config = { + .src = { + .block_transfer_type = DW_GDMA_BLOCK_TRANSFER_CONTIGUOUS, +#if SOC_ISP_SHARE_CSI_BRG + .role = DW_GDMA_ROLE_PERIPH_CSI, //CSI bridge +#endif + .handshake_type = DW_GDMA_HANDSHAKE_HW, + .num_outstanding_requests = 5, + .status_fetch_addr = MIPI_CSI_BRG_MEM_BASE, + }, + .dst = { + .block_transfer_type = DW_GDMA_BLOCK_TRANSFER_CONTIGUOUS, + .role = DW_GDMA_ROLE_MEM, + .handshake_type = DW_GDMA_HANDSHAKE_HW, + .num_outstanding_requests = 5, + }, + .flow_controller = DW_GDMA_FLOW_CTRL_SRC, + .chan_priority = 1, + }; + ESP_ERROR_CHECK(dw_gdma_new_channel(&dvp_dma_alloc_config, &dvp_ctlr->dma_chan)); + + size_t dvp_transfer_size = isp_proc->h_res * isp_proc->v_res * dvp_ctlr->in_bpp / 64; + dvp_ctlr->dvp_transfer_size = dvp_transfer_size; + ESP_LOGD(TAG, "dvp_transfer_size: 0d %d", dvp_transfer_size); + + dvp_ctlr->fsm = ISP_FSM_INIT; + isp_proc->csi_brg_hw = MIPI_CSI_BRG_LL_GET_HW(isp_proc->csi_brg_id); + mipi_csi_brg_ll_set_intput_data_h_pixel_num(isp_proc->csi_brg_hw, isp_proc->h_res); + mipi_csi_brg_ll_set_intput_data_v_row_num(isp_proc->csi_brg_hw, isp_proc->v_res); + mipi_csi_brg_ll_set_burst_len(isp_proc->csi_brg_hw, 512); + + esp_cam_ctlr_t *cam_ctlr = &(dvp_ctlr->base); + cam_ctlr->del = s_isp_del_dvp_controller; + cam_ctlr->enable = s_isp_dvp_enable; + cam_ctlr->start = s_isp_dvp_start; + cam_ctlr->stop = s_isp_dvp_stop; + cam_ctlr->disable = s_isp_dvp_disable; + cam_ctlr->receive = s_isp_dvp_receive; + cam_ctlr->register_event_callbacks = s_isp_dvp_register_event_callbacks; + cam_ctlr->get_internal_buffer = s_isp_dvp_get_frame_buffer; + cam_ctlr->get_buffer_len = s_isp_dvp_get_frame_buffer_length; + *ret_handle = cam_ctlr; + + return ESP_OK; + +err: + if (dvp_ctlr) { + s_isp_del_dvp_controller(&(dvp_ctlr->base)); + } + + return ret; +} + +esp_err_t s_isp_del_dvp_controller(esp_cam_ctlr_handle_t handle) +{ + ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base); + + ESP_RETURN_ON_FALSE(dvp_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state"); + if (dvp_ctlr->dma_chan) { + ESP_RETURN_ON_ERROR(dw_gdma_del_channel(dvp_ctlr->dma_chan), TAG, "failed to delete dwgdma channel"); + } +#if SOC_ISP_SHARE_CSI_BRG + ESP_RETURN_ON_ERROR(mipi_csi_brg_declaim(dvp_ctlr->isp_proc->csi_brg_id), TAG, "declaim csi bridge fail"); +#endif + ESP_RETURN_ON_ERROR(s_isp_declaim_dvp_controller(dvp_ctlr), TAG, "controller isn't in use"); + ESP_RETURN_ON_ERROR(dvp_shared_ctrl_declaim_io_signals(), TAG, "failed to declaim io signals"); + if (!dvp_ctlr->bk_buffer_dis) { + free(dvp_ctlr->backup_buffer); + } + if (dvp_ctlr->trans_que) { + vQueueDeleteWithCaps(dvp_ctlr->trans_que); + } + free(dvp_ctlr); + + return ESP_OK; +} + +static esp_err_t s_isp_dvp_get_frame_buffer(esp_cam_ctlr_handle_t handle, uint32_t fb_num, const void **fb0, ...) +{ + isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base); + ESP_RETURN_ON_FALSE((dvp_ctlr->fsm >= ISP_FSM_INIT) && (dvp_ctlr->backup_buffer), ESP_ERR_INVALID_STATE, TAG, "driver isn't initialized or back_buffer isn't available"); + ESP_RETURN_ON_FALSE(fb_num && fb_num <= 1, ESP_ERR_INVALID_ARG, TAG, "invalid frame buffer number"); + + dvp_ctlr->bk_buffer_exposed = true; + const void **fb_itor = fb0; + va_list args; + va_start(args, fb0); + for (uint32_t i = 0; i < fb_num; i++) { + if (fb_itor) { + *fb_itor = dvp_ctlr->backup_buffer; + fb_itor = va_arg(args, const void **); + } + } + va_end(args); + + return ESP_OK; +} + +static esp_err_t s_isp_dvp_get_frame_buffer_length(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len) +{ + isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base); + ESP_RETURN_ON_FALSE((dvp_ctlr->fsm >= ISP_FSM_INIT) && (dvp_ctlr->backup_buffer), ESP_ERR_INVALID_STATE, TAG, "driver isn't initialized or back_buffer isn't available"); + + *ret_fb_len = dvp_ctlr->fb_size_in_bytes; + return ESP_OK; +} + +static esp_err_t s_isp_dvp_register_event_callbacks(esp_cam_ctlr_handle_t handle, const esp_cam_ctlr_evt_cbs_t *cbs, void *user_data) +{ + ESP_RETURN_ON_FALSE(handle && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base); + ESP_RETURN_ON_FALSE(dvp_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state"); + +#if CONFIG_CAM_CTLR_MIPI_CSI_ISR_IRAM_SAFE + if (cbs->on_get_new_trans) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_get_new_trans), ESP_ERR_INVALID_ARG, TAG, "on_get_new_trans callback not in IRAM"); + } + if (cbs->on_trans_finished) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_trans_finished), ESP_ERR_INVALID_ARG, TAG, "on_trans_finished callback not in IRAM"); + } +#endif + + if (!dvp_ctlr->isr_installed) { + dw_gdma_event_callbacks_t csi_dma_cbs = { + .on_full_trans_done = s_dvp_dma_trans_done_callback, + }; + ESP_RETURN_ON_ERROR(dw_gdma_channel_register_event_callbacks(dvp_ctlr->dma_chan, &csi_dma_cbs, dvp_ctlr), TAG, "failed to register dma callbacks"); + dvp_ctlr->isr_installed = true; + } + + dvp_ctlr->cbs.on_get_new_trans = cbs->on_get_new_trans; + dvp_ctlr->cbs.on_trans_finished = cbs->on_trans_finished; + dvp_ctlr->cbs_user_data = user_data; + + return ESP_OK; +} + +static esp_err_t s_isp_dvp_enable(esp_cam_ctlr_handle_t handle) +{ + ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base); + ESP_RETURN_ON_FALSE(dvp_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state"); + + portENTER_CRITICAL(&dvp_ctlr->spinlock); + dvp_ctlr->fsm = ISP_FSM_ENABLE; + portEXIT_CRITICAL(&dvp_ctlr->spinlock); + + return ESP_OK; +} + +static esp_err_t s_isp_dvp_disable(esp_cam_ctlr_handle_t handle) +{ + ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base); + ESP_RETURN_ON_FALSE(dvp_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "controller isn't in enable state"); + + portENTER_CRITICAL(&dvp_ctlr->spinlock); + dvp_ctlr->fsm = ISP_FSM_INIT; + portEXIT_CRITICAL(&dvp_ctlr->spinlock); + + return ESP_OK; +} + +static esp_err_t s_isp_dvp_start(esp_cam_ctlr_handle_t handle) +{ + ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base); + ESP_RETURN_ON_FALSE(dvp_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "controller isn't in enable state"); + ESP_RETURN_ON_FALSE(dvp_ctlr->isp_proc->isp_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "ISP processor isn't in enable state"); + ESP_RETURN_ON_FALSE(dvp_ctlr->cbs.on_trans_finished, ESP_ERR_INVALID_STATE, TAG, "no on_trans_finished callback registered"); + + mipi_csi_brg_ll_enable(dvp_ctlr->isp_proc->csi_brg_hw, true); + isp_ll_cam_enable(dvp_ctlr->isp_proc->hal.hw, true); + + esp_cam_ctlr_trans_t trans = {}; + bool has_new_trans = false; + + if (dvp_ctlr->cbs.on_get_new_trans) { + dvp_ctlr->cbs.on_get_new_trans(handle, &trans, dvp_ctlr->cbs_user_data); + if (trans.buffer) { + has_new_trans = true; + } + } + + if (!has_new_trans) { + if (!dvp_ctlr->bk_buffer_dis) { + trans.buffer = dvp_ctlr->backup_buffer; + trans.buflen = dvp_ctlr->fb_size_in_bytes; + } else { + ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "no ready transaction, and no backup buffer"); + } + } + + ESP_LOGD(TAG, "trans.buffer: %p, trans.buflen: %d", trans.buffer, trans.buflen); + dvp_ctlr->trans = trans; + + portENTER_CRITICAL(&dvp_ctlr->spinlock); + dvp_ctlr->fsm = ISP_FSM_START; + portEXIT_CRITICAL(&dvp_ctlr->spinlock); + + dw_gdma_block_transfer_config_t dvp_dma_transfer_config = {}; + dvp_dma_transfer_config = (dw_gdma_block_transfer_config_t) { + .src = { + .addr = MIPI_CSI_BRG_MEM_BASE, + .burst_mode = DW_GDMA_BURST_MODE_FIXED, + .burst_items = DW_GDMA_BURST_ITEMS_512, + .burst_len = 16, + .width = DW_GDMA_TRANS_WIDTH_64, + }, + .dst = { + .addr = (uint32_t)(trans.buffer), + .burst_mode = DW_GDMA_BURST_MODE_INCREMENT, + .burst_items = DW_GDMA_BURST_ITEMS_512, + .burst_len = 16, + .width = DW_GDMA_TRANS_WIDTH_64, + }, + .size = dvp_ctlr->dvp_transfer_size, + }; + ESP_RETURN_ON_ERROR(dw_gdma_channel_config_transfer(dvp_ctlr->dma_chan, &dvp_dma_transfer_config), TAG, "failed to configure dwgdma transfer"); + ESP_RETURN_ON_ERROR(dw_gdma_channel_enable_ctrl(dvp_ctlr->dma_chan, true), TAG, "failed to enable dwgdma"); + + return ESP_OK; +} + +static esp_err_t s_isp_dvp_stop(esp_cam_ctlr_handle_t handle) +{ + ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base); + ESP_RETURN_ON_FALSE(dvp_ctlr->fsm == ISP_FSM_START, ESP_ERR_INVALID_STATE, TAG, "driver isn't started"); + + isp_ll_cam_enable(dvp_ctlr->isp_proc->hal.hw, false); + mipi_csi_brg_ll_enable(dvp_ctlr->isp_proc->csi_brg_hw, false); + ESP_RETURN_ON_ERROR(dw_gdma_channel_enable_ctrl(dvp_ctlr->dma_chan, false), TAG, "failed to disable dwgdma"); + + portENTER_CRITICAL(&dvp_ctlr->spinlock); + dvp_ctlr->fsm = ISP_FSM_INIT; + portEXIT_CRITICAL(&dvp_ctlr->spinlock); + + return ESP_OK; +} + +static esp_err_t s_isp_dvp_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms) +{ + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + isp_dvp_controller_t *dvp_ctlr = __containerof(handle, isp_dvp_controller_t, base); + + ESP_RETURN_ON_FALSE(trans->buffer, ESP_ERR_INVALID_ARG, TAG, "invalid argument: no trans buffer"); + ESP_RETURN_ON_FALSE((trans->buflen >= dvp_ctlr->fb_size_in_bytes), ESP_ERR_INVALID_ARG, TAG, "invalid argument: trans buffer smaller than framebuffer size"); + + TickType_t ticks_to_wait = timeout_ms / portTICK_PERIOD_MS; + if (timeout_ms == ESP_CAM_CTLR_MAX_DELAY) { + ticks_to_wait = portMAX_DELAY; + } + + BaseType_t r = xQueueSend(dvp_ctlr->trans_que, trans, ticks_to_wait); + if (r != pdTRUE) { + ret = ESP_ERR_TIMEOUT; + ESP_LOGW(TAG, "csi recv API, transaction queue is full, failed to send transaction to the queue"); + return ret; + } + + return ESP_OK; +} + +IRAM_ATTR static bool s_dvp_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data) +{ + bool need_yield = false; + BaseType_t high_task_woken = pdFALSE; + isp_dvp_controller_t *dvp_ctlr = (isp_dvp_controller_t *)user_data; + bool has_new_trans = false; + + dw_gdma_block_transfer_config_t dvp_dma_transfer_config = {}; + dvp_dma_transfer_config = (dw_gdma_block_transfer_config_t) { + .src = { + .addr = MIPI_CSI_BRG_MEM_BASE, + .burst_mode = DW_GDMA_BURST_MODE_FIXED, + .burst_items = DW_GDMA_BURST_ITEMS_512, + .burst_len = 16, + .width = DW_GDMA_TRANS_WIDTH_64, + }, + .dst = { + .addr = 0, + .burst_mode = DW_GDMA_BURST_MODE_INCREMENT, + .burst_items = DW_GDMA_BURST_ITEMS_512, + .burst_len = 16, + .width = DW_GDMA_TRANS_WIDTH_64, + }, + .size = dvp_ctlr->dvp_transfer_size, + }; + esp_cam_ctlr_trans_t new_trans = {}; + + if (dvp_ctlr->cbs.on_get_new_trans) { + need_yield = dvp_ctlr->cbs.on_get_new_trans(&(dvp_ctlr->base), &new_trans, dvp_ctlr->cbs_user_data); + if (new_trans.buffer && new_trans.buflen >= dvp_ctlr->fb_size_in_bytes) { + dvp_dma_transfer_config.dst.addr = (uint32_t)(new_trans.buffer); + has_new_trans = true; + } + } else if (xQueueReceiveFromISR(dvp_ctlr->trans_que, &new_trans, &high_task_woken) == pdTRUE) { + if (new_trans.buffer && new_trans.buflen >= dvp_ctlr->fb_size_in_bytes) { + dvp_dma_transfer_config.dst.addr = (uint32_t)(new_trans.buffer); + has_new_trans = true; + } + } + + if (!has_new_trans) { + if (!dvp_ctlr->bk_buffer_dis) { + new_trans.buffer = dvp_ctlr->backup_buffer; + new_trans.buflen = dvp_ctlr->fb_size_in_bytes; + ESP_EARLY_LOGD(TAG, "no new buffer or no long enough new buffer, use driver internal buffer"); + dvp_dma_transfer_config.dst.addr = (uint32_t)dvp_ctlr->backup_buffer; + } else { + assert(false && "no new buffer, and no driver internal buffer"); + } + } + + ESP_EARLY_LOGD(TAG, "new_trans.buffer: %p, new_trans.buflen: %d", new_trans.buffer, new_trans.buflen); + dw_gdma_channel_config_transfer(chan, &dvp_dma_transfer_config); + dw_gdma_channel_enable_ctrl(chan, true); + + if ((dvp_ctlr->trans.buffer != dvp_ctlr->backup_buffer) || dvp_ctlr->bk_buffer_exposed) { + esp_err_t ret = esp_cache_msync((void *)(dvp_ctlr->trans.buffer), dvp_ctlr->trans.received_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(ret == ESP_OK); + assert(dvp_ctlr->cbs.on_trans_finished); + if (dvp_ctlr->cbs.on_trans_finished) { + dvp_ctlr->trans.received_size = dvp_ctlr->fb_size_in_bytes; + need_yield |= dvp_ctlr->cbs.on_trans_finished(&(dvp_ctlr->base), &dvp_ctlr->trans, dvp_ctlr->cbs_user_data); + } + } + + //dvp_ctlr->trans is the transaction saved before dma starts + memset(&dvp_ctlr->trans, 0x0, sizeof(esp_cam_ctlr_trans_t)); + dvp_ctlr->trans = new_trans; + + need_yield |= high_task_woken == pdTRUE; + return need_yield; +} + +static esp_err_t s_isp_io_init(isp_dvp_controller_t *dvp_ctlr, const esp_cam_ctlr_isp_dvp_cfg_t *ctlr_config) +{ + gpio_config_t gpio_conf = { + .intr_type = GPIO_INTR_DISABLE, + .mode = GPIO_MODE_INPUT, + .pull_down_en = false, + .pull_up_en = true, + }; + + if (ctlr_config->pclk_io) { + gpio_conf.pin_bit_mask = 1ULL << ctlr_config->pclk_io; + ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "failed to configure pclk gpio"); + ESP_LOGD(TAG, "pclk_io: %d, dvp_pclk_sig: %"PRId32, ctlr_config->pclk_io, isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_pclk_sig); + esp_rom_gpio_connect_in_signal(ctlr_config->pclk_io, isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_pclk_sig, false); + } + + if (ctlr_config->hsync_io) { + gpio_conf.pin_bit_mask = 1ULL << ctlr_config->hsync_io; + ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "failed to configure hsync gpio"); + ESP_LOGD(TAG, "hsync_io: %d, dvp_hsync_sig: %"PRId32, ctlr_config->hsync_io, isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_hsync_sig); + esp_rom_gpio_connect_in_signal(ctlr_config->hsync_io, isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_hsync_sig, false); + } + + if (ctlr_config->vsync_io) { + gpio_conf.pin_bit_mask = 1ULL << ctlr_config->vsync_io; + ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "failed to configure vsync gpio"); + ESP_LOGD(TAG, "vsync_io: %d, dvp_vsync_sig: %"PRId32, ctlr_config->vsync_io, isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_vsync_sig); + esp_rom_gpio_connect_in_signal(ctlr_config->vsync_io, isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_vsync_sig, false); + } + + if (ctlr_config->de_io) { + gpio_conf.pin_bit_mask = 1ULL << ctlr_config->de_io; + ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "failed to configure de gpio"); + ESP_LOGD(TAG, "de_io: %d, dvp_de_sig: %"PRId32, ctlr_config->de_io, isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_de_sig); + esp_rom_gpio_connect_in_signal(ctlr_config->de_io, isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_de_sig, false); + } + + for (size_t i = 0; i < ctlr_config->data_width; i++) { + gpio_conf.pin_bit_mask = 1ULL << ctlr_config->data_io[i]; + ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "failed to configure data gpio"); + ESP_LOGD(TAG, "data_io: %d, dvp_data_sig: %"PRId32, ctlr_config->data_io[i], isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_data_sig[i]); + esp_rom_gpio_connect_in_signal(ctlr_config->data_io[i], isp_hw_info.dvp_ctlr[dvp_ctlr->id].dvp_data_sig[i], false); + } + + return ESP_OK; +} + +static esp_err_t s_isp_claim_dvp_controller(isp_proc_handle_t isp_proc, isp_dvp_controller_t *dvp_ctlr) +{ + assert(isp_proc && dvp_ctlr); + + _lock_acquire(&s_ctx.mutex); + bool found = false; + for (int i = 0; i < SOC_ISP_DVP_CTLR_NUMS; i++) { + found = !s_ctx.dvp_ctlr[i]; + if (found) { + s_ctx.dvp_ctlr[i] = dvp_ctlr; + dvp_ctlr->id = i; + + break; + } + } + _lock_release(&s_ctx.mutex); + + if (!found) { + return ESP_ERR_NOT_FOUND; + } + return ESP_OK; +} + +static esp_err_t s_isp_declaim_dvp_controller(isp_dvp_controller_t *dvp_ctlr) +{ + assert(dvp_ctlr); + + _lock_acquire(&s_ctx.mutex); + s_ctx.dvp_ctlr[dvp_ctlr->id] = NULL; + _lock_release(&s_ctx.mutex); + + return ESP_OK; +} diff --git a/components/esp_driver_cam/test_apps/.build-test-rules.yml b/components/esp_driver_cam/test_apps/.build-test-rules.yml index 025201a69d13..0d419e7609c7 100644 --- a/components/esp_driver_cam/test_apps/.build-test-rules.yml +++ b/components/esp_driver_cam/test_apps/.build-test-rules.yml @@ -3,3 +3,15 @@ components/esp_driver_cam/test_apps/csi: - if: SOC_MIPI_CSI_SUPPORTED != 1 depends_components: - esp_driver_cam + +components/esp_driver_cam/test_apps/dvp: + disable: + - if: SOC_LCDCAM_CAM_SUPPORTED != 1 + depends_components: + - esp_driver_cam + +components/esp_driver_cam/test_apps/isp_dvp: + disable: + - if: SOC_ISP_DVP_SUPPORTED != 1 + depends_components: + - esp_driver_cam diff --git a/components/esp_driver_cam/test_apps/csi/main/test_csi_driver.c b/components/esp_driver_cam/test_apps/csi/main/test_csi_driver.c index e7b42583ce3e..28a995d1b1f1 100644 --- a/components/esp_driver_cam/test_apps/csi/main/test_csi_driver.c +++ b/components/esp_driver_cam/test_apps/csi/main/test_csi_driver.c @@ -16,8 +16,8 @@ TEST_CASE("TEST CSI driver allocation", "[csi]") .h_res = 800, .v_res = 640, .lane_bit_rate_mbps = 200, - .input_data_color_type = MIPI_CSI_COLOR_RAW8, - .output_data_color_type = MIPI_CSI_COLOR_RGB565, + .input_data_color_type = CAM_CTLR_COLOR_RAW8, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .data_lane_num = 2, .byte_swap_en = false, .queue_items = 1, @@ -32,7 +32,7 @@ TEST_CASE("TEST CSI driver allocation", "[csi]") TEST_ESP_OK(esp_cam_ctlr_get_frame_buffer_len(handle, &bk_buffer_len)); TEST_ASSERT_NOT_NULL(bk_buffer); TEST_ASSERT_EQUAL((csi_config.h_res * csi_config.v_res * 2), bk_buffer_len); // out type RGB565 using 2 byte / pixel - TEST_ESP_OK(esp_cam_del_ctlr(handle)); + TEST_ESP_OK(esp_cam_ctlr_del(handle)); } TEST_CASE("TEST CSI driver no backup buffer usage", "[csi]") @@ -42,8 +42,8 @@ TEST_CASE("TEST CSI driver no backup buffer usage", "[csi]") .h_res = 800, .v_res = 640, .lane_bit_rate_mbps = 200, - .input_data_color_type = MIPI_CSI_COLOR_RAW8, - .output_data_color_type = MIPI_CSI_COLOR_RGB565, + .input_data_color_type = CAM_CTLR_COLOR_RAW8, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .data_lane_num = 2, .byte_swap_en = false, .queue_items = 1, @@ -59,5 +59,5 @@ TEST_CASE("TEST CSI driver no backup buffer usage", "[csi]") TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_cam_ctlr_get_frame_buffer_len(handle, &bk_buffer_len)); TEST_ASSERT_NULL(bk_buffer); TEST_ASSERT_EQUAL(0, bk_buffer_len); - TEST_ESP_OK(esp_cam_del_ctlr(handle)); + TEST_ESP_OK(esp_cam_ctlr_del(handle)); } diff --git a/components/esp_driver_cam/test_apps/dvp/CMakeLists.txt b/components/esp_driver_cam/test_apps/dvp/CMakeLists.txt new file mode 100644 index 000000000000..d49275de9109 --- /dev/null +++ b/components/esp_driver_cam/test_apps/dvp/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) + +list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components") + +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(test_dvp) diff --git a/components/esp_driver_cam/test_apps/dvp/README.md b/components/esp_driver_cam/test_apps/dvp/README.md new file mode 100644 index 000000000000..909282018f26 --- /dev/null +++ b/components/esp_driver_cam/test_apps/dvp/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | diff --git a/components/esp_driver_cam/test_apps/dvp/main/CMakeLists.txt b/components/esp_driver_cam/test_apps/dvp/main/CMakeLists.txt new file mode 100644 index 000000000000..3ad81cd956b7 --- /dev/null +++ b/components/esp_driver_cam/test_apps/dvp/main/CMakeLists.txt @@ -0,0 +1,16 @@ +set(srcs "test_app_main.c") + +if(CONFIG_SOC_LCDCAM_CAM_SUPPORTED) + list(APPEND srcs "test_dvp_driver.c") +endif() + +set(priv_requires + unity + esp_driver_cam + esp_psram +) + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS "." + PRIV_REQUIRES ${priv_requires} + WHOLE_ARCHIVE TRUE) diff --git a/components/esp_driver_cam/test_apps/dvp/main/test_app_main.c b/components/esp_driver_cam/test_apps/dvp/main/test_app_main.c new file mode 100644 index 000000000000..a47ab1a130d3 --- /dev/null +++ b/components/esp_driver_cam/test_apps/dvp/main/test_app_main.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "unity.h" +#include "unity_test_utils.h" +#include "esp_heap_caps.h" +#include "sdkconfig.h" + +#define TEST_MEMORY_LEAK_THRESHOLD (400) + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); +} + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/esp_driver_cam/test_apps/dvp/main/test_dvp_driver.c b/components/esp_driver_cam/test_apps/dvp/main/test_dvp_driver.c new file mode 100644 index 000000000000..4f6b7041e818 --- /dev/null +++ b/components/esp_driver_cam/test_apps/dvp/main/test_dvp_driver.c @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "sdkconfig.h" +#include "unity.h" +#include "esp_cam_ctlr_dvp.h" +#include "esp_cam_ctlr.h" + +TEST_CASE("TEST DVP driver allocation", "[DVP]") +{ + esp_cam_ctlr_dvp_config_t dvp_config = { + .ctlr_id = 0, + .clk_src = CAM_CLK_SRC_DEFAULT, + .h_res = 800, + .v_res = 640, + .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .dma_burst_size = 128, + .byte_swap_en = false, + .pin_dont_init = true, + }; + esp_cam_ctlr_handle_t handle = NULL; + TEST_ESP_OK(esp_cam_new_dvp_ctlr(&dvp_config, &handle)); + TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_cam_new_dvp_ctlr(&dvp_config, &handle)); + + uint8_t *bk_buffer = NULL; + size_t bk_buffer_len = 0; + TEST_ESP_OK(esp_cam_ctlr_get_frame_buffer(handle, 1, (const void **)&bk_buffer)); + TEST_ESP_OK(esp_cam_ctlr_get_frame_buffer_len(handle, &bk_buffer_len)); + TEST_ASSERT_NOT_NULL(bk_buffer); + TEST_ASSERT_EQUAL((dvp_config.h_res * dvp_config.v_res * 2), bk_buffer_len); // type RGB565 using 2 byte / pixel + TEST_ESP_OK(esp_cam_ctlr_del(handle)); +} + +TEST_CASE("TEST DVP driver allocation with JPEG input", "[DVP]") +{ + esp_cam_ctlr_dvp_config_t dvp_config = { + .ctlr_id = 0, + .clk_src = CAM_CLK_SRC_DEFAULT, + .h_res = 800, + .v_res = 640, + .dma_burst_size = 128, + .byte_swap_en = false, + .pin_dont_init = true, + .pic_format_jpeg = true, + }; + esp_cam_ctlr_handle_t handle = NULL; + TEST_ESP_OK(esp_cam_new_dvp_ctlr(&dvp_config, &handle)); + TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_cam_new_dvp_ctlr(&dvp_config, &handle)); + + uint8_t *bk_buffer = NULL; + size_t bk_buffer_len = 0; + TEST_ESP_OK(esp_cam_ctlr_get_frame_buffer(handle, 1, (const void **)&bk_buffer)); + TEST_ESP_OK(esp_cam_ctlr_get_frame_buffer_len(handle, &bk_buffer_len)); + TEST_ASSERT_NOT_NULL(bk_buffer); + TEST_ASSERT_EQUAL((dvp_config.h_res * dvp_config.v_res * 1), bk_buffer_len); // type JPEG using 1 byte / pixel + TEST_ESP_OK(esp_cam_ctlr_del(handle)); +} + +TEST_CASE("TEST DVP driver no backup buffer usage", "[DVP]") +{ + esp_cam_ctlr_dvp_config_t dvp_config = { + .ctlr_id = 0, + .clk_src = CAM_CLK_SRC_DEFAULT, + .h_res = 800, + .v_res = 640, + .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .dma_burst_size = 128, + .byte_swap_en = false, + .bk_buffer_dis = true, + .pin_dont_init = true, + }; + esp_cam_ctlr_handle_t handle = NULL; + TEST_ESP_OK(esp_cam_new_dvp_ctlr(&dvp_config, &handle)); + TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_cam_new_dvp_ctlr(&dvp_config, &handle)); + + uint8_t *bk_buffer = NULL; + size_t bk_buffer_len = 0; + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_cam_ctlr_get_frame_buffer(handle, 1, (const void **)&bk_buffer)); + TEST_ESP_OK(esp_cam_ctlr_get_frame_buffer_len(handle, &bk_buffer_len)); + TEST_ASSERT_NULL(bk_buffer); + TEST_ASSERT_EQUAL((dvp_config.h_res * dvp_config.v_res * 2), bk_buffer_len); // out type RGB565 using 2 byte / pixel + TEST_ESP_OK(esp_cam_ctlr_del(handle)); +} diff --git a/components/esp_driver_cam/test_apps/dvp/pytest_dvp.py b/components/esp_driver_cam/test_apps/dvp/pytest_dvp.py new file mode 100644 index 000000000000..139f1c0694b3 --- /dev/null +++ b/components/esp_driver_cam/test_apps/dvp/pytest_dvp.py @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_dvp(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_driver_cam/test_apps/dvp/sdkconfig.defaults b/components/esp_driver_cam/test_apps/dvp/sdkconfig.defaults new file mode 100644 index 000000000000..f02afdd3c698 --- /dev/null +++ b/components/esp_driver_cam/test_apps/dvp/sdkconfig.defaults @@ -0,0 +1,6 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration +# +CONFIG_SPIRAM=y +CONFIG_ESP_TASK_WDT_EN=n +CONFIG_FREERTOS_HZ=1000 diff --git a/components/esp_driver_cam/test_apps/dvp/sdkconfig.defaults.esp32p4 b/components/esp_driver_cam/test_apps/dvp/sdkconfig.defaults.esp32p4 new file mode 100644 index 000000000000..5fca5fa08051 --- /dev/null +++ b/components/esp_driver_cam/test_apps/dvp/sdkconfig.defaults.esp32p4 @@ -0,0 +1,3 @@ +CONFIG_IDF_TARGET="esp32p4" +CONFIG_SPIRAM_SPEED_200M=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y diff --git a/components/esp_driver_cam/test_apps/isp_dvp/CMakeLists.txt b/components/esp_driver_cam/test_apps/isp_dvp/CMakeLists.txt new file mode 100644 index 000000000000..89ec188d05c9 --- /dev/null +++ b/components/esp_driver_cam/test_apps/isp_dvp/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.16) + +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(test_isp_dvp) diff --git a/components/esp_driver_cam/test_apps/isp_dvp/README.md b/components/esp_driver_cam/test_apps/isp_dvp/README.md new file mode 100644 index 000000000000..909282018f26 --- /dev/null +++ b/components/esp_driver_cam/test_apps/isp_dvp/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | diff --git a/components/esp_driver_cam/test_apps/isp_dvp/main/CMakeLists.txt b/components/esp_driver_cam/test_apps/isp_dvp/main/CMakeLists.txt new file mode 100644 index 000000000000..382e87b8ca30 --- /dev/null +++ b/components/esp_driver_cam/test_apps/isp_dvp/main/CMakeLists.txt @@ -0,0 +1,16 @@ +set(srcs "test_app_main.c") + +if(CONFIG_SOC_ISP_DVP_SUPPORTED) + list(APPEND srcs "test_isp_dvp_driver.c") +endif() + +set(priv_requires + unity + esp_driver_cam + esp_psram +) + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS "." + PRIV_REQUIRES ${priv_requires} + WHOLE_ARCHIVE TRUE) diff --git a/components/esp_driver_cam/test_apps/isp_dvp/main/test_app_main.c b/components/esp_driver_cam/test_apps/isp_dvp/main/test_app_main.c new file mode 100644 index 000000000000..a47ab1a130d3 --- /dev/null +++ b/components/esp_driver_cam/test_apps/isp_dvp/main/test_app_main.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "unity.h" +#include "unity_test_utils.h" +#include "esp_heap_caps.h" +#include "sdkconfig.h" + +#define TEST_MEMORY_LEAK_THRESHOLD (400) + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); +} + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/esp_driver_cam/test_apps/isp_dvp/main/test_isp_dvp_driver.c b/components/esp_driver_cam/test_apps/isp_dvp/main/test_isp_dvp_driver.c new file mode 100644 index 000000000000..5d0fa2f64d92 --- /dev/null +++ b/components/esp_driver_cam/test_apps/isp_dvp/main/test_isp_dvp_driver.c @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "sdkconfig.h" +#include "unity.h" +#include "esp_cam_ctlr_isp_dvp.h" +#include "esp_cam_ctlr.h" +#include "driver/isp.h" + +TEST_CASE("ISP DVP controller exhausted allocation", "[isp]") +{ + esp_isp_processor_cfg_t isp_config = { + .clk_hz = 120 * 1000 * 1000, + .input_data_source = ISP_INPUT_DATA_SOURCE_DVP, + .input_data_color_type = ISP_COLOR_RAW8, + .output_data_color_type = ISP_COLOR_RGB565, + .has_line_start_packet = false, + .has_line_end_packet = false, + .h_res = 800, + .v_res = 640, + }; + isp_proc_handle_t isp_proc = NULL; + TEST_ESP_OK(esp_isp_new_processor(&isp_config, &isp_proc)); + + esp_cam_ctlr_isp_dvp_cfg_t dvp_ctlr_config = { + .data_width = 8, + .data_io = {53, 54, 52, 0, 1, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1}, + .pclk_io = 21, + .hsync_io = 5, + .vsync_io = 23, + .de_io = 22, + .io_flags.vsync_invert = 1, + .queue_items = 10, + }; + esp_cam_ctlr_handle_t dvp_ctrlr[SOC_ISP_DVP_CTLR_NUMS + 1] = {}; + for (int i = 0; i < SOC_ISP_DVP_CTLR_NUMS; i++) { + TEST_ESP_OK(esp_cam_new_isp_dvp_ctlr(isp_proc, &dvp_ctlr_config, &dvp_ctrlr[i])); + } + + TEST_ASSERT(esp_cam_new_isp_dvp_ctlr(isp_proc, &dvp_ctlr_config, &dvp_ctrlr[SOC_ISP_DVP_CTLR_NUMS]) == ESP_ERR_NOT_FOUND); + + for (int i = 0; i < SOC_ISP_DVP_CTLR_NUMS; i++) { + TEST_ESP_OK(esp_cam_ctlr_del(dvp_ctrlr[i])); + } + TEST_ESP_OK(esp_isp_del_processor(isp_proc)); +} diff --git a/components/esp_driver_cam/test_apps/isp_dvp/pytest_isp_dvp.py b/components/esp_driver_cam/test_apps/isp_dvp/pytest_isp_dvp.py new file mode 100644 index 000000000000..a9922987c5a2 --- /dev/null +++ b/components/esp_driver_cam/test_apps/isp_dvp/pytest_isp_dvp.py @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_isp_dvp(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_driver_cam/test_apps/isp_dvp/sdkconfig.defaults b/components/esp_driver_cam/test_apps/isp_dvp/sdkconfig.defaults new file mode 100644 index 000000000000..3f0207c5d6e8 --- /dev/null +++ b/components/esp_driver_cam/test_apps/isp_dvp/sdkconfig.defaults @@ -0,0 +1,6 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT_EN=n + +CONFIG_SPIRAM=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM_SPEED_200M=y diff --git a/components/esp_driver_dac/Kconfig b/components/esp_driver_dac/Kconfig index e0a1546db505..6fa1356cd610 100644 --- a/components/esp_driver_dac/Kconfig +++ b/components/esp_driver_dac/Kconfig @@ -15,14 +15,6 @@ menu "ESP-Driver:DAC Configurations" Ensure the DAC interrupt is IRAM-Safe by allowing the interrupt handler to be executable when the cache is disabled (e.g. SPI Flash write). - config DAC_SUPPRESS_DEPRECATE_WARN - bool "Suppress legacy driver deprecated warning" - default n - help - whether to suppress the deprecation warnings when using legacy DAC driver (driver/dac.h). - If you want to continue using the legacy driver, and don't want to see related deprecation warnings, - you can enable this option. - config DAC_ENABLE_DEBUG_LOG bool "Enable debug log" default n diff --git a/components/esp_driver_gpio/include/driver/gpio_etm.h b/components/esp_driver_gpio/include/driver/gpio_etm.h index e7d4b0b7ad81..374f2920d0a6 100644 --- a/components/esp_driver_gpio/include/driver/gpio_etm.h +++ b/components/esp_driver_gpio/include/driver/gpio_etm.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,20 +13,29 @@ extern "C" { #endif +#define GPIO_ETM_EVENT_EDGE_TYPES 3 /*!< GPIO ETM edge events are POS/NEG/ANY */ +#define GPIO_ETM_TASK_ACTION_TYPES 3 /*!< GPIO ETM action tasks are SET/CLEAR/TOGGLE */ + /** * @brief GPIO edges that can be used as ETM event */ typedef enum { - GPIO_ETM_EVENT_EDGE_POS, /*!< A rising edge on the GPIO will generate an ETM event signal */ - GPIO_ETM_EVENT_EDGE_NEG, /*!< A falling edge on the GPIO will generate an ETM event signal */ - GPIO_ETM_EVENT_EDGE_ANY, /*!< Any edge on the GPIO can generate an ETM event signal */ + GPIO_ETM_EVENT_EDGE_POS = 1, /*!< A rising edge on the GPIO will generate an ETM event signal */ + GPIO_ETM_EVENT_EDGE_NEG, /*!< A falling edge on the GPIO will generate an ETM event signal */ + GPIO_ETM_EVENT_EDGE_ANY, /*!< Any edge on the GPIO can generate an ETM event signal */ } gpio_etm_event_edge_t; /** * @brief GPIO ETM event configuration + * + * If more than one kind of ETM edge event want to be triggered on the same GPIO pin, you can configure them together. + * It helps to save GPIO ETM event channel resources for other GPIOs. */ typedef struct { - gpio_etm_event_edge_t edge; /*!< Which kind of edge can trigger the ETM event module */ + union { + gpio_etm_event_edge_t edge; /*!< Which kind of edge can trigger the ETM event module */ + gpio_etm_event_edge_t edges[GPIO_ETM_EVENT_EDGE_TYPES]; /*!< Array of kinds of edges to trigger the ETM event module on the same GPIO */ + }; } gpio_etm_event_config_t; /** @@ -34,9 +43,11 @@ typedef struct { * * @note The created ETM event object can be deleted later by calling `esp_etm_del_event` * @note The newly created ETM event object is not bind to any GPIO, you need to call `gpio_etm_event_bind_gpio` to bind the wanted GPIO + * @note Every success call to this function will acquire a free GPIO ETM event channel * * @param[in] config GPIO ETM event configuration * @param[out] ret_event Returned ETM event handle + * @param[out] ... Other returned ETM event handles if any (the order of the returned event handles is aligned with the array order in field `edges` in `gpio_etm_event_config_t`) * @return * - ESP_OK: Create ETM event successfully * - ESP_ERR_INVALID_ARG: Create ETM event failed because of invalid argument @@ -44,7 +55,7 @@ typedef struct { * - ESP_ERR_NOT_FOUND: Create ETM event failed because all events are used up and no more free one * - ESP_FAIL: Create ETM event failed because of other reasons */ -esp_err_t gpio_new_etm_event(const gpio_etm_event_config_t *config, esp_etm_event_handle_t *ret_event); +esp_err_t gpio_new_etm_event(const gpio_etm_event_config_t *config, esp_etm_event_handle_t *ret_event, ...); /** * @brief Bind the GPIO with the ETM event @@ -65,16 +76,21 @@ esp_err_t gpio_etm_event_bind_gpio(esp_etm_event_handle_t event, int gpio_num); * @brief GPIO actions that can be taken by the ETM task */ typedef enum { - GPIO_ETM_TASK_ACTION_SET, /*!< Set the GPIO level to high */ - GPIO_ETM_TASK_ACTION_CLR, /*!< Clear the GPIO level to low */ - GPIO_ETM_TASK_ACTION_TOG, /*!< Toggle the GPIO level */ + GPIO_ETM_TASK_ACTION_SET = 1, /*!< Set the GPIO level to high */ + GPIO_ETM_TASK_ACTION_CLR, /*!< Clear the GPIO level to low */ + GPIO_ETM_TASK_ACTION_TOG, /*!< Toggle the GPIO level */ } gpio_etm_task_action_t; /** * @brief GPIO ETM task configuration + * + * If multiple actions wants to be added to the same GPIO pin, you have to configure all the GPIO ETM tasks together. */ typedef struct { - gpio_etm_task_action_t action; /*!< Which action to take by the ETM task module */ + union { + gpio_etm_task_action_t action; /*!< Action to take by the ETM task module */ + gpio_etm_task_action_t actions[GPIO_ETM_TASK_ACTION_TYPES]; /*!< Array of actions to take by the ETM task module on the same GPIO */ + }; } gpio_etm_task_config_t; /** @@ -83,9 +99,11 @@ typedef struct { * @note The created ETM task object can be deleted later by calling `esp_etm_del_task` * @note The GPIO ETM task works like a container, a newly created ETM task object doesn't have GPIO members to be managed. * You need to call `gpio_etm_task_add_gpio` to put one or more GPIOs to the container. + * @note Every success call to this function will acquire a free GPIO ETM task channel * * @param[in] config GPIO ETM task configuration * @param[out] ret_task Returned ETM task handle + * @param[out] ... Other returned ETM task handles if any (the order of the returned task handles is aligned with the array order in field `actions` in `gpio_etm_task_config_t`) * @return * - ESP_OK: Create ETM task successfully * - ESP_ERR_INVALID_ARG: Create ETM task failed because of invalid argument @@ -93,7 +111,7 @@ typedef struct { * - ESP_ERR_NOT_FOUND: Create ETM task failed because all tasks are used up and no more free one * - ESP_FAIL: Create ETM task failed because of other reasons */ -esp_err_t gpio_new_etm_task(const gpio_etm_task_config_t *config, esp_etm_task_handle_t *ret_task); +esp_err_t gpio_new_etm_task(const gpio_etm_task_config_t *config, esp_etm_task_handle_t *ret_task, ...); /** * @brief Add GPIO to the ETM task. diff --git a/components/esp_driver_gpio/src/gpio.c b/components/esp_driver_gpio/src/gpio.c index d52dcde29750..5e878b7e7d81 100644 --- a/components/esp_driver_gpio/src/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -22,13 +22,7 @@ #include "hal/gpio_hal.h" #include "esp_rom_gpio.h" #include "esp_private/esp_gpio_reserve.h" -#include "esp_private/periph_ctrl.h" - -#if SOC_LP_IO_CLOCK_IS_INDEPENDENT && !SOC_RTCIO_RCC_IS_INDEPENDENT -#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -#else -#define RTCIO_RCC_ATOMIC() -#endif +#include "esp_private/io_mux.h" #if (SOC_RTCIO_PIN_COUNT > 0) #include "hal/rtc_io_hal.h" @@ -66,9 +60,6 @@ typedef struct { gpio_isr_func_t *gpio_isr_func; gpio_isr_handle_t gpio_isr_handle; uint64_t isr_clr_on_entry_mask; // for edge-triggered interrupts, interrupt status bits should be cleared before entering per-pin handlers -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_LP_IO_CLOCK_IS_INDEPENDENT - uint32_t gpio_wakeup_mask; -#endif } gpio_context_t; static gpio_hal_context_t _gpio_hal = { @@ -81,9 +72,6 @@ static gpio_context_t gpio_context = { .isr_core_id = GPIO_ISR_CORE_ID_UNINIT, .gpio_isr_func = NULL, .isr_clr_on_entry_mask = 0, -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_LP_IO_CLOCK_IS_INDEPENDENT - .gpio_wakeup_mask = 0, -#endif }; esp_err_t gpio_pullup_en(gpio_num_t gpio_num) @@ -639,6 +627,11 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) if ((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) { #if SOC_RTCIO_WAKE_SUPPORTED if (rtc_gpio_is_valid_gpio(gpio_num)) { +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT + // LP_IO Wake-up function does not depend on LP_IO Matrix, but uses its clock to + // sample the wake-up signal, we need to enable the LP_IO clock here. + io_mux_enable_lp_io_clock(gpio_num, true); +#endif ret = rtc_gpio_wakeup_enable(gpio_num, intr_type); } #endif @@ -664,6 +657,9 @@ esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num) #if SOC_RTCIO_WAKE_SUPPORTED if (rtc_gpio_is_valid_gpio(gpio_num)) { ret = rtc_gpio_wakeup_disable(gpio_num); +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT + io_mux_enable_lp_io_clock(gpio_num, false); +#endif } #endif portENTER_CRITICAL(&gpio_context.gpio_spinlock); @@ -992,12 +988,7 @@ esp_err_t gpio_deep_sleep_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t int } portENTER_CRITICAL(&gpio_context.gpio_spinlock); #if SOC_LP_IO_CLOCK_IS_INDEPENDENT - if (gpio_context.gpio_wakeup_mask == 0) { - RTCIO_RCC_ATOMIC() { - rtcio_ll_enable_io_clock(true); - } - } - gpio_context.gpio_wakeup_mask |= (1ULL << gpio_num); + io_mux_enable_lp_io_clock(gpio_num, true); #endif gpio_hal_deepsleep_wakeup_enable(gpio_context.gpio_hal, gpio_num, intr_type); #if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO @@ -1019,12 +1010,7 @@ esp_err_t gpio_deep_sleep_wakeup_disable(gpio_num_t gpio_num) gpio_hal_sleep_sel_en(gpio_context.gpio_hal, gpio_num); #endif #if SOC_LP_IO_CLOCK_IS_INDEPENDENT - gpio_context.gpio_wakeup_mask &= ~(1ULL << gpio_num); - if (gpio_context.gpio_wakeup_mask == 0) { - RTCIO_RCC_ATOMIC() { - rtcio_ll_enable_io_clock(false); - } - } + io_mux_enable_lp_io_clock(gpio_num, false); #endif portEXIT_CRITICAL(&gpio_context.gpio_spinlock); return ESP_OK; diff --git a/components/esp_driver_gpio/src/gpio_etm.c b/components/esp_driver_gpio/src/gpio_etm.c index 61fe15de98dc..b0a3ea61ea4c 100644 --- a/components/esp_driver_gpio/src/gpio_etm.c +++ b/components/esp_driver_gpio/src/gpio_etm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,19 +34,23 @@ typedef struct gpio_etm_event_t gpio_etm_event_t; typedef struct gpio_etm_group_t { portMUX_TYPE spinlock; gpio_etm_dev_t *dev; - gpio_etm_task_t *tasks[SOC_GPIO_ETM_TASKS_PER_GROUP]; - gpio_etm_event_t *events[SOC_GPIO_ETM_EVENTS_PER_GROUP]; + uint8_t tasks[GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP]; // Array of the acquired action masks in each GPIO ETM task channel + uint8_t events[GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP]; // Array of the acquired event masks in each GPIO ETM event channel + uint8_t actions[SOC_GPIO_PIN_COUNT]; // Array of the masks of the added actions to each GPIO + uint8_t edges[GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP]; // Array of the masks of the bound event edges in each GPIO ETM event channel } gpio_etm_group_t; struct gpio_etm_event_t { esp_etm_event_t base; int chan_id; + gpio_etm_event_edge_t edge_id; gpio_etm_group_t *group; }; struct gpio_etm_task_t { esp_etm_task_t base; int chan_id; + gpio_etm_task_action_t action_id; gpio_etm_group_t *group; size_t num_of_gpios; // record the number of GPIOs that are bound to the etm task }; @@ -56,81 +60,65 @@ static gpio_etm_group_t s_gpio_etm_group = { .spinlock = portMUX_INITIALIZER_UNLOCKED, }; -static esp_err_t gpio_etm_event_register_to_group(gpio_etm_event_t *event) +static esp_err_t gpio_etm_acquire_event_channel(uint8_t event_mask, int *chan_id) { + assert(chan_id); gpio_etm_group_t *group = &s_gpio_etm_group; - int chan_id = -1; - // loop to search free one in the group + + int free_chan_id = -1; + // loop to search free event channel in the group portENTER_CRITICAL(&group->spinlock); - for (int j = 0; j < SOC_GPIO_ETM_EVENTS_PER_GROUP; j++) { + for (int j = 0; j < GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP; j++) { if (!group->events[j]) { - chan_id = j; - group->events[j] = event; + free_chan_id = j; + group->events[j] = event_mask; break; } } portEXIT_CRITICAL(&group->spinlock); - ESP_RETURN_ON_FALSE(chan_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free event channel"); - event->group = group; - event->chan_id = chan_id; + ESP_RETURN_ON_FALSE(free_chan_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free event channel"); + *chan_id = free_chan_id; return ESP_OK; } -static esp_err_t gpio_etm_task_register_to_group(gpio_etm_task_t *task) +static esp_err_t gpio_etm_release_event_channel(int chan_id, uint8_t event_mask) { gpio_etm_group_t *group = &s_gpio_etm_group; - int chan_id = -1; - // loop to search free one in the group portENTER_CRITICAL(&group->spinlock); - for (int j = 0; j < SOC_GPIO_ETM_TASKS_PER_GROUP; j++) { - if (!group->tasks[j]) { - chan_id = j; - group->tasks[j] = task; - break; - } - } + group->events[chan_id] &= ~event_mask; portEXIT_CRITICAL(&group->spinlock); - - ESP_RETURN_ON_FALSE(chan_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free task channel"); - task->group = group; - task->chan_id = chan_id; return ESP_OK; } -static void gpio_etm_event_unregister_from_group(gpio_etm_event_t *event) +static esp_err_t gpio_etm_acquire_task_channel(uint8_t task_mask, int *chan_id) { - gpio_etm_group_t *group = event->group; - int chan_id = event->chan_id; - portENTER_CRITICAL(&group->spinlock); - group->events[chan_id] = NULL; - portEXIT_CRITICAL(&group->spinlock); -} + assert(chan_id); + gpio_etm_group_t *group = &s_gpio_etm_group; -static void gpio_etm_task_unregister_from_group(gpio_etm_task_t *task) -{ - gpio_etm_group_t *group = task->group; - int chan_id = task->chan_id; + int free_chan_id = -1; + // loop to search free task channel in the group portENTER_CRITICAL(&group->spinlock); - group->tasks[chan_id] = NULL; + for (int j = 0; j < GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP; j++) { + if (!group->tasks[j]) { + free_chan_id = j; + group->tasks[j] = task_mask; + break; + } + } portEXIT_CRITICAL(&group->spinlock); -} -static esp_err_t gpio_etm_event_destroy(gpio_etm_event_t *event) -{ - if (event->group) { - gpio_etm_event_unregister_from_group(event); - } - free(event); + ESP_RETURN_ON_FALSE(free_chan_id != -1, ESP_ERR_NOT_FOUND, TAG, "no free task channel"); + *chan_id = free_chan_id; return ESP_OK; } -static esp_err_t gpio_etm_task_destroy(gpio_etm_task_t *task) +static esp_err_t gpio_etm_release_task_channel(int chan_id, uint8_t task_mask) { - if (task->group) { - gpio_etm_task_unregister_from_group(task); - } - free(task); + gpio_etm_group_t *group = &s_gpio_etm_group; + portENTER_CRITICAL(&group->spinlock); + group->tasks[chan_id] &= ~task_mask; + portEXIT_CRITICAL(&group->spinlock); return ESP_OK; } @@ -138,9 +126,16 @@ static esp_err_t gpio_del_etm_event(esp_etm_event_t *event) { gpio_etm_event_t *gpio_event = __containerof(event, gpio_etm_event_t, base); gpio_etm_group_t *group = gpio_event->group; - // disable event channel - gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, false); - gpio_etm_event_destroy(gpio_event); + // unbind it from the GPIO and check if the GPIO ETM event channel can be disabled + portENTER_CRITICAL(&group->spinlock); + group->edges[gpio_event->chan_id] &= ~(1 << gpio_event->edge_id); + if (!group->edges[gpio_event->chan_id]) { + gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, false); + } + portEXIT_CRITICAL(&group->spinlock); + + gpio_etm_release_event_channel(gpio_event->chan_id, 1 << gpio_event->edge_id); + free(gpio_event); return ESP_OK; } @@ -149,95 +144,192 @@ static esp_err_t gpio_del_etm_task(esp_etm_task_t *task) gpio_etm_task_t *gpio_task = __containerof(task, gpio_etm_task_t, base); // make sure user has called `gpio_etm_task_rm_gpio` to clean the etm task channel ESP_RETURN_ON_FALSE(gpio_task->num_of_gpios == 0, ESP_ERR_INVALID_STATE, TAG, "some GPIO till bounded to the etm task"); - gpio_etm_task_destroy(gpio_task); + gpio_etm_release_task_channel(gpio_task->chan_id, 1 << gpio_task->action_id); + free(gpio_task); return ESP_OK; } -esp_err_t gpio_new_etm_event(const gpio_etm_event_config_t *config, esp_etm_event_handle_t *ret_event) +esp_err_t gpio_new_etm_event(const gpio_etm_event_config_t *config, esp_etm_event_handle_t *ret_event, ...) { #if CONFIG_ETM_ENABLE_DEBUG_LOG esp_log_level_set(TAG, ESP_LOG_DEBUG); #endif esp_err_t ret = ESP_OK; - gpio_etm_event_t *event = NULL; - ESP_GOTO_ON_FALSE(config && ret_event, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + int chan_id = -1; + uint8_t event_mask = 0; + esp_etm_event_handle_t *ret_event_itor = ret_event; + va_list args; + ESP_RETURN_ON_FALSE(config && ret_event, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + for (int i = 0; i < GPIO_ETM_EVENT_EDGE_TYPES; i++) { + if (config->edges[i]) { + uint8_t msk = (1 << config->edges[i]); + ESP_RETURN_ON_FALSE(!(msk & event_mask), ESP_ERR_INVALID_ARG, TAG, "no identical edge event allowed in one call"); + event_mask |= msk; + } + } + ESP_RETURN_ON_FALSE(event_mask, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + uint32_t event_num = __builtin_popcount(event_mask); + gpio_etm_event_t *events[event_num]; - event = heap_caps_calloc(1, sizeof(gpio_etm_event_t), ETM_MEM_ALLOC_CAPS); - ESP_GOTO_ON_FALSE(event, ESP_ERR_NO_MEM, err, TAG, "no mem for event channel"); - // register the event channel to the group - ESP_GOTO_ON_ERROR(gpio_etm_event_register_to_group(event), err, TAG, "register event channel to group failed"); - int chan_id = event->chan_id; - - uint32_t event_id = 0; - switch (config->edge) { - case GPIO_ETM_EVENT_EDGE_ANY: - event_id = GPIO_LL_ETM_EVENT_ID_ANY_EDGE(chan_id); - break; - case GPIO_ETM_EVENT_EDGE_POS: - event_id = GPIO_LL_ETM_EVENT_ID_POS_EDGE(chan_id); - break; - case GPIO_ETM_EVENT_EDGE_NEG: - event_id = GPIO_LL_ETM_EVENT_ID_NEG_EDGE(chan_id); - break; - default: - ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid edge"); + for (int i = 0; i < event_num; i++) { + events[i] = (gpio_etm_event_t *)heap_caps_calloc(1, sizeof(gpio_etm_event_t), ETM_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(events[i], ESP_ERR_NO_MEM, err, TAG, "no mem for event channel(s)"); } - event->base.del = gpio_del_etm_event; - event->base.event_id = event_id; - event->base.trig_periph = ETM_TRIG_PERIPH_GPIO; - ESP_LOGD(TAG, "new event @%p, event_id=%"PRIu32", chan_id=%d", event, event_id, chan_id); - *ret_event = &event->base; + // register the event channel to the group + ESP_GOTO_ON_ERROR(gpio_etm_acquire_event_channel(event_mask, &chan_id), err, TAG, "register event channel to group failed"); + + bool no_avail_ret_arg = false; + va_start(args, ret_event); + for (int i = 0, j = 0; i < event_num; i++, j++) { + if (!ret_event_itor) { + no_avail_ret_arg = true; + break; + } + // assign to the ret_event handles in the configuration order + gpio_etm_event_edge_t event_edge; + do { + event_edge = config->edges[j]; + } while (!event_edge && ++j); + uint32_t event_id = 0; + switch (event_edge) { + case GPIO_ETM_EVENT_EDGE_ANY: + event_id = GPIO_LL_ETM_EVENT_ID_ANY_EDGE(chan_id); + break; + case GPIO_ETM_EVENT_EDGE_POS: + event_id = GPIO_LL_ETM_EVENT_ID_POS_EDGE(chan_id); + break; + case GPIO_ETM_EVENT_EDGE_NEG: + event_id = GPIO_LL_ETM_EVENT_ID_NEG_EDGE(chan_id); + break; + default: + va_end(args); + ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid edge"); + } + + gpio_etm_event_t *event = events[i]; + event->base.del = gpio_del_etm_event; + event->base.event_id = event_id; + event->base.trig_periph = ETM_TRIG_PERIPH_GPIO; + event->group = &s_gpio_etm_group; + event->chan_id = chan_id; + event->edge_id = event_edge; + ESP_LOGD(TAG, "new event @%p, event_id=%"PRIu32", chan_id=%d", event, event_id, chan_id); + *ret_event_itor = &event->base; + ret_event_itor = va_arg(args, esp_etm_event_handle_t *); + } + va_end(args); + ESP_GOTO_ON_FALSE(!no_avail_ret_arg, ESP_ERR_INVALID_ARG, err, TAG, "mismatch number of events with number of pointers to store event handles"); return ESP_OK; err: - if (event) { - gpio_etm_event_destroy(event); + if (chan_id != -1) { + gpio_etm_release_event_channel(chan_id, event_mask); + } + for (int i = 0; i < event_num; i++) { + if (events[i]) { + free(events[i]); + } } + ret_event_itor = ret_event; + va_start(args, ret_event); + while (ret_event_itor) { + *ret_event_itor = NULL; + ret_event_itor = va_arg(args, esp_etm_event_handle_t *); + } + va_end(args); return ret; } -esp_err_t gpio_new_etm_task(const gpio_etm_task_config_t *config, esp_etm_task_handle_t *ret_task) +esp_err_t gpio_new_etm_task(const gpio_etm_task_config_t *config, esp_etm_task_handle_t *ret_task, ...) { #if CONFIG_ETM_ENABLE_DEBUG_LOG esp_log_level_set(TAG, ESP_LOG_DEBUG); #endif esp_err_t ret = ESP_OK; - gpio_etm_task_t *task = NULL; - ESP_GOTO_ON_FALSE(config && ret_task, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + int chan_id = -1; + uint8_t task_mask = 0; + esp_etm_task_handle_t *ret_task_itor = ret_task; + va_list args; + ESP_RETURN_ON_FALSE(config && ret_task, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + for (int i = 0; i < GPIO_ETM_TASK_ACTION_TYPES; i++) { + if (config->actions[i]) { + uint8_t msk = (1 << config->actions[i]); + ESP_RETURN_ON_FALSE(!(msk & task_mask), ESP_ERR_INVALID_ARG, TAG, "no identical action allowed in one call"); + task_mask |= msk; + } + } + ESP_RETURN_ON_FALSE(task_mask, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + uint32_t task_num = __builtin_popcount(task_mask); + gpio_etm_task_t *tasks[task_num]; - task = heap_caps_calloc(1, sizeof(gpio_etm_task_t), ETM_MEM_ALLOC_CAPS); - ESP_GOTO_ON_FALSE(task, ESP_ERR_NO_MEM, err, TAG, "no mem for task channel"); - // register the task channel to the group - ESP_GOTO_ON_ERROR(gpio_etm_task_register_to_group(task), err, TAG, "register task channel to group failed"); - int chan_id = task->chan_id; - - uint32_t task_id = 0; - switch (config->action) { - case GPIO_ETM_TASK_ACTION_SET: - task_id = GPIO_LL_ETM_TASK_ID_SET(chan_id); - break; - case GPIO_ETM_TASK_ACTION_CLR: - task_id = GPIO_LL_ETM_TASK_ID_CLR(chan_id); - break; - case GPIO_ETM_TASK_ACTION_TOG: - task_id = GPIO_LL_ETM_TASK_ID_TOG(chan_id); - break; - default: - ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid action"); + for (int i = 0; i < task_num; i++) { + tasks[i] = (gpio_etm_task_t *)heap_caps_calloc(1, sizeof(gpio_etm_task_t), ETM_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(tasks[i], ESP_ERR_NO_MEM, err, TAG, "no mem for task channel(s)"); } - task->base.del = gpio_del_etm_task; - task->base.task_id = task_id; - task->base.trig_periph = ETM_TRIG_PERIPH_GPIO; - ESP_LOGD(TAG, "new task @%p, task_id=%"PRIu32", chan_id=%d", task, task_id, chan_id); - *ret_task = &task->base; + // register the task channel to the group + ESP_GOTO_ON_ERROR(gpio_etm_acquire_task_channel(task_mask, &chan_id), err, TAG, "register task channel to group failed"); + + bool no_avail_ret_arg = false; + va_start(args, ret_task); + for (int i = 0, j = 0; i < task_num; i++, j++) { + if (!ret_task_itor) { + no_avail_ret_arg = true; + break; + } + // assign to the ret_task handles in the configuration order + gpio_etm_task_action_t action; + do { + action = config->actions[i]; + } while (!action && ++j); + uint32_t task_id = 0; + switch (action) { + case GPIO_ETM_TASK_ACTION_SET: + task_id = GPIO_LL_ETM_TASK_ID_SET(chan_id); + break; + case GPIO_ETM_TASK_ACTION_CLR: + task_id = GPIO_LL_ETM_TASK_ID_CLR(chan_id); + break; + case GPIO_ETM_TASK_ACTION_TOG: + task_id = GPIO_LL_ETM_TASK_ID_TOG(chan_id); + break; + default: + va_end(args); + ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid action"); + } + + gpio_etm_task_t *task = tasks[i]; + task->base.del = gpio_del_etm_task; + task->base.task_id = task_id; + task->base.trig_periph = ETM_TRIG_PERIPH_GPIO; + task->group = &s_gpio_etm_group; + task->chan_id = chan_id; + task->action_id = action; + ESP_LOGD(TAG, "new task @%p, task_id=%"PRIu32", gpio_etm_task_chan_id=%d", task, task_id, chan_id); + *ret_task_itor = &task->base; + ret_task_itor = va_arg(args, esp_etm_task_handle_t *); + } + va_end(args); + ESP_GOTO_ON_FALSE(!no_avail_ret_arg, ESP_ERR_INVALID_ARG, err, TAG, "mismatch number of tasks with number of pointers to store task handles"); return ESP_OK; err: - if (task) { - gpio_etm_task_destroy(task); + if (chan_id != -1) { + gpio_etm_release_task_channel(chan_id, task_mask); } + for (int i = 0; i < task_num; i++) { + if (tasks[i]) { + free(tasks[i]); + } + } + ret_task_itor = ret_task; + va_start(args, ret_task); + while (ret_task_itor) { + *ret_task_itor = NULL; + ret_task_itor = va_arg(args, esp_etm_task_handle_t *); + } + va_end(args); return ret; } @@ -248,12 +340,27 @@ esp_err_t gpio_etm_event_bind_gpio(esp_etm_event_handle_t event, int gpio_num) ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "gpio is not input capable"); gpio_etm_event_t *gpio_event = __containerof(event, gpio_etm_event_t, base); gpio_etm_group_t *group = gpio_event->group; - // disable gpio etm event channel first - gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, false); - // then set the gpio number - gpio_ll_etm_event_channel_set_gpio(group->dev, gpio_event->chan_id, gpio_num); - // enable gpio etm event channel again - gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, true); + + bool allowed = true; + portENTER_CRITICAL(&group->spinlock); + // check if the GPIO ETM event channel where the new event belongs to has previously been bound to another GPIO + // one GPIO ETM event channel can only be bound to one GPIO + if (group->edges[gpio_event->chan_id]) { + if (gpio_ll_etm_event_channel_get_gpio(group->dev, gpio_event->chan_id) != gpio_num) { + allowed = false; + } + } else { + // set the GPIO number + gpio_ll_etm_event_channel_set_gpio(group->dev, gpio_event->chan_id, gpio_num); + // enable GPIO ETM event channel + gpio_ll_etm_enable_event_channel(group->dev, gpio_event->chan_id, true); + } + + if (allowed) { + group->edges[gpio_event->chan_id] |= (1 << gpio_event->edge_id); + } + portEXIT_CRITICAL(&group->spinlock); + ESP_RETURN_ON_FALSE(allowed, ESP_ERR_INVALID_ARG, TAG, "the GPIO ETM event channel where the event belongs to has already been bound to another GPIO"); return ESP_OK; } @@ -264,19 +371,28 @@ esp_err_t gpio_etm_task_add_gpio(esp_etm_task_handle_t task, int gpio_num) ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "gpio is not output capable"); gpio_etm_task_t *gpio_task = __containerof(task, gpio_etm_task_t, base); gpio_etm_group_t *group = gpio_task->group; - bool gpio_not_enabled = true; + + bool allowed = true; // use spinlock as this function may be called with different task object in different threads // and the gpio_num might reside in the same register portENTER_CRITICAL(&group->spinlock); - // check if the gpio has been enabled - if (!gpio_ll_etm_is_task_gpio_enabled(group->dev, gpio_num)) { + // check if the new task is compatible with the tasks that has previously been added to the GPIO + // the tasks have to be from the same GPIO ETM task channel + if (group->actions[gpio_num]) { + if (gpio_ll_etm_gpio_get_task_channel(group->dev, gpio_num) != gpio_task->chan_id) { + allowed = false; + } + } else { + // first action added to the GPIO gpio_ll_etm_gpio_set_task_channel(group->dev, gpio_num, gpio_task->chan_id); gpio_ll_etm_enable_task_gpio(group->dev, gpio_num, true); - } else { - gpio_not_enabled = false; + } + + if (allowed) { + group->actions[gpio_num] |= (1 << gpio_task->action_id); } portEXIT_CRITICAL(&group->spinlock); - ESP_RETURN_ON_FALSE(gpio_not_enabled, ESP_ERR_INVALID_STATE, TAG, "gpio already enabled by other task channel"); + ESP_RETURN_ON_FALSE(allowed, ESP_ERR_INVALID_ARG, TAG, "the task does not belong to the GPIO ETM task channel that the GPIO has already binded to"); gpio_task->num_of_gpios++; return ESP_OK; } @@ -287,19 +403,24 @@ esp_err_t gpio_etm_task_rm_gpio(esp_etm_task_handle_t task, int gpio_num) ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "gpio is not output capable"); gpio_etm_task_t *gpio_task = __containerof(task, gpio_etm_task_t, base); gpio_etm_group_t *group = gpio_task->group; - bool gpio_enabled_by_this_task = true; + + bool allowed = true; // use spinlock as this function may be called with different task object in different threads // and the gpio_num might reside in the same register portENTER_CRITICAL(&group->spinlock); - // check if the gpio is managed by this etm task channel - if (gpio_ll_etm_is_task_gpio_enabled(group->dev, gpio_num) && + if ((group->actions[gpio_num] & (1 << gpio_task->action_id)) && + gpio_ll_etm_is_task_gpio_enabled(group->dev, gpio_num) && (gpio_ll_etm_gpio_get_task_channel(group->dev, gpio_num) == gpio_task->chan_id)) { - gpio_ll_etm_enable_task_gpio(group->dev, gpio_num, false); + group->actions[gpio_num] &= ~(1 << gpio_task->action_id); + if (!group->actions[gpio_num]) { + // all actions removed from the GPIO + gpio_ll_etm_enable_task_gpio(group->dev, gpio_num, false); + } } else { - gpio_enabled_by_this_task = false; + allowed = false; } portEXIT_CRITICAL(&group->spinlock); - ESP_RETURN_ON_FALSE(gpio_enabled_by_this_task, ESP_ERR_INVALID_STATE, TAG, "gpio is not enabled by this task channel"); + ESP_RETURN_ON_FALSE(allowed, ESP_ERR_INVALID_ARG, TAG, "the task was not added to the GPIO"); gpio_task->num_of_gpios--; return ESP_OK; } diff --git a/components/esp_driver_gpio/src/rtc_io.c b/components/esp_driver_gpio/src/rtc_io.c index 9a582b1867de..c382a7c9d8b0 100644 --- a/components/esp_driver_gpio/src/rtc_io.c +++ b/components/esp_driver_gpio/src/rtc_io.c @@ -9,6 +9,7 @@ #include "esp_err.h" #include "esp_check.h" #include "esp_private/periph_ctrl.h" +#include "esp_private/io_mux.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/timers.h" @@ -18,16 +19,6 @@ #include "soc/rtc_io_periph.h" #include "soc/soc_caps.h" -#if SOC_LP_IO_CLOCK_IS_INDEPENDENT && !SOC_RTCIO_RCC_IS_INDEPENDENT -// For `rtcio_hal_function_select` using, clock reg option is inlined in it, -// so remove the declaration check of __DECLARE_RCC_RC_ATOMIC_ENV -#define RTCIO_RCC_ATOMIC() \ - for (int i = 1; i ? (periph_rcc_enter(), 1) : 0; \ - periph_rcc_exit(), i--) -#else -#define RTCIO_RCC_ATOMIC() -#endif - static const char __attribute__((__unused__)) *RTCIO_TAG = "RTCIO"; extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. @@ -56,9 +47,10 @@ esp_err_t rtc_gpio_init(gpio_num_t gpio_num) { ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error"); RTCIO_ENTER_CRITICAL(); - RTCIO_RCC_ATOMIC() { - rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_RTC); - } +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT + io_mux_enable_lp_io_clock(gpio_num, true); +#endif + rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_RTC); RTCIO_EXIT_CRITICAL(); return ESP_OK; @@ -68,10 +60,12 @@ esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num) { ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error"); RTCIO_ENTER_CRITICAL(); - RTCIO_RCC_ATOMIC() { - // Select Gpio as Digital Gpio - rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_DIGITAL); - } + // Select Gpio as Digital Gpio + rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_DIGITAL); + +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT + io_mux_enable_lp_io_clock(gpio_num, false); +#endif RTCIO_EXIT_CRITICAL(); return ESP_OK; diff --git a/components/esp_driver_gpio/test_apps/.build-test-rules.yml b/components/esp_driver_gpio/test_apps/.build-test-rules.yml index 68cfc3a41d3f..f0eb84e6e240 100644 --- a/components/esp_driver_gpio/test_apps/.build-test-rules.yml +++ b/components/esp_driver_gpio/test_apps/.build-test-rules.yml @@ -1,10 +1,6 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps components/esp_driver_gpio/test_apps: - disable: - - if: IDF_TARGET == "esp32c5" - temporary: true - reason: not support yet # TODO: [ESP32C5] IDF-8717 disable_test: - if: IDF_TARGET == "esp32p4" temporary: true diff --git a/components/esp_driver_gpio/test_apps/gpio/README.md b/components/esp_driver_gpio/test_apps/gpio/README.md index bf47d80ec649..3a502b1f86f4 100644 --- a/components/esp_driver_gpio/test_apps/gpio/README.md +++ b/components/esp_driver_gpio/test_apps/gpio/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_driver_gptimer/include/driver/gptimer.h b/components/esp_driver_gptimer/include/driver/gptimer.h index b9c0b8b14bc2..825f93db79a5 100644 --- a/components/esp_driver_gptimer/include/driver/gptimer.h +++ b/components/esp_driver_gptimer/include/driver/gptimer.h @@ -28,6 +28,9 @@ typedef struct { if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */ struct { uint32_t intr_shared: 1; /*!< Set true, the timer interrupt number can be shared with other peripherals */ + uint32_t backup_before_sleep: 1; /*!< If set, the driver will backup/restore the GPTimer registers before/after entering/exist sleep mode. + By this approach, the system can power off GPTimer's power domain. + This can save power, but at the expense of more RAM being consumed */ } flags; /*!< GPTimer config flags*/ } gptimer_config_t; diff --git a/components/esp_driver_gptimer/src/gptimer.c b/components/esp_driver_gptimer/src/gptimer.c index f1d4af466401..6fd66b9b95a3 100644 --- a/components/esp_driver_gptimer/src/gptimer.c +++ b/components/esp_driver_gptimer/src/gptimer.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,6 +30,10 @@ #include "esp_clk_tree.h" #include "gptimer_priv.h" +#if GPTIMER_USE_RETENTION_LINK +#include "esp_private/sleep_retention.h" +#endif + static const char *TAG = "gptimer"; #if SOC_PERIPH_CLK_CTRL_SHARED @@ -52,6 +56,37 @@ static void gptimer_release_group_handle(gptimer_group_t *group); static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t src_clk, uint32_t resolution_hz); static void gptimer_default_isr(void *args); +#if GPTIMER_USE_RETENTION_LINK +static esp_err_t sleep_tg_timer_retention_link_cb(void *arg) +{ + uint32_t group_id = *(uint32_t *)arg; + esp_err_t err = sleep_retention_entries_create(tg_timer_regs_retention[group_id].link_list, + tg_timer_regs_retention[group_id].link_num, + REGDMA_LINK_PRI_6, + (group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER); + if (err == ESP_OK) { + ESP_LOGD(TAG, "Timer group %ld retention initialization", group_id); + } + ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for timer group %ld", group_id); + return err; +} + +static void gptimer_create_retention_module(gptimer_group_t *group) +{ + _lock_acquire(&s_platform.mutex); + int group_id = group->group_id; + if ((group->sleep_retention_initialized == true) && (group->retention_link_created == false)) { + esp_err_t err = sleep_retention_module_allocate((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for timer group %d retention, power domain can't turn off", group_id); + } else { + group->retention_link_created = true; + } + } + _lock_release(&s_platform.mutex); +} +#endif + static esp_err_t gptimer_register_to_group(gptimer_t *timer) { gptimer_group_t *group = NULL; @@ -129,6 +164,12 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re int group_id = group->group_id; int timer_id = timer->timer_id; +#if GPTIMER_USE_RETENTION_LINK + if (config->flags.backup_before_sleep != 0) { + gptimer_create_retention_module(group); + } +#endif // GPTIMER_USE_RETENTION_LINK + // initialize HAL layer timer_hal_init(&timer->hal, group_id, timer_id); // select clock source, set clock resolution @@ -404,7 +445,6 @@ static gptimer_group_t *gptimer_acquire_group_handle(int group_id) // someone acquired the group handle means we have a new object that refer to this group s_platform.group_ref_counts[group_id]++; } - _lock_release(&s_platform.mutex); if (new_group) { // !!! HARDWARE SHARED RESOURCE !!! @@ -417,7 +457,28 @@ static gptimer_group_t *gptimer_acquire_group_handle(int group_id) } } ESP_LOGD(TAG, "new group (%d) @%p", group_id, group); +#if GPTIMER_USE_RETENTION_LINK + if (group->sleep_retention_initialized != true) { + sleep_retention_module_init_param_t init_param = { + .cbs = { + .create = { + .handle = sleep_tg_timer_retention_link_cb, + .arg = &group_id + }, + }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + esp_err_t err = sleep_retention_module_init((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER, &init_param); + + if (err == ESP_OK) { + group->sleep_retention_initialized = true; + } else { + ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for timer group %d retention", group_id); + } + } +#endif // GPTIMER_USE_RETENTION_LINK } + _lock_release(&s_platform.mutex); return group; } @@ -434,7 +495,6 @@ static void gptimer_release_group_handle(gptimer_group_t *group) do_deinitialize = true; s_platform.groups[group_id] = NULL; } - _lock_release(&s_platform.mutex); if (do_deinitialize) { // disable bus clock for the timer group @@ -443,9 +503,18 @@ static void gptimer_release_group_handle(gptimer_group_t *group) timer_ll_enable_bus_clock(group_id, false); } } +#if GPTIMER_USE_RETENTION_LINK + if (group->retention_link_created) { + sleep_retention_module_free((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER); + } + if (group->sleep_retention_initialized) { + sleep_retention_module_deinit((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER); + } +#endif free(group); ESP_LOGD(TAG, "del group (%d)", group_id); } + _lock_release(&s_platform.mutex); } static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t src_clk, uint32_t resolution_hz) diff --git a/components/esp_driver_gptimer/src/gptimer_priv.h b/components/esp_driver_gptimer/src/gptimer_priv.h index 78428ce09cba..fe072c85d43a 100644 --- a/components/esp_driver_gptimer/src/gptimer_priv.h +++ b/components/esp_driver_gptimer/src/gptimer_priv.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -39,12 +39,18 @@ extern "C" { #define GPTIMER_PM_LOCK_NAME_LEN_MAX 16 +#define GPTIMER_USE_RETENTION_LINK (SOC_TIMER_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP) + typedef struct gptimer_t gptimer_t; typedef struct gptimer_group_t { int group_id; portMUX_TYPE spinlock; // to protect per-group register level concurrent access gptimer_t *timers[SOC_TIMER_GROUP_TIMERS_PER_GROUP]; +#if GPTIMER_USE_RETENTION_LINK + bool sleep_retention_initialized; // mark if the retention link is initialized + bool retention_link_created; // mark if the retention link is created +#endif } gptimer_group_t; typedef enum { diff --git a/components/esp_driver_gptimer/test_apps/gptimer/README.md b/components/esp_driver_gptimer/test_apps/gptimer/README.md index bf47d80ec649..3a502b1f86f4 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/README.md +++ b/components/esp_driver_gptimer/test_apps/gptimer/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c index 04c08ce05e9e..4d3e6b49878c 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c +++ b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,15 @@ #include "soc/soc_caps.h" #include "esp_attr.h" +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +#include "esp_random.h" +#include "esp_rom_uart.h" +#include "esp_sleep.h" +#include "esp_private/esp_sleep_internal.h" +#include "esp_private/sleep_cpu.h" +#include "esp_private/esp_pmu.h" +#endif + #if CONFIG_GPTIMER_ISR_IRAM_SAFE #define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR #else @@ -596,3 +605,82 @@ TEST_CASE("gptimer_trig_alarm_with_old_count", "[gptimer]") TEST_ESP_OK(gptimer_disable(timer)); TEST_ESP_OK(gptimer_del_timer(timer)); } + +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +static gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS]; +static uint32_t timer_resolution_hz[SOC_TIMER_GROUP_TOTAL_TIMERS]; + +static void test_gptimer_retention(gptimer_config_t *timer_config) +{ + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + TEST_ESP_OK(gptimer_new_timer(timer_config, &timers[i])); + TEST_ESP_OK(gptimer_get_resolution(timers[i], &timer_resolution_hz[i])); + + unsigned long long count_start_value = 0, count_end_value = 0; + + // Let gptimer run for a while + TEST_ESP_OK(gptimer_enable(timers[i])); + TEST_ESP_OK(gptimer_start(timers[i])); + vTaskDelay((esp_random() % 500) / portTICK_PERIOD_MS); + TEST_ESP_OK(gptimer_stop(timers[i])); + TEST_ESP_OK(gptimer_disable(timers[i])); + TEST_ESP_OK(gptimer_get_raw_count(timers[i], &count_start_value)); + + esp_sleep_context_t sleep_ctx; + esp_sleep_set_sleep_context(&sleep_ctx); + TEST_ESP_OK(sleep_cpu_configure(true)); + esp_rom_output_tx_wait_idle(0); + esp_sleep_enable_timer_wakeup(50 * 1000); + esp_light_sleep_start(); + + if (timer_config->flags.backup_before_sleep) { + TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); + } else { + TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); + } + + TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); + + TEST_ESP_OK(gptimer_enable(timers[i])); + TEST_ESP_OK(gptimer_start(timers[i])); + + uint32_t random_time_ms = 500 + esp_random() % 2000; + vTaskDelay(random_time_ms / portTICK_PERIOD_MS); + TEST_ESP_OK(gptimer_get_raw_count(timers[i], &count_end_value)); + + // Error tolerance is 2% + TEST_ASSERT_UINT_WITHIN(random_time_ms / 50, random_time_ms, 1000 * (count_end_value - count_start_value) / (unsigned long long)timer_resolution_hz[i]); + + TEST_ESP_OK(gptimer_stop(timers[i])); + TEST_ESP_OK(gptimer_disable(timers[i])); + TEST_ESP_OK(gptimer_del_timer(timers[i])); + TEST_ESP_OK(sleep_cpu_configure(false)); + } +} + +TEST_CASE("gptimer context kept after peripheral powerdown lightsleep with backup_before_sleep enable", "[gptimer]") +{ + printf("install gptimer driver\r\n"); + gptimer_config_t timer_config = { + .resolution_hz = 10 * 1000, // 10KHz, 1 tick = 0.1ms + .clk_src = GPTIMER_CLK_SRC_DEFAULT, + .direction = GPTIMER_COUNT_UP, + .flags.backup_before_sleep = true + }; + + test_gptimer_retention(&timer_config); +} + +TEST_CASE("gptimer context kept after peripheral powerdown lightsleep with backup_before_sleep disable", "[gptimer]") +{ + printf("install gptimer driver\r\n"); + gptimer_config_t timer_config = { + .resolution_hz = 10 * 1000, // 10KHz, 1 tick = 0.1ms + .clk_src = GPTIMER_CLK_SRC_DEFAULT, + .direction = GPTIMER_COUNT_UP, + .flags.backup_before_sleep = false + }; + + test_gptimer_retention(&timer_config); +} +#endif diff --git a/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release index 199b0cf97c3e..05634936f485 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release +++ b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release @@ -4,3 +4,6 @@ CONFIG_PM_DFS_INIT_AUTO=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +# For TASK WDT timer PD_TOP sleep retention test +CONFIG_ESP_SLEEP_DEBUG=y +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y diff --git a/components/esp_driver_i2c/i2c_common.c b/components/esp_driver_i2c/i2c_common.c index f0daf1a3b8c5..8c3f86952e00 100644 --- a/components/esp_driver_i2c/i2c_common.c +++ b/components/esp_driver_i2c/i2c_common.c @@ -52,7 +52,7 @@ static esp_err_t s_i2c_sleep_retention_init(void *arg) { i2c_bus_t *bus = (i2c_bus_t *)arg; i2c_port_num_t port_num = bus->port_num; - esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[port_num].link_list, i2c_regs_retention[port_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(port_num)); + esp_err_t ret = sleep_retention_entries_create(i2c_regs_retention[port_num].link_list, i2c_regs_retention[port_num].link_num, REGDMA_LINK_PRI_I2C, I2C_SLEEP_RETENTION_MODULE(port_num)); ESP_RETURN_ON_ERROR(ret, TAG, "failed to allocate mem for sleep retention"); return ret; } diff --git a/components/esp_driver_i2c/i2c_master.c b/components/esp_driver_i2c/i2c_master.c index 4ee7c2b409e6..34a7106ef9fb 100644 --- a/components/esp_driver_i2c/i2c_master.c +++ b/components/esp_driver_i2c/i2c_master.c @@ -425,6 +425,8 @@ static void s_i2c_send_commands(i2c_master_bus_handle_t i2c_master, TickType_t t i2c_master->cmd_idx = 0; i2c_master->trans_idx = 0; atomic_store(&i2c_master->status, I2C_STATUS_TIMEOUT); + ESP_LOGE(TAG, "I2C software timeout"); + xSemaphoreGive(i2c_master->cmd_semphr); return; } diff --git a/components/esp_driver_i2s/Kconfig b/components/esp_driver_i2s/Kconfig index b3413eafb4ba..72628d820e3d 100644 --- a/components/esp_driver_i2s/Kconfig +++ b/components/esp_driver_i2s/Kconfig @@ -7,12 +7,6 @@ menu "ESP-Driver:I2S Configurations" Ensure the I2S interrupt is IRAM-Safe by allowing the interrupt handler to be executable when the cache is disabled (e.g. SPI Flash write). - config I2S_SUPPRESS_DEPRECATE_WARN - bool "Suppress legacy driver deprecated warning" - default n - help - Enable this option will suppress the deprecation warnings of using APIs in legacy I2S driver. - config I2S_ENABLE_DEBUG_LOG bool "Enable I2S debug log" default n diff --git a/components/esp_driver_i2s/i2s_common.c b/components/esp_driver_i2s/i2s_common.c index 7bd6cddd6d79..55bb984661d4 100644 --- a/components/esp_driver_i2s/i2s_common.c +++ b/components/esp_driver_i2s/i2s_common.c @@ -54,7 +54,6 @@ #include "esp_intr_alloc.h" #include "esp_check.h" #include "esp_attr.h" -#include "esp_dma_utils.h" #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #include "esp_cache.h" #endif @@ -69,16 +68,9 @@ static const char *TAG = "i2s_common"; __attribute__((always_inline)) -inline void *i2s_dma_calloc(i2s_chan_handle_t handle, size_t num, size_t size, size_t *actual_size) +inline void *i2s_dma_calloc(i2s_chan_handle_t handle, size_t num, size_t size) { - void *ptr = NULL; - esp_dma_mem_info_t dma_mem_info = { - .extra_heap_caps = I2S_DMA_ALLOC_CAPS, - .dma_alignment_bytes = 4, - }; - //TODO: IDF-9636 - esp_dma_capable_calloc(num, size, &dma_mem_info, &ptr, actual_size); - return ptr; + return heap_caps_aligned_calloc(4, num, size, I2S_DMA_ALLOC_CAPS); } /*--------------------------------------------------------------------------- @@ -425,10 +417,9 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu handle->dma.desc = (lldesc_t **)heap_caps_calloc(num, sizeof(lldesc_t *), I2S_MEM_ALLOC_CAPS); ESP_GOTO_ON_FALSE(handle->dma.desc, ESP_ERR_NO_MEM, err, TAG, "create I2S DMA descriptor array failed"); handle->dma.bufs = (uint8_t **)heap_caps_calloc(num, sizeof(uint8_t *), I2S_MEM_ALLOC_CAPS); - size_t desc_size = 0; for (int i = 0; i < num; i++) { /* Allocate DMA descriptor */ - handle->dma.desc[i] = (lldesc_t *) i2s_dma_calloc(handle, 1, sizeof(lldesc_t), &desc_size); + handle->dma.desc[i] = (lldesc_t *) i2s_dma_calloc(handle, 1, sizeof(lldesc_t)); ESP_GOTO_ON_FALSE(handle->dma.desc[i], ESP_ERR_NO_MEM, err, TAG, "allocate DMA description failed"); handle->dma.desc[i]->owner = 1; handle->dma.desc[i]->eof = 1; @@ -436,7 +427,7 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu handle->dma.desc[i]->length = bufsize; handle->dma.desc[i]->size = bufsize; handle->dma.desc[i]->offset = 0; - handle->dma.bufs[i] = (uint8_t *) i2s_dma_calloc(handle, 1, bufsize * sizeof(uint8_t), NULL); + handle->dma.bufs[i] = (uint8_t *) i2s_dma_calloc(handle, 1, bufsize * sizeof(uint8_t)); ESP_GOTO_ON_FALSE(handle->dma.bufs[i], ESP_ERR_NO_MEM, err, TAG, "allocate DMA buffer failed"); #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE esp_cache_msync(handle->dma.bufs[i], bufsize * sizeof(uint8_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M); @@ -449,7 +440,7 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu /* Link to the next descriptor */ STAILQ_NEXT(handle->dma.desc[i], qe) = (i < (num - 1)) ? (handle->dma.desc[i + 1]) : handle->dma.desc[0]; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - esp_cache_msync(handle->dma.desc[i], desc_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + esp_cache_msync(handle->dma.desc[i], sizeof(lldesc_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); #endif } if (handle->dir == I2S_DIR_RX) { @@ -696,6 +687,7 @@ static void IRAM_ATTR i2s_dma_tx_callback(void *arg) */ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) { + esp_err_t ret = ESP_OK; i2s_port_t port_id = handle->controller->id; ESP_RETURN_ON_FALSE((port_id >= 0) && (port_id < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "invalid handle"); #if SOC_GDMA_SUPPORTED @@ -703,14 +695,22 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) gdma_trigger_t trig = {.periph = GDMA_TRIG_PERIPH_I2S}; switch (port_id) { +#if SOC_I2S_NUM > 2 + case I2S_NUM_2: + trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S2; + break; +#endif #if SOC_I2S_NUM > 1 case I2S_NUM_1: trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S1; break; #endif - default: + case I2S_NUM_0: trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S0; break; + default: + ESP_LOGE(TAG, "Unsupported I2S port number"); + return ESP_ERR_NOT_SUPPORTED; } /* Set GDMA config */ @@ -719,18 +719,18 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) dma_cfg.direction = GDMA_CHANNEL_DIRECTION_TX; /* Register a new GDMA tx channel */ ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register tx dma channel error"); - ESP_RETURN_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), TAG, "Connect tx dma channel error"); + ESP_GOTO_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), err1, TAG, "Connect tx dma channel error"); gdma_tx_event_callbacks_t cb = {.on_trans_eof = i2s_dma_tx_callback}; /* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */ - gdma_register_tx_event_callbacks(handle->dma.dma_chan, &cb, handle); + ESP_GOTO_ON_ERROR(gdma_register_tx_event_callbacks(handle->dma.dma_chan, &cb, handle), err2, TAG, "Register tx callback failed"); } else { dma_cfg.direction = GDMA_CHANNEL_DIRECTION_RX; /* Register a new GDMA rx channel */ ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register rx dma channel error"); - ESP_RETURN_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), TAG, "Connect rx dma channel error"); + ESP_GOTO_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), err1, TAG, "Connect rx dma channel error"); gdma_rx_event_callbacks_t cb = {.on_recv_eof = i2s_dma_rx_callback}; /* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */ - gdma_register_rx_event_callbacks(handle->dma.dma_chan, &cb, handle); + ESP_GOTO_ON_ERROR(gdma_register_rx_event_callbacks(handle->dma.dma_chan, &cb, handle), err2, TAG, "Register rx callback failed"); } #else intr_flag |= handle->intr_prio_flags; @@ -747,7 +747,15 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) /* Start DMA */ i2s_ll_enable_dma(handle->controller->hal.dev, true); #endif // SOC_GDMA_SUPPORTED - return ESP_OK; + return ret; +#if SOC_GDMA_SUPPORTED +err2: + gdma_disconnect(handle->dma.dma_chan); +err1: + gdma_del_channel(handle->dma.dma_chan); + handle->dma.dma_chan = NULL; + return ret; +#endif } static uint64_t s_i2s_get_pair_chan_gpio_mask(i2s_chan_handle_t handle) diff --git a/components/esp_driver_i2s/i2s_private.h b/components/esp_driver_i2s/i2s_private.h index 0f6e388e8cde..3675d29897ea 100644 --- a/components/esp_driver_i2s/i2s_private.h +++ b/components/esp_driver_i2s/i2s_private.h @@ -38,7 +38,7 @@ extern "C" { #define I2S_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) #define I2S_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT #endif //CONFIG_I2S_ISR_IRAM_SAFE -#define I2S_DMA_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA) +#define I2S_DMA_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT) #if SOC_PERIPH_CLK_CTRL_SHARED #define I2S_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() diff --git a/components/esp_driver_i2s/include/driver/i2s_types.h b/components/esp_driver_i2s/include/driver/i2s_types.h index 2135124389cd..9f103f0718c8 100644 --- a/components/esp_driver_i2s/include/driver/i2s_types.h +++ b/components/esp_driver_i2s/include/driver/i2s_types.h @@ -22,6 +22,9 @@ typedef enum { I2S_NUM_0 = 0, /*!< I2S controller port 0 */ #if SOC_I2S_NUM > 1 I2S_NUM_1 = 1, /*!< I2S controller port 1 */ +#endif +#if SOC_I2S_NUM > 2 + I2S_NUM_2 = 2, /*!< I2S controller port 2 */ #endif I2S_NUM_AUTO, /*!< Select whichever port is available */ } i2s_port_t; diff --git a/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c b/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c index 5cb9489b5dcf..93aca31233a7 100644 --- a/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c +++ b/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c @@ -190,7 +190,21 @@ TEST_CASE("I2S_basic_channel_allocation_reconfig_deleting_test", "[i2s]") TEST_ESP_OK(i2s_channel_enable(tx_handle)); TEST_ESP_OK(i2s_channel_disable(tx_handle)); TEST_ESP_OK(i2s_del_channel(tx_handle)); - TEST_ASSERT(i2s_channel_get_info(tx_handle, &chan_info) == ESP_ERR_NOT_FOUND); + TEST_ESP_ERR(ESP_ERR_NOT_FOUND, i2s_channel_get_info(tx_handle, &chan_info)); + + /* Exhaust test */ + std_cfg.gpio_cfg.mclk = -1; + i2s_chan_handle_t tx_ex[SOC_I2S_NUM] = {}; + for (int i = 0; i < SOC_I2S_NUM; i++) { + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_ex[i], NULL)); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_ex[i], &std_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_ex[i])); + } + TEST_ESP_ERR(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + for (int i = 0; i < SOC_I2S_NUM; i++) { + TEST_ESP_OK(i2s_channel_disable(tx_ex[i])); + TEST_ESP_OK(i2s_del_channel(tx_ex[i])); + } /* Duplex channel basic test */ chan_cfg.id = I2S_NUM_0; // Specify port id to I2S port 0 @@ -208,7 +222,7 @@ TEST_CASE("I2S_basic_channel_allocation_reconfig_deleting_test", "[i2s]") /* Hold the occupation */ TEST_ESP_OK(i2s_platform_acquire_occupation(I2S_NUM_0, "test_i2s")); - TEST_ASSERT(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle) == ESP_ERR_NOT_FOUND); + TEST_ESP_ERR(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); TEST_ESP_OK(i2s_platform_release_occupation(I2S_NUM_0)); TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); TEST_ESP_OK(i2s_del_channel(tx_handle)); diff --git a/components/esp_driver_isp/CMakeLists.txt b/components/esp_driver_isp/CMakeLists.txt index b75c9bfc4a86..b3b04938f62a 100644 --- a/components/esp_driver_isp/CMakeLists.txt +++ b/components/esp_driver_isp/CMakeLists.txt @@ -1,12 +1,30 @@ +idf_build_get_property(target IDF_TARGET) + set(srcs) set(public_include "include") +set(priv_requires "esp_driver_gpio") + +set(requires) + if(CONFIG_SOC_ISP_SUPPORTED) - list(APPEND srcs "src/isp.c" - "src/isp_af.c") + list(APPEND srcs "src/isp_core.c" + "src/isp_af.c" + "src/isp_ccm.c" + "src/isp_awb.c") +endif() + +if(CONFIG_SOC_ISP_BF_SUPPORTED) + list(APPEND srcs "src/isp_bf.c") +endif() + +if(NOT ${target} STREQUAL "linux") + list(APPEND requires esp_mm) endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${public_include} + REQUIRES ${requires} + PRIV_REQUIRES ${priv_requires} ) diff --git a/components/esp_driver_isp/include/driver/isp.h b/components/esp_driver_isp/include/driver/isp.h index 436ba24dbe2d..7a36bb172c78 100644 --- a/components/esp_driver_isp/include/driver/isp.h +++ b/components/esp_driver_isp/include/driver/isp.h @@ -4,84 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -#pragma once - -#include -#include -#include "esp_err.h" -#include "driver/isp_types.h" -#include "driver/isp_af.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief ISP configurations - */ -typedef struct { - isp_clk_src_t clk_src; ///< Clock source - uint32_t clk_hz; ///< Clock frequency in Hz, suggest twice higher than cam sensor speed - isp_input_data_source_t input_data_source; ///< Input data source - isp_color_t input_data_color_type; ///< Input color type - isp_color_t output_data_color_type; ///< Output color type - bool has_line_start_packet; ///< Enable line start packet - bool has_line_end_packet; ///< Enable line end packet - uint32_t h_res; ///< Input horizontal resolution, i.e. the number of pixels in a line - uint32_t v_res; ///< Input vertical resolution, i.e. the number of lines in a frame -} esp_isp_processor_cfg_t; - -/** - * @brief New an ISP processor - * - * @param[in] proc_config Pointer to ISP config. Refer to ``esp_isp_processor_cfg_t``. - * @param[out] ret_proc Processor handle - * - * @return - * - ESP_OK On success - * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. - * - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags - * - ESP_ERR_NOT_SUPPORTED Not supported mode - * - ESP_ERR_NO_MEM If out of memory - */ -esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_proc_handle_t *ret_proc); - /** - * @brief Delete an ISP processor - * - * @param[in] proc Processor handle - * - * @return - * - ESP_OK On success - * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. - * - ESP_ERR_INVALID_STATE Driver state is invalid. - */ -esp_err_t esp_isp_del_processor(isp_proc_handle_t proc); - -/** - * @brief Enable an ISP processor - * - * @param[in] proc Processor handle - * - * @return - * - ESP_OK On success - * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. - * - ESP_ERR_INVALID_STATE Driver state is invalid. + * @brief ISP peripheral contains many submodules, whose drivers are scattered in different header files. + * This header file serves as a prelude, contains every thing that is needed to work with the ISP peripheral. */ -esp_err_t esp_isp_enable(isp_proc_handle_t proc); -/** - * @brief Disable an ISP processor - * - * @param[in] proc Processor handle - * - * @return - * - ESP_OK On success - * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. - * - ESP_ERR_INVALID_STATE Driver state is invalid. - */ -esp_err_t esp_isp_disable(isp_proc_handle_t proc); +#pragma once -#ifdef __cplusplus -} -#endif +#include "driver/isp_core.h" +#include "driver/isp_af.h" +#include "driver/isp_awb.h" +#include "driver/isp_bf.h" +#include "driver/isp_ccm.h" diff --git a/components/esp_driver_isp/include/driver/isp_af.h b/components/esp_driver_isp/include/driver/isp_af.h index 9e448b133f4a..67bfa58b52e7 100644 --- a/components/esp_driver_isp/include/driver/isp_af.h +++ b/components/esp_driver_isp/include/driver/isp_af.h @@ -10,8 +10,6 @@ #include #include "esp_err.h" #include "driver/isp_types.h" -#include "driver/isp.h" -#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { @@ -21,10 +19,9 @@ extern "C" { * @brief AF controller config */ typedef struct { -#if SOC_ISP_AF_WINDOW_NUMS - isp_af_window_t window[SOC_ISP_AF_WINDOW_NUMS]; ///< AF window settings -#endif + isp_window_t window[ISP_AF_WINDOW_NUM]; ///< The sampling windows of AF int edge_thresh; ///< Edge threshold, definition higher than this value will be counted as a valid pixel for calculating AF result + int intr_priority; ///< The interrupt priority, range 0~7, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) otherwise the larger the higher, 7 is NMI } esp_isp_af_config_t; /** @@ -41,7 +38,7 @@ typedef struct { * - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags * - ESP_ERR_NO_MEM If out of memory */ -esp_err_t esp_isp_new_af_controller(isp_proc_handle_t isp_proc, const esp_isp_af_config_t *af_config, isp_af_ctrlr_t *ret_hdl); +esp_err_t esp_isp_new_af_controller(isp_proc_handle_t isp_proc, const esp_isp_af_config_t *af_config, isp_af_ctlr_t *ret_hdl); /** * @brief Delete an ISP AF controller @@ -53,7 +50,7 @@ esp_err_t esp_isp_new_af_controller(isp_proc_handle_t isp_proc, const esp_isp_af * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. * - ESP_ERR_INVALID_STATE Driver state is invalid. */ -esp_err_t esp_isp_del_af_controller(isp_af_ctrlr_t af_ctrlr); +esp_err_t esp_isp_del_af_controller(isp_af_ctlr_t af_ctrlr); /** * @brief Enable an ISP AF controller @@ -65,7 +62,7 @@ esp_err_t esp_isp_del_af_controller(isp_af_ctrlr_t af_ctrlr); * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. * - ESP_ERR_INVALID_STATE Driver state is invalid. */ -esp_err_t esp_isp_af_controller_enable(isp_af_ctrlr_t af_ctrlr); +esp_err_t esp_isp_af_controller_enable(isp_af_ctlr_t af_ctrlr); /** * @brief Disable an ISP AF controller @@ -77,20 +74,60 @@ esp_err_t esp_isp_af_controller_enable(isp_af_ctrlr_t af_ctrlr); * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. * - ESP_ERR_INVALID_STATE Driver state is invalid. */ -esp_err_t esp_isp_af_controller_disable(isp_af_ctrlr_t af_ctrlr); +esp_err_t esp_isp_af_controller_disable(isp_af_ctlr_t af_ctrlr); + +/** + * @brief Trigger AF luminance and definition statistics for one time and get the result + * @note This function is a synchronous and block function, + * it only returns when AF luminance and definition statistics is done or timeout. + * It's a simple method to get the result directly for one time. + * + * @param[in] af_ctrlr AF controller handle + * @param[in] timeout_ms Timeout in millisecond + * - timeout_ms < 0: Won't return until finished + * - timeout_ms = 0: No timeout, trigger one time statistics and return immediately, + * in this case, the result won't be assigned in this function, + * but you can get the result in the callback `esp_isp_af_env_detector_evt_cbs_t::on_env_statistics_done` + * - timeout_ms > 0: Wait for specified milliseconds, if not finished, then return timeout error + * @param[out] out_res AF luminance and definition statistics result, can be NULL if `timeout_ms = 0` + * + * @return + * - ESP_OK On success + * - ESP_ERR_TIMEOUT If the waiting time exceeds the specified timeout. + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_af_controller_get_oneshot_statistics(isp_af_ctlr_t af_ctrlr, int timeout_ms, isp_af_result_t *out_res); + +/** @cond */ +#define esp_isp_af_controller_get_oneshot_result(af_ctrlr, out_res) \ + esp_isp_af_controller_get_oneshot_statistics(af_ctrlr, -1, out_res) // Alias +/** @endcond */ /** - * @brief Get AF result + * @brief Start AF continuous statistics of the luminance and definition in the windows + * @note This function is an asynchronous and non-block function, + * it will start the continuous statistics and return immediately. + * You have to register the AF callback and get the result from the callback event data. * * @param[in] af_ctrlr AF controller handle - * @param[out] out_res AF result + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Null pointer + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_af_controller_start_continuous_statistics(isp_af_ctlr_t af_ctrlr); + +/** + * @brief Stop AF continuous statistics of the luminance and definition in the windows * + * @param[in] af_ctrlr AF controller handle * @return * - ESP_OK On success - * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_ARG Null pointer * - ESP_ERR_INVALID_STATE Driver state is invalid. */ -esp_err_t esp_isp_af_controller_get_oneshot_result(isp_af_ctrlr_t af_ctrlr, isp_af_result_t *out_res); +esp_err_t esp_isp_af_controller_stop_continuous_statistics(isp_af_ctlr_t af_ctrlr); /*--------------------------------------------- AF Env Monitor @@ -99,7 +136,9 @@ esp_err_t esp_isp_af_controller_get_oneshot_result(isp_af_ctrlr_t af_ctrlr, isp_ * @brief AF environment detector config */ typedef struct { - int interval; ///< Interval between environment detection, in frames + int interval; /*!< Interval between environment detection, in frames. + * i.e., AF controller will trigger the statistic periodically to detect the environment change. + */ } esp_isp_af_env_config_t; /** @@ -113,7 +152,7 @@ typedef struct { * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. * - ESP_ERR_INVALID_STATE Driver state is invalid. */ -esp_err_t esp_isp_af_controller_set_env_detector(isp_af_ctrlr_t af_ctrlr, const esp_isp_af_env_config_t *env_config); +esp_err_t esp_isp_af_controller_set_env_detector(isp_af_ctlr_t af_ctrlr, const esp_isp_af_env_config_t *env_config); /** * @brief Set ISP AF environment detector detecting threshold @@ -127,25 +166,25 @@ esp_err_t esp_isp_af_controller_set_env_detector(isp_af_ctrlr_t af_ctrlr, const * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. * - ESP_ERR_INVALID_STATE Driver state is invalid. */ -esp_err_t esp_isp_af_controller_set_env_detector_threshold(isp_af_ctrlr_t af_ctrlr, int definition_thresh, int luminance_thresh); +esp_err_t esp_isp_af_controller_set_env_detector_threshold(isp_af_ctlr_t af_ctrlr, int definition_thresh, int luminance_thresh); /** * @brief Event data structure */ typedef struct { - //empty for future proof + isp_af_result_t af_result; /*!< The AF statistics result */ } esp_isp_af_env_detector_evt_data_t; /** * @brief Prototype of ISP AF Env detector event callback * - * @param[in] handle ISP AF controller handle + * @param[in] af_ctrlr ISP AF controller handle * @param[in] edata ISP AF Env detector event data * @param[in] user_data User registered context, registered when in `esp_isp_af_env_detector_register_event_callbacks()` * * @return Whether a high priority task is woken up by this function */ -typedef bool (*esp_isp_af_env_detector_callback_t)(isp_af_ctrlr_t af_ctrlr, const esp_isp_af_env_detector_evt_data_t *edata, void *user_data); +typedef bool (*esp_isp_af_env_detector_callback_t)(isp_af_ctlr_t af_ctrlr, const esp_isp_af_env_detector_evt_data_t *edata, void *user_data); /** * @brief Group of ISP AF Env detector callbacks @@ -155,7 +194,8 @@ typedef bool (*esp_isp_af_env_detector_callback_t)(isp_af_ctrlr_t af_ctrlr, cons * Involved variables should be in internal RAM as well. */ typedef struct { - esp_isp_af_env_detector_callback_t on_env_change; ///< Event callback, invoked when environment change happens. + esp_isp_af_env_detector_callback_t on_env_statistics_done; ///< Event callback, invoked when environment sample done. + esp_isp_af_env_detector_callback_t on_env_change; ///< Event callback, invoked when environment change happens. } esp_isp_af_env_detector_evt_cbs_t; /** @@ -175,7 +215,7 @@ typedef struct { * - ESP_ERR_INVALID_ARG: Invalid arguments * - ESP_ERR_INVALID_STATE: Driver state is invalid, you shouldn't call this API at this moment */ -esp_err_t esp_isp_af_env_detector_register_event_callbacks(isp_af_ctrlr_t af_ctrlr, const esp_isp_af_env_detector_evt_cbs_t *cbs, void *user_data); +esp_err_t esp_isp_af_env_detector_register_event_callbacks(isp_af_ctlr_t af_ctrlr, const esp_isp_af_env_detector_evt_cbs_t *cbs, void *user_data); #ifdef __cplusplus } diff --git a/components/esp_driver_isp/include/driver/isp_awb.h b/components/esp_driver_isp/include/driver/isp_awb.h new file mode 100644 index 000000000000..ee85513e947b --- /dev/null +++ b/components/esp_driver_isp/include/driver/isp_awb.h @@ -0,0 +1,220 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" +#include "driver/isp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief AWB controller config + */ +typedef struct { + isp_awb_sample_point_t sample_point; /*!< AWB sample point of the ISP pipeline. + * ISP_AWB_SAMPLE_POINT_BEFORE_CCM: sample before Color Correction Matrix(CCM). + * ISP_AWB_SAMPLE_POINT_AFTER_CCM: sample after Color Correction Matrix(CCM). + * If your camera support to set the manual gain to the RGB channels, + * then you can choose to sample before CCM, and set the gain to the camera registers. + * If your camera doesn't support the manual gain or don't want to change the camera configuration, + * then you can choose to sample after CCM, and set the calculated gain to the CCM + */ + isp_window_t window; /*!< Statistic window of AWB. + * Suggest to set it at the middle of the image and a little smaller than the whole image. + * It will be more reliable because the edges of image are easily to be overexposure, + * the overexposure pixels are almost at maximum luminance, + * which are not good references to calculate the gain for white balance. + */ + struct { + isp_u32_range_t luminance; /*!< Luminance range of the white patch. Range [0, 255 * 3] + * Not suggest to set the max value to 255 * 3, + * because these pixels are too bright, very possible to be overexposure. + * So the pixels that too bright should not be the reference of the white balance. + * And the minimum value better to be 0 to allow the white balance work under low luminance environment. + */ + isp_float_range_t red_green_ratio; /*!< Red to green ratio of the white patch. Range [0, 4.0). + * The ratio could be as wider as possible, + * so that all the distorted pixels will be counted for the reference of white balance. + */ + isp_float_range_t blue_green_ratio; /*!< Blue to green ratio of the white patch. Range [0, 4.0) + * The ratio could be as wider as possible, + * so that all the distorted pixels will be counted for the reference of white balance. + */ + } white_patch; /*!< white patch configuration */ + int intr_priority; /*!< The interrupt priority, range 0~3, if set to 0, the driver will try to allocate an interrupt with + * a relative low priority (1,2,3) + */ +} esp_isp_awb_config_t; + +/** + * @brief New an ISP AWB controller + * + * @param[in] isp_proc ISP Processor handle + * @param[in] awb_cfg Pointer to AWB config. Refer to ``esp_isp_awb_config_t``. + * @param[out] ret_hdl AWB controller handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid + * - ESP_ERR_INVALID_STATE Invalid state + * - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags + * - ESP_ERR_NO_MEM If out of memory + */ +esp_err_t esp_isp_new_awb_controller(isp_proc_handle_t isp_proc, const esp_isp_awb_config_t *awb_cfg, isp_awb_ctlr_t *ret_hdl); + +/** + * @brief Delete an ISP AWB controller + * + * @param[in] awb_ctlr AWB controller handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_del_awb_controller(isp_awb_ctlr_t awb_ctlr); + +/** + * @brief Reconfigure the ISP AWB controller + * @note This function is allowed to be called no matter the awb controller is enabled or not. + * + * @param[in] awb_ctlr AWB controller handle + * @param[in] awb_cfg Pointer to AWB config. Refer to ``esp_isp_awb_config_t`` + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid + */ +esp_err_t esp_isp_awb_controller_reconfig(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_config_t *awb_cfg); + +/** + * @brief Enable an ISP AWB controller + * + * @param[in] awb_ctlr AWB controller handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_awb_controller_enable(isp_awb_ctlr_t awb_ctlr); + +/** + * @brief Disable an ISP AWB controller + * + * @param[in] awb_ctlr AWB controller handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_awb_controller_disable(isp_awb_ctlr_t awb_ctlr); + +/** + * @brief Trigger AWB white patch statistics for one time and get the result + * @note This function is a synchronous and block function, + * it only returns when AWB white patch statistics is done or timeout. + * It's a simple method to get the result directly for one time. + * + * @param[in] awb_ctlr AWB controller handle + * @param[in] timeout_ms Timeout in millisecond + * - timeout_ms < 0: Won't return until finished + * - timeout_ms = 0: No timeout, trigger one time statistics and return immediately, + * in this case, the result won't be assigned in this function, + * but you can get the result in the callback `esp_isp_awb_cbs_t::on_statistics_done` + * - timeout_ms > 0: Wait for specified milliseconds, if not finished, then return timeout error + * @param[out] out_res AWB white patch statistics result + * + * @return + * - ESP_OK On success + * - ESP_ERR_TIMEOUT Wait for the result timeout + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_awb_controller_get_oneshot_statistics(isp_awb_ctlr_t awb_ctlr, int timeout_ms, isp_awb_stat_result_t *out_res); + +/** + * @brief Start AWB continuous statistics of the white patch in the window + * @note This function is an asynchronous and non-block function, + * it will start the continuous statistics and return immediately. + * You have to register the AWB callback and get the result from the callback event data. + * + * @param[in] awb_ctlr AWB controller handle + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Null pointer + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_awb_controller_start_continuous_statistics(isp_awb_ctlr_t awb_ctlr); + +/** + * @brief Stop AWB continuous statistics of the white patch in the window + * + * @param[in] awb_ctlr AWB controller handle + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Null pointer + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_awb_controller_stop_continuous_statistics(isp_awb_ctlr_t awb_ctlr); + +/** + * @brief Event data of callbacks + */ +typedef struct { + isp_awb_stat_result_t awb_result; /*!< The AWB white patch statistics result */ +} esp_isp_awb_evt_data_t; + +/** + * @brief Prototype of ISP AWB event callback + * + * @param[in] awb_ctlr ISP AWB controller handle + * @param[in] edata ISP AWB event data + * @param[in] user_data User registered context, registered when in `esp_isp_awb_env_detector_register_event_callbacks()` + * + * @return Whether a high priority task is woken up by this function + */ +typedef bool (*esp_isp_awb_callback_t)(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_evt_data_t *edata, void *user_data); + +/** + * @brief Group of ISP AWB callbacks + * + * @note These callbacks are all running in an ISR environment. + * @note When CONFIG_ISP_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. + * Involved variables should be in internal RAM as well. + */ +typedef struct { + esp_isp_awb_callback_t on_statistics_done; ///< Event callback, invoked when white patches statistic done. +} esp_isp_awb_cbs_t; + +/** + * @brief Register AWB event callbacks + * + * @note User can deregister a previously registered callback by calling this function and setting the to-be-deregistered callback member in + * the `cbs` structure to NULL. + * @note When CONFIG_ISP_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. + * Involved variables (including `user_data`) should be in internal RAM as well. + * + * @param[in] awb_ctlr AWB controller handle + * @param[in] cbs Group of callback functions + * @param[in] user_data User data, which will be delivered to the callback functions directly + * + * @return + * - ESP_OK: On success + * - ESP_ERR_INVALID_ARG: Invalid arguments + * - ESP_ERR_INVALID_STATE: Driver state is invalid, you shouldn't call this API at this moment + */ +esp_err_t esp_isp_awb_register_event_callbacks(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_cbs_t *cbs, void *user_data); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_isp/include/driver/isp_bf.h b/components/esp_driver_isp/include/driver/isp_bf.h new file mode 100644 index 000000000000..b1301301a9af --- /dev/null +++ b/components/esp_driver_isp/include/driver/isp_bf.h @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" +#include "driver/isp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief ISP BF configurations + */ +typedef struct { + isp_bf_edge_padding_mode_t padding_mode; ///< BF edge padding mode + uint8_t padding_data; ///< BF edge padding pixel data + uint8_t bf_template[ISP_BF_TEMPLATE_X_NUMS][ISP_BF_TEMPLATE_Y_NUMS]; ///< BF template data + uint8_t denoising_level; ///< BF denoising level, from 2 to 20, the bigger the better denoising performance, but the worse detailed + uint8_t padding_line_tail_valid_start_pixel; ///< BF edge padding line tail valid start pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid + uint8_t padding_line_tail_valid_end_pixel; ///< BF edge padding line tail valid end pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid +} esp_isp_bf_config_t; + +/** + * @brief ISP BF configuration + * + * @note After calling this API, BF doesn't take into effect until `esp_isp_bf_enable` is called + * + * @param[in] proc Processor handle + * @param[in] config BF configurations, set NULL to de-configure the ISP BF + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_STATE Not allowed to be called under current state + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid + */ +esp_err_t esp_isp_bf_configure(isp_proc_handle_t proc, const esp_isp_bf_config_t *config); + +/** + * @brief Enable ISP BF function + * + * @param[in] proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_bf_enable(isp_proc_handle_t proc); + +/** + * @brief Disable ISP BF function + * + * @param[in] proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_bf_disable(isp_proc_handle_t proc); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_isp/include/driver/isp_ccm.h b/components/esp_driver_isp/include/driver/isp_ccm.h new file mode 100644 index 000000000000..451c69bcba07 --- /dev/null +++ b/components/esp_driver_isp/include/driver/isp_ccm.h @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" +#include "driver/isp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Color Correction Matrix configurations + * + */ +typedef struct { + float matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION]; /*!< The color correction matrix in float, range (-4.0, 4.0) */ + bool saturation; /*!< Whether to use saturation when the float data in the matrix is out of the range, + * For example, if one of the matrix data is 5.0, + * When saturation is true, and final value will be limited to 4.0, and won't rise error + * When saturation is false, `esp_isp_ccm_configure` will rise ESP_ERR_INVALID_ARG error + */ +} esp_isp_ccm_config_t; + +/** + * @brief ISP Color Correction Matrix (CCM) configuration + * + * @note This function is allowed to be called before or after `esp_isp_ccm_enable`, + * but it only takes effect until `esp_isp_ccm_enable` is called + * + * @param[in] proc Processor handle + * @param[in] ccm_cfg CCM configurations, set NULL to de-configure the ISP CCM + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid + */ +esp_err_t esp_isp_ccm_configure(isp_proc_handle_t proc, const esp_isp_ccm_config_t *ccm_cfg); + +/** + * @brief Enable ISP CCM function + * + * @param[in] proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + */ +esp_err_t esp_isp_ccm_enable(isp_proc_handle_t proc); + +/** + * @brief Disable ISP CCM function + * + * @param[in] proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + */ +esp_err_t esp_isp_ccm_disable(isp_proc_handle_t proc); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_isp/include/driver/isp_core.h b/components/esp_driver_isp/include/driver/isp_core.h new file mode 100644 index 000000000000..8081e945fe0d --- /dev/null +++ b/components/esp_driver_isp/include/driver/isp_core.h @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" +#include "driver/isp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief ISP configurations + */ +typedef struct { + isp_clk_src_t clk_src; ///< Clock source + uint32_t clk_hz; ///< Clock frequency in Hz, suggest twice higher than cam sensor speed + isp_input_data_source_t input_data_source; ///< Input data source + isp_color_t input_data_color_type; ///< Input color type + isp_color_t output_data_color_type; ///< Output color type + bool has_line_start_packet; ///< Enable line start packet + bool has_line_end_packet; ///< Enable line end packet + uint32_t h_res; ///< Input horizontal resolution, i.e. the number of pixels in a line + uint32_t v_res; ///< Input vertical resolution, i.e. the number of lines in a frame +} esp_isp_processor_cfg_t; + +/** + * @brief New an ISP processor + * + * @param[in] proc_config Pointer to ISP config. Refer to ``esp_isp_processor_cfg_t``. + * @param[out] ret_proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags + * - ESP_ERR_NOT_SUPPORTED Not supported mode + * - ESP_ERR_NO_MEM If out of memory + */ +esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_proc_handle_t *ret_proc); + +/** + * @brief Delete an ISP processor + * + * @param[in] proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_del_processor(isp_proc_handle_t proc); + +/** + * @brief Enable an ISP processor + * + * @param[in] proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_enable(isp_proc_handle_t proc); + +/** + * @brief Disable an ISP processor + * + * @param[in] proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. + * - ESP_ERR_INVALID_STATE Driver state is invalid. + */ +esp_err_t esp_isp_disable(isp_proc_handle_t proc); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_isp/include/driver/isp_types.h b/components/esp_driver_isp/include/driver/isp_types.h index 14e0f6568fee..ea171bb0927c 100644 --- a/components/esp_driver_isp/include/driver/isp_types.h +++ b/components/esp_driver_isp/include/driver/isp_types.h @@ -12,6 +12,42 @@ extern "C" { #endif +/** + * @brief ISP unsigned integer range type + * @note Whether the edge value are included depends on the variable itself + */ +typedef struct { + uint32_t min; ///< Minimum unsigned int value + uint32_t max; ///< Maximum unsigned int value +} isp_u32_range_t; + +/** + * @brief ISP float range type + * @note Whether the edge value are included depends on the variable itself + */ +typedef struct { + float min; ///< Minimum float value + float max; ///< Maximum float value +} isp_float_range_t; + +/** + * @brief ISP AF result + */ +typedef struct { + int definition[ISP_AF_WINDOW_NUM]; ///< Definition, it refers how clear and sharp an image is + int luminance[ISP_AF_WINDOW_NUM]; ///< Luminance, it refers how luminant an image is +} isp_af_result_t; + +/** + * @brief ISP AWB result + */ +typedef struct { + uint32_t white_patch_num; ///< white patch number that counted by AWB in the window + uint32_t sum_r; ///< The sum of R channel of these white patches + uint32_t sum_g; ///< The sum of G channel of these white patches + uint32_t sum_b; ///< The sum of B channel of these white patches +} isp_awb_stat_result_t; + /** * @brief Type of ISP processor handle */ @@ -20,7 +56,12 @@ typedef struct isp_processor_t *isp_proc_handle_t; /** * @brief Type of ISP AF controller handle */ -typedef struct isp_af_controller_t *isp_af_ctrlr_t; +typedef struct isp_af_controller_t *isp_af_ctlr_t; + +/** + * @brief Type of ISP AWB controller handle + */ +typedef struct isp_awb_controller_t *isp_awb_ctlr_t; #ifdef __cplusplus } diff --git a/components/esp_driver_isp/include/esp_private/isp_private.h b/components/esp_driver_isp/include/esp_private/isp_private.h new file mode 100644 index 000000000000..03b0f078434f --- /dev/null +++ b/components/esp_driver_isp/include/esp_private/isp_private.h @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "esp_intr_alloc.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/idf_additions.h" +#include "driver/isp_types.h" +#include "soc/soc_caps.h" +#if SOC_ISP_SUPPORTED +#include "hal/isp_hal.h" +#include "hal/isp_ll.h" +#include "hal/isp_types.h" +#include "soc/isp_periph.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_ISP_ISR_IRAM_SAFE +#define ISP_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_IRAM) +#define ISP_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#else +#define ISP_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_INTRDISABLED) +#define ISP_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT +#endif + +typedef enum { + ISP_FSM_INIT, + ISP_FSM_ENABLE, + ISP_FSM_START, +} isp_fsm_t; + +#if SOC_ISP_SUPPORTED +/*--------------------------------------------------------------- + Driver Context +---------------------------------------------------------------*/ +typedef struct isp_processor_t { + int proc_id; + isp_hal_context_t hal; +#if SOC_ISP_SHARE_CSI_BRG + int csi_brg_id; + void *csi_brg_hw; +#endif + isp_fsm_t isp_fsm; + portMUX_TYPE spinlock; + color_space_pixel_format_t in_color_format; + color_space_pixel_format_t out_color_format; + uint32_t h_res; + uint32_t v_res; + /* sub module contexts */ + isp_af_ctlr_t af_ctlr[SOC_ISP_AF_CTLR_NUMS]; + isp_awb_ctlr_t awb_ctlr; + isp_fsm_t bf_fsm; +} isp_processor_t; +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_isp/src/isp_af.c b/components/esp_driver_isp/src/isp_af.c index f2e0087a3d63..dd7ad8d4f3e1 100644 --- a/components/esp_driver_isp/src/isp_af.c +++ b/components/esp_driver_isp/src/isp_af.c @@ -11,23 +11,29 @@ #include "esp_check.h" #include "esp_heap_caps.h" #include "freertos/FreeRTOS.h" -#include "driver/isp.h" -#include "hal/isp_hal.h" -#include "hal/isp_ll.h" -#include "isp_internal.h" - -#if CONFIG_ISP_ISR_IRAM_SAFE -#define ISP_AF_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) -#else -#define ISP_AF_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT -#endif +#include "driver/isp_af.h" +#include "esp_private/isp_private.h" static const char *TAG = "ISP_AF"; +typedef struct isp_af_controller_t { + int id; + isp_fsm_t fsm; + portMUX_TYPE spinlock; + intr_handle_t intr_handle; + isp_proc_handle_t isp_proc; + QueueHandle_t evt_que; + esp_isp_af_env_config_t config; + esp_isp_af_env_detector_evt_cbs_t cbs; + void *user_data; +} isp_af_controller_t; + +static void s_isp_af_default_isr(void *arg); + /*--------------------------------------------- AF ----------------------------------------------*/ -static esp_err_t s_isp_claim_af_controller(isp_proc_handle_t isp_proc, isp_af_controller_t *af_ctlr) +static esp_err_t s_isp_claim_af_controller(isp_proc_handle_t isp_proc, isp_af_ctlr_t af_ctlr) { assert(isp_proc && af_ctlr); @@ -50,18 +56,29 @@ static esp_err_t s_isp_claim_af_controller(isp_proc_handle_t isp_proc, isp_af_co return ESP_OK; } -static esp_err_t s_isp_declaim_af_controller(isp_af_controller_t *af_ctlr) +static void s_isp_declaim_af_controller(isp_af_ctlr_t af_ctlr) { assert(af_ctlr && af_ctlr->isp_proc); portENTER_CRITICAL(&af_ctlr->isp_proc->spinlock); af_ctlr->isp_proc->af_ctlr[af_ctlr->id] = NULL; portEXIT_CRITICAL(&af_ctlr->isp_proc->spinlock); +} - return ESP_OK; +static void s_isp_af_free_controller(isp_af_ctlr_t af_ctlr) +{ + if (af_ctlr) { + if (af_ctlr->intr_handle) { + esp_intr_free(af_ctlr->intr_handle); + } + if (af_ctlr->evt_que) { + vQueueDelete(af_ctlr->evt_que); + } + free(af_ctlr); + } } -esp_err_t esp_isp_new_af_controller(isp_proc_handle_t isp_proc, const esp_isp_af_config_t *af_config, isp_af_ctrlr_t *ret_hdl) +esp_err_t esp_isp_new_af_controller(isp_proc_handle_t isp_proc, const esp_isp_af_config_t *af_config, isp_af_ctlr_t *ret_hdl) { esp_err_t ret = ESP_FAIL; ESP_RETURN_ON_FALSE(isp_proc && af_config && ret_hdl, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); @@ -71,30 +88,37 @@ esp_err_t esp_isp_new_af_controller(isp_proc_handle_t isp_proc, const esp_isp_af ESP_RETURN_ON_FALSE(demosaic_en && rgb2yuv_en, ESP_ERR_INVALID_STATE, TAG, "RGB2YUV not enabled, please update the output_data_color_type"); for (int i = 0; i < SOC_ISP_AF_WINDOW_NUMS; i++) { - ESP_LOGV(TAG, "af_config->window[%d].top_left_x: %"PRId32, i, af_config->window[i].top_left_x); - ESP_LOGV(TAG, "af_config->window[%d].bottom_right_x: %"PRId32, i, af_config->window[i].bottom_right_x); - ESP_LOGV(TAG, "af_config->window[%d].bottom_right_y: %"PRId32, i, af_config->window[i].bottom_right_y); - ESP_LOGV(TAG, "af_config->window[%d].top_left_y: %"PRId32, i, af_config->window[i].top_left_y); - - ESP_RETURN_ON_FALSE(((af_config->window[i].top_left_x < ISP_LL_AF_WINDOW_MAX_RANGE) && - (af_config->window[i].bottom_right_x >= af_config->window[i].top_left_x) && - (af_config->window[i].bottom_right_x < ISP_LL_AF_WINDOW_MAX_RANGE) && - (af_config->window[i].top_left_y < ISP_LL_AF_WINDOW_MAX_RANGE) && - (af_config->window[i].bottom_right_y >= af_config->window[i].top_left_y) && - (af_config->window[i].bottom_right_y < ISP_LL_AF_WINDOW_MAX_RANGE)), ESP_ERR_INVALID_ARG, TAG, "invalid window"); + ESP_LOGV(TAG, "af_config->window[%d].top_left.x: %"PRId32, i, af_config->window[i].top_left.x); + ESP_LOGV(TAG, "af_config->window[%d].btm_right.x: %"PRId32, i, af_config->window[i].btm_right.x); + ESP_LOGV(TAG, "af_config->window[%d].btm_right.y: %"PRId32, i, af_config->window[i].btm_right.y); + ESP_LOGV(TAG, "af_config->window[%d].top_left.y: %"PRId32, i, af_config->window[i].top_left.y); + + ESP_RETURN_ON_FALSE(((af_config->window[i].top_left.x < ISP_LL_AF_WINDOW_MAX_RANGE) && + (af_config->window[i].btm_right.x >= af_config->window[i].top_left.x) && + (af_config->window[i].btm_right.x < ISP_LL_AF_WINDOW_MAX_RANGE) && + (af_config->window[i].top_left.y < ISP_LL_AF_WINDOW_MAX_RANGE) && + (af_config->window[i].btm_right.y >= af_config->window[i].top_left.y) && + (af_config->window[i].btm_right.y < ISP_LL_AF_WINDOW_MAX_RANGE)), ESP_ERR_INVALID_ARG, TAG, "invalid window"); } ESP_RETURN_ON_FALSE(af_config->edge_thresh > 0, ESP_ERR_INVALID_ARG, TAG, "edge threshold should be larger than 0"); - isp_af_controller_t *af_ctlr = heap_caps_calloc(1, sizeof(isp_af_controller_t), ISP_AF_MEM_ALLOC_CAPS); + isp_af_ctlr_t af_ctlr = heap_caps_calloc(1, sizeof(isp_af_controller_t), ISP_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(af_ctlr, ESP_ERR_NO_MEM, TAG, "no mem"); - - //claim an AF controller - ESP_GOTO_ON_ERROR(s_isp_claim_af_controller(isp_proc, af_ctlr), err, TAG, "no available controller"); - + af_ctlr->evt_que = xQueueCreateWithCaps(1, sizeof(isp_af_result_t), ISP_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(af_ctlr->evt_que, ESP_ERR_NO_MEM, err1, TAG, "no mem for af event queue"); af_ctlr->fsm = ISP_FSM_INIT; af_ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; af_ctlr->isp_proc = isp_proc; + //claim an AF controller + ESP_GOTO_ON_ERROR(s_isp_claim_af_controller(isp_proc, af_ctlr), err1, TAG, "no available controller"); + + // Register the AF ISR + uint32_t intr_st_reg_addr = isp_ll_get_intr_status_reg_addr(isp_proc->hal.hw); + int intr_priority = af_config->intr_priority > 0 && af_config->intr_priority <= 7 ? BIT(af_config->intr_priority) : ESP_INTR_FLAG_LOWMED; + ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(isp_hw_info.instances[isp_proc->proc_id].irq, ISP_INTR_ALLOC_FLAGS | intr_priority, intr_st_reg_addr, ISP_LL_EVENT_AF_MASK, + s_isp_af_default_isr, af_ctlr, &af_ctlr->intr_handle), err2, TAG, "allocate interrupt failed"); + isp_ll_af_enable_auto_update(isp_proc->hal.hw, false); isp_ll_af_enable(isp_proc->hal.hw, false); @@ -109,54 +133,97 @@ esp_err_t esp_isp_new_af_controller(isp_proc_handle_t isp_proc, const esp_isp_af *ret_hdl = af_ctlr; return ESP_OK; - -err: - free(af_ctlr); +err2: + s_isp_declaim_af_controller(af_ctlr); +err1: + s_isp_af_free_controller(af_ctlr); return ret; } -esp_err_t esp_isp_del_af_controller(isp_af_ctrlr_t af_ctlr) +esp_err_t esp_isp_del_af_controller(isp_af_ctlr_t af_ctlr) { ESP_RETURN_ON_FALSE(af_ctlr && af_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); - ESP_RETURN_ON_ERROR(s_isp_declaim_af_controller(af_ctlr), TAG, "controller isn't in use"); ESP_RETURN_ON_FALSE(af_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state"); - - free(af_ctlr); + bool exist = false; + for (int i = 0; i < SOC_ISP_AF_CTLR_NUMS; i++) { + if (af_ctlr->isp_proc->af_ctlr[i] == af_ctlr) { + exist = true; + break; + } + } + ESP_RETURN_ON_FALSE(exist, ESP_ERR_INVALID_ARG, TAG, "controller isn't in use"); + s_isp_declaim_af_controller(af_ctlr); + s_isp_af_free_controller(af_ctlr); return ESP_OK; } -esp_err_t esp_isp_af_controller_enable(isp_af_ctrlr_t af_ctlr) +esp_err_t esp_isp_af_controller_enable(isp_af_ctlr_t af_ctlr) { ESP_RETURN_ON_FALSE(af_ctlr && af_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); ESP_RETURN_ON_FALSE(af_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state"); + esp_intr_enable(af_ctlr->intr_handle); isp_ll_af_clk_enable(af_ctlr->isp_proc->hal.hw, true); + isp_ll_enable_intr(af_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AF_MASK, true); isp_ll_af_enable(af_ctlr->isp_proc->hal.hw, true); af_ctlr->fsm = ISP_FSM_ENABLE; return ESP_OK; } -esp_err_t esp_isp_af_controller_disable(isp_af_ctrlr_t af_ctlr) +esp_err_t esp_isp_af_controller_disable(isp_af_ctlr_t af_ctlr) { ESP_RETURN_ON_FALSE(af_ctlr && af_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); ESP_RETURN_ON_FALSE(af_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "controller isn't in enable state"); isp_ll_af_clk_enable(af_ctlr->isp_proc->hal.hw, false); + isp_ll_enable_intr(af_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AF_MASK, false); isp_ll_af_enable(af_ctlr->isp_proc->hal.hw, false); + esp_intr_disable(af_ctlr->intr_handle); af_ctlr->fsm = ISP_FSM_INIT; return ESP_OK; } -esp_err_t esp_isp_af_controller_get_oneshot_result(isp_af_ctrlr_t af_ctlr, isp_af_result_t *out_res) +esp_err_t esp_isp_af_controller_get_oneshot_statistics(isp_af_ctlr_t af_ctrlr, int timeout_ms, isp_af_result_t *out_res) +{ + ESP_RETURN_ON_FALSE_ISR(af_ctrlr && (out_res || timeout_ms == 0), ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE_ISR(af_ctrlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "controller isn't enabled or continuous statistics has started"); + + esp_err_t ret = ESP_OK; + TickType_t ticks = timeout_ms < 0 ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms); + // Reset the queue in case receiving the legacy data in the queue + xQueueReset(af_ctrlr->evt_que); + // Trigger the AF statistics manually + isp_ll_af_manual_update(af_ctrlr->isp_proc->hal.hw); + // Wait the statistics to finish and receive the result from the queue + if ((ticks > 0) && xQueueReceive(af_ctrlr->evt_que, out_res, ticks) != pdTRUE) { + ret = ESP_ERR_TIMEOUT; + } + + return ret; +} + +esp_err_t esp_isp_af_controller_start_continuous_statistics(isp_af_ctlr_t af_ctrlr) +{ + ESP_RETURN_ON_FALSE_ISR(af_ctrlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE_ISR(af_ctrlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "controller isn't in enable state"); + + af_ctrlr->fsm = ISP_FSM_START; + isp_ll_af_enable_auto_update(af_ctrlr->isp_proc->hal.hw, true); + + return ESP_OK; +} + +esp_err_t esp_isp_af_controller_stop_continuous_statistics(isp_af_ctlr_t af_ctrlr) { - ESP_RETURN_ON_FALSE_ISR(af_ctlr && out_res, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); - ESP_RETURN_ON_FALSE_ISR(af_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "controller isn't in enable state"); + ESP_RETURN_ON_FALSE_ISR(af_ctrlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE_ISR(af_ctrlr->fsm == ISP_FSM_START, ESP_ERR_INVALID_STATE, TAG, "controller isn't in continuous state"); - isp_hal_af_get_oneshot_result(&af_ctlr->isp_proc->hal, out_res); + isp_ll_af_enable_auto_update(af_ctrlr->isp_proc->hal.hw, false); + af_ctrlr->fsm = ISP_FSM_ENABLE; return ESP_OK; } @@ -164,7 +231,7 @@ esp_err_t esp_isp_af_controller_get_oneshot_result(isp_af_ctrlr_t af_ctlr, isp_a /*--------------------------------------------- AF Env Monitor ----------------------------------------------*/ -esp_err_t esp_isp_af_controller_set_env_detector(isp_af_ctrlr_t af_ctrlr, const esp_isp_af_env_config_t *env_config) +esp_err_t esp_isp_af_controller_set_env_detector(isp_af_ctlr_t af_ctrlr, const esp_isp_af_env_config_t *env_config) { ESP_RETURN_ON_FALSE(af_ctrlr && env_config, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); ESP_RETURN_ON_FALSE(af_ctrlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "invalid fsm, should be called when in init state"); @@ -174,29 +241,37 @@ esp_err_t esp_isp_af_controller_set_env_detector(isp_af_ctrlr_t af_ctrlr, const isp_ll_af_env_monitor_set_period(af_ctrlr->isp_proc->hal.hw, 0); isp_ll_clear_intr(af_ctrlr->isp_proc->hal.hw, ISP_LL_EVENT_AF_ENV); + isp_ll_af_env_monitor_set_mode(af_ctrlr->isp_proc->hal.hw, ISP_LL_AF_ENV_MONITOR_MODE_ABS); + isp_ll_af_env_monitor_set_period(af_ctrlr->isp_proc->hal.hw, af_ctrlr->config.interval); + isp_ll_enable_intr(af_ctrlr->isp_proc->hal.hw, ISP_LL_EVENT_AF_ENV, true); + return ESP_OK; } -esp_err_t esp_isp_af_env_detector_register_event_callbacks(isp_af_ctrlr_t af_ctrlr, const esp_isp_af_env_detector_evt_cbs_t *cbs, void *user_data) +esp_err_t esp_isp_af_env_detector_register_event_callbacks(isp_af_ctlr_t af_ctrlr, const esp_isp_af_env_detector_evt_cbs_t *cbs, void *user_data) { ESP_RETURN_ON_FALSE(af_ctrlr && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(af_ctrlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "detector isn't in the init state"); #if CONFIG_ISP_ISR_IRAM_SAFE + if (cbs->on_env_statistics_done) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_env_statistics_done), ESP_ERR_INVALID_ARG, TAG, "on_env_statistics_done callback not in IRAM"); + } if (cbs->on_env_change) { ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_env_change), ESP_ERR_INVALID_ARG, TAG, "on_env_change callback not in IRAM"); } + if (user_data) { + ESP_RETURN_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); + } #endif - - ESP_RETURN_ON_ERROR(esp_isp_register_isr(af_ctrlr->isp_proc, ISP_SUBMODULE_AF), TAG, "fail to register ISR"); - + af_ctrlr->cbs.on_env_statistics_done = cbs->on_env_statistics_done; af_ctrlr->cbs.on_env_change = cbs->on_env_change; af_ctrlr->user_data = user_data; return ESP_OK; } -esp_err_t esp_isp_af_env_detector_set_threshold(isp_af_ctrlr_t af_ctrlr, int definition_thresh, int luminance_thresh) +esp_err_t esp_isp_af_controller_set_env_detector_threshold(isp_af_ctlr_t af_ctrlr, int definition_thresh, int luminance_thresh) { ESP_RETURN_ON_FALSE_ISR(af_ctrlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE_ISR(af_ctrlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "detector isn't in enable state"); @@ -209,36 +284,47 @@ esp_err_t esp_isp_af_env_detector_set_threshold(isp_af_ctrlr_t af_ctrlr, int def /*--------------------------------------------------------------- INTR ---------------------------------------------------------------*/ -static bool IRAM_ATTR s_af_env_isr(isp_af_ctrlr_t af_ctrlr) +static void IRAM_ATTR s_isp_af_default_isr(void *arg) { - bool need_yield = false; + isp_af_ctlr_t af_ctrlr = (isp_af_ctlr_t)arg; + isp_proc_handle_t proc = af_ctrlr->isp_proc; + + uint32_t af_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AF_MASK); + bool need_yield = false; esp_isp_af_env_detector_evt_data_t edata = {}; - if (af_ctrlr->cbs.on_env_change(af_ctrlr, &edata, af_ctrlr->user_data)) { - need_yield |= true; - } - return need_yield; -} + if (af_events) { + // Get the statistics result + for (int i = 0; i < SOC_ISP_AF_WINDOW_NUMS; i++) { + edata.af_result.definition[i] = isp_ll_af_get_window_sum(proc->hal.hw, i); + edata.af_result.luminance[i] = isp_ll_af_get_window_lum(proc->hal.hw, i); + } + } -bool IRAM_ATTR esp_isp_af_isr(isp_proc_handle_t proc, uint32_t af_events) -{ /** - * HW events are cleared in the ISP ISR dispatcher. - * We only deal with HW events + * Deal with the interrupts. + * Now only one detector. + * Should decide a detector instance according to the hw event. */ - - bool need_yield = false; - + if (af_events & ISP_LL_EVENT_AF_FDONE) { + BaseType_t high_task_awake = false; + // Send the event data to the queue, overwrite the legacy one if exist + xQueueOverwriteFromISR(af_ctrlr->evt_que, &edata.af_result, &high_task_awake); + // Invoke the callback if the callback is registered + need_yield |= high_task_awake == pdTRUE; + if (af_ctrlr->cbs.on_env_statistics_done) { + need_yield |= af_ctrlr->cbs.on_env_statistics_done(af_ctrlr, &edata, af_ctrlr->user_data); + } + } if (af_events & ISP_LL_EVENT_AF_ENV) { - /** - * Now only one detector. - * Should decide a detector instance according to the hw event. - */ - isp_af_ctrlr_t af_ctrlr = proc->af_ctlr[0]; - - need_yield |= s_af_env_isr(af_ctrlr); + // Invoke the callback if the callback is registered + if (af_ctrlr->cbs.on_env_change) { + need_yield |= af_ctrlr->cbs.on_env_change(af_ctrlr, &edata, af_ctrlr->user_data); + } } - return need_yield; + if (need_yield) { + portYIELD_FROM_ISR(); + } } diff --git a/components/esp_driver_isp/src/isp_awb.c b/components/esp_driver_isp/src/isp_awb.c new file mode 100644 index 000000000000..435515a9a4bd --- /dev/null +++ b/components/esp_driver_isp/src/isp_awb.c @@ -0,0 +1,304 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "driver/isp_awb.h" +#include "esp_private/isp_private.h" + +typedef struct isp_awb_controller_t { + isp_fsm_t fsm; + portMUX_TYPE spinlock; + intr_handle_t intr_handle; + int intr_priority; + isp_proc_handle_t isp_proc; + QueueHandle_t evt_que; + SemaphoreHandle_t stat_lock; + esp_isp_awb_cbs_t cbs; + void *user_data; +} isp_awb_controller_t; + +static const char *TAG = "ISP_AWB"; + +static void s_isp_awb_default_isr(void *arg); + +/*--------------------------------------------- + AWB +----------------------------------------------*/ +static esp_err_t s_isp_claim_awb_controller(isp_proc_handle_t isp_proc, isp_awb_ctlr_t awb_ctlr) +{ + assert(isp_proc && awb_ctlr); + + esp_err_t ret = ESP_ERR_NOT_FOUND; + portENTER_CRITICAL(&isp_proc->spinlock); + if (!isp_proc->awb_ctlr) { + isp_proc->awb_ctlr = awb_ctlr; + ret = ESP_OK; + } + portEXIT_CRITICAL(&isp_proc->spinlock); + + return ret; +} + +static void s_isp_declaim_awb_controller(isp_awb_ctlr_t awb_ctlr) +{ + if (awb_ctlr && awb_ctlr->isp_proc) { + portENTER_CRITICAL(&awb_ctlr->isp_proc->spinlock); + awb_ctlr->isp_proc->awb_ctlr = NULL; + portEXIT_CRITICAL(&awb_ctlr->isp_proc->spinlock); + } +} + +static void s_isp_awb_free_controller(isp_awb_ctlr_t awb_ctlr) +{ + if (awb_ctlr) { + if (awb_ctlr->intr_handle) { + esp_intr_free(awb_ctlr->intr_handle); + } + if (awb_ctlr->evt_que) { + vQueueDelete(awb_ctlr->evt_que); + } + if (awb_ctlr->stat_lock) { + vSemaphoreDelete(awb_ctlr->stat_lock); + } + free(awb_ctlr); + } +} + +static esp_err_t s_esp_isp_awb_config_hardware(isp_proc_handle_t isp_proc, const esp_isp_awb_config_t *awb_cfg) +{ + isp_ll_awb_set_sample_point(isp_proc->hal.hw, awb_cfg->sample_point); + ESP_RETURN_ON_FALSE(isp_hal_awb_set_window_range(&isp_proc->hal, &awb_cfg->window), + ESP_ERR_INVALID_ARG, TAG, "invalid window"); + isp_u32_range_t lum_range = awb_cfg->white_patch.luminance; + ESP_RETURN_ON_FALSE(isp_hal_awb_set_luminance_range(&isp_proc->hal, lum_range.min, lum_range.max), + ESP_ERR_INVALID_ARG, TAG, "invalid luminance range"); + isp_float_range_t rg_range = awb_cfg->white_patch.red_green_ratio; + ESP_RETURN_ON_FALSE(rg_range.min < rg_range.max && rg_range.min >= 0 && + isp_hal_awb_set_rg_ratio_range(&isp_proc->hal, rg_range.min, rg_range.max), + ESP_ERR_INVALID_ARG, TAG, "invalid range of Red Green ratio"); + isp_float_range_t bg_range = awb_cfg->white_patch.blue_green_ratio; + ESP_RETURN_ON_FALSE(bg_range.min < bg_range.max && bg_range.min >= 0 && + isp_hal_awb_set_bg_ratio_range(&isp_proc->hal, bg_range.min, bg_range.max), + ESP_ERR_INVALID_ARG, TAG, "invalid range of Blue to Green ratio"); + return ESP_OK; +} + +esp_err_t esp_isp_new_awb_controller(isp_proc_handle_t isp_proc, const esp_isp_awb_config_t *awb_cfg, isp_awb_ctlr_t *ret_hdl) +{ + esp_err_t ret = ESP_FAIL; + ESP_RETURN_ON_FALSE(isp_proc && awb_cfg && ret_hdl, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + + isp_awb_ctlr_t awb_ctlr = heap_caps_calloc(1, sizeof(isp_awb_controller_t), ISP_MEM_ALLOC_CAPS); + ESP_RETURN_ON_FALSE(awb_ctlr, ESP_ERR_NO_MEM, TAG, "no mem for awb controller"); + awb_ctlr->evt_que = xQueueCreateWithCaps(1, sizeof(isp_awb_stat_result_t), ISP_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(awb_ctlr->evt_que, ESP_ERR_NO_MEM, err1, TAG, "no mem for awb event queue"); + awb_ctlr->stat_lock = xSemaphoreCreateBinaryWithCaps(ISP_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(awb_ctlr->stat_lock, ESP_ERR_NO_MEM, err1, TAG, "no mem for awb semaphore"); + awb_ctlr->fsm = ISP_FSM_INIT; + awb_ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; + awb_ctlr->isp_proc = isp_proc; + + // Claim an AWB controller + ESP_GOTO_ON_ERROR(s_isp_claim_awb_controller(isp_proc, awb_ctlr), err1, TAG, "no available controller"); + // Register the AWB ISR + uint32_t intr_st_reg_addr = isp_ll_get_intr_status_reg_addr(isp_proc->hal.hw); + awb_ctlr->intr_priority = awb_cfg->intr_priority > 0 && awb_cfg->intr_priority <= 3 ? BIT(awb_cfg->intr_priority) : ESP_INTR_FLAG_LOWMED; + ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(isp_hw_info.instances[isp_proc->proc_id].irq, ISP_INTR_ALLOC_FLAGS | awb_ctlr->intr_priority, intr_st_reg_addr, ISP_LL_EVENT_AWB_MASK, + s_isp_awb_default_isr, awb_ctlr, &awb_ctlr->intr_handle), err2, TAG, "allocate interrupt failed"); + + // Configure the hardware + isp_ll_awb_enable(isp_proc->hal.hw, false); + isp_ll_awb_enable_algorithm_mode(isp_proc->hal.hw, true); + ESP_GOTO_ON_ERROR(s_esp_isp_awb_config_hardware(isp_proc, awb_cfg), err2, TAG, "configure awb hardware failed"); + + *ret_hdl = awb_ctlr; + + return ESP_OK; + +err2: + s_isp_declaim_awb_controller(awb_ctlr); +err1: + s_isp_awb_free_controller(awb_ctlr); + + return ret; +} + +esp_err_t esp_isp_del_awb_controller(isp_awb_ctlr_t awb_ctlr) +{ + ESP_RETURN_ON_FALSE(awb_ctlr && awb_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(awb_ctlr->isp_proc->awb_ctlr == awb_ctlr, ESP_ERR_INVALID_ARG, TAG, "controller isn't in use"); + ESP_RETURN_ON_FALSE(awb_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state"); + s_isp_declaim_awb_controller(awb_ctlr); + + isp_ll_awb_enable_algorithm_mode(awb_ctlr->isp_proc->hal.hw, false); + s_isp_awb_free_controller(awb_ctlr); + + return ESP_OK; +} + +esp_err_t esp_isp_awb_controller_reconfig(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_config_t *awb_cfg) +{ + ESP_RETURN_ON_FALSE(awb_ctlr && awb_cfg, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + int intr_priority = awb_cfg->intr_priority > 0 && awb_cfg->intr_priority <= 3 ? BIT(awb_cfg->intr_priority) : ESP_INTR_FLAG_LOWMED; + ESP_RETURN_ON_FALSE(intr_priority == awb_ctlr->intr_priority, ESP_ERR_INVALID_ARG, TAG, "can't change interrupt priority after initialized"); + + return s_esp_isp_awb_config_hardware(awb_ctlr->isp_proc, awb_cfg); +} + +esp_err_t esp_isp_awb_controller_enable(isp_awb_ctlr_t awb_ctlr) +{ + ESP_RETURN_ON_FALSE(awb_ctlr && awb_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(awb_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "controller isn't in init state"); + awb_ctlr->fsm = ISP_FSM_ENABLE; + + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_ERROR(esp_intr_enable(awb_ctlr->intr_handle), err, TAG, "failed to enable the AWB interrupt"); + isp_ll_awb_clk_enable(awb_ctlr->isp_proc->hal.hw, true); + isp_ll_enable_intr(awb_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AWB_MASK, true); + xSemaphoreGive(awb_ctlr->stat_lock); + + return ret; +err: + awb_ctlr->fsm = ISP_FSM_INIT; + return ret; +} + +esp_err_t esp_isp_awb_controller_disable(isp_awb_ctlr_t awb_ctlr) +{ + ESP_RETURN_ON_FALSE(awb_ctlr && awb_ctlr->isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(awb_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "controller isn't in enable state"); + xSemaphoreTake(awb_ctlr->stat_lock, 0); + awb_ctlr->fsm = ISP_FSM_INIT; + + isp_ll_enable_intr(awb_ctlr->isp_proc->hal.hw, ISP_LL_EVENT_AWB_MASK, false); + isp_ll_awb_clk_enable(awb_ctlr->isp_proc->hal.hw, false); + esp_intr_disable(awb_ctlr->intr_handle); + + return ESP_OK; +} + +esp_err_t esp_isp_awb_controller_get_oneshot_statistics(isp_awb_ctlr_t awb_ctlr, int timeout_ms, isp_awb_stat_result_t *out_res) +{ + ESP_RETURN_ON_FALSE(awb_ctlr && (out_res || timeout_ms == 0), ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + esp_err_t ret = ESP_OK; + TickType_t ticks = timeout_ms < 0 ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms); + xSemaphoreTake(awb_ctlr->stat_lock, ticks); + ESP_GOTO_ON_FALSE(awb_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, err, TAG, "controller isn't in enable state"); + // Update state to avoid race condition + awb_ctlr->fsm = ISP_FSM_START; + // Reset the queue in case receiving the legacy data in the queue + xQueueReset(awb_ctlr->evt_que); + // Start the AWB white patch statistics and waiting it done + isp_ll_awb_enable(awb_ctlr->isp_proc->hal.hw, true); + // Wait the statistics to finish and receive the result from the queue + if ((ticks > 0) && xQueueReceive(awb_ctlr->evt_que, out_res, ticks) != pdTRUE) { + ret = ESP_ERR_TIMEOUT; + } + // Stop the AWB white patch statistics + isp_ll_awb_enable(awb_ctlr->isp_proc->hal.hw, false); + awb_ctlr->fsm = ISP_FSM_ENABLE; +err: + xSemaphoreGive(awb_ctlr->stat_lock); + return ret; +} + +esp_err_t esp_isp_awb_controller_start_continuous_statistics(isp_awb_ctlr_t awb_ctlr) +{ + ESP_RETURN_ON_FALSE(awb_ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(awb_ctlr->cbs.on_statistics_done, ESP_ERR_INVALID_STATE, TAG, "invalid state: on_statistics_done callback not registered"); + esp_err_t ret = ESP_OK; + if (xSemaphoreTake(awb_ctlr->stat_lock, 0) == pdFALSE) { + ESP_LOGW(TAG, "statistics lock is not acquired, controller is busy"); + return ESP_ERR_INVALID_STATE; + } + ESP_GOTO_ON_FALSE(awb_ctlr->fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, err, TAG, "controller isn't in enable state"); + awb_ctlr->fsm = ISP_FSM_START; + isp_ll_awb_enable(awb_ctlr->isp_proc->hal.hw, true); + + return ret; +err: + xSemaphoreGive(awb_ctlr->stat_lock); + return ret; +} + +esp_err_t esp_isp_awb_controller_stop_continuous_statistics(isp_awb_ctlr_t awb_ctlr) +{ + ESP_RETURN_ON_FALSE(awb_ctlr, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(awb_ctlr->fsm == ISP_FSM_START, ESP_ERR_INVALID_STATE, TAG, "controller isn't in continuous state"); + + isp_ll_awb_enable(awb_ctlr->isp_proc->hal.hw, false); + awb_ctlr->fsm = ISP_FSM_ENABLE; + xSemaphoreGive(awb_ctlr->stat_lock); + + return ESP_OK; +} + +/*--------------------------------------------------------------- + INTR +---------------------------------------------------------------*/ +static void IRAM_ATTR s_isp_awb_default_isr(void *arg) +{ + isp_awb_ctlr_t awb_ctlr = (isp_awb_ctlr_t)arg; + isp_proc_handle_t proc = awb_ctlr->isp_proc; + + uint32_t awb_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AWB_MASK); + + bool need_yield = false; + + if (awb_events & ISP_LL_EVENT_AWB_FDONE) { + isp_awb_ctlr_t awb_ctlr = proc->awb_ctlr; + // Get the statistics result + esp_isp_awb_evt_data_t edata = { + .awb_result = { + .white_patch_num = isp_ll_awb_get_white_patch_cnt(proc->hal.hw), + .sum_r = isp_ll_awb_get_accumulated_r_value(proc->hal.hw), + .sum_g = isp_ll_awb_get_accumulated_g_value(proc->hal.hw), + .sum_b = isp_ll_awb_get_accumulated_b_value(proc->hal.hw), + }, + }; + // Invoke the callback if the callback is registered + if (awb_ctlr->cbs.on_statistics_done) { + need_yield |= awb_ctlr->cbs.on_statistics_done(awb_ctlr, &edata, awb_ctlr->user_data); + } + BaseType_t high_task_awake = false; + // Send the event data to the queue, overwrite the legacy one if exist + xQueueOverwriteFromISR(awb_ctlr->evt_que, &edata.awb_result, &high_task_awake); + need_yield |= high_task_awake == pdTRUE; + /* If started continuous sampling, then trigger the next AWB sample */ + if (awb_ctlr->fsm == ISP_FSM_START) { + isp_ll_awb_enable(awb_ctlr->isp_proc->hal.hw, false); + isp_ll_awb_enable(awb_ctlr->isp_proc->hal.hw, true); + } + } + + if (need_yield) { + portYIELD_FROM_ISR(); + } +} + +esp_err_t esp_isp_awb_register_event_callbacks(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_cbs_t *cbs, void *user_data) +{ + ESP_RETURN_ON_FALSE(awb_ctlr && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(awb_ctlr->fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "detector isn't in the init state"); +#if CONFIG_ISP_ISR_IRAM_SAFE + if (cbs->on_statistics_done) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_env_change), ESP_ERR_INVALID_ARG, TAG, "on_env_change callback not in IRAM"); + } + if (user_data) { + ESP_RETURN_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); + } +#endif + awb_ctlr->cbs.on_statistics_done = cbs->on_statistics_done; + awb_ctlr->user_data = user_data; + + return ESP_OK; +} diff --git a/components/esp_driver_isp/src/isp_bf.c b/components/esp_driver_isp/src/isp_bf.c new file mode 100644 index 000000000000..b8b7cf39867c --- /dev/null +++ b/components/esp_driver_isp/src/isp_bf.c @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "esp_clk_tree.h" +#include "driver/isp_core.h" +#include "driver/isp_bf.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/mipi_csi_share_hw_ctrl.h" +#include "hal/hal_utils.h" +#include "soc/mipi_csi_bridge_struct.h" +#include "soc/isp_periph.h" +#include "esp_private/isp_private.h" + +static const char *TAG = "ISP_BF"; + +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +esp_err_t esp_isp_bf_configure(isp_proc_handle_t proc, const esp_isp_bf_config_t *config) +{ + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(proc->bf_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "bf is enabled already"); + + if (config) { + bool valid_padding_setting = (!config->padding_line_tail_valid_end_pixel && !config->padding_line_tail_valid_start_pixel) || (config->padding_line_tail_valid_end_pixel > config->padding_line_tail_valid_start_pixel); + ESP_RETURN_ON_FALSE(valid_padding_setting, ESP_ERR_INVALID_ARG, TAG, "wrong padding line tail valid pixel setting"); + + isp_hal_bf_cfg_t bf_hal_cfg = { + .denoising_level = config->denoising_level, + .padding_mode = config->padding_mode, + .padding_data = config->padding_data, + .padding_line_tail_valid_start_pixel = config->padding_line_tail_valid_start_pixel, + .padding_line_tail_valid_end_pixel = config->padding_line_tail_valid_end_pixel, + }; + memcpy(bf_hal_cfg.bf_template, config->bf_template, ISP_BF_TEMPLATE_X_NUMS * ISP_BF_TEMPLATE_X_NUMS * sizeof(uint8_t)); + isp_hal_bf_config(&(proc->hal), &bf_hal_cfg); + } else { + isp_hal_bf_config(&(proc->hal), NULL); + } + + return ESP_OK; +} + +esp_err_t esp_isp_bf_enable(isp_proc_handle_t proc) +{ + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(proc->bf_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "bf is enabled already"); + + isp_ll_bf_clk_enable(proc->hal.hw, true); + isp_ll_bf_enable(proc->hal.hw, true); + proc->bf_fsm = ISP_FSM_ENABLE; + + return ESP_OK; +} + +esp_err_t esp_isp_bf_disable(isp_proc_handle_t proc) +{ + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(proc->bf_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "bf isn't enabled yet"); + + isp_ll_bf_enable(proc->hal.hw, false); + isp_ll_bf_clk_enable(proc->hal.hw, false); + proc->bf_fsm = ISP_FSM_INIT; + + return ESP_OK; +} diff --git a/components/esp_driver_isp/src/isp_ccm.c b/components/esp_driver_isp/src/isp_ccm.c new file mode 100644 index 000000000000..5fb45984884e --- /dev/null +++ b/components/esp_driver_isp/src/isp_ccm.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_log.h" +#include "esp_check.h" +#include "freertos/FreeRTOS.h" +#include "driver/isp_core.h" +#include "driver/isp_ccm.h" +#include "esp_private/isp_private.h" + +static const char *TAG = "ISP_CCM"; + +/*--------------------------------------------------------------- + CCM +---------------------------------------------------------------*/ +esp_err_t esp_isp_ccm_configure(isp_proc_handle_t proc, const esp_isp_ccm_config_t *ccm_cfg) +{ + ESP_RETURN_ON_FALSE(proc && ccm_cfg, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + + bool ret = true; + portENTER_CRITICAL(&proc->spinlock); + ret = isp_hal_ccm_set_matrix(&proc->hal, ccm_cfg->saturation, ccm_cfg->matrix); + portEXIT_CRITICAL(&proc->spinlock); + ESP_RETURN_ON_FALSE(ret, ESP_ERR_INVALID_ARG, TAG, "invalid argument: ccm matrix contain NaN or out of range"); + + return ESP_OK; +} + +esp_err_t esp_isp_ccm_enable(isp_proc_handle_t proc) +{ + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + + portENTER_CRITICAL(&proc->spinlock); + isp_ll_ccm_clk_enable(proc->hal.hw, true); + isp_ll_ccm_enable(proc->hal.hw, true); + portEXIT_CRITICAL(&proc->spinlock); + + return ESP_OK; +} + +esp_err_t esp_isp_ccm_disable(isp_proc_handle_t proc) +{ + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + + portENTER_CRITICAL(&proc->spinlock); + isp_ll_ccm_enable(proc->hal.hw, false); + isp_ll_ccm_clk_enable(proc->hal.hw, false); + portEXIT_CRITICAL(&proc->spinlock); + + return ESP_OK; +} diff --git a/components/esp_driver_isp/src/isp.c b/components/esp_driver_isp/src/isp_core.c similarity index 63% rename from components/esp_driver_isp/src/isp.c rename to components/esp_driver_isp/src/isp_core.c index c0d8a2699d05..8fbf9e5f66a9 100644 --- a/components/esp_driver_isp/src/isp.c +++ b/components/esp_driver_isp/src/isp_core.c @@ -12,28 +12,14 @@ #include "esp_heap_caps.h" #include "freertos/FreeRTOS.h" #include "esp_clk_tree.h" -#include "driver/isp.h" +#include "driver/isp_core.h" +#include "driver/isp_bf.h" #include "esp_private/periph_ctrl.h" #include "esp_private/mipi_csi_share_hw_ctrl.h" #include "hal/hal_utils.h" -#include "hal/isp_types.h" -#include "hal/isp_hal.h" -#include "hal/isp_ll.h" #include "soc/mipi_csi_bridge_struct.h" #include "soc/isp_periph.h" -#include "isp_internal.h" - -#if CONFIG_ISP_ISR_IRAM_SAFE -#define ISP_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM) -#else -#define ISP_INTR_ALLOC_FLAGS 0 -#endif - -#if CONFIG_ISP_ISR_IRAM_SAFE -#define ISP_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) -#else -#define ISP_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT -#endif +#include "esp_private/isp_private.h" typedef struct isp_platform_t { _lock_t mutex; @@ -87,7 +73,7 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ { esp_err_t ret = ESP_FAIL; ESP_RETURN_ON_FALSE(proc_config && ret_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); - ESP_RETURN_ON_FALSE(proc_config->input_data_source == ISP_INPUT_DATA_SOURCE_CSI, ESP_ERR_NOT_SUPPORTED, TAG, "only support CSI as input source at this moment"); + ESP_RETURN_ON_FALSE(proc_config->input_data_source != ISP_INPUT_DATA_SOURCE_DWGDMA, ESP_ERR_NOT_SUPPORTED, TAG, "input source not supported yet"); isp_processor_t *proc = heap_caps_calloc(1, sizeof(isp_processor_t), ISP_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(proc, ESP_ERR_NO_MEM, TAG, "no mem"); @@ -118,13 +104,6 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ } isp_hal_init(&proc->hal, proc->proc_id); - //necessary ISP submodules that needs basic initialisation - isp_ll_bf_clk_enable(proc->hal.hw, true); - isp_ll_bf_enable(proc->hal.hw, true); - isp_ll_ccm_clk_enable(proc->hal.hw, true); - isp_ll_ccm_enable(proc->hal.hw, true); - isp_ll_color_clk_enable(proc->hal.hw, true); - isp_ll_color_enable(proc->hal.hw, true); PERIPH_RCC_ATOMIC() { isp_ll_select_clk_source(proc->hal.hw, clk_src); isp_ll_set_clock_div(proc->hal.hw, &clk_div); @@ -156,6 +135,11 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ isp_ll_set_intput_data_h_pixel_num(proc->hal.hw, proc_config->h_res); isp_ll_set_intput_data_v_row_num(proc->hal.hw, proc_config->v_res); + proc->in_color_format = in_color_format; + proc->out_color_format = out_color_format; + proc->h_res = proc_config->h_res; + proc->v_res = proc_config->v_res; + *ret_proc = proc; return ESP_OK; @@ -202,100 +186,3 @@ esp_err_t esp_isp_disable(isp_proc_handle_t proc) return ESP_OK; } - -/*--------------------------------------------------------------- - INTR ----------------------------------------------------------------*/ -static void IRAM_ATTR s_isp_isr_dispatcher(void *arg) -{ - isp_processor_t *proc = (isp_processor_t *)arg; - bool need_yield = false; - - //Check and clear hw events - uint32_t af_events = isp_hal_check_clear_intr_event(&proc->hal, ISP_LL_EVENT_AF_MASK); - - bool do_dispatch = false; - //Deal with hw events - if (af_events) { - portENTER_CRITICAL_ISR(&proc->spinlock); - do_dispatch = proc->af_isr_added; - portEXIT_CRITICAL_ISR(&proc->spinlock); - - if (do_dispatch) { - need_yield |= esp_isp_af_isr(proc, af_events); - } - do_dispatch = false; - } - - if (need_yield) { - portYIELD_FROM_ISR(); - } -} - -esp_err_t esp_isp_register_isr(isp_proc_handle_t proc, isp_submodule_t submodule) -{ - esp_err_t ret = ESP_FAIL; - ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); - - bool do_alloc = false; - portENTER_CRITICAL(&proc->spinlock); - proc->isr_ref_counts++; - if (proc->isr_ref_counts == 1) { - assert(!proc->intr_hdl); - do_alloc = true; - } - - switch (submodule) { - case ISP_SUBMODULE_AF: - proc->af_isr_added = true; - break; - default: - assert(false); - } - portEXIT_CRITICAL(&proc->spinlock); - - if (do_alloc) { - ret = esp_intr_alloc(isp_hw_info.instances[proc->proc_id].irq, ISP_INTR_ALLOC_FLAGS, s_isp_isr_dispatcher, (void *)proc, &proc->intr_hdl); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "no intr source"); - return ret; - } - esp_intr_enable(proc->intr_hdl); - } - - return ESP_OK; -} - -esp_err_t esp_isp_deregister_isr(isp_proc_handle_t proc, isp_submodule_t submodule) -{ - esp_err_t ret = ESP_FAIL; - ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); - - bool do_free = false; - portENTER_CRITICAL(&proc->spinlock); - proc->isr_ref_counts--; - assert(proc->isr_ref_counts >= 0); - if (proc->isr_ref_counts == 0) { - assert(proc->intr_hdl); - do_free = true; - } - - switch (submodule) { - case ISP_SUBMODULE_AF: - proc->af_isr_added = false; - break; - default: - assert(false); - } - portEXIT_CRITICAL(&proc->spinlock); - - if (do_free) { - esp_intr_disable(proc->intr_hdl); - ret = esp_intr_free(proc->intr_hdl); - if (ret != ESP_OK) { - return ret; - } - } - - return ESP_OK; -} diff --git a/components/esp_driver_isp/src/isp_internal.h b/components/esp_driver_isp/src/isp_internal.h deleted file mode 100644 index eab28412287a..000000000000 --- a/components/esp_driver_isp/src/isp_internal.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include -#include -#include "sdkconfig.h" -#include "esp_attr.h" -#include "esp_log.h" -#include "esp_check.h" -#include "esp_heap_caps.h" -#include "esp_intr_alloc.h" -#include "freertos/FreeRTOS.h" -#include "hal/isp_hal.h" -#include "hal/isp_types.h" -#include "soc/isp_periph.h" -#include "soc/soc_caps.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - ISP_FSM_INIT, - ISP_FSM_ENABLE, -} isp_fsm_t; - -/*--------------------------------------------------------------- - Driver Context ----------------------------------------------------------------*/ -typedef enum { - ISP_SUBMODULE_AF, -} isp_submodule_t; - -typedef struct isp_af_controller_t isp_af_controller_t; -typedef struct isp_processor_t isp_processor_t; - -struct isp_af_controller_t { - int id; - isp_fsm_t fsm; - portMUX_TYPE spinlock; - isp_processor_t *isp_proc; - esp_isp_af_env_config_t config; - esp_isp_af_env_detector_evt_cbs_t cbs; - void *user_data; -}; - -struct isp_processor_t { - int proc_id; - isp_hal_context_t hal; -#if SOC_ISP_SHARE_CSI_BRG - int csi_brg_id; - void *csi_brg_hw; -#endif - isp_fsm_t isp_fsm; - portMUX_TYPE spinlock; - intr_handle_t intr_hdl; - - /* sub module contexts */ - isp_af_controller_t *af_ctlr[SOC_ISP_AF_CTLR_NUMS]; - - /* should be accessed within isp_processor_t spinlock */ - int isr_ref_counts; - bool af_isr_added; -}; - -/*--------------------------------------------------------------- - INTR ----------------------------------------------------------------*/ -esp_err_t esp_isp_register_isr(isp_proc_handle_t proc, isp_submodule_t submodule); -esp_err_t esp_isp_deregister_isr(isp_proc_handle_t proc, isp_submodule_t submodule); -bool esp_isp_af_isr(isp_proc_handle_t proc, uint32_t af_events); - -#ifdef __cplusplus -} -#endif diff --git a/components/esp_driver_isp/test_apps/isp/main/CMakeLists.txt b/components/esp_driver_isp/test_apps/isp/main/CMakeLists.txt index 49f618de17d6..941c781eaf7a 100644 --- a/components/esp_driver_isp/test_apps/isp/main/CMakeLists.txt +++ b/components/esp_driver_isp/test_apps/isp/main/CMakeLists.txt @@ -8,6 +8,7 @@ endif() set(priv_requires unity esp_driver_isp + esp_psram ) idf_component_register(SRCS ${srcs} diff --git a/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c b/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c index 310124e0e228..d2f660ea5dcf 100644 --- a/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c +++ b/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c @@ -7,8 +7,7 @@ #include "sdkconfig.h" #include "unity.h" #include "driver/isp.h" - -#include "esp_rom_sys.h" +#include "soc/soc_caps.h" TEST_CASE("ISP processor exhausted allocation", "[isp]") { @@ -45,7 +44,7 @@ TEST_CASE("ISP AF controller exhausted allocation", "[isp]") esp_isp_af_config_t af_config = { .edge_thresh = 128, }; - isp_af_ctrlr_t af_ctrlr[SOC_ISP_AF_CTLR_NUMS + 1] = {}; + isp_af_ctlr_t af_ctrlr[SOC_ISP_AF_CTLR_NUMS + 1] = {}; for (int i = 0; i < SOC_ISP_AF_CTLR_NUMS; i++) { TEST_ESP_OK(esp_isp_new_af_controller(isp_proc, &af_config, &af_ctrlr[i])); } @@ -57,3 +56,100 @@ TEST_CASE("ISP AF controller exhausted allocation", "[isp]") } TEST_ESP_OK(esp_isp_del_processor(isp_proc)); } + +static bool test_isp_awb_default_on_statistics_done_cb(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_evt_data_t *edata, void *user_data) +{ + (void) awb_ctlr; + (void) edata; + (void) user_data; + // Do nothing + return false; +} + +TEST_CASE("ISP AWB driver basic function", "[isp]") +{ + esp_isp_processor_cfg_t isp_config = { + .clk_hz = 80 * 1000 * 1000, + .input_data_source = ISP_INPUT_DATA_SOURCE_CSI, + .input_data_color_type = ISP_COLOR_RAW8, + .output_data_color_type = ISP_COLOR_RGB565, + }; + isp_proc_handle_t isp_proc = NULL; + TEST_ESP_OK(esp_isp_new_processor(&isp_config, &isp_proc)); + TEST_ESP_OK(esp_isp_enable(isp_proc)); + + isp_awb_ctlr_t awb_ctlr = NULL; + uint32_t image_width = 800; + uint32_t image_height = 600; + /* Default parameters from helper macro */ + esp_isp_awb_config_t awb_config = { + .sample_point = ISP_AWB_SAMPLE_POINT_AFTER_CCM, + .window = { + .top_left = {.x = image_width * 0.2, .y = image_height * 0.2}, + .btm_right = {.x = image_width * 0.8, .y = image_height * 0.8}, + }, + .white_patch = { + .luminance = {.min = 0, .max = 220 * 3}, + .red_green_ratio = {.min = 0.0f, .max = 3.999f}, + .blue_green_ratio = {.min = 0.0f, .max = 3.999f}, + }, + }; + isp_awb_stat_result_t stat_res = {}; + /* Create the awb controller */ + TEST_ESP_OK(esp_isp_new_awb_controller(isp_proc, &awb_config, &awb_ctlr)); + /* Register AWB callback */ + esp_isp_awb_cbs_t awb_cb = { + .on_statistics_done = test_isp_awb_default_on_statistics_done_cb, + }; + TEST_ESP_OK(esp_isp_awb_register_event_callbacks(awb_ctlr, &awb_cb, NULL)); + /* Enabled the awb controller */ + TEST_ESP_OK(esp_isp_awb_controller_enable(awb_ctlr)); + /* Start continuous AWB statistics */ + TEST_ESP_OK(esp_isp_awb_controller_start_continuous_statistics(awb_ctlr)); + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_isp_awb_controller_get_oneshot_statistics(awb_ctlr, 0, &stat_res)); + /* Stop continuous AWB statistics */ + TEST_ESP_OK(esp_isp_awb_controller_stop_continuous_statistics(awb_ctlr)); + TEST_ESP_ERR(ESP_ERR_TIMEOUT, esp_isp_awb_controller_get_oneshot_statistics(awb_ctlr, 1, &stat_res)); + /* Disable the awb controller */ + TEST_ESP_OK(esp_isp_awb_controller_disable(awb_ctlr)); + /* Delete the awb controller and free the resources */ + TEST_ESP_OK(esp_isp_del_awb_controller(awb_ctlr)); + + TEST_ESP_OK(esp_isp_disable(isp_proc)); + TEST_ESP_OK(esp_isp_del_processor(isp_proc)); +} + +TEST_CASE("ISP CCM basic function", "[isp]") +{ + esp_isp_processor_cfg_t isp_config = { + .clk_hz = 80 * 1000 * 1000, + .input_data_source = ISP_INPUT_DATA_SOURCE_CSI, + .input_data_color_type = ISP_COLOR_RAW8, + .output_data_color_type = ISP_COLOR_RGB565, + }; + isp_proc_handle_t isp_proc = NULL; + TEST_ESP_OK(esp_isp_new_processor(&isp_config, &isp_proc)); + TEST_ESP_OK(esp_isp_enable(isp_proc)); + + esp_isp_ccm_config_t ccm_cfg = { + .matrix = { + {5.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0} + }, + .saturation = false, + }; + // Out of range case + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_isp_ccm_configure(isp_proc, &ccm_cfg)); + // saturation case + ccm_cfg.saturation = true; + TEST_ESP_OK(esp_isp_ccm_configure(isp_proc, &ccm_cfg)); + TEST_ESP_OK(esp_isp_ccm_enable(isp_proc)); + // Allow to be called after enabled + ccm_cfg.matrix[0][0] = -1.1; + TEST_ESP_OK(esp_isp_ccm_configure(isp_proc, &ccm_cfg)); + TEST_ESP_OK(esp_isp_ccm_disable(isp_proc)); + + TEST_ESP_OK(esp_isp_disable(isp_proc)); + TEST_ESP_OK(esp_isp_del_processor(isp_proc)); +} diff --git a/components/esp_driver_isp/test_apps/isp/sdkconfig.defaults b/components/esp_driver_isp/test_apps/isp/sdkconfig.defaults index fa8ac618b948..5bce69ad381b 100644 --- a/components/esp_driver_isp/test_apps/isp/sdkconfig.defaults +++ b/components/esp_driver_isp/test_apps/isp/sdkconfig.defaults @@ -1,2 +1,5 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_ESP_TASK_WDT_EN=n +CONFIG_SPIRAM=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM_SPEED_200M=y diff --git a/components/esp_driver_jpeg/jpeg_decode.c b/components/esp_driver_jpeg/jpeg_decode.c index 422c2afd2b62..90b1632e4150 100644 --- a/components/esp_driver_jpeg/jpeg_decode.c +++ b/components/esp_driver_jpeg/jpeg_decode.c @@ -217,12 +217,12 @@ esp_err_t jpeg_decoder_process(jpeg_decoder_handle_t decoder_engine, const jpeg_ decoder_engine->conv_std = decode_cfg->conv_std; decoder_engine->decoded_buf = decode_outbuf; - ESP_GOTO_ON_ERROR(jpeg_parse_marker(decoder_engine, bit_stream, stream_size), err, TAG, "jpeg parse marker failed"); - ESP_GOTO_ON_ERROR(jpeg_parse_header_info_to_hw(decoder_engine), err, TAG, "write header info to hw failed"); - ESP_GOTO_ON_ERROR(jpeg_dec_config_dma_descriptor(decoder_engine), err, TAG, "config dma descriptor failed"); + ESP_GOTO_ON_ERROR(jpeg_parse_marker(decoder_engine, bit_stream, stream_size), err2, TAG, "jpeg parse marker failed"); + ESP_GOTO_ON_ERROR(jpeg_parse_header_info_to_hw(decoder_engine), err2, TAG, "write header info to hw failed"); + ESP_GOTO_ON_ERROR(jpeg_dec_config_dma_descriptor(decoder_engine), err2, TAG, "config dma descriptor failed"); *out_size = decoder_engine->header_info->process_h * decoder_engine->header_info->process_v * decoder_engine->bit_per_pixel / 8; - ESP_GOTO_ON_FALSE((*out_size <= outbuf_size), ESP_ERR_INVALID_ARG, err, TAG, "Given buffer size % " PRId32 " is smaller than actual jpeg decode output size % " PRId32 "the height and width of output picture size will be adjusted to 16 bytes aligned automatically", outbuf_size, *out_size); + ESP_GOTO_ON_FALSE((*out_size <= outbuf_size), ESP_ERR_INVALID_ARG, err2, TAG, "Given buffer size % " PRId32 " is smaller than actual jpeg decode output size % " PRId32 "the height and width of output picture size will be adjusted to 16 bytes aligned automatically", outbuf_size, *out_size); dma2d_trans_config_t trans_desc = { .tx_channel_num = 1, @@ -236,21 +236,20 @@ esp_err_t jpeg_decoder_process(jpeg_decoder_handle_t decoder_engine, const jpeg_ ret = esp_cache_msync((void*)decoder_engine->header_info->buffer_offset, decoder_engine->header_info->buffer_left, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); assert(ret == ESP_OK); - ESP_GOTO_ON_ERROR(dma2d_enqueue(decoder_engine->dma2d_group_handle, &trans_desc, decoder_engine->trans_desc), err, TAG, "enqueue dma2d failed"); + ESP_GOTO_ON_ERROR(dma2d_enqueue(decoder_engine->dma2d_group_handle, &trans_desc, decoder_engine->trans_desc), err2, TAG, "enqueue dma2d failed"); bool need_yield; // Blocking for JPEG decode transaction finishes. while (1) { jpeg_dma2d_dec_evt_t jpeg_dma2d_event; BaseType_t ret_val = xQueueReceive(decoder_engine->evt_queue, &jpeg_dma2d_event, decoder_engine->timeout_tick); - ESP_GOTO_ON_FALSE(ret_val == pdTRUE, ESP_ERR_TIMEOUT, err, TAG, "jpeg-dma2d handle jpeg decode timeout, please check `timeout_ms` "); + ESP_GOTO_ON_FALSE(ret_val == pdTRUE, ESP_ERR_TIMEOUT, err1, TAG, "jpeg-dma2d handle jpeg decode timeout, please check image accuracy and `timeout_ms` "); // Dealing with JPEG event if (jpeg_dma2d_event.jpgd_status != 0) { uint32_t status = jpeg_dma2d_event.jpgd_status; s_decoder_error_log_print(status); - dma2d_force_end(decoder_engine->trans_desc, &need_yield); - xSemaphoreGive(decoder_engine->codec_base->codec_mutex); - return ESP_ERR_INVALID_STATE; + ret = ESP_ERR_INVALID_STATE; + goto err1; } if (jpeg_dma2d_event.dma_evt & JPEG_DMA2D_RX_EOF) { @@ -260,18 +259,25 @@ esp_err_t jpeg_decoder_process(jpeg_decoder_handle_t decoder_engine, const jpeg_ } } -err: xSemaphoreGive(decoder_engine->codec_base->codec_mutex); if (decoder_engine->codec_base->pm_lock) { ESP_RETURN_ON_ERROR(esp_pm_lock_release(decoder_engine->codec_base->pm_lock), TAG, "release pm_lock failed"); } + return ESP_OK; + +err1: + dma2d_force_end(decoder_engine->trans_desc, &need_yield); +err2: + xSemaphoreGive(decoder_engine->codec_base->codec_mutex); + if (decoder_engine->codec_base->pm_lock) { + esp_pm_lock_release(decoder_engine->codec_base->pm_lock); + } return ret; } esp_err_t jpeg_del_decoder_engine(jpeg_decoder_handle_t decoder_engine) { ESP_RETURN_ON_FALSE(decoder_engine, ESP_ERR_INVALID_ARG, TAG, "jpeg decode handle is null"); - ESP_RETURN_ON_ERROR(jpeg_release_codec_handle(decoder_engine->codec_base), TAG, "release codec failed"); if (decoder_engine) { if (decoder_engine->rxlink) { @@ -295,6 +301,7 @@ esp_err_t jpeg_del_decoder_engine(jpeg_decoder_handle_t decoder_engine) if (decoder_engine->intr_handle) { jpeg_isr_deregister(decoder_engine->codec_base, decoder_engine->intr_handle); } + ESP_RETURN_ON_ERROR(jpeg_release_codec_handle(decoder_engine->codec_base), TAG, "release codec failed"); free(decoder_engine); } return ESP_OK; diff --git a/components/esp_driver_jpeg/jpeg_encode.c b/components/esp_driver_jpeg/jpeg_encode.c index d4df1137ec70..9a6cb6f364fc 100644 --- a/components/esp_driver_jpeg/jpeg_encode.c +++ b/components/esp_driver_jpeg/jpeg_encode.c @@ -186,7 +186,7 @@ esp_err_t jpeg_encoder_process(jpeg_encoder_handle_t encoder_engine, const jpeg_ default: ESP_LOGE(TAG, "wrong, we don't support encode from such format."); ret = ESP_ERR_NOT_SUPPORTED; - goto err; + goto err2; } encoder_engine->header_info->sub_sample = encode_cfg->sub_sample; encoder_engine->header_info->quality = encode_cfg->image_quality; @@ -202,7 +202,7 @@ esp_err_t jpeg_encoder_process(jpeg_encoder_handle_t encoder_engine, const jpeg_ jpeg_ll_add_tail(hal->dev, true); jpeg_ll_enable_ff_check(hal->dev, true); jpeg_ll_set_qnr_presition(hal->dev, 0); - ESP_GOTO_ON_ERROR(s_jpeg_set_header_info(encoder_engine), err, TAG, "set header failed"); + ESP_GOTO_ON_ERROR(s_jpeg_set_header_info(encoder_engine), err2, TAG, "set header failed"); jpeg_hal_set_quantization_coefficient(hal, encoder_engine->header_info->m_quantization_tables[0], encoder_engine->header_info->m_quantization_tables[1]); uint8_t sample_method_idx = 0; @@ -227,7 +227,7 @@ esp_err_t jpeg_encoder_process(jpeg_encoder_handle_t encoder_engine, const jpeg_ uint32_t dma_hb = enc_hb_tbl[best_hb_idx][sample_method_idx]; uint32_t dma_vb = encoder_engine->mcuy; - ESP_GOTO_ON_FALSE((encoder_engine->header_info->header_len % cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA)) == 0, ESP_ERR_INVALID_STATE, err, TAG, "The header is not cache line aligned, please check"); + ESP_GOTO_ON_FALSE((encoder_engine->header_info->header_len % cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA)) == 0, ESP_ERR_INVALID_STATE, err2, TAG, "The header is not cache line aligned, please check"); // 1D direction memset(encoder_engine->rxlink, 0, sizeof(dma2d_descriptor_t)); @@ -248,23 +248,24 @@ esp_err_t jpeg_encoder_process(jpeg_encoder_handle_t encoder_engine, const jpeg_ .on_job_picked = s_jpeg_enc_transaction_on_job_picked, }; - ESP_GOTO_ON_ERROR(dma2d_enqueue(encoder_engine->dma2d_group_handle, &trans_desc, encoder_engine->trans_desc), err, TAG, "DMA2D enqueue failed"); - + ESP_GOTO_ON_ERROR(dma2d_enqueue(encoder_engine->dma2d_group_handle, &trans_desc, encoder_engine->trans_desc), err2, TAG, "DMA2D enqueue failed"); + bool need_yield; while (1) { jpeg_enc_dma2d_evt_t s_rcv_event; BaseType_t ret_val = xQueueReceive(encoder_engine->evt_queue, &s_rcv_event, encoder_engine->timeout_tick); - ESP_GOTO_ON_FALSE(ret_val == pdTRUE, ESP_ERR_TIMEOUT, err, TAG, "jpeg-dma2d handle jpeg decode timeout, please check `timeout_ms`"); + ESP_GOTO_ON_FALSE(ret_val == pdTRUE, ESP_ERR_TIMEOUT, err1, TAG, "jpeg-dma2d handle jpeg decode timeout, please check image accuracy and `timeout_ms`"); if (s_rcv_event.encoder_status != 0) { s_encoder_error_log_print(s_rcv_event.encoder_status); ret = ESP_ERR_INVALID_STATE; - goto err; + goto err1; } if (s_rcv_event.dma_evt & JPEG_DMA2D_RX_EOF) { + ESP_GOTO_ON_ERROR(esp_cache_msync((void*)encoder_engine->rxlink, encoder_engine->dma_desc_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C), err1, TAG, "sync memory to cache failed"); compressed_size = s_dma_desc_get_len(encoder_engine->rxlink); uint32_t _compressed_size = JPEG_ALIGN_UP(compressed_size, cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA)); - ESP_GOTO_ON_ERROR(esp_cache_msync((void*)(bit_stream + encoder_engine->header_info->header_len), _compressed_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C), err, TAG, "sync memory to cache failed"); + ESP_GOTO_ON_ERROR(esp_cache_msync((void*)(bit_stream + encoder_engine->header_info->header_len), _compressed_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C), err1, TAG, "sync memory to cache failed"); break; } } @@ -272,18 +273,25 @@ esp_err_t jpeg_encoder_process(jpeg_encoder_handle_t encoder_engine, const jpeg_ compressed_size += encoder_engine->header_info->header_len; *out_size = compressed_size; -err: xSemaphoreGive(encoder_engine->codec_base->codec_mutex); if (encoder_engine->codec_base->pm_lock) { ESP_RETURN_ON_ERROR(esp_pm_lock_release(encoder_engine->codec_base->pm_lock), TAG, "release pm_lock failed"); } + return ESP_OK; + +err1: + dma2d_force_end(encoder_engine->trans_desc, &need_yield); +err2: + xSemaphoreGive(encoder_engine->codec_base->codec_mutex); + if (encoder_engine->codec_base->pm_lock) { + esp_pm_lock_release(encoder_engine->codec_base->pm_lock); + } return ret; } esp_err_t jpeg_del_encoder_engine(jpeg_encoder_handle_t encoder_engine) { ESP_RETURN_ON_FALSE(encoder_engine, ESP_ERR_INVALID_ARG, TAG, "jpeg encoder handle is null"); - ESP_RETURN_ON_ERROR(jpeg_release_codec_handle(encoder_engine->codec_base), TAG, "release codec failed"); if (encoder_engine) { if (encoder_engine->rxlink) { @@ -307,6 +315,7 @@ esp_err_t jpeg_del_encoder_engine(jpeg_encoder_handle_t encoder_engine) if (encoder_engine->intr_handle) { jpeg_isr_deregister(encoder_engine->codec_base, encoder_engine->intr_handle); } + ESP_RETURN_ON_ERROR(jpeg_release_codec_handle(encoder_engine->codec_base), TAG, "release codec failed"); free(encoder_engine); } return ESP_OK; diff --git a/components/esp_driver_jpeg/jpeg_parse_marker.c b/components/esp_driver_jpeg/jpeg_parse_marker.c index e457ccfd5f3c..13fcc831d0a1 100644 --- a/components/esp_driver_jpeg/jpeg_parse_marker.c +++ b/components/esp_driver_jpeg/jpeg_parse_marker.c @@ -130,10 +130,10 @@ esp_err_t jpeg_parse_sof_marker(jpeg_dec_header_info_t *header_info) // The vertical and horizontal in process must be divided by mcu block. if (header_info->origin_v % header_info->mcuy != 0) { - header_info->process_v = (ceil(header_info->origin_v / header_info->mcuy) + 1) * header_info->mcuy; + header_info->process_v = (uint32_t)(ceil(header_info->origin_v / header_info->mcuy) + 1) * header_info->mcuy; } if (header_info->origin_h % header_info->mcux != 0) { - header_info->process_h = (ceil(header_info->origin_h / header_info->mcux) + 1) * header_info->mcux; + header_info->process_h = (uint32_t)(ceil(header_info->origin_h / header_info->mcux) + 1) * header_info->mcux; } return ESP_OK; diff --git a/components/esp_driver_jpeg/jpeg_private.h b/components/esp_driver_jpeg/jpeg_private.h index 01a489f930aa..2c43cdd06fad 100644 --- a/components/esp_driver_jpeg/jpeg_private.h +++ b/components/esp_driver_jpeg/jpeg_private.h @@ -87,7 +87,7 @@ typedef struct { uint8_t huffcode[2][2][JPEG_HUFFMAN_AC_VALUE_TABLE_LEN]; // Huffman decoded data tables [id][dcac] uint32_t tmp_huff[JPEG_HUFFMAN_AC_VALUE_TABLE_LEN]; // temp buffer to store huffman code bool dri_marker; // If we have dri marker in table - uint8_t ri; // Restart interval + uint16_t ri; // Restart interval } jpeg_dec_header_info_t; struct jpeg_decoder_t { diff --git a/components/esp_driver_ledc/test_apps/.build-test-rules.yml b/components/esp_driver_ledc/test_apps/.build-test-rules.yml index 00d99826d130..b18d676013a3 100644 --- a/components/esp_driver_ledc/test_apps/.build-test-rules.yml +++ b/components/esp_driver_ledc/test_apps/.build-test-rules.yml @@ -3,6 +3,9 @@ components/esp_driver_ledc/test_apps/ledc: disable: - if: SOC_LEDC_SUPPORTED != 1 + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: build failed. track in IDFCI-2204 disable_test: - if: IDF_TARGET == "esp32p4" temporary: true diff --git a/components/esp_driver_parlio/src/parlio_common.c b/components/esp_driver_parlio/src/parlio_common.c index f8358d90c8cc..48518ddb0cca 100644 --- a/components/esp_driver_parlio/src/parlio_common.c +++ b/components/esp_driver_parlio/src/parlio_common.c @@ -48,6 +48,8 @@ parlio_group_t *parlio_acquire_group_handle(int group_id) } // hal layer initialize parlio_hal_init(&group->hal); + group->dma_align = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + group->dma_align = group->dma_align < 4 ? 4 : group->dma_align; } } else { // group already install group = s_platform.groups[group_id]; diff --git a/components/esp_driver_parlio/src/parlio_private.h b/components/esp_driver_parlio/src/parlio_private.h index 52ab3bec1c43..d728359b09eb 100644 --- a/components/esp_driver_parlio/src/parlio_private.h +++ b/components/esp_driver_parlio/src/parlio_private.h @@ -30,6 +30,7 @@ #else #define PARLIO_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT #endif +#define PARLIO_DMA_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA) #if SOC_PARLIO_TX_RX_SHARE_INTERRUPT #define PARLIO_INTR_ALLOC_FLAG_SHARED ESP_INTR_FLAG_SHARED @@ -57,6 +58,12 @@ typedef dma_descriptor_align8_t parlio_dma_desc_t; #define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#define PARLIO_MAX_ALIGNED_DMA_BUF_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_64B_ALIGNED +#else +#define PARLIO_MAX_ALIGNED_DMA_BUF_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED +#endif + #ifdef CACHE_LL_L2MEM_NON_CACHE_ADDR /* The descriptor address can be mapped by a fixed offset */ #define PARLIO_GET_NON_CACHED_DESC_ADDR(desc) (desc ? (parlio_dma_desc_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(desc)) : NULL) @@ -107,11 +114,12 @@ typedef enum { typedef struct parlio_unit_t *parlio_unit_base_handle_t; typedef struct parlio_group_t { - int group_id; // group ID, index from 0 - portMUX_TYPE spinlock; // to protect per-group register level concurrent access - parlio_hal_context_t hal; // hal layer context - parlio_unit_base_handle_t tx_units[SOC_PARLIO_TX_UNITS_PER_GROUP]; // tx unit handles - parlio_unit_base_handle_t rx_units[SOC_PARLIO_RX_UNITS_PER_GROUP]; // rx unit handles + int group_id; // group ID, index from 0 + portMUX_TYPE spinlock; // to protect per-group register level concurrent access + parlio_hal_context_t hal; // hal layer context + uint32_t dma_align; // DMA buffer alignment + parlio_unit_base_handle_t tx_units[SOC_PARLIO_TX_UNITS_PER_GROUP]; // tx unit handles + parlio_unit_base_handle_t rx_units[SOC_PARLIO_RX_UNITS_PER_GROUP]; // rx unit handles } parlio_group_t; /** diff --git a/components/esp_driver_parlio/src/parlio_rx.c b/components/esp_driver_parlio/src/parlio_rx.c index 6ea8fcd03843..c6e3eadf8855 100644 --- a/components/esp_driver_parlio/src/parlio_rx.c +++ b/components/esp_driver_parlio/src/parlio_rx.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,6 +34,7 @@ #include "esp_clk_tree.h" #include "esp_attr.h" #include "esp_private/gdma.h" +#include "esp_cache.h" static const char *TAG = "parlio-rx"; @@ -81,8 +82,9 @@ typedef struct parlio_rx_unit_t { gdma_channel_handle_t dma_chan; /*!< DMA channel */ size_t max_recv_size; /*!< Maximum receive size for a normal transaction */ size_t desc_num; /*!< DMA descriptor number */ - dma_descriptor_t *dma_descs; /*!< DMA descriptor array pointer */ - dma_descriptor_t *curr_desc; /*!< The pointer of the current descriptor */ + size_t desc_size; /*!< DMA descriptors total size */ + parlio_dma_desc_t **dma_descs; /*!< DMA descriptor array pointer */ + parlio_dma_desc_t *curr_desc; /*!< The pointer of the current descriptor */ void *usr_recv_buf; /*!< The pointe to the user's receiving buffer */ /* Infinite transaction specific */ void *dma_buf; /*!< Additional internal DMA buffer only for infinite transactions */ @@ -125,19 +127,21 @@ typedef struct parlio_rx_delimiter_t { } flags; } parlio_rx_delimiter_t; +#define PRALIO_RX_MOUNT_SIZE_CALC(total_size, div, align) ((((total_size) / (align)) / (div)) * (align)) + static portMUX_TYPE s_rx_spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; static IRAM_ATTR size_t s_parlio_mount_transaction_buffer(parlio_rx_unit_handle_t rx_unit, parlio_rx_transaction_t *trans) { - dma_descriptor_t *p_desc = rx_unit->dma_descs; + parlio_dma_desc_t **p_desc = rx_unit->dma_descs; /* Update the current transaction to the next one, and declare the delimiter is under using of the rx unit */ memcpy(&rx_unit->curr_trans, trans, sizeof(parlio_rx_transaction_t)); portENTER_CRITICAL_SAFE(&s_rx_spinlock); trans->delimiter->under_using = true; portEXIT_CRITICAL_SAFE(&s_rx_spinlock); - uint32_t desc_num = trans->size / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; - uint32_t remain_num = trans->size % DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; + uint32_t desc_num = trans->size / PARLIO_MAX_ALIGNED_DMA_BUF_SIZE; + uint32_t remain_num = trans->size % PARLIO_MAX_ALIGNED_DMA_BUF_SIZE; /* If there are still data remained, need one more descriptor */ desc_num += remain_num ? 1 : 0; if (trans->flags.infinite && desc_num < 2) { @@ -146,30 +150,40 @@ static IRAM_ATTR size_t s_parlio_mount_transaction_buffer(parlio_rx_unit_handle_ } size_t mount_size = 0; size_t offset = 0; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + uint32_t alignment = rx_unit->base.group->dma_align; +#else + uint32_t alignment = 4; +#endif /* Loop the descriptors to assign the data */ for (int i = 0; i < desc_num; i++) { size_t rest_size = trans->size - offset; - if (rest_size >= 2 * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) { - mount_size = trans->size / desc_num; - } else if (rest_size <= DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) { - mount_size = (desc_num == 2) && (i == 0) ? rest_size / 2 : rest_size; + + if (rest_size >= 2 * PARLIO_MAX_ALIGNED_DMA_BUF_SIZE) { + mount_size = PRALIO_RX_MOUNT_SIZE_CALC(trans->size, desc_num, alignment); + } else if (rest_size <= PARLIO_MAX_ALIGNED_DMA_BUF_SIZE) { + mount_size = (desc_num == 2) && (i == 0) ? PRALIO_RX_MOUNT_SIZE_CALC(rest_size, 2, alignment) : rest_size; } else { - mount_size = rest_size / 2; + mount_size = PRALIO_RX_MOUNT_SIZE_CALC(rest_size, 2, alignment); } - p_desc[i].buffer = (void *)((uint8_t *)trans->payload + offset); - p_desc[i].dw0.size = mount_size; - p_desc[i].dw0.length = mount_size; - p_desc[i].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + p_desc[i]->buffer = (void *)((uint8_t *)trans->payload + offset); + p_desc[i]->dw0.size = mount_size; + p_desc[i]->dw0.length = mount_size; + p_desc[i]->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; // Link the descriptor - if (i > 0) { - p_desc[i - 1].next = &p_desc[i]; + if (i < desc_num - 1) { + p_desc[i]->next = p_desc[i + 1]; + } else { + /* For infinite transaction, link the descriptor as a ring */ + p_desc[i]->next = trans->flags.infinite ? p_desc[0] : NULL; } offset += mount_size; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + esp_cache_msync(p_desc[i], rx_unit->desc_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); +#endif } - /* For infinite transaction, link the descriptor as a ring */ - p_desc[desc_num - 1].next = trans->flags.infinite ? &p_desc[0] : NULL; /* Reset the current DMA node */ - rx_unit->curr_desc = p_desc; + rx_unit->curr_desc = p_desc[0]; return offset; } @@ -251,6 +265,8 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons gpio_conf.mode = config->flags.io_loop_back ? GPIO_MODE_INPUT_OUTPUT : GPIO_MODE_INPUT; gpio_conf.pin_bit_mask = BIT64(config->clk_in_gpio_num); ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config clk in GPIO failed"); + } else { + gpio_ll_input_enable(&GPIO, config->clk_in_gpio_num); } esp_rom_gpio_connect_in_signal(config->clk_in_gpio_num, parlio_periph_signals.groups[group_id].rx_units[unit_id].clk_in_sig, false); @@ -275,6 +291,8 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons if (!config->flags.io_no_init) { gpio_conf.pin_bit_mask = BIT64(config->valid_gpio_num); ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config data GPIO failed"); + } else { + gpio_ll_input_enable(&GPIO, config->valid_gpio_num); } /* Not connect the signal here, the signal is lazy connected until the delimiter takes effect */ } @@ -286,7 +304,8 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons if (!config->flags.io_no_init) { gpio_conf.pin_bit_mask = BIT64(config->data_gpio_nums[i]); ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config data GPIO failed"); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[config->data_gpio_nums[i]], PIN_FUNC_GPIO); + } else { + gpio_ll_input_enable(&GPIO, config->data_gpio_nums[i]); } esp_rom_gpio_connect_in_signal(config->data_gpio_nums[i], parlio_periph_signals.groups[group_id].rx_units[unit_id].data_sigs[i], false); @@ -330,18 +349,22 @@ static IRAM_ATTR bool s_parlio_rx_default_eof_callback(gdma_channel_handle_t dma /* The current transaction finished, try to get the next transaction from the transaction queue */ if (xQueueReceiveFromISR(rx_unit->trans_que, &next_trans, &high_task_woken) == pdTRUE) { if (rx_unit->cfg.flags.free_clk) { - parlio_ll_rx_enable_clock(rx_unit->base.group->hal.regs, false); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_enable_clock(rx_unit->base.group->hal.regs, false); + } } /* If the delimiter of the next transaction is not same as the current one, need to re-config the hardware */ - if (next_trans.delimiter != rx_unit->curr_trans.delimiter) { + if ((next_trans.delimiter != NULL) && (next_trans.delimiter != rx_unit->curr_trans.delimiter)) { s_parlio_set_delimiter_config(rx_unit, next_trans.delimiter); } /* Mount the new transaction buffer and start the new transaction */ s_parlio_mount_transaction_buffer(rx_unit, &next_trans); - gdma_start(rx_unit->dma_chan, (intptr_t)rx_unit->dma_descs); + gdma_start(rx_unit->dma_chan, (intptr_t)rx_unit->dma_descs[0]); if (rx_unit->cfg.flags.free_clk) { parlio_ll_rx_start(rx_unit->base.group->hal.regs, true); - parlio_ll_rx_enable_clock(rx_unit->base.group->hal.regs, true); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_enable_clock(rx_unit->base.group->hal.regs, true); + } } } else if (rx_unit->curr_trans.delimiter) { // Add condition in case the curr_trans has been cleared in the last timeout isr /* No more transaction pending to receive, clear the current transaction */ @@ -368,7 +391,15 @@ static IRAM_ATTR bool s_parlio_rx_default_desc_done_callback(gdma_channel_handle } /* Get the finished descriptor from the current descriptor */ - dma_descriptor_t *finished_desc = rx_unit->curr_desc; + parlio_dma_desc_t *finished_desc = rx_unit->curr_desc; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + esp_err_t ret = ESP_OK; + ret |= esp_cache_msync((void *)finished_desc, rx_unit->desc_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + ret |= esp_cache_msync((void *)(finished_desc->buffer), finished_desc->dw0.size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + if (ret != ESP_OK) { + ESP_EARLY_LOGW(TAG, "failed to sync dma buffer from memory to cache"); + } +#endif parlio_rx_event_data_t evt_data = { .delimiter = rx_unit->curr_trans.delimiter, .data = finished_desc->buffer, @@ -399,21 +430,41 @@ static IRAM_ATTR bool s_parlio_rx_default_desc_done_callback(gdma_channel_handle static esp_err_t s_parlio_rx_create_dma_descriptors(parlio_rx_unit_handle_t rx_unit, uint32_t max_recv_size) { ESP_RETURN_ON_FALSE(rx_unit, ESP_ERR_INVALID_ARG, TAG, "invalid param"); - + esp_err_t ret = ESP_OK; uint32_t desc_num = max_recv_size / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED + 1; /* set at least 2 descriptors */ if (desc_num < 2) { - desc_num = 4; + desc_num = 2; } rx_unit->desc_num = desc_num; /* Allocated and link the descriptor nodes */ - rx_unit->dma_descs = (dma_descriptor_t *)heap_caps_calloc(desc_num, sizeof(dma_descriptor_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); - ESP_RETURN_ON_FALSE(rx_unit->dma_descs, ESP_ERR_NO_MEM, TAG, "no memory for DMA descriptors"); + rx_unit->dma_descs = heap_caps_calloc(desc_num, sizeof(parlio_dma_desc_t *), MALLOC_CAP_DMA); + ESP_RETURN_ON_FALSE(rx_unit->dma_descs, ESP_ERR_NO_MEM, TAG, "no memory for DMA descriptor array"); + uint32_t cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + size_t alignment = MAX(cache_line_size, PARLIO_DMA_DESC_ALIGNMENT); + rx_unit->desc_size = ALIGN_UP(sizeof(parlio_dma_desc_t), alignment); + for (int i = 0; i < desc_num; i++) { + rx_unit->dma_descs[i] = heap_caps_aligned_calloc(alignment, 1, rx_unit->desc_size, PARLIO_DMA_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(rx_unit->dma_descs[i], ESP_ERR_NO_MEM, err, TAG, "no memory for DMA descriptors"); +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + esp_cache_msync(rx_unit->dma_descs[i], rx_unit->desc_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); +#endif + } rx_unit->max_recv_size = max_recv_size; - return ESP_OK; + return ret; +err: + for (int i = 0; i < desc_num; i++) { + if (rx_unit->dma_descs[i]) { + free(rx_unit->dma_descs[i]); + rx_unit->dma_descs[i] = NULL; + } + } + free(rx_unit->dma_descs); + rx_unit->dma_descs = NULL; + return ret; } static esp_err_t s_parlio_rx_unit_init_dma(parlio_rx_unit_handle_t rx_unit) @@ -422,7 +473,7 @@ static esp_err_t s_parlio_rx_unit_init_dma(parlio_rx_unit_handle_t rx_unit) gdma_channel_alloc_config_t dma_chan_config = { .direction = GDMA_CHANNEL_DIRECTION_RX, }; - ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_chan_config, &rx_unit->dma_chan), TAG, "allocate RX DMA channel failed"); + ESP_RETURN_ON_ERROR(PARLIO_GDMA_NEW_CHANNEL(&dma_chan_config, &rx_unit->dma_chan), TAG, "allocate RX DMA channel failed"); gdma_connect(rx_unit->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_PARLIO, 0)); /* Set GDMA strategy */ @@ -487,8 +538,10 @@ static esp_err_t s_parlio_select_periph_clock(parlio_rx_unit_handle_t rx_unit, c #endif /* Set clock configuration */ - parlio_ll_rx_set_clock_source(hal->regs, clk_src); - parlio_ll_rx_set_clock_div(hal->regs, &clk_div); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_set_clock_source(hal->regs, clk_src); + parlio_ll_rx_set_clock_div(hal->regs, &clk_div); + } rx_unit->clk_src = clk_src; /* warning if precision lost due to division */ @@ -525,7 +578,14 @@ static esp_err_t s_parlio_destroy_rx_unit(parlio_rx_unit_handle_t rx_unit) } /* Free the DMA descriptors */ if (rx_unit->dma_descs) { + for (int i = 0; i < rx_unit->desc_num; i++) { + if (rx_unit->dma_descs[i]) { + free(rx_unit->dma_descs[i]); + rx_unit->dma_descs[i] = NULL; + } + } free(rx_unit->dma_descs); + rx_unit->dma_descs = NULL; } /* Free the internal DMA buffer */ if (rx_unit->dma_buf) { @@ -591,9 +651,13 @@ esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_un /* Install DMA service */ ESP_GOTO_ON_ERROR(s_parlio_rx_unit_init_dma(unit), err, TAG, "install rx DMA failed"); /* Reset RX module */ - parlio_ll_rx_reset_clock(hal->regs); + PARLIO_RCC_ATOMIC() { + parlio_ll_rx_reset_clock(hal->regs); + } parlio_ll_rx_reset_fifo(hal->regs); - parlio_ll_rx_enable_clock(hal->regs, false); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_enable_clock(hal->regs, false); + } parlio_ll_rx_start(hal->regs, false); /* parlio_ll_clock_source_t and parlio_clock_source_t are binary compatible if the clock source is from internal */ ESP_GOTO_ON_ERROR(s_parlio_select_periph_clock(unit, config), err, TAG, "set clock source failed"); @@ -651,7 +715,9 @@ esp_err_t parlio_rx_unit_enable(parlio_rx_unit_handle_t rx_unit, bool reset_queu if (!rx_unit->cfg.flags.free_clk) { parlio_ll_rx_reset_fifo(hal->regs); parlio_ll_rx_start(hal->regs, true); - parlio_ll_rx_enable_clock(hal->regs, true); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_enable_clock(hal->regs, true); + } } /* Check if we need to start a pending transaction */ @@ -663,14 +729,18 @@ esp_err_t parlio_rx_unit_enable(parlio_rx_unit_handle_t rx_unit, bool reset_queu // The semaphore always supposed to be taken successfully assert(xSemaphoreTake(rx_unit->trans_sem, 0) == pdTRUE); if (rx_unit->cfg.flags.free_clk) { - parlio_ll_rx_enable_clock(hal->regs, false); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_enable_clock(hal->regs, false); + } } s_parlio_set_delimiter_config(rx_unit, trans.delimiter); s_parlio_mount_transaction_buffer(rx_unit, &trans); gdma_start(rx_unit->dma_chan, (intptr_t)rx_unit->curr_desc); if (rx_unit->cfg.flags.free_clk) { parlio_ll_rx_start(hal->regs, true); - parlio_ll_rx_enable_clock(hal->regs, true); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_enable_clock(hal->regs, true); + } } } err: @@ -691,7 +761,9 @@ esp_err_t parlio_rx_unit_disable(parlio_rx_unit_handle_t rx_unit) rx_unit->is_enabled = false; /* stop the RX engine */ gdma_stop(rx_unit->dma_chan); - parlio_ll_rx_enable_clock(hal->regs, false); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_enable_clock(hal->regs, false); + } parlio_ll_rx_start(hal->regs, false); if (rx_unit->curr_trans.delimiter) { portENTER_CRITICAL(&s_rx_spinlock); @@ -842,7 +914,9 @@ static esp_err_t s_parlio_rx_unit_do_transaction(parlio_rx_unit_handle_t rx_unit portEXIT_CRITICAL_ISR(&s_rx_spinlock); if (is_stopped) { if (rx_unit->cfg.flags.free_clk) { - parlio_ll_rx_enable_clock(rx_unit->base.group->hal.regs, false); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_enable_clock(rx_unit->base.group->hal.regs, false); + } } if (trans->delimiter != rx_unit->curr_trans.delimiter) { s_parlio_set_delimiter_config(rx_unit, trans->delimiter); @@ -853,7 +927,9 @@ static esp_err_t s_parlio_rx_unit_do_transaction(parlio_rx_unit_handle_t rx_unit gdma_start(rx_unit->dma_chan, (intptr_t)rx_unit->curr_desc); if (rx_unit->cfg.flags.free_clk) { parlio_ll_rx_start(rx_unit->base.group->hal.regs, true); - parlio_ll_rx_enable_clock(rx_unit->base.group->hal.regs, true); + PARLIO_CLOCK_SRC_ATOMIC() { + parlio_ll_rx_enable_clock(rx_unit->base.group->hal.regs, true); + } } } else { // Otherwise send to the queue /* Send the transaction to the queue */ @@ -871,8 +947,17 @@ esp_err_t parlio_rx_unit_receive(parlio_rx_unit_handle_t rx_unit, ESP_RETURN_ON_FALSE(rx_unit && payload && recv_cfg, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(recv_cfg->delimiter, ESP_ERR_INVALID_ARG, TAG, "no delimiter specified"); ESP_RETURN_ON_FALSE(payload_size <= rx_unit->max_recv_size, ESP_ERR_INVALID_ARG, TAG, "trans length too large"); + uint32_t alignment = rx_unit->base.group->dma_align; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + ESP_RETURN_ON_FALSE(payload_size % alignment == 0, ESP_ERR_INVALID_ARG, TAG, "The payload size should align with %"PRIu32, alignment); + if (recv_cfg->flags.partial_rx_en) { + ESP_RETURN_ON_FALSE(payload_size >= 2 * alignment, ESP_ERR_INVALID_ARG, TAG, "The payload size should greater than %"PRIu32, 2 * alignment); + } +#endif #if CONFIG_GDMA_ISR_IRAM_SAFE ESP_RETURN_ON_FALSE(esp_ptr_internal(payload), ESP_ERR_INVALID_ARG, TAG, "payload not in internal RAM"); +#else + ESP_RETURN_ON_FALSE(recv_cfg->flags.indirect_mount || esp_ptr_internal(payload), ESP_ERR_INVALID_ARG, TAG, "payload not in internal RAM"); #endif if (recv_cfg->delimiter->eof_data_len) { ESP_RETURN_ON_FALSE(payload_size >= recv_cfg->delimiter->eof_data_len, ESP_ERR_INVALID_ARG, @@ -895,7 +980,7 @@ esp_err_t parlio_rx_unit_receive(parlio_rx_unit_handle_t rx_unit, if (recv_cfg->flags.partial_rx_en && recv_cfg->flags.indirect_mount) { ESP_RETURN_ON_FALSE(!rx_unit->dma_buf, ESP_ERR_INVALID_STATE, TAG, "infinite transaction is using the internal DMA buffer"); /* Allocate the internal DMA buffer to store the data temporary */ - rx_unit->dma_buf = heap_caps_calloc(1, payload_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + rx_unit->dma_buf = heap_caps_aligned_calloc(alignment, 1, payload_size, PARLIO_DMA_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(rx_unit->dma_buf, ESP_ERR_NO_MEM, TAG, "No memory for the internal DMA buffer"); /* Use the internal DMA buffer so that the user buffer can always be available */ p_buffer = rx_unit->dma_buf; diff --git a/components/esp_driver_parlio/src/parlio_tx.c b/components/esp_driver_parlio/src/parlio_tx.c index c03849675457..e27e2de320d5 100644 --- a/components/esp_driver_parlio/src/parlio_tx.c +++ b/components/esp_driver_parlio/src/parlio_tx.c @@ -389,10 +389,12 @@ static void IRAM_ATTR parlio_tx_mount_dma_data(parlio_tx_unit_t *tx_unit, const { size_t prepared_length = 0; uint8_t *data = (uint8_t *)buffer; + uint32_t mount_bytes = 0; parlio_dma_desc_t *desc_nc = tx_unit->dma_nodes_nc; while (len) { - uint32_t mount_bytes = len > DMA_DESCRIPTOR_BUFFER_MAX_SIZE ? DMA_DESCRIPTOR_BUFFER_MAX_SIZE : len; + assert(desc_nc); + mount_bytes = len > PARLIO_MAX_ALIGNED_DMA_BUF_SIZE ? PARLIO_MAX_ALIGNED_DMA_BUF_SIZE : len; len -= mount_bytes; desc_nc->dw0.suc_eof = (len == 0); // whether the last frame desc_nc->dw0.size = mount_bytes; @@ -402,11 +404,6 @@ static void IRAM_ATTR parlio_tx_mount_dma_data(parlio_tx_unit_t *tx_unit, const desc_nc = PARLIO_GET_NON_CACHED_DESC_ADDR(desc_nc->next); prepared_length += mount_bytes; } - -#if CONFIG_IDF_TARGET_ESP32P4 - // Write back to cache to synchronize the cache before DMA start - esp_cache_msync(buffer, len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); -#endif // CONFIG_IDF_TARGET_ESP32P4 } esp_err_t parlio_tx_unit_wait_all_done(parlio_tx_unit_handle_t tx_unit, int timeout_ms) @@ -570,6 +567,11 @@ esp_err_t parlio_tx_unit_transmit(parlio_tx_unit_handle_t tx_unit, const void *p t->payload = payload; t->payload_bits = payload_bits; t->idle_value = config->idle_value & tx_unit->idle_value_mask; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + // Write back to cache to synchronize the cache before DMA start + ESP_RETURN_ON_ERROR(esp_cache_msync((void *)payload, (payload_bits + 7) / 8, + ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED), TAG, "cache sync failed"); +#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE // send the transaction descriptor to progress queue ESP_RETURN_ON_FALSE(xQueueSend(tx_unit->trans_queues[PARLIO_TX_QUEUE_PROGRESS], &t, 0) == pdTRUE, diff --git a/components/esp_driver_parlio/test_apps/.build-test-rules.yml b/components/esp_driver_parlio/test_apps/.build-test-rules.yml index bc30d2fe7ba2..c2c576d51f4f 100644 --- a/components/esp_driver_parlio/test_apps/.build-test-rules.yml +++ b/components/esp_driver_parlio/test_apps/.build-test-rules.yml @@ -4,8 +4,8 @@ components/esp_driver_parlio/test_apps/parlio: disable: - if: SOC_PARLIO_SUPPORTED != 1 disable_test: - - if: IDF_TARGET == "esp32p4" + - if: IDF_TARGET in ["esp32h2", "esp32p4"] temporary: true - reason: lack of runner + reason: IDF-9806 waiting for the fix of the bit shift issue after reset depends_components: - esp_driver_parlio diff --git a/components/esp_driver_parlio/test_apps/parlio/README.md b/components/esp_driver_parlio/test_apps/parlio/README.md index b450dc5ffac0..7b822bdb0efd 100644 --- a/components/esp_driver_parlio/test_apps/parlio/README.md +++ b/components/esp_driver_parlio/test_apps/parlio/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C6 | ESP32-H2 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C6 | ESP32-H2 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | diff --git a/components/esp_driver_parlio/test_apps/parlio/main/test_board.h b/components/esp_driver_parlio/test_apps/parlio/main/test_board.h index 81c64cbc8c76..931cc957f7d1 100644 --- a/components/esp_driver_parlio/test_apps/parlio/main/test_board.h +++ b/components/esp_driver_parlio/test_apps/parlio/main/test_board.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ extern "C" { #define TEST_PARLIO_CALLBACK_ATTR #define TEST_PARLIO_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT #endif +#define TEST_PARLIO_DMA_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA) #if CONFIG_IDF_TARGET_ESP32C6 #define TEST_CLK_GPIO 10 @@ -42,15 +43,16 @@ extern "C" { #define TEST_DATA6_GPIO 8 #define TEST_DATA7_GPIO 9 #elif CONFIG_IDF_TARGET_ESP32P4 -#define TEST_CLK_GPIO 20 -#define TEST_DATA0_GPIO 21 -#define TEST_DATA1_GPIO 22 -#define TEST_DATA2_GPIO 34 -#define TEST_DATA3_GPIO 35 -#define TEST_DATA4_GPIO 48 -#define TEST_DATA5_GPIO 49 -#define TEST_DATA6_GPIO 10 -#define TEST_DATA7_GPIO 11 +#define TEST_CLK_GPIO 32 +#define TEST_VALID_GPIO 36 +#define TEST_DATA0_GPIO 20 +#define TEST_DATA1_GPIO 21 +#define TEST_DATA2_GPIO 22 +#define TEST_DATA3_GPIO 23 +#define TEST_DATA4_GPIO 45 +#define TEST_DATA5_GPIO 46 +#define TEST_DATA6_GPIO 47 +#define TEST_DATA7_GPIO 48 #else #error "Unsupported target" #endif diff --git a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c index c9b38bde6af0..60aacfd5b9ed 100644 --- a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c +++ b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,8 @@ #include "driver/spi_master.h" #include "driver/gpio.h" #include "hal/gpio_hal.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" #include "soc/soc_caps.h" #include "soc/i2s_periph.h" #include "soc/spi_periph.h" @@ -27,6 +29,13 @@ #define TEST_SPI_HOST SPI2_HOST #define TEST_I2S_PORT I2S_NUM_0 #define TEST_VALID_SIG (PARLIO_RX_UNIT_MAX_DATA_WIDTH - 1) + +#if SOC_PARLIO_RX_CLK_SUPPORT_OUTPUT +#define TEST_OUTPUT_CLK_PIN TEST_CLK_GPIO +#else +#define TEST_OUTPUT_CLK_PIN -1 +#endif + #define TEST_DEFAULT_UNIT_CONFIG(_clk_src, _clk_freq) { \ .trans_queue_depth = 10, \ .max_recv_size = 10 * 1024, \ @@ -35,7 +44,7 @@ .ext_clk_freq_hz = _clk_src == PARLIO_CLK_SRC_EXTERNAL ? _clk_freq : 0, \ .clk_in_gpio_num = _clk_src == PARLIO_CLK_SRC_EXTERNAL ? TEST_CLK_GPIO : -1, \ .exp_clk_freq_hz = _clk_freq, \ - .clk_out_gpio_num = -1, \ + .clk_out_gpio_num = _clk_src == PARLIO_CLK_SRC_EXTERNAL ? -1 : TEST_OUTPUT_CLK_PIN, \ .valid_gpio_num = TEST_VALID_GPIO, \ .data_gpio_nums = { \ [0] = TEST_DATA0_GPIO, \ @@ -56,6 +65,10 @@ typedef struct { uint32_t timeout_cnt; } test_data_t; +#ifndef ALIGN_UP +#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) +#endif + TEST_PARLIO_CALLBACK_ATTR static bool test_parlio_rx_partial_recv_callback(parlio_rx_unit_handle_t rx_unit, const parlio_rx_event_data_t *edata, void *user_data) { @@ -285,11 +298,15 @@ static bool test_delimiter(parlio_rx_delimiter_handle_t deli, bool free_running_ .delimiter = deli, .flags.partial_rx_en = false, }; - uint8_t recv_buff[TEST_EOF_DATA_LEN]; + uint8_t *recv_buff = NULL; + uint32_t alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + alignment = alignment < 4 ? 4 : alignment; + size_t buff_size = ALIGN_UP(TEST_EOF_DATA_LEN, alignment); + recv_buff = heap_caps_aligned_calloc(alignment, 1, buff_size, TEST_PARLIO_DMA_MEM_ALLOC_CAPS); bool is_success = false; // sample 5 times for (int i = 0; i < 5 && !is_success; i++) { - TEST_ESP_OK(parlio_rx_unit_receive(rx_unit, recv_buff, TEST_EOF_DATA_LEN, &recv_config)); + TEST_ESP_OK(parlio_rx_unit_receive(rx_unit, recv_buff, buff_size, &recv_config)); TEST_ESP_OK(parlio_rx_unit_wait_all_done(rx_unit, 5000)); for (int k = 0; k < TEST_EOF_DATA_LEN; k++) { printf("%x ", recv_buff[k]); @@ -315,6 +332,7 @@ static bool test_delimiter(parlio_rx_delimiter_handle_t deli, bool free_running_ } // Delete the sender task vTaskDelete(sender_task); + free(recv_buff); TEST_ESP_OK(parlio_rx_unit_disable(rx_unit)); TEST_ESP_OK(parlio_del_rx_unit(rx_unit)); @@ -409,8 +427,7 @@ TEST_CASE("parallel_rx_unit_install_uninstall", "[parlio_rx]") TEST_ESP_OK(parlio_rx_unit_disable(units[0])); TEST_ESP_OK(parlio_del_rx_unit(units[0])); } - -#define TEST_PAYLOAD_SIZE 5000 +#define TEST_PAYLOAD_SIZE 5120 // This test case uses soft delimiter TEST_CASE("parallel_rx_unit_receive_transaction_test", "[parlio_rx]") @@ -444,7 +461,11 @@ TEST_CASE("parallel_rx_unit_receive_transaction_test", "[parlio_rx]") .delimiter = deli, .flags.partial_rx_en = false, }; - uint8_t *payload = heap_caps_calloc(1, TEST_PAYLOAD_SIZE, TEST_PARLIO_MEM_ALLOC_CAPS); + uint8_t *payload = NULL; + uint32_t alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + alignment = alignment < 4 ? 4 : alignment; + size_t payload_size = ALIGN_UP(TEST_PAYLOAD_SIZE, alignment); + payload = heap_caps_aligned_calloc(alignment, 1, payload_size, TEST_PARLIO_DMA_MEM_ALLOC_CAPS); TEST_ASSERT(payload); printf("Testing one normal transaction...\n"); @@ -535,7 +556,11 @@ TEST_CASE("parallel_rx_unit_receive_timeout_test", "[parlio_rx]") .delimiter = timeout_deli, .flags.partial_rx_en = false, }; - uint8_t *payload = heap_caps_calloc(1, TEST_PAYLOAD_SIZE, TEST_PARLIO_MEM_ALLOC_CAPS); + uint8_t *payload = NULL; + uint32_t alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + alignment = alignment < 4 ? 4 : alignment; + size_t payload_size = ALIGN_UP(TEST_PAYLOAD_SIZE, alignment); + payload = heap_caps_aligned_calloc(alignment, 1, payload_size, TEST_PARLIO_DMA_MEM_ALLOC_CAPS); TEST_ASSERT(payload); printf("Testing the timeout callback...\n"); diff --git a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_tx.c b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_tx.c index 061fefae1226..a1fd71d8883c 100644 --- a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_tx.c +++ b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_tx.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -109,7 +109,7 @@ TEST_CASE("parallel_tx_unit_trans_done_event", "[parlio_tx]") parlio_transmit_config_t transmit_config = { .idle_value = 0x00, }; - uint8_t payload[64] = {0}; + __attribute__((aligned(64))) uint8_t payload[64] = {0}; for (int i = 0; i < 64; i++) { payload[i] = i; } @@ -155,7 +155,7 @@ TEST_CASE("parallel_tx_unit_enable_disable", "[parlio_tx]") parlio_transmit_config_t transmit_config = { .idle_value = 0x00, }; - uint8_t payload[128] = {0}; + __attribute__((aligned(64))) uint8_t payload[128] = {0}; for (int i = 0; i < 128; i++) { payload[i] = i; } @@ -210,8 +210,9 @@ TEST_CASE("parallel_tx_unit_idle_value", "[parlio_tx]") parlio_transmit_config_t transmit_config = { .idle_value = 0x00, }; - uint8_t payload[8] = {0}; - for (int i = 0; i < 8; i++) { + uint32_t size = 64; + __attribute__((aligned(64))) uint8_t payload[size]; + for (int i = 0; i < size; i++) { payload[i] = i; } for (int j = 0; j < 16; j++) { @@ -255,15 +256,16 @@ TEST_CASE("parallel_tx_clock_gating", "[paralio_tx]") parlio_transmit_config_t transmit_config = { .idle_value = 0x00, }; - uint8_t payload[8] = {0}; - for (int i = 0; i < 8; i++) { + uint32_t size = 64; + __attribute__((aligned(64))) uint8_t payload[size]; + for (int i = 0; i < size; i++) { payload[i] = 0x1B; // 8'b00011011, in PARLIO_BIT_PACK_ORDER_MSB, you should see 2'b00, 2'b01, 2'b10, 2'b11 on the data line } - TEST_ESP_OK(parlio_tx_unit_transmit(tx_unit, payload, 8 * sizeof(uint8_t) * 8, &transmit_config)); + TEST_ESP_OK(parlio_tx_unit_transmit(tx_unit, payload, size * sizeof(uint8_t) * 8, &transmit_config)); TEST_ESP_OK(parlio_tx_unit_wait_all_done(tx_unit, -1)); // check if the level on the clock line is low TEST_ASSERT_EQUAL(0, gpio_get_level(TEST_CLK_GPIO)); - TEST_ESP_OK(parlio_tx_unit_transmit(tx_unit, payload, 8 * sizeof(uint8_t) * 8, &transmit_config)); + TEST_ESP_OK(parlio_tx_unit_transmit(tx_unit, payload, size * sizeof(uint8_t) * 8, &transmit_config)); TEST_ESP_OK(parlio_tx_unit_wait_all_done(tx_unit, -1)); TEST_ASSERT_EQUAL(0, gpio_get_level(TEST_CLK_GPIO)); TEST_ASSERT_EQUAL(0, gpio_get_level(TEST_CLK_GPIO)); diff --git a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py index 4f572edd2077..dbb3f9d4e069 100644 --- a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py +++ b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py @@ -1,12 +1,10 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @pytest.mark.esp32c6 -@pytest.mark.esp32h2 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/esp_driver_pcnt/Kconfig b/components/esp_driver_pcnt/Kconfig index f34768a0fb42..2b1949bd871c 100644 --- a/components/esp_driver_pcnt/Kconfig +++ b/components/esp_driver_pcnt/Kconfig @@ -15,14 +15,6 @@ menu "ESP-Driver:PCNT Configurations" Ensure the PCNT interrupt is IRAM-Safe by allowing the interrupt handler to be executable when the cache is disabled (e.g. SPI Flash write). - config PCNT_SUPPRESS_DEPRECATE_WARN - bool "Suppress legacy driver deprecated warning" - default n - help - whether to suppress the deprecation warnings when using legacy PCNT driver (driver/pcnt.h). - If you want to continue using the legacy driver, and don't want to see related deprecation warnings, - you can enable this option. - config PCNT_ENABLE_DEBUG_LOG bool "Enable debug log" default n diff --git a/components/esp_driver_ppa/CMakeLists.txt b/components/esp_driver_ppa/CMakeLists.txt new file mode 100644 index 000000000000..ed0d3ac201d8 --- /dev/null +++ b/components/esp_driver_ppa/CMakeLists.txt @@ -0,0 +1,13 @@ +set(srcs) +set(public_include "include") +if(CONFIG_SOC_PPA_SUPPORTED) + list(APPEND srcs "src/ppa_core.c" + "src/ppa_srm.c" + "src/ppa_blend.c" + "src/ppa_fill.c") +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${public_include} + PRIV_REQUIRES esp_mm esp_pm + ) diff --git a/components/esp_driver_ppa/include/driver/ppa.h b/components/esp_driver_ppa/include/driver/ppa.h new file mode 100644 index 000000000000..5f209e85e05c --- /dev/null +++ b/components/esp_driver_ppa/include/driver/ppa.h @@ -0,0 +1,292 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" +#include "hal/ppa_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumeration of all PPA available operations + */ +typedef enum { + PPA_OPERATION_SRM, /*!< Do scale-rotate-mirror operation */ + PPA_OPERATION_BLEND, /*!< Do blend operation */ + PPA_OPERATION_FILL, /*!< Do fill operation, use one constant pixel to fill a target window */ + PPA_OPERATION_INVALID, /*!< Invalid PPA operations, indicates the quantity of available PPA operations */ +} ppa_operation_t; + +/** + * @brief Type of PPA client handle + */ +typedef struct ppa_client_t *ppa_client_handle_t; + +/** + * @brief A collection of configuration items that used for registering a PPA client + */ +typedef struct { + ppa_operation_t oper_type; /*!< The desired PPA operation for the client */ + uint32_t max_pending_trans_num; /*!< The maximum number of pending transactions for the client. + By default, it will be 1, which is sufficient if all transactions are performed with `PPA_TRANS_MODE_BLOCKING` */ + ppa_data_burst_length_t data_burst_length; /*!< The desired data burst length for all the transactions of the client. + Use a small burst length will decrease PPA performance, but can save burst bandwidth for other peripheral usages. + By default, it will be at the maximum burst length, `PPA_DATA_BURST_LENGTH_128` */ +} ppa_client_config_t; + +/** + * @brief Register a PPA client to do a specific PPA operation + * + * @param[in] config Pointer to a collection of configurations for the client + * @param[out] ret_client Returned client handle + * + * @return + * - ESP_OK: Register the PPA client successfully + * - ESP_ERR_INVALID_ARG: Register the PPA client failed because of invalid argument + * - ESP_ERR_NO_MEM: Register the PPA client failed because out of memory + * - ESP_FAIL: Register the PPA client failed because of other error + */ +esp_err_t ppa_register_client(const ppa_client_config_t *config, ppa_client_handle_t *ret_client); + +/** + * @brief Unregister a PPA client + * + * @note This will also free the resources occupied by the client + * + * @param[in] ppa_client PPA client handle, allocated by `ppa_register_client` + * + * @return + * - ESP_OK: Unregister the PPA client successfully + * - ESP_ERR_INVALID_ARG: Unregister the PPA client failed because of invalid argument + * - ESP_ERR_INVALID_STATE: Unregister the PPA client failed because there are unfinished transactions + */ +esp_err_t ppa_unregister_client(ppa_client_handle_t ppa_client); + +/** + * @brief Type of PPA event data + */ +typedef struct { +} ppa_event_data_t; + +/** + * @brief Type of PPA event callback + * + * @param[in] ppa_client PPA client handle + * @param[in] event_data PPA event data + * @param[in] user_data User registered data from calling `ppa_do_xxx` to perform an operation + * + * @return Whether a task switch is needed after the callback function returns, this is usually due to the callback + * wakes up some high priority task. + */ +typedef bool (*ppa_event_callback_t)(ppa_client_handle_t ppa_client, ppa_event_data_t *event_data, void *user_data); + +/** + * @brief Group of supported PPA callbacks + */ +typedef struct { + ppa_event_callback_t on_trans_done; /*!< Invoked when a PPA transaction finishes */ +} ppa_event_callbacks_t; + +/** + * @brief Register event callbacks for a PPA client + * + * @param[in] ppa_client PPA client handle + * @param[in] cbs Structure with all PPA callbacks + * + * @note Any user private data that wants to be passed directly to callback's user_data is provided per PPA transaction. + * Please check the `user_data` field in `ppa_xxx_oper_config_t` structure. + * + * @return + * - ESP_OK: Register event callbacks for the PPA client successfully + * - ESP_ERR_INVALID_ARG: Register event callbacks for the PPA client failed because of invalid argument + */ +esp_err_t ppa_client_register_event_callbacks(ppa_client_handle_t ppa_client, const ppa_event_callbacks_t *cbs); + +/** + * @brief A collection of configuration items for an input picture and the target block inside the picture + */ +typedef struct { + const void *buffer; /*!< Pointer to the input picture buffer */ + uint32_t pic_w; /*!< Input picture width (unit: pixel) */ + uint32_t pic_h; /*!< Input picture height (unit: pixel) */ + uint32_t block_w; /*!< Target block width (unit: pixel) */ + uint32_t block_h; /*!< Target block height (unit: pixel) */ + uint32_t block_offset_x; /*!< Target block offset in x direction in the picture (unit: pixel) */ + uint32_t block_offset_y; /*!< Target block offset in y direction in the picture (unit: pixel) */ + union { + ppa_srm_color_mode_t srm_cm; /*!< Color mode of the picture in a PPA SRM operation. Supported color mode in `ppa_srm_color_mode_t` */ + ppa_blend_color_mode_t blend_cm; /*!< Color mode of the picture in a PPA blend operation. Supported color mode in `ppa_blend_color_mode_t` */ + ppa_fill_color_mode_t fill_cm; /*!< Color mode of the picture in a PPA fill operation. Supported color mode in `ppa_fill_color_mode_t` */ + }; + ppa_color_range_t yuv_range; /*!< When the color mode is any YUV color space, this field is to describe its color range */ + ppa_color_conv_std_rgb_yuv_t yuv_std; /*!< When the color mode is any YUV color space, this field is to describe its YUV<->RGB conversion standard */ +} ppa_in_pic_blk_config_t; + +/** + * @brief A collection of configuration items for an output picture and the target block inside the picture + */ +typedef struct { + void *buffer; /*!< Pointer to the output picture buffer (requires alignment: internal memory needs align to L1 cache line size, external memory needs align to L1 and L2 cache line size) */ + uint32_t buffer_size; /*!< Size of the output picture buffer (requires alignment: internal memory needs align to L1 cache line size, external memory needs align to L1 and L2 cache line size) */ + uint32_t pic_w; /*!< Output picture width (unit: pixel) */ + uint32_t pic_h; /*!< Output picture height (unit: pixel) */ + uint32_t block_offset_x; /*!< Target block offset in x direction in the picture (unit: pixel) */ + uint32_t block_offset_y; /*!< Target block offset in y direction in the picture (unit: pixel) */ + union { + ppa_srm_color_mode_t srm_cm; /*!< Color mode of the picture in a PPA SRM operation. Supported color mode in `ppa_srm_color_mode_t` */ + ppa_blend_color_mode_t blend_cm; /*!< Color mode of the picture in a PPA blend operation. Supported color mode in `ppa_blend_color_mode_t` */ + ppa_fill_color_mode_t fill_cm; /*!< Color mode of the picture in a PPA fill operation. Supported color mode in `ppa_fill_color_mode_t` */ + }; + ppa_color_range_t yuv_range; /*!< When the color mode is any YUV color space, this field is to describe its color range */ + ppa_color_conv_std_rgb_yuv_t yuv_std; /*!< When the color mode is any YUV color space, this field is to describe its YUV<->RGB conversion standard */ +} ppa_out_pic_blk_config_t; + +/** + * @brief Modes to perform the PPA operations + */ +typedef enum { + PPA_TRANS_MODE_BLOCKING, /*!< `ppa_do_xxx` function will block until the PPA operation is finished */ + PPA_TRANS_MODE_NON_BLOCKING, /*!< `ppa_do_xxx` function will return immediately after the PPA operation is pushed to the internal queue */ +} ppa_trans_mode_t; + +/** + * @brief A collection of configuration items to do a PPA SRM operation transaction + */ +typedef struct { + ppa_in_pic_blk_config_t in; /*!< Information of the input picture and the target block */ + ppa_out_pic_blk_config_t out; /*!< Information of the output picture and the target block */ + + // scale-rotate-mirror manipulation + ppa_srm_rotation_angle_t rotation_angle; /*!< Rotation (counter-clockwise) to the target block, select from `ppa_srm_rotation_angle_t` */ + float scale_x; /*!< Scaling factor to the target block in the x direction */ + float scale_y; /*!< Scaling factor to the target block in the y direction */ + bool mirror_x; /*!< Whether to mirror the target block in the x direction */ + bool mirror_y; /*!< Whether to mirror the target block in the y direction */ + + // input data manipulation + bool rgb_swap; /*!< Whether to swap the input data in RGB (e.g. ARGB becomes BGRA, RGB becomes BGR) */ + bool byte_swap; /*!< Whether to swap the input data in byte. Only available feature if input picture color mode is ARGB8888 or RGB565 */ + ppa_alpha_update_mode_t alpha_update_mode; /*!< Select whether the alpha channel of the input picture needs update */ + union { + uint32_t alpha_fix_val; /*!< Range: [0, 255] + When PPA_ALPHA_FIX_VALUE mode is selected, alpha_fix_val is the new alpha value to replace the input alpha value (output_alpha = alpha_fix_val) */ + float alpha_scale_ratio; /*!< Range: (0, 1) + When PPA_ALPHA_SCALE mode is selected, alpha_scale_ratio is the multiplier to the input alpha value (output_alpha = alpha_scale_ratio * input_alpha) + Ratio resolution is 1/256 */ + }; + + ppa_trans_mode_t mode; /*!< Determines whether to block inside the operation functions, see `ppa_trans_mode_t` */ + void *user_data; /*!< User registered data to be passed into `done_cb` callback function */ +} ppa_srm_oper_config_t; + +/** + * @brief Perform a scaling-rotating-mirroring (SRM) operation to a picture + * + * @param[in] ppa_client PPA client handle that has been registered to do SRM operations + * @param[in] config Pointer to a collection of configurations for the SRM operation transaction, ppa_srm_oper_config_t + * + * @return + * - ESP_OK: Perform a SRM operation successfully + * - ESP_ERR_INVALID_ARG: Perform a SRM operation failed because of invalid argument + * - ESP_FAIL: Perform a SRM operation failed because the client's pending transactions has reached its maximum capacity + */ +esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_srm_oper_config_t *config); + +/** + * @brief A collection of configuration items to do a PPA blend operation transaction + */ +typedef struct { + ppa_in_pic_blk_config_t in_bg; /*!< Information of the input background picture and the target block */ + ppa_in_pic_blk_config_t in_fg; /*!< Information of the input foreground picture and the target block */ + ppa_out_pic_blk_config_t out; /*!< Information of the output picture and the target block */ + + // input data manipulation + bool bg_rgb_swap; /*!< Whether to swap the background input data in RGB (e.g. ARGB becomes BGRA, RGB becomes BGR) */ + bool bg_byte_swap; /*!< Whether to swap the background input data in byte. Only available feature if input BG picture color mode is ARGB8888 or RGB565 */ + ppa_alpha_update_mode_t bg_alpha_update_mode; /*!< Select whether the alpha channel of the input background picture needs update */ + union { + uint32_t bg_alpha_fix_val; /*!< Range: [0, 255] + When PPA_ALPHA_FIX_VALUE mode is selected, alpha_fix_val is the new alpha value to replace the input alpha value (output_alpha = alpha_fix_val) */ + float bg_alpha_scale_ratio; /*!< Range: (0, 1) + When PPA_ALPHA_SCALE mode is selected, alpha_scale_ratio is the multiplier to the input alpha value (output_alpha = alpha_scale_ratio * input_alpha) + Ratio resolution is 1/256 */ + }; + bool fg_rgb_swap; /*!< Whether to swap the foreground input data in RGB (e.g. ARGB becomes BGRA, RGB becomes BGR) */ + bool fg_byte_swap; /*!< Whether to swap the foreground input data in byte. Only available feature if input FG picture color mode is ARGB8888 or RGB565 */ + ppa_alpha_update_mode_t fg_alpha_update_mode; /*!< Select whether the alpha channel of the input foreground picture needs update */ + union { + uint32_t fg_alpha_fix_val; /*!< Range: [0, 255] + When PPA_ALPHA_FIX_VALUE mode is selected, alpha_fix_val is the new alpha value to replace the input alpha value (output_alpha = alpha_fix_val) */ + float fg_alpha_scale_ratio; /*!< Range: (0, 1) + When PPA_ALPHA_SCALE mode is selected, alpha_scale_ratio is the multiplier to the input alpha value (output_alpha = alpha_scale_ratio * input_alpha) + Ratio resolution is 1/256 */ + }; + color_pixel_rgb888_data_t fg_fix_rgb_val; /*!< When in_fg.blend_cm is PPA_BLEND_COLOR_MODE_A8/4, this field can be used to set a fixed color for the foreground, in RGB888 format */ + + // color-keying + // A pixel, where its background element and foreground element are both out of their color-keying ranges, will follow Alpha Blending + bool bg_ck_en; /*!< Whether to enable color keying for background + If not enabled, all background pixels are considered as out of the color-keying range */ + color_pixel_rgb888_data_t bg_ck_rgb_low_thres; /*!< The lower threshold of the color-keying range for the background, in RGB888 format */ + color_pixel_rgb888_data_t bg_ck_rgb_high_thres;/*!< The higher threshold of the color-keying range for the background, in RGB888 format */ + bool fg_ck_en; /*!< Whether to enable color keying for foreground + If not enabled, all foreground pixels are considered as out of the color-keying range */ + color_pixel_rgb888_data_t fg_ck_rgb_low_thres; /*!< The lower threshold of the color-keying range for the foreground, in RGB888 format */ + color_pixel_rgb888_data_t fg_ck_rgb_high_thres;/*!< The higher threshold of the color-keying range for the foreground, in RGB888 format */ + color_pixel_rgb888_data_t ck_rgb_default_val; /*!< The color to overwrite when a pixel, where its background element and foreground element are both within their color-keying ranges, in RGB888 format */ + bool ck_reverse_bg2fg; /*!< If this bit is set, in color-keying, for the pixel, where its background element is in the color range, but its foreground element is not in the color range, it will output the foreground element instead of the background element */ + + ppa_trans_mode_t mode; /*!< Determines whether to block inside the operation functions, see `ppa_trans_mode_t` */ + void *user_data; /*!< User registered data to be passed into `done_cb` callback function */ +} ppa_blend_oper_config_t; + +/** + * @brief Perform a blending operation to a picture + * + * @param[in] ppa_client PPA client handle that has been registered to do blend operations + * @param[in] config Pointer to a collection of configurations for the blend operation transaction, ppa_blend_oper_config_t + * + * @return + * - ESP_OK: Perform a blend operation successfully + * - ESP_ERR_INVALID_ARG: Perform a blend operation failed because of invalid argument + * - ESP_FAIL: Perform a blend operation failed because the client's pending transactions has reached its maximum capacity + */ +esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_config_t *config); + +/** + * @brief A collection of configuration items to do a PPA fill operation transaction + */ +typedef struct { + ppa_out_pic_blk_config_t out; /*!< Information of the output picture and the target block */ + + uint32_t fill_block_w; /*!< The width of the block to be filled (unit: pixel) */ + uint32_t fill_block_h; /*!< The height of the block to be filled (unit: pixel) */ + color_pixel_argb8888_data_t fill_argb_color; /*!< The color to be filled, in ARGB8888 format */ + + ppa_trans_mode_t mode; /*!< Determines whether to block inside the operation functions, see `ppa_trans_mode_t` */ + void *user_data; /*!< User registered data to be passed into `done_cb` callback function */ +} ppa_fill_oper_config_t; + +/** + * @brief Perform a filling operation to a picture + * + * @param[in] ppa_client PPA client handle that has been registered to do fill operations + * @param[in] config Pointer to a collection of configurations for the fill operation transaction, ppa_fill_oper_config_t + * + * @return + * - ESP_OK: Perform a fill operation successfully + * - ESP_ERR_INVALID_ARG: Perform a fill operation failed because of invalid argument + * - ESP_FAIL: Perform a fill operation failed because the client's pending transactions has reached its maximum capacity + */ +esp_err_t ppa_do_fill(ppa_client_handle_t ppa_client, const ppa_fill_oper_config_t *config); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_ppa/src/ppa_blend.c b/components/esp_driver_ppa/src/ppa_blend.c new file mode 100644 index 000000000000..08c3e93e8cc9 --- /dev/null +++ b/components/esp_driver_ppa/src/ppa_blend.c @@ -0,0 +1,287 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" +#include "driver/ppa.h" +#include "ppa_priv.h" +#include "esp_private/dma2d.h" +#include "hal/ppa_ll.h" +#include "esp_cache.h" +#include "esp_memory_utils.h" +#include "soc/dma2d_channel.h" + +static const char *TAG = "ppa_blend"; + +bool ppa_blend_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel_info_t *dma2d_chans, void *user_config) +{ + assert(num_chans == 3 && dma2d_chans && user_config); + ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = (ppa_dma2d_trans_on_picked_config_t *)user_config; + assert(trans_on_picked_desc->trigger_periph == DMA2D_TRIG_PERIPH_PPA_BLEND && trans_on_picked_desc->blend_desc && trans_on_picked_desc->ppa_engine); + + ppa_blend_oper_t *blend_trans_desc = (ppa_blend_oper_t *)trans_on_picked_desc->blend_desc; + ppa_blend_engine_t *blend_engine = __containerof(trans_on_picked_desc->ppa_engine, ppa_blend_engine_t, base); + ppa_platform_t *platform = blend_engine->base.platform; + + // Reset blending engine + ppa_ll_blend_reset(platform->hal.dev); + + // Get the required 2D-DMA channel handles + dma2d_channel_handle_t dma2d_tx_bg_chan = NULL; + dma2d_channel_handle_t dma2d_tx_fg_chan = NULL; + dma2d_channel_handle_t dma2d_rx_chan = NULL; + for (uint32_t i = 0; i < num_chans; i++) { + if (dma2d_chans[i].dir == DMA2D_CHANNEL_DIRECTION_TX) { + if (!dma2d_tx_bg_chan) { + dma2d_tx_bg_chan = dma2d_chans[i].chan; + } else { + dma2d_tx_fg_chan = dma2d_chans[i].chan; + } + } + if (dma2d_chans[i].dir == DMA2D_CHANNEL_DIRECTION_RX) { + dma2d_rx_chan = dma2d_chans[i].chan; + } + } + assert(dma2d_tx_bg_chan && dma2d_tx_fg_chan && dma2d_rx_chan); + + color_space_pixel_format_t in_bg_pixel_format = { + .color_type_id = blend_trans_desc->in_bg.blend_cm, + }; + color_space_pixel_format_t in_fg_pixel_format = { + .color_type_id = blend_trans_desc->in_fg.blend_cm, + }; + color_space_pixel_format_t out_pixel_format = { + .color_type_id = blend_trans_desc->out.blend_cm, + }; + + // Fill 2D-DMA descriptors + blend_engine->dma_tx_bg_desc->vb_size = blend_trans_desc->in_bg.block_h; + blend_engine->dma_tx_bg_desc->hb_length = blend_trans_desc->in_bg.block_w; + blend_engine->dma_tx_bg_desc->err_eof = 0; + blend_engine->dma_tx_bg_desc->dma2d_en = 1; + blend_engine->dma_tx_bg_desc->suc_eof = 1; + blend_engine->dma_tx_bg_desc->owner = DMA2D_DESCRIPTOR_BUFFER_OWNER_DMA; + blend_engine->dma_tx_bg_desc->va_size = blend_trans_desc->in_bg.pic_h; + blend_engine->dma_tx_bg_desc->ha_length = blend_trans_desc->in_bg.pic_w; + blend_engine->dma_tx_bg_desc->pbyte = dma2d_desc_pixel_format_to_pbyte_value(in_bg_pixel_format); + blend_engine->dma_tx_bg_desc->y = blend_trans_desc->in_bg.block_offset_y; + blend_engine->dma_tx_bg_desc->x = blend_trans_desc->in_bg.block_offset_x; + blend_engine->dma_tx_bg_desc->mode = DMA2D_DESCRIPTOR_BLOCK_RW_MODE_SINGLE; + blend_engine->dma_tx_bg_desc->buffer = (void *)blend_trans_desc->in_bg.buffer; + blend_engine->dma_tx_bg_desc->next = NULL; + + blend_engine->dma_tx_fg_desc->vb_size = blend_trans_desc->in_fg.block_h; + blend_engine->dma_tx_fg_desc->hb_length = blend_trans_desc->in_fg.block_w; + blend_engine->dma_tx_fg_desc->err_eof = 0; + blend_engine->dma_tx_fg_desc->dma2d_en = 1; + blend_engine->dma_tx_fg_desc->suc_eof = 1; + blend_engine->dma_tx_fg_desc->owner = DMA2D_DESCRIPTOR_BUFFER_OWNER_DMA; + blend_engine->dma_tx_fg_desc->va_size = blend_trans_desc->in_fg.pic_h; + blend_engine->dma_tx_fg_desc->ha_length = blend_trans_desc->in_fg.pic_w; + blend_engine->dma_tx_fg_desc->pbyte = dma2d_desc_pixel_format_to_pbyte_value(in_fg_pixel_format); + blend_engine->dma_tx_fg_desc->y = blend_trans_desc->in_fg.block_offset_y; + blend_engine->dma_tx_fg_desc->x = blend_trans_desc->in_fg.block_offset_x; + blend_engine->dma_tx_fg_desc->mode = DMA2D_DESCRIPTOR_BLOCK_RW_MODE_SINGLE; + blend_engine->dma_tx_fg_desc->buffer = (void *)blend_trans_desc->in_fg.buffer; + blend_engine->dma_tx_fg_desc->next = NULL; + + blend_engine->dma_rx_desc->vb_size = blend_trans_desc->in_fg.block_h; // in_bg.block_h == in_fg.block_h + blend_engine->dma_rx_desc->hb_length = blend_trans_desc->in_fg.block_w; // in_bg.block_w == in_fg.block_w + blend_engine->dma_rx_desc->err_eof = 0; + blend_engine->dma_rx_desc->dma2d_en = 1; + blend_engine->dma_rx_desc->suc_eof = 1; + blend_engine->dma_rx_desc->owner = DMA2D_DESCRIPTOR_BUFFER_OWNER_DMA; + blend_engine->dma_rx_desc->va_size = blend_trans_desc->out.pic_h; + blend_engine->dma_rx_desc->ha_length = blend_trans_desc->out.pic_w; + blend_engine->dma_rx_desc->pbyte = dma2d_desc_pixel_format_to_pbyte_value(out_pixel_format); + blend_engine->dma_rx_desc->y = blend_trans_desc->out.block_offset_y; + blend_engine->dma_rx_desc->x = blend_trans_desc->out.block_offset_x; + blend_engine->dma_rx_desc->mode = DMA2D_DESCRIPTOR_BLOCK_RW_MODE_SINGLE; + blend_engine->dma_rx_desc->buffer = (void *)blend_trans_desc->out.buffer; + blend_engine->dma_rx_desc->next = NULL; + + esp_cache_msync((void *)blend_engine->dma_tx_bg_desc, platform->dma_desc_mem_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + esp_cache_msync((void *)blend_engine->dma_tx_fg_desc, platform->dma_desc_mem_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + esp_cache_msync((void *)blend_engine->dma_rx_desc, platform->dma_desc_mem_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + + // Configure 2D-DMA channels + dma2d_trigger_t trig_periph = { + .periph = DMA2D_TRIG_PERIPH_PPA_BLEND, + .periph_sel_id = SOC_DMA2D_TRIG_PERIPH_PPA_BLEND_BG_TX, + }; + dma2d_connect(dma2d_tx_bg_chan, &trig_periph); + trig_periph.periph_sel_id = SOC_DMA2D_TRIG_PERIPH_PPA_BLEND_FG_TX; + dma2d_connect(dma2d_tx_fg_chan, &trig_periph); + trig_periph.periph_sel_id = SOC_DMA2D_TRIG_PERIPH_PPA_BLEND_RX; + dma2d_connect(dma2d_rx_chan, &trig_periph); + + dma2d_transfer_ability_t dma_transfer_ability = { + .data_burst_length = blend_trans_desc->data_burst_length, + .desc_burst_en = true, + .mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE, + }; + dma2d_set_transfer_ability(dma2d_tx_bg_chan, &dma_transfer_ability); + dma2d_set_transfer_ability(dma2d_tx_fg_chan, &dma_transfer_ability); + dma2d_set_transfer_ability(dma2d_rx_chan, &dma_transfer_ability); + + dma2d_rx_event_callbacks_t dma_event_cbs = { + .on_recv_eof = ppa_transaction_done_cb, + }; + dma2d_register_rx_event_callbacks(dma2d_rx_chan, &dma_event_cbs, (void *)trans_on_picked_desc->trans_elm); + + dma2d_set_desc_addr(dma2d_tx_bg_chan, (intptr_t)blend_engine->dma_tx_bg_desc); + dma2d_set_desc_addr(dma2d_tx_fg_chan, (intptr_t)blend_engine->dma_tx_fg_desc); + dma2d_set_desc_addr(dma2d_rx_chan, (intptr_t)blend_engine->dma_rx_desc); + dma2d_start(dma2d_tx_bg_chan); + dma2d_start(dma2d_tx_fg_chan); + dma2d_start(dma2d_rx_chan); + + // Configure PPA Blending engine + ppa_ll_blend_set_rx_bg_color_mode(platform->hal.dev, blend_trans_desc->in_bg.blend_cm); + ppa_ll_blend_enable_rx_bg_byte_swap(platform->hal.dev, blend_trans_desc->bg_byte_swap); + ppa_ll_blend_enable_rx_bg_rgb_swap(platform->hal.dev, blend_trans_desc->bg_rgb_swap); + ppa_ll_blend_configure_rx_bg_alpha(platform->hal.dev, blend_trans_desc->bg_alpha_update_mode, blend_trans_desc->bg_alpha_value); + + ppa_ll_blend_set_rx_fg_color_mode(platform->hal.dev, blend_trans_desc->in_fg.blend_cm); + if (COLOR_SPACE_TYPE((uint32_t)blend_trans_desc->in_fg.blend_cm) == COLOR_SPACE_ALPHA) { + ppa_ll_blend_set_rx_fg_fix_rgb(platform->hal.dev, &blend_trans_desc->fg_fix_rgb_val); + } + ppa_ll_blend_enable_rx_fg_byte_swap(platform->hal.dev, blend_trans_desc->fg_byte_swap); + ppa_ll_blend_enable_rx_fg_rgb_swap(platform->hal.dev, blend_trans_desc->fg_rgb_swap); + ppa_ll_blend_configure_rx_fg_alpha(platform->hal.dev, blend_trans_desc->fg_alpha_update_mode, blend_trans_desc->fg_alpha_value); + + ppa_ll_blend_set_tx_color_mode(platform->hal.dev, blend_trans_desc->out.blend_cm); + + // Color keying + color_pixel_rgb888_data_t rgb888_min = {.b = 0x00, .g = 0x00, .r = 0x00}; + color_pixel_rgb888_data_t rgb888_max = {.b = 0xFF, .g = 0xFF, .r = 0xFF}; + ppa_ll_blend_configure_rx_bg_ck_range(platform->hal.dev, + blend_trans_desc->bg_ck_en ? &blend_trans_desc->bg_ck_rgb_low_thres : &rgb888_max, + blend_trans_desc->bg_ck_en ? &blend_trans_desc->bg_ck_rgb_high_thres : &rgb888_min); + ppa_ll_blend_configure_rx_fg_ck_range(platform->hal.dev, + blend_trans_desc->fg_ck_en ? &blend_trans_desc->fg_ck_rgb_low_thres : &rgb888_max, + blend_trans_desc->fg_ck_en ? &blend_trans_desc->fg_ck_rgb_high_thres : &rgb888_min); + ppa_ll_blend_set_ck_default_rgb(platform->hal.dev, (blend_trans_desc->bg_ck_en && blend_trans_desc->fg_ck_en) ? &blend_trans_desc->ck_rgb_default_val : &rgb888_min); + ppa_ll_blend_enable_ck_fg_bg_reverse(platform->hal.dev, blend_trans_desc->ck_reverse_bg2fg); + + ppa_ll_blend_start(platform->hal.dev, PPA_LL_BLEND_TRANS_MODE_BLEND); + + // No need to yield + return false; +} + +esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_config_t *config) +{ + ESP_RETURN_ON_FALSE(ppa_client && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(ppa_client->oper_type == PPA_OPERATION_BLEND, ESP_ERR_INVALID_ARG, TAG, "client is not for blend operations"); + ESP_RETURN_ON_FALSE(config->mode <= PPA_TRANS_MODE_NON_BLOCKING, ESP_ERR_INVALID_ARG, TAG, "invalid mode"); + // in_buffer could be anywhere (ram, flash, psram), out_buffer ptr cannot in flash region + ESP_RETURN_ON_FALSE(esp_ptr_internal(config->out.buffer) || esp_ptr_external_ram(config->out.buffer), ESP_ERR_INVALID_ARG, TAG, "invalid out.buffer addr"); + uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size; + ESP_RETURN_ON_FALSE(((uint32_t)config->out.buffer & (buf_alignment_size - 1)) == 0 && (config->out.buffer_size & (buf_alignment_size - 1)) == 0, + ESP_ERR_INVALID_ARG, TAG, "out.buffer addr or out.buffer_size not aligned to cache line size"); + color_space_pixel_format_t out_pixel_format = { + .color_type_id = config->out.blend_cm, + }; + uint32_t out_pixel_depth = color_hal_pixel_format_get_bit_depth(out_pixel_format); // bits + uint32_t out_pic_len = config->out.pic_w * config->out.pic_h * out_pixel_depth / 8; + ESP_RETURN_ON_FALSE(out_pic_len <= config->out.buffer_size, ESP_ERR_INVALID_ARG, TAG, "out.pic_w/h mismatch with out.buffer_size"); + ESP_RETURN_ON_FALSE(config->in_bg.block_w == config->in_fg.block_w && config->in_bg.block_h == config->in_fg.block_h, + ESP_ERR_INVALID_ARG, TAG, "in_bg.block_w/h must be equal to in_fg.block_w/h"); + if (config->bg_byte_swap) { + PPA_CHECK_CM_SUPPORT_BYTE_SWAP("in_bg.blend", (uint32_t)config->in_bg.blend_cm); + } + if (config->bg_rgb_swap) { + PPA_CHECK_CM_SUPPORT_RGB_SWAP("in_bg.blend", (uint32_t)config->in_bg.blend_cm); + } + if (config->fg_byte_swap) { + PPA_CHECK_CM_SUPPORT_BYTE_SWAP("in_fg.blend", (uint32_t)config->in_fg.blend_cm); + } + if (config->fg_rgb_swap) { + PPA_CHECK_CM_SUPPORT_RGB_SWAP("in_fg.blend", (uint32_t)config->in_fg.blend_cm); + } + uint32_t new_bg_alpha_value = 0; + if (config->bg_alpha_update_mode == PPA_ALPHA_FIX_VALUE) { + ESP_RETURN_ON_FALSE(config->bg_alpha_fix_val <= 0xFF, ESP_ERR_INVALID_ARG, TAG, "invalid bg_alpha_fix_val"); + new_bg_alpha_value = config->bg_alpha_fix_val; + } else if (config->bg_alpha_update_mode == PPA_ALPHA_SCALE) { + ESP_RETURN_ON_FALSE(config->bg_alpha_scale_ratio > 0 && config->bg_alpha_scale_ratio < 1, ESP_ERR_INVALID_ARG, TAG, "invalid bg_alpha_scale_ratio"); + new_bg_alpha_value = (uint32_t)(config->bg_alpha_scale_ratio * 256); + } + uint32_t new_fg_alpha_value = 0; + if (config->fg_alpha_update_mode == PPA_ALPHA_FIX_VALUE) { + ESP_RETURN_ON_FALSE(config->fg_alpha_fix_val <= 0xFF, ESP_ERR_INVALID_ARG, TAG, "invalid fg_alpha_fix_val"); + new_fg_alpha_value = config->fg_alpha_fix_val; + } else if (config->fg_alpha_update_mode == PPA_ALPHA_SCALE) { + ESP_RETURN_ON_FALSE(config->fg_alpha_scale_ratio > 0 && config->fg_alpha_scale_ratio < 1, ESP_ERR_INVALID_ARG, TAG, "invalid fg_alpha_scale_ratio"); + new_fg_alpha_value = (uint32_t)(config->fg_alpha_scale_ratio * 256); + } + // if (config->in_bg.blend_cm == PPA_BLEND_COLOR_MODE_L4) { + // ESP_RETURN_ON_FALSE(config->in_bg.block_w % 2 == 0 && config->in_bg.block_offset_x % 2 == 0, + // ESP_ERR_INVALID_ARG, TAG, "in_bg.block_w and in_bg.block_offset_x must be even"); + // } + if (config->in_fg.blend_cm == PPA_BLEND_COLOR_MODE_A4) { // || config->in_fg.blend_cm == PPA_BLEND_COLOR_MODE_L4 + ESP_RETURN_ON_FALSE(config->in_fg.block_w % 2 == 0 && config->in_fg.block_offset_x % 2 == 0, + ESP_ERR_INVALID_ARG, TAG, "in_fg.block_w and in_fg.block_offset_x must be even"); + } + // To reduce complexity, color_mode, alpha_update_mode correctness are checked in their corresponding LL functions + + // Write back and invalidate necessary data (note that the window content is not continuous in the buffer) + // Write back in_bg_buffer, in_fg_buffer extended windows (alignment not necessary on C2M direction) + color_space_pixel_format_t in_bg_pixel_format = { + .color_type_id = config->in_bg.blend_cm, + }; + uint32_t in_bg_pixel_depth = color_hal_pixel_format_get_bit_depth(in_bg_pixel_format); // bits + uint32_t in_bg_ext_window = (uint32_t)config->in_bg.buffer + config->in_bg.block_offset_y * config->in_bg.pic_w * in_bg_pixel_depth / 8; + uint32_t in_bg_ext_window_len = config->in_bg.pic_w * config->in_bg.block_h * in_bg_pixel_depth / 8; + esp_cache_msync((void *)in_bg_ext_window, in_bg_ext_window_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); + color_space_pixel_format_t in_fg_pixel_format = { + .color_type_id = config->in_fg.blend_cm, + }; + uint32_t in_fg_pixel_depth = color_hal_pixel_format_get_bit_depth(in_fg_pixel_format); // bits + uint32_t in_fg_ext_window = (uint32_t)config->in_fg.buffer + config->in_fg.block_offset_y * config->in_fg.pic_w * in_fg_pixel_depth / 8; + uint32_t in_fg_ext_window_len = config->in_fg.pic_w * config->in_fg.block_h * in_fg_pixel_depth / 8; + esp_cache_msync((void *)in_fg_ext_window, in_fg_ext_window_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); + // Invalidate out_buffer extended window (alignment strict on M2C direction) + uint32_t out_ext_window = (uint32_t)config->out.buffer + config->out.block_offset_y * config->out.pic_w * out_pixel_depth / 8; + uint32_t out_ext_window_len = config->out.pic_w * config->in_bg.block_h * out_pixel_depth / 8; + esp_cache_msync((void *)PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size), PPA_ALIGN_UP(out_ext_window_len, buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C); + + esp_err_t ret = ESP_OK; + ppa_trans_t *trans_elm = NULL; + if (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0)) { + dma2d_trans_config_t *dma_trans_desc = trans_elm->trans_desc; + + ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = dma_trans_desc->user_config; + + ppa_blend_oper_t *blend_trans_desc = (ppa_blend_oper_t *)trans_on_picked_desc->blend_desc; + memcpy(blend_trans_desc, config, sizeof(ppa_blend_oper_config_t)); + blend_trans_desc->bg_alpha_value = new_bg_alpha_value; + blend_trans_desc->fg_alpha_value = new_fg_alpha_value; + blend_trans_desc->data_burst_length = ppa_client->data_burst_length; + + trans_on_picked_desc->ppa_engine = ppa_client->engine; + trans_on_picked_desc->trigger_periph = DMA2D_TRIG_PERIPH_PPA_BLEND; + + dma_trans_desc->tx_channel_num = 2; + dma_trans_desc->rx_channel_num = 1; + dma_trans_desc->channel_flags = 0; + dma_trans_desc->specified_tx_channel_mask = 0; + dma_trans_desc->specified_rx_channel_mask = 0; + + trans_elm->client = ppa_client; + trans_elm->user_data = config->user_data; + xSemaphoreTake(trans_elm->sem, 0); // Ensure no transaction semaphore before transaction starts + + ret = ppa_do_operation(ppa_client, ppa_client->engine, trans_elm, config->mode); + if (ret != ESP_OK) { + ppa_recycle_transaction(ppa_client, trans_elm); + } + } else { + ret = ESP_FAIL; + ESP_LOGE(TAG, "exceed maximum pending transactions for the client, consider increase max_pending_trans_num"); + } + return ret; +} diff --git a/components/esp_driver_ppa/src/ppa_core.c b/components/esp_driver_ppa/src/ppa_core.c new file mode 100644 index 000000000000..a622abdbb564 --- /dev/null +++ b/components/esp_driver_ppa/src/ppa_core.c @@ -0,0 +1,515 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_check.h" +#include "esp_log.h" +#include "freertos/portmacro.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/idf_additions.h" +#include "freertos/queue.h" +#include "esp_heap_caps.h" +#include "esp_cache.h" +#include "esp_private/esp_cache_private.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" +#include "driver/ppa.h" +#include "ppa_priv.h" +#include "esp_private/dma2d.h" +#include "hal/dma2d_ll.h" +#include "hal/ppa_hal.h" +#include "hal/ppa_ll.h" +#include "hal/ppa_types.h" +#include "esp_private/periph_ctrl.h" + +static const char *TAG = "ppa_core"; + +// PPA driver platform +static ppa_platform_t s_platform = { + .spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED, +}; + +static esp_err_t ppa_engine_acquire(const ppa_engine_config_t *config, ppa_engine_t **ret_engine); +static esp_err_t ppa_engine_release(ppa_engine_t *ppa_engine); +static bool ppa_malloc_transaction(QueueHandle_t trans_elm_ptr_queue, uint32_t trans_elm_num, ppa_operation_t oper_type); +static void ppa_free_transaction(ppa_trans_t *trans_elm); + +const dma2d_trans_on_picked_callback_t ppa_oper_trans_on_picked_func[PPA_OPERATION_INVALID] = { + [PPA_OPERATION_SRM] = ppa_srm_transaction_on_picked, + [PPA_OPERATION_BLEND] = ppa_blend_transaction_on_picked, + [PPA_OPERATION_FILL] = ppa_fill_transaction_on_picked, +}; + +static esp_err_t ppa_engine_acquire(const ppa_engine_config_t *config, ppa_engine_t **ret_engine) +{ + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(config && ret_engine, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(config->engine == PPA_ENGINE_TYPE_SRM || config->engine == PPA_ENGINE_TYPE_BLEND, ESP_ERR_INVALID_ARG, TAG, "invalid engine"); + + *ret_engine = NULL; + + uint32_t data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + size_t alignment = MAX(DMA2D_LL_DESC_ALIGNMENT, data_cache_line_size); + + _lock_acquire(&s_platform.mutex); + if (s_platform.dma_desc_mem_size == 0) { + s_platform.dma_desc_mem_size = PPA_ALIGN_UP(sizeof(dma2d_descriptor_align8_t), alignment); + } + if (s_platform.buf_alignment_size == 0) { + esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &s_platform.buf_alignment_size); + } + + if (config->engine == PPA_ENGINE_TYPE_SRM) { + if (!s_platform.srm) { + ppa_srm_engine_t *srm_engine = heap_caps_calloc(1, sizeof(ppa_srm_engine_t), PPA_MEM_ALLOC_CAPS); + SemaphoreHandle_t srm_sem = xSemaphoreCreateBinaryWithCaps(PPA_MEM_ALLOC_CAPS); + dma2d_descriptor_t *srm_tx_dma_desc = (dma2d_descriptor_t *)heap_caps_aligned_calloc(alignment, 1, s_platform.dma_desc_mem_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + dma2d_descriptor_t *srm_rx_dma_desc = (dma2d_descriptor_t *)heap_caps_aligned_calloc(alignment, 1, s_platform.dma_desc_mem_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + if (srm_engine && srm_sem && srm_tx_dma_desc && srm_rx_dma_desc) { + srm_engine->dma_tx_desc = srm_tx_dma_desc; + srm_engine->dma_rx_desc = srm_rx_dma_desc; + srm_engine->base.platform = &s_platform; + srm_engine->base.type = PPA_ENGINE_TYPE_SRM; + srm_engine->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; + srm_engine->base.sem = srm_sem; + xSemaphoreGive(srm_engine->base.sem); + STAILQ_INIT(&srm_engine->base.trans_stailq); + s_platform.srm = srm_engine; + s_platform.srm_engine_ref_count++; + *ret_engine = &srm_engine->base; + + // TODO: Register PPA interrupt? Useful for SRM parameter error. If SRM parameter error, blocks at 2D-DMA, transaction can never finish, stuck... + // need a way to force end + } else { + ret = ESP_ERR_NO_MEM; + ESP_LOGE(TAG, "no mem to register PPA SRM engine"); + free(srm_engine); + if (srm_sem) { + vSemaphoreDeleteWithCaps(srm_sem); + } + free(srm_tx_dma_desc); + free(srm_rx_dma_desc); + } + +#if CONFIG_PM_ENABLE + if (ret == ESP_OK) { + ret = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "ppa_srm", &srm_engine->base.pm_lock); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "create pm lock failed"); + } + } +#endif + } else { + // SRM engine already registered + s_platform.srm_engine_ref_count++; + *ret_engine = &s_platform.srm->base; + } + } else if (config->engine == PPA_ENGINE_TYPE_BLEND) { + if (!s_platform.blending) { + ppa_blend_engine_t *blending_engine = heap_caps_calloc(1, sizeof(ppa_blend_engine_t), PPA_MEM_ALLOC_CAPS); + SemaphoreHandle_t blending_sem = xSemaphoreCreateBinaryWithCaps(PPA_MEM_ALLOC_CAPS); + dma2d_descriptor_t *blending_tx_bg_dma_desc = (dma2d_descriptor_t *)heap_caps_aligned_calloc(alignment, 1, s_platform.dma_desc_mem_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + dma2d_descriptor_t *blending_tx_fg_dma_desc = (dma2d_descriptor_t *)heap_caps_aligned_calloc(alignment, 1, s_platform.dma_desc_mem_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + dma2d_descriptor_t *blending_rx_dma_desc = (dma2d_descriptor_t *)heap_caps_aligned_calloc(alignment, 1, s_platform.dma_desc_mem_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + if (blending_engine && blending_sem && blending_tx_bg_dma_desc && blending_tx_fg_dma_desc && blending_rx_dma_desc) { + blending_engine->dma_tx_bg_desc = blending_tx_bg_dma_desc; + blending_engine->dma_tx_fg_desc = blending_tx_fg_dma_desc; + blending_engine->dma_rx_desc = blending_rx_dma_desc; + blending_engine->base.platform = &s_platform; + blending_engine->base.type = PPA_ENGINE_TYPE_BLEND; + blending_engine->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; + blending_engine->base.sem = blending_sem; + xSemaphoreGive(blending_engine->base.sem); + STAILQ_INIT(&blending_engine->base.trans_stailq); + s_platform.blending = blending_engine; + s_platform.blend_engine_ref_count++; + *ret_engine = &blending_engine->base; + } else { + ret = ESP_ERR_NO_MEM; + ESP_LOGE(TAG, "no mem to register PPA Blending engine"); + free(blending_engine); + if (blending_sem) { + vSemaphoreDeleteWithCaps(blending_sem); + } + free(blending_tx_bg_dma_desc); + free(blending_tx_fg_dma_desc); + free(blending_rx_dma_desc); + } + +#if CONFIG_PM_ENABLE + if (ret == ESP_OK) { + ret = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "ppa_blending", &blending_engine->base.pm_lock); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "create pm lock failed"); + } + } +#endif + } else { + // Blending engine already registered + s_platform.blend_engine_ref_count++; + *ret_engine = &s_platform.blending->base; + } + } + + if (ret == ESP_OK) { + if (!s_platform.hal.dev) { + assert(!s_platform.dma2d_pool_handle); + + // Enable the bus clock to access PPA registers + PERIPH_RCC_ATOMIC() { + ppa_ll_enable_bus_clock(true); + ppa_ll_reset_register(); + } + + ppa_hal_init(&s_platform.hal); // initialize HAL context + + // Get 2D-DMA pool handle + dma2d_pool_config_t dma2d_config = { + .pool_id = 0, + }; + ret = dma2d_acquire_pool(&dma2d_config, &s_platform.dma2d_pool_handle); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "install 2D-DMA failed"); + goto wrap_up; + } + } + } +wrap_up: + _lock_release(&s_platform.mutex); + + if (ret != ESP_OK && *ret_engine != NULL) { + ppa_engine_release(*ret_engine); + } + + return ret; +} + +static esp_err_t ppa_engine_release(ppa_engine_t *ppa_engine) +{ + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(ppa_engine, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + + _lock_acquire(&s_platform.mutex); + if (ppa_engine->type == PPA_ENGINE_TYPE_SRM) { + ppa_srm_engine_t *srm_engine = __containerof(ppa_engine, ppa_srm_engine_t, base); + s_platform.srm_engine_ref_count--; + if (s_platform.srm_engine_ref_count == 0) { + assert(STAILQ_EMPTY(&srm_engine->base.trans_stailq)); + // Now, time to free + s_platform.srm = NULL; + free(srm_engine->dma_tx_desc); + free(srm_engine->dma_rx_desc); + vSemaphoreDeleteWithCaps(srm_engine->base.sem); +#if CONFIG_PM_ENABLE + if (srm_engine->base.pm_lock) { + ret = esp_pm_lock_delete(srm_engine->base.pm_lock); + assert(ret == ESP_OK); + } +#endif + free(srm_engine); + } + } else if (ppa_engine->type == PPA_ENGINE_TYPE_BLEND) { + ppa_blend_engine_t *blending_engine = __containerof(ppa_engine, ppa_blend_engine_t, base); + s_platform.blend_engine_ref_count--; + if (s_platform.blend_engine_ref_count == 0) { + assert(STAILQ_EMPTY(&blending_engine->base.trans_stailq)); + // Now, time to free + s_platform.blending = NULL; + free(blending_engine->dma_tx_bg_desc); + free(blending_engine->dma_tx_fg_desc); + free(blending_engine->dma_rx_desc); + vSemaphoreDeleteWithCaps(blending_engine->base.sem); +#if CONFIG_PM_ENABLE + if (blending_engine->base.pm_lock) { + ret = esp_pm_lock_delete(blending_engine->base.pm_lock); + assert(ret == ESP_OK); + } +#endif + free(blending_engine); + } + } + + if (!s_platform.srm && !s_platform.blending) { + assert(s_platform.srm_engine_ref_count == 0 && s_platform.blend_engine_ref_count == 0); + + if (s_platform.dma2d_pool_handle) { + dma2d_release_pool(s_platform.dma2d_pool_handle); // TODO: check return value. If not ESP_OK, then must be error on other 2D-DMA clients :( Give a warning log? + s_platform.dma2d_pool_handle = NULL; + } + + ppa_hal_deinit(&s_platform.hal); // De-initialize HAL context + + // Disable the bus clock to access PPA registers + PERIPH_RCC_ATOMIC() { + ppa_ll_enable_bus_clock(false); + } + } + _lock_release(&s_platform.mutex); + return ret; +} + +esp_err_t ppa_register_client(const ppa_client_config_t *config, ppa_client_handle_t *ret_client) +{ + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(config && ret_client, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(config->oper_type < PPA_OPERATION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown operation"); + + ppa_client_t *client = (ppa_client_t *)heap_caps_calloc(1, sizeof(ppa_client_t), PPA_MEM_ALLOC_CAPS); + ESP_RETURN_ON_FALSE(client, ESP_ERR_NO_MEM, TAG, "no mem to register client"); + + // Allocate memory for storing transaction contexts and create a queue to save these trans_elm_ptr + uint32_t queue_size = MAX(1, config->max_pending_trans_num); + client->trans_elm_ptr_queue = xQueueCreateWithCaps(queue_size, sizeof(uint32_t), PPA_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(client->trans_elm_ptr_queue && ppa_malloc_transaction(client->trans_elm_ptr_queue, queue_size, config->oper_type), + ESP_ERR_NO_MEM, err, TAG, "no mem for transaction storage"); + + client->oper_type = config->oper_type; + client->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; + client->data_burst_length = config->data_burst_length ? config->data_burst_length : PPA_DATA_BURST_LENGTH_128; + if (config->oper_type == PPA_OPERATION_SRM) { + ppa_engine_config_t engine_config = { + .engine = PPA_ENGINE_TYPE_SRM, + }; + ESP_GOTO_ON_ERROR(ppa_engine_acquire(&engine_config, &client->engine), err, TAG, "unable to acquire SRM engine"); + } else if (config->oper_type == PPA_OPERATION_BLEND || config->oper_type == PPA_OPERATION_FILL) { + ppa_engine_config_t engine_config = { + .engine = PPA_ENGINE_TYPE_BLEND, + }; + ESP_GOTO_ON_ERROR(ppa_engine_acquire(&engine_config, &client->engine), err, TAG, "unable to acquire Blending engine"); + } + *ret_client = client; + +err: + if (ret != ESP_OK) { + ppa_unregister_client(client); + } + return ret; +} + +esp_err_t ppa_unregister_client(ppa_client_handle_t ppa_client) +{ + ESP_RETURN_ON_FALSE(ppa_client, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + + bool do_unregister = false; + portENTER_CRITICAL(&ppa_client->spinlock); + if (ppa_client->trans_cnt == 0) { + do_unregister = true; + } + portEXIT_CRITICAL(&ppa_client->spinlock); + ESP_RETURN_ON_FALSE(do_unregister, ESP_ERR_INVALID_STATE, TAG, "client still has unprocessed trans"); + + if (ppa_client->engine) { + ppa_engine_release(ppa_client->engine); + } + + if (ppa_client->trans_elm_ptr_queue) { + ppa_trans_t *trans_elm = NULL; + while (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0)) { + ppa_free_transaction(trans_elm); + } + vQueueDeleteWithCaps(ppa_client->trans_elm_ptr_queue); + } + free(ppa_client); + return ESP_OK; +} + +esp_err_t ppa_client_register_event_callbacks(ppa_client_handle_t ppa_client, const ppa_event_callbacks_t *cbs) +{ + ESP_RETURN_ON_FALSE(ppa_client && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + + ppa_client->done_cb = cbs->on_trans_done; + return ESP_OK; +} + +// Each PPA engine should only have one transaction being pushed to 2D-DMA queue, the rest transactions should stay in engine's own transaction queue. +// This is to avoid 2D-DMA channels being hold, but not actually being used (waiting for PPA engine to be free) +static esp_err_t ppa_dma2d_enqueue(const ppa_trans_t *trans_elm) +{ + return dma2d_enqueue(s_platform.dma2d_pool_handle, trans_elm->trans_desc, trans_elm->dma_trans_placeholder); +} + +static bool ppa_malloc_transaction(QueueHandle_t trans_elm_ptr_queue, uint32_t trans_elm_num, ppa_operation_t oper_type) +{ + bool res = true; + size_t ppa_trans_desc_size = (oper_type == PPA_OPERATION_SRM) ? sizeof(ppa_srm_oper_t) : + (oper_type == PPA_OPERATION_BLEND) ? sizeof(ppa_blend_oper_t) : + (oper_type == PPA_OPERATION_FILL) ? sizeof(ppa_fill_oper_t) : 0; + assert(ppa_trans_desc_size != 0); + size_t trans_elm_storage_size = sizeof(ppa_trans_t) + SIZEOF_DMA2D_TRANS_T + sizeof(dma2d_trans_config_t) + sizeof(ppa_dma2d_trans_on_picked_config_t) + ppa_trans_desc_size; + for (int i = 0; i < trans_elm_num; i++) { + void *trans_elm_storage = heap_caps_calloc(1, trans_elm_storage_size, PPA_MEM_ALLOC_CAPS); + SemaphoreHandle_t ppa_trans_sem = xSemaphoreCreateBinaryWithCaps(PPA_MEM_ALLOC_CAPS); + + if (!trans_elm_storage || !ppa_trans_sem) { + if (trans_elm_storage) { + free(trans_elm_storage); + } + if (ppa_trans_sem) { + vSemaphoreDeleteWithCaps(ppa_trans_sem); + } + res = false; + break; + } + + // Construct trans_elm + ppa_trans_t *new_trans_elm = (ppa_trans_t *)trans_elm_storage; + dma2d_trans_t *dma_trans_elm = (dma2d_trans_t *)((uint32_t)trans_elm_storage + sizeof(ppa_trans_t)); + dma2d_trans_config_t *dma_trans_desc = (dma2d_trans_config_t *)((uint32_t)dma_trans_elm + SIZEOF_DMA2D_TRANS_T); + ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = (ppa_dma2d_trans_on_picked_config_t *)((uint32_t)dma_trans_desc + sizeof(dma2d_trans_config_t)); + void *ppa_trans_desc = (void *)((uint32_t)trans_on_picked_desc + sizeof(ppa_dma2d_trans_on_picked_config_t)); + + trans_on_picked_desc->op_desc = ppa_trans_desc; + trans_on_picked_desc->trans_elm = new_trans_elm; + dma_trans_desc->user_config = (void *)trans_on_picked_desc; + dma_trans_desc->on_job_picked = ppa_oper_trans_on_picked_func[oper_type]; + new_trans_elm->trans_desc = dma_trans_desc; + new_trans_elm->dma_trans_placeholder = dma_trans_elm; + new_trans_elm->sem = ppa_trans_sem; + + // Fill the queue with allocated transaction element pointer + BaseType_t sent = xQueueSend(trans_elm_ptr_queue, &new_trans_elm, 0); + assert(sent); + } + return res; +} + +static void ppa_free_transaction(ppa_trans_t *trans_elm) +{ + if (trans_elm) { + if (trans_elm->sem) { + vSemaphoreDeleteWithCaps(trans_elm->sem); + } + free(trans_elm); + } +} + +bool ppa_recycle_transaction(ppa_client_handle_t ppa_client, ppa_trans_t *trans_elm) +{ + // Reset transaction and send back to client's trans_elm_ptr_queue + // TODO: To be very safe, we shall memset all to 0, and reconnect necessary pointers? + BaseType_t HPTaskAwoken; + BaseType_t sent = xQueueSendFromISR(ppa_client->trans_elm_ptr_queue, &trans_elm, &HPTaskAwoken); + assert(sent); + return HPTaskAwoken; +} + +esp_err_t ppa_do_operation(ppa_client_handle_t ppa_client, ppa_engine_t *ppa_engine_base, ppa_trans_t *trans_elm, ppa_trans_mode_t mode) +{ + esp_err_t ret = ESP_OK; + esp_err_t pm_lock_ret __attribute__((unused)); + + portENTER_CRITICAL(&ppa_client->spinlock); + // Send transaction into PPA engine queue + portENTER_CRITICAL(&ppa_engine_base->spinlock); + STAILQ_INSERT_TAIL(&ppa_engine_base->trans_stailq, trans_elm, entry); + portEXIT_CRITICAL(&ppa_engine_base->spinlock); + ppa_client->trans_cnt++; + portEXIT_CRITICAL(&ppa_client->spinlock); + + TickType_t ticks_to_wait = (mode == PPA_TRANS_MODE_NON_BLOCKING) ? 0 : portMAX_DELAY; + if (xSemaphoreTake(ppa_engine_base->sem, ticks_to_wait) == pdTRUE) { + // Check if the transaction has already been started from the ISR + // If so, then the transaction should have been removed from queue at this moment (transaction completed) + bool found = false; + ppa_trans_t *temp = NULL; + portENTER_CRITICAL(&ppa_engine_base->spinlock); + STAILQ_FOREACH(temp, &ppa_engine_base->trans_stailq, entry) { + if (temp == trans_elm) { + found = true; + break; + } + } + portEXIT_CRITICAL(&ppa_engine_base->spinlock); + if (found) { +#if CONFIG_PM_ENABLE + pm_lock_ret = esp_pm_lock_acquire(ppa_engine_base->pm_lock); + assert((pm_lock_ret == ESP_OK) && "acquire pm_lock failed"); +#endif + ret = ppa_dma2d_enqueue(trans_elm); + if (ret != ESP_OK) { + portENTER_CRITICAL(&ppa_engine_base->spinlock); + STAILQ_REMOVE(&ppa_engine_base->trans_stailq, trans_elm, ppa_trans_s, entry); + portEXIT_CRITICAL(&ppa_engine_base->spinlock); + xSemaphoreGive(ppa_engine_base->sem); +#if CONFIG_PM_ENABLE + pm_lock_ret = esp_pm_lock_release(ppa_engine_base->pm_lock); + assert((pm_lock_ret == ESP_OK) && "release pm_lock failed"); +#endif + portENTER_CRITICAL(&ppa_client->spinlock); + ppa_client->trans_cnt--; + portEXIT_CRITICAL(&ppa_client->spinlock); + goto err; + } + } else { + xSemaphoreGive(ppa_engine_base->sem); + } + } + + if (mode == PPA_TRANS_MODE_BLOCKING) { + xSemaphoreTake(trans_elm->sem, portMAX_DELAY); // Given in the ISR + } + +err: + return ret; +} + +bool ppa_transaction_done_cb(dma2d_channel_handle_t dma2d_chan, dma2d_event_data_t *event_data, void *user_data) +{ + bool need_yield = false; + BaseType_t HPTaskAwoken; + ppa_trans_t *trans_elm = (ppa_trans_t *)user_data; + ppa_client_t *client = trans_elm->client; + ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = (ppa_dma2d_trans_on_picked_config_t *)trans_elm->trans_desc->user_config; + ppa_engine_t *engine_base = trans_on_picked_desc->ppa_engine; + // Save callback contexts + ppa_event_callback_t done_cb = client->done_cb; + void *trans_elm_user_data = trans_elm->user_data; + + ppa_trans_t *next_start_trans = NULL; + portENTER_CRITICAL_ISR(&engine_base->spinlock); + // Remove this transaction from transaction queue + STAILQ_REMOVE(&engine_base->trans_stailq, trans_elm, ppa_trans_s, entry); + next_start_trans = STAILQ_FIRST(&engine_base->trans_stailq); + portEXIT_CRITICAL_ISR(&engine_base->spinlock); + + portENTER_CRITICAL_ISR(&client->spinlock); + // Release transaction semaphore to unblock ppa_do_operation + xSemaphoreGiveFromISR(trans_elm->sem, &HPTaskAwoken); + need_yield |= (HPTaskAwoken == pdTRUE); + + // Then recycle transaction elm + need_yield |= ppa_recycle_transaction(client, trans_elm); + + client->trans_cnt--; + portEXIT_CRITICAL_ISR(&client->spinlock); + + // If there is next trans in PPA engine queue, send it to DMA queue; otherwise, release the engine semaphore + if (next_start_trans) { + ppa_dma2d_enqueue(next_start_trans); + } else { + xSemaphoreGiveFromISR(engine_base->sem, &HPTaskAwoken); + need_yield |= (HPTaskAwoken == pdTRUE); +#if CONFIG_PM_ENABLE + esp_err_t pm_lock_ret = esp_pm_lock_release(engine_base->pm_lock); + assert(pm_lock_ret == ESP_OK); +#endif + } + + // Process last transaction's callback + if (done_cb) { + ppa_event_data_t edata = {}; + need_yield |= done_cb(client, &edata, trans_elm_user_data); + } + + return need_yield; +} diff --git a/components/esp_driver_ppa/src/ppa_fill.c b/components/esp_driver_ppa/src/ppa_fill.c new file mode 100644 index 000000000000..d34c338dcaa8 --- /dev/null +++ b/components/esp_driver_ppa/src/ppa_fill.c @@ -0,0 +1,146 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" +#include "driver/ppa.h" +#include "ppa_priv.h" +#include "esp_private/dma2d.h" +#include "hal/ppa_ll.h" +#include "esp_cache.h" +#include "esp_memory_utils.h" +#include "soc/dma2d_channel.h" + +static const char *TAG = "ppa_fill"; + +bool ppa_fill_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel_info_t *dma2d_chans, void *user_config) +{ + assert(num_chans == 1 && dma2d_chans && user_config); + ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = (ppa_dma2d_trans_on_picked_config_t *)user_config; + assert(trans_on_picked_desc->trigger_periph == DMA2D_TRIG_PERIPH_PPA_BLEND && trans_on_picked_desc->fill_desc && trans_on_picked_desc->ppa_engine); + + ppa_fill_oper_t *fill_trans_desc = (ppa_fill_oper_t *)trans_on_picked_desc->fill_desc; + ppa_blend_engine_t *blend_engine = __containerof(trans_on_picked_desc->ppa_engine, ppa_blend_engine_t, base); + ppa_platform_t *platform = blend_engine->base.platform; + + // Reset blending engine + ppa_ll_blend_reset(platform->hal.dev); + + // Get the required 2D-DMA channel handles + assert(dma2d_chans[0].dir == DMA2D_CHANNEL_DIRECTION_RX); + dma2d_channel_handle_t dma2d_rx_chan = dma2d_chans[0].chan; + + color_space_pixel_format_t out_pixel_format = { + .color_type_id = fill_trans_desc->out.fill_cm, + }; + + // Fill 2D-DMA descriptors + blend_engine->dma_rx_desc->vb_size = fill_trans_desc->fill_block_h; + blend_engine->dma_rx_desc->hb_length = fill_trans_desc->fill_block_w; + blend_engine->dma_rx_desc->err_eof = 0; + blend_engine->dma_rx_desc->dma2d_en = 1; + blend_engine->dma_rx_desc->suc_eof = 1; + blend_engine->dma_rx_desc->owner = DMA2D_DESCRIPTOR_BUFFER_OWNER_DMA; + blend_engine->dma_rx_desc->va_size = fill_trans_desc->out.pic_h; + blend_engine->dma_rx_desc->ha_length = fill_trans_desc->out.pic_w; + blend_engine->dma_rx_desc->pbyte = dma2d_desc_pixel_format_to_pbyte_value(out_pixel_format); + blend_engine->dma_rx_desc->y = fill_trans_desc->out.block_offset_y; + blend_engine->dma_rx_desc->x = fill_trans_desc->out.block_offset_x; + blend_engine->dma_rx_desc->mode = DMA2D_DESCRIPTOR_BLOCK_RW_MODE_SINGLE; + blend_engine->dma_rx_desc->buffer = (void *)fill_trans_desc->out.buffer; + blend_engine->dma_rx_desc->next = NULL; + + esp_cache_msync((void *)blend_engine->dma_rx_desc, platform->dma_desc_mem_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + + // Configure 2D-DMA channels + dma2d_trigger_t trig_periph = { + .periph = DMA2D_TRIG_PERIPH_PPA_BLEND, + .periph_sel_id = SOC_DMA2D_TRIG_PERIPH_PPA_BLEND_RX, + }; + dma2d_connect(dma2d_rx_chan, &trig_periph); + + dma2d_transfer_ability_t dma_transfer_ability = { + .data_burst_length = fill_trans_desc->data_burst_length, + .desc_burst_en = true, + .mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE, + }; + dma2d_set_transfer_ability(dma2d_rx_chan, &dma_transfer_ability); + + dma2d_rx_event_callbacks_t dma_event_cbs = { + .on_recv_eof = ppa_transaction_done_cb, + }; + dma2d_register_rx_event_callbacks(dma2d_rx_chan, &dma_event_cbs, (void *)trans_on_picked_desc->trans_elm); + + dma2d_set_desc_addr(dma2d_rx_chan, (intptr_t)blend_engine->dma_rx_desc); + dma2d_start(dma2d_rx_chan); + + // Configure PPA Blending engine + ppa_ll_blend_configure_filling_block(platform->hal.dev, &fill_trans_desc->fill_argb_color, fill_trans_desc->fill_block_w, fill_trans_desc->fill_block_h); + ppa_ll_blend_set_tx_color_mode(platform->hal.dev, fill_trans_desc->out.fill_cm); + + ppa_ll_blend_start(platform->hal.dev, PPA_LL_BLEND_TRANS_MODE_FILL); + + // No need to yield + return false; +} + +esp_err_t ppa_do_fill(ppa_client_handle_t ppa_client, const ppa_fill_oper_config_t *config) +{ + ESP_RETURN_ON_FALSE(ppa_client && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(ppa_client->oper_type == PPA_OPERATION_FILL, ESP_ERR_INVALID_ARG, TAG, "client is not for fill operations"); + ESP_RETURN_ON_FALSE(config->mode <= PPA_TRANS_MODE_NON_BLOCKING, ESP_ERR_INVALID_ARG, TAG, "invalid mode"); + // out_buffer ptr cannot in flash region + ESP_RETURN_ON_FALSE(esp_ptr_internal(config->out.buffer) || esp_ptr_external_ram(config->out.buffer), ESP_ERR_INVALID_ARG, TAG, "invalid out.buffer addr"); + uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size; + ESP_RETURN_ON_FALSE(((uint32_t)config->out.buffer & (buf_alignment_size - 1)) == 0 && (config->out.buffer_size & (buf_alignment_size - 1)) == 0, + ESP_ERR_INVALID_ARG, TAG, "out.buffer addr or out.buffer_size not aligned to cache line size"); + color_space_pixel_format_t out_pixel_format = { + .color_type_id = config->out.fill_cm, + }; + uint32_t out_pixel_depth = color_hal_pixel_format_get_bit_depth(out_pixel_format); + uint32_t out_pic_len = config->out.pic_w * config->out.pic_h * out_pixel_depth / 8; + ESP_RETURN_ON_FALSE(out_pic_len <= config->out.buffer_size, ESP_ERR_INVALID_ARG, TAG, "out.pic_w/h mismatch with out.buffer_size"); + // To reduce complexity, color_mode, fill_block_w/h correctness are checked in their corresponding LL functions + + // Write back and invalidate necessary data (note that the window content is not continuous in the buffer) + // Write back and invalidate buffer extended window (alignment not necessary on C2M direction, but alignment strict on M2C direction) + uint32_t out_ext_window = (uint32_t)config->out.buffer + config->out.block_offset_y * config->out.pic_w * out_pixel_depth / 8; + uint32_t out_ext_window_len = config->out.pic_w * config->fill_block_h * out_pixel_depth / 8; + esp_cache_msync((void *)PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size), PPA_ALIGN_UP(out_ext_window_len, buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE); + + esp_err_t ret = ESP_OK; + ppa_trans_t *trans_elm = NULL; + if (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0)) { + dma2d_trans_config_t *dma_trans_desc = trans_elm->trans_desc; + + ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = dma_trans_desc->user_config; + + ppa_fill_oper_t *fill_trans_desc = (ppa_fill_oper_t *)trans_on_picked_desc->fill_desc; + memcpy(fill_trans_desc, config, sizeof(ppa_fill_oper_config_t)); + fill_trans_desc->data_burst_length = ppa_client->data_burst_length; + + trans_on_picked_desc->ppa_engine = ppa_client->engine; + trans_on_picked_desc->trigger_periph = DMA2D_TRIG_PERIPH_PPA_BLEND; + + dma_trans_desc->tx_channel_num = 0; + dma_trans_desc->rx_channel_num = 1; + dma_trans_desc->channel_flags = 0; + dma_trans_desc->specified_tx_channel_mask = 0; + dma_trans_desc->specified_rx_channel_mask = 0; + + trans_elm->client = ppa_client; + trans_elm->user_data = config->user_data; + xSemaphoreTake(trans_elm->sem, 0); // Ensure no transaction semaphore before transaction starts + + ret = ppa_do_operation(ppa_client, ppa_client->engine, trans_elm, config->mode); + if (ret != ESP_OK) { + ppa_recycle_transaction(ppa_client, trans_elm); + } + } else { + ret = ESP_FAIL; + ESP_LOGE(TAG, "exceed maximum pending transactions for the client, consider increase max_pending_trans_num"); + } + return ret; +} diff --git a/components/esp_driver_ppa/src/ppa_priv.h b/components/esp_driver_ppa/src/ppa_priv.h new file mode 100644 index 000000000000..2a3b1e5d57de --- /dev/null +++ b/components/esp_driver_ppa/src/ppa_priv.h @@ -0,0 +1,235 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "sdkconfig.h" +#include "driver/ppa.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "esp_private/dma2d.h" +#include "hal/dma2d_types.h" +#include "hal/ppa_types.h" +#include "hal/ppa_hal.h" +#include "esp_pm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PPA_MEM_ALLOC_CAPS (MALLOC_CAP_DEFAULT) + +#define PPA_PM_LOCK_NAME_LEN_MAX 16 + +#define PPA_CHECK_CM_SUPPORT_BYTE_SWAP(str, color_type_id) \ + ESP_RETURN_ON_FALSE(color_type_id == COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888) || color_type_id == COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), \ + ESP_ERR_INVALID_ARG, TAG, str "_cm does not support byte_swap"); + +#define PPA_CHECK_CM_SUPPORT_RGB_SWAP(str, color_type_id) \ + ESP_RETURN_ON_FALSE(COLOR_SPACE_TYPE(color_type_id) == COLOR_SPACE_ARGB || COLOR_SPACE_TYPE(color_type_id) == COLOR_SPACE_RGB, \ + ESP_ERR_INVALID_ARG, TAG, str "_cm does not support rgb_swap"); + +#define PPA_ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) +#define PPA_ALIGN_DOWN(num, align) ((num) & ~((align) - 1)) + +typedef struct ppa_platform_t ppa_platform_t; + +/******************************** ENGINE *************************************/ +// PPA module contains SRM engine and Blending engine + +typedef struct ppa_engine_t ppa_engine_t; + +struct ppa_engine_t { + ppa_platform_t *platform; // PPA driver platform + ppa_engine_type_t type; // Type of the PPA engine + portMUX_TYPE spinlock; // Engine level spinlock + SemaphoreHandle_t sem; // Semaphore for whether the engine is processing a transaction + STAILQ_HEAD(trans, ppa_trans_s) trans_stailq; // link head of pending transactions for the PPA engine +#if CONFIG_PM_ENABLE + esp_pm_lock_handle_t pm_lock; // Power management lock +#endif +}; + +typedef struct ppa_srm_engine_t { + ppa_engine_t base; // PPA engine base structure + dma2d_descriptor_t *dma_tx_desc; // Into PPA SRM engine direction 2D-DMA descriptor + dma2d_descriptor_t *dma_rx_desc; // Out from PPA SRM engine direction 2D-DMA descriptor +} ppa_srm_engine_t; + +typedef struct ppa_blend_engine_t { + ppa_engine_t base; // PPA engine base structure + dma2d_descriptor_t *dma_tx_bg_desc; // Into PPA Blending engine direction background channel 2D-DMA descriptor + dma2d_descriptor_t *dma_tx_fg_desc; // Into PPA Blending engine direction foreground channel 2D-DMA descriptor + dma2d_descriptor_t *dma_rx_desc; // Out from PPA blending engine direction 2D-DMA descriptor +} ppa_blend_engine_t; + +typedef struct { + ppa_engine_type_t engine; // Engine type +} ppa_engine_config_t; + +/******************************** CLIENT *************************************/ + +typedef struct ppa_client_t ppa_client_t; + +struct ppa_client_t { + ppa_operation_t oper_type; // The PPA operation type that the client wants to do in speciality + ppa_engine_t *engine; // Pointer to the PPA engine that in charge of performing the PPA operation + uint32_t trans_cnt; // Number of pending PPA transactions + portMUX_TYPE spinlock; // Client level spinlock + ppa_event_callback_t done_cb; // Transaction done callback + QueueHandle_t trans_elm_ptr_queue; // Queue that contains the pointers to the allocated memory to save the transaction contexts + ppa_data_burst_length_t data_burst_length; // The desired data burst length for all the transactions of the client +}; + +/****************************** OPERATION ************************************/ + +// The elements in this structure listed first are identical to the elements in structure `ppa_srm_oper_config_t` +// With adding a few extra elements at the end +// This allows memcpy +typedef struct { + ppa_in_pic_blk_config_t in; + ppa_out_pic_blk_config_t out; + + // scale-rotate-mirror manipulation + ppa_srm_rotation_angle_t rotation_angle; + float scale_x; + float scale_y; + bool mirror_x; + bool mirror_y; + + // input data manipulation + bool rgb_swap; + bool byte_swap; + ppa_alpha_update_mode_t alpha_update_mode; + union { + uint32_t alpha_fix_val; + float alpha_scale_ratio; + }; + + ppa_trans_mode_t mode; + void *user_data; + + uint32_t scale_x_int; // Calculation result for the integral part of the scale_x to be directly written to register + uint32_t scale_x_frag; // Calculation result for the fractional part of the scale_x to be directly written to register + uint32_t scale_y_int; // Calculation result for the integral part of the scale_y to be directly written to register + uint32_t scale_y_frag; // Calculation result for the fractional part of the scale_y to be directly written to register + uint32_t alpha_value; // Calculation result for the fix alpha value to be directly written to register + ppa_data_burst_length_t data_burst_length; // Data burst length for the transaction, information passed from the client +} ppa_srm_oper_t; + +// The elements in this structure listed first are identical to the elements in structure `ppa_blend_oper_config_t` +// With adding a few extra elements at the end +// This allows memcpy +typedef struct { + ppa_in_pic_blk_config_t in_bg; + ppa_in_pic_blk_config_t in_fg; + ppa_out_pic_blk_config_t out; + + // input data manipulation + bool bg_rgb_swap; + bool bg_byte_swap; + ppa_alpha_update_mode_t bg_alpha_update_mode; + union { + uint32_t bg_alpha_fix_val; + float bg_alpha_scale_ratio; + }; + bool fg_rgb_swap; + bool fg_byte_swap; + ppa_alpha_update_mode_t fg_alpha_update_mode; + union { + uint32_t fg_alpha_fix_val; + float fg_alpha_scale_ratio; + }; + color_pixel_rgb888_data_t fg_fix_rgb_val; + + // color-keying + bool bg_ck_en; + color_pixel_rgb888_data_t bg_ck_rgb_low_thres; + color_pixel_rgb888_data_t bg_ck_rgb_high_thres; + bool fg_ck_en; + color_pixel_rgb888_data_t fg_ck_rgb_low_thres; + color_pixel_rgb888_data_t fg_ck_rgb_high_thres; + color_pixel_rgb888_data_t ck_rgb_default_val; + bool ck_reverse_bg2fg; + + ppa_trans_mode_t mode; + void *user_data; + + uint32_t bg_alpha_value; // Calculation result for the fix alpha value for BG to be directly written to register + uint32_t fg_alpha_value; // Calculation result for the fix alpha value for FG to be directly written to register + ppa_data_burst_length_t data_burst_length; // Data burst length for the transaction, information passed from the client +} ppa_blend_oper_t; + +// The elements in this structure listed first are identical to the elements in structure `ppa_fill_oper_config_t` +// With adding a few extra elements at the end +// This allows memcpy +typedef struct { + ppa_out_pic_blk_config_t out; + + uint32_t fill_block_w; + uint32_t fill_block_h; + color_pixel_argb8888_data_t fill_argb_color; + + ppa_trans_mode_t mode; + void *user_data; + + ppa_data_burst_length_t data_burst_length; // Data burst length for the transaction, information passed from the client +} ppa_fill_oper_t; + +/***************************** TRANSACTION ***********************************/ + +// PPA transaction element +typedef struct ppa_trans_s { + STAILQ_ENTRY(ppa_trans_s) entry; // Link entry + dma2d_trans_config_t *trans_desc; // Pointer to the structure containing the configurations for a 2D-DMA transaction + dma2d_trans_t *dma_trans_placeholder; // Pointer to the memory to store the 2D-DMA transaction context + SemaphoreHandle_t sem; // Semaphore to block when the transaction has not finished + ppa_client_t *client; // Pointer to the client who requested the transaction + void *user_data; // User registered event data (per transaction) +} ppa_trans_t; + +typedef struct { + union { + ppa_srm_oper_t *srm_desc; // Pointer to the structure containing the configurations for a PPA SRM operation transaction + ppa_blend_oper_t *blend_desc; // Pointer to the structure containing the configurations for a PPA blend operation transaction + ppa_fill_oper_t *fill_desc; // Pointer to the structure containing the configurations for a PPA fill operation transaction + void *op_desc; // General pointer to the structure containing the configurations for a PPA transaction + }; + ppa_engine_t *ppa_engine; // Pointer to the PPA engine + ppa_trans_t *trans_elm; // Pointer to the PPA transaction element + dma2d_trigger_peripheral_t trigger_periph; // The 2D-DMA trigger peripheral +} ppa_dma2d_trans_on_picked_config_t; + +bool ppa_srm_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel_info_t *dma2d_chans, void *user_config); +bool ppa_blend_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel_info_t *dma2d_chans, void *user_config); +bool ppa_fill_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel_info_t *dma2d_chans, void *user_config); + +esp_err_t ppa_do_operation(ppa_client_handle_t ppa_client, ppa_engine_t *ppa_engine_base, ppa_trans_t *trans_elm, ppa_trans_mode_t mode); + +bool ppa_transaction_done_cb(dma2d_channel_handle_t dma2d_chan, dma2d_event_data_t *event_data, void *user_data); + +bool ppa_recycle_transaction(ppa_client_handle_t ppa_client, ppa_trans_t *trans_elm); + +/****************************** PPA DRIVER ***********************************/ + +struct ppa_platform_t { + _lock_t mutex; // Platform level mutex lock to protect the ppa_engine_acquire/ppa_engine_release process + portMUX_TYPE spinlock; // Platform level spinlock + ppa_hal_context_t hal; // PPA HAL context + dma2d_pool_handle_t dma2d_pool_handle; // Pointer to the acquired 2D-DMA pool + ppa_srm_engine_t *srm; // Pointer to the PPA SRM engine + ppa_blend_engine_t *blending; // Pointer to the PPA blending engine + uint32_t srm_engine_ref_count; // Reference count used to protect PPA SRM engine acquire and release + uint32_t blend_engine_ref_count; // Reference count used to protect PPA blending engine acquire and release + size_t buf_alignment_size; // Alignment requirement for the outgoing buffer addr and size to satisfy cache line size + uint32_t dma_desc_mem_size; // Alignment requirement for the 2D-DMA descriptor to satisfy cache line size +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_ppa/src/ppa_srm.c b/components/esp_driver_ppa/src/ppa_srm.c new file mode 100644 index 000000000000..6fbcc4f7eddb --- /dev/null +++ b/components/esp_driver_ppa/src/ppa_srm.c @@ -0,0 +1,292 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" +#include "driver/ppa.h" +#include "ppa_priv.h" +#include "esp_private/dma2d.h" +#include "hal/ppa_ll.h" +#include "esp_cache.h" +#include "esp_memory_utils.h" +#include "soc/dma2d_channel.h" + +static const char *TAG = "ppa_srm"; + +bool ppa_srm_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel_info_t *dma2d_chans, void *user_config) +{ + assert(num_chans == 2 && dma2d_chans && user_config); + ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = (ppa_dma2d_trans_on_picked_config_t *)user_config; + assert(trans_on_picked_desc->trigger_periph == DMA2D_TRIG_PERIPH_PPA_SRM && trans_on_picked_desc->srm_desc && trans_on_picked_desc->ppa_engine); + + ppa_srm_oper_t *srm_trans_desc = (ppa_srm_oper_t *)trans_on_picked_desc->srm_desc; + ppa_srm_engine_t *srm_engine = __containerof(trans_on_picked_desc->ppa_engine, ppa_srm_engine_t, base); + ppa_platform_t *platform = srm_engine->base.platform; + + // Reset SRM engine + ppa_ll_srm_reset(platform->hal.dev); + + // Get the required 2D-DMA channel handles + dma2d_channel_handle_t dma2d_tx_chan = NULL; + dma2d_channel_handle_t dma2d_rx_chan = NULL; + for (uint32_t i = 0; i < num_chans; i++) { + if (dma2d_chans[i].dir == DMA2D_CHANNEL_DIRECTION_TX) { + dma2d_tx_chan = dma2d_chans[i].chan; + } + if (dma2d_chans[i].dir == DMA2D_CHANNEL_DIRECTION_RX) { + dma2d_rx_chan = dma2d_chans[i].chan; + } + } + assert(dma2d_tx_chan && dma2d_rx_chan); + + color_space_pixel_format_t in_pixel_format = { + .color_type_id = srm_trans_desc->in.srm_cm, + }; + + // Fill 2D-DMA descriptors + srm_engine->dma_tx_desc->vb_size = srm_trans_desc->in.block_h; + srm_engine->dma_tx_desc->hb_length = srm_trans_desc->in.block_w; + srm_engine->dma_tx_desc->err_eof = 0; + srm_engine->dma_tx_desc->dma2d_en = 1; + srm_engine->dma_tx_desc->suc_eof = 1; + srm_engine->dma_tx_desc->owner = DMA2D_DESCRIPTOR_BUFFER_OWNER_DMA; + srm_engine->dma_tx_desc->va_size = srm_trans_desc->in.pic_h; + srm_engine->dma_tx_desc->ha_length = srm_trans_desc->in.pic_w; + srm_engine->dma_tx_desc->pbyte = dma2d_desc_pixel_format_to_pbyte_value(in_pixel_format); + srm_engine->dma_tx_desc->y = srm_trans_desc->in.block_offset_y; + srm_engine->dma_tx_desc->x = srm_trans_desc->in.block_offset_x; + srm_engine->dma_tx_desc->mode = DMA2D_DESCRIPTOR_BLOCK_RW_MODE_SINGLE; + srm_engine->dma_tx_desc->buffer = (void *)srm_trans_desc->in.buffer; + srm_engine->dma_tx_desc->next = NULL; + + // vb_size, hb_length can be any value (auto writeback) + // However, if vb_size/hb_length is 0, it triggers 2D-DMA DESC_ERROR interrupt, and dma2d driver will automatically ends the transaction + // Moreover, for YUV420, hb/vb have to be even + // Therefore, we set them to 2 + srm_engine->dma_rx_desc->vb_size = 2; + srm_engine->dma_rx_desc->hb_length = 2; + srm_engine->dma_rx_desc->err_eof = 0; + srm_engine->dma_rx_desc->dma2d_en = 1; + srm_engine->dma_rx_desc->suc_eof = 1; + srm_engine->dma_rx_desc->owner = DMA2D_DESCRIPTOR_BUFFER_OWNER_DMA; + srm_engine->dma_rx_desc->va_size = srm_trans_desc->out.pic_h; + srm_engine->dma_rx_desc->ha_length = srm_trans_desc->out.pic_w; + // pbyte can be any value + srm_engine->dma_rx_desc->y = srm_trans_desc->out.block_offset_y; + srm_engine->dma_rx_desc->x = srm_trans_desc->out.block_offset_x; + srm_engine->dma_rx_desc->mode = DMA2D_DESCRIPTOR_BLOCK_RW_MODE_SINGLE; + srm_engine->dma_rx_desc->buffer = (void *)srm_trans_desc->out.buffer; + srm_engine->dma_rx_desc->next = NULL; + + esp_cache_msync((void *)srm_engine->dma_tx_desc, platform->dma_desc_mem_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + esp_cache_msync((void *)srm_engine->dma_rx_desc, platform->dma_desc_mem_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + + // Configure 2D-DMA channels + dma2d_trigger_t trig_periph = { + .periph = DMA2D_TRIG_PERIPH_PPA_SRM, + .periph_sel_id = SOC_DMA2D_TRIG_PERIPH_PPA_SRM_TX, + }; + dma2d_connect(dma2d_tx_chan, &trig_periph); + trig_periph.periph_sel_id = SOC_DMA2D_TRIG_PERIPH_PPA_SRM_RX; + dma2d_connect(dma2d_rx_chan, &trig_periph); + + dma2d_transfer_ability_t dma_transfer_ability = { + .data_burst_length = srm_trans_desc->data_burst_length, + .desc_burst_en = true, + .mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE, + }; + dma2d_set_transfer_ability(dma2d_tx_chan, &dma_transfer_ability); + dma2d_set_transfer_ability(dma2d_rx_chan, &dma_transfer_ability); + + // Configure the block size to be received by the SRM engine, which is passed from the 2D-DMA TX channel (i.e. 2D-DMA dscr-port mode) + dma2d_dscr_port_mode_config_t dma_dscr_port_mode_config = { + .block_h = (srm_trans_desc->in.srm_cm == PPA_SRM_COLOR_MODE_YUV420) ? PPA_LL_SRM_YUV420_BLOCK_SIZE : PPA_LL_SRM_DEFAULT_BLOCK_SIZE, + .block_v = (srm_trans_desc->in.srm_cm == PPA_SRM_COLOR_MODE_YUV420) ? PPA_LL_SRM_YUV420_BLOCK_SIZE : PPA_LL_SRM_DEFAULT_BLOCK_SIZE, + }; + dma2d_configure_dscr_port_mode(dma2d_tx_chan, &dma_dscr_port_mode_config); + + // YUV444 is not supported by PPA module, need to utilize 2D-DMA color space conversion feature to do a conversion + ppa_srm_color_mode_t ppa_in_color_mode = srm_trans_desc->in.srm_cm; + if (ppa_in_color_mode == PPA_SRM_COLOR_MODE_YUV444) { + ppa_in_color_mode = PPA_SRM_COLOR_MODE_RGB888; + dma2d_csc_config_t dma_tx_csc = {0}; + if (srm_trans_desc->in.yuv_std == PPA_COLOR_CONV_STD_RGB_YUV_BT601) { + dma_tx_csc.tx_csc_option = DMA2D_CSC_TX_YUV444_TO_RGB888_601; + } else { + dma_tx_csc.tx_csc_option = DMA2D_CSC_TX_YUV444_TO_RGB888_709; + } + dma2d_configure_color_space_conversion(dma2d_tx_chan, &dma_tx_csc); + } + + ppa_srm_color_mode_t ppa_out_color_mode = srm_trans_desc->out.srm_cm; + if (ppa_out_color_mode == PPA_SRM_COLOR_MODE_YUV444) { + ppa_out_color_mode = PPA_SRM_COLOR_MODE_YUV420; + dma2d_csc_config_t dma_rx_csc = { + .rx_csc_option = DMA2D_CSC_RX_YUV420_TO_YUV444, + }; + dma2d_configure_color_space_conversion(dma2d_rx_chan, &dma_rx_csc); + } + + dma2d_rx_event_callbacks_t dma_event_cbs = { + .on_recv_eof = ppa_transaction_done_cb, + }; + dma2d_register_rx_event_callbacks(dma2d_rx_chan, &dma_event_cbs, (void *)trans_on_picked_desc->trans_elm); + + dma2d_set_desc_addr(dma2d_tx_chan, (intptr_t)srm_engine->dma_tx_desc); + dma2d_set_desc_addr(dma2d_rx_chan, (intptr_t)srm_engine->dma_rx_desc); + dma2d_start(dma2d_tx_chan); + dma2d_start(dma2d_rx_chan); + + // Configure PPA SRM engine + ppa_ll_srm_set_rx_color_mode(platform->hal.dev, ppa_in_color_mode); + if (COLOR_SPACE_TYPE((uint32_t)ppa_in_color_mode) == COLOR_SPACE_YUV) { + ppa_ll_srm_set_rx_yuv_range(platform->hal.dev, srm_trans_desc->in.yuv_range); + ppa_ll_srm_set_rx_yuv2rgb_std(platform->hal.dev, srm_trans_desc->in.yuv_std); + } + ppa_ll_srm_enable_rx_byte_swap(platform->hal.dev, srm_trans_desc->byte_swap); + ppa_ll_srm_enable_rx_rgb_swap(platform->hal.dev, srm_trans_desc->rgb_swap); + ppa_ll_srm_configure_rx_alpha(platform->hal.dev, srm_trans_desc->alpha_update_mode, srm_trans_desc->alpha_value); + + ppa_ll_srm_set_tx_color_mode(platform->hal.dev, ppa_out_color_mode); + if (COLOR_SPACE_TYPE((uint32_t)ppa_out_color_mode) == COLOR_SPACE_YUV) { + ppa_ll_srm_set_tx_yuv_range(platform->hal.dev, srm_trans_desc->out.yuv_range); + ppa_ll_srm_set_tx_rgb2yuv_std(platform->hal.dev, srm_trans_desc->out.yuv_std); + } + + ppa_ll_srm_set_rotation_angle(platform->hal.dev, srm_trans_desc->rotation_angle); + ppa_ll_srm_set_scaling_x(platform->hal.dev, srm_trans_desc->scale_x_int, srm_trans_desc->scale_x_frag); + ppa_ll_srm_set_scaling_y(platform->hal.dev, srm_trans_desc->scale_y_int, srm_trans_desc->scale_y_frag); + ppa_ll_srm_enable_mirror_x(platform->hal.dev, srm_trans_desc->mirror_x); + ppa_ll_srm_enable_mirror_y(platform->hal.dev, srm_trans_desc->mirror_y); + + ppa_ll_srm_start(platform->hal.dev); + + // No need to yield + return false; +} + +esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_srm_oper_config_t *config) +{ + ESP_RETURN_ON_FALSE(ppa_client && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(ppa_client->oper_type == PPA_OPERATION_SRM, ESP_ERR_INVALID_ARG, TAG, "client is not for SRM operations"); + ESP_RETURN_ON_FALSE(config->mode <= PPA_TRANS_MODE_NON_BLOCKING, ESP_ERR_INVALID_ARG, TAG, "invalid mode"); + // in_buffer could be anywhere (ram, flash, psram), out_buffer ptr cannot in flash region + ESP_RETURN_ON_FALSE(esp_ptr_internal(config->out.buffer) || esp_ptr_external_ram(config->out.buffer), ESP_ERR_INVALID_ARG, TAG, "invalid out.buffer addr"); + uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size; + ESP_RETURN_ON_FALSE(((uint32_t)config->out.buffer & (buf_alignment_size - 1)) == 0 && (config->out.buffer_size & (buf_alignment_size - 1)) == 0, + ESP_ERR_INVALID_ARG, TAG, "out.buffer addr or out.buffer_size not aligned to cache line size"); + // For YUV420 input/output: in desc, ha/hb/va/vb/x/y must be even number + if (config->in.srm_cm == PPA_SRM_COLOR_MODE_YUV420) { + ESP_RETURN_ON_FALSE(config->in.pic_h % 2 == 0 && config->in.pic_w % 2 == 0 && + config->in.block_h % 2 == 0 && config->in.block_w % 2 == 0 && + config->in.block_offset_x % 2 == 0 && config->in.block_offset_y % 2 == 0, + ESP_ERR_INVALID_ARG, TAG, "YUV420 input does not support odd h/w/offset_x/offset_y"); + } + // TODO: P4 ECO2 support YUV422 + // else if (config->in.srm_cm == PPA_SRM_COLOR_MODE_YUV422) { + // ESP_RETURN_ON_FALSE(config->in.pic_w % 2 == 0 && config->in.block_w % 2 == 0 && config->in.block_offset_x % 2 == 0, + // ESP_ERR_INVALID_ARG, TAG, "YUV422 input does not support odd w/offset_x"); + // } + if (config->out.srm_cm == PPA_SRM_COLOR_MODE_YUV420) { + ESP_RETURN_ON_FALSE(config->out.pic_h % 2 == 0 && config->out.pic_w % 2 == 0 && + config->out.block_offset_x % 2 == 0 && config->out.block_offset_y % 2 == 0, + ESP_ERR_INVALID_ARG, TAG, "YUV420 output does not support odd h/w/offset_x/offset_y"); + } + color_space_pixel_format_t out_pixel_format = { + .color_type_id = config->out.srm_cm, + }; + uint32_t out_pixel_depth = color_hal_pixel_format_get_bit_depth(out_pixel_format); // bits + uint32_t out_pic_len = config->out.pic_w * config->out.pic_h * out_pixel_depth / 8; + ESP_RETURN_ON_FALSE(out_pic_len <= config->out.buffer_size, ESP_ERR_INVALID_ARG, TAG, "out.pic_w/h mismatch with out.buffer_size"); + ESP_RETURN_ON_FALSE(config->scale_x < (PPA_LL_SRM_SCALING_INT_MAX + 1) && config->scale_x >= (1.0 / PPA_LL_SRM_SCALING_FRAG_MAX) && + config->scale_y < (PPA_LL_SRM_SCALING_INT_MAX + 1) && config->scale_y >= (1.0 / PPA_LL_SRM_SCALING_FRAG_MAX), + ESP_ERR_INVALID_ARG, TAG, "invalid scale"); + uint32_t new_block_w = 0; + uint32_t new_block_h = 0; + if (config->rotation_angle == PPA_SRM_ROTATION_ANGLE_0 || config->rotation_angle == PPA_SRM_ROTATION_ANGLE_180) { + new_block_w = (uint32_t)(config->scale_x * config->in.block_w); + new_block_h = (uint32_t)(config->scale_y * config->in.block_h); + } else { + new_block_w = (uint32_t)(config->scale_y * config->in.block_h); + new_block_h = (uint32_t)(config->scale_x * config->in.block_w); + } + ESP_RETURN_ON_FALSE(new_block_w <= (config->out.pic_w - config->out.block_offset_x) && + new_block_h <= (config->out.pic_h - config->out.block_offset_y), + ESP_ERR_INVALID_ARG, TAG, "scale does not fit in the out pic"); + if (config->byte_swap) { + PPA_CHECK_CM_SUPPORT_BYTE_SWAP("in.srm", (uint32_t)config->in.srm_cm); + } + if (config->rgb_swap) { + PPA_CHECK_CM_SUPPORT_RGB_SWAP("in.srm", (uint32_t)config->in.srm_cm); + } + uint32_t new_alpha_value = 0; + if (config->alpha_update_mode == PPA_ALPHA_FIX_VALUE) { + ESP_RETURN_ON_FALSE(config->alpha_fix_val <= 0xFF, ESP_ERR_INVALID_ARG, TAG, "invalid alpha_fix_val"); + new_alpha_value = config->alpha_fix_val; + } else if (config->alpha_update_mode == PPA_ALPHA_SCALE) { + ESP_RETURN_ON_FALSE(config->alpha_scale_ratio > 0 && config->alpha_scale_ratio < 1, ESP_ERR_INVALID_ARG, TAG, "invalid alpha_scale_ratio"); + new_alpha_value = (uint32_t)(config->alpha_scale_ratio * 256); + } + // To reduce complexity, rotation_angle, color_mode, alpha_update_mode correctness are checked in their corresponding LL functions + + // Write back and invalidate necessary data (note that the window content is not continuous in the buffer) + // Write back in_buffer extended window (alignment not necessary on C2M direction) + color_space_pixel_format_t in_pixel_format = { + .color_type_id = config->in.srm_cm, + }; + uint32_t in_pixel_depth = color_hal_pixel_format_get_bit_depth(in_pixel_format); // bits + uint32_t in_ext_window = (uint32_t)config->in.buffer + config->in.block_offset_y * config->in.pic_w * in_pixel_depth / 8; + uint32_t in_ext_window_len = config->in.pic_w * config->in.block_h * in_pixel_depth / 8; + esp_cache_msync((void *)in_ext_window, in_ext_window_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); + // Invalidate out_buffer extended window (alignment strict on M2C direction) + uint32_t out_ext_window = (uint32_t)config->out.buffer + config->out.block_offset_y * config->out.pic_w * out_pixel_depth / 8; + uint32_t out_ext_window_len = config->out.pic_w * config->in.block_h * out_pixel_depth / 8; + esp_cache_msync((void *)PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size), PPA_ALIGN_UP(out_ext_window_len, buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C); + + esp_err_t ret = ESP_OK; + ppa_trans_t *trans_elm = NULL; + if (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0)) { + dma2d_trans_config_t *dma_trans_desc = trans_elm->trans_desc; + + ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = dma_trans_desc->user_config; + + ppa_srm_oper_t *srm_trans_desc = (ppa_srm_oper_t *)trans_on_picked_desc->srm_desc; + memcpy(srm_trans_desc, config, sizeof(ppa_srm_oper_config_t)); + srm_trans_desc->scale_x_int = (uint32_t)srm_trans_desc->scale_x; + srm_trans_desc->scale_x_frag = (uint32_t)(srm_trans_desc->scale_x * (PPA_LL_SRM_SCALING_FRAG_MAX + 1)) & PPA_LL_SRM_SCALING_FRAG_MAX; + srm_trans_desc->scale_y_int = (uint32_t)srm_trans_desc->scale_y; + srm_trans_desc->scale_y_frag = (uint32_t)(srm_trans_desc->scale_y * (PPA_LL_SRM_SCALING_FRAG_MAX + 1)) & PPA_LL_SRM_SCALING_FRAG_MAX; + srm_trans_desc->alpha_value = new_alpha_value; + srm_trans_desc->data_burst_length = ppa_client->data_burst_length; + + trans_on_picked_desc->ppa_engine = ppa_client->engine; + trans_on_picked_desc->trigger_periph = DMA2D_TRIG_PERIPH_PPA_SRM; + + dma_trans_desc->tx_channel_num = 1; + dma_trans_desc->rx_channel_num = 1; + dma_trans_desc->channel_flags = 0; + if (config->in.srm_cm == PPA_SRM_COLOR_MODE_YUV444) { + dma_trans_desc->channel_flags |= DMA2D_CHANNEL_FUNCTION_FLAG_TX_CSC; + } + if (config->out.srm_cm == PPA_SRM_COLOR_MODE_YUV444) { + dma_trans_desc->channel_flags |= DMA2D_CHANNEL_FUNCTION_FLAG_RX_CSC; + } + dma_trans_desc->specified_tx_channel_mask = 0; + dma_trans_desc->specified_rx_channel_mask = 0; + + trans_elm->client = ppa_client; + trans_elm->user_data = config->user_data; + xSemaphoreTake(trans_elm->sem, 0); // Ensure no transaction semaphore before transaction starts + + ret = ppa_do_operation(ppa_client, ppa_client->engine, trans_elm, config->mode); + if (ret != ESP_OK) { + ppa_recycle_transaction(ppa_client, trans_elm); + } + } else { + ret = ESP_FAIL; + ESP_LOGE(TAG, "exceed maximum pending transactions for the client, consider increase max_pending_trans_num"); + } + return ret; +} diff --git a/components/esp_driver_ppa/test_apps/.build-test-rules.yml b/components/esp_driver_ppa/test_apps/.build-test-rules.yml new file mode 100644 index 000000000000..7767104a7fb3 --- /dev/null +++ b/components/esp_driver_ppa/test_apps/.build-test-rules.yml @@ -0,0 +1,7 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/esp_driver_ppa/test_apps: + disable: + - if: SOC_PPA_SUPPORTED != 1 + depends_components: + - esp_driver_ppa diff --git a/components/esp_driver_ppa/test_apps/CMakeLists.txt b/components/esp_driver_ppa/test_apps/CMakeLists.txt new file mode 100644 index 000000000000..dde414194371 --- /dev/null +++ b/components/esp_driver_ppa/test_apps/CMakeLists.txt @@ -0,0 +1,9 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +set(COMPONENTS main) + +project(ppa_test) diff --git a/components/esp_driver_ppa/test_apps/README.md b/components/esp_driver_ppa/test_apps/README.md new file mode 100644 index 000000000000..909282018f26 --- /dev/null +++ b/components/esp_driver_ppa/test_apps/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | diff --git a/components/esp_driver_ppa/test_apps/main/CMakeLists.txt b/components/esp_driver_ppa/test_apps/main/CMakeLists.txt new file mode 100644 index 000000000000..5988460a63c6 --- /dev/null +++ b/components/esp_driver_ppa/test_apps/main/CMakeLists.txt @@ -0,0 +1,9 @@ +set(srcs "test_app_main.c" + "test_ppa.c") + +# In order for the cases defined by `TEST_CASE` to be linked into the final elf, +# the component can be registered as WHOLE_ARCHIVE +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS "." + PRIV_REQUIRES esp_driver_ppa esp_psram unity esp_mm + WHOLE_ARCHIVE) diff --git a/components/esp_driver_ppa/test_apps/main/idf_component.yml b/components/esp_driver_ppa/test_apps/main/idf_component.yml new file mode 100644 index 000000000000..2ae836a9359b --- /dev/null +++ b/components/esp_driver_ppa/test_apps/main/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + ccomp_timer: "^1.0.0" diff --git a/components/esp_driver_ppa/test_apps/main/test_app_main.c b/components/esp_driver_ppa/test_apps/main/test_app_main.c new file mode 100644 index 000000000000..bdc0d7ecb3ec --- /dev/null +++ b/components/esp_driver_ppa/test_apps/main/test_app_main.c @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" +#include "unity_test_utils.h" + +// Some resources are lazy allocated in the driver, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (300) + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); +} + +void app_main(void) +{ + printf(" ________ \n"); + printf("|___ ___ \\ \n"); + printf(" | \\_/ | \n"); + printf(" '.___.' \n"); + printf(" ________ \n"); + printf("|___ ___ \\ \n"); + printf(" | \\_/ | \n"); + printf(" '.___.' \n"); + printf(" _______ \n"); + printf("|__. _ '. \n"); + printf(" __||_/ / \n"); + printf("|______.' \n"); + + unity_run_menu(); +} diff --git a/components/esp_driver_ppa/test_apps/main/test_ppa.c b/components/esp_driver_ppa/test_apps/main/test_ppa.c new file mode 100644 index 000000000000..b1ce98914159 --- /dev/null +++ b/components/esp_driver_ppa/test_apps/main/test_ppa.c @@ -0,0 +1,800 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "driver/ppa.h" +#include "esp_heap_caps.h" +#include "esp_err.h" +#include "ccomp_timer.h" +#include "hal/color_hal.h" +#include "esp_cache.h" + +#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) + +TEST_CASE("ppa_client_do_ppa_operation", "[PPA]") +{ + const uint32_t w = 480; + const uint32_t h = 480; + const uint32_t buf_1_color_type_id = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888); + const uint32_t buf_2_color_type_id = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888); + + color_space_pixel_format_t buf_1_cm = { + .color_type_id = buf_1_color_type_id, + }; + color_space_pixel_format_t buf_2_cm = { + .color_type_id = buf_2_color_type_id, + }; + + uint32_t buf_1_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(buf_1_cm) / 8, 64); + uint32_t buf_2_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(buf_2_cm) / 8, 64); + uint8_t *buf_1 = heap_caps_aligned_calloc(4, buf_1_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); // cache alignment is implicited by MALLOC_CAP_DMA + TEST_ASSERT_NOT_NULL(buf_1); + uint8_t *buf_2 = heap_caps_aligned_calloc(4, buf_2_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(buf_2); + + // Register different types of PPA clients + ppa_client_handle_t ppa_client_srm_handle; + ppa_client_handle_t ppa_client_blend_handle; + ppa_client_handle_t ppa_client_fill_handle_a; + ppa_client_handle_t ppa_client_fill_handle_b; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_SRM, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_srm_handle)); + ppa_client_config.oper_type = PPA_OPERATION_BLEND; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_blend_handle)); + ppa_client_config.oper_type = PPA_OPERATION_FILL; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_fill_handle_a)); + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_fill_handle_b)); + + ppa_srm_oper_config_t srm_oper_config = { + .in.buffer = buf_1, + .in.pic_w = w, + .in.pic_h = h, + .in.block_w = w, + .in.block_h = h, + .in.block_offset_x = 0, + .in.block_offset_y = 0, + .in.srm_cm = buf_1_color_type_id, + + .out.buffer = buf_2, + .out.buffer_size = buf_2_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = 0, + .out.block_offset_y = 0, + .out.srm_cm = buf_2_color_type_id, + + .rotation_angle = PPA_SRM_ROTATION_ANGLE_0, + .scale_x = 1.0, + .scale_y = 1.0, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + // A SRM client can request to do a SRM operation + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_srm_handle, &srm_oper_config)); + // A non-SRM client can not request to do a SRM operation + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, ppa_do_scale_rotate_mirror(ppa_client_blend_handle, &srm_oper_config)); + + ppa_blend_oper_config_t blend_oper_config = { + .in_bg.buffer = buf_1, + .in_bg.pic_w = w, + .in_bg.pic_h = h, + .in_bg.block_w = w, + .in_bg.block_h = h, + .in_bg.block_offset_x = 0, + .in_bg.block_offset_y = 0, + .in_bg.blend_cm = buf_1_color_type_id, + + .in_fg.buffer = buf_2, + .in_fg.pic_w = w, + .in_fg.pic_h = h, + .in_fg.block_w = w, + .in_fg.block_h = h, + .in_fg.block_offset_x = 0, + .in_fg.block_offset_y = 0, + .in_fg.blend_cm = buf_2_color_type_id, + + .out.buffer = buf_1, + .out.buffer_size = buf_1_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = 0, + .out.block_offset_y = 0, + .out.blend_cm = buf_1_color_type_id, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + // A blend client can request to do a blend operation + TEST_ESP_OK(ppa_do_blend(ppa_client_blend_handle, &blend_oper_config)); + // A non-blend client can not request to do a blend operation + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, ppa_do_blend(ppa_client_fill_handle_b, &blend_oper_config)); + + ppa_fill_oper_config_t fill_oper_config = { + .out.buffer = buf_1, + .out.buffer_size = buf_1_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = 0, + .out.block_offset_y = 0, + .out.fill_cm = buf_1_color_type_id, + + .fill_block_w = w, + .fill_block_h = h, + .fill_argb_color = { + .val = 0xFF00FF00, + }, + + .mode = PPA_TRANS_MODE_NON_BLOCKING, + }; + // A fill client can request to do a fill operation + TEST_ESP_OK(ppa_do_fill(ppa_client_fill_handle_a, &fill_oper_config)); + // Another fill client can also request another fill operation at the same time + TEST_ESP_OK(ppa_do_fill(ppa_client_fill_handle_b, &fill_oper_config)); + + vTaskDelay(pdMS_TO_TICKS(500)); + + // Unregister all PPA clients + TEST_ESP_OK(ppa_unregister_client(ppa_client_srm_handle)); + TEST_ESP_OK(ppa_unregister_client(ppa_client_blend_handle)); + TEST_ESP_OK(ppa_unregister_client(ppa_client_fill_handle_a)); + TEST_ESP_OK(ppa_unregister_client(ppa_client_fill_handle_b)); + + free(buf_1); + free(buf_2); +} + +static bool ppa_trans_done_cb(ppa_client_handle_t ppa_client, ppa_event_data_t *event_data, void *user_data) +{ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + SemaphoreHandle_t sem = (SemaphoreHandle_t)user_data; + xSemaphoreGiveFromISR(sem, &xHigherPriorityTaskWoken); + return (xHigherPriorityTaskWoken == pdTRUE); +} + +TEST_CASE("ppa_pending_transactions_in_queue", "[PPA]") +{ + // A big picture block takes longer time to process, desired for this test case + const uint32_t w = 1920; + const uint32_t h = 1080; + const uint32_t buf_1_color_type_id = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888); + const uint32_t buf_2_color_type_id = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420); + + color_space_pixel_format_t buf_1_cm = { + .color_type_id = buf_1_color_type_id, + }; + color_space_pixel_format_t buf_2_cm = { + .color_type_id = buf_2_color_type_id, + }; + + uint32_t buf_1_size = w * h * color_hal_pixel_format_get_bit_depth(buf_1_cm) / 8; + uint32_t buf_2_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(buf_2_cm) / 8, 64); + uint8_t *buf_1 = heap_caps_aligned_calloc(4, buf_1_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(buf_1); + uint8_t *buf_2 = heap_caps_aligned_calloc(4, buf_2_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(buf_2); + + // Register two PPA SRM clients with different max_pending_trans_num + ppa_client_handle_t ppa_client_a_handle; + ppa_client_handle_t ppa_client_b_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_SRM, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_a_handle)); + ppa_client_config.max_pending_trans_num = 3; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_b_handle)); + + ppa_event_callbacks_t cbs = { + .on_trans_done = ppa_trans_done_cb, + }; + ppa_client_register_event_callbacks(ppa_client_a_handle, &cbs); + + SemaphoreHandle_t sem = xSemaphoreCreateBinary(); + + ppa_srm_oper_config_t oper_config = { + .in.buffer = buf_1, + .in.pic_w = w, + .in.pic_h = h, + .in.block_w = w, + .in.block_h = h, + .in.block_offset_x = 0, + .in.block_offset_y = 0, + .in.srm_cm = buf_1_color_type_id, + + .out.buffer = buf_2, + .out.buffer_size = buf_2_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = 0, + .out.block_offset_y = 0, + .out.srm_cm = buf_2_color_type_id, + + .rotation_angle = PPA_SRM_ROTATION_ANGLE_0, + .scale_x = 1.0, + .scale_y = 1.0, + + .user_data = (void *)sem, + .mode = PPA_TRANS_MODE_NON_BLOCKING, + }; + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_a_handle, &oper_config)); + + // Another transaction cannot be accept since client_a can only hold one transaction + TEST_ESP_ERR(ESP_FAIL, ppa_do_scale_rotate_mirror(ppa_client_a_handle, &oper_config)); + + // Wait for the last transaction finishes + xSemaphoreTake(sem, portMAX_DELAY); + // Then a new transaction can be accepted again + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_a_handle, &oper_config)); + + // Client can not be unregistered when there are unfinished transactions + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, ppa_unregister_client(ppa_client_a_handle)); + + oper_config.mode = PPA_TRANS_MODE_BLOCKING; + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_b_handle, &oper_config)); + // Every PPA engine can only process one operation at a time + // Transactions are being processed with First-In-First-Out + // So, at the moment, the new transaction requested by client_b has finished, the last transaction requested by client_a for sure has finished + TEST_ASSERT(xSemaphoreTake(sem, 0) == pdTRUE); + // client_b can accept more than one transactions + oper_config.mode = PPA_TRANS_MODE_NON_BLOCKING; + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_b_handle, &oper_config)); + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_b_handle, &oper_config)); + oper_config.mode = PPA_TRANS_MODE_BLOCKING; + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_b_handle, &oper_config)); + // The last transaction requested is with BLOCKING mode, so the last call to ppa_do_scale_rotate_mirror returned means all transactions finished + + // Unregister all PPA clients + TEST_ESP_OK(ppa_unregister_client(ppa_client_a_handle)); + TEST_ESP_OK(ppa_unregister_client(ppa_client_b_handle)); + + vSemaphoreDelete(sem); + free(buf_1); + free(buf_2); +} + +TEST_CASE("ppa_srm_basic_data_correctness_check", "[PPA]") +{ + const uint32_t w = 4; + const uint32_t h = 4; + const uint32_t block_w = 3; + const uint32_t block_h = 3; + const uint32_t in_block_offset_x = 1; + const uint32_t in_block_offset_y = 1; + const uint32_t out_block_offset_x = 1; + const uint32_t out_block_offset_y = 0; + const ppa_srm_color_mode_t cm = PPA_SRM_COLOR_MODE_RGB565; + const ppa_srm_rotation_angle_t rotation = PPA_SRM_ROTATION_ANGLE_90; // CCW + const float scale_x = 1.0; + const float scale_y = 1.0; + + color_space_pixel_format_t buf_cm = { + .color_type_id = cm, + }; + const uint32_t buf_len = w * h * color_hal_pixel_format_get_bit_depth(buf_cm) / 8; // 32 + uint32_t out_buf_size = ALIGN_UP(buf_len, 64); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(out_buf); + esp_cache_msync((void *)out_buf, out_buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + const uint16_t in_buf[16] = { + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + // /*******************************/ + 0xFFFF, /**/ 0x8080, 0x8080, 0x8080, /**/ + 0xFFFF, /**/ 0x8F80, 0x8F80, 0x8F80, /**/ + 0xFFFF, /**/ 0xFF80, 0xFF80, 0xFF80, /**/ + // /*******************************/ + }; + // Expected SRM output + const uint16_t out_buf_expected[16] = { + // /*******************************/ + 0x0000, /**/ 0x8080, 0x8F80, 0xFF80, /**/ + 0x0000, /**/ 0x8080, 0x8F80, 0xFF80, /**/ + 0x0000, /**/ 0x8080, 0x8F80, 0xFF80, /**/ + // /*******************************/ + 0x0000, 0x0000, 0x0000, 0x0000 + }; + + ppa_client_handle_t ppa_client_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_SRM, + .max_pending_trans_num = 1, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_handle)); + + ppa_srm_oper_config_t oper_config = { + .in.buffer = in_buf, + .in.pic_w = w, + .in.pic_h = h, + .in.block_w = block_w, + .in.block_h = block_h, + .in.block_offset_x = in_block_offset_x, + .in.block_offset_y = in_block_offset_y, + .in.srm_cm = cm, + + .out.buffer = out_buf, + .out.buffer_size = out_buf_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = out_block_offset_x, + .out.block_offset_y = out_block_offset_y, + .out.srm_cm = cm, + + .rotation_angle = rotation, + .scale_x = scale_x, + .scale_y = scale_y, + + .rgb_swap = 0, + .byte_swap = 0, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_handle, &oper_config)); + + // Check result + for (int i = 0; i < buf_len; i++) { + if (i % 8 == 0) { + printf("\n"); + } + printf("0x%02X ", out_buf[i]); + } + printf("\n"); + TEST_ASSERT_EQUAL_UINT8_ARRAY((void *)out_buf_expected, (void *)out_buf, buf_len); + + TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); + + free(out_buf); +} + +TEST_CASE("ppa_blend_basic_data_correctness_check", "[PPA]") +{ + const uint32_t w = 2; + const uint32_t h = 2; + const uint32_t block_w = 1; + const uint32_t block_h = 1; + const uint32_t block_offset_x = 1; + const uint32_t block_offset_y = 1; + const ppa_blend_color_mode_t in_bg_cm = PPA_BLEND_COLOR_MODE_RGB888; + const ppa_blend_color_mode_t in_fg_cm = PPA_BLEND_COLOR_MODE_ARGB8888; + const ppa_blend_color_mode_t out_cm = PPA_BLEND_COLOR_MODE_ARGB8888; + + color_space_pixel_format_t bg_buf_cm = { + .color_type_id = in_bg_cm, + }; + const uint32_t bg_buf_len __attribute__((unused)) = w * h * color_hal_pixel_format_get_bit_depth(bg_buf_cm) / 8; // 12 + color_space_pixel_format_t fg_buf_cm = { + .color_type_id = in_fg_cm, + }; + const uint32_t fg_buf_len __attribute__((unused)) = w * h * color_hal_pixel_format_get_bit_depth(fg_buf_cm) / 8; // 16 + const uint32_t out_buf_len = fg_buf_len; // 16 + // We will make the output write to the in_fg_buffer, therefore, it has cache line alignment requirement + const uint32_t out_buf_size = 64; + + // Alpha of BG will be scaled by 0.8 + // Alpha of FG will be inverted + const float bg_alpha_scale_ratio = 0.8; + const uint8_t in_bg_buf[12] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // /*************************/ + 0xFF, 0xFF, 0xFF, /**/ 0x80, 0x40, 0xA0, /**/ + // /*************************/ + }; + uint8_t in_fg_buf[64] __attribute__((aligned(64))) = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // /*******************************/ + 0xFF, 0xFF, 0xFF, 0xFF, /**/ 0x00, 0x80, 0x80, 0xC0, /**/ + // /* (B) (G) (R) (A) */ + // /*******************************/ + [16 ... 63] = 0, + }; + uint8_t *out_buf = in_fg_buf; + // Expected blend output + // Alpha Blending calculation: + // A_bg' = (255 * 0.8) / 255 = 0.8, A_fg' = (255 - 0xC0) / 255 = 0.247 + // A_out = 0.8 + 0.247 - 0.8 * 0.247 = 0.849 (216 -> 0xD8) + // C_out_b = (0x80 * 0.8 * (1 - 0.247) + 0x00 * 0.247) / 0.849 = 91 -> 0x5B + // C_out_g = (0x40 * 0.8 * (1 - 0.247) + 0x80 * 0.247) / 0.849 = 83 -> 0x53 + // C_out_g = (0xA0 * 0.8 * (1 - 0.247) + 0x80 * 0.247) / 0.849 = 150 -> 0x96 + const uint8_t out_buf_expected[16] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // /*******************************/ + 0xFF, 0xFF, 0xFF, 0xFF, /**/ 0x5B, 0x53, 0x96, 0xD8, /**/ + // /*******************************/ + }; + + ppa_client_handle_t ppa_client_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_BLEND, + .max_pending_trans_num = 1, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_handle)); + + ppa_blend_oper_config_t oper_config = { + .in_bg.buffer = in_bg_buf, + .in_bg.pic_w = w, + .in_bg.pic_h = h, + .in_bg.block_w = block_w, + .in_bg.block_h = block_h, + .in_bg.block_offset_x = block_offset_x, + .in_bg.block_offset_y = block_offset_y, + .in_bg.blend_cm = in_bg_cm, + + .in_fg.buffer = in_fg_buf, + .in_fg.pic_w = w, + .in_fg.pic_h = h, + .in_fg.block_w = block_w, + .in_fg.block_h = block_h, + .in_fg.block_offset_x = block_offset_x, + .in_fg.block_offset_y = block_offset_y, + .in_fg.blend_cm = in_fg_cm, + + .out.buffer = out_buf, + .out.buffer_size = out_buf_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = block_offset_x, + .out.block_offset_y = block_offset_y, + .out.blend_cm = out_cm, + + .bg_alpha_update_mode = PPA_ALPHA_SCALE, + .bg_alpha_scale_ratio = bg_alpha_scale_ratio, + + .fg_alpha_update_mode = PPA_ALPHA_INVERT, + + .bg_ck_en = false, + .fg_ck_en = false, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + TEST_ESP_OK(ppa_do_blend(ppa_client_handle, &oper_config)); + + // Check result + for (int i = 0; i < out_buf_len; i++) { + if (i % 8 == 0) { + printf("\n"); + } + printf("0x%02X ", out_buf[i]); + } + printf("\n"); + TEST_ASSERT_EQUAL_UINT8_ARRAY((void *)out_buf_expected, (void *)out_buf, out_buf_len); + + TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); +} + +TEST_CASE("ppa_fill_basic_data_correctness_check", "[PPA]") +{ + const uint32_t w = 80; + const uint32_t h = 120; + const uint32_t block_w = 80; + const uint32_t block_h = 80; + const uint32_t block_offset_x = 0; + const uint32_t block_offset_y = 40; + const ppa_fill_color_mode_t out_cm = PPA_FILL_COLOR_MODE_RGB565; + const color_pixel_argb8888_data_t fill_color = {.a = 0x80, .r = 0xFF, .g = 0x55, .b = 0xAA}; + + color_space_pixel_format_t out_pixel_format = { + .color_type_id = out_cm, + }; + + uint32_t out_pixel_depth = color_hal_pixel_format_get_bit_depth(out_pixel_format); // bits + uint32_t out_buf_len = w * h * out_pixel_depth / 8; + uint32_t out_buf_size = ALIGN_UP(out_buf_len, 64); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(out_buf); + + memset(out_buf, 0xFF, out_buf_len); + + ppa_client_handle_t ppa_client_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_FILL, + .max_pending_trans_num = 1, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_handle)); + + ppa_fill_oper_config_t oper_config = { + .out.buffer = out_buf, + .out.buffer_size = out_buf_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = block_offset_x, + .out.block_offset_y = block_offset_y, + .out.fill_cm = out_cm, + + .fill_block_w = block_w, + .fill_block_h = block_h, + .fill_argb_color = fill_color, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + TEST_ESP_OK(ppa_do_fill(ppa_client_handle, &oper_config)); + + // Check result + const color_pixel_rgb565_data_t fill_pixel_expected = {.r = fill_color.r >> 3, + .g = fill_color.g >> 2, + .b = fill_color.b >> 3, + }; + TEST_ASSERT_EACH_EQUAL_UINT16(fill_pixel_expected.val, (void *)((uint32_t)out_buf + w * block_offset_y * out_pixel_depth / 8), block_w * block_h); + + TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); + + free(out_buf); +} + +/* All performance tests are tested under the following situations: + * - Testing PPA speed where in_buffer(s) and out_buffer all located in PSRAM + * - Only 2D-DMA is using PSRAM + * - 2D-DMA burst length is at maximum 128B + * - Input and output color mode is ARGB8888 (maximizing 2D-DMA data transafer amount) + * + * The time spend (T) to complete a PPA transaction is proportional to the amount of pixels (x) need to be processed. + * T = k * x + b + * k = (T - b) / x + */ + +#define PPA_SRM_MIN_PERFORMANCE_PX_PER_SEC (21000 * 1000) // k_min +#define PPA_SRM_TIME_OFFSET (-26000) // b_approx + +#define PPA_BLEND_MIN_PERFORMANCE_PX_PER_SEC (31500 * 1000) // k_min +#define PPA_BLEND_TIME_OFFSET (-37150) // b_approx + +#define PPA_FILL_MIN_PERFORMANCE_PX_PER_SEC (150000 * 1000) // k_min +#define PPA_FILL_TIME_OFFSET (-106000) // b_approx + +TEST_CASE("ppa_srm_performance", "[PPA]") +{ + // Configurable parameters + const uint32_t w = 1920; // 1920 / 1280 / 800 / 640 + const uint32_t h = 1080; // 1080 / 720 / 480 + const uint32_t block_w = w; + const uint32_t block_h = h; + const ppa_srm_color_mode_t in_cm = PPA_SRM_COLOR_MODE_ARGB8888; + const ppa_srm_color_mode_t out_cm = PPA_SRM_COLOR_MODE_ARGB8888; + const ppa_srm_rotation_angle_t rotation = PPA_SRM_ROTATION_ANGLE_0; + const float scale_x = 1.0; + const float scale_y = 1.0; + + color_space_pixel_format_t in_pixel_format = { + .color_type_id = in_cm, + }; + color_space_pixel_format_t out_pixel_format = { + .color_type_id = out_cm, + }; + + uint32_t in_buf_size = w * h * color_hal_pixel_format_get_bit_depth(in_pixel_format) / 8; + uint32_t out_buf_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(out_pixel_format) / 8, 64); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(out_buf); + uint8_t *in_buf = heap_caps_aligned_calloc(4, in_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(in_buf); + + uint8_t *ptr = in_buf; + for (int x = 0; x < in_buf_size; x++) { + ptr[x] = x; + } + + ppa_client_handle_t ppa_client_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_SRM, + .max_pending_trans_num = 1, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_handle)); + + uint32_t out_pic_w = (rotation == PPA_SRM_ROTATION_ANGLE_0 || rotation == PPA_SRM_ROTATION_ANGLE_180) ? w : h; + uint32_t out_pic_h = (rotation == PPA_SRM_ROTATION_ANGLE_0 || rotation == PPA_SRM_ROTATION_ANGLE_180) ? h : w; + ppa_srm_oper_config_t oper_config = { + .in.buffer = in_buf, + .in.pic_w = w, + .in.pic_h = h, + .in.block_w = block_w, + .in.block_h = block_h, + .in.block_offset_x = 0, + .in.block_offset_y = 0, + .in.srm_cm = in_cm, + + .out.buffer = out_buf, + .out.buffer_size = out_buf_size, + .out.pic_w = out_pic_w, + .out.pic_h = out_pic_h, + .out.block_offset_x = 0, + .out.block_offset_y = 0, + .out.srm_cm = out_cm, + + .rotation_angle = rotation, + .scale_x = scale_x, + .scale_y = scale_y, + + .rgb_swap = 0, + .byte_swap = 0, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + ccomp_timer_start(); + + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_handle, &oper_config)); + + int64_t oper_time = ccomp_timer_stop(); // us + printf("PPA SRM - Process Time: %lld us\n", oper_time); + + // Check performance + uint64_t num_pixels_processed = block_w * block_h; + uint64_t px_per_second = (num_pixels_processed - PPA_SRM_TIME_OFFSET) * 1000 * 1000 / oper_time; + printf("PPA SRM performance = %lld pixels/sec\n", px_per_second); + TEST_ASSERT_GREATER_THAN(PPA_SRM_MIN_PERFORMANCE_PX_PER_SEC, px_per_second); + + TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); + + free(in_buf); + free(out_buf); +} + +TEST_CASE("ppa_blend_performance", "[PPA]") +{ + // Configurable parameters + const uint32_t w = 1280; + const uint32_t h = 720; + const uint32_t block_w = w; + const uint32_t block_h = h; + const ppa_blend_color_mode_t in_bg_cm = PPA_BLEND_COLOR_MODE_ARGB8888; + const ppa_blend_color_mode_t in_fg_cm = PPA_BLEND_COLOR_MODE_ARGB8888; + const ppa_blend_color_mode_t out_cm = PPA_BLEND_COLOR_MODE_ARGB8888; + + color_space_pixel_format_t in_bg_pixel_format = { + .color_type_id = in_bg_cm, + }; + color_space_pixel_format_t in_fg_pixel_format = { + .color_type_id = in_fg_cm, + }; + color_space_pixel_format_t out_pixel_format = { + .color_type_id = out_cm, + }; + + uint32_t in_bg_buf_size = w * h * color_hal_pixel_format_get_bit_depth(in_bg_pixel_format) / 8; + uint32_t in_fg_buf_size = w * h * color_hal_pixel_format_get_bit_depth(in_fg_pixel_format) / 8; + uint32_t out_buf_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(out_pixel_format) / 8, 64); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(out_buf); + uint8_t *in_bg_buf = heap_caps_aligned_calloc(4, in_bg_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(in_bg_buf); + uint8_t *in_fg_buf = heap_caps_aligned_calloc(4, in_fg_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(in_fg_buf); + + uint8_t *ptr = in_bg_buf; + for (int x = 0; x < in_bg_buf_size; x++) { + ptr[x] = x & 0x55; + } + ptr = in_fg_buf; + for (int x = 0; x < in_fg_buf_size; x++) { + ptr[x] = x & 0xAA; + } + + ppa_client_handle_t ppa_client_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_BLEND, + .max_pending_trans_num = 1, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_handle)); + + ppa_blend_oper_config_t oper_config = { + .in_bg.buffer = in_bg_buf, + .in_bg.pic_w = w, + .in_bg.pic_h = h, + .in_bg.block_w = block_w, + .in_bg.block_h = block_h, + .in_bg.block_offset_x = 0, + .in_bg.block_offset_y = 0, + .in_bg.blend_cm = in_bg_cm, + + .in_fg.buffer = in_fg_buf, + .in_fg.pic_w = w, + .in_fg.pic_h = h, + .in_fg.block_w = block_w, + .in_fg.block_h = block_h, + .in_fg.block_offset_x = 0, + .in_fg.block_offset_y = 0, + .in_fg.blend_cm = in_fg_cm, + + .out.buffer = out_buf, + .out.buffer_size = out_buf_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = 0, + .out.block_offset_y = 0, + .out.blend_cm = out_cm, + + .bg_ck_en = false, + .fg_ck_en = false, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + ccomp_timer_start(); + + TEST_ESP_OK(ppa_do_blend(ppa_client_handle, &oper_config)); + + int64_t oper_time = ccomp_timer_stop(); + printf("PPA Blend - Process Time: %lld us\n", oper_time); + + // Check performance + uint64_t num_pixels_processed = block_w * block_h; + uint64_t px_per_second = (num_pixels_processed - PPA_BLEND_TIME_OFFSET) * 1000 * 1000 / oper_time; + printf("PPA Blend performance = %lld pixels/sec\n", px_per_second); + TEST_ASSERT_GREATER_THAN(PPA_BLEND_MIN_PERFORMANCE_PX_PER_SEC, px_per_second); + + TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); + + free(in_bg_buf); + free(in_fg_buf); + free(out_buf); +} + +TEST_CASE("ppa_fill_performance", "[PPA]") +{ + // Configurable parameters + const uint32_t w = 1280; + const uint32_t h = 720; + const uint32_t block_w = 800; + const uint32_t block_h = 480; + const ppa_fill_color_mode_t out_cm = PPA_FILL_COLOR_MODE_RGB565; + + color_space_pixel_format_t out_pixel_format = { + .color_type_id = out_cm, + }; + + uint32_t out_buf_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(out_pixel_format) / 8, 64); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(out_buf); + + ppa_client_handle_t ppa_client_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_FILL, + .max_pending_trans_num = 1, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_handle)); + + ppa_fill_oper_config_t oper_config = { + .out.buffer = out_buf, + .out.buffer_size = out_buf_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = 0, + .out.block_offset_y = 0, + .out.fill_cm = out_cm, + + .fill_block_w = block_w, + .fill_block_h = block_h, + .fill_argb_color = { + .val = 0xFF00FFFF, + }, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + ccomp_timer_start(); + + TEST_ESP_OK(ppa_do_fill(ppa_client_handle, &oper_config)); + + int64_t oper_time = ccomp_timer_stop(); + printf("PPA Fill - Process Time: %lld us\n", oper_time); + + // Check performance + uint64_t num_pixels_processed = block_w * block_h; + uint64_t px_per_second = (num_pixels_processed - PPA_FILL_TIME_OFFSET) * 1000 * 1000 / oper_time; + printf("PPA Blend performance = %lld pixels/sec\n", px_per_second); + TEST_ASSERT_GREATER_THAN(PPA_FILL_MIN_PERFORMANCE_PX_PER_SEC, px_per_second); + + TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); + + free(out_buf); +} diff --git a/components/esp_driver_ppa/test_apps/pytest_ppa.py b/components/esp_driver_ppa/test_apps/pytest_ppa.py new file mode 100644 index 000000000000..534d32cee197 --- /dev/null +++ b/components/esp_driver_ppa/test_apps/pytest_ppa.py @@ -0,0 +1,17 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32p4 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +def test_ppa(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_driver_ppa/test_apps/sdkconfig.ci.release b/components/esp_driver_ppa/test_apps/sdkconfig.ci.release new file mode 100644 index 000000000000..199b0cf97c3e --- /dev/null +++ b/components/esp_driver_ppa/test_apps/sdkconfig.ci.release @@ -0,0 +1,6 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_PM_DFS_INIT_AUTO=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_driver_ppa/test_apps/sdkconfig.defaults b/components/esp_driver_ppa/test_apps/sdkconfig.defaults new file mode 100644 index 000000000000..1ee5d718bc23 --- /dev/null +++ b/components/esp_driver_ppa/test_apps/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT_EN=n +CONFIG_IDF_EXPERIMENTAL_FEATURES=y diff --git a/components/esp_driver_ppa/test_apps/sdkconfig.defaults.esp32p4 b/components/esp_driver_ppa/test_apps/sdkconfig.defaults.esp32p4 new file mode 100644 index 000000000000..702fac3342dd --- /dev/null +++ b/components/esp_driver_ppa/test_apps/sdkconfig.defaults.esp32p4 @@ -0,0 +1,3 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_HEX=y +CONFIG_SPIRAM_SPEED_200M=y diff --git a/components/esp_driver_rmt/src/rmt_private.h b/components/esp_driver_rmt/src/rmt_private.h index cf56d52c6b27..ec6edc721738 100644 --- a/components/esp_driver_rmt/src/rmt_private.h +++ b/components/esp_driver_rmt/src/rmt_private.h @@ -64,7 +64,7 @@ extern "C" { typedef dma_descriptor_align4_t rmt_dma_descriptor_t; #ifdef CACHE_LL_L2MEM_NON_CACHE_ADDR -#define RMT_GET_NON_CACHE_ADDR(addr) ((addr) ? CACHE_LL_L2MEM_NON_CACHE_ADDR(addr) : 0) +#define RMT_GET_NON_CACHE_ADDR(addr) (CACHE_LL_L2MEM_NON_CACHE_ADDR(addr)) #else #define RMT_GET_NON_CACHE_ADDR(addr) (addr) #endif diff --git a/components/esp_driver_rmt/src/rmt_tx.c b/components/esp_driver_rmt/src/rmt_tx.c index 1d9e1a06e330..aafa4613b245 100644 --- a/components/esp_driver_rmt/src/rmt_tx.c +++ b/components/esp_driver_rmt/src/rmt_tx.c @@ -1098,27 +1098,30 @@ static void IRAM_ATTR rmt_tx_default_isr(void *args) static bool IRAM_ATTR rmt_dma_tx_eof_cb(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) { rmt_tx_channel_t *tx_chan = (rmt_tx_channel_t *)user_data; + // tx_eof_desc_addr must be non-zero, guaranteed by the hardware rmt_dma_descriptor_t *eof_desc_nc = (rmt_dma_descriptor_t *)RMT_GET_NON_CACHE_ADDR(event_data->tx_eof_desc_addr); - rmt_dma_descriptor_t *n = (rmt_dma_descriptor_t *)RMT_GET_NON_CACHE_ADDR(eof_desc_nc->next); // next points to a cache address, needs to convert it to a non-cached one - if (n) { - rmt_dma_descriptor_t *nn = (rmt_dma_descriptor_t *)RMT_GET_NON_CACHE_ADDR(n->next); - // if the DMA descriptor link is still a ring (i.e. hasn't broken down by `rmt_tx_mark_eof()`), then we treat it as a valid ping-pong event - if (nn) { - // continue ping-pong transmission - rmt_tx_trans_desc_t *t = tx_chan->cur_trans; - size_t encoded_symbols = t->transmitted_symbol_num; - if (t->flags.encoding_done) { - rmt_tx_mark_eof(tx_chan); - encoded_symbols += 1; - } else { - encoded_symbols += rmt_encode_check_result(tx_chan, t); - } - t->transmitted_symbol_num = encoded_symbols; - tx_chan->mem_end = tx_chan->ping_pong_symbols * 3 - tx_chan->mem_end; // mem_end equals to either ping_pong_symbols or ping_pong_symbols*2 - // tell DMA that we have a new descriptor attached - gdma_append(dma_chan); - } + if (!eof_desc_nc->next) { + return false; + } + // next points to a cache address, convert it to a non-cached one + rmt_dma_descriptor_t *n = (rmt_dma_descriptor_t *)RMT_GET_NON_CACHE_ADDR(eof_desc_nc->next); + if (!n->next) { + return false; } + // if the DMA descriptor link is still a ring (i.e. hasn't broken down by `rmt_tx_mark_eof()`), then we treat it as a valid ping-pong event + // continue ping-pong transmission + rmt_tx_trans_desc_t *t = tx_chan->cur_trans; + size_t encoded_symbols = t->transmitted_symbol_num; + if (t->flags.encoding_done) { + rmt_tx_mark_eof(tx_chan); + encoded_symbols += 1; + } else { + encoded_symbols += rmt_encode_check_result(tx_chan, t); + } + t->transmitted_symbol_num = encoded_symbols; + tx_chan->mem_end = tx_chan->ping_pong_symbols * 3 - tx_chan->mem_end; // mem_end equals to either ping_pong_symbols or ping_pong_symbols*2 + // tell DMA that we have a new descriptor attached + gdma_append(dma_chan); return false; } #endif // SOC_RMT_SUPPORT_DMA diff --git a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc/main/test_sdio_sdhost.c b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc/main/test_sdio_sdhost.c index f33985da786e..8a63f2b9b6ad 100644 --- a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc/main/test_sdio_sdhost.c +++ b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc/main/test_sdio_sdhost.c @@ -14,6 +14,7 @@ #include "freertos/task.h" #include "esp_timer.h" #include "ccomp_timer.h" +#include "string.h" #include "sdmmc_cmd.h" #include "driver/sdmmc_host.h" @@ -43,7 +44,7 @@ typedef struct { ---------------------------------------------------------------*/ static sdmmc_card_t s_card; -static void s_master_init(test_sdio_param_t *host_param, essl_handle_t *out_handle) +static void s_master_init(test_sdio_param_t *host_param, essl_handle_t *out_handle, sdmmc_card_t** out_card) { sdmmc_host_t host_config = (sdmmc_host_t)SDMMC_HOST_DEFAULT(); host_config.flags = host_param->host_flags; @@ -81,6 +82,10 @@ static void s_master_init(test_sdio_param_t *host_param, essl_handle_t *out_hand TEST_ESP_OK(essl_sdio_init_dev(out_handle, &essl_sdio_config)); TEST_ESP_OK(essl_init(*out_handle, TEST_TIMEOUT_MAX)); + + if (out_card) { + *out_card = card; + } } static void s_master_deinit(void) @@ -114,7 +119,7 @@ TEST_CASE("SDIO_SDMMC: test interrupt", "[sdio]") .max_freq_khz = SDMMC_FREQ_HIGHSPEED, }; //essl init and sdmmc init - s_master_init(&test_param, &handle); + s_master_init(&test_param, &handle, NULL); TEST_ESP_OK(essl_set_intr_ena(handle, TEST_INT_MASK_ALL, TEST_TIMEOUT_MAX)); ret = essl_wait_int(handle, 0); @@ -149,7 +154,7 @@ TEST_CASE("SDIO_SDMMC: test register", "[sdio]") .max_freq_khz = SDMMC_FREQ_HIGHSPEED, }; //essl init and sdmmc init - s_master_init(&test_param, &handle); + s_master_init(&test_param, &handle, NULL); uint32_t init_val = 30; srand(850); @@ -183,7 +188,7 @@ TEST_CASE("SDIO_SDMMC: test reset", "[sdio]") .max_freq_khz = SDMMC_FREQ_HIGHSPEED, }; //essl init and sdmmc init - s_master_init(&test_param, &handle); + s_master_init(&test_param, &handle, NULL); //wait for the slave to stop, reset and start again vTaskDelay(10); @@ -215,6 +220,66 @@ TEST_CASE("SDIO_SDMMC: test reset", "[sdio]") s_master_deinit(); } +/*--------------------------------------------------------------- + SDMMC_SDIO: test fixed addr +---------------------------------------------------------------*/ +#include "soc/soc.h" +#define HOST_SLCHOST_CONF_W0_REG (DR_REG_SLCHOST_BASE + 0x6C) + +TEST_CASE("SDIO_SDMMC: test fixed addr", "[sdio]") +{ + essl_handle_t handle = NULL; + sdmmc_card_t* card; + test_sdio_param_t test_param = { + .host_flags = SDMMC_HOST_FLAG_4BIT | SDMMC_HOST_FLAG_ALLOC_ALIGNED_BUF, + .max_freq_khz = SDMMC_FREQ_HIGHSPEED, + }; + //essl init and sdmmc init + s_master_init(&test_param, &handle, &card); + + vTaskDelay(10); + + const int test_size = 128; + const int write_addr = 6; + uint8_t buf[test_size] = {}; + srand(850); + for (int i = 0; i < test_size; i++) { + buf[i] = rand(); + } + ESP_LOG_BUFFER_HEX("write_val", buf, test_size); + + TEST_ESP_OK(sdmmc_io_write_bytes(card, 1, ((HOST_SLCHOST_CONF_W0_REG + write_addr) & 0x3FF) | SDMMC_IO_FIXED_ADDR, buf, test_size)); + + const int max_size = 64; + uint8_t read_buf[max_size] = {}; + TEST_ESP_OK(sdmmc_io_read_bytes(card, 1, HOST_SLCHOST_CONF_W0_REG & 0x3FF, read_buf, max_size)); + ESP_LOG_BUFFER_HEX("read_all", read_buf, max_size); + for (int i = 0; i < max_size; i++) { + if (i >= 24 && i < 28) { + continue; + } + if (i >= 32 && i < 48) { + continue; + } + if (i == write_addr) { + TEST_ASSERT_EQUAL_HEX8(buf[test_size - 1], read_buf[i]); + } else { + TEST_ASSERT_EQUAL_HEX8(0xcc, read_buf[i]); + } + } + + const int read_size = (test_size > max_size ? max_size : test_size); + memset(read_buf, 0, read_size); + TEST_ESP_OK(sdmmc_io_read_bytes(card, 1, ((HOST_SLCHOST_CONF_W0_REG + write_addr) & 0x3FF) | SDMMC_IO_FIXED_ADDR, read_buf, read_size)); + ESP_LOG_BUFFER_HEX("read_fixed", read_buf, read_size); + for (int i = 0; i < read_size; i++) { + TEST_ASSERT_EQUAL_HEX8(buf[test_size - 1], read_buf[i]); + } + + s_send_finish_test(handle); + s_master_deinit(); +} + /*--------------------------------------------------------------- Transaction Tests ---------------------------------------------------------------*/ @@ -241,7 +306,7 @@ static void test_from_host(bool check_data) ESP_LOGI(TAG, "host speed: %"PRIu32" kHz", test_param_lists[i].max_freq_khz); essl_handle_t handle = NULL; - s_master_init(&test_param_lists[i], &handle); + s_master_init(&test_param_lists[i], &handle, NULL); // Two counters are used. The `esp_timer_get_time()` is for the typical time, and the // `ccomp_timer` is for performance test to reduce influence caused by cache miss. @@ -298,7 +363,7 @@ static void test_to_host(bool check_data) ESP_LOGI(TAG, "host speed: %"PRIu32" kHz", test_param_lists[i].max_freq_khz); essl_handle_t handle = NULL; - s_master_init(&test_param_lists[i], &handle); + s_master_init(&test_param_lists[i], &handle, NULL); esp_err_t ret; int offset = 0; diff --git a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/main/test_sdio_slave.c b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/main/test_sdio_slave.c index ca3e6816d2eb..d91e19dd7ce5 100644 --- a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/main/test_sdio_slave.c +++ b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/main/test_sdio_slave.c @@ -155,6 +155,24 @@ TEST_CASE("SDIO_Slave: test reset", "[sdio]") sdio_slave_deinit(); } +/*--------------------------------------------------------------- + SDMMC_SDIO: test fixed addr +---------------------------------------------------------------*/ +TEST_CASE("SDIO_Slave: test fixed addr", "[sdio]") +{ + s_slave_init(SDIO_SLAVE_SEND_PACKET); + TEST_ESP_OK(sdio_slave_start()); + ESP_LOGI(TAG, "slave ready"); + + for (int i = 0; i < 64; i++) { + sdio_slave_write_reg(i, 0xcc); + } + + wait_for_finish(&s_test_slv_ctx); + + sdio_slave_stop(); + sdio_slave_deinit(); +} /*--------------------------------------------------------------- Transaction Tests ---------------------------------------------------------------*/ diff --git a/components/esp_driver_sdm/Kconfig b/components/esp_driver_sdm/Kconfig index 50de62c3c660..ba89cac12525 100644 --- a/components/esp_driver_sdm/Kconfig +++ b/components/esp_driver_sdm/Kconfig @@ -8,14 +8,6 @@ menu "ESP-Driver:Sigma Delta Modulator Configurations" so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. Enabling this option can improve driver performance as well. - config SDM_SUPPRESS_DEPRECATE_WARN - bool "Suppress legacy driver deprecated warning" - default n - help - whether to suppress the deprecation warnings when using legacy sigma delta driver. - If you want to continue using the legacy driver, and don't want to see related deprecation warnings, - you can enable this option. - config SDM_ENABLE_DEBUG_LOG bool "Enable debug log" default n diff --git a/components/esp_driver_sdmmc/test_apps/.build-test-rules.yml b/components/esp_driver_sdmmc/test_apps/.build-test-rules.yml index cc6c1807730a..bb3416b4f338 100644 --- a/components/esp_driver_sdmmc/test_apps/.build-test-rules.yml +++ b/components/esp_driver_sdmmc/test_apps/.build-test-rules.yml @@ -1,10 +1,6 @@ components/esp_driver_sdmmc/test_apps/sdmmc: disable: - if: SOC_SDMMC_HOST_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: lack of runner # TODO: IDF-8970 depends_components: - sdmmc diff --git a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c index 360928efd887..b883e0043594 100644 --- a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c +++ b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c @@ -149,7 +149,7 @@ void sdmmc_test_rw_performance(sdmmc_card_t *card, FILE *perf_log) do_single_rw_perf_test(card, offset, 1, 1, perf_log, 0); do_single_rw_perf_test(card, offset, 8, 1, perf_log, 0); do_single_rw_perf_test(card, offset, 128, 1, perf_log, 0); -#if CONFIG_SPIRAM && SOC_SDMMC_PSRAM_DMA_CAPABLE +#if CONFIG_SPIRAM /* spiram */ do_single_rw_perf_test(card, offset, 1, 4, perf_log, MALLOC_CAP_SPIRAM); do_single_rw_perf_test(card, offset, 4, 4, perf_log, MALLOC_CAP_SPIRAM); diff --git a/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_rw_sd.c b/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_rw_sd.c index b8740ff533e3..942bae84b77c 100644 --- a/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_rw_sd.c +++ b/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_rw_sd.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,6 +37,11 @@ TEST_CASE("sdmmc read/write performance, slot 0, 8-bit", "[sdmmc]") do_one_sdmmc_perf_test(SLOT_0, 8, SDMMC_FREQ_HIGHSPEED, NO_DDR, NULL); } +TEST_CASE("sdmmc read/write performance, slot 1, 1-bit", "[sdmmc]") +{ + do_one_sdmmc_perf_test(SLOT_1, 1, SDMMC_FREQ_HIGHSPEED, NO_DDR, NULL); +} + TEST_CASE("sdmmc read/write performance, slot 1, 4-bit", "[sdmmc]") { /* Set up in-memory file for collecting performance logs */ diff --git a/components/esp_driver_sdmmc/test_apps/sdmmc/pytest_sdmmc.py b/components/esp_driver_sdmmc/test_apps/sdmmc/pytest_sdmmc.py index 747b8f36ff46..6feedee57e0e 100644 --- a/components/esp_driver_sdmmc/test_apps/sdmmc/pytest_sdmmc.py +++ b/components/esp_driver_sdmmc/test_apps/sdmmc/pytest_sdmmc.py @@ -7,7 +7,6 @@ @pytest.mark.esp32 @pytest.mark.esp32s3 @pytest.mark.esp32p4 -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runners, IDF-8970') @pytest.mark.sdcard def test_sdmmc(dut: IdfDut) -> None: # SDMMC driver can't be reinitialized if the test fails, diff --git a/components/esp_driver_sdmmc/test_apps/sdmmc/sdkconfig.defaults.esp32p4 b/components/esp_driver_sdmmc/test_apps/sdmmc/sdkconfig.defaults.esp32p4 index 7b8ca4566cf7..bae8235e8d7f 100644 --- a/components/esp_driver_sdmmc/test_apps/sdmmc/sdkconfig.defaults.esp32p4 +++ b/components/esp_driver_sdmmc/test_apps/sdmmc/sdkconfig.defaults.esp32p4 @@ -3,3 +3,4 @@ CONFIG_SDMMC_BOARD_ESP32P4_EV_BOARD=y CONFIG_SPIRAM=y CONFIG_IDF_EXPERIMENTAL_FEATURES=y CONFIG_SPIRAM_SPEED_200M=y +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index 7d5b139a0c17..3e2ba4895c8c 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.c @@ -243,12 +243,13 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch gdma_connect(dma_ctx->rx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); } #endif - gdma_transfer_ability_t ability = { - .psram_trans_align = 0, // fall back to use the same size of the psram data cache line size - .sram_trans_align = 4, + // TODO: add support to allow SPI transfer PSRAM buffer + gdma_transfer_config_t trans_cfg = { + .max_data_burst_size = 16, + .access_ext_mem = false, }; - ESP_RETURN_ON_ERROR(gdma_set_transfer_ability(dma_ctx->tx_dma_chan, &ability), SPI_TAG, "set gdma tx transfer ability failed"); - ESP_RETURN_ON_ERROR(gdma_set_transfer_ability(dma_ctx->rx_dma_chan, &ability), SPI_TAG, "set gdma rx transfer ability failed"); + ESP_RETURN_ON_ERROR(gdma_config_transfer(dma_ctx->tx_dma_chan, &trans_cfg), SPI_TAG, "config gdma tx transfer failed"); + ESP_RETURN_ON_ERROR(gdma_config_transfer(dma_ctx->rx_dma_chan, &trans_cfg), SPI_TAG, "config gdma rx transfer failed"); } return ret; } diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index ca791e25c53f..0cc45980621f 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -1458,6 +1458,40 @@ esp_err_t spi_bus_get_max_transaction_len(spi_host_device_t host_id, size_t *max /*----------------------------------------------------------- * Below functions should be in the same spinlock *-----------------------------------------------------------*/ +static SPI_MASTER_ISR_ATTR spi_dma_desc_t *s_sct_setup_desc_anywhere(spi_dma_desc_t *desc_root, spi_dma_desc_t *desc_start, uint32_t desc_num, const void *data, int len, bool is_rx) +{ + while (len) { + int dmachunklen = len; + if (dmachunklen > LLDESC_MAX_NUM_PER_DESC) { + dmachunklen = LLDESC_MAX_NUM_PER_DESC; + } + if (is_rx) { + //Receive needs DMA length rounded to next 32-bit boundary + desc_start->dw0.size = (dmachunklen + 3) & (~3); + } else { + desc_start->dw0.size = dmachunklen; + desc_start->dw0.length = dmachunklen; + } + desc_start->buffer = (uint8_t *)data; + desc_start->dw0.suc_eof = 0; + desc_start->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + len -= dmachunklen; + data += dmachunklen; + if (len) { + desc_start->next = (desc_start == &desc_root[desc_num - 1]) ? desc_root : &desc_start[1]; + desc_start = desc_start->next; + } + } + // desc_start is now walk to the end of used desc + desc_start->dw0.suc_eof = 1; //Mark last DMA desc as end of stream. + desc_start->next = NULL; + return desc_start; +} + +static SPI_MASTER_ISR_ATTR int s_sct_desc_get_required_num(uint32_t bytes_len) +{ + return (bytes_len + LLDESC_MAX_NUM_PER_DESC - 1) / LLDESC_MAX_NUM_PER_DESC; +} /*------------------------- * TX *------------------------*/ @@ -1466,13 +1500,12 @@ static void SPI_MASTER_ISR_ATTR spi_hal_sct_tx_dma_desc_recycle(spi_sct_desc_ctx desc_ctx->tx_free_desc_num += recycle_num; } -static void s_sct_prepare_tx_seg(spi_sct_desc_ctx_t *desc_ctx, const uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], const void *send_buffer, uint32_t buf_len_bytes, spi_dma_desc_t **trans_head) +static void SPI_MASTER_ISR_ATTR s_sct_prepare_tx_seg(spi_sct_desc_ctx_t *desc_ctx, const uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], const void *send_buffer, uint32_t buf_len_bytes, spi_dma_desc_t **trans_head) { - HAL_ASSERT(desc_ctx->tx_free_desc_num >= 1 + lldesc_get_required_num(buf_len_bytes)); const spi_dma_ctx_t *dma_ctx = __containerof(desc_ctx, spi_host_t, sct_desc_pool)->dma_ctx; *trans_head = desc_ctx->cur_tx_seg_link; - spicommon_dma_desc_setup_link(desc_ctx->cur_tx_seg_link, conf_buffer, SOC_SPI_SCT_BUFFER_NUM_MAX * 4, false); + s_sct_setup_desc_anywhere(dma_ctx->dmadesc_tx, desc_ctx->cur_tx_seg_link, dma_ctx->dma_desc_num, conf_buffer, SOC_SPI_SCT_BUFFER_NUM_MAX * 4, false); spi_dma_desc_t *conf_buffer_link = desc_ctx->cur_tx_seg_link; desc_ctx->tx_free_desc_num -= 1; @@ -1484,37 +1517,36 @@ static void s_sct_prepare_tx_seg(spi_sct_desc_ctx_t *desc_ctx, const uint32_t co } if (send_buffer && buf_len_bytes) { - spicommon_dma_desc_setup_link(desc_ctx->cur_tx_seg_link, send_buffer, buf_len_bytes, false); + desc_ctx->tx_seg_link_tail = s_sct_setup_desc_anywhere(dma_ctx->dmadesc_tx, desc_ctx->cur_tx_seg_link, dma_ctx->dma_desc_num, send_buffer, buf_len_bytes, false); conf_buffer_link->next = desc_ctx->cur_tx_seg_link; - for (int i = 0; i < lldesc_get_required_num(buf_len_bytes); i++) { - desc_ctx->tx_seg_link_tail = desc_ctx->cur_tx_seg_link; - desc_ctx->cur_tx_seg_link++; - if (desc_ctx->cur_tx_seg_link == dma_ctx->dmadesc_tx + dma_ctx->dma_desc_num) { - //As there is enough space, so we simply point this to the pool head - desc_ctx->cur_tx_seg_link = dma_ctx->dmadesc_tx; - } + desc_ctx->cur_tx_seg_link = desc_ctx->tx_seg_link_tail + 1; + if (desc_ctx->cur_tx_seg_link == dma_ctx->dmadesc_tx + dma_ctx->dma_desc_num) { + //As there is enough space, so we simply point this to the pool head + desc_ctx->cur_tx_seg_link = dma_ctx->dmadesc_tx; } - desc_ctx->tx_free_desc_num -= lldesc_get_required_num(buf_len_bytes); + desc_ctx->tx_free_desc_num -= s_sct_desc_get_required_num(buf_len_bytes); } } -static esp_err_t spi_hal_sct_new_tx_dma_desc_head(spi_sct_desc_ctx_t *desc_ctx, const uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], const void *send_buffer, uint32_t buf_len_bytes, spi_dma_desc_t **trans_head, uint32_t *used_desc_num) +static esp_err_t SPI_MASTER_ISR_ATTR spi_hal_sct_new_tx_dma_desc_head(spi_sct_desc_ctx_t *desc_ctx, const uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], const void *send_buffer, uint32_t buf_len_bytes, spi_dma_desc_t **trans_head, uint32_t *used_desc_num) { //1 desc for the conf_buffer, other for data. - if (desc_ctx->tx_free_desc_num < 1 + lldesc_get_required_num(buf_len_bytes)) { + int desc_need = 1 + s_sct_desc_get_required_num(buf_len_bytes); + if (desc_ctx->tx_free_desc_num < desc_need) { return ESP_ERR_NO_MEM; } s_sct_prepare_tx_seg(desc_ctx, conf_buffer, send_buffer, buf_len_bytes, trans_head); - *used_desc_num = 1 + lldesc_get_required_num(buf_len_bytes); + *used_desc_num = desc_need; return ESP_OK; } -static esp_err_t spi_hal_sct_link_tx_seg_dma_desc(spi_sct_desc_ctx_t *desc_ctx, const uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], const void *send_buffer, uint32_t buf_len_bytes, uint32_t *used_desc_num) +static esp_err_t SPI_MASTER_ISR_ATTR spi_hal_sct_link_tx_seg_dma_desc(spi_sct_desc_ctx_t *desc_ctx, const uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], const void *send_buffer, uint32_t buf_len_bytes, uint32_t *used_desc_num) { //1 desc for the conf_buffer, other for data. - if (desc_ctx->tx_free_desc_num < 1 + lldesc_get_required_num(buf_len_bytes)) { + int desc_need = 1 + s_sct_desc_get_required_num(buf_len_bytes); + if (desc_ctx->tx_free_desc_num < desc_need) { return ESP_ERR_NO_MEM; } @@ -1525,7 +1557,7 @@ static esp_err_t spi_hal_sct_link_tx_seg_dma_desc(spi_sct_desc_ctx_t *desc_ctx, spi_dma_desc_t *internal_head = NULL; s_sct_prepare_tx_seg(desc_ctx, conf_buffer, send_buffer, buf_len_bytes, &internal_head); - *used_desc_num += 1 + lldesc_get_required_num(buf_len_bytes); + *used_desc_num += desc_need; return ESP_OK; } @@ -1538,40 +1570,38 @@ static void SPI_MASTER_ISR_ATTR spi_hal_sct_rx_dma_desc_recycle(spi_sct_desc_ctx desc_ctx->rx_free_desc_num += recycle_num; } -static void s_sct_prepare_rx_seg(spi_sct_desc_ctx_t *desc_ctx, const void *recv_buffer, uint32_t buf_len_bytes, spi_dma_desc_t **trans_head) +static void SPI_MASTER_ISR_ATTR s_sct_prepare_rx_seg(spi_sct_desc_ctx_t *desc_ctx, const void *recv_buffer, uint32_t buf_len_bytes, spi_dma_desc_t **trans_head) { - HAL_ASSERT(desc_ctx->rx_free_desc_num >= lldesc_get_required_num(buf_len_bytes)); const spi_dma_ctx_t *dma_ctx = __containerof(desc_ctx, spi_host_t, sct_desc_pool)->dma_ctx; *trans_head = desc_ctx->cur_rx_seg_link; - spicommon_dma_desc_setup_link(desc_ctx->cur_rx_seg_link, recv_buffer, buf_len_bytes, true); - for (int i = 0; i < lldesc_get_required_num(buf_len_bytes); i++) { - desc_ctx->rx_seg_link_tail = desc_ctx->cur_rx_seg_link; - desc_ctx->cur_rx_seg_link++; - if (desc_ctx->cur_rx_seg_link == dma_ctx->dmadesc_rx + dma_ctx->dma_desc_num) { - //As there is enough space, so we simply point this to the pool head - desc_ctx->cur_rx_seg_link = dma_ctx->dmadesc_rx; - } + desc_ctx->rx_seg_link_tail = s_sct_setup_desc_anywhere(dma_ctx->dmadesc_rx, desc_ctx->cur_rx_seg_link, dma_ctx->dma_desc_num, recv_buffer, buf_len_bytes, true); + desc_ctx->cur_rx_seg_link = desc_ctx->rx_seg_link_tail + 1; + if (desc_ctx->cur_rx_seg_link == dma_ctx->dmadesc_rx + dma_ctx->dma_desc_num) { + //As there is enough space, so we simply point this to the pool head + desc_ctx->cur_rx_seg_link = dma_ctx->dmadesc_rx; } - desc_ctx->rx_free_desc_num -= lldesc_get_required_num(buf_len_bytes); + desc_ctx->rx_free_desc_num -= s_sct_desc_get_required_num(buf_len_bytes); } -static esp_err_t spi_hal_sct_new_rx_dma_desc_head(spi_sct_desc_ctx_t *desc_ctx, const void *recv_buffer, uint32_t buf_len_bytes, spi_dma_desc_t **trans_head, uint32_t *used_desc_num) +static esp_err_t SPI_MASTER_ISR_ATTR spi_hal_sct_new_rx_dma_desc_head(spi_sct_desc_ctx_t *desc_ctx, const void *recv_buffer, uint32_t buf_len_bytes, spi_dma_desc_t **trans_head, uint32_t *used_desc_num) { - if (desc_ctx->rx_free_desc_num < lldesc_get_required_num(buf_len_bytes)) { + int desc_need = s_sct_desc_get_required_num(buf_len_bytes); + if (desc_ctx->rx_free_desc_num < desc_need) { return ESP_ERR_NO_MEM; } s_sct_prepare_rx_seg(desc_ctx, recv_buffer, buf_len_bytes, trans_head); - *used_desc_num = lldesc_get_required_num(buf_len_bytes); + *used_desc_num = desc_need; return ESP_OK; } -static esp_err_t spi_hal_sct_link_rx_seg_dma_desc(spi_sct_desc_ctx_t *desc_ctx, const void *recv_buffer, uint32_t buf_len_bytes, uint32_t *used_desc_num) +static esp_err_t SPI_MASTER_ISR_ATTR spi_hal_sct_link_rx_seg_dma_desc(spi_sct_desc_ctx_t *desc_ctx, const void *recv_buffer, uint32_t buf_len_bytes, uint32_t *used_desc_num) { - if (desc_ctx->rx_free_desc_num < lldesc_get_required_num(buf_len_bytes)) { + int desc_need = s_sct_desc_get_required_num(buf_len_bytes); + if (desc_ctx->rx_free_desc_num < desc_need) { return ESP_ERR_NO_MEM; } @@ -1582,7 +1612,7 @@ static esp_err_t spi_hal_sct_link_rx_seg_dma_desc(spi_sct_desc_ctx_t *desc_ctx, spi_dma_desc_t *internal_head = NULL; s_sct_prepare_rx_seg(desc_ctx, recv_buffer, buf_len_bytes, &internal_head); - *used_desc_num += lldesc_get_required_num(buf_len_bytes); + *used_desc_num += desc_need; return ESP_OK; } diff --git a/components/esp_driver_spi/src/gpspi/spi_slave_hd.c b/components/esp_driver_spi/src/gpspi/spi_slave_hd.c index 22a53255cff7..c9518d70826f 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave_hd.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave_hd.c @@ -51,8 +51,8 @@ typedef struct { QueueHandle_t tx_ret_queue; QueueHandle_t rx_trans_queue; QueueHandle_t rx_ret_queue; - QueueHandle_t tx_cnting_sem; - QueueHandle_t rx_cnting_sem; + SemaphoreHandle_t tx_cnting_sem; + SemaphoreHandle_t rx_cnting_sem; spi_slave_hd_trans_priv_t tx_curr_trans; spi_slave_hd_trans_priv_t rx_curr_trans; @@ -335,16 +335,14 @@ static IRAM_ATTR void spi_slave_hd_intr_segment(void *arg) awoken |= intr_check_clear_callback(host, SPI_EV_CMD9, callback->cb_cmd9); awoken |= intr_check_clear_callback(host, SPI_EV_CMDA, callback->cb_cmdA); - bool tx_done = false; - bool rx_done = false; + bool tx_done = false, rx_done = false; + bool tx_event = false, rx_event = false; portENTER_CRITICAL_ISR(&host->int_spinlock); - if (host->tx_curr_trans.trans && spi_slave_hd_hal_check_disable_event(hal, SPI_EV_SEND)) { - tx_done = true; - } - if (host->rx_curr_trans.trans && spi_slave_hd_hal_check_disable_event(hal, SPI_EV_RECV)) { - rx_done = true; - } + tx_event = spi_slave_hd_hal_check_disable_event(hal, SPI_EV_SEND); + rx_event = spi_slave_hd_hal_check_disable_event(hal, SPI_EV_RECV); + tx_done = host->tx_curr_trans.trans && tx_event; + rx_done = host->rx_curr_trans.trans && rx_event; portEXIT_CRITICAL_ISR(&host->int_spinlock); if (tx_done) { diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_master_sct.c b/components/esp_driver_spi/test_apps/master/main/test_spi_master_sct.c index 527ee76cad15..2efb4184d91a 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_master_sct.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_master_sct.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -226,4 +226,69 @@ static void hd_slave(void) TEST_CASE_MULTIPLE_DEVICES("SPI_Master_SCT_HD_Functional", "[spi_ms]", hd_master, hd_slave); +#define SCT_LONG_TRANS_SEG_LEN 10000 //anything lager than 4092 +TEST_CASE("spi_master: test_sct_dma_desc_oob_on_tail", "[spi]") +{ + spi_device_handle_t handle; + + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + buscfg.max_transfer_sz = 4092 * 8; + + spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG(); + devcfg.clock_speed_hz = 100 * 1000; //low speed ensure cpu faster then HW + devcfg.flags = SPI_DEVICE_HALFDUPLEX; + + TEST_ESP_OK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO)); + TEST_ESP_OK(spi_bus_add_device(SPI2_HOST, &devcfg, &handle)); + printf("master init OK\n"); + uint8_t *master_tx_buf = heap_caps_calloc(1, SCT_LONG_TRANS_SEG_LEN, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + + //---------------------Master TX---------------------------// + spi_multi_transaction_t tx_seg_trans_cmd[1] = { //uing 1 dma desc, test trans without data phases + { + .base = { + .cmd = 0x7, + } + }, + }; + spi_multi_transaction_t tx_seg_trans_dummy[1] = { //using 4 dma desc + { + .base = { + .length = SCT_LONG_TRANS_SEG_LEN * 8, + .tx_buffer = master_tx_buf, + }, + }, + }; + spi_multi_transaction_t tx_seg_trans_data[1] = { //using 4 dma desc, should using (last 3 + first 1) of desc pool + { + .base = { + .cmd = 0x3, + .length = SCT_LONG_TRANS_SEG_LEN * 8, + .tx_buffer = master_tx_buf, + }, + .dummy_bits = 8, + .seg_trans_flags = SPI_MULTI_TRANS_DUMMY_LEN_UPDATED, + }, + }; + + spi_multi_transaction_t *ret_seg_trans; + printf("enabling sct multi trans mode ...\n"); + TEST_ESP_OK(spi_bus_multi_trans_mode_enable(handle, true)); + printf("start sct transaction\n"); + TEST_ESP_OK(spi_device_queue_multi_trans(handle, tx_seg_trans_cmd, 1, portMAX_DELAY)); + TEST_ESP_OK(spi_device_queue_multi_trans(handle, tx_seg_trans_dummy, 1, portMAX_DELAY)); + vTaskDelay(10 / portTICK_PERIOD_MS); //ensure `tx_seg_trans_cmd` had finish + TEST_ESP_OK(spi_device_queue_multi_trans(handle, tx_seg_trans_data, 1, portMAX_DELAY)); + + printf("waiting result ...\n"); + TEST_ESP_OK(spi_device_get_multi_trans_result(handle, &ret_seg_trans, portMAX_DELAY)); + TEST_ESP_OK(spi_device_get_multi_trans_result(handle, &ret_seg_trans, portMAX_DELAY)); + TEST_ESP_OK(spi_device_get_multi_trans_result(handle, &ret_seg_trans, portMAX_DELAY)); + TEST_ESP_OK(spi_bus_multi_trans_mode_enable(handle, false)); + + free(master_tx_buf); + TEST_ESP_OK(spi_bus_remove_device(handle)); + TEST_ESP_OK(spi_bus_free(SPI2_HOST)); +} + #endif //#if (SOC_SPI_SUPPORT_SLAVE_HD_VER2 && SOC_SPI_SCT_SUPPORTED) diff --git a/components/esp_driver_touch_sens/CMakeLists.txt b/components/esp_driver_touch_sens/CMakeLists.txt new file mode 100644 index 000000000000..e2a0c6040f86 --- /dev/null +++ b/components/esp_driver_touch_sens/CMakeLists.txt @@ -0,0 +1,21 @@ +idf_build_get_property(target IDF_TARGET) + +if(${target} STREQUAL "linux") + return() # This component is not supported by the POSIX/Linux simulator +endif() + +set(srcs) +set(public_inc) + +if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED) + if(CONFIG_SOC_TOUCH_SENSOR_VERSION EQUAL 3) + list(APPEND srcs "hw_ver3/touch_version_specific.c" + "common/touch_sens_common.c") + list(APPEND public_inc "include" "hw_ver3/include") + endif() +endif() + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES esp_driver_gpio + INCLUDE_DIRS ${public_inc} + ) diff --git a/components/esp_driver_touch_sens/Kconfig b/components/esp_driver_touch_sens/Kconfig new file mode 100644 index 000000000000..ef9d304d2a87 --- /dev/null +++ b/components/esp_driver_touch_sens/Kconfig @@ -0,0 +1,25 @@ +menu "ESP-Driver:Touch Sensor Configurations" + depends on SOC_TOUCH_SENSOR_SUPPORTED + config TOUCH_CTRL_FUNC_IN_IRAM + bool "Place touch sensor control functions into IRAM" + default n + help + Place touch sensor oneshot scanning and continuous scanning functions into IRAM, + so that these function can be IRAM-safe and able to be called when the flash cache is disabled. + Enabling this option can improve driver performance as well. + + config TOUCH_ISR_IRAM_SAFE + bool "Touch sensor ISR IRAM-Safe" + default n + help + Ensure the touch sensor interrupt is IRAM-Safe by allowing the interrupt handler to be + executable when the cache is disabled (e.g. SPI Flash write). + + config TOUCH_ENABLE_DEBUG_LOG + bool "Enable debug log" + default n + help + Whether to enable the debug log message for touch driver. + Note that, this option only controls the touch driver log, won't affect other drivers. + +endmenu # Touch Sensor Configuration diff --git a/components/esp_driver_touch_sens/common/touch_sens_common.c b/components/esp_driver_touch_sens/common/touch_sens_common.c new file mode 100644 index 000000000000..f5119c723721 --- /dev/null +++ b/components/esp_driver_touch_sens/common/touch_sens_common.c @@ -0,0 +1,428 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "soc/soc_caps.h" +#include "soc/rtc.h" +#include "soc/clk_tree_defs.h" +#include "soc/touch_sensor_periph.h" +#include "driver/rtc_io.h" +#include "driver/touch_sens.h" + +#if SOC_TOUCH_SENSOR_VERSION <= 2 +#include "esp_private/rtc_ctrl.h" +#else +#include "soc/interrupts.h" +#include "esp_intr_alloc.h" +#endif + +#if CONFIG_TOUCH_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif +#include "esp_check.h" +#include "touch_sens_private.h" + +#define TOUCH_CHANNEL_CHECK(num) ESP_RETURN_ON_FALSE(num >= TOUCH_MIN_CHAN_ID && num <= TOUCH_MAX_CHAN_ID, \ + ESP_ERR_INVALID_ARG, TAG, "The channel number is out of supported range"); + +static const char *TAG = "touch"; + +touch_sensor_handle_t g_touch = NULL; + +static void touch_channel_pin_init(int id) +{ + gpio_num_t pin = touch_sensor_channel_io_map[id]; + rtc_gpio_init(pin); + rtc_gpio_set_direction(pin, RTC_GPIO_MODE_DISABLED); + rtc_gpio_pulldown_dis(pin); + rtc_gpio_pullup_dis(pin); +} + +static void s_touch_free_resource(touch_sensor_handle_t sens_handle) +{ + if (!sens_handle) { + return; + } + if (sens_handle->mutex) { + vSemaphoreDeleteWithCaps(sens_handle->mutex); + sens_handle->mutex = NULL; + } + free(g_touch); + g_touch = NULL; +} + +esp_err_t touch_sensor_new_controller(const touch_sensor_config_t *sens_cfg, touch_sensor_handle_t *ret_sens_handle) +{ +#if CONFIG_TOUCH_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif + esp_err_t ret = ESP_OK; + TOUCH_NULL_POINTER_CHECK(sens_cfg); + TOUCH_NULL_POINTER_CHECK(ret_sens_handle); + ESP_RETURN_ON_FALSE(!g_touch, ESP_ERR_INVALID_STATE, TAG, "Touch sensor has been allocated"); + + g_touch = (touch_sensor_handle_t)heap_caps_calloc(1, sizeof(struct touch_sensor_s), TOUCH_MEM_ALLOC_CAPS); + ESP_RETURN_ON_FALSE(g_touch, ESP_ERR_NO_MEM, TAG, "No memory for touch sensor struct"); + + g_touch->mutex = xSemaphoreCreateMutexWithCaps(TOUCH_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(g_touch->mutex, ESP_ERR_NO_MEM, err, TAG, "No memory for mutex semaphore"); + + touch_priv_enable_module(true); + ESP_GOTO_ON_ERROR(touch_priv_config_controller(g_touch, sens_cfg), err, TAG, "Failed to configure the touch controller"); +#if SOC_TOUCH_SENSOR_VERSION <= 2 + ESP_GOTO_ON_ERROR(rtc_isr_register(touch_priv_default_intr_handler, NULL, TOUCH_LL_INTR_MASK_ALL, 0), err, TAG, "Failed to register interrupt handler"); +#else + ESP_GOTO_ON_ERROR(esp_intr_alloc(ETS_LP_TOUCH_INTR_SOURCE, TOUCH_INTR_ALLOC_FLAGS, touch_priv_default_intr_handler, NULL, &(g_touch->intr_handle)), + err, TAG, "Failed to register interrupt handler"); +#endif + *ret_sens_handle = g_touch; + return ret; + +err: + touch_priv_enable_module(false); + s_touch_free_resource(g_touch); + return ret; +} + +esp_err_t touch_sensor_del_controller(touch_sensor_handle_t sens_handle) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + ESP_RETURN_ON_FALSE(g_touch == sens_handle, ESP_ERR_INVALID_ARG, TAG, "The input touch sensor handle is unmatched"); + + esp_err_t ret = ESP_OK; + // Take the semaphore to make sure the touch has stopped + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Touch sensor has not disabled"); + FOR_EACH_TOUCH_CHANNEL(i) { + ESP_GOTO_ON_FALSE(!sens_handle->ch[i], ESP_ERR_INVALID_STATE, err, TAG, "There are still some touch channels not deleted"); + } + + ESP_GOTO_ON_ERROR(touch_priv_deinit_controller(sens_handle), err, TAG, "Failed to deinitialize the controller"); +#if SOC_TOUCH_SENSOR_VERSION <= 2 + ESP_GOTO_ON_ERROR(rtc_isr_deregister(touch_priv_default_intr_handler, NULL), err, TAG, "Failed to deregister the interrupt handler"); +#else + ESP_GOTO_ON_ERROR(esp_intr_free(sens_handle->intr_handle), err, TAG, "Failed to deregister the interrupt handler"); +#endif + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + touch_ll_intr_disable(TOUCH_LL_INTR_MASK_ALL); + touch_ll_clear_active_channel_status(); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + + touch_priv_enable_module(false); + s_touch_free_resource(sens_handle); +err: + if (g_touch && g_touch->mutex) { + xSemaphoreGive(g_touch->mutex); + } + return ret; +} + +esp_err_t touch_sensor_new_channel(touch_sensor_handle_t sens_handle, int chan_id, + const touch_channel_config_t *chan_cfg, + touch_channel_handle_t *ret_chan_handle) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + TOUCH_NULL_POINTER_CHECK(chan_cfg); + TOUCH_NULL_POINTER_CHECK(ret_chan_handle); + TOUCH_CHANNEL_CHECK(chan_id); + ESP_RETURN_ON_FALSE(g_touch == sens_handle, ESP_ERR_INVALID_ARG, TAG, "The input touch sensor handle is unmatched"); + + esp_err_t ret = ESP_OK; + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err2, TAG, "Please disable the touch sensor first"); + ESP_GOTO_ON_FALSE(!sens_handle->ch[chan_id], ESP_ERR_INVALID_STATE, err2, TAG, "The channel %d has been registered", chan_id); + + sens_handle->ch[chan_id] = (touch_channel_handle_t)heap_caps_calloc(1, sizeof(struct touch_channel_s), TOUCH_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(sens_handle->ch[chan_id], ESP_ERR_NO_MEM, err2, TAG, "No memory for touch channel"); + sens_handle->ch[chan_id]->id = chan_id; + sens_handle->ch[chan_id]->base = sens_handle; + sens_handle->ch[chan_id]->is_prox_chan = false; + + /* Init the channel */ + ESP_GOTO_ON_ERROR(touch_priv_config_channel(sens_handle->ch[chan_id], chan_cfg), + err1, TAG, "Failed to configure the touch channel %d", chan_id); + touch_channel_pin_init(chan_id); + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); +#if SOC_TOUCH_SENSOR_VERSION == 2 + touch_ll_reset_chan_benchmark(1 << chan_id); +#endif + sens_handle->chan_mask |= 1 << chan_id; + touch_ll_set_channel_mask(sens_handle->chan_mask); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + + *ret_chan_handle = sens_handle->ch[chan_id]; + + xSemaphoreGive(sens_handle->mutex); + return ret; +err1: + free(sens_handle->ch[chan_id]); + sens_handle->ch[chan_id] = NULL; +err2: + xSemaphoreGive(sens_handle->mutex); + return ret; +} + +esp_err_t touch_sensor_del_channel(touch_channel_handle_t chan_handle) +{ + TOUCH_NULL_POINTER_CHECK(chan_handle); + + esp_err_t ret = ESP_OK; + touch_sensor_handle_t sens_handle = chan_handle->base; + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first"); +#if SOC_TOUCH_SENSOR_VERSION == 2 + if (sens_handle->guard_chan == chan_handle || (BIT(chan_handle->id) & sens_handle->shield_chan_mask)) { + ESP_GOTO_ON_ERROR(touch_sensor_config_waterproof(sens_handle, NULL), err, TAG, "Failed to disable waterproof on this channel"); + } + if (sens_handle->sleep_chan == chan_handle) { + ESP_GOTO_ON_ERROR(touch_sensor_config_sleep_channel(sens_handle, NULL), err, TAG, "Failed to disable sleep function on this channel"); + } +#endif + int id = chan_handle->id; + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + sens_handle->chan_mask &= ~(1UL << id); + touch_ll_set_channel_mask(sens_handle->chan_mask); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + + free(g_touch->ch[id]); + g_touch->ch[id] = NULL; +err: + xSemaphoreGive(sens_handle->mutex); + return ret; +} + +esp_err_t touch_sensor_reconfig_controller(touch_sensor_handle_t sens_handle, const touch_sensor_config_t *sens_cfg) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + TOUCH_NULL_POINTER_CHECK(sens_cfg); + ESP_RETURN_ON_FALSE(sens_cfg->meas_interval_us >= 0, ESP_ERR_INVALID_ARG, TAG, "interval_us should be a positive value"); + + esp_err_t ret = ESP_OK; + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first"); + + ESP_GOTO_ON_ERROR(touch_priv_config_controller(sens_handle, sens_cfg), err, TAG, "Configure touch controller failed"); + +err: + xSemaphoreGive(sens_handle->mutex); + return ret; +} + +esp_err_t touch_sensor_enable(touch_sensor_handle_t sens_handle) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + + esp_err_t ret = ESP_OK; + xSemaphoreTakeRecursive(sens_handle->mutex, portMAX_DELAY); + + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Touch sensor has already enabled"); + ESP_GOTO_ON_FALSE(sens_handle->sample_cfg_num, ESP_ERR_INVALID_STATE, err, TAG, "No sample configuration was added to the touch controller"); + + sens_handle->is_enabled = true; + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + touch_ll_intr_clear(TOUCH_LL_INTR_MASK_ALL); + touch_ll_intr_enable(TOUCH_LL_INTR_MASK_ALL); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); +#if SOC_TOUCH_SUPPORT_PROX_SENSING + /* Reset the cached data of proximity channel */ + FOR_EACH_TOUCH_CHANNEL(i) { + if (sens_handle->ch[i] && sens_handle->ch[i]->is_prox_chan) { + sens_handle->ch[i]->prox_cnt = 0; + memset(sens_handle->ch[i]->prox_val, 0, sizeof(sens_handle->ch[i]->prox_val[0]) * TOUCH_SAMPLE_CFG_NUM); + } + } +#endif + +err: + xSemaphoreGiveRecursive(sens_handle->mutex); + return ret; +} + +esp_err_t touch_sensor_disable(touch_sensor_handle_t sens_handle) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + + esp_err_t ret = ESP_OK; + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Touch sensor has not enabled"); + + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + touch_ll_intr_disable(TOUCH_LL_INTR_MASK_ALL); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + sens_handle->is_enabled = false; + +err: + xSemaphoreGive(sens_handle->mutex); + return ret; +} + +esp_err_t touch_sensor_reconfig_channel(touch_channel_handle_t chan_handle, const touch_channel_config_t *chan_cfg) +{ + TOUCH_NULL_POINTER_CHECK(chan_handle); + TOUCH_NULL_POINTER_CHECK(chan_cfg); + + esp_err_t ret = ESP_OK; + touch_sensor_handle_t sens_handle = chan_handle->base; + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first"); + + ESP_GOTO_ON_ERROR(touch_priv_config_channel(chan_handle, chan_cfg), err, TAG, "Configure touch channel failed"); + +err: + xSemaphoreGive(sens_handle->mutex); + return ret; +} + +esp_err_t touch_sensor_start_continuous_scanning(touch_sensor_handle_t sens_handle) +{ + TOUCH_NULL_POINTER_CHECK_ISR(sens_handle); + + esp_err_t ret = ESP_OK; + + ESP_GOTO_ON_FALSE_ISR(sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please enable the touch sensor first"); + ESP_GOTO_ON_FALSE_ISR(!sens_handle->is_started, ESP_ERR_INVALID_STATE, err, TAG, "Continuous scanning has started already"); + + TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + sens_handle->is_started = true; +#if SOC_TOUCH_SENSOR_VERSION <= 2 + touch_ll_set_fsm_mode(TOUCH_FSM_MODE_TIMER); + touch_ll_start_fsm(); +#else + touch_ll_enable_fsm_timer(true); + touch_ll_start_fsm_repeated_timer(false); +#endif + TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + +err: + return ret; +} + +esp_err_t touch_sensor_stop_continuous_scanning(touch_sensor_handle_t sens_handle) +{ + TOUCH_NULL_POINTER_CHECK_ISR(sens_handle); + + esp_err_t ret = ESP_OK; + + ESP_GOTO_ON_FALSE_ISR(sens_handle->is_started, ESP_ERR_INVALID_STATE, err, TAG, "Continuous scanning not started yet"); + + TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); +#if SOC_TOUCH_SENSOR_VERSION <= 2 + touch_ll_stop_fsm(); + touch_ll_set_fsm_mode(TOUCH_FSM_MODE_SW); +#else + touch_ll_stop_fsm_repeated_timer(false); + touch_ll_enable_fsm_timer(false); +#endif + sens_handle->is_started = false; + TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + +err: + return ret; +} + +esp_err_t touch_sensor_trigger_oneshot_scanning(touch_sensor_handle_t sens_handle, int timeout_ms) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please enable the touch sensor first"); + ESP_GOTO_ON_FALSE(!sens_handle->is_started, ESP_ERR_INVALID_STATE, err, TAG, "Failed to trigger oneshot scanning because scanning has started"); + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + sens_handle->is_started = true; + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + + TickType_t ticks = 0; + if (timeout_ms > 0) { + ticks = pdMS_TO_TICKS(timeout_ms); + if (!ticks) { + ESP_LOGW(TAG, "The timeout is too small, use the minimum tick resolution as default: %"PRIu32" ms", portTICK_PERIOD_MS); + ticks = 1; + } + } + xSemaphoreTake(sens_handle->mutex, ticks); + TickType_t end_tick = xTaskGetTickCount() + ticks; + // TODO: extract the following implementation into version specific source file when supporting other targets + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + touch_ll_enable_fsm_timer(false); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + FOR_EACH_TOUCH_CHANNEL(i) { + if (sens_handle->ch[i]) { + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + touch_ll_channel_sw_measure_mask(BIT(i)); + touch_ll_trigger_oneshot_measurement(); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + while (!touch_ll_is_measure_done()) { + if (g_touch->is_meas_timeout) { + g_touch->is_meas_timeout = false; + ESP_LOGW(TAG, "The measurement time on channel %d exceed the limitation", i); + break; + } + if (timeout_ms >= 0) { + ESP_GOTO_ON_FALSE(xTaskGetTickCount() <= end_tick, ESP_ERR_TIMEOUT, err, TAG, "Wait for measurement done timeout"); + } + vTaskDelay(1); + } + } + } + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + touch_ll_channel_sw_measure_mask(0); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + +err: + xSemaphoreGive(sens_handle->mutex); + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + sens_handle->is_started = false; + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + return ret; +} + +esp_err_t touch_sensor_register_callbacks(touch_sensor_handle_t sens_handle, const touch_event_callbacks_t *callbacks, void *user_ctx) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + TOUCH_NULL_POINTER_CHECK(callbacks); + +#if CONFIG_TOUCH_ISR_IRAM_SAFE + const uint32_t **ptr = (const uint32_t **)callbacks; + for (int i = 0; i < sizeof(touch_event_callbacks_t) / sizeof(uint32_t *); i++) { + ESP_RETURN_ON_FALSE(TOUCH_IRAM_CHECK(ptr[i]), ESP_ERR_INVALID_ARG, TAG, "callback not in IRAM"); + } + ESP_RETURN_ON_FALSE(!user_ctx || esp_ptr_internal(user_ctx), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); +#endif + + esp_err_t ret = ESP_OK; + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first"); + + memcpy(&sens_handle->cbs, callbacks, sizeof(touch_event_callbacks_t)); + sens_handle->user_ctx = user_ctx; + +err: + xSemaphoreGive(sens_handle->mutex); + return ret; +} + +esp_err_t touch_channel_read_data(touch_channel_handle_t chan_handle, touch_chan_data_type_t type, uint32_t *data) +{ + TOUCH_NULL_POINTER_CHECK_ISR(chan_handle); + TOUCH_NULL_POINTER_CHECK_ISR(data); + return touch_priv_channel_read_data(chan_handle, type, data); +} + +esp_err_t touch_channel_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg) +{ + TOUCH_NULL_POINTER_CHECK_ISR(chan_handle); + TOUCH_NULL_POINTER_CHECK_ISR(benchmark_cfg); + touch_priv_config_benchmark(chan_handle, benchmark_cfg); + return ESP_OK; +} diff --git a/components/esp_driver_touch_sens/common/touch_sens_private.h b/components/esp_driver_touch_sens/common/touch_sens_private.h new file mode 100644 index 000000000000..325acb775e57 --- /dev/null +++ b/components/esp_driver_touch_sens/common/touch_sens_private.h @@ -0,0 +1,192 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief This header file is private for the internal use of the touch driver + * DO NOT use any APIs or types in this file outside of the touch driver + */ + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "soc/soc_caps.h" +#include "hal/touch_sensor_hal.h" +#include "driver/touch_sens_types.h" +#include "esp_memory_utils.h" +#include "esp_check.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper macros */ +#define TOUCH_NULL_POINTER_CHECK(p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, TAG, "input parameter '"#p"' is NULL") +#define TOUCH_NULL_POINTER_CHECK_ISR(p) ESP_RETURN_ON_FALSE_ISR((p), ESP_ERR_INVALID_ARG, TAG, "input parameter '"#p"' is NULL") +#define FOR_EACH_TOUCH_CHANNEL(i) for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) +#define TOUCH_IRAM_CHECK(cb) (!(cb) || esp_ptr_in_iram(cb)) + +/* IRAM safe caps */ +#if CONFIG_TOUCH_ISR_IRAM_SAFE || CONFIG_TOUCH_CTRL_FUNC_IN_IRAM +#define TOUCH_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED) +#define TOUCH_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#else +#define TOUCH_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED) +#define TOUCH_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT +#endif //CONFIG_TOUCH_ISR_IRAM_SAFE + +/* DMA caps */ +#define TOUCH_DMA_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA) + +/* RTC peripheral spin lock */ +extern portMUX_TYPE rtc_spinlock; +#define TOUCH_RTC_LOCK (&rtc_spinlock) + +#if SOC_TOUCH_SENSOR_VERSION <= 2 +#define TOUCH_PERIPH_LOCK (&rtc_spinlock) +#else +extern portMUX_TYPE g_touch_spinlock; +#define TOUCH_PERIPH_LOCK (&g_touch_spinlock) +#endif + +#define TOUCH_ENTER_CRITICAL(spinlock) portENTER_CRITICAL(spinlock) +#define TOUCH_EXIT_CRITICAL(spinlock) portEXIT_CRITICAL(spinlock) +#define TOUCH_ENTER_CRITICAL_SAFE(spinlock) portENTER_CRITICAL_SAFE(spinlock) +#define TOUCH_EXIT_CRITICAL_SAFE(spinlock) portEXIT_CRITICAL_SAFE(spinlock) + +/** + * @brief The touch sensor controller instance structure + * @note A touch sensor controller includes multiple channels and sample configurations + * + */ +struct touch_sensor_s { + touch_channel_handle_t ch[SOC_TOUCH_SENSOR_NUM]; /*!< Touch sensor channel handles, will be NULL if the channel is not registered */ + uint32_t chan_mask; /*!< Enabled channel mask, corresponding bit will be set if the channel is registered */ + uint32_t src_freq_hz; /*!< Source clock frequency */ + intr_handle_t intr_handle; /*!< Interrupt handle */ + touch_event_callbacks_t cbs; /*!< Event callbacks */ + touch_channel_handle_t deep_slp_chan; /*!< The configured channel for depp sleep, will be NULL if not enable the deep sleep */ + touch_channel_handle_t guard_chan; /*!< The configured channel for the guard ring, will be NULL if not set */ + touch_channel_handle_t shield_chan; /*!< The configured channel for the shield pad, will be NULL if not set */ + + SemaphoreHandle_t mutex; /*!< Mutex lock to ensure thread safety */ + + uint8_t sample_cfg_num; /*!< The number of sample configurations that in used */ + void *user_ctx; /*!< User context that will pass to the callback function */ + bool is_enabled; /*!< Flag to indicate whether the scanning is enabled */ + bool is_started; /*!< Flag to indicate whether the scanning has started */ + bool is_meas_timeout; /*!< Flag to indicate whether the measurement timeout, will force to stop the current measurement if the timeout is triggered */ + bool sleep_en; /*!< Flag to indicate whether the sleep wake-up feature is enabled */ + bool waterproof_en; /*!< Flag to indicate whether the water proof feature is enabled */ + bool immersion_proof; /*!< Flag to indicate whether to disable scanning when the guard ring is triggered */ + bool proximity_en; /*!< Flag to indicate whether the proximity sensing feature is enabled */ + bool timeout_en; /*!< Flag to indicate whether the measurement timeout feature (hardware timeout) is enabled */ +}; + +/** + * @brief The touch sensor channel instance structure + * + */ +struct touch_channel_s { + touch_sensor_handle_t base; /*!< The touch sensor controller handle */ + int id; /*!< Touch channel id, the range is target-specific */ + bool is_prox_chan; /*!< Flag to indicate whether this is a proximity channel */ + uint32_t prox_cnt; /*!< Cache the proximity measurement count, only takes effect when the channel is a proximity channel. + * When this count reaches `touch_proximity_config_t::scan_times`, + * this field will be cleared and call the `on_proximity_meas_done` callback. + */ + uint32_t prox_val[TOUCH_SAMPLE_CFG_NUM]; /*!< The accumulated proximity value of each sample config. + * The value will accumulate for each scanning until it reaches `touch_proximity_config_t::scan_times`. + * This accumulated proximity value can be read via `touch_channel_read_data` when all scanning finished. + */ +}; + +extern touch_sensor_handle_t g_touch; /*!< Global touch sensor controller handle for `esp_driver_touch_sens` use only */ + +/** + * @brief Touch sensor module enable interface + * @note This is a private interface of `esp_driver_touch_sens` + * It should be implemented by each hardware version + * + * @param[in] enable Set true to enable touch sensor module clock + */ +void touch_priv_enable_module(bool enable); + +/** + * @brief Touch sensor default interrupt handler + * @note This is a private interface of `esp_driver_touch_sens` + * It should be implemented by each hardware version + * + * @param[in] arg The input argument + */ +void touch_priv_default_intr_handler(void *arg); + +/** + * @brief Touch sensor controller configuration interface + * @note This is a private interface of `esp_driver_touch_sens` + * It should be implemented by each hardware version + * + * @param[in] sens_handle The touch sensor controller handle + * @param[in] sens_cfg The touch sensor controller configuration pointer + * @return + * - ESP_OK On success + * - Others Version-specific failure code + */ +esp_err_t touch_priv_config_controller(touch_sensor_handle_t sens_handle, const touch_sensor_config_t *sens_cfg); + +/** + * @brief Touch sensor channel configuration interface + * @note This is a private interface of `esp_driver_touch_sens` + * It should be implemented by each hardware version + * + * @param[in] chan_handle The touch sensor channel handle + * @param[in] chan_cfg The touch sensor channel configuration pointer + * @return + * - ESP_OK On success + * - Others Version-specific failure code + */ +esp_err_t touch_priv_config_channel(touch_channel_handle_t chan_handle, const touch_channel_config_t *chan_cfg); + +/** + * @brief Touch sensor controller de-initialize interface + * @note This is a private interface of `esp_driver_touch_sens` + * It should be implemented by each hardware version + * + * @param[in] sens_handle The touch sensor handle + * @return + * - ESP_OK On success + * - Others Version-specific failure code + */ +esp_err_t touch_priv_deinit_controller(touch_sensor_handle_t sens_handle); + +/** + * @brief Touch sensor channel data read interface + * @note This is a private interface of `esp_driver_touch_sens` + * It should be implemented by each hardware version + * + * @param[in] chan_handle The touch sensor channel handle + * @param[in] type The read data type + * @param[out] data The output data pointer + * @return + * - ESP_OK On success + * - Others Version-specific failure code + */ +esp_err_t touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch_chan_data_type_t type, uint32_t *data); + +/** + * @brief Touch sensor channel benchmark set interface + * @note This is a private interface of `esp_driver_touch_sens` + * It should be implemented by each hardware version + * + * @param[in] chan_handle The channel handle + * @param[in] benchmark_cfg The benchmark operation + */ +void touch_priv_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_touch_sens/hw_ver1/include/driver/touch_version_types.h b/components/esp_driver_touch_sens/hw_ver1/include/driver/touch_version_types.h new file mode 100644 index 000000000000..230a0df55ee1 --- /dev/null +++ b/components/esp_driver_touch_sens/hw_ver1/include/driver/touch_version_types.h @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief This file is only applicable to the touch hardware version1 + * Version 1 includes ESP32 + */ + +#error "'esp_driver_touch_sens' does not support for ESP32 yet" diff --git a/components/esp_driver_touch_sens/hw_ver2/include/driver/touch_version_types.h b/components/esp_driver_touch_sens/hw_ver2/include/driver/touch_version_types.h new file mode 100644 index 000000000000..3eb0d2167e96 --- /dev/null +++ b/components/esp_driver_touch_sens/hw_ver2/include/driver/touch_version_types.h @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief This file is only applicable to the touch hardware version2 + * Version 2 includes ESP32-S2 and ESP32-S3 + */ + +#error "'esp_driver_touch_sens' does not support for ESP32-S2 and ESP32-S3 yet" diff --git a/components/esp_driver_touch_sens/hw_ver3/include/driver/touch_version_types.h b/components/esp_driver_touch_sens/hw_ver3/include/driver/touch_version_types.h new file mode 100644 index 000000000000..cf15c14be8aa --- /dev/null +++ b/components/esp_driver_touch_sens/hw_ver3/include/driver/touch_version_types.h @@ -0,0 +1,424 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief This file is only applicable to the touch hardware version3 + * Version 3 includes ESP32-P4 + */ + +#pragma once + +#include "soc/soc_caps.h" +#include "driver/touch_sens_types.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TOUCH_MIN_CHAN_ID 0 /*!< The minimum available channel id of the touch pad */ +#define TOUCH_MAX_CHAN_ID 13 /*!< The maximum available channel id of the touch pad */ + +/** + * @brief Helper macro to the default configurations of the touch sensor controller + * + */ +#define TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(sample_cfg_number, sample_cfg_array) { \ + .power_on_wait_us = 256, \ + .meas_interval_us = 32.0, \ + .max_meas_time_us = 0, \ + .output_mode = TOUCH_PAD_OUT_AS_CLOCK, \ + .sample_cfg_num = sample_cfg_number, \ + .sample_cfg = sample_cfg_array, \ +} + +/** + * @brief Helper macro to the default sample configurations + * @note This default configuration uses `sample frequency = clock frequency / 1` + * + */ +#define TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_div_num, coarse_freq_tune, fine_freq_tune) { \ + .div_num = _div_num, \ + .charge_times = 500, \ + .rc_filter_res = 1, \ + .rc_filter_cap = 1, \ + .low_drv = fine_freq_tune, \ + .high_drv = coarse_freq_tune, \ + .bias_volt = 5, \ + .bypass_shield_output = false, \ +} + +#define TOUCH_SENSOR_DEFAULT_FILTER_CONFIG() { \ + .benchmark = { \ + .filter_mode = TOUCH_BM_IIR_FILTER_4, \ + .jitter_step = 4, \ + .denoise_lvl = 1, \ + }, \ + .data = { \ + .smooth_filter = TOUCH_SMOOTH_IIR_FILTER_2, \ + .active_hysteresis = 2, \ + }, \ +} + +/** + * @brief The data type of the touch channel + * + */ +typedef enum { + TOUCH_CHAN_DATA_TYPE_SMOOTH, /*!< The smooth data of the touch channel */ + TOUCH_CHAN_DATA_TYPE_BENCHMARK, /*!< The benchmark of the touch channel */ + TOUCH_CHAN_DATA_TYPE_PROXIMITY, /*!< The proximity data of the proximity channel */ +} touch_chan_data_type_t; + +/** + * @brief The chip sleep level that allows the touch sensor to wake-up + * + */ +typedef enum { + TOUCH_LIGHT_SLEEP_WAKEUP, /*!< Only enable the touch sensor to wake up the chip from light sleep */ + TOUCH_DEEP_SLEEP_WAKEUP, /*!< Enable the touch sensor to wake up the chip from deep sleep or light sleep */ +} touch_sleep_wakeup_level_t; + +/** + * @brief Touch sensor shield channel drive capability level + * + */ +typedef enum { + TOUCH_SHIELD_CAP_40PF, /*!< The max equivalent capacitance in shield channel is 40pf */ + TOUCH_SHIELD_CAP_80PF, /*!< The max equivalent capacitance in shield channel is 80pf */ + TOUCH_SHIELD_CAP_120PF, /*!< The max equivalent capacitance in shield channel is 120pf */ + TOUCH_SHIELD_CAP_160PF, /*!< The max equivalent capacitance in shield channel is 160pf */ + TOUCH_SHIELD_CAP_200PF, /*!< The max equivalent capacitance in shield channel is 200pf */ + TOUCH_SHIELD_CAP_240PF, /*!< The max equivalent capacitance in shield channel is 240pf */ + TOUCH_SHIELD_CAP_280PF, /*!< The max equivalent capacitance in shield channel is 280pf */ + TOUCH_SHIELD_CAP_320PF, /*!< The max equivalent capacitance in shield channel is 320pf */ +} touch_chan_shield_cap_t; + +/** + * @brief Touch channel Infinite Impulse Response (IIR) filter or Jitter filter for benchmark + * @note Recommended filter coefficient selection is `IIR_16`. + */ +typedef enum { + TOUCH_BM_IIR_FILTER_4, /*!< IIR Filter for benchmark, 1/4 raw_value + 3/4 benchmark */ + TOUCH_BM_IIR_FILTER_8, /*!< IIR Filter for benchmark, 1/8 raw_value + 7/8 benchmark */ + TOUCH_BM_IIR_FILTER_16, /*!< IIR Filter for benchmark, 1/16 raw_value + 15/16 benchmark (typical) */ + TOUCH_BM_IIR_FILTER_32, /*!< IIR Filter for benchmark, 1/32 raw_value + 31/32 benchmark */ + TOUCH_BM_IIR_FILTER_64, /*!< IIR Filter for benchmark, 1/64 raw_value + 63/64 benchmark */ + TOUCH_BM_IIR_FILTER_128, /*!< IIR Filter for benchmark, 1/128 raw_value + 127/128 benchmark */ + TOUCH_BM_JITTER_FILTER, /*!< Jitter Filter for benchmark, raw value +/- jitter_step */ +} touch_benchmark_filter_mode_t; + +/** + * @brief Touch channel Infinite Impulse Response (IIR) filter for smooth data + * + */ +typedef enum { + TOUCH_SMOOTH_NO_FILTER, /*!< No filter adopted for smooth data, smooth data equals raw data */ + TOUCH_SMOOTH_IIR_FILTER_2, /*!< IIR filter adopted for smooth data, smooth data equals 1/2 raw data + 1/2 last smooth data (typical) */ + TOUCH_SMOOTH_IIR_FILTER_4, /*!< IIR filter adopted for smooth data, smooth data equals 1/4 raw data + 3/4 last smooth data */ + TOUCH_SMOOTH_IIR_FILTER_8, /*!< IIR filter adopted for smooth data, smooth data equals 1/8 raw data + 7/8 last smooth data */ +} touch_smooth_filter_mode_t; + +/** + * @brief Interrupt events + * + */ +typedef enum { + TOUCH_INTR_EVENT_ACTIVE, /*!< Touch channel active event */ + TOUCH_INTR_EVENT_INACTIVE, /*!< Touch channel inactive event */ + TOUCH_INTR_EVENT_MEASURE_DONE, /*!< Touch channel measure done event */ + TOUCH_INTR_EVENT_SCAN_DONE, /*!< All touch channels scan done event */ + TOUCH_INTR_EVENT_TIMEOUT, /*!< Touch channel measurement timeout event */ + TOUCH_INTR_EVENT_PROXIMITY_DONE, /*!< Proximity channel measurement done event */ +} touch_intr_event_t; + +/** + * @brief Sample configurations of the touch sensor + * + */ +typedef struct { + uint32_t div_num; /*!< Division of the touch output pulse, `touch_out_pulse / div_num = charge_times` */ + uint32_t charge_times; /*!< The charge and discharge times of this sample configuration, the read data are positive correlation to the charge_times */ + uint8_t rc_filter_res; /*!< The resistance of the RC filter of this sample configuration, range [0, 3], while 0 = 0K, 1 = 1.5K, 2 = 3K, 3 = 4.5K */ + uint8_t rc_filter_cap; /*!< The capacitance of the RC filter of this sample configuration, range [0, 127], while 0 = 0pF, 1 = 20fF, ..., 127 = 2.54pF */ + uint8_t low_drv; /*!< Low speed touch driver, only effective when high speed driver is disabled */ + uint8_t high_drv; /*!< High speed touch driver */ + uint8_t bias_volt; /*!< The Internal LDO voltage, which decide the bias voltage of the sample wave, range [0,15] */ + bool bypass_shield_output; /*!< Whether to bypass the shield output, enable when the charging/discharging rate greater than 10MHz */ +} touch_sensor_sample_config_t; + +/** + * @brief Configurations of the touch sensor controller + * + */ +typedef struct { + uint32_t power_on_wait_us; /*!< The waiting time between the channels power on and able to measure, to ensure the data stability */ + float meas_interval_us; /*!< Measurement interval of each channels */ + uint32_t max_meas_time_us; /*!< The maximum time of measuring one channel, if the time exceeds this value, the timeout interrupt will be triggered. + * Set to '0' to ignore the measurement time limitation, otherwise please set a proper time considering the configurations + * of this sample configurations below. + */ + touch_out_mode_t output_mode; /*!< Touch channel counting mode of the binarized touch output */ + uint32_t sample_cfg_num; /*!< The sample configuration number that used for sampling */ + touch_sensor_sample_config_t *sample_cfg; /*!< The array of this sample configuration configurations, the length should be specified in `touch_sensor_config_t::sample_cfg_num` */ +} touch_sensor_config_t; + +/** + * @brief Configurations of the touch sensor channel + * + */ +typedef struct { + uint32_t active_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The active threshold of each sample configuration, + * while the touch channel smooth value minus benchmark value exceed this threshold, + * will be regarded as activated + */ +} touch_channel_config_t; + +/** + * @brief Configurations of the touch sensor filter + * + */ +typedef struct { + /** + * @brief Benchmark configuration + */ + struct { + touch_benchmark_filter_mode_t filter_mode; /*!< Benchmark filter mode. IIR filter and Jitter filter can be selected, + * TOUCH_BM_IIR_FILTER_16 is recommended + */ + uint32_t jitter_step; /*!< Jitter filter step size, only takes effect when the `filter_mode` is TOUCH_BM_JITTER_FILTER. Range: [0 ~ 15] */ + int denoise_lvl; /*!< The denoise level, which determines the noise bouncing range that won't trigger benchmark update. + * Range: [0 ~ 4]. The greater the denoise_lvl is, more noise resistance will be. Specially, `0` stands for no denoise + * Typically, recommend to set this field to 1. + */ + } benchmark; /*!< Benchmark filter */ + /** + * @brief Data configuration + */ + struct { + touch_smooth_filter_mode_t smooth_filter; /*!< Smooth data IIR filter mode */ + uint32_t active_hysteresis; /*!< The hysteresis threshold to judge whether the touch channel is active + * If the channel data exceed the 'touch_channel_config_t::active_thresh + active_hysteresis' + * The channel will be activated. If the channel data is below to + * 'touch_channel_config_t::active_thresh - active_hysteresis' the channel will be inactivated. + */ + uint32_t debounce_cnt; /*!< The debounce count of the touch channel. + * Only when the channel data exceed the `touch_channel_config_t::active_thresh + active_hysteresis` for `debounce_cnt` times + * The channel will be activated. And only if the channel data is below to the `touch_channel_config_t::active_thresh - active_hysteresis` + * for `debounce_cnt` times, the channel will be inactivated. + * (The unit of `debounce_cnt` is the tick of the slow clock source) + */ + } data; /*!< Channel data filter */ +} touch_sensor_filter_config_t; + +/** + * @brief Touch sensor configuration during the deep sleep + * @note Currently it is the same as the normal controller configuration. + * The deep sleep configuration only takes effect when the chip entered sleep, + * so that to update a more power efficient configuration. + * + */ +typedef touch_sensor_config_t touch_sensor_config_dslp_t; + +/** + * @brief Configure the touch sensor sleep function + * + */ +typedef struct { + touch_sleep_wakeup_level_t slp_wakeup_lvl; /*!< The sleep level that can be woke up by touch sensor. */ + touch_channel_handle_t deep_slp_chan; /*!< The touch channel handle that supposed to work in the deep sleep. It can wake up the chip + * from deep sleep when this channel is activated. + * Only effective when the `touch_sleep_config_t::slp_wakeup_lvl` is `TOUCH_DEEP_SLEEP_WAKEUP` + */ + uint32_t deep_slp_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The active threshold of the deep sleep channel during deep sleep, + * while the sleep channel exceed this threshold, it will be regarded as activated + * Only effective when the `touch_sleep_config_t::slp_wakeup_lvl` is `TOUCH_DEEP_SLEEP_WAKEUP` + */ + touch_sensor_config_dslp_t *deep_slp_sens_cfg; /*!< Specify the touch sensor configuration during the deep sleep. + * Note that these configurations will no take effect immediately, + * they will be set automatically while the chip prepare to enter sleep. + * Set NULL to not change the configurations before entering sleep. + * The sleep configuration mainly aims at lower down the charging and measuring times, + * so that to save power consumption during the sleep. + * Only effective when the `touch_sleep_config_t::slp_wakeup_lvl` is `TOUCH_DEEP_SLEEP_WAKEUP` + */ +} touch_sleep_config_t; + +/** + * @brief Configure the touch sensor waterproof function + * + */ +typedef struct { + touch_channel_handle_t guard_chan; /*!< The guard channel of that used for immersion detect. Set NULL if you don't need the guard channel. + * Typically, the guard channel is a ring that surrounds the touch panels, + * it is used to detect the large area that covered by water. + * While large area of water covers the touch panel, the guard channel will be activated. + */ + touch_channel_handle_t shield_chan; /*!< The shield channel that used for water droplets shield, can't be NULL. + * Typically, the shield channel uses grid layout which covers the touch area, + * it is used to shield the influence of water droplets covering both the touch panel and the shield channel. + * The shield channel will be paralleled to the current measuring channel (except the guard channel) to reduce the influence of water droplets. + */ + uint32_t shield_drv; /*!< The shield channel driver, which controls the drive capability of shield channel, range: 0 ~ 7 + * The larger the parasitic capacitance on the shielding channel, the higher the drive capability needs to be set. + */ + struct { + uint32_t immersion_proof: 1; /*!< Enable to protect the touch sensor pad when immersion detected. + * It will temporary disable the touch scanning if the guard channel triggered, and enable again if guard channel released. + * So that to avoid the fake touch when the touch panel is immersed in water. + */ + } flags; /*!< Flags of the water proof function */ +} touch_waterproof_config_t; + +/** + * @brief Configure the touch sensor proximity function + * + */ +typedef struct { + touch_channel_handle_t proximity_chan[TOUCH_PROXIMITY_CHAN_NUM]; /*!< The touch channel handles that will be configured as proximity sensing channels */ + uint32_t scan_times; /*!< The total scan times of EACH sample configuration, all sample configurations share a same `scan_times`. + * The measurement result of each scanning will be accumulated together to get the final result. + */ + uint32_t charge_times[TOUCH_SAMPLE_CFG_NUM]; /*!< The charge times of EACH scanning, different sample configurations can set different `charge_times`. + * The measurement result of each scanning is positive correlation to the `charge_times`, + * please set a proper value in case of the final accumulated result overflow. + */ +} touch_proximity_config_t; + +/** + * @brief Base event structure used in touch event queue + */ +typedef struct { + touch_channel_handle_t chan; /*!< the current triggered touch channel handle */ + int chan_id; /*!< the current triggered touch channel number */ + uint32_t status_mask; /*!< the current channel triggered status. + * For the bits in the status mask, + * if the bit is set, the corresponding channel is active + * if the bit is cleared, the corresponding channel is inactive + */ +} touch_base_event_data_t; + +/** + * @brief Measure done event data + * @note Currently same as base event data + * + */ +typedef touch_base_event_data_t touch_meas_done_event_data_t; + +/** + * @brief Scan done event data + * @note Currently same as base event data + * + */ +typedef touch_base_event_data_t touch_scan_done_event_data_t; + +/** + * @brief Active event data + * @note Currently same as base event data + * + */ +typedef touch_base_event_data_t touch_active_event_data_t; + +/** + * @brief Inactive event data + * @note Currently same as base event data + * + */ +typedef touch_base_event_data_t touch_inactive_event_data_t; + +/** + * @brief Proximity sensing measure done event data + * @note Currently same as base event data + * + */ +typedef touch_base_event_data_t touch_prox_done_event_data_t; + +/** + * @brief Timeout event data + * @note Currently same as base event data + * + */ +typedef touch_base_event_data_t touch_timeout_event_data_t; + +/** + * @brief Touch sensor callbacks + * @note Set NULL for the used callbacks. + * + */ +typedef struct { + /** + * @brief Touch sensor on active event callback. + * Callback when any touch channel is activated. + * @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()` + * @param[in] event Touch sensor active event data + * @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()` + * + * @return Whether a high priority task has been waken up by this callback function + */ + bool (*on_active)(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx); + /** + * @brief Touch sensor on inactive event callback. + * Callback when any touch channel is inactivated. + * @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()` + * @param[in] event Touch sensor inactive event data + * @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()` + * + * @return Whether a high priority task has been waken up by this callback function + */ + bool (*on_inactive)(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx); + /** + * @brief Touch sensor on measure done event callback. + * Callback when the measurement of all the sample configurations on the current touch channel is done. + * @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()` + * @param[in] event Touch sensor measure done event data + * @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()` + * + * @return Whether a high priority task has been waken up by this callback function + */ + bool (*on_measure_done)(touch_sensor_handle_t sens_handle, const touch_meas_done_event_data_t *event, void *user_ctx); + /** + * @brief Touch sensor on scan done event callback. + * Callback when finished scanning all the registered touch channels. + * @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()` + * @param[in] event Touch sensor scan done event data + * @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()` + * + * @return Whether a high priority task has been waken up by this callback function + */ + bool (*on_scan_done)(touch_sensor_handle_t sens_handle, const touch_scan_done_event_data_t *event, void *user_ctx); + /** + * @brief Touch sensor on measurement timeout event callback. + * Callback when measure the current touch channel timeout. + * @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()` + * @param[in] event Touch sensor timeout event data + * @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()` + * + * @return Whether a high priority task has been waken up by this callback function + */ + bool (*on_timeout)(touch_sensor_handle_t sens_handle, const touch_timeout_event_data_t *event, void *user_ctx); + /** + * @brief Touch sensor on proximity sensing measurement done event callback. + * Callback when proximity sensing measurement of the current channel is done. + * @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()` + * @param[in] event Touch sensor proximity sensing measure done event data + * @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()` + * + * @return Whether a high priority task has been waken up by this callback function + */ + bool (*on_proximity_meas_done)(touch_sensor_handle_t sens_handle, const touch_prox_done_event_data_t *event, void *user_ctx); +} touch_event_callbacks_t; + +/** + * @brief Touch sensor benchmark configurations, to set or reset the benchmark of the channel + * + */ +typedef struct { + bool do_reset; /*!< Whether to reset the benchmark to the channel's latest smooth data */ +} touch_chan_benchmark_config_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_touch_sens/hw_ver3/touch_version_specific.c b/components/esp_driver_touch_sens/hw_ver3/touch_version_specific.c new file mode 100644 index 000000000000..ebf9acecdd6a --- /dev/null +++ b/components/esp_driver_touch_sens/hw_ver3/touch_version_specific.c @@ -0,0 +1,473 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief This file is only applicable to the touch hardware version3 + * Version 3 includes ESP32-P4 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "soc/soc_caps.h" +#include "soc/clk_tree_defs.h" +#include "soc/touch_sensor_periph.h" +#include "soc/rtc.h" +#include "hal/hal_utils.h" +#include "driver/touch_sens.h" +#include "esp_private/rtc_ctrl.h" +#include "esp_private/periph_ctrl.h" +#include "esp_clk_tree.h" +#include "esp_sleep.h" +#include "../../common/touch_sens_private.h" +#if CONFIG_TOUCH_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif +#include "esp_check.h" + +static const char *TAG = "touch"; + +portMUX_TYPE g_touch_spinlock = portMUX_INITIALIZER_UNLOCKED; + +/****************************************************************************** + * Scope: touch driver private * + ******************************************************************************/ + +void touch_priv_enable_module(bool enable) +{ + TOUCH_ENTER_CRITICAL(TOUCH_RTC_LOCK); + touch_ll_enable_module_clock(enable); + touch_ll_enable_out_gate(enable); +#if SOC_TOUCH_SENSOR_VERSION >= 2 + // Reset the benchmark after finished the scanning + touch_ll_reset_chan_benchmark(TOUCH_LL_FULL_CHANNEL_MASK); +#endif + TOUCH_EXIT_CRITICAL(TOUCH_RTC_LOCK); +} + +void IRAM_ATTR touch_priv_default_intr_handler(void *arg) +{ + /* If the touch controller object has not been allocated, return directly */ + if (!g_touch) { + return; + } + bool need_yield = false; + uint32_t status = touch_ll_get_intr_status_mask(); + g_touch->is_meas_timeout = false; + touch_ll_intr_clear(status); + touch_base_event_data_t data; + touch_ll_get_active_channel_mask(&data.status_mask); + data.chan = g_touch->ch[touch_ll_get_current_meas_channel()]; + /* If the channel is not registered, return directly */ + if (!data.chan) { + return; + } + data.chan_id = data.chan->id; + + if (status & TOUCH_LL_INTR_MASK_DONE) { + if (g_touch->cbs.on_measure_done) { + need_yield |= g_touch->cbs.on_measure_done(g_touch, &data, g_touch->user_ctx); + } + } + if (status & TOUCH_LL_INTR_MASK_SCAN_DONE) { + if (g_touch->cbs.on_scan_done) { + need_yield |= g_touch->cbs.on_scan_done(g_touch, &data, g_touch->user_ctx); + } + } + if (status & TOUCH_LL_INTR_MASK_PROX_DONE) { + data.chan->prox_cnt++; + /* The proximity sensing result only accurate when the scanning times equal to the sample_cfg_num */ + if (data.chan->prox_cnt == g_touch->sample_cfg_num) { + data.chan->prox_cnt = 0; + for (uint32_t i = 0; i < g_touch->sample_cfg_num; i++) { + touch_ll_read_chan_data(data.chan_id, i, TOUCH_LL_READ_BENCHMARK, &data.chan->prox_val[i]); + } + if (g_touch->cbs.on_proximity_meas_done) { + need_yield |= g_touch->cbs.on_proximity_meas_done(g_touch, &data, g_touch->user_ctx); + } + } + } + if (status & TOUCH_LL_INTR_MASK_ACTIVE) { + /* When the guard ring activated, disable the scanning of other channels to avoid fake touch */ + TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + if (g_touch->immersion_proof && data.chan == g_touch->guard_chan) { + touch_ll_enable_scan_mask(~BIT(data.chan->id), false); + } + TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + if (g_touch->cbs.on_active) { + need_yield |= g_touch->cbs.on_active(g_touch, &data, g_touch->user_ctx); + } + } + if (status & TOUCH_LL_INTR_MASK_INACTIVE) { + /* When the guard ring inactivated, enable the scanning of other channels again */ + TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + if (g_touch->immersion_proof && data.chan == g_touch->guard_chan) { + touch_ll_enable_scan_mask(g_touch->chan_mask & (~BIT(g_touch->shield_chan->id)), true); + } + TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + if (g_touch->cbs.on_inactive) { + need_yield |= g_touch->cbs.on_inactive(g_touch, &data, g_touch->user_ctx); + } + } + if (status & TOUCH_LL_INTR_MASK_TIMEOUT) { + g_touch->is_meas_timeout = true; + touch_ll_force_done_curr_measurement(); + if (g_touch->cbs.on_timeout) { + need_yield |= g_touch->cbs.on_timeout(g_touch, &data, g_touch->user_ctx); + } + } + + if (need_yield) { + portYIELD_FROM_ISR(); + } +} + +static esp_err_t s_touch_convert_to_hal_config(touch_sensor_handle_t sens_handle, const touch_sensor_config_t *sens_cfg, touch_hal_config_t *hal_cfg) +{ + TOUCH_NULL_POINTER_CHECK(sens_cfg); + TOUCH_NULL_POINTER_CHECK(hal_cfg); + TOUCH_NULL_POINTER_CHECK(hal_cfg->sample_cfg); + ESP_RETURN_ON_FALSE(sens_cfg->sample_cfg_num && sens_cfg->sample_cfg, ESP_ERR_INVALID_ARG, TAG, + "at least one sample configuration required"); + ESP_RETURN_ON_FALSE(sens_cfg->sample_cfg_num <= TOUCH_SAMPLE_CFG_NUM, ESP_ERR_INVALID_ARG, TAG, + "at most %d sample configurations supported", (int)(TOUCH_SAMPLE_CFG_NUM)); + + /* Get the source clock frequency for the first time */ + if (!sens_handle->src_freq_hz) { + /* Touch sensor actually uses dynamic fast clock LP_DYN_FAST_CLK, but it will only switch to the slow clock during sleep, + * This driver only designed for wakeup case (sleep case should use ULP driver), so we only need to consider RTC_FAST here */ + ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_RTC_FAST, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sens_handle->src_freq_hz), + TAG, "get clock frequency failed"); + ESP_LOGD(TAG, "touch rtc clock source: RTC_FAST, frequency: %"PRIu32" Hz", sens_handle->src_freq_hz); + } + + uint32_t src_freq_hz = sens_handle->src_freq_hz; + uint32_t src_freq_mhz = src_freq_hz / 1000000; + hal_cfg->power_on_wait_ticks = (uint32_t)sens_cfg->power_on_wait_us * src_freq_mhz; + hal_cfg->meas_interval_ticks = (uint32_t)(sens_cfg->meas_interval_us * src_freq_mhz); + hal_cfg->timeout_ticks = (uint32_t)sens_cfg->max_meas_time_us * src_freq_mhz; + ESP_RETURN_ON_FALSE(hal_cfg->timeout_ticks <= TOUCH_LL_TIMEOUT_MAX, ESP_ERR_INVALID_ARG, TAG, + "max_meas_time_ms should within %"PRIu32, TOUCH_LL_TIMEOUT_MAX / src_freq_mhz); + hal_cfg->sample_cfg_num = sens_cfg->sample_cfg_num; + hal_cfg->output_mode = sens_cfg->output_mode; + + for (uint32_t smp_cfg_id = 0; smp_cfg_id < sens_cfg->sample_cfg_num; smp_cfg_id++) { + const touch_sensor_sample_config_t *sample_cfg = &(sens_cfg->sample_cfg[smp_cfg_id]); + ESP_RETURN_ON_FALSE(sample_cfg->div_num > 0, ESP_ERR_INVALID_ARG, TAG, + "div_num can't be 0"); + /* Assign the hal configurations */ + hal_cfg->sample_cfg[smp_cfg_id].div_num = sample_cfg->div_num; + hal_cfg->sample_cfg[smp_cfg_id].charge_times = sample_cfg->charge_times; + hal_cfg->sample_cfg[smp_cfg_id].rc_filter_res = sample_cfg->rc_filter_res; + hal_cfg->sample_cfg[smp_cfg_id].rc_filter_cap = sample_cfg->rc_filter_cap; + hal_cfg->sample_cfg[smp_cfg_id].low_drv = sample_cfg->low_drv; + hal_cfg->sample_cfg[smp_cfg_id].high_drv = sample_cfg->high_drv; + hal_cfg->sample_cfg[smp_cfg_id].bias_volt = sample_cfg->bias_volt; + } + return ESP_OK; +} + +esp_err_t touch_priv_config_controller(touch_sensor_handle_t sens_handle, const touch_sensor_config_t *sens_cfg) +{ +#if CONFIG_TOUCH_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif + /* Check and convert the configuration to hal configurations */ + touch_hal_sample_config_t sample_cfg[TOUCH_SAMPLE_CFG_NUM] = {}; + touch_hal_config_t hal_cfg = { + .sample_cfg = sample_cfg, + }; + ESP_RETURN_ON_ERROR(s_touch_convert_to_hal_config(sens_handle, sens_cfg, &hal_cfg), + TAG, "parse the configuration failed due to the invalid configuration"); + sens_handle->sample_cfg_num = sens_cfg->sample_cfg_num; + + /* Configure the hardware */ + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + touch_hal_config_controller(&hal_cfg); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + + return ESP_OK; +} + +esp_err_t touch_priv_config_channel(touch_channel_handle_t chan_handle, const touch_channel_config_t *chan_cfg) +{ + uint8_t sample_cfg_num = chan_handle->base->sample_cfg_num; + // Check the validation of the channel active threshold + for (uint8_t smp_cfg_id = 0; smp_cfg_id < sample_cfg_num; smp_cfg_id++) { + ESP_RETURN_ON_FALSE(chan_cfg->active_thresh[smp_cfg_id] <= TOUCH_LL_ACTIVE_THRESH_MAX, ESP_ERR_INVALID_ARG, + TAG, "the active threshold out of range 0~%d", TOUCH_LL_ACTIVE_THRESH_MAX); + } + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + for (uint8_t smp_cfg_id = 0; smp_cfg_id < sample_cfg_num; smp_cfg_id++) { + touch_ll_set_chan_active_threshold(chan_handle->id, smp_cfg_id, chan_cfg->active_thresh[smp_cfg_id]); + } + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + return ESP_OK; +} + +esp_err_t touch_priv_deinit_controller(touch_sensor_handle_t sens_handle) +{ + /* Disable the additional functions */ + if (sens_handle->proximity_en) { + touch_sensor_config_proximity_sensing(sens_handle, NULL); + } + if (sens_handle->sleep_en) { + touch_sensor_config_sleep_wakeup(sens_handle, NULL); + } + if (sens_handle->waterproof_en) { + touch_sensor_config_waterproof(sens_handle, NULL); + } + return ESP_OK; +} + +esp_err_t touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch_chan_data_type_t type, uint32_t *data) +{ + ESP_RETURN_ON_FALSE_ISR(type >= TOUCH_CHAN_DATA_TYPE_SMOOTH && type <= TOUCH_CHAN_DATA_TYPE_PROXIMITY, + ESP_ERR_INVALID_ARG, TAG, "The channel data type is invalid"); +#if CONFIG_TOUCH_CTRL_FUNC_IN_IRAM + ESP_RETURN_ON_FALSE_ISR(esp_ptr_internal(data), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); +#endif + uint8_t sample_cfg_num = chan_handle->base->sample_cfg_num; + if (type < TOUCH_CHAN_DATA_TYPE_PROXIMITY) { + uint32_t internal_type = 0; + switch (type) { + default: // fall through + case TOUCH_CHAN_DATA_TYPE_SMOOTH: + internal_type = TOUCH_LL_READ_SMOOTH; + break; + case TOUCH_CHAN_DATA_TYPE_BENCHMARK: + internal_type = TOUCH_LL_READ_BENCHMARK; + break; + } + if (type <= TOUCH_CHAN_DATA_TYPE_BENCHMARK) { + TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + for (int i = 0; i < sample_cfg_num; i++) { + touch_ll_read_chan_data(chan_handle->id, i, internal_type, &data[i]); + } + TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + } + } else { + if (!chan_handle->is_prox_chan) { + ESP_EARLY_LOGW(TAG, "This is not a proximity sensing channel"); + } + TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + /* Get the proximity value from the stored data. + * The proximity value are updated in the isr when proximity scanning is done */ + for (int i = 0; i < sample_cfg_num; i++) { + data[i] = chan_handle->prox_val[i]; + } + TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK); + } + return ESP_OK; +} + +void touch_priv_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg) +{ + if (benchmark_cfg->do_reset) { + touch_ll_reset_chan_benchmark(BIT(chan_handle->id)); + } +} + +/****************************************************************************** + * Scope: public APIs * + ******************************************************************************/ + +esp_err_t touch_sensor_config_filter(touch_sensor_handle_t sens_handle, const touch_sensor_filter_config_t *filter_cfg) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + if (filter_cfg) { + ESP_RETURN_ON_FALSE(filter_cfg->benchmark.denoise_lvl >= 0 && filter_cfg->benchmark.denoise_lvl <= 4, + ESP_ERR_INVALID_ARG, TAG, "denoise_lvl is out of range"); + } + + esp_err_t ret = ESP_OK; + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + + if (filter_cfg) { + touch_ll_filter_enable(true); + /* Configure the benchmark filter and update strategy */ + touch_ll_filter_set_filter_mode(filter_cfg->benchmark.filter_mode); + if (filter_cfg->benchmark.filter_mode == TOUCH_BM_JITTER_FILTER) { + touch_ll_filter_set_jitter_step(filter_cfg->benchmark.jitter_step); + } + touch_ll_filter_set_denoise_level(filter_cfg->benchmark.denoise_lvl); + /* Configure the touch data filter */ + touch_ll_filter_set_smooth_mode(filter_cfg->data.smooth_filter); + touch_ll_filter_set_active_hysteresis(filter_cfg->data.active_hysteresis); + touch_ll_filter_set_debounce(filter_cfg->data.debounce_cnt); + } else { + touch_ll_filter_enable(false); + } + + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + xSemaphoreGive(sens_handle->mutex); + return ret; +} + +esp_err_t touch_sensor_config_sleep_wakeup(touch_sensor_handle_t sens_handle, const touch_sleep_config_t *sleep_cfg) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + + esp_err_t ret = ESP_OK; + int dp_slp_chan_id = -1; + touch_hal_sample_config_t sample_cfg[TOUCH_SAMPLE_CFG_NUM] = {}; + touch_hal_config_t hal_cfg = { + .sample_cfg = sample_cfg, + }; + touch_hal_config_t *hal_cfg_ptr = NULL; + + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first"); + + if (sleep_cfg) { + ESP_GOTO_ON_FALSE(sleep_cfg->slp_wakeup_lvl == TOUCH_LIGHT_SLEEP_WAKEUP || sleep_cfg->slp_wakeup_lvl == TOUCH_DEEP_SLEEP_WAKEUP, + ESP_ERR_INVALID_ARG, err, TAG, "Invalid sleep level"); + /* Enabled touch sensor as wake-up source */ + ESP_GOTO_ON_ERROR(esp_sleep_enable_touchpad_wakeup(), err, TAG, "Failed to enable touch sensor wakeup"); +#if SOC_PM_SUPPORT_RC_FAST_PD + ESP_GOTO_ON_ERROR(esp_sleep_pd_config(ESP_PD_DOMAIN_RC_FAST, ESP_PD_OPTION_ON), err, TAG, "Failed to keep touch sensor module clock during the sleep"); +#endif + + /* If set the deep sleep channel (i.e., enable deep sleep wake-up), + configure the deep sleep related settings. */ + if (sleep_cfg->slp_wakeup_lvl == TOUCH_DEEP_SLEEP_WAKEUP) { + ESP_GOTO_ON_FALSE(sleep_cfg->deep_slp_chan, ESP_ERR_INVALID_ARG, err, TAG, "deep sleep waken channel can't be NULL"); + dp_slp_chan_id = sleep_cfg->deep_slp_chan->id; + + /* Check and convert the configuration to hal configurations */ + if (sleep_cfg->deep_slp_sens_cfg) { + hal_cfg_ptr = &hal_cfg; + ESP_GOTO_ON_ERROR(s_touch_convert_to_hal_config(sens_handle, (const touch_sensor_config_t *)sleep_cfg->deep_slp_sens_cfg, hal_cfg_ptr), + err, TAG, "parse the configuration failed due to the invalid configuration"); + } + sens_handle->sleep_en = true; + sens_handle->deep_slp_chan = sleep_cfg->deep_slp_chan; + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + /* Set sleep threshold */ + for (uint8_t smp_cfg_id = 0; smp_cfg_id < TOUCH_SAMPLE_CFG_NUM; smp_cfg_id++) { + touch_ll_sleep_set_threshold(smp_cfg_id, sleep_cfg->deep_slp_thresh[smp_cfg_id]); + } + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + } + + } else { + /* Disable the touch sensor as wake-up source */ + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TOUCHPAD); +#if SOC_PM_SUPPORT_RC_FAST_PD + esp_sleep_pd_config(ESP_PD_DOMAIN_RC_FAST, ESP_PD_OPTION_AUTO); +#endif + + sens_handle->sleep_en = false; + } + + /* Save or update the sleep config */ + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + touch_hal_save_sleep_config(dp_slp_chan_id, hal_cfg_ptr); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + +err: + xSemaphoreGive(sens_handle->mutex); + return ret; +} + +// Water proof can be enabled separately +esp_err_t touch_sensor_config_waterproof(touch_sensor_handle_t sens_handle, const touch_waterproof_config_t *wp_cfg) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + + esp_err_t ret = ESP_OK; + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first"); + + if (wp_cfg) { + // Check the validation of the waterproof configuration + TOUCH_NULL_POINTER_CHECK(wp_cfg->shield_chan); + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + sens_handle->waterproof_en = true; + sens_handle->immersion_proof = wp_cfg->flags.immersion_proof; + sens_handle->guard_chan = wp_cfg->guard_chan; + sens_handle->shield_chan = wp_cfg->shield_chan; + touch_ll_waterproof_set_guard_chan(wp_cfg->guard_chan ? wp_cfg->guard_chan->id : TOUCH_LL_NULL_CHANNEL); + touch_ll_waterproof_set_shield_chan_mask(BIT(wp_cfg->shield_chan->id)); + // need to disable the scanning of the shield channel + touch_ll_enable_scan_mask(BIT(wp_cfg->shield_chan->id), false); + touch_ll_waterproof_set_shield_driver(wp_cfg->shield_drv); + touch_ll_waterproof_enable(true); + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + } else { + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + touch_ll_waterproof_enable(false); + touch_ll_waterproof_set_guard_chan(TOUCH_LL_NULL_CHANNEL); + touch_ll_waterproof_set_shield_chan_mask(0); + if (sens_handle->shield_chan) { + touch_ll_enable_scan_mask(BIT(sens_handle->shield_chan->id), true); + } + touch_ll_waterproof_set_shield_driver(0); + sens_handle->guard_chan = NULL; + sens_handle->shield_chan = NULL; + sens_handle->immersion_proof = false; + sens_handle->waterproof_en = false; + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + } +err: + xSemaphoreGive(sens_handle->mutex); + return ret; +} + +esp_err_t touch_sensor_config_proximity_sensing(touch_sensor_handle_t sens_handle, const touch_proximity_config_t *prox_cfg) +{ + TOUCH_NULL_POINTER_CHECK(sens_handle); + + esp_err_t ret = ESP_OK; + xSemaphoreTake(sens_handle->mutex, portMAX_DELAY); + + ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first"); + + TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK); + + /* Reset proximity sensing part of all channels */ + FOR_EACH_TOUCH_CHANNEL(i) { + if (sens_handle->ch[i] && sens_handle->ch[i]->is_prox_chan) { + sens_handle->ch[i]->is_prox_chan = false; + sens_handle->ch[i]->prox_cnt = 0; + for (int i = 0; i < TOUCH_SAMPLE_CFG_NUM; i++) { + sens_handle->ch[i]->prox_val[i] = 0; + } + } + } + + if (prox_cfg) { + sens_handle->proximity_en = true; + uint8_t sample_cfg_num = sens_handle->sample_cfg_num; + for (int i = 0; i < TOUCH_PROXIMITY_CHAN_NUM; i++) { + if (prox_cfg->proximity_chan[i]) { + prox_cfg->proximity_chan[i]->is_prox_chan = true; + touch_ll_set_proximity_sensing_channel(i, prox_cfg->proximity_chan[i]->id); + } else { + touch_ll_set_proximity_sensing_channel(i, TOUCH_LL_NULL_CHANNEL); + } + } + touch_ll_proximity_set_total_scan_times(prox_cfg->scan_times * sample_cfg_num); + for (uint8_t smp_cfg_id = 0; smp_cfg_id < sample_cfg_num; smp_cfg_id++) { + touch_ll_proximity_set_charge_times(smp_cfg_id, prox_cfg->charge_times[smp_cfg_id]); + } + } else { + for (int i = 0; i < TOUCH_PROXIMITY_CHAN_NUM; i++) { + touch_ll_set_proximity_sensing_channel(i, TOUCH_LL_NULL_CHANNEL); + } + sens_handle->proximity_en = false; + } + TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK); + +err: + xSemaphoreGive(sens_handle->mutex); + return ret; +} diff --git a/components/esp_driver_touch_sens/include/driver/touch_sens.h b/components/esp_driver_touch_sens/include/driver/touch_sens.h new file mode 100644 index 000000000000..cba510baef9c --- /dev/null +++ b/components/esp_driver_touch_sens/include/driver/touch_sens.h @@ -0,0 +1,294 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" +#include "driver/touch_sens_types.h" +#include "driver/touch_version_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Allocate a new touch sensor controller + * @note The touch sensor driver will be in INIT state after this function is called successfully. + * + * @param[in] sens_cfg Touch sensor controller configurations + * @param[out] ret_sens_handle The return handle of the touch controller instance + * @return + * - ESP_OK On success + * - ESP_ERR_NO_MEM No memory for the touch sensor controller + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE The touch sensor controller is already allocated + */ +esp_err_t touch_sensor_new_controller(const touch_sensor_config_t *sens_cfg, touch_sensor_handle_t *ret_sens_handle); + +/** + * @brief Delete the touch sensor controller + * @note This function can be called when the touch sensor controller is NOT enabled (i.e. INIT state). + * + * @param[in] sens_handle Touch sensor controller handle + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE Controller not disabled or still some touch channels not deleted + */ +esp_err_t touch_sensor_del_controller(touch_sensor_handle_t sens_handle); + +/** + * @brief Allocate a new touch channel from the touch sensor controller + * @note This function can be called when the touch sensor controller is NOT enabled (i.e. INIT state). + * + * @param[in] sens_handle Touch sensor controller handle + * @param[in] chan_id Touch channel index + * @param[in] chan_cfg Touch channel configurations + * @param[out] ret_chan_handle The return handle of the touch channel instance + * @return + * - ESP_OK On success + * - ESP_ERR_NO_MEM No memory for the touch sensor channel + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE The touch sensor controller has not disabled or this channel has been allocated + */ +esp_err_t touch_sensor_new_channel(touch_sensor_handle_t sens_handle, int chan_id, + const touch_channel_config_t *chan_cfg, + touch_channel_handle_t *ret_chan_handle); + +/** + * @brief Delete the touch channel + * @note This function can be called when the touch sensor controller is NOT enabled (i.e. INIT state). + * + * @param[in] chan_handle Touch channel handle + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE The touch sensor controller has not disabled + */ +esp_err_t touch_sensor_del_channel(touch_channel_handle_t chan_handle); + +/** + * @brief Re-configure the touch sensor controller + * @note This function can be called when the touch sensor controller is NOT enabled (i.e. INIT state). + * @note The re-configuration only applies to the touch controller, + * so it requires the controller handle that allocated from ``touch_sensor_new_controller``, + * meanwhile, it won't affect the touch channels, no matter the channels are allocated or not. + * + * @param[in] sens_handle Touch sensor controller handle + * @param[in] sens_cfg Touch sensor controller configurations + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE The touch sensor controller has not disabled + */ +esp_err_t touch_sensor_reconfig_controller(touch_sensor_handle_t sens_handle, const touch_sensor_config_t *sens_cfg); + +/** + * @brief Re-configure the touch channel + * @note This function can be called when the touch sensor controller is NOT enabled (i.e. INIT state). + * @note The re-configuration only applies to a particular touch channel, + * so it requires the channel handle that allocated from ``touch_sensor_new_channel`` + * + * @param[in] chan_handle Touch channel handle + * @param[in] chan_cfg Touch channel configurations + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE The touch sensor controller has not disabled + */ +esp_err_t touch_sensor_reconfig_channel(touch_channel_handle_t chan_handle, const touch_channel_config_t *chan_cfg); + +/** + * @brief Configure the touch sensor filter + * @note This function is allowed to be called after the touch sensor is enabled + * + * @param[in] sens_handle Touch sensor controller handle + * @param[in] filter_cfg Filter configurations, set NULL to disable the filter + * @return + * - ESP_OK: Configure the filter success + * - ESP_ERR_INVALID_ARG: The sensor handle is NULL + */ +esp_err_t touch_sensor_config_filter(touch_sensor_handle_t sens_handle, const touch_sensor_filter_config_t *filter_cfg); + +/** + * @brief Enable the touch sensor controller + * @note This function can be called when the touch sensor controller is NOT enabled (i.e. INIT state). + * And the touch sensor driver will be in ENABLED state after this function is called successfully. + * @note Enable the touch sensor will power on the registered touch channels + * + * @param[in] sens_handle Touch sensor controller handle + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE The touch sensor controller has already enabled + */ +esp_err_t touch_sensor_enable(touch_sensor_handle_t sens_handle); + +/** + * @brief Disable the touch sensor controller + * @note This function can only be called after the touch sensor controller is enabled (i.e. ENABLED state). + * And the touch sensor driver will be in INIT state after this function is called successfully. + * @note Disable the touch sensor will power off the registered touch channels + * + * @param[in] sens_handle Touch sensor controller handle + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE The touch sensor controller has already disabled + */ +esp_err_t touch_sensor_disable(touch_sensor_handle_t sens_handle); + +/** + * @brief Start the scanning of the registered touch channels continuously + * @note This function can only be called after the touch sensor controller is enabled (i.e. ENABLED state). + * And the touch sensor driver will be in SCANNING state after this function is called successfully. + * And it can also be called in ISR/callback context. + * @note The hardware FSM (Finite-State Machine) of touch sensor will be driven by + * its hardware timer continuously and repeatedly. + * i.e., the registered channels will be scanned one by one repeatedly. + * + * @param[in] sens_handle Touch sensor controller handle + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE The touch sensor controller is not enabled or the continuous scanning has started + */ +esp_err_t touch_sensor_start_continuous_scanning(touch_sensor_handle_t sens_handle); + +/** + * @brief Stop the continuous scanning of the registered touch channels immediately + * @note This function can only be called after the continuous scanning started (i.e. SCANNING state). + * And the touch sensor driver will be in ENABLED state after this function is called successfully. + * And it can also be called in ISR/callback context. + * @note Stop the hardware timer and reset the FSM (Finite-State Machine) of the touch sensor controller + * + * @param[in] sens_handle Touch sensor controller handle + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + * - ESP_ERR_INVALID_STATE The continuous scanning has stopped + */ +esp_err_t touch_sensor_stop_continuous_scanning(touch_sensor_handle_t sens_handle); + +/** + * @brief Trigger an oneshot scanning for all the registered channels + * @note This function can only be called after the touch sensor controller is enabled (i.e. ENABLED state). + * And the touch sensor driver will be in SCANNING state after this function is called successfully, + * and then switch back to ENABLED state after the scanning is done or timeout. + * @note The block time of this function depends on various factors, + * In common practice, recommend to set the timeout to several seconds or wait forever, + * because oneshot scanning can't last for so long. + * + * @param[in] sens_handle Touch sensor controller handle + * @param[in] timeout_ms Set a positive value or zero means scan timeout in milliseconds + * Set a negative value means wait forever until finished scanning + * @return + * - ESP_OK On success + * - ESP_ERR_TIMEOUT Timeout to finish the oneshot scanning + * - ESP_ERR_INVALID_ARG Invalid argument + * - ESP_ERR_INVALID_STATE The touch sensor controller is not enabled or the continuous scanning has started + */ +esp_err_t touch_sensor_trigger_oneshot_scanning(touch_sensor_handle_t sens_handle, int timeout_ms); + +/** + * @brief Register the touch sensor callbacks + * @note This function can be called when the touch sensor controller is NOT enabled (i.e. INIT state). + * + * @param[in] sens_handle Touch sensor controller handle + * @param[in] callbacks Callback functions + * @param[in] user_ctx User context that will be passed to the callback functions + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG NULL pointer + * - ESP_ERR_INVALID_STATE Touch sensor controller has not disabled + */ +esp_err_t touch_sensor_register_callbacks(touch_sensor_handle_t sens_handle, const touch_event_callbacks_t *callbacks, void *user_ctx); + +/** + * @brief Confiture the touch sensor benchmark for all the registered channels + * @note This function can be called no matter the touch sensor controller is enabled or not (i.e. ENABLED or SCANNING state). + * And it can also be called in ISR/callback context. + * + * @param[in] chan_handle Touch channel handle + * @param[in] benchmark_cfg The benchmark configurations + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG NULL pointer + */ +esp_err_t touch_channel_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg); + +/** + * @brief Read the touch channel data according to the types + * @note This function can be called no matter the touch sensor controller is enabled or not (i.e. ENABLED or SCANNING state). + * And it can also be called in ISR/callback context. + * @note Specially, `TOUCH_CHAN_DATA_TYPE_PROXIMITY` data type will be read from the cached data in the driver, + * because the proximity data need to be accumulated in several scan times that specified by `touch_proximity_config_t::scan_times`. + * For other data types, the data are read from the hardware registers directly (not cached in the driver). + * The channel data in the register will be updated once the measurement of this channels is done, + * And keep locked until the next measurement is done. + * + * @param[in] chan_handle Touch channel handle + * @param[in] type Specify the data type to read + * @param[out] data The data array pointer. If the target supports multiple sample configurations (SOC_TOUCH_SAMPLE_CFG_NUM), the array length should be equal to + * the frequency hopping number that specified in `touch_sensor_config_t::sample_cfg_num`, otherwise the array length should be 1. + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument or NULL pointer + */ +esp_err_t touch_channel_read_data(touch_channel_handle_t chan_handle, touch_chan_data_type_t type, uint32_t *data); + +#if SOC_TOUCH_SUPPORT_WATERPROOF +/** + * @brief Configure the touch sensor water proof channels + * @note Once waterproof is enabled, the other touch channels won't be updated unless the shield channels is activated. + * + * @param[in] sens_handle Touch sensor controller handle + * @param[in] wp_cfg Water proof channel configurations, set NULL to disable the water proof function + * @return + * - ESP_OK: Configure the water proof success + * - ESP_ERR_INVALID_ARG: The sensor handle is NULL + * - ESP_ERR_INVALID_STATE: The touch sensor is enabled + */ +esp_err_t touch_sensor_config_waterproof(touch_sensor_handle_t sens_handle, const touch_waterproof_config_t *wp_cfg); +#endif + +#if SOC_TOUCH_SUPPORT_PROX_SENSING +/** + * @brief Configure the touch sensor proximity sensing channels + * + * @param[in] sens_handle Touch sensor controller handle + * @param[in] prox_cfg Proximity channels configurations, set NULL to disable the proximity sensing + * @return + * - ESP_OK: Configure the proximity channel success + * - ESP_ERR_INVALID_ARG: The sensor handle is NULL + * - ESP_ERR_INVALID_STATE: The touch sensor is enabled + */ +esp_err_t touch_sensor_config_proximity_sensing(touch_sensor_handle_t sens_handle, const touch_proximity_config_t *prox_cfg); +#endif + +#if SOC_TOUCH_SUPPORT_SLEEP_WAKEUP +/** + * @brief Configure the touch sensor to wake-up the chip from sleep + * @note Call this function to enable/disable the touch sensor wake-up the chip from deep/light sleep + * To only enable the touch sensor wake-up the chip from light sleep, set the `touch_sleep_config_t::deep_slp_chan` to NULL. + * During the light sleep, all enabled touch channels will keep working, and any one of them can wake-up the chip from light sleep. + * To enable the touch sensor wake-up the chip from both light and deep sleep, set the `touch_sleep_config_t::deep_slp_chan` to an enabled channel. + * During the deep sleep, only this specified channels can work and wake-up the chip from the deep sleep, + * and other enabled channels can only wake-up the chip from light sleep. + * + * @param[in] sens_handle Touch sensor controller handle + * @param[in] sleep_cfg Sleep wake-up configurations, set NULL to disable the touch sensor wake-up the chip from sleep + * @return + * - ESP_OK: Configure the sleep channel success + * - ESP_ERR_INVALID_ARG: The sensor handle is NULL + * - ESP_ERR_INVALID_STATE: The touch sensor is enabled + */ +esp_err_t touch_sensor_config_sleep_wakeup(touch_sensor_handle_t sens_handle, const touch_sleep_config_t *sleep_cfg); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_touch_sens/include/driver/touch_sens_types.h b/components/esp_driver_touch_sens/include/driver/touch_sens_types.h new file mode 100644 index 000000000000..3b802cc6ccd2 --- /dev/null +++ b/components/esp_driver_touch_sens/include/driver/touch_sens_types.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include "soc/soc_caps.h" +#include "hal/touch_sensor_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TOUCH_TOTAL_CHAN_NUM SOC_TOUCH_SENSOR_NUM /*!< The total channel number of the touch sensor */ +#define TOUCH_SAMPLE_CFG_NUM SOC_TOUCH_SAMPLE_CFG_NUM /*!< The supported max sample configuration number */ +#if SOC_TOUCH_SUPPORT_PROX_SENSING +#define TOUCH_PROXIMITY_CHAN_NUM SOC_TOUCH_PROXIMITY_CHANNEL_NUM /*!< The supported proximity channel number in proximity sensing mode */ +#endif + +typedef struct touch_sensor_s *touch_sensor_handle_t; /*!< The handle of touch sensor controller */ +typedef struct touch_channel_s *touch_channel_handle_t; /*!< The handle of touch channel */ + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_touch_sens/linker.lf b/components/esp_driver_touch_sens/linker.lf new file mode 100644 index 000000000000..9dbc60f17533 --- /dev/null +++ b/components/esp_driver_touch_sens/linker.lf @@ -0,0 +1,10 @@ +[mapping:touch_sens_driver] +archive: libesp_driver_touch_sens.a +entries: + if TOUCH_CTRL_FUNC_IN_IRAM = y: + touch_sens_common: touch_sensor_start_continuous_scanning (noflash) + touch_sens_common: touch_sensor_stop_continuous_scanning (noflash) + touch_sens_common: touch_channel_read_data (noflash) + touch_sens_common: touch_channel_config_benchmark (noflash) + touch_sens_version_specific: touch_priv_channel_read_data (noflash) + touch_sens_version_specific: touch_priv_config_benchmark (noflash) diff --git a/components/esp_driver_touch_sens/test_apps/.build-test-rules.yml b/components/esp_driver_touch_sens/test_apps/.build-test-rules.yml new file mode 100644 index 000000000000..ff1dc3e64cac --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/.build-test-rules.yml @@ -0,0 +1,10 @@ +components/esp_driver_touch_sens/test_apps/touch_sens: + disable: + - if: SOC_TOUCH_SENSOR_VERSION != 3 + temporary: currently driver ng only support version 3 + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: the runners do not support the pins for touch sensor + depends_components: + - esp_driver_touch_sens diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/CMakeLists.txt b/components/esp_driver_touch_sens/test_apps/touch_sens/CMakeLists.txt new file mode 100644 index 000000000000..e774828c4d60 --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/CMakeLists.txt @@ -0,0 +1,22 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +set(COMPONENTS main) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(touch_sens) + +if(CONFIG_COMPILER_DUMP_RTL_FILES) + add_custom_target(check_test_app_sections ALL + COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py + --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_touch_sens/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --elf-file ${CMAKE_BINARY_DIR}/touch_sens.elf + find-refs + --from-sections=.iram0.text + --to-sections=.flash.text,.flash.rodata + --exit-code + DEPENDS ${elf} + ) +endif() diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/README.md b/components/esp_driver_touch_sens/test_apps/touch_sens/README.md new file mode 100644 index 000000000000..f8ea707124d7 --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/README.md @@ -0,0 +1,3 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | + diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/main/CMakeLists.txt b/components/esp_driver_touch_sens/test_apps/touch_sens/main/CMakeLists.txt new file mode 100644 index 000000000000..97285a112230 --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/main/CMakeLists.txt @@ -0,0 +1,6 @@ +set(srcs "test_app_main.c" "test_touch_sens_common.c") + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS "." + PRIV_REQUIRES unity esp_driver_touch_sens + WHOLE_ARCHIVE) diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/main/test_app_main.c b/components/esp_driver_touch_sens/test_apps/touch_sens/main/test_app_main.c new file mode 100644 index 000000000000..a7498bd1eb3b --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/main/test_app_main.c @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in Touch Sensor driver, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-300) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + // _____ _ ____ _____ _ + // |_ _|__ _ _ ___| |__ / ___| ___ _ __ ___ ___ _ __ |_ _|__ ___| |_ + // | |/ _ \| | | |/ __| '_ \ \___ \ / _ \ '_ \/ __|/ _ \| '__| | |/ _ \/ __| __| + // | | (_) | |_| | (__| | | | ___) | __/ | | \__ \ (_) | | | | __/\__ \ |_ + // |_|\___/ \__,_|\___|_| |_| |____/ \___|_| |_|___/\___/|_| |_|\___||___/\__| + + printf(" _____ _ ____ _____ _ \n"); + printf(" |_ _|__ _ _ ___| |__ / ___| ___ _ __ ___ ___ _ __ |_ _|__ ___| |_ \n"); + printf(" | |/ _ \\| | | |/ __| '_ \\ \\___ \\ / _ \\ '_ \\/ __|/ _ \\| '__| | |/ _ \\/ __| __|\n"); + printf(" | | (_) | |_| | (__| | | | ___) | __/ | | \\__ \\ (_) | | | | __/\\__ \\ |_ \n"); + printf(" |_|\\___/ \\__,_|\\___|_| |_| |____/ \\___|_| |_|___/\\___/|_| |_|\\___||___/\\__|\n"); + + unity_run_menu(); +} diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/main/test_touch_sens_common.c b/components/esp_driver_touch_sens/test_apps/touch_sens/main/test_touch_sens_common.c new file mode 100644 index 000000000000..226b8549fa22 --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/main/test_touch_sens_common.c @@ -0,0 +1,198 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "unity.h" +#include "driver/touch_sens.h" +#include "hal/touch_sensor_ll.h" +#include "esp_log.h" +#include "esp_attr.h" + +static touch_sensor_sample_config_t s_sample_cfg[TOUCH_SAMPLE_CFG_NUM] = { + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(1, 1, 1), +#if TOUCH_SAMPLE_CFG_NUM > 1 + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(2, 1, 1), +#endif +#if TOUCH_SAMPLE_CFG_NUM > 2 + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(4, 1, 1), +#endif +}; + +static touch_channel_config_t s_chan_cfg = { + .active_thresh = { + 5000, +#if TOUCH_SAMPLE_CFG_NUM > 1 + 2500, +#endif +#if TOUCH_SAMPLE_CFG_NUM > 2 + 1000, +#endif + }, +}; + +TEST_CASE("touch_sens_install_uninstall_test", "[touch]") +{ + touch_sensor_handle_t touch = NULL; + touch_channel_handle_t touch_chan[TOUCH_TOTAL_CHAN_NUM] = {NULL}; + + touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(TOUCH_SAMPLE_CFG_NUM, s_sample_cfg); + /* Allocate new controller */ + TEST_ESP_OK(touch_sensor_new_controller(&sens_cfg, &touch)); + TEST_ASSERT(touch_sensor_new_controller(&sens_cfg, &touch) == ESP_ERR_INVALID_STATE); + /* Configuring the filter */ + touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG(); + TEST_ESP_OK(touch_sensor_config_filter(touch, &filter_cfg)); + + for (int i = 0; i < TOUCH_TOTAL_CHAN_NUM; i++) { + TEST_ESP_OK(touch_sensor_new_channel(touch, i, &s_chan_cfg, &touch_chan[i])); + } + touch_channel_handle_t fault_chan = NULL; + TEST_ASSERT(touch_sensor_new_channel(touch, TOUCH_TOTAL_CHAN_NUM, &s_chan_cfg, &fault_chan) == ESP_ERR_INVALID_ARG); + TEST_ASSERT(touch_sensor_new_channel(touch, 0, &s_chan_cfg, &fault_chan) == ESP_ERR_INVALID_STATE); + + TEST_ESP_OK(touch_sensor_enable(touch)); + TEST_ASSERT(touch_sensor_del_channel(touch_chan[0]) == ESP_ERR_INVALID_STATE); + TEST_ESP_OK(touch_sensor_disable(touch)); + + TEST_ASSERT(touch_sensor_del_controller(touch) == ESP_ERR_INVALID_STATE); + + for (int i = 0; i < TOUCH_TOTAL_CHAN_NUM; i++) { + TEST_ESP_OK(touch_sensor_del_channel(touch_chan[i])); + } + TEST_ESP_OK(touch_sensor_del_controller(touch)); +} + +typedef struct { + int active_count; + int inactive_count; +} test_touch_cb_data_t; + +static touch_channel_config_t s_test_get_chan_cfg_by_benchmark(uint32_t benchmark[], uint32_t num, float coeff) +{ + touch_channel_config_t chan_cfg = {}; + for (int i = 0; i < num; i++) { + chan_cfg.active_thresh[i] = benchmark[i] * coeff; + printf("[Sampler %d] benchmark %5"PRIu32" thresh %4"PRIu32"\n", + i, benchmark[i], chan_cfg.active_thresh[i]); + } + return chan_cfg; +} + +static void s_test_touch_do_initial_scanning(touch_sensor_handle_t touch, int scan_times) +{ + /* Enable the touch sensor to do the initial scanning, so that to initialize the channel data */ + TEST_ESP_OK(touch_sensor_enable(touch)); + /* Scan the enabled touch channels for several times, to make sure the initial channel data is stable */ + for (int i = 0; i < scan_times; i++) { + TEST_ESP_OK(touch_sensor_trigger_oneshot_scanning(touch, 2000)); + } + /* Disable the touch channel to rollback the state */ + TEST_ESP_OK(touch_sensor_disable(touch)); +} + +#if CONFIG_TOUCH_ISR_IRAM_SAFE +#define TEST_TCH_IRAM_ATTR IRAM_ATTR +#else +#define TEST_TCH_IRAM_ATTR +#endif + +static bool TEST_TCH_IRAM_ATTR s_test_touch_on_active_callback(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx) +{ + ESP_EARLY_LOGI("touch_callback", "[CH %d] active", (int)event->chan_id); + test_touch_cb_data_t *cb_data = (test_touch_cb_data_t *)user_ctx; + cb_data->active_count++; + return false; +} + +static bool TEST_TCH_IRAM_ATTR s_test_touch_on_inactive_callback(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx) +{ + ESP_EARLY_LOGI("touch_callback", "[CH %d] inactive", (int)event->chan_id); + test_touch_cb_data_t *cb_data = (test_touch_cb_data_t *)user_ctx; + cb_data->inactive_count++; + return false; +} + +static void s_test_touch_simulate_touch(touch_sensor_handle_t touch, touch_channel_handle_t touch_chan, bool active) +{ + touch_ll_set_internal_capacitor(active ? 0x7f : 0); +} + +static void s_test_touch_log_data(touch_channel_handle_t touch_chan, uint32_t sample_cfg_num, const char *tag) +{ + uint32_t data[sample_cfg_num]; + TEST_ESP_OK(touch_channel_read_data(touch_chan, TOUCH_CHAN_DATA_TYPE_SMOOTH, data)); + printf("%s:", tag); + for (int i = 0; i < sample_cfg_num; i++) { + printf(" %"PRIu32, data[i]); + } + printf("\n"); +} + +#define TEST_ACTIVE_THRESH_RATIO (0.01f) + +TEST_CASE("touch_sens_active_inactive_test", "[touch]") +{ + touch_sensor_handle_t touch = NULL; + touch_channel_handle_t touch_chan = NULL; + + touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(TOUCH_SAMPLE_CFG_NUM, s_sample_cfg); + TEST_ESP_OK(touch_sensor_new_controller(&sens_cfg, &touch)); + + /* Configuring the filter */ + touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG(); + TEST_ESP_OK(touch_sensor_config_filter(touch, &filter_cfg)); + TEST_ESP_OK(touch_sensor_new_channel(touch, 0, &s_chan_cfg, &touch_chan)); + /* Connect the touch channels to the internal capacitor */ + touch_ll_enable_internal_capacitor(true); + + s_test_touch_do_initial_scanning(touch, 3); + + /* Read benchmark */ + uint32_t benchmark[TOUCH_SAMPLE_CFG_NUM] = {0}; + TEST_ESP_OK(touch_channel_read_data(touch_chan, TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark)); + /* Re-configure the threshold according to the benchmark */ + touch_channel_config_t chan_cfg = s_test_get_chan_cfg_by_benchmark(benchmark, TOUCH_SAMPLE_CFG_NUM, TEST_ACTIVE_THRESH_RATIO); + TEST_ESP_OK(touch_sensor_reconfig_channel(touch_chan, &chan_cfg)); + + touch_event_callbacks_t callbacks = { + .on_active = s_test_touch_on_active_callback, + .on_inactive = s_test_touch_on_inactive_callback, + }; + test_touch_cb_data_t cb_data = {}; + TEST_ESP_OK(touch_sensor_register_callbacks(touch, &callbacks, &cb_data)); + + TEST_ESP_OK(touch_sensor_enable(touch)); + TEST_ESP_OK(touch_sensor_start_continuous_scanning(touch)); + vTaskDelay(pdMS_TO_TICKS(20)); + + int touch_cnt = 3; + for (int i = 0; i < touch_cnt; i++) { + printf("\nSimulate Touch [%d] ->\n--------------------------\n", i + 1); + // Read data before touched + s_test_touch_log_data(touch_chan, TOUCH_SAMPLE_CFG_NUM, "Data Before"); + // Simulate touch + s_test_touch_simulate_touch(touch, touch_chan, true); + vTaskDelay(pdMS_TO_TICKS(50)); + + // Read data after touched + s_test_touch_log_data(touch_chan, TOUCH_SAMPLE_CFG_NUM, "Data After "); + // Simulate release + s_test_touch_simulate_touch(touch, touch_chan, false); + vTaskDelay(pdMS_TO_TICKS(50)); + } + printf("\n"); + + TEST_ESP_OK(touch_sensor_stop_continuous_scanning(touch)); + TEST_ESP_OK(touch_sensor_disable(touch)); + TEST_ESP_OK(touch_sensor_del_channel(touch_chan)); + TEST_ESP_OK(touch_sensor_del_controller(touch)); + + /* Check the callback count */ + TEST_ASSERT_EQUAL_INT32(touch_cnt, cb_data.active_count); + TEST_ASSERT_EQUAL_INT32(touch_cnt, cb_data.inactive_count); +} diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/pytest_touch_sens.py b/components/esp_driver_touch_sens/test_apps/touch_sens/pytest_touch_sens.py new file mode 100644 index 000000000000..871cdb6baf07 --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/pytest_touch_sens.py @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32p4 +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 runners do not support touch pins') +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + 'iram_safe', + ], + indirect=True, +) +def test_touch_sens(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/sdkconfig.ci.iram_safe b/components/esp_driver_touch_sens/test_apps/touch_sens/sdkconfig.ci.iram_safe new file mode 100644 index 000000000000..e8074e7fa864 --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/sdkconfig.ci.iram_safe @@ -0,0 +1,7 @@ +CONFIG_COMPILER_DUMP_RTL_FILES=y +CONFIG_TOUCH_CTRL_FUNC_IN_IRAM=y +CONFIG_TOUCH_ISR_IRAM_SAFE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y +CONFIG_COMPILER_OPTIMIZATION_NONE=y +# silent the error check, as the error string are stored in rodata, causing RTL check failure +CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/sdkconfig.ci.release b/components/esp_driver_touch_sens/test_apps/touch_sens/sdkconfig.ci.release new file mode 100644 index 000000000000..91d93f163e62 --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/sdkconfig.ci.release @@ -0,0 +1,5 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/sdkconfig.defaults b/components/esp_driver_touch_sens/test_apps/touch_sens/sdkconfig.defaults new file mode 100644 index 000000000000..b308cb2ddda0 --- /dev/null +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_driver_tsens/Kconfig b/components/esp_driver_tsens/Kconfig index 9bc99c722266..4ed4294078e8 100644 --- a/components/esp_driver_tsens/Kconfig +++ b/components/esp_driver_tsens/Kconfig @@ -1,14 +1,6 @@ menu "ESP-Driver:Temperature Sensor Configurations" depends on SOC_TEMP_SENSOR_SUPPORTED - config TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN - bool "Suppress legacy driver deprecated warning" - default n - help - whether to suppress the deprecation warnings when using legacy temperature sensor driver - (driver/temp_sensor.h). If you want to continue using the legacy driver, - and don't want to see related deprecation warnings, you can enable this option. - config TEMP_SENSOR_ENABLE_DEBUG_LOG bool "Enable debug log" default n diff --git a/components/esp_driver_uart/include/driver/uart.h b/components/esp_driver_uart/include/driver/uart.h index 2ade613f599e..aeb0176bfd1f 100644 --- a/components/esp_driver_uart/include/driver/uart.h +++ b/components/esp_driver_uart/include/driver/uart.h @@ -46,6 +46,11 @@ typedef struct { lp_uart_sclk_t lp_source_clk; /*!< LP_UART source clock selection */ #endif }; + struct { + uint32_t backup_before_sleep: 1; /*!< If set, the driver will backup/restore the HP UART registers before entering/after exiting sleep mode. + By this approach, the system can power off HP UART's power domain. + This can save power, but at the expense of more RAM being consumed */ + } flags; /*!< Configuration flags */ } uart_config_t; /** diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 98a0b912e6dd..6f4ddf48abe3 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -5,6 +5,7 @@ */ #include #include +#include #include "esp_types.h" #include "esp_attr.h" #include "esp_intr_alloc.h" @@ -32,6 +33,7 @@ #include "esp_rom_gpio.h" #include "clk_ctrl_os.h" #include "esp_pm.h" +#include "esp_private/sleep_retention.h" #ifdef CONFIG_UART_ISR_IN_IRAM #define UART_ISR_ATTR IRAM_ATTR @@ -95,10 +97,11 @@ static const char *UART_TAG = "uart"; // Check actual UART mode set #define UART_IS_MODE_SET(uart_number, mode) ((p_uart_obj[uart_number]->uart_mode == mode)) -#define UART_CONTEXT_INIT_DEF(uart_num) {\ - .hal.dev = UART_LL_GET_HW(uart_num),\ - INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock)\ - .hw_enabled = false,\ +#define UART_CONTEXT_INIT_DEF(uart_num) { \ + .port_id = uart_num, \ + .hal.dev = UART_LL_GET_HW(uart_num), \ + INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) \ + .hw_enabled = false, \ } typedef struct { @@ -155,9 +158,15 @@ typedef struct { } uart_obj_t; typedef struct { + _lock_t mutex; /*!< Protect uart_module_enable, uart_module_disable, retention, etc. */ + uart_port_t port_id; uart_hal_context_t hal; /*!< UART hal context*/ DECLARE_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) bool hw_enabled; +#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + bool retention_link_inited; /*!< Mark whether the retention link is inited */ + bool retention_link_created; /*!< Mark whether the retention link is created */ +#endif } uart_context_t; static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0}; @@ -181,9 +190,13 @@ static uart_context_t uart_context[UART_NUM_MAX] = { static portMUX_TYPE uart_selectlock = portMUX_INITIALIZER_UNLOCKED; +#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP +static esp_err_t uart_create_sleep_retention_link_cb(void *arg); +#endif + static void uart_module_enable(uart_port_t uart_num) { - UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); + _lock_acquire(&(uart_context[uart_num].mutex)); if (uart_context[uart_num].hw_enabled != true) { if (uart_num < SOC_UART_HP_NUM) { HP_UART_BUS_CLK_ATOMIC() { @@ -194,6 +207,28 @@ static void uart_module_enable(uart_port_t uart_num) uart_ll_reset_register(uart_num); } } + +#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + // Initialize sleep retention module for HP UART + if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM) { // Console uart retention has been taken care in sleep_sys_periph_stdout_console_uart_retention_init + assert(!uart_context[uart_num].retention_link_inited); + sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num); + sleep_retention_module_init_param_t init_param = { + .cbs = { + .create = { + .handle = uart_create_sleep_retention_link_cb, + .arg = &uart_context[uart_num], + }, + }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM), + }; + if (sleep_retention_module_init(module, &init_param) == ESP_OK) { + uart_context[uart_num].retention_link_inited = true; + } else { + ESP_LOGW(UART_TAG, "init sleep retention failed for uart%d, power domain may be turned off during sleep", uart_num); + } + } +#endif } #if (SOC_UART_LP_NUM >= 1) else { @@ -205,14 +240,24 @@ static void uart_module_enable(uart_port_t uart_num) #endif uart_context[uart_num].hw_enabled = true; } - UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); + _lock_release(&(uart_context[uart_num].mutex)); } static void uart_module_disable(uart_port_t uart_num) { - UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); + _lock_acquire(&(uart_context[uart_num].mutex)); if (uart_context[uart_num].hw_enabled != false) { if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) { +#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + // Uninitialize sleep retention module for HP UART + sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num); + assert(!uart_context[uart_num].retention_link_created); // HP UART sleep retention should have been freed at this moment + if (uart_context[uart_num].retention_link_inited) { + sleep_retention_module_deinit(module); + uart_context[uart_num].retention_link_inited = false; + } +#endif + HP_UART_BUS_CLK_ATOMIC() { uart_ll_enable_bus_clock(uart_num, false); } @@ -226,7 +271,7 @@ static void uart_module_disable(uart_port_t uart_num) #endif uart_context[uart_num].hw_enabled = false; } - UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); + _lock_release(&(uart_context[uart_num].mutex)); } esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t *out_freq_hz) @@ -797,8 +842,37 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf ESP_RETURN_ON_FALSE((uart_config->flow_ctrl < UART_HW_FLOWCTRL_MAX), ESP_FAIL, UART_TAG, "hw_flowctrl mode error"); ESP_RETURN_ON_FALSE((uart_config->data_bits < UART_DATA_BITS_MAX), ESP_FAIL, UART_TAG, "data bit error"); +#if !SOC_UART_SUPPORT_SLEEP_RETENTION + ESP_RETURN_ON_FALSE(uart_config->flags.backup_before_sleep == 0, ESP_ERR_NOT_SUPPORTED, UART_TAG, "register back up is not supported"); +#endif + uart_module_enable(uart_num); +#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + // Create sleep retention link if desired + if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) { + _lock_acquire(&(uart_context[uart_num].mutex)); + sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num); + if (uart_config->flags.backup_before_sleep && !uart_context[uart_num].retention_link_created) { + if (uart_context[uart_num].retention_link_inited) { + if (sleep_retention_module_allocate(module) == ESP_OK) { + uart_context[uart_num].retention_link_created = true; + } else { + // Even though the sleep retention module create failed, UART driver should still work, so just warning here + ESP_LOGW(UART_TAG, "create retention module failed, power domain can't turn off"); + } + } else { + ESP_LOGW(UART_TAG, "retention module not initialized first, unable to create retention module"); + } + } else if (!uart_config->flags.backup_before_sleep && uart_context[uart_num].retention_link_created) { + assert(uart_context[uart_num].retention_link_inited); + sleep_retention_module_free(module); + uart_context[uart_num].retention_link_created = false; + } + _lock_release(&(uart_context[uart_num].mutex)); + } +#endif + soc_module_clk_t uart_sclk_sel = 0; // initialize to an invalid module clock ID if (uart_num < SOC_UART_HP_NUM) { uart_sclk_sel = (soc_module_clk_t)((uart_config->source_clk) ? uart_config->source_clk : UART_SCLK_DEFAULT); // if no specifying the clock source (soc_module_clk_t starts from 1), then just use the default clock @@ -1396,7 +1470,7 @@ int uart_write_bytes_with_break(uart_port_t uart_num, const void *src, size_t si static bool uart_check_buf_full(uart_port_t uart_num) { if (p_uart_obj[uart_num]->rx_buffer_full_flg) { - BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1); + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 0); if (res == pdTRUE) { UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len; @@ -1510,7 +1584,7 @@ esp_err_t uart_flush_input(uart_port_t uart_num) UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); vRingbufferReturnItem(p_uart->rx_ring_buf, data); if (p_uart_obj[uart_num]->rx_buffer_full_flg) { - BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1); + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 0); if (res == pdTRUE) { UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len; @@ -1711,6 +1785,20 @@ esp_err_t uart_driver_delete(uart_port_t uart_num) periph_rtc_dig_clk8m_disable(); } #endif + +#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + // Free sleep retention link for HP UART + if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) { + sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num); + _lock_acquire(&(uart_context[uart_num].mutex)); + if (uart_context[uart_num].retention_link_created) { + assert(uart_context[uart_num].retention_link_inited); + sleep_retention_module_free(module); + uart_context[uart_num].retention_link_created = false; + } + _lock_release(&(uart_context[uart_num].mutex)); + } +#endif uart_module_disable(uart_num); return ESP_OK; } @@ -1866,3 +1954,17 @@ void uart_set_always_rx_timeout(uart_port_t uart_num, bool always_rx_timeout) p_uart_obj[uart_num]->rx_always_timeout_flg = false; } } + +#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP +static esp_err_t uart_create_sleep_retention_link_cb(void *arg) +{ + uart_context_t *group = (uart_context_t *)arg; + uart_port_t uart_num = group->port_id; + sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num); + esp_err_t err = sleep_retention_entries_create(uart_reg_retention_info[uart_num].regdma_entry_array, + uart_reg_retention_info[uart_num].array_size, + REGDMA_LINK_PRI_UART, module); + ESP_RETURN_ON_ERROR(err, UART_TAG, "create retention link failed"); + return ESP_OK; +} +#endif diff --git a/components/esp_driver_uart/test_apps/rs485/README.md b/components/esp_driver_uart/test_apps/rs485/README.md index bf47d80ec649..3a502b1f86f4 100644 --- a/components/esp_driver_uart/test_apps/rs485/README.md +++ b/components/esp_driver_uart/test_apps/rs485/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_driver_uart/test_apps/uart/README.md b/components/esp_driver_uart/test_apps/uart/README.md index bf47d80ec649..3a502b1f86f4 100644 --- a/components/esp_driver_uart/test_apps/uart/README.md +++ b/components/esp_driver_uart/test_apps/uart/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_driver_uart/test_apps/uart/main/CMakeLists.txt b/components/esp_driver_uart/test_apps/uart/main/CMakeLists.txt index 22ab1202d2a9..27ff3d84b7d8 100644 --- a/components/esp_driver_uart/test_apps/uart/main/CMakeLists.txt +++ b/components/esp_driver_uart/test_apps/uart/main/CMakeLists.txt @@ -1,7 +1,19 @@ +set(srcs "test_app_main.c" + "test_uart.c") + +if(CONFIG_PM_ENABLE) + list(APPEND srcs "test_uart_auto_lightsleep.c") +endif() + +# Only if the target supports uart retention and the sdkconfig.ci.xxx contains at least PM_ENABLE=y +if(CONFIG_SOC_UART_SUPPORT_SLEEP_RETENTION AND CONFIG_PM_ENABLE) + list(APPEND srcs "test_uart_retention.c") +endif() + # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register( - SRCS "test_app_main.c" "test_uart.c" "test_uart_auto_lightsleep.c" + SRCS ${srcs} REQUIRES esp_driver_uart unity esp_psram test_utils esp_driver_gpio esp_pm PRIV_INCLUDE_DIRS . WHOLE_ARCHIVE diff --git a/components/esp_driver_uart/test_apps/uart/main/test_uart_auto_lightsleep.c b/components/esp_driver_uart/test_apps/uart/main/test_uart_auto_lightsleep.c index b409deafd81e..a7df3a10bdcf 100644 --- a/components/esp_driver_uart/test_apps/uart/main/test_uart_auto_lightsleep.c +++ b/components/esp_driver_uart/test_apps/uart/main/test_uart_auto_lightsleep.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,15 +27,14 @@ #if CONFIG_XTAL_FREQ_40 #define MIN_FREQ 10 +#elif CONFIG_XTAL_FREQ_48 +#define MIN_FREQ 12 #elif CONFIG_XTAL_FREQ_32 #define MIN_FREQ 8 #elif CONFIG_XTAL_FREQ_26 #define MIN_FREQ 13 #endif -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) -#if CONFIG_PM_ENABLE - TEST_CASE("uart tx won't be blocked by auto light sleep", "[uart]") { uart_port_param_t port_param = {}; @@ -82,10 +81,8 @@ TEST_CASE("uart tx won't be blocked by auto light sleep", "[uart]") uart_driver_delete(port_num); free(data); -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP - //When PD_CPU enabled, retention may cause 14K memory leak. Workaround to release the memory - sleep_cpu_configure(false); +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE + pm_config.light_sleep_enable = false; + TEST_ESP_OK(esp_pm_configure(&pm_config)); #endif } -#endif // CONFIG_PM_ENABLE -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) diff --git a/components/esp_driver_uart/test_apps/uart/main/test_uart_retention.c b/components/esp_driver_uart/test_apps/uart/main/test_uart_retention.c new file mode 100644 index 000000000000..692d24f72f84 --- /dev/null +++ b/components/esp_driver_uart/test_apps/uart/main/test_uart_retention.c @@ -0,0 +1,148 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "unity.h" +#include "driver/uart.h" +#include "esp_pm.h" +#include "esp_private/sleep_cpu.h" +#include "esp_clk_tree.h" +#include "esp_sleep.h" + +// UART retention test only need to be done on HP UART + +static const uart_port_t uart_num = UART_NUM_1; + +static void uart_init(bool backup_before_sleep) +{ + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_DEFAULT, + .flags.backup_before_sleep = backup_before_sleep, + }; + + TEST_ESP_OK(uart_driver_install(uart_num, 256, 0, 20, NULL, 0)); + TEST_ESP_OK(uart_param_config(uart_num, &uart_config)); + TEST_ESP_OK(uart_set_loop_back(uart_num, true)); +} + +TEST_CASE("uart restored correctly after auto light sleep", "[uart][hp-uart-only]") +{ + // Configure dynamic frequency scaling: + // maximum and minimum frequencies are set in sdkconfig, + // automatic light sleep is enabled if tickless idle support is enabled. + uint32_t xtal_hz = 0; + esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_XTAL, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &xtal_hz); + esp_pm_config_t pm_config = { + .max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, + .min_freq_mhz = xtal_hz / 1000000, +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE + .light_sleep_enable = true, +#endif + }; + TEST_ESP_OK(esp_pm_configure(&pm_config)); + + uart_init(true); + + // Ensure UART is fully idle before starting loopback RX/TX test + TEST_ESP_OK(uart_wait_tx_done(uart_num, portMAX_DELAY)); + vTaskDelay(pdMS_TO_TICKS(20)); // make sure last byte has flushed from TX FIFO + TEST_ESP_OK(uart_flush_input(uart_num)); + + for (int i = 0; i < 5; i++) { + char tx_data[20] = {0}; + char rx_data[20] = {0}; + int len = sprintf(tx_data, "Hello World %d!\n", i); + uart_write_bytes(uart_num, tx_data, len); + int size = 0; + // Polling to read the data back to avoid getting into auto light sleep + while (size < len) { + int bytes = uart_read_bytes(uart_num, (void *)((uint32_t)rx_data + size), 1, 0); + size += bytes; + } + rx_data[len] = '\0'; + printf("%s", rx_data); + TEST_ASSERT_TRUE(strcmp(tx_data, rx_data) == 0); + + vTaskDelay(pdMS_TO_TICKS(1000)); // auto light sleep + } + + TEST_ESP_OK(uart_driver_delete(uart_num)); + + pm_config.light_sleep_enable = false; + TEST_ESP_OK(esp_pm_configure(&pm_config)); +} + +TEST_CASE("uart restored correctly after manually enter light sleep", "[uart][hp-uart-only]") +{ + // Prepare a TOP PD sleep + TEST_ESP_OK(esp_sleep_enable_timer_wakeup(1 * 1000 * 1000)); + sleep_cpu_configure(true); + + uart_init(true); + + // Ensure UART is fully idle before starting loopback RX/TX test + TEST_ESP_OK(uart_wait_tx_done(uart_num, portMAX_DELAY)); + vTaskDelay(pdMS_TO_TICKS(20)); // make sure last byte has flushed from TX FIFO + TEST_ESP_OK(uart_flush_input(uart_num)); + + for (int i = 0; i < 5; i++) { + char tx_data[20] = {0}; + char rx_data[20] = {0}; + int len = sprintf(tx_data, "Hello World %d!\n", i); + uart_write_bytes(uart_num, tx_data, len); + int size = uart_read_bytes(uart_num, rx_data, len, pdMS_TO_TICKS(20)); + TEST_ASSERT_EQUAL(len, size); + rx_data[len] = '\0'; + printf("%s", rx_data); + TEST_ASSERT_TRUE(strcmp(tx_data, rx_data) == 0); + + printf("Going into sleep...\n"); + TEST_ESP_OK(esp_light_sleep_start()); + printf("Waked up!\n"); + } + + TEST_ESP_OK(uart_driver_delete(uart_num)); + TEST_ESP_OK(sleep_cpu_configure(false)); +} + +TEST_CASE("uart won't be powered down in light sleep if retention not created", "[uart][hp-uart-only]") +{ + // Prepare a TOP PD sleep + TEST_ESP_OK(esp_sleep_enable_timer_wakeup(1 * 1000 * 1000)); + sleep_cpu_configure(true); + + uart_init(false); // backup_before_sleep set to false, sleep retention module will be inited, but not created + + // Ensure UART is fully idle before starting loopback RX/TX test + TEST_ESP_OK(uart_wait_tx_done(uart_num, portMAX_DELAY)); + vTaskDelay(pdMS_TO_TICKS(20)); // make sure last byte has flushed from TX FIFO + TEST_ESP_OK(uart_flush_input(uart_num)); + + for (int i = 0; i < 3; i++) { + char tx_data[20] = {0}; + char rx_data[20] = {0}; + int len = sprintf(tx_data, "Hello World %d!\n", i); + uart_write_bytes(uart_num, tx_data, len); + int size = uart_read_bytes(uart_num, rx_data, len, pdMS_TO_TICKS(20)); + TEST_ASSERT_EQUAL(len, size); + rx_data[len] = '\0'; + printf("%s", rx_data); + TEST_ASSERT_TRUE(strcmp(tx_data, rx_data) == 0); + + printf("Going into sleep...\n"); + TEST_ESP_OK(esp_light_sleep_start()); // sleep without powering down TOP domain + printf("Waked up!\n"); + } + + TEST_ESP_OK(uart_driver_delete(uart_num)); + TEST_ESP_OK(sleep_cpu_configure(false)); +} diff --git a/components/esp_driver_uart/test_apps/uart/pytest_uart.py b/components/esp_driver_uart/test_apps/uart/pytest_uart.py index 4c94d8565231..e1be06ea5f96 100644 --- a/components/esp_driver_uart/test_apps/uart/pytest_uart.py +++ b/components/esp_driver_uart/test_apps/uart/pytest_uart.py @@ -28,15 +28,18 @@ def test_uart_single_dev(case_tester) -> None: # type: ignore dut = case_tester.first_dut chip_type = dut.app.target - for uart_port in input_argv.get(chip_type, []): - for case in case_tester.test_menu: - dut.serial.hard_reset() - dut._get_ready() - dut.confirm_write(case.index, expect_str=f'Running {case.name}...') + for case in case_tester.test_menu: + if 'hp-uart-only' not in case.groups: + for uart_port in input_argv.get(chip_type, []): + dut.serial.hard_reset() + dut._get_ready() + dut.confirm_write(case.index, expect_str=f'Running {case.name}...') - dut.expect("select to test 'uart' or 'lp_uart' port", timeout=10) - dut.write(f'{uart_port}') - dut.expect_unity_test_output() + dut.expect("select to test 'uart' or 'lp_uart' port", timeout=10) + dut.write(f'{uart_port}') + dut.expect_unity_test_output() + else: + dut._run_normal_case(case, reset=True) @pytest.mark.esp32s3 diff --git a/components/esp_driver_uart/test_apps/uart/sdkconfig.ci.release b/components/esp_driver_uart/test_apps/uart/sdkconfig.ci.release index 673b6f8f748a..a6be7c649bed 100644 --- a/components/esp_driver_uart/test_apps/uart/sdkconfig.ci.release +++ b/components/esp_driver_uart/test_apps/uart/sdkconfig.ci.release @@ -1,5 +1,6 @@ CONFIG_PM_ENABLE=y CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_driver_uart/test_apps/uart_vfs/main/test_app_main.c b/components/esp_driver_uart/test_apps/uart_vfs/main/test_app_main.c index 6ee4144067a1..6ab21f1f6736 100644 --- a/components/esp_driver_uart/test_apps/uart_vfs/main/test_app_main.c +++ b/components/esp_driver_uart/test_apps/uart_vfs/main/test_app_main.c @@ -9,7 +9,7 @@ #include "esp_heap_caps.h" // Some resources are lazy allocated, the threadhold is left for that case -#define TEST_MEMORY_LEAK_THRESHOLD (400) +#define TEST_MEMORY_LEAK_THRESHOLD (500) void setUp(void) { diff --git a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c index e03b4efc764f..bf96f06d0145 100644 --- a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c +++ b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag.c @@ -19,35 +19,31 @@ #include "esp_check.h" #include "esp_private/periph_ctrl.h" +/* + Note: Before you add a workaround for an issue in this driver, please please try + to figure out the actual root cause first. The USB-serial-JTAG is a simple device, + it shouldn't need anything more than a simple, straightforward driver. +*/ + #if !SOC_RCC_IS_INDEPENDENT #define USJ_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #else #define USJ_RCC_ATOMIC() #endif -typedef enum { - FIFO_IDLE = 0, /*!< Indicates the fifo is in idle state */ - FIFO_BUSY = 1, /*!< Indicates the fifo is in busy state */ -} fifo_status_t; - -// The hardware buffer max size is 64 +// The hardware buffer max size is 64, both for RX and TX. #define USB_SER_JTAG_ENDP_SIZE (64) -#define USB_SER_JTAG_RX_MAX_SIZE (64) +#define USB_SER_JTAG_RX_MAX_SIZE (USB_SER_JTAG_ENDP_SIZE) typedef struct { intr_handle_t intr_handle; /*!< USB-SERIAL-JTAG interrupt handler */ - portMUX_TYPE spinlock; /*!< Spinlock for usb_serial_jtag */ - _Atomic fifo_status_t fifo_status; /*!< Record the status of fifo */ // RX parameters RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler */ - uint32_t rx_buf_size; /*!< TX buffer size */ - uint8_t rx_data_buf[USB_SER_JTAG_ENDP_SIZE]; /*!< Data buffer to stash FIFO data */ // TX parameters - uint32_t tx_buf_size; /*!< TX buffer size */ RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler */ - uint8_t tx_data_buf[USB_SER_JTAG_ENDP_SIZE]; /*!< Data buffer to stash TX FIFO data */ + uint8_t tx_stash_buf[USB_SER_JTAG_ENDP_SIZE]; /*!< Data buffer to stash TX FIFO data */ size_t tx_stash_cnt; /*!< Number of stashed TX FIFO bytes */ } usb_serial_jtag_obj_t; @@ -55,13 +51,6 @@ static usb_serial_jtag_obj_t *p_usb_serial_jtag_obj = NULL; static const char* USB_SERIAL_JTAG_TAG = "usb_serial_jtag"; -static size_t usb_serial_jtag_write_and_flush(const uint8_t *buf, uint32_t wr_len) -{ - size_t size = usb_serial_jtag_ll_write_txfifo(buf, wr_len); - usb_serial_jtag_ll_txfifo_flush(); - return size; -} - static void usb_serial_jtag_isr_handler_default(void *arg) { BaseType_t xTaskWoken = 0; @@ -69,77 +58,70 @@ static void usb_serial_jtag_isr_handler_default(void *arg) usbjtag_intr_status = usb_serial_jtag_ll_get_intsts_mask(); if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY) { + //Clear interrupt so we won't be called until the next transfer finishes. + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + // Interrupt tells us the host picked up the data we sent. // If we have more data, we can put it in the buffer and the host will pick that up next. - // Send data in isr. - // If the hardware fifo is available, write in it. Otherwise, do nothing. + // We expect the TX FIFO to be writable for this. If it's not, somehow someone else + // (ROM print routines?) have snuck in a full buffer before we got here. In that case, + // we simply ignore the interrupt, a new one will come if the buffer is empty again. if (usb_serial_jtag_ll_txfifo_writable() == 1) { - // We disable the interrupt here so that the interrupt won't be triggered if there is no data to send. - + // Retrieve data from either the stash buffer or, if that's empty, from the ring buffer. size_t queued_size; - uint8_t *queued_buff = NULL; - bool is_stashed_data = false; + uint8_t *queued_buf = NULL; if (p_usb_serial_jtag_obj->tx_stash_cnt != 0) { // Send stashed tx bytes before reading bytes from ring buffer - queued_buff = p_usb_serial_jtag_obj->tx_data_buf; + queued_buf = p_usb_serial_jtag_obj->tx_stash_buf; queued_size = p_usb_serial_jtag_obj->tx_stash_cnt; - is_stashed_data = true; } else { // Max 64 data payload size in a single EndPoint - queued_buff = (uint8_t *)xRingbufferReceiveUpToFromISR(p_usb_serial_jtag_obj->tx_ring_buf, &queued_size, USB_SER_JTAG_ENDP_SIZE); + queued_buf = (uint8_t *)xRingbufferReceiveUpToFromISR(p_usb_serial_jtag_obj->tx_ring_buf, &queued_size, USB_SER_JTAG_ENDP_SIZE); } - usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); - - if (queued_buff != NULL) { - - // Although tx_queued_bytes may be larger than 0, we may have - // interrupted before xRingbufferSend() was called. - // Copy the queued buffer into the TX FIFO - - // On ringbuffer wrap-around the size can be 0 even though the buffer returned is not NULL - if (queued_size > 0) { - portENTER_CRITICAL_ISR(&p_usb_serial_jtag_obj->spinlock); - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_BUSY); - uint32_t sent_size = usb_serial_jtag_write_and_flush(queued_buff, queued_size); - portEXIT_CRITICAL_ISR(&p_usb_serial_jtag_obj->spinlock); - - if (sent_size < queued_size) { - // Not all bytes could be sent at once; stash the unwritten bytes in a tx buffer - // stash_size will not larger than USB_SER_JTAG_ENDP_SIZE because queued_size is got from xRingbufferReceiveUpToFromISR - size_t stash_size = queued_size - sent_size; - memcpy(p_usb_serial_jtag_obj->tx_data_buf, &queued_buff[sent_size], stash_size); - p_usb_serial_jtag_obj->tx_stash_cnt = stash_size; - } else { - p_usb_serial_jtag_obj->tx_stash_cnt = 0; - // assert if sent_size is larger than queued_size. - assert(sent_size <= queued_size); - } + if (queued_buf != NULL && queued_size > 0) { + // We have some data to send. Send it. + uint32_t sent_size = usb_serial_jtag_ll_write_txfifo(queued_buf, queued_size); + usb_serial_jtag_ll_txfifo_flush(); + + // Check if we were able to send everything. + if (sent_size < queued_size) { + // Not all bytes could be sent at once; stash the unwritten bytes in a buffer + // This will happen if e.g. the rom output functions manage to sneak a few bytes into the + // TX FIFO before this interrupt triggers. Note stash_size will not larger than + // USB_SER_JTAG_ENDP_SIZE because queued_size is obtained from xRingbufferReceiveUpToFromISR. + size_t stash_size = queued_size - sent_size; + memcpy(p_usb_serial_jtag_obj->tx_stash_buf, &queued_buf[sent_size], stash_size); + p_usb_serial_jtag_obj->tx_stash_cnt = stash_size; + } else { + p_usb_serial_jtag_obj->tx_stash_cnt = 0; } - if (is_stashed_data == false) { - vRingbufferReturnItemFromISR(p_usb_serial_jtag_obj->tx_ring_buf, queued_buff, &xTaskWoken); + // Return the buffer if we got it from the ring buffer. + if (queued_buf != p_usb_serial_jtag_obj->tx_stash_buf) { + vRingbufferReturnItemFromISR(p_usb_serial_jtag_obj->tx_ring_buf, queued_buf, &xTaskWoken); } } else { + // No data to send. // The last transmit may have sent a full EP worth of data. The host will interpret // this as a transaction that hasn't finished yet and keep the data in its internal // buffers rather than releasing it to the program listening on the CDC serial port. // We need to flush again in order to send a 0-byte packet that ends the transaction. usb_serial_jtag_ll_txfifo_flush(); - // Note that since this doesn't re-enable USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY, the - // flush will not by itself cause this ISR to be called again. + + // We will also disable the interrupt as for now there's no need to handle the + // TX interrupt again. We'll re-enable this externally if we need data sent. + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); } - } else { - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_IDLE); - usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); } } if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) { - // read rx buffer(max length is 64), and send available data to ringbuffer. - // Ensure the rx buffer size is larger than RX_MAX_SIZE. + // Acknowledge interrupt usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); - uint32_t rx_fifo_len = usb_serial_jtag_ll_read_rxfifo(p_usb_serial_jtag_obj->rx_data_buf, USB_SER_JTAG_RX_MAX_SIZE); - xRingbufferSendFromISR(p_usb_serial_jtag_obj->rx_ring_buf, p_usb_serial_jtag_obj->rx_data_buf, rx_fifo_len, &xTaskWoken); + // Read RX FIFO and send available data to ringbuffer. + uint8_t buf[USB_SER_JTAG_RX_MAX_SIZE]; + uint32_t rx_fifo_len = usb_serial_jtag_ll_read_rxfifo(buf, USB_SER_JTAG_RX_MAX_SIZE); + xRingbufferSendFromISR(p_usb_serial_jtag_obj->rx_ring_buf, buf, rx_fifo_len, &xTaskWoken); } if (xTaskWoken == pdTRUE) { @@ -155,17 +137,15 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se ESP_RETURN_ON_FALSE((usb_serial_jtag_config->rx_buffer_size > USB_SER_JTAG_RX_MAX_SIZE), ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "RX buffer prepared is so small, should larger than 64"); ESP_RETURN_ON_FALSE((usb_serial_jtag_config->tx_buffer_size > 0), ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "TX buffer is not prepared"); p_usb_serial_jtag_obj = (usb_serial_jtag_obj_t*) heap_caps_calloc(1, sizeof(usb_serial_jtag_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - p_usb_serial_jtag_obj->rx_buf_size = usb_serial_jtag_config->rx_buffer_size; - p_usb_serial_jtag_obj->tx_buf_size = usb_serial_jtag_config->tx_buffer_size; p_usb_serial_jtag_obj->tx_stash_cnt = 0; - p_usb_serial_jtag_obj->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; if (p_usb_serial_jtag_obj == NULL) { ESP_LOGE(USB_SERIAL_JTAG_TAG, "memory allocate error"); - err = ESP_ERR_NO_MEM; - goto _exit; + // no `goto _exit` here as there's nothing to clean up and that would make the uninstall + // routine unhappy. + return ESP_ERR_NO_MEM; } - p_usb_serial_jtag_obj->rx_ring_buf = xRingbufferCreate(p_usb_serial_jtag_obj->rx_buf_size, RINGBUF_TYPE_BYTEBUF); + p_usb_serial_jtag_obj->rx_ring_buf = xRingbufferCreate(usb_serial_jtag_config->rx_buffer_size, RINGBUF_TYPE_BYTEBUF); if (p_usb_serial_jtag_obj->rx_ring_buf == NULL) { ESP_LOGE(USB_SERIAL_JTAG_TAG, "ringbuffer create error"); err = ESP_ERR_NO_MEM; @@ -183,7 +163,6 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se USJ_RCC_ATOMIC() { usb_serial_jtag_ll_enable_bus_clock(true); } - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_IDLE); // Configure PHY #if USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED @@ -193,10 +172,14 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se usb_serial_jtag_ll_phy_set_defaults(); // External PHY not supported. Set default values. #endif // USB_WRAP_LL_EXT_PHY_SUPPORTED - usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | - USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); - usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | - USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + // Note: DO NOT clear the interrupt status bits here. The output routine needs + // USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY set because it needs the ISR to trigger + // as soon as data is sent; the input routine needs the status to retrieve any + // data that is still in the FIFOs. + + // We only enable the RX interrupt; we'll enable the TX one when we actually + // have anything to send. + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); err = esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, 0, usb_serial_jtag_isr_handler_default, NULL, &p_usb_serial_jtag_obj->intr_handle); if (err != ESP_OK) { @@ -238,37 +221,29 @@ int usb_serial_jtag_write_bytes(const void* src, size_t size, TickType_t ticks_t ESP_RETURN_ON_FALSE(src != NULL, ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "Invalid buffer pointer."); ESP_RETURN_ON_FALSE(p_usb_serial_jtag_obj != NULL, ESP_ERR_INVALID_ARG, USB_SERIAL_JTAG_TAG, "The driver hasn't been initialized"); - size_t sent_data = 0; BaseType_t result = pdTRUE; - const uint8_t *buff = (const uint8_t *)src; - if (p_usb_serial_jtag_obj->fifo_status == FIFO_IDLE) { - portENTER_CRITICAL(&p_usb_serial_jtag_obj->spinlock); - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_BUSY); - sent_data = usb_serial_jtag_write_and_flush(src, size); - portEXIT_CRITICAL(&p_usb_serial_jtag_obj->spinlock); - } - - // Blocking method, Sending data to ringbuffer, and handle the data in ISR. - if (size - sent_data > 0) { - result = xRingbufferSend(p_usb_serial_jtag_obj->tx_ring_buf, (void*)(buff + sent_data), size - sent_data, ticks_to_wait); - } else { - atomic_store(&p_usb_serial_jtag_obj->fifo_status, FIFO_IDLE); - } + result = xRingbufferSend(p_usb_serial_jtag_obj->tx_ring_buf, (void*)src, size, ticks_to_wait); + // Re-enable the TX interrupt. If this was disabled, this will immediately trigger the ISR + // and send the things we just put in the ringbuffer. usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); return (result == pdFALSE) ? 0 : size; } +//Note that this is also called when usb_serial_jtag_driver_install errors out and as such should +//work on a half-initialized driver as well. esp_err_t usb_serial_jtag_driver_uninstall(void) { if (p_usb_serial_jtag_obj == NULL) { - ESP_LOGI(USB_SERIAL_JTAG_TAG, "ALREADY NULL"); + ESP_LOGE(USB_SERIAL_JTAG_TAG, "uninstall without install called"); return ESP_OK; } - /* Not disable the module clock and usb_pad_enable here since the USJ stdout might still depends on it. */ - //Disable tx/rx interrupt. + /* Don't disable the module clock and usb_pad_enable here since the USJ stdout might still depends on it. */ + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); - esp_intr_free(p_usb_serial_jtag_obj->intr_handle); + if (p_usb_serial_jtag_obj->intr_handle) { + esp_intr_free(p_usb_serial_jtag_obj->intr_handle); + } if (p_usb_serial_jtag_obj->rx_ring_buf) { vRingbufferDelete(p_usb_serial_jtag_obj->rx_ring_buf); diff --git a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_connection_monitor.c b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_connection_monitor.c index eb38a267e684..a730a636c0e6 100644 --- a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_connection_monitor.c +++ b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_connection_monitor.c @@ -52,7 +52,7 @@ static void IRAM_ATTR usb_serial_jtag_sof_tick_hook(void) #if CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION esp_pm_lock_release(s_usb_serial_jtag_pm_lock); #endif -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7496 SOC_USB_SERIAL_JTAG_PHY_ON_BBPLL +#if USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL rtc_clk_bbpll_remove_consumer(); #endif s_usb_serial_jtag_conn_status = false; @@ -62,7 +62,7 @@ static void IRAM_ATTR usb_serial_jtag_sof_tick_hook(void) #if CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION esp_pm_lock_acquire(s_usb_serial_jtag_pm_lock); #endif -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7496 SOC_USB_SERIAL_JTAG_PHY_ON_BBPLL +#if USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL rtc_clk_bbpll_add_consumer(); #endif s_usb_serial_jtag_conn_status = true; @@ -79,8 +79,8 @@ ESP_SYSTEM_INIT_FN(usb_serial_jtag_conn_status_init, SECONDARY, BIT(0), 230) // We always assume it is connected at first, so acquires the lock to avoid auto light sleep esp_pm_lock_acquire(s_usb_serial_jtag_pm_lock); #endif -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7496 SOC_USB_SERIAL_JTAG_PHY_ON_BBPLL -// TODO: esp32p4 USJ rely on SPLL, if it will also be disabled during sleep, we need to call spll_add_consumer? +#if USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL +// TODO: esp32p4 USJ rely on SPLL, if it will also be disabled during sleep, we need to call spll_add_consumer? IDF-9947 rtc_clk_bbpll_add_consumer(); #endif s_usb_serial_jtag_conn_status = true; diff --git a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c index 9446a6d24ed3..ea400bbb65d7 100644 --- a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c +++ b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_vfs.c @@ -121,6 +121,11 @@ static void usb_serial_jtag_tx_char(int fd, int c) do { if (usb_serial_jtag_ll_txfifo_writable()) { usb_serial_jtag_ll_write_txfifo(&cc, 1); + if (c == '\n') { + //Make sure line doesn't linger in fifo + usb_serial_jtag_ll_txfifo_flush(); + } + //update time of last successful tx to now. s_ctx.last_tx_ts = esp_timer_get_time(); break; } @@ -155,10 +160,6 @@ static ssize_t usb_serial_jtag_write(int fd, const void * data, size_t size) } } s_ctx.tx_func(fd, c); - if (c == '\n') { - //Make sure line doesn't linger in fifo - usb_serial_jtag_ll_txfifo_flush(); - } } _lock_release_recursive(&s_ctx.write_lock); return size; diff --git a/components/esp_driver_usb_serial_jtag/test_apps/.build-test-rules.yml b/components/esp_driver_usb_serial_jtag/test_apps/.build-test-rules.yml index 5605004cfc96..18ab2db959d5 100644 --- a/components/esp_driver_usb_serial_jtag/test_apps/.build-test-rules.yml +++ b/components/esp_driver_usb_serial_jtag/test_apps/.build-test-rules.yml @@ -3,6 +3,10 @@ components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag: disable: - if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET in ["esp32p4"] + temporary: true + reason: No runners. depends_components: - vfs - esp_driver_gpio diff --git a/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/README.md b/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/README.md index f1988f4a4025..ad95e4113393 100644 --- a/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/README.md +++ b/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_eth/CMakeLists.txt b/components/esp_eth/CMakeLists.txt index 071cb776d808..132f01a30110 100644 --- a/components/esp_eth/CMakeLists.txt +++ b/components/esp_eth/CMakeLists.txt @@ -12,11 +12,11 @@ set(ld_fragments linker.lf) # As CONFIG_ETH_ENABLED comes from Kconfig, it is not evaluated yet # when components are being registered. # Thus, always add the (private) requirements, regardless of Kconfig -set(priv_requires driver log esp_timer) +set(priv_requires log esp_timer esp_driver_spi esp_driver_gpio) # If Ethernet disabled in Kconfig, this is a config-only component if(CONFIG_ETH_ENABLED) - set(srcs "src/esp_eth.c" "src/esp_eth_phy_802_3.c") + set(srcs "src/esp_eth.c" "src/phy/esp_eth_phy_802_3.c") set(include "include") if(NOT CMAKE_BUILD_EARLY_EXPANSION) @@ -27,34 +27,34 @@ if(CONFIG_ETH_ENABLED) endif() if(CONFIG_ETH_USE_ESP32_EMAC) - list(APPEND srcs "src/esp_eth_mac_esp.c" - "src/esp_eth_mac_esp_dma.c" - "src/esp_eth_mac_esp_gpio.c" - "src/esp_eth_phy_dp83848.c" - "src/esp_eth_phy_ip101.c" - "src/esp_eth_phy_ksz80xx.c" - "src/esp_eth_phy_lan87xx.c" - "src/esp_eth_phy_rtl8201.c") + list(APPEND srcs "src/mac/esp_eth_mac_esp.c" + "src/mac/esp_eth_mac_esp_dma.c" + "src/mac/esp_eth_mac_esp_gpio.c" + "src/phy/esp_eth_phy_dp83848.c" + "src/phy/esp_eth_phy_ip101.c" + "src/phy/esp_eth_phy_ksz80xx.c" + "src/phy/esp_eth_phy_lan87xx.c" + "src/phy/esp_eth_phy_rtl8201.c") endif() if(CONFIG_ETH_SPI_ETHERNET_DM9051) - list(APPEND srcs "src/esp_eth_mac_dm9051.c" - "src/esp_eth_phy_dm9051.c") + list(APPEND srcs "src/spi/dm9051/esp_eth_mac_dm9051.c" + "src/spi/dm9051/esp_eth_phy_dm9051.c") endif() if(CONFIG_ETH_SPI_ETHERNET_W5500) - list(APPEND srcs "src/esp_eth_mac_w5500.c" - "src/esp_eth_phy_w5500.c") + list(APPEND srcs "src/spi/w5500/esp_eth_mac_w5500.c" + "src/spi/w5500/esp_eth_phy_w5500.c") endif() if(CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL) - list(APPEND srcs "src/esp_eth_mac_ksz8851snl.c" - "src/esp_eth_phy_ksz8851snl.c") + list(APPEND srcs "src/spi/ksz8851snl/esp_eth_mac_ksz8851snl.c" + "src/spi/ksz8851snl/esp_eth_phy_ksz8851snl.c") endif() if(CONFIG_ETH_USE_OPENETH) - list(APPEND srcs "src/esp_eth_mac_openeth.c" - "src/esp_eth_phy_dp83848.c") + list(APPEND srcs "src/openeth/esp_eth_mac_openeth.c" + "src/phy/esp_eth_phy_dp83848.c") endif() endif() @@ -66,10 +66,7 @@ idf_component_register(SRCS "${srcs}" if(CONFIG_ETH_ENABLED) if(CONFIG_ETH_USE_SPI_ETHERNET) - idf_component_optional_requires(PUBLIC driver esp_driver_gpio) - endif() - idf_component_optional_requires(PRIVATE esp_netif esp_pm) - if(CONFIG_SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE) - idf_component_optional_requires(PRIVATE esp_mm) + idf_component_optional_requires(PUBLIC esp_driver_spi) endif() + idf_component_optional_requires(PRIVATE esp_netif esp_pm esp_mm) endif() diff --git a/components/esp_eth/Kconfig b/components/esp_eth/Kconfig index 9de9df49e0a3..fe8fd3961d71 100644 --- a/components/esp_eth/Kconfig +++ b/components/esp_eth/Kconfig @@ -24,7 +24,7 @@ menu "Ethernet" endchoice if ETH_PHY_INTERFACE_RMII - choice ETH_RMII_CLK_MODE + choice ETH_RMII_CLK_MODE # IDF-9724 depends on IDF_TARGET_ESP32 prompt "RMII clock mode" default ETH_RMII_CLK_INPUT diff --git a/components/esp_eth/include/esp_eth_com.h b/components/esp_eth/include/esp_eth_com.h index a81ac058fbb0..a2c494594384 100644 --- a/components/esp_eth/include/esp_eth_com.h +++ b/components/esp_eth/include/esp_eth_com.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,17 @@ extern "C" { #endif +/** + * @brief Offset for start of MAC custom ioctl commands + * + */ +#define ETH_CMD_CUSTOM_MAC_CMDS_OFFSET 0x0FFF +/** + * @brief Offset for start of PHY custom ioctl commands + * + */ +#define ETH_CMD_CUSTOM_PHY_CMDS_OFFSET 0x1FFF + /** * @brief Ethernet driver state * diff --git a/components/esp_eth/include/esp_eth_driver.h b/components/esp_eth/include/esp_eth_driver.h index 068a911dfb1c..3a253f71c45b 100644 --- a/components/esp_eth/include/esp_eth_driver.h +++ b/components/esp_eth/include/esp_eth_driver.h @@ -1,12 +1,20 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include "esp_eth_com.h" -#include "esp_eth_mac.h" +#if CONFIG_ETH_USE_SPI_ETHERNET +#include "esp_eth_mac_spi.h" +#endif // CONFIG_ETH_USE_SPI_ETHERNET +#if CONFIG_ETH_USE_ESP32_EMAC +#include "esp_eth_mac_esp.h" +#endif // CONFIG_ETH_USE_ESP32_EMAC +#if CONFIG_ETH_USE_OPENETH +#include "esp_eth_mac_openeth.h" +#endif // CONFIG_ETH_USE_OPENETH #include "esp_eth_phy.h" #ifdef __cplusplus @@ -151,8 +159,8 @@ typedef enum { ETH_CMD_READ_PHY_REG, /*!< Read PHY register */ ETH_CMD_WRITE_PHY_REG, /*!< Write PHY register */ - ETH_CMD_CUSTOM_MAC_CMDS = 0x0FFF, // Offset for start of MAC custom commands - ETH_CMD_CUSTOM_PHY_CMDS = 0x1FFF, // Offset for start of PHY custom commands + ETH_CMD_CUSTOM_MAC_CMDS = ETH_CMD_CUSTOM_MAC_CMDS_OFFSET, // Offset for start of MAC custom commands + ETH_CMD_CUSTOM_PHY_CMDS = ETH_CMD_CUSTOM_PHY_CMDS_OFFSET, // Offset for start of PHY custom commands } esp_eth_io_cmd_t; /** @@ -272,7 +280,7 @@ esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, void *buf, size_t length); * @param[in] argc number variable arguments * @param ... variable arguments * @return -* - ESP_OK: transmit successfull +* - ESP_OK: transmit successful * - ESP_ERR_INVALID_STATE: invalid driver state (e.i. driver is not started) * - ESP_ERR_TIMEOUT: transmit frame buffer failed because HW was not get available in predefined period * - ESP_FAIL: transmit frame buffer failed because some other error occurred @@ -280,7 +288,7 @@ esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, void *buf, size_t length); esp_err_t esp_eth_transmit_vargs(esp_eth_handle_t hdl, uint32_t argc, ...); /** -* @brief Misc IO function of Etherent driver +* @brief Misc IO function of Ethernet driver * * @param[in] hdl: handle of Ethernet driver * @param[in] cmd: IO control command @@ -314,6 +322,28 @@ esp_err_t esp_eth_transmit_vargs(esp_eth_handle_t hdl, uint32_t argc, ...); */ esp_err_t esp_eth_ioctl(esp_eth_handle_t hdl, esp_eth_io_cmd_t cmd, void *data); +/** +* @brief Get PHY instance memory address +* +* @param[in] hdl handle of Ethernet driver +* @param[out] phy pointer to memory to store the instance +* @return esp_err_t +* - ESP_OK: success +* - ESP_ERR_INVALID_ARG: failed because of some invalid argument +*/ +esp_err_t esp_eth_get_phy_instance(esp_eth_handle_t hdl, esp_eth_phy_t **phy); + +/** +* @brief Get MAC instance memory address +* +* @param[in] hdl handle of Ethernet driver +* @param[out] mac pointer to memory to store the instance +* @return esp_err_t +* - ESP_OK: success +* - ESP_ERR_INVALID_ARG: failed because of some invalid argument +*/ +esp_err_t esp_eth_get_mac_instance(esp_eth_handle_t hdl, esp_eth_mac_t **mac); + /** * @brief Increase Ethernet driver reference * @note Ethernet driver handle can be obtained by os timer, netif, etc. diff --git a/components/esp_eth/include/esp_eth_mac.h b/components/esp_eth/include/esp_eth_mac.h index c10b81370903..cabfb127239d 100644 --- a/components/esp_eth/include/esp_eth_mac.h +++ b/components/esp_eth/include/esp_eth_mac.h @@ -9,9 +9,6 @@ #include "soc/soc_caps.h" #include "esp_eth_com.h" #include "sdkconfig.h" -#if CONFIG_ETH_USE_SPI_ETHERNET -#include "driver/spi_master.h" -#endif #ifdef __cplusplus extern "C" { @@ -306,7 +303,7 @@ struct esp_eth_mac_s { * - ESP_FAIL: process io command failed because some other error occurred * - ESP_ERR_NOT_SUPPORTED: requested feature is not supported */ - esp_err_t (*custom_ioctl)(esp_eth_mac_t *mac, uint32_t cmd, void *data); + esp_err_t (*custom_ioctl)(esp_eth_mac_t *mac, int cmd, void *data); /** * @brief Free memory of Ethernet MAC @@ -321,115 +318,6 @@ struct esp_eth_mac_s { esp_err_t (*del)(esp_eth_mac_t *mac); }; -/** - * @brief RMII Clock Mode Options - * - */ -typedef enum { - /** - * @brief Default values configured using Kconfig are going to be used when "Default" selected. - * - * @note May not be supported on all targets. - * - */ - EMAC_CLK_DEFAULT, - - /** - * @brief Input RMII Clock from external. EMAC Clock GPIO number needs to be configured when this option is selected. - * - * @note MAC will get RMII clock from outside. Note that ESP32 only supports GPIO0 to input the RMII clock. - * - */ - EMAC_CLK_EXT_IN, - - /** - * @brief Output RMII Clock from internal (A/M)PLL Clock. EMAC Clock GPIO number needs to be configured when this option is selected. - * - */ - EMAC_CLK_OUT -} emac_rmii_clock_mode_t; - -#if CONFIG_IDF_TARGET_ESP32 -/** - * @brief RMII Clock GPIO number Options for ESP32 - * - */ -typedef enum { - /** - * @brief MAC will get RMII clock from outside at this GPIO. - * - * @note ESP32 only supports GPIO0 to input the RMII clock. - * - */ - EMAC_CLK_IN_GPIO = 0, - - /** - * @brief Output RMII Clock from internal APLL Clock available at GPIO0 - * - * @note GPIO0 can be set to output a pre-divided PLL clock (test only!). Enabling this option will configure GPIO0 to output a 50MHz clock. - * In fact this clock doesn’t have directly relationship with EMAC peripheral. Sometimes this clock won’t work well with your PHY chip. - * You might need to add some extra devices after GPIO0 (e.g. inverter). Note that outputting RMII clock on GPIO0 is an experimental practice. - * If you want the Ethernet to work with WiFi, don’t select GPIO0 output mode for stability. - * - */ - EMAC_APPL_CLK_OUT_GPIO = 0, - - /** - * @brief Output RMII Clock from internal APLL Clock available at GPIO16 - * - */ - EMAC_CLK_OUT_GPIO = 16, - - /** - * @brief Inverted Output RMII Clock from internal APLL Clock available at GPIO17 - * - */ - EMAC_CLK_OUT_180_GPIO = 17 -} emac_rmii_clock_gpio_t; -#else -/** - * @brief RMII Clock GPIO number - * - */ -typedef int emac_rmii_clock_gpio_t; -#endif // CONFIG_IDF_TARGET_ESP32 - -/** - * @brief Ethernet MAC Clock Configuration - * - */ -typedef union { - struct { - // MII interface is not fully implemented... - // Reserved for GPIO number, clock source, etc. in MII mode - } mii; /*!< EMAC MII Clock Configuration */ - struct { - emac_rmii_clock_mode_t clock_mode; /*!< RMII Clock Mode Configuration */ - emac_rmii_clock_gpio_t clock_gpio; /*!< RMII Clock GPIO Configuration */ - } rmii; /*!< EMAC RMII Clock Configuration */ -} eth_mac_clock_config_t; - -#if SOC_EMAC_USE_IO_MUX -/** - * @brief Ethernet MAC MII/RMII data plane GPIO configuration - * - */ -typedef union { - struct { - // MII interface is not fully implemented... - // Reserved for data interface GPIO numbers in MII mode - } mii; /*!< EMAC MII Data GPIO Configuration */ - struct { - int32_t tx_en_num; /*!< TX_EN GPIO number */ - int32_t txd0_num; /*!< TXD0 GPIO number */ - int32_t txd1_num; /*!< TXD1 GPIO number */ - int32_t crs_dv_num; /*!< CRS_DV GPIO number */ - int32_t rxd0_num; /*!< RXD0 GPIO number */ - int32_t rxd1_num; /*!< RXD1 GPIO number */ - } rmii; /*!< EMAC RMII Data GPIO Configuration */ -} eth_mac_dataif_gpio_config_t; -#endif // SOC_EMAC_USE_IO_MUX - /** * @brief Configuration of Ethernet MAC object * @@ -456,327 +344,6 @@ typedef struct { .flags = 0, \ } -#if CONFIG_ETH_USE_ESP32_EMAC -/** -* @brief EMAC specific configuration -* -*/ -typedef struct { - int smi_mdc_gpio_num; /*!< SMI MDC GPIO number, set to -1 could bypass the SMI GPIO configuration */ - int smi_mdio_gpio_num; /*!< SMI MDIO GPIO number, set to -1 could bypass the SMI GPIO configuration */ - eth_data_interface_t interface; /*!< EMAC Data interface to PHY (MII/RMII) */ - eth_mac_clock_config_t clock_config; /*!< EMAC Interface clock configuration */ - eth_mac_dma_burst_len_t dma_burst_len; /*!< EMAC DMA burst length for both Tx and Rx */ - int intr_priority; /*!< EMAC interrupt priority, if set to 0 or a negative value, the driver will try to allocate an interrupt with a default priority */ -#if SOC_EMAC_USE_IO_MUX - eth_mac_dataif_gpio_config_t emac_dataif_gpio; /*!< EMAC MII/RMII data plane GPIO configuration */ -#endif // SOC_EMAC_USE_IO_MUX -#if !SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK - eth_mac_clock_config_t clock_config_out_in; /*!< EMAC input clock configuration for internally generated output clock (when output clock is looped back externally) */ -#endif //SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK -} eth_esp32_emac_config_t; - -/** - * @brief Default ESP32's EMAC specific configuration - * - */ -#if CONFIG_IDF_TARGET_ESP32 -#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \ - { \ - .smi_mdc_gpio_num = 23, \ - .smi_mdio_gpio_num = 18, \ - .interface = EMAC_DATA_INTERFACE_RMII, \ - .clock_config = \ - { \ - .rmii = \ - { \ - .clock_mode = EMAC_CLK_DEFAULT, \ - .clock_gpio = EMAC_CLK_IN_GPIO \ - } \ - }, \ - .dma_burst_len = ETH_DMA_BURST_LEN_32, \ - .intr_priority = 0, \ - } -#elif CONFIG_IDF_TARGET_ESP32P4 -#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \ - { \ - .smi_mdc_gpio_num = 31, \ - .smi_mdio_gpio_num = 27, \ - .interface = EMAC_DATA_INTERFACE_RMII, \ - .clock_config = \ - { \ - .rmii = \ - { \ - .clock_mode = EMAC_CLK_EXT_IN, \ - .clock_gpio = 50 \ - } \ - }, \ - .clock_config_out_in = \ - { \ - .rmii = \ - { \ - .clock_mode = EMAC_CLK_DEFAULT, \ - .clock_gpio = -1 \ - } \ - }, \ - .dma_burst_len = ETH_DMA_BURST_LEN_32, \ - .intr_priority = 0, \ - .emac_dataif_gpio = \ - { \ - .rmii = \ - { \ - .tx_en_num = 49, \ - .txd0_num = 34, \ - .txd1_num = 35, \ - .crs_dv_num = 28, \ - .rxd0_num = 29, \ - .rxd1_num = 30 \ - } \ - }, \ - } -#endif // CONFIG_IDF_TARGET_ESP32P4 - - -/** -* @brief Create ESP32 Ethernet MAC instance -* -* @param esp32_config: EMAC specific configuration -* @param config: Ethernet MAC configuration -* -* @return -* - instance: create MAC instance successfully -* - NULL: create MAC instance failed because some error occurred -*/ -esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_esp32_emac_config_t *esp32_config, const eth_mac_config_t *config); -#endif // CONFIG_ETH_USE_ESP32_EMAC - -#if CONFIG_ETH_USE_SPI_ETHERNET -/** - * @brief Custom SPI Driver Configuration. - * This structure declares configuration and callback functions to access Ethernet SPI module via - * user's custom SPI driver. - * - */ -typedef struct -{ - /** - * @brief Custom driver specific configuration data used by `init()` function. - * - * @note Type and its content is fully under user's control - * - */ - void *config; - - /** - * @brief Custom driver SPI Initialization - * - * @param[in] spi_config: Custom driver specific configuration - * - * @return - * - spi_ctx: when initialization is successful, a pointer to context structure holding all variables - * needed for subsequent SPI access operations (e.g. SPI bus identification, mutexes, etc.) - * - NULL: driver initialization failed - * - * @note return type and its content is fully under user's control - */ - void *(*init)(const void *spi_config); - - /** - * @brief Custom driver De-initialization - * - * @param[in] spi_ctx: a pointer to driver specific context structure - * - * @return - * - ESP_OK: driver de-initialization was successful - * - ESP_FAIL: driver de-initialization failed - * - any other failure codes are allowed to be used to provide failure isolation - */ - esp_err_t (*deinit)(void *spi_ctx); - - /** - * @brief Custom driver SPI read - * - * @note The read function is responsible to construct command, address and data fields - * of the SPI frame in format expected by particular SPI Ethernet module - * - * @param[in] spi_ctx: a pointer to driver specific context structure - * @param[in] cmd: command - * @param[in] addr: register address - * @param[out] data: read data - * @param[in] data_len: read data length in bytes - * - * @return - * - ESP_OK: read was successful - * - ESP_FAIL: read failed - * - any other failure codes are allowed to be used to provide failure isolation - */ - esp_err_t (*read)(void *spi_ctx, uint32_t cmd, uint32_t addr, void *data, uint32_t data_len); - - /** - * @brief Custom driver SPI write - * - * @note The write function is responsible to construct command, address and data fields - * of the SPI frame in format expected by particular SPI Ethernet module - * - * @param[in] spi_ctx: a pointer to driver specific context structure - * @param[in] cmd: command - * @param[in] addr: register address - * @param[in] data: data to write - * @param[in] data_len: length of data to write in bytes - * - * @return - * - ESP_OK: write was successful - * - ESP_FAIL: write failed - * - any other failure codes are allowed to be used to provide failure isolation - */ - esp_err_t (*write)(void *spi_ctx, uint32_t cmd, uint32_t addr, const void *data, uint32_t data_len); -} eth_spi_custom_driver_config_t; - -/** - * @brief Default configuration of the custom SPI driver. - * Internal ESP-IDF SPI Master driver is used by default. - * - */ -#define ETH_DEFAULT_SPI \ - { \ - .config = NULL, \ - .init = NULL, \ - .deinit = NULL, \ - .read = NULL, \ - .write = NULL \ - } -#endif // CONFIG_ETH_USE_SPI_ETHERNET - -#if CONFIG_ETH_SPI_ETHERNET_DM9051 -/** - * @brief DM9051 specific configuration - * - */ -typedef struct { - int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */ - uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */ - spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined) */ - spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined) */ - eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */ -} eth_dm9051_config_t; - -/** - * @brief Default DM9051 specific configuration - * - */ -#define ETH_DM9051_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \ - { \ - .int_gpio_num = 4, \ - .poll_period_ms = 0, \ - .spi_host_id = spi_host, \ - .spi_devcfg = spi_devcfg_p, \ - .custom_spi_driver = ETH_DEFAULT_SPI, \ - } - -/** -* @brief Create DM9051 Ethernet MAC instance -* -* @param dm9051_config: DM9051 specific configuration -* @param mac_config: Ethernet MAC configuration -* -* @return -* - instance: create MAC instance successfully -* - NULL: create MAC instance failed because some error occurred -*/ -esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config, const eth_mac_config_t *mac_config); -#endif // CONFIG_ETH_SPI_ETHERNET_DM9051 - -#if CONFIG_ETH_SPI_ETHERNET_W5500 -/** - * @brief W5500 specific configuration - * - */ -typedef struct { - int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */ - uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */ - spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined)*/ - spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined)*/ - eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */ -} eth_w5500_config_t; - -/** - * @brief Default W5500 specific configuration - * - */ -#define ETH_W5500_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \ - { \ - .int_gpio_num = 4, \ - .poll_period_ms = 0, \ - .spi_host_id = spi_host, \ - .spi_devcfg = spi_devcfg_p, \ - .custom_spi_driver = ETH_DEFAULT_SPI, \ - } - -/** -* @brief Create W5500 Ethernet MAC instance -* -* @param w5500_config: W5500 specific configuration -* @param mac_config: Ethernet MAC configuration -* -* @return -* - instance: create MAC instance successfully -* - NULL: create MAC instance failed because some error occurred -*/ -esp_eth_mac_t *esp_eth_mac_new_w5500(const eth_w5500_config_t *w5500_config, const eth_mac_config_t *mac_config); -#endif // CONFIG_ETH_SPI_ETHERNET_W5500 - -#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL -/** - * @brief KSZ8851SNL specific configuration - * - */ -typedef struct { - int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */ - uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */ - spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined) */ - spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined) */ - eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */ -} eth_ksz8851snl_config_t; - -/** - * @brief Default KSZ8851SNL specific configuration - * - */ -#define ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \ - { \ - .int_gpio_num = 4, \ - .poll_period_ms = 0, \ - .spi_host_id = spi_host, \ - .spi_devcfg = spi_devcfg_p, \ - .custom_spi_driver = ETH_DEFAULT_SPI, \ - } - -/** -* @brief Create KSZ8851SNL Ethernet MAC instance -* -* @param ksz8851snl_config: KSZ8851SNL specific configuration -* @param mac_config: Ethernet MAC configuration -* -* @return -* - instance: create MAC instance successfully -* - NULL: create MAC instance failed because some error occurred -*/ -esp_eth_mac_t *esp_eth_mac_new_ksz8851snl(const eth_ksz8851snl_config_t *ksz8851snl_config, const eth_mac_config_t *mac_config); -#endif // CONFIG_ETH_SPI_ETHERNET_KSZ8851 - -#if CONFIG_ETH_USE_OPENETH -/** -* @brief Create OpenCores Ethernet MAC instance -* -* @param config: Ethernet MAC configuration -* -* @return -* - instance: create MAC instance successfully -* - NULL: create MAC instance failed because some error occurred -*/ -esp_eth_mac_t *esp_eth_mac_new_openeth(const eth_mac_config_t *config); -#endif // CONFIG_ETH_USE_OPENETH - #ifdef __cplusplus } #endif diff --git a/components/esp_eth/include/esp_eth_mac_esp.h b/components/esp_eth/include/esp_eth_mac_esp.h new file mode 100644 index 000000000000..8c4909b8c559 --- /dev/null +++ b/components/esp_eth/include/esp_eth_mac_esp.h @@ -0,0 +1,296 @@ +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "soc/soc_caps.h" +#include "esp_eth_com.h" +#include "esp_eth_mac.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_ETH_USE_ESP32_EMAC + +/** + * @brief RMII Clock Mode Options + * + */ +typedef enum { + /** + * @brief Default values configured using Kconfig are going to be used when "Default" selected. + * + * @warning Deprecated option. Clock configuration using Kconfig is limitedly supported only for ESP32 SoC via @c ETH_ESP32_EMAC_DEFAULT_CONFIG + * and is going to be reevaluated in the next major release. + * Clock mode and clock GPIO number is supposed to be defined in `EMAC specific configuration` structure from user's code. + * + */ + EMAC_CLK_DEFAULT __attribute__((deprecated)), // IDF-9724 + + /** + * @brief Input RMII Clock from external. EMAC Clock GPIO number needs to be configured when this option is selected. + * + * @note MAC will get RMII clock from outside. Note that ESP32 only supports GPIO0 to input the RMII clock. + * + */ + EMAC_CLK_EXT_IN, + + /** + * @brief Output RMII Clock from internal (A/M)PLL Clock. EMAC Clock GPIO number needs to be configured when this option is selected. + * + */ + EMAC_CLK_OUT +} emac_rmii_clock_mode_t; + +#if CONFIG_IDF_TARGET_ESP32 +/** + * @brief RMII Clock GPIO number Options for ESP32 + * + */ +typedef enum { + /** + * @brief MAC will get RMII clock from outside at this GPIO. + * + * @note ESP32 only supports GPIO0 to input the RMII clock. + * + */ + EMAC_CLK_IN_GPIO = 0, + + /** + * @brief Output RMII Clock from internal APLL Clock available at GPIO0 + * + * @note GPIO0 can be set to output a pre-divided PLL clock (test only!). Enabling this option will configure GPIO0 to output a 50MHz clock. + * In fact this clock doesn’t have directly relationship with EMAC peripheral. Sometimes this clock won’t work well with your PHY chip. + * You might need to add some extra devices after GPIO0 (e.g. inverter). Note that outputting RMII clock on GPIO0 is an experimental practice. + * If you want the Ethernet to work with WiFi, don’t select GPIO0 output mode for stability. + * + */ + EMAC_APPL_CLK_OUT_GPIO = 0, + + /** + * @brief Output RMII Clock from internal APLL Clock available at GPIO16 + * + */ + EMAC_CLK_OUT_GPIO = 16, + + /** + * @brief Inverted Output RMII Clock from internal APLL Clock available at GPIO17 + * + */ + EMAC_CLK_OUT_180_GPIO = 17 +} emac_rmii_clock_gpio_t; +#else +/** + * @brief RMII Clock GPIO number + * + */ +typedef int emac_rmii_clock_gpio_t; +#endif // CONFIG_IDF_TARGET_ESP32 + +/** + * @brief Ethernet MAC Clock Configuration + * + */ +typedef union { + struct { + // MII interface is not fully implemented... + // Reserved for GPIO number, clock source, etc. in MII mode + } mii; /*!< EMAC MII Clock Configuration */ + struct { + emac_rmii_clock_mode_t clock_mode; /*!< RMII Clock Mode Configuration */ + emac_rmii_clock_gpio_t clock_gpio; /*!< RMII Clock GPIO Configuration */ + } rmii; /*!< EMAC RMII Clock Configuration */ +} eth_mac_clock_config_t; + +/** + * @brief EMAC SMI GPIO configuration + */ +typedef struct { + int mdc_num; /*!< SMI MDC GPIO number, set to -1 could bypass the SMI GPIO configuration */ + int mdio_num; /*!< SMI MDIO GPIO number, set to -1 could bypass the SMI GPIO configuration */ +} emac_esp_smi_gpio_config_t; + +/** + * @brief EMAC MII data interface GPIO configuration + */ +typedef struct { + int tx_clk_num; /*!< TX_CLK GPIO number */ + int tx_en_num; /*!< TX_EN GPIO number */ + int txd0_num; /*!< TXD0 GPIO number */ + int txd1_num; /*!< TXD1 GPIO number */ + int txd2_num; /*!< TXD2 GPIO number */ + int txd3_num; /*!< TXD3 GPIO number */ + int rx_clk_num; /*!< RX_CLK GPIO number */ + int rx_dv_num; /*!< RX_DV GPIO number */ + int rxd0_num; /*!< RXD0 GPIO number */ + int rxd1_num; /*!< RXD1 GPIO number */ + int rxd2_num; /*!< RXD2 GPIO number */ + int rxd3_num; /*!< RXD3 GPIO number */ + int col_in_num; /*!< COL_IN GPIO number */ + int crs_in_num; /*!< CRS_IN GPIO number */ + int tx_er_num; /*!< TX_ER GPIO number */ + int rx_er_num; /*!< RX_ER GPIO number */ +} eth_mac_mii_gpio_config_t; + +/** + * @brief EMAC RMII data interface GPIO configuration + */ +typedef struct { + int tx_en_num; /*!< TX_EN GPIO number */ + int txd0_num; /*!< TXD0 GPIO number */ + int txd1_num; /*!< TXD1 GPIO number */ + int crs_dv_num; /*!< CRS_DV GPIO number */ + int rxd0_num; /*!< RXD0 GPIO number */ + int rxd1_num; /*!< RXD1 GPIO number */ +} eth_mac_rmii_gpio_config_t; + +#if SOC_EMAC_USE_MULTI_IO_MUX || SOC_EMAC_MII_USE_GPIO_MATRIX +/** + * @brief Ethernet MAC MII/RMII data plane GPIO configuration + * + */ +typedef union { + eth_mac_mii_gpio_config_t mii; /*!< EMAC MII Data GPIO Configuration */ + eth_mac_rmii_gpio_config_t rmii; /*!< EMAC RMII Data GPIO Configuration */ +} eth_mac_dataif_gpio_config_t; +#endif // SOC_EMAC_USE_MULTI_IO_MUX + +/** +* @brief EMAC specific configuration +* +*/ +typedef struct { + union { + emac_esp_smi_gpio_config_t smi_gpio; /*!< SMI GPIO numbers */ + struct { + int smi_mdc_gpio_num __attribute__((deprecated("Please use smi_gpio instead"))); /*!< SMI MDC GPIO number, set to -1 could bypass the SMI GPIO configuration */ + int smi_mdio_gpio_num __attribute__((deprecated("Please use smi_gpio instead"))); /*!< SMI MDIO GPIO number, set to -1 could bypass the SMI GPIO configuration */ + }; + }; + eth_data_interface_t interface; /*!< EMAC Data interface to PHY (MII/RMII) */ + eth_mac_clock_config_t clock_config; /*!< EMAC Interface clock configuration */ + eth_mac_dma_burst_len_t dma_burst_len; /*!< EMAC DMA burst length for both Tx and Rx */ + int intr_priority; /*!< EMAC interrupt priority, if set to 0 or a negative value, the driver will try to allocate an interrupt with a default priority */ +#if SOC_EMAC_USE_MULTI_IO_MUX || SOC_EMAC_MII_USE_GPIO_MATRIX + eth_mac_dataif_gpio_config_t emac_dataif_gpio; /*!< EMAC MII/RMII data plane GPIO configuration */ +#endif // SOC_EMAC_USE_MULTI_IO_MUX +#if !SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK + eth_mac_clock_config_t clock_config_out_in; /*!< EMAC input clock configuration for internally generated output clock (when output clock is looped back externally) */ +#endif //SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK +} eth_esp32_emac_config_t; + +/** + * @brief List of ESP EMAC specific commands for ioctl API + * + */ +typedef enum { + ETH_MAC_ESP_CMD_SET_TDES0_CFG_BITS = ETH_CMD_CUSTOM_MAC_CMDS_OFFSET, /*!< Set Transmit Descriptor Word 0 control bit mask (debug option)*/ + ETH_MAC_ESP_CMD_CLEAR_TDES0_CFG_BITS, /*!< Clear Transmit Descriptor Word 0 control bit mask (debug option)*/ + ETH_MAC_ESP_CMD_PTP_ENABLE, /*!< Enable IEEE1588 Time stamping */ +} eth_mac_esp_io_cmd_t; + +/** + * @brief Default ESP32's EMAC specific configuration + * + */ +#if CONFIG_IDF_TARGET_ESP32 +#if CONFIG_ETH_RMII_CLK_INPUT // IDF-9724 + #define DEFAULT_RMII_CLK_MODE EMAC_CLK_EXT_IN +#if CONFIG_ETH_RMII_CLK_IN_GPIO == 0 + #define DEFAULT_RMII_CLK_GPIO CONFIG_ETH_RMII_CLK_IN_GPIO +#else + #error "ESP32 EMAC only support input RMII clock to GPIO0" +#endif // CONFIG_ETH_RMII_CLK_IN_GPIO == 0 +#elif CONFIG_ETH_RMII_CLK_OUTPUT + #define DEFAULT_RMII_CLK_MODE EMAC_CLK_OUT +#if CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0 + #define DEFAULT_RMII_CLK_GPIO EMAC_APPL_CLK_OUT_GPIO +#else + #define DEFAULT_RMII_CLK_GPIO CONFIG_ETH_RMII_CLK_OUT_GPIO +#endif // CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0 +#else +#error "Unsupported RMII clock mode" +#endif // CONFIG_ETH_RMII_CLK_INPUT + +#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \ + { \ + .smi_gpio = \ + { \ + .mdc_num = 23, \ + .mdio_num = 18 \ + }, \ + .interface = EMAC_DATA_INTERFACE_RMII, \ + .clock_config = \ + { \ + .rmii = \ + { \ + .clock_mode = DEFAULT_RMII_CLK_MODE, \ + .clock_gpio = DEFAULT_RMII_CLK_GPIO \ + } \ + }, \ + .dma_burst_len = ETH_DMA_BURST_LEN_32, \ + .intr_priority = 0, \ + } +#elif CONFIG_IDF_TARGET_ESP32P4 +#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \ + { \ + .smi_gpio = \ + { \ + .mdc_num = 31, \ + .mdio_num = 27 \ + }, \ + .interface = EMAC_DATA_INTERFACE_RMII, \ + .clock_config = \ + { \ + .rmii = \ + { \ + .clock_mode = EMAC_CLK_EXT_IN, \ + .clock_gpio = 50 \ + } \ + }, \ + .clock_config_out_in = \ + { \ + .rmii = \ + { \ + .clock_mode = EMAC_CLK_EXT_IN, \ + .clock_gpio = -1 \ + } \ + }, \ + .dma_burst_len = ETH_DMA_BURST_LEN_32, \ + .intr_priority = 0, \ + .emac_dataif_gpio = \ + { \ + .rmii = \ + { \ + .tx_en_num = 49, \ + .txd0_num = 34, \ + .txd1_num = 35, \ + .crs_dv_num = 28, \ + .rxd0_num = 29, \ + .rxd1_num = 30 \ + } \ + }, \ + } +#endif // CONFIG_IDF_TARGET_ESP32P4 + +/** +* @brief Create ESP32 Ethernet MAC instance +* +* @param esp32_config: EMAC specific configuration +* @param config: Ethernet MAC configuration +* +* @return +* - instance: create MAC instance successfully +* - NULL: create MAC instance failed because some error occurred +*/ +esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_esp32_emac_config_t *esp32_config, const eth_mac_config_t *config); +#endif // CONFIG_ETH_USE_ESP32_EMAC + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_eth/include/esp_eth_mac_openeth.h b/components/esp_eth/include/esp_eth_mac_openeth.h new file mode 100644 index 000000000000..a118a96139aa --- /dev/null +++ b/components/esp_eth/include/esp_eth_mac_openeth.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_eth_com.h" +#include "esp_eth_mac.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_ETH_USE_OPENETH +/** +* @brief Create OpenCores Ethernet MAC instance +* +* @param config: Ethernet MAC configuration +* +* @return +* - instance: create MAC instance successfully +* - NULL: create MAC instance failed because some error occurred +*/ +esp_eth_mac_t *esp_eth_mac_new_openeth(const eth_mac_config_t *config); +#endif // CONFIG_ETH_USE_OPENETH + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_eth/include/esp_eth_mac_spi.h b/components/esp_eth/include/esp_eth_mac_spi.h new file mode 100644 index 000000000000..74f246df724c --- /dev/null +++ b/components/esp_eth/include/esp_eth_mac_spi.h @@ -0,0 +1,236 @@ +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "soc/soc_caps.h" +#include "esp_eth_com.h" +#include "esp_eth_mac.h" +#include "sdkconfig.h" +#include "driver/spi_master.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_ETH_USE_SPI_ETHERNET + +/** + * @brief Custom SPI Driver Configuration. + * This structure declares configuration and callback functions to access Ethernet SPI module via + * user's custom SPI driver. + * + */ +typedef struct +{ + /** + * @brief Custom driver specific configuration data used by `init()` function. + * + * @note Type and its content is fully under user's control + * + */ + void *config; + + /** + * @brief Custom driver SPI Initialization + * + * @param[in] spi_config: Custom driver specific configuration + * + * @return + * - spi_ctx: when initialization is successful, a pointer to context structure holding all variables + * needed for subsequent SPI access operations (e.g. SPI bus identification, mutexes, etc.) + * - NULL: driver initialization failed + * + * @note return type and its content is fully under user's control + */ + void *(*init)(const void *spi_config); + + /** + * @brief Custom driver De-initialization + * + * @param[in] spi_ctx: a pointer to driver specific context structure + * + * @return + * - ESP_OK: driver de-initialization was successful + * - ESP_FAIL: driver de-initialization failed + * - any other failure codes are allowed to be used to provide failure isolation + */ + esp_err_t (*deinit)(void *spi_ctx); + + /** + * @brief Custom driver SPI read + * + * @note The read function is responsible to construct command, address and data fields + * of the SPI frame in format expected by particular SPI Ethernet module + * + * @param[in] spi_ctx: a pointer to driver specific context structure + * @param[in] cmd: command + * @param[in] addr: register address + * @param[out] data: read data + * @param[in] data_len: read data length in bytes + * + * @return + * - ESP_OK: read was successful + * - ESP_FAIL: read failed + * - any other failure codes are allowed to be used to provide failure isolation + */ + esp_err_t (*read)(void *spi_ctx, uint32_t cmd, uint32_t addr, void *data, uint32_t data_len); + + /** + * @brief Custom driver SPI write + * + * @note The write function is responsible to construct command, address and data fields + * of the SPI frame in format expected by particular SPI Ethernet module + * + * @param[in] spi_ctx: a pointer to driver specific context structure + * @param[in] cmd: command + * @param[in] addr: register address + * @param[in] data: data to write + * @param[in] data_len: length of data to write in bytes + * + * @return + * - ESP_OK: write was successful + * - ESP_FAIL: write failed + * - any other failure codes are allowed to be used to provide failure isolation + */ + esp_err_t (*write)(void *spi_ctx, uint32_t cmd, uint32_t addr, const void *data, uint32_t data_len); +} eth_spi_custom_driver_config_t; + +/** + * @brief Default configuration of the custom SPI driver. + * Internal ESP-IDF SPI Master driver is used by default. + * + */ +#define ETH_DEFAULT_SPI \ + { \ + .config = NULL, \ + .init = NULL, \ + .deinit = NULL, \ + .read = NULL, \ + .write = NULL \ + } +#endif // CONFIG_ETH_USE_SPI_ETHERNET + +#if CONFIG_ETH_SPI_ETHERNET_DM9051 +/** + * @brief DM9051 specific configuration + * + */ +typedef struct { + int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */ + uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */ + spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined) */ + spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined) */ + eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */ +} eth_dm9051_config_t; + +/** + * @brief Default DM9051 specific configuration + * + */ +#define ETH_DM9051_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \ + { \ + .int_gpio_num = 4, \ + .poll_period_ms = 0, \ + .spi_host_id = spi_host, \ + .spi_devcfg = spi_devcfg_p, \ + .custom_spi_driver = ETH_DEFAULT_SPI, \ + } + +/** +* @brief Create DM9051 Ethernet MAC instance +* +* @param dm9051_config: DM9051 specific configuration +* @param mac_config: Ethernet MAC configuration +* +* @return +* - instance: create MAC instance successfully +* - NULL: create MAC instance failed because some error occurred +*/ +esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config, const eth_mac_config_t *mac_config); +#endif // CONFIG_ETH_SPI_ETHERNET_DM9051 + +#if CONFIG_ETH_SPI_ETHERNET_W5500 +/** + * @brief W5500 specific configuration + * + */ +typedef struct { + int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */ + uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */ + spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined)*/ + spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined)*/ + eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */ +} eth_w5500_config_t; + +/** + * @brief Default W5500 specific configuration + * + */ +#define ETH_W5500_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \ + { \ + .int_gpio_num = 4, \ + .poll_period_ms = 0, \ + .spi_host_id = spi_host, \ + .spi_devcfg = spi_devcfg_p, \ + .custom_spi_driver = ETH_DEFAULT_SPI, \ + } + +/** +* @brief Create W5500 Ethernet MAC instance +* +* @param w5500_config: W5500 specific configuration +* @param mac_config: Ethernet MAC configuration +* +* @return +* - instance: create MAC instance successfully +* - NULL: create MAC instance failed because some error occurred +*/ +esp_eth_mac_t *esp_eth_mac_new_w5500(const eth_w5500_config_t *w5500_config, const eth_mac_config_t *mac_config); +#endif // CONFIG_ETH_SPI_ETHERNET_W5500 + +#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL +/** + * @brief KSZ8851SNL specific configuration + * + */ +typedef struct { + int int_gpio_num; /*!< Interrupt GPIO number, set -1 to not use interrupt and to poll rx status periodically */ + uint32_t poll_period_ms; /*!< Period in ms to poll rx status when interrupt mode is not used */ + spi_host_device_t spi_host_id; /*!< SPI peripheral (this field is invalid when custom SPI driver is defined) */ + spi_device_interface_config_t *spi_devcfg; /*!< SPI device configuration (this field is invalid when custom SPI driver is defined) */ + eth_spi_custom_driver_config_t custom_spi_driver; /*!< Custom SPI driver definitions */ +} eth_ksz8851snl_config_t; + +/** + * @brief Default KSZ8851SNL specific configuration + * + */ +#define ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_host, spi_devcfg_p) \ + { \ + .int_gpio_num = 4, \ + .poll_period_ms = 0, \ + .spi_host_id = spi_host, \ + .spi_devcfg = spi_devcfg_p, \ + .custom_spi_driver = ETH_DEFAULT_SPI, \ + } + +/** +* @brief Create KSZ8851SNL Ethernet MAC instance +* +* @param ksz8851snl_config: KSZ8851SNL specific configuration +* @param mac_config: Ethernet MAC configuration +* +* @return +* - instance: create MAC instance successfully +* - NULL: create MAC instance failed because some error occurred +*/ +esp_eth_mac_t *esp_eth_mac_new_ksz8851snl(const eth_ksz8851snl_config_t *ksz8851snl_config, const eth_mac_config_t *mac_config); +#endif // CONFIG_ETH_SPI_ETHERNET_KSZ8851 + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_eth/include/esp_eth_phy.h b/components/esp_eth/include/esp_eth_phy.h index 07bcf8fb9307..82c16aef41d0 100644 --- a/components/esp_eth/include/esp_eth_phy.h +++ b/components/esp_eth/include/esp_eth_phy.h @@ -16,7 +16,7 @@ extern "C" { #define ESP_ETH_PHY_ADDR_AUTO (-1) /** - * @brief Auto-negotiation controll commands + * @brief Auto-negotiation control commands * */ typedef enum { @@ -253,7 +253,7 @@ struct esp_eth_phy_s { * - ESP_FAIL: process io command failed because some other error occurred * - ESP_ERR_NOT_SUPPORTED: requested feature is not supported */ - esp_err_t (*custom_ioctl)(esp_eth_phy_t *phy, uint32_t cmd, void *data); + esp_err_t (*custom_ioctl)(esp_eth_phy_t *phy, int cmd, void *data); /** * @brief Free memory of Ethernet PHY instance diff --git a/components/esp_eth/include/esp_eth_phy_802_3.h b/components/esp_eth/include/esp_eth_phy_802_3.h index 4d1b022f797d..0cc83ed1390c 100644 --- a/components/esp_eth/include/esp_eth_phy_802_3.h +++ b/components/esp_eth/include/esp_eth_phy_802_3.h @@ -6,7 +6,7 @@ #pragma once #include -#include "esp_eth.h" +#include "esp_eth_phy.h" #include "sdkconfig.h" #include "eth_phy_802_3_regs.h" @@ -45,7 +45,7 @@ typedef enum { * @param phy_802_3 IEEE 802.3 PHY object infostructure * @param eth Ethernet mediator pointer * @return - * - ESP_OK: Ethermet mediator set successfuly + * - ESP_OK: Ethermet mediator set successfully * - ESP_ERR_INVALID_ARG: if @c eth is @c NULL */ esp_err_t esp_eth_phy_802_3_set_mediator(phy_802_3_t *phy_802_3, esp_eth_mediator_t *eth); @@ -55,8 +55,8 @@ esp_err_t esp_eth_phy_802_3_set_mediator(phy_802_3_t *phy_802_3, esp_eth_mediato * * @param phy_802_3 IEEE 802.3 PHY object infostructure * @return - * - ESP_OK: Ethernet PHY reset successfuly - * - ESP_FAIL: reset Ethernet PHY failed because some error occured + * - ESP_OK: Ethernet PHY reset successfully + * - ESP_FAIL: reset Ethernet PHY failed because some error occurred */ esp_err_t esp_eth_phy_802_3_reset(phy_802_3_t *phy_802_3); @@ -67,8 +67,8 @@ esp_err_t esp_eth_phy_802_3_reset(phy_802_3_t *phy_802_3); * @param cmd autonegotiation command enumeration * @param[out] autonego_en_stat autonegotiation enabled flag * @return - * - ESP_OK: Ethernet PHY autonegotiation configured successfuly - * - ESP_FAIL: Ethernet PHY autonegotiation configuration fail because some error occured + * - ESP_OK: Ethernet PHY autonegotiation configured successfully + * - ESP_FAIL: Ethernet PHY autonegotiation configuration fail because some error occurred * - ESP_ERR_INVALID_ARG: invalid value of @c cmd */ esp_err_t esp_eth_phy_802_3_autonego_ctrl(phy_802_3_t *phy_802_3, eth_phy_autoneg_cmd_t cmd, bool *autonego_en_stat); @@ -79,8 +79,8 @@ esp_err_t esp_eth_phy_802_3_autonego_ctrl(phy_802_3_t *phy_802_3, eth_phy_autone * @param phy_802_3 IEEE 802.3 PHY object infostructure * @param enable set true to power ON Ethernet PHY; set false to power OFF Ethernet PHY * @return - * - ESP_OK: Ethernet PHY power down mode set successfuly - * - ESP_FAIL: Ethernet PHY power up or power down failed because some error occured + * - ESP_OK: Ethernet PHY power down mode set successfully + * - ESP_FAIL: Ethernet PHY power up or power down failed because some error occurred */ esp_err_t esp_eth_phy_802_3_pwrctl(phy_802_3_t *phy_802_3, bool enable); @@ -100,7 +100,7 @@ esp_err_t esp_eth_phy_802_3_set_addr(phy_802_3_t *phy_802_3, uint32_t addr); * @param phy_802_3 IEEE 802.3 PHY object infostructure * @param[out] addr Ethernet PHY address * @return - * - ESP_OK: Ethernet PHY address read successfuly + * - ESP_OK: Ethernet PHY address read successfully * - ESP_ERR_INVALID_ARG: @c addr pointer is @c NULL */ esp_err_t esp_eth_phy_802_3_get_addr(phy_802_3_t *phy_802_3, uint32_t *addr); @@ -111,8 +111,8 @@ esp_err_t esp_eth_phy_802_3_get_addr(phy_802_3_t *phy_802_3, uint32_t *addr); * @param phy_802_3 IEEE 802.3 PHY object infostructure * @param ability enable or disable pause ability * @return - * - ESP_OK: pause ability set successfuly - * - ESP_FAIL: Advertise pause function ability failed because some error occured + * - ESP_OK: pause ability set successfully + * - ESP_FAIL: Advertise pause function ability failed because some error occurred */ esp_err_t esp_eth_phy_802_3_advertise_pause_ability(phy_802_3_t *phy_802_3, uint32_t ability); @@ -122,8 +122,8 @@ esp_err_t esp_eth_phy_802_3_advertise_pause_ability(phy_802_3_t *phy_802_3, uint * @param phy_802_3 IEEE 802.3 PHY object infostructure * @param enable set true to enable loopback; set false to disable loopback * @return - * - ESP_OK: Ethernet PHY loopback mode set successfuly - * - ESP_FAIL: Ethernet PHY loopback configuration failed because some error occured + * - ESP_OK: Ethernet PHY loopback mode set successfully + * - ESP_FAIL: Ethernet PHY loopback configuration failed because some error occurred */ esp_err_t esp_eth_phy_802_3_loopback(phy_802_3_t *phy_802_3, bool enable); @@ -133,8 +133,8 @@ esp_err_t esp_eth_phy_802_3_loopback(phy_802_3_t *phy_802_3, bool enable); * @param phy_802_3 IEEE 802.3 PHY object infostructure * @param speed new speed of Ethernet PHY link * @return - * - ESP_OK: Ethernet PHY speed set successfuly - * - ESP_FAIL: Set Ethernet PHY speed failed because some error occured + * - ESP_OK: Ethernet PHY speed set successfully + * - ESP_FAIL: Set Ethernet PHY speed failed because some error occurred */ esp_err_t esp_eth_phy_802_3_set_speed(phy_802_3_t *phy_802_3, eth_speed_t speed); @@ -144,9 +144,9 @@ esp_err_t esp_eth_phy_802_3_set_speed(phy_802_3_t *phy_802_3, eth_speed_t speed) * @param phy_802_3 IEEE 802.3 PHY object infostructure * @param duplex new duplex mode for Ethernet PHY link * @return - * - ESP_OK: Ethernet PHY duplex mode set successfuly + * - ESP_OK: Ethernet PHY duplex mode set successfully * - ESP_ERR_INVALID_STATE: unable to set duplex mode to Half if loopback is enabled - * - ESP_FAIL: Set Ethernet PHY duplex mode failed because some error occured + * - ESP_FAIL: Set Ethernet PHY duplex mode failed because some error occurred */ esp_err_t esp_eth_phy_802_3_set_duplex(phy_802_3_t *phy_802_3, eth_duplex_t duplex); @@ -156,7 +156,7 @@ esp_err_t esp_eth_phy_802_3_set_duplex(phy_802_3_t *phy_802_3, eth_duplex_t dupl * @param phy_802_3 IEEE 802.3 PHY object infostructure * @param link new link status * @return - * - ESP_OK: Ethernet PHY link set successfuly + * - ESP_OK: Ethernet PHY link set successfully */ esp_err_t esp_eth_phy_802_3_set_link(phy_802_3_t *phy_802_3, eth_link_t link); @@ -165,7 +165,7 @@ esp_err_t esp_eth_phy_802_3_set_link(phy_802_3_t *phy_802_3, eth_link_t link); * * @param phy_802_3 IEEE 802.3 PHY object infostructure * @return - * - ESP_OK: Ethernet PHY initialized successfuly + * - ESP_OK: Ethernet PHY initialized successfully */ esp_err_t esp_eth_phy_802_3_init(phy_802_3_t *phy_802_3); @@ -174,7 +174,7 @@ esp_err_t esp_eth_phy_802_3_init(phy_802_3_t *phy_802_3); * * @param phy_802_3 IEEE 802.3 PHY object infostructure * @return - * - ESP_OK: Ethernet PHY powered off successfuly + * - ESP_OK: Ethernet PHY powered off successfully */ esp_err_t esp_eth_phy_802_3_deinit(phy_802_3_t *phy_802_3); @@ -275,8 +275,8 @@ esp_err_t esp_eth_phy_802_3_read_manufac_info(phy_802_3_t *phy_802_3, uint8_t *m * @param devaddr Address of MDIO device * @param[out] mmd_addr Current address stored in device's register * @return - * - ESP_OK: Address register read successfuly - * - ESP_FAIL: Address register read failed because of some error occured + * - ESP_OK: Address register read successfully + * - ESP_FAIL: Address register read failed because of some error occurred * - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits) */ esp_err_t esp_eth_phy_802_3_get_mmd_addr(phy_802_3_t *phy_802_3, uint8_t devaddr, uint16_t *mmd_addr); @@ -288,8 +288,8 @@ esp_err_t esp_eth_phy_802_3_get_mmd_addr(phy_802_3_t *phy_802_3, uint8_t devaddr * @param devaddr Address of MDIO device * @param[out] mmd_addr New value of MDIO device's address register value * @return - * - ESP_OK: Address register written to successfuly - * - ESP_FAIL: Address register write failed because of some error occured + * - ESP_OK: Address register written to successfully + * - ESP_FAIL: Address register write failed because of some error occurred * - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits) */ esp_err_t esp_eth_phy_802_3_set_mmd_addr(phy_802_3_t *phy_802_3, uint8_t devaddr, uint16_t mmd_addr); @@ -302,8 +302,8 @@ esp_err_t esp_eth_phy_802_3_set_mmd_addr(phy_802_3_t *phy_802_3, uint8_t devaddr * @param function MMD function * @param[out] data Data read from the device's memory * @return - * - ESP_OK: Memory read successfuly - * - ESP_FAIL: Memory read failed because of some error occured + * - ESP_OK: Memory read successfully + * - ESP_FAIL: Memory read failed because of some error occurred * - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits) or MMD access function is invalid */ esp_err_t esp_eth_phy_802_3_read_mmd_data(phy_802_3_t *phy_802_3, uint8_t devaddr, esp_eth_phy_802_3_mmd_func_t function, uint32_t *data); @@ -316,8 +316,8 @@ esp_err_t esp_eth_phy_802_3_read_mmd_data(phy_802_3_t *phy_802_3, uint8_t devadd * @param function MMD function * @param[out] data Data to write to the device's memory * @return - * - ESP_OK: Memory written successfuly - * - ESP_FAIL: Memory write failed because of some error occured + * - ESP_OK: Memory written successfully + * - ESP_FAIL: Memory write failed because of some error occurred * - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits) or MMD access function is invalid */ esp_err_t esp_eth_phy_802_3_write_mmd_data(phy_802_3_t *phy_802_3, uint8_t devaddr, esp_eth_phy_802_3_mmd_func_t function, uint32_t data); @@ -330,8 +330,8 @@ esp_err_t esp_eth_phy_802_3_write_mmd_data(phy_802_3_t *phy_802_3, uint8_t devad * @param mmd_addr Address of MDIO device register * @param[out] data Data read from the device's memory * @return - * - ESP_OK: Memory read successfuly - * - ESP_FAIL: Memory read failed because of some error occured + * - ESP_OK: Memory read successfully + * - ESP_FAIL: Memory read failed because of some error occurred * - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits) */ esp_err_t esp_eth_phy_802_3_read_mmd_register(phy_802_3_t *phy_802_3, uint8_t devaddr, uint16_t mmd_addr, uint32_t *data); @@ -344,8 +344,8 @@ esp_err_t esp_eth_phy_802_3_read_mmd_register(phy_802_3_t *phy_802_3, uint8_t de * @param mmd_addr Address of MDIO device register * @param[out] data Data to write to the device's memory * @return - * - ESP_OK: Memory written to successfuly - * - ESP_FAIL: Memory write failed because of some error occured + * - ESP_OK: Memory written to successfully + * - ESP_FAIL: Memory write failed because of some error occurred * - ESP_ERR_INVALID_ARG: Device address provided is out of range (hardware limits device address to 5 bits) */ esp_err_t esp_eth_phy_802_3_write_mmd_register(phy_802_3_t *phy_802_3, uint8_t devaddr, uint16_t mmd_addr, uint32_t data); diff --git a/components/esp_eth/include/esp_private/eth_mac_esp_dma.h b/components/esp_eth/include/esp_private/eth_mac_esp_dma.h index 9d363c4ebf87..3fc496534cce 100644 --- a/components/esp_eth/include/esp_private/eth_mac_esp_dma.h +++ b/components/esp_eth/include/esp_private/eth_mac_esp_dma.h @@ -15,20 +15,144 @@ extern "C" { * @brief Indicate to ::emac_esp_dma_receive_frame that receive frame buffer was allocated by ::emac_esp_dma_alloc_recv_buf * */ -#define EMAC_HAL_BUF_SIZE_AUTO 0 +#define EMAC_DMA_BUF_SIZE_AUTO 0 +/** + * @brief EMAC DMA handle + * + */ typedef struct emac_esp_dma_t *emac_esp_dma_handle_t; -typedef void *emac_esp_dma_config_t; -void emac_esp_dma_reset_desc_chain(emac_esp_dma_handle_t emac_esp_dma); +/** + * @brief EMAC DMA configuration + * @note Currently just a placeholder + * + */ +typedef struct emac_esp_dma_config_t emac_esp_dma_config_t; + +/** + * @brief Reset DMA + * @note This function should be called prior each EMAC start + * + * @param[in] emac_esp_dma EMAC DMA handle + */ +void emac_esp_dma_reset(emac_esp_dma_handle_t emac_esp_dma); + +/** + * @brief Transmit data from buffer over EMAC + * + * @param[in] emac_esp_dma EMAC DMA handle + * @param[in] buf buffer to be transmitted + * @param[in] length length of the buffer + * @return number of transmitted bytes on success + * zero on fail + */ uint32_t emac_esp_dma_transmit_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t length); + +/** + * @brief Transmit data from multiple buffers over EMAC in single Ethernet frame. Data will be joint into + * single frame in order in which the buffers are stored in input array. + * + * @param[in] emac_esp_dma EMAC DMA handle + * @param[in] buffs array of pointers to buffers to be transmitted + * @param[in] lengths array of lengths of the buffers + * @param[in] inbuffs_cnt number of buffers (i.e. input arrays size) + * @return number of transmitted bytes on success + * zero on fail + * + * @pre @p lengths array must have the same size as @p buffs array and their elements need to be stored in the same + * order, i.e. lengths[1] is a length associated with data buffer referenced at buffs[1] position. + */ uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t **buffs, uint32_t *lengths, uint32_t buffs_cnt); + +/** + * @brief Allocate buffer with size equal to actually received Ethernet frame size. + * + * @param[in] emac_esp_dma EMAC DMA handle + * @param[in, out] size as an input defines maximum size of buffer to be allocated. As an output, indicates actual size of received + * Ethernet frame which is waiting to be processed. Returned size may be 0 when there is no waiting valid frame. + * + * @note If maximum allowed size of buffer to be allocated is less than actual size of received Ethernet frame, the buffer + * is allocated with that limit and the frame will be truncated by emac_hal_receive_frame. + * + * @return Pointer to allocated buffer + * NULL when allocation fails (returned @p size is non-zero) + * NULL when there is no waiting Ethernet frame (returned @p size is zero) + */ uint8_t *emac_esp_dma_alloc_recv_buf(emac_esp_dma_handle_t emac_esp_dma, uint32_t *size); -uint32_t emac_esp_dma_receive_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t size, uint32_t *frames_remain, uint32_t *free_desc); -void emac_esp_dma_flush_recv_frame(emac_esp_dma_handle_t emac_esp_dma, uint32_t *frames_remain, uint32_t *free_desc); +/** + * @brief Copy received Ethernet frame from EMAC DMA memory space to application. + * + * @param[in] emac_esp_dma EMAC DMA handle + * @param[in] buf buffer into which the Ethernet frame is to be copied + * @param[in] size buffer size. When buffer was allocated by ::emac_esp_dma_alloc_recv_buf, this parameter needs to be set + * to @c EMAC_DMA_BUF_SIZE_AUTO + * + * @return - number of copied bytes when success + * - number of bytes of received Ethernet frame when maximum allowed buffer @p size is less than actual size of + * received Ethernet frame and @p size is NOT set to @c EMAC_DMA_BUF_SIZE_AUTO + * - 0 when there is no waiting Ethernet frame or on frame error when @p size is NOT set to @c EMAC_DMA_BUF_SIZE_AUTO + * + * @note When this function is called with @c EMAC_DMA_BUF_SIZE_AUTO size option (preferred), buffer needs to be + * successfully allocated by ::emac_esp_dma_alloc_recv_buf function at first. + * @note When this function is NOT called with @c EMAC_DMA_BUF_SIZE_AUTO size option and maximum allowed buffer @p size + * is less than actual size of received Ethernet frame, the frame will be truncated. + * @note FCS field is never copied + */ +uint32_t emac_esp_dma_receive_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t size); + +/** + * @brief Flush frame stored in Rx DMA + * + * @param[in] emac_esp_dma EMAC DMA handle + */ +void emac_esp_dma_flush_recv_frame(emac_esp_dma_handle_t emac_esp_dma); + +/** + * @brief Get number of frames remaining in Rx DMA + * + * @param[in] emac_esp_dma EMAC DMA handle + * @param[out] frames_remain number of frames remaining to be processed + * @param[out] free_desc number of free DMA Rx descriptors + */ +void emac_esp_dma_get_remain_frames(emac_esp_dma_handle_t emac_esp_dma, uint32_t *remain_frames, uint32_t *used_descs); + +/** + * @brief Set the Transmit Descriptor Word 0 (TDES0) control bits + * + * @param[in] emac_esp_dma EMAC DMA handle + * @param[in] bit_mask mask of control bits to be set + */ +void emac_esp_dma_set_tdes0_ctrl_bits(emac_esp_dma_handle_t emac_esp_dma, uint32_t bit_mask); + +/** + * @brief Clear the Transmit Descriptor Word 0 (TDES0) control bits + * + * @param[in] emac_esp_dma EMAC DMA handle + * @param[in] bit_mask mask of control bits to be cleared + */ +void emac_esp_dma_clear_tdes0_ctrl_bits(emac_esp_dma_handle_t emac_esp_dma, uint32_t bit_mask); + +/** + * @brief Creates a new instance of the ESP EMAC DMA + * + * @param config ESP EMAC DMA configuration + * @param[out] ret_handle EMAC DMA handle + * @return esp_err_t + * ESP_OK on success + * ESP_ERR_NO_MEM when there is not enough memory to allocate instance + */ esp_err_t emac_esp_new_dma(const emac_esp_dma_config_t* config, emac_esp_dma_handle_t *ret_handle); + +/** + * @brief Deletes the ESP EMAC DMA instance + * + * @param[in] emac_esp_dma EMAC DMA handle + * @return esp_err_t + * ESP_OK on success + */ esp_err_t emac_esp_del_dma(emac_esp_dma_handle_t emac_esp_dma); #ifdef __cplusplus diff --git a/components/esp_eth/include/esp_private/eth_mac_esp_gpio.h b/components/esp_eth/include/esp_private/eth_mac_esp_gpio.h index d2c2736575b4..6dbe9bd6efd5 100644 --- a/components/esp_eth/include/esp_private/eth_mac_esp_gpio.h +++ b/components/esp_eth/include/esp_private/eth_mac_esp_gpio.h @@ -10,53 +10,23 @@ extern "C" { #endif #include "esp_err.h" -#include "esp_eth_mac.h" +#include "esp_eth_mac_esp.h" -/** - * @brief EMAC SMI GPIO configuration - */ -typedef struct { - int mdc_num; - int mdio_num; -} emac_esp_smi_gpio_config_t; - -/** - * @brief EMAC MII data interface GPIO configuration - */ -typedef struct { - uint8_t tx_clk_num; - uint8_t tx_en_num; - uint8_t txd0_num; - uint8_t txd1_num; - uint8_t txd2_num; - uint8_t txd3_num; - uint8_t rx_clk_num; - uint8_t rx_dv_num; - uint8_t rxd0_num; - uint8_t rxd1_num; - uint8_t rxd2_num; - uint8_t rxd3_num; -} emac_esp_mii_gpio_config_t; +#if CONFIG_ETH_USE_ESP32_EMAC -/** - * @brief EMAC RMII data interface GPIO configuration - */ -typedef struct { - uint8_t tx_en_num; - uint8_t txd0_num; - uint8_t txd1_num; - uint8_t crs_dv_num; - uint8_t rxd0_num; - uint8_t rxd1_num; -} emac_esp_rmii_gpio_config_t; - -esp_err_t emac_esp_iomux_init_mii(emac_esp_mii_gpio_config_t *mii_gpio); -esp_err_t emac_esp_iomux_init_rmii(emac_esp_rmii_gpio_config_t *rmii_gpio); +esp_err_t emac_esp_gpio_matrix_init_mii(const eth_mac_mii_gpio_config_t *mii_gpio); +esp_err_t emac_esp_iomux_init_mii(const eth_mac_mii_gpio_config_t *mii_gpio); +esp_err_t emac_esp_iomux_init_rmii(const eth_mac_rmii_gpio_config_t *rmii_gpio); esp_err_t emac_esp_iomux_rmii_clk_input(int num); esp_err_t emac_esp_iomux_rmii_clk_ouput(int num); -esp_err_t emac_esp_iomux_init_tx_er(int num); -esp_err_t emac_esp_iomux_init_rx_er(int num); -void emac_esp32_gpio_init_smi(emac_esp_smi_gpio_config_t *smi_gpio); +esp_err_t emac_esp_iomux_rmii_init_tx_er(int num); +esp_err_t emac_esp_iomux_rmii_init_rx_er(int num); +esp_err_t emac_esp_iomux_mii_init_tx_er(int num); +esp_err_t emac_esp_iomux_mii_init_rx_er(int num); +esp_err_t emac_esp_gpio_init_smi(const emac_esp_smi_gpio_config_t *smi_gpio); +esp_err_t emac_esp_gpio_deinit_all(void); + +#endif // CONFIG_ETH_USE_ESP32_EMAC #ifdef __cplusplus } diff --git a/components/esp_eth/src/esp_eth.c b/components/esp_eth/src/esp_eth.c index e776da16d6c5..d9439ca316bf 100644 --- a/components/esp_eth/src/esp_eth.c +++ b/components/esp_eth/src/esp_eth.c @@ -499,6 +499,24 @@ esp_err_t esp_eth_ioctl(esp_eth_handle_t hdl, esp_eth_io_cmd_t cmd, void *data) return ret; } +esp_err_t esp_eth_get_phy_instance(esp_eth_handle_t hdl, esp_eth_phy_t **phy) +{ + esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; + ESP_RETURN_ON_FALSE(eth_driver, ESP_ERR_INVALID_ARG, TAG, "ethernet driver handle can't be null"); + ESP_RETURN_ON_FALSE(phy != NULL, ESP_ERR_INVALID_ARG, TAG, "can't store PHY instance to null"); + *phy = eth_driver->phy; + return ESP_OK; +} + +esp_err_t esp_eth_get_mac_instance(esp_eth_handle_t hdl, esp_eth_mac_t **mac) +{ + esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; + ESP_RETURN_ON_FALSE(eth_driver, ESP_ERR_INVALID_ARG, TAG, "ethernet driver handle can't be null"); + ESP_RETURN_ON_FALSE(mac != NULL, ESP_ERR_INVALID_ARG, TAG, "can't store MAC instance to null"); + *mac = eth_driver->mac; + return ESP_OK; +} + esp_err_t esp_eth_increase_reference(esp_eth_handle_t hdl) { esp_err_t ret = ESP_OK; diff --git a/components/esp_eth/src/esp_eth_mac_esp_gpio.c b/components/esp_eth/src/esp_eth_mac_esp_gpio.c deleted file mode 100644 index b1499ba96aff..000000000000 --- a/components/esp_eth/src/esp_eth_mac_esp_gpio.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "esp_check.h" -#include "sdkconfig.h" -#include "esp_rom_gpio.h" -#include "driver/gpio.h" -#include "soc/soc_caps.h" -#include "soc/gpio_sig_map.h" -#include "soc/io_mux_reg.h" -#include "soc/gpio_periph.h" -#include "esp_private/gpio.h" -#include "esp_private/eth_mac_esp_gpio.h" -#include "esp_log.h" - -static const char *TAG = "esp.emac.gpio"; - -void emac_esp32_gpio_init_smi(emac_esp_smi_gpio_config_t *smi_gpio) -{ - if (smi_gpio->mdc_num >= 0) { - /* Setup SMI MDC GPIO */ - gpio_set_direction(smi_gpio->mdc_num, GPIO_MODE_OUTPUT); -#if CONFIG_IDF_TARGET_ESP32 - esp_rom_gpio_connect_out_signal(smi_gpio->mdc_num, EMAC_MDC_O_IDX, false, false); -#elif CONFIG_IDF_TARGET_ESP32P4 - esp_rom_gpio_connect_out_signal(smi_gpio->mdc_num, GMII_MDC_PAD_OUT_IDX, false, false); -#endif - gpio_func_sel(smi_gpio->mdc_num, PIN_FUNC_GPIO); - } - if (smi_gpio->mdio_num >= 0) { - /* Setup SMI MDIO GPIO */ - gpio_set_direction(smi_gpio->mdio_num, GPIO_MODE_INPUT_OUTPUT); -#if CONFIG_IDF_TARGET_ESP32 - esp_rom_gpio_connect_out_signal(smi_gpio->mdio_num, EMAC_MDO_O_IDX, false, false); - esp_rom_gpio_connect_in_signal(smi_gpio->mdio_num, EMAC_MDI_I_IDX, false); -#elif CONFIG_IDF_TARGET_ESP32P4 - esp_rom_gpio_connect_out_signal(smi_gpio->mdio_num, GMII_MDO_PAD_OUT_IDX, false, false); - esp_rom_gpio_connect_in_signal(smi_gpio->mdio_num, GMII_MDI_PAD_IN_IDX, false); -#endif - gpio_func_sel(smi_gpio->mdio_num, PIN_FUNC_GPIO); - } -} - -esp_err_t emac_esp_iomux_init_mii(emac_esp_mii_gpio_config_t *mii_gpio) -{ - (void)mii_gpio; -#if CONFIG_IDF_TARGET_ESP32 - /* TX_CLK to GPIO0 */ - gpio_func_sel(0, FUNC_GPIO0_EMAC_TX_CLK); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[0]); - /* TX_EN to GPIO21 */ - gpio_func_sel(21, FUNC_GPIO21_EMAC_TX_EN); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[21]); - /* TXD0 to GPIO19 */ - gpio_func_sel(19, FUNC_GPIO19_EMAC_TXD0); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[19]); - /* TXD1 to GPIO22 */ - gpio_func_sel(22, FUNC_GPIO22_EMAC_TXD1); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[22]); - /* TXD2 to MTMS */ - gpio_func_sel(14, FUNC_MTMS_EMAC_TXD2); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[14]); - /* TXD3 to MTDI */ - gpio_func_sel(12, FUNC_MTDI_EMAC_TXD3); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[12]); - - /* RX_CLK to GPIO5 */ - gpio_func_sel(5, FUNC_GPIO5_EMAC_RX_CLK); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[5]); - /* RX_DV to GPIO27 */ - gpio_func_sel(27, FUNC_GPIO27_EMAC_RX_DV); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[27]); - /* RXD0 to GPIO25 */ - gpio_func_sel(25, FUNC_GPIO25_EMAC_RXD0); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[25]); - /* RXD1 to GPIO26 */ - gpio_func_sel(26, FUNC_GPIO26_EMAC_RXD1); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[26]); - /* RXD2 to U0TXD */ - gpio_func_sel(1, FUNC_U0TXD_EMAC_RXD2); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[1]); - /* RXD3 to MTDO */ - gpio_func_sel(15, FUNC_MTDO_EMAC_RXD3); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[15]); - return ESP_OK; -#elif CONFIG_IDF_TARGET_ESP32P4 - ESP_LOGW(TAG, "MII is currently not supported"); - return ESP_ERR_NOT_SUPPORTED; -#endif -} - -esp_err_t emac_esp_iomux_rmii_clk_input(int num) -{ -#if CONFIG_IDF_TARGET_ESP32 - if (num != 0) { - return ESP_ERR_INVALID_ARG; - } - /* REF_CLK(RMII mode) to GPIO0 */ - gpio_func_sel(0, FUNC_GPIO0_EMAC_TX_CLK); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[0]); -#elif CONFIG_IDF_TARGET_ESP32P4 - /* REF_CLK(RMII mode) to `num` */ - switch(num) { - case 32: - gpio_func_sel(num, FUNC_GPIO32_GMAC_RMII_CLK_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[32]); - break; - case 44: - gpio_func_sel(num, FUNC_GPIO44_GMAC_RMII_CLK_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[44]); - break; - case 50: - gpio_func_sel(num, FUNC_GPIO50_GMAC_RMII_CLK_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[50]); - break; - default: - ESP_LOGE(TAG, "invalid RMII CLK input GPIO number. Expected [32, 44, 50], actual %i", num); - return ESP_ERR_INVALID_ARG; - } -#endif - return ESP_OK; -} - -esp_err_t emac_esp_iomux_rmii_clk_ouput(int num) -{ -#if CONFIG_IDF_TARGET_ESP32 - switch (num) { - case 0: - /* APLL clock output to GPIO0 (must be configured to 50MHz!) */ - gpio_func_sel(num, FUNC_GPIO0_CLK_OUT1); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[0]); - break; - case 16: - /* RMII CLK (50MHz) output to GPIO16 */ - gpio_func_sel(num, FUNC_GPIO16_EMAC_CLK_OUT); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[16]); - break; - case 17: - /* RMII CLK (50MHz) output to GPIO17 */ - gpio_func_sel(num, FUNC_GPIO17_EMAC_CLK_OUT_180); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[17]); - break; - default: - ESP_LOGE(TAG, "invalid RMII CLK output GPIO number. Expected [0, 16, 17], actual %i", num); - return ESP_ERR_INVALID_ARG; - } -#elif CONFIG_IDF_TARGET_ESP32P4 - /*RMII CLK output to num */ - switch (num) { - case 23: - gpio_func_sel(num, FUNC_GPIO23_REF_50M_CLK_PAD); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[23]); - break; - case 39: - gpio_func_sel(num, FUNC_GPIO39_REF_50M_CLK_PAD); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[39]); - break; - default: - ESP_LOGE(TAG, "invalid RMII CLK input GPIO number. Expected [23, 39], actual %i", num); - return ESP_ERR_INVALID_ARG; - } -#endif - return ESP_OK; -} - -esp_err_t emac_esp_iomux_init_rmii(emac_esp_rmii_gpio_config_t *rmii_gpio) -{ -#if CONFIG_IDF_TARGET_ESP32 - (void)rmii_gpio; - /* TX_EN to GPIO21 */ - gpio_func_sel(21, FUNC_GPIO21_EMAC_TX_EN); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[21]); - /* TXD0 to GPIO19 */ - gpio_func_sel(19, FUNC_GPIO19_EMAC_TXD0); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[19]); - /* TXD1 to GPIO22 */ - gpio_func_sel(22, FUNC_GPIO22_EMAC_TXD1); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[22]); - - /* CRS_DV to GPIO27 */ - gpio_func_sel(27, FUNC_GPIO27_EMAC_RX_DV); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[27]); - /* RXD0 to GPIO25 */ - gpio_func_sel(25, FUNC_GPIO25_EMAC_RXD0); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[25]); - /* RXD1 to GPIO26 */ - gpio_func_sel(26, FUNC_GPIO26_EMAC_RXD1); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[26]); - return ESP_OK; -#elif CONFIG_IDF_TARGET_ESP32P4 - if (rmii_gpio == NULL) { - return ESP_ERR_INVALID_ARG; - } - /* TX_EN */ - switch(rmii_gpio->tx_en_num) { - case 33: - gpio_func_sel(rmii_gpio->tx_en_num, FUNC_GPIO33_GMAC_PHY_TXEN_PAD); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[33]); - break; - case 40: - gpio_func_sel(rmii_gpio->tx_en_num, FUNC_GPIO40_GMAC_PHY_TXEN_PAD); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[40]); - break; - case 49: - gpio_func_sel(rmii_gpio->tx_en_num, FUNC_GPIO49_GMAC_PHY_TXEN_PAD); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[49]); - break; - default: - ESP_LOGE(TAG, "invalid TX_EN GPIO number. Expected [33, 40, 49], actual %" PRIu8, rmii_gpio->tx_en_num); - return ESP_ERR_INVALID_ARG; - } - /* TXD0 */ - switch(rmii_gpio->txd0_num) { - case 34: - gpio_func_sel(rmii_gpio->txd0_num, FUNC_GPIO34_GMAC_PHY_TXD0_PAD); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[34]); - break; - case 41: - gpio_func_sel(rmii_gpio->txd0_num, FUNC_GPIO41_GMAC_PHY_TXD0_PAD); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[41]); - break; - default: - ESP_LOGE(TAG, "invalid TXD0 GPIO number. Expected [34, 41], actual %" PRIu8, rmii_gpio->txd0_num); - return ESP_ERR_INVALID_ARG; - } - /* TXD1 */ - switch(rmii_gpio->txd1_num) { - case 35: - gpio_func_sel(rmii_gpio->txd1_num, FUNC_GPIO35_GMAC_PHY_TXD1_PAD ); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[35]); - break; - case 42: - gpio_func_sel(rmii_gpio->txd1_num, FUNC_GPIO42_GMAC_PHY_TXD1_PAD ); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[42]); - break; - default: - ESP_LOGE(TAG, "invalid TXD1 GPIO number. Expected [35, 42], actual %" PRIu8, rmii_gpio->txd1_num); - return ESP_ERR_INVALID_ARG; - } - - /* CRS_DV */ - switch(rmii_gpio->crs_dv_num) { - case 28: - gpio_func_sel(rmii_gpio->crs_dv_num, FUNC_GPIO28_GMAC_PHY_RXDV_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[28]); - break; - case 45: - gpio_func_sel(rmii_gpio->crs_dv_num, FUNC_GPIO45_GMAC_PHY_RXDV_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[45]); - break; - case 51: - gpio_func_sel(rmii_gpio->crs_dv_num, FUNC_GPIO51_GMAC_PHY_RXDV_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[51]); - break; - default: - ESP_LOGE(TAG, "invalid CRS_DV GPIO number. Expected [28, 45, 51], actual %" PRIu8, rmii_gpio->crs_dv_num); - return ESP_ERR_INVALID_ARG; - } - /* RXD0 */ - switch(rmii_gpio->rxd0_num) { - case 29: - gpio_func_sel(rmii_gpio->rxd0_num, FUNC_GPIO29_GMAC_PHY_RXD0_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[29]); - break; - case 46: - gpio_func_sel(rmii_gpio->rxd0_num, FUNC_GPIO46_GMAC_PHY_RXD0_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[46]); - break; - case 52: - gpio_func_sel(rmii_gpio->rxd0_num, FUNC_GPIO52_GMAC_PHY_RXD0_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[52]); - break; - default: - ESP_LOGE(TAG, "invalid RXD0 GPIO number. Expected [29, 46, 52], actual %" PRIu8, rmii_gpio->rxd0_num); - return ESP_ERR_INVALID_ARG; - } - /* RXD1 */ - switch(rmii_gpio->rxd1_num) { - case 30: - gpio_func_sel(rmii_gpio->rxd1_num, FUNC_GPIO30_GMAC_PHY_RXD1_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[30]); - break; - case 47: - gpio_func_sel(rmii_gpio->rxd1_num, FUNC_GPIO47_GMAC_PHY_RXD1_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[47]); - break; - case 53: - gpio_func_sel(rmii_gpio->rxd1_num, FUNC_GPIO53_GMAC_PHY_RXD1_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[53]); - break; - default: - ESP_LOGE(TAG, "invalid RXD1 GPIO number. Expected [30, 47, 53], actual %" PRIu8, rmii_gpio->rxd1_num); - return ESP_ERR_INVALID_ARG; - } - return ESP_OK; -#endif -} - -esp_err_t emac_esp_iomux_init_tx_er(int num) -{ -#if CONFIG_IDF_TARGET_ESP32 - (void)num; - /* TX_ER to GPIO4 */ - gpio_func_sel(4, FUNC_GPIO4_EMAC_TX_ER); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[4]); -#elif CONFIG_IDF_TARGET_ESP32P4 - /* TX_ER */ - switch (num) - { - case 36: - gpio_func_sel(num, FUNC_GPIO36_GMAC_PHY_TXER_PAD); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[36]); - break; - case 43: - gpio_func_sel(num, FUNC_GPIO43_GMAC_PHY_TXER_PAD); - PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[43]); - break; - default: - ESP_LOGE(TAG, "invalid TX_ER GPIO number. Expected [36, 43], actual %i", num); - return ESP_ERR_INVALID_ARG; - } -#endif - return ESP_OK; -} - -esp_err_t emac_esp_iomux_init_rx_er(int num) -{ -#if CONFIG_IDF_TARGET_ESP32 - (void)num; - /* RX_ER to MTCK */ - gpio_func_sel(13, FUNC_MTCK_EMAC_RX_ER); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[13]); -#elif CONFIG_IDF_TARGET_ESP32P4 - /* RX_ER */ - switch (num) - { - case 31: - gpio_func_sel(num, FUNC_GPIO31_GMAC_PHY_RXER_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[31]); - break; - case 48: - gpio_func_sel(num, FUNC_GPIO48_GMAC_PHY_RXER_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[48]); - break; - case 54: - gpio_func_sel(num, FUNC_GPIO54_GMAC_PHY_RXER_PAD); - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[54]); - break; - default: - ESP_LOGE(TAG, "invalid RX_ER GPIO number. Expected [31, 48, 54], actual %i", num); - return ESP_ERR_INVALID_ARG; - } -#endif - return ESP_OK; -} diff --git a/components/esp_eth/src/esp_eth_netif_glue.c b/components/esp_eth/src/esp_eth_netif_glue.c index ad33eb0d2f68..f3bc36005050 100644 --- a/components/esp_eth/src/esp_eth_netif_glue.c +++ b/components/esp_eth/src/esp_eth_netif_glue.c @@ -6,7 +6,6 @@ #include #include #include "esp_netif.h" -#include "esp_eth_driver.h" #include "esp_eth_netif_glue.h" #include "esp_netif_net_stack.h" #include "esp_event.h" diff --git a/components/esp_eth/src/esp_openeth.h b/components/esp_eth/src/esp_openeth.h deleted file mode 100644 index f4d10ea3b852..000000000000 --- a/components/esp_eth/src/esp_openeth.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once - -#include "sdkconfig.h" -#include "soc/interrupts.h" - -#if CONFIG_IDF_TARGET_ESP32C3 - -/** - * @brief Since ESP32-C3 target in QEMU doesn't support Wifi, re-use its interrupt source for ethernet - */ -#define ETS_ETH_MAC_INTR_SOURCE ETS_WIFI_MAC_INTR_SOURCE - - -/** - * @brief Use an empty I/O range for the ethernet registers - */ -#define DR_REG_EMAC_BASE 0x600CD000 - -#endif // CONFIG_IDF_TARGET_ESP32C3 diff --git a/components/esp_eth/src/esp_eth_mac_esp.c b/components/esp_eth/src/mac/esp_eth_mac_esp.c similarity index 82% rename from components/esp_eth/src/esp_eth_mac_esp.c rename to components/esp_eth/src/mac/esp_eth_mac_esp.c index 6ad4157e8676..2ceb2d15b87d 100644 --- a/components/esp_eth/src/esp_eth_mac_esp.c +++ b/components/esp_eth/src/mac/esp_eth_mac_esp.c @@ -12,7 +12,6 @@ #include "esp_attr.h" #include "esp_log.h" #include "esp_check.h" -#include "esp_eth_driver.h" #include "esp_pm.h" #include "esp_mac.h" #include "esp_cpu.h" @@ -66,8 +65,6 @@ typedef struct { uint32_t free_rx_descriptor; uint32_t flow_control_high_water_mark; uint32_t flow_control_low_water_mark; - emac_esp_smi_gpio_config_t smi_gpio; - eth_mac_clock_config_t clock_config; uint8_t addr[ETH_ADDR_LEN]; bool isr_need_yield; bool flow_ctrl_enabled; // indicates whether the user want to do flow control @@ -82,19 +79,10 @@ typedef struct { #ifdef CONFIG_IDF_TARGET_ESP32 esp_clock_output_mapping_handle_t rmii_clk_hdl; // we use the esp_clock_output driver to output a pre-configured APLL clock as the RMII reference clock #endif - -#ifdef CONFIG_IDF_TARGET_ESP32P4 - eth_mac_clock_config_t clock_config_out_in; - union - { - emac_esp_mii_gpio_config_t mii_gpio; - emac_esp_rmii_gpio_config_t rmii_gpio; - }; -#endif // CONFIG_IDF_TARGET_ESP32P4 } emac_esp32_t; -static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_esp32_t **emac_out_hdl); -static void esp_emac_free_driver_obj(emac_esp32_t *emac); +static esp_err_t emac_esp_alloc_driver_obj(const eth_mac_config_t *config, emac_esp32_t **emac_out_hdl); +static void emac_esp_free_driver_obj(emac_esp32_t *emac); static esp_err_t emac_esp32_start(esp_eth_mac_t *mac); static esp_err_t emac_esp32_stop(esp_eth_mac_t *mac); @@ -209,11 +197,11 @@ static esp_err_t emac_esp32_set_speed(esp_eth_mac_t *mac, eth_speed_t speed) // Set RMII clk_rx/clk_tx divider to get 25MHz for 100mbps mode or 2.5MHz for 10mbps mode if (emac_hal_get_phy_intf(&emac->hal) == EMAC_DATA_INTERFACE_RMII) { if (speed == ETH_SPEED_10M) { - EMAC_IF_RCC_ATOMIC () { + EMAC_IF_RCC_ATOMIC() { emac_hal_clock_rmii_rx_tx_div(&emac->hal, RMII_10M_SPEED_RX_TX_CLK_DIV); } } else { - EMAC_IF_RCC_ATOMIC () { + EMAC_IF_RCC_ATOMIC() { emac_hal_clock_rmii_rx_tx_div(&emac->hal, RMII_100M_SPEED_RX_TX_CLK_DIV); } } @@ -268,6 +256,28 @@ static esp_err_t emac_esp32_set_peer_pause_ability(esp_eth_mac_t *mac, uint32_t return ESP_OK; } +esp_err_t emac_esp_custom_ioctl(esp_eth_mac_t *mac, int cmd, void *data) +{ + emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); + + switch (cmd) + { + case ETH_MAC_ESP_CMD_PTP_ENABLE: + return ESP_ERR_NOT_SUPPORTED; + case ETH_MAC_ESP_CMD_SET_TDES0_CFG_BITS: + ESP_RETURN_ON_FALSE(data != NULL, ESP_ERR_INVALID_ARG, TAG, "cannot set DMA tx desc flag to null"); + emac_esp_dma_set_tdes0_ctrl_bits(emac->emac_dma_hndl, *(uint32_t *)data); + break; + case ETH_MAC_ESP_CMD_CLEAR_TDES0_CFG_BITS: + ESP_RETURN_ON_FALSE(data != NULL, ESP_ERR_INVALID_ARG, TAG, "cannot clear DMA tx desc flag with null"); + emac_esp_dma_clear_tdes0_ctrl_bits(emac->emac_dma_hndl, *(uint32_t *)data); + break; + default: + ESP_RETURN_ON_ERROR(ESP_ERR_INVALID_ARG, TAG, "unknown io command: %i", cmd); + } + return ESP_OK; +} + static esp_err_t emac_esp32_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t length) { esp_err_t ret = ESP_OK; @@ -304,7 +314,8 @@ static esp_err_t emac_esp32_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t * uint32_t expected_len = *length; emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); ESP_GOTO_ON_FALSE(buf && length, ESP_ERR_INVALID_ARG, err, TAG, "can't set buf and length to null"); - uint32_t receive_len = emac_esp_dma_receive_frame(emac->emac_dma_hndl, buf, expected_len, &emac->frames_remain, &emac->free_rx_descriptor); + uint32_t receive_len = emac_esp_dma_receive_frame(emac->emac_dma_hndl, buf, expected_len); + emac_esp_dma_get_remain_frames(emac->emac_dma_hndl, &emac->frames_remain, &emac->free_rx_descriptor); /* we need to check the return value in case the buffer size is not enough */ ESP_GOTO_ON_FALSE(expected_len >= receive_len, ESP_ERR_INVALID_SIZE, err, TAG, "received buffer longer than expected"); *length = receive_len; @@ -327,12 +338,12 @@ static void emac_esp32_rx_task(void *arg) buffer = emac_esp_dma_alloc_recv_buf(emac->emac_dma_hndl, &frame_len); /* we have memory to receive the frame of maximal size previously defined */ if (buffer != NULL) { - uint32_t recv_len = emac_esp_dma_receive_frame(emac->emac_dma_hndl, buffer, EMAC_HAL_BUF_SIZE_AUTO, &emac->frames_remain, &emac->free_rx_descriptor); + uint32_t recv_len = emac_esp_dma_receive_frame(emac->emac_dma_hndl, buffer, EMAC_DMA_BUF_SIZE_AUTO); if (recv_len == 0) { ESP_LOGE(TAG, "frame copy error"); free(buffer); /* ensure that interface to EMAC does not get stuck with unprocessed frames */ - emac_esp_dma_flush_recv_frame(emac->emac_dma_hndl, &emac->frames_remain, &emac->free_rx_descriptor); + emac_esp_dma_flush_recv_frame(emac->emac_dma_hndl); } else if (frame_len > recv_len) { ESP_LOGE(TAG, "received frame was truncated"); free(buffer); @@ -344,8 +355,9 @@ static void emac_esp32_rx_task(void *arg) } else if (frame_len) { ESP_LOGE(TAG, "no mem for receive buffer"); /* ensure that interface to EMAC does not get stuck with unprocessed frames */ - emac_esp_dma_flush_recv_frame(emac->emac_dma_hndl, &emac->frames_remain, &emac->free_rx_descriptor); + emac_esp_dma_flush_recv_frame(emac->emac_dma_hndl); } + emac_esp_dma_get_remain_frames(emac->emac_dma_hndl, &emac->frames_remain, &emac->free_rx_descriptor); #if CONFIG_ETH_SOFT_FLOW_CONTROL // we need to do extra checking of remained frames in case there are no unhandled frames left, but pause frame is still undergoing if ((emac->free_rx_descriptor < emac->flow_control_low_water_mark) && emac->do_flow_ctrl && emac->frames_remain) { @@ -401,8 +413,6 @@ static esp_err_t emac_esp32_init(esp_eth_mac_t *mac) emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); esp_eth_mediator_t *eth = emac->eth; - /* init gpio used by smi interface */ - emac_esp32_gpio_init_smi(&emac->smi_gpio); ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL), err, TAG, "lowlevel init failed"); /* software reset */ emac_hal_reset(&emac->hal); @@ -451,7 +461,7 @@ static esp_err_t emac_esp32_start(esp_eth_mac_t *mac) { emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); /* reset descriptor chain */ - emac_esp_dma_reset_desc_chain(emac->emac_dma_hndl); + emac_esp_dma_reset(emac->emac_dma_hndl); emac_hal_start(&emac->hal); return ESP_OK; } @@ -474,8 +484,9 @@ static esp_err_t emac_esp32_stop(esp_eth_mac_t *mac) static esp_err_t emac_esp32_del(esp_eth_mac_t *mac) { emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); - esp_emac_free_driver_obj(emac); - /// disable bus clock + emac_esp_free_driver_obj(emac); + emac_esp_gpio_deinit_all(); + // disable bus clock PERIPH_RCC_ATOMIC() { emac_ll_enable_bus_clock(0, false); } @@ -502,7 +513,7 @@ IRAM_ATTR void emac_isr_default_handler(void *args) #endif } -static void esp_emac_free_driver_obj(emac_esp32_t *emac) +static void emac_esp_free_driver_obj(emac_esp32_t *emac) { if (emac) { if (emac->rx_task_hdl) { @@ -537,7 +548,7 @@ static void esp_emac_free_driver_obj(emac_esp32_t *emac) } } -static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_esp32_t **emac_out_hdl) +static esp_err_t emac_esp_alloc_driver_obj(const eth_mac_config_t *config, emac_esp32_t **emac_out_hdl) { esp_err_t ret = ESP_OK; emac_esp32_t *emac = NULL; @@ -548,8 +559,7 @@ static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_ } ESP_GOTO_ON_FALSE(emac, ESP_ERR_NO_MEM, err, TAG, "no mem for esp emac object"); - emac_esp_dma_config_t emac_dma_config; - ESP_GOTO_ON_ERROR(emac_esp_new_dma(&emac_dma_config, &emac->emac_dma_hndl), err, TAG, "create EMAC DMA object failed"); + ESP_GOTO_ON_ERROR(emac_esp_new_dma(NULL, &emac->emac_dma_hndl), err, TAG, "create EMAC DMA object failed"); /* alloc PM lock */ #ifdef CONFIG_PM_ENABLE @@ -564,89 +574,66 @@ static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_ config->rx_task_prio, &emac->rx_task_hdl, core_num); ESP_GOTO_ON_FALSE(xReturned == pdPASS, ESP_FAIL, err, TAG, "create emac_rx task failed"); - *emac_out_hdl = emac; - return ESP_OK; err: - esp_emac_free_driver_obj(emac); + *emac_out_hdl = emac; return ret; } -static esp_err_t esp_emac_config_data_interface(const eth_esp32_emac_config_t *esp32_emac_config, emac_esp32_t *emac) +static esp_err_t emac_esp_config_data_interface(const eth_esp32_emac_config_t *esp32_emac_config, emac_esp32_t *emac) { esp_err_t ret = ESP_OK; switch (esp32_emac_config->interface) { case EMAC_DATA_INTERFACE_MII: - emac->clock_config = esp32_emac_config->clock_config; /* MII interface GPIO initialization */ - ESP_GOTO_ON_ERROR(emac_esp_iomux_init_mii(NULL), err, TAG, "invalid EMAC MII data plane GPIO"); +#if SOC_EMAC_MII_USE_GPIO_MATRIX + ESP_GOTO_ON_ERROR(emac_esp_gpio_matrix_init_mii(&esp32_emac_config->emac_dataif_gpio.mii), err, TAG, "failed to initialize EMAC MII GPIO Matrix"); +#else + eth_mac_mii_gpio_config_t *mii_data_gpio = NULL; +#if SOC_EMAC_USE_MULTI_IO_MUX + mii_data_gpio = &esp32_emac_config->emac_dataif_gpio.mii; +#endif // SOC_EMAC_USE_MULTI_IO_MUX + ESP_GOTO_ON_ERROR(emac_esp_iomux_init_mii(mii_data_gpio), err, TAG, "invalid EMAC MII data plane GPIO"); +#endif // SOC_EMAC_MII_USE_GPIO_MATRIX /* Enable MII clock */ EMAC_IF_RCC_ATOMIC() { emac_hal_clock_enable_mii(&emac->hal); } break; case EMAC_DATA_INTERFACE_RMII: - // by default, the clock mode is selected at compile time (by Kconfig) - if (esp32_emac_config->clock_config.rmii.clock_mode == EMAC_CLK_DEFAULT) { -#ifdef CONFIG_IDF_TARGET_ESP32 -#if CONFIG_ETH_RMII_CLK_INPUT -#if CONFIG_ETH_RMII_CLK_IN_GPIO == 0 - emac->clock_config.rmii.clock_mode = EMAC_CLK_EXT_IN; - emac->clock_config.rmii.clock_gpio = CONFIG_ETH_RMII_CLK_IN_GPIO; -#else -#error "ESP32 EMAC only support input RMII clock to GPIO0" -#endif // CONFIG_ETH_RMII_CLK_IN_GPIO == 0 -#elif CONFIG_ETH_RMII_CLK_OUTPUT - emac->clock_config.rmii.clock_mode = EMAC_CLK_OUT; -#if CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0 - emac->clock_config.rmii.clock_gpio = 0; -#elif CONFIG_ETH_RMII_CLK_OUT_GPIO - emac->clock_config.rmii.clock_gpio = CONFIG_ETH_RMII_CLK_OUT_GPIO; -#endif // CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0 -#else -#error "Unsupported RMII clock mode" -#endif // CONFIG_ETH_RMII_CLK_INPUT -#else // EMAC_CLK_DEFAULT "not supported for ESP32P4" - this configuration has been kept due to compatibility reasons for ESP32 - ESP_LOGE(TAG, "EMAC_CLK_DEFAULT options is only supported by ESP32"); - return ESP_ERR_INVALID_ARG; -#endif // CONFIG_IDF_TARGET_ESP32 - } else { - emac->clock_config = esp32_emac_config->clock_config; -#ifdef CONFIG_IDF_TARGET_ESP32P4 - emac->clock_config_out_in = esp32_emac_config->clock_config_out_in; -#endif // CONFIG_IDF_TARGET_ESP32P4 - } /* RMII interface GPIO initialization */ -#ifdef CONFIG_IDF_TARGET_ESP32 - ESP_GOTO_ON_ERROR(emac_esp_iomux_init_rmii(NULL), err, TAG, "invalid EMAC RMII data plane GPIO"); -#else - ESP_GOTO_ON_ERROR(emac_esp_iomux_init_rmii(&emac->rmii_gpio), err, TAG, "invalid EMAC RMII data plane GPIO"); -#endif // CONFIG_IDF_TARGET_ESP32 + const eth_mac_rmii_gpio_config_t *rmii_data_gpio = NULL; +#if SOC_EMAC_USE_MULTI_IO_MUX + rmii_data_gpio = &esp32_emac_config->emac_dataif_gpio.rmii; +#endif // SOC_EMAC_USE_MULTI_IO_MUX + ESP_GOTO_ON_ERROR(emac_esp_iomux_init_rmii(rmii_data_gpio), err, TAG, "invalid EMAC RMII data plane GPIO"); /* If ref_clk is configured as input */ - if (emac->clock_config.rmii.clock_mode == EMAC_CLK_EXT_IN) { - ESP_GOTO_ON_ERROR(emac_esp_iomux_rmii_clk_input(emac->clock_config.rmii.clock_gpio), err, TAG, "invalid EMAC RMII clock input GPIO"); + if (esp32_emac_config->clock_config.rmii.clock_mode == EMAC_CLK_EXT_IN) { + ESP_GOTO_ON_ERROR(emac_esp_iomux_rmii_clk_input(esp32_emac_config->clock_config.rmii.clock_gpio), err, TAG, "invalid EMAC RMII clock input GPIO"); EMAC_IF_RCC_ATOMIC() { emac_hal_clock_enable_rmii_input(&emac->hal); } - } else if (emac->clock_config.rmii.clock_mode == EMAC_CLK_OUT) { + } else if (esp32_emac_config->clock_config.rmii.clock_mode == EMAC_CLK_OUT) { ESP_GOTO_ON_ERROR(emac_config_pll_clock(emac), err, TAG, "Configure (A/M)PLL for RMII failed"); -#if CONFIG_IDF_TARGET_ESP32 - // we can also use the IOMUX to route the APLL clock to specific GPIO - if (emac->clock_config.rmii.clock_gpio == EMAC_APPL_CLK_OUT_GPIO) { - ESP_GOTO_ON_ERROR(esp_clock_output_start(CLKOUT_SIG_APLL, EMAC_APPL_CLK_OUT_GPIO, &emac->rmii_clk_hdl), - err, TAG, "start APLL clock output failed"); - } -#elif CONFIG_IDF_TARGET_ESP32P4 +#if CONFIG_IDF_TARGET_ESP32P4 /* Output RMII clock is routed back to input externally */ - ESP_GOTO_ON_FALSE(emac->clock_config_out_in.rmii.clock_mode == EMAC_CLK_EXT_IN && emac->clock_config_out_in.rmii.clock_gpio >= 0, + ESP_GOTO_ON_FALSE(esp32_emac_config->clock_config_out_in.rmii.clock_mode == EMAC_CLK_EXT_IN && esp32_emac_config->clock_config_out_in.rmii.clock_gpio >= 0, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC input of output clock mode"); - ESP_GOTO_ON_ERROR(emac_esp_iomux_rmii_clk_input(emac->clock_config_out_in.rmii.clock_gpio), err, TAG, "invalid EMAC RMII clock input GPIO"); + ESP_GOTO_ON_ERROR(emac_esp_iomux_rmii_clk_input(esp32_emac_config->clock_config_out_in.rmii.clock_gpio), err, TAG, "invalid EMAC RMII clock input GPIO"); EMAC_IF_RCC_ATOMIC() { emac_hal_clock_enable_rmii_input(&emac->hal); } +#elif CONFIG_IDF_TARGET_ESP32 + // we can also use the IOMUX to route the APLL clock to specific GPIO + if (esp32_emac_config->clock_config.rmii.clock_gpio == EMAC_APPL_CLK_OUT_GPIO) { + ESP_GOTO_ON_ERROR(esp_clock_output_start(CLKOUT_SIG_APLL, EMAC_APPL_CLK_OUT_GPIO, &emac->rmii_clk_hdl), + err, TAG, "start APLL clock output failed"); + } else #endif - ESP_GOTO_ON_ERROR(emac_esp_iomux_rmii_clk_ouput(emac->clock_config.rmii.clock_gpio), err, TAG, "invalid EMAC RMII clock output GPIO"); + { + ESP_GOTO_ON_ERROR(emac_esp_iomux_rmii_clk_ouput(esp32_emac_config->clock_config.rmii.clock_gpio), err, TAG, "invalid EMAC RMII clock output GPIO"); + } /* Enable RMII Output clock */ - EMAC_IF_RCC_ATOMIC () { + EMAC_IF_RCC_ATOMIC() { emac_hal_clock_enable_rmii_output(&emac->hal); } } else { @@ -671,8 +658,8 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_esp32_emac_config_t *esp32_config TAG, "invalid interrupt priority: %d", esp32_config->intr_priority); } - ret_code = esp_emac_alloc_driver_obj(config, &emac); - ESP_RETURN_ON_FALSE(ret_code == ESP_OK, NULL, TAG, "alloc driver object failed"); + ret_code = emac_esp_alloc_driver_obj(config, &emac); + ESP_GOTO_ON_FALSE(ret_code == ESP_OK, NULL, err, TAG, "alloc driver object failed"); // enable bus clock for the EMAC module, and reset the registers into default state // this must be called before HAL layer initialization @@ -697,21 +684,15 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_esp32_emac_config_t *esp32_config emac_isr_default_handler, &emac->hal, &(emac->intr_hdl)); ESP_GOTO_ON_FALSE(ret_code == ESP_OK, NULL, err, TAG, "alloc emac interrupt failed"); -#ifdef SOC_EMAC_USE_IO_MUX - emac->rmii_gpio.tx_en_num = esp32_config->emac_dataif_gpio.rmii.tx_en_num; - emac->rmii_gpio.txd0_num = esp32_config->emac_dataif_gpio.rmii.txd0_num; - emac->rmii_gpio.txd1_num = esp32_config->emac_dataif_gpio.rmii.txd1_num; - emac->rmii_gpio.crs_dv_num = esp32_config->emac_dataif_gpio.rmii.crs_dv_num; - emac->rmii_gpio.rxd0_num = esp32_config->emac_dataif_gpio.rmii.rxd0_num; - emac->rmii_gpio.rxd1_num = esp32_config->emac_dataif_gpio.rmii.rxd1_num; -#endif // SOC_EMAC_USE_IO_MUX - ret_code = esp_emac_config_data_interface(esp32_config, emac); + /* init GPIO used by SMI interface */ + ret_code = emac_esp_gpio_init_smi(&esp32_config->smi_gpio); + ESP_GOTO_ON_FALSE(ret_code == ESP_OK, NULL, err, TAG, "SMI GPIO init failed"); + /* init GPIO and CLK for data interface */ + ret_code = emac_esp_config_data_interface(esp32_config, emac); ESP_GOTO_ON_FALSE(ret_code == ESP_OK, NULL, err, TAG, "config emac interface failed"); emac->dma_burst_len = esp32_config->dma_burst_len; emac->sw_reset_timeout_ms = config->sw_reset_timeout_ms; - emac->smi_gpio.mdc_num = esp32_config->smi_mdc_gpio_num; - emac->smi_gpio.mdio_num = esp32_config->smi_mdio_gpio_num; emac->flow_control_high_water_mark = FLOW_CONTROL_HIGH_WATER_MARK; emac->flow_control_low_water_mark = FLOW_CONTROL_LOW_WATER_MARK; @@ -734,9 +715,11 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_esp32_emac_config_t *esp32_config emac->parent.transmit = emac_esp32_transmit; emac->parent.transmit_vargs = emac_esp32_transmit_multiple_bufs; emac->parent.receive = emac_esp32_receive; + emac->parent.custom_ioctl = emac_esp_custom_ioctl; return &(emac->parent); err: - esp_emac_free_driver_obj(emac); + emac_esp_free_driver_obj(emac); + emac_esp_gpio_deinit_all(); return ret; } diff --git a/components/esp_eth/src/esp_eth_mac_esp_dma.c b/components/esp_eth/src/mac/esp_eth_mac_esp_dma.c similarity index 64% rename from components/esp_eth/src/esp_eth_mac_esp_dma.c rename to components/esp_eth/src/mac/esp_eth_mac_esp_dma.c index b885fe0cee02..73f5ee40c7c3 100644 --- a/components/esp_eth/src/esp_eth_mac_esp_dma.c +++ b/components/esp_eth/src/mac/esp_eth_mac_esp_dma.c @@ -5,24 +5,44 @@ */ #include "esp_check.h" -#include "esp_dma_utils.h" #include "sdkconfig.h" #include "soc/soc_caps.h" -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #include "esp_cache.h" -#endif #include "hal/emac_hal.h" +#include "esp_heap_caps.h" #include "esp_private/eth_mac_esp_dma.h" #define ETH_CRC_LENGTH (4) -#define EMAC_HAL_BUF_MAGIC_ID 0x1E1C8416 +#define EMAC_ALLOC_BUF_MAGIC_ID 0x1E1C8416 + +#define EMAC_TDES0_FS_CTRL_FLAGS_MASK 0x0FCC0000 // modifiable bits mask associated with the First Segment +#define EMAC_TDES0_LS_CTRL_FLAGS_MASK 0x40000000 // modifiable bits mask associated with the Last Segment + +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#define DMA_CACHE_WB(addr, size) do { \ + esp_err_t msync_ret = esp_cache_msync((void *)addr, size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); \ + assert(msync_ret == ESP_OK); \ + } while(0) +#else +#define DMA_CACHE_WB(addr, size) +#endif + +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#define DMA_CACHE_INVALIDATE(addr, size) do { \ + esp_err_t msync_ret = esp_cache_msync((void *)addr, size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); \ + assert(msync_ret == ESP_OK); \ + } while(0) +#else +#define DMA_CACHE_INVALIDATE(addr, size) +#endif static const char *TAG = "esp.emac.dma"; -struct emac_esp_dma_t -{ +struct emac_esp_dma_t { emac_hal_context_t hal; + uint32_t tx_desc_flags; + uint32_t rx_desc_flags; void *descriptors; eth_dma_rx_descriptor_t *rx_desc; eth_dma_tx_descriptor_t *tx_desc; @@ -35,19 +55,14 @@ typedef struct { uint32_t magic_id; #endif // NDEBUG uint32_t copy_len; -}__attribute__((packed)) emac_esp_dma_auto_buf_info_t; +} __attribute__((packed)) emac_esp_dma_auto_buf_info_t; -void emac_esp_dma_reset_desc_chain(emac_esp_dma_handle_t emac_esp_dma) +void emac_esp_dma_reset(emac_esp_dma_handle_t emac_esp_dma) { -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - size_t cache_sync_len; - esp_err_t ret = ESP_OK; -#endif - /* reset DMA descriptors */ emac_esp_dma->rx_desc = (eth_dma_rx_descriptor_t *)(emac_esp_dma->descriptors); emac_esp_dma->tx_desc = (eth_dma_tx_descriptor_t *)(emac_esp_dma->descriptors + - sizeof(eth_dma_rx_descriptor_t) * CONFIG_ETH_DMA_RX_BUFFER_NUM); + sizeof(eth_dma_rx_descriptor_t) * CONFIG_ETH_DMA_RX_BUFFER_NUM); /* init rx chain */ for (int i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) { /* Set Own bit of the Rx descriptor Status: DMA */ @@ -66,11 +81,7 @@ void emac_esp_dma_reset_desc_chain(emac_esp_dma_handle_t emac_esp_dma) if (i == CONFIG_ETH_DMA_RX_BUFFER_NUM - 1) { emac_esp_dma->rx_desc[i].Buffer2NextDescAddr = (uint32_t)(emac_esp_dma->rx_desc); } -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - ret = esp_cache_msync((void *)&emac_esp_dma->rx_desc[i], cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif + DMA_CACHE_WB(&emac_esp_dma->rx_desc[i], EMAC_HAL_DMA_DESC_SIZE); } /* init tx chain */ @@ -79,10 +90,6 @@ void emac_esp_dma_reset_desc_chain(emac_esp_dma_handle_t emac_esp_dma) emac_esp_dma->tx_desc[i].TDES0.Own = EMAC_LL_DMADESC_OWNER_CPU; emac_esp_dma->tx_desc[i].TDES0.SecondAddressChained = 1; emac_esp_dma->tx_desc[i].TDES1.TransmitBuffer1Size = CONFIG_ETH_DMA_BUFFER_SIZE; - /* Enable Ethernet DMA Tx Descriptor interrupt */ - emac_esp_dma->tx_desc[1].TDES0.InterruptOnComplete = 1; - /* Enable Transmit Timestamp */ - emac_esp_dma->tx_desc[i].TDES0.TransmitTimestampEnable = 1; /* point to the buffer */ emac_esp_dma->tx_desc[i].Buffer1Addr = (uint32_t)(emac_esp_dma->tx_buf[i]); /* point to next descriptor */ @@ -92,24 +99,25 @@ void emac_esp_dma_reset_desc_chain(emac_esp_dma_handle_t emac_esp_dma) if (i == CONFIG_ETH_DMA_TX_BUFFER_NUM - 1) { emac_esp_dma->tx_desc[i].Buffer2NextDescAddr = (uint32_t)(emac_esp_dma->tx_desc); } -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_tx_descriptor_t); - ret = esp_cache_msync((void *)&emac_esp_dma->tx_desc[i], cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif + DMA_CACHE_WB(&emac_esp_dma->tx_desc[i], EMAC_HAL_DMA_DESC_SIZE); } /* set base address of the first descriptor */ emac_hal_set_rx_tx_desc_addr(&emac_esp_dma->hal, emac_esp_dma->rx_desc, emac_esp_dma->tx_desc); } -uint32_t emac_esp_dma_transmit_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t length) +void emac_esp_dma_set_tdes0_ctrl_bits(emac_esp_dma_handle_t emac_esp_dma, uint32_t flag) { -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - esp_err_t ret; - size_t cache_sync_len; -#endif + emac_esp_dma->tx_desc_flags |= flag; +} + +void emac_esp_dma_clear_tdes0_ctrl_bits(emac_esp_dma_handle_t emac_esp_dma, uint32_t flag) +{ + emac_esp_dma->tx_desc_flags &= ~flag; +} +uint32_t emac_esp_dma_transmit_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t length) +{ /* Get the number of Tx buffers to use for the frame */ uint32_t bufcount = 0; uint32_t lastlen = length; @@ -128,11 +136,7 @@ uint32_t emac_esp_dma_transmit_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t eth_dma_tx_descriptor_t *desc_iter = emac_esp_dma->tx_desc; /* A frame is transmitted in multiple descriptor */ for (size_t i = 0; i < bufcount; i++) { -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_tx_descriptor_t); - ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); -#endif + DMA_CACHE_INVALIDATE(desc_iter, EMAC_HAL_DMA_DESC_SIZE); /* Check if the descriptor is owned by the Ethernet DMA (when 1) or CPU (when 0) */ if (desc_iter->TDES0.Own != EMAC_LL_DMADESC_OWNER_CPU) { goto err; @@ -140,17 +144,16 @@ uint32_t emac_esp_dma_transmit_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t /* Clear FIRST and LAST segment bits */ desc_iter->TDES0.FirstSegment = 0; desc_iter->TDES0.LastSegment = 0; - desc_iter->TDES0.InterruptOnComplete = 0; + desc_iter->TDES0.Value &= ~(EMAC_TDES0_FS_CTRL_FLAGS_MASK | EMAC_TDES0_LS_CTRL_FLAGS_MASK); if (i == 0) { /* Setting the first segment bit */ desc_iter->TDES0.FirstSegment = 1; - //desc_iter->TDES0.DisableCRC = 1; + desc_iter->TDES0.Value |= emac_esp_dma->tx_desc_flags & EMAC_TDES0_FS_CTRL_FLAGS_MASK; } if (i == (bufcount - 1)) { /* Setting the last segment bit */ desc_iter->TDES0.LastSegment = 1; - /* Enable transmit interrupt */ - desc_iter->TDES0.InterruptOnComplete = 1; + desc_iter->TDES0.Value |= emac_esp_dma->tx_desc_flags & EMAC_TDES0_LS_CTRL_FLAGS_MASK; /* Program size */ desc_iter->TDES1.TransmitBuffer1Size = lastlen; /* copy data from uplayer stack buffer */ @@ -163,11 +166,7 @@ uint32_t emac_esp_dma_transmit_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t memcpy((void *)(desc_iter->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, CONFIG_ETH_DMA_BUFFER_SIZE); sentout += CONFIG_ETH_DMA_BUFFER_SIZE; } -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = CONFIG_ETH_DMA_BUFFER_SIZE; - ret = esp_cache_msync((void *)desc_iter->Buffer1Addr, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif + DMA_CACHE_WB(desc_iter->Buffer1Addr, CONFIG_ETH_DMA_BUFFER_SIZE); /* Point to next descriptor */ desc_iter = (eth_dma_tx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); } @@ -175,11 +174,7 @@ uint32_t emac_esp_dma_transmit_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ for (size_t i = 0; i < bufcount; i++) { emac_esp_dma->tx_desc->TDES0.Own = EMAC_LL_DMADESC_OWNER_DMA; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_tx_descriptor_t); - ret = esp_cache_msync((void *)emac_esp_dma->tx_desc, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif + DMA_CACHE_WB(emac_esp_dma->tx_desc, EMAC_HAL_DMA_DESC_SIZE); emac_esp_dma->tx_desc = (eth_dma_tx_descriptor_t *)(emac_esp_dma->tx_desc->Buffer2NextDescAddr); } emac_hal_transmit_poll_demand(&emac_esp_dma->hal); @@ -190,11 +185,6 @@ uint32_t emac_esp_dma_transmit_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t **buffs, uint32_t *lengths, uint32_t buffs_cnt) { -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - esp_err_t ret; - size_t cache_sync_len; -#endif - /* Get the number of Tx buffers to use for the frame */ uint32_t dma_bufcount = 0; uint32_t sentout = 0; @@ -205,11 +195,7 @@ uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp eth_dma_tx_descriptor_t *desc_iter = emac_esp_dma->tx_desc; /* A frame is transmitted in multiple descriptor */ while (dma_bufcount < CONFIG_ETH_DMA_TX_BUFFER_NUM) { -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_tx_descriptor_t); - ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); -#endif + DMA_CACHE_INVALIDATE(desc_iter, EMAC_HAL_DMA_DESC_SIZE); /* Check if the descriptor is owned by the Ethernet DMA (when 1) or CPU (when 0) */ if (desc_iter->TDES0.Own != EMAC_LL_DMADESC_OWNER_CPU) { goto err; @@ -217,11 +203,12 @@ uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp /* Clear FIRST and LAST segment bits */ desc_iter->TDES0.FirstSegment = 0; desc_iter->TDES0.LastSegment = 0; - desc_iter->TDES0.InterruptOnComplete = 0; + desc_iter->TDES0.Value &= ~(EMAC_TDES0_FS_CTRL_FLAGS_MASK | EMAC_TDES0_LS_CTRL_FLAGS_MASK); desc_iter->TDES1.TransmitBuffer1Size = 0; if (dma_bufcount == 0) { /* Setting the first segment bit */ desc_iter->TDES0.FirstSegment = 1; + desc_iter->TDES0.Value |= emac_esp_dma->tx_desc_flags & EMAC_TDES0_FS_CTRL_FLAGS_MASK; } while (buffs_cnt > 0) { @@ -237,7 +224,7 @@ uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp buffs_cnt--; ptr = *(++buffs); lastlen = *(++lengths); - /* There is only limited available space in the current descriptor, use it all */ + /* There is only limited available space in the current descriptor, use it all */ } else { /* copy data from uplayer stack buffer */ memcpy((void *)(desc_iter->Buffer1Addr + (CONFIG_ETH_DMA_BUFFER_SIZE - avail_len)), ptr, avail_len); @@ -246,7 +233,7 @@ uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp /* If lastlen is not zero, input buff will be fragmented over multiple descriptors */ if (lastlen > 0) { ptr += avail_len; - /* Input buff fully fits the descriptor, move to the next input buff */ + /* Input buff fully fits the descriptor, move to the next input buff */ } else { /* Update processed input buffers info */ buffs_cnt--; @@ -259,11 +246,7 @@ uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp break; } } -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = CONFIG_ETH_DMA_BUFFER_SIZE; - ret = esp_cache_msync((void *)desc_iter->Buffer1Addr, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif + DMA_CACHE_WB(desc_iter->Buffer1Addr, CONFIG_ETH_DMA_BUFFER_SIZE); /* Increase counter of utilized DMA buffers */ dma_bufcount++; @@ -271,8 +254,7 @@ uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp if (buffs_cnt == 0) { /* Setting the last segment bit */ desc_iter->TDES0.LastSegment = 1; - /* Enable transmit interrupt */ - desc_iter->TDES0.InterruptOnComplete = 1; + desc_iter->TDES0.Value |= emac_esp_dma->tx_desc_flags & EMAC_TDES0_LS_CTRL_FLAGS_MASK; break; } @@ -283,11 +265,7 @@ uint32_t emac_esp_dma_transmit_multiple_buf_frame(emac_esp_dma_handle_t emac_esp /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ for (size_t i = 0; i < dma_bufcount; i++) { emac_esp_dma->tx_desc->TDES0.Own = EMAC_LL_DMADESC_OWNER_DMA; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_tx_descriptor_t); - ret = esp_cache_msync((void *)emac_esp_dma->tx_desc, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif + DMA_CACHE_WB(emac_esp_dma->tx_desc, EMAC_HAL_DMA_DESC_SIZE); emac_esp_dma->tx_desc = (eth_dma_tx_descriptor_t *)(emac_esp_dma->tx_desc->Buffer2NextDescAddr); } @@ -301,25 +279,20 @@ static esp_err_t emac_esp_dma_get_valid_recv_len(emac_esp_dma_handle_t emac_esp_ { eth_dma_rx_descriptor_t *desc_iter = emac_esp_dma->rx_desc; uint32_t used_descs = 0; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - size_t cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - esp_err_t ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); -#endif + DMA_CACHE_INVALIDATE(desc_iter, EMAC_HAL_DMA_DESC_SIZE); /* Traverse descriptors owned by CPU */ - while ((desc_iter->RDES0.Own != EMAC_LL_DMADESC_OWNER_DMA) && (used_descs < CONFIG_ETH_DMA_RX_BUFFER_NUM)) { + while ((desc_iter->RDES0.Own == EMAC_LL_DMADESC_OWNER_CPU) && (used_descs < CONFIG_ETH_DMA_RX_BUFFER_NUM)) { used_descs++; /* Last segment in frame */ if (desc_iter->RDES0.LastDescriptor) { -#if CONFIG_IDF_TARGET_ESP32P4 - /* Since Store Forward must be disabled at ESP32P4, DMA descriptors may contain erroneous frames */ + /* Since Store Forward must be disabled on some targets, DMA descriptors may contain erroneous frames */ + /* In addition, "Descriptor Error" (no free descriptors) may truncate a frame even if Store Forward is enabled */ if (desc_iter->RDES0.ErrSummary) { - emac_esp_dma_flush_recv_frame(emac_esp_dma, NULL, NULL); + emac_esp_dma_flush_recv_frame(emac_esp_dma); *ret_len = 0; return ESP_FAIL; } -#endif //CONFIG_IDF_TARGET_ESP32P4 /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ *ret_len = desc_iter->RDES0.FrameLength - ETH_CRC_LENGTH; break; @@ -330,42 +303,31 @@ static esp_err_t emac_esp_dma_get_valid_recv_len(emac_esp_dma_handle_t emac_esp_ } /* point to next descriptor */ desc_iter = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - size_t cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - esp_err_t ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); -#endif + DMA_CACHE_INVALIDATE(desc_iter, EMAC_HAL_DMA_DESC_SIZE); } return ESP_OK; } -static void emac_esp_dma_get_remain_frames(emac_esp_dma_handle_t emac_esp_dma, uint32_t *remain_frames, uint32_t *used_descs) +void emac_esp_dma_get_remain_frames(emac_esp_dma_handle_t emac_esp_dma, uint32_t *remain_frames, uint32_t *free_descs) { eth_dma_rx_descriptor_t *desc_iter = emac_esp_dma->rx_desc; *remain_frames = 0; - *used_descs = 0; + uint32_t used_descs = 0; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - size_t cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - esp_err_t ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); -#endif + DMA_CACHE_INVALIDATE(desc_iter, EMAC_HAL_DMA_DESC_SIZE); /* Traverse descriptors owned by CPU */ - while ((desc_iter->RDES0.Own != EMAC_LL_DMADESC_OWNER_DMA) && (*used_descs < CONFIG_ETH_DMA_RX_BUFFER_NUM)) { - (*used_descs)++; + while ((desc_iter->RDES0.Own == EMAC_LL_DMADESC_OWNER_CPU) && (used_descs < CONFIG_ETH_DMA_RX_BUFFER_NUM)) { + used_descs++; /* Last segment in frame */ if (desc_iter->RDES0.LastDescriptor) { (*remain_frames)++; } /* point to next descriptor */ desc_iter = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - size_t cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - esp_err_t ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); -#endif + DMA_CACHE_INVALIDATE(desc_iter, EMAC_HAL_DMA_DESC_SIZE); } + *free_descs = CONFIG_ETH_DMA_RX_BUFFER_NUM - used_descs; } uint8_t *emac_esp_dma_alloc_recv_buf(emac_esp_dma_handle_t emac_esp_dma, uint32_t *size) @@ -388,7 +350,7 @@ uint8_t *emac_esp_dma_alloc_recv_buf(emac_esp_dma_handle_t emac_esp_dma, uint32_ /* no need to check allocated buffer min length prior writing since we know that EMAC DMA is configured to not forward erroneous or undersized frames (less than 64B) on ESP32, see emac_hal_init_dma_default */ #ifndef NDEBUG - buff_info->magic_id = EMAC_HAL_BUF_MAGIC_ID; + buff_info->magic_id = EMAC_ALLOC_BUF_MAGIC_ID; #endif // NDEBUG buff_info->copy_len = copy_len; } @@ -398,20 +360,14 @@ uint8_t *emac_esp_dma_alloc_recv_buf(emac_esp_dma_handle_t emac_esp_dma, uint32_ return buf; } -uint32_t emac_esp_dma_receive_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t size, uint32_t *frames_remain, uint32_t *free_desc) +uint32_t emac_esp_dma_receive_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t *buf, uint32_t size) { -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - size_t cache_sync_len; - esp_err_t ret; -#endif - eth_dma_rx_descriptor_t *desc_iter = emac_esp_dma->rx_desc; - eth_dma_rx_descriptor_t *first_desc = emac_esp_dma->rx_desc; uint32_t ret_len = 0; uint32_t copy_len = 0; - if (size != EMAC_HAL_BUF_SIZE_AUTO) { + if (size != EMAC_DMA_BUF_SIZE_AUTO) { if (emac_esp_dma_get_valid_recv_len(emac_esp_dma, &ret_len) != ESP_OK) { - goto err; + return 0; } /* packets larger than expected will be truncated */ copy_len = ret_len > size ? size : ret_len; @@ -419,109 +375,78 @@ uint32_t emac_esp_dma_receive_frame(emac_esp_dma_handle_t emac_esp_dma, uint8_t emac_esp_dma_auto_buf_info_t *buff_info = (emac_esp_dma_auto_buf_info_t *)buf; #ifndef NDEBUG /* check that buffer was allocated by emac_esp_dma_alloc_recv_buf */ - assert(buff_info->magic_id == EMAC_HAL_BUF_MAGIC_ID); + assert(buff_info->magic_id == EMAC_ALLOC_BUF_MAGIC_ID); #endif // NDEBUG copy_len = buff_info->copy_len; ret_len = copy_len; } if (copy_len) { - desc_iter = first_desc; - while(copy_len > CONFIG_ETH_DMA_BUFFER_SIZE) { -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = CONFIG_ETH_DMA_BUFFER_SIZE; - ret = esp_cache_msync((void *)desc_iter->Buffer1Addr, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); -#endif + eth_dma_rx_descriptor_t *desc_iter = emac_esp_dma->rx_desc; + while (copy_len > CONFIG_ETH_DMA_BUFFER_SIZE) { + DMA_CACHE_INVALIDATE(desc_iter->Buffer1Addr, CONFIG_ETH_DMA_BUFFER_SIZE); memcpy(buf, (void *)(desc_iter->Buffer1Addr), CONFIG_ETH_DMA_BUFFER_SIZE); buf += CONFIG_ETH_DMA_BUFFER_SIZE; copy_len -= CONFIG_ETH_DMA_BUFFER_SIZE; /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ desc_iter->RDES0.Own = EMAC_LL_DMADESC_OWNER_DMA; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif + DMA_CACHE_WB(desc_iter, EMAC_HAL_DMA_DESC_SIZE); desc_iter = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); } -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE // TODO cleanup (IDF-8993) - cache_sync_len = CONFIG_ETH_DMA_BUFFER_SIZE; - ret = esp_cache_msync((void *)desc_iter->Buffer1Addr, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); -#endif + DMA_CACHE_INVALIDATE(desc_iter->Buffer1Addr, CONFIG_ETH_DMA_BUFFER_SIZE); memcpy(buf, (void *)(desc_iter->Buffer1Addr), copy_len); desc_iter->RDES0.Own = EMAC_LL_DMADESC_OWNER_DMA; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif + DMA_CACHE_WB(desc_iter, EMAC_HAL_DMA_DESC_SIZE); /* `copy_len` does not include CRC (which may be stored in separate buffer), hence check if we reached the last descriptor */ while (!desc_iter->RDES0.LastDescriptor) { desc_iter = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); desc_iter->RDES0.Own = EMAC_LL_DMADESC_OWNER_DMA; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif + DMA_CACHE_WB(desc_iter, EMAC_HAL_DMA_DESC_SIZE); } /* update rxdesc */ emac_esp_dma->rx_desc = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); /* poll rx demand */ emac_hal_receive_poll_demand(&emac_esp_dma->hal); } -err: - /* check how many frames left to handle */ - uint32_t used_descs = 0; - emac_esp_dma_get_remain_frames(emac_esp_dma, frames_remain, &used_descs); - *free_desc = CONFIG_ETH_DMA_RX_BUFFER_NUM - used_descs; return ret_len; } -void emac_esp_dma_flush_recv_frame(emac_esp_dma_handle_t emac_esp_dma, uint32_t *frames_remain, uint32_t *free_desc) +void emac_esp_dma_flush_recv_frame(emac_esp_dma_handle_t emac_esp_dma) { eth_dma_rx_descriptor_t *desc_iter = emac_esp_dma->rx_desc; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - size_t cache_sync_len; - esp_err_t ret; - cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert (ret == ESP_OK); -#endif + DMA_CACHE_INVALIDATE(desc_iter, EMAC_HAL_DMA_DESC_SIZE); /* While not last descriptor => return back to DMA */ while (!desc_iter->RDES0.LastDescriptor) { desc_iter->RDES0.Own = EMAC_LL_DMADESC_OWNER_DMA; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert (ret == ESP_OK); -#endif + DMA_CACHE_WB(desc_iter, EMAC_HAL_DMA_DESC_SIZE); desc_iter = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); } /* the last descriptor */ desc_iter->RDES0.Own = EMAC_LL_DMADESC_OWNER_DMA; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - cache_sync_len = sizeof(eth_dma_rx_descriptor_t); - ret = esp_cache_msync((void *)desc_iter, cache_sync_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert (ret == ESP_OK); -#endif + DMA_CACHE_WB(desc_iter, EMAC_HAL_DMA_DESC_SIZE); /* update rxdesc */ emac_esp_dma->rx_desc = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); /* poll rx demand */ emac_hal_receive_poll_demand(&emac_esp_dma->hal); +} - if (frames_remain != NULL && free_desc != NULL) { - /* check how many frames left to handle */ - uint32_t used_descs = 0; - emac_esp_dma_get_remain_frames(emac_esp_dma, frames_remain, &used_descs); - *free_desc = CONFIG_ETH_DMA_RX_BUFFER_NUM - used_descs; +esp_err_t emac_esp_del_dma(emac_esp_dma_handle_t emac_esp_dma) +{ + if (emac_esp_dma) { + for (int i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) { + free(emac_esp_dma->tx_buf[i]); + } + for (int i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) { + free(emac_esp_dma->rx_buf[i]); + } + free(emac_esp_dma->descriptors); + free(emac_esp_dma); } + return ESP_OK; } -esp_err_t emac_esp_new_dma(const emac_esp_dma_config_t* config, emac_esp_dma_handle_t *ret_handle) +esp_err_t emac_esp_new_dma(const emac_esp_dma_config_t *config, emac_esp_dma_handle_t *ret_handle) { esp_err_t ret = ESP_OK; *ret_handle = NULL; @@ -531,40 +456,21 @@ esp_err_t emac_esp_new_dma(const emac_esp_dma_config_t* config, emac_esp_dma_han /* alloc memory for ethernet dma descriptor */ uint32_t desc_size = CONFIG_ETH_DMA_RX_BUFFER_NUM * sizeof(eth_dma_rx_descriptor_t) + CONFIG_ETH_DMA_TX_BUFFER_NUM * sizeof(eth_dma_tx_descriptor_t); - esp_dma_mem_info_t dma_mem_info = { - .extra_heap_caps = MALLOC_CAP_INTERNAL, - .dma_alignment_bytes = 4, - }; - esp_dma_capable_calloc(1, desc_size, &dma_mem_info, (void*)&emac_esp_dma->descriptors, NULL); - + emac_esp_dma->descriptors = heap_caps_aligned_calloc(4, 1, desc_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ESP_GOTO_ON_FALSE(emac_esp_dma->descriptors, ESP_ERR_NO_MEM, err, TAG, "no mem for descriptors"); /* alloc memory for ethernet dma buffer */ for (int i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) { - esp_dma_capable_calloc(1, CONFIG_ETH_DMA_BUFFER_SIZE, &dma_mem_info, (void*)&emac_esp_dma->rx_buf[i], NULL); + emac_esp_dma->rx_buf[i] = heap_caps_aligned_calloc(4, 1, CONFIG_ETH_DMA_BUFFER_SIZE, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ESP_GOTO_ON_FALSE(emac_esp_dma->rx_buf[i], ESP_ERR_NO_MEM, err, TAG, "no mem for RX DMA buffers"); } for (int i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) { - esp_dma_capable_calloc(1, CONFIG_ETH_DMA_BUFFER_SIZE, &dma_mem_info, (void*)&emac_esp_dma->tx_buf[i], NULL); + emac_esp_dma->tx_buf[i] = heap_caps_aligned_calloc(4, 1, CONFIG_ETH_DMA_BUFFER_SIZE, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ESP_GOTO_ON_FALSE(emac_esp_dma->tx_buf[i], ESP_ERR_NO_MEM, err, TAG, "no mem for TX DMA buffers"); } emac_hal_init(&emac_esp_dma->hal); *ret_handle = emac_esp_dma; return ESP_OK; err: + emac_esp_del_dma(emac_esp_dma); return ret; } - -esp_err_t emac_esp_del_dma(emac_esp_dma_handle_t emac_esp_dma) -{ - if (emac_esp_dma) { - for (int i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) { - free(emac_esp_dma->tx_buf[i]); - } - for (int i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) { - free(emac_esp_dma->rx_buf[i]); - } - free(emac_esp_dma->descriptors); - free(emac_esp_dma); - } - return ESP_OK; -} diff --git a/components/esp_eth/src/mac/esp_eth_mac_esp_gpio.c b/components/esp_eth/src/mac/esp_eth_mac_esp_gpio.c new file mode 100644 index 000000000000..3117832b294c --- /dev/null +++ b/components/esp_eth/src/mac/esp_eth_mac_esp_gpio.c @@ -0,0 +1,270 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_check.h" +#include "sdkconfig.h" +#include "esp_rom_gpio.h" +#include "driver/gpio.h" +#include "soc/soc_caps.h" +#include "soc/gpio_sig_map.h" +#include "soc/io_mux_reg.h" +#include "soc/gpio_periph.h" +#include "soc/emac_periph.h" +#include "esp_private/gpio.h" +#include "esp_private/eth_mac_esp_gpio.h" +#include "esp_private/esp_gpio_reserve.h" +#include "esp_log.h" + +#define GET_GPIO_OR_SINGLE(cfg, num) cfg == NULL ? GPIO_NUM_MAX : cfg->num + +static const char *TAG = "esp.emac.gpio"; + +static uint64_t s_emac_esp_used_gpio_mask = 0x0; + +static esp_err_t emac_esp_gpio_matrix_init(gpio_num_t gpio_num, uint32_t signal_in_idx, uint32_t signal_out_idx, gpio_mode_t mode) +{ + // silently skip when user don't want to connect the signal to GPIO pad + if (gpio_num <= GPIO_NUM_NC) { + ESP_LOGD(TAG, "%s skipping signal in_idx %" PRIu32 ", out_idx %" PRIu32, __func__, signal_in_idx, signal_out_idx); + return ESP_OK; + } + ESP_RETURN_ON_ERROR(gpio_set_direction(gpio_num, mode), TAG, "failed to set direction %i at GPIO #%i", mode, gpio_num); + switch(mode) { + case GPIO_MODE_INPUT: + ESP_RETURN_ON_FALSE(signal_in_idx != SIG_GPIO_OUT_IDX, ESP_ERR_NOT_SUPPORTED, + TAG, "requested periph signal cannot be connect via GPIO Matrix"); + ESP_RETURN_ON_FALSE(esp_gpio_is_reserved(BIT64(gpio_num)) == false, ESP_ERR_INVALID_STATE, + TAG, "GPIO %i is reserved", gpio_num); + esp_rom_gpio_connect_in_signal(gpio_num, signal_in_idx, false); + break; + case GPIO_MODE_OUTPUT: + ESP_RETURN_ON_FALSE(signal_out_idx != SIG_GPIO_OUT_IDX, ESP_ERR_NOT_SUPPORTED, + TAG, "requested periph signal cannot be connect via GPIO Matrix"); + ESP_RETURN_ON_FALSE((esp_gpio_reserve(BIT64(gpio_num)) & BIT64(gpio_num)) == 0, ESP_ERR_INVALID_STATE, + TAG, "GPIO %i is already reserved", gpio_num); + esp_rom_gpio_connect_out_signal(gpio_num, signal_out_idx, false, false); + break; + case GPIO_MODE_INPUT_OUTPUT: + ESP_RETURN_ON_FALSE(signal_in_idx != SIG_GPIO_OUT_IDX, ESP_ERR_NOT_SUPPORTED, + TAG, "requested periph signal cannot be connect via GPIO Matrix"); + ESP_RETURN_ON_FALSE(signal_out_idx != SIG_GPIO_OUT_IDX, ESP_ERR_NOT_SUPPORTED, + TAG, "requested periph signal cannot be connect via GPIO Matrix"); + ESP_RETURN_ON_FALSE((esp_gpio_reserve(BIT64(gpio_num)) & BIT64(gpio_num)) == 0, ESP_ERR_INVALID_STATE, + TAG, "GPIO %i is already reserved", gpio_num); + esp_rom_gpio_connect_out_signal(gpio_num, signal_out_idx, false, false); + esp_rom_gpio_connect_in_signal(gpio_num, signal_in_idx, false); + break; + default: + return ESP_ERR_INVALID_ARG; + } + s_emac_esp_used_gpio_mask |= BIT64(gpio_num); + ESP_RETURN_ON_ERROR(gpio_set_pull_mode(gpio_num, GPIO_FLOATING), TAG, "failed to set pull mode at GPIO %i", gpio_num); + ESP_RETURN_ON_ERROR(gpio_func_sel(gpio_num, PIN_FUNC_GPIO), TAG, "failed to set GPIO function at GPIO #%i", gpio_num); + return ESP_OK; +} + +static esp_err_t emac_esp_iomux_init(gpio_num_t gpio_num, const emac_iomux_info_t *iomux_info, bool is_input) +{ + // silently skip undefined iomux functions (for example, ESP32 does not use MII COL_IN/CRS_IN) + if (iomux_info == NULL) { + ESP_LOGD(TAG, "%s skipping target undefined iomux periph function", __func__); + return ESP_OK; + } + // silently skip when user don't want to iomux the function to GPIO pad + if (gpio_num <= GPIO_NUM_NC) { + ESP_LOGD(TAG, "%s user defined GPIO not connected - skipping", __func__); + return ESP_OK; + } + // loop over target iomux_info until reached end of list indicated by invalid GPIO num + while (iomux_info->gpio_num != GPIO_NUM_MAX) { + // if requested GPIO number can be IO muxed or select single pad that can be muxed on the target + if(gpio_num == iomux_info->gpio_num || gpio_num == GPIO_NUM_MAX) { + ESP_RETURN_ON_FALSE((esp_gpio_reserve(BIT64(iomux_info->gpio_num)) & BIT64(iomux_info->gpio_num)) == 0, ESP_ERR_INVALID_STATE, + TAG, "GPIO %i is already reserved", iomux_info->gpio_num); + s_emac_esp_used_gpio_mask |= BIT64(iomux_info->gpio_num); + ESP_RETURN_ON_ERROR(gpio_func_sel(iomux_info->gpio_num, iomux_info->func), TAG, "failed to set GPIO function at GPIO %i", iomux_info->gpio_num); + if (is_input) { + PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[iomux_info->gpio_num]); + } else { + PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[iomux_info->gpio_num]); + } + ESP_RETURN_ON_ERROR(gpio_set_pull_mode(iomux_info->gpio_num, GPIO_FLOATING), + TAG, "failed to set pull mode at GPIO %i", iomux_info->gpio_num); + return ESP_OK; + } + iomux_info++; + } + return ESP_FAIL; +} + +esp_err_t emac_esp_gpio_init_smi(const emac_esp_smi_gpio_config_t *smi_gpio) +{ + if (smi_gpio->mdc_num >= 0) { + /* Setup SMI MDC GPIO */ + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(smi_gpio->mdc_num, 0, emac_io_idx.mdc_idx, GPIO_MODE_OUTPUT), + TAG, "MDC GPIO matrix config failed"); + } + if (smi_gpio->mdio_num >= 0) { + /* Setup SMI MDIO GPIO */ + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(smi_gpio->mdio_num, emac_io_idx.mdi_idx, emac_io_idx.mdo_idx, GPIO_MODE_INPUT_OUTPUT), + TAG, "MDIO GPIO matrix config failed"); + } + return ESP_OK; +} + +esp_err_t emac_esp_gpio_matrix_init_mii(const eth_mac_mii_gpio_config_t *mii_gpio) +{ + ESP_RETURN_ON_FALSE(mii_gpio != NULL, ESP_ERR_INVALID_ARG, TAG, "MII IO matrix config cannot be NULL"); + + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->tx_clk_num, emac_io_idx.mii_tx_clk_i_idx, 0, GPIO_MODE_INPUT), + TAG, "TX_CLK GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->tx_en_num, 0, emac_io_idx.mii_tx_en_o_idx, GPIO_MODE_OUTPUT), + TAG, "TX_EN GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->txd0_num, 0, emac_io_idx.mii_txd0_o_idx, GPIO_MODE_OUTPUT), + TAG, "TDX0 GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->txd1_num, 0, emac_io_idx.mii_txd1_o_idx, GPIO_MODE_OUTPUT), + TAG, "TDX1 GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->txd2_num, 0, emac_io_idx.mii_txd2_o_idx, GPIO_MODE_OUTPUT), + TAG, "TDX2 GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->txd3_num, 0, emac_io_idx.mii_txd3_o_idx, GPIO_MODE_OUTPUT), + TAG, "TDX3 GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->rx_clk_num, emac_io_idx.mii_rx_clk_i_idx, 0, GPIO_MODE_INPUT), + TAG, "RX_CLK GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->rxd0_num, emac_io_idx.mii_rxd0_i_idx, 0, GPIO_MODE_INPUT), + TAG, "RXD0 GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->rxd1_num, emac_io_idx.mii_rxd1_i_idx, 0, GPIO_MODE_INPUT), + TAG, "RXD1 GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->rxd2_num, emac_io_idx.mii_rxd2_i_idx, 0, GPIO_MODE_INPUT), + TAG, "RXD2 GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->rxd3_num, emac_io_idx.mii_rxd3_i_idx, 0, GPIO_MODE_INPUT), + TAG, "RXD3 GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->col_in_num, emac_io_idx.mii_col_i_idx, 0, GPIO_MODE_INPUT), + TAG, "COL_IN GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->crs_in_num, emac_io_idx.mii_crs_i_idx, 0, GPIO_MODE_INPUT), + TAG, "CRS_IN GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->tx_er_num, 0, emac_io_idx.mii_tx_er_o_idx, GPIO_MODE_OUTPUT), + TAG, "TX_ER GPIO matrix config failed"); + ESP_RETURN_ON_ERROR(emac_esp_gpio_matrix_init(mii_gpio->rx_er_num, emac_io_idx.mii_rx_er_i_idx, 0, GPIO_MODE_INPUT), + TAG, "RX_ER GPIO matrix config failed"); + + return ESP_OK; +} + +esp_err_t emac_esp_iomux_init_mii(const eth_mac_mii_gpio_config_t *mii_gpio) +{ + ESP_RETURN_ON_FALSE(emac_mii_iomux_pins.clk_tx != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support MII IOMUX"); + + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, tx_clk_num), emac_mii_iomux_pins.clk_tx, true), + TAG, "invalid TX_CLK GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, tx_en_num), emac_mii_iomux_pins.tx_en, false), + TAG, "invalid TX_EN GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd0_num), emac_mii_iomux_pins.txd0, false), + TAG, "invalid TXD0 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd1_num), emac_mii_iomux_pins.txd1, false), + TAG, "invalid TXD1 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd2_num), emac_mii_iomux_pins.txd2, false), + TAG, "invalid TXD2 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, txd3_num), emac_mii_iomux_pins.txd3, false), + TAG, "invalid TXD3 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rx_clk_num), emac_mii_iomux_pins.clk_rx, true), + TAG, "invalid RX_CLK GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rx_dv_num), emac_mii_iomux_pins.rx_dv, true), + TAG, "invalid RX_DV GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd0_num), emac_mii_iomux_pins.rxd0, true), + TAG, "invalid RXD0 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd1_num), emac_mii_iomux_pins.rxd1, true), + TAG, "invalid RXD1 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd2_num), emac_mii_iomux_pins.rxd2, true), + TAG, "invalid RXD2 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, rxd3_num), emac_mii_iomux_pins.rxd3, true), + TAG, "invalid RXD3 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, col_in_num), emac_mii_iomux_pins.col_in, true), + TAG, "invalid COL_IN GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(mii_gpio, crs_in_num), emac_mii_iomux_pins.crs_in, true), + TAG, "invalid CRS_IN GPIO number"); + return ESP_OK; +} + +esp_err_t emac_esp_iomux_rmii_clk_input(int num) +{ + ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.clki != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII CLKI IOMUX"); + + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.clki, true), TAG, "invalid RMII CLK input GPIO number"); + return ESP_OK; +} + +esp_err_t emac_esp_iomux_rmii_clk_ouput(int num) +{ + ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.clko != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII CLKO IOMUX"); + + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.clko, false), TAG, "invalid RMII CLK output GPIO number"); + return ESP_OK; +} + +esp_err_t emac_esp_iomux_init_rmii(const eth_mac_rmii_gpio_config_t *rmii_gpio) +{ + ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.clki != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII IOMUX"); + + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, tx_en_num), emac_rmii_iomux_pins.tx_en, false), + TAG, "invalid TX_EN GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, txd0_num), emac_rmii_iomux_pins.txd0, false), + TAG, "invalid TXD0 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, txd1_num), emac_rmii_iomux_pins.txd1, false), + TAG, "invalid TXD1 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, crs_dv_num), emac_rmii_iomux_pins.crs_dv, true), + TAG,"invalid CRS_DV GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, rxd0_num), emac_rmii_iomux_pins.rxd0, true), + TAG,"invalid RXD0 GPIO number"); + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(GET_GPIO_OR_SINGLE(rmii_gpio, rxd1_num), emac_rmii_iomux_pins.rxd1, true), + TAG,"invalid RXD1 GPIO number"); + + return ESP_OK; +} + +esp_err_t emac_esp_iomux_rmii_init_tx_er(int num) +{ + ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.tx_er != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII TX_ER IOMUX"); + + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.tx_er, false), TAG, "invalid TX_ER GPIO number"); + return ESP_OK; +} + +esp_err_t emac_esp_iomux_rmii_init_rx_er(int num) +{ + ESP_RETURN_ON_FALSE(emac_rmii_iomux_pins.rx_er != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII RX_ER IOMUX"); + + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_rmii_iomux_pins.rx_er, true), TAG, "invalid RX_ER GPIO number"); + return ESP_OK; +} + +esp_err_t emac_esp_iomux_mii_init_tx_er(int num) +{ + ESP_RETURN_ON_FALSE(emac_mii_iomux_pins.tx_er != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support MII TX_ER IOMUX"); + + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_mii_iomux_pins.tx_er, false), TAG, "invalid TX_ER GPIO number"); + return ESP_OK; +} + +esp_err_t emac_esp_iomux_mii_init_rx_er(int num) +{ + ESP_RETURN_ON_FALSE(emac_mii_iomux_pins.rx_er != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "target does not support RMII RX_ER IOMUX"); + + ESP_RETURN_ON_ERROR(emac_esp_iomux_init(num, emac_mii_iomux_pins.rx_er, true), TAG, "invalid RX_ER GPIO number"); + return ESP_OK; +} + +esp_err_t emac_esp_gpio_deinit_all(void) +{ + for (int gpio_num = 0; gpio_num < 64; gpio_num++) { + if (BIT64(gpio_num) & s_emac_esp_used_gpio_mask) { + gpio_reset_pin(gpio_num); + esp_gpio_revoke(BIT64(gpio_num)); + } + s_emac_esp_used_gpio_mask &= ~BIT64(gpio_num); + } + return ESP_OK; +} diff --git a/components/esp_eth/src/esp_eth_mac_openeth.c b/components/esp_eth/src/openeth/esp_eth_mac_openeth.c similarity index 99% rename from components/esp_eth/src/esp_eth_mac_openeth.c rename to components/esp_eth/src/openeth/esp_eth_mac_openeth.c index 60241c8f7e47..0cf8d914423f 100644 --- a/components/esp_eth/src/esp_eth_mac_openeth.c +++ b/components/esp_eth/src/openeth/esp_eth_mac_openeth.c @@ -21,12 +21,12 @@ #include "esp_log.h" #include "esp_check.h" #include "esp_cpu.h" -#include "esp_eth_driver.h" #include "esp_intr_alloc.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "openeth.h" #include "esp_mac.h" +#include "esp_eth_mac_openeth.h" static const char *TAG = "opencores.emac"; diff --git a/components/esp_eth/src/openeth/esp_openeth.h b/components/esp_eth/src/openeth/esp_openeth.h new file mode 100644 index 000000000000..2aab7410c1bf --- /dev/null +++ b/components/esp_eth/src/openeth/esp_openeth.h @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "sdkconfig.h" +#include "soc/interrupts.h" + +/* + * For targets which don't have an ethernet MAC and the associated interrupt source, + * we can reuse the Wifi interrupt source for ethernet, since QEMU doesn't emulate Wifi (yet). + * We also map the EMAC registers to an unused address range. + */ +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#define ETS_ETH_MAC_INTR_SOURCE ETS_WIFI_MAC_INTR_SOURCE +#define DR_REG_EMAC_BASE 0x600CD000 +#endif diff --git a/components/esp_eth/src/openeth.h b/components/esp_eth/src/openeth/openeth.h similarity index 99% rename from components/esp_eth/src/openeth.h rename to components/esp_eth/src/openeth/openeth.h index da1e25a0d5d0..70a4c9d8209d 100644 --- a/components/esp_eth/src/openeth.h +++ b/components/esp_eth/src/openeth/openeth.h @@ -114,7 +114,7 @@ extern "C" { typedef struct { uint16_t cs: 1; //!< Carrier sense lost (flag set by HW) uint16_t df: 1; //!< Defer indication (flag set by HW) - uint16_t lc: 1; //!< Late collision occured (flag set by HW) + uint16_t lc: 1; //!< Late collision occurred (flag set by HW) uint16_t rl: 1; //!< TX failed due to retransmission limit (flag set by HW) uint16_t rtry: 4; //!< Number of retries before the frame was sent (set by HW) uint16_t ur: 1; //!< Underrun status (flag set by HW) diff --git a/components/esp_eth/src/esp_eth_phy_802_3.c b/components/esp_eth/src/phy/esp_eth_phy_802_3.c similarity index 100% rename from components/esp_eth/src/esp_eth_phy_802_3.c rename to components/esp_eth/src/phy/esp_eth_phy_802_3.c diff --git a/components/esp_eth/src/esp_eth_phy_dp83848.c b/components/esp_eth/src/phy/esp_eth_phy_dp83848.c similarity index 94% rename from components/esp_eth/src/esp_eth_phy_dp83848.c rename to components/esp_eth/src/phy/esp_eth_phy_dp83848.c index fc771b072f76..7ae69b24bf1e 100644 --- a/components/esp_eth/src/esp_eth_phy_dp83848.c +++ b/components/esp_eth/src/phy/esp_eth_phy_dp83848.c @@ -77,13 +77,15 @@ static esp_err_t dp83848_update_link_duplex_speed(phy_dp83848_t *dp83848) uint32_t peer_pause_ability = false; anlpar_reg_t anlpar; physts_reg_t physts; - ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_ANLPAR_REG_ADDR, &(anlpar.val)), err, TAG, "read ANLPAR failed"); - ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_STS_REG_ADDR, &(physts.val)), err, TAG, "read PHYSTS failed"); - eth_link_t link = physts.link_status ? ETH_LINK_UP : ETH_LINK_DOWN; + bmsr_reg_t bmsr; + ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed"); + eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN; /* check if link status changed */ if (dp83848->phy_802_3.link_status != link) { /* when link up, read negotiation result */ if (link == ETH_LINK_UP) { + ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_ANLPAR_REG_ADDR, &(anlpar.val)), err, TAG, "read ANLPAR failed"); + ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_STS_REG_ADDR, &(physts.val)), err, TAG, "read PHYSTS failed"); if (physts.speed_status) { speed = ETH_SPEED_10M; } else { diff --git a/components/esp_eth/src/esp_eth_phy_ip101.c b/components/esp_eth/src/phy/esp_eth_phy_ip101.c similarity index 99% rename from components/esp_eth/src/esp_eth_phy_ip101.c rename to components/esp_eth/src/phy/esp_eth_phy_ip101.c index c9a187d690ac..e66fb78b93e5 100644 --- a/components/esp_eth/src/esp_eth_phy_ip101.c +++ b/components/esp_eth/src/phy/esp_eth_phy_ip101.c @@ -62,7 +62,7 @@ typedef union { */ typedef union { struct { - uint32_t op_mode : 3; /* Operation Mode Idicator */ + uint32_t op_mode : 3; /* Operation Mode Indicator */ uint32_t force_mdix : 1; /* Force the MDIX channel to be selected */ uint32_t reserved1 : 4; /* Reserved */ uint32_t link_up : 1; /* Indicate the link status is OK or FAIL */ diff --git a/components/esp_eth/src/esp_eth_phy_ksz80xx.c b/components/esp_eth/src/phy/esp_eth_phy_ksz80xx.c similarity index 100% rename from components/esp_eth/src/esp_eth_phy_ksz80xx.c rename to components/esp_eth/src/phy/esp_eth_phy_ksz80xx.c diff --git a/components/esp_eth/src/esp_eth_phy_lan87xx.c b/components/esp_eth/src/phy/esp_eth_phy_lan87xx.c similarity index 100% rename from components/esp_eth/src/esp_eth_phy_lan87xx.c rename to components/esp_eth/src/phy/esp_eth_phy_lan87xx.c diff --git a/components/esp_eth/src/esp_eth_phy_rtl8201.c b/components/esp_eth/src/phy/esp_eth_phy_rtl8201.c similarity index 100% rename from components/esp_eth/src/esp_eth_phy_rtl8201.c rename to components/esp_eth/src/phy/esp_eth_phy_rtl8201.c diff --git a/components/esp_eth/src/dm9051.h b/components/esp_eth/src/spi/dm9051/dm9051.h similarity index 100% rename from components/esp_eth/src/dm9051.h rename to components/esp_eth/src/spi/dm9051/dm9051.h diff --git a/components/esp_eth/src/esp_eth_mac_dm9051.c b/components/esp_eth/src/spi/dm9051/esp_eth_mac_dm9051.c similarity index 99% rename from components/esp_eth/src/esp_eth_mac_dm9051.c rename to components/esp_eth/src/spi/dm9051/esp_eth_mac_dm9051.c index 4ae68ba9a599..6e892b38b780 100644 --- a/components/esp_eth/src/esp_eth_mac_dm9051.c +++ b/components/esp_eth/src/spi/dm9051/esp_eth_mac_dm9051.c @@ -8,12 +8,12 @@ #include #include #include +#include "esp_eth_mac_spi.h" #include "driver/gpio.h" #include "driver/spi_master.h" #include "esp_attr.h" #include "esp_log.h" #include "esp_check.h" -#include "esp_eth_driver.h" #include "esp_timer.h" #include "esp_system.h" #include "esp_intr_alloc.h" diff --git a/components/esp_eth/src/esp_eth_phy_dm9051.c b/components/esp_eth/src/spi/dm9051/esp_eth_phy_dm9051.c similarity index 99% rename from components/esp_eth/src/esp_eth_phy_dm9051.c rename to components/esp_eth/src/spi/dm9051/esp_eth_phy_dm9051.c index 6db49f8fad0a..4e0507f1e181 100644 --- a/components/esp_eth/src/esp_eth_phy_dm9051.c +++ b/components/esp_eth/src/spi/dm9051/esp_eth_phy_dm9051.c @@ -67,7 +67,7 @@ typedef union { uint32_t monsel1 : 1; /* Vendor monitor select */ uint32_t mdix_down : 1; /* Set 1 to disable HP Auto-MDIX */ uint32_t mdix_fix : 1; /* When mdix_down = 1, MDIX_CNTL value depend on the register value. */ - uint32_t autoneg_lpbk : 1; /* Set 1 to enable autonegotioation loopback */ + uint32_t autoneg_lpbk : 1; /* Set 1 to enable autonegotiation loopback */ uint32_t mdxi_cntl : 1; /* Polarity of MDI/MDIX value */ uint32_t reserved2 : 1; /* Reserved */ uint32_t nway_pwr : 1; /* Set 1 to enable power savings during autonegotiation period */ @@ -195,7 +195,7 @@ static esp_err_t dm9051_loopback(esp_eth_phy_t *phy, bool enable) phy_802_3_t *phy_802_3 = esp_eth_phy_into_phy_802_3(phy); esp_eth_mediator_t *eth = phy_802_3->eth; /* Set Loopback function */ - // Enable Auto-negotiation loopback in Speficic control register + // Enable Auto-negotiation loopback in Specific control register bmcr_reg_t bmcr; scr_reg_t scr; ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, phy_802_3->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed"); diff --git a/components/esp_eth/src/esp_eth_mac_ksz8851snl.c b/components/esp_eth/src/spi/ksz8851snl/esp_eth_mac_ksz8851snl.c similarity index 99% rename from components/esp_eth/src/esp_eth_mac_ksz8851snl.c rename to components/esp_eth/src/spi/ksz8851snl/esp_eth_mac_ksz8851snl.c index 76fa5d998743..ae0b60f88186 100644 --- a/components/esp_eth/src/esp_eth_mac_ksz8851snl.c +++ b/components/esp_eth/src/spi/ksz8851snl/esp_eth_mac_ksz8851snl.c @@ -8,6 +8,7 @@ #include #include +#include "esp_eth_mac_spi.h" #include "esp_log.h" #include "esp_check.h" #include "esp_cpu.h" @@ -17,7 +18,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" -#include "esp_eth_driver.h" #include "ksz8851.h" #include "esp_timer.h" diff --git a/components/esp_eth/src/esp_eth_phy_ksz8851snl.c b/components/esp_eth/src/spi/ksz8851snl/esp_eth_phy_ksz8851snl.c similarity index 99% rename from components/esp_eth/src/esp_eth_phy_ksz8851snl.c rename to components/esp_eth/src/spi/ksz8851snl/esp_eth_phy_ksz8851snl.c index d520000bd65a..cbec083a0cc4 100644 --- a/components/esp_eth/src/esp_eth_phy_ksz8851snl.c +++ b/components/esp_eth/src/spi/ksz8851snl/esp_eth_phy_ksz8851snl.c @@ -6,6 +6,7 @@ * SPDX-FileContributor: 2021-2024 Espressif Systems (Shanghai) CO LTD */ #include +#include "esp_eth_phy.h" #include "esp_check.h" #include "esp_heap_caps.h" #include "esp_log.h" @@ -13,7 +14,6 @@ #include "esp_rom_gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_eth_driver.h" #include "ksz8851.h" @@ -149,7 +149,7 @@ static esp_err_t phy_ksz8851_deinit(esp_eth_phy_t *phy) /** * @note This function is responsible for restarting a new auto-negotiation, - * the result of negotiation won't be relected to uppler layers. + * the result of negotiation won't be reflected to upper layers. * Instead, the negotiation result is fetched by linker timer, see `phy_ksz8851_get_link()` */ static esp_err_t phy_ksz8851_autonego_ctrl(esp_eth_phy_t *phy, eth_phy_autoneg_cmd_t cmd, bool *autonego_en_stat) diff --git a/components/esp_eth/src/ksz8851.h b/components/esp_eth/src/spi/ksz8851snl/ksz8851.h similarity index 95% rename from components/esp_eth/src/ksz8851.h rename to components/esp_eth/src/spi/ksz8851snl/ksz8851.h index 44c1087b6c57..02b2a4e35594 100644 --- a/components/esp_eth/src/ksz8851.h +++ b/components/esp_eth/src/spi/ksz8851snl/ksz8851.h @@ -1,22 +1,11 @@ -// Copyright (c) 2021 Vladimir Chistyakov -// -// 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. +/* + * SPDX-FileCopyrightText: 2021 Vladimir Chistyakov + * + * SPDX-License-Identifier: MIT + * + * SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD + */ + #pragma once @@ -314,7 +303,7 @@ typedef enum { P1ANAR_ADV_10_HALF = 0x0020U, ///< RW Adv 10 Half P1ANLPR_NEXT_PAGE = 0x8000U, ///< RO Next page (not supported) - P1ANLPR_LP_ACK = 0x4000U, ///< RO LP ACK (not suppported) + P1ANLPR_LP_ACK = 0x4000U, ///< RO LP ACK (not supported) P1ANLPR_REMOTE_FAULT = 0x2000U, ///< RO Remote fault (not supported) P1ANLPR_PAUSE = 0x0400U, ///< RO Pause P1ANLPR_ADV_100_FULL = 0x0100U, ///< RO Adv 100 Full diff --git a/components/esp_eth/src/esp_eth_mac_w5500.c b/components/esp_eth/src/spi/w5500/esp_eth_mac_w5500.c similarity index 99% rename from components/esp_eth/src/esp_eth_mac_w5500.c rename to components/esp_eth/src/spi/w5500/esp_eth_mac_w5500.c index 895585160366..2f0ea028fe7e 100644 --- a/components/esp_eth/src/esp_eth_mac_w5500.c +++ b/components/esp_eth/src/spi/w5500/esp_eth_mac_w5500.c @@ -7,12 +7,12 @@ #include #include #include +#include "esp_eth_mac_spi.h" #include "driver/gpio.h" #include "driver/spi_master.h" #include "esp_attr.h" #include "esp_log.h" #include "esp_check.h" -#include "esp_eth_driver.h" #include "esp_system.h" #include "esp_intr_alloc.h" #include "esp_heap_caps.h" @@ -550,7 +550,7 @@ static esp_err_t emac_w5500_enable_flow_ctrl(esp_eth_mac_t *mac, bool enable) static esp_err_t emac_w5500_set_peer_pause_ability(esp_eth_mac_t *mac, uint32_t ability) { - /* w5500 doesn't suppport PAUSE function, so accept any value */ + /* w5500 doesn't support PAUSE function, so accept any value */ return ESP_ERR_NOT_SUPPORTED; } @@ -823,7 +823,7 @@ static esp_err_t emac_w5500_init(esp_eth_mac_t *mac) /* reset w5500 */ ESP_GOTO_ON_ERROR(w5500_reset(emac), err, TAG, "reset w5500 failed"); /* verify chip id */ - ESP_GOTO_ON_ERROR(w5500_verify_id(emac), err, TAG, "vefiry chip ID failed"); + ESP_GOTO_ON_ERROR(w5500_verify_id(emac), err, TAG, "verify chip ID failed"); /* default setup of internal registers */ ESP_GOTO_ON_ERROR(w5500_setup_default(emac), err, TAG, "w5500 default setup failed"); return ESP_OK; diff --git a/components/esp_eth/src/esp_eth_phy_w5500.c b/components/esp_eth/src/spi/w5500/esp_eth_phy_w5500.c similarity index 99% rename from components/esp_eth/src/esp_eth_phy_w5500.c rename to components/esp_eth/src/spi/w5500/esp_eth_phy_w5500.c index d211681c1c18..834cf54088fc 100644 --- a/components/esp_eth/src/esp_eth_phy_w5500.c +++ b/components/esp_eth/src/spi/w5500/esp_eth_phy_w5500.c @@ -6,9 +6,9 @@ #include #include #include +#include "esp_eth_phy.h" #include "esp_log.h" #include "esp_check.h" -#include "esp_eth_driver.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" diff --git a/components/esp_eth/src/w5500.h b/components/esp_eth/src/spi/w5500/w5500.h similarity index 100% rename from components/esp_eth/src/w5500.h rename to components/esp_eth/src/spi/w5500/w5500.h diff --git a/components/esp_eth/test_apps/main/CMakeLists.txt b/components/esp_eth/test_apps/main/CMakeLists.txt index a1c785ae45a4..ff51914b322b 100644 --- a/components/esp_eth/test_apps/main/CMakeLists.txt +++ b/components/esp_eth/test_apps/main/CMakeLists.txt @@ -5,6 +5,6 @@ idf_component_register(SRCS "esp_eth_test_apps.c" "esp_eth_test_main.c" INCLUDE_DIRS "." PRIV_INCLUDE_DIRS "." - PRIV_REQUIRES unity test_utils esp_eth esp_netif esp_http_client + PRIV_REQUIRES unity test_utils esp_eth esp_netif esp_http_client esp_driver_gpio EMBED_TXTFILES dl_espressif_com_root_cert.pem WHOLE_ARCHIVE) diff --git a/components/esp_eth/test_apps/main/esp_eth_test_common.c b/components/esp_eth/test_apps/main/esp_eth_test_common.c index 2e366d12b6f4..4876307b8630 100644 --- a/components/esp_eth/test_apps/main/esp_eth_test_common.c +++ b/components/esp_eth/test_apps/main/esp_eth_test_common.c @@ -36,15 +36,15 @@ esp_eth_mac_t *mac_init(void *vendor_emac_config, eth_mac_config_t *mac_config) #if CONFIG_TARGET_USE_INTERNAL_ETHERNET eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); #if !CONFIG_TARGET_USE_DEFAULT_EMAC_CONFIG - esp32_emac_config.smi_mdc_gpio_num = CONFIG_TARGET_IO_MDC; - esp32_emac_config.smi_mdio_gpio_num = CONFIG_TARGET_IO_MDIO; + esp32_emac_config.smi_gpio.mdc_num = CONFIG_TARGET_IO_MDC; + esp32_emac_config.smi_gpio.mdio_num = CONFIG_TARGET_IO_MDIO; #endif // CONFIG_TARGET_USE_DEFAULT_EMAC_CONFIG if (vendor_emac_config == NULL) { vendor_emac_config = &esp32_emac_config; } mac = esp_eth_mac_new_esp32(vendor_emac_config, mac_config); #elif CONFIG_TARGET_USE_SPI_ETHERNET - // Install GPIO ISR handler to be able to service SPI Eth modlues interrupts + // Install GPIO ISR handler to be able to service SPI Eth modules interrupts gpio_install_isr_service(0); spi_bus_config_t buscfg = { diff --git a/components/esp_eth/test_apps/main/esp_eth_test_esp_emac.c b/components/esp_eth/test_apps/main/esp_eth_test_esp_emac.c index 43cfa34897d3..5056c8648256 100644 --- a/components/esp_eth/test_apps/main/esp_eth_test_esp_emac.c +++ b/components/esp_eth/test_apps/main/esp_eth_test_esp_emac.c @@ -9,10 +9,11 @@ #include "freertos/event_groups.h" #include "esp_log.h" #include "esp_eth_test_common.h" +#include "hal/emac_hal.h" // for MAC_HAL_TDES0_* control bits -#define ETHERTYPE_TX_STD 0x2222 // frame transmitted via emac_hal_transmit_frame -#define ETHERTYPE_TX_MULTI_2 0x2223 // frame transmitted via emac_hal_transmit_multiple_buf_frame (2 buffers) -#define ETHERTYPE_TX_MULTI_3 0x2224 // frame transmitted via emac_hal_transmit_multiple_buf_frame (3 buffers) +#define ETHERTYPE_TX_STD 0x2222 // frame transmitted via _transmit_frame +#define ETHERTYPE_TX_MULTI_2 0x2223 // frame transmitted via _transmit_multiple_buf_frame (2 buffers) +#define ETHERTYPE_TX_MULTI_3 0x2224 // frame transmitted via _transmit_multiple_buf_frame (3 buffers) #define MINIMUM_TEST_FRAME_SIZE 64 @@ -36,12 +37,12 @@ static esp_err_t eth_recv_esp_emac_check_cb(esp_eth_handle_t hdl, uint8_t *buffe ESP_LOGI(TAG, "recv frame size: %" PRIu16, expected_size); TEST_ASSERT_EQUAL(expected_size, length); - // frame transmitted via emac_hal_transmit_frame + // frame transmitted via _transmit_frame if (pkt->proto == ETHERTYPE_TX_STD) { for (int i = 0; i < recv_info->expected_size - ETH_HEADER_LEN; i++) { TEST_ASSERT_EQUAL(pkt->data[i], i & 0xFF); } - // frame transmitted via emac_hal_transmit_multiple_buf_frame (2 buffers) + // frame transmitted via _multiple_buf_frame (2 buffers) } else if (pkt->proto == ETHERTYPE_TX_MULTI_2) { uint8_t *data_p = pkt->data; for (int i = 0; i < recv_info->expected_size - ETH_HEADER_LEN; i++) { @@ -357,15 +358,17 @@ TEST_CASE("internal emac interrupt priority", "[esp_emac]") vEventGroupDelete(eth_event_group); } -#if CONFIG_IDF_TARGET_ESP32P4 // IDF-8993 -#include "hal/emac_hal.h" -#include "hal/emac_ll.h" -#include "soc/emac_mac_struct.h" -static esp_err_t eth_recv_err_esp_emac_check_cb(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv) +#define TEST_FRAMES_NUM CONFIG_ETH_DMA_RX_BUFFER_NUM + +static uint8_t *s_recv_frames[TEST_FRAMES_NUM]; +static uint8_t s_recv_frames_cnt = 0; + +static esp_err_t eth_recv_esp_emac_err_check_cb(esp_eth_handle_t hdl, uint8_t *buffer, uint32_t length, void *priv) { SemaphoreHandle_t mutex = (SemaphoreHandle_t)priv; - free(buffer); - xSemaphoreGive(mutex); + s_recv_frames[s_recv_frames_cnt++] = buffer; + if (s_recv_frames_cnt >= TEST_FRAMES_NUM) + xSemaphoreGive(mutex); return ESP_OK; } @@ -394,7 +397,7 @@ TEST_CASE("internal emac erroneous frames", "[esp_emac]") bool loopback_en = true; esp_eth_ioctl(eth_handle, ETH_CMD_S_PHY_LOOPBACK, &loopback_en); - TEST_ESP_OK(esp_eth_update_input_path(eth_handle, eth_recv_err_esp_emac_check_cb, mutex)); + TEST_ESP_OK(esp_eth_update_input_path(eth_handle, eth_recv_esp_emac_err_check_cb, mutex)); // start the driver TEST_ESP_OK(esp_eth_start(eth_handle)); @@ -413,23 +416,96 @@ TEST_CASE("internal emac erroneous frames", "[esp_emac]") TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, local_mac_addr)); memcpy(test_pkt->src, local_mac_addr, ETH_ADDR_LEN); // fill with data - for (int i = 0; i < ETH_MAX_PAYLOAD_LEN; i++) { + int i; + for (i = 1; i < ETH_MAX_PAYLOAD_LEN; i++) { test_pkt->data[i] = i & 0xFF; } - emac_ll_checksum_offload_mode(&EMAC_MAC, ETH_CHECKSUM_SW); + size_t transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE; + uint8_t frame_id = 0; - size_t transmit_size = 1072; - TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size)); + ESP_LOGI(TAG, "Verify non-failure frame condition"); + for (i = 1; i <= TEST_FRAMES_NUM; i++) { + test_pkt->data[0] = frame_id++; + TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size)); + // if we have only 10 or less Rx buffers, they can be all used pretty fast => wait to be freed prior next Tx + if (CONFIG_ETH_DMA_RX_BUFFER_NUM <= 10 && !(i % (CONFIG_ETH_DMA_RX_BUFFER_NUM / 2))) { + ESP_LOGI(TAG, "wait prior Tx (frame num %i)", i); + vTaskDelay(10); + } + } + ESP_LOGI(TAG, "num of sent frames: %d", TEST_FRAMES_NUM); TEST_ASSERT(xSemaphoreTake(mutex, pdMS_TO_TICKS(500))); + ESP_LOGI(TAG, "num of recv frames: %d", s_recv_frames_cnt); - free(test_pkt); + for (i = 0; i < s_recv_frames_cnt; i++) { + emac_frame_t *recv_frame = (emac_frame_t *)s_recv_frames[i]; + ESP_LOGI(TAG, "recv frame id %" PRIu8, recv_frame->data[0]); + free(recv_frame); + } + TEST_ASSERT_EQUAL_UINT8(TEST_FRAMES_NUM, s_recv_frames_cnt); + s_recv_frames_cnt = 0; + + printf("\n"); + ESP_LOGI(TAG, "Verify failure condition when every second frame has invalid CRC"); + uint32_t emac_tx_dbg_flag = EMAC_HAL_TDES0_CRC_APPEND_DISABLE; + for (i = 1; i <= TEST_FRAMES_NUM; i++) { + test_pkt->data[0] = frame_id++; + // make every 2nd frame invalid + if (!(i % 2)) { + TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_MAC_ESP_CMD_SET_TDES0_CFG_BITS, &emac_tx_dbg_flag)); + } + TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size)); + if (!(i % 2)) { + TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_MAC_ESP_CMD_CLEAR_TDES0_CFG_BITS, &emac_tx_dbg_flag)); + } + } + ESP_LOGI(TAG, "num of sent frames: %d (every 2nd invalid)", TEST_FRAMES_NUM); + TEST_ASSERT_FALSE(xSemaphoreTake(mutex, pdMS_TO_TICKS(500))); + ESP_LOGI(TAG, "num of recv frames: %d", s_recv_frames_cnt); + + for (i = 0; i < s_recv_frames_cnt; i++) { + emac_frame_t *recv_frame = (emac_frame_t *)s_recv_frames[i]; + ESP_LOGI(TAG, "recv frame id %" PRIu8, recv_frame->data[0]); + free(recv_frame); + } + TEST_ASSERT_EQUAL_UINT8(TEST_FRAMES_NUM / 2, s_recv_frames_cnt); + s_recv_frames_cnt = 0; + + ESP_LOGI(TAG, "Verify full Rx DMA failure condition"); + // suspend ETH Rx task so the DMA is filled + vTaskSuspend(xTaskGetHandle("emac_rx")); + transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE - 4; // -4 bytes to the frame fit into one descriptor even with CRC + // fill the descriptors, keep one free + for (i = 1; i <= CONFIG_ETH_DMA_RX_BUFFER_NUM - 1; i++) { + test_pkt->data[0] = frame_id++; + TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size)); + vTaskDelay(1); // to prevent "insufficient TX buffer size" error + } + transmit_size = CONFIG_ETH_DMA_BUFFER_SIZE; // now, we will need 2 descriptors to store the frame (with CRC) but only one is free + test_pkt->data[0] = frame_id++; + TEST_ESP_OK(esp_eth_transmit(eth_handle, test_pkt, transmit_size)); + vTaskDelay(50); + vTaskResume(xTaskGetHandle("emac_rx")); + + ESP_LOGI(TAG, "num of sent frames: %d", i); + TEST_ASSERT_FALSE(xSemaphoreTake(mutex, pdMS_TO_TICKS(500))); + ESP_LOGI(TAG, "num of recv frames: %d", s_recv_frames_cnt); + + for (i = 0; i < s_recv_frames_cnt; i++) { + emac_frame_t *recv_frame = (emac_frame_t *)s_recv_frames[i]; + ESP_LOGI(TAG, "recv frame id %" PRIu8, recv_frame->data[0]); + free(recv_frame); + } + TEST_ASSERT_EQUAL_INT(CONFIG_ETH_DMA_RX_BUFFER_NUM - 1, s_recv_frames_cnt); // one frame is missing due to "Descriptor Error" + s_recv_frames_cnt = 0; // stop Ethernet driver TEST_ESP_OK(esp_eth_stop(eth_handle)); - /* wait for connection stop */ + // wait for connection stop bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS)); TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT); + free(test_pkt); TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle)); TEST_ESP_OK(phy->del(phy)); TEST_ESP_OK(mac->del(mac)); @@ -439,4 +515,3 @@ TEST_CASE("internal emac erroneous frames", "[esp_emac]") vEventGroupDelete(eth_event_group); vSemaphoreDelete(mutex); } -#endif diff --git a/components/esp_hid/src/nimble_hidd.c b/components/esp_hid/src/nimble_hidd.c index eec5fc4abffe..dc37302e05f2 100644 --- a/components/esp_hid/src/nimble_hidd.c +++ b/components/esp_hid/src/nimble_hidd.c @@ -657,7 +657,7 @@ esp_err_t esp_ble_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_conf .queue_size = 5, .task_name = "ble_hidd_events", .task_priority = uxTaskPriorityGet(NULL), - .task_stack_size = 2048, + .task_stack_size = 4096, .task_core_id = tskNO_AFFINITY }; rc = esp_event_loop_create(&event_task_args, &s_dev->event_loop_handle); diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 372d86e900f3..8ac63e8f8bdb 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/esp_http_client.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -657,9 +657,11 @@ static bool init_common_tcp_transport(esp_http_client_handle_t client, const esp } if (config->if_name) { - client->if_name = calloc(1, sizeof(struct ifreq)); - ESP_RETURN_ON_FALSE(client->if_name, false, TAG, "Memory exhausted"); - memcpy(client->if_name, config->if_name, sizeof(struct ifreq)); + if (client->if_name == NULL) { + client->if_name = calloc(1, sizeof(struct ifreq)); + ESP_RETURN_ON_FALSE(client->if_name, false, TAG, "Memory exhausted"); + memcpy(client->if_name, config->if_name, sizeof(struct ifreq)); + } esp_transport_tcp_set_interface_name(transport, client->if_name); } return true; @@ -957,9 +959,19 @@ esp_err_t esp_http_client_set_redirection(esp_http_client_handle_t client) return err; } +esp_err_t esp_http_client_reset_redirect_counter(esp_http_client_handle_t client) +{ + if (client == NULL) { + return ESP_ERR_INVALID_ARG; + } + client->redirect_counter = 0; + return ESP_OK; +} + static esp_err_t esp_http_check_response(esp_http_client_handle_t client) { if (client->response->status_code >= HttpStatus_Ok && client->response->status_code < HttpStatus_MultipleChoices) { + client->redirect_counter = 0; return ESP_OK; } if (client->redirect_counter >= client->max_redirection_count) { diff --git a/components/esp_http_client/include/esp_http_client.h b/components/esp_http_client/include/esp_http_client.h index 1c50a1fa5aef..bb9319e42d1d 100644 --- a/components/esp_http_client/include/esp_http_client.h +++ b/components/esp_http_client/include/esp_http_client.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -36,7 +36,7 @@ typedef enum { HTTP_EVENT_ERROR = 0, /*!< This event occurs when there are any errors during execution */ HTTP_EVENT_ON_CONNECTED, /*!< Once the HTTP has been connected to the server, no data exchange has been performed */ HTTP_EVENT_HEADERS_SENT, /*!< After sending all the headers to the server */ - HTTP_EVENT_HEADER_SENT = HTTP_EVENT_HEADERS_SENT, /*!< This header has been kept for backward compatability + HTTP_EVENT_HEADER_SENT = HTTP_EVENT_HEADERS_SENT, /*!< This header has been kept for backward compatibility and will be deprecated in future versions esp-idf */ HTTP_EVENT_ON_HEADER, /*!< Occurs when receiving each header sent from the server */ HTTP_EVENT_ON_DATA, /*!< Occurs when receiving data from the server, possibly multiple portions of the packet */ @@ -125,7 +125,7 @@ typedef enum { typedef enum { HTTP_AUTH_TYPE_NONE = 0, /*!< No authention */ HTTP_AUTH_TYPE_BASIC, /*!< HTTP Basic authentication */ - HTTP_AUTH_TYPE_DIGEST, /*!< HTTP Disgest authentication */ + HTTP_AUTH_TYPE_DIGEST, /*!< HTTP Digest authentication */ } esp_http_client_auth_type_t; /** @@ -249,7 +249,7 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co * must be set while making a call to esp_http_client_init() API. * You can do any amount of calls to esp_http_client_perform while using the same esp_http_client_handle_t. The underlying connection may be kept open if the server allows it. * If you intend to transfer more than one file, you are even encouraged to do so. - * esp_http_client will then attempt to re-use the same connection for the following transfers, thus making the operations faster, less CPU intense and using less network resources. + * esp_http_client will then attempt to reuse the same connection for the following transfers, thus making the operations faster, less CPU intense and using less network resources. * Just note that you will have to use `esp_http_client_set_**` between the invokes to set options for the following esp_http_client_perform. * * @note You must never call this function simultaneously from two places using the same client handle. @@ -612,7 +612,7 @@ esp_http_client_transport_t esp_http_client_get_transport_type(esp_http_client_h * @brief Set redirection URL. * When received the 30x code from the server, the client stores the redirect URL provided by the server. * This function will set the current URL to redirect to enable client to execute the redirection request. - * When `disable_auto_redirect` is set, the client will not call this function but the event `HTTP_EVENT_REDIRECT` will be dispatched giving the user contol over the redirection event. + * When `disable_auto_redirect` is set, the client will not call this function but the event `HTTP_EVENT_REDIRECT` will be dispatched giving the user control over the redirection event. * * @param[in] client The esp_http_client handle * @@ -622,6 +622,18 @@ esp_http_client_transport_t esp_http_client_get_transport_type(esp_http_client_h */ esp_err_t esp_http_client_set_redirection(esp_http_client_handle_t client); +/** + * @brief Reset the redirection counter. + * This is useful to reset redirect counter in cases where the same handle is used for multiple requests. + * + * @param[in] client The esp_http_client handle + * + * @return + * - ESP_OK + * - ESP_ERR_INVALID_ARG + */ +esp_err_t esp_http_client_reset_redirect_counter(esp_http_client_handle_t client); + /** * @brief On receiving a custom authentication header, this API can be invoked to set the * authentication information from the header. This API can be called from the event @@ -676,7 +688,7 @@ int esp_http_client_read_response(esp_http_client_handle_t client, char *buffer, /** * @brief Process all remaining response data * This uses an internal buffer to repeatedly receive, parse, and discard response data until complete data is processed. - * As no additional user-supplied buffer is required, this may be preferrable to `esp_http_client_read_response` in situations where the content of the response may be ignored. + * As no additional user-supplied buffer is required, this may be preferable to `esp_http_client_read_response` in situations where the content of the response may be ignored. * * @param[in] client The esp_http_client handle * @param len Length of data discarded diff --git a/components/esp_http_server/src/util/ctrl_sock.c b/components/esp_http_server/src/util/ctrl_sock.c index 65d6e7f972d4..36eb5b055bb7 100644 --- a/components/esp_http_server/src/util/ctrl_sock.c +++ b/components/esp_http_server/src/util/ctrl_sock.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,7 @@ #include #include #include "sdkconfig.h" - +#include "esp_log.h" #include "ctrl_sock.h" #if CONFIG_IDF_TARGET_LINUX @@ -22,11 +22,20 @@ #define IPV6_ENABLED CONFIG_LWIP_IPV6 #endif // !CONFIG_IDF_TARGET_LINUX +#if !CONFIG_LWIP_NETIF_LOOPBACK +static const char *TAG = "esp_http_server"; +#endif + /* Control socket, because in some network stacks select can't be woken up any * other way */ int cs_create_ctrl_sock(int port) { +#if !CONFIG_LWIP_NETIF_LOOPBACK + ESP_LOGE(TAG, "Please enable LWIP_NETIF_LOOPBACK for %s API", __func__); + return -1; +#endif + int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { return -1; diff --git a/components/esp_https_server/src/https_server.c b/components/esp_https_server/src/https_server.c index f8693ffb9461..058faab30e80 100644 --- a/components/esp_https_server/src/https_server.c +++ b/components/esp_https_server/src/https_server.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -366,7 +366,6 @@ static esp_err_t create_secure_context(const struct httpd_ssl_config *config, ht free((void *) cfg->cacert_buf); } free(cfg); - free(*ssl_ctx); return ret; } @@ -379,14 +378,17 @@ esp_err_t httpd_ssl_start(httpd_handle_t *pHandle, struct httpd_ssl_config *conf ESP_LOGI(TAG, "Starting server"); esp_err_t ret = ESP_OK; + httpd_ssl_ctx_t *ssl_ctx = NULL; + if (HTTPD_SSL_TRANSPORT_SECURE == config->transport_mode) { - httpd_ssl_ctx_t *ssl_ctx = calloc(1, sizeof(httpd_ssl_ctx_t)); + ssl_ctx = calloc(1, sizeof(httpd_ssl_ctx_t)); if (!ssl_ctx) { return ESP_ERR_NO_MEM; } ret = create_secure_context(config, &ssl_ctx); if (ret != ESP_OK) { + free(ssl_ctx); return ret; } @@ -411,7 +413,11 @@ esp_err_t httpd_ssl_start(httpd_handle_t *pHandle, struct httpd_ssl_config *conf httpd_handle_t handle = NULL; ret = httpd_start(&handle, &config->httpd); - if (ret != ESP_OK) return ret; + if (ret != ESP_OK) { + free(ssl_ctx); + ssl_ctx = NULL; + return ret; + } *pHandle = handle; diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index db2c68dadd81..c872e56b7166 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -68,13 +68,16 @@ if(NOT BOOTLOADER_BUILD) endif() if(CONFIG_SOC_GDMA_SUPPORTED) - list(APPEND srcs "dma/gdma.c") + list(APPEND srcs "dma/gdma.c" "deprecated/gdma_legacy.c") if(CONFIG_SOC_GDMA_SUPPORT_SLEEP_RETENTION) list(APPEND srcs "dma/gdma_sleep_retention.c") endif() if(CONFIG_SOC_GDMA_SUPPORT_ETM) list(APPEND srcs "dma/gdma_etm.c") endif() + if(CONFIG_SOC_GDMA_SUPPORT_CRC) + list(APPEND srcs "dma/gdma_crc.c") + endif() endif() if(CONFIG_SOC_GP_LDO_SUPPORTED) @@ -185,7 +188,7 @@ idf_component_register(SRCS ${srcs} PRIV_INCLUDE_DIRS port/include include/esp_private REQUIRES ${requires} PRIV_REQUIRES "${priv_requires}" - LDFRAGMENTS linker.lf dma/linker.lf) + LDFRAGMENTS linker.lf dma/linker.lf ldo/linker.lf) idf_build_get_property(target IDF_TARGET) add_subdirectory(port/${target}) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index e1924af8c9b7..196d54e723d0 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -214,18 +214,6 @@ menu "Hardware Settings" callback and hence it is highly recommended to keep them as short as possible. endmenu - menu "ESP_SLEEP_WORKAROUND" - # No visible menu/configs for workaround - visible if 0 - config ESP_SLEEP_SYSTIMER_STALL_WORKAROUND - bool "ESP32C3 SYSTIMER Stall Issue Workaround" - depends on IDF_TARGET_ESP32C3 - help - Its not able to stall ESP32C3 systimer in sleep. - To fix related RTOS TICK issue, select it to disable related systimer during sleep. - TODO: IDF-7036 - endmenu - menu "RTC Clock Config" orsource "./port/$IDF_TARGET/Kconfig.rtc" endmenu @@ -337,6 +325,8 @@ menu "Hardware Settings" endmenu + orsource "./port/$IDF_TARGET/Kconfig.dcdc" + orsource "./port/$IDF_TARGET/Kconfig.ldo" # Invisible bringup bypass options for esp_hw_support component diff --git a/components/esp_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c index 86d3738d5e0c..32f3c67b79b8 100644 --- a/components/esp_hw_support/adc_share_hw_ctrl.c +++ b/components/esp_hw_support/adc_share_hw_ctrl.c @@ -12,7 +12,7 @@ * * However, usages of above components are different. * Therefore, we put the common used parts into `esp_hw_support`, including: - * - adc power maintainance + * - adc power maintenance * - adc hw calibration settings * - adc locks, to prevent concurrently using adc hw */ @@ -205,10 +205,10 @@ void adc_apb_periph_claim(void) portENTER_CRITICAL(&s_spinlock); s_adc_digi_ctrlr_cnt++; if (s_adc_digi_ctrlr_cnt == 1) { - //enable ADC digital part - periph_module_enable(PERIPH_SARADC_MODULE); - //reset ADC digital part - periph_module_reset(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_enable_bus_clock(true); + adc_ll_reset_register(); + } } portEXIT_CRITICAL(&s_spinlock); @@ -219,7 +219,9 @@ void adc_apb_periph_free(void) portENTER_CRITICAL(&s_spinlock); s_adc_digi_ctrlr_cnt--; if (s_adc_digi_ctrlr_cnt == 0) { - periph_module_disable(PERIPH_SARADC_MODULE); + ADC_BUS_CLK_ATOMIC() { + adc_ll_enable_bus_clock(false); + } } else if (s_adc_digi_ctrlr_cnt < 0) { portEXIT_CRITICAL(&s_spinlock); ESP_LOGE(TAG, "%s called, but `s_adc_digi_ctrlr_cnt == 0`", __func__); diff --git a/components/esp_hw_support/clk_ctrl_os.c b/components/esp_hw_support/clk_ctrl_os.c index 4866b65a8eb8..a8b2560abb85 100644 --- a/components/esp_hw_support/clk_ctrl_os.c +++ b/components/esp_hw_support/clk_ctrl_os.c @@ -10,6 +10,8 @@ #include "esp_ldo_regulator.h" #include "esp_private/esp_clk_tree_common.h" #include "esp_check.h" +#include "hal/clk_tree_hal.h" +#include "hal/clk_tree_ll.h" #if SOC_CLK_MPLL_SUPPORTED #include "rtc_clk.h" #endif @@ -137,7 +139,7 @@ esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq, uint32_t *real_freq) #endif // SOC_CLK_APLL_SUPPORTED #if SOC_CLK_MPLL_SUPPORTED -esp_err_t periph_rtc_mpll_acquire(void) +esp_err_t IRAM_ATTR periph_rtc_mpll_acquire(void) { // power up LDO for the MPLL #if defined(CONFIG_ESP_LDO_CHAN_PSRAM_DOMAIN) && CONFIG_ESP_LDO_CHAN_PSRAM_DOMAIN != -1 @@ -176,7 +178,7 @@ void periph_rtc_mpll_release(void) portEXIT_CRITICAL(&periph_spinlock); } -esp_err_t periph_rtc_mpll_freq_set(uint32_t expt_freq, uint32_t *real_freq) +esp_err_t IRAM_ATTR periph_rtc_mpll_freq_set(uint32_t expt_freq, uint32_t *real_freq) { esp_err_t ret = ESP_OK; @@ -190,10 +192,9 @@ esp_err_t periph_rtc_mpll_freq_set(uint32_t expt_freq, uint32_t *real_freq) /* If MPLL is not in use or only one peripheral in use, its frequency can be changed as will * But when more than one peripheral refers MPLL, its frequency is not allowed to change once it is set */ if (s_cur_mpll_freq == 0 || s_mpll_ref_cnt < 2) { - uint32_t xtal_freq = 0; - ESP_ERROR_CHECK(esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_XTAL, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &xtal_freq)); - rtc_clk_mpll_configure(xtal_freq / MHZ, expt_freq / MHZ); - ESP_ERROR_CHECK(esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_MPLL, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &s_cur_mpll_freq)); + uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz(); + rtc_clk_mpll_configure(xtal_freq_mhz, expt_freq / MHZ); + s_cur_mpll_freq = clk_ll_mpll_get_freq_mhz(xtal_freq_mhz); } else { ret = ESP_ERR_INVALID_STATE; } diff --git a/components/esp_hw_support/deprecated/gdma_legacy.c b/components/esp_hw_support/deprecated/gdma_legacy.c new file mode 100644 index 000000000000..f25dd2c8ab51 --- /dev/null +++ b/components/esp_hw_support/deprecated/gdma_legacy.c @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +#include "esp_check.h" +#include "../dma/gdma_priv.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" + +static const char *TAG = "gdma"; + +esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability) +{ + ESP_RETURN_ON_FALSE(dma_chan && ability, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + gdma_pair_t *pair = dma_chan->pair; + gdma_group_t *group = pair->group; + gdma_hal_context_t *hal = &group->hal; + + size_t int_mem_alignment = ability->sram_trans_align; + size_t ext_mem_alignment = ability->psram_trans_align; + // alignment should be 2^n + ESP_RETURN_ON_FALSE((int_mem_alignment & (int_mem_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, + TAG, "invalid sram alignment: %zu", int_mem_alignment); + + uint32_t ext_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); + if (ext_mem_alignment == 0) { + // fall back to use the same size of the psram data cache line size + ext_mem_alignment = ext_mem_cache_line_size; + } + if ((ext_mem_cache_line_size > 0) && (ext_mem_alignment > ext_mem_cache_line_size)) { + ESP_RETURN_ON_FALSE(((ext_mem_alignment % ext_mem_cache_line_size) == 0), ESP_ERR_INVALID_ARG, + TAG, "ext_mem_alignment(%d) should be multiple of the ext_mem_cache_line_size(%"PRIu32")", + ext_mem_alignment, ext_mem_cache_line_size); + } + + // if the DMA can't access the PSRAM, this HAL function is no-op + gdma_hal_set_burst_size(hal, pair->pair_id, dma_chan->direction, ext_mem_alignment); + + // TX channel can always enable burst mode, no matter data alignment + bool en_burst = true; + if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) { + // RX channel burst mode depends on specific data alignment + en_burst = int_mem_alignment >= 4; + } + gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_burst, en_burst); + + dma_chan->int_mem_alignment = int_mem_alignment; + dma_chan->ext_mem_alignment = ext_mem_alignment; + ESP_LOGD(TAG, "%s channel (%d,%d), (%u:%u) bytes aligned, burst %s", dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX ? "tx" : "rx", + group->group_id, pair->pair_id, int_mem_alignment, ext_mem_alignment, en_burst ? "enabled" : "disabled"); + + return ESP_OK; +} diff --git a/components/esp_hw_support/dma/Kconfig.dma b/components/esp_hw_support/dma/Kconfig.dma index 48aef8846a19..fa43dd6ea8ee 100644 --- a/components/esp_hw_support/dma/Kconfig.dma +++ b/components/esp_hw_support/dma/Kconfig.dma @@ -19,7 +19,7 @@ menu "GDMA Configurations" bool "Enable debug log" default n help - Wether to enable the debug log message for GDMA driver. + Whether to enable the debug log message for GDMA driver. Note that, this option only controls the GDMA driver log, won't affect other drivers. endmenu # GDMA Configurations @@ -40,6 +40,13 @@ menu "DW_GDMA Configurations" Place DW_GDMA setter functions (e.g. dw_gdma_channel_set_block_markers) into IRAM, so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. + config DW_GDMA_GETTER_FUNC_IN_IRAM + bool + default n + help + Place DW_GDMA getter functions (e.g. dw_gdma_link_list_get_item) into IRAM, + so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. + config DW_GDMA_ISR_IRAM_SAFE bool default n @@ -52,7 +59,7 @@ menu "DW_GDMA Configurations" bool "Enable debug log" default n help - Wether to enable the debug log message for DW_GDMA driver. + Whether to enable the debug log message for DW_GDMA driver. Note that, this option only controls the DW_GDMA driver log, won't affect other drivers. endmenu # DW_GDMA Configurations diff --git a/components/esp_hw_support/dma/async_memcpy_cp_dma.c b/components/esp_hw_support/dma/async_memcpy_cp_dma.c index 975bb92c369e..e86bf10a18e8 100644 --- a/components/esp_hw_support/dma/async_memcpy_cp_dma.c +++ b/components/esp_hw_support/dma/async_memcpy_cp_dma.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -48,7 +48,6 @@ typedef struct async_memcpy_transaction_t { /// @note - Number of transaction objects are determined by the backlog parameter typedef struct { async_memcpy_context_t parent; // Parent IO interface - size_t sram_trans_align; // DMA transfer alignment (both in size and address) for SRAM memory size_t max_single_dma_buffer; // max DMA buffer size by a single descriptor cp_dma_hal_context_t hal; // CPDMA hal intr_handle_t intr; // CPDMA interrupt handle @@ -90,7 +89,7 @@ esp_err_t esp_async_memcpy_install_cpdma(const async_memcpy_config_t *config, as uint32_t trans_queue_len = config->backlog ? config->backlog : DEFAULT_TRANSACTION_QUEUE_LENGTH; // allocate memory for transaction pool, aligned to 4 because the trans->eof_node requires that alignment mcp_dma->transaction_pool = heap_caps_aligned_calloc(4, trans_queue_len, sizeof(async_memcpy_transaction_t), - MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); + MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); ESP_GOTO_ON_FALSE(mcp_dma->transaction_pool, ESP_ERR_NO_MEM, err, TAG, "no mem for transaction pool"); // Init hal context @@ -111,8 +110,7 @@ esp_err_t esp_async_memcpy_install_cpdma(const async_memcpy_config_t *config, as // initialize other members portMUX_INITIALIZE(&mcp_dma->spin_lock); atomic_init(&mcp_dma->fsm, MCP_FSM_IDLE); - mcp_dma->sram_trans_align = config->sram_trans_align; - size_t trans_align = config->sram_trans_align; + size_t trans_align = config->dma_burst_size; mcp_dma->max_single_dma_buffer = trans_align ? ALIGN_DOWN(DMA_DESCRIPTOR_BUFFER_MAX_SIZE, trans_align) : DMA_DESCRIPTOR_BUFFER_MAX_SIZE; mcp_dma->parent.del = mcp_cpdma_del; mcp_dma->parent.memcpy = mcp_cpdma_memcpy; @@ -240,12 +238,6 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void * esp_err_t ret = ESP_OK; async_memcpy_cpdma_context_t *mcp_dma = __containerof(ctx, async_memcpy_cpdma_context_t, parent); ESP_RETURN_ON_FALSE(esp_ptr_internal(src) && esp_ptr_internal(dst), ESP_ERR_INVALID_ARG, TAG, "CP_DMA can only access SRAM"); - // alignment check - if (mcp_dma->sram_trans_align) { - ESP_RETURN_ON_FALSE((((intptr_t)dst & (mcp_dma->sram_trans_align - 1)) == 0), ESP_ERR_INVALID_ARG, TAG, "buffer address not aligned: %p -> %p", src, dst); - ESP_RETURN_ON_FALSE(((n & (mcp_dma->sram_trans_align - 1)) == 0), ESP_ERR_INVALID_ARG, TAG, - "copy size should align to %d bytes", mcp_dma->sram_trans_align); - } async_memcpy_transaction_t *trans = NULL; // pick one transaction node from idle queue trans = try_pop_trans_from_idle_queue(mcp_dma); @@ -257,12 +249,12 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void * uint32_t num_desc_per_path = (n + max_single_dma_buffer - 1) / max_single_dma_buffer; // allocate DMA descriptors, descriptors need a strict alignment trans->tx_desc_link = heap_caps_aligned_calloc(4, num_desc_per_path, sizeof(dma_descriptor_align4_t), - MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); + MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); ESP_GOTO_ON_FALSE(trans->tx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors"); // don't have to allocate the EOF descriptor, we will use trans->eof_node as the RX EOF descriptor if (num_desc_per_path > 1) { trans->rx_desc_link = heap_caps_aligned_calloc(4, num_desc_per_path - 1, sizeof(dma_descriptor_align4_t), - MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); + MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); ESP_GOTO_ON_FALSE(trans->rx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors"); } else { // small copy buffer, use the trans->eof_node is sufficient diff --git a/components/esp_hw_support/dma/async_memcpy_gdma.c b/components/esp_hw_support/dma/async_memcpy_gdma.c index 8b8fa19930fe..b2a2db7574b5 100644 --- a/components/esp_hw_support/dma/async_memcpy_gdma.c +++ b/components/esp_hw_support/dma/async_memcpy_gdma.c @@ -68,9 +68,10 @@ typedef struct async_memcpy_transaction_t { /// @note - Number of transaction objects are determined by the backlog parameter typedef struct { async_memcpy_context_t parent; // Parent IO interface - size_t descriptor_align; // DMA descriptor alignment - size_t sram_trans_align; // DMA buffer alignment (both in size and address) for SRAM memory - size_t psram_trans_align; // DMA buffer alignment (both in size and address) for PSRAM memory + size_t rx_int_mem_alignment; // DMA buffer alignment (both in size and address) for internal RX memory + size_t rx_ext_mem_alignment; // DMA buffer alignment (both in size and address) for external RX memory + size_t tx_int_mem_alignment; // DMA buffer alignment (both in size and address) for internal TX memory + size_t tx_ext_mem_alignment; // DMA buffer alignment (both in size and address) for external TX memory size_t max_single_dma_buffer; // max DMA buffer size by a single descriptor int gdma_bus_id; // GDMA bus id (AHB, AXI, etc.) gdma_channel_handle_t tx_channel; // GDMA TX channel handle @@ -117,13 +118,10 @@ static esp_err_t esp_async_memcpy_install_gdma_template(const async_memcpy_confi mcp_gdma = heap_caps_calloc(1, sizeof(async_memcpy_gdma_context_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ESP_GOTO_ON_FALSE(mcp_gdma, ESP_ERR_NO_MEM, err, TAG, "no mem for driver context"); uint32_t trans_queue_len = config->backlog ? config->backlog : DEFAULT_TRANSACTION_QUEUE_LENGTH; - // allocate memory for transaction pool - uint32_t data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); - uint32_t alignment = MAX(data_cache_line_size, MCP_DMA_DESC_ALIGN); - mcp_gdma->transaction_pool = heap_caps_aligned_calloc(alignment, trans_queue_len, sizeof(async_memcpy_transaction_t), + // allocate memory for transaction pool from internal memory because transaction structure contains DMA descriptor + mcp_gdma->transaction_pool = heap_caps_aligned_calloc(MCP_DMA_DESC_ALIGN, trans_queue_len, sizeof(async_memcpy_transaction_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); ESP_GOTO_ON_FALSE(mcp_gdma->transaction_pool, ESP_ERR_NO_MEM, err, TAG, "no mem for transaction pool"); - mcp_gdma->descriptor_align = alignment; // create TX channel and RX channel, they should reside in the same DMA pair gdma_channel_alloc_config_t tx_alloc_config = { @@ -146,12 +144,12 @@ static esp_err_t esp_async_memcpy_install_gdma_template(const async_memcpy_confi ESP_GOTO_ON_ERROR(gdma_connect(mcp_gdma->rx_channel, m2m_trigger), err, TAG, "GDMA rx connect failed"); ESP_GOTO_ON_ERROR(gdma_connect(mcp_gdma->tx_channel, m2m_trigger), err, TAG, "GDMA tx connect failed"); - gdma_transfer_ability_t transfer_ability = { - .sram_trans_align = config->sram_trans_align, - .psram_trans_align = config->psram_trans_align, + gdma_transfer_config_t transfer_cfg = { + .max_data_burst_size = config->dma_burst_size ? config->dma_burst_size : 16, + .access_ext_mem = true, // allow to do memory copy from/to external memory }; - ESP_GOTO_ON_ERROR(gdma_set_transfer_ability(mcp_gdma->tx_channel, &transfer_ability), err, TAG, "set tx trans ability failed"); - ESP_GOTO_ON_ERROR(gdma_set_transfer_ability(mcp_gdma->rx_channel, &transfer_ability), err, TAG, "set rx trans ability failed"); + ESP_GOTO_ON_ERROR(gdma_config_transfer(mcp_gdma->tx_channel, &transfer_cfg), err, TAG, "config transfer for tx channel failed"); + ESP_GOTO_ON_ERROR(gdma_config_transfer(mcp_gdma->rx_channel, &transfer_cfg), err, TAG, "config transfer for rx channel failed"); // register rx eof callback gdma_rx_event_callbacks_t cbs = { @@ -172,15 +170,13 @@ static esp_err_t esp_async_memcpy_install_gdma_template(const async_memcpy_confi atomic_init(&mcp_gdma->fsm, MCP_FSM_IDLE); mcp_gdma->gdma_bus_id = gdma_bus_id; - uint32_t psram_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); - uint32_t sram_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); - // if the psram_trans_align is configured to zero, we should fall back to use the data cache line size - size_t psram_trans_align = MAX(psram_cache_line_size, config->psram_trans_align); - size_t sram_trans_align = MAX(sram_cache_line_size, config->sram_trans_align); - size_t trans_align = MAX(sram_trans_align, psram_trans_align); - mcp_gdma->max_single_dma_buffer = ALIGN_DOWN(DMA_DESCRIPTOR_BUFFER_MAX_SIZE, trans_align); - mcp_gdma->psram_trans_align = psram_trans_align; - mcp_gdma->sram_trans_align = sram_trans_align; + // get the buffer alignment required by the GDMA channel + gdma_get_alignment_constraints(mcp_gdma->rx_channel, &mcp_gdma->rx_int_mem_alignment, &mcp_gdma->rx_ext_mem_alignment); + gdma_get_alignment_constraints(mcp_gdma->tx_channel, &mcp_gdma->tx_int_mem_alignment, &mcp_gdma->tx_ext_mem_alignment); + + size_t buf_align = MAX(MAX(mcp_gdma->rx_int_mem_alignment, mcp_gdma->rx_ext_mem_alignment), + MAX(mcp_gdma->tx_int_mem_alignment, mcp_gdma->tx_ext_mem_alignment)); + mcp_gdma->max_single_dma_buffer = ALIGN_DOWN(DMA_DESCRIPTOR_BUFFER_MAX_SIZE, buf_align); mcp_gdma->parent.del = mcp_gdma_del; mcp_gdma->parent.memcpy = mcp_gdma_memcpy; #if SOC_GDMA_SUPPORT_ETM @@ -335,29 +331,21 @@ static async_memcpy_transaction_t *try_pop_trans_from_idle_queue(async_memcpy_gd static bool check_buffer_alignment(async_memcpy_gdma_context_t *mcp_gdma, void *src, void *dst, size_t n) { bool valid = true; - uint32_t psram_align_mask = 0; - uint32_t sram_align_mask = 0; - if (mcp_gdma->psram_trans_align) { - psram_align_mask = mcp_gdma->psram_trans_align - 1; - } - if (mcp_gdma->sram_trans_align) { - sram_align_mask = mcp_gdma->sram_trans_align - 1; - } if (esp_ptr_external_ram(dst)) { - valid = valid && (((uint32_t)dst & psram_align_mask) == 0); - valid = valid && ((n & psram_align_mask) == 0); + valid = valid && (((uint32_t)dst & (mcp_gdma->rx_ext_mem_alignment - 1)) == 0); + valid = valid && ((n & (mcp_gdma->rx_ext_mem_alignment - 1)) == 0); } else { - valid = valid && (((uint32_t)dst & sram_align_mask) == 0); - valid = valid && ((n & sram_align_mask) == 0); + valid = valid && (((uint32_t)dst & (mcp_gdma->rx_int_mem_alignment - 1)) == 0); + valid = valid && ((n & (mcp_gdma->rx_int_mem_alignment - 1)) == 0); } if (esp_ptr_external_ram(src)) { - valid = valid && (((uint32_t)src & psram_align_mask) == 0); - valid = valid && ((n & psram_align_mask) == 0); + valid = valid && (((uint32_t)src & (mcp_gdma->tx_ext_mem_alignment - 1)) == 0); + valid = valid && ((n & (mcp_gdma->tx_ext_mem_alignment - 1)) == 0); } else { - valid = valid && (((uint32_t)src & sram_align_mask) == 0); - valid = valid && ((n & sram_align_mask) == 0); + valid = valid && (((uint32_t)src & (mcp_gdma->tx_int_mem_alignment - 1)) == 0); + valid = valid && ((n & (mcp_gdma->tx_int_mem_alignment - 1)) == 0); } return valid; @@ -390,14 +378,14 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s // calculate how many descriptors we want size_t max_single_dma_buffer = mcp_gdma->max_single_dma_buffer; uint32_t num_desc_per_path = (n + max_single_dma_buffer - 1) / max_single_dma_buffer; - // allocate DMA descriptors, descriptors need a strict alignment - trans->tx_desc_link = heap_caps_aligned_calloc(mcp_gdma->descriptor_align, num_desc_per_path, sizeof(mcp_dma_descriptor_t), + // allocate DMA descriptors from internal memory + trans->tx_desc_link = heap_caps_aligned_calloc(MCP_DMA_DESC_ALIGN, num_desc_per_path, sizeof(mcp_dma_descriptor_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); ESP_GOTO_ON_FALSE(trans->tx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors"); trans->tx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->tx_desc_link); // don't have to allocate the EOF descriptor, we will use trans->eof_node as the RX EOF descriptor if (num_desc_per_path > 1) { - trans->rx_desc_link = heap_caps_aligned_calloc(mcp_gdma->descriptor_align, num_desc_per_path - 1, sizeof(mcp_dma_descriptor_t), + trans->rx_desc_link = heap_caps_aligned_calloc(MCP_DMA_DESC_ALIGN, num_desc_per_path - 1, sizeof(mcp_dma_descriptor_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); ESP_GOTO_ON_FALSE(trans->rx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors"); trans->rx_desc_nc = (mcp_dma_descriptor_t *)MCP_GET_NON_CACHE_ADDR(trans->rx_desc_link); diff --git a/components/esp_hw_support/dma/dma2d.c b/components/esp_hw_support/dma/dma2d.c index dab310d02cc3..bd6f0a4dbb5a 100644 --- a/components/esp_hw_support/dma/dma2d.c +++ b/components/esp_hw_support/dma/dma2d.c @@ -571,7 +571,7 @@ esp_err_t dma2d_connect(dma2d_channel_handle_t dma2d_chan, const dma2d_trigger_t // Configure reorder functionality dma2d_ll_tx_enable_reorder(group->hal.dev, channel_id, dma2d_chan->status.reorder_en); // Assume dscr_port enable or not can be directly derived from trig_periph - dma2d_ll_tx_enable_dscr_port(group->hal.dev, channel_id, trig_periph->periph == DMA2D_TRIG_PERIPH_PPA_SR); + dma2d_ll_tx_enable_dscr_port(group->hal.dev, channel_id, trig_periph->periph == DMA2D_TRIG_PERIPH_PPA_SRM); // Reset to certain settings dma2d_ll_tx_enable_owner_check(group->hal.dev, channel_id, false); @@ -596,7 +596,7 @@ esp_err_t dma2d_connect(dma2d_channel_handle_t dma2d_chan, const dma2d_trigger_t // Configure reorder functionality dma2d_ll_rx_enable_reorder(group->hal.dev, channel_id, dma2d_chan->status.reorder_en); // Assume dscr_port enable or not can be directly derived from trig_periph - dma2d_ll_rx_enable_dscr_port(group->hal.dev, channel_id, trig_periph->periph == DMA2D_TRIG_PERIPH_PPA_SR); + dma2d_ll_rx_enable_dscr_port(group->hal.dev, channel_id, trig_periph->periph == DMA2D_TRIG_PERIPH_PPA_SRM); // Reset to certain settings dma2d_ll_rx_enable_owner_check(group->hal.dev, channel_id, false); @@ -871,6 +871,24 @@ esp_err_t dma2d_configure_color_space_conversion(dma2d_channel_handle_t dma2d_ch return ret; } +esp_err_t dma2d_configure_dscr_port_mode(dma2d_channel_handle_t dma2d_chan, const dma2d_dscr_port_mode_config_t *config) +{ + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE_ISR(dma2d_chan && config, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + + dma2d_group_t *group = dma2d_chan->group; + int channel_id = dma2d_chan->channel_id; + + if (dma2d_chan->direction == DMA2D_CHANNEL_DIRECTION_TX) { + ESP_GOTO_ON_FALSE_ISR(config->block_h > 0 && config->block_v > 0, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + + dma2d_ll_tx_set_dscr_port_block_size(group->hal.dev, channel_id, config->block_h, config->block_v); + } + +err: + return ret; +} + esp_err_t dma2d_enqueue(dma2d_pool_handle_t dma2d_pool, const dma2d_trans_config_t *trans_desc, dma2d_trans_t *trans_placeholder) { esp_err_t ret = ESP_OK; diff --git a/components/esp_hw_support/dma/dw_gdma.c b/components/esp_hw_support/dma/dw_gdma.c index 33c44c4f89c1..765d931c0dd7 100644 --- a/components/esp_hw_support/dma/dw_gdma.c +++ b/components/esp_hw_support/dma/dw_gdma.c @@ -42,8 +42,10 @@ static const char *TAG = "dw-gdma"; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #define DW_GDMA_GET_NON_CACHE_ADDR(addr) ((addr) ? CACHE_LL_L2MEM_NON_CACHE_ADDR(addr) : 0) +#define DW_GDMA_GET_CACHE_ADDRESS(nc_addr) ((nc_addr) ? CACHE_LL_L2MEM_CACHE_ADDR(nc_addr) : 0) #else #define DW_GDMA_GET_NON_CACHE_ADDR(addr) (addr) +#define DW_GDMA_GET_CACHE_ADDRESS(nc_addr) (nc_addr) #endif #if CONFIG_DW_GDMA_ISR_IRAM_SAFE || CONFIG_DW_GDMA_CTRL_FUNC_IN_IRAM || DW_GDMA_SETTER_FUNC_IN_IRAM @@ -385,22 +387,16 @@ esp_err_t dw_gdma_new_link_list(const dw_gdma_link_list_config_t *config, dw_gdm uint32_t num_items = config->num_items; list = heap_caps_calloc(1, sizeof(dw_gdma_link_list_t), DW_GDMA_MEM_ALLOC_CAPS); ESP_GOTO_ON_FALSE(list, ESP_ERR_NO_MEM, err, TAG, "no mem for link list"); - // allocate memory for link list items, from SRAM - // the link list items has itw own alignment requirement - // also we should respect the data cache line size + // allocate memory for link list items, from internal memory + // the link list items has its own alignment requirement, the heap allocator can help handle the cache alignment as well + items = heap_caps_aligned_calloc(DW_GDMA_LL_LINK_LIST_ALIGNMENT, num_items, sizeof(dw_gdma_link_list_item_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + ESP_GOTO_ON_FALSE(items, ESP_ERR_NO_MEM, err, TAG, "no mem for link list items"); + // do memory sync when the link list items are cached uint32_t data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); - uint32_t alignment = MAX(DW_GDMA_LL_LINK_LIST_ALIGNMENT, data_cache_line_size); - // because we want to access the link list items via non-cache address, so the memory size should also align to the cache line size - uint32_t lli_size = num_items * sizeof(dw_gdma_link_list_item_t); if (data_cache_line_size) { - lli_size = ALIGN_UP(lli_size, data_cache_line_size); - } - items = heap_caps_aligned_calloc(alignment, 1, lli_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); - ESP_GOTO_ON_FALSE(items, ESP_ERR_NO_MEM, err, TAG, "no mem for link list items"); - if (data_cache_line_size) { // do memory sync only when the cache exists - // write back and then invalidate the cache, we won't use the cache to operate the link list items afterwards - // even the cache auto-write back happens, there's no risk the link list items will be overwritten - ESP_GOTO_ON_ERROR(esp_cache_msync(items, lli_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE), + // write back and then invalidate the cache, because later we will read/write the link list items by non-cacheable address + ESP_GOTO_ON_ERROR(esp_cache_msync(items, num_items * sizeof(dw_gdma_link_list_item_t), + ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE | ESP_CACHE_MSYNC_FLAG_UNALIGNED), err, TAG, "cache sync failed"); } @@ -466,6 +462,7 @@ dw_gdma_lli_handle_t dw_gdma_link_list_get_item(dw_gdma_link_list_handle_t list, { ESP_RETURN_ON_FALSE_ISR(list, NULL, TAG, "invalid argument"); ESP_RETURN_ON_FALSE_ISR(item_index < list->num_items, NULL, TAG, "invalid item index"); + // Note: the returned address is non-cached dw_gdma_link_list_item_t *lli = list->items_nc + item_index; return lli; } @@ -474,8 +471,8 @@ esp_err_t dw_gdma_lli_set_next(dw_gdma_lli_handle_t lli, dw_gdma_lli_handle_t ne { ESP_RETURN_ON_FALSE(lli && next, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - // the next field must use a cached address - dw_gdma_ll_lli_set_next_item_addr(lli, CACHE_LL_L2MEM_CACHE_ADDR(next)); + // the next field must use a cached address, so convert it to a cached address + dw_gdma_ll_lli_set_next_item_addr(lli, DW_GDMA_GET_CACHE_ADDRESS(next)); return ESP_OK; } diff --git a/components/esp_hw_support/dma/esp_dma_utils.c b/components/esp_hw_support/dma/esp_dma_utils.c index a8e7611a7419..0c1f0df1af8d 100644 --- a/components/esp_hw_support/dma/esp_dma_utils.c +++ b/components/esp_hw_support/dma/esp_dma_utils.c @@ -130,7 +130,7 @@ bool esp_dma_is_buffer_alignment_satisfied(const void *ptr, size_t size, esp_dma int cache_flags = 0; size_t cache_alignment_bytes = 0; if (esp_ptr_external_ram(ptr)) { - cache_flags |= ESP_DMA_MALLOC_FLAG_PSRAM; + cache_flags |= MALLOC_CAP_SPIRAM; } esp_err_t ret = esp_cache_get_alignment(cache_flags, &cache_alignment_bytes); assert(ret == ESP_OK); diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index c283a30bd010..d78c5cbf1b3b 100644 --- a/components/esp_hw_support/dma/gdma.c +++ b/components/esp_hw_support/dma/gdma.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "sdkconfig.h" #if CONFIG_GDMA_ENABLE_DEBUG_LOG // The local log level must be defined before including esp_log.h @@ -42,10 +43,9 @@ #include "esp_log.h" #include "esp_check.h" #include "esp_memory_utils.h" +#include "esp_flash_encrypt.h" #include "esp_private/periph_ctrl.h" #include "gdma_priv.h" -#include "hal/cache_hal.h" -#include "hal/cache_ll.h" #if CONFIG_PM_ENABLE && SOC_PM_SUPPORT_TOP_PD #include "esp_private/gdma_sleep_retention.h" @@ -354,46 +354,68 @@ esp_err_t gdma_get_free_m2m_trig_id_mask(gdma_channel_handle_t dma_chan, uint32_ return ESP_OK; } -esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability) +esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transfer_config_t *config) { - ESP_RETURN_ON_FALSE(dma_chan && ability, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(dma_chan && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + uint32_t max_data_burst_size = config->max_data_burst_size; + if (max_data_burst_size) { + // burst size must be power of 2 + ESP_RETURN_ON_FALSE((max_data_burst_size & (max_data_burst_size - 1)) == 0, ESP_ERR_INVALID_ARG, + TAG, "invalid max_data_burst_size: %"PRIu32, max_data_burst_size); + } gdma_pair_t *pair = dma_chan->pair; gdma_group_t *group = pair->group; gdma_hal_context_t *hal = &group->hal; + size_t int_mem_alignment = 1; + size_t ext_mem_alignment = 1; - size_t sram_alignment = ability->sram_trans_align; - size_t psram_alignment = ability->psram_trans_align; - // alignment should be 2^n - ESP_RETURN_ON_FALSE((sram_alignment & (sram_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, - TAG, "invalid sram alignment: %zu", sram_alignment); - - uint32_t ext_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); - if (psram_alignment == 0) { - // fall back to use the same size of the psram data cache line size - psram_alignment = ext_mem_cache_line_size; + // always enable descriptor burst as the descriptor is always word aligned and is in the internal SRAM + bool en_desc_burst = true; + bool en_data_burst = max_data_burst_size > 0; + gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_data_burst, en_desc_burst); + if (en_data_burst) { + gdma_hal_set_burst_size(hal, pair->pair_id, dma_chan->direction, max_data_burst_size); } - if (psram_alignment > ext_mem_cache_line_size) { - ESP_RETURN_ON_FALSE(((psram_alignment % ext_mem_cache_line_size) == 0), ESP_ERR_INVALID_ARG, - TAG, "psram_alignment(%d) should be multiple of the ext_mem_cache_line_size(%"PRIu32")", - psram_alignment, ext_mem_cache_line_size); + +#if GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT + if (en_data_burst && dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) { + int_mem_alignment = MAX(int_mem_alignment, 4); + ext_mem_alignment = MAX(ext_mem_alignment, max_data_burst_size); } +#endif - // if the DMA can't access the PSRAM, this HAL function is no-op - gdma_hal_set_ext_mem_align(hal, pair->pair_id, dma_chan->direction, psram_alignment); + // if MSPI encryption is enabled, and DMA wants to read/write external memory + if (esp_flash_encryption_enabled()) { + gdma_hal_enable_access_encrypt_mem(hal, pair->pair_id, dma_chan->direction, config->access_ext_mem); + // when DMA access the encrypted memory, extra alignment is needed, for both internal and external memory + if (config->access_ext_mem) { + ext_mem_alignment = MAX(ext_mem_alignment, GDMA_ACCESS_ENCRYPTION_MEM_ALIGNMENT); + int_mem_alignment = MAX(int_mem_alignment, GDMA_ACCESS_ENCRYPTION_MEM_ALIGNMENT); + } + } else { + gdma_hal_enable_access_encrypt_mem(hal, pair->pair_id, dma_chan->direction, false); + } - // TX channel can always enable burst mode, no matter data alignment - bool en_burst = true; - if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) { - // RX channel burst mode depends on specific data alignment - en_burst = sram_alignment >= 4; + // if the channel is not allowed to access external memory, set a super big (meaningless) alignment value + // so when the upper layer checks the alignment with an external buffer, the check should fail + if (!config->access_ext_mem) { + ext_mem_alignment = BIT(31); } - gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_burst, en_burst); - dma_chan->sram_alignment = sram_alignment; - dma_chan->psram_alignment = psram_alignment; - ESP_LOGD(TAG, "%s channel (%d,%d), (%u:%u) bytes aligned, burst %s", dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX ? "tx" : "rx", - group->group_id, pair->pair_id, sram_alignment, psram_alignment, en_burst ? "enabled" : "disabled"); + dma_chan->int_mem_alignment = int_mem_alignment; + dma_chan->ext_mem_alignment = ext_mem_alignment; + return ESP_OK; +} +esp_err_t gdma_get_alignment_constraints(gdma_channel_handle_t dma_chan, size_t *int_mem_alignment, size_t *ext_mem_alignment) +{ + ESP_RETURN_ON_FALSE(dma_chan, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + if (int_mem_alignment) { + *int_mem_alignment = dma_chan->int_mem_alignment; + } + if (ext_mem_alignment) { + *ext_mem_alignment = dma_chan->ext_mem_alignment; + } return ESP_OK; } @@ -421,57 +443,6 @@ esp_err_t gdma_set_priority(gdma_channel_handle_t dma_chan, uint32_t priority) return ESP_OK; } -#if SOC_GDMA_SUPPORT_CRC -esp_err_t gdma_config_crc_calculator(gdma_channel_handle_t dma_chan, const gdma_crc_calculator_config_t *config) -{ - ESP_RETURN_ON_FALSE(dma_chan && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - gdma_pair_t *pair = dma_chan->pair; - gdma_group_t *group = pair->group; - gdma_hal_context_t *hal = &group->hal; - switch (group->bus_id) { -#if SOC_AHB_GDMA_SUPPORTED - case SOC_GDMA_BUS_AHB: - ESP_RETURN_ON_FALSE(config->crc_bit_width <= GDMA_LL_AHB_MAX_CRC_BIT_WIDTH, ESP_ERR_INVALID_ARG, TAG, "invalid crc bit width"); - break; -#endif // SOC_AHB_GDMA_SUPPORTED -#if SOC_AXI_GDMA_SUPPORTED - case SOC_GDMA_BUS_AXI: - ESP_RETURN_ON_FALSE(config->crc_bit_width <= GDMA_LL_AXI_MAX_CRC_BIT_WIDTH, ESP_ERR_INVALID_ARG, TAG, "invalid crc bit width"); - break; -#endif // SOC_AXI_GDMA_SUPPORTED - default: - ESP_LOGE(TAG, "invalid bus id: %d", group->bus_id); - return ESP_ERR_INVALID_ARG; - } - - // clear the previous CRC result - gdma_hal_clear_crc(hal, pair->pair_id, dma_chan->direction); - - // set polynomial and initial value - gdma_hal_crc_config_t hal_config = { - .crc_bit_width = config->crc_bit_width, - .poly_hex = config->poly_hex, - .init_value = config->init_value, - .reverse_data_mask = config->reverse_data_mask, - }; - gdma_hal_set_crc_poly(hal, pair->pair_id, dma_chan->direction, &hal_config); - - return ESP_OK; -} - -esp_err_t gdma_crc_get_result(gdma_channel_handle_t dma_chan, uint32_t *result) -{ - ESP_RETURN_ON_FALSE(dma_chan && result, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - gdma_pair_t *pair = dma_chan->pair; - gdma_group_t *group = pair->group; - gdma_hal_context_t *hal = &group->hal; - - *result = gdma_hal_get_crc_result(hal, pair->pair_id, dma_chan->direction); - - return ESP_OK; -} -#endif // SOC_GDMA_SUPPORT_CRC - esp_err_t gdma_register_tx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_tx_event_callbacks_t *cbs, void *user_data) { ESP_RETURN_ON_FALSE(dma_chan && cbs && dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); diff --git a/components/esp_hw_support/dma/gdma_crc.c b/components/esp_hw_support/dma/gdma_crc.c new file mode 100644 index 000000000000..da7425d39db2 --- /dev/null +++ b/components/esp_hw_support/dma/gdma_crc.c @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "sdkconfig.h" +#if CONFIG_GDMA_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "soc/soc_caps.h" +#include "soc/periph_defs.h" +#include "esp_log.h" +#include "esp_check.h" +#include "gdma_priv.h" + +static const char *TAG = "gdma"; + +esp_err_t gdma_config_crc_calculator(gdma_channel_handle_t dma_chan, const gdma_crc_calculator_config_t *config) +{ + ESP_RETURN_ON_FALSE(dma_chan && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + gdma_pair_t *pair = dma_chan->pair; + gdma_group_t *group = pair->group; + gdma_hal_context_t *hal = &group->hal; + switch (group->bus_id) { +#if SOC_AHB_GDMA_SUPPORTED + case SOC_GDMA_BUS_AHB: + ESP_RETURN_ON_FALSE(config->crc_bit_width <= GDMA_LL_AHB_MAX_CRC_BIT_WIDTH, ESP_ERR_INVALID_ARG, TAG, "invalid crc bit width"); + break; +#endif // SOC_AHB_GDMA_SUPPORTED +#if SOC_AXI_GDMA_SUPPORTED + case SOC_GDMA_BUS_AXI: + ESP_RETURN_ON_FALSE(config->crc_bit_width <= GDMA_LL_AXI_MAX_CRC_BIT_WIDTH, ESP_ERR_INVALID_ARG, TAG, "invalid crc bit width"); + break; +#endif // SOC_AXI_GDMA_SUPPORTED + default: + ESP_LOGE(TAG, "invalid bus id: %d", group->bus_id); + return ESP_ERR_INVALID_ARG; + } + + // clear the previous CRC result + gdma_hal_clear_crc(hal, pair->pair_id, dma_chan->direction); + + // set polynomial and initial value + gdma_hal_crc_config_t hal_config = { + .crc_bit_width = config->crc_bit_width, + .poly_hex = config->poly_hex, + .init_value = config->init_value, + .reverse_data_mask = config->reverse_data_mask, + }; + gdma_hal_set_crc_poly(hal, pair->pair_id, dma_chan->direction, &hal_config); + + return ESP_OK; +} + +esp_err_t gdma_crc_get_result(gdma_channel_handle_t dma_chan, uint32_t *result) +{ + ESP_RETURN_ON_FALSE(dma_chan && result, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + gdma_pair_t *pair = dma_chan->pair; + gdma_group_t *group = pair->group; + gdma_hal_context_t *hal = &group->hal; + + *result = gdma_hal_get_crc_result(hal, pair->pair_id, dma_chan->direction); + + return ESP_OK; +} diff --git a/components/esp_hw_support/dma/gdma_priv.h b/components/esp_hw_support/dma/gdma_priv.h index 202f3ec949cd..600397be0234 100644 --- a/components/esp_hw_support/dma/gdma_priv.h +++ b/components/esp_hw_support/dma/gdma_priv.h @@ -32,6 +32,8 @@ #define GDMA_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED #endif +#define GDMA_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 /*!< The alignment of the memory and size when DMA accesses the encryption memory */ + #ifdef __cplusplus extern "C" { #endif @@ -67,8 +69,8 @@ struct gdma_channel_t { portMUX_TYPE spinlock; // channel level spinlock gdma_channel_direction_t direction; // channel direction int periph_id; // Peripheral instance ID, indicates which peripheral is connected to this GDMA channel - size_t sram_alignment; // alignment for memory in SRAM - size_t psram_alignment; // alignment for memory in PSRAM + size_t int_mem_alignment; // alignment for memory in internal memory + size_t ext_mem_alignment; // alignment for memory in external memory esp_err_t (*del)(gdma_channel_t *channel); // channel deletion function, it's polymorphic, see `gdma_del_tx_channel` or `gdma_del_rx_channel` struct { uint32_t start_stop_by_etm: 1; // whether the channel is started/stopped by ETM diff --git a/components/esp_hw_support/dma/include/esp_private/dma2d.h b/components/esp_hw_support/dma/include/esp_private/dma2d.h index 33cd74ad569d..4524ca95c68a 100644 --- a/components/esp_hw_support/dma/include/esp_private/dma2d.h +++ b/components/esp_hw_support/dma/include/esp_private/dma2d.h @@ -104,7 +104,7 @@ typedef struct { * @return Whether a task switch is needed after the callback function returns, * this is usually due to the callback wakes up some high priority task. */ -typedef bool (*dma2d_trans_callback_t)(uint32_t num_chans, const dma2d_trans_channel_info_t *dma2d_chans, void *user_config); +typedef bool (*dma2d_trans_on_picked_callback_t)(uint32_t num_chans, const dma2d_trans_channel_info_t *dma2d_chans, void *user_config); /** * @brief 2D-DMA channel special function flags @@ -131,7 +131,7 @@ typedef struct { uint32_t specified_tx_channel_mask; /*!< Bit mask of the specific TX channels to be used, the specified TX channels should have been reserved */ uint32_t specified_rx_channel_mask; /*!< Bit mask of the specific RX channels to be used, the specified RX channels should have been reserved */ - dma2d_trans_callback_t on_job_picked; /*!< Callback function to be called when all necessary channels to do the transaction have been acquired */ + dma2d_trans_on_picked_callback_t on_job_picked; /*!< Callback function to be called when all necessary channels to do the transaction have been acquired */ void *user_config; /*!< User registered data to be passed into `on_job_picked` callback */ } dma2d_trans_config_t; @@ -271,6 +271,27 @@ typedef struct { */ esp_err_t dma2d_configure_color_space_conversion(dma2d_channel_handle_t dma2d_chan, const dma2d_csc_config_t *config); +/** + * @brief A collection of configurations apply to 2D-DMA channel DSCR-PORT mode + */ +typedef struct { + uint32_t block_h; /*!< Horizontal width of the block in dscr-port mode (unit: pixel) */ + uint32_t block_v; /*!< Vertical height of the block in dscr-port mode (unit: pixel) */ +} dma2d_dscr_port_mode_config_t; + +/** + * @brief Configure 2D-DMA channel DSCR-PORT mode + * + * @note This API only targets PPA SRM, which uses 2D-DMA DSCR-PORT mode. + * + * @param[in] dma2d_chan 2D-DMA channel handle, get from the `on_job_picked` callback input argument `dma2d_chans` + * @param[in] config Configuration of 2D-DMA channel DSCR-PORT mode + * @return + * - ESP_OK: Configure 2D-DMA dscr-port mode successfully + * - ESP_ERR_INVALID_ARG: Configure 2D-DMA dscr-port mode failed because of invalid argument + */ +esp_err_t dma2d_configure_dscr_port_mode(dma2d_channel_handle_t dma2d_chan, const dma2d_dscr_port_mode_config_t *config); + /** * @brief Type of 2D-DMA event data */ diff --git a/components/esp_hw_support/dma/include/esp_private/dw_gdma.h b/components/esp_hw_support/dma/include/esp_private/dw_gdma.h index 6d1ad024c0df..dd9105e9d36e 100644 --- a/components/esp_hw_support/dma/include/esp_private/dw_gdma.h +++ b/components/esp_hw_support/dma/include/esp_private/dw_gdma.h @@ -169,7 +169,7 @@ esp_err_t dw_gdma_channel_suspend_ctrl(dw_gdma_channel_handle_t chan, bool enter /** * @brief Abort the DMA channel * - * @note If the channel is aborted, it will be diabled immediately, which may cause AXI bus protocol violation. + * @note If the channel is aborted, it will be disabled immediately, which may cause AXI bus protocol violation. * @note This function is recommended to only be used when the channel hangs. Recommend to try `dw_gdma_channel_enable_ctrl` first, then opt for aborting. * * @param[in] chan DMA channel handle, allocated by `dw_gdma_new_channel` @@ -366,8 +366,8 @@ esp_err_t dw_gdma_lli_config_transfer(dw_gdma_lli_handle_t lli, dw_gdma_block_tr /** * @brief Set the next link list item for a given DMA link list item * - * @param[in] lli Link list item - * @param[in] next Next link list item + * @param[in] lli Current link list item, can be obtained from `dw_gdma_link_list_get_item` + * @param[in] next Next link list item, can be obtained from `dw_gdma_link_list_get_item` * @return * - ESP_OK: Set next link list item successfully * - ESP_ERR_INVALID_ARG: Set next link list item failed because of invalid argument diff --git a/components/esp_hw_support/dma/include/esp_private/gdma.h b/components/esp_hw_support/dma/include/esp_private/gdma.h index 2d61d531be82..cd58cd285ba8 100644 --- a/components/esp_hw_support/dma/include/esp_private/gdma.h +++ b/components/esp_hw_support/dma/include/esp_private/gdma.h @@ -4,9 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -// DO NOT USE THESE APIS IN ANY APPLICATIONS -// GDMA driver is not public for end users, but for ESP-IDF developers. - #pragma once #include @@ -37,19 +34,6 @@ typedef struct { } flags; } gdma_channel_alloc_config_t; -/** - * @brief GDMA transfer ability - * - * @note The alignment set in this structure is **not** a guarantee that gdma driver will take care of the nonalignment cases. - * Actually the GDMA driver has no knowledge about the DMA buffer (address and size) used by upper layer. - * So it's the responsibility of the **upper layer** to take care of the buffer address and size. - * - */ -typedef struct { - size_t sram_trans_align; /*!< DMA transfer alignment for memory in SRAM, in bytes. The driver enables/disables burst mode based on this value. 0 means no alignment is required */ - size_t psram_trans_align; /*!< DMA transfer alignment for memory in PSRAM, in bytes. The driver sets proper burst block size based on the alignment value. 0 means no alignment is required */ -} gdma_transfer_ability_t; - /** * @brief Type of GDMA event data */ @@ -199,16 +183,48 @@ esp_err_t gdma_connect(gdma_channel_handle_t dma_chan, gdma_trigger_t trig_perip esp_err_t gdma_disconnect(gdma_channel_handle_t dma_chan); /** - * @brief Set DMA channel transfer ability + * @brief Channel transfer configurations + */ +typedef struct { + uint32_t max_data_burst_size; /*!< Set the max burst size when DMA read/write the data buffer. + Set to 0 means to disable the data burst. + Other value must be power of 2, e.g., 4/8/16/32/64 */ + bool access_ext_mem; /*!< Set this if the DMA transfer will access external memory */ +} gdma_transfer_config_t; + +/** + * @brief Configure transfer parameters for a DMA channel + * + * @note It's highly recommended to enable the burst mode and set proper burst size for the DMA channel, + * which can improve the performance in accessing external memory by a lot. + * + * @param[in] chan DMA channel handle, allocated by `gdma_new_channel` + * @param[in] config Transfer configurations + * @return + * - ESP_OK: Configure DMA transfer parameters successfully + * - ESP_ERR_INVALID_ARG: Configure DMA transfer parameters failed because of invalid argument + * - ESP_FAIL: Configure DMA transfer parameters failed because of other error + */ +esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transfer_config_t *config); + +/** + * @brief Get the alignment constraints for internal and external memory + * + * @note You should call this function after `gdma_config_transfer`, the later one can + * adjust the alignment constraints based on various conditions, e.g. burst size, memory encryption, etc. + * @note You can use returned alignment value to validate if a DMA buffer provided by the upper layer meets the constraints. + * @note The returned alignment doesn't take the cache line size into account, if you want to do aligned memory allocation, + * you should align the buffer size to the cache line size by yourself if the DMA buffer is behind a cache. * * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel` - * @param[in] ability Transfer ability, e.g. alignment + * @param[out] int_mem_alignment Internal memory alignment + * @param[out] ext_mem_alignment External memory alignment * @return - * - ESP_OK: Set DMA channel transfer ability successfully - * - ESP_ERR_INVALID_ARG: Set DMA channel transfer ability failed because of invalid argument - * - ESP_FAIL: Set DMA channel transfer ability failed because of other error + * - ESP_OK: Get alignment constraints successfully + * - ESP_ERR_INVALID_ARG: Get alignment constraints failed because of invalid argument + * - ESP_FAIL: Get alignment constraints failed because of other error */ -esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability); +esp_err_t gdma_get_alignment_constraints(gdma_channel_handle_t dma_chan, size_t *int_mem_alignment, size_t *ext_mem_alignment); /** * @brief Apply channel strategy for GDMA channel @@ -457,6 +473,36 @@ esp_err_t gdma_config_crc_calculator(gdma_channel_handle_t dma_chan, const gdma_ esp_err_t gdma_crc_get_result(gdma_channel_handle_t dma_chan, uint32_t *result); #endif // SOC_GDMA_SUPPORT_CRC +/**************************************************************************************** + * Deprecated APIs + ****************************************************************************************/ + +/** + * @brief GDMA transfer ability + * + * @note The alignment set in this structure is **not** a guarantee that gdma driver will take care of the nonalignment cases. + * Actually the GDMA driver has no knowledge about the DMA buffer (address and size) used by upper layer. + * So it's the responsibility of the **upper layer** to take care of the buffer address and size. + * + */ +typedef struct { + size_t sram_trans_align; /*!< DMA transfer alignment for memory in SRAM, in bytes. The driver enables/disables burst mode based on this value. 0 means no alignment is required */ + size_t psram_trans_align; /*!< DMA transfer alignment for memory in PSRAM, in bytes. The driver sets proper burst block size based on the alignment value. 0 means no alignment is required */ +} gdma_transfer_ability_t; + +/** + * @brief Set DMA channel transfer ability + * + * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel` + * @param[in] ability Transfer ability, e.g. alignment + * @return + * - ESP_OK: Set DMA channel transfer ability successfully + * - ESP_ERR_INVALID_ARG: Set DMA channel transfer ability failed because of invalid argument + * - ESP_FAIL: Set DMA channel transfer ability failed because of other error + */ +esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability) +__attribute__((deprecated("please use gdma_config_transfer instead"))); + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/dma/linker.lf b/components/esp_hw_support/dma/linker.lf index c4ace066f19e..db6159eed14d 100644 --- a/components/esp_hw_support/dma/linker.lf +++ b/components/esp_hw_support/dma/linker.lf @@ -78,10 +78,15 @@ entries: # put DW_GDMA control functions in IRAM if DW_GDMA_CTRL_FUNC_IN_IRAM = y: dw_gdma: dw_gdma_channel_continue (noflash) + dw_gdma: dw_gdma_channel_enable_ctrl (noflash) if DW_GDMA_SETTER_FUNC_IN_IRAM = y: dw_gdma: dw_gdma_channel_set_block_markers (noflash) dw_gdma: dw_gdma_lli_set_block_markers (noflash) + dw_gdma: dw_gdma_channel_use_link_list (noflash) + + if DW_GDMA_GETTER_FUNC_IN_IRAM = y: + dw_gdma: dw_gdma_link_list_get_item (noflash) [mapping:dma2d_driver] archive: libesp_hw_support.a @@ -108,6 +113,7 @@ entries: dma2d: dma2d_apply_strategy (noflash) dma2d: dma2d_set_transfer_ability (noflash) dma2d: dma2d_configure_color_space_conversion (noflash) + dma2d: dma2d_configure_dscr_port_mode (noflash) dma2d: dma2d_enqueue (noflash) [mapping:dma2d_hal] diff --git a/components/esp_hw_support/include/esp_async_memcpy.h b/components/esp_hw_support/include/esp_async_memcpy.h index 033bb9ed917b..1b91b840930f 100644 --- a/components/esp_hw_support/include/esp_async_memcpy.h +++ b/components/esp_hw_support/include/esp_async_memcpy.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -51,8 +51,11 @@ typedef bool (*async_memcpy_isr_cb_t)(async_memcpy_handle_t mcp_hdl, async_memcp */ typedef struct { uint32_t backlog; /*!< Maximum number of transactions that can be prepared in the background */ - size_t sram_trans_align; /*!< DMA transfer alignment (both in size and address) for SRAM memory */ - size_t psram_trans_align; /*!< DMA transfer alignment (both in size and address) for PSRAM memory */ + size_t sram_trans_align __attribute__((deprecated)); /*!< DMA transfer alignment (both in size and address) for SRAM memory */ + union { + size_t psram_trans_align; /*!< DMA transfer alignment (both in size and address) for PSRAM memory */ + size_t dma_burst_size; /*!< DMA transfer burst size, in bytes */ + }; uint32_t flags; /*!< Extra flags to control async memcpy feature */ } async_memcpy_config_t; @@ -62,8 +65,7 @@ typedef struct { #define ASYNC_MEMCPY_DEFAULT_CONFIG() \ { \ .backlog = 8, \ - .sram_trans_align = 0, \ - .psram_trans_align = 0, \ + .dma_burst_size = 16, \ .flags = 0, \ } diff --git a/components/esp_hw_support/include/esp_intr_alloc.h b/components/esp_hw_support/include/esp_intr_alloc.h index 369084886f1f..3106332c0de8 100644 --- a/components/esp_hw_support/include/esp_intr_alloc.h +++ b/components/esp_hw_support/include/esp_intr_alloc.h @@ -45,9 +45,10 @@ extern "C" { #define ESP_INTR_FLAG_LOWMED (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3) ///< Low and medium prio interrupts. These can be handled in C. #define ESP_INTR_FLAG_HIGH (ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6|ESP_INTR_FLAG_NMI) ///< High level interrupts. Need to be handled in assembly. +/** Mask for all level flags */ #define ESP_INTR_FLAG_LEVELMASK (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3| \ ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6| \ - ESP_INTR_FLAG_NMI) ///< Mask for all level flags + ESP_INTR_FLAG_NMI) /** @addtogroup Intr_Alloc_Pseudo_Src diff --git a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h index 5bf1084730f4..a0c82e394bc1 100644 --- a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h +++ b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h @@ -12,7 +12,7 @@ * * However, usages of above components are different. * Therefore, we put the common used parts into `esp_hw_support`, including: - * - adc power maintainance + * - adc power maintenance * - adc hw calibration settings * - adc locks, to prevent concurrently using adc hw */ @@ -26,6 +26,12 @@ extern "C" { #endif +#if SOC_RCC_IS_INDEPENDENT || CONFIG_IDF_TARGET_ESP32 +#define ADC_BUS_CLK_ATOMIC() +#else +#define ADC_BUS_CLK_ATOMIC() PERIPH_RCC_ATOMIC() +#endif + #if SOC_ADC_CALIBRATION_V1_SUPPORTED /*--------------------------------------------------------------- ADC Hardware Calibration diff --git a/components/esp_hw_support/include/esp_private/esp_pmu.h b/components/esp_hw_support/include/esp_private/esp_pmu.h index 5661db987435..47db5ab06664 100644 --- a/components/esp_hw_support/include/esp_private/esp_pmu.h +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -62,7 +62,11 @@ typedef enum { #define RTC_EXT1_TRIG_EN 0 #endif -#define RTC_GPIO_TRIG_EN PMU_GPIO_WAKEUP_EN //!< GPIO wakeup +#if SOC_LP_IO_HAS_INDEPENDENT_WAKEUP_SOURCE +#define RTC_GPIO_TRIG_EN (PMU_GPIO_WAKEUP_EN | PMU_LP_GPIO_WAKEUP_EN) //!< GPIO & LP_GPIO wakeup +#else +#define RTC_GPIO_TRIG_EN (PMU_GPIO_WAKEUP_EN) +#endif #if SOC_LP_TIMER_SUPPORTED #define RTC_TIMER_TRIG_EN PMU_LP_TIMER_WAKEUP_EN //!< Timer wakeup @@ -90,6 +94,12 @@ typedef enum { #define RTC_BT_TRIG_EN 0 #endif +#if SOC_TOUCH_SENSOR_SUPPORTED +#define RTC_TOUCH_TRIG_EN PMU_TOUCH_WAKEUP_EN //!< TOUCH wakeup +#else +#define RTC_TOUCH_TRIG_EN 0 +#endif + #define RTC_USB_TRIG_EN PMU_USB_WAKEUP_EN #if SOC_LP_CORE_SUPPORTED @@ -113,6 +123,7 @@ typedef enum { RTC_UART1_TRIG_EN | \ RTC_BT_TRIG_EN | \ RTC_LP_CORE_TRIG_EN | \ + RTC_TOUCH_TRIG_EN | \ RTC_XTAL32K_DEAD_TRIG_EN | \ RTC_USB_TRIG_EN | \ RTC_BROWNOUT_DET_TRIG_EN) @@ -270,7 +281,7 @@ void pmu_sleep_shutdown_dcdc(void); * @brief DCDC has taken over power supply, shut down LDO to save power consumption */ void pmu_sleep_shutdown_ldo(void); -#endif +#endif // SOC_DCDC_SUPPORTED /** * @brief Enter deep or light sleep mode @@ -302,9 +313,10 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp /** * @brief Finish sleep process settings and get sleep reject status + * @param dslp True if sleep requests id deep-sleep * @return return sleep reject status */ -bool pmu_sleep_finish(void); +bool pmu_sleep_finish(bool dslp); /** * @brief Initialize PMU related power/clock/digital parameters and functions diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index 57f2ccc487be..03b551d64bb5 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -22,8 +22,6 @@ extern "C" { #if SOC_PAU_SUPPORTED #include "hal/pau_types.h" -#define REGDMA_LINK_DBG 0 /* Enable REGDMA link info dump apis*/ - /** * @brief Create a REGDMA continuous type linked list node without retention buffer and the retention buffer is passed in by the caller * @param backup Register address to be backed up by REGDMA diff --git a/components/esp_hw_support/include/esp_private/etm_interface.h b/components/esp_hw_support/include/esp_private/etm_interface.h index 04c02964f92c..a3924a064b1e 100644 --- a/components/esp_hw_support/include/esp_private/etm_interface.h +++ b/components/esp_hw_support/include/esp_private/etm_interface.h @@ -27,6 +27,7 @@ typedef enum { ETM_TRIG_PERIPH_MCPWM, /*!< ETM trigger source: MCPWM */ ETM_TRIG_PERIPH_ANA_CMPR, /*!< ETM trigger source: Analog Comparator */ ETM_TRIG_PERIPH_TSENS, /*!< ETM trigger source: Temperature Sensor */ + ETM_TRIG_PERIPH_LP_CORE, /*!< ETM trigger source: Low-Power Core */ } etm_trigger_peripheral_t; /** diff --git a/components/esp_hw_support/include/esp_private/io_mux.h b/components/esp_hw_support/include/esp_private/io_mux.h index 3c3056d76209..dd8ea49ffb94 100644 --- a/components/esp_hw_support/include/esp_private/io_mux.h +++ b/components/esp_hw_support/include/esp_private/io_mux.h @@ -1,13 +1,17 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include #include "esp_err.h" #include "soc/clk_tree_defs.h" +#include "soc/gpio_num.h" +#include "soc/soc_caps.h" +#include "soc/io_mux_reg.h" #ifdef __cplusplus extern "C" { @@ -26,6 +30,20 @@ extern "C" { */ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src); +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT +typedef struct { + uint8_t rtc_io_enabled_cnt[MAX_RTC_GPIO_NUM]; + uint32_t rtc_io_using_mask; +} rtc_io_status_t; + +/** + * Enable/Disable LP_IO peripheral clock. + * @param gpio_num GPIO number + * @param enable true to enable the clock / false to disable the clock + */ +void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable); +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/esp_private/rtc_clk.h b/components/esp_hw_support/include/esp_private/rtc_clk.h index 5c143b839670..52610fa0d1ce 100644 --- a/components/esp_hw_support/include/esp_private/rtc_clk.h +++ b/components/esp_hw_support/include/esp_private/rtc_clk.h @@ -74,12 +74,6 @@ uint32_t rtc_clk_mpll_get_freq(void); #endif //#if SOC_CLK_MPLL_SUPPORTED -/** - * @brief Workaround for C2, S3, C6, H2. Trigger the calibration of PLL. Should be called when the bootloader doesn't provide a good enough PLL accuracy. -*/ -void rtc_clk_recalib_bbpll(void); - - #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/esp_private/sleep_cpu.h b/components/esp_hw_support/include/esp_private/sleep_cpu.h index 136c03410310..cc2dd35980b3 100644 --- a/components/esp_hw_support/include/esp_private/sleep_cpu.h +++ b/components/esp_hw_support/include/esp_private/sleep_cpu.h @@ -9,6 +9,7 @@ #include #include "sdkconfig.h" #include "esp_err.h" +#include "esp_sleep.h" #include "soc/soc_caps.h" #ifdef __cplusplus @@ -21,7 +22,7 @@ extern "C" { * This file contains declarations of cpu retention related functions in light sleep mode. */ -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP || SOC_PM_SUPPORT_CPU_PD +#if ESP_SLEEP_POWER_DOWN_CPU || SOC_PM_SUPPORT_CPU_PD /** * @brief Whether to allow the cpu power domain to be powered off. * @@ -31,7 +32,7 @@ extern "C" { bool cpu_domain_pd_allowed(void); #endif -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU /** * @brief Configure the parameters of the CPU domain during the sleep process * @@ -64,9 +65,9 @@ void sleep_disable_cpu_retention(void); esp_err_t esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp); #endif // SOC_PM_CPU_RETENTION_BY_SW -#endif // CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#endif // ESP_SLEEP_POWER_DOWN_CPU -#if !CONFIG_FREERTOS_UNICORE && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU /** * Do sleep prepare for other smp cores */ @@ -77,13 +78,11 @@ void sleep_smp_cpu_sleep_prepare(void); */ void sleep_smp_cpu_wakeup_prepare(void); -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP /** * Notify the other core that this sleep does not require retention. */ void esp_sleep_cpu_skip_retention(void); -#endif // CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP -#endif // !CONFIG_FREERTOS_UNICORE && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#endif // !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU #ifdef __cplusplus } diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 018820e364c8..ec282ab59fce 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -83,6 +83,9 @@ typedef enum { #endif #if SOC_PM_SUPPORT_TOP_PD ESP_PD_DOMAIN_TOP, //!< SoC TOP +#endif +#if SOC_PM_SUPPORT_CNNT_PD + ESP_PD_DOMAIN_CNNT, //!< Hight-speed connect peripherals power domain #endif ESP_PD_DOMAIN_MAX //!< Number of domains } esp_sleep_pd_domain_t; @@ -133,6 +136,8 @@ enum { ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION = ESP_ERR_INVALID_ARG, }; +#define ESP_SLEEP_POWER_DOWN_CPU (CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP || (SOC_CPU_IN_TOP_DOMAIN && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)) + /** * @brief Disable wakeup source * @@ -713,7 +718,7 @@ void esp_default_wake_deep_sleep(void); */ void esp_deep_sleep_disable_rom_logging(void); -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU #if SOC_PM_CPU_RETENTION_BY_RTCCNTL /** @@ -752,7 +757,7 @@ esp_err_t esp_sleep_cpu_retention_init(void); * Release system retention memory. */ esp_err_t esp_sleep_cpu_retention_deinit(void); -#endif // CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#endif // ESP_SLEEP_POWER_DOWN_CPU /** * @brief Configure to isolate all GPIO pins in sleep state diff --git a/components/esp_hw_support/ldo/linker.lf b/components/esp_hw_support/ldo/linker.lf new file mode 100644 index 000000000000..462edd8b9302 --- /dev/null +++ b/components/esp_hw_support/ldo/linker.lf @@ -0,0 +1,6 @@ +[mapping:ldo_driver] +archive: libesp_hw_support.a +entries: + if SOC_GP_LDO_SUPPORTED = y: + if SPIRAM_FLASH_LOAD_TO_PSRAM = y: + esp_ldo_regulator: esp_ldo_acquire_channel (noflash) diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 0ad8003c5644..00bcae6634ef 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -21,6 +21,9 @@ entries: rtc_time (noflash_text) if SOC_PMU_SUPPORTED = y: pmu_sleep (noflash) + if SPIRAM_FLASH_LOAD_TO_PSRAM = y: + pmu_init (noflash) + pmu_param (noflash) if SOC_USB_SERIAL_JTAG_SUPPORTED = y: sleep_console (noflash) if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y: diff --git a/components/esp_hw_support/lowpower/CMakeLists.txt b/components/esp_hw_support/lowpower/CMakeLists.txt index 6727506080c8..3ba4d4d6a8b5 100644 --- a/components/esp_hw_support/lowpower/CMakeLists.txt +++ b/components/esp_hw_support/lowpower/CMakeLists.txt @@ -4,7 +4,8 @@ endif() set(srcs) -if(CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP) +if(CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP OR + (CONFIG_SOC_CPU_IN_TOP_DOMAIN AND CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)) list(APPEND srcs "cpu_retention/port/${target}/sleep_cpu.c") if(CONFIG_SOC_PM_CPU_RETENTION_BY_SW) list(APPEND srcs "cpu_retention/port/${target}/sleep_cpu_asm.S") diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c3/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c3/sleep_cpu.c index 4547bd1f9e0b..ebc050fa6f1c 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c3/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c3/sleep_cpu.c @@ -14,7 +14,6 @@ #include "esp_check.h" #include "esp_sleep.h" #include "esp_log.h" -#include "esp_crc.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_heap_caps.h" @@ -102,7 +101,7 @@ bool cpu_domain_pd_allowed(void) esp_err_t sleep_cpu_configure(bool light_sleep_enable) { -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU if (light_sleep_enable) { ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); } else { diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c index d12d2d47f80a..69d2abc5d3c6 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c @@ -14,7 +14,7 @@ #include "esp_check.h" #include "esp_sleep.h" #include "esp_log.h" -#include "esp_crc.h" +#include "esp_rom_crc.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_heap_caps.h" @@ -391,12 +391,12 @@ static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t * #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME static IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - *(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size); + *(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size); } static IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ + if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ // resume uarts for (int i = 0; i < SOC_UART_NUM; ++i) { if (!uart_ll_is_enabled(i)) { @@ -435,7 +435,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, } #endif - return pmu_sleep_finish(); + return pmu_sleep_finish(dslp); } esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), @@ -489,7 +489,7 @@ bool cpu_domain_pd_allowed(void) esp_err_t sleep_cpu_configure(bool light_sleep_enable) { -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU if (light_sleep_enable) { ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); } else { diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c index 87642de1d700..66adf7de72fe 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c @@ -14,7 +14,7 @@ #include "esp_check.h" #include "esp_sleep.h" #include "esp_log.h" -#include "esp_crc.h" +#include "esp_rom_crc.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_heap_caps.h" @@ -431,12 +431,12 @@ static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t * #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME static IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - *(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size); + *(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size); } static IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ + if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ // resume uarts for (int i = 0; i < SOC_UART_NUM; ++i) { if (!uart_ll_is_enabled(i)) { @@ -475,7 +475,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, } #endif - return pmu_sleep_finish(); + return pmu_sleep_finish(dslp); } esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), @@ -532,7 +532,7 @@ bool cpu_domain_pd_allowed(void) esp_err_t sleep_cpu_configure(bool light_sleep_enable) { -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU if (light_sleep_enable) { ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); } else { diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c index 3734807b885f..c4ed6893094e 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c @@ -15,7 +15,7 @@ #include "esp_check.h" #include "esp_sleep.h" #include "esp_log.h" -#include "esp_crc.h" +#include "esp_rom_crc.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_heap_caps.h" @@ -431,12 +431,12 @@ static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t * #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME static IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - *(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size); + *(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size); } static IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ + if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ // resume uarts for (int i = 0; i < SOC_UART_NUM; ++i) { if (!uart_ll_is_enabled(i)) { @@ -475,7 +475,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, } #endif - return pmu_sleep_finish(); + return pmu_sleep_finish(dslp); } esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), @@ -532,7 +532,7 @@ bool cpu_domain_pd_allowed(void) esp_err_t sleep_cpu_configure(bool light_sleep_enable) { -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU if (light_sleep_enable) { ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); } else { diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c index f27af1d5dc4b..e7756703bc1b 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c @@ -15,7 +15,7 @@ #include "esp_ipc_isr.h" #include "esp_sleep.h" #include "esp_log.h" -#include "esp_crc.h" +#include "esp_rom_crc.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_heap_caps.h" @@ -41,7 +41,7 @@ #endif -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE +#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE #include #include "soc/hp_system_reg.h" typedef enum { @@ -81,7 +81,7 @@ typedef struct { } retent; } sleep_cpu_retention_t; -static DRAM_ATTR __attribute__((unused)) sleep_cpu_retention_t s_cpu_retention; +static TCM_DRAM_ATTR __attribute__((unused)) sleep_cpu_retention_t s_cpu_retention; extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame[portNUM_PROCESSORS]; @@ -162,7 +162,7 @@ static esp_err_t esp_sleep_cpu_retention_init_impl(void) s_cpu_retention.retent.clic_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame; } } -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE +#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) { atomic_init(&s_smp_retention_state[core_id], SMP_IDLE); } @@ -209,7 +209,7 @@ FORCE_INLINE_ATTR void restore_mstatus(uint32_t mstatus_val) RV_WRITE_CSR(mstatus, mstatus_val); } -static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(void) +static TCM_IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(void) { RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[esp_cpu_get_core_id()]; @@ -277,7 +277,7 @@ static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(voi return frame; } -static IRAM_ATTR void rv_core_noncritical_regs_restore(void) +static TCM_IRAM_ATTR void rv_core_noncritical_regs_restore(void) { RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[esp_cpu_get_core_id()]; @@ -343,7 +343,7 @@ static IRAM_ATTR void rv_core_noncritical_regs_restore(void) RV_WRITE_CSR(mcycle, frame->mcycle); } -static IRAM_ATTR void cpu_domain_dev_regs_save(cpu_domain_dev_sleep_frame_t *frame) +static TCM_IRAM_ATTR void cpu_domain_dev_regs_save(cpu_domain_dev_sleep_frame_t *frame) { assert(frame); cpu_domain_dev_regs_region_t *region = frame->region; @@ -357,7 +357,7 @@ static IRAM_ATTR void cpu_domain_dev_regs_save(cpu_domain_dev_sleep_frame_t *fra } } -static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *frame) +static TCM_IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *frame) { assert(frame); cpu_domain_dev_regs_region_t *region = frame->region; @@ -372,14 +372,14 @@ static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t * } #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME -static IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) +static TCM_IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - *(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size); + *(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size); } -static IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) +static TCM_IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ + if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ // resume uarts for (int i = 0; i < SOC_UART_NUM; ++i) { if (!uart_ll_is_enabled(i)) { @@ -399,7 +399,7 @@ extern RvCoreCriticalSleepFrame * rv_core_critical_regs_save(void); extern RvCoreCriticalSleepFrame * rv_core_critical_regs_restore(void); typedef uint32_t (* sleep_cpu_entry_cb_t)(uint32_t, uint32_t, uint32_t, bool); -static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, +static TCM_IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) { uint8_t core_id = esp_cpu_get_core_id(); @@ -410,11 +410,11 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0); #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME /* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */ - update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); + update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); #endif REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE +#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_DONE); while (atomic_load(&s_smp_retention_state[!core_id]) != SMP_BACKUP_DONE) { ; @@ -425,20 +425,20 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, } #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME else { - validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); + validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_SZ1 - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); } #endif - return pmu_sleep_finish(); + return pmu_sleep_finish(dslp); } -esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), +esp_err_t TCM_IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) { esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_START, (void *)0); uint32_t mstatus = save_mstatus_and_disable_global_int(); uint8_t core_id = esp_cpu_get_core_id(); -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE +#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_START); #endif cpu_domain_dev_regs_save(s_cpu_retention.retent.clic_frame[core_id]); @@ -457,7 +457,7 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin validate_retention_frame_crc((uint32_t*)frame, sizeof(RvCoreNonCriticalSleepFrame) - sizeof(long), (uint32_t *)(&frame->frame_crc)); #endif -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE +#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE // Start core1 if (core_id == 0) { REG_SET_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_CORE1_CPU_CLK_EN); @@ -472,7 +472,7 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin cpu_domain_dev_regs_restore(s_cpu_retention.retent.clic_frame[core_id]); restore_mstatus(mstatus); -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE +#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE atomic_store(&s_smp_retention_state[core_id], SMP_RESTORE_DONE); #endif return err; @@ -504,7 +504,7 @@ bool cpu_domain_pd_allowed(void) esp_err_t sleep_cpu_configure(bool light_sleep_enable) { -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU if (light_sleep_enable) { ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); } else { @@ -515,7 +515,7 @@ esp_err_t sleep_cpu_configure(bool light_sleep_enable) } #if !CONFIG_FREERTOS_UNICORE -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU static TCM_IRAM_ATTR void smp_core_do_retention(void) { uint8_t core_id = esp_cpu_get_core_id(); @@ -528,8 +528,9 @@ static TCM_IRAM_ATTR void smp_core_do_retention(void) // Wait another core start to do retention bool smp_skip_retention = false; + smp_retention_state_t another_core_state; while (1) { - smp_retention_state_t another_core_state = atomic_load(&s_smp_retention_state[!core_id]); + another_core_state = atomic_load(&s_smp_retention_state[!core_id]); if (another_core_state == SMP_SKIP_RETENTION) { // If another core skips the retention, the current core should also have to skip it. smp_skip_retention = true; @@ -548,9 +549,12 @@ static TCM_IRAM_ATTR void smp_core_do_retention(void) if ((frame_critical->pmufunc & 0x3) == 0x1) { atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_DONE); // wait another core trigger sleep and wakeup - esp_cpu_wait_for_intr(); while (1) { - ; + // If another core's sleep request is rejected by the hardware, jumps out of blocking. + another_core_state = atomic_load(&s_smp_retention_state[!core_id]); + if (another_core_state == SMP_SKIP_RETENTION) { + break; + } } } else { // Start core1 @@ -572,14 +576,14 @@ static TCM_IRAM_ATTR void smp_core_do_retention(void) } -IRAM_ATTR void esp_sleep_cpu_skip_retention(void) { +TCM_IRAM_ATTR void esp_sleep_cpu_skip_retention(void) { atomic_store(&s_smp_retention_state[esp_cpu_get_core_id()], SMP_SKIP_RETENTION); } #endif void sleep_smp_cpu_sleep_prepare(void) { -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU while (atomic_load(&s_smp_retention_state[!esp_cpu_get_core_id()]) != SMP_IDLE) { ; } @@ -591,7 +595,7 @@ void sleep_smp_cpu_sleep_prepare(void) void sleep_smp_cpu_wakeup_prepare(void) { -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU uint8_t core_id = esp_cpu_get_core_id(); if (atomic_load(&s_smp_retention_state[core_id]) == SMP_RESTORE_DONE) { while (atomic_load(&s_smp_retention_state[!core_id]) != SMP_RESTORE_DONE) { diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu_asm.S b/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu_asm.S index ed46453f3192..ef6aa2d19b0a 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu_asm.S +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu_asm.S @@ -9,6 +9,7 @@ #include "freertos/FreeRTOSConfig.h" #include "sdkconfig.h" +#include "esp32p4/rom/cache.h" #include "soc/cache_reg.h" #define MTVT (0x307) @@ -117,28 +118,6 @@ rv_core_critical_regs_save: mv t3, t0 csrr t0, mscratch sw t0, RV_SLP_CTX_T0(t3) - - /* writeback dcache is required here!!! */ - la t0, CACHE_SYNC_MAP_REG - li t1, 0x10 /* map l1 dcache */ - sw t1, 0x0(t0) /* set EXTMEM_CACHE_SYNC_MAP_REG bit 4 */ - la t2, CACHE_SYNC_ADDR_REG - sw zero, 0x0(t2) /* clear EXTMEM_CACHE_SYNC_ADDR_REG */ - la t0, CACHE_SYNC_SIZE_REG - sw zero, 0x0(t0) /* clear EXTMEM_CACHE_SYNC_SIZE_REG */ - - la t1, CACHE_SYNC_CTRL_REG - lw t2, 0x0(t1) - ori t2, t2, 0x4 - sw t2, 0x0(t1) - - li t0, 0x10 /* SYNC_DONE bit */ -wait_sync_done: - lw t2, 0x0(t1) - and t2, t0, t2 - beqz t2, wait_sync_done - - lw t0, RV_SLP_CTX_T0(t3) lw t1, RV_SLP_CTX_T1(t3) lw t2, RV_SLP_CTX_T2(t3) lw t3, RV_SLP_CTX_T3(t3) @@ -176,7 +155,7 @@ rv_core_critical_regs_restore: /* Core 0 is wakeup core, Invalidate L1 Cache here */ /* Invalidate L1 cache is required here!!! */ la t0, CACHE_SYNC_MAP_REG - li t1, 0x7 /* map l1 i/dcache */ + li t1, CACHE_MAP_L1_CACHE_MASK /* map l1 i/dcache */ sw t1, 0x0(t0) /* set EXTMEM_CACHE_SYNC_MAP_REG bit 4 */ la t2, CACHE_SYNC_ADDR_REG sw zero, 0x0(t2) /* clear EXTMEM_CACHE_SYNC_ADDR_REG */ diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32s3/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32s3/sleep_cpu.c index cc0f11b37890..cba8f6ee308d 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32s3/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32s3/sleep_cpu.c @@ -15,7 +15,6 @@ #include "esp_ipc_isr.h" #include "esp_sleep.h" #include "esp_log.h" -#include "esp_crc.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_heap_caps.h" @@ -232,7 +231,7 @@ bool cpu_domain_pd_allowed(void) esp_err_t sleep_cpu_configure(bool light_sleep_enable) { -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU if (light_sleep_enable) { ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep."); } else { diff --git a/components/esp_hw_support/modem_clock.c b/components/esp_hw_support/modem_clock.c index ec89c4bcf20d..9b2ad58a588a 100644 --- a/components/esp_hw_support/modem_clock.c +++ b/components/esp_hw_support/modem_clock.c @@ -381,8 +381,8 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl modem_clock_hal_enable_ble_rtc_timer_clock(MODEM_CLOCK_instance()->hal, true); #if CONFIG_IDF_TARGET_ESP32H2 if (!rc_clk_en) { - extern void esp_ble_rtc_ticks_delay(uint32_t ticks); - esp_ble_rtc_ticks_delay(2); + extern void r_esp_ble_rtc_ticks_delay(uint32_t ticks); + r_esp_ble_rtc_ticks_delay(2); clk_ll_rc32k_disable(); } #endif // CONFIG_IDF_TARGET_ESP32H2 @@ -390,9 +390,9 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl if (efuse_hal_chip_revision() != 0) { if (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { pmu_sleep_enable_hp_sleep_sysclk(true); + modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, true); + modem_clock_domain_clk_gate_disable(MODEM_CLOCK_DOMAIN_WIFIPWR, PMU_HP_ICG_MODEM_CODE_SLEEP); } - modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, true); - modem_clock_domain_clk_gate_disable(MODEM_CLOCK_DOMAIN_WIFIPWR, PMU_HP_ICG_MODEM_CODE_SLEEP); } #endif break; @@ -452,9 +452,9 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module) if (efuse_hal_chip_revision() != 0) { if (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { pmu_sleep_enable_hp_sleep_sysclk(false); + modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, false); + modem_clock_domain_clk_gate_enable(MODEM_CLOCK_DOMAIN_WIFIPWR, PMU_HP_ICG_MODEM_CODE_SLEEP); } - modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, false); - modem_clock_domain_clk_gate_enable(MODEM_CLOCK_DOMAIN_WIFI, PMU_HP_ICG_MODEM_CODE_SLEEP); } #endif break; diff --git a/components/esp_hw_support/port/esp32c2/rtc_clk.c b/components/esp_hw_support/port/esp32c2/rtc_clk.c index 20ef6d1d562c..425b72b17f5e 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c2/rtc_clk.c @@ -356,24 +356,6 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} - /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32c3/esp_cpu_intr.c b/components/esp_hw_support/port/esp32c3/esp_cpu_intr.c index 1c95ca8e70ac..6dfc26cbe687 100644 --- a/components/esp_hw_support/port/esp32c3/esp_cpu_intr.c +++ b/components/esp_hw_support/port/esp32c3/esp_cpu_intr.c @@ -11,11 +11,10 @@ void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_ { /* On the ESP32-C3, interrupt: * - 1 is for Wi-Fi - * - 5 and 8 for Bluetooth * - 6 for "permanently disabled interrupt", named INT_MUX_DISABLED_INTNO in the interrupt allocator */ // [TODO: IDF-2465] - const uint32_t rsvd_mask = BIT(1) | BIT(5) | BIT(6) | BIT(8); + const uint32_t rsvd_mask = BIT(1) | BIT(6); intr_desc_ret->priority = 1; intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; diff --git a/components/esp_hw_support/port/esp32c3/include/soc/rtc.h b/components/esp_hw_support/port/esp32c3/include/soc/rtc.h index 70c8a91ce3b4..260df1293054 100644 --- a/components/esp_hw_support/port/esp32c3/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c3/include/soc/rtc.h @@ -646,18 +646,6 @@ void rtc_sleep_init(rtc_sleep_config_t cfg); */ void rtc_sleep_low_init(uint32_t slowclk_period); -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND -/** - * @brief Configure systimer for esp32c3 systimer stall issue workaround - * - * This function configures related systimer for esp32c3 systimer stall issue. - * Only apply workaround when xtal powered up. - * - * @param en enable systimer or not - */ -void rtc_sleep_systimer_enable(bool en); -#endif - #define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup #define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup #define RTC_WIFI_TRIG_EN BIT(5) //!< WIFI wakeup (light sleep only) diff --git a/components/esp_hw_support/port/esp32c3/rtc_sleep.c b/components/esp_hw_support/port/esp32c3/rtc_sleep.c index ac771a47af13..3c246f869019 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c3/rtc_sleep.c @@ -24,7 +24,7 @@ #include "soc/regi2c_dig_reg.h" #include "soc/regi2c_lp_bias.h" #include "hal/efuse_hal.h" -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND #include "soc/systimer_reg.h" #endif @@ -252,17 +252,6 @@ void rtc_sleep_low_init(uint32_t slowclk_period) REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES); } -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND -void rtc_sleep_systimer_enable(bool en) -{ - if (en) { - REG_SET_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN); - } else { - REG_CLR_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN); - } -} -#endif - static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu); uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu) diff --git a/components/esp_hw_support/port/esp32c5/pmu_sleep.c b/components/esp_hw_support/port/esp32c5/pmu_sleep.c index 6d8e27faf384..7b6cce729325 100644 --- a/components/esp_hw_support/port/esp32c5/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32c5/pmu_sleep.c @@ -14,6 +14,7 @@ #include "soc/soc.h" #include "soc/rtc.h" #include "soc/pmu_struct.h" +#include "hal/efuse_hal.h" #include "hal/lp_aon_hal.h" #include "esp_private/esp_pmu.h" #include "pmu_param.h" @@ -274,11 +275,16 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp ; } - return pmu_sleep_finish(); + return pmu_sleep_finish(dslp); } -bool pmu_sleep_finish(void) +bool pmu_sleep_finish(bool dslp) { + (void)dslp; + + // Wait eFuse memory update done. + while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE); + return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); } diff --git a/components/esp_hw_support/port/esp32c6/clock_retention_init.c b/components/esp_hw_support/port/esp32c6/clock_retention_init.c index f79c39693996..3027347483c1 100644 --- a/components/esp_hw_support/port/esp32c6/clock_retention_init.c +++ b/components/esp_hw_support/port/esp32c6/clock_retention_init.c @@ -29,15 +29,27 @@ esp_err_t sleep_clock_modem_retention_init(void *arg) { #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) + #define MODEM_WIFI_RETENTION_CLOCK (MODEM_SYSCON_CLK_WIFI_APB_FO | MODEM_SYSCON_CLK_FE_APB_FO) + #define MODEM_WIFI_RETENTION_CLOCK_MASK (MODEM_SYSCON_CLK_WIFI_APB_FO_M | MODEM_SYSCON_CLK_FE_APB_FO_M) + const static sleep_retention_entries_config_t modem_regs_retention[] = { [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */ + [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(1), MODEM_SYSCON_CLK_CONF1_FORCE_ON_REG, MODEM_WIFI_RETENTION_CLOCK, MODEM_WIFI_RETENTION_CLOCK_MASK, 0, 0), .owner = ENTRY(0) }, /* WiFi (MAC, BB and FE) retention clock enable */ #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ #endif }; + const static sleep_retention_entries_config_t modem_retention_clock[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(0xf0), MODEM_SYSCON_CLK_CONF1_FORCE_ON_REG, 0x0, MODEM_WIFI_RETENTION_CLOCK_MASK, 0, 0), .owner = ENTRY(0) } /* WiFi (MAC, BB and FE) retention clock disable */ + }; + esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 1 level priority"); + + err = sleep_retention_entries_create(modem_retention_clock, ARRAY_SIZE(modem_retention_clock), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_CLOCK_MODEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, lowest level priority"); + ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization"); return ESP_OK; } diff --git a/components/esp_hw_support/port/esp32c6/io_mux.c b/components/esp_hw_support/port/esp32c6/io_mux.c index e5679e40b4bd..bd164ce683e3 100644 --- a/components/esp_hw_support/port/esp32c6/io_mux.c +++ b/components/esp_hw_support/port/esp32c6/io_mux.c @@ -1,16 +1,29 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "esp_attr.h" #include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" +#include "esp_private/periph_ctrl.h" #include "hal/gpio_ll.h" +#include "hal/rtc_io_ll.h" + +#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) +#if CONFIG_ULP_COPROC_ENABLED +RTC_DATA_ATTR +#endif +static rtc_io_status_t s_rtc_io_status = { + .rtc_io_enabled_cnt = { 0 }, + .rtc_io_using_mask = 0 +}; + esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) { bool clk_conflict = false; @@ -31,3 +44,27 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) return ESP_OK; } + +void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) +{ + portENTER_CRITICAL(&s_io_mux_spinlock); + if (enable) { + if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); + } + s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++; + } else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) { + s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--; + if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); + } + } + RTCIO_RCC_ATOMIC() { + if (s_rtc_io_status.rtc_io_using_mask == 0) { + rtcio_ll_enable_io_clock(false); + } else { + rtcio_ll_enable_io_clock(true); + } + } + portEXIT_CRITICAL(&s_io_mux_spinlock); +} diff --git a/components/esp_hw_support/port/esp32c6/pmu_sleep.c b/components/esp_hw_support/port/esp32c6/pmu_sleep.c index c85fd72c2c79..a50e7bec68a2 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32c6/pmu_sleep.c @@ -236,6 +236,10 @@ const pmu_sleep_config_t* pmu_sleep_config_default( analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = PMU_DBG_ATTEN_ACTIVE_DEFAULT; analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias(); + } else if (!(pd_flags & PMU_SLEEP_PD_RC_FAST)) { + analog_default.hp_sys.analog.dbias = get_act_hp_dbias(); + analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_NODROP; + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias(); } config->analog = analog_default; @@ -337,11 +341,16 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp ; } - return pmu_sleep_finish(); + return pmu_sleep_finish(dslp); } -bool pmu_sleep_finish(void) +bool pmu_sleep_finish(bool dslp) { + (void)dslp; + + // Wait eFuse memory update done. + while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE); + return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); } diff --git a/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h b/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h index 751076f7521a..aad6f976ba47 100644 --- a/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h @@ -35,6 +35,7 @@ extern "C" { #define PMU_LP_DRVB_LIGHTSLEEP 0 #define PMU_HP_XPD_LIGHTSLEEP 1 +#define PMU_DBG_ATTEN_LIGHTSLEEP_NODROP 0 #define PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT 0 #define PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT 1 #define PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT 12 diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk.c b/components/esp_hw_support/port/esp32c6/rtc_clk.c index 3beac67c3c2e..228a713ad9ef 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk.c @@ -362,6 +362,7 @@ soc_xtal_freq_t rtc_clk_xtal_freq_get(void) uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz(); if (xtal_freq_mhz == 0) { ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz"); + clk_ll_xtal_store_freq_mhz(SOC_XTAL_FREQ_40M); return SOC_XTAL_FREQ_40M; } return (soc_xtal_freq_t)xtal_freq_mhz; @@ -422,25 +423,6 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} - - /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32c61/rtc_clk.c b/components/esp_hw_support/port/esp32c61/rtc_clk.c index 4644e1df393c..3a20ede1b94b 100644 --- a/components/esp_hw_support/port/esp32c61/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c61/rtc_clk.c @@ -427,25 +427,6 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} - - /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32h2/io_mux.c b/components/esp_hw_support/port/esp32h2/io_mux.c index 653c0b298129..3ff1884c10de 100644 --- a/components/esp_hw_support/port/esp32h2/io_mux.c +++ b/components/esp_hw_support/port/esp32h2/io_mux.c @@ -1,15 +1,21 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" +#include "esp_private/periph_ctrl.h" #include "hal/gpio_ll.h" +#include "hal/rtc_io_ll.h" + +#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter) +static uint8_t s_rtc_io_enabled_cnt[MAX_RTC_GPIO_NUM] = { 0 }; +static uint32_t s_rtc_io_using_mask = 0; esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) { @@ -31,3 +37,27 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) return ESP_OK; } + +void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable) +{ + portENTER_CRITICAL(&s_io_mux_spinlock); + if (enable) { + if (s_rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_using_mask |= (1ULL << gpio_num); + } + s_rtc_io_enabled_cnt[gpio_num]++; + } else if (!enable && (s_rtc_io_enabled_cnt[gpio_num] > 0)) { + s_rtc_io_enabled_cnt[gpio_num]--; + if (s_rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_using_mask &= ~(1ULL << gpio_num); + } + } + RTCIO_RCC_ATOMIC() { + if (s_rtc_io_using_mask == 0) { + rtcio_ll_enable_io_clock(false); + } else { + rtcio_ll_enable_io_clock(true); + } + } + portEXIT_CRITICAL(&s_io_mux_spinlock); +} diff --git a/components/esp_hw_support/port/esp32h2/pmu_sleep.c b/components/esp_hw_support/port/esp32h2/pmu_sleep.c index 5c2b902523e9..ab32613ab59d 100644 --- a/components/esp_hw_support/port/esp32h2/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32h2/pmu_sleep.c @@ -164,6 +164,9 @@ const pmu_sleep_config_t* pmu_sleep_config_default( analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON; analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias(); + } else if (!(pd_flags & PMU_SLEEP_PD_RC_FAST)) { + analog_default.hp_sys.analog.dbias = get_act_hp_dbias(); + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias(); } config->analog = analog_default; } @@ -255,11 +258,12 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp ; } - return ESP_OK; + return pmu_sleep_finish(dslp); } -bool pmu_sleep_finish(void) +bool pmu_sleep_finish(bool dslp) { + (void)dslp; return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); } diff --git a/components/esp_hw_support/port/esp32h2/rtc_clk.c b/components/esp_hw_support/port/esp32h2/rtc_clk.c index f2ca1ca3ff58..27898a95b411 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32h2/rtc_clk.c @@ -238,7 +238,7 @@ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) /** * Switch to FLASH_PLL as cpu clock source. * On ESP32H2, FLASH_PLL frequency is 64MHz. - * PLL must alreay be enabled. + * PLL must already be enabled. */ static void rtc_clk_cpu_freq_to_flash_pll(uint32_t cpu_freq_mhz, uint32_t cpu_divider) { @@ -474,21 +474,3 @@ bool rtc_dig_8m_enabled(void) { return clk_ll_rc_fast_digi_is_enabled(); } - -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. Flash_PLL comes from the same source as PLL. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL || old_config.source == SOC_CPU_CLK_SRC_FLASH_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} diff --git a/components/esp_hw_support/port/esp32p4/CMakeLists.txt b/components/esp_hw_support/port/esp32p4/CMakeLists.txt index f81f017081a2..2965e1746d3b 100644 --- a/components/esp_hw_support/port/esp32p4/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32p4/CMakeLists.txt @@ -10,7 +10,8 @@ set(srcs "rtc_clk_init.c" ) if(NOT BOOTLOADER_BUILD) - list(APPEND srcs "esp_crypto_lock.c") + list(APPEND srcs "sar_periph_ctrl.c" + "esp_crypto_lock.c") if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) list(APPEND srcs "mspi_timing_config.c") diff --git a/components/esp_hw_support/port/esp32p4/Kconfig.dcdc b/components/esp_hw_support/port/esp32p4/Kconfig.dcdc new file mode 100644 index 000000000000..a4d3ab3d37a8 --- /dev/null +++ b/components/esp_hw_support/port/esp32p4/Kconfig.dcdc @@ -0,0 +1,30 @@ +menu "DCDC Regulator Configurations" + depends on SOC_GP_LDO_SUPPORTED + + config ESP_SLEEP_KEEP_DCDC_ALWAYS_ON + bool "Keep DC-DC power always on during light-sleep" + default y + help + ESP32P4 will switch the power supply to LDO before sleeping, and switch to DCDC after waking up. + These two processes take a long time and may bring some risks for some short duration + light sleep. (DCDC -> LDO: 2.5ms (max), LDO -> DCDC: 1.2 ms) + Enabling this option will make chip powered by DCDC during light sleep to reduce some power switch + risks, this will also increase the power consumption during the light sleep. + + DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING. + + config ESP_SLEEP_DCM_VSET_VAL_IN_SLEEP + int "DCDC voltage parameter during sleep" + default 14 + range 0 31 + depends on ESP_SLEEP_KEEP_DCDC_ALWAYS_ON + help + This value determines the voltage of the DCDC chip during sleep. The same parameter value may + correspond to different voltage values on different models of DCDC chips. Please update this + value according to the model of external DCDC selected in your hardware solution. + + For the DCDC chip model recommended by ESP, the recommended configuration + values are listed below: + + - TI-TLV62569/TLV62569P: 14 +endmenu diff --git a/components/esp_hw_support/port/esp32p4/Kconfig.hw_support b/components/esp_hw_support/port/esp32p4/Kconfig.hw_support index a7c2840267a9..2471aaa60238 100644 --- a/components/esp_hw_support/port/esp32p4/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32p4/Kconfig.hw_support @@ -1,6 +1,6 @@ choice ESP32P4_REV_MIN prompt "Minimum Supported ESP32-P4 Revision" - default ESP32P4_REV_MIN_0 + default ESP32P4_REV_MIN_1 help Required minimum chip revision. ESP-IDF will check for it and reject to boot if the chip revision fails the check. @@ -11,11 +11,14 @@ choice ESP32P4_REV_MIN config ESP32P4_REV_MIN_0 bool "Rev v0.0" + config ESP32P4_REV_MIN_1 + bool "Rev v0.1" endchoice config ESP32P4_REV_MIN_FULL int default 0 if ESP32P4_REV_MIN_0 + default 1 if ESP32P4_REV_MIN_1 config ESP_REV_MIN_FULL int diff --git a/components/esp_hw_support/port/esp32p4/cpu_region_protect.c b/components/esp_hw_support/port/esp32p4/cpu_region_protect.c index cfed9a0f0c65..acf88eae27bf 100644 --- a/components/esp_hw_support/port/esp32p4/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32p4/cpu_region_protect.c @@ -38,39 +38,38 @@ static void esp_cpu_configure_invalid_regions(void) __attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X; __attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X; - // 0. Special case - This whitelists the External flash/RAM, HP ROM and HP L2MEM regions and make them cacheable. - // At the startup, this is done using PMA entry 15 by the ROM code. - // We are reconfiguring and making it the highest priority entry here. - PMA_ENTRY_SET_NAPOT(0, SOC_IROM_LOW, SOC_PERIPHERAL_LOW - SOC_IROM_LOW, PMA_NAPOT | PMA_RWX); + // 0. Gap at bottom of address space + PMA_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE); - // 1. Gap at bottom of address space - PMA_ENTRY_SET_NAPOT(1, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE); + // 1. Gap between CPU subsystem region & HP TCM + PMA_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(2, SOC_TCM_LOW, PMA_TOR | PMA_NONE); - // 2. Gap between CPU subsystem region & HP TCM - PMA_ENTRY_SET_TOR(2, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(3, SOC_TCM_LOW, PMA_TOR | PMA_NONE); + // 2. Gap between HP TCM and CPU Peripherals + PMA_ENTRY_SET_TOR(3, SOC_TCM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(4, CPU_PERIPH_LOW, PMA_TOR | PMA_NONE); - // 3. Gap between HP TCM and CPU Peripherals - PMA_ENTRY_SET_TOR(4, SOC_TCM_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(5, CPU_PERIPH_LOW, PMA_TOR | PMA_NONE); + // 3. Gap between CPU Peripherals and I_Cache + PMA_ENTRY_SET_TOR(5, CPU_PERIPH_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE); - // 4. Gap between CPU Peripherals and I_Cache - PMA_ENTRY_SET_TOR(6, CPU_PERIPH_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(7, SOC_IROM_LOW, PMA_TOR | PMA_NONE); + // 4. Gap between I_Cache and external memory range + PMA_ENTRY_SET_NAPOT(7, SOC_DROM_HIGH, SOC_EXTRAM_LOW - SOC_DROM_HIGH, PMA_NAPOT | PMA_NONE); - // 5. Gap between I_Cache and external memory range - PMA_ENTRY_SET_NAPOT(8, SOC_DROM_HIGH, SOC_EXTRAM_LOW - SOC_DROM_HIGH, PMA_NAPOT | PMA_NONE); + // 5. Gap between external memory and ROM + PMA_ENTRY_SET_TOR(8, SOC_EXTRAM_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(9, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE); - // 6. Gap between external memory and ROM - PMA_ENTRY_SET_TOR(9, SOC_EXTRAM_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(10, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE); + // 6. Gap between ROM and internal memory + PMA_ENTRY_SET_TOR(10, SOC_IROM_MASK_HIGH, PMA_NONE); + PMA_ENTRY_SET_TOR(11, SOC_IRAM_LOW, PMA_TOR | PMA_NONE); - // 7. Gap between ROM and internal memory - PMA_ENTRY_SET_TOR(11, SOC_IROM_MASK_HIGH, PMA_NONE); - PMA_ENTRY_SET_TOR(12, SOC_IRAM_LOW, PMA_TOR | PMA_NONE); + // 7. Gap between internal memory and HP peripherals + PMA_ENTRY_SET_NAPOT(12, SOC_DRAM_HIGH, SOC_PERIPHERAL_LOW - SOC_DRAM_HIGH, PMA_NAPOT | PMA_NONE); - // 8. Gap between internal memory and HP peripherals - PMA_ENTRY_SET_NAPOT(13, SOC_DRAM_HIGH, SOC_PERIPHERAL_LOW - SOC_DRAM_HIGH, PMA_NAPOT | PMA_NONE); + // 8. Special case - This whitelists the External flash/RAM, HP ROM and HP L2MEM regions and make them cacheable. + // At the startup, this is done using PMA entry 15 by the ROM code. + PMA_ENTRY_SET_NAPOT(13, SOC_IROM_LOW, SOC_PERIPHERAL_LOW - SOC_IROM_LOW, PMA_NAPOT | PMA_RWX); // 9. Gap between Uncacheable L2 Mem and end of address space PMA_ENTRY_SET_TOR(14, CACHE_LL_L2MEM_NON_CACHE_ADDR(SOC_DRAM_HIGH), PMA_NONE); diff --git a/components/esp_hw_support/port/esp32p4/esp_clk_tree.c b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c index 835f427078cf..788ddfcfac7e 100644 --- a/components/esp_hw_support/port/esp32p4/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c @@ -16,7 +16,7 @@ static const char *TAG = "esp_clk_tree"; esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision, -uint32_t *freq_value) + uint32_t *freq_value) { ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src"); ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision"); diff --git a/components/esp_hw_support/port/esp32p4/pmu_init.c b/components/esp_hw_support/port/esp32p4/pmu_init.c index a0d3c53be26d..92d67002fdf9 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_init.c +++ b/components/esp_hw_support/port/esp32p4/pmu_init.c @@ -79,7 +79,6 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias); pmu_ll_hp_set_dcm_mode (ctx->hal->dev, mode, anlg->bias.dcm_mode); pmu_ll_hp_set_dcm_vset (ctx->hal->dev, mode, anlg->bias.dcm_vset); - pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias); pmu_ll_hp_set_dbg_atten (ctx->hal->dev, mode, anlg->bias.dbg_atten); pmu_ll_hp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur); pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep); diff --git a/components/esp_hw_support/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index 919197fb4817..0ac1107cc652 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -11,14 +11,19 @@ #include "sdkconfig.h" #include "esp_err.h" #include "esp_attr.h" +#include "esp_private/rtc_clk.h" #include "esp_private/regi2c_ctrl.h" +#include "esp32p4/rom/cache.h" +#include "soc/chip_revision.h" #include "soc/soc.h" #include "soc/regi2c_syspll.h" #include "soc/regi2c_cpll.h" #include "soc/rtc.h" +#include "soc/cache_reg.h" #include "soc/pau_reg.h" #include "soc/pmu_reg.h" #include "soc/pmu_struct.h" +#include "hal/clk_tree_hal.h" #include "hal/lp_aon_hal.h" #include "soc/lp_system_reg.h" #include "hal/pmu_hal.h" @@ -27,6 +32,7 @@ #include "pmu_param.h" #include "esp_rom_sys.h" #include "esp_rom_uart.h" +#include "hal/efuse_hal.h" #define HP(state) (PMU_MODE_HP_ ## state) #define LP(state) (PMU_MODE_LP_ ## state) @@ -145,26 +151,39 @@ const pmu_sleep_config_t* pmu_sleep_config_default( iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G1) ? BIT(1) : 0; iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G2) ? BIT(2) : 0; iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G3) ? BIT(3) : 0; - config->power = power_default; - - pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags); - config->param = *pmu_sleep_param_config_default(¶m_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period); if (dslp) { config->param.lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US, slowclk_period); + + pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(pd_flags); + config->digital = digital_default; + pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags); config->analog = analog_default; } else { + // Get light sleep digital_default pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags); config->digital = digital_default; + // Get light sleep analog default pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags); #if CONFIG_SPIRAM analog_default.hp_sys.analog.pd_cur = 1; analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 1; #endif + +#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON + power_default.hp_sys.dig_power.dcdc_switch_pd_en = 0; + analog_default.hp_sys.analog.dcm_vset = CONFIG_ESP_SLEEP_DCM_VSET_VAL_IN_SLEEP; + analog_default.hp_sys.analog.dcm_mode = 1; +#endif config->analog = analog_default; } + + config->power = power_default; + pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags); + config->param = *pmu_sleep_param_config_default(¶m_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period); + return config; } @@ -185,11 +204,14 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_config_t *dig) { pmu_ll_hp_set_dig_pad_slp_sel (ctx->hal->dev, HP(SLEEP), dig->syscntl.dig_pad_slp_sel); + pmu_ll_hp_set_hold_all_lp_pad (ctx->hal->dev, HP(SLEEP), dig->syscntl.lp_pad_hold_all); } static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp) { assert(ctx->hal); + pmu_ll_hp_set_dcm_mode (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dcm_mode); + pmu_ll_hp_set_dcm_vset (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dcm_vset); pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur); pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep); pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_xpd); @@ -238,31 +260,16 @@ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp) { assert(PMU_instance()); pmu_sleep_power_init(PMU_instance(), &config->power, dslp); - if(!dslp){ - pmu_sleep_digital_init(PMU_instance(), &config->digital); - } + pmu_sleep_digital_init(PMU_instance(), &config->digital); pmu_sleep_analog_init(PMU_instance(), &config->analog, dslp); pmu_sleep_param_init(PMU_instance(), &config->param, dslp); - - // When light sleep (PD_TOP), the PAU will power down. so need use LP_SYS_BACKUP_DMA_CFG2_REG to store recover link address. - if (!dslp && PMU.hp_sys[PMU_MODE_HP_SLEEP].dig_power.top_pd_en) { - if (PMU.hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en || - PMU.hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en) { - uint32_t link_sel = PMU.hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_mode & 0x3; - uint32_t link_addr = REG_READ(PAU_REGDMA_LINK_0_ADDR_REG + link_sel * 4); - lp_sys_ll_set_pau_link_addr(link_addr); - pmu_sleep_enable_regdma_backup(); - } - } else { - pmu_sleep_disable_regdma_backup(); - } } void pmu_sleep_increase_ldo_volt(void) { - REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 30); - REG_SET_BIT(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD); + pmu_ll_hp_set_regulator_dbias(&PMU, PMU_MODE_HP_ACTIVE, 30); + pmu_ll_hp_set_regulator_xpd(&PMU, PMU_MODE_HP_ACTIVE, 1); // Decrease the DCDC voltage to reduce the voltage difference between the DCDC and the LDO to avoid overshooting the DCDC voltage during wake-up. - REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 24); + pmu_ll_hp_set_dcm_vset(&PMU, PMU_MODE_HP_ACTIVE, 24); } void pmu_sleep_shutdown_dcdc(void) { @@ -283,6 +290,13 @@ void pmu_sleep_shutdown_ldo(void) { CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD); } +FORCE_INLINE_ATTR void sleep_writeback_l1_dcache(void) { + Cache_WriteBack_All(CACHE_MAP_L1_DCACHE); + while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); +} + +static TCM_DRAM_ATTR uint32_t s_mpll_freq_mhz_before_sleep = 0; + TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) { lp_aon_hal_inform_wakeup_type(dslp); @@ -295,6 +309,15 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev); pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev); + // !!! Need to manually check that data in L2 memory will not be modified from now on. !!! + sleep_writeback_l1_dcache(); + + // !!! Need to manually check that data in PSRAM will not be accessed from now on. !!! + s_mpll_freq_mhz_before_sleep = rtc_clk_mpll_get_freq(); + if (s_mpll_freq_mhz_before_sleep) { + rtc_clk_mpll_disable(); + } + /* Start entry into sleep mode */ pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev); @@ -303,22 +326,40 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, ; } - return pmu_sleep_finish(); + return pmu_sleep_finish(dslp); } -TCM_IRAM_ATTR bool pmu_sleep_finish(void) +TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp) { - REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 27); - if (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) { - // If sleep is rejected, the hardware wake-up process that turns on DCDC - // is skipped, and software is used to enable DCDC here. - pmu_sleep_enable_dcdc(); - esp_rom_delay_us(950); +#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON + if (!dslp) { + // Keep DCDC always on during light sleep, no need to adjust LDO. + } else +#endif + { + pmu_ll_hp_set_dcm_vset(&PMU, PMU_MODE_HP_ACTIVE, 27); + if (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) { + // If sleep is rejected, the hardware wake-up process that turns on DCDC + // is skipped, and software is used to enable DCDC here. + pmu_sleep_enable_dcdc(); + esp_rom_delay_us(950); + } + pmu_sleep_shutdown_ldo(); } - pmu_sleep_shutdown_ldo(); - REGI2C_WRITE_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, 6); // lower default cpu_pll freq to 400M - REGI2C_WRITE_MASK(I2C_SYSPLL, I2C_SYSPLL_OC_DIV_7_0, 8); // lower default sys_pll freq to 480M + if (s_mpll_freq_mhz_before_sleep) { + rtc_clk_mpll_enable(); + rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), s_mpll_freq_mhz_before_sleep); + } + + // Wait eFuse memory update done. + while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE); + + unsigned chip_version = efuse_hal_chip_revision(); + if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) { + REGI2C_WRITE_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, 6); // lower default cpu_pll freq to 400M + REGI2C_WRITE_MASK(I2C_SYSPLL, I2C_SYSPLL_OC_DIV_7_0, 8); // lower default sys_pll freq to 480M + } return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); } diff --git a/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h b/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h index b1c3aec17518..0d2bb42bf65a 100644 --- a/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h @@ -105,7 +105,7 @@ const pmu_lp_system_analog_param_t* pmu_lp_system_analog_param_default(pmu_lp_mo typedef union { struct { uint32_t reserved0 : 21; - uint32_t dcdc_switch_pd_en: 1; + uint32_t dcdc_switch_pd_en: 1; uint32_t mem_dslp : 1; uint32_t mem_pd_en : 1; uint32_t reserved1 : 6; @@ -153,7 +153,9 @@ typedef union { typedef struct { struct { - uint32_t reserved0 : 25; + uint32_t reserved0 : 18; + uint32_t dcm_vset : 5; + uint32_t dcm_mode : 2; uint32_t xpd_bias : 1; uint32_t dbg_atten : 4; uint32_t pd_cur : 1; @@ -312,9 +314,18 @@ typedef struct { pmu_hp_sys_cntl_reg_t syscntl; } pmu_sleep_digital_config_t; + +#define PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(pd_flags) { \ + .syscntl = { \ + .dig_pad_slp_sel = 0, \ + .lp_pad_hold_all = (pd_flags & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \ + } \ +} + #define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags) { \ .syscntl = { \ - .dig_pad_slp_sel = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 0 : 1, \ + .dig_pad_slp_sel = (pd_flags & PMU_SLEEP_PD_TOP) ? 0 : 1, \ + .lp_pad_hold_all = (pd_flags & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \ } \ } diff --git a/components/esp_hw_support/port/esp32p4/rtc_clk.c b/components/esp_hw_support/port/esp32p4/rtc_clk.c index a5e45222cc98..4bcccf422e18 100644 --- a/components/esp_hw_support/port/esp32p4/rtc_clk.c +++ b/components/esp_hw_support/port/esp32p4/rtc_clk.c @@ -14,6 +14,7 @@ #include "soc/rtc.h" #include "esp_private/rtc_clk.h" #include "esp_attr.h" +#include "esp_cpu.h" #include "esp_hw_log.h" #include "esp_rom_sys.h" #include "hal/clk_tree_ll.h" @@ -28,7 +29,7 @@ static const char *TAG = "rtc_clk"; static int s_cur_cpll_freq = 0; // MPLL frequency option, 400MHz. Zero if MPLL is not enabled. -static DRAM_ATTR uint32_t s_cur_mpll_freq = 0; +static TCM_DRAM_ATTR uint32_t s_cur_mpll_freq = 0; void rtc_clk_32k_enable(bool enable) { @@ -182,7 +183,13 @@ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div, bool to_default) clk_ll_mem_set_divider(mem_divider); clk_ll_sys_set_divider(sys_divider); clk_ll_apb_set_divider(apb_divider); +#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2)) + esp_cpu_stall(1 - esp_cpu_get_core_id()); +#endif clk_ll_bus_update(); +#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2)) + esp_cpu_unstall(1 - esp_cpu_get_core_id()); +#endif esp_rom_set_cpu_ticks_per_us(cpu_freq); } @@ -194,7 +201,13 @@ static void rtc_clk_cpu_freq_to_8m(void) clk_ll_sys_set_divider(1); clk_ll_apb_set_divider(1); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST); +#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2)) + esp_cpu_stall(1 - esp_cpu_get_core_id()); +#endif clk_ll_bus_update(); +#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2)) + esp_cpu_unstall(1 - esp_cpu_get_core_id()); +#endif esp_rom_set_cpu_ticks_per_us(20); } @@ -240,14 +253,22 @@ static void rtc_clk_cpu_freq_to_cpll_mhz(int cpu_freq_mhz, hal_utils_clk_div_t * // Update bit does not control CPU clock sel mux. Therefore, there may be a middle state during the switch (CPU rises) // Since this is upscaling, we need to configure the frequency division coefficient before switching the clock source. // Otherwise, an intermediate state will occur, in the intermediate state, the frequency of APB/MEM does not meet the - // timing requirements. If there are periperals/CPU access that depend on these two clocks at this moment, some exception + // timing requirements. If there are periperals access that depend on these two clocks at this moment, some exception // might occur. clk_ll_cpu_set_divider(div->integer, div->numerator, div->denominator); clk_ll_mem_set_divider(mem_divider); clk_ll_sys_set_divider(sys_divider); clk_ll_apb_set_divider(apb_divider); +#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2)) + // During frequency switching, non-frequency switching cores may have ongoing memory accesses, which may cause access + // failures, stalling non-frequency switching cores here can avoid such failures. + esp_cpu_stall(1 - esp_cpu_get_core_id()); +#endif clk_ll_bus_update(); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); +#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2)) + esp_cpu_unstall(1 - esp_cpu_get_core_id()); +#endif esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); } @@ -484,13 +505,13 @@ bool rtc_dig_8m_enabled(void) } //------------------------------------MPLL-------------------------------------// -void rtc_clk_mpll_disable(void) +TCM_IRAM_ATTR void rtc_clk_mpll_disable(void) { clk_ll_mpll_disable(); s_cur_mpll_freq = 0; } -void rtc_clk_mpll_enable(void) +TCM_IRAM_ATTR void rtc_clk_mpll_enable(void) { clk_ll_mpll_enable(); } @@ -508,7 +529,7 @@ void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq) s_cur_mpll_freq = mpll_freq; } -uint32_t rtc_clk_mpll_get_freq(void) +TCM_IRAM_ATTR uint32_t rtc_clk_mpll_get_freq(void) { return s_cur_mpll_freq; } diff --git a/components/esp_hw_support/port/esp32p4/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32p4/sar_periph_ctrl.c new file mode 100644 index 000000000000..90a4b986aede --- /dev/null +++ b/components/esp_hw_support/port/esp32p4/sar_periph_ctrl.c @@ -0,0 +1,116 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SAR related peripherals are interdependent. This file + * provides a united control to these registers, as multiple + * components require these controls. + * + * Related peripherals are: + * - ADC + * - PWDET + */ + +#include "sdkconfig.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "esp_private/sar_periph_ctrl.h" +#include "esp_private/esp_modem_clock.h" +#include "hal/sar_ctrl_ll.h" + +static const char *TAG = "sar_periph_ctrl"; +extern portMUX_TYPE rtc_spinlock; + + +void sar_periph_ctrl_init(void) +{ + //Put SAR control mux to FSM state + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); +} + +void sar_periph_ctrl_power_enable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + +void sar_periph_ctrl_power_disable(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_OFF); + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + +/** + * This gets incremented when s_sar_power_acquire() is called, + * and decremented when s_sar_power_release() is called. + * PWDET is powered down when the value reaches zero. + * Should be modified within critical section. + */ +static int s_sar_power_on_cnt; + +static void s_sar_power_acquire(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + s_sar_power_on_cnt++; + if (s_sar_power_on_cnt == 1) { + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_ON); + } + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + +static void s_sar_power_release(void) +{ + portENTER_CRITICAL_SAFE(&rtc_spinlock); + s_sar_power_on_cnt--; + if (s_sar_power_on_cnt < 0) { + portEXIT_CRITICAL(&rtc_spinlock); + ESP_LOGE(TAG, "%s called, but s_sar_power_on_cnt == 0", __func__); + abort(); + } else if (s_sar_power_on_cnt == 0) { + sar_ctrl_ll_set_power_mode(SAR_CTRL_LL_POWER_FSM); + } + portEXIT_CRITICAL_SAFE(&rtc_spinlock); +} + + +/*------------------------------------------------------------------------------ +* PWDET Power +*----------------------------------------------------------------------------*/ +void sar_periph_ctrl_pwdet_power_acquire(void) +{ + s_sar_power_acquire(); +} + +void sar_periph_ctrl_pwdet_power_release(void) +{ + s_sar_power_release(); +} + + +/*------------------------------------------------------------------------------ +* ADC Power +*----------------------------------------------------------------------------*/ +void sar_periph_ctrl_adc_oneshot_power_acquire(void) +{ + s_sar_power_acquire(); +} + +void sar_periph_ctrl_adc_oneshot_power_release(void) +{ + s_sar_power_release(); +} + +void sar_periph_ctrl_adc_continuous_power_acquire(void) +{ + s_sar_power_acquire(); +} + +void sar_periph_ctrl_adc_continuous_power_release(void) +{ + s_sar_power_release(); +} diff --git a/components/esp_hw_support/port/esp32s3/esp_cpu_intr.c b/components/esp_hw_support/port/esp32s3/esp_cpu_intr.c index acd0cbe83dd6..7c0ef80acc72 100644 --- a/components/esp_hw_support/port/esp32s3/esp_cpu_intr.c +++ b/components/esp_hw_support/port/esp32s3/esp_cpu_intr.c @@ -20,31 +20,6 @@ typedef struct { } intr_desc_t; -/** - * @brief Reserve the interrupts on the core where Bluetooth will run. - * The macro CONFIG_BT_CTRL_PINNED_TO_CORE is only defined if Bluetooth controller is enabled. - * It is set to the core where it will run. - */ -#ifdef CONFIG_BT_CTRL_PINNED_TO_CORE - #if CONFIG_BT_CTRL_PINNED_TO_CORE == 0 - #define CORE_0_INTERRUPT_5 ESP_CPU_INTR_DESC_FLAG_RESVD - #define CORE_1_INTERRUPT_5 0 - #define CORE_0_INTERRUPT_8 ESP_CPU_INTR_DESC_FLAG_RESVD - #define CORE_1_INTERRUPT_8 0 - #elif CONFIG_BT_CTRL_PINNED_TO_CORE == 1 - #define CORE_0_INTERRUPT_5 0 - #define CORE_1_INTERRUPT_5 ESP_CPU_INTR_DESC_FLAG_RESVD - #define CORE_0_INTERRUPT_8 0 - #define CORE_1_INTERRUPT_8 ESP_CPU_INTR_DESC_FLAG_RESVD - #endif -#else // Bluetooth not enabled - #define CORE_0_INTERRUPT_5 0 - #define CORE_1_INTERRUPT_5 0 - #define CORE_0_INTERRUPT_8 0 - #define CORE_1_INTERRUPT_8 0 -#endif - - const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = { /* Interrupt 0 reserved for WMAC (Wifi) */ #if CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0 @@ -57,12 +32,10 @@ const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = { [3] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, /* Interrupt 4 reserved for WBB */ [4] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, 0 } }, - /* Interrupt 5 reserved for BT/BLE Controller */ - [5] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_5, CORE_1_INTERRUPT_5 } }, + [5] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, [6] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, [7] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, - /* Interrupt 8 reserved for BT/BLE Controller */ - [8] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_8, CORE_1_INTERRUPT_8 } }, + [8] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, [9] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, [10] = { 1, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, [11] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, diff --git a/components/esp_hw_support/port/esp32s3/rtc_clk.c b/components/esp_hw_support/port/esp32s3/rtc_clk.c index a795619b99e5..1416b2862c66 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s3/rtc_clk.c @@ -187,7 +187,7 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) { - /* There are totally 6 LDO slaves(all on by default). At the moment of swithing LDO slave, LDO voltage will also change instantaneously. + /* There are totally 6 LDO slaves(all on by default). At the moment of switching LDO slave, LDO voltage will also change instantaneously. * LDO slave can reduce the voltage change caused by switching frequency. * CPU frequency <= 40M : just open 3 LDO slaves; CPU frequency = 80M : open 4 LDO slaves; CPU frequency = 160M : open 5 LDO slaves; CPU frequency = 240M : open 6 LDO slaves; * @@ -460,25 +460,6 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} - - /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/linux/esp_random.c b/components/esp_hw_support/port/linux/esp_random.c index e1dc505a2eef..19bed4dc65f3 100644 --- a/components/esp_hw_support/port/linux/esp_random.c +++ b/components/esp_hw_support/port/linux/esp_random.c @@ -17,13 +17,16 @@ static void __attribute__((constructor)) esp_random_init(void) { } uint32_t esp_random(void) { uint32_t random_number; - assert(getentropy(&random_number, sizeof(random_number)) == 0); + int result = getentropy(&random_number, sizeof(random_number)); + assert(result == 0); + (void)result; return random_number; } void esp_fill_random(void *buf, size_t len) { assert(buf != NULL); + int result; // Note that we can't use getentropy() with len > 256 directly (see getentropy man page), // hence reading in chunks @@ -31,8 +34,12 @@ void esp_fill_random(void *buf, size_t len) const size_t REST_CHUNK_SIZE = len % GETENTROPY_MAX_LEN; for (size_t chunk_num = 0; chunk_num < FULL_CHUNKS_NUM; chunk_num++) { - assert(getentropy(buf + chunk_num * GETENTROPY_MAX_LEN, GETENTROPY_MAX_LEN) == 0); + result = getentropy(buf + chunk_num * GETENTROPY_MAX_LEN, GETENTROPY_MAX_LEN); + assert(result == 0); + (void)result; } - assert(getentropy(buf + FULL_CHUNKS_NUM * GETENTROPY_MAX_LEN, REST_CHUNK_SIZE) == 0); + result = getentropy(buf + FULL_CHUNKS_NUM * GETENTROPY_MAX_LEN, REST_CHUNK_SIZE); + assert(result == 0); + (void)result; } diff --git a/components/esp_hw_support/port/regdma_link.c b/components/esp_hw_support/port/regdma_link.c index d2f0c908cfce..0af808ae3234 100644 --- a/components/esp_hw_support/port/regdma_link.c +++ b/components/esp_hw_support/port/regdma_link.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include #include #include +#include #include "esp_private/regdma_link.h" @@ -445,9 +446,22 @@ static void regdma_link_update_stats_wrapper(void *link, int entry, int depth) regdma_link_update_stats(regdma_link_get_stats(link), entry, depth); } +static void regdma_link_iterator(void *link, int entry, void (*hook)(void *, int, int)) +{ + assert(entry < REGDMA_LINK_ENTRY_NUM); + + int iter = 0; + while (link) { + if (hook) { + (*hook)(link, entry, iter++); + } + link = regdma_link_get_next(link, entry); + } +} + void regdma_link_stats(void *link, int entry) { - regdma_link_recursive_impl(link, entry, 0, regdma_link_update_stats_wrapper); + regdma_link_iterator(link, entry, regdma_link_update_stats_wrapper); } static void regdma_link_destroy_wrapper(void *link, int entry, int depth) @@ -700,13 +714,17 @@ void * regdma_find_prev_module_link_tail(void *link, void *tail, int entry, uint return NULL; } -#if REGDMA_LINK_DBG static __attribute__((unused)) const char *TAG = "regdma_link"; +static const char* s_link_mode_str[] = { "CONTINUOUS", "ADDR_MAP", "WRITE", "WAIT" }; +static const char* s_boolean_str[] = { "false", "true" }; static void print_info_link_data(FILE *out, const uint32_t buf[], int len) { for (int i = 0; i < len; i++) { - fprintf(out, ((i + 1) % 8) ? "%08lx " : "%08lx\n", buf[i]); + if (i % 8 == 0) { + fprintf(out, "\t\t"); + } + fprintf(out, ((i + 1) % 8) ? "%08"PRIx32" " : "%08"PRIx32"\n", buf[i]); } if (len % 8) { fprintf(out, "\n"); @@ -717,9 +735,13 @@ static void print_info_continuous_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_continuous_t *cons = __containerof(link, regdma_link_continuous_t, head); - fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p\n", - cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next, - cons->body.backup, cons->body.restore, cons->body.mem); + assert((cons->stat.module & (cons->stat.module - 1)) == 0); + fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p\n" LOG_RESET_COLOR, + __builtin_ffs(cons->stat.module) - 1, cons->stat.id, link, + s_link_mode_str[cons->head.mode], cons->head.length, s_boolean_str[cons->head.branch], s_boolean_str[cons->head.skip_r], s_boolean_str[cons->head.skip_b], s_boolean_str[cons->head.eof], + cons->body.next, + cons->body.backup, cons->body.restore, + cons->body.mem); print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length); } @@ -727,18 +749,23 @@ static void print_info_addr_map_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_addr_map_t *map = __containerof(link, regdma_link_addr_map_t, head); - fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n", - map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next, map->body.backup, - map->body.restore, map->body.mem, map->body.map[0], map->body.map[1], - map->body.map[2], map->body.map[3]); + assert((map->stat.module & (map->stat.module - 1)) == 0); + fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p, map:{%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32"}\n" LOG_RESET_COLOR, + __builtin_ffs(map->stat.module) - 1, map->stat.id, link, + s_link_mode_str[map->head.mode], map->head.length, s_boolean_str[map->head.branch], s_boolean_str[map->head.skip_r], s_boolean_str[map->head.skip_b], s_boolean_str[map->head.eof], + map->body.next, + map->body.backup, map->body.restore, + map->body.mem, map->body.map[0], map->body.map[1], map->body.map[2], map->body.map[3]); print_info_link_data(out, (const uint32_t *)map->body.mem, head.length); } static void print_info_write_wait_wrapper(FILE *out, void *link) { regdma_link_write_wait_t *ww = __containerof(link, regdma_link_write_wait_t, head); - fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, value:%lx, mask:%lx\n", - ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next, + fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, value:%"PRIx32", mask:%"PRIx32"\n" LOG_RESET_COLOR, + __builtin_ffs(ww->stat.module) - 1, ww->stat.id, link, + s_link_mode_str[ww->head.mode], ww->head.length, s_boolean_str[ww->head.branch], s_boolean_str[ww->head.skip_r], s_boolean_str[ww->head.skip_b], s_boolean_str[ww->head.eof], + ww->body.next, ww->body.backup, ww->body.value, ww->body.mask); } @@ -746,9 +773,12 @@ static void print_info_branch_continuous_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_branch_continuous_t *cons = __containerof(link, regdma_link_branch_continuous_t, head); - fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p\n", - cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next[0], cons->body.next[1], - cons->body.next[2], cons->body.next[3], cons->body.backup, cons->body.restore, + assert((cons->stat.module & (cons->stat.module - 1)) == 0); + fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p\n" LOG_RESET_COLOR, + __builtin_ffs(cons->stat.module) - 1, cons->stat.id, link, + s_link_mode_str[cons->head.mode], cons->head.length, s_boolean_str[cons->head.branch], s_boolean_str[cons->head.skip_r], s_boolean_str[cons->head.skip_b], s_boolean_str[cons->head.eof], + cons->body.next, + cons->body.backup, cons->body.restore, cons->body.mem); print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length); } @@ -757,20 +787,24 @@ static void print_info_branch_addr_map_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_branch_addr_map_t *map = __containerof(link, regdma_link_branch_addr_map_t, head); - fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n", - map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next[0], map->body.next[1], map->body.next[2], - map->body.next[3], map->body.backup, map->body.restore, map->body.mem, map->body.map[0], - map->body.map[1], map->body.map[2], map->body.map[3]); + assert((map->stat.module & (map->stat.module - 1)) == 0); + fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, restore start:%p, buff_ptr:%p, map:{%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32"}\n" LOG_RESET_COLOR, + __builtin_ffs(map->stat.module) - 1, map->stat.id, link, + s_link_mode_str[map->head.mode], map->head.length, s_boolean_str[map->head.branch], s_boolean_str[map->head.skip_r], s_boolean_str[map->head.skip_b], s_boolean_str[map->head.eof], + map->body.next, + map->body.backup, map->body.restore, + map->body.mem, map->body.map[0], map->body.map[1], map->body.map[2], map->body.map[3]); print_info_link_data(out, (const uint32_t *)map->body.mem, head.length); } static void print_info_branch_write_wait_wrapper(FILE *out, void *link) { regdma_link_branch_write_wait_t *ww = __containerof(link, regdma_link_branch_write_wait_t, head); - fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, value:%lx, mask:%lx\n", - ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next[0], ww->body.next[1], - ww->body.next[2], ww->body.next[3], ww->body.backup, ww->body.value, - ww->body.mask); + fprintf(out, LOG_COLOR_I " [%02d/%04x] link_ptr:%p, head: {mode:%s len:%d branch:%s skip_r:%s skip_b:%s eof:%s}, next:%p, backup start:%p, value:%"PRIx32", mask:%"PRIx32"\n" LOG_RESET_COLOR, + __builtin_ffs(ww->stat.module) - 1, ww->stat.id, link, + s_link_mode_str[ww->head.mode], ww->head.length, s_boolean_str[ww->head.branch], s_boolean_str[ww->head.skip_r], s_boolean_str[ww->head.skip_b], s_boolean_str[ww->head.eof], + ww->body.next, + ww->body.backup, ww->body.value, ww->body.mask); } static void print_link_info(FILE *out, void *args, int entry, int depth) @@ -808,4 +842,3 @@ void regdma_link_dump(FILE *out, void *link, int entry) fprintf(out, "This REGDMA linked list is empty!\n"); } } -#endif diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index c049ae73acc4..e30bc2038bc9 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -15,10 +15,10 @@ #include "esp_sleep.h" #include "esp_private/esp_sleep_internal.h" #include "esp_private/esp_timer_private.h" -#include "esp_private/periph_ctrl.h" #include "esp_private/rtc_clk.h" #include "esp_private/sleep_event.h" #include "esp_private/system_internal.h" +#include "esp_private/io_mux.h" #include "esp_log.h" #include "esp_newlib.h" #include "esp_timer.h" @@ -26,10 +26,21 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "soc/soc_caps.h" +#include "soc/chip_revision.h" #include "driver/rtc_io.h" +#include "hal/efuse_hal.h" #include "hal/rtc_io_hal.h" #include "hal/clk_tree_hal.h" +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND +#include "hal/systimer_ll.h" +#endif + +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND +#include "hal/mwdt_ll.h" +#include "hal/timer_ll.h" +#endif + #if SOC_PM_SUPPORT_PMU_MODEM_STATE #include "esp_private/pm_impl.h" #endif @@ -110,16 +121,6 @@ #include "esp_private/sleep_retention.h" #endif -#if SOC_LP_IO_CLOCK_IS_INDEPENDENT && !SOC_RTCIO_RCC_IS_INDEPENDENT -// For `rtcio_hal_function_select` using, clock reg option is inlined in it, -// so remove the declaration check of __DECLARE_RCC_RC_ATOMIC_ENV -#define RTCIO_RCC_ATOMIC() \ - for (int i = 1; i ? (periph_rcc_enter(), 1) : 0; \ - periph_rcc_exit(), i--) -#else -#define RTCIO_RCC_ATOMIC() -#endif - // If light sleep time is less than that, don't power down flash #define FLASH_PD_MIN_SLEEP_TIME_US 2000 @@ -216,8 +217,8 @@ typedef struct { uint32_t ext0_rtc_gpio_num : 5; #endif #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP - uint32_t gpio_wakeup_mask : 8; // 8 is the maximum RTCIO number in all chips that support GPIO wakeup - uint32_t gpio_trigger_mode : 8; + uint32_t gpio_wakeup_mask : SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT; // Only RTC_GPIO supports wakeup deepsleep + uint32_t gpio_trigger_mode : SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT; #endif uint32_t sleep_time_adjustment; uint32_t ccount_ticks_record; @@ -285,7 +286,7 @@ static void ext0_wakeup_prepare(void); static void ext1_wakeup_prepare(void); #endif static esp_err_t timer_wakeup_prepare(int64_t sleep_duration); -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if SOC_TOUCH_SENSOR_SUPPORTED && SOC_TOUCH_SENSOR_VERSION != 1 static void touch_wakeup_prepare(void); #endif #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP @@ -489,6 +490,52 @@ static void IRAM_ATTR resume_cache(void) { } } +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND +static uint32_t s_stopped_tgwdt_bmap = 0; +#endif + +// Must be called from critical sections. +static void IRAM_ATTR suspend_timers(uint32_t pd_flags) { + if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND + /* If timegroup implemented task watchdog or interrupt watchdog is running, we have to stop it. */ + for (uint32_t tg_num = 0; tg_num < SOC_TIMER_GROUPS; ++tg_num) { + if (mwdt_ll_check_if_enabled(TIMER_LL_GET_HW(tg_num))) { + mwdt_ll_write_protect_disable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_disable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_write_protect_enable(TIMER_LL_GET_HW(tg_num)); + s_stopped_tgwdt_bmap |= BIT(tg_num); + } + } +#endif +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { + systimer_ll_enable_counter(&SYSTIMER, counter_id, false); + } +#endif + } +} + +// Must be called from critical sections. +static void IRAM_ATTR resume_timers(uint32_t pd_flags) { + if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { + systimer_ll_enable_counter(&SYSTIMER, counter_id, true); + } +#endif +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND + for (uint32_t tg_num = 0; tg_num < SOC_TIMER_GROUPS; ++tg_num) { + if (s_stopped_tgwdt_bmap & BIT(tg_num)) { + mwdt_ll_write_protect_disable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_enable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_write_protect_enable(TIMER_LL_GET_HW(tg_num)); + } + } +#endif + } +} + // [refactor-todo] provide target logic for body of uart functions below static void IRAM_ATTR flush_uarts(void) { @@ -618,7 +665,7 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep) #endif } -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-6496 +#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7370 if (!(deep_sleep && s_adc_tsen_enabled)){ sar_periph_ctrl_power_disable(); @@ -629,16 +676,23 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep) /** * These save-restore workaround should be moved to lower layer */ -FORCE_INLINE_ATTR void misc_modules_wake_prepare(void) +FORCE_INLINE_ATTR void misc_modules_wake_prepare(uint32_t pd_flags) { +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + if (pd_flags & PMU_SLEEP_PD_TOP) { + // There is no driver to manage the flashboot watchdog, and it is definitely be in off state when + // the system is running, after waking up from pd_top sleep, shut it down by software here. + wdt_hal_context_t mwdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; + wdt_hal_write_protect_disable(&mwdt_ctx); + wdt_hal_set_flashboot_en(&mwdt_ctx, false); + wdt_hal_write_protect_enable(&mwdt_ctx); + } +#endif + #if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP sleep_console_usj_pad_restore(); #endif - -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-6496 sar_periph_ctrl_power_enable(); -#endif - #if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_RTCCNTL sleep_disable_cpu_retention(); #endif @@ -791,7 +845,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m misc_modules_sleep_prepare(deep_sleep); -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if SOC_TOUCH_SENSOR_VERSION >= 2 if (deep_sleep) { if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) { touch_wakeup_prepare(); @@ -806,10 +860,21 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m /* In light sleep, the RTC_PERIPH power domain should be in the power-on state (Power on the touch circuit in light sleep), * otherwise the touch sensor FSM will be cleared, causing touch sensor false triggering. */ - if (touch_ll_get_fsm_state()) { // Check if the touch sensor is working properly. +#if SOC_TOUCH_SENSOR_VERSION == 3 + bool keep_rtc_power_on = touch_ll_is_fsm_repeated_timer_enabled(); +#else + bool keep_rtc_power_on = touch_ll_get_fsm_state(); +#endif + if (keep_rtc_power_on) { // Check if the touch sensor is working properly. pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; } } +#elif CONFIG_IDF_TARGET_ESP32P4 + /* Due to esp32p4 eco0 hardware bug, if LP peripheral power domain is powerdowned in sleep, there will be a possibility of + triggering the EFUSE_CRC reset, so disable the power-down of this power domain on lightsleep for ECO0 version. */ + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { + pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; + } #endif uint32_t reject_triggers = allow_sleep_rejection ? (s_config.wakeup_triggers & RTC_SLEEP_REJECT_MASK) : 0; @@ -844,8 +909,15 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #if SOC_PMU_SUPPORTED #if SOC_DCDC_SUPPORTED - s_config.rtc_ticks_at_ldo_prepare = rtc_time_get(); - pmu_sleep_increase_ldo_volt(); +#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON + if (!deep_sleep) { + // Keep DCDC always on during light sleep, no need to adjust LDO voltage. + } else +#endif + { + s_config.rtc_ticks_at_ldo_prepare = rtc_time_get(); + pmu_sleep_increase_ldo_volt(); + } #endif pmu_sleep_config_t config; @@ -870,22 +942,17 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m } } -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND - if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { - rtc_sleep_systimer_enable(false); - } -#endif if (should_skip_sleep) { result = ESP_ERR_SLEEP_REJECT; -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE && SOC_PM_CPU_RETENTION_BY_SW +#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE && SOC_PM_CPU_RETENTION_BY_SW esp_sleep_cpu_skip_retention(); #endif } else { #if CONFIG_ESP_SLEEP_DEBUG - if (s_sleep_ctx != NULL) { - s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers; - } + if (s_sleep_ctx != NULL) { + s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers; + } #endif if (deep_sleep) { #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP @@ -913,12 +980,13 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers); #endif } else { + suspend_timers(pd_flags); /* Cache Suspend 1: will wait cache idle in cache suspend */ suspend_cache(); /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode. In order to avoid the leakage of the SPI cs pin, hold it here */ #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) -#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet +#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359 if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO)) { /* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */ gpio_ll_hold_en(&GPIO, SPI_CS0_GPIO_NUM); @@ -926,30 +994,30 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #endif #endif -#if SOC_CLK_MPLL_SUPPORTED - uint32_t mpll_freq_mhz = rtc_clk_mpll_get_freq(); - if (mpll_freq_mhz) { - rtc_clk_mpll_disable(); - } -#endif - #if SOC_DCDC_SUPPORTED - uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period); - if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) { - esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us); +#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON + if (!deep_sleep) { + // Keep DCDC always on during light sleep, no need to adjust LDO voltage. + } else +#endif + { + uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period); + if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) { + esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us); + } + pmu_sleep_shutdown_dcdc(); } - pmu_sleep_shutdown_dcdc(); #endif #if SOC_PMU_SUPPORTED -#if SOC_PM_CPU_RETENTION_BY_SW && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if SOC_PM_CPU_RETENTION_BY_SW && ESP_SLEEP_POWER_DOWN_CPU esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_GOTO_SLEEP, (void *)0); if (pd_flags & (PMU_SLEEP_PD_CPU | PMU_SLEEP_PD_TOP)) { result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); } else #endif { -#if !CONFIG_FREERTOS_UNICORE && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW +#if !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW // Skip smp retention if CPU power domain power-down is not allowed esp_sleep_cpu_skip_retention(); #endif @@ -960,16 +1028,9 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep); #endif -#if SOC_CLK_MPLL_SUPPORTED - if (mpll_freq_mhz) { - rtc_clk_mpll_enable(); - rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), mpll_freq_mhz); - } -#endif - /* Unhold the SPI CS pin */ #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) -#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet +#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359 if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO)) { gpio_ll_hold_dis(&GPIO, SPI_CS0_GPIO_NUM); } @@ -977,13 +1038,8 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #endif /* Cache Resume 1: Resume cache for continue running*/ resume_cache(); + resume_timers(pd_flags); } - -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND - if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { - rtc_sleep_systimer_enable(true); - } -#endif } #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { @@ -1011,7 +1067,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m sleep_retention_do_system_retention(false); } #endif - misc_modules_wake_prepare(); + misc_modules_wake_prepare(pd_flags); } #if SOC_SPI_MEM_SUPPORT_TIMING_TUNING @@ -1256,7 +1312,7 @@ esp_err_t esp_light_sleep_start(void) #endif #if !CONFIG_FREERTOS_UNICORE -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW +#if ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW sleep_smp_cpu_sleep_prepare(); #else esp_ipc_isr_stall_other_cpu(); @@ -1374,7 +1430,7 @@ esp_err_t esp_light_sleep_start(void) // Enter sleep, then wait for flash to be ready on wakeup err = esp_light_sleep_inner(pd_flags, flash_enable_time_us); } -#if !CONFIG_FREERTOS_UNICORE && CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW +#if !CONFIG_FREERTOS_UNICORE && ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW if (err != ESP_OK) { esp_sleep_cpu_skip_retention(); } @@ -1412,7 +1468,7 @@ esp_err_t esp_light_sleep_start(void) #if !CONFIG_FREERTOS_UNICORE esp_ipc_isr_stall_resume(); -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_SW +#if ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW sleep_smp_cpu_wakeup_prepare(); #else esp_ipc_isr_release_other_cpu(); @@ -1551,7 +1607,7 @@ static esp_err_t timer_wakeup_prepare(int64_t sleep_duration) return ESP_OK; } -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if SOC_TOUCH_SENSOR_VERSION == 2 /* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */ static void touch_wakeup_prepare(void) { @@ -1570,6 +1626,11 @@ static void touch_wakeup_prepare(void) touch_ll_start_fsm(); } } +#elif SOC_TOUCH_SENSOR_VERSION == 3 +static void touch_wakeup_prepare(void) +{ + touch_hal_prepare_deep_sleep(); +} #endif #if SOC_TOUCH_SENSOR_SUPPORTED @@ -1597,7 +1658,11 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status(void) return TOUCH_PAD_MAX; } touch_pad_t pad_num; +#if SOC_TOUCH_SENSOR_VERSION == 3 + touch_ll_sleep_get_channel_num((uint32_t *)(&pad_num)); +#else touch_hal_get_wakeup_status(&pad_num); +#endif return pad_num; } @@ -1641,10 +1706,11 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level) static void ext0_wakeup_prepare(void) { int rtc_gpio_num = s_config.ext0_rtc_gpio_num; +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT + io_mux_enable_lp_io_clock(rtc_gpio_num, true); +#endif rtcio_hal_ext0_set_wakeup_pin(rtc_gpio_num, s_config.ext0_trigger_level); - RTCIO_RCC_ATOMIC() { - rtcio_hal_function_select(rtc_gpio_num, RTCIO_LL_FUNC_RTC); - } + rtcio_hal_function_select(rtc_gpio_num, RTCIO_LL_FUNC_RTC); rtcio_hal_input_enable(rtc_gpio_num); } @@ -1773,11 +1839,12 @@ static void ext1_wakeup_prepare(void) if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) { continue; } +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT + io_mux_enable_lp_io_clock(rtc_pin, true); +#endif #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED // Route pad to RTC - RTCIO_RCC_ATOMIC() { - rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_RTC); - } + rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_RTC); // set input enable in sleep mode rtcio_hal_input_enable(rtc_pin); #if SOC_PM_SUPPORT_RTC_PERIPH_PD @@ -1792,9 +1859,7 @@ static void ext1_wakeup_prepare(void) * a pathway to EXT1. */ // Route pad to DIGITAL - RTCIO_RCC_ATOMIC() { - rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_DIGITAL); - } + rtcio_hal_function_select(rtc_pin, RTCIO_LL_FUNC_DIGITAL); // set input enable gpio_ll_input_enable(&GPIO, gpio); // hold rtc_pin to use it during sleep state @@ -2063,7 +2128,7 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_ #if SOC_PM_SUPPORT_TOP_PD FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) { bool top_pd_allowed = true; -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU top_pd_allowed &= cpu_domain_pd_allowed(); #else top_pd_allowed = false; @@ -2179,7 +2244,7 @@ static uint32_t get_power_down_flags(void) } #endif -#if SOC_PM_SUPPORT_CPU_PD +#if SOC_PM_SUPPORT_CPU_PD && ESP_SLEEP_POWER_DOWN_CPU if ((s_config.domain[ESP_PD_DOMAIN_CPU].pd_option != ESP_PD_OPTION_ON) && cpu_domain_pd_allowed()) { pd_flags |= RTC_SLEEP_PD_CPU; } @@ -2218,6 +2283,12 @@ static uint32_t get_power_down_flags(void) } #endif +#if SOC_PM_SUPPORT_CNNT_PD + if (s_config.domain[ESP_PD_DOMAIN_CNNT].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= PMU_SLEEP_PD_CNNT; + } +#endif + #if SOC_PM_SUPPORT_VDDSDIO_PD if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option != ESP_PD_OPTION_ON) { pd_flags |= RTC_SLEEP_PD_VDDSDIO; diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index c7b88c648ac7..8f7a73bf6910 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -303,7 +303,6 @@ static void sleep_retention_entries_stats(void) _lock_release_recursive(&s_retention.lock); } -#if REGDMA_LINK_DBG void sleep_retention_dump_entries(FILE *out) { _lock_acquire_recursive(&s_retention.lock); @@ -315,7 +314,6 @@ void sleep_retention_dump_entries(FILE *out) } _lock_release_recursive(&s_retention.lock); } -#endif void * sleep_retention_find_link_by_id(int id) { diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 3ba63ffafffa..97cbafd73b48 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -10,6 +10,7 @@ #include "sdkconfig.h" #include "soc/soc_caps.h" #include "soc/system_periph_retention.h" +#include "soc/uart_periph.h" #include "esp_sleep.h" #include "esp_log.h" @@ -39,31 +40,30 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_hp_system_retention_in #if SOC_APM_SUPPORTED static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init(void *arg) { +/* TBD for ESP32P4 IDF-10020. */ +#ifndef CONFIG_IDF_TARGET_ESP32P4 esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_NON_CRITICAL_TEE_APM, SLEEP_RETENTION_MODULE_SYS_PERIPH); if (err == ESP_OK) { err = sleep_retention_entries_create(tee_apm_highpri_regs_retention, ARRAY_SIZE(tee_apm_highpri_regs_retention), REGDMA_LINK_PRI_CRITICAL_TEE_APM, SLEEP_RETENTION_MODULE_SYS_PERIPH); } ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "TEE/APM"); ESP_LOGD(TAG, "TEE/APM sleep retention initialization"); +#endif return ESP_OK; } #endif -static __attribute__((unused)) esp_err_t sleep_sys_periph_uart0_retention_init(void *arg) +#if CONFIG_ESP_CONSOLE_UART +static __attribute__((unused)) esp_err_t sleep_sys_periph_stdout_console_uart_retention_init(void *arg) { - esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_HIGH, SLEEP_RETENTION_MODULE_SYS_PERIPH); + esp_err_t err = sleep_retention_entries_create(uart_reg_retention_info[CONFIG_ESP_CONSOLE_UART_NUM].regdma_entry_array, + uart_reg_retention_info[CONFIG_ESP_CONSOLE_UART_NUM].array_size, + REGDMA_LINK_PRI_SYS_PERIPH_HIGH, SLEEP_RETENTION_MODULE_SYS_PERIPH); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "UART"); - ESP_LOGD(TAG, "UART sleep retention initialization"); - return ESP_OK; -} - -static __attribute__((unused)) esp_err_t sleep_sys_periph_tg0_retention_init(void *arg) -{ - esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Timer Group"); - ESP_LOGD(TAG, "Timer Group sleep retention initialization"); + ESP_LOGD(TAG, "stdout console UART sleep retention initialization"); return ESP_OK; } +#endif static __attribute__((unused)) esp_err_t sleep_sys_periph_iomux_retention_init(void *arg) { @@ -92,7 +92,7 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_systimer_retention_ini #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE esp_err_t sleep_sys_periph_l2_cache_retention_init(void) { - esp_err_t err = sleep_retention_entries_create(l2_cache_regs_retention, ARRAY_SIZE(l2_cache_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + esp_err_t err = sleep_retention_entries_create(l2_cache_regs_retention, ARRAY_SIZE(l2_cache_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_HIGH, SLEEP_RETENTION_MODULE_SYS_PERIPH); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (L2 Cache) retention"); ESP_LOGI(TAG, "L2 Cache sleep retention initialization"); return ESP_OK; @@ -102,7 +102,7 @@ esp_err_t sleep_sys_periph_l2_cache_retention_init(void) #if SOC_PAU_IN_TOP_DOMAIN esp_err_t sleep_pau_retention_init(void) { - esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_SYS_PERIPH); + esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PAU) retention"); ESP_LOGI(TAG, "PAU sleep retention initialization"); return ESP_OK; @@ -124,10 +124,10 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a err = sleep_sys_periph_tee_apm_retention_init(arg); if(err) goto error; #endif - err = sleep_sys_periph_uart0_retention_init(arg); - if(err) goto error; - err = sleep_sys_periph_tg0_retention_init(arg); +#if CONFIG_ESP_CONSOLE_UART + err = sleep_sys_periph_stdout_console_uart_retention_init(arg); if(err) goto error; +#endif err = sleep_sys_periph_iomux_retention_init(arg); if(err) goto error; err = sleep_sys_periph_spimem_retention_init(arg); @@ -147,9 +147,7 @@ bool peripheral_domain_pd_allowed(void) #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP const uint32_t inited_modules = sleep_retention_get_inited_modules(); const uint32_t created_modules = sleep_retention_get_created_modules(); - const uint32_t mask = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); - - return ((inited_modules & mask) == (created_modules & mask)); + return (((inited_modules ^ created_modules) & TOP_DOMAIN_PERIPHERALS_BM) == 0); #else return false; #endif diff --git a/components/esp_hw_support/test_apps/.build-test-rules.yml b/components/esp_hw_support/test_apps/.build-test-rules.yml index a395b6061925..b7e85dae37c8 100644 --- a/components/esp_hw_support/test_apps/.build-test-rules.yml +++ b/components/esp_hw_support/test_apps/.build-test-rules.yml @@ -17,10 +17,6 @@ components/esp_hw_support/test_apps/dma2d: components/esp_hw_support/test_apps/esp_hw_support_unity_tests: disable: - if: SOC_GPSPI_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8972 components/esp_hw_support/test_apps/etm: disable: diff --git a/components/esp_hw_support/test_apps/dma/main/CMakeLists.txt b/components/esp_hw_support/test_apps/dma/main/CMakeLists.txt index d7baeb0936a0..643898bfb5cd 100644 --- a/components/esp_hw_support/test_apps/dma/main/CMakeLists.txt +++ b/components/esp_hw_support/test_apps/dma/main/CMakeLists.txt @@ -8,12 +8,20 @@ if(CONFIG_SOC_GDMA_SUPPORTED) list(APPEND srcs "test_gdma.c") endif() +if(CONFIG_SOC_ETM_SUPPORTED AND CONFIG_SOC_GDMA_SUPPORT_ETM) + list(APPEND srcs "test_gdma_etm.c") +endif() + if(CONFIG_SOC_DW_GDMA_SUPPORTED) list(APPEND srcs "test_dw_gdma.c") endif() +if(CONFIG_SOC_GDMA_SUPPORT_CRC) + list(APPEND srcs "test_gdma_crc.c") +endif() + # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity esp_mm + PRIV_REQUIRES unity esp_mm esp_driver_gpio WHOLE_ARCHIVE) diff --git a/components/esp_hw_support/test_apps/dma/main/test_async_memcpy.c b/components/esp_hw_support/test_apps/dma/main/test_async_memcpy.c index 8a166b3be6a8..7d706491e769 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_async_memcpy.c +++ b/components/esp_hw_support/test_apps/dma/main/test_async_memcpy.c @@ -26,10 +26,7 @@ #define ALIGN_DOWN(size, align) ((size) & ~((align) - 1)) #if CONFIG_IDF_TARGET_ESP32P4 -#define TEST_MEMCPY_DST_BASE_ALIGN 64 #define TEST_MEMCPY_BUFFER_SIZE_MUST_ALIGN_CACHE 1 -#else -#define TEST_MEMCPY_DST_BASE_ALIGN 4 #endif typedef struct { @@ -56,23 +53,15 @@ static void async_memcpy_setup_testbench(memcpy_testbench_context_t *test_contex uint8_t *dst_buf = NULL; uint8_t *from_addr = NULL; uint8_t *to_addr = NULL; -#if CONFIG_SPIRAM && SOC_AHB_GDMA_SUPPORT_PSRAM - if (test_context->src_in_psram) { - src_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_SPIRAM); - } else { - src_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - } - if (test_context->dst_in_psram) { - dst_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_SPIRAM); - } else { - dst_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - } -#else - src_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - dst_buf = heap_caps_aligned_alloc(test_context->align, buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); -#endif - TEST_ASSERT_NOT_NULL_MESSAGE(src_buf, "allocate source buffer failed"); - TEST_ASSERT_NOT_NULL_MESSAGE(dst_buf, "allocate destination buffer failed"); + + uint32_t mem_caps = test_context->src_in_psram ? MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_8BIT : MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT ; + src_buf = heap_caps_aligned_calloc(test_context->align, 1, buffer_size, mem_caps); + TEST_ASSERT_NOT_NULL(src_buf); + + mem_caps = test_context->dst_in_psram ? MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_8BIT : MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT ; + dst_buf = heap_caps_aligned_calloc(test_context->align, 1, buffer_size, mem_caps); + TEST_ASSERT_NOT_NULL(dst_buf); + // adding extra offset from_addr = src_buf + test_context->offset; to_addr = dst_buf; @@ -113,8 +102,11 @@ TEST_CASE("memory copy the same buffer with different content", "[async mcp]") async_memcpy_config_t config = ASYNC_MEMCPY_DEFAULT_CONFIG(); async_memcpy_handle_t driver = NULL; TEST_ESP_OK(esp_async_memcpy_install(&config, &driver)); - uint8_t *sbuf = heap_caps_aligned_alloc(TEST_MEMCPY_DST_BASE_ALIGN, 256, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - uint8_t *dbuf = heap_caps_aligned_alloc(TEST_MEMCPY_DST_BASE_ALIGN, 256, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *sbuf = heap_caps_aligned_calloc(4, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *dbuf = heap_caps_aligned_calloc(4, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(sbuf); + TEST_ASSERT_NOT_NULL(dbuf); + for (int j = 0; j < 20; j++) { TEST_ESP_OK(esp_async_memcpy(driver, dbuf, sbuf, 256, NULL, NULL)); vTaskDelay(pdMS_TO_TICKS(10)); @@ -136,7 +128,7 @@ static void test_memory_copy_one_by_one(async_memcpy_handle_t driver) { uint32_t aligned_test_buffer_size[] = {256, 512, 1024, 2048, 4096}; memcpy_testbench_context_t test_context = { - .align = TEST_MEMCPY_DST_BASE_ALIGN, + .align = 4, }; for (int i = 0; i < sizeof(aligned_test_buffer_size) / sizeof(aligned_test_buffer_size[0]); i++) { @@ -216,9 +208,10 @@ TEST_CASE("memory copy done callback", "[async mcp]") async_memcpy_handle_t driver = NULL; TEST_ESP_OK(esp_async_memcpy_install(&config, &driver)); - uint8_t *src_buf = heap_caps_aligned_alloc(TEST_MEMCPY_DST_BASE_ALIGN, 256, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - // destination address should aligned to data cache line - uint8_t *dst_buf = heap_caps_aligned_alloc(TEST_MEMCPY_DST_BASE_ALIGN, 256, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *src_buf = heap_caps_aligned_calloc(4, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *dst_buf = heap_caps_aligned_calloc(4, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(src_buf); + TEST_ASSERT_NOT_NULL(dst_buf); SemaphoreHandle_t sem = xSemaphoreCreateBinary(); TEST_ESP_OK(esp_async_memcpy(driver, dst_buf, src_buf, 256, test_async_memcpy_cb_v1, sem)); @@ -235,38 +228,39 @@ TEST_CASE("memory copy by DMA on the fly", "[async mcp]") async_memcpy_handle_t driver = NULL; TEST_ESP_OK(esp_async_memcpy_install(&config, &driver)); - uint32_t test_buffer_len[] = {512, 1024, 2048, 4096, 5011}; + uint32_t aligned_test_buffer_size[] = {512, 1024, 2048, 4096, 4608}; memcpy_testbench_context_t test_context[5] = { [0 ... 4] = { - .align = TEST_MEMCPY_DST_BASE_ALIGN, + .align = 4, } }; // Aligned case - for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) { + for (int i = 0; i < sizeof(aligned_test_buffer_size) / sizeof(aligned_test_buffer_size[0]); i++) { test_context[i].seed = i; - test_context[i].buffer_size = test_buffer_len[i]; + test_context[i].buffer_size = aligned_test_buffer_size[i]; async_memcpy_setup_testbench(&test_context[i]); } - for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) { + for (int i = 0; i < sizeof(aligned_test_buffer_size) / sizeof(aligned_test_buffer_size[0]); i++) { TEST_ESP_OK(esp_async_memcpy(driver, test_context[i].to_addr, test_context[i].from_addr, test_context[i].copy_size, NULL, NULL)); } - for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) { + for (int i = 0; i < sizeof(aligned_test_buffer_size) / sizeof(aligned_test_buffer_size[0]); i++) { async_memcpy_verify_and_clear_testbench(i, test_context[i].copy_size, test_context[i].src_buf, test_context[i].dst_buf, test_context[i].from_addr, test_context[i].to_addr); } #if !TEST_MEMCPY_BUFFER_SIZE_MUST_ALIGN_CACHE + uint32_t unaligned_test_buffer_size[] = {511, 1023, 2047, 4095, 5011}; // Non-aligned case - for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) { + for (int i = 0; i < sizeof(unaligned_test_buffer_size) / sizeof(unaligned_test_buffer_size[0]); i++) { test_context[i].seed = i; - test_context[i].buffer_size = test_buffer_len[i]; + test_context[i].buffer_size = unaligned_test_buffer_size[i]; test_context[i].offset = 3; async_memcpy_setup_testbench(&test_context[i]); } - for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) { + for (int i = 0; i < sizeof(unaligned_test_buffer_size) / sizeof(unaligned_test_buffer_size[0]); i++) { TEST_ESP_OK(esp_async_memcpy(driver, test_context[i].to_addr, test_context[i].from_addr, test_context[i].copy_size, NULL, NULL)); } - for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) { + for (int i = 0; i < sizeof(unaligned_test_buffer_size) / sizeof(unaligned_test_buffer_size[0]); i++) { async_memcpy_verify_and_clear_testbench(i, test_context[i].copy_size, test_context[i].src_buf, test_context[i].dst_buf, test_context[i].from_addr, test_context[i].to_addr); } #endif @@ -294,8 +288,7 @@ static void memcpy_performance_test(uint32_t buffer_size) async_memcpy_config_t config = ASYNC_MEMCPY_DEFAULT_CONFIG(); config.backlog = (buffer_size / DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1) * TEST_ASYNC_MEMCPY_BENCH_COUNTS; - config.sram_trans_align = 4; // at least 4 bytes aligned for SRAM transfer - config.psram_trans_align = 64; // at least 64 bytes aligned for PSRAM transfer + config.dma_burst_size = 64; // set a big burst size for performance async_memcpy_handle_t driver = NULL; int64_t elapse_us = 0; float throughput = 0.0; @@ -303,7 +296,7 @@ static void memcpy_performance_test(uint32_t buffer_size) // 1. SRAM->SRAM memcpy_testbench_context_t test_context = { - .align = config.psram_trans_align, + .align = config.dma_burst_size, .buffer_size = buffer_size, .src_in_psram = false, .dst_in_psram = false, @@ -328,7 +321,7 @@ static void memcpy_performance_test(uint32_t buffer_size) IDF_LOG_PERFORMANCE("CPU_COPY", "%.2f MB/s, dir: SRAM->SRAM, size: %zu Bytes", throughput, test_context.buffer_size); async_memcpy_verify_and_clear_testbench(test_context.seed, test_context.copy_size, test_context.src_buf, test_context.dst_buf, test_context.from_addr, test_context.to_addr); -#if CONFIG_SPIRAM && SOC_AHB_GDMA_SUPPORT_PSRAM +#if SOC_AHB_GDMA_SUPPORT_PSRAM // 2. PSRAM->PSRAM test_context.src_in_psram = true; test_context.dst_in_psram = true; diff --git a/components/esp_hw_support/test_apps/dma/main/test_dw_gdma.c b/components/esp_hw_support/test_apps/dma/main/test_dw_gdma.c index d4b2b3cf28d9..eb927a04b6a1 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_dw_gdma.c +++ b/components/esp_hw_support/test_apps/dma/main/test_dw_gdma.c @@ -56,17 +56,20 @@ TEST_CASE("DW_GDMA M2M Test: Contiguous Mode", "[DW_GDMA]") TEST_ASSERT_NOT_NULL(done_sem); printf("prepare the source and destination buffers\r\n"); - uint8_t *src_buf = heap_caps_aligned_calloc(64, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - uint8_t *dst_buf = heap_caps_aligned_calloc(64, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + size_t sram_alignment = 0; + TEST_ESP_OK(esp_cache_get_alignment(0, &sram_alignment)); + size_t alignment = MAX(sram_alignment, 8); + uint8_t *src_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *dst_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(src_buf); TEST_ASSERT_NOT_NULL(dst_buf); for (int i = 0; i < 256; i++) { src_buf[i] = i; } -#if CONFIG_IDF_TARGET_ESP32P4 - // do write-back for the source data because it's in the cache - TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); -#endif + if (sram_alignment) { + // do write-back for the source data because it's in the cache + TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + } printf("allocate a channel for memory copy\r\n"); dw_gdma_channel_static_config_t static_config = { @@ -117,10 +120,10 @@ TEST_CASE("DW_GDMA M2M Test: Contiguous Mode", "[DW_GDMA]") TEST_ASSERT_EQUAL(pdFALSE, xSemaphoreTake(done_sem, pdMS_TO_TICKS(100))); printf("check the memory copy result\r\n"); -#if CONFIG_IDF_TARGET_ESP32P4 - // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data - TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); -#endif + if (sram_alignment) { + // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data + TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); + } for (int i = 0; i < 256; i++) { TEST_ASSERT_EQUAL_UINT8(i, dst_buf[i]); } @@ -145,17 +148,20 @@ TEST_CASE("DW_GDMA M2M Test: Reload Mode", "[DW_GDMA]") TEST_ASSERT_NOT_NULL(done_sem); printf("prepare the source and destination buffers\r\n"); - uint8_t *src_buf = heap_caps_aligned_calloc(64, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - uint8_t *dst_buf = heap_caps_aligned_calloc(64, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + size_t sram_alignment = 0; + TEST_ESP_OK(esp_cache_get_alignment(0, &sram_alignment)); + size_t alignment = MAX(sram_alignment, 8); + uint8_t *src_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *dst_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(src_buf); TEST_ASSERT_NOT_NULL(dst_buf); for (int i = 0; i < 256; i++) { src_buf[i] = i; } -#if CONFIG_IDF_TARGET_ESP32P4 - // do write-back for the source data because it's in the cache - TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); -#endif + if (sram_alignment) { + // do write-back for the source data because it's in the cache + TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + } printf("allocate a channel for memory copy\r\n"); dw_gdma_channel_static_config_t static_config = { @@ -212,10 +218,10 @@ TEST_CASE("DW_GDMA M2M Test: Reload Mode", "[DW_GDMA]") TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(done_sem, pdMS_TO_TICKS(100))); printf("check the memory copy result\r\n"); -#if CONFIG_IDF_TARGET_ESP32P4 - // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data - TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); -#endif + if (sram_alignment) { + // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data + TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); + } for (int i = 0; i < 256; i++) { TEST_ASSERT_EQUAL_UINT8(i, dst_buf[i]); } @@ -264,17 +270,20 @@ TEST_CASE("DW_GDMA M2M Test: Shadow Mode", "[DW_GDMA]") TEST_ASSERT_NOT_NULL(done_sem); printf("prepare the source and destination buffers\r\n"); - uint8_t *src_buf = heap_caps_aligned_calloc(64, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - uint8_t *dst_buf = heap_caps_aligned_calloc(64, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + size_t sram_alignment = 0; + TEST_ESP_OK(esp_cache_get_alignment(0, &sram_alignment)); + size_t alignment = MAX(sram_alignment, 8); + uint8_t *src_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *dst_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(src_buf); TEST_ASSERT_NOT_NULL(dst_buf); for (int i = 0; i < 256; i++) { src_buf[i] = i; } -#if CONFIG_IDF_TARGET_ESP32P4 - // do write-back for the source data because it's in the cache - TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); -#endif + if (sram_alignment) { + // do write-back for the source data because it's in the cache + TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + } printf("allocate a channel for memory copy\r\n"); dw_gdma_channel_static_config_t static_config = { @@ -334,10 +343,10 @@ TEST_CASE("DW_GDMA M2M Test: Shadow Mode", "[DW_GDMA]") TEST_ASSERT_EQUAL_UINT8(1, user_data.count); printf("check the memory copy result\r\n"); -#if CONFIG_IDF_TARGET_ESP32P4 - // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data - TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); -#endif + if (sram_alignment) { + // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data + TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); + } for (int i = 0; i < 256; i++) { TEST_ASSERT_EQUAL_UINT8(i, dst_buf[i]); } @@ -387,17 +396,20 @@ TEST_CASE("DW_GDMA M2M Test: Link-List Mode", "[DW_GDMA]") TEST_ASSERT_NOT_NULL(done_sem); printf("prepare the source and destination buffers\r\n"); - uint8_t *src_buf = heap_caps_aligned_calloc(64, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - uint8_t *dst_buf = heap_caps_aligned_calloc(64, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + size_t sram_alignment = 0; + TEST_ESP_OK(esp_cache_get_alignment(0, &sram_alignment)); + size_t alignment = MAX(sram_alignment, 8); + uint8_t *src_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *dst_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(src_buf); TEST_ASSERT_NOT_NULL(dst_buf); for (int i = 0; i < 256; i++) { src_buf[i] = i; } -#if CONFIG_IDF_TARGET_ESP32P4 - // do write-back for the source data because it's in the cache - TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); -#endif + if (sram_alignment) { + // do write-back for the source data because it's in the cache + TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + } printf("allocate a channel for memory copy\r\n"); dw_gdma_channel_static_config_t static_config = { @@ -472,10 +484,10 @@ TEST_CASE("DW_GDMA M2M Test: Link-List Mode", "[DW_GDMA]") TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(done_sem, pdMS_TO_TICKS(1000))); printf("check the memory copy result\r\n"); -#if CONFIG_IDF_TARGET_ESP32P4 - // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data - TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); -#endif + if (sram_alignment) { + // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data + TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); + } for (int i = 0; i < 256; i++) { TEST_ASSERT_EQUAL_UINT8(i, dst_buf[i]); } @@ -504,10 +516,10 @@ TEST_CASE("DW_GDMA M2M Test: Link-List Mode", "[DW_GDMA]") TEST_ASSERT_EQUAL_UINT8(1, user_data.count); printf("check the memory copy result\r\n"); -#if CONFIG_IDF_TARGET_ESP32P4 - // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data - TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); -#endif + if (sram_alignment) { + // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data + TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); + } for (int i = 0; i < 256; i++) { TEST_ASSERT_EQUAL_UINT8(i, dst_buf[i]); } @@ -536,10 +548,10 @@ TEST_CASE("DW_GDMA M2M Test: memory set with fixed address", "[DW_GDMA]") src_buf[i] = 0; } src_buf[0] = 66; -#if CONFIG_IDF_TARGET_ESP32P4 - // do write-back for the source data because it's in the cache - TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); -#endif + if (ext_mem_alignment) { + // do write-back for the source data because it's in the cache + TEST_ESP_OK(esp_cache_msync((void *)src_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + } printf("allocate a channel for memory set\r\n"); dw_gdma_channel_static_config_t static_config = { @@ -581,10 +593,10 @@ TEST_CASE("DW_GDMA M2M Test: memory set with fixed address", "[DW_GDMA]") vTaskDelay(pdMS_TO_TICKS(100)); printf("check the memory set result\r\n"); -#if CONFIG_IDF_TARGET_ESP32P4 - // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data - TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); -#endif + if (int_mem_alignment) { + // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data + TEST_ESP_OK(esp_cache_msync((void *)dst_buf, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); + } for (int i = 0; i < 256; i++) { TEST_ASSERT_EQUAL_UINT8(66, dst_buf[i]); } diff --git a/components/esp_hw_support/test_apps/dma/main/test_gdma.c b/components/esp_hw_support/test_apps/dma/main/test_gdma.c index 6d3d909d1f85..d68d3a2ea0b0 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_gdma.c +++ b/components/esp_hw_support/test_apps/dma/main/test_gdma.c @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -16,7 +17,10 @@ #include "soc/soc_caps.h" #include "hal/gdma_ll.h" #include "hal/cache_ll.h" +#include "hal/cache_hal.h" #include "esp_cache.h" +#include "esp_memory_utils.h" +#include "soc/soc_caps.h" TEST_CASE("GDMA channel allocation", "[GDMA]") { @@ -174,90 +178,111 @@ static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handl TEST_ESP_OK(gdma_connect(tx_chan, m2m_trigger)); TEST_ESP_OK(gdma_connect(rx_chan, m2m_trigger)); - uint8_t *src_buf = heap_caps_aligned_alloc(64, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - uint8_t *dst_buf = heap_caps_aligned_alloc(64, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + // allocate the source and destination buffer from SRAM + // |--------------------------------------------------| + // | 128 bytes DMA descriptor | 128 bytes data buffer | + // |--------------------------------------------------| + size_t sram_alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + size_t alignment = MAX(sram_alignment, 8); + uint8_t *src_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *dst_buf = heap_caps_aligned_calloc(alignment, 1, 384, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(src_buf); TEST_ASSERT_NOT_NULL(dst_buf); - memset(src_buf, 0, 256); - memset(dst_buf, 0, 256); - dma_descriptor_align8_t *tx_descs = (dma_descriptor_align8_t *) src_buf; dma_descriptor_align8_t *rx_descs = (dma_descriptor_align8_t *) dst_buf; - uint8_t *src_data = src_buf + 64; - uint8_t *dst_data = dst_buf + 64; + uint8_t *src_data = src_buf + 128; + uint8_t *dst_data = dst_buf + 128; // prepare the source data for (int i = 0; i < 128; i++) { src_data[i] = i; } + if (sram_alignment) { + // do write-back for the source data because it's in the cache + TEST_ESP_OK(esp_cache_msync((void *)src_data, 128, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + } +#if SOC_DMA_CAN_ACCESS_FLASH + const char *src_string = "GDMA can fetch data from MSPI Flash"; + size_t src_string_len = strlen(src_string); + TEST_ASSERT_TRUE(esp_ptr_in_drom(src_string)); + + // Only gonna copy length = src_string_len, set the character after to be 0xFF + // So that we can check if the copied length is correct + dst_data[128 + src_string_len] = 0xFF; + if (sram_alignment) { + // do write-back for the dst data because it's in the cache + TEST_ESP_OK(esp_cache_msync((void *)dst_data, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + } +#endif -#if CONFIG_IDF_TARGET_ESP32P4 - // CPU and DMA both can write to the DMA descriptor, so if there is a cache, multiple descriptors may reside in the same cache line - // causing data inconsistency. To avoid this, we want to access the descriptor memory without the cache. - dma_descriptor_align8_t *tx_descs_noncache = (dma_descriptor_align8_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(tx_descs)); - dma_descriptor_align8_t *rx_descs_noncache = (dma_descriptor_align8_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(rx_descs)); - - tx_descs_noncache[0].buffer = src_data; - tx_descs_noncache[0].dw0.size = 64; - tx_descs_noncache[0].dw0.length = 64; - tx_descs_noncache[0].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - tx_descs_noncache[0].dw0.suc_eof = 0; - tx_descs_noncache[0].next = &tx_descs[1]; // Note, the DMA doesn't recognize a non-cacheable address, here must be the cached address - - tx_descs_noncache[1].buffer = src_data + 64; - tx_descs_noncache[1].dw0.size = 64; - tx_descs_noncache[1].dw0.length = 64; - tx_descs_noncache[1].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - tx_descs_noncache[1].dw0.suc_eof = 1; - tx_descs_noncache[1].next = NULL; - - rx_descs_noncache->buffer = dst_data; - rx_descs_noncache->dw0.size = 128; - rx_descs_noncache->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - rx_descs_noncache->dw0.suc_eof = 1; - rx_descs_noncache->next = NULL; +#ifdef CACHE_LL_L2MEM_NON_CACHE_ADDR + dma_descriptor_align8_t *tx_descs_nc = (dma_descriptor_align8_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(tx_descs)); + dma_descriptor_align8_t *rx_descs_nc = (dma_descriptor_align8_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(rx_descs)); #else - tx_descs->buffer = src_data; - tx_descs->dw0.size = 128; - tx_descs->dw0.length = 128; - tx_descs->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - tx_descs->dw0.suc_eof = 1; - tx_descs->next = NULL; - - rx_descs->buffer = dst_data; - rx_descs->dw0.size = 128; - rx_descs->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - rx_descs->next = NULL; + dma_descriptor_align8_t *tx_descs_nc = tx_descs; + dma_descriptor_align8_t *rx_descs_nc = rx_descs; #endif -#if CONFIG_IDF_TARGET_ESP32P4 - // do write-back for the source data because it's in the cache - TEST_ESP_OK(esp_cache_msync((void *)src_data, 128, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + tx_descs_nc[0].buffer = src_data; + tx_descs_nc[0].dw0.size = 64; + tx_descs_nc[0].dw0.length = 64; + tx_descs_nc[0].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + tx_descs_nc[0].dw0.suc_eof = 0; + tx_descs_nc[0].next = &tx_descs[1]; // Note, the DMA doesn't recognize a non-cacheable address, here must be the cached address + + tx_descs_nc[1].buffer = src_data + 64; + tx_descs_nc[1].dw0.size = 64; + tx_descs_nc[1].dw0.length = 64; + tx_descs_nc[1].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; +#if !SOC_DMA_CAN_ACCESS_FLASH + tx_descs_nc[1].dw0.suc_eof = 1; + tx_descs_nc[1].next = NULL; +#else + tx_descs_nc[1].dw0.suc_eof = 0; + tx_descs_nc[1].next = &tx_descs[2]; + + tx_descs_nc[2].buffer = (void *)src_string; + tx_descs_nc[2].dw0.size = src_string_len + 1; // +1 for '\0' + tx_descs_nc[2].dw0.length = src_string_len; + tx_descs_nc[2].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + tx_descs_nc[2].dw0.suc_eof = 1; + tx_descs_nc[2].next = NULL; #endif + rx_descs_nc->buffer = dst_data; + rx_descs_nc->dw0.size = 256; + rx_descs_nc->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + rx_descs_nc->dw0.suc_eof = 1; + rx_descs_nc->next = NULL; + TEST_ESP_OK(gdma_start(rx_chan, (intptr_t)rx_descs)); TEST_ESP_OK(gdma_start(tx_chan, (intptr_t)tx_descs)); xSemaphoreTake(done_sem, portMAX_DELAY); -#if CONFIG_IDF_TARGET_ESP32P4 - // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data - TEST_ESP_OK(esp_cache_msync((void *)dst_data, 128, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); -#endif + if (sram_alignment) { + // the destination data are not reflected to the cache, so do an invalidate to ask the cache load new data + TEST_ESP_OK(esp_cache_msync((void *)dst_data, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); + } // check the DMA descriptor write-back feature - TEST_ASSERT_EQUAL(DMA_DESCRIPTOR_BUFFER_OWNER_CPU, tx_descs[0].dw0.owner); - TEST_ASSERT_EQUAL(DMA_DESCRIPTOR_BUFFER_OWNER_CPU, rx_descs[0].dw0.owner); + TEST_ASSERT_EQUAL(DMA_DESCRIPTOR_BUFFER_OWNER_CPU, tx_descs_nc[0].dw0.owner); + TEST_ASSERT_EQUAL(DMA_DESCRIPTOR_BUFFER_OWNER_CPU, rx_descs_nc[0].dw0.owner); for (int i = 0; i < 128; i++) { TEST_ASSERT_EQUAL(i, dst_data[i]); } +#if SOC_DMA_CAN_ACCESS_FLASH + TEST_ASSERT_TRUE(dst_data[128 + src_string_len] == 0xFF); + dst_data[128 + src_string_len] = '\0'; + TEST_ASSERT_TRUE(strcmp(src_string, (const char *)((uint32_t)dst_data + 128)) == 0); +#endif free((void *)src_buf); free((void *)dst_buf); vSemaphoreDelete(done_sem); } -TEST_CASE("GDMA M2M Mode", "[GDMA]") +TEST_CASE("GDMA M2M Mode", "[GDMA][M2M]") { gdma_channel_handle_t tx_chan = NULL; gdma_channel_handle_t rx_chan = NULL; @@ -300,117 +325,3 @@ TEST_CASE("GDMA M2M Mode", "[GDMA]") TEST_ESP_OK(gdma_del_channel(rx_chan)); #endif // SOC_AXI_GDMA_SUPPORTED } - -#if SOC_GDMA_SUPPORT_CRC -typedef struct { - uint32_t init_value; - uint32_t crc_bit_width; - uint32_t poly_hex; - bool reverse_data_mask; - uint32_t expected_result; -} test_crc_case_t; -static test_crc_case_t crc_test_cases[] = { - // CRC8, x^8+x^2+x+1 - [0] = { - .crc_bit_width = 8, - .init_value = 0x00, - .poly_hex = 0x07, - .expected_result = 0xC6, - }, - [1] = { - .crc_bit_width = 8, - .init_value = 0x00, - .poly_hex = 0x07, - .reverse_data_mask = true, // refin = true - .expected_result = 0xDE, - }, - // CRC16, x^16+x^12+x^5+1 - [2] = { - .crc_bit_width = 16, - .init_value = 0xFFFF, - .poly_hex = 0x1021, - .expected_result = 0x5289, - }, - // CRC32, x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 - [3] = { - .crc_bit_width = 32, - .init_value = 0xFFFFFFFF, - .poly_hex = 0x04C11DB7, - .expected_result = 0x63B3E283, - } -}; - -// CRC online: https://www.lddgo.net/en/encrypt/crc -static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_num_crc_algorithm) -{ - uint32_t crc_result = 0; - const char *test_input_string = "Share::Connect::Innovate"; - size_t input_data_size = strlen(test_input_string); - printf("Calculate CRC value for string: \"%s\"\r\n", test_input_string); - - gdma_trigger_t m2m_trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_M2M, 0); - // get a free DMA trigger ID - uint32_t free_m2m_id_mask = 0; - gdma_get_free_m2m_trig_id_mask(tx_chan, &free_m2m_id_mask); - m2m_trigger.instance_id = __builtin_ctz(free_m2m_id_mask); - TEST_ESP_OK(gdma_connect(tx_chan, m2m_trigger)); - - uint8_t *src_buf = heap_caps_aligned_calloc(64, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - TEST_ASSERT_NOT_NULL(src_buf); - dma_descriptor_align8_t *tx_descs = (dma_descriptor_align8_t *) src_buf; - uint8_t *src_data = src_buf + 64; - memcpy(src_data, test_input_string, input_data_size); - - tx_descs->buffer = src_data; - tx_descs->dw0.size = 256 - 64; - tx_descs->dw0.length = input_data_size; - tx_descs->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - tx_descs->dw0.suc_eof = 1; - tx_descs->next = NULL; - -#if CONFIG_IDF_TARGET_ESP32P4 - // do write-back for the buffer because it's in the cache - Cache_WriteBack_Addr(CACHE_MAP_L1_DCACHE, (uint32_t)src_buf, 256); -#endif - - for (int i = 0; i < test_num_crc_algorithm; i++) { - gdma_crc_calculator_config_t crc_config = { - .crc_bit_width = crc_test_cases[i].crc_bit_width, - .init_value = crc_test_cases[i].init_value, - .poly_hex = crc_test_cases[i].poly_hex, - .reverse_data_mask = crc_test_cases[i].reverse_data_mask, - }; - TEST_ESP_OK(gdma_config_crc_calculator(tx_chan, &crc_config)); - TEST_ESP_OK(gdma_reset(tx_chan)); - TEST_ESP_OK(gdma_start(tx_chan, (intptr_t)tx_descs)); - // simply wait for the transfer done - vTaskDelay(pdMS_TO_TICKS(100)); - TEST_ESP_OK(gdma_crc_get_result(tx_chan, &crc_result)); - printf("CRC Result: 0x%"PRIx32"\r\n", crc_result); - TEST_ASSERT_EQUAL(crc_test_cases[i].expected_result, crc_result); - } - - free(src_buf); -} - -TEST_CASE("GDMA CRC Calculation", "[GDMA]") -{ - gdma_channel_handle_t tx_chan = NULL; - gdma_channel_alloc_config_t tx_chan_alloc_config = { - .direction = GDMA_CHANNEL_DIRECTION_TX, - }; -#if SOC_AHB_GDMA_SUPPORTED - printf("Test CRC calculation for AHB GDMA\r\n"); - TEST_ESP_OK(gdma_new_ahb_channel(&tx_chan_alloc_config, &tx_chan)); - test_gdma_crc_calculation(tx_chan, 4); - TEST_ESP_OK(gdma_del_channel(tx_chan)); -#endif // SOC_AHB_GDMA_SUPPORTED - -#if SOC_AXI_GDMA_SUPPORTED - printf("Test CRC calculation for AXI GDMA\r\n"); - TEST_ESP_OK(gdma_new_axi_channel(&tx_chan_alloc_config, &tx_chan)); - test_gdma_crc_calculation(tx_chan, 3); - TEST_ESP_OK(gdma_del_channel(tx_chan)); -#endif // SOC_AXI_GDMA_SUPPORTED -} -#endif // SOC_GDMA_SUPPORT_CRC diff --git a/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c b/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c new file mode 100644 index 000000000000..fd0e75a5fdfe --- /dev/null +++ b/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c @@ -0,0 +1,134 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "unity.h" +#include "esp_heap_caps.h" +#include "esp_memory_utils.h" +#include "esp_private/gdma.h" +#include "hal/dma_types.h" +#include "soc/soc_caps.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" +#include "esp_cache.h" + +typedef struct { + uint32_t init_value; + uint32_t crc_bit_width; + uint32_t poly_hex; + bool reverse_data_mask; + uint32_t expected_result; +} test_crc_case_t; +static test_crc_case_t crc_test_cases[] = { + // CRC8, x^8+x^2+x+1 + [0] = { + .crc_bit_width = 8, + .init_value = 0x00, + .poly_hex = 0x07, + .expected_result = 0xC6, + }, + [1] = { + .crc_bit_width = 8, + .init_value = 0x00, + .poly_hex = 0x07, + .reverse_data_mask = true, // refin = true + .expected_result = 0xDE, + }, + // CRC16, x^16+x^12+x^5+1 + [2] = { + .crc_bit_width = 16, + .init_value = 0xFFFF, + .poly_hex = 0x1021, + .expected_result = 0x5289, + }, + // CRC32, x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 + [3] = { + .crc_bit_width = 32, + .init_value = 0xFFFFFFFF, + .poly_hex = 0x04C11DB7, + .expected_result = 0x63B3E283, + } +}; + +// CRC online: https://www.lddgo.net/en/encrypt/crc +static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_num_crc_algorithm) +{ + uint32_t crc_result = 0; + const char *test_input_string = "Share::Connect::Innovate"; + size_t input_data_size = strlen(test_input_string); + // this test case also test the GDMA can fetch data from MSPI Flash + TEST_ASSERT_TRUE(esp_ptr_in_drom(test_input_string)); + printf("Calculate CRC value for string: \"%s\"\r\n", test_input_string); + + gdma_trigger_t m2m_trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_M2M, 0); + // get a free DMA trigger ID + uint32_t free_m2m_id_mask = 0; + gdma_get_free_m2m_trig_id_mask(tx_chan, &free_m2m_id_mask); + m2m_trigger.instance_id = __builtin_ctz(free_m2m_id_mask); + TEST_ESP_OK(gdma_connect(tx_chan, m2m_trigger)); + + size_t sram_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + size_t alignment = MAX(sram_cache_line_size, 8); + dma_descriptor_align8_t *tx_descs = heap_caps_aligned_calloc(alignment, 1, sizeof(dma_descriptor_align8_t), + MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(tx_descs); + + tx_descs->buffer = (void *)test_input_string; + tx_descs->dw0.size = input_data_size + 1; // +1 for '\0' + tx_descs->dw0.length = input_data_size; + tx_descs->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + tx_descs->dw0.suc_eof = 1; + tx_descs->next = NULL; + + if (sram_cache_line_size) { + // do write-back for the buffer because it's in the cache + TEST_ESP_OK(esp_cache_msync((void *)tx_descs, sizeof(dma_descriptor_align8_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED)); + } + + for (int i = 0; i < test_num_crc_algorithm; i++) { + gdma_crc_calculator_config_t crc_config = { + .crc_bit_width = crc_test_cases[i].crc_bit_width, + .init_value = crc_test_cases[i].init_value, + .poly_hex = crc_test_cases[i].poly_hex, + .reverse_data_mask = crc_test_cases[i].reverse_data_mask, + }; + TEST_ESP_OK(gdma_config_crc_calculator(tx_chan, &crc_config)); + TEST_ESP_OK(gdma_reset(tx_chan)); + TEST_ESP_OK(gdma_start(tx_chan, (intptr_t)tx_descs)); + // simply wait for the transfer done + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ESP_OK(gdma_crc_get_result(tx_chan, &crc_result)); + printf("CRC Result: 0x%"PRIx32"\r\n", crc_result); + TEST_ASSERT_EQUAL(crc_test_cases[i].expected_result, crc_result); + } + + free(tx_descs); +} + +TEST_CASE("GDMA CRC Calculation", "[GDMA][CRC]") +{ + gdma_channel_handle_t tx_chan = NULL; + gdma_channel_alloc_config_t tx_chan_alloc_config = { + .direction = GDMA_CHANNEL_DIRECTION_TX, + }; +#if SOC_AHB_GDMA_SUPPORTED + printf("Test CRC calculation for AHB GDMA\r\n"); + TEST_ESP_OK(gdma_new_ahb_channel(&tx_chan_alloc_config, &tx_chan)); + test_gdma_crc_calculation(tx_chan, 4); + TEST_ESP_OK(gdma_del_channel(tx_chan)); +#endif // SOC_AHB_GDMA_SUPPORTED + +#if SOC_AXI_GDMA_SUPPORTED + printf("Test CRC calculation for AXI GDMA\r\n"); + TEST_ESP_OK(gdma_new_axi_channel(&tx_chan_alloc_config, &tx_chan)); + test_gdma_crc_calculation(tx_chan, 3); + TEST_ESP_OK(gdma_del_channel(tx_chan)); +#endif // SOC_AXI_GDMA_SUPPORTED +} diff --git a/components/esp_hw_support/test_apps/etm/main/test_gdma_etm.c b/components/esp_hw_support/test_apps/dma/main/test_gdma_etm.c similarity index 96% rename from components/esp_hw_support/test_apps/etm/main/test_gdma_etm.c rename to components/esp_hw_support/test_apps/dma/main/test_gdma_etm.c index 3ecedea85850..51e8a7d540ba 100644 --- a/components/esp_hw_support/test_apps/etm/main/test_gdma_etm.c +++ b/components/esp_hw_support/test_apps/dma/main/test_gdma_etm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ #include "driver/gpio.h" #include "esp_async_memcpy.h" -TEST_CASE("async_memcpy_eof_event", "[etm]") +TEST_CASE("async_memcpy_eof_event", "[GDMA][ETM]") { const uint32_t output_gpio = 1; // async_memcpy done ---> ETM channel A ---> GPIO toggle diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py index a96369107b01..303f5bc685e4 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py @@ -1,11 +1,9 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8972 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt b/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt index 214712238d3c..e9207be15a13 100644 --- a/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt +++ b/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt @@ -13,10 +13,6 @@ if(CONFIG_SOC_SYSTIMER_SUPPORT_ETM) list(APPEND srcs "test_systimer_etm.c") endif() -if(CONFIG_SOC_GDMA_SUPPORT_ETM) - list(APPEND srcs "test_gdma_etm.c") -endif() - if(CONFIG_SOC_MCPWM_SUPPORT_ETM) list(APPEND srcs "test_mcpwm_etm.c") endif() diff --git a/components/esp_hw_support/test_apps/etm/main/test_gpio_etm.c b/components/esp_hw_support/test_apps/etm/main/test_gpio_etm.c index ee80ca8a4dde..cd2c0d1bcb65 100644 --- a/components/esp_hw_support/test_apps/etm/main/test_gpio_etm.c +++ b/components/esp_hw_support/test_apps/etm/main/test_gpio_etm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -81,7 +81,7 @@ TEST_CASE("gpio_etm_self_trigger", "[etm]") // delete gpio etm task without remove all bounded GPIOs should fail TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_etm_del_task(gpio_task)); // remove unrelated GPIO from the task should fail - TEST_ESP_ERR(ESP_ERR_INVALID_STATE, gpio_etm_task_rm_gpio(gpio_task, 10)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_etm_task_rm_gpio(gpio_task, 10)); // delete etm primitives TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task, output_gpio)); @@ -90,3 +90,118 @@ TEST_CASE("gpio_etm_self_trigger", "[etm]") TEST_ESP_OK(esp_etm_del_event(gpio_event)); TEST_ESP_OK(esp_etm_del_channel(etm_channel_a)); } + +TEST_CASE("gpio_etm_self_trigger_multi_action", "[etm]") +{ + // GPIO 0 pos edge event ---> GPIO 1 set level task + // GPIO 22 pos edge event ---> GPIO 1 clear level task + + const uint32_t input_gpio1 = 0; + const uint32_t input_gpio2 = 22; + const uint32_t output_gpio = 1; + printf("allocate etm channels\r\n"); + esp_etm_channel_config_t etm_config = {}; + esp_etm_channel_handle_t etm_channel_a = NULL; + esp_etm_channel_handle_t etm_channel_b = NULL; + TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_a)); + TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_b)); + + printf("allocate GPIO etm event and task\r\n"); + esp_etm_task_handle_t gpio_task_a = NULL; + esp_etm_event_handle_t gpio_event_a = NULL; + esp_etm_task_handle_t gpio_task_b = NULL; + esp_etm_event_handle_t gpio_event_b = NULL; + gpio_etm_event_config_t gpio_event_config = {}; + gpio_event_config.edges[0] = GPIO_ETM_EVENT_EDGE_POS; + TEST_ESP_OK(gpio_new_etm_event(&gpio_event_config, &gpio_event_a)); + esp_etm_event_handle_t gpio_event_c = NULL; // an extra event only used for testing binding + gpio_event_config.edges[1] = GPIO_ETM_EVENT_EDGE_ANY; + TEST_ESP_OK(gpio_new_etm_event(&gpio_event_config, &gpio_event_b, &gpio_event_c)); + gpio_etm_task_config_t gpio_task_config = {}; + gpio_task_config.actions[0] = GPIO_ETM_TASK_ACTION_CLR; + gpio_task_config.actions[1] = GPIO_ETM_TASK_ACTION_SET; + TEST_ESP_OK(gpio_new_etm_task(&gpio_task_config, &gpio_task_b, &gpio_task_a)); + + // bind GPIO to the event and task + TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_a, input_gpio1)); + TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_b, input_gpio2)); + TEST_ESP_OK(gpio_etm_task_add_gpio(gpio_task_a, output_gpio)); + TEST_ESP_OK(gpio_etm_task_add_gpio(gpio_task_b, output_gpio)); + + // try an infeasible bind of second event to a GPIO + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_etm_event_bind_gpio(gpio_event_c, input_gpio1)); + // try a feasible bind of second event to a GPIO + TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_c, input_gpio2)); + // delete the event to unbind it from the GPIO + TEST_ESP_OK(esp_etm_del_event(gpio_event_c)); + + printf("initialize gpio\r\n"); + gpio_config_t task_gpio_config = { + .intr_type = GPIO_INTR_DISABLE, + .mode = GPIO_MODE_INPUT_OUTPUT, // we want to read the GPIO value, so it should be input and output + .pin_bit_mask = 1ULL << output_gpio, + }; + TEST_ESP_OK(gpio_config(&task_gpio_config)); + // set the initial level + TEST_ESP_OK(gpio_set_level(output_gpio, 0)); + + gpio_config_t event_gpio_config = { + .intr_type = GPIO_INTR_DISABLE, + .mode = GPIO_MODE_INPUT_OUTPUT, // we want to simulate the edge signal by software, so it should be input and output + .pull_up_en = GPIO_PULLUP_ENABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .pin_bit_mask = (1ULL << input_gpio1) | (1ULL << input_gpio2), + }; + TEST_ESP_OK(gpio_config(&event_gpio_config)); + // set the initial level + TEST_ESP_OK(gpio_set_level(input_gpio1, 0)); + TEST_ESP_OK(gpio_set_level(input_gpio2, 0)); + + printf("connect event and task to the channel\r\n"); + TEST_ESP_OK(esp_etm_channel_connect(etm_channel_a, gpio_event_a, gpio_task_a)); + TEST_ESP_OK(esp_etm_channel_connect(etm_channel_b, gpio_event_b, gpio_task_b)); + + TEST_ESP_OK(esp_etm_channel_enable(etm_channel_a)); + TEST_ESP_OK(esp_etm_channel_enable(etm_channel_b)); + + // input_gpio1 pos edge ---> output_gpio level being set + TEST_ESP_OK(gpio_set_level(input_gpio1, 1)); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ASSERT_EQUAL(1, gpio_get_level(output_gpio)); + + // input_gpio1 neg edge does not affect output_gpio level + TEST_ESP_OK(gpio_set_level(input_gpio1, 0)); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ASSERT_EQUAL(1, gpio_get_level(output_gpio)); + + // input_gpio2 pos edge ---> output_gpio level being cleared + TEST_ESP_OK(gpio_set_level(input_gpio2, 1)); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ASSERT_EQUAL(0, gpio_get_level(output_gpio)); + + // input_gpio2 neg edge does not affect output_gpio level + TEST_ESP_OK(gpio_set_level(input_gpio2, 0)); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ASSERT_EQUAL(0, gpio_get_level(output_gpio)); + + // Create a new gpio etm task separately, and add it to the output_gpio should fail (the task does not belong to the same GPIO ETM task channel as gpio_task_a and gpio_task_b) + esp_etm_task_handle_t gpio_task_c = NULL; + gpio_etm_task_config_t gpio_task_config_2 = { + .action = GPIO_ETM_TASK_ACTION_TOG, + }; + TEST_ESP_OK(gpio_new_etm_task(&gpio_task_config_2, &gpio_task_c)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_etm_task_add_gpio(gpio_task_c, output_gpio)); + + // delete etm primitives + TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task_a, output_gpio)); + TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task_b, output_gpio)); + TEST_ESP_OK(esp_etm_channel_disable(etm_channel_a)); + TEST_ESP_OK(esp_etm_channel_disable(etm_channel_b)); + TEST_ESP_OK(esp_etm_del_task(gpio_task_a)); + TEST_ESP_OK(esp_etm_del_task(gpio_task_b)); + TEST_ESP_OK(esp_etm_del_task(gpio_task_c)); + TEST_ESP_OK(esp_etm_del_event(gpio_event_a)); + TEST_ESP_OK(esp_etm_del_event(gpio_event_b)); + TEST_ESP_OK(esp_etm_del_channel(etm_channel_a)); + TEST_ESP_OK(esp_etm_del_channel(etm_channel_b)); +} diff --git a/components/esp_lcd/CMakeLists.txt b/components/esp_lcd/CMakeLists.txt index b35a4becd51e..3365a205ce52 100644 --- a/components/esp_lcd/CMakeLists.txt +++ b/components/esp_lcd/CMakeLists.txt @@ -11,8 +11,8 @@ set(srcs "src/esp_lcd_common.c" "src/esp_lcd_panel_st7789.c" "src/esp_lcd_panel_ops.c") set(includes "include" "interface") -set(priv_requires "esp_mm" "esp_psram" "esp_pm" "esp_driver_spi" "esp_driver_i2s") -set(public_requires "driver" "esp_driver_gpio" "esp_driver_i2c") +set(priv_requires "esp_mm" "esp_psram" "esp_pm" "esp_driver_i2s") +set(public_requires "driver" "esp_driver_gpio" "esp_driver_i2c" "esp_driver_spi") if(CONFIG_SOC_DMA2D_SUPPORTED) list(APPEND srcs "src/esp_async_fbcpy.c") diff --git a/components/esp_lcd/Kconfig b/components/esp_lcd/Kconfig index 60cde6973cbd..1f93e5e03615 100644 --- a/components/esp_lcd/Kconfig +++ b/components/esp_lcd/Kconfig @@ -36,5 +36,20 @@ menu "LCD and Touch Panel" Only need to enable it when in your application, the DMA can't deliver data as fast as the LCD consumes it. endif # SOC_LCD_RGB_SUPPORTED + + if SOC_MIPI_DSI_SUPPORTED + config LCD_DSI_ISR_IRAM_SAFE + bool "DSI LCD ISR IRAM-Safe" + default n + select DW_GDMA_ISR_IRAM_SAFE + select DW_GDMA_CTRL_FUNC_IN_IRAM + select DW_GDMA_SETTER_FUNC_IN_IRAM + select DW_GDMA_GETTER_FUNC_IN_IRAM + help + Ensure the LCD interrupt is IRAM-Safe by allowing the interrupt handler to be + executable when the cache is disabled (e.g. SPI Flash write). + If you want the LCD driver to keep flushing the screen even when cache ops disabled, + you can enable this option. Note, this will also increase the IRAM usage. + endif # SOC_MIPI_DSI_SUPPORTED endmenu endmenu diff --git a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c index 9ecab59f6d7c..7fa3e1dc9439 100644 --- a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c +++ b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c @@ -21,6 +21,8 @@ esp_err_t esp_lcd_new_dsi_bus(const esp_lcd_dsi_bus_config_t *bus_config, esp_lc { esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE(bus_config && ret_bus, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(bus_config->num_data_lanes <= MIPI_DSI_LL_MAX_DATA_LANES, + ESP_ERR_INVALID_ARG, TAG, "invalid number of data lanes %d", bus_config->num_data_lanes); ESP_RETURN_ON_FALSE(bus_config->lane_bit_rate_mbps >= MIPI_DSI_LL_MIN_PHY_MBPS && bus_config->lane_bit_rate_mbps <= MIPI_DSI_LL_MAX_PHY_MBPS, ESP_ERR_INVALID_ARG, TAG, "invalid lane bit rate %"PRIu32, bus_config->lane_bit_rate_mbps); @@ -55,11 +57,25 @@ esp_err_t esp_lcd_new_dsi_bus(const esp_lcd_dsi_bus_config_t *bus_config, esp_lc mipi_dsi_ll_enable_phy_reference_clock(bus_id, true); } +#if CONFIG_PM_ENABLE + // When MIPI DSI is working, we don't expect the clock source would be turned off + esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP; + ret = esp_pm_lock_create(pm_lock_type, 0, "dsi_phy", &dsi_bus->pm_lock); + ESP_GOTO_ON_ERROR(ret, err, TAG, "create PM lock failed"); + // before we configure the PLL, we want the clock source to be stable + esp_pm_lock_acquire(dsi_bus->pm_lock); +#endif + + // if the number of data lanes is not assigned, fallback to the maximum number of data lanes + int num_data_lanes = bus_config->num_data_lanes; + if (num_data_lanes == 0) { + num_data_lanes = MIPI_DSI_LL_MAX_DATA_LANES; + } // initialize HAL context mipi_dsi_hal_config_t hal_config = { .bus_id = bus_id, .lane_bit_rate_mbps = bus_config->lane_bit_rate_mbps, - .num_data_lanes = bus_config->num_data_lanes, + .num_data_lanes = num_data_lanes, }; mipi_dsi_hal_init(&dsi_bus->hal, &hal_config); mipi_dsi_hal_context_t *hal = &dsi_bus->hal; @@ -75,7 +91,7 @@ esp_err_t esp_lcd_new_dsi_bus(const esp_lcd_dsi_bus_config_t *bus_config, esp_lc while (!mipi_dsi_phy_ll_is_pll_locked(hal->host)) { vTaskDelay(pdMS_TO_TICKS(1)); } - while (!mipi_dsi_phy_ll_are_lanes_stopped(hal->host)) { + while (!mipi_dsi_phy_ll_are_lanes_stopped(hal->host, num_data_lanes)) { vTaskDelay(pdMS_TO_TICKS(1)); } @@ -89,8 +105,8 @@ esp_err_t esp_lcd_new_dsi_bus(const esp_lcd_dsi_bus_config_t *bus_config, esp_lc // enable CRC reception and ECC reception, error correction, and reporting mipi_dsi_host_ll_enable_rx_crc(hal->host, true); mipi_dsi_host_ll_enable_rx_ecc(hal->host, true); - // enable sending the EoTp packet at the end of each transmission - mipi_dsi_host_ll_enable_tx_eotp(hal->host, true, true); + // enable sending the EoTp packet at the end of each transmission for HS mode + mipi_dsi_host_ll_enable_tx_eotp(hal->host, true, false); // Set the divider to get the Time Out clock, clock source is the high-speed byte clock mipi_dsi_host_ll_set_timeout_clock_division(hal->host, bus_config->lane_bit_rate_mbps / 8 / MIPI_DSI_DEFAULT_TIMEOUT_CLOCK_FREQ_MHZ); @@ -125,6 +141,10 @@ esp_err_t esp_lcd_del_dsi_bus(esp_lcd_dsi_bus_handle_t bus) DSI_RCC_ATOMIC() { mipi_dsi_ll_enable_bus_clock(bus_id, false); } + if (bus->pm_lock) { + esp_pm_lock_release(bus->pm_lock); + esp_pm_lock_delete(bus->pm_lock); + } free(bus); return ESP_OK; } diff --git a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c index 9c707920290e..e4fcdc7e5430 100644 --- a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c +++ b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" @@ -14,6 +15,7 @@ #include "esp_cache.h" #include "mipi_dsi_priv.h" #include "esp_async_fbcpy.h" +#include "esp_memory_utils.h" #include "esp_private/dw_gdma.h" #include "hal/cache_hal.h" #include "hal/cache_ll.h" @@ -30,18 +32,19 @@ struct esp_lcd_dpi_panel_t { esp_lcd_panel_t base; // Base class of generic lcd panel esp_lcd_dsi_bus_handle_t bus; // DSI bus handle uint8_t virtual_channel; // Virtual channel ID, index from 0 - uint8_t cur_fb_index; // Current frame buffer index - uint8_t num_fbs; // Number of frame buffers + uint8_t cur_fb_index; // Current frame buffer index + uint8_t num_fbs; // Number of frame buffers uint8_t *fbs[DPI_PANEL_MAX_FB_NUM]; // Frame buffers uint32_t h_pixels; // Horizontal pixels uint32_t v_pixels; // Vertical pixels - size_t frame_buffer_size; // Frame buffer size - size_t bytes_per_pixel; // Bytes per pixel + size_t fb_size; // Frame buffer size, in bytes + size_t bits_per_pixel; // Bits per pixel lcd_color_rgb_pixel_format_t pixel_format; // RGB Pixel format dw_gdma_channel_handle_t dma_chan; // DMA channel dw_gdma_link_list_handle_t link_lists[DPI_PANEL_MAX_FB_NUM]; // DMA link list esp_async_fbcpy_handle_t fbcpy_handle; // Use DMA2D to do frame buffer copy SemaphoreHandle_t draw_sem; // A semaphore used to synchronize the draw operations when DMA2D is used + esp_pm_lock_handle_t pm_lock; // Power management lock esp_lcd_dpi_panel_color_trans_done_cb_t on_color_trans_done; // Callback invoked when color data transfer has finished esp_lcd_dpi_panel_refresh_done_cb_t on_refresh_done; // Callback invoked when one refresh operation finished (kinda like a vsync end) void *user_ctx; // User context for the callback @@ -115,7 +118,7 @@ static esp_err_t dpi_panel_create_dma_link(esp_lcd_dpi_panel_t *dpi_panel) .handshake_type = DW_GDMA_HANDSHAKE_HW, .num_outstanding_requests = 2, }, - .flow_controller = DW_GDMA_FLOW_CTRL_DST, // the DSI bridge as the DMA flow controller + .flow_controller = DW_GDMA_FLOW_CTRL_SELF, // DMA as the flow controller .chan_priority = 1, }; ESP_RETURN_ON_ERROR(dw_gdma_new_channel(&dma_alloc_config, &dma_chan), TAG, "create DMA channel failed"); @@ -123,7 +126,7 @@ static esp_err_t dpi_panel_create_dma_link(esp_lcd_dpi_panel_t *dpi_panel) // create DMA link lists dw_gdma_link_list_config_t link_list_config = { - .num_items = DPI_PANEL_LLI_PER_FRAME, + .num_items = DPI_PANEL_MIN_DMA_NODES_PER_LINK, .link_type = DW_GDMA_LINKED_LIST_TYPE_SINGLY, }; for (int i = 0; i < dpi_panel->num_fbs; i++) { @@ -158,6 +161,22 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_ } ESP_RETURN_ON_FALSE(num_fbs <= DPI_PANEL_MAX_FB_NUM, ESP_ERR_INVALID_ARG, TAG, "num_fbs not within [1,%d]", DPI_PANEL_MAX_FB_NUM); + size_t bits_per_pixel = 0; + switch (panel_config->pixel_format) { + case LCD_COLOR_PIXEL_FORMAT_RGB565: + bits_per_pixel = 16; + break; + case LCD_COLOR_PIXEL_FORMAT_RGB666: + // RGB data in the memory must be constructed in 6-6-6 (18 bits) for each pixel + bits_per_pixel = 18; + break; + case LCD_COLOR_PIXEL_FORMAT_RGB888: + bits_per_pixel = 24; + break; + } + ESP_RETURN_ON_FALSE(panel_config->video_timing.h_size * panel_config->video_timing.v_size * bits_per_pixel % 8 == 0, + ESP_ERR_INVALID_ARG, TAG, "frame buffer size not aligned to byte boundary"); + int bus_id = bus->bus_id; mipi_dsi_hal_context_t *hal = &bus->hal; @@ -169,37 +188,25 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_ dpi_panel->num_fbs = num_fbs; // allocate frame buffer from PSRAM - size_t bytes_per_pixel = 0; - switch (panel_config->pixel_format) { - case LCD_COLOR_PIXEL_FORMAT_RGB565: - bytes_per_pixel = 2; - break; - case LCD_COLOR_PIXEL_FORMAT_RGB666: - bytes_per_pixel = 3; - break; - case LCD_COLOR_PIXEL_FORMAT_RGB888: - bytes_per_pixel = 3; - break; - } uint32_t cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); // DMA doesn't have requirement on the buffer alignment, but the cache does uint32_t alignment = cache_line_size; - size_t frame_buffer_size = panel_config->video_timing.h_size * panel_config->video_timing.v_size * bytes_per_pixel; + size_t fb_size = panel_config->video_timing.h_size * panel_config->video_timing.v_size * bits_per_pixel / 8; uint8_t *frame_buffer = NULL; for (int i = 0; i < num_fbs; i++) { - frame_buffer = heap_caps_aligned_calloc(alignment, 1, frame_buffer_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + frame_buffer = heap_caps_aligned_calloc(alignment, 1, fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); ESP_GOTO_ON_FALSE(frame_buffer, ESP_ERR_NO_MEM, err, TAG, "no memory for frame buffer"); dpi_panel->fbs[i] = frame_buffer; ESP_LOGD(TAG, "fb[%d] @%p", i, frame_buffer); // preset the frame buffer with black color // the frame buffer address alignment is ensured by `heap_caps_aligned_calloc` - // while the value of the frame_buffer_size may not be aligned to the cache line size + // while the value of the fb_size may not be aligned to the cache line size // but that's not a problem because the `heap_caps_aligned_calloc` internally allocated a buffer whose size is aligned up to the cache line size - ESP_GOTO_ON_ERROR(esp_cache_msync(frame_buffer, frame_buffer_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED), + ESP_GOTO_ON_ERROR(esp_cache_msync(frame_buffer, fb_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED), err, TAG, "cache write back failed"); } - dpi_panel->frame_buffer_size = frame_buffer_size; - dpi_panel->bytes_per_pixel = bytes_per_pixel; + dpi_panel->fb_size = fb_size; + dpi_panel->bits_per_pixel = bits_per_pixel; dpi_panel->h_pixels = panel_config->video_timing.h_size; dpi_panel->v_pixels = panel_config->video_timing.v_size; @@ -232,6 +239,14 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_ mipi_dsi_ll_enable_dpi_clock(bus_id, true); } +#if CONFIG_PM_ENABLE + // When MIPI DSI is working, we don't expect the clock source would be turned off + esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP; + ret = esp_pm_lock_create(pm_lock_type, 0, "dsi_dpi", &dpi_panel->pm_lock); + ESP_GOTO_ON_ERROR(ret, err, TAG, "create PM lock failed"); + esp_pm_lock_acquire(dpi_panel->pm_lock); +#endif + // create DMA resources ESP_GOTO_ON_ERROR(dpi_panel_create_dma_link(dpi_panel), err, TAG, "initialize DMA link failed"); @@ -263,10 +278,11 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_ panel_config->video_timing.vsync_back_porch, panel_config->video_timing.v_size, panel_config->video_timing.vsync_front_porch); - mipi_dsi_brg_ll_set_num_pixel_bits(hal->bridge, panel_config->video_timing.h_size * panel_config->video_timing.v_size * bytes_per_pixel * 8); + mipi_dsi_brg_ll_set_num_pixel_bits(hal->bridge, panel_config->video_timing.h_size * panel_config->video_timing.v_size * bits_per_pixel); mipi_dsi_brg_ll_set_underrun_discard_count(hal->bridge, panel_config->video_timing.h_size); - // let the DSI bridge as the DMA flow controller - mipi_dsi_brg_ll_set_flow_controller(hal->bridge, MIPI_DSI_LL_FLOW_CONTROLLER_BRIDGE); + // use the DW_GDMA as the flow controller + mipi_dsi_brg_ll_set_flow_controller(hal->bridge, MIPI_DSI_LL_FLOW_CONTROLLER_DMA); + mipi_dsi_brg_ll_set_multi_block_number(hal->bridge, DPI_PANEL_MIN_DMA_NODES_PER_LINK); mipi_dsi_brg_ll_set_burst_len(hal->bridge, 256); mipi_dsi_brg_ll_set_empty_threshold(hal->bridge, 1024 - 256); // enable DSI bridge @@ -318,6 +334,10 @@ static esp_err_t dpi_panel_del(esp_lcd_panel_t *panel) if (dpi_panel->draw_sem) { vSemaphoreDelete(dpi_panel->draw_sem); } + if (dpi_panel->pm_lock) { + esp_pm_lock_release(dpi_panel->pm_lock); + esp_pm_lock_delete(dpi_panel->pm_lock); + } free(dpi_panel); return ESP_OK; } @@ -362,7 +382,7 @@ static esp_err_t dpi_panel_init(esp_lcd_panel_t *panel) .burst_len = 16, .width = DW_GDMA_TRANS_WIDTH_64, }, - .size = dpi_panel->frame_buffer_size * 8 / 64, + .size = dpi_panel->fb_size * 8 / 64, }; for (int i = 0; i < dpi_panel->num_fbs; i++) { link_list = dpi_panel->link_lists[i]; @@ -400,18 +420,26 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int uint8_t cur_fb_index = dpi_panel->cur_fb_index; uint8_t *frame_buffer = dpi_panel->fbs[cur_fb_index]; uint8_t *draw_buffer = (uint8_t *)color_data; - size_t frame_buffer_size = dpi_panel->frame_buffer_size; - size_t bytes_per_pixel = dpi_panel->bytes_per_pixel; + size_t fb_size = dpi_panel->fb_size; + size_t bits_per_pixel = dpi_panel->bits_per_pixel; + + // clip to boundaries + int h_res = dpi_panel->h_pixels; + int v_res = dpi_panel->v_pixels; + x_start = MAX(x_start, 0); + x_end = MIN(x_end, h_res); + y_start = MAX(y_start, 0); + y_end = MIN(y_end, v_res); bool do_copy = false; uint8_t draw_buf_fb_index = 0; // check if the user draw buffer resides in any frame buffer's memory range // if so, we don't need to copy the data, just do cache write back - if (draw_buffer >= dpi_panel->fbs[0] && draw_buffer < dpi_panel->fbs[0] + frame_buffer_size) { + if (draw_buffer >= dpi_panel->fbs[0] && draw_buffer < dpi_panel->fbs[0] + fb_size) { draw_buf_fb_index = 0; - } else if (draw_buffer >= dpi_panel->fbs[1] && draw_buffer < dpi_panel->fbs[1] + frame_buffer_size) { + } else if (draw_buffer >= dpi_panel->fbs[1] && draw_buffer < dpi_panel->fbs[1] + fb_size) { draw_buf_fb_index = 1; - } else if (draw_buffer >= dpi_panel->fbs[2] && draw_buffer < dpi_panel->fbs[2] + frame_buffer_size) { + } else if (draw_buffer >= dpi_panel->fbs[2] && draw_buffer < dpi_panel->fbs[2] + fb_size) { draw_buf_fb_index = 2; } else { do_copy = true; @@ -420,8 +448,8 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int if (!do_copy) { // no copy, just do cache memory write back ESP_LOGD(TAG, "draw buffer is in frame buffer memory range, do cache write back only"); // only write back the LCD lines that updated by the draw buffer - uint8_t *cache_sync_start = dpi_panel->fbs[draw_buf_fb_index] + (y_start * dpi_panel->h_pixels) * bytes_per_pixel; - size_t cache_sync_size = (y_end - y_start) * dpi_panel->h_pixels * bytes_per_pixel; + uint8_t *cache_sync_start = dpi_panel->fbs[draw_buf_fb_index] + (y_start * dpi_panel->h_pixels) * bits_per_pixel / 8; + size_t cache_sync_size = (y_end - y_start) * dpi_panel->h_pixels * bits_per_pixel / 8; // the buffer to be flushed is still within the frame buffer, so even an unaligned address is OK esp_cache_msync(cache_sync_start, cache_sync_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); @@ -433,9 +461,9 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int } else if (!dpi_panel->fbcpy_handle) { // copy by CPU ESP_LOGD(TAG, "copy draw buffer by CPU"); const uint8_t *from = draw_buffer; - uint8_t *to = frame_buffer + (y_start * dpi_panel->h_pixels + x_start) * bytes_per_pixel; - uint32_t copy_bytes_per_line = (x_end - x_start) * bytes_per_pixel; - uint32_t bytes_per_line = bytes_per_pixel * dpi_panel->h_pixels; + uint8_t *to = frame_buffer + (y_start * dpi_panel->h_pixels + x_start) * bits_per_pixel / 8; + uint32_t copy_bytes_per_line = (x_end - x_start) * bits_per_pixel / 8; + uint32_t bytes_per_line = bits_per_pixel * dpi_panel->h_pixels / 8; // please note, we assume the user provided draw_buffer is compact, // but the destination is a sub-window of the frame buffer, so we need to skip the stride for (int y = y_start; y < y_end; y++) { @@ -443,8 +471,8 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int to += bytes_per_line; from += copy_bytes_per_line; } - uint8_t *cache_sync_start = frame_buffer + (y_start * dpi_panel->h_pixels) * bytes_per_pixel; - size_t cache_sync_size = (y_end - y_start) * dpi_panel->h_pixels * bytes_per_pixel; + uint8_t *cache_sync_start = frame_buffer + (y_start * dpi_panel->h_pixels) * bits_per_pixel / 8; + size_t cache_sync_size = (y_end - y_start) * dpi_panel->h_pixels * bits_per_pixel / 8; // the buffer to be flushed is still within the frame buffer, so even an unaligned address is OK esp_cache_msync(cache_sync_start, cache_sync_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); // invoke the trans done callback @@ -459,7 +487,7 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int // write back the user's draw buffer, so that the DMA can see the correct data // Note, the user draw buffer should be 1D array, and contiguous in memory, no stride - size_t color_data_size = (x_end - x_start) * (y_end - y_start) * bytes_per_pixel; + size_t color_data_size = (x_end - x_start) * (y_end - y_start) * bits_per_pixel / 8; esp_cache_msync(draw_buffer, color_data_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); esp_async_fbcpy_trans_desc_t fbcpy_trans_config = { @@ -515,6 +543,17 @@ esp_err_t esp_lcd_dpi_panel_register_event_callbacks(esp_lcd_panel_handle_t pane { ESP_RETURN_ON_FALSE(panel && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); esp_lcd_dpi_panel_t *dpi_panel = __containerof(panel, esp_lcd_dpi_panel_t, base); +#if CONFIG_LCD_DSI_ISR_IRAM_SAFE + if (cbs->on_color_trans_done) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_color_trans_done), ESP_ERR_INVALID_ARG, TAG, "on_color_trans_done callback not in IRAM"); + } + if (cbs->on_refresh_done) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_refresh_done), ESP_ERR_INVALID_ARG, TAG, "on_refresh_done callback not in IRAM"); + } + if (user_ctx) { + ESP_RETURN_ON_FALSE(esp_ptr_internal(user_ctx), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); + } +#endif // CONFIG_LCD_RGB_ISR_IRAM_SAFE dpi_panel->on_color_trans_done = cbs->on_color_trans_done; dpi_panel->on_refresh_done = cbs->on_refresh_done; dpi_panel->user_ctx = user_ctx; diff --git a/components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h b/components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h index bd7e50d2846a..0977468d2212 100644 --- a/components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h +++ b/components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h @@ -21,7 +21,7 @@ extern "C" { */ typedef struct { int bus_id; /*!< Select which DSI controller, index from 0 */ - uint8_t num_data_lanes; /*!< Number of data lanes */ + uint8_t num_data_lanes; /*!< Number of data lanes, if set to 0, the driver will fallback to use maximum number of lanes */ mipi_dsi_phy_clock_source_t phy_clk_src; /*!< MIPI DSI PHY clock source */ uint32_t lane_bit_rate_mbps; /*!< Lane bit rate in Mbps */ } esp_lcd_dsi_bus_config_t; diff --git a/components/esp_lcd/dsi/mipi_dsi_priv.h b/components/esp_lcd/dsi/mipi_dsi_priv.h index cdf89e30e309..bb6fd2fe63c2 100644 --- a/components/esp_lcd/dsi/mipi_dsi_priv.h +++ b/components/esp_lcd/dsi/mipi_dsi_priv.h @@ -9,6 +9,7 @@ #include "hal/mipi_dsi_ll.h" #include "esp_heap_caps.h" #include "esp_private/periph_ctrl.h" +#include "esp_pm.h" #if SOC_PERIPH_CLK_CTRL_SHARED #define DSI_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() @@ -22,11 +23,14 @@ #define DSI_RCC_ATOMIC() #endif -#define DSI_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT - -#define DPI_PANEL_MAX_FB_NUM 3 // maximum number of supported frame buffers for DPI panel +#if CONFIG_LCD_DSI_ISR_IRAM_SAFE +#define DSI_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#else +#define DSI_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT +#endif -#define DPI_PANEL_LLI_PER_FRAME 1 // NOTE: we assume ONE DMA link item can carry the WHOLE image (1920*1080) +#define DPI_PANEL_MAX_FB_NUM 3 // maximum number of frame buffers that can be maintained by the driver +#define DPI_PANEL_MIN_DMA_NODES_PER_LINK 1 // NOTE: we assume 1 DMA link item can carry the WHOLE image #ifdef __cplusplus extern "C" { @@ -35,6 +39,7 @@ extern "C" { typedef struct esp_lcd_dsi_bus_t { int bus_id; mipi_dsi_hal_context_t hal; + esp_pm_lock_handle_t pm_lock; } esp_lcd_dsi_bus_t; #ifdef __cplusplus diff --git a/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v2.c b/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v2.c index e8a50d8ee44d..b32699477147 100644 --- a/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v2.c +++ b/components/esp_lcd/i2c/esp_lcd_panel_io_i2c_v2.c @@ -121,10 +121,10 @@ static esp_err_t panel_io_i2c_rx_buffer(esp_lcd_panel_io_t *io, int lcd_cmd, voi lcd_panel_io_i2c_t *i2c_panel_io = __containerof(io, lcd_panel_io_i2c_t, base); bool send_param = (lcd_cmd >= 0); - int write_size = 0; - uint8_t write_buffer[CONTROL_PHASE_LENGTH + CMD_LENGTH] = {0}; - if (send_param) { + int write_size = 0; + uint8_t write_buffer[CONTROL_PHASE_LENGTH + CMD_LENGTH] = {0}; + if (i2c_panel_io->control_phase_enabled) { write_buffer[0] = i2c_panel_io->control_phase_cmd; write_size += 1; @@ -136,9 +136,12 @@ static esp_err_t panel_io_i2c_rx_buffer(esp_lcd_panel_io_t *io, int lcd_cmd, voi memcpy(write_buffer + write_size, cmds + (sizeof(cmds) - cmds_size), cmds_size); write_size += cmds_size; } + + ESP_GOTO_ON_ERROR(i2c_master_transmit_receive(i2c_panel_io->i2c_handle, write_buffer, write_size, buffer, buffer_size, -1), err, TAG, "i2c transaction failed"); + } else { + ESP_GOTO_ON_ERROR(i2c_master_receive(i2c_panel_io->i2c_handle, buffer, buffer_size, -1), err, TAG, "i2c transaction failed"); } - ESP_GOTO_ON_ERROR(i2c_master_transmit_receive(i2c_panel_io->i2c_handle, write_buffer, write_size, buffer, buffer_size, -1), err, TAG, "i2c transaction failed"); return ESP_OK; err: return ret; diff --git a/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c b/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c index 3e4e6a1323dc..68db94d8b34d 100644 --- a/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -321,6 +321,14 @@ esp_err_t esp_lcd_new_panel_io_i80(esp_lcd_i80_bus_handle_t bus, const esp_lcd_p return ret; } +void *esp_lcd_i80_alloc_draw_buffer(esp_lcd_panel_io_handle_t io, size_t size, uint32_t caps) +{ + ESP_RETURN_ON_FALSE(io, NULL, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE((caps & MALLOC_CAP_SPIRAM) == 0, NULL, TAG, "external memory is not supported"); + // DMA can only carry internal memory + return heap_caps_aligned_calloc(4, 1, size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); +} + static esp_err_t panel_io_i80_del(esp_lcd_panel_io_t *io) { lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base); diff --git a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c index 5f2911e5737c..8e7e50ed6f0f 100644 --- a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,10 +27,9 @@ #include "soc/soc_caps.h" #include "esp_clk_tree.h" #include "esp_memory_utils.h" +#include "esp_cache.h" #include "hal/dma_types.h" #include "hal/gpio_hal.h" -#include "hal/cache_hal.h" -#include "hal/cache_ll.h" #include "esp_private/gdma.h" #include "driver/gpio.h" #include "esp_private/periph_ctrl.h" @@ -38,7 +37,6 @@ #include "soc/lcd_periph.h" #include "hal/lcd_ll.h" #include "hal/lcd_hal.h" -#include "esp_cache.h" #define ALIGN_UP(size, align) (((size) + (align) - 1) & ~((align) - 1)) #define ALIGN_DOWN(size, align) ((size) & ~((align) - 1)) @@ -52,7 +50,7 @@ typedef struct lcd_i80_trans_descriptor_t lcd_i80_trans_descriptor_t; static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, const void *param, size_t param_size); static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, const void *color, size_t color_size); static esp_err_t panel_io_i80_del(esp_lcd_panel_io_t *io); -static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus); +static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config); static void lcd_periph_trigger_quick_trans_done_event(esp_lcd_i80_bus_handle_t bus); static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_clock_source_t clk_src); static esp_err_t lcd_i80_bus_configure_gpio(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config); @@ -72,8 +70,8 @@ struct esp_lcd_i80_bus_t { uint8_t *format_buffer; // The driver allocates an internal buffer for DMA to do data format transformer size_t resolution_hz; // LCD_CLK resolution, determined by selected clock source gdma_channel_handle_t dma_chan; // DMA channel handle - size_t psram_trans_align; // DMA transfer alignment for data allocated from PSRAM - size_t sram_trans_align; // DMA transfer alignment for data allocated from SRAM + size_t int_mem_align; // Alignment for internal memory + size_t ext_mem_align; // Alignment for external memory lcd_i80_trans_descriptor_t *cur_trans; // Current transaction lcd_panel_io_i80_t *cur_device; // Current working device LIST_HEAD(i80_device_list, lcd_panel_io_i80_t) device_list; // Head of i80 device list @@ -175,10 +173,8 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc lcd_ll_enable_interrupt(bus->hal.dev, LCD_LL_EVENT_TRANS_DONE, false); // disable all interrupts lcd_ll_clear_interrupt_status(bus->hal.dev, UINT32_MAX); // clear pending interrupt // install DMA service - bus->psram_trans_align = bus_config->psram_trans_align; - bus->sram_trans_align = bus_config->sram_trans_align; bus->bus_width = bus_config->bus_width; - ret = lcd_i80_init_dma_link(bus); + ret = lcd_i80_init_dma_link(bus, bus_config); ESP_GOTO_ON_ERROR(ret, err, TAG, "install DMA failed"); // disable RGB-LCD mode lcd_ll_enable_rgb_mode(bus->hal.dev, false); @@ -481,6 +477,18 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons esp_lcd_i80_bus_t *bus = i80_device->bus; lcd_i80_trans_descriptor_t *trans_desc = NULL; assert(color_size <= (bus->num_dma_nodes * DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "color bytes too long, enlarge max_transfer_bytes"); + if (esp_ptr_external_ram(color)) { + // check alignment + ESP_RETURN_ON_FALSE(((uint32_t)color & (bus->ext_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color address not aligned"); + ESP_RETURN_ON_FALSE((color_size & (bus->ext_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color size not aligned"); + // flush frame buffer from cache to the physical PSRAM + esp_cache_msync((void *)color, color_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); + } else { + // check alignment + ESP_RETURN_ON_FALSE(((uint32_t)color & (bus->int_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color address not aligned"); + ESP_RETURN_ON_FALSE((color_size & (bus->int_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color size not aligned"); + } + // in case bus_width=16 and cmd_bits=8, we still need 1 cmd_cycle uint32_t cmd_cycles = i80_device->lcd_cmd_bits / bus->bus_width; if (cmd_cycles * bus->bus_width < i80_device->lcd_cmd_bits) { @@ -503,13 +511,6 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons trans_desc->trans_done_cb = i80_device->on_color_trans_done; trans_desc->user_ctx = i80_device->user_ctx; - if (esp_ptr_external_ram(color)) { - uint32_t dcache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); - // flush frame buffer from cache to the physical PSRAM - // note the esp_cache_msync function will check the alignment of the address and size, make sure they're aligned to current cache line size - esp_cache_msync((void *)ALIGN_DOWN((intptr_t)color, dcache_line_size), ALIGN_UP(color_size, dcache_line_size), 0); - } - // send transaction to trans_queue xQueueSend(i80_device->trans_queue, &trans_desc, portMAX_DELAY); i80_device->num_trans_inflight++; @@ -542,7 +543,7 @@ static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c return ESP_OK; } -static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus) +static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config) { esp_err_t ret = ESP_OK; // chain DMA descriptors @@ -567,12 +568,13 @@ static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus) .owner_check = true }; gdma_apply_strategy(bus->dma_chan, &strategy_config); - // set DMA transfer ability - gdma_transfer_ability_t ability = { - .psram_trans_align = bus->psram_trans_align, - .sram_trans_align = bus->sram_trans_align, + // config DMA transfer parameters + gdma_transfer_config_t trans_cfg = { + .max_data_burst_size = bus_config->dma_burst_size ? bus_config->dma_burst_size : 16, // Enable DMA burst transfer for better performance + .access_ext_mem = true, // the LCD can carry pixel buffer from the external memory }; - gdma_set_transfer_ability(bus->dma_chan, &ability); + ESP_GOTO_ON_ERROR(gdma_config_transfer(bus->dma_chan, &trans_cfg), err, TAG, "config DMA transfer failed"); + gdma_get_alignment_constraints(bus->dma_chan, &bus->int_mem_align, &bus->ext_mem_align); return ESP_OK; err: if (bus->dma_chan) { @@ -581,6 +583,21 @@ static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus) return ret; } +void *esp_lcd_i80_alloc_draw_buffer(esp_lcd_panel_io_handle_t io, size_t size, uint32_t caps) +{ + ESP_RETURN_ON_FALSE(io, NULL, TAG, "invalid argument"); + lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base); + esp_lcd_i80_bus_t *bus = i80_device->bus; + void *buf = NULL; + // alloc from external memory + if (caps & MALLOC_CAP_SPIRAM) { + buf = heap_caps_aligned_calloc(bus->ext_mem_align, 1, size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); + } else { + buf = heap_caps_aligned_calloc(bus->int_mem_align, 1, size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + } + return buf; +} + static esp_err_t lcd_i80_bus_configure_gpio(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config) { int bus_id = bus->bus_id; diff --git a/components/esp_lcd/include/esp_lcd_io_i2c.h b/components/esp_lcd/include/esp_lcd_io_i2c.h new file mode 100644 index 000000000000..7d1b0fc02c95 --- /dev/null +++ b/components/esp_lcd/include/esp_lcd_io_i2c.h @@ -0,0 +1,122 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "esp_lcd_types.h" +#include "driver/i2c_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint32_t esp_lcd_i2c_bus_handle_t; /*!< Type of LCD I2C bus handle */ + +/** + * @brief Panel IO configuration structure, for I2C interface + * + */ +typedef struct { + uint32_t dev_addr; /*!< I2C device address */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ + size_t control_phase_bytes; /*!< I2C LCD panel will encode control information (e.g. D/C selection) into control phase, in several bytes */ + unsigned int dc_bit_offset; /*!< Offset of the D/C selection bit in control phase */ + int lcd_cmd_bits; /*!< Bit-width of LCD command */ + int lcd_param_bits; /*!< Bit-width of LCD parameter */ + struct { + unsigned int dc_low_on_data: 1; /*!< If this flag is enabled, DC line = 0 means transfer data, DC line = 1 means transfer command; vice versa */ + unsigned int disable_control_phase: 1; /*!< If this flag is enabled, the control phase isn't used */ + } flags; /*!< Extra flags to fine-tune the I2C device */ + uint32_t scl_speed_hz; /*!< I2C LCD SCL frequency (hz) */ +} esp_lcd_panel_io_i2c_config_t; + +/** + * @brief Create LCD panel IO handle, for I2C interface in legacy implementation + * + * @param[in] bus I2C bus handle, (in uint32_t) + * @param[in] io_config IO configuration, for I2C interface + * @param[out] ret_io Returned IO handle + * + * @note Please don't call this function in your project directly. Please call `esp_lcd_new_panel_to_i2c` instead. + * + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NO_MEM if out of memory + * - ESP_OK on success + */ +esp_err_t esp_lcd_new_panel_io_i2c_v1(uint32_t bus, const esp_lcd_panel_io_i2c_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io); + +/** + * @brief Create LCD panel IO handle, for I2C interface in new implementation + * + * @param[in] bus I2C bus handle, (in i2c_master_dev_handle_t) + * @param[in] io_config IO configuration, for I2C interface + * @param[out] ret_io Returned IO handle + * + * @note Please don't call this function in your project directly. Please call `esp_lcd_new_panel_to_i2c` instead. + * + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NO_MEM if out of memory + * - ESP_OK on success + */ +esp_err_t esp_lcd_new_panel_io_i2c_v2(i2c_master_bus_handle_t bus, const esp_lcd_panel_io_i2c_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +/** + * @brief Create LCD panel IO handle + * + * @param[in] bus I2C bus ID, indicates which I2C port to use + * @param[in] io_config IO configuration, for I2C interface + * @param[out] ret_io Returned IO handle + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NO_MEM if out of memory + * - ESP_OK on success + */ +static inline void esp_lcd_new_panel_io_i2c(uint32_t bus, const esp_lcd_panel_io_i2c_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io) +{ + esp_lcd_new_panel_io_i2c_v1(bus, io_config, ret_io); +} + +/** + * @brief Create LCD panel IO handle + * + * @param[in] bus I2C bus handle, returned from `i2c_new_master_bus` + * @param[in] io_config IO configuration, for I2C interface + * @param[out] ret_io Returned IO handle + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NO_MEM if out of memory + * - ESP_OK on success + */ +static inline void esp_lcd_new_panel_io_i2c(i2c_master_bus_handle_t bus, const esp_lcd_panel_io_i2c_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io) +{ + esp_lcd_new_panel_io_i2c_v2(bus, io_config, ret_io); +} +#else +/** + * @brief Create LCD panel IO handle + * + * @param[in] bus I2C bus handle + * @param[in] io_config IO configuration, for I2C interface + * @param[out] ret_io Returned IO handle + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NO_MEM if out of memory + * - ESP_OK on success + */ +#define esp_lcd_new_panel_io_i2c(bus, io_config, ret_io) _Generic((bus), \ + i2c_master_bus_handle_t : esp_lcd_new_panel_io_i2c_v2, \ + default : esp_lcd_new_panel_io_i2c_v1) (bus, io_config, ret_io) + +#endif diff --git a/components/esp_lcd/include/esp_lcd_io_i80.h b/components/esp_lcd/include/esp_lcd_io_i80.h new file mode 100644 index 000000000000..7b6bd90422f1 --- /dev/null +++ b/components/esp_lcd/include/esp_lcd_io_i80.h @@ -0,0 +1,119 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "esp_lcd_types.h" +#include "soc/soc_caps.h" + +#define ESP_LCD_I80_BUS_WIDTH_MAX 16 /*!< Maximum width of I80 bus */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct esp_lcd_i80_bus_t *esp_lcd_i80_bus_handle_t; /*!< Type of LCD intel 8080 bus handle */ + +#if SOC_LCD_I80_SUPPORTED +/** + * @brief LCD Intel 8080 bus configuration structure + */ +typedef struct { + int dc_gpio_num; /*!< GPIO used for D/C line */ + int wr_gpio_num; /*!< GPIO used for WR line */ + lcd_clock_source_t clk_src; /*!< Clock source for the I80 LCD peripheral */ + int data_gpio_nums[ESP_LCD_I80_BUS_WIDTH_MAX]; /*!< GPIOs used for data lines */ + size_t bus_width; /*!< Number of data lines, 8 or 16 */ + size_t max_transfer_bytes; /*!< Maximum transfer size, this determines the length of internal DMA link */ + union { + size_t psram_trans_align; /*!< DMA transfer alignment for data allocated from PSRAM */ + size_t dma_burst_size; /*!< DMA burst size, in bytes */ + }; + size_t sram_trans_align __attribute__((deprecated)); /*!< DMA transfer alignment for data allocated from SRAM */ +} esp_lcd_i80_bus_config_t; + +/** + * @brief Create Intel 8080 bus handle + * + * @param[in] bus_config Bus configuration + * @param[out] ret_bus Returned bus handle + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NO_MEM if out of memory + * - ESP_ERR_NOT_FOUND if no free bus is available + * - ESP_OK on success + */ +esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lcd_i80_bus_handle_t *ret_bus); + +/** + * @brief Destroy Intel 8080 bus handle + * + * @param[in] bus Intel 8080 bus handle, created by `esp_lcd_new_i80_bus()` + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_INVALID_STATE if there still be some device attached to the bus + * - ESP_OK on success + */ +esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus); + +/** + * @brief Panel IO configuration structure, for intel 8080 interface + */ +typedef struct { + int cs_gpio_num; /*!< GPIO used for CS line, set to -1 will declaim exclusively use of I80 bus */ + uint32_t pclk_hz; /*!< Frequency of pixel clock */ + size_t trans_queue_depth; /*!< Transaction queue size, larger queue, higher throughput */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data was transferred done */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ + int lcd_cmd_bits; /*!< Bit-width of LCD command */ + int lcd_param_bits; /*!< Bit-width of LCD parameter */ + struct { + unsigned int dc_idle_level: 1; /*!< Level of DC line in IDLE phase */ + unsigned int dc_cmd_level: 1; /*!< Level of DC line in CMD phase */ + unsigned int dc_dummy_level: 1; /*!< Level of DC line in DUMMY phase */ + unsigned int dc_data_level: 1; /*!< Level of DC line in DATA phase */ + } dc_levels; /*!< Each i80 device might have its own D/C control logic */ + struct { + unsigned int cs_active_high: 1; /*!< If set, a high level of CS line will select the device, otherwise, CS line is low level active */ + unsigned int reverse_color_bits: 1; /*!< Reverse the data bits, D[N:0] -> D[0:N] */ + unsigned int swap_color_bytes: 1; /*!< Swap adjacent two color bytes */ + unsigned int pclk_active_neg: 1; /*!< The display will write data lines when there's a falling edge on WR signal (a.k.a the PCLK) */ + unsigned int pclk_idle_low: 1; /*!< The WR signal (a.k.a the PCLK) stays at low level in IDLE phase */ + } flags; /*!< Panel IO config flags */ +} esp_lcd_panel_io_i80_config_t; + +/** + * @brief Create LCD panel IO, for Intel 8080 interface + * + * @param[in] bus Intel 8080 bus handle, created by `esp_lcd_new_i80_bus()` + * @param[in] io_config IO configuration, for i80 interface + * @param[out] ret_io Returned panel IO handle + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NOT_SUPPORTED if some configuration can't be satisfied, e.g. pixel clock out of the range + * - ESP_ERR_NO_MEM if out of memory + * - ESP_OK on success + */ +esp_err_t esp_lcd_new_panel_io_i80(esp_lcd_i80_bus_handle_t bus, const esp_lcd_panel_io_i80_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io); + +/** + * @brief Allocate a draw buffer that can be used by I80 interfaced LCD panel + * + * @note This function differs from the normal 'heap_caps_*' functions in that it can also automatically handle the alignment required by DMA burst, cache line size, etc. + * + * @param[in] io Panel IO handle, created by `esp_lcd_new_panel_io_i80()` + * @param[in] size Size of memory to be allocated + * @param[in] caps Bitwise OR of MALLOC_CAP_* flags indicating the type of memory desired for the allocation + * @return Pointer to a new buffer of size 'size' with capabilities 'caps', or NULL if allocation failed + */ +void *esp_lcd_i80_alloc_draw_buffer(esp_lcd_panel_io_handle_t io, size_t size, uint32_t caps); + +#endif // SOC_LCD_I80_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_lcd/include/esp_lcd_io_spi.h b/components/esp_lcd/include/esp_lcd_io_spi.h new file mode 100644 index 000000000000..43e1f571295e --- /dev/null +++ b/components/esp_lcd/include/esp_lcd_io_spi.h @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "esp_lcd_types.h" +#include "driver/spi_master.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int esp_lcd_spi_bus_handle_t; /*!< Type of LCD SPI bus handle */ + +/** + * @brief Panel IO configuration structure, for SPI interface + */ +typedef struct { + int cs_gpio_num; /*!< GPIO used for CS line */ + int dc_gpio_num; /*!< GPIO used to select the D/C line, set this to -1 if the D/C line is not used */ + int spi_mode; /*!< Traditional SPI mode (0~3) */ + unsigned int pclk_hz; /*!< Frequency of pixel clock */ + size_t trans_queue_depth; /*!< Size of internal transaction queue */ + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ + void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ + int lcd_cmd_bits; /*!< Bit-width of LCD command */ + int lcd_param_bits; /*!< Bit-width of LCD parameter */ + struct { + unsigned int dc_high_on_cmd: 1; /*!< If enabled, DC level = 1 indicates command transfer */ + unsigned int dc_low_on_data: 1; /*!< If enabled, DC level = 0 indicates color data transfer */ + unsigned int dc_low_on_param: 1; /*!< If enabled, DC level = 0 indicates parameter transfer */ + unsigned int octal_mode: 1; /*!< transmit with octal mode (8 data lines), this mode is used to simulate Intel 8080 timing */ + unsigned int quad_mode: 1; /*!< transmit with quad mode (4 data lines), this mode is useful when transmitting LCD parameters (Only use one line for command) */ + unsigned int sio_mode: 1; /*!< Read and write through a single data line (MOSI) */ + unsigned int lsb_first: 1; /*!< transmit LSB bit first */ + unsigned int cs_high_active: 1; /*!< CS line is high active */ + } flags; /*!< Extra flags to fine-tune the SPI device */ +} esp_lcd_panel_io_spi_config_t; + +/** + * @brief Create LCD panel IO handle, for SPI interface + * + * @param[in] bus SPI bus handle + * @param[in] io_config IO configuration, for SPI interface + * @param[out] ret_io Returned IO handle + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NO_MEM if out of memory + * - ESP_OK on success + */ +esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_panel_io_spi_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_lcd/include/esp_lcd_panel_dev.h b/components/esp_lcd/include/esp_lcd_panel_dev.h index 1a86d2b964b2..f39bdf299faa 100644 --- a/components/esp_lcd/include/esp_lcd_panel_dev.h +++ b/components/esp_lcd/include/esp_lcd_panel_dev.h @@ -20,8 +20,8 @@ extern "C" { typedef struct { int reset_gpio_num; /*!< GPIO used to reset the LCD panel, set to -1 if it's not used */ union { - lcd_rgb_element_order_t color_space; /*!< @deprecated Set RGB color space, please use rgb_ele_order instead */ - lcd_rgb_element_order_t rgb_endian; /*!< @deprecated Set RGB data endian, please use rgb_ele_order instead */ + esp_lcd_color_space_t color_space; /*!< @deprecated Set RGB color space, please use rgb_ele_order instead */ + lcd_color_rgb_endian_t rgb_endian; /*!< @deprecated Set RGB data endian, please use rgb_ele_order instead */ lcd_rgb_element_order_t rgb_ele_order; /*!< Set RGB element order, RGB or BGR */ }; lcd_rgb_data_endian_t data_endian; /*!< Set the data endian for color data larger than 1 byte */ diff --git a/components/esp_lcd/include/esp_lcd_panel_io.h b/components/esp_lcd/include/esp_lcd_panel_io.h index ffae62e68059..ee2707f4eaa4 100644 --- a/components/esp_lcd/include/esp_lcd_panel_io.h +++ b/components/esp_lcd/include/esp_lcd_panel_io.h @@ -8,44 +8,14 @@ #include #include "esp_err.h" #include "esp_lcd_types.h" -#include "soc/soc_caps.h" -#include "hal/lcd_types.h" -#include "hal/i2c_types.h" -#include "driver/i2c_types.h" - -#define ESP_LCD_I80_BUS_WIDTH_MAX 16 /*!< Maximum width of I80 bus */ +#include "esp_lcd_io_i80.h" +#include "esp_lcd_io_i2c.h" +#include "esp_lcd_io_spi.h" #ifdef __cplusplus extern "C" { #endif -typedef void *esp_lcd_spi_bus_handle_t; /*!< Type of LCD SPI bus handle */ -typedef uint32_t esp_lcd_i2c_bus_handle_t; /*!< Type of LCD I2C bus handle */ -typedef struct esp_lcd_i80_bus_t *esp_lcd_i80_bus_handle_t; /*!< Type of LCD intel 8080 bus handle */ - -/** - * @brief Type of LCD panel IO event data - */ -typedef struct { -} esp_lcd_panel_io_event_data_t; - -/** - * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data - * - * @param[in] panel_io LCD panel IO handle, which is created by factory API like `esp_lcd_new_panel_io_spi()` - * @param[in] edata Panel IO event data, fed by driver - * @param[in] user_ctx User data, passed from `esp_lcd_panel_io_xxx_config_t` - * @return Whether a high priority task has been waken up by this function - */ -typedef bool (*esp_lcd_panel_io_color_trans_done_cb_t)(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx); - -/** - * @brief Type of LCD panel IO callbacks - */ -typedef struct { - esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ -} esp_lcd_panel_io_callbacks_t; - /** * @brief Transmit LCD command and receive corresponding parameters * @@ -123,191 +93,6 @@ esp_err_t esp_lcd_panel_io_del(esp_lcd_panel_io_handle_t io); */ esp_err_t esp_lcd_panel_io_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx); -/** - * @brief Panel IO configuration structure, for SPI interface - */ -typedef struct { - int cs_gpio_num; /*!< GPIO used for CS line */ - int dc_gpio_num; /*!< GPIO used to select the D/C line, set this to -1 if the D/C line is not used */ - int spi_mode; /*!< Traditional SPI mode (0~3) */ - unsigned int pclk_hz; /*!< Frequency of pixel clock */ - size_t trans_queue_depth; /*!< Size of internal transaction queue */ - esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ - void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ - int lcd_cmd_bits; /*!< Bit-width of LCD command */ - int lcd_param_bits; /*!< Bit-width of LCD parameter */ - struct { - unsigned int dc_high_on_cmd: 1; /*!< If enabled, DC level = 1 indicates command transfer */ - unsigned int dc_low_on_data: 1; /*!< If enabled, DC level = 0 indicates color data transfer */ - unsigned int dc_low_on_param: 1; /*!< If enabled, DC level = 0 indicates parameter transfer */ - unsigned int octal_mode: 1; /*!< transmit with octal mode (8 data lines), this mode is used to simulate Intel 8080 timing */ - unsigned int quad_mode: 1; /*!< transmit with quad mode (4 data lines), this mode is useful when transmitting LCD parameters (Only use one line for command) */ - unsigned int sio_mode: 1; /*!< Read and write through a single data line (MOSI) */ - unsigned int lsb_first: 1; /*!< transmit LSB bit first */ - unsigned int cs_high_active: 1; /*!< CS line is high active */ - } flags; /*!< Extra flags to fine-tune the SPI device */ -} esp_lcd_panel_io_spi_config_t; - -/** - * @brief Create LCD panel IO handle, for SPI interface - * - * @param[in] bus SPI bus handle - * @param[in] io_config IO configuration, for SPI interface - * @param[out] ret_io Returned IO handle - * @return - * - ESP_ERR_INVALID_ARG if parameter is invalid - * - ESP_ERR_NO_MEM if out of memory - * - ESP_OK on success - */ -esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_panel_io_spi_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io); - -/** - * @brief Panel IO configuration structure, for I2C interface - * - */ -typedef struct { - uint32_t dev_addr; /*!< I2C device address */ - esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ - void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ - size_t control_phase_bytes; /*!< I2C LCD panel will encode control information (e.g. D/C selection) into control phase, in several bytes */ - unsigned int dc_bit_offset; /*!< Offset of the D/C selection bit in control phase */ - int lcd_cmd_bits; /*!< Bit-width of LCD command */ - int lcd_param_bits; /*!< Bit-width of LCD parameter */ - struct { - unsigned int dc_low_on_data: 1; /*!< If this flag is enabled, DC line = 0 means transfer data, DC line = 1 means transfer command; vice versa */ - unsigned int disable_control_phase: 1; /*!< If this flag is enabled, the control phase isn't used */ - } flags; /*!< Extra flags to fine-tune the I2C device */ - uint32_t scl_speed_hz; /*!< I2C LCD SCL frequency (hz) */ -} esp_lcd_panel_io_i2c_config_t; - -/** - * @brief Create LCD panel IO handle, for I2C interface in legacy implementation - * - * @param[in] bus I2C bus handle, (in uint32_t) - * @param[in] io_config IO configuration, for I2C interface - * @param[out] ret_io Returned IO handle - * - * @note Please don't call this function in your project directly. Please call `esp_lcd_new_panel_to_i2c` instead. - * - * @return - * - ESP_ERR_INVALID_ARG if parameter is invalid - * - ESP_ERR_NO_MEM if out of memory - * - ESP_OK on success - */ -esp_err_t esp_lcd_new_panel_io_i2c_v1(uint32_t bus, const esp_lcd_panel_io_i2c_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io); - -/** - * @brief Create LCD panel IO handle, for I2C interface in new implementation - * - * @param[in] bus I2C bus handle, (in i2c_master_dev_handle_t) - * @param[in] io_config IO configuration, for I2C interface - * @param[out] ret_io Returned IO handle - * - * @note Please don't call this function in your project directly. Please call `esp_lcd_new_panel_to_i2c` instead. - * - * @return - * - ESP_ERR_INVALID_ARG if parameter is invalid - * - ESP_ERR_NO_MEM if out of memory - * - ESP_OK on success - */ -esp_err_t esp_lcd_new_panel_io_i2c_v2(i2c_master_bus_handle_t bus, const esp_lcd_panel_io_i2c_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io); - -/** - * @brief Create LCD panel IO handle - * - * @param[in] bus I2C bus handle - * @param[in] io_config IO configuration, for I2C interface - * @param[out] ret_io Returned IO handle - * @return - * - ESP_ERR_INVALID_ARG if parameter is invalid - * - ESP_ERR_NO_MEM if out of memory - * - ESP_OK on success - */ -#define esp_lcd_new_panel_io_i2c(bus, io_config, ret_io) _Generic((bus), \ - i2c_master_bus_handle_t : esp_lcd_new_panel_io_i2c_v2, \ - default : esp_lcd_new_panel_io_i2c_v1) (bus, io_config, ret_io) \ - -#if SOC_LCD_I80_SUPPORTED -/** - * @brief LCD Intel 8080 bus configuration structure - */ -typedef struct { - int dc_gpio_num; /*!< GPIO used for D/C line */ - int wr_gpio_num; /*!< GPIO used for WR line */ - lcd_clock_source_t clk_src; /*!< Clock source for the I80 LCD peripheral */ - int data_gpio_nums[ESP_LCD_I80_BUS_WIDTH_MAX]; /*!< GPIOs used for data lines */ - size_t bus_width; /*!< Number of data lines, 8 or 16 */ - size_t max_transfer_bytes; /*!< Maximum transfer size, this determines the length of internal DMA link */ - size_t psram_trans_align; /*!< DMA transfer alignment for data allocated from PSRAM */ - size_t sram_trans_align; /*!< DMA transfer alignment for data allocated from SRAM */ -} esp_lcd_i80_bus_config_t; - -/** - * @brief Create Intel 8080 bus handle - * - * @param[in] bus_config Bus configuration - * @param[out] ret_bus Returned bus handle - * @return - * - ESP_ERR_INVALID_ARG if parameter is invalid - * - ESP_ERR_NO_MEM if out of memory - * - ESP_ERR_NOT_FOUND if no free bus is available - * - ESP_OK on success - */ -esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lcd_i80_bus_handle_t *ret_bus); - -/** - * @brief Destroy Intel 8080 bus handle - * - * @param[in] bus Intel 8080 bus handle, created by `esp_lcd_new_i80_bus()` - * @return - * - ESP_ERR_INVALID_ARG if parameter is invalid - * - ESP_ERR_INVALID_STATE if there still be some device attached to the bus - * - ESP_OK on success - */ -esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus); - -/** - * @brief Panel IO configuration structure, for intel 8080 interface - */ -typedef struct { - int cs_gpio_num; /*!< GPIO used for CS line, set to -1 will declaim exclusively use of I80 bus */ - uint32_t pclk_hz; /*!< Frequency of pixel clock */ - size_t trans_queue_depth; /*!< Transaction queue size, larger queue, higher throughput */ - esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data was transferred done */ - void *user_ctx; /*!< User private data, passed directly to on_color_trans_done's user_ctx */ - int lcd_cmd_bits; /*!< Bit-width of LCD command */ - int lcd_param_bits; /*!< Bit-width of LCD parameter */ - struct { - unsigned int dc_idle_level: 1; /*!< Level of DC line in IDLE phase */ - unsigned int dc_cmd_level: 1; /*!< Level of DC line in CMD phase */ - unsigned int dc_dummy_level: 1; /*!< Level of DC line in DUMMY phase */ - unsigned int dc_data_level: 1; /*!< Level of DC line in DATA phase */ - } dc_levels; /*!< Each i80 device might have its own D/C control logic */ - struct { - unsigned int cs_active_high: 1; /*!< If set, a high level of CS line will select the device, otherwise, CS line is low level active */ - unsigned int reverse_color_bits: 1; /*!< Reverse the data bits, D[N:0] -> D[0:N] */ - unsigned int swap_color_bytes: 1; /*!< Swap adjacent two color bytes */ - unsigned int pclk_active_neg: 1; /*!< The display will write data lines when there's a falling edge on WR signal (a.k.a the PCLK) */ - unsigned int pclk_idle_low: 1; /*!< The WR signal (a.k.a the PCLK) stays at low level in IDLE phase */ - } flags; /*!< Panel IO config flags */ -} esp_lcd_panel_io_i80_config_t; - -/** - * @brief Create LCD panel IO, for Intel 8080 interface - * - * @param[in] bus Intel 8080 bus handle, created by `esp_lcd_new_i80_bus()` - * @param[in] io_config IO configuration, for i80 interface - * @param[out] ret_io Returned panel IO handle - * @return - * - ESP_ERR_INVALID_ARG if parameter is invalid - * - ESP_ERR_NOT_SUPPORTED if some configuration can't be satisfied, e.g. pixel clock out of the range - * - ESP_ERR_NO_MEM if out of memory - * - ESP_OK on success - */ -esp_err_t esp_lcd_new_panel_io_i80(esp_lcd_i80_bus_handle_t bus, const esp_lcd_panel_io_i80_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io); - -#endif // SOC_LCD_I80_SUPPORTED - #ifdef __cplusplus } #endif diff --git a/components/esp_lcd/include/esp_lcd_types.h b/components/esp_lcd/include/esp_lcd_types.h index 777254010795..ca15370b93d7 100644 --- a/components/esp_lcd/include/esp_lcd_types.h +++ b/components/esp_lcd/include/esp_lcd_types.h @@ -5,6 +5,7 @@ */ #pragma once +#include #include "esp_assert.h" #include "hal/lcd_types.h" #include "hal/mipi_dsi_types.h" @@ -40,26 +41,39 @@ typedef enum { } lcd_rgb_element_order_t; /** @cond */ +/// for backward compatible +typedef lcd_rgb_element_order_t lcd_color_rgb_endian_t; +#define LCD_RGB_ENDIAN_RGB (lcd_color_rgb_endian_t)LCD_RGB_ELEMENT_ORDER_RGB +#define LCD_RGB_ENDIAN_BGR (lcd_color_rgb_endian_t)LCD_RGB_ELEMENT_ORDER_BGR + +typedef lcd_rgb_element_order_t esp_lcd_color_space_t; +#define ESP_LCD_COLOR_SPACE_RGB (esp_lcd_color_space_t)LCD_RGB_ELEMENT_ORDER_RGB +#define ESP_LCD_COLOR_SPACE_BGR (esp_lcd_color_space_t)LCD_RGB_ELEMENT_ORDER_BGR +#define ESP_LCD_COLOR_SPACE_MONOCHROME (esp_lcd_color_space_t)2 +/** @endcond */ + /** - * @brief LCD color space type definition (WRONG!) - * @deprecated RGB and BGR should belong to the same color space, but this enum take them both as two different color spaces. - * If you want to use a enum to describe a color space, please use lcd_color_space_t instead. + * @brief Type of LCD panel IO event data */ -typedef enum { - ESP_LCD_COLOR_SPACE_RGB, /*!< Color space: RGB */ - ESP_LCD_COLOR_SPACE_BGR, /*!< Color space: BGR */ - ESP_LCD_COLOR_SPACE_MONOCHROME, /*!< Color space: monochrome */ -} esp_lcd_color_space_t __attribute__((deprecated)); +typedef struct { +} esp_lcd_panel_io_event_data_t; -// Ensure binary compatibility with lcd_color_rgb_endian_t -ESP_STATIC_ASSERT((lcd_rgb_element_order_t)ESP_LCD_COLOR_SPACE_RGB == LCD_RGB_ELEMENT_ORDER_RGB, "ESP_LCD_COLOR_SPACE_RGB is not compatible with LCD_RGB_ORDER_RGB"); -ESP_STATIC_ASSERT((lcd_rgb_element_order_t)ESP_LCD_COLOR_SPACE_BGR == LCD_RGB_ELEMENT_ORDER_BGR, "ESP_LCD_COLOR_SPACE_BGR is not compatible with LCD_RGB_ORDER_BGR"); +/** + * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data + * + * @param[in] panel_io LCD panel IO handle, which is created by factory API like `esp_lcd_new_panel_io_spi()` + * @param[in] edata Panel IO event data, fed by driver + * @param[in] user_ctx User data, passed from `esp_lcd_panel_io_xxx_config_t` + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*esp_lcd_panel_io_color_trans_done_cb_t)(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx); -/// for backward compatible -typedef lcd_rgb_element_order_t lcd_color_rgb_endian_t; -#define LCD_RGB_ENDIAN_RGB LCD_RGB_ELEMENT_ORDER_RGB -#define LCD_RGB_ENDIAN_BGR LCD_RGB_ELEMENT_ORDER_BGR -/** @endcond */ +/** + * @brief Type of LCD panel IO callbacks + */ +typedef struct { + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ +} esp_lcd_panel_io_callbacks_t; #ifdef __cplusplus } diff --git a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c index 16d189e0a4cf..a12f244229dc 100644 --- a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c @@ -39,7 +39,8 @@ #include "soc/lcd_periph.h" #include "hal/lcd_hal.h" #include "hal/lcd_ll.h" -#include "hal/gdma_ll.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" #include "rom/cache.h" #include "esp_cache.h" @@ -77,7 +78,8 @@ static esp_err_t rgb_panel_swap_xy(esp_lcd_panel_t *panel, bool swap_axes); static esp_err_t rgb_panel_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap); static esp_err_t rgb_panel_disp_on_off(esp_lcd_panel_t *panel, bool off); static esp_err_t lcd_rgb_panel_select_clock_src(esp_rgb_panel_t *panel, lcd_clock_source_t clk_src); -static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel); +static esp_err_t lcd_rgb_create_dma_channel(esp_rgb_panel_t *panel); +static void lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *panel); static esp_err_t lcd_rgb_panel_configure_gpio(esp_rgb_panel_t *panel, const esp_lcd_rgb_panel_config_t *panel_config); static void lcd_rgb_panel_start_transmission(esp_rgb_panel_t *rgb_panel); static void lcd_default_isr_handler(void *args); @@ -90,8 +92,7 @@ struct esp_rgb_panel_t { size_t fb_bits_per_pixel; // Frame buffer color depth, in bpp size_t num_fbs; // Number of frame buffers size_t output_bits_per_pixel; // Color depth seen from the output data line. Default to fb_bits_per_pixel, but can be changed by YUV-RGB conversion - size_t sram_trans_align; // Alignment for framebuffer that allocated in SRAM - size_t psram_trans_align; // Alignment for framebuffer that allocated in PSRAM + size_t dma_burst_size; // DMA transfer burst size int disp_gpio_num; // Display control GPIO, which is used to perform action like "disp_off" intr_handle_t intr; // LCD peripheral interrupt handle esp_pm_lock_handle_t pm_lock; // Power management lock @@ -134,10 +135,20 @@ struct esp_rgb_panel_t { static esp_err_t lcd_rgb_panel_alloc_frame_buffers(const esp_lcd_rgb_panel_config_t *rgb_panel_config, esp_rgb_panel_t *rgb_panel) { bool fb_in_psram = false; - size_t psram_trans_align = rgb_panel_config->psram_trans_align ? rgb_panel_config->psram_trans_align : 64; - size_t sram_trans_align = rgb_panel_config->sram_trans_align ? rgb_panel_config->sram_trans_align : 4; - rgb_panel->psram_trans_align = psram_trans_align; - rgb_panel->sram_trans_align = sram_trans_align; + size_t ext_mem_align = 0; + size_t int_mem_align = 0; + gdma_get_alignment_constraints(rgb_panel->dma_chan, &int_mem_align, &ext_mem_align); + + // also take the cache line size into account when allocating the frame buffer + uint32_t ext_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); + uint32_t int_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + // The buffer must be aligned to the cache line size + if (ext_mem_cache_line_size) { + ext_mem_align = MAX(ext_mem_align, ext_mem_cache_line_size); + } + if (int_mem_cache_line_size) { + int_mem_align = MAX(int_mem_align, int_mem_cache_line_size); + } // alloc frame buffer if (rgb_panel->num_fbs > 0) { @@ -152,13 +163,13 @@ static esp_err_t lcd_rgb_panel_alloc_frame_buffers(const esp_lcd_rgb_panel_confi for (int i = 0; i < rgb_panel->num_fbs; i++) { if (fb_in_psram) { // the low level malloc function will help check the validation of alignment - rgb_panel->fbs[i] = heap_caps_aligned_calloc(psram_trans_align, 1, rgb_panel->fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + rgb_panel->fbs[i] = heap_caps_aligned_calloc(ext_mem_align, 1, rgb_panel->fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); ESP_RETURN_ON_FALSE(rgb_panel->fbs[i], ESP_ERR_NO_MEM, TAG, "no mem for frame buffer"); // calloc not only allocates but also zero's the buffer. We have to make sure this is // properly committed to the PSRAM, otherwise all sorts of visual corruption will happen. ESP_RETURN_ON_ERROR(esp_cache_msync(rgb_panel->fbs[i], rgb_panel->fb_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M), TAG, "cache write back failed"); } else { - rgb_panel->fbs[i] = heap_caps_aligned_calloc(sram_trans_align, 1, rgb_panel->fb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + rgb_panel->fbs[i] = heap_caps_aligned_calloc(int_mem_align, 1, rgb_panel->fb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); ESP_RETURN_ON_FALSE(rgb_panel->fbs[i], ESP_ERR_NO_MEM, TAG, "no mem for frame buffer"); } } @@ -168,7 +179,7 @@ static esp_err_t lcd_rgb_panel_alloc_frame_buffers(const esp_lcd_rgb_panel_confi if (rgb_panel->bb_size) { for (int i = 0; i < RGB_LCD_PANEL_BOUNCE_BUF_NUM; i++) { // bounce buffer must come from SRAM - rgb_panel->bounce_buffer[i] = heap_caps_aligned_calloc(sram_trans_align, 1, rgb_panel->bb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + rgb_panel->bounce_buffer[i] = heap_caps_aligned_calloc(int_mem_align, 1, rgb_panel->bb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); ESP_RETURN_ON_FALSE(rgb_panel->bounce_buffer[i], ESP_ERR_NO_MEM, TAG, "no mem for bounce buffer"); } } @@ -302,9 +313,6 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf } } - // allocate frame buffers + bounce buffers - ESP_GOTO_ON_ERROR(lcd_rgb_panel_alloc_frame_buffers(rgb_panel_config, rgb_panel), err, TAG, "alloc frame buffers failed"); - // initialize HAL layer, so we can call LL APIs later lcd_hal_init(&rgb_panel->hal, panel_id); // enable clock @@ -334,8 +342,13 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf // install DMA service rgb_panel->flags.stream_mode = !rgb_panel_config->flags.refresh_on_demand; rgb_panel->fb_bits_per_pixel = fb_bits_per_pixel; - ret = lcd_rgb_panel_create_trans_link(rgb_panel); - ESP_GOTO_ON_ERROR(ret, err, TAG, "install DMA failed"); + rgb_panel->dma_burst_size = rgb_panel_config->dma_burst_size ? rgb_panel_config->dma_burst_size : 64; + ESP_GOTO_ON_ERROR(lcd_rgb_create_dma_channel(rgb_panel), err, TAG, "install DMA failed"); + // allocate frame buffers + bounce buffers + ESP_GOTO_ON_ERROR(lcd_rgb_panel_alloc_frame_buffers(rgb_panel_config, rgb_panel), err, TAG, "alloc frame buffers failed"); + // initialize DMA descriptor link + lcd_rgb_panel_init_trans_link(rgb_panel); + // configure GPIO ret = lcd_rgb_panel_configure_gpio(rgb_panel, rgb_panel_config); ESP_GOTO_ON_ERROR(ret, err, TAG, "configure GPIO failed"); @@ -706,7 +719,6 @@ static esp_err_t rgb_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int { esp_rgb_panel_t *rgb_panel = __containerof(panel, esp_rgb_panel_t, base); ESP_RETURN_ON_FALSE(rgb_panel->num_fbs > 0, ESP_ERR_NOT_SUPPORTED, TAG, "no frame buffer installed"); - assert((x_start < x_end) && (y_start < y_end) && "start position must be smaller than end position"); // check if we need to copy the draw buffer (pointed by the color_data) to the driver's frame buffer bool do_copy = false; @@ -726,18 +738,19 @@ static esp_err_t rgb_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start += rgb_panel->y_gap; x_end += rgb_panel->x_gap; y_end += rgb_panel->y_gap; - // round the boundary + + // clip to boundaries int h_res = rgb_panel->timings.h_res; int v_res = rgb_panel->timings.v_res; if (rgb_panel->rotate_mask & ROTATE_MASK_SWAP_XY) { - x_start = MIN(x_start, v_res); + x_start = MAX(x_start, 0); x_end = MIN(x_end, v_res); - y_start = MIN(y_start, h_res); + y_start = MAX(y_start, 0); y_end = MIN(y_end, h_res); } else { - x_start = MIN(x_start, h_res); + x_start = MAX(x_start, 0); x_end = MIN(x_end, h_res); - y_start = MIN(y_start, v_res); + y_start = MAX(y_start, 0); y_end = MIN(y_end, v_res); } @@ -959,11 +972,42 @@ static IRAM_ATTR bool lcd_rgb_panel_eof_handler(gdma_channel_handle_t dma_chan, return lcd_rgb_panel_fill_bounce_buffer(panel, panel->bounce_buffer[bb]); } +static esp_err_t lcd_rgb_create_dma_channel(esp_rgb_panel_t *panel) +{ + // alloc DMA channel and connect to LCD peripheral + gdma_channel_alloc_config_t dma_chan_config = { + .direction = GDMA_CHANNEL_DIRECTION_TX, + }; +#if SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AHB + ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_chan_config, &panel->dma_chan), TAG, "alloc DMA channel failed"); +#elif SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AXI + ESP_RETURN_ON_ERROR(gdma_new_axi_channel(&dma_chan_config, &panel->dma_chan), TAG, "alloc DMA channel failed"); +#endif + gdma_connect(panel->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0)); + + // configure DMA transfer parameters + gdma_transfer_config_t trans_cfg = { + .max_data_burst_size = panel->dma_burst_size, + .access_ext_mem = true, // frame buffer was allocated from external memory + }; + ESP_RETURN_ON_ERROR(gdma_config_transfer(panel->dma_chan, &trans_cfg), TAG, "config DMA transfer failed"); + + // we need to refill the bounce buffer in the DMA EOF interrupt, so only register the callback for bounce buffer mode + if (panel->bb_size) { + gdma_tx_event_callbacks_t cbs = { + .on_trans_eof = lcd_rgb_panel_eof_handler, + }; + gdma_register_tx_event_callbacks(panel->dma_chan, &cbs, panel); + } + + return ESP_OK; +} + // If we restart GDMA, many pixels already have been transferred to the LCD peripheral. // Looks like that has 16 pixels of FIFO plus one holding register. #define LCD_FIFO_PRESERVE_SIZE_PX (LCD_LL_FIFO_DEPTH + 1) -static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel) +static void lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *panel) { for (int i = 0; i < RGB_LCD_PANEL_DMA_LINKS_REPLICA; i++) { panel->dma_links[i] = &panel->dma_nodes[panel->num_dma_nodes * i]; @@ -1007,32 +1051,6 @@ static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel) panel->dma_restart_node.buffer = &p[restart_skip_bytes]; panel->dma_restart_node.dw0.length -= restart_skip_bytes; panel->dma_restart_node.dw0.size -= restart_skip_bytes; - - // alloc DMA channel and connect to LCD peripheral - gdma_channel_alloc_config_t dma_chan_config = { - .direction = GDMA_CHANNEL_DIRECTION_TX, - }; -#if SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AHB - ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_chan_config, &panel->dma_chan), TAG, "alloc DMA channel failed"); -#elif SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AXI - ESP_RETURN_ON_ERROR(gdma_new_axi_channel(&dma_chan_config, &panel->dma_chan), TAG, "alloc DMA channel failed"); -#endif - gdma_connect(panel->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0)); - gdma_transfer_ability_t ability = { - .psram_trans_align = panel->psram_trans_align, - .sram_trans_align = panel->sram_trans_align, - }; - gdma_set_transfer_ability(panel->dma_chan, &ability); - - // we need to refill the bounce buffer in the DMA EOF interrupt, so only register the callback for bounce buffer mode - if (panel->bb_size) { - gdma_tx_event_callbacks_t cbs = { - .on_trans_eof = lcd_rgb_panel_eof_handler, - }; - gdma_register_tx_event_callbacks(panel->dma_chan, &cbs, panel); - } - - return ESP_OK; } // reset the GDMA channel every VBlank to stop permanent desyncs from happening. diff --git a/components/esp_lcd/rgb/include/esp_lcd_panel_rgb.h b/components/esp_lcd/rgb/include/esp_lcd_panel_rgb.h index 7cd4c690b7b4..2e9e5a95a6e3 100644 --- a/components/esp_lcd/rgb/include/esp_lcd_panel_rgb.h +++ b/components/esp_lcd/rgb/include/esp_lcd_panel_rgb.h @@ -132,8 +132,11 @@ typedef struct { size_t num_fbs; /*!< Number of screen-sized frame buffers that allocated by the driver. By default (set to either 0 or 1) only one frame buffer will be used. Maximum number of buffers are 3 */ size_t bounce_buffer_size_px; /*!< If it's non-zero, the driver allocates two DRAM bounce buffers for DMA use. DMA fetching from DRAM bounce buffer is much faster than PSRAM frame buffer. */ - size_t sram_trans_align; /*!< Alignment of buffers (frame buffer or bounce buffer) that allocated in SRAM */ - size_t psram_trans_align; /*!< Alignment of buffers (frame buffer) that allocated in PSRAM */ + size_t sram_trans_align __attribute__((deprecated)); /*!< Alignment of buffers (frame buffer or bounce buffer) that allocated in SRAM */ + union { + size_t psram_trans_align; /*!< Alignment of buffers (frame buffer) that allocated in PSRAM */ + size_t dma_burst_size; /*!< DMA burst size, in bytes */ + }; int hsync_gpio_num; /*!< GPIO used for HSYNC signal */ int vsync_gpio_num; /*!< GPIO used for VSYNC signal */ int de_gpio_num; /*!< GPIO used for DE signal, set to -1 if it's not used */ diff --git a/components/esp_lcd/src/esp_lcd_panel_nt35510.c b/components/esp_lcd/src/esp_lcd_panel_nt35510.c index aa2a472b2324..5a9e34273898 100644 --- a/components/esp_lcd/src/esp_lcd_panel_nt35510.c +++ b/components/esp_lcd/src/esp_lcd_panel_nt35510.c @@ -188,7 +188,6 @@ static esp_err_t panel_nt35510_draw_bitmap(esp_lcd_panel_t *panel, int x_start, const void *color_data) { nt35510_panel_t *nt35510 = __containerof(panel, nt35510_panel_t, base); - assert((x_start < x_end) && (y_start < y_end) && "start position must be smaller than end position"); esp_lcd_panel_io_handle_t io = nt35510->io; x_start += nt35510->x_gap; diff --git a/components/esp_lcd/src/esp_lcd_panel_ops.c b/components/esp_lcd/src/esp_lcd_panel_ops.c index ef19e3d328a3..d4e6bd9aded5 100644 --- a/components/esp_lcd/src/esp_lcd_panel_ops.c +++ b/components/esp_lcd/src/esp_lcd_panel_ops.c @@ -32,6 +32,7 @@ esp_err_t esp_lcd_panel_del(esp_lcd_panel_handle_t panel) esp_err_t esp_lcd_panel_draw_bitmap(esp_lcd_panel_handle_t panel, int x_start, int y_start, int x_end, int y_end, const void *color_data) { ESP_RETURN_ON_FALSE(panel, ESP_ERR_INVALID_ARG, TAG, "invalid panel handle"); + ESP_RETURN_ON_FALSE((x_start < x_end) && (y_start < y_end), ESP_ERR_INVALID_ARG, TAG, "start position must be smaller than end position"); ESP_RETURN_ON_FALSE(panel->draw_bitmap, ESP_ERR_NOT_SUPPORTED, TAG, "draw_bitmap is not supported by this panel"); return panel->draw_bitmap(panel, x_start, y_start, x_end, y_end, color_data); } diff --git a/components/esp_lcd/src/esp_lcd_panel_ssd1306.c b/components/esp_lcd/src/esp_lcd_panel_ssd1306.c index 4ccb6710a507..fbac5c0884b7 100644 --- a/components/esp_lcd/src/esp_lcd_panel_ssd1306.c +++ b/components/esp_lcd/src/esp_lcd_panel_ssd1306.c @@ -168,7 +168,6 @@ static esp_err_t panel_ssd1306_init(esp_lcd_panel_t *panel) static esp_err_t panel_ssd1306_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data) { ssd1306_panel_t *ssd1306 = __containerof(panel, ssd1306_panel_t, base); - assert((x_start < x_end) && (y_start < y_end) && "start position must be smaller than end position"); esp_lcd_panel_io_handle_t io = ssd1306->io; // adding extra gap diff --git a/components/esp_lcd/src/esp_lcd_panel_st7789.c b/components/esp_lcd/src/esp_lcd_panel_st7789.c index e6cd329d13b0..8076fce67ab4 100644 --- a/components/esp_lcd/src/esp_lcd_panel_st7789.c +++ b/components/esp_lcd/src/esp_lcd_panel_st7789.c @@ -198,7 +198,6 @@ static esp_err_t panel_st7789_draw_bitmap(esp_lcd_panel_t *panel, int x_start, i const void *color_data) { st7789_panel_t *st7789 = __containerof(panel, st7789_panel_t, base); - assert((x_start < x_end) && (y_start < y_end) && "start position must be smaller than end position"); esp_lcd_panel_io_handle_t io = st7789->io; x_start += st7789->x_gap; diff --git a/components/esp_lcd/test_apps/.build-test-rules.yml b/components/esp_lcd/test_apps/.build-test-rules.yml index a4c2fd499520..d6308cf692b2 100644 --- a/components/esp_lcd/test_apps/.build-test-rules.yml +++ b/components/esp_lcd/test_apps/.build-test-rules.yml @@ -38,7 +38,7 @@ components/esp_lcd/test_apps/mipi_dsi_lcd: disable_test: - if: IDF_TARGET == "esp32p4" temporary: true - reason: lack of runners + reason: lack of runners, DSI can't work without an LCD connected components/esp_lcd/test_apps/rgb_lcd: depends_components: @@ -52,7 +52,3 @@ components/esp_lcd/test_apps/spi_lcd: - esp_driver_spi disable: - if: SOC_GPSPI_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8975 diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/CMakeLists.txt b/components/esp_lcd/test_apps/mipi_dsi_lcd/CMakeLists.txt index b28d8784fe71..9a4ba3eaaa27 100644 --- a/components/esp_lcd/test_apps/mipi_dsi_lcd/CMakeLists.txt +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/CMakeLists.txt @@ -6,3 +6,16 @@ set(COMPONENTS main) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mipi_dsi_lcd_panel_test) + +if(CONFIG_COMPILER_DUMP_RTL_FILES) + add_custom_target(check_test_app_sections ALL + COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py + --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_lcd/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --elf-file ${CMAKE_BINARY_DIR}/mipi_dsi_lcd_panel_test.elf + find-refs + --from-sections=.iram0.text + --to-sections=.flash.text,.flash.rodata + --exit-code + DEPENDS ${elf} + ) +endif() diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/main/CMakeLists.txt b/components/esp_lcd/test_apps/mipi_dsi_lcd/main/CMakeLists.txt index ab9796d92d23..8ee501adaed3 100644 --- a/components/esp_lcd/test_apps/mipi_dsi_lcd/main/CMakeLists.txt +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/main/CMakeLists.txt @@ -2,6 +2,10 @@ set(srcs "test_app_main.c" "test_mipi_dsi_board.c" "test_mipi_dsi_panel.c") +if(CONFIG_LCD_DSI_ISR_IRAM_SAFE) + list(APPEND srcs "test_mipi_dsi_iram.c") +endif() + # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/main/idf_component.yml b/components/esp_lcd/test_apps/mipi_dsi_lcd/main/idf_component.yml index bcad3c93db37..27d4953b96c4 100644 --- a/components/esp_lcd/test_apps/mipi_dsi_lcd/main/idf_component.yml +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/main/idf_component.yml @@ -1,2 +1,2 @@ dependencies: - esp_lcd_ili9881c: ">=0.1.0" + esp_lcd_ili9881c: "~0.2.0" diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/main/test_mipi_dsi_iram.c b/components/esp_lcd/test_apps/mipi_dsi_lcd/main/test_mipi_dsi_iram.c new file mode 100644 index 000000000000..85cef15288ff --- /dev/null +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/main/test_mipi_dsi_iram.c @@ -0,0 +1,119 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "unity.h" +#include "unity_test_utils.h" +#include "esp_lcd_mipi_dsi.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_panel_io.h" +#include "esp_random.h" +#include "esp_attr.h" +#include "test_mipi_dsi_board.h" +#include "esp_lcd_ili9881c.h" + +IRAM_ATTR static bool test_rgb_panel_count_in_callback(esp_lcd_panel_handle_t panel, esp_lcd_dpi_panel_event_data_t *edata, void *user_ctx) +{ + uint32_t *count = (uint32_t *)user_ctx; + *count = *count + 1; + return false; +} + +static void IRAM_ATTR test_delay_post_cache_disable(void *args) +{ + esp_rom_delay_us(200000); +} + +#define TEST_IMG_SIZE (100 * 100 * sizeof(uint16_t)) + +TEST_CASE("MIPI DSI draw bitmap (ILI9881C) IRAM Safe", "[mipi_dsi]") +{ + esp_lcd_dsi_bus_handle_t mipi_dsi_bus; + esp_lcd_panel_io_handle_t mipi_dbi_io; + esp_lcd_panel_handle_t mipi_dpi_panel; + esp_lcd_panel_handle_t ili9881c_ctrl_panel; + + test_bsp_enable_dsi_phy_power(); + + uint8_t *img = malloc(TEST_IMG_SIZE); + TEST_ASSERT_NOT_NULL(img); + + esp_lcd_dsi_bus_config_t bus_config = { + .bus_id = 0, + .num_data_lanes = 2, + .phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, + .lane_bit_rate_mbps = 1000, // 1000 Mbps + }; + TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus)); + + esp_lcd_dbi_io_config_t dbi_config = { + .virtual_channel = 0, + .lcd_cmd_bits = 8, + .lcd_param_bits = 8, + }; + TEST_ESP_OK(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &mipi_dbi_io)); + + esp_lcd_panel_dev_config_t lcd_dev_config = { + .bits_per_pixel = 16, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, + .reset_gpio_num = -1, + }; + TEST_ESP_OK(esp_lcd_new_panel_ili9881c(mipi_dbi_io, &lcd_dev_config, &ili9881c_ctrl_panel)); + TEST_ESP_OK(esp_lcd_panel_reset(ili9881c_ctrl_panel)); + TEST_ESP_OK(esp_lcd_panel_init(ili9881c_ctrl_panel)); + // turn on display + TEST_ESP_OK(esp_lcd_panel_disp_on_off(ili9881c_ctrl_panel, true)); + + esp_lcd_dpi_panel_config_t dpi_config = { + .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, + .dpi_clock_freq_mhz = MIPI_DSI_DPI_CLK_MHZ, + .virtual_channel = 0, + .pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565, + .video_timing = { + .h_size = MIPI_DSI_LCD_H_RES, + .v_size = MIPI_DSI_LCD_V_RES, + .hsync_back_porch = MIPI_DSI_LCD_HBP, + .hsync_pulse_width = MIPI_DSI_LCD_HSYNC, + .hsync_front_porch = MIPI_DSI_LCD_HFP, + .vsync_back_porch = MIPI_DSI_LCD_VBP, + .vsync_pulse_width = MIPI_DSI_LCD_VSYNC, + .vsync_front_porch = MIPI_DSI_LCD_VFP, + }, + }; + TEST_ESP_OK(esp_lcd_new_panel_dpi(mipi_dsi_bus, &dpi_config, &mipi_dpi_panel)); + TEST_ESP_OK(esp_lcd_panel_init(mipi_dpi_panel)); + uint32_t callback_calls = 0; + esp_lcd_dpi_panel_event_callbacks_t cbs = { + .on_refresh_done = test_rgb_panel_count_in_callback, + }; + TEST_ESP_OK(esp_lcd_dpi_panel_register_event_callbacks(mipi_dpi_panel, &cbs, &callback_calls)); + + uint8_t color_byte = rand() & 0xFF; + int x_start = rand() % (MIPI_DSI_LCD_H_RES - 100); + int y_start = rand() % (MIPI_DSI_LCD_V_RES - 100); + memset(img, color_byte, TEST_IMG_SIZE); + esp_lcd_panel_draw_bitmap(mipi_dpi_panel, x_start, y_start, x_start + 100, y_start + 100, img); + vTaskDelay(pdMS_TO_TICKS(100)); + + printf("The LCD driver should keep flushing the color block in the background\r\n"); + + // disable the cache for a while, the LCD driver should stay working + printf("disable the cache for a while\r\n"); + unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL); + printf("callback calls: %"PRIu32"\r\n", callback_calls); + TEST_ASSERT(callback_calls > 2); + + TEST_ESP_OK(esp_lcd_panel_del(mipi_dpi_panel)); + TEST_ESP_OK(esp_lcd_panel_del(ili9881c_ctrl_panel)); + TEST_ESP_OK(esp_lcd_panel_io_del(mipi_dbi_io)); + TEST_ESP_OK(esp_lcd_del_dsi_bus(mipi_dsi_bus)); + free(img); + + test_bsp_disable_dsi_phy_power(); +} diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/main/test_mipi_dsi_panel.c b/components/esp_lcd/test_apps/mipi_dsi_lcd/main/test_mipi_dsi_panel.c index eec61a14b7f8..a31d26e01fdd 100644 --- a/components/esp_lcd/test_apps/mipi_dsi_lcd/main/test_mipi_dsi_panel.c +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/main/test_mipi_dsi_panel.c @@ -222,16 +222,16 @@ TEST_CASE("MIPI DSI with multiple frame buffers (ILI9881C)", "[mipi_dsi]") uint16_t *fbs[3]; TEST_ESP_OK(esp_lcd_dpi_panel_get_frame_buffer(mipi_dpi_panel, 3, (void **)&fbs[0], (void **)&fbs[1], (void **)&fbs[2])); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 9; i++) { uint16_t color_byte = rand() & 0xFFFF; int x_start = rand() % (MIPI_DSI_LCD_H_RES - 100); int y_start = rand() % (MIPI_DSI_LCD_V_RES - 100); for (int j = y_start; j < y_start + 100; j++) { for (int k = x_start; k < x_start + 100; k++) { - fbs[i][j * MIPI_DSI_LCD_H_RES + k] = color_byte; + fbs[i % 3][j * MIPI_DSI_LCD_H_RES + k] = color_byte; } } - esp_lcd_panel_draw_bitmap(mipi_dpi_panel, x_start, y_start, x_start + 100, y_start + 100, fbs[i]); + esp_lcd_panel_draw_bitmap(mipi_dpi_panel, x_start, y_start, x_start + 100, y_start + 100, fbs[i % 3]); vTaskDelay(pdMS_TO_TICKS(1000)); } diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/pytest_mipi_dsi_lcd.py b/components/esp_lcd/test_apps/mipi_dsi_lcd/pytest_mipi_dsi_lcd.py index eab77ed4c9fa..7e4dc07e7d12 100644 --- a/components/esp_lcd/test_apps/mipi_dsi_lcd/pytest_mipi_dsi_lcd.py +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/pytest_mipi_dsi_lcd.py @@ -1,11 +1,18 @@ # SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @pytest.mark.esp32p4 @pytest.mark.generic -def test_rgb_lcd(dut: Dut) -> None: +@pytest.mark.parametrize( + 'config', + [ + 'iram_safe', + 'release', + ], + indirect=True, +) +def test_dsi_lcd(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/sdkconfig.ci.iram_safe b/components/esp_lcd/test_apps/mipi_dsi_lcd/sdkconfig.ci.iram_safe new file mode 100644 index 000000000000..9d1d9f005f35 --- /dev/null +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/sdkconfig.ci.iram_safe @@ -0,0 +1,8 @@ +CONFIG_COMPILER_DUMP_RTL_FILES=y +CONFIG_COMPILER_OPTIMIZATION_NONE=y +# silent the error check, as the error string are stored in rodata, causing RTL check failure +CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +# place non-ISR FreeRTOS functions in Flash +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +CONFIG_LCD_DSI_ISR_IRAM_SAFE=y diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/sdkconfig.ci.release b/components/esp_lcd/test_apps/mipi_dsi_lcd/sdkconfig.ci.release new file mode 100644 index 000000000000..91d93f163e62 --- /dev/null +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/sdkconfig.ci.release @@ -0,0 +1,5 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c index 4e1eb3edd39d..8c39c32121f4 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c @@ -31,7 +31,7 @@ static esp_lcd_panel_handle_t test_rgb_panel_initialization(size_t data_width, s esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_rgb_panel_config_t panel_config = { .data_width = data_width, - .psram_trans_align = 64, + .dma_burst_size = 64, .bounce_buffer_size_px = bb_pixels, .bits_per_pixel = bpp, .clk_src = LCD_CLK_SRC_DEFAULT, diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/test_yuv_rgb_conv.c b/components/esp_lcd/test_apps/rgb_lcd/main/test_yuv_rgb_conv.c index 4bcf65dbdc8e..73ab6dede793 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/main/test_yuv_rgb_conv.c +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_yuv_rgb_conv.c @@ -27,7 +27,7 @@ TEST_CASE("lcd_rgb_panel_yuv422_conversion", "[lcd]") esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_rgb_panel_config_t panel_config = { .data_width = 16, - .psram_trans_align = 64, + .dma_burst_size = 64, .bits_per_pixel = 16, // YUV422: 16bits per pixel .clk_src = LCD_CLK_SRC_DEFAULT, .disp_gpio_num = TEST_LCD_DISP_EN_GPIO, diff --git a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 index 36a4a647ea75..aea303d4f9ea 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 +++ b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 @@ -3,5 +3,4 @@ CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SPEED_80M=y # Enable the XIP-PSRAM feature, so the ext-mem cache won't be disabled when SPI1 is operating the main flash -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y -CONFIG_SPIRAM_RODATA=y +CONFIG_SPIRAM_XIP_FROM_PSRAM=y diff --git a/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h index ec4600376d86..9ce7d5224e84 100644 --- a/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h +++ b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,6 +28,20 @@ extern "C" { #define TEST_LCD_DC_GPIO 1 #define TEST_LCD_PCLK_GPIO 2 #define TEST_LCD_DATA0_GPIO 4 +#elif CONFIG_IDF_TARGET_ESP32P4 +#define TEST_LCD_BK_LIGHT_GPIO 23 +#define TEST_LCD_RST_GPIO 6 +#define TEST_LCD_CS_GPIO 4 +#define TEST_LCD_DC_GPIO 3 +#define TEST_LCD_PCLK_GPIO 2 +#define TEST_LCD_DATA0_GPIO 32 +#define TEST_LCD_DATA1_GPIO 33 +#define TEST_LCD_DATA2_GPIO 22 +#define TEST_LCD_DATA3_GPIO 8 +#define TEST_LCD_DATA4_GPIO 21 +#define TEST_LCD_DATA5_GPIO 53 +#define TEST_LCD_DATA6_GPIO 20 +#define TEST_LCD_DATA7_GPIO 5 #else #define TEST_LCD_BK_LIGHT_GPIO 18 #define TEST_LCD_RST_GPIO 5 diff --git a/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py b/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py index f2ad352216e7..2cdeaf11e8ad 100644 --- a/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py +++ b/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py @@ -1,11 +1,9 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8975 @pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( diff --git a/components/esp_mm/CMakeLists.txt b/components/esp_mm/CMakeLists.txt index 9878840babcb..06f5b3bc9ee7 100644 --- a/components/esp_mm/CMakeLists.txt +++ b/components/esp_mm/CMakeLists.txt @@ -21,6 +21,8 @@ if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) endif() endif() +list(APPEND srcs "heap_align_hw.c") + idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} PRIV_REQUIRES ${priv_requires} diff --git a/components/esp_mm/esp_cache.c b/components/esp_mm/esp_cache.c index 213a80943135..84a265a2197f 100644 --- a/components/esp_mm/esp_cache.c +++ b/components/esp_mm/esp_cache.c @@ -93,7 +93,10 @@ esp_err_t esp_cache_msync(void *addr, size_t size, int flags) return ESP_OK; } -esp_err_t esp_cache_aligned_malloc(size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size) +//The esp_cache_aligned_malloc function is marked deprecated but also called by other +//(also deprecated) functions in this file. In order to work around that generating warnings, it's +//split into a non-deprecated internal function and the stubbed external deprecated function. +static esp_err_t esp_cache_aligned_malloc_internal(size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size) { ESP_RETURN_ON_FALSE_ISR(out_ptr, ESP_ERR_INVALID_ARG, TAG, "null pointer"); uint32_t valid_caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; @@ -127,6 +130,12 @@ esp_err_t esp_cache_aligned_malloc(size_t size, uint32_t heap_caps, void **out_p return ESP_OK; } +//this is the deprecated stub for the above function +esp_err_t esp_cache_aligned_malloc(size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size) +{ + return esp_cache_aligned_malloc_internal(size, heap_caps, out_ptr, actual_size); +} + esp_err_t esp_cache_aligned_malloc_prefer(size_t size, void **out_ptr, size_t *actual_size, size_t flag_nums, ...) { ESP_RETURN_ON_FALSE_ISR(out_ptr, ESP_ERR_INVALID_ARG, TAG, "null pointer"); @@ -139,7 +148,7 @@ esp_err_t esp_cache_aligned_malloc_prefer(size_t size, void **out_ptr, size_t *a while (flag_nums--) { flags = va_arg(argp, uint32_t); - ret = esp_cache_aligned_malloc(size, flags, out_ptr, actual_size); + ret = esp_cache_aligned_malloc_internal(size, flags, out_ptr, actual_size); if (ret == ESP_OK) { break; } @@ -161,7 +170,7 @@ esp_err_t esp_cache_aligned_calloc(size_t n, size_t size, uint32_t heap_caps, vo ESP_RETURN_ON_FALSE_ISR(!ovf, ESP_ERR_INVALID_ARG, TAG, "wrong size, total size overflow"); void *ptr = NULL; - ret = esp_cache_aligned_malloc(size_bytes, heap_caps, &ptr, actual_size); + ret = esp_cache_aligned_malloc_internal(size_bytes, heap_caps, &ptr, actual_size); if (ret == ESP_OK) { memset(ptr, 0, size_bytes); *out_ptr = ptr; @@ -188,7 +197,7 @@ esp_err_t esp_cache_aligned_calloc_prefer(size_t n, size_t size, void **out_ptr, int arg; for (int i = 0; i < flag_nums; i++) { arg = va_arg(argp, int); - ret = esp_cache_aligned_malloc_prefer(size_bytes, &ptr, actual_size, flag_nums, arg); + ret = esp_cache_aligned_malloc_internal(size_bytes, arg, &ptr, actual_size); if (ret == ESP_OK) { memset(ptr, 0, size_bytes); *out_ptr = ptr; diff --git a/components/esp_mm/esp_mmu_map.c b/components/esp_mm/esp_mmu_map.c index 24e06c5298cb..cc3260f7c669 100644 --- a/components/esp_mm/esp_mmu_map.c +++ b/components/esp_mm/esp_mmu_map.c @@ -38,7 +38,7 @@ #define MEM_REGION_MERGED -1 /** - * We have some hw related tests for vaddr region capabilites + * We have some hw related tests for vaddr region capabilities * Use this macro to disable paddr check as we need to reuse certain paddr blocks */ #define ENABLE_PADDR_CHECK !ESP_MMAP_TEST_ALLOW_MAP_TO_MAPPED_PADDR @@ -185,6 +185,13 @@ static void s_reserve_drom_region(mem_region_t *hw_mem_regions, int region_nums) } #endif //#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS +#if SOC_MMU_PER_EXT_MEM_TARGET +FORCE_INLINE_ATTR uint32_t s_get_mmu_id_from_target(mmu_target_t target) +{ + return (target == MMU_TARGET_FLASH0) ? MMU_LL_FLASH_MMU_ID : MMU_LL_PSRAM_MMU_ID; +} +#endif + void esp_mmu_map_init(void) { mem_region_t hw_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = {}; @@ -381,16 +388,11 @@ static void IRAM_ATTR NOINLINE_ATTR s_do_cache_invalidate(uint32_t vaddr_start, #endif // CONFIG_IDF_TARGET_ESP32 } -#if MMU_LL_MMU_PER_TARGET +#if SOC_MMU_PER_EXT_MEM_TARGET FORCE_INLINE_ATTR uint32_t s_mapping_operation(mmu_target_t target, uint32_t vaddr_start, esp_paddr_t paddr_start, uint32_t size) { uint32_t actual_mapped_len = 0; - uint32_t mmu_id = 0; - if (target == MMU_TARGET_FLASH0) { - mmu_id = MMU_LL_FLASH_MMU_ID; - } else { - mmu_id = MMU_LL_PSRAM_MMU_ID; - } + uint32_t mmu_id = s_get_mmu_id_from_target(target); mmu_hal_map_region(mmu_id, target, vaddr_start, paddr_start, size, &actual_mapped_len); return actual_mapped_len; @@ -507,7 +509,15 @@ esp_err_t esp_mmu_map(esp_paddr_t paddr_start, size_t size, mmu_target_t target, if (is_enclosed) { ESP_LOGW(TAG, "paddr block is mapped already, vaddr_start: %p, size: 0x%x", (void *)mem_block->vaddr_start, mem_block->size); - *out_ptr = (void *)mem_block->vaddr_start; + /* + * This condition is triggered when `s_is_enclosed` is true and hence + * we are sure that `paddr_start` >= `mem_block->paddr_start`. + * + * Add the offset of new physical address while returning the virtual + * address. + */ + const uint32_t new_paddr_offset = paddr_start - mem_block->paddr_start; + *out_ptr = (void *)mem_block->vaddr_start + new_paddr_offset; return ESP_ERR_INVALID_STATE; } @@ -584,17 +594,11 @@ esp_err_t esp_mmu_map(esp_paddr_t paddr_start, size_t size, mmu_target_t target, return ret; } -#if MMU_LL_MMU_PER_TARGET +#if SOC_MMU_PER_EXT_MEM_TARGET FORCE_INLINE_ATTR void s_unmapping_operation(uint32_t vaddr_start, uint32_t size) { - uint32_t mmu_id = 0; mmu_target_t target = mmu_ll_vaddr_to_target(vaddr_start); - - if (target == MMU_TARGET_FLASH0) { - mmu_id = MMU_LL_FLASH_MMU_ID; - } else { - mmu_id = MMU_LL_PSRAM_MMU_ID; - } + uint32_t mmu_id = s_get_mmu_id_from_target(target); mmu_hal_unmap_region(mmu_id, vaddr_start, size); } #else @@ -748,8 +752,12 @@ static bool NOINLINE_ATTR IRAM_ATTR s_vaddr_to_paddr(uint32_t vaddr, esp_paddr_t { //we call this for now, but this will be refactored to move out of `spi_flash` spi_flash_disable_interrupts_caches_and_other_cpu(); - //On ESP32, core 1 settings should be the same as the core 0 bool is_mapped = mmu_hal_vaddr_to_paddr(0, vaddr, out_paddr, out_target); +#if SOC_MMU_PER_EXT_MEM_TARGET + if (!is_mapped) { + is_mapped = mmu_hal_vaddr_to_paddr(1, vaddr, out_paddr, out_target); + } +#endif spi_flash_enable_interrupts_caches_and_other_cpu(); return is_mapped; @@ -776,8 +784,11 @@ static bool NOINLINE_ATTR IRAM_ATTR s_paddr_to_vaddr(esp_paddr_t paddr, mmu_targ { //we call this for now, but this will be refactored to move out of `spi_flash` spi_flash_disable_interrupts_caches_and_other_cpu(); - //On ESP32, core 1 settings should be the same as the core 0 - bool found = mmu_hal_paddr_to_vaddr(0, paddr, target, type, out_vaddr); + uint32_t mmu_id = 0; +#if SOC_MMU_PER_EXT_MEM_TARGET + mmu_id = s_get_mmu_id_from_target(target); +#endif + bool found = mmu_hal_paddr_to_vaddr(mmu_id, paddr, target, type, out_vaddr); spi_flash_enable_interrupts_caches_and_other_cpu(); return found; diff --git a/components/esp_mm/heap_align_hw.c b/components/esp_mm/heap_align_hw.c new file mode 100644 index 000000000000..96787f19d095 --- /dev/null +++ b/components/esp_mm/heap_align_hw.c @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "esp_heap_caps.h" +#include "esp_private/esp_cache_private.h" +#include "soc/soc_caps.h" +#if SOC_GDMA_SUPPORTED +#include "hal/gdma_ll.h" +#endif + +#if CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH +#define HEAP_IRAM_ATTR +#else +#define HEAP_IRAM_ATTR IRAM_ATTR +#endif + +#define CAPS_NEEDING_ALIGNMENT (MALLOC_CAP_DMA|MALLOC_CAP_DMA_DESC_AHB|MALLOC_CAP_DMA_DESC_AXI|MALLOC_CAP_CACHE_ALIGNED) + +HEAP_IRAM_ATTR void esp_heap_adjust_alignment_to_hw(size_t *p_alignment, size_t *p_size, uint32_t *p_caps) +{ + size_t size = *p_size; + size_t alignment = *p_alignment; + uint32_t caps = *p_caps; + + //Bail out early if we don't need alignment + if (!(caps & CAPS_NEEDING_ALIGNMENT)) { + return; + } + +#if CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +//Cache functions aren't linked in so we cannot allocate anything needing alignment. +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + //Cannot do this for either internal or external memory. + *p_caps |= MALLOC_CAP_INVALID; +#else + //Internal memory DMA alloc is allowed. + if (caps & MALLOC_CAP_SPIRAM) { + *p_caps |= MALLOC_CAP_INVALID; + } +#endif + return; +#endif + + //Ask cache driver what alignment is applicable here. + size_t cache_alignment_bytes = 0; + esp_err_t ret = esp_cache_get_alignment(caps, &cache_alignment_bytes); + if (ret != ESP_OK) { + //This is not supposed to happen. + *p_caps |= MALLOC_CAP_INVALID; + return; + } + +#if SOC_GDMA_SUPPORTED && SOC_AXI_GDMA_SUPPORTED + //Special case: AXI DMA descriptors need to be aligned to 8-byte boundaries. + if ((caps & MALLOC_CAP_DMA_DESC_AXI) && (cache_alignment_bytes < GDMA_LL_AXI_DESC_ALIGNMENT)) { + cache_alignment_bytes = GDMA_LL_AXI_DESC_ALIGNMENT; + } +#endif + + // We assume both DMA alignment and requested alignment are powers of two. We can safely + // do this because: + // - DMA alignment in current chips always is a power of two, and is unlikely to ever + // be something else, + // - Requested alignment is checked by heap_caps_aligned_check_args to be a power + // of two. + if (cache_alignment_bytes > alignment) { + alignment = cache_alignment_bytes; + } + // Align up `size` to resulting alignment as well. + size = (size + alignment - 1) & (~(alignment - 1)); + + // For the heap allocator itself, there's no difference between data and descriptor DMA; the regions + // are only marked as DMA-capable. + if (caps & (MALLOC_CAP_DMA_DESC_AHB | MALLOC_CAP_DMA_DESC_AXI)) { + caps &= ~(MALLOC_CAP_DMA_DESC_AHB | MALLOC_CAP_DMA_DESC_AXI); + caps |= MALLOC_CAP_DMA; + } + + // Workaround: the heap allocator doesn't have regions marked `MALLOC_CAP_DMA | MALLOC_CAP_SPIRAM` + // so we need to request those without the DMA flag. + if (caps & MALLOC_CAP_SPIRAM) { + caps &= ~MALLOC_CAP_DMA; + //Note: we do not erase any DMA descriptor caps. DMA descriptors cannot be in external + //memory, so the MALLOC_CAP_SPIRAM|MALLOC_CAP_DMA_DESC_* simply will not return any + //usable memory. + } + // MALLOC_CAP_CACHE_ALIGNED is not a real flag the heap_base component will understand; it + // only sets alignment (which we handled here) + caps &= ~ MALLOC_CAP_CACHE_ALIGNED; + + *p_size = size; + *p_alignment = alignment; + *p_caps = caps; +} diff --git a/components/esp_mm/include/esp_mmu_map.h b/components/esp_mm/include/esp_mmu_map.h index e4a42e483d00..2e64a0d84254 100644 --- a/components/esp_mm/include/esp_mmu_map.h +++ b/components/esp_mm/include/esp_mmu_map.h @@ -75,7 +75,7 @@ typedef uint32_t esp_paddr_t; * - ESP_ERR_NOT_SUPPORTED: Only on ESP32, PSRAM is not a supported physical memory target * - ESP_ERR_NOT_FOUND: No enough size free block to use * - ESP_ERR_NO_MEM: Out of memory, this API will allocate some heap memory for internal usage - * - ESP_ERR_INVALID_STATE: Paddr is mapped already, this API will return corresponding vaddr_start of the previously mapped block. + * - ESP_ERR_INVALID_STATE: Paddr is mapped already, this API will return corresponding `vaddr_start + new_block_offset` as per the previously mapped block. * Only to-be-mapped paddr block is totally enclosed by a previously mapped block will lead to this error. (Identical scenario will behave similarly) * new_block_start new_block_end * |-------- New Block --------| diff --git a/components/esp_mm/include/esp_private/esp_cache_private.h b/components/esp_mm/include/esp_private/esp_cache_private.h index 97a4afafcc47..3f28554220a8 100644 --- a/components/esp_mm/include/esp_private/esp_cache_private.h +++ b/components/esp_mm/include/esp_private/esp_cache_private.h @@ -25,11 +25,15 @@ extern "C" { * @param[out] out_ptr A pointer to the memory allocated successfully * @param[out] actual_size Actual size for allocation in bytes, when the size you specified doesn't meet the cache alignment requirements, this value might be bigger than the size you specified. Set null if you don't care this value. * + * @deprecated This function is deprecated and will be removed in the future. + * Use 'heap_caps_malloc' with MALLOC_CAP_CACHE_ALIGNED caps instead + * * @return * - ESP_OK: * - ESP_ERR_INVALID_ARG: Invalid argument * - ESP_ERR_NO_MEM: No enough memory for allocation */ +__attribute__((deprecated("Use 'heap_caps_malloc' with MALLOC_CAP_CACHE_ALIGNED caps instead"))) esp_err_t esp_cache_aligned_malloc(size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size); /** @@ -45,11 +49,15 @@ esp_err_t esp_cache_aligned_malloc(size_t size, uint32_t heap_caps, void **out_p * the next parameter. It will try in this order until allocating a chunk of memory successfully * or fail to allocate memories with any of the parameters. * + * @deprecated This function is deprecated and will be removed in the future. + * Use 'heap_caps_malloc_prefer' with MALLOC_CAP_CACHE_ALIGNED caps instead + * * @return * - ESP_OK: * - ESP_ERR_INVALID_ARG: Invalid argument * - ESP_ERR_NO_MEM: No enough memory for allocation */ +__attribute__((deprecated("Use 'heap_caps_malloc_prefer' with MALLOC_CAP_CACHE_ALIGNED caps instead"))) esp_err_t esp_cache_aligned_malloc_prefer(size_t size, void **out_ptr, size_t *actual_size, size_t flag_nums, ...); /** @@ -63,11 +71,15 @@ esp_err_t esp_cache_aligned_malloc_prefer(size_t size, void **out_ptr, size_t *a * @param[out] out_ptr A pointer to the memory allocated successfully * @param[out] actual_size Actual size for allocation in bytes, when the size you specified doesn't meet the cache alignment requirements, this value might be bigger than the size you specified. Set null if you don't care this value. * + * @deprecated This function is deprecated and will be removed in the future. + * Use 'heap_caps_calloc' with MALLOC_CAP_CACHE_ALIGNED caps instead + * * @return * - ESP_OK: * - ESP_ERR_INVALID_ARG: Invalid argument * - ESP_ERR_NO_MEM: No enough memory for allocation */ +__attribute__((deprecated("Use 'heap_caps_calloc' with MALLOC_CAP_CACHE_ALIGNED caps instead"))) esp_err_t esp_cache_aligned_calloc(size_t n, size_t size, uint32_t heap_caps, void **out_ptr, size_t *actual_size); /** @@ -84,11 +96,15 @@ esp_err_t esp_cache_aligned_calloc(size_t n, size_t size, uint32_t heap_caps, vo * the next parameter. It will try in this order until allocating a chunk of memory successfully * or fail to allocate memories with any of the parameters. * + * @deprecated This function is deprecated and will be removed in the future. + * Use 'heap_caps_calloc_prefer' with MALLOC_CAP_CACHE_ALIGNED caps instead + * * @return * - ESP_OK: * - ESP_ERR_INVALID_ARG: Invalid argument * - ESP_ERR_NO_MEM: No enough memory for allocation */ +__attribute__((deprecated("Use 'heap_caps_calloc' with MALLOC_CAP_CACHE_ALIGNED caps instead"))) esp_err_t esp_cache_aligned_calloc_prefer(size_t n, size_t size, void **out_ptr, size_t *actual_size, size_t flag_nums, ...); /** diff --git a/components/esp_mm/include/esp_private/heap_align_hw.h b/components/esp_mm/include/esp_private/heap_align_hw.h new file mode 100644 index 000000000000..452f00bde86d --- /dev/null +++ b/components/esp_mm/include/esp_private/heap_align_hw.h @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "multi_heap.h" +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Adjust size, alignment and caps of a memory allocation request to the specific + * hardware requirements, dependent on where the memory gets allocated. + * + * @note Note that heap_caps_base.c has its own definition for this function in order not to depend + * on this component. + * + * @param[in,out] p_alignment Pointer to alignment requirements. This may be modified upwards if the + * hardware has stricter alignment requirements. + * @param[in,out] p_size Pointer to size of memory to be allocated. This may be modified upwards + * if e.g. the memory needs to be aligned to a cache line. + * @param[in,out] p_caps Pointer to memory requirements. This may be adjusted if the memory + * requirements need modification for the heap caps allocator to work + * properly. + */ +void esp_heap_adjust_alignment_to_hw(size_t *p_alignment, size_t *p_size, uint32_t *p_caps); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_mm/linker.lf b/components/esp_mm/linker.lf index a48fe34cbf9e..1af07775ddb5 100644 --- a/components/esp_mm/linker.lf +++ b/components/esp_mm/linker.lf @@ -7,3 +7,10 @@ entries: if IDF_TARGET_ESP32 = y: cache_esp32 (noflash) + + if SPIRAM_FLASH_LOAD_TO_PSRAM = y: + esp_mmu_map: s_get_bus_mask (noflash) + esp_mmu_map: s_reserve_irom_region (noflash) + esp_mmu_map: s_reserve_drom_region (noflash) + esp_mmu_map: esp_mmu_map_init (noflash) + ext_mem_layout (noflash) diff --git a/components/esp_mm/test_apps/mm/main/test_cache_msync_malloc.c b/components/esp_mm/test_apps/mm/main/test_cache_msync_malloc.c index cd3ac554d21d..f1e7b5901600 100644 --- a/components/esp_mm/test_apps/mm/main/test_cache_msync_malloc.c +++ b/components/esp_mm/test_apps/mm/main/test_cache_msync_malloc.c @@ -11,7 +11,9 @@ #include "esp_log.h" #include "esp_attr.h" #include "unity.h" + #include "esp_private/esp_cache_private.h" + #include "esp_memory_utils.h" const static char *TAG = "CACHE_MALLOC_TEST"; @@ -20,7 +22,10 @@ TEST_CASE("test esp_cache_aligned_malloc_prefer", "[cache]") { void *ptr = NULL; size_t actual_size = 0; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TEST_ESP_OK(esp_cache_aligned_malloc_prefer(40, &ptr, &actual_size, 1, MALLOC_CAP_DMA, 0)); +#pragma GCC diagnostic pop TEST_ASSERT(esp_ptr_dma_capable(ptr)); ESP_LOGI(TAG, "actual size: 0x%x", actual_size); @@ -31,7 +36,10 @@ TEST_CASE("test esp_cache_aligned_calloc_prefer", "[cache]") { void *ptr = NULL; size_t actual_size = 0; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TEST_ESP_OK(esp_cache_aligned_calloc_prefer(1, 40, &ptr, &actual_size, 1, MALLOC_CAP_DMA, 0)); +#pragma GCC diagnostic pop TEST_ASSERT(esp_ptr_dma_capable(ptr)); ESP_LOGI(TAG, "actual size: 0d%d", actual_size); diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index 02af33fd68d2..bf5560f49646 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -140,8 +140,8 @@ static void esp_netif_internal_dhcpc_cb(struct netif *netif); #endif #if LWIP_IPV6 static void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index); -static void netif_set_mldv6_flag(struct netif *netif); -static void netif_unset_mldv6_flag(struct netif *netif); +static void netif_set_mldv6_flag(esp_netif_t *netif); +static void netif_unset_mldv6_flag(esp_netif_t *netif); #endif /* LWIP_IPV6 */ static esp_err_t esp_netif_destroy_api(esp_netif_api_msg_t *msg); @@ -156,7 +156,8 @@ static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, co #if LWIP_IPV6 if ((reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) && (args != NULL)) { s8_t addr_idx = args->ipv6_addr_state_changed.addr_index; - if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { + if (!(args->ipv6_addr_state_changed.old_state & IP6_ADDR_VALID) && + netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { /* address is valid -> call the callback function */ esp_netif_internal_nd6_cb(netif, addr_idx); } @@ -844,7 +845,7 @@ static void esp_netif_lwip_remove(esp_netif_t *esp_netif) #endif #if ESP_MLDV6_REPORT && LWIP_IPV6 if (esp_netif->flags & ESP_NETIF_FLAG_MLDV6_REPORT) { - netif_unset_mldv6_flag(esp_netif->lwip_netif); + netif_unset_mldv6_flag(esp_netif); } #endif if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) { @@ -1692,7 +1693,7 @@ static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg) #if CONFIG_LWIP_IPV6 #if ESP_MLDV6_REPORT if (esp_netif->flags & ESP_NETIF_FLAG_MLDV6_REPORT) { - netif_unset_mldv6_flag(esp_netif->lwip_netif); + netif_unset_mldv6_flag(esp_netif); } #endif for(int8_t i = 0 ;i < LWIP_IPV6_NUM_ADDRESSES ;i++) { @@ -1996,25 +1997,31 @@ esp_err_t esp_netif_get_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t ty static void netif_send_mldv6(void *arg) { - struct netif *netif = arg; - if (!netif_is_up(netif)) { + esp_netif_t *esp_netif = arg; + esp_netif->mldv6_report_timer_started = false; + if (!netif_is_up(esp_netif->lwip_netif)) { return; } - mld6_report_groups(netif); - sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, netif); + mld6_report_groups(esp_netif->lwip_netif); + esp_netif->mldv6_report_timer_started = true; + sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, esp_netif); } -static void netif_set_mldv6_flag(struct netif *netif) +static void netif_set_mldv6_flag(esp_netif_t *esp_netif) { - if (!netif_is_up(netif)) { + if (!netif_is_up(esp_netif->lwip_netif) || esp_netif->mldv6_report_timer_started) { return; } - sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, netif); + esp_netif->mldv6_report_timer_started = true; + sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, esp_netif); } -static void netif_unset_mldv6_flag(struct netif *netif) +static void netif_unset_mldv6_flag(esp_netif_t *esp_netif) { - sys_untimeout(netif_send_mldv6, netif); + if (esp_netif->mldv6_report_timer_started) { + esp_netif->mldv6_report_timer_started = false; + sys_untimeout(netif_send_mldv6, esp_netif); + } } #endif @@ -2061,7 +2068,7 @@ static void esp_netif_internal_nd6_cb(struct netif *netif, uint8_t ip_index) if (esp_netif->flags&ESP_NETIF_FLAG_MLDV6_REPORT) { #if ESP_MLDV6_REPORT - netif_set_mldv6_flag(netif); + netif_set_mldv6_flag(esp_netif); #else ESP_LOGW(TAG,"CONFIG_LWIP_ESP_MLDV6_REPORT not enabled, but esp-netif configured with ESP_NETIF_FLAG_MLDV6_REPORT"); #endif @@ -2145,7 +2152,7 @@ int esp_netif_get_all_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[]) if (p_netif != NULL && netif_is_up(p_netif)) { for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (!ip_addr_cmp(&p_netif->ip6_addr[i], IP6_ADDR_ANY)) { + if (ip6_addr_isvalid(netif_ip6_addr_state(p_netif, i)) && !ip_addr_cmp(&p_netif->ip6_addr[i], IP6_ADDR_ANY)) { memcpy(&if_ip6[addr_count++], &p_netif->ip6_addr[i], sizeof(ip6_addr_t)); } } diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index f1fc1f8bf8b8..842fc8173580 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -112,4 +112,6 @@ struct esp_netif_obj { uint16_t max_fdb_sta_entries; uint8_t max_ports; #endif // CONFIG_ESP_NETIF_BRIDGE_EN + // mldv6 timer + bool mldv6_report_timer_started; }; diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.c b/components/esp_netif/lwip/esp_netif_lwip_ppp.c index db5e9f44f5ed..7e4a61a17f3f 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.c +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.c @@ -165,7 +165,7 @@ static void on_ppp_notify_phase(ppp_pcb *pcb, u8_t phase, void *ctx) #endif // PPP_NOTIFY_PHASE /** - * @brief PPP low level output callback used to transmit data using standard esp-netif interafce + * @brief PPP low level output callback used to transmit data using standard esp-netif interface * * @param pcb PPP control block * @param data Buffer to write to serial port @@ -263,6 +263,10 @@ esp_err_t esp_netif_start_ppp(esp_netif_t *esp_netif) } #endif // CONFIG_LWIP_PPP_SERVER_SUPPORT +#if ESP_IPV6_AUTOCONFIG + ppp_ctx->ppp->netif->ip6_autoconfig_enabled = 1; +#endif + ESP_LOGD(TAG, "%s: Starting PPP connection: %p", __func__, ppp_ctx->ppp); #ifdef CONFIG_LWIP_PPP_SERVER_SUPPORT esp_err_t err = ppp_listen(ppp_ctx->ppp); diff --git a/components/esp_netif/test_apps/test_app_vfs_l2tap/sdkconfig.defaults b/components/esp_netif/test_apps/test_app_vfs_l2tap/sdkconfig.defaults index c439354b15d3..d5365ebde979 100644 --- a/components/esp_netif/test_apps/test_app_vfs_l2tap/sdkconfig.defaults +++ b/components/esp_netif/test_apps/test_app_vfs_l2tap/sdkconfig.defaults @@ -1,5 +1,7 @@ CONFIG_UNITY_ENABLE_FIXTURE=y CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +CONFIG_ETH_USE_ESP32_EMAC=y + CONFIG_ESP_NETIF_L2_TAP=y CONFIG_LWIP_CHECK_THREAD_SAFETY=y diff --git a/components/esp_partition/partition.c b/components/esp_partition/partition.c index 174d1c1f0d0d..d32ff0ff1ec6 100644 --- a/components/esp_partition/partition.c +++ b/components/esp_partition/partition.c @@ -27,6 +27,7 @@ #if !CONFIG_IDF_TARGET_LINUX #include "esp_flash.h" #include "esp_flash_encrypt.h" +#include "spi_flash_mmap.h" #endif #include "esp_log.h" #include "esp_rom_md5.h" diff --git a/components/esp_phy/lib b/components/esp_phy/lib index c28825eb1be6..06e7625de197 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit c28825eb1be6bbe30e0ee8cfcd54614bf86273e7 +Subproject commit 06e7625de197bc12797dd701d6762229bca01826 diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index d56e8d6e34c9..34316de51831 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -873,8 +873,7 @@ void esp_phy_load_cal_and_init(void) ESP_LOGW(TAG, "saving new calibration data because of checksum failure, mode(%d)", calibration_mode); } - if ((calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) || - (calibration_mode != PHY_RF_CAL_FULL && ret == ESP_CAL_DATA_CHECK_FAIL)) { + if ((calibration_mode != PHY_RF_CAL_NONE) && ((err != ESP_OK) || (ret == ESP_CAL_DATA_CHECK_FAIL))) { err = esp_phy_store_cal_data_to_nvs(cal_data); } else { err = ESP_OK; diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index 3058381fbd0e..d7f0ee7d3b87 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -2,7 +2,7 @@ menu "Power Management" config PM_ENABLE bool "Support for power management" # SMP FreeRTOS currently does not support power management IDF-4997 - depends on !FREERTOS_SMP || __DOXYGEN__ + depends on (!FREERTOS_SMP && SOC_PM_SUPPORTED) || __DOXYGEN__ default n help If enabled, application is compiled with support for power management. @@ -84,7 +84,8 @@ menu "Power Management" config PM_CHECK_SLEEP_RETENTION_FRAME bool - depends on PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP + depends on (PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP || \ + (SOC_CPU_IN_TOP_DOMAIN && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)) default y if IDF_CI_BUILD default n help @@ -141,8 +142,8 @@ menu "Power Management" config PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP bool "Power down Digital Peripheral in light sleep (EXPERIMENTAL)" - depends on SOC_PM_SUPPORT_TOP_PD - select PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP + depends on SOC_PM_SUPPORT_TOP_PD && SOC_PAU_SUPPORTED + select PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP if !SOC_CPU_IN_TOP_DOMAIN default n #TODO: enable by default if periph init/deinit management supported (WIFI-5252) help If enabled, digital peripherals will be powered down in light sleep, it will reduce sleep diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index d4be371ce406..8216d8a8607a 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -29,7 +29,7 @@ entries: sleep_gpio:gpio_sleep_mode_config_apply (noflash) if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y && (PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || SOC_PM_SUPPORT_TAGMEM_PD = y): sleep_cpu:sleep_enable_cpu_retention (noflash) - if PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y: + if PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || (SOC_CPU_IN_TOP_DOMAIN = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y): sleep_cpu:cpu_domain_pd_allowed (noflash) if SOC_PM_SUPPORT_TOP_PD = y: sleep_clock:clock_domain_pd_allowed (noflash) diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 3159ba3703c1..37d76df5d106 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -372,7 +372,7 @@ static esp_err_t esp_pm_sleep_configure(const void *vconfig) esp_err_t err = ESP_OK; const esp_pm_config_t* config = (const esp_pm_config_t*) vconfig; -#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP +#if ESP_SLEEP_POWER_DOWN_CPU err = sleep_cpu_configure(config->light_sleep_enable); if (err != ESP_OK) { return err; diff --git a/components/esp_pm/test_apps/.build-test-rules.yml b/components/esp_pm/test_apps/.build-test-rules.yml index 8aece557bd35..67cf500b6ce3 100644 --- a/components/esp_pm/test_apps/.build-test-rules.yml +++ b/components/esp_pm/test_apps/.build-test-rules.yml @@ -4,6 +4,7 @@ components/esp_pm/test_apps: enable: - if: INCLUDE_DEFAULT == 1 disable: + - if: CONFIG_NAME == "pm_pd_top_sleep" and IDF_TARGET not in ["esp32c6", "esp32h2", "esp32p4"] - if: IDF_TARGET == "esp32c5" temporary: true reason: not support yet # TODO: [ESP32C5] IDF-8643 diff --git a/components/esp_pm/test_apps/esp_pm/main/test_pm.c b/components/esp_pm/test_apps/esp_pm/main/test_pm.c index 8ce1178db808..dfba174a2433 100644 --- a/components/esp_pm/test_apps/esp_pm/main/test_pm.c +++ b/components/esp_pm/test_apps/esp_pm/main/test_pm.c @@ -226,8 +226,9 @@ TEST_CASE("Can wake up from automatic light sleep by GPIO", "[pm][ignore]") printf("%lld %lld %u\n", end_rtc - start_rtc, end_hs - start_hs, end_tick - start_tick); TEST_ASSERT_INT32_WITHIN(3, delay_ticks, end_tick - start_tick); - TEST_ASSERT_INT32_WITHIN(2 * portTICK_PERIOD_MS * 1000, delay_ms * 1000, end_hs - start_hs); - TEST_ASSERT_INT32_WITHIN(2 * portTICK_PERIOD_MS * 1000, delay_ms * 1000, end_rtc - start_rtc); + // Error tolerance is 2 tick + duration * 5% + TEST_ASSERT_INT32_WITHIN((2 * portTICK_PERIOD_MS + delay_ms / 20) * 1000, delay_ms * 1000, end_hs - start_hs); + TEST_ASSERT_INT32_WITHIN((2 * portTICK_PERIOD_MS + delay_ms / 20) * 1000, delay_ms * 1000, end_rtc - start_rtc); } REG_CLR_BIT(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].hold_force); rtc_gpio_deinit(ext1_wakeup_gpio); @@ -277,13 +278,15 @@ TEST_CASE("vTaskDelay duration is correct with light sleep enabled", "[pm]") xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void *) &args, 3, NULL, 0); TEST_ASSERT( xSemaphoreTake(done_sem, delay_ms * 10 / portTICK_PERIOD_MS) ); printf("CPU0: %d %d\n", args.delay_us, args.result); - TEST_ASSERT_INT32_WITHIN(1000 * portTICK_PERIOD_MS * 2, args.delay_us, args.result); + // Error tolerance is 2 tick + duration * 5% + TEST_ASSERT_INT32_WITHIN((portTICK_PERIOD_MS * 2 + args.delay_us / 20) * 1000, args.delay_us, args.result); #if CONFIG_FREERTOS_NUMBER_OF_CORES == 2 xTaskCreatePinnedToCore(test_delay_task, "", 2048, (void *) &args, 3, NULL, 1); TEST_ASSERT( xSemaphoreTake(done_sem, delay_ms * 10 / portTICK_PERIOD_MS) ); printf("CPU1: %d %d\n", args.delay_us, args.result); - TEST_ASSERT_INT32_WITHIN(1000 * portTICK_PERIOD_MS * 2, args.delay_us, args.result); + // Error tolerance is 2 tick + duration * 5% + TEST_ASSERT_INT32_WITHIN((portTICK_PERIOD_MS * 2 + args.delay_us / 20) * 1000, args.delay_us, args.result); #endif } vSemaphoreDelete(done_sem); diff --git a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py index 9d7ff9eaffb1..a2c2fc0f7656 100644 --- a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py +++ b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded import Dut @@ -42,3 +42,18 @@ def test_esp_attr_xip_psram_esp32s2(dut: Dut) -> None: ) def test_esp_attr_xip_psram_esp32s3(dut: Dut) -> None: dut.run_all_single_board_cases() + + +# power down CPU and TOP domain in auto-lightsleep +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.esp32p4 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'pm_pd_top_sleep' + ], +) +def test_esp_pd_top_and_cpu_sleep(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.pm_pd_top_sleep b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.pm_pd_top_sleep new file mode 100644 index 000000000000..5658858b8508 --- /dev/null +++ b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.pm_pd_top_sleep @@ -0,0 +1 @@ +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y diff --git a/components/esp_psram/CMakeLists.txt b/components/esp_psram/CMakeLists.txt index 41068ce78d46..a9693334d418 100644 --- a/components/esp_psram/CMakeLists.txt +++ b/components/esp_psram/CMakeLists.txt @@ -16,14 +16,25 @@ endif() set(srcs) if(CONFIG_SPIRAM) - list(APPEND srcs "esp_psram.c" - "mmu_psram_flash.c") + list(APPEND srcs "esp_psram.c") if(${target} STREQUAL "esp32") list(APPEND srcs "esp32/esp_psram_extram_cache.c" "esp32/esp_himem.c") endif() + if(${target} STREQUAL "esp32s2") + list(APPEND srcs "mmu_psram_flash.c") + endif() + + if(${target} STREQUAL "esp32s3") + list(APPEND srcs "mmu_psram_flash.c") + endif() + + if(CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM) + list(APPEND srcs "mmu_psram_flash_v2.c") + endif() + if(CONFIG_SPIRAM_MODE_QUAD) list(APPEND srcs "${target}/esp_psram_impl_quad.c") elseif(CONFIG_SPIRAM_MODE_OCT) diff --git a/components/esp_psram/device/esp_psram_impl_ap_hex.c b/components/esp_psram/device/esp_psram_impl_ap_hex.c index 82a1b4e0b832..7832460eb387 100644 --- a/components/esp_psram/device/esp_psram_impl_ap_hex.c +++ b/components/esp_psram/device/esp_psram_impl_ap_hex.c @@ -384,8 +384,8 @@ esp_err_t esp_psram_impl_enable(void) s_configure_psram_ecc(); #endif //enter MSPI slow mode to init PSRAM device registers - psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, 40); - psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, 40); + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_MPLL_DEFAULT_FREQ_MHZ / CONFIG_SPIRAM_SPEED); + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, AP_HEX_PSRAM_MPLL_DEFAULT_FREQ_MHZ / CONFIG_SPIRAM_SPEED); psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_2, true); psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_3, true); diff --git a/components/esp_psram/esp32p4/Kconfig.spiram b/components/esp_psram/esp32p4/Kconfig.spiram index ea37e7f54b7f..f17fb795eeca 100644 --- a/components/esp_psram/esp32p4/Kconfig.spiram +++ b/components/esp_psram/esp32p4/Kconfig.spiram @@ -44,6 +44,45 @@ menu "PSRAM config" default 100 if SPIRAM_SPEED_100M default 200 if SPIRAM_SPEED_200M + config SPIRAM_FETCH_INSTRUCTIONS + bool + help + Enable this option allows moving application's instruction segment from the SPI Flash to + PSRAM + + config SPIRAM_RODATA + bool + help + Enable this option allows moving application's rodata segment from the SPI Flash to + PSRAM + + config SPIRAM_XIP_FROM_PSRAM + bool "Enable Executable in place from (XiP) from PSRAM feature (READ HELP)" + default n + select SPIRAM_FETCH_INSTRUCTIONS + select SPIRAM_RODATA + select SPIRAM_FLASH_LOAD_TO_PSRAM + help + If enabled, firmware in flash including instructions and data will be moved into PSRAM on startup, + firmware code will execute directly from PSRAM. + + With this option enabled, code that requires execution during an MSPI1 Flash operation + does not have to be placed in IRAM. Therefore codes that need to be executing during Flash + operations can continue working normally. + + Because P4 flash and PSRAM are using two separate SPI buses, moving flash content to PSRAM will + actually increase the load of the PSRAM MSPI bus, so the exact impact on performance will be dependent + on your app usage of PSRAM. For example, as the PSRAM bus speed could be much faster than flash bus speed, + if the instructions and data that are used to be in flash are not accessed very frequently, you might + get better performance with this option enabled. We suggest doing performance profiling to determine + if enabling this option. + + config SPIRAM_FLASH_LOAD_TO_PSRAM + bool + help + This is a helper indicating this condition: + `CONFIG_SPIRAM_XIP_FROM_PSRAM && CONFIG_IDF_TARGET_ESP32P4` + config SPIRAM_ECC_ENABLE bool "Enable PSRAM ECC" default n diff --git a/components/esp_psram/esp32s2/Kconfig.spiram b/components/esp_psram/esp32s2/Kconfig.spiram index e732ac147b78..1af865756aaf 100644 --- a/components/esp_psram/esp32s2/Kconfig.spiram +++ b/components/esp_psram/esp32s2/Kconfig.spiram @@ -47,25 +47,39 @@ menu "SPI RAM config" int default 26 + config SPIRAM_XIP_FROM_PSRAM + bool "Enable Executable in place from (XiP) from PSRAM feature" + default n + select SPIRAM_FETCH_INSTRUCTIONS + select SPIRAM_RODATA + help + Helper for selecting both `SPIRAM_FETCH_INSTRUCTIONS` and `SPIRAM_RODATA` + config SPIRAM_FETCH_INSTRUCTIONS bool "Move Instructions in Flash to PSRAM" default n help If enabled, instructions in flash will be moved into PSRAM on startup. - If SPIRAM_RODATA is also enabled, code that requires execution during an SPI1 Flash operation - can forgo being placed in IRAM, thus optimizing RAM usage (see External RAM documentation - for more details). + If SPIRAM_RODATA is also enabled, code that requires execution during an MSPI1 Flash operation + can forgo being placed in IRAM. Therefore codes that need to be executing during Flash + operation can continue working normally. + This feature is useful for high throughput peripheral involved applications to improve + the performance during MSPI1 flash operations. PSRAM access speed is faster than Flash access. + So the performance is better. (see External RAM documentation for more details). config SPIRAM_RODATA bool "Move Read-Only Data in Flash to PSRAM" default n help If enabled, rodata in flash will be moved into PSRAM on startup. - If SPIRAM_FETCH_INSTRUCTIONS is also enabled, code that requires execution during an SPI1 Flash operation - can forgo being placed in IRAM, thus optimizing RAM usage (see External RAM documentation - for more details). + If SPIRAM_FETCH_INSTRUCTIONS is also enabled, code that requires execution during an MSPI1 Flash operation + is not necessary to be placed in IRAM. Therefore codes that need to be executing during Flash + operation can continue working normally. + This feature is useful for high throughput peripheral involved applications to improve + the performance during MSPI1 flash operations. PSRAM access speed is faster than Flash access. + So the performance is better. (see External RAM documentation for more details). choice SPIRAM_SPEED prompt "Set RAM clock speed" diff --git a/components/esp_psram/esp32s3/Kconfig.spiram b/components/esp_psram/esp32s3/Kconfig.spiram index fe97ed014f78..8152ff680a0b 100644 --- a/components/esp_psram/esp32s3/Kconfig.spiram +++ b/components/esp_psram/esp32s3/Kconfig.spiram @@ -56,24 +56,39 @@ menu "SPI RAM config" int default 26 + config SPIRAM_XIP_FROM_PSRAM + bool "Enable Executable in place from (XiP) from PSRAM feature" + default n + select SPIRAM_FETCH_INSTRUCTIONS + select SPIRAM_RODATA + help + Helper for selecting both `SPIRAM_FETCH_INSTRUCTIONS` and `SPIRAM_RODATA` + config SPIRAM_FETCH_INSTRUCTIONS bool "Move Instructions in Flash to PSRAM" default n help If enabled, instructions in flash will be moved into PSRAM on startup. - If SPIRAM_RODATA is also enabled, code that requires execution during an SPI1 Flash operation - can forgo being placed in IRAM, thus optimizing RAM usage (see External RAM documentation - for more details). + If SPIRAM_RODATA is also enabled, code that requires execution during an MSPI1 Flash operation + can forgo being placed in IRAM. Therefore codes that need to be executing during Flash + operation can continue working normally. + This feature is useful for high throughput peripheral involved applications to improve + the performance during MSPI1 flash operations. PSRAM access speed is faster than Flash access. + So the performance is better. (see External RAM documentation for more details). config SPIRAM_RODATA bool "Move Read-Only Data in Flash to PSRAM" default n help If enabled, rodata in flash will be moved into PSRAM on startup. - If SPIRAM_FETCH_INSTRUCTIONS is also enabled, code that requires execution during an SPI1 Flash operation - can forgo being placed in IRAM, thus optimizing RAM usage (see External RAM documentation - for more details). + If SPIRAM_FETCH_INSTRUCTIONS is also enabled, code that requires execution during an MSPI1 Flash operation + is not necessary to be placed in IRAM. Therefore codes that need to be executing during Flash + operation can continue working normally. + + This feature is useful for high throughput peripheral involved applications to improve + the performance during MSPI1 flash operations. PSRAM access speed is faster than Flash access. + So the performance is better. (see External RAM documentation for more details). choice SPIRAM_SPEED prompt "Set RAM clock speed" diff --git a/components/esp_psram/esp32s3/esp_psram_impl_quad.c b/components/esp_psram/esp32s3/esp_psram_impl_quad.c index 12a428d3d770..cd76304092bb 100644 --- a/components/esp_psram/esp32s3/esp_psram_impl_quad.c +++ b/components/esp_psram/esp32s3/esp_psram_impl_quad.c @@ -24,44 +24,46 @@ static const char* TAG = "quad_psram"; //Commands for PSRAM chip -#define PSRAM_READ 0x03 -#define PSRAM_FAST_READ 0x0B -#define PSRAM_FAST_READ_QUAD 0xEB -#define PSRAM_WRITE 0x02 -#define PSRAM_QUAD_WRITE 0x38 -#define PSRAM_ENTER_QMODE 0x35 -#define PSRAM_EXIT_QMODE 0xF5 -#define PSRAM_RESET_EN 0x66 -#define PSRAM_RESET 0x99 -#define PSRAM_SET_BURST_LEN 0xC0 -#define PSRAM_DEVICE_ID 0x9F - -#define PSRAM_FAST_READ_DUMMY 4 -#define PSRAM_FAST_READ_QUAD_DUMMY 6 +#define PSRAM_READ 0x03 +#define PSRAM_FAST_READ 0x0B +#define PSRAM_FAST_READ_QUAD 0xEB +#define PSRAM_WRITE 0x02 +#define PSRAM_QUAD_WRITE 0x38 +#define PSRAM_ENTER_QMODE 0x35 +#define PSRAM_EXIT_QMODE 0xF5 +#define PSRAM_RESET_EN 0x66 +#define PSRAM_RESET 0x99 +#define PSRAM_SET_BURST_LEN 0xC0 +#define PSRAM_DEVICE_ID 0x9F + +#define PSRAM_FAST_READ_DUMMY 4 +#define PSRAM_FAST_READ_QUAD_DUMMY 6 // ID -#define PSRAM_ID_KGD_M 0xff -#define PSRAM_ID_KGD_S 8 -#define PSRAM_ID_KGD 0x5d -#define PSRAM_ID_EID_M 0xff -#define PSRAM_ID_EID_S 16 - -// Use the [7:5](bit7~bit5) of EID to distinguish the psram size: +#define PSRAM_ID_BITS_NUM 24 +#define PSRAM_EID_BITS_NUM 48 +#define PSRAM_ID_KGD_M 0xff +#define PSRAM_ID_KGD_S 8 +#define PSRAM_ID_KGD 0x5d +#define PSRAM_ID_EID_BIT_47_40_M 0xff +#define PSRAM_ID_EID_BIT_47_40_S 16 + +// Use the [47:45](bit47~bit45) of EID to distinguish the psram size: // -// BIT7 | BIT6 | BIT5 | SIZE(MBIT) +// BIT47 | BIT46 | BIT45 | SIZE(MBIT) // ------------------------------------- -// 0 | 0 | 0 | 16 -// 0 | 0 | 1 | 32 -// 0 | 1 | 0 | 64 -#define PSRAM_EID_SIZE_M 0x07 -#define PSRAM_EID_SIZE_S 5 +// 0 | 0 | 0 | 16 +// 0 | 0 | 1 | 32 +// 0 | 1 | 0 | 64 +#define PSRAM_EID_BIT_47_45_M 0x07 +#define PSRAM_EID_BIT_47_45_S 5 -#define PSRAM_KGD(id) (((id) >> PSRAM_ID_KGD_S) & PSRAM_ID_KGD_M) -#define PSRAM_EID(id) (((id) >> PSRAM_ID_EID_S) & PSRAM_ID_EID_M) -#define PSRAM_SIZE_ID(id) ((PSRAM_EID(id) >> PSRAM_EID_SIZE_S) & PSRAM_EID_SIZE_M) -#define PSRAM_IS_VALID(id) (PSRAM_KGD(id) == PSRAM_ID_KGD) +#define PSRAM_KGD(id) (((id) >> PSRAM_ID_KGD_S) & PSRAM_ID_KGD_M) +#define PSRAM_EID_BIT_47_40(id) (((id) >> PSRAM_ID_EID_BIT_47_40_S) & PSRAM_ID_EID_BIT_47_40_M) +#define PSRAM_SIZE_ID(id) ((PSRAM_EID_BIT_47_40(id) >> PSRAM_EID_BIT_47_45_S) & PSRAM_EID_BIT_47_45_M) +#define PSRAM_IS_VALID(id) (PSRAM_KGD(id) == PSRAM_ID_KGD) -#define PSRAM_IS_64MBIT_TRIAL(id) (PSRAM_EID(id) == 0x26) +#define PSRAM_IS_64MBIT_TRIAL(id) (PSRAM_EID_BIT_47_40(id) == 0x26) // IO-pins for PSRAM. // WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines @@ -241,15 +243,15 @@ bool psram_support_wrap_size(uint32_t wrap_size) } //Read ID operation only supports SPI CMD and mode, should issue `psram_disable_qio_mode` before calling this -static void psram_read_id(int spi_num, uint32_t* dev_id) +static void psram_read_id(int spi_num, uint8_t* dev_id, int id_bits) { psram_exec_cmd(spi_num, PSRAM_CMD_SPI, PSRAM_DEVICE_ID, 8, /* command and command bit len*/ 0, 24, /* address and address bit len*/ 0, /* dummy bit len */ NULL, 0, /* tx data and tx bit len*/ - (uint8_t*) dev_id, 24, /* rx data and rx bit len*/ - CS_PSRAM_SEL, /* cs bit mask*/ + dev_id, id_bits, /* rx data and rx bit len*/ + CS_PSRAM_SEL, /* cs bit mask*/ false); /* whether is program/erase operation */ } @@ -302,6 +304,24 @@ static void psram_gpio_config(void) esp_gpio_reserve(BIT64(cs1_io) | BIT64(wp_io)); } +/** + * For certain wafer version and 8MB case, we consider it as 4MB mode as it uses 2T mode + */ +bool s_check_aps3204_2tmode(void) +{ + uint64_t full_eid = 0; + psram_read_id(SPI1_NUM, (uint8_t *)&full_eid, PSRAM_EID_BITS_NUM); + + bool is_2t = false; + uint32_t eid_47_16 = __builtin_bswap32((full_eid >> 16) & UINT32_MAX); + ESP_EARLY_LOGD(TAG, "full_eid: 0x%" PRIx64", eid_47_16: 0x%"PRIx32", (eid_47_16 >> 5) & 0xfffff: 0x%"PRIx32, full_eid, eid_47_16, (eid_47_16 >> 5) & 0xfffff); + if (((eid_47_16 >> 5) & 0xfffff) == 0x8a445) { + is_2t = true; + } + + return is_2t; +} + esp_err_t esp_psram_impl_enable(void) //psram init { psram_gpio_config(); @@ -312,13 +332,13 @@ esp_err_t esp_psram_impl_enable(void) //psram init //We use SPI1 to init PSRAM psram_disable_qio_mode(SPI1_NUM); - psram_read_id(SPI1_NUM, &s_psram_id); + psram_read_id(SPI1_NUM, (uint8_t *)&s_psram_id, PSRAM_ID_BITS_NUM); if (!PSRAM_IS_VALID(s_psram_id)) { /* 16Mbit psram ID read error workaround: * treat the first read id as a dummy one as the pre-condition, * Send Read ID command again */ - psram_read_id(SPI1_NUM, &s_psram_id); + psram_read_id(SPI1_NUM, (uint8_t *)&s_psram_id, PSRAM_ID_BITS_NUM); if (!PSRAM_IS_VALID(s_psram_id)) { ESP_EARLY_LOGE(TAG, "PSRAM ID read error: 0x%08" PRIx32 ", PSRAM chip not found or not supported, or wrong PSRAM line mode", (uint32_t)s_psram_id); return ESP_ERR_NOT_SUPPORTED; @@ -334,6 +354,10 @@ esp_err_t esp_psram_impl_enable(void) //psram init density == 0x2 ? PSRAM_SIZE_8MB : 0; } + if ((s_psram_size == PSRAM_SIZE_8MB) && s_check_aps3204_2tmode()) { + s_psram_size = PSRAM_SIZE_4MB; + } + //SPI1: send psram reset command psram_reset_mode(SPI1_NUM); //SPI1: send QPI enable command diff --git a/components/esp_psram/esp_psram.c b/components/esp_psram/esp_psram.c index 7064c84b2bdd..debbf9de31b6 100644 --- a/components/esp_psram/esp_psram.c +++ b/components/esp_psram/esp_psram.c @@ -5,12 +5,13 @@ */ /*---------------------------------------------------------------------------------------------------- - * Abstraction layer for PSRAM. PSRAM device related registers and MMU/Cache related code shouls be + * Abstraction layer for PSRAM. PSRAM device related registers and MMU/Cache related code should be * abstracted to lower layers. * * When we add more types of external RAM memory, this can be made into a more intelligent dispatcher. *----------------------------------------------------------------------------------------------------*/ #include +#include #include "sdkconfig.h" #include "esp_attr.h" #include "esp_err.h" @@ -20,6 +21,7 @@ #include "hal/mmu_hal.h" #include "hal/mmu_ll.h" #include "hal/cache_ll.h" +#include "soc/soc_caps.h" #include "esp_private/esp_psram_io.h" #include "esp_private/esp_psram_extram.h" #include "esp_private/mmu_psram_flash.h" @@ -43,6 +45,12 @@ #define PSRAM_MEM_8BIT_ALIGNED 0 #define PSRAM_MEM_32BIT_ALIGNED 1 +#if CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM +#define PSRAM_EARLY_LOGI ESP_DRAM_LOGI +#else +#define PSRAM_EARLY_LOGI ESP_EARLY_LOGI +#endif + #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY extern uint8_t _ext_ram_bss_start; extern uint8_t _ext_ram_bss_end; @@ -80,7 +88,7 @@ typedef struct { } psram_ctx_t; static psram_ctx_t s_psram_ctx; -static const char* TAG = "esp_psram"; +static const DRAM_ATTR char TAG[] = "esp_psram"; ESP_SYSTEM_INIT_FN(init_psram, CORE, BIT(0), 103) { @@ -120,7 +128,7 @@ static void IRAM_ATTR s_mapping(int v_start, int size) } #endif //CONFIG_IDF_TARGET_ESP32 -esp_err_t esp_psram_init(void) +static esp_err_t s_psram_chip_init(uint32_t *out_available_size) { if (s_psram_ctx.is_initialised) { return ESP_ERR_INVALID_STATE; @@ -140,8 +148,8 @@ esp_err_t esp_psram_init(void) ret = esp_psram_impl_get_physical_size(&psram_physical_size); assert(ret == ESP_OK); - ESP_EARLY_LOGI(TAG, "Found %" PRIu32 "MB PSRAM device", psram_physical_size / (1024 * 1024)); - ESP_EARLY_LOGI(TAG, "Speed: %dMHz", CONFIG_SPIRAM_SPEED); + PSRAM_EARLY_LOGI(TAG, "Found %" PRIu32 "MB PSRAM device", psram_physical_size / (1024 * 1024)); + PSRAM_EARLY_LOGI(TAG, "Speed: %dMHz", CONFIG_SPIRAM_SPEED); #if CONFIG_IDF_TARGET_ESP32 #if CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE ESP_EARLY_LOGI(TAG, "PSRAM initialized, cache is in normal (1-core) mode."); @@ -154,7 +162,16 @@ esp_err_t esp_psram_init(void) ret = esp_psram_impl_get_available_size(&psram_available_size); assert(ret == ESP_OK); - __attribute__((unused)) uint32_t total_available_size = psram_available_size; + *out_available_size = psram_available_size; + + return ESP_OK; +} + +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA +static void s_xip_psram_placement(uint32_t *psram_available_size, uint32_t *out_start_page) +{ + __attribute__((unused)) uint32_t total_available_size = *psram_available_size; + uint32_t available_size = *psram_available_size; /** * `start_page` is the psram physical address in MMU page size. * MMU page size on ESP32S2 is 64KB @@ -162,10 +179,21 @@ esp_err_t esp_psram_init(void) * * Here we plan to copy FLASH instructions to psram physical address 0, which is the No.0 page. */ - __attribute__((unused)) uint32_t start_page = 0; -#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA + uint32_t start_page = 0; uint32_t used_page = 0; -#endif + esp_err_t ret = ESP_FAIL; + + //------------------------------------Copy Flash .rodata to PSRAM-------------------------------------// +#if CONFIG_SPIRAM_RODATA + ret = mmu_config_psram_rodata_segment(start_page, total_available_size, &used_page); + if (ret != ESP_OK) { + ESP_EARLY_LOGE(TAG, "No enough psram memory for rodata!"); + abort(); + } + start_page += used_page; + available_size -= MMU_PAGE_TO_BYTES(used_page); + ESP_EARLY_LOGV(TAG, "after copy .rodata, used page is %d, start_page is %d, available_size is %d B", used_page, start_page, available_size); +#endif //#if CONFIG_SPIRAM_RODATA //------------------------------------Copy Flash .text to PSRAM-------------------------------------// #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS @@ -175,22 +203,18 @@ esp_err_t esp_psram_init(void) abort(); } start_page += used_page; - psram_available_size -= MMU_PAGE_TO_BYTES(used_page); + available_size -= MMU_PAGE_TO_BYTES(used_page); ESP_EARLY_LOGV(TAG, "after copy .text, used page is %" PRIu32 ", start_page is %" PRIu32 ", psram_available_size is %" PRIu32 " B", used_page, start_page, psram_available_size); #endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS - //------------------------------------Copy Flash .rodata to PSRAM-------------------------------------// -#if CONFIG_SPIRAM_RODATA - ret = mmu_config_psram_rodata_segment(start_page, total_available_size, &used_page); - if (ret != ESP_OK) { - ESP_EARLY_LOGE(TAG, "No enough psram memory for rodata!"); - abort(); - } - start_page += used_page; - psram_available_size -= MMU_PAGE_TO_BYTES(used_page); - ESP_EARLY_LOGV(TAG, "after copy .rodata, used page is %" PRIu32 ", start_page is %" PRIu32 ", psram_available_size is %" PRIu32 " B", used_page, start_page, psram_available_size); -#endif //#if CONFIG_SPIRAM_RODATA + *psram_available_size = available_size; + *out_start_page = start_page; +} +#endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA +static void s_psram_mapping(uint32_t psram_available_size, uint32_t start_page) +{ + esp_err_t ret = ESP_FAIL; //----------------------------------Map the PSRAM physical range to MMU-----------------------------// /** * @note 2 @@ -213,7 +237,7 @@ esp_err_t esp_psram_init(void) s_mapping((int)v_start_8bit_aligned, size_to_map); #else uint32_t actual_mapped_len = 0; -#if MMU_LL_MMU_PER_TARGET +#if SOC_MMU_PER_EXT_MEM_TARGET mmu_hal_map_region(1, MMU_TARGET_PSRAM0, (intptr_t)v_start_8bit_aligned, MMU_PAGE_TO_BYTES(start_page), size_to_map, &actual_mapped_len); #else mmu_hal_map_region(0, MMU_TARGET_PSRAM0, (intptr_t)v_start_8bit_aligned, MMU_PAGE_TO_BYTES(start_page), size_to_map, &actual_mapped_len); @@ -280,7 +304,7 @@ esp_err_t esp_psram_init(void) } /*------------------------------------------------------------------------------ - * After mapping, we DON'T care about the PSRAM PHYSICAL ADDRESSS ANYMORE! + * After mapping, we DON'T care about the PSRAM PHYSICAL ADDRESS ANYMORE! *----------------------------------------------------------------------------*/ //------------------------------------Configure .bss in PSRAM-------------------------------------// @@ -302,6 +326,31 @@ esp_err_t esp_psram_init(void) #if CONFIG_IDF_TARGET_ESP32 s_psram_ctx.regions_to_heap[PSRAM_MEM_8BIT_ALIGNED].size -= esp_himem_reserved_area_size() - 1; #endif +} + +esp_err_t esp_psram_init(void) +{ + esp_err_t ret = ESP_FAIL; + uint32_t psram_available_size = 0; + ret = s_psram_chip_init(&psram_available_size); + if (ret != ESP_OK) { + return ret; + } + + /** + * `start_page` is the psram physical address in MMU page size. + * MMU page size on ESP32S2 is 64KB + * e.g.: psram physical address 16 is in page 0 + * + * Here we plan to copy FLASH instructions to psram physical address 0, which is the No.0 page. + */ + __attribute__((unused)) uint32_t start_page = 0; + +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA + s_xip_psram_placement(&psram_available_size, &start_page); +#endif + + s_psram_mapping(psram_available_size, start_page); //will be removed, TODO: IDF-6944 #if CONFIG_IDF_TARGET_ESP32 @@ -473,3 +522,11 @@ bool esp_psram_extram_test(void) return true; } + +void esp_psram_bss_init(void) +{ +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + size_t size = (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start); + memset(&_ext_ram_bss_start, 0, size); +#endif +} diff --git a/components/esp_psram/include/esp_private/esp_psram_extram.h b/components/esp_psram/include/esp_private/esp_psram_extram.h index 5cd7e52a1537..0b44e1bfd873 100644 --- a/components/esp_psram/include/esp_private/esp_psram_extram.h +++ b/components/esp_psram/include/esp_private/esp_psram_extram.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -55,6 +55,11 @@ esp_err_t esp_psram_extram_reserve_dma_pool(size_t size); */ bool esp_psram_extram_test(void); +/** + * @brief Init .bss on psram + */ +void esp_psram_bss_init(void); + #if CONFIG_IDF_TARGET_ESP32 /** * @brief Force a writeback of the data in the PSRAM cache. This is to be called whenever diff --git a/components/esp_psram/include/esp_private/mmu_psram_flash.h b/components/esp_psram/include/esp_private/mmu_psram_flash.h index b45b14010002..554ab77d164a 100644 --- a/components/esp_psram/include/esp_private/mmu_psram_flash.h +++ b/components/esp_psram/include/esp_private/mmu_psram_flash.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,6 +63,18 @@ esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_si /*---------------------------------------------------------------------------- Part 2 APIs (See @Backgrounds on top of this file) -------------------------------------------------------------------------------*/ +#if CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM +/** + * TODO: IDF-9049 + * @brief Vaddr to paddr, when XIP on PSRAM + * @note This API only works for the original flash.text and flash.rodata, others vaddrs will return UINT32_MAX + * + * @param[in] ptr Pointer + * + * @return Pointer corresponding physical addr + */ +size_t mmu_xip_psram_flash_vaddr_to_paddr(const void *ptr); +#else #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS /** * @brief Init other file requested MMU variables @@ -130,6 +142,7 @@ uint32_t rodata_flash_end_page_get(void); */ int rodata_flash2spiram_offset(void); #endif // #if CONFIG_SPIRAM_RODATA +#endif // #if CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM #ifdef __cplusplus } diff --git a/components/esp_psram/linker.lf b/components/esp_psram/linker.lf index 389c28abcfde..1069e7823131 100644 --- a/components/esp_psram/linker.lf +++ b/components/esp_psram/linker.lf @@ -16,3 +16,10 @@ entries: if SPIRAM_MODE_HEX = y: esp_psram_impl_ap_hex (noflash) + + if SPIRAM_FLASH_LOAD_TO_PSRAM = y: + esp_psram_impl_ap_hex (noflash) + mmu_psram_flash_v2 (noflash) + esp_psram: esp_psram_init (noflash) + esp_psram: s_psram_chip_init (noflash) + esp_psram: s_xip_psram_placement (noflash) diff --git a/components/esp_psram/mmu_psram_flash_v2.c b/components/esp_psram/mmu_psram_flash_v2.c new file mode 100644 index 000000000000..0ae669c838a8 --- /dev/null +++ b/components/esp_psram/mmu_psram_flash_v2.c @@ -0,0 +1,173 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief + * This is for P4 and future chips with similar arch. + * The XIP PSRAM is done by CPU copy, v1(see mmu_psram_flash.c) is done by Cache copy + */ + +#include +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_attr.h" +#include "esp_err.h" +#include "soc/ext_mem_defs.h" +#include "hal/mmu_hal.h" +#include "hal/mmu_ll.h" +#include "hal/cache_hal.h" +#include "esp_private/mmu_psram_flash.h" +#include "esp_mmu_map.h" +#include "esp_heap_caps.h" +#include "esp_private/image_process.h" + +#define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) +#define ALIGN_DOWN_BY(num, align) ((num) & (~((align) - 1))) + +extern int _instruction_reserved_start; +extern int _instruction_reserved_end; +extern int _rodata_reserved_start; +extern int _rodata_reserved_end; + +const static char *TAG = "mmu_psram"; +static uint32_t s_irom_vaddr_start; +static uint32_t s_drom_vaddr_start; +static size_t s_irom_size; +static size_t s_drom_size; +static int s_irom_paddr_offset; +static int s_drom_paddr_offset; + +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA +static uint32_t s_do_load_from_flash(uint32_t flash_paddr_start, uint32_t size, uint32_t target_vaddr_start, uint32_t target_paddr_start) +{ + uint32_t flash_end_page_vaddr = SOC_DRAM_FLASH_ADDRESS_HIGH - CONFIG_MMU_PAGE_SIZE; + ESP_EARLY_LOGV(TAG, "flash_paddr_start: 0x%"PRIx32", flash_end_page_vaddr: 0x%"PRIx32", size: 0x%"PRIx32", target_vaddr_start: 0x%"PRIx32, flash_paddr_start, flash_end_page_vaddr, size, target_vaddr_start); + assert((flash_paddr_start % CONFIG_MMU_PAGE_SIZE) == 0); + assert((flash_end_page_vaddr % CONFIG_MMU_PAGE_SIZE) == 0); + assert((target_vaddr_start % CONFIG_MMU_PAGE_SIZE) == 0); + + uint32_t mapped_size = 0; + while (mapped_size < size) { + uint32_t actual_mapped_len = 0; + mmu_hal_map_region(MMU_LL_PSRAM_MMU_ID, MMU_TARGET_PSRAM0, target_vaddr_start, target_paddr_start + mapped_size, CONFIG_MMU_PAGE_SIZE, &actual_mapped_len); + assert(actual_mapped_len == CONFIG_MMU_PAGE_SIZE); + + mmu_hal_map_region(MMU_LL_FLASH_MMU_ID, MMU_TARGET_FLASH0, flash_end_page_vaddr, flash_paddr_start + mapped_size, CONFIG_MMU_PAGE_SIZE, &actual_mapped_len); + assert(actual_mapped_len == CONFIG_MMU_PAGE_SIZE); + + cache_hal_invalidate_addr(target_vaddr_start, CONFIG_MMU_PAGE_SIZE); + cache_hal_invalidate_addr(flash_end_page_vaddr, CONFIG_MMU_PAGE_SIZE); + memcpy((void *)target_vaddr_start, (void *)flash_end_page_vaddr, CONFIG_MMU_PAGE_SIZE); + + ESP_EARLY_LOGV(TAG, "target_vaddr_start: 0x%"PRIx32, target_vaddr_start); + mapped_size += CONFIG_MMU_PAGE_SIZE; + target_vaddr_start += CONFIG_MMU_PAGE_SIZE; + } + + ESP_EARLY_LOGV(TAG, "mapped_size: 0x%"PRIx32, mapped_size); + assert(mapped_size == ALIGN_UP_BY(size, CONFIG_MMU_PAGE_SIZE)); + + return mapped_size; +} +#endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA + +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS +esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size, uint32_t *out_page) +{ + size_t irom_size = ALIGN_UP_BY((uint32_t)&_instruction_reserved_end, CONFIG_MMU_PAGE_SIZE) - ALIGN_DOWN_BY((uint32_t)&_instruction_reserved_start, CONFIG_MMU_PAGE_SIZE); + s_irom_size = irom_size; + + uint32_t flash_drom_paddr_start = 0; + uint32_t flash_irom_paddr_start = 0; + image_process_get_flash_segments_info(&flash_drom_paddr_start, &flash_irom_paddr_start); + flash_irom_paddr_start = ALIGN_DOWN_BY(flash_irom_paddr_start, CONFIG_MMU_PAGE_SIZE); + ESP_EARLY_LOGI(TAG, "flash_irom_paddr_start: 0x%x", flash_irom_paddr_start); + + if ((MMU_PAGE_TO_BYTES(start_page) + irom_size) > psram_size) { + ESP_EARLY_LOGE(TAG, "PSRAM space not enough for the Flash instructions, need %"PRId32" B, from %"PRId32" B to %"PRId32" B", irom_size, MMU_PAGE_TO_BYTES(start_page), MMU_PAGE_TO_BYTES(start_page) + irom_size); + return ESP_ERR_NO_MEM; + } + + uint32_t irom_load_addr_aligned = ALIGN_DOWN_BY((uint32_t)&_instruction_reserved_start, CONFIG_MMU_PAGE_SIZE); + s_irom_paddr_offset = flash_irom_paddr_start - MMU_PAGE_TO_BYTES(start_page); + s_irom_vaddr_start = irom_load_addr_aligned; + ESP_EARLY_LOGV(TAG, "flash_irom_paddr_start: 0x%"PRIx32", MMU_PAGE_TO_BYTES(start_page): 0x%"PRIx32", s_irom_paddr_offset: 0x%"PRIx32", s_irom_vaddr_start: 0x%"PRIx32, flash_irom_paddr_start, MMU_PAGE_TO_BYTES(start_page), s_irom_paddr_offset, s_irom_vaddr_start); + + uint32_t mapped_size = 0; + mapped_size = s_do_load_from_flash(flash_irom_paddr_start, irom_size, irom_load_addr_aligned, MMU_PAGE_TO_BYTES(start_page)); + cache_hal_writeback_addr(irom_load_addr_aligned, irom_size); + + ESP_EARLY_LOGV(TAG, "after mapping text, starting from paddr=0x%08"PRIx32" and vaddr=0x%08"PRIx32", 0x%"PRIx32" bytes are mapped", MMU_PAGE_TO_BYTES(start_page), irom_load_addr_aligned, mapped_size); + + start_page += BYTES_TO_MMU_PAGE(irom_size); + *out_page = start_page; + + return ESP_OK; +} +#endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS + +#if CONFIG_SPIRAM_RODATA +esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_size, uint32_t *out_page) +{ + size_t drom_size = ALIGN_UP_BY((uint32_t)&_rodata_reserved_end, CONFIG_MMU_PAGE_SIZE) - ALIGN_DOWN_BY((uint32_t)&_rodata_reserved_start, CONFIG_MMU_PAGE_SIZE); + s_drom_size = drom_size; + + uint32_t flash_drom_paddr_start = 0; + uint32_t flash_irom_paddr_start = 0; + image_process_get_flash_segments_info(&flash_drom_paddr_start, &flash_irom_paddr_start); + flash_drom_paddr_start = ALIGN_DOWN_BY(flash_drom_paddr_start, CONFIG_MMU_PAGE_SIZE); + ESP_EARLY_LOGI(TAG, "flash_drom_paddr_start: 0x%x", flash_drom_paddr_start); + + if ((MMU_PAGE_TO_BYTES(start_page) + drom_size) > psram_size) { + ESP_EARLY_LOGE(TAG, "PSRAM space not enough for the Flash rodata, need %"PRId32" B, from %"PRId32" B to %"PRId32" B", drom_size, MMU_PAGE_TO_BYTES(start_page), MMU_PAGE_TO_BYTES(start_page) + drom_size); + return ESP_ERR_NO_MEM; + } + + uint32_t drom_load_addr_aligned = ALIGN_DOWN_BY((uint32_t)&_rodata_reserved_start, CONFIG_MMU_PAGE_SIZE); + s_drom_paddr_offset = flash_drom_paddr_start - MMU_PAGE_TO_BYTES(start_page); + s_drom_vaddr_start = drom_load_addr_aligned; + ESP_EARLY_LOGV(TAG, "flash_drom_paddr_start: 0x%"PRIx32", MMU_PAGE_TO_BYTES(start_page): 0x%"PRIx32", s_drom_paddr_offset: 0x%"PRIx32", s_drom_vaddr_start: 0x%"PRIx32, flash_drom_paddr_start, MMU_PAGE_TO_BYTES(start_page), s_drom_paddr_offset, s_drom_vaddr_start); + + uint32_t mapped_size = 0; + mapped_size = s_do_load_from_flash(flash_drom_paddr_start, drom_size, drom_load_addr_aligned, MMU_PAGE_TO_BYTES(start_page)); + cache_hal_writeback_addr(drom_load_addr_aligned, drom_size); + + ESP_EARLY_LOGV(TAG, "after mapping rodata, starting from paddr=0x%08"PRIx32" and vaddr=0x%08"PRIx32", 0x%"PRIx32" bytes are mapped", MMU_PAGE_TO_BYTES(start_page), drom_load_addr_aligned, mapped_size); + + start_page += BYTES_TO_MMU_PAGE(drom_size); + *out_page = start_page; + + return ESP_OK; +} +#endif //#if CONFIG_SPIRAM_RODATA + +size_t mmu_xip_psram_flash_vaddr_to_paddr(const void *ptr) +{ + if (ptr == NULL) { + return UINT32_MAX; + } + + size_t paddr_on_flash = 0; + uint32_t psram_paddr = 0; + mmu_target_t target = MMU_TARGET_FLASH0; + + if ((uint32_t)ptr >= s_irom_vaddr_start && (uint32_t)ptr < (s_irom_vaddr_start + s_irom_size)) { + bool is_mapped = mmu_hal_vaddr_to_paddr(MMU_LL_PSRAM_MMU_ID, (uint32_t)ptr, &psram_paddr, &target); + assert(is_mapped); + assert(target == MMU_TARGET_PSRAM0); + paddr_on_flash = psram_paddr + s_irom_paddr_offset; + } else if ((uint32_t)ptr >= s_drom_vaddr_start && (uint32_t)ptr < (s_drom_vaddr_start + s_drom_size)) { + bool is_mapped = mmu_hal_vaddr_to_paddr(MMU_LL_PSRAM_MMU_ID, (uint32_t)ptr, &psram_paddr, &target); + assert(is_mapped); + assert(target == MMU_TARGET_PSRAM0); + paddr_on_flash = psram_paddr + s_drom_paddr_offset; + } else { + paddr_on_flash = UINT32_MAX; + } + + return paddr_on_flash; +} diff --git a/components/esp_psram/test_apps/psram/pytest_psram.py b/components/esp_psram/test_apps/psram/pytest_psram.py index 7ceb29e7fb33..327a201311a8 100644 --- a/components/esp_psram/test_apps/psram/pytest_psram.py +++ b/components/esp_psram/test_apps/psram/pytest_psram.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -81,6 +80,7 @@ def test_psram_esp32s3_octal(dut: Dut) -> None: 'config', [ 'esp32p4_200m_release', + 'esp32p4_xip' ], indirect=True, ) diff --git a/components/esp_psram/test_apps/psram/sdkconfig.ci.esp32p4_xip b/components/esp_psram/test_apps/psram/sdkconfig.ci.esp32p4_xip new file mode 100644 index 000000000000..e163e81b0bf0 --- /dev/null +++ b/components/esp_psram/test_apps/psram/sdkconfig.ci.esp32p4_xip @@ -0,0 +1,14 @@ +CONFIG_IDF_TARGET="esp32p4" + +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y + +CONFIG_SPIRAM=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM_SPEED_200M=y +CONFIG_SPIRAM_XIP_FROM_PSRAM=y + +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 859ebcd58a6e..808d05195756 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -204,7 +204,7 @@ else() # Regular app build rom_linker_script("newlib") if(CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT AND CONFIG_NEWLIB_NANO_FORMAT) - if(NOT CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME) + if(NOT CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME AND NOT CONFIG_ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG) # Newlib-nano functions contains time_t related functions # and cannot be used if they were compiled with 32 bit time_t rom_linker_script("newlib-nano") diff --git a/components/esp_rom/esp32/ld/esp32.rom.ld b/components/esp_rom/esp32/ld/esp32.rom.ld index 814eb8219bd7..b47c3140b894 100644 --- a/components/esp_rom/esp32/ld/esp32.rom.ld +++ b/components/esp_rom/esp32/ld/esp32.rom.ld @@ -1474,7 +1474,7 @@ PROVIDE ( uart_tx_switch = 0x40009028 ); /* These functions are part of the ROM GPIO driver. We do not use them; the provided esp-idf functions -replace them and this way we can re-use the fixed RAM addresses these routines need. +replace them and this way we can reuse the fixed RAM addresses these routines need. */ /* <-- So you don't read over it: This comment disables the next lines. PROVIDE ( gpio_init = 0x40009c20 ); @@ -1623,6 +1623,7 @@ PROVIDE ( ld_acl_sniff_trans_sched = 0x40033734 ); PROVIDE ( lc_pwr_decr_ind_handler = 0x4002859c ); PROVIDE ( lc_pwr_incr_ind_handler = 0x400284a8 ); PROVIDE ( lc_pwr_max_ind_handler = 0x40028690 ); +PROVIDE ( lc_setup_sync_param_check = 0x4002354c ); PROVIDE ( lm_sync_conf = 0x3ffb8348 ); PROVIDE ( lm_nb_sync_active = 0x3ffb8346 ); diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 7f6b0ad04831..007732f4e281 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -583,8 +583,6 @@ r_ble_ll_adv_scan_req_rxd = 0x40000c98; r_ble_ll_adv_scan_rsp_legacy_pdu_make = 0x40000c9c; r_ble_ll_adv_scan_rsp_pdu_make = 0x40000ca0; r_ble_ll_adv_scheduled = 0x40000ca4; -r_ble_ll_adv_set_adv_params = 0x40000cb0; -r_ble_ll_adv_set_enable = 0x40000cb4; r_ble_ll_adv_set_random_addr = 0x40000cb8; r_ble_ll_adv_sm_deinit = 0x40000cc4; r_ble_ll_adv_sm_event_init = 0x40000cc8; @@ -606,7 +604,6 @@ r_ble_ll_auth_pyld_tmo_event_send = 0x40000d14; r_ble_ll_calc_offset_ticks_us_for_rampup = 0x40000d18; r_ble_ll_calc_session_key = 0x40000d1c; r_ble_ll_calc_ticks_per_slot = 0x40000d20; -r_ble_ll_check_scan_params = 0x40000d24; r_ble_ll_chk_txrx_octets = 0x40000d28; r_ble_ll_chk_txrx_time = 0x40000d2c; r_ble_ll_conn_adjust_pyld_len = 0x40000d30; @@ -690,8 +687,6 @@ r_ble_ll_ctrl_rej_ext_ind_make = 0x40000ec0; r_ble_ll_ctrl_reject_ind_send = 0x40000ec4; r_ble_ll_ctrl_rx_chanmap_req = 0x40000ec8; r_ble_ll_ctrl_rx_conn_param_req = 0x40000ecc; -r_ble_ll_ctrl_rx_conn_param_rsp = 0x40000ed0; -r_ble_ll_ctrl_rx_conn_update = 0x40000ed4; r_ble_ll_ctrl_rx_enc_req = 0x40000ed8; r_ble_ll_ctrl_rx_enc_rsp = 0x40000edc; r_ble_ll_ctrl_rx_feature_req = 0x40000ee0; @@ -754,7 +749,6 @@ r_ble_ll_hci_ev_send_adv_set_terminated = 0x40000ff4; r_ble_ll_hci_ev_send_scan_req_recv = 0x40000ff8; r_ble_ll_hci_ev_send_scan_timeout = 0x40000ffc; r_ble_ll_hci_ev_send_vendor_err = 0x40001000; -r_ble_ll_hci_event_send = 0x40001004; r_ble_ll_hci_ext_scan_set_enable = 0x40001008; r_ble_ll_hci_get_num_cmd_pkts = 0x4000100c; r_ble_ll_hci_info_params_cmd_proc = 0x40001010; @@ -782,8 +776,6 @@ r_ble_ll_hci_rd_local_version = 0x4000106c; r_ble_ll_hci_scan_set_enable = 0x40001070; r_ble_ll_hci_send_adv_report = 0x40001074; r_ble_ll_hci_send_dir_adv_report = 0x40001078; -r_ble_ll_hci_send_ext_adv_report = 0x4000107c; -r_ble_ll_hci_send_legacy_ext_adv_report = 0x40001080; r_ble_ll_hci_send_noop = 0x40001084; r_ble_ll_hci_set_adv_data = 0x40001088; r_ble_ll_hci_set_le_event_mask = 0x4000108c; @@ -975,7 +967,6 @@ r_ble_lll_adv_coex_dpc_update_on_event_scheduled = 0x40001418; r_ble_lll_adv_done = 0x4000141c; r_ble_lll_adv_event_done = 0x40001424; r_ble_lll_adv_event_rmvd_from_sched = 0x40001428; -r_ble_lll_adv_ext_estimate_data_itvl = 0x4000142c; r_ble_lll_adv_get_sec_pdu_len = 0x40001430; r_ble_lll_adv_make_done = 0x40001438; r_ble_lll_adv_periodic_done = 0x4000143c; @@ -1430,7 +1421,7 @@ mac_tx_set_plcp2 = 0x40001b68; /* pm_check_state = 0x40001b6c; */ pm_disable_dream_timer = 0x40001b70; pm_disable_sleep_delay_timer = 0x40001b74; -pm_dream = 0x40001b78; +/*pm_dream = 0x40001b78;*/ pm_mac_wakeup = 0x40001b7c; pm_mac_sleep = 0x40001b80; pm_enable_active_timer = 0x40001b84; @@ -1519,7 +1510,7 @@ trc_SetTxAmpduState = 0x40001ccc; trc_tid_isTxAmpduOperational = 0x40001cd0; trcAmpduSetState = 0x40001cd4; wDevCheckBlockError = 0x40001cd8; -wDev_AppendRxBlocks = 0x40001cdc; +/*wDev_AppendRxBlocks = 0x40001cdc;*/ wDev_DiscardFrame = 0x40001ce0; wDev_GetNoiseFloor = 0x40001ce4; wDev_IndicateAmpdu = 0x40001ce8; @@ -1611,7 +1602,7 @@ hal_disable_sta_tbtt = 0x40001e3c; ppCalTxopDur = 0x40001e40; wDev_IndicateCtrlFrame = 0x40001e44; hal_enable_sta_tbtt = 0x40001e48; -hal_set_sta_tbtt = 0x40001e4c; +/*hal_set_sta_tbtt = 0x40001e4c;*/ /* pm_update_next_tbtt = 0x40001e50;*/ /* pm_set_sleep_type = 0x40001e54; */ wDev_Rxbuf_Init = 0x40001e58; @@ -1655,7 +1646,7 @@ hal_sniffer_enable = 0x40001eec; hal_sniffer_disable = 0x40001ef0; /*hal_sniffer_rx_set_promis = 0x40001ef4;*/ hal_sniffer_rx_clr_statistics = 0x40001ef8; -hal_sniffer_set_promis_misc_pkt = 0x40001efc; +/*hal_sniffer_set_promis_misc_pkt = 0x40001efc;*/ tsf_hal_set_tsf_enable = 0x40001f00; tsf_hal_set_tsf_disable = 0x40001f04; tsf_hal_is_tsf_enabled = 0x40001f08; @@ -1670,7 +1661,7 @@ tsf_hal_set_tbtt_intr_enable = 0x40001f28; tsf_hal_set_tbtt_intr_disable = 0x40001f2c; tsf_hal_set_tbtt_soc_wakeup_enable = 0x40001f30; tsf_hal_set_tbtt_soc_wakeup_disable = 0x40001f34; -tsf_hal_set_tbtt_start_time = 0x40001f38; +/*tsf_hal_set_tbtt_start_time = 0x40001f38;*/ tsf_hal_set_tbtt_early_time = 0x40001f3c; tsf_hal_set_tbtt_interval = 0x40001f40; tsf_hal_get_tbtt_interval = 0x40001f44; @@ -1849,11 +1840,11 @@ ieee80211_alloc_tx_buf = 0x40002108; /* ieee80211_send_nulldata = 0x40002110; */ /* ieee80211_setup_robust_mgmtframe = 0x40002114; */ ieee80211_encap_null_data = 0x4000211c; -ieee80211_send_deauth = 0x40002120; +ieee80211_send_deauth_no_bss = 0x40002120; ieee80211_alloc_deauth = 0x40002124; ieee80211_send_proberesp = 0x40002128; ieee80211_getcapinfo = 0x40002130; -sta_rx_csa = 0x40002134; +/* sta_rx_csa = 0x40002134; */ /* sta_recv_sa_query_resp = 0x40002144; */ ieee80211_set_max_rate = 0x4000214c; ic_set_sta = 0x40002150; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld index 748ce1d1f7a1..9150a4e32ceb 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld @@ -15,7 +15,7 @@ lmacTxFrame = 0x40001630; mac_tx_set_htsig = 0x40001638; mac_tx_set_plcp1 = 0x40001640; pm_check_state = 0x40001648; -pm_on_beacon_rx = 0x4000167c; +/*pm_on_beacon_rx = 0x4000167c;*/ /*pm_parse_beacon = 0x40001688;*/ pm_process_tim = 0x4000168c; pm_rx_beacon_process = 0x40001690; @@ -31,9 +31,9 @@ rcUpdateTxDone = 0x4000177c; wDevCheckBlockError = 0x400017b4; /* wDev_IndicateFrame = 0x400017c8;*/ wDev_ProcessFiq = 0x400017f0; -wDev_ProcessRxSucData = 0x400017f4; +/*wDev_ProcessRxSucData = 0x400017f4;*/ /*ppProcTxDone = 0x40001804;*/ -pm_tx_data_done_process = 0x40001808; +/*pm_tx_data_done_process = 0x40001808;*/ ppMapWaitTxq = 0x40001810; /*ieee80211_encap_esfbuf = 0x4000185c;*/ /*sta_input = 0x40001870;*/ @@ -115,7 +115,6 @@ r_lld_con_evt_time_update_eco = 0x40001d0c; r_lld_con_start_eco = 0x40001d10; r_lld_con_frm_isr_eco = 0x40001d14; r_lld_con_tx_eco = 0x40001d18; -r_lld_scan_evt_start_cbk_eco = 0x40001d20; r_lld_ext_scan_dynamic_pti_process_eco = 0x40001d28; r_lld_scan_frm_eof_isr_eco = 0x40001d2c; r_lld_sync_start_eco = 0x40001d30; @@ -142,7 +141,6 @@ r_bt_bb_recorrect_is_dead = 0x40001d84; r_bt_bb_restart_hw_recorrect = 0x40001d88; r_ke_task_handler_pre = 0x40001da0; r_ke_task_handler_end = 0x40001da4; -r_ke_task_handler_get_overwrite = 0x40001da8; r_lld_scan_frm_skip_isr_eco = 0x40001db0; r_lld_ext_scan_dynamic_pti_reset = 0x40001db4; r_llc_rem_phy_upd_proc_continue_eco = 0x40001db8; @@ -165,9 +163,7 @@ r_lld_cca_lbt_handle = 0x40001df8; r_lld_cca_scst_timeout_check = 0x40001dfc; r_lld_cca_chan_avl_timeout_check = 0x40001e00; -r_lld_scan_start_hook = 0x40001c74; r_lld_con_start_hook = 0x40001ca8; -r_lld_init_start_hook = 0x40001cb8; /* ble Functions eco */ r_bt_bb_isr = 0x40000b9c; @@ -215,6 +211,10 @@ r_llc_llcp_channel_map_ind_ack = 0x40001d68; r_rwble_isr = 0x40001464; r_lld_scan_start_eco = 0x40001d24; r_lld_scan_try_sched_eco = 0x40001dac; +r_lld_scan_start_hook = 0x40001c74; +r_lld_init_start_hook = 0x40001cb8; +r_lld_scan_evt_start_cbk_eco = 0x40001d20; +r_ke_task_handler_get_overwrite = 0x40001da8; */ diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index a5731b2bb270..b9201bc0c7ac 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -1036,7 +1036,7 @@ r_lld_con_pref_slave_evt_dur_set = 0x400010f0; r_lld_con_pref_slave_latency_set = 0x400010f4; r_lld_con_rssi_get = 0x400010f8; r_lld_con_rx = 0x400010fc; -r_lld_con_rx_channel_assess = 0x40001100; +/* r_lld_con_rx_channel_assess = 0x40001100; */ r_lld_con_rx_enc = 0x40001104; r_lld_con_rx_isr = 0x40001108; r_lld_con_rx_link_info_check = 0x4000110c; @@ -1107,7 +1107,7 @@ r_lld_res_list_is_empty = 0x40001220; r_lld_res_list_local_rpa_get = 0x40001224; r_lld_res_list_peer_rpa_get = 0x40001228; r_lld_res_list_peer_update = 0x4000122c; -r_lld_res_list_priv_mode_update = 0x40001230; +/* r_lld_res_list_priv_mode_update = 0x40001230; */ r_lld_reset_reg = 0x40001238; r_lld_rpa_renew = 0x4000123c; r_lld_rpa_renew_evt_canceled_cbk = 0x40001240; @@ -1243,10 +1243,10 @@ r_rw_cryto_aes_cmac = 0x4000145c; r_rw_v9_init_em_radio_table = 0x40001460; r_rwble_sleep_enter = 0x40001468; r_rwble_sleep_wakeup_end = 0x4000146c; -r_rwbtdm_isr_wrapper = 0x40001470; +/* r_rwbtdm_isr_wrapper = 0x40001470; */ r_rwip_active_check = 0x40001474; r_rwip_aes_encrypt = 0x40001478; -r_rwip_assert = 0x4000147c; +/* r_rwip_assert = 0x4000147c; */ r_rwip_crypt_evt_handler = 0x40001480; r_rwip_crypt_isr_handler = 0x40001484; r_rwip_eif_get = 0x40001488; @@ -1538,7 +1538,7 @@ mac_tx_set_plcp2 = 0x40001644; /* pm_check_state = 0x40001648; */ pm_disable_dream_timer = 0x4000164c; pm_disable_sleep_delay_timer = 0x40001650; -pm_dream = 0x40001654; +/*pm_dream = 0x40001654;*/ pm_mac_wakeup = 0x40001658; pm_mac_sleep = 0x4000165c; pm_enable_active_timer = 0x40001660; @@ -1623,7 +1623,7 @@ TRC_PER_IS_GOOD = 0x400017a4; trc_SetTxAmpduState = 0x400017a8; trc_tid_isTxAmpduOperational = 0x400017ac; trcAmpduSetState = 0x400017b0; -wDev_AppendRxBlocks = 0x400017b8; +/*wDev_AppendRxBlocks = 0x400017b8;*/ wDev_DiscardFrame = 0x400017bc; wDev_GetNoiseFloor = 0x400017c0; wDev_IndicateAmpdu = 0x400017c4; diff --git a/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.heap.ld b/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.heap.ld index 2a100bd3630e..90acc2b6ce05 100644 --- a/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.heap.ld +++ b/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.heap.ld @@ -76,5 +76,6 @@ PROVIDE (multi_heap_aligned_alloc = multi_heap_aligned_alloc_impl); PROVIDE (multi_heap_aligned_free = multi_heap_aligned_free_impl); PROVIDE (multi_heap_check = multi_heap_check); PROVIDE (multi_heap_set_lock = multi_heap_set_lock); +PROVIDE (multi_heap_os_funcs_init = multi_heap_mutex_init); PROVIDE (multi_heap_internal_lock = multi_heap_internal_lock); PROVIDE (multi_heap_internal_unlock = multi_heap_internal_unlock); diff --git a/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.pp.ld b/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.pp.ld index 1a8175af9007..54d3ae9e75f7 100644 --- a/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.pp.ld +++ b/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.pp.ld @@ -62,7 +62,7 @@ ic_get_he_rts_threshold_bytes = 0x40000c88; lmacAdjustTimestamp = 0x40000c8c; lmacDiscardAgedMSDU = 0x40000c90; lmacDiscardMSDU = 0x40000c94; -/*lmacEndFrameExchangeSequence = 0x40000c98;*/ +lmacEndFrameExchangeSequence = 0x40000c98; lmacIsIdle = 0x40000c9c; lmacIsLongFrame = 0x40000ca0; lmacMSDUAged = 0x40000ca4; @@ -74,7 +74,7 @@ lmacReachLongLimit = 0x40000cb8; lmacReachShortLimit = 0x40000cbc; lmacRecycleMPDU = 0x40000cc0; lmacRxDone = 0x40000cc4; -lmacSetTxFrame = 0x40000cc8; +/*lmacSetTxFrame = 0x40000cc8;*/ lmacTxDone = 0x40000ccc; lmacTxFrame = 0x40000cd0; lmacDisableTransmit = 0x40000cd4; @@ -109,7 +109,7 @@ mac_tx_set_pti = 0x40000d44; pm_check_state = 0x40000d48; pm_disable_dream_timer = 0x40000d4c; pm_disable_sleep_delay_timer = 0x40000d50; -pm_dream = 0x40000d54; +/*pm_dream = 0x40000d54;*/ pm_mac_wakeup = 0x40000d58; pm_mac_sleep = 0x40000d5c; pm_enable_active_timer = 0x40000d60; @@ -119,7 +119,7 @@ pm_set_beacon_filter = 0x40000d6c; pm_is_in_wifi_slice_threshold = 0x40000d70; pm_is_waked = 0x40000d74; pm_keep_alive = 0x40000d78; -pm_on_beacon_rx = 0x40000d7c; +/*pm_on_beacon_rx = 0x40000d7c;*/ pm_on_data_rx = 0x40000d80; pm_on_data_tx = 0x40000d84; pm_on_tbtt = 0x40000d88; @@ -133,16 +133,16 @@ pm_parse_beacon = 0x40000da4; pm_process_tim = 0x40000da8; pm_rx_beacon_process = 0x40000dac; pm_rx_data_process = 0x40000db0; -pm_sleep = 0x40000db4; +/*pm_sleep = 0x40000db4;*/ pm_sleep_for = 0x40000db8; -pm_tbtt_process = 0x40000dbc; -pm_tx_data_done_process = 0x40000dc0; +/*pm_tbtt_process = 0x40000dbc;*/ +/*pm_tx_data_done_process = 0x40000dc0;*/ pm_allow_tx = 0x40000dc4; pm_extend_tbtt_adaptive_servo = 0x40000dc8; -pm_scale_listen_interval = 0x40000dcc; +/*pm_scale_listen_interval = 0x40000dcc;*/ pm_parse_mbssid_element = 0x40000dd0; pm_disconnected_wake = 0x40000dd4; -pm_tx_data_process = 0x40000dd8; +/*pm_tx_data_process = 0x40000dd8;*/ pm_is_twt_awake = 0x40000ddc; pm_enable_twt_keep_alive = 0x40000de0; pm_twt_on_tsf_timer = 0x40000de4; @@ -153,7 +153,7 @@ pm_twt_set_target_tsf = 0x40000df4; pm_enable_twt_keep_alive_timer = 0x40000df8; pm_mac_try_enable_modem_state = 0x40000dfc; pm_beacon_monitor_tbtt_timeout_process = 0x40000e00; -pm_update_next_tbtt = 0x40000e04; +/*pm_update_next_tbtt = 0x40000e04;*/ pm_twt_disallow_tx = 0x40000e08; pm_clear_wakeup_signal = 0x40000e0c; pm_mac_disable_tsf_tbtt_soc_wakeup = 0x40000e10; @@ -260,7 +260,7 @@ trcAmpduSetState = 0x40000fa0; trc_set_bf_report_rate = 0x40000fa4; trc_onPPTxDone = 0x40000fa8; wDevCheckBlockError = 0x40000fac; -wDev_AppendRxBlocks = 0x40000fb0; +/*wDev_AppendRxBlocks = 0x40000fb0;*/ wDev_DiscardFrame = 0x40000fb4; wDev_GetNoiseFloor = 0x40000fb8; wDev_IndicateAmpdu = 0x40000fbc; diff --git a/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.rvfp.ld b/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.rvfp.ld index 53fe001c90c0..b6853454f5a7 100644 --- a/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.rvfp.ld +++ b/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.rvfp.ld @@ -18,23 +18,23 @@ ***************************************/ /* Functions */ -_rvfp__addsf3 = 0x40000a2c; -_rvfp__eqsf2 = 0x40000a30; -_rvfp__extendsfdf2 = 0x40000a34; -_rvfp__fixsfsi = 0x40000a38; -_rvfp__fixunssfsi = 0x40000a3c; -_rvfp__floatdisf = 0x40000a40; -_rvfp__floatsisf = 0x40000a44; -_rvfp__floatundisf = 0x40000a48; -_rvfp__floatunsisf = 0x40000a4c; -_rvfp__gesf2 = 0x40000a50; -_rvfp__gtsf2 = 0x40000a54; -_rvfp__lesf2 = 0x40000a58; -_rvfp__ltsf2 = 0x40000a5c; -_rvfp__mulsf3 = 0x40000a60; -_rvfp__nesf2 = 0x40000a64; -_rvfp__subsf3 = 0x40000a68; -_rvfp__truncdfsf2 = 0x40000a6c; +__addsf3 = 0x40000a2c; +__eqsf2 = 0x40000a30; +__extendsfdf2 = 0x40000a34; +__fixsfsi = 0x40000a38; +__fixunssfsi = 0x40000a3c; +__floatdisf = 0x40000a40; +__floatsisf = 0x40000a44; +__floatundisf = 0x40000a48; +__floatunsisf = 0x40000a4c; +__gesf2 = 0x40000a50; +__gtsf2 = 0x40000a54; +__lesf2 = 0x40000a58; +__ltsf2 = 0x40000a5c; +__mulsf3 = 0x40000a60; +__nesf2 = 0x40000a64; +__subsf3 = 0x40000a68; +__truncdfsf2 = 0x40000a6c; /*************************************** @@ -42,21 +42,84 @@ _rvfp__truncdfsf2 = 0x40000a6c; ***************************************/ /* Functions */ -_rvfp__adddf3 = 0x40000a70; -_rvfp__eqdf2 = 0x40000a74; -_rvfp__fixdfdi = 0x40000a78; -_rvfp__fixdfsi = 0x40000a7c; -_rvfp__fixsfdi = 0x40000a80; -_rvfp__fixunsdfsi = 0x40000a84; -_rvfp__fixunssfdi = 0x40000a88; -_rvfp__floatdidf = 0x40000a8c; -_rvfp__floatsidf = 0x40000a90; -_rvfp__floatundidf = 0x40000a94; -_rvfp__floatunsidf = 0x40000a98; -_rvfp__gedf2 = 0x40000a9c; -_rvfp__gtdf2 = 0x40000aa0; -_rvfp__ledf2 = 0x40000aa4; -_rvfp__ltdf2 = 0x40000aa8; -_rvfp__muldf3 = 0x40000aac; -_rvfp__nedf2 = 0x40000ab0; -_rvfp__subdf3 = 0x40000ab4; +__adddf3 = 0x40000a70; +__eqdf2 = 0x40000a74; +__fixdfdi = 0x40000a78; +__fixdfsi = 0x40000a7c; +__fixsfdi = 0x40000a80; +__fixunsdfsi = 0x40000a84; +__fixunssfdi = 0x40000a88; +__floatdidf = 0x40000a8c; +__floatsidf = 0x40000a90; +__floatundidf = 0x40000a94; +__floatunsidf = 0x40000a98; +__gedf2 = 0x40000a9c; +__gtdf2 = 0x40000aa0; +__ledf2 = 0x40000aa4; +__ltdf2 = 0x40000aa8; +__muldf3 = 0x40000aac; +__nedf2 = 0x40000ab0; +__subdf3 = 0x40000ab4; + +/*************************************** + Group libgcc +***************************************/ + +/* Functions */ +__divsf3 = 0x400008c0; +__negsf2 = 0x400008e8; +__powisf2 = 0x400008f0; +__unordsf2 = 0x400008fc; +__absvdi2 = 0x40000900; +__absvsi2 = 0x40000904; +__addvdi3 = 0x4000090c; +__addvsi3 = 0x40000910; +__ashldi3 = 0x40000914; +__ashrdi3 = 0x40000918; +__bswapdi2 = 0x4000091c; +__bswapsi2 = 0x40000920; +__clear_cache = 0x40000924; +__clrsbdi2 = 0x40000928; +__clrsbsi2 = 0x4000092c; +__clzdi2 = 0x40000930; +__clzsi2 = 0x40000934; +__cmpdi2 = 0x40000938; +__ctzdi2 = 0x4000093c; +__ctzsi2 = 0x40000940; +__divdc3 = 0x40000944; +__divdf3 = 0x40000948; +__divdi3 = 0x4000094c; +__divsc3 = 0x40000950; +__divsi3 = 0x40000954; +__ffsdi2 = 0x40000960; +__ffssi2 = 0x40000964; +__gcc_bcmp = 0x40000998; +__lshrdi3 = 0x400009a8; +__moddi3 = 0x400009b0; +__modsi3 = 0x400009b4; +__muldc3 = 0x400009b8; +__muldi3 = 0x400009c0; +__mulsc3 = 0x400009c4; +__mulsi3 = 0x400009c8; +__mulvdi3 = 0x400009cc; +__mulvsi3 = 0x400009d0; +__negdf2 = 0x400009d8; +__negdi2 = 0x400009dc; +__negvdi2 = 0x400009e0; +__negvsi2 = 0x400009e4; +__paritysi2 = 0x400009e8; +__popcountdi2 = 0x400009ec; +__popcountsi2 = 0x400009f0; +__powidf2 = 0x400009f4; +__subvdi3 = 0x400009fc; +__subvsi3 = 0x40000a00; +__ucmpdi2 = 0x40000a04; +__udivdi3 = 0x40000a08; +__udivmoddi4 = 0x40000a0c; +__udivsi3 = 0x40000a10; +__udiv_w_sdiv = 0x40000a14; +__umoddi3 = 0x40000a18; +__umodsi3 = 0x40000a1c; +__unorddf2 = 0x40000a20; +__extenddftf2 = 0x40000a24; +__trunctfdf2 = 0x40000a28; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld index 7a73b4d5a7d9..56761322bdc2 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld @@ -37,7 +37,7 @@ ieee80211_ampdu_start_age_timer = 0x40000b84; ieee80211_is_tx_allowed = 0x40000b8c; ieee80211_output_pending_eb = 0x40000b90; /*ieee80211_output_process = 0x40000b94;*/ -ieee80211_set_tx_desc = 0x40000b98; +//ieee80211_set_tx_desc = 0x40000b98; //sta_input = 0x40000b9c; wifi_get_macaddr = 0x40000ba0; wifi_rf_phy_disable = 0x40000ba4; @@ -52,7 +52,7 @@ ieee80211_crypto_encap = 0x40000bc0; ieee80211_decap = 0x40000bc8; wifi_is_started = 0x40000bcc; ieee80211_gettid = 0x40000bd0; -ieee80211_encap_esfbuf_htc = 0x40000bd4; +//ieee80211_encap_esfbuf_htc = 0x40000bd4; /* Data (.data, .bss, .rodata) */ net80211_funcs = 0x4087ffac; g_scan = 0x4087ffa8; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index 78014c5e5937..24ae23143f03 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -51,7 +51,7 @@ lmacRecycleMPDU = 0x40000c4c; lmacRxDone = 0x40000c50; //lmacSetTxFrame = 0x40000c54; //lmacTxDone = 0x40000c58; -lmacTxFrame = 0x40000c5c; +//lmacTxFrame = 0x40000c5c; mac_tx_set_duration = 0x40000c60; //mac_tx_set_plcp0 = 0x40000c64; //mac_tx_set_plcp1 = 0x40000c68; @@ -59,7 +59,7 @@ mac_tx_set_plcp2 = 0x40000c6c; /* pm_check_state = 0x40000c70; */ /* pm_disable_dream_timer = 0x40000c74; */ pm_disable_sleep_delay_timer = 0x40000c78; -pm_dream = 0x40000c7c; +/*pm_dream = 0x40000c7c;*/ pm_mac_wakeup = 0x40000c80; pm_mac_sleep = 0x40000c84; //pm_enable_active_timer = 0x40000c88; @@ -145,7 +145,7 @@ trc_SetTxAmpduState = 0x40000dc4; trc_tid_isTxAmpduOperational = 0x40000dc8; trcAmpduSetState = 0x40000dcc; //wDevCheckBlockError = 0x40000dd0; -wDev_AppendRxBlocks = 0x40000dd4; +/*wDev_AppendRxBlocks = 0x40000dd4;*/ wDev_DiscardFrame = 0x40000dd8; wDev_GetNoiseFloor = 0x40000ddc; wDev_IndicateAmpdu = 0x40000de0; @@ -173,8 +173,8 @@ pm_allow_tx = 0x40000e30; ppProcTxCallback = 0x40000e38; //mac_tx_set_hesig = 0x40000e3c; ppCalPreFecPaddingFactor = 0x40000e40; -mac_tx_set_tb = 0x40000e44; -mac_tx_set_mplen = 0x40000e48; +//mac_tx_set_tb = 0x40000e44; +//mac_tx_set_mplen = 0x40000e48; hal_get_tsf_timer = 0x40000e4c; ppTxPktForceWaked = 0x40000e50; lmacProcessLongFrameSuccess = 0x40000e54; @@ -187,8 +187,8 @@ lmacProcessAckTimeout = 0x40000e68; //ppRemoveHTC = 0x40000e70; get_estimated_batime = 0x40000e74; is_use_muedca = 0x40000e78; -hal_mac_tx_clr_mplen = 0x40000e7c; -hal_mac_get_txq_state = 0x40000e80; +//hal_mac_tx_clr_mplen = 0x40000e7c; +//hal_mac_get_txq_state = 0x40000e80; hal_mac_clr_txq_state = 0x40000e84; hal_mac_get_txq_complete = 0x40000e88; ht_get_min_subframe_len = 0x40000e8c; @@ -274,7 +274,7 @@ tsf_hal_set_tbtt_rf_ctrl_enable = 0x40000fc8; tsf_hal_set_tbtt_rf_ctrl_wait_cycles = 0x40000fcc; tsf_hal_set_tbtt_soc_wakeup_disable = 0x40000fd0; tsf_hal_set_tbtt_soc_wakeup_enable = 0x40000fd4; -tsf_hal_set_tbtt_start_time = 0x40000fd8; +/*tsf_hal_set_tbtt_start_time = 0x40000fd8;*/ tsf_hal_set_time = 0x40000fdc; tsf_hal_set_timer_disable = 0x40000fe0; tsf_hal_set_timer_enable = 0x40000fe4; diff --git a/components/esp_rom/esp32c61/Kconfig.soc_caps.in b/components/esp_rom/esp32c61/Kconfig.soc_caps.in index edb2c52a3d78..f3bea7e1e6b6 100644 --- a/components/esp_rom/esp32c61/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c61/Kconfig.soc_caps.in @@ -67,6 +67,10 @@ config ESP_ROM_HAS_NEWLIB_NANO_FORMAT bool default y +config ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG + bool + default y + config ESP_ROM_HAS_VERSION bool default y diff --git a/components/esp_rom/esp32c61/esp_rom_caps.h b/components/esp_rom/esp32c61/esp_rom_caps.h index a5eea647eff8..9bcc14320be1 100644 --- a/components/esp_rom/esp32c61/esp_rom_caps.h +++ b/components/esp_rom/esp32c61/esp_rom_caps.h @@ -24,6 +24,7 @@ // #define ESP_ROM_HAS_REGI2C_BUG (1) // ROM has the regi2c bug #define ESP_ROM_HAS_NEWLIB (1) // ROM has newlib (at least parts of it) functions included #define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano version of formatting functions +#define ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG (1) // ROM has the printf float bug with newlib nano version #define ESP_ROM_HAS_VERSION (1) // ROM has version/eco information #define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock #define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init diff --git a/components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld b/components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld index b69157baaed4..a3f9c9586d55 100644 --- a/components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld +++ b/components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld @@ -48,7 +48,7 @@ lmacReachLongLimit = 0x40000b60; lmacReachShortLimit = 0x40000b64; lmacRecycleMPDU = 0x40000b68; lmacRxDone = 0x40000b6c; -lmacSetTxFrame = 0x40000b70; +/*lmacSetTxFrame = 0x40000b70;*/ lmacTxDone = 0x40000b74; lmacTxFrame = 0x40000b78; mac_tx_set_duration = 0x40000b7c; diff --git a/components/esp_rom/esp32h2/Kconfig.soc_caps.in b/components/esp_rom/esp32h2/Kconfig.soc_caps.in index ade2e7af59ae..bc719bac1199 100644 --- a/components/esp_rom/esp32h2/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32h2/Kconfig.soc_caps.in @@ -67,6 +67,10 @@ config ESP_ROM_HAS_NEWLIB_NANO_FORMAT bool default y +config ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG + bool + default y + config ESP_ROM_WDT_INIT_PATCH bool default y diff --git a/components/esp_rom/esp32h2/esp_rom_caps.h b/components/esp_rom/esp32h2/esp_rom_caps.h index fbea5f010402..95ae23593627 100644 --- a/components/esp_rom/esp32h2/esp_rom_caps.h +++ b/components/esp_rom/esp32h2/esp_rom_caps.h @@ -22,6 +22,7 @@ #define ESP_ROM_WITHOUT_REGI2C (1) // ROM has no regi2c APIs #define ESP_ROM_HAS_NEWLIB (1) // ROM has newlib (at least parts of it) functions included #define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano versions of formatting functions +#define ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG (1) // ROM has the printf float bug with newlib nano version #define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock #define ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE (1) // ROM needs to set cache MMU size according to instruction and rodata for flash mmap #define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init diff --git a/components/esp_rom/esp32p4/Kconfig.soc_caps.in b/components/esp_rom/esp32p4/Kconfig.soc_caps.in index af5b84d70760..a7a0a9c08503 100644 --- a/components/esp_rom/esp32p4/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32p4/Kconfig.soc_caps.in @@ -67,6 +67,10 @@ config ESP_ROM_HAS_NEWLIB_NANO_FORMAT bool default y +config ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG + bool + default y + config ESP_ROM_HAS_VERSION bool default y diff --git a/components/esp_rom/esp32p4/esp_rom_caps.h b/components/esp_rom/esp32p4/esp_rom_caps.h index f0c1d32bb39d..8578f4401fae 100644 --- a/components/esp_rom/esp32p4/esp_rom_caps.h +++ b/components/esp_rom/esp32p4/esp_rom_caps.h @@ -22,5 +22,6 @@ #define ESP_ROM_WITHOUT_REGI2C (1) // ROM has no regi2c APIs #define ESP_ROM_HAS_NEWLIB (1) // ROM has newlib (at least parts of it) functions included #define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano version of formatting functions +#define ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG (1) // ROM has the printf float bug with newlib nano version #define ESP_ROM_HAS_VERSION (1) // ROM has version/eco information #define ESP_ROM_CLIC_INT_TYPE_PATCH (1) // ROM api esprv_intc_int_set_type configuring edge type interrupt is invalid diff --git a/components/esp_rom/esp32p4/ld/esp32p4lp.rom.api.ld b/components/esp_rom/esp32p4/ld/esp32p4lp.rom.api.ld new file mode 100644 index 000000000000..4d7fc793e200 --- /dev/null +++ b/components/esp_rom/esp32p4/ld/esp32p4lp.rom.api.ld @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** ROM APIs + */ + +PROVIDE ( esp_rom_output_putc = uart_tx_one_char ); diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index 6d964839b3e4..ccc4a539fe5d 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -1286,7 +1286,7 @@ r_lld_con_pref_slave_evt_dur_set = 0x400042b4; r_lld_con_pref_slave_latency_set = 0x400042c0; r_lld_con_rssi_get = 0x400042cc; r_lld_con_rx = 0x400042d8; -r_lld_con_rx_channel_assess = 0x400042e4; +/* r_lld_con_rx_channel_assess = 0x400042e4; */ r_lld_con_rx_enc = 0x400042f0; r_lld_con_rx_isr = 0x400042fc; r_lld_con_rx_link_info_check = 0x40004308; @@ -1357,7 +1357,7 @@ r_lld_res_list_is_empty = 0x40004644; r_lld_res_list_local_rpa_get = 0x40004650; r_lld_res_list_peer_rpa_get = 0x4000465c; r_lld_res_list_peer_update = 0x40004668; -r_lld_res_list_priv_mode_update = 0x40004674; +/* r_lld_res_list_priv_mode_update = 0x40004674; */ r_lld_reset_reg = 0x4000468c; r_lld_rpa_renew = 0x40004698; r_lld_rpa_renew_evt_canceled_cbk = 0x400046a4; @@ -1493,10 +1493,10 @@ r_rw_cryto_aes_cmac = 0x40004cf8; r_rw_v9_init_em_radio_table = 0x40004d04; r_rwble_sleep_enter = 0x40004d1c; r_rwble_sleep_wakeup_end = 0x40004d28; -r_rwbtdm_isr_wrapper = 0x40004d34; +/* r_rwbtdm_isr_wrapper = 0x40004d34; */ r_rwip_active_check = 0x40004d40; r_rwip_aes_encrypt = 0x40004d4c; -r_rwip_assert = 0x40004d58; +/* r_rwip_assert = 0x40004d58; */ r_rwip_crypt_evt_handler = 0x40004d64; r_rwip_crypt_isr_handler = 0x40004d70; r_rwip_eif_get = 0x40004d7c; @@ -1816,7 +1816,7 @@ mac_tx_set_plcp2 = 0x4000540c; /* pm_check_state = 0x40005418; */ pm_disable_dream_timer = 0x40005424; pm_disable_sleep_delay_timer = 0x40005430; -pm_dream = 0x4000543c; +/*pm_dream = 0x4000543c;*/ pm_mac_wakeup = 0x40005448; pm_mac_sleep = 0x40005454; pm_enable_active_timer = 0x40005460; @@ -1904,7 +1904,7 @@ trc_SetTxAmpduState = 0x40005838; trc_tid_isTxAmpduOperational = 0x40005844; trcAmpduSetState = 0x40005850; wDevCheckBlockError = 0x4000585c; -wDev_AppendRxBlocks = 0x40005868; +/*wDev_AppendRxBlocks = 0x40005868;*/ wDev_DiscardFrame = 0x40005874; wDev_GetNoiseFloor = 0x40005880; wDev_IndicateAmpdu = 0x4000588c; diff --git a/components/esp_rom/include/esp32c61/rom/cache.h b/components/esp_rom/include/esp32c61/rom/cache.h index 5ed6740a626c..1e0f1baa0e97 100644 --- a/components/esp_rom/include/esp32c61/rom/cache.h +++ b/components/esp_rom/include/esp32c61/rom/cache.h @@ -530,7 +530,7 @@ void Cache_Resume_Cache(uint32_t autoload); * * @return uint32_t: 16, 32, 64 Byte */ -uint32_t Cache_Get_Cache_Line_Size(void); +uint32_t Cache_Get_Line_Size(void); /** * @brief Enable freeze for ICache. @@ -574,7 +574,7 @@ void Cache_Travel_Tag_Memory(struct cache_mode * mode, uint32_t filter_addr, voi * * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. * - * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * @param uint32_t tag : the tag part of a tag item, 12-14 bits. * * @param uint32_t addr_offset : the virtual address offset of the cache ways. * diff --git a/components/esp_rom/include/esp32p4/rom/cache.h b/components/esp_rom/include/esp32p4/rom/cache.h index 95f4a4db05ee..f505f6f46b50 100644 --- a/components/esp_rom/include/esp32p4/rom/cache.h +++ b/components/esp_rom/include/esp32p4/rom/cache.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,8 +7,10 @@ #ifndef _ROM_CACHE_H_ #define _ROM_CACHE_H_ +#if (!defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)) #include #include "esp_bit_defs.h" +#endif #ifdef __cplusplus extern "C" { @@ -86,6 +88,16 @@ extern "C" { // should NOT = #define SMMU_GID_TBIT_INDEX_HIGH (SMMU_GID_TBIT_INDEX_LOW + SMMU_GID_TBIT_NUM) +#define CACHE_MAP_L1_ICACHE_0 BIT(0) +#define CACHE_MAP_L1_ICACHE_1 BIT(1) +#define CACHE_MAP_L1_DCACHE BIT(4) +#define CACHE_MAP_L2_CACHE BIT(5) + +#define CACHE_MAP_L1_ICACHE_MASK (CACHE_MAP_L1_ICACHE_0 | CACHE_MAP_L1_ICACHE_1) +#define CACHE_MAP_L1_CACHE_MASK (CACHE_MAP_L1_ICACHE_MASK | CACHE_MAP_L1_DCACHE) +#define CACHE_MAP_MASK (CACHE_MAP_L1_ICACHE_MASK | CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE) + +#if (!defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)) typedef enum { CACHE_L1_ICACHE0 = 0, CACHE_L1_ICACHE1 = 1, @@ -225,14 +237,6 @@ typedef enum { CACHE_SYNC_WRITEBACK_INVALIDATE = BIT(3), } cache_sync_t; -#define CACHE_MAP_L1_ICACHE_0 BIT(0) -#define CACHE_MAP_L1_ICACHE_1 BIT(1) -#define CACHE_MAP_L1_DCACHE BIT(4) -#define CACHE_MAP_L2_CACHE BIT(5) - -#define CACHE_MAP_L1_ICACHE_MASK (CACHE_MAP_L1_ICACHE_0 | CACHE_MAP_L1_ICACHE_1) -#define CACHE_MAP_MASK (CACHE_MAP_L1_ICACHE_MASK | CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE) - struct cache_internal_stub_table { uint32_t (*l1_icache_line_size)(void); uint32_t (*l1_dcache_line_size)(void); @@ -507,7 +511,7 @@ void ROM_Direct_Boot_Cache_Init(void); * * @param None * - * @return 0 if mmu map is sucessfully, others if not. + * @return 0 if mmu map is successfully, others if not. */ int ROM_Direct_Boot_MMU_Init(void); @@ -1517,7 +1521,7 @@ void Cache_Freeze_L2_Cache_Disable(void); void Cache_Travel_Tag_Memory(struct cache_mode *mode, uint32_t filter_addr, void (*process)(struct tag_group_info *, int res[]), int res[]); /** - * @brief Travel tag memory to run a call back function using 2rd tag api. + * @brief Travel tag memory to run a call back function using 2nd tag api. * ICache and DCache are suspend when doing this. * The callback will get the parameter tag_group_info, which will include a group of tag memory addresses and cache memory addresses. * Please do not call this function in your SDK application. @@ -1539,7 +1543,7 @@ void Cache_Travel_Tag_Memory2(struct cache_mode *mode, uint32_t filter_addr, voi * * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. * - * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * @param uint32_t tag : the tag part for a tag item, 12-14 bits. * * @param uint32_t addr_offset : the virtual address offset of the cache ways. * @@ -1602,6 +1606,8 @@ int flash2spiram_rodata_offset(void); uint32_t flash_instr_rodata_start_page(uint32_t bus); uint32_t flash_instr_rodata_end_page(uint32_t bus); +#endif // #if (!defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)) + #ifdef __cplusplus } #endif diff --git a/components/esp_rom/test_apps/.build-test-rules.yml b/components/esp_rom/test_apps/.build-test-rules.yml index 7f94e30b5966..2def446d9d29 100644 --- a/components/esp_rom/test_apps/.build-test-rules.yml +++ b/components/esp_rom/test_apps/.build-test-rules.yml @@ -7,8 +7,12 @@ components/esp_rom/test_apps/linux_rom_apis: components/esp_rom/test_apps/rom_impl_components: disable: # For ROM impl build tests, disable them if none of the tested features are supported in the ROM + - if: CONFIG_NAME == "no_rom_impl_components" and IDF_TARGET == "esp32c5" + temporary: true + reason: build failed. track in IDFCI-2204 - if: CONFIG_NAME == "rom_impl_components" and ((ESP_ROM_HAS_HAL_WDT != 1 and ESP_ROM_HAS_HAL_SYSTIMER != 1) and (ESP_ROM_HAS_HEAP_TLSF != 1 and ESP_ROM_HAS_SPI_FLASH != 1)) - if: CONFIG_NAME == "no_rom_impl_components" and ((ESP_ROM_HAS_HAL_WDT != 1 and ESP_ROM_HAS_HAL_SYSTIMER != 1) and (ESP_ROM_HAS_HEAP_TLSF != 1 and ESP_ROM_HAS_SPI_FLASH != 1)) + - if: SOC_WDT_SUPPORTED == 0 components/esp_rom/test_apps/rom_tests: disable_test: diff --git a/components/esp_rom/test_apps/rom_impl_components/README.md b/components/esp_rom/test_apps/rom_impl_components/README.md index 3a502b1f86f4..bf47d80ec649 100644 --- a/components/esp_rom/test_apps/rom_impl_components/README.md +++ b/components/esp_rom/test_apps/rom_impl_components/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index c5f33787edad..ea4290cae813 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -411,7 +411,7 @@ menu "ESP System Settings" default 800 if (SPIRAM && IDF_TARGET_ESP32) range 10 10000 help - The timeout of the watchdog, in miliseconds. Make this higher than the FreeRTOS tick rate. + The timeout of the watchdog, in milliseconds. Make this higher than the FreeRTOS tick rate. config ESP_INT_WDT_CHECK_CPU1 bool "Also watch CPU1 tick interrupt" @@ -485,7 +485,7 @@ menu "ESP System Settings" config ESP_XT_WDT bool "Initialize XTAL32K watchdog timer on startup" - depends on !IDF_TARGET_ESP32 && (ESP_SYSTEM_RTC_EXT_OSC || ESP_SYSTEM_RTC_EXT_XTAL) + depends on SOC_XT_WDT_SUPPORTED && (ESP_SYSTEM_RTC_EXT_OSC || ESP_SYSTEM_RTC_EXT_XTAL) default n help This watchdog timer can detect oscillation failure of the XTAL32K_CLK. When such a failure diff --git a/components/esp_system/fpga_overrides_clk.c b/components/esp_system/fpga_overrides_clk.c index a3b4b43de590..1b1f9efad2f1 100644 --- a/components/esp_system/fpga_overrides_clk.c +++ b/components/esp_system/fpga_overrides_clk.c @@ -62,14 +62,18 @@ void bootloader_clock_configure(void) REG_WRITE(RTC_XTAL_FREQ_REG, (xtal_freq_mhz) | ((xtal_freq_mhz) << 16)); } -void esp_clk_init(void) +void esp_rtc_init(void) { - s_warn(); #if SOC_PMU_SUPPORTED pmu_init(); #endif } +void esp_clk_init(void) +{ + s_warn(); +} + void esp_perip_clk_init(void) { } diff --git a/components/esp_system/int_wdt.c b/components/esp_system/int_wdt.c index e4936f0a6677..9a8db626f3b9 100644 --- a/components/esp_system/int_wdt.c +++ b/components/esp_system/int_wdt.c @@ -14,6 +14,7 @@ #include "hal/timer_ll.h" #include "freertos/FreeRTOS.h" #include "esp_cpu.h" +#include "esp_check.h" #include "esp_err.h" #include "esp_attr.h" #include "esp_log.h" @@ -23,6 +24,10 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/esp_int_wdt.h" +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +#include "esp_private/sleep_retention.h" +#endif + #if SOC_TIMER_GROUPS > 1 /* If we have two hardware timer groups, use the second one for interrupt watchdog. */ @@ -47,6 +52,38 @@ #endif // SOC_TIMER_GROUPS > 1 #if CONFIG_ESP_INT_WDT +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +static const char* TAG = "int_wdt"; +static esp_err_t sleep_int_wdt_retention_init(void *arg) +{ + uint32_t group_id = *(uint32_t *)arg; + esp_err_t err = sleep_retention_entries_create(tg_wdt_regs_retention[group_id].link_list, + tg_wdt_regs_retention[group_id].link_num, + REGDMA_LINK_PRI_SYS_PERIPH_LOW, + (group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err == ESP_OK) { + ESP_LOGD(TAG, "Interrupt watchdog timer retention initialization"); + } + ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for interrupt watchdog timer"); + return err; +} + +static esp_err_t esp_int_wdt_retention_enable(uint32_t group_id) +{ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_int_wdt_retention_init, .arg = &group_id } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + esp_err_t err = sleep_retention_module_init((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for interrupt watchdog timer retention"); + } + } + return err; +} +#endif static wdt_hal_context_t iwdt_context; @@ -122,6 +159,10 @@ void esp_int_wdt_init(void) wdt_hal_enable(&iwdt_context); wdt_hal_write_protect_enable(&iwdt_context); +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION + esp_int_wdt_retention_enable(IWDT_TIMER_GROUP); +#endif + #if (CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_BTDM_CTRL_HLI) #define APB_DCRSET (0x200c) #define APB_ITCTRL (0x3f00) diff --git a/components/esp_system/ld/elf_misc.ld.in b/components/esp_system/ld/elf_misc.ld.in new file mode 100644 index 000000000000..f1e9d5a8001b --- /dev/null +++ b/components/esp_system/ld/elf_misc.ld.in @@ -0,0 +1,87 @@ +#include "sdkconfig.h" + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + +#if CONFIG_IDF_TARGET_ARCH_RISCV + .riscv.attributes 0: { *(.riscv.attributes) } + + /DISCARD/ : + { + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + *(.rela.*) +#if !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + *(.eh_frame_hdr) + *(.eh_frame) +#endif // !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + } +#elif CONFIG_IDF_TARGET_ARCH_XTENSA +/** + * .xt.prop and .xt.lit sections will be used by the debugger and disassembler + * to get more information about raw data present in the code. + * Indeed, it may be required to add some padding at some points in the code + * in order to align a branch/jump destination on a particular bound. + * Padding these instructions will generate null bytes that shall be + * interpreted as data, and not code by the debugger or disassembler. + * This section will only be present in the ELF file, not in the final binary + * For more details, check GCC-212 + */ + .xtensa.info 0: { *(.xtensa.info) } + .xt.prop 0 : { *(.xt.prop .xt.prop.* .gnu.linkonce.prop.*) } + .xt.lit 0 : { *(.xt.lit .xt.lit.* .gnu.linkonce.p.*) } + + /DISCARD/ : + { + *(.fini) + *(.eh_frame_hdr) +#if !CONFIG_COMPILER_CXX_EXCEPTIONS + *(.eh_frame) +#endif // !CONFIG_COMPILER_CXX_EXCEPTIONS + } +#else + #error "Target architecture is not supported!" +#endif diff --git a/components/esp_system/ld/esp32/sections.ld.in b/components/esp_system/ld/esp32/sections.ld.in index 19c395cbe500..066994b743ec 100644 --- a/components/esp_system/ld/esp32/sections.ld.in +++ b/components/esp_system/ld/esp32/sections.ld.in @@ -218,6 +218,7 @@ SECTIONS *(.UserEnter.literal); *(.UserEnter.text); . = ALIGN (16); + *(.entry.literal) *(.entry.text) *(.init.literal) *(.init) @@ -352,6 +353,7 @@ SECTIONS __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); *(.xt_except_desc_end) +#if CONFIG_COMPILER_CXX_EXCEPTIONS ALIGNED_SYMBOL(4, __eh_frame) KEEP(*(.eh_frame)) /** @@ -359,6 +361,7 @@ SECTIONS * (see __FRAME_END__ in libgcc sources), it is manually provided here. */ LONG(0); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS /** * C++ constructor tables. @@ -488,25 +491,7 @@ SECTIONS ALIGNED_SYMBOL(8, _heap_low_start) } > dram0_0_seg - /** - * This section will be used by the debugger and disassembler to get more - * information about raw data present in the code. - * Indeed, it may be required to add some padding at some points in the code - * in order to align a branch/jump destination on a particular bound. - * Padding these instructions will generate null bytes that shall be - * interpreted as data, and not code by the debugger or disassembler. - * This section will only be present in the ELF file, not in the final binary - * For more details, check GCC-212 - */ - .xt.prop 0 : - { - KEEP (*(.xt.prop .gnu.linkonce.prop.*)) - } - - .xt.lit 0 : - { - KEEP (*(.xt.lit .gnu.linkonce.p.*)) - } +#include "elf_misc.ld.in" } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32c2/sections.ld.in b/components/esp_system/ld/esp32c2/sections.ld.in index 42c906acad12..d6cd3757832e 100644 --- a/components/esp_system/ld/esp32c2/sections.ld.in +++ b/components/esp_system/ld/esp32c2/sections.ld.in @@ -233,17 +233,21 @@ SECTIONS .eh_frame_hdr : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame_hdr) KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.eh_frame)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) .eh_frame : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame) KEEP (*(.eh_frame)) @@ -254,6 +258,8 @@ SECTIONS LONG(0); __eh_frame_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.flash.tdata)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) @@ -339,13 +345,7 @@ SECTIONS ALIGNED_SYMBOL(16, _heap_start) } > dram0_0_seg - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } +#include "elf_misc.ld.in" } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32c3/sections.ld.in b/components/esp_system/ld/esp32c3/sections.ld.in index f5962dd6f072..1077f6966dd9 100644 --- a/components/esp_system/ld/esp32c3/sections.ld.in +++ b/components/esp_system/ld/esp32c3/sections.ld.in @@ -351,17 +351,21 @@ SECTIONS .eh_frame_hdr : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame_hdr) KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.eh_frame)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) .eh_frame : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame) KEEP (*(.eh_frame)) @@ -372,6 +376,8 @@ SECTIONS LONG(0); __eh_frame_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.flash.tdata)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) @@ -451,13 +457,7 @@ SECTIONS ALIGNED_SYMBOL(16, _heap_start) } > dram0_0_seg - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } +#include "elf_misc.ld.in" } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32c5/beta3/sections.ld.in b/components/esp_system/ld/esp32c5/beta3/sections.ld.in index c18b9510f239..e2db66dab417 100644 --- a/components/esp_system/ld/esp32c5/beta3/sections.ld.in +++ b/components/esp_system/ld/esp32c5/beta3/sections.ld.in @@ -374,17 +374,21 @@ SECTIONS .eh_frame_hdr : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame_hdr) KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.eh_frame)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) .eh_frame : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame) KEEP (*(.eh_frame)) @@ -395,6 +399,8 @@ SECTIONS LONG(0); __eh_frame_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.flash.tdata)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) @@ -442,13 +448,7 @@ SECTIONS ALIGNED_SYMBOL(16, _heap_start) } > dram0_0_seg - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } +#include "elf_misc.ld.in" } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32c5/mp/sections.ld.in b/components/esp_system/ld/esp32c5/mp/sections.ld.in index c0b76d0af281..54673f7a822a 100644 --- a/components/esp_system/ld/esp32c5/mp/sections.ld.in +++ b/components/esp_system/ld/esp32c5/mp/sections.ld.in @@ -374,17 +374,21 @@ SECTIONS .eh_frame_hdr : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame_hdr) KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.eh_frame)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) .eh_frame : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame) KEEP (*(.eh_frame)) @@ -395,6 +399,8 @@ SECTIONS LONG(0); __eh_frame_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.flash.tdata)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) @@ -442,13 +448,7 @@ SECTIONS ALIGNED_SYMBOL(16, _heap_start) } > sram_seg - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } +#include "elf_misc.ld.in" } ASSERT(((_iram_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), diff --git a/components/esp_system/ld/esp32c6/sections.ld.in b/components/esp_system/ld/esp32c6/sections.ld.in index 2af340515482..ff44c831b6e4 100644 --- a/components/esp_system/ld/esp32c6/sections.ld.in +++ b/components/esp_system/ld/esp32c6/sections.ld.in @@ -364,17 +364,21 @@ SECTIONS .eh_frame_hdr : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame_hdr) KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.eh_frame)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) .eh_frame : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame) KEEP (*(.eh_frame)) @@ -385,6 +389,8 @@ SECTIONS LONG(0); __eh_frame_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.flash.tdata)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) @@ -432,11 +438,5 @@ SECTIONS ALIGNED_SYMBOL(16, _heap_start) } > sram_seg - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } +#include "elf_misc.ld.in" } diff --git a/components/esp_system/ld/esp32c61/sections.ld.in b/components/esp_system/ld/esp32c61/sections.ld.in index c0b76d0af281..54673f7a822a 100644 --- a/components/esp_system/ld/esp32c61/sections.ld.in +++ b/components/esp_system/ld/esp32c61/sections.ld.in @@ -374,17 +374,21 @@ SECTIONS .eh_frame_hdr : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame_hdr) KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.eh_frame)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) .eh_frame : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame) KEEP (*(.eh_frame)) @@ -395,6 +399,8 @@ SECTIONS LONG(0); __eh_frame_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.flash.tdata)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) @@ -442,13 +448,7 @@ SECTIONS ALIGNED_SYMBOL(16, _heap_start) } > sram_seg - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } +#include "elf_misc.ld.in" } ASSERT(((_iram_end - ORIGIN(sram_seg)) <= LENGTH(sram_seg)), diff --git a/components/esp_system/ld/esp32h2/sections.ld.in b/components/esp_system/ld/esp32h2/sections.ld.in index 2af340515482..ff44c831b6e4 100644 --- a/components/esp_system/ld/esp32h2/sections.ld.in +++ b/components/esp_system/ld/esp32h2/sections.ld.in @@ -364,17 +364,21 @@ SECTIONS .eh_frame_hdr : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame_hdr) KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.eh_frame)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) .eh_frame : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame) KEEP (*(.eh_frame)) @@ -385,6 +389,8 @@ SECTIONS LONG(0); __eh_frame_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.flash.tdata)); } > default_rodata_seg ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) @@ -432,11 +438,5 @@ SECTIONS ALIGNED_SYMBOL(16, _heap_start) } > sram_seg - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } +#include "elf_misc.ld.in" } diff --git a/components/esp_system/ld/esp32p4/memory.ld.in b/components/esp_system/ld/esp32p4/memory.ld.in index 775ae8ab94bd..226803c29337 100644 --- a/components/esp_system/ld/esp32p4/memory.ld.in +++ b/components/esp_system/ld/esp32p4/memory.ld.in @@ -47,6 +47,10 @@ MEMORY tcm_idram_seg (RX) : org = 0x30100000, len = 0x2000 #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS + /* PSRAM mapped instruction data */ + irom_seg (RX) : org = 0x48000020, len = IDROM_SEG_SIZE - 0x20 +#else /* Flash mapped instruction data */ irom_seg (RX) : org = 0x40000020, len = IDROM_SEG_SIZE - 0x20 @@ -57,6 +61,7 @@ MEMORY * header. Setting this offset makes it simple to meet the flash cache MMU's * constraint that (paddr % 64KB == vaddr % 64KB).) */ +#endif // CONFIG_SPIRAM_FETCH_INSTRUCTIONS #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS /** @@ -68,8 +73,13 @@ MEMORY sram_high (RW) : org = SRAM_HIGH_START, len = SRAM_HIGH_SIZE #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS +#if CONFIG_SPIRAM_RODATA + /* PSRAM mapped constant data */ + drom_seg (R) : org = 0x48000020, len = IDROM_SEG_SIZE - 0x20 +#else /* Flash mapped constant data */ drom_seg (R) : org = 0x40000020, len = IDROM_SEG_SIZE - 0x20 +#endif // CONFIG_SPIRAM_RODATA /* (See irom_seg for meaning of 0x20 offset in the above.) */ #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS @@ -93,6 +103,9 @@ MEMORY This segment is placed at the beginning of LP RAM, as the end of LP RAM is occupied by LP ROM stack/data */ lp_reserved_seg(RW) : org = 0x50108000, len = RESERVE_RTC_MEM + + /* PSRAM seg */ + extern_ram_seg(RWX) : org = 0x48000000, len = IDROM_SEG_SIZE } /* Heap ends at top of dram0_0_seg */ @@ -125,6 +138,12 @@ REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); REGION_ALIAS("rodata_seg_high", sram_high); #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS +#if CONFIG_SPIRAM_XIP_FROM_PSRAM + REGION_ALIAS("ext_ram_seg", drom_seg); +#else + REGION_ALIAS("ext_ram_seg", extern_ram_seg); +#endif //#if CONFIG_SPIRAM_XIP_FROM_PSRAM + /** * If rodata default segment is placed in `drom_seg`, then flash's first rodata section must * also be first in the segment. diff --git a/components/esp_system/ld/esp32p4/sections.ld.in b/components/esp_system/ld/esp32p4/sections.ld.in index 2f0ff2d0f001..ef288b49a955 100644 --- a/components/esp_system/ld/esp32p4/sections.ld.in +++ b/components/esp_system/ld/esp32p4/sections.ld.in @@ -406,17 +406,21 @@ SECTIONS .eh_frame_hdr : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame_hdr) KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.eh_frame)); } > rodata_seg_low ASSERT_SECTIONS_GAP(.eh_frame_hdr, .eh_frame) .eh_frame : { +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME ALIGNED_SYMBOL(4, __eh_frame) KEEP (*(.eh_frame)) @@ -427,6 +431,8 @@ SECTIONS LONG(0); __eh_frame_end = ABSOLUTE(.); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME + . = ALIGN(ALIGNOF(.flash.tdata)); } > rodata_seg_low ASSERT_SECTIONS_GAP(.eh_frame, .flash.tdata) @@ -469,6 +475,28 @@ SECTIONS mapping[rodata_noload] } > rodata_seg_low +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY +#if CONFIG_SPIRAM_XIP_FROM_PSRAM + /** + * This section is required to skip flash sections, because `extern_ram_seg` + * and `drom_seg` / `irom_seg` are on the same bus when xip on psram + */ + .ext_ram.dummy (NOLOAD): + { + . = ORIGIN(ext_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start); + . = ALIGN (0x10000); + } > ext_ram_seg +#endif //CONFIG_SPIRAM_XIP_FROM_PSRAM + + /* This section holds .ext_ram.bss data, and will be put in PSRAM */ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + mapping[extern_ram] + ALIGNED_SYMBOL(4, _ext_ram_bss_end) + } > ext_ram_seg +#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + .dram0.bss (NOLOAD) : { ALIGNED_SYMBOL(4, _bss_start_low) @@ -508,11 +536,5 @@ SECTIONS ALIGNED_SYMBOL(16, _heap_start_high) } > sram_high - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } +#include "elf_misc.ld.in" } diff --git a/components/esp_system/ld/esp32s2/sections.ld.in b/components/esp_system/ld/esp32s2/sections.ld.in index f177a766fef1..65935dcf976f 100644 --- a/components/esp_system/ld/esp32s2/sections.ld.in +++ b/components/esp_system/ld/esp32s2/sections.ld.in @@ -204,6 +204,7 @@ SECTIONS *(.UserEnter.literal); *(.UserEnter.text); . = ALIGN (16); + *(.entry.literal) *(.entry.text) *(.init.literal) *(.init) @@ -335,6 +336,7 @@ SECTIONS __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); *(.xt_except_desc_end) +#if CONFIG_COMPILER_CXX_EXCEPTIONS ALIGNED_SYMBOL(4, __eh_frame) KEEP(*(.eh_frame)) /** @@ -342,6 +344,7 @@ SECTIONS * (see __FRAME_END__ in libgcc sources), it is manually provided here. */ LONG(0); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS /** * C++ constructor tables. @@ -452,25 +455,7 @@ SECTIONS ALIGNED_SYMBOL(8, _heap_low_start) } > dram0_0_seg - /** - * This section will be used by the debugger and disassembler to get more - * information about raw data present in the code. - * Indeed, it may be required to add some padding at some points in the code - * in order to align a branch/jump destination on a particular bound. - * Padding these instructions will generate null bytes that shall be - * interpreted as data, and not code by the debugger or disassembler. - * This section will only be present in the ELF file, not in the final binary - * For more details, check GCC-212 - */ - .xt.prop 0 : - { - KEEP (*(.xt.prop .gnu.linkonce.prop.*)) - } - - .xt.lit 0 : - { - KEEP (*(.xt.lit .gnu.linkonce.p.*)) - } +#include "elf_misc.ld.in" } ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index 553c4f2e255a..48173b875724 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -20,7 +20,7 @@ SECTIONS ALIGNED_SYMBOL(4, _rtc_fast_start) ALIGNED_SYMBOL(4, _rtc_text_start) - *(.rtc.entry.text) + *(.rtc.entry.literal .rtc.entry.text) mapping[rtc_text] @@ -187,6 +187,7 @@ SECTIONS *(.UserEnter.literal); *(.UserEnter.text); . = ALIGN (16); + *(.entry.literal) *(.entry.text) *(.init.literal) *(.init) @@ -362,6 +363,7 @@ SECTIONS __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); *(.xt_except_desc_end) +#if CONFIG_COMPILER_CXX_EXCEPTIONS ALIGNED_SYMBOL(4, __eh_frame) KEEP(*(.eh_frame)) /** @@ -369,6 +371,7 @@ SECTIONS * (see __FRAME_END__ in libgcc sources), it is manually provided here. */ LONG(0); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS /** * C++ constructor tables. @@ -485,25 +488,7 @@ SECTIONS ALIGNED_SYMBOL(8, _heap_low_start) } > dram0_0_seg - /** - * This section will be used by the debugger and disassembler to get more - * information about raw data present in the code. - * Indeed, it may be required to add some padding at some points in the code - * in order to align a branch/jump destination on a particular bound. - * Padding these instructions will generate null bytes that shall be - * interpreted as data, and not code by the debugger or disassembler. - * This section will only be present in the ELF file, not in the final binary - * For more details, check GCC-212 - */ - .xt.prop 0 : - { - KEEP (*(.xt.prop .gnu.linkonce.prop.*)) - } - - .xt.lit 0 : - { - KEEP (*(.xt.lit .gnu.linkonce.p.*)) - } +#include "elf_misc.ld.in" } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/linker.lf b/components/esp_system/linker.lf index f3eac77bc052..666714c4952d 100644 --- a/components/esp_system/linker.lf +++ b/components/esp_system/linker.lf @@ -30,6 +30,9 @@ entries: usb_console:esp_usb_console_before_restart (noflash) usb_console:esp_usb_console_on_restart_timeout (noflash) + if APP_BUILD_TYPE_RAM = n: + image_process (noflash) + [mapping:vfs_cdcacm] archive: libvfs.a entries: diff --git a/components/esp_system/port/CMakeLists.txt b/components/esp_system/port/CMakeLists.txt index 7f6861b51270..05a476f8cfea 100644 --- a/components/esp_system/port/CMakeLists.txt +++ b/components/esp_system/port/CMakeLists.txt @@ -8,6 +8,10 @@ target_include_directories(${COMPONENT_LIB} PRIVATE ${INCLUDE_FILES} include/pri set(srcs "cpu_start.c" "panic_handler.c" "esp_system_chip.c") +if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + list(APPEND srcs "image_process.c") +endif() + if(CONFIG_SOC_BOD_SUPPORTED) list(APPEND srcs "brownout.c") endif() diff --git a/components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c b/components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c index 62877ae7d90d..564690a44759 100644 --- a/components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c +++ b/components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c @@ -5,8 +5,9 @@ */ #include "stdint.h" +#include "esp_attr.h" -void esp_ipc_isr_waiting_for_finish_cmd(void* ipc_isr_finish_cmd) +void IRAM_ATTR esp_ipc_isr_waiting_for_finish_cmd(void* ipc_isr_finish_cmd) { while (*(volatile uint32_t *)ipc_isr_finish_cmd == 0) { }; } diff --git a/components/esp_system/port/arch/riscv/panic_arch.c b/components/esp_system/port/arch/riscv/panic_arch.c index 718a01116b81..b2278dacb7d3 100644 --- a/components/esp_system/port/arch/riscv/panic_arch.c +++ b/components/esp_system/port/arch/riscv/panic_arch.c @@ -39,7 +39,6 @@ */ static inline void print_cache_err_details(const void *frame) { -#if !CONFIG_IDF_TARGET_ESP32P4 const char* cache_err_msg = esp_cache_err_panic_string(); if (cache_err_msg) { panic_print_str(cache_err_msg); @@ -47,7 +46,6 @@ static inline void print_cache_err_details(const void *frame) panic_print_str("Cache error active, but failed to find a corresponding error message"); } panic_print_str("\r\n"); -#endif } #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD @@ -195,7 +193,7 @@ bool panic_soc_check_pseudo_cause(void *f, panic_info_t *info) /* Cache errors when reading instructions will result in an illegal instructions, before any cache error interrupts trigger. We override the exception cause if any cache errors are active to more accurately report the actual reason */ - if (esp_cache_err_has_active_err() && (frame->mcause == MCAUSE_ILLEGAL_INSTRUCTION)) { + if (esp_cache_err_has_active_err() && ((frame->mcause == MCAUSE_ILLEGAL_INSTRUCTION) || (frame->mcause == MCAUSE_ILLIGAL_INSTRUCTION_ACCESS) || (frame->mcause == MCAUSE_LOAD_ACCESS_FAULT))) { pseudo_cause = true; frame->mcause = ETS_CACHEERR_INUM; } diff --git a/components/esp_system/port/arch/xtensa/panic_arch.c b/components/esp_system/port/arch/xtensa/panic_arch.c index feb128fa1499..5c2dd2f9d9b5 100644 --- a/components/esp_system/port/arch/xtensa/panic_arch.c +++ b/components/esp_system/port/arch/xtensa/panic_arch.c @@ -340,6 +340,7 @@ static inline void print_cache_err_details(const void *f) break; case EXTMEM_DCACHE_WRITE_FLASH_ST: panic_print_str("Write back error occurred while dcache tries to write back to flash\r\n"); + panic_print_str("The following backtrace may not indicate the code that caused Cache invalid access\r\n"); break; case EXTMEM_MMU_ENTRY_FAULT_ST: vaddr = REG_READ(EXTMEM_CACHE_MMU_FAULT_VADDR_REG); diff --git a/components/esp_system/port/brownout.c b/components/esp_system/port/brownout.c index ef1a5ed67b50..d90dcc911ad3 100644 --- a/components/esp_system/port/brownout.c +++ b/components/esp_system/port/brownout.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,7 @@ #include "soc/soc.h" #include "soc/rtc_periph.h" #include "esp_attr.h" +#include "esp_rom_sys.h" #include "bootloader_flash.h" #include "esp_intr_alloc.h" #include "hal/brownout_hal.h" @@ -28,7 +29,7 @@ #define BROWNOUT_DET_LVL 0 #endif -static __attribute__((unused)) DRAM_ATTR const char *TAG = "BOD"; +static __attribute__((unused)) DRAM_ATTR const char TAG[] = "BOD"; #if CONFIG_ESP_SYSTEM_BROWNOUT_INTR IRAM_ATTR static void rtc_brownout_isr_handler(void *arg) @@ -56,7 +57,10 @@ IRAM_ATTR static void rtc_brownout_isr_handler(void *arg) ESP_DRAM_LOGI(TAG, "Brownout detector was triggered\r\n\r\n"); } - esp_restart_noos(); + esp_rom_software_reset_system(); + while (true) { + ; + } } #endif // CONFIG_ESP_SYSTEM_BROWNOUT_INTR @@ -76,7 +80,9 @@ void esp_brownout_init(void) #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 // TODO: [ESP32C5] IDF-8647, [ESP32C61] IDF-9254 // TODO IDF-6606: LP_RTC_TIMER interrupt source is shared by lp_timer and brownout detector, but lp_timer interrupt // is not used now. An interrupt allocator is needed when lp_timer intr gets supported. - esp_intr_alloc(ETS_LP_RTC_TIMER_INTR_SOURCE, ESP_INTR_FLAG_IRAM, &rtc_brownout_isr_handler, NULL, NULL); + esp_intr_alloc_intrstatus(ETS_LP_RTC_TIMER_INTR_SOURCE, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_SHARED, (uint32_t)brownout_ll_intr_get_status_reg(), BROWNOUT_DETECTOR_LL_INTERRUPT_MASK, &rtc_brownout_isr_handler, NULL, NULL); +#elif CONFIG_IDF_TARGET_ESP32P4 + esp_intr_alloc(ETS_LP_ANAPERI_INTR_SOURCE, ESP_INTR_FLAG_IRAM, &rtc_brownout_isr_handler, NULL, NULL); #else rtc_isr_register(rtc_brownout_isr_handler, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M, RTC_INTR_FLAG_IRAM); #endif diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 73255e146466..6fbe2ff95d3c 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -71,8 +71,8 @@ #include "soc/hp_sys_clkrst_reg.h" #endif -#if SOC_KEY_MANAGER_SUPPORTED -#include "hal/key_mgr_hal.h" +#if SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY || SOC_KEY_MANAGER_FE_KEY_DEPLOY +#include "hal/key_mgr_ll.h" #endif #include "esp_private/rtc_clk.h" @@ -82,6 +82,7 @@ #endif // SOC_INT_CLIC_SUPPORTED #include "esp_private/esp_mmu_map_private.h" +#include "esp_private/image_process.h" #if CONFIG_SPIRAM #include "esp_psram.h" #include "esp_private/mmu_psram_flash.h" @@ -93,7 +94,6 @@ #include "bootloader_flash_config.h" #include "bootloader_flash.h" #include "esp_private/crosscore_int.h" -#include "esp_flash_encrypt.h" #include "esp_private/sleep_gpio.h" #include "hal/wdt_hal.h" @@ -114,6 +114,7 @@ #include "esp_rom_spiflash.h" #include "bootloader_init.h" #include "esp_private/bootloader_flash_internal.h" +#include "spi_flash_mmap.h" #endif // CONFIG_APP_BUILD_TYPE_RAM //This dependency will be removed in the future @@ -147,11 +148,6 @@ extern int _mtvt_table; static const char *TAG = "cpu_start"; -#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY -extern int _ext_ram_bss_start; -extern int _ext_ram_bss_end; -#endif - #ifdef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY extern int _iram_bss_start; extern int _iram_bss_end; @@ -223,7 +219,7 @@ void IRAM_ATTR call_start_cpu1(void) #if CONFIG_ESP_CONSOLE_NONE esp_rom_install_channel_putc(1, NULL); esp_rom_install_channel_putc(2, NULL); -#else // CONFIG_ESP_CONSOLE_NONE +#elif !CONFIG_ESP_CONSOLE_USB_CDC esp_rom_install_uart_printf(); esp_rom_output_set_as_console(CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM); #endif @@ -313,13 +309,22 @@ static void start_other_core(void) } #endif -#if SOC_KEY_MANAGER_SUPPORTED // The following operation makes the Key Manager to use eFuse key for ECDSA and XTS-AES operation by default // This is to keep the default behavior same as the other chips // If the Key Manager configuration is already locked then following operation does not have any effect - key_mgr_hal_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_EFUSE_KEY); - key_mgr_hal_set_key_usage(ESP_KEY_MGR_XTS_AES_128_KEY, ESP_KEY_MGR_USE_EFUSE_KEY); +#if SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY || SOC_KEY_MANAGER_FE_KEY_DEPLOY + // Enable key manager clock + // Using ll APIs which do not require critical section + _key_mgr_ll_enable_bus_clock(true); + _key_mgr_ll_enable_peripheral_clock(true); +#if SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY + key_mgr_ll_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_EFUSE_KEY); +#endif +#if SOC_KEY_MANAGER_FE_KEY_DEPLOY + key_mgr_ll_set_key_usage(ESP_KEY_MGR_XTS_AES_128_KEY, ESP_KEY_MGR_USE_EFUSE_KEY); #endif +#endif /* SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY || SOC_KEY_MANAGER_FE_KEY_DEPLOY */ + ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1); bool cpus_up = false; @@ -440,17 +445,10 @@ void IRAM_ATTR call_start_cpu0(void) } #endif -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP -#if CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE - ESP_EARLY_LOGI(TAG, "Unicore app"); -#else - ESP_EARLY_LOGI(TAG, "Multicore app"); -#if !SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP && !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE && !SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE // It helps to fix missed cache settings for other cores. It happens when bootloader is unicore. do_multicore_settings(); -#endif // !SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #endif -#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP // When the APP is loaded into ram for execution, some hardware initialization behaviors // in the bootloader are still necessary @@ -538,7 +536,7 @@ void IRAM_ATTR call_start_cpu0(void) #if CONFIG_ESPTOOLPY_OCT_FLASH && !CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT bool efuse_opflash_en = efuse_ll_get_flash_type(); if (!efuse_opflash_en) { - ESP_EARLY_LOGE(TAG, "Octal Flash option selected, but EFUSE not configured!"); + ESP_DRAM_LOGE(TAG, "Octal Flash option selected, but EFUSE not configured!"); abort(); } #endif @@ -547,6 +545,10 @@ void IRAM_ATTR call_start_cpu0(void) // For Octal flash, it's hard to implement a read_id function in OPI mode for all vendors. // So we have to read it here in SPI mode, before entering the OPI mode. bootloader_flash_update_id(); + + // Configure the power related stuff. After this the MSPI timing tuning can be done. + esp_rtc_init(); + /** * This function initialise the Flash chip to the user-defined settings. * @@ -555,36 +557,52 @@ void IRAM_ATTR call_start_cpu0(void) * In this stage, we re-configure the Flash (and MSPI) to required configuration */ spi_flash_init_chip_state(); - - // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. - // Do calibration again here so that we can use better clock for the timing tuning. -#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB - rtc_clk_recalib_bbpll(); -#endif #if SOC_MEMSPI_SRC_FREQ_120M - // This function needs to be called when PLL is enabled + // This function needs to be called when PLL is enabled. Needs to be called after spi_flash_init_chip_state in case + // some state of flash is modified. mspi_timing_flash_tuning(); #endif esp_mmu_map_init(); +#if !CONFIG_APP_BUILD_TYPE_ELF_RAM +#if CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM + ESP_ERROR_CHECK(image_process()); +#endif +#endif + #if CONFIG_SPIRAM_BOOT_INIT if (esp_psram_init() != ESP_OK) { #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - ESP_EARLY_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment"); + ESP_DRAM_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment"); abort(); #endif #if CONFIG_SPIRAM_IGNORE_NOTFOUND ESP_EARLY_LOGI(TAG, "Failed to init external RAM; continuing without it."); #else - ESP_EARLY_LOGE(TAG, "Failed to init external RAM!"); + ESP_DRAM_LOGE(TAG, "Failed to init external RAM!"); abort(); #endif } #endif + + //----------------------------------Separator-----------------------------// + /** + * @note + * After this stage, you can access the flash through the cache, i.e. run code which is not placed in IRAM + * or print string which locates on flash + */ + esp_mspi_pin_reserve(); + #endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE + ESP_EARLY_LOGI(TAG, "Unicore app"); +#else + ESP_EARLY_LOGI(TAG, "Multicore app"); +#endif + bootloader_init_mem(); #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE @@ -669,7 +687,7 @@ void IRAM_ATTR call_start_cpu0(void) #endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - memset(&_ext_ram_bss_start, 0, (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start)); + esp_psram_bss_init(); #endif //Enable trace memory and immediately start trace. diff --git a/components/esp_system/port/image_process.c b/components/esp_system/port/image_process.c new file mode 100644 index 000000000000..2f795bf7657e --- /dev/null +++ b/components/esp_system/port/image_process.c @@ -0,0 +1,244 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_types.h" +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_check.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_image_format.h" +#include "esp_app_format.h" +#include "esp_flash_partitions.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" +#include "hal/mmu_hal.h" +#include "hal/mmu_ll.h" +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/ext_mem_defs.h" +#include "esp_private/image_process.h" +#include "esp_private/esp_cache_esp32_private.h" + +/** + * ESP32 bootloader size is not enough, not enable this feature for now + */ +#define IMAGE_PROCESS_SUPPORTED_TARGETS (!CONFIG_IDF_TARGET_ESP32) + +#if CONFIG_IDF_TARGET_ESP32 +#define MMAP_MMU_SIZE 0x320000 +#elif CONFIG_IDF_TARGET_ESP32S2 +#define MMAP_MMU_SIZE (SOC_DRAM0_CACHE_ADDRESS_HIGH - SOC_DRAM0_CACHE_ADDRESS_LOW) +#else +#define MMAP_MMU_SIZE (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_DRAM_FLASH_ADDRESS_LOW) +#endif + +#if CONFIG_IDF_TARGET_ESP32 +#define FLASH_READ_VADDR (SOC_DROM_LOW + MMAP_MMU_SIZE) +#else +#define FLASH_READ_VADDR (SOC_DROM_LOW + MMAP_MMU_SIZE - CONFIG_MMU_PAGE_SIZE) +#endif + +#define MMU_FLASH_MASK (~(CONFIG_MMU_PAGE_SIZE - 1)) + +/** + * @brief Image process driver + */ +struct image_process_driver_s { + + /** + * @brief Process segments + * + * @param[in] data image meta data + * + * @return + * - ESP_OK + * - ESP_ERR_INVALID_ARG: invalid argument + * - ESP_ERR_INVALID_STATE: invalid state + */ + esp_err_t (*process_segments)(esp_image_metadata_t *data); +}; + +const static char *TAG = "image_process"; + +static uint32_t s_current_read_mapping = UINT32_MAX; +static uint32_t s_flash_drom_paddr_start = 0; +static uint32_t s_flash_irom_paddr_start = 0; +static esp_err_t process_segments(esp_image_metadata_t *data); + +static image_process_driver_t s_image_process_driver = { + process_segments, +}; + +static esp_err_t flash_read(size_t src_addr, void *dest, size_t size) +{ + if (src_addr & 3) { + ESP_EARLY_LOGE(TAG, "flash_read src_addr 0x%x not 4-byte aligned", src_addr); + return ESP_ERR_INVALID_ARG; + } + if (size & 3) { + ESP_EARLY_LOGE(TAG, "flash_read size 0x%x not 4-byte aligned", size); + return ESP_ERR_INVALID_ARG; + } + if ((intptr_t)dest & 3) { + ESP_EARLY_LOGE(TAG, "flash_read dest 0x%x not 4-byte aligned", (intptr_t)dest); + return ESP_ERR_INVALID_ARG; + } + + uint32_t *dest_words = (uint32_t *)dest; + + for (size_t word = 0; word < size / 4; word++) { + uint32_t word_src = src_addr + word * 4; /* Read this offset from flash */ + uint32_t map_at = word_src & MMU_FLASH_MASK; /* Map this 64KB block from flash */ + uint32_t *map_ptr; + + /* Move the 64KB mmu mapping window to fit map_at */ + if (map_at != s_current_read_mapping) { + + cache_hal_suspend(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + uint32_t actual_mapped_len = 0; + mmu_hal_map_region(0, MMU_TARGET_FLASH0, FLASH_READ_VADDR, map_at, CONFIG_MMU_PAGE_SIZE - 1, &actual_mapped_len); + s_current_read_mapping = map_at; + ESP_EARLY_LOGD(TAG, "starting from paddr=0x%" PRIx32 " and vaddr=0x%" PRIx32 ", 0x%" PRIx32 " bytes are mapped", map_at, FLASH_READ_VADDR, actual_mapped_len); +#if CONFIG_IDF_TARGET_ESP32 + cache_sync(); +#else + cache_hal_invalidate_addr(FLASH_READ_VADDR, actual_mapped_len); +#endif + cache_hal_resume(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + } + map_ptr = (uint32_t *)(FLASH_READ_VADDR + (word_src - map_at)); + dest_words[word] = *map_ptr; + } + + return ESP_OK; +} + +#if IMAGE_PROCESS_SUPPORTED_TARGETS +static esp_err_t process_image_header(esp_image_metadata_t *data, uint32_t part_offset) +{ + bzero(data, sizeof(esp_image_metadata_t)); + data->start_addr = part_offset; + + ESP_RETURN_ON_ERROR_ISR(flash_read(data->start_addr, &data->image, sizeof(esp_image_header_t)), TAG, "failed to read image"); + data->image_len = sizeof(esp_image_header_t); + ESP_EARLY_LOGD(TAG, "reading image header=0x%"PRIx32" image_len=0x%"PRIx32" image.segment_count=0x%x", data->start_addr, data->image_len, data->image.segment_count); + + return ESP_OK; +} +#endif + +static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, esp_image_metadata_t *metadata, int *cnt) +{ + /* read segment header */ + ESP_RETURN_ON_ERROR_ISR(flash_read(flash_addr, header, sizeof(esp_image_segment_header_t)), TAG, "failed to do flash read"); + + intptr_t load_addr = header->load_addr; + uint32_t data_len = header->data_len; + uint32_t data_addr = flash_addr + sizeof(esp_image_segment_header_t); + +#if SOC_MMU_DI_VADDR_SHARED +#if CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM + if (load_addr >= SOC_DRAM_PSRAM_ADDRESS_LOW && load_addr < SOC_DRAM_PSRAM_ADDRESS_HIGH) { + if (*cnt == 0) { + s_flash_drom_paddr_start = data_addr; + } else if (*cnt == 1) { + s_flash_irom_paddr_start = data_addr; + } + (*cnt)++; + } +#else + if (load_addr >= SOC_DRAM_FLASH_ADDRESS_LOW && load_addr < SOC_DRAM_FLASH_ADDRESS_HIGH) { + if (*cnt == 0) { + s_flash_drom_paddr_start = data_addr; + } else if (*cnt == 1) { + s_flash_irom_paddr_start = data_addr; + } + (*cnt)++; + } +#endif +#else + if (load_addr >= SOC_IRAM_FLASH_ADDRESS_LOW && load_addr < SOC_IRAM_FLASH_ADDRESS_HIGH) { + s_flash_drom_paddr_start = data_addr; + (*cnt)++; + } + if (load_addr >= SOC_DRAM_FLASH_ADDRESS_LOW && load_addr < SOC_DRAM_FLASH_ADDRESS_HIGH) { + s_flash_irom_paddr_start = data_addr; + (*cnt)++; + } +#endif + + ESP_EARLY_LOGD(TAG, "load_addr: %x, data_len: %x, flash_addr: 0x%x, data_addr: %x", load_addr, data_len, flash_addr, data_addr); + if (data_len % 4 != 0) { + ESP_RETURN_ON_FALSE_ISR(false, ESP_ERR_INVALID_STATE, TAG, "unaligned segment length 0x%"PRIx32, data_len); + } + + return ESP_OK; +} + +static esp_err_t process_segments(esp_image_metadata_t *data) +{ + uint32_t start_segments = data->start_addr + data->image_len; + uint32_t next_addr = start_segments; + int cnt = 0; + + for (int i = 0; i < data->image.segment_count; i++) { + esp_image_segment_header_t *header = &data->segments[i]; + ESP_EARLY_LOGD(TAG, "loading segment header %d at offset 0x%"PRIx32, i, next_addr); + ESP_RETURN_ON_ERROR_ISR(process_segment(i, next_addr, header, data, &cnt), TAG, "failed to process segment"); + next_addr += sizeof(esp_image_segment_header_t); + data->segment_data[i] = next_addr; + next_addr += header->data_len; + } + assert(cnt == 2); + + uint32_t end_addr = next_addr; + if (end_addr < data->start_addr) { + return ESP_FAIL; + } + + data->image_len += end_addr - start_segments; + + return ESP_OK; +} + +void image_process_get_flash_segments_info(uint32_t *out_drom_paddr_start, uint32_t *out_irom_paddr_start) +{ + assert(out_drom_paddr_start && out_irom_paddr_start); + *out_drom_paddr_start = s_flash_drom_paddr_start; + *out_irom_paddr_start = s_flash_irom_paddr_start; +} + +esp_err_t image_process(void) +{ +#if IMAGE_PROCESS_SUPPORTED_TARGETS + esp_err_t ret = ESP_FAIL; + /** + * We use the MMU_LL_END_DROM_ENTRY_ID mmu entry as a map page for app to find the boot partition + * This depends on 2nd bootloader to set the entry + */ + uint32_t paddr_base = mmu_ll_entry_id_to_paddr_base(0, MMU_LL_END_DROM_ENTRY_ID); + uint32_t part_offset = paddr_base; + esp_image_metadata_t image_data = {0}; + ret = process_image_header(&image_data, part_offset); + if (ret != ESP_OK) { + ESP_EARLY_LOGE(TAG, "failed to process image header"); + abort(); + } + + ret = s_image_process_driver.process_segments(&image_data); + if (ret != ESP_OK) { + ESP_EARLY_LOGE(TAG, "failed to process segments"); + return ESP_FAIL; + } + + mmu_ll_set_entry_invalid(0, MMU_LL_END_DROM_ENTRY_ID); +#else + (void)s_image_process_driver; +#endif + + return ESP_OK; +} diff --git a/components/esp_system/port/include/esp_clk_internal.h b/components/esp_system/port/include/esp_clk_internal.h index 358002e2a197..a3829368b326 100644 --- a/components/esp_system/port/include/esp_clk_internal.h +++ b/components/esp_system/port/include/esp_clk_internal.h @@ -18,6 +18,15 @@ extern "C" { * Private clock-related functions */ +/** + * @brief Initialize rtc-related settings + * + * Called from cpu_start.c, not intended to be called from other places. + * This function configures the power related stuff. + * After this the MSPI timing tuning can be done. + */ +void esp_rtc_init(void); + /** * @brief Initialize clock-related settings * diff --git a/components/esp_system/port/include/private/esp_private/image_process.h b/components/esp_system/port/include/private/esp_private/image_process.h new file mode 100644 index 000000000000..e68bd82899f1 --- /dev/null +++ b/components/esp_system/port/include/private/esp_private/image_process.h @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Image process driver + */ +typedef struct image_process_driver_s image_process_driver_t; + +/** + * @brief Image process flow + * @note This API first reads the image header, then process the segments from the image header. + * This API can be further inserted with more steps about the image processing by registering + * more function pointer in `image_process_driver_t`. + * + * @return + * - ESP_OK + * - ESP_FAIL: image process flow fails + */ +esp_err_t image_process(void); + +/** + * @brief get flash segments info, only available after image_process() has been called + * + * @param[out] out_drom_paddr_start drom paddr start + * @param[out] out_irom_paddr_start irom paddr start + */ +void image_process_get_flash_segments_info(uint32_t *out_drom_paddr_start, uint32_t *out_irom_paddr_start); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_system/port/panic_handler.c b/components/esp_system/port/panic_handler.c index 4f27c1061d95..de55b1cd8ec7 100644 --- a/components/esp_system/port/panic_handler.c +++ b/components/esp_system/port/panic_handler.c @@ -151,9 +151,20 @@ static void panic_handler(void *frame, bool pseudo_excause) busy_wait(); } else if (panic_get_cause(frame) == PANIC_RSN_INTWDT_CPU1 && core_id == 0) { busy_wait(); - } else if (panic_get_cause(frame) == PANIC_RSN_CACHEERR && core_id != esp_cache_err_get_cpuid()) { - g_exc_frames[core_id] = NULL; // Only print the backtrace for the offending core - busy_wait(); + } else if (panic_get_cause(frame) == PANIC_RSN_CACHEERR) { + // The invalid cache access interrupt calls to the panic handler. + // When the cache interrupt happens, we can not determine the CPU where the + // invalid cache access has occurred. + if (esp_cache_err_get_cpuid() == -1) { + // We can not determine the CPU where the invalid cache access has occurred. + // Print backtraces for both CPUs. + if (core_id != 0) { + busy_wait(); + } + } else if (core_id != esp_cache_err_get_cpuid()) { + g_exc_frames[core_id] = NULL; // Only print the backtrace for the offending core + busy_wait(); + } } #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD else if (panic_get_cause(frame) == ETS_ASSIST_DEBUG_INUM && @@ -183,7 +194,7 @@ static void panic_handler(void *frame, bool pseudo_excause) #if __XTENSA__ if (!(esp_ptr_executable(esp_cpu_pc_to_addr(panic_get_address(frame))) && (panic_get_address(frame) & 0xC0000000U))) { /* Xtensa ABI sets the 2 MSBs of the PC according to the windowed call size - * Incase the PC is invalid, GDB will fail to translate addresses to function names + * In case the PC is invalid, GDB will fail to translate addresses to function names * Hence replacing the PC to a placeholder address in case of invalid PC */ panic_set_address(frame, (uint32_t)&_invalid_pc_placeholder); diff --git a/components/esp_system/port/soc/esp32/clk.c b/components/esp_system/port/soc/esp32/clk.c index 0de819e687e6..88f72ff94733 100644 --- a/components/esp_system/port/soc/esp32/clk.c +++ b/components/esp_system/port/soc/esp32/clk.c @@ -106,11 +106,14 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk) esp_clk_slowclk_cal_set(cal_val); } -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { rtc_config_t cfg = RTC_CONFIG_DEFAULT(); rtc_init(cfg); +} +__attribute__((weak)) void esp_clk_init(void) +{ #if (CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS || CONFIG_APP_INIT_CLK) /* Check the bootloader set the XTAL frequency. diff --git a/components/esp_system/port/soc/esp32c2/clk.c b/components/esp_system/port/soc/esp32c2/clk.c index 25d79e21993a..6cc267ea6c88 100644 --- a/components/esp_system/port/soc/esp32c2/clk.c +++ b/components/esp_system/port/soc/esp32c2/clk.c @@ -51,11 +51,18 @@ typedef enum { } slow_clk_sel_t; static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); +static __attribute__((unused)) void recalib_bbpll(void); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { +#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB + // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. + // Do calibration again here so that we can use better clock for the timing tuning. + recalib_bbpll(); +#endif + #if !CONFIG_IDF_ENV_FPGA rtc_config_t cfg = RTC_CONFIG_DEFAULT(); soc_reset_reason_t rst_reas; @@ -64,7 +71,12 @@ __attribute__((weak)) void esp_clk_init(void) cfg.cali_ocode = 1; } rtc_init(cfg); +#endif +} +__attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA #ifndef CONFIG_XTAL_FREQ_AUTO assert(rtc_clk_xtal_freq_get() == CONFIG_XTAL_FREQ); #endif @@ -77,11 +89,16 @@ __attribute__((weak)) void esp_clk_init(void) #ifdef CONFIG_BOOTLOADER_WDT_ENABLE // WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed. // If the frequency changes from 150kHz to 32kHz, then the timeout set for the WDT will increase 4.6 times. - // Therefore, for the time of frequency change, set a new lower timeout value (1.6 sec). + // Therefore, for the time of frequency change, set a new lower timeout value (1.6 sec on 40MHz XTAL and 2.5 sec on 26MHz XTAL). // This prevents excessive delay before resetting in case the supply voltage is drawdown. - // (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 1.6sec * 150/32 = 7.5 sec). + // (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 1.6sec * 150/32 = 7.5 sec 40MHz XTAL, + // or 11.72 sec on 26MHz XTAL). wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#ifdef CONFIG_XTAL_FREQ_26 + uint32_t stage_timeout_ticks = (uint32_t)(2500ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); +#else uint32_t stage_timeout_ticks = (uint32_t)(1600ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); +#endif wdt_hal_write_protect_disable(&rtc_wdt_ctx); wdt_hal_feed(&rtc_wdt_ctx); //Bootloader has enabled RTC WDT until now. We're only modifying timeout, so keep the stage and timeout action the same @@ -260,3 +277,21 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); } + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +static void IRAM_ATTR NOINLINE_ATTR recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index 972dc75d1ba2..ece3d4c732fc 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -56,7 +56,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { #if !CONFIG_IDF_ENV_FPGA rtc_config_t cfg = RTC_CONFIG_DEFAULT(); @@ -70,7 +70,10 @@ __attribute__((weak)) void esp_clk_init(void) cfg.cali_ocode = 1; } rtc_init(cfg); +} +__attribute__((weak)) void esp_clk_init(void) +{ assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); diff --git a/components/esp_system/port/soc/esp32c5/clk.c b/components/esp_system/port/soc/esp32c5/clk.c index 38aa5f9a6cd6..b8828072ce40 100644 --- a/components/esp_system/port/soc/esp32c5/clk.c +++ b/components/esp_system/port/soc/esp32c5/clk.c @@ -47,31 +47,25 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; // TODO: [ESP32C5] IDF-8642 -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { #if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION #if SOC_PMU_SUPPORTED pmu_init(); #endif +#endif +} +// TODO: [ESP32C5] IDF-8642 +__attribute__((weak)) void esp_clk_init(void) +{ +#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION assert((rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M) || (rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_48M)); #if SOC_MODEM_CLOCK_SUPPORTED modem_lpcon_ll_set_pwr_tick_target(&MODEM_LPCON, rtc_clk_xtal_freq_get() - 1); #endif rtc_clk_8m_enable(true); rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); -#elif CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION -#if !CONFIG_IDF_ENV_FPGA - pmu_init(); - if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { - esp_ocode_calib_init(); - } - - assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); - - rtc_clk_8m_enable(true); - rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); -#endif #endif #ifdef CONFIG_BOOTLOADER_WDT_ENABLE diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index e2b1e8d20e82..42a2f8f00a30 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -58,17 +58,29 @@ #define MHZ (1000000) static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); +static __attribute__((unused)) void recalib_bbpll(void); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { +#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB + // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. + // Do calibration again here so that we can use better clock for the timing tuning. + recalib_bbpll(); +#endif + #if !CONFIG_IDF_ENV_FPGA pmu_init(); if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { esp_ocode_calib_init(); } +#endif +} +__attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); rtc_clk_8m_enable(true); @@ -302,3 +314,21 @@ __attribute__((weak)) void esp_perip_clk_init(void) WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); } } + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +static void IRAM_ATTR NOINLINE_ATTR recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} diff --git a/components/esp_system/port/soc/esp32c61/clk.c b/components/esp_system/port/soc/esp32c61/clk.c index 9eabae25939e..9a82793f6f73 100644 --- a/components/esp_system/port/soc/esp32c61/clk.c +++ b/components/esp_system/port/soc/esp32c61/clk.c @@ -41,14 +41,19 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { #if !CONFIG_IDF_ENV_FPGA pmu_init(); if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { esp_ocode_calib_init(); } +#endif +} +__attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); rtc_clk_8m_enable(true); diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 0523bd8c92b4..87e2140cf3e6 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -58,14 +58,26 @@ #define MHZ (1000000) static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); +static __attribute__((unused)) void recalib_bbpll(void); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { +#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB + // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. + // Do calibration again here so that we can use better clock for the timing tuning. + recalib_bbpll(); +#endif + #if !CONFIG_IDF_ENV_FPGA pmu_init(); +#endif +} +__attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_32M); rtc_clk_8m_enable(true); @@ -290,3 +302,21 @@ __attribute__((weak)) void esp_perip_clk_init(void) WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); } } + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +static void IRAM_ATTR NOINLINE_ATTR recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. Flash_PLL comes from the same source as PLL. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL || old_config.source == SOC_CPU_CLK_SRC_FLASH_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} diff --git a/components/esp_system/port/soc/esp32p4/Kconfig.system b/components/esp_system/port/soc/esp32p4/Kconfig.system index e69de29bb2d1..5ffec7fe769b 100644 --- a/components/esp_system/port/soc/esp32p4/Kconfig.system +++ b/components/esp_system/port/soc/esp32p4/Kconfig.system @@ -0,0 +1,45 @@ +menu "Brownout Detector" + config ESP_BROWNOUT_DET + bool "Hardware brownout detect & reset" + depends on !IDF_ENV_FPGA + default y + help + The ESP32-P4 has a built-in brownout detector which can detect if the voltage is lower than + a specific value. If this happens, it will reset the chip in order to prevent unintended + behaviour. + + choice ESP_BROWNOUT_DET_LVL_SEL + prompt "Brownout voltage level" + depends on ESP_BROWNOUT_DET + default ESP_BROWNOUT_DET_LVL_SEL_7 + help + The brownout detector will reset the chip when the supply voltage is approximately + below this level. Note that there may be some variation of brownout voltage level + between each chip. + + #The voltage levels here are estimates, more work needs to be done to figure out the exact voltages + #of the brownout threshold levels. + config ESP_BROWNOUT_DET_LVL_SEL_7 + bool "2.51V" + config ESP_BROWNOUT_DET_LVL_SEL_6 + bool "2.64V" + config ESP_BROWNOUT_DET_LVL_SEL_5 + bool "2.76V" + config ESP_BROWNOUT_DET_LVL_SEL_4 + bool "2.92V" + config ESP_BROWNOUT_DET_LVL_SEL_3 + bool "3.10V" + config ESP_BROWNOUT_DET_LVL_SEL_2 + bool "3.27V" + endchoice + + config ESP_BROWNOUT_DET_LVL + int + default 2 if ESP_BROWNOUT_DET_LVL_SEL_2 + default 3 if ESP_BROWNOUT_DET_LVL_SEL_3 + default 4 if ESP_BROWNOUT_DET_LVL_SEL_4 + default 5 if ESP_BROWNOUT_DET_LVL_SEL_5 + default 6 if ESP_BROWNOUT_DET_LVL_SEL_6 + default 7 if ESP_BROWNOUT_DET_LVL_SEL_7 + +endmenu diff --git a/components/esp_system/port/soc/esp32p4/cache_err_int.c b/components/esp_system/port/soc/esp32p4/cache_err_int.c index c1a20bbee16c..24904c2d5a8e 100644 --- a/components/esp_system/port/soc/esp32p4/cache_err_int.c +++ b/components/esp_system/port/soc/esp32p4/cache_err_int.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,19 +20,24 @@ static const char *TAG = "CACHE_ERR"; -//TODO: IDF-7515 +const char cache_error_msg[] = "Cache access error"; + const char *esp_cache_err_panic_string(void) { - return NULL; + uint32_t access_err_status = cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK) | cache_ll_l2_get_access_error_intr_status(0, CACHE_LL_L2_ACCESS_EVENT_MASK); + + /* Return the error string if a cache error is active */ + const char* err_str = access_err_status ? cache_error_msg : NULL; + + return err_str; } -//TODO: IDF-7515 bool esp_cache_err_has_active_err(void) { - return false; + bool has_active_err = cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK) | cache_ll_l2_get_access_error_intr_status(0, CACHE_LL_L2_ACCESS_EVENT_MASK); + return has_active_err; } -//TODO: IDF-7515 void esp_cache_err_int_init(void) { const uint32_t core_id = 0; @@ -56,10 +61,13 @@ void esp_cache_err_int_init(void) esprv_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM); ESP_DRAM_LOGV(TAG, "access error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ACCESS_EVENT_MASK); - /* On the hardware side, start by clearing all the bits reponsible for cache access error */ + /* On the hardware side, start by clearing all the bits responsible for cache access error */ cache_ll_l1_clear_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + cache_ll_l2_clear_access_error_intr(0, CACHE_LL_L2_ACCESS_EVENT_MASK); + /* Then enable cache access error interrupts. */ cache_ll_l1_enable_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK); + cache_ll_l2_enable_access_error_intr(0, CACHE_LL_L2_ACCESS_EVENT_MASK); /* Enable the interrupts for cache error. */ ESP_INTR_ENABLE(ETS_CACHEERR_INUM); @@ -67,7 +75,11 @@ void esp_cache_err_int_init(void) int esp_cache_err_get_cpuid(void) { - //TODO: IDF-7515 - //Should return hart ID according to the cache error - return 0; + if (cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_CORE0_EVENT_MASK)) { + return 0; + } else if (cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_CORE1_EVENT_MASK)) { + return 1; + } else { + return -1; + } } diff --git a/components/esp_system/port/soc/esp32p4/clk.c b/components/esp_system/port/soc/esp32p4/clk.c index c00287e5a10c..49f9737e8efb 100644 --- a/components/esp_system/port/soc/esp32p4/clk.c +++ b/components/esp_system/port/soc/esp32p4/clk.c @@ -41,12 +41,15 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void IRAM_ATTR esp_rtc_init(void) { #if SOC_PMU_SUPPORTED pmu_init(); #endif //SOC_PMU_SUPPORTED +} +__attribute__((weak)) void esp_clk_init(void) +{ assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); rtc_clk_8m_enable(true); diff --git a/components/esp_system/port/soc/esp32p4/reset_reason.c b/components/esp_system/port/soc/esp32p4/reset_reason.c index afcb6184df11..b9cea8ddfeef 100644 --- a/components/esp_system/port/soc/esp32p4/reset_reason.c +++ b/components/esp_system/port/soc/esp32p4/reset_reason.c @@ -8,6 +8,8 @@ #include "esp_rom_sys.h" #include "esp_private/system_internal.h" #include "soc/rtc_periph.h" +#include "soc/chip_revision.h" +#include "hal/efuse_hal.h" #include "esp32p4/rom/rtc.h" static void esp_reset_reason_clear_hint(void); @@ -57,7 +59,9 @@ static esp_reset_reason_t get_reset_reason(soc_reset_reason_t rtc_reset_reason, case RESET_REASON_CORE_EFUSE_CRC: #if CONFIG_IDF_TARGET_ESP32P4 - return ESP_RST_DEEPSLEEP; // TODO: IDF-9564 + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { + return ESP_RST_DEEPSLEEP; + } #endif return ESP_RST_EFUSE; diff --git a/components/esp_system/port/soc/esp32p4/system_internal.c b/components/esp_system/port/soc/esp32p4/system_internal.c index 2bd22c2be2ff..547f29181010 100644 --- a/components/esp_system/port/soc/esp32p4/system_internal.c +++ b/components/esp_system/port/soc/esp32p4/system_internal.c @@ -49,6 +49,7 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART3_CORE); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART4_CORE); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_GDMA); + SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_ADC); // Clear Peripheral clk rst CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_TIMERGRP0); @@ -62,6 +63,7 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART3_CORE); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART4_CORE); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_GDMA); + CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_ADC); #if CONFIG_ESP32P4_REV_MIN_FULL <= 100 // enable soc clk and reset parent crypto diff --git a/components/esp_system/port/soc/esp32s2/clk.c b/components/esp_system/port/soc/esp32s2/clk.c index 7da508fde773..45d932ba5205 100644 --- a/components/esp_system/port/soc/esp32s2/clk.c +++ b/components/esp_system/port/soc/esp32s2/clk.c @@ -59,7 +59,7 @@ typedef enum { static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { rtc_config_t cfg = RTC_CONFIG_DEFAULT(); soc_reset_reason_t rst_reas = esp_rom_get_reset_reason(0); @@ -73,7 +73,10 @@ __attribute__((weak)) void esp_clk_init(void) } } rtc_init(cfg); +} +__attribute__((weak)) void esp_clk_init(void) +{ bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); rtc_clk_8m_enable(true, rc_fast_d256_is_enabled); rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); diff --git a/components/esp_system/port/soc/esp32s3/clk.c b/components/esp_system/port/soc/esp32s3/clk.c index 4589d5e4f941..fac148fb41a5 100644 --- a/components/esp_system/port/soc/esp32s3/clk.c +++ b/components/esp_system/port/soc/esp32s3/clk.c @@ -54,9 +54,16 @@ typedef enum { } slow_clk_sel_t; static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); +static __attribute__((unused)) void recalib_bbpll(void); -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { +#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB + // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. + // Do calibration again here so that we can use better clock for the timing tuning. + recalib_bbpll(); +#endif + rtc_config_t cfg = RTC_CONFIG_DEFAULT(); soc_reset_reason_t rst_reas; rst_reas = esp_rom_get_reset_reason(0); @@ -65,7 +72,10 @@ __attribute__((weak)) void esp_clk_init(void) cfg.cali_ocode = 1; } rtc_init(cfg); +} +__attribute__((weak)) void esp_clk_init(void) +{ assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); @@ -325,3 +335,21 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); } + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +static void IRAM_ATTR NOINLINE_ATTR recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} diff --git a/components/esp_system/task_wdt/task_wdt_impl_timergroup.c b/components/esp_system/task_wdt/task_wdt_impl_timergroup.c index 5d0fef7234c8..8b8ed6318053 100644 --- a/components/esp_system/task_wdt/task_wdt_impl_timergroup.c +++ b/components/esp_system/task_wdt/task_wdt_impl_timergroup.c @@ -11,13 +11,19 @@ #include "hal/wdt_hal.h" #include "hal/mwdt_ll.h" #include "hal/timer_ll.h" +#include "esp_check.h" #include "esp_err.h" #include "esp_attr.h" #include "esp_intr_alloc.h" +#include "esp_log.h" #include "esp_private/system_internal.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_task_wdt_impl.h" +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +#include "esp_private/sleep_retention.h" +#endif + #define TWDT_INSTANCE WDT_MWDT0 #define TWDT_TICKS_PER_US 500 #define TWDT_PRESCALER MWDT_LL_DEFAULT_CLK_PRESCALER // Tick period of 500us if WDT source clock is 80MHz @@ -39,6 +45,48 @@ typedef struct { * init function. */ static twdt_ctx_hard_t init_context; +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +static const char* TAG = "task_wdt"; +static esp_err_t sleep_task_wdt_retention_init(void *arg) +{ + uint32_t group_id = *(uint32_t *)arg; + esp_err_t err = sleep_retention_entries_create(tg_wdt_regs_retention[group_id].link_list, + tg_wdt_regs_retention[group_id].link_num, + REGDMA_LINK_PRI_SYS_PERIPH_LOW, + (group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err == ESP_OK) { + ESP_LOGD(TAG, "Task watchdog timer retention initialization"); + } + ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for task watchdog timer"); + return err; +} + +static esp_err_t esp_task_wdt_retention_enable(uint32_t group_id) +{ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_task_wdt_retention_init, .arg = &group_id } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + esp_err_t err = sleep_retention_module_init((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for task watchdog timer retention"); + } + } + return err; +} + +static esp_err_t esp_task_wdt_retention_disable(uint32_t group_id) +{ + esp_err_t err = sleep_retention_module_free((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + if (err == ESP_OK) { + err = sleep_retention_module_deinit((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_WDT : SLEEP_RETENTION_MODULE_TG1_WDT); + } + return err; +} +#endif + esp_err_t esp_task_wdt_impl_timer_allocate(const esp_task_wdt_config_t *config, twdt_isr_callback callback, twdt_ctx_t *obj) @@ -74,8 +122,11 @@ esp_err_t esp_task_wdt_impl_timer_allocate(const esp_task_wdt_config_t *config, /* Return the implementation context to the caller */ *obj = (twdt_ctx_t) ctx; - } +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION + esp_task_wdt_retention_enable(TWDT_TIMER_GROUP); +#endif + } return ret; } @@ -118,6 +169,10 @@ void esp_task_wdt_impl_timer_free(twdt_ctx_t obj) /* Deregister interrupt */ ESP_ERROR_CHECK(esp_intr_free(ctx->intr_handle)); + +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION + ESP_ERROR_CHECK(esp_task_wdt_retention_disable(TWDT_TIMER_GROUP)); +#endif } } diff --git a/components/esp_system/test_apps/.build-test-rules.yml b/components/esp_system/test_apps/.build-test-rules.yml index d35ca3820c77..e0343c14e304 100644 --- a/components/esp_system/test_apps/.build-test-rules.yml +++ b/components/esp_system/test_apps/.build-test-rules.yml @@ -7,8 +7,6 @@ components/esp_system/test_apps/console: components/esp_system/test_apps/esp_system_unity_tests: disable: - if: IDF_TARGET == "esp32c5" or (CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1) - temporary: true - reason: C5 not support yet # TODO: [ESP32C5] IDF-8690 components/esp_system/test_apps/linux_apis: enable: diff --git a/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py b/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py index 730a390a4754..06432a8158ec 100644 --- a/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py +++ b/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py @@ -20,7 +20,6 @@ def not_expect(dut: Dut, output_regex: str) -> None: pytest.mark.esp32c3, pytest.mark.esp32c6, pytest.mark.esp32h2, - pytest.mark.esp32p4, ] diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c index 08fbb40a4f49..c924b5c5bbe7 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -15,6 +15,13 @@ #include "test_utils.h" #include "soc/rtc.h" +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +#include "esp_sleep.h" +#include "esp_private/esp_sleep_internal.h" +#include "esp_private/sleep_cpu.h" +#include "esp_private/esp_pmu.h" +#endif + #define TASK_WDT_TIMEOUT_MS 1000 static volatile bool timeout_flag; @@ -41,6 +48,36 @@ TEST_CASE("Task WDT task timeout", "[task_wdt]") TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit()); } +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION +TEST_CASE("Task WDT task timeout after peripheral powerdown lightsleep", "[task_wdt]") +{ + timeout_flag = false; + esp_task_wdt_config_t twdt_config = { + .timeout_ms = TASK_WDT_TIMEOUT_MS, + .idle_core_mask = 0, + .trigger_panic = false, + }; + TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_init(&twdt_config)); + TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_add(NULL)); + + TEST_ESP_OK(sleep_cpu_configure(true)); + esp_sleep_context_t sleep_ctx; + esp_sleep_set_sleep_context(&sleep_ctx); + esp_sleep_enable_timer_wakeup(10 * 1000); + esp_light_sleep_start(); + + TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); + TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); + + // Short delay to allow timeout to occur + esp_rom_delay_us(TASK_WDT_TIMEOUT_MS * 1000); + TEST_ASSERT_EQUAL(true, timeout_flag); + TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_delete(NULL)); + TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit()); + TEST_ESP_OK(sleep_cpu_configure(false)); +} +#endif + #if SOC_MWDT_SUPPORT_XTAL #if CONFIG_IDF_TARGET_ESP32H2 @@ -92,7 +129,7 @@ TEST_CASE("Task WDT inactive when no task to watch", "[task_wdt]") TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_add(NULL)); esp_rom_delay_us(TASK_WDT_TIMEOUT_MS * 1000); TEST_ASSERT_EQUAL(true, timeout_flag); - /* Remove the task we just addded and make sure the WDT is stopped*/ + /* Remove the task we just added and make sure the WDT is stopped*/ timeout_flag = false; TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_delete(NULL)); esp_rom_delay_us(2 * TASK_WDT_TIMEOUT_MS * 1000); diff --git a/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.default b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.default index 31d50f69086f..fcbda27d4066 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.default +++ b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.default @@ -1,3 +1,5 @@ # Default configuration # Used for testing stack smashing protection CONFIG_COMPILER_STACK_CHECK=y +CONFIG_ESP_SLEEP_DEBUG=y +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y diff --git a/components/esp_timer/src/esp_timer_impl_systimer.c b/components/esp_timer/src/esp_timer_impl_systimer.c index 1f2161fa9969..549316a6dacd 100644 --- a/components/esp_timer/src/esp_timer_impl_systimer.c +++ b/components/esp_timer/src/esp_timer_impl_systimer.c @@ -180,6 +180,10 @@ esp_err_t esp_timer_impl_early_init(void) systimer_hal_select_alarm_mode(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_ALARM_MODE_ONESHOT); systimer_hal_connect_alarm_counter(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_COUNTER_ESPTIMER); + for (unsigned cpuid = 0; cpuid < SOC_CPU_CORES_NUM; ++cpuid) { + systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_COUNTER_ESPTIMER, cpuid, (cpuid < portNUM_PROCESSORS) ? true : false); + } + return ESP_OK; } diff --git a/components/esp_timer/test_apps/.build-test-rules.yml b/components/esp_timer/test_apps/.build-test-rules.yml deleted file mode 100644 index 748bc781b276..000000000000 --- a/components/esp_timer/test_apps/.build-test-rules.yml +++ /dev/null @@ -1,7 +0,0 @@ -# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps - -components/esp_timer/test_apps: - disable: - - if: IDF_TARGET == "esp32c5" - temporary: true - reason: C5 not support yet # TODO: [ESP32C5] IDF-8705 diff --git a/components/esp_timer/test_apps/README.md b/components/esp_timer/test_apps/README.md index c75201fb88f7..351f5fdebc72 100644 --- a/components/esp_timer/test_apps/README.md +++ b/components/esp_timer/test_apps/README.md @@ -1,3 +1,3 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_vfs_console/vfs_console.c b/components/esp_vfs_console/vfs_console.c index b071d521ad8b..980514c1d46d 100644 --- a/components/esp_vfs_console/vfs_console.c +++ b/components/esp_vfs_console/vfs_console.c @@ -73,7 +73,7 @@ ssize_t console_write(int fd, const void *data, size_t size) int console_fstat(int fd, struct stat * st) { - return fstat(fd, st); + return fstat(vfs_console.fd_primary, st); } int console_close(int fd) diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index b83613ec2407..67f268c8fd73 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -348,17 +348,30 @@ menu "Wi-Fi" int "Minimum active time" range 8 60 default 50 - depends on ESP_WIFI_SLP_IRAM_OPT help - The minimum timeout for waiting to receive data, unit: milliseconds. + Only for station in WIFI_PS_MIN_MODEM or WIFI_PS_MAX_MODEM. When the station enters the active state, + it will work for at least ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME. If a data packet is received or sent + during this period, the time will be refreshed. If the time is up, but the station still has packets + to receive or send, the time will also be refreshed. unit: milliseconds. config ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME int "Maximum keep alive time" range 10 60 default 10 - depends on ESP_WIFI_SLP_IRAM_OPT help - The maximum time that wifi keep alive, unit: seconds. + Only for station in WIFI_PS_MIN_MODEM or WIFI_PS_MAX_MODEM. If no packet has been + sent within ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME, a null data packet will be sent + to maintain the connection with the AP. unit: seconds. + + config ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME + int "Minimum wait broadcast data time" + range 10 30 + default 15 + help + Only for station in WIFI_PS_MIN_MODEM or WIFI_PS_MAX_MODEM. When the station knows through the beacon + that AP will send broadcast packet, it will wait for ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME + before entering the sleep process. If a broadcast packet is received with more data bits, the time + will refreshed. unit: milliseconds. config ESP_WIFI_FTM_ENABLE bool "WiFi FTM" @@ -393,7 +406,7 @@ menu "Wi-Fi" config ESP_WIFI_GMAC_SUPPORT bool "WiFi GMAC Support(GMAC128 and GMAC256)" - default n + default y help Select this option to enable GMAC support. GMAC support is compulsory for WiFi 192 bit certification. diff --git a/components/esp_wifi/esp32/esp_adapter.c b/components/esp_wifi/esp32/esp_adapter.c index 4bc3a36706b1..ce79917000c6 100644 --- a/components/esp_wifi/esp32/esp_adapter.c +++ b/components/esp_wifi/esp32/esp_adapter.c @@ -578,6 +578,24 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { @@ -712,5 +730,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32c2/esp_adapter.c b/components/esp_wifi/esp32c2/esp_adapter.c index 6efcee961014..4c0b4212cc4d 100644 --- a/components/esp_wifi/esp32c2/esp_adapter.c +++ b/components/esp_wifi/esp32c2/esp_adapter.c @@ -517,6 +517,24 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { @@ -650,5 +668,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32c3/esp_adapter.c b/components/esp_wifi/esp32c3/esp_adapter.c index 923c3fcefdee..10ec230ee967 100644 --- a/components/esp_wifi/esp32c3/esp_adapter.c +++ b/components/esp_wifi/esp32c3/esp_adapter.c @@ -534,6 +534,24 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { @@ -667,5 +685,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32c5/esp_adapter.c b/components/esp_wifi/esp32c5/esp_adapter.c index bf123ecf84b2..c0c735e01a79 100644 --- a/components/esp_wifi/esp32c5/esp_adapter.c +++ b/components/esp_wifi/esp32c5/esp_adapter.c @@ -61,17 +61,17 @@ extern void wifi_apb80m_request(void); extern void wifi_apb80m_release(void); #endif -IRAM_ATTR void *wifi_malloc( size_t size ) +IRAM_ATTR void *wifi_malloc(size_t size) { return malloc(size); } -IRAM_ATTR void *wifi_realloc( void *ptr, size_t size ) +IRAM_ATTR void *wifi_realloc(void *ptr, size_t size) { return realloc(ptr, size); } -IRAM_ATTR void *wifi_calloc( size_t n, size_t size ) +IRAM_ATTR void *wifi_calloc(size_t n, size_t size) { return calloc(n, size); } @@ -82,7 +82,7 @@ static void *IRAM_ATTR wifi_zalloc_wrapper(size_t size) return ptr; } -wifi_static_queue_t *wifi_create_queue( int queue_len, int item_size) +wifi_static_queue_t *wifi_create_queue(int queue_len, int item_size) { wifi_static_queue_t *queue = NULL; @@ -91,7 +91,7 @@ wifi_static_queue_t *wifi_create_queue( int queue_len, int item_size) return NULL; } - queue->handle = xQueueCreate( queue_len, item_size); + queue->handle = xQueueCreate(queue_len, item_size); return queue; } @@ -522,6 +522,24 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { @@ -664,5 +682,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { #endif ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32c6/esp_adapter.c b/components/esp_wifi/esp32c6/esp_adapter.c index b44e9860001d..aec8785a10b0 100644 --- a/components/esp_wifi/esp32c6/esp_adapter.c +++ b/components/esp_wifi/esp32c6/esp_adapter.c @@ -523,6 +523,24 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { @@ -672,5 +690,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { #endif ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32p4/esp_adapter.c b/components/esp_wifi/esp32p4/esp_adapter.c index e004f3c0d012..f78dc1972d6e 100644 --- a/components/esp_wifi/esp32p4/esp_adapter.c +++ b/components/esp_wifi/esp32p4/esp_adapter.c @@ -496,6 +496,16 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) return 0; } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ + return 0; +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ + return 1; +} + static void IRAM_ATTR esp_empty_wrapper(void) { @@ -750,5 +760,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32s2/esp_adapter.c b/components/esp_wifi/esp32s2/esp_adapter.c index 72d9fd4b54b6..95f9f2dbb102 100644 --- a/components/esp_wifi/esp32s2/esp_adapter.c +++ b/components/esp_wifi/esp32s2/esp_adapter.c @@ -573,6 +573,24 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { @@ -706,6 +724,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, - + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32s3/esp_adapter.c b/components/esp_wifi/esp32s3/esp_adapter.c index eaa13b29e988..ba3311a24001 100644 --- a/components/esp_wifi/esp32s3/esp_adapter.c +++ b/components/esp_wifi/esp32s3/esp_adapter.c @@ -590,6 +590,24 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { @@ -723,5 +741,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/include/esp_mesh.h b/components/esp_wifi/include/esp_mesh.h index 449365382980..18e55c2dfdb9 100644 --- a/components/esp_wifi/include/esp_mesh.h +++ b/components/esp_wifi/include/esp_mesh.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -141,7 +141,7 @@ extern "C" { #define MESH_ASSOC_FLAG_STA_VOTED (0x04) /**< station vote done, set when connect to router */ #define MESH_ASSOC_FLAG_NETWORK_FREE (0x08) /**< no root in current network */ #define MESH_ASSOC_FLAG_STA_VOTE_EXPIRE (0x10) /**< the voted address is expired, means the voted device lose the chance to be root */ -#define MESH_ASSOC_FLAG_ROOTS_FOUND (0x20) /**< roots conflict is found, means that thre are at least two roots in the mesh network */ +#define MESH_ASSOC_FLAG_ROOTS_FOUND (0x20) /**< roots conflict is found, means that there are at least two roots in the mesh network */ #define MESH_ASSOC_FLAG_ROOT_FIXED (0x40) /**< the root is fixed in the mesh network */ /** @@ -216,7 +216,7 @@ typedef enum { MESH_ROOT, /**< the only sink of the mesh network. Has the ability to access external IP network */ MESH_NODE, /**< intermediate device. Has the ability to forward packets over the mesh network */ MESH_LEAF, /**< has no forwarding ability */ - MESH_STA, /**< connect to router with a standlone Wi-Fi station mode, no network expansion capability */ + MESH_STA, /**< connect to router with a standalone Wi-Fi station mode, no network expansion capability */ } mesh_type_t; /** @@ -642,14 +642,16 @@ esp_err_t esp_mesh_stop(void); * - Field size should not exceed MESH_MPS. Note that the size of one mesh packet should not exceed MESH_MTU. * - Field proto should be set to data protocol in use (default is MESH_PROTO_BIN for binary). * - Field tos should be set to transmission tos (type of service) in use (default is MESH_TOS_P2P for point-to-point reliable). + * - If the packet is to the root, MESH_TOS_P2P must be set to ensure reliable transmission. + * - As long as the MESH_TOS_P2P is set, the API is blocking, even if the flag is set with MESH_DATA_NONBLOCK. + * - As long as the MESH_TOS_DEF is set, the API is non-blocking. * @param[in] flag bitmap for data sent + * - Flag is at least one of the three MESH_DATA_P2P/MESH_DATA_FROMDS/MESH_DATA_TODS, which represents the direction of packet sending. * - Speed up the route search - * - If the packet is to the root and "to" parameter is NULL, set this parameter to 0. * - If the packet is to an internal device, MESH_DATA_P2P should be set. * - If the packet is to the root ("to" parameter isn't NULL) or to external IP network, MESH_DATA_TODS should be set. * - If the packet is from the root to an internal device, MESH_DATA_FROMDS should be set. - * - Specify whether this API is block or non-block, block by default - * - If needs non-blocking, MESH_DATA_NONBLOCK should be set. Otherwise, may use esp_mesh_send_block_time() to specify a blocking time. + * - Specify whether this API is blocking or non-blocking, blocking by default. * - In the situation of the root change, MESH_DATA_DROP identifies this packet can be dropped by the new root * for upstream data to external IP network, we try our best to avoid data loss caused by the root change, but * there is a risk that the new root is running out of memory because most of memory is occupied by the pending data which @@ -684,6 +686,7 @@ esp_err_t esp_mesh_send(const mesh_addr_t *to, const mesh_data_t *data, int flag, const mesh_opt_t opt[], int opt_count); /** * @brief Set blocking time of esp_mesh_send() + * - Suggest to set the blocking time to at least 5s when the environment is poor. Otherwise, esp_mesh_send() may timeout frequently. * * @attention This API shall be called before mesh is started. * @@ -1202,6 +1205,7 @@ int esp_mesh_get_xon_qsize(void); /** * @brief Set whether allow more than one root existing in one network + * - The default value is true, that is, multiple roots are allowed. * * @param[in] allowed allow or not * diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index 880dd83076f5..59ea571db8e5 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -614,13 +614,13 @@ esp_err_t esp_wifi_internal_set_spp_amsdu(wifi_interface_t ifidx, bool spp_cap, void esp_wifi_internal_update_light_sleep_default_params(int min_freq_mhz, int max_freq_mhz); /** - * @brief Set the delay time for wifi to enter the sleep state when light sleep + * @brief Set the min active time for wifi to enter the sleep state when light sleep * - * @param return_to_sleep_delay: minimum timeout time for waiting to receive + * @param min_active_time: minimum timeout time for waiting to receive * data, when no data is received during the timeout period, * the wifi enters the sleep process. */ -void esp_wifi_set_sleep_delay_time(uint32_t return_to_sleep_delay); +void esp_wifi_set_sleep_min_active_time(uint32_t min_active_time); /** * @brief Set wifi keep alive time @@ -629,6 +629,17 @@ void esp_wifi_set_sleep_delay_time(uint32_t return_to_sleep_delay); */ void esp_wifi_set_keep_alive_time(uint32_t keep_alive_time); +/** + * @brief Set the min broadcast data wait time for wifi to enter the sleep state + * + * @attention Default sleep wait broadcast data time is 15000, Uint µs. + * + * @param time: When the station knows through the beacon that the AP + * will send broadcast packet, it will wait for a minimum of + * wait_broadcast_data_time before entering the sleep process. + */ +void esp_wifi_set_sleep_wait_broadcast_data_time(uint32_t time); + /** * @brief Configure wifi beacon montior default parameters * diff --git a/components/esp_wifi/include/esp_private/wifi_os_adapter.h b/components/esp_wifi/include/esp_private/wifi_os_adapter.h index 4cf59977e67a..ded8bc0c21a9 100644 --- a/components/esp_wifi/include/esp_private/wifi_os_adapter.h +++ b/components/esp_wifi/include/esp_private/wifi_os_adapter.h @@ -153,6 +153,8 @@ typedef struct wifi_osi_funcs_t { void (* _regdma_link_set_write_wait_content)(void *, uint32_t, uint32_t); void * (* _sleep_retention_find_link_by_id)(int); #endif + int (*_coex_schm_flexible_period_set)(uint8_t); + uint8_t (*_coex_schm_flexible_period_get)(void); int32_t _magic; } wifi_osi_funcs_t; diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 6e49fc282dfd..7f8cde1c8591 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -242,6 +242,30 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; #define WIFI_FTM_RESPONDER 0 #endif +#if CONFIG_ESP_WIFI_GCMP_SUPPORT +#define WIFI_ENABLE_GCMP (1<<4) +#else +#define WIFI_ENABLE_GCMP 0 +#endif + +#if CONFIG_ESP_WIFI_GMAC_SUPPORT +#define WIFI_ENABLE_GMAC (1<<5) +#else +#define WIFI_ENABLE_GMAC 0 +#endif + +#if CONFIG_ESP_WIFI_11R_SUPPORT +#define WIFI_ENABLE_11R (1<<6) +#else +#define WIFI_ENABLE_11R 0 +#endif + +#if CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT +#define WIFI_ENABLE_ENTERPRISE (1<<7) +#else +#define WIFI_ENABLE_ENTERPRISE 0 +#endif + #if CONFIG_ESP_WIFI_ENABLE_DUMP_HESIGB && !WIFI_CSI_ENABLED #define WIFI_DUMP_HESIGB_ENABLED true #else @@ -258,12 +282,20 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs; #define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1) #define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2) #define CONFIG_FEATURE_FTM_RESPONDER_BIT (1<<3) +#define CONFIG_FEATURE_GCMP_BIT (1<<4) +#define CONFIG_FEATURE_GMAC_BIT (1<<5) +#define CONFIG_FEATURE_11R_BIT (1<<6) +#define CONFIG_FEATURE_WIFI_ENT_BIT (1<<7) /* Set additional WiFi features and capabilities */ #define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \ WIFI_ENABLE_SPIRAM | \ WIFI_FTM_INITIATOR | \ - WIFI_FTM_RESPONDER) + WIFI_FTM_RESPONDER | \ + WIFI_ENABLE_GCMP | \ + WIFI_ENABLE_GMAC | \ + WIFI_ENABLE_11R | \ + WIFI_ENABLE_ENTERPRISE) #define WIFI_INIT_CONFIG_DEFAULT() { \ .osi_funcs = &g_wifi_osi_funcs, \ @@ -365,7 +397,7 @@ esp_err_t esp_wifi_get_mode(wifi_mode_t *mode); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_INVALID_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: It doesn't normally happen, the function called inside the API was passed invalid argument, user should check if the wifi related config is correct * - ESP_ERR_NO_MEM: out of memory * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong * - ESP_FAIL: other WiFi internal errors @@ -598,7 +630,7 @@ esp_err_t esp_wifi_scan_get_ap_record(wifi_ap_record_t *ap_record); * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start * - ESP_ERR_WIFI_MODE: WiFi mode is wrong - * - ESP_ERR_INVALID_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: It doesn't normally happen, the function called inside the API was passed invalid argument, user should check if the wifi related config is correct */ esp_err_t esp_wifi_clear_ap_list(void); @@ -1596,6 +1628,21 @@ esp_err_t esp_wifi_set_band(wifi_band_t band); esp_err_t esp_wifi_get_band(wifi_band_t* band); #endif /* SOC_WIFI_HE_SUPPORT_5G */ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT +/** + * @brief Enable Wi-Fi coexistence power management + * + * @attention This API should be called after esp_wifi_init(). + * + * @param enabled Wi-Fi coexistence power management is enabled or not. + * + * @return + * - ESP_OK: succeed + * - others: failed + */ +esp_err_t esp_wifi_coex_pwr_configure(bool enabled); +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi_he.h b/components/esp_wifi/include/esp_wifi_he.h index 5bc361c2f818..57bf819afd93 100644 --- a/components/esp_wifi/include/esp_wifi_he.h +++ b/components/esp_wifi/include/esp_wifi_he.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -35,7 +35,7 @@ extern "C" { * - ESP_ERR_WIFI_TWT_FULL: no available flow id * - ESP_ERR_INVALID_ARG: invalid argument */ -esp_err_t esp_wifi_sta_itwt_setup(wifi_twt_setup_config_t *setup_config); +esp_err_t esp_wifi_sta_itwt_setup(wifi_itwt_setup_config_t *setup_config); /** * @brief Tear down individual TWT agreements @@ -142,6 +142,80 @@ esp_err_t esp_wifi_enable_rx_statistics(bool rx_stats, bool rx_mu_stats); */ esp_err_t esp_wifi_enable_tx_statistics(esp_wifi_aci_t aci, bool tx_stats); +/** + * @brief Set up an broadcast TWT agreement (NegotiationType=3) or change TWT parameters of the existing TWT agreement + * - TWT Wake Interval = TWT Wake Interval Mantissa * (2 ^ TWT Wake Interval Exponent), unit: us + * - e.g. TWT Wake Interval Mantissa = 512, TWT Wake Interval Exponent = 12, then TWT Wake Interval is 2097.152 ms + * Nominal Minimum Wake Duration = 255, then TWT Wake Duration is 65.28 ms + * + * @attention Support at most 32 TWT agreements, otherwise ESP_ERR_WIFI_TWT_FULL will be returned. + * Support sleep time up to (1 << 35) us. + * + * @param[in,out] config pointer to btwt setup config structure. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_NOT_CONNECT: The station is in disconnect status + * - ESP_ERR_WIFI_TWT_FULL: no available flow id + * - ESP_ERR_INVALID_ARG: invalid argument + */ +esp_err_t esp_wifi_sta_btwt_setup(wifi_btwt_setup_config_t *config); + +/** + * @brief Tear down broadcast TWT agreements + * + * @param[in] btwt_id The value range is [0, 31]. + * BTWT_ID_ALL indicates tear down all broadcast TWT agreements. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + * - ESP_ERR_WIFI_NOT_CONNECT: The station is in disconnect status + * - ESP_ERR_INVALID_ARG: invalid argument + */ +esp_err_t esp_wifi_sta_btwt_teardown(uint8_t btwt_id); + +/** + * @brief Get number of broadcast TWTs supported by the connected AP + * + * @param[out] btwt_number store number of btwts supported by the connected AP + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_INVALID_ARG: invalid argument + */ +esp_err_t esp_wifi_sta_get_btwt_num(uint8_t *btwt_number); + +/** + * @brief Get broadcast TWT information + * + * @param[in] btwt_number As input param, it stores max btwt number AP supported. + * @param[in] btwt_info array to hold the btwt information supported by AP, and the array size must be at least as large as the BTWT number. + * + * @return + * - ESP_OK: succeed + * - ESP_FAIL: fail + * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong + */ +esp_err_t esp_wifi_sta_btwt_get_info(uint8_t btwt_number, esp_wifi_btwt_info_t *btwt_info); + +/** + * @brief Set WiFi TWT config + * + * @param[in] config pointer to the WiFi TWT configure structure. + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_sta_twt_config(wifi_twt_config_t *config); + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi_he_types.h b/components/esp_wifi/include/esp_wifi_he_types.h index 0baf7a66d15c..404dc1cf1dbd 100644 --- a/components/esp_wifi/include/esp_wifi_he_types.h +++ b/components/esp_wifi/include/esp_wifi_he_types.h @@ -15,6 +15,7 @@ extern "C" { #endif #define FLOW_ID_ALL (8) +#define BTWT_ID_ALL (32) #define BSS_MAX_COLOR (63) /** @@ -112,24 +113,37 @@ typedef enum { } wifi_twt_setup_cmds_t; /** - * @brief TWT setup config + * @brief broadcast TWT setup config + */ +typedef struct { + wifi_twt_setup_cmds_t setup_cmd; /**< Indicates the type of TWT command*/ + uint8_t btwt_id; /**< When set up an broadcast TWT agreement, the broadcast twt id will be assigned by AP after a successful agreement setup. + broadcast twt id could be specified to a value in the range of [1, 31], but it might be change by AP in the response. + When change TWT parameters of the existing TWT agreement, broadcast twt id should be an existing one. The value range is [1, 31].*/ + uint16_t timeout_time_ms; /**< Timeout times of receiving setup action frame response, default 5s*/ +} wifi_btwt_setup_config_t; + +/** + * @brief Individual TWT setup config */ typedef struct { wifi_twt_setup_cmds_t setup_cmd; /**< Indicates the type of TWT command */ - uint16_t trigger : 1; /**< 1: a trigger-enabled TWT, 0: a non-trigger-enabled TWT */ - uint16_t flow_type : 1; /**< 0: an announced TWT, 1: an unannounced TWT */ + uint16_t trigger : 1; /**< 1: a trigger-enabled individual TWT, 0: a non-trigger-enabled individual TWT */ + uint16_t flow_type : 1; /**< 0: an announced individual TWT, 1: an unannounced individual TWT */ uint16_t flow_id : 3; /**< When set up an individual TWT agreement, the flow id will be assigned by AP after a successful agreement setup. flow_id could be specified to a value in the range of [0, 7], but it might be changed by AP in the response. When change TWT parameters of the existing TWT agreement, flow_id should be an existing one. The value range is [0, 7]. */ - uint16_t wake_invl_expn : 5; /**< TWT Wake Interval Exponent. The value range is [0, 31]. */ - uint16_t wake_duration_unit : 1; /**< TWT Wake duration unit, 0: 256us 1: TU (TU = 1024us)*/ + uint16_t wake_invl_expn : 5; /**< Individual TWT Wake Interval Exponent. The value range is [0, 31]. */ + uint16_t wake_duration_unit : 1; /**< Individual TWT Wake duration unit, 0: 256us 1: TU (TU = 1024us)*/ uint16_t reserved : 5; /**< bit: 11.15 reserved */ - uint8_t min_wake_dura; /**< Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the TWT requesting STA expects that it needs to be awake. The value range is [1, 255]. */ - uint16_t wake_invl_mant; /**< TWT Wake Interval Mantissa. The value range is [1, 65535]. */ - uint16_t twt_id; /**< TWT connection id, the value range is [0, 32767]. */ + uint8_t min_wake_dura; /**< Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the individual TWT requesting STA expects that it needs to be awake. The value range is [1, 255]. */ + uint16_t wake_invl_mant; /**< Individual TWT Wake Interval Mantissa. The value range is [1, 65535]. */ + uint16_t twt_id; /**< Individual TWT connection id, the value range is [0, 32767]. */ uint16_t timeout_time_ms; /**< Timeout times of receiving setup action frame response, default 5s*/ } wifi_twt_setup_config_t; +typedef wifi_twt_setup_config_t wifi_itwt_setup_config_t; + /** * @brief HE SU GI and LTF types */ @@ -294,19 +308,68 @@ typedef struct { } __attribute__((packed)) esp_wifi_rxctrl_t; #endif +/** + * @brief bTWT setup status + */ +typedef enum { + BTWT_SETUP_TXFAIL, /**< station sends btwt setup request frame fail */ + BTWT_SETUP_SUCCESS, /**< station receives btwt setup response frame and setup btwt sucessfully */ + BTWT_SETUP_TIMEOUT, /**< timeout of receiving btwt setup response frame */ + BTWT_SETUP_FULL, /**< indicate there is no available btwt id */ + BTWT_SETUP_INVALID_ARG, /**< indicate invalid argument to setup btwt */ + BTWT_SETUP_INTERNAL_ERR, /**< indicate internal error to setup btwt */ +} wifi_btwt_setup_status_t; + /** Argument structure for WIFI_EVENT_TWT_SET_UP event */ typedef struct { - wifi_twt_setup_config_t config; /**< itwt setup config, this value is determined by the AP */ + wifi_itwt_setup_config_t config; /**< itwt setup config, this value is determined by the AP */ esp_err_t status; /**< itwt setup status, 1: indicate setup success, others : indicate setup fail */ uint8_t reason; /**< itwt setup frame tx fail reason */ uint64_t target_wake_time; /**< TWT SP start time */ } wifi_event_sta_itwt_setup_t; +/** + * @brief iTWT teardown status + */ +typedef enum { + ITWT_TEARDOWN_FAIL, /**< station sends teardown frame fail */ + ITWT_TEARDOWN_SUCCESS, /**< 1) station successfully sends teardown frame to AP; 2) station receives teardown frame from AP */ +} wifi_itwt_teardown_status_t; + /** Argument structure for WIFI_EVENT_TWT_TEARDOWN event */ typedef struct { uint8_t flow_id; /**< flow id */ + wifi_itwt_teardown_status_t status; /**< itwt teardown status */ } wifi_event_sta_itwt_teardown_t; +/** Argument structure for WIFI_EVENT_BTWT_SET_UP event */ +typedef struct { + wifi_btwt_setup_status_t status; /**< indicate btwt setup status */ + wifi_twt_setup_cmds_t setup_cmd; /**< indicate the type of TWT command */ + uint8_t btwt_id; /**< indicate btwt id */ + uint8_t min_wake_dura; /**< Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the TWT requesting STA expects that it needs to be awake. The value range is [1, 255]. */ + uint8_t wake_invl_expn; /**< TWT Wake Interval Exponent. The value range is [0, 31]. */ + uint16_t wake_invl_mant; /**< TWT Wake Interval Mantissa. The value range is [1, 65535]. */ + bool trigger; /**< 1: a trigger-enabled TWT, 0: a non-trigger-enabled TWT */ + uint8_t flow_type; /**< 0: an announced TWT, 1: an unannounced TWT */ + uint8_t reason; /**< btwt setup frame tx fail reason */ + uint64_t target_wake_time; /**< TWT SP start time */ +} wifi_event_sta_btwt_setup_t; + +/** + * @brief BTWT teardown status + */ +typedef enum { + BTWT_TEARDOWN_FAIL, /**< station sends teardown frame fail */ + BTWT_TEARDOWN_SUCCESS, /**< 1) station successfully sends teardown frame to AP; 2) station receives teardown frame from AP */ +} wifi_btwt_teardown_status_t; + +/** Argument structure for WIFI_EVENT_TWT_TEARDOWN event */ +typedef struct { + uint8_t btwt_id; /**< btwt id */ + wifi_btwt_teardown_status_t status; /**< btwt teardown status */ +} wifi_event_sta_btwt_teardown_t; + /** * @brief iTWT probe status */ @@ -351,6 +414,21 @@ typedef struct { uint8_t flow_id; /**< flow id */ } wifi_event_sta_twt_wakeup_t; +/** Argument structure for twt information */ +typedef struct { + bool btwt_id_in_use; /**< indicate whether the btwt id is in use or not */ + uint16_t btwt_trigger : 1; /**< 1: a trigger-enabled TWT, 0: a non-trigger-enabled TWT */ + uint16_t btwt_flow_type : 1; /**< 0: an announced TWT, 1: an unannounced TWT */ + uint16_t btwt_recommendation : 3; /**< indicate recommendations on the types of frames. 0: no constraints, [1, 3], [4, 7] reserved */ + uint16_t btwt_wake_interval_exponent : 5; /**< TWT Wake Interval Exponent. The value range is [0, 31]. */ + uint16_t btwt_rsvd : 6; /**< reserved */ + uint8_t btwt_wake_duration; /**< TWT Wake duration unit, 0: 256us 1: TU (TU = 1024us) */ + uint16_t btwt_wake_interval_mantissa; /**< TWT Wake Interval Mantissa. The value range is [1, 65535]. */ + uint16_t btwt_info_id : 5; /**< btwt id */ + uint16_t btwt_info_persistence : 8; /**< indicate the number of TBTTs during which the Broadcast TWT SPs corresponding to this broadcast TWT parameters set are present */ + uint16_t btwt_info_rsvd : 3; /**< reserved */ +} esp_wifi_btwt_info_t; + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi_types_generic.h b/components/esp_wifi/include/esp_wifi_types_generic.h index 754672d84e20..37e6b203cbdd 100644 --- a/components/esp_wifi/include/esp_wifi_types_generic.h +++ b/components/esp_wifi/include/esp_wifi_types_generic.h @@ -70,6 +70,8 @@ typedef enum { WIFI_AUTH_WAPI_PSK, /**< authenticate mode : WAPI_PSK */ WIFI_AUTH_OWE, /**< authenticate mode : OWE */ WIFI_AUTH_WPA3_ENT_192, /**< authenticate mode : WPA3_ENT_SUITE_B_192_BIT */ + WIFI_AUTH_WPA3_EXT_PSK, /**< this authentication mode will yield same result as WIFI_AUTH_WPA3_PSK and not recommended to be used. It will be deprecated in future, please use WIFI_AUTH_WPA3_PSK instead. */ + WIFI_AUTH_WPA3_EXT_PSK_MIXED_MODE, /**< this authentication mode will yield same result as WIFI_AUTH_WPA3_PSK and not recommended to be used. It will be deprecated in future, please use WIFI_AUTH_WPA3_PSK instead.*/ WIFI_AUTH_DPP, /**< authenticate mode : DPP */ WIFI_AUTH_MAX } wifi_auth_mode_t; @@ -338,6 +340,8 @@ typedef struct { uint8_t ssid_hidden; /**< Broadcast SSID or not, default 0, broadcast the SSID */ uint8_t max_connection; /**< Max number of stations allowed to connect in */ uint16_t beacon_interval; /**< Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 */ + uint8_t csa_count; /**< Channel Switch Announcement Count. Notify the station that the channel will switch after the csa_count beacon intervals. Default value: 3 */ + uint8_t dtim_period; /**< Dtim period of soft-AP. Default value: 2 */ wifi_cipher_type_t pairwise_cipher; /**< Pairwise cipher of SoftAP, group cipher will be derived using this. Cipher values are valid starting from WIFI_CIPHER_TYPE_TKIP, enum values before that will be considered as invalid and default cipher suites(TKIP+CCMP) will be used. Valid cipher suites in softAP mode are WIFI_CIPHER_TYPE_TKIP, WIFI_CIPHER_TYPE_CCMP and WIFI_CIPHER_TYPE_TKIP_CCMP. */ bool ftm_responder; /**< Enable FTM Responder mode */ wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame */ @@ -813,6 +817,8 @@ typedef enum { WIFI_EVENT_ITWT_PROBE, /**< iTWT probe */ WIFI_EVENT_ITWT_SUSPEND, /**< iTWT suspend */ WIFI_EVENT_TWT_WAKEUP, /**< TWT wakeup */ + WIFI_EVENT_BTWT_SETUP, /**< bTWT setup */ + WIFI_EVENT_BTWT_TEARDOWN, /**< bTWT teardown*/ WIFI_EVENT_NAN_STARTED, /**< NAN Discovery has started */ WIFI_EVENT_NAN_STOPPED, /**< NAN Discovery has stopped */ @@ -875,6 +881,7 @@ typedef struct { typedef enum { WPS_FAIL_REASON_NORMAL = 0, /**< WPS normal fail reason */ WPS_FAIL_REASON_RECV_M2D, /**< WPS receive M2D frame */ + WPS_FAIL_REASON_RECV_DEAUTH, /**< Recv deauth from AP while wps handshake */ WPS_FAIL_REASON_MAX } wifi_event_sta_wps_fail_reason_t; @@ -903,7 +910,7 @@ typedef struct { uint8_t mac[6]; /**< MAC address of the station disconnects to soft-AP */ uint8_t aid; /**< the aid that soft-AP gave to the station disconnects to */ bool is_mesh_child; /**< flag to identify mesh child */ - uint8_t reason; /**< reason of disconnection */ + uint16_t reason; /**< reason of disconnection */ } wifi_event_ap_stadisconnected_t; /** Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 516ae8c58688..d1df171e4c97 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 516ae8c586881cc71c9f5a464e4f40cb3014b58f +Subproject commit d1df171e4c9756dac17aa586201c7f94b99dc8aa diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index c0dc4023e1b4..29543b503667 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -328,12 +328,16 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) esp_pm_register_light_sleep_default_params_config_callback(esp_wifi_internal_update_light_sleep_default_params); - uint32_t sleep_delay_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME * 1000; - esp_wifi_set_sleep_delay_time(sleep_delay_us); +#endif + + uint32_t min_active_time_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME * 1000; + esp_wifi_set_sleep_min_active_time(min_active_time_us); uint32_t keep_alive_time_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME * 1000 * 1000; esp_wifi_set_keep_alive_time(keep_alive_time_us); -#endif + + uint32_t wait_broadcast_data_time_us = CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME * 1000; + esp_wifi_set_sleep_wait_broadcast_data_time(wait_broadcast_data_time_us); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE #if SOC_PM_MODEM_RETENTION_BY_REGDMA diff --git a/components/esp_wifi/wifi_apps/nan_app/src/nan_app.c b/components/esp_wifi/wifi_apps/nan_app/src/nan_app.c index 64b2c5bbf0a3..783ce7fbfb88 100644 --- a/components/esp_wifi/wifi_apps/nan_app/src/nan_app.c +++ b/components/esp_wifi/wifi_apps/nan_app/src/nan_app.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,12 +28,13 @@ #define NDP_REJECTED BIT5 /* Macros */ -#define MACADDR_LEN 6 +#define MACADDR_LEN 6 #define MACADDR_EQUAL(a1, a2) (memcmp(a1, a2, MACADDR_LEN)) #define MACADDR_COPY(dst, src) (memcpy(dst, src, MACADDR_LEN)) -#define NAN_DW_INTVL_MS 524 /* NAN DW interval (512 TU's ~= 524 mSec) */ -#define NAN_NDP_RESP_TIMEOUT_DW 4 +#define NAN_DW_INTVL_MS 524 /* NAN DW interval (512 TU's ~= 524 mSec) */ +#define NAN_NDP_RESP_TIMEOUT_DW 8 #define NAN_NDP_RESP_TIMEOUT NAN_NDP_RESP_TIMEOUT_DW*NAN_DW_INTVL_MS +#define NAN_NDP_TERM_TIMEOUT 2*NAN_DW_INTVL_MS /* NDP Termination Timeout - 2 DW*/ /* Global Variables */ static const char *TAG = "nan_app"; @@ -800,7 +801,7 @@ esp_err_t esp_wifi_nan_stop(void) NAN_DATA_UNLOCK(); os_event_group_clear_bits(nan_event_group, NDP_TERMINATED); - os_event_group_wait_bits(nan_event_group, NDP_TERMINATED, pdFALSE, pdFALSE, portMAX_DELAY); + os_event_group_wait_bits(nan_event_group, NDP_TERMINATED, pdFALSE, pdFALSE, pdMS_TO_TICKS(NAN_NDP_TERM_TIMEOUT)); os_event_group_clear_bits(nan_event_group, NDP_TERMINATED); /* Wait for 1 NAN DW interval (512 TU's ~= 524 mSec) for successful termination */ g_wifi_osi_funcs._task_delay(NAN_DW_INTVL_MS/portTICK_PERIOD_MS); diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 271e0d04c043..5f33b2c89bc1 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -35,9 +35,11 @@ static void *scan_results_lock = NULL; #define ROAM_SCAN_RESULTS_LOCK() os_mutex_lock(scan_results_lock) #define ROAM_SCAN_RESULTS_UNLOCK() os_mutex_unlock(scan_results_lock) +#if PERIODIC_RRM_MONITORING static void *neighbor_list_lock = NULL; #define ROAM_NEIGHBOR_LIST_LOCK() os_mutex_lock(neighbor_list_lock) #define ROAM_NEIGHBOR_LIST_UNLOCK() os_mutex_unlock(neighbor_list_lock) +#endif /*PERIODIC_RRM_MONITORING*/ static int wifi_post_roam_event(struct cand_bss *bss); static void determine_best_ap(int8_t rssi_threshold); @@ -815,8 +817,15 @@ void deinit_roaming_app(void) #if PERIODIC_SCAN_MONITORING g_roaming_app.periodic_scan_active = false; #endif /*PERIODIC_SCAN_MONITORING*/ - os_mutex_delete(neighbor_list_lock); - neighbor_list_lock = NULL; - os_mutex_delete(scan_results_lock); - scan_results_lock = NULL; + +#if PERIODIC_RRM_MONITORING + if (neighbor_list_lock) { + os_mutex_delete(neighbor_list_lock); + neighbor_list_lock = NULL; + } +#endif /*PERIODIC_RRM_MONITORING*/ + if (scan_results_lock) { + os_mutex_delete(scan_results_lock); + scan_results_lock = NULL; + } } diff --git a/components/espcoredump/Kconfig b/components/espcoredump/Kconfig index 8de6fdd26cb2..d95090c74356 100644 --- a/components/espcoredump/Kconfig +++ b/components/espcoredump/Kconfig @@ -47,6 +47,18 @@ menu "Core dump" depends on ESP_COREDUMP_DATA_FORMAT_ELF endchoice + config ESP_COREDUMP_CAPTURE_DRAM + bool "Include whole .bss and .data sections and heap data into core dump file" + default n + #TODO: Heap walker api is not ready for the esp32c5 (IDF-9641) + depends on ESP_COREDUMP_DATA_FORMAT_ELF && !IDF_TARGET_ESP32C5 + help + Storing these sections can help with easier debugging and troubleshooting. + However, additional storage space will be required in the core dump partition. + At least 128KB should be reserved, but the actual amount required may vary based + on the application's DRAM usage. + Note that sections located in external RAM will not be stored. + config ESP_COREDUMP_CHECK_BOOT bool "Check core dump data integrity on boot" default y @@ -112,7 +124,8 @@ menu "Core dump" help Size of the memory to be reserved for core dump stack. If 0 core dump process will run on the stack of crashed task/ISR, otherwise special stack will be allocated. - To ensure that core dump itself will not overflow task/ISR stack set this to the value above 800. + To ensure that core dump itself will not overflow task/ISR stack set this to the value around 1300-1800 + depending on the chosen checksum calculation method. SHA256 method needs more stack space than CRC32. NOTE: It eats DRAM. config ESP_COREDUMP_SUMMARY_STACKDUMP_SIZE diff --git a/components/espcoredump/include_core_dump/esp_core_dump_common.h b/components/espcoredump/include_core_dump/esp_core_dump_common.h index f5a26749e73c..9e9efb2ef1c8 100644 --- a/components/espcoredump/include_core_dump/esp_core_dump_common.h +++ b/components/espcoredump/include_core_dump/esp_core_dump_common.h @@ -20,15 +20,25 @@ extern "C" { * One can use these definitions to retrieve the start address and/or the size * of a specific region using the functions below. */ + typedef enum { - COREDUMP_MEMORY_DRAM, COREDUMP_MEMORY_IRAM, +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM + COREDUMP_MEMORY_DRAM_BSS, + COREDUMP_MEMORY_DRAM_DATA, +#if CONFIG_IDF_TARGET_ESP32P4 + COREDUMP_MEMORY_DRAM_BSS_HIGH, + COREDUMP_MEMORY_DRAM_DATA_HIGH, +#endif +#else + COREDUMP_MEMORY_DRAM, +#endif #if SOC_RTC_MEM_SUPPORTED COREDUMP_MEMORY_RTC, COREDUMP_MEMORY_RTC_FAST, #endif COREDUMP_MEMORY_MAX, - COREDUMP_MEMORY_START = COREDUMP_MEMORY_DRAM + COREDUMP_MEMORY_START = COREDUMP_MEMORY_IRAM } coredump_region_t; /** @@ -126,6 +136,12 @@ esp_err_t esp_core_dump_write_data(core_dump_write_data_t *wr_data, void *data, */ esp_err_t esp_core_dump_write_end(core_dump_write_data_t *wr_data); +/** + * @brief Retrieve the stack information which will be used from the coredump module itself. + * It will show the whole stack boundaries in case the stack is shared with the crashed task. + */ +void esp_core_dump_get_own_stack_info(uint32_t *addr, uint32_t *size); + /** * @brief Stores the core dump in either binary or ELF format. */ @@ -157,7 +173,7 @@ static inline core_dump_task_handle_t esp_core_dump_get_current_task_handle(void * @brief Get the length, in bytes, of a given memory location. Padding is * taken into account in this calculation. * - * @param start Start address of the momery location. + * @param start Start address of the memory location. * @param end End address of the memory location. * * @return Size of the memory location, multiple of sizeof(uint32_t). diff --git a/components/espcoredump/src/core_dump_common.c b/components/espcoredump/src/core_dump_common.c index afca899b6054..d455bc9d3b35 100644 --- a/components/espcoredump/src/core_dump_common.c +++ b/components/espcoredump/src/core_dump_common.c @@ -25,6 +25,25 @@ const static char TAG[] __attribute__((unused)) = "esp_core_dump_common"; /** * @brief Memory regions to dump, defined at compile time. */ +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM +#if !CONFIG_IDF_TARGET_ESP32P4 +extern int _bss_start; +extern int _bss_end; +extern int _data_start; +extern int _data_end; +#else +extern int _bss_start_low; +extern int _bss_end_low; +extern int _data_start_low; +extern int _data_end_low; +extern int _bss_start_high; +extern int _bss_end_high; +extern int _data_start_high; +extern int _data_end_high; +#endif +#endif + +/* Regions for the user defined variable locations */ extern int _coredump_dram_start; extern int _coredump_dram_end; extern int _coredump_iram_start; @@ -160,6 +179,7 @@ FORCE_INLINE_ATTR void esp_core_dump_setup_stack(void) FORCE_INLINE_ATTR void esp_core_dump_report_stack_usage(void) { } + #endif // CONFIG_ESP_COREDUMP_STACK_SIZE > 0 static void* s_exc_frame = NULL; @@ -254,19 +274,29 @@ uint32_t esp_core_dump_get_user_ram_segments(void) return total_sz; } -uint32_t esp_core_dump_get_user_ram_size(void) -{ - uint32_t total_sz = 0; - - total_sz += COREDUMP_GET_MEMORY_SIZE(&_coredump_dram_end, &_coredump_dram_start); +static const struct { + int *start; + int *end; +} s_memory_sections[COREDUMP_MEMORY_MAX] = { + [COREDUMP_MEMORY_IRAM] = { &_coredump_iram_start, &_coredump_iram_end }, +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM +#if !CONFIG_IDF_TARGET_ESP32P4 + [COREDUMP_MEMORY_DRAM_BSS] = { &_bss_start, &_bss_end }, + [COREDUMP_MEMORY_DRAM_DATA] = { &_data_start, &_data_end }, +#else + [COREDUMP_MEMORY_DRAM_BSS] = { &_bss_start_low, &_bss_end_low }, + [COREDUMP_MEMORY_DRAM_DATA] = { &_data_start_low, &_data_end_low }, + [COREDUMP_MEMORY_DRAM_BSS_HIGH] = { &_bss_start_high, &_bss_end_high }, + [COREDUMP_MEMORY_DRAM_DATA_HIGH] = { &_data_start_high, &_data_end_high }, +#endif +#else + [COREDUMP_MEMORY_DRAM] = { &_coredump_dram_start, &_coredump_dram_end }, +#endif #if SOC_RTC_MEM_SUPPORTED - total_sz += COREDUMP_GET_MEMORY_SIZE(&_coredump_rtc_end, &_coredump_rtc_start); - total_sz += COREDUMP_GET_MEMORY_SIZE(&_coredump_rtc_fast_end, &_coredump_rtc_fast_start); + [COREDUMP_MEMORY_RTC] = { &_coredump_rtc_start, &_coredump_rtc_end }, + [COREDUMP_MEMORY_RTC_FAST] = { &_coredump_rtc_fast_start, &_coredump_rtc_fast_end }, #endif - total_sz += COREDUMP_GET_MEMORY_SIZE(&_coredump_iram_end, &_coredump_iram_start); - - return total_sz; -} +}; int esp_core_dump_get_user_ram_info(coredump_region_t region, uint32_t *start) { @@ -274,36 +304,34 @@ int esp_core_dump_get_user_ram_info(coredump_region_t region, uint32_t *start) ESP_COREDUMP_DEBUG_ASSERT(start != NULL); - switch (region) { - case COREDUMP_MEMORY_DRAM: - *start = (uint32_t)&_coredump_dram_start; - total_sz = (uint8_t *)&_coredump_dram_end - (uint8_t *)&_coredump_dram_start; - break; - - case COREDUMP_MEMORY_IRAM: - *start = (uint32_t)&_coredump_iram_start; - total_sz = (uint8_t *)&_coredump_iram_end - (uint8_t *)&_coredump_iram_start; - break; - -#if SOC_RTC_MEM_SUPPORTED - case COREDUMP_MEMORY_RTC: - *start = (uint32_t)&_coredump_rtc_start; - total_sz = (uint8_t *)&_coredump_rtc_end - (uint8_t *)&_coredump_rtc_start; - break; - - case COREDUMP_MEMORY_RTC_FAST: - *start = (uint32_t)&_coredump_rtc_fast_start; - total_sz = (uint8_t *)&_coredump_rtc_fast_end - (uint8_t *)&_coredump_rtc_fast_start; - break; -#endif - - default: - break; + if (region >= COREDUMP_MEMORY_START && region < COREDUMP_MEMORY_MAX) { + total_sz = (uint8_t *)s_memory_sections[region].end - (uint8_t *)s_memory_sections[region].start; + *start = (uint32_t)s_memory_sections[region].start; } return total_sz; } +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM +void esp_core_dump_get_own_stack_info(uint32_t *addr, uint32_t *size) +{ +#if CONFIG_ESP_COREDUMP_STACK_SIZE > 0 + /* Custom stack reserved for the coredump */ + *addr = (uint32_t)s_coredump_stack; + *size = sizeof(s_coredump_stack); +#else + /* Shared stack with the crashed task */ + core_dump_task_handle_t handle = esp_core_dump_get_current_task_handle(); + TaskSnapshot_t rtos_snapshot = { 0 }; + vTaskGetSnapshot(handle, &rtos_snapshot); + StaticTask_t *current = (StaticTask_t *)handle; + *addr = (uint32_t)current->pxDummy6; //pxStack + *size = (uint32_t)rtos_snapshot.pxTopOfStack - (uint32_t)current->pxDummy6; /* free */ +#endif +} + +#endif /* CONFIG_ESP_COREDUMP_CAPTURE_DRAM */ + inline bool esp_core_dump_tcb_addr_is_sane(uint32_t addr) { return esp_core_dump_mem_seg_is_sane(addr, esp_core_dump_get_tcb_len()); diff --git a/components/espcoredump/src/core_dump_elf.c b/components/espcoredump/src/core_dump_elf.c index f83b49f16e3e..2e3da6ee0289 100644 --- a/components/espcoredump/src/core_dump_elf.c +++ b/components/espcoredump/src/core_dump_elf.c @@ -80,6 +80,11 @@ typedef struct _core_dump_elf_t { uint16_t segs_count; core_dump_write_data_t write_data; uint32_t note_data_size; /* can be used where static storage needed */ +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM + /* To avoid checksum failure, coredump stack region will be excluded while storing the sections. */ + uint32_t coredump_stack_start; + uint32_t coredump_stack_size; +#endif } core_dump_elf_t; typedef struct { @@ -202,8 +207,8 @@ static int elf_write_note_header(core_dump_elf_t *self, static char name_buffer[ELF_NOTE_NAME_MAX_SIZE] = { 0 }; elf_note note_hdr = { 0 }; - memcpy((void*)name_buffer, (void*)name, name_len); - note_hdr.n_namesz = name_len; + memcpy(name_buffer, name, name_len); + note_hdr.n_namesz = ALIGN_UP(name_len, 4); note_hdr.n_descsz = data_sz; note_hdr.n_type = type; // write note header @@ -211,7 +216,7 @@ static int elf_write_note_header(core_dump_elf_t *self, ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note header failure (%d)", err); // write note name - err = esp_core_dump_write_data(&self->write_data, name_buffer, name_len); + err = esp_core_dump_write_data(&self->write_data, name_buffer, note_hdr.n_namesz); ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note name failure (%d)", err); @@ -474,10 +479,17 @@ static int elf_write_tasks_data(core_dump_elf_t *self) bad_tasks_num++; continue; } - ret = elf_save_task(self, &task_hdr); - ELF_CHECK_ERR((ret > 0), ret, - "Task %x, TCB write failed, return (%d).", task_iter.pxTaskHandle, ret); - elf_len += ret; + +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM + /* Only crashed task data will be saved here. The other task's data will be automatically saved within the sections */ + if (esp_core_dump_get_current_task_handle() == task_iter.pxTaskHandle) +#endif + { + ret = elf_save_task(self, &task_hdr); + ELF_CHECK_ERR((ret > 0), ret, + "Task %x, TCB write failed, return (%d).", task_iter.pxTaskHandle, ret); + elf_len += ret; + } if (interrupted_stack.size > 0) { ESP_COREDUMP_LOG_PROCESS("Add interrupted task stack %lu bytes @ %x", interrupted_stack.size, interrupted_stack.start); @@ -493,28 +505,148 @@ static int elf_write_tasks_data(core_dump_elf_t *self) return elf_len; } +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM + +/* Coredump stack will also be used by the checksum functions while saving sections. + * There is a potential for inconsistency when writing coredump stack to the flash and calculating checksum simultaneously. + * This is because, coredump stack will be modified during the process, leading to incorrect checksum calculations. + * To mitigate this issue, it's important to ensure that the coredump stack excluded from checksum calculation by + * filter out from the written regions. + * Typically, the coredump stack can be located in two different sections. + * 1. In the bss section; + * 1.a if `CONFIG_ESP_COREDUMP_STACK_SIZE` set to a nonzero value + * 1.b if the crashed task is created with a static task buffer using the xTaskCreateStatic() api + * 2. In the heap section, if custom stack is not defined and the crashed task buffer is allocated in the heap + * with the xTaskCreate() api + * + * esp_core_dump_store_section() will check if the coredump stack is located inside the section. + * If it is, this part will be skipped. + * |+++++++++| xxxxxxxxxxxxxx |++++++++| + * |+++++++++| coredump stack |++++++++| +*/ +static int esp_core_dump_store_section(core_dump_elf_t *self, uint32_t start, uint32_t data_len) +{ + uint32_t end = start + data_len; + int total_sz = 0; + int ret; + + if (self->coredump_stack_start > start && self->coredump_stack_start < end) { + /* write until the coredump stack. */ + data_len = self->coredump_stack_start - start; + ret = elf_add_segment(self, PT_LOAD, + start, + (void*)start, + data_len); + + if (ret <= 0) { + return ret; + } + total_sz += ret; + + /* Skip coredump stack and set offset for the rest of the section */ + start = self->coredump_stack_start + self->coredump_stack_size; + data_len = end - start; + } + + if (data_len > 0) { + ret = elf_add_segment(self, PT_LOAD, + (uint32_t)start, + (void*)start, + (uint32_t)data_len); + if (ret <= 0) { + return ret; + } + total_sz += ret; + } + + return total_sz; +} + +typedef struct { + core_dump_elf_t *self; + int *total_sz; + int ret; +} heap_block_data_t; + +bool esp_core_dump_write_heap_blocks(walker_heap_into_t heap_info, walker_block_info_t block_info, void* user_data) +{ + heap_block_data_t *param = user_data; + int *total_sz = param->total_sz; + core_dump_elf_t *self = param->self; + int *ret = ¶m->ret; + + if (*ret <= 0) { + /* There was a flash write failure at the previous write attempt */ + return false; + } + + if ((intptr_t)heap_info.end - (intptr_t)block_info.ptr < block_info.size) { + ESP_COREDUMP_LOGE("Block corruption detected in the heap (%p-%p)", heap_info.start, heap_info.end); + ESP_COREDUMP_LOGE("Corrupted block addr:%p size:%x)", block_info.ptr, block_info.size); + /* Heap walker will skip the next block in the same heap region and it will continue from the next heap region's block. */ + return false; + } + + if (block_info.used && block_info.size > 0) { + ESP_COREDUMP_LOG_PROCESS("heap block @%p sz:(%x)", (void *)block_info.ptr, block_info.size); + + if (!esp_core_dump_mem_seg_is_sane((uint32_t)block_info.ptr, block_info.size)) { + return false; + } + + if (self->coredump_stack_start == (uint32_t)block_info.ptr) { + /* skip writing coredump stack block */ + return true; + } + + *ret = elf_add_segment(self, PT_LOAD, + (uint32_t)block_info.ptr, + (void*)block_info.ptr, + block_info.size); + if (*ret <= 0) { + return false; + } + *total_sz += *ret; + } + + return true; +} + +#else + +static int esp_core_dump_store_section(core_dump_elf_t *self, uint32_t start, uint32_t data_len) +{ + return elf_add_segment(self, PT_LOAD, + start, + (void*)start, + data_len); +} + +#endif + static int elf_write_core_dump_user_data(core_dump_elf_t *self) { - int data_len = 0; int total_sz = 0; uint32_t start = 0; for (coredump_region_t i = COREDUMP_MEMORY_START; i < COREDUMP_MEMORY_MAX; i++) { - data_len = esp_core_dump_get_user_ram_info(i, &start); + int data_len = esp_core_dump_get_user_ram_info(i, &start); ELF_CHECK_ERR((data_len >= 0), ELF_PROC_ERR_OTHER, "invalid memory region"); if (data_len > 0) { - int ret = elf_add_segment(self, PT_LOAD, - (uint32_t)start, - (void*)start, - (uint32_t) data_len); - + int ret = esp_core_dump_store_section(self, start, data_len); ELF_CHECK_ERR((ret > 0), ret, "memory region write failed. Returned (%d).", ret); total_sz += ret; } } +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM + heap_block_data_t user_data = {.self = self, .total_sz = &total_sz, .ret = 1}; + heap_caps_walk(MALLOC_CAP_8BIT, esp_core_dump_write_heap_blocks, &user_data); + ELF_CHECK_ERR((user_data.ret > 0), user_data.ret, "Heap memory write failed. Returned (%d).", user_data.ret); +#endif + return total_sz; } @@ -539,7 +671,7 @@ static void elf_write_core_dump_note_cb(void *opaque, const char *data) static int elf_add_wdt_panic_details(core_dump_elf_t *self) { - uint32_t name_len = ALIGN_UP(sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME), 4); + uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME); core_dump_elf_opaque_t param = { .self = self, .total_size = 0, @@ -573,7 +705,7 @@ static int elf_add_wdt_panic_details(core_dump_elf_t *self) } } - return ALIGN_UP(name_len + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note), 4); + return ALIGN_UP(ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note), 4); } #endif //CONFIG_ESP_TASK_WDT_EN @@ -676,6 +808,12 @@ static esp_err_t esp_core_dump_write_elf(void) int tot_len = sizeof(dump_hdr); int write_len = sizeof(dump_hdr); +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM + esp_core_dump_get_own_stack_info(&self.coredump_stack_start, &self.coredump_stack_size); + ESP_COREDUMP_LOG_PROCESS("Core dump stack start=%p size = %d", + (void *)self.coredump_stack_start, self.coredump_stack_size); +#endif + esp_err_t err = esp_core_dump_write_init(); if (err != ESP_OK) { ESP_COREDUMP_LOGE("Elf write init failed!"); @@ -762,25 +900,22 @@ typedef struct { void *n_ptr; } elf_note_content_t; +esp_err_t esp_core_dump_partition_and_size_get(const esp_partition_t **partition, uint32_t* size); + /* Below are the helper function to parse the core dump ELF stored in flash */ static esp_err_t elf_core_dump_image_mmap(esp_partition_mmap_handle_t* core_data_handle, const void **map_addr) { - size_t out_size; + const esp_partition_t *core_part = NULL; + uint32_t out_size; assert(core_data_handle); assert(map_addr); - /* Find the partition that could potentially contain a (previous) core dump. */ - const esp_partition_t *core_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, - ESP_PARTITION_SUBTYPE_DATA_COREDUMP, - NULL); - if (!core_part) { - ESP_COREDUMP_LOGE("Core dump partition not found!"); - return ESP_ERR_NOT_FOUND; - } - if (core_part->size < sizeof(uint32_t)) { - ESP_COREDUMP_LOGE("Core dump partition too small!"); - return ESP_ERR_INVALID_SIZE; + /* Retrieve the partition and size. */ + esp_err_t err = esp_core_dump_partition_and_size_get(&core_part, &out_size); + if (err != ESP_OK) { + return err; } + /* Data read from the mmapped core dump partition will be garbage if flash * encryption is enabled in hardware and core dump partition is not encrypted */ @@ -788,13 +923,8 @@ static esp_err_t elf_core_dump_image_mmap(esp_partition_mmap_handle_t* core_data ESP_COREDUMP_LOGE("Flash encryption enabled in hardware and core dump partition is not encrypted!"); return ESP_ERR_NOT_SUPPORTED; } - /* Read the size of the core dump file from the partition */ - esp_err_t ret = esp_partition_read(core_part, 0, &out_size, sizeof(uint32_t)); - if (ret != ESP_OK) { - ESP_COREDUMP_LOGE("Failed to read core dump data size"); - return ret; - } - /* map the full core dump parition, including the checksum. */ + + /* map the full core dump partition, including the checksum. */ return esp_partition_mmap(core_part, 0, out_size, ESP_PARTITION_MMAP_DATA, map_addr, core_data_handle); } diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index 7cd6382fd986..2cd6bfb55bb0 100644 --- a/components/espcoredump/src/core_dump_flash.c +++ b/components/espcoredump/src/core_dump_flash.c @@ -12,6 +12,7 @@ #include "esp_flash_encrypt.h" #include "esp_rom_crc.h" #include "esp_private/spi_flash_os.h" +#include "spi_flash_mmap.h" #define BLANK_COREDUMP_SIZE 0xFFFFFFFF @@ -55,7 +56,7 @@ esp_err_t esp_core_dump_write_data(core_dump_write_data_t *wr_data, void *data, #define ESP_COREDUMP_FLASH_ERASE(_off_, _len_) esp_flash_erase_region(esp_flash_default_chip, _off_, _len_) esp_err_t esp_core_dump_image_check(void); -static esp_err_t esp_core_dump_partition_and_size_get(const esp_partition_t **partition, uint32_t* size); +esp_err_t esp_core_dump_partition_and_size_get(const esp_partition_t **partition, uint32_t* size); static void esp_core_dump_flash_print_write_start(void) { @@ -258,7 +259,7 @@ static esp_err_t esp_core_dump_flash_write_prepare(core_dump_write_data_t *wr_da padding = COREDUMP_CACHE_SIZE - modulo; } - /* Now we can check whether we have enough space in our core dump parition + /* Now we can check whether we have enough space in our core dump partition * or not. */ if ((*data_len + padding + cs_len) > s_core_flash_config.partition.size) { ESP_COREDUMP_LOGE("Not enough space to save core dump!"); @@ -488,7 +489,7 @@ esp_err_t esp_core_dump_image_erase(void) return err; } -static esp_err_t esp_core_dump_partition_and_size_get(const esp_partition_t **partition, uint32_t* size) +esp_err_t esp_core_dump_partition_and_size_get(const esp_partition_t **partition, uint32_t* size) { uint32_t core_size = 0; const esp_partition_t *core_part = NULL; diff --git a/components/espcoredump/src/core_dump_uart.c b/components/espcoredump/src/core_dump_uart.c index b859c4ea0d60..69ab1c280540 100644 --- a/components/espcoredump/src/core_dump_uart.c +++ b/components/espcoredump/src/core_dump_uart.c @@ -6,6 +6,7 @@ #include #include "soc/uart_reg.h" #include "soc/gpio_periph.h" +#include "soc/uart_pins.h" #include "driver/gpio.h" #include "hal/gpio_hal.h" #include "esp_core_dump_types.h" @@ -147,17 +148,15 @@ static esp_err_t esp_core_dump_uart_hw_init(void) uint32_t tm_cur = 0; int ch = 0; - // TODO: move chip dependent code to portable part + gpio_hal_context_t gpio_hal = { + .dev = GPIO_HAL_GET_HW(GPIO_PORT_0) + }; + //Make sure txd/rxd are enabled // use direct reg access instead of gpio_pullup_dis which can cause exception when flash cache is disabled - REG_CLR_BIT(GPIO_PIN_REG_1, FUN_PU); -#if CONFIG_IDF_TARGET_ESP32P4 - gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U_PAD_GPIO38, FUNC_GPIO38_UART0_RXD_PAD); - gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U_PAD_GPIO37, FUNC_GPIO37_UART0_TXD_PAD); -#else - gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD); - gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD); -#endif + REG_CLR_BIT(GPIO_PIN_REG_1, FUN_PU); //TODO: IDF-9948 + gpio_hal_func_sel(&gpio_hal, U0RXD_GPIO_NUM, U0RXD_MUX_FUNC); + gpio_hal_func_sel(&gpio_hal, U0TXD_GPIO_NUM, U0TXD_MUX_FUNC); ESP_COREDUMP_LOGI("Press Enter to print core dump to UART..."); const int cpu_ticks_per_ms = esp_clk_cpu_freq() / 1000; tm_end = esp_cpu_get_cycle_count() / cpu_ticks_per_ms + CONFIG_ESP_COREDUMP_UART_DELAY; diff --git a/components/fatfs/vfs/vfs_fat_sdmmc.c b/components/fatfs/vfs/vfs_fat_sdmmc.c index 7c65324dfff8..075a5ca16315 100644 --- a/components/fatfs/vfs/vfs_fat_sdmmc.c +++ b/components/fatfs/vfs/vfs_fat_sdmmc.c @@ -140,7 +140,7 @@ static esp_err_t s_f_mount(sdmmc_card_t *card, FATFS *fs, const char *drv, uint8 } ESP_LOGW(TAG, "mounting again"); - res = f_mount(fs, drv, 0); + res = f_mount(fs, drv, 1); if (res != FR_OK) { err = ESP_FAIL; ESP_LOGD(TAG, "f_mount failed after formatting (%d)", res); diff --git a/components/fatfs/vfs/vfs_fat_spiflash.c b/components/fatfs/vfs/vfs_fat_spiflash.c index 2057f194cf88..7b5fb2491cce 100644 --- a/components/fatfs/vfs/vfs_fat_spiflash.c +++ b/components/fatfs/vfs/vfs_fat_spiflash.c @@ -104,7 +104,7 @@ static esp_err_t s_f_mount_rw(FATFS *fs, const char *drv, const esp_vfs_fat_moun } ESP_LOGI(TAG, "Mounting again"); - fresult = f_mount(fs, drv, 0); + fresult = f_mount(fs, drv, 1); ESP_RETURN_ON_FALSE(fresult == FR_OK, ESP_FAIL, TAG, "f_mount failed after formatting (%d)", fresult); } else { if (out_flags) { diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/linux/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel-SMP/portable/linux/include/freertos/portmacro.h index f4ee05e14e9e..02cbdedada7a 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/linux/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/linux/include/freertos/portmacro.h @@ -244,6 +244,12 @@ static inline BaseType_t xPortInIsrContext(void) return xPortCheckIfInISR(); } +static inline void vPortAssertIfInISR(void) +{ + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortInIsrContext() == 0); +} + // xPortInterruptedFromISRContext() is only used in panic handler and core dump, // both probably not relevant on POSIX sim. //BaseType_t xPortInterruptedFromISRContext(void); @@ -301,7 +307,7 @@ extern void vPortCancelThread( void *pxTaskToDelete ); * are always a full memory barrier. ISRs are emulated as signals * which also imply a full memory barrier. * - * Thus, only a compilier barrier is needed to prevent the compiler + * Thus, only a compiler barrier is needed to prevent the compiler * reordering. */ #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h index 7ffcb5e6d4e7..ba635dcfeefd 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h @@ -113,6 +113,13 @@ typedef spinlock_t portMUX_TYPE; /**< Spi BaseType_t xPortCheckIfInISR(void); +/** + * @brief Assert if in ISR context + * + * - Asserts on xPortCheckIfInISR() internally + */ +void vPortAssertIfInISR(void); + // ------------------ Critical Sections -------------------- #if ( configNUMBER_OF_CORES > 1 ) @@ -187,6 +194,15 @@ void vPortTCBPreDeleteHook( void *pxTCB ); #define portENABLE_INTERRUPTS() vPortClearInterruptMask(1) #define portRESTORE_INTERRUPTS(x) vPortClearInterruptMask(x) +/** + * @brief Assert if in ISR context + * + * TODO: Enable once ISR safe version of vTaskEnter/ExitCritical() is implemented + * for single-core SMP FreeRTOS Kernel. (IDF-10540) + */ +// #define portASSERT_IF_IN_ISR() vPortAssertIfInISR() + + // ------------------ Critical Sections -------------------- #if ( configNUMBER_OF_CORES > 1 ) diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index ea2e46c41d5f..955587ba427f 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -168,6 +168,12 @@ BaseType_t xPortCheckIfInISR(void) return uxInterruptNesting; } +void vPortAssertIfInISR(void) +{ + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortCheckIfInISR() == 0); +} + // ------------------ Critical Sections -------------------- #if ( configNUMBER_OF_CORES > 1 ) @@ -373,7 +379,7 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u #if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER static void vPortTaskWrapper(TaskFunction_t pxCode, void *pvParameters) { - __asm__ volatile(".cfi_undefined ra"); // tell to debugger that it's outermost (inital) frame + __asm__ volatile(".cfi_undefined ra"); // tell to debugger that it's outermost (initial) frame extern void __attribute__((noreturn)) panic_abort(const char *details); static char DRAM_ATTR msg[80] = "FreeRTOS: FreeRTOS Task \"\0"; pxCode(pvParameters); @@ -440,7 +446,7 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC HIGH ADDRESS |---------------------------| <- pxTopOfStack on entry | TLS Variables | - | ------------------------- | <- Start of useable stack + | ------------------------- | <- Start of usable stack | Starting stack frame | | ------------------------- | <- pxTopOfStack on return (which is the tasks current SP) | | | diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h index 2e87cd39f9cd..422ad609774c 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h @@ -95,6 +95,13 @@ typedef spinlock_t portMUX_TYPE; /**< Spi BaseType_t xPortCheckIfInISR(void); +/** + * @brief Assert if in ISR context + * + * - Asserts on xPortCheckIfInISR() internally + */ +void vPortAssertIfInISR(void); + // ------------------ Critical Sections -------------------- UBaseType_t uxPortEnterCriticalFromISR( void ); @@ -161,6 +168,14 @@ void vPortTCBPreDeleteHook( void *pxTCB ); #define portSET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK() #define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK() +/** + * @brief Assert if in ISR context + * + * TODO: Enable once ISR safe version of vTaskEnter/ExitCritical() is implemented + * for single-core SMP FreeRTOS Kernel. (IDF-10540) + */ +// #define portASSERT_IF_IN_ISR() vPortAssertIfInISR() + /* Note: XTOS_RESTORE_INTLEVEL() will overwrite entire PS register on XEA2. So we need to set the value of the INTLEVEL field ourselves */ diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index d5010bf708d4..4cd6918472f1 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -139,7 +139,7 @@ BaseType_t xPortEnterCriticalTimeout(portMUX_TYPE *lock, BaseType_t timeout) void vPortExitCriticalIDF(portMUX_TYPE *lock) { /* This function may be called in a nested manner. Therefore, we only need - * to reenable interrupts if this is the last call to exit the critical. We + * to re-enable interrupts if this is the last call to exit the critical. We * can use the nesting count to determine whether this is the last exit call. */ spinlock_release(lock); @@ -204,6 +204,12 @@ BaseType_t xPortCheckIfInISR(void) return ret; } +void vPortAssertIfInISR(void) +{ + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortCheckIfInISR() == 0); +} + // ------------------ Critical Sections -------------------- #if ( configNUMBER_OF_CORES > 1 ) @@ -614,7 +620,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, | Coproc Save Area | (CPSA MUST BE FIRST) | ------------------------- | | TLS Variables | - | ------------------------- | <- Start of useable stack + | ------------------------- | <- Start of usable stack | Starting stack frame | | ------------------------- | <- pxTopOfStack on return (which is the tasks current SP) | | | diff --git a/components/freertos/FreeRTOS-Kernel/portable/linux/include/freertos/portmacro_idf.h b/components/freertos/FreeRTOS-Kernel/portable/linux/include/freertos/portmacro_idf.h index a4b75c066a59..bff384a77db5 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/linux/include/freertos/portmacro_idf.h +++ b/components/freertos/FreeRTOS-Kernel/portable/linux/include/freertos/portmacro_idf.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -104,6 +104,17 @@ static inline BaseType_t xPortInIsrContext(void) return xPortCheckIfInISR(); } +static inline void vPortAssertIfInISR(void) +{ + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortInIsrContext() == 0); +} + +/** + * @brief Assert if in ISR context + */ +#define portASSERT_IF_IN_ISR() vPortAssertIfInISR() + #if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP /* If enabled, users must provide an implementation of vPortCleanUpTCB() */ extern void vPortCleanUpTCB ( void *pxTCB ); diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h index 5df719405c48..f1b0257d544a 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h @@ -166,6 +166,13 @@ void vPortClearInterruptMaskFromISR(UBaseType_t prev_int_level); */ BaseType_t xPortInIsrContext(void); +/** + * @brief Assert if in ISR context + * + * - Asserts on xPortInIsrContext() internally + */ +void vPortAssertIfInISR(void); + /** * @brief Check if in ISR context from High priority ISRs * @@ -478,6 +485,11 @@ void vPortTCBPreDeleteHook( void *pxTCB ); #define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMaskFromISR() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(prev_level) vPortClearInterruptMaskFromISR(prev_level) +/** + * @brief Assert if in ISR context + */ +#define portASSERT_IF_IN_ISR() vPortAssertIfInISR() + /** * @brief Used by FreeRTOS functions to call the correct version of critical section API */ diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index 18aa79db670a..29cc3fe09636 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -60,6 +60,11 @@ #include "soc/hp_system_reg.h" #endif +#if SOC_CPU_HAS_HWLOOP +#include "riscv/csr.h" +#include "riscv/csr_hwlp.h" +#endif + #if ( SOC_CPU_COPROC_NUM > 0 ) #include "esp_private/panic_internal.h" @@ -125,9 +130,23 @@ StackType_t *xIsrStackBottom[portNUM_PROCESSORS] = {0}; BaseType_t xPortStartScheduler(void) { #if ( SOC_CPU_COPROC_NUM > 0 ) + +#if SOC_CPU_HAS_FPU /* Disable FPU so that the first task to use it will trigger an exception */ rv_utils_disable_fpu(); -#endif +#endif /* SOC_CPU_HAS_FPU */ + +#if SOC_CPU_HAS_PIE + /* Similarly, disable PIE */ + rv_utils_disable_pie(); +#endif /* SOC_CPU_HAS_FPU */ + +#if SOC_CPU_HAS_HWLOOP + /* Initialize the Hardware loop feature */ + RV_WRITE_CSR(CSR_HWLP_STATE_REG, HWLP_INITIAL_STATE); +#endif /* SOC_CPU_HAS_HWLOOP */ +#endif /* ( SOC_CPU_COPROC_NUM > 0 ) */ + /* Initialize all kernel state tracking variables */ BaseType_t coreID = xPortGetCoreID(); port_uxInterruptNesting[coreID] = 0; @@ -230,7 +249,7 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u #if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER static void vPortTaskWrapper(TaskFunction_t pxCode, void *pvParameters) { - __asm__ volatile(".cfi_undefined ra"); // tell to debugger that it's outermost (inital) frame + __asm__ volatile(".cfi_undefined ra"); // tell to debugger that it's outermost (initial) frame extern void __attribute__((noreturn)) panic_abort(const char *details); static char DRAM_ATTR msg[80] = "FreeRTOS: FreeRTOS Task \"\0"; pxCode(pvParameters); @@ -356,7 +375,7 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC HIGH ADDRESS |---------------------------| <- pxTopOfStack on entry | TLS Variables | - | ------------------------- | <- Start of useable stack + | ------------------------- | <- Start of usable stack | Starting stack frame | | ------------------------- | <- pxTopOfStack on return (which is the tasks current SP) | | | @@ -374,7 +393,7 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC | Coproc. Save Area | <- RvCoprocSaveArea | ------------------------- | | TLS Variables | - | ------------------------- | <- Start of useable stack + | ------------------------- | <- Start of usable stack | Starting stack frame | | ------------------------- | <- pxTopOfStack on return (which is the tasks current SP) | | | @@ -430,7 +449,7 @@ BaseType_t xPortInIsrContext(void) /* Disable interrupts to fetch the coreID atomically */ irqStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - /* Return the interrupt nexting counter for this core */ + /* Return the interrupt nesting counter for this core */ ret = port_uxInterruptNesting[xPortGetCoreID()]; /* Restore interrupts */ @@ -443,9 +462,15 @@ BaseType_t xPortInIsrContext(void) #endif /* (configNUM_CORES > 1) */ } +void vPortAssertIfInISR(void) +{ + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortInIsrContext() == 0); +} + BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void) { - /* Return the interrupt nexting counter for this core */ + /* Return the interrupt nesting counter for this core */ return port_uxInterruptNesting[xPortGetCoreID()]; } @@ -536,7 +561,7 @@ BaseType_t __attribute__((optimize("-O3"))) xPortEnterCriticalTimeout(portMUX_TY void __attribute__((optimize("-O3"))) vPortExitCriticalMultiCore(portMUX_TYPE *mux) { /* This function may be called in a nested manner. Therefore, we only need - * to reenable interrupts if this is the last call to exit the critical. We + * to re-enable interrupts if this is the last call to exit the critical. We * can use the nesting count to determine whether this is the last exit call. */ spinlock_release(mux); @@ -787,9 +812,14 @@ RvCoprocSaveArea* pxPortGetCoprocArea(StaticTask_t* task, bool allocate, int cop /* Check if coprocessor area is allocated */ if (allocate && sa->sa_coprocs[coproc] == NULL) { const uint32_t coproc_sa_sizes[] = { - RV_COPROC0_SIZE, RV_COPROC1_SIZE + RV_COPROC0_SIZE, RV_COPROC1_SIZE, RV_COPROC2_SIZE + }; + const uint32_t coproc_sa_align[] = { + RV_COPROC0_ALIGN, RV_COPROC1_ALIGN, RV_COPROC2_ALIGN }; - /* The allocator points to a usable part of the stack, use it for the coprocessor */ + /* The allocator points to a usable part of the stack, use it for the coprocessor. + * Align it up to the coprocessor save area requirement */ + sa->sa_allocator = (sa->sa_allocator + coproc_sa_align[coproc] - 1) & ~(coproc_sa_align[coproc] - 1); sa->sa_coprocs[coproc] = (void*) (sa->sa_allocator); sa->sa_allocator += coproc_sa_sizes[coproc]; /* Update the lowest address of the stack to prevent FreeRTOS performing overflow/watermark checks on the coprocessors contexts */ @@ -800,9 +830,9 @@ RvCoprocSaveArea* pxPortGetCoprocArea(StaticTask_t* task, bool allocate, int cop if (task_sp <= task->pxDummy6) { /* In theory we need to call vApplicationStackOverflowHook to trigger the stack overflow callback, * but in practice, since we are already in an exception handler, this won't work, so let's manually - * trigger an exception with the previous FPU owner's TCB */ + * trigger an exception with the previous coprocessor owner's TCB */ g_panic_abort = true; - g_panic_abort_details = (char *) "ERROR: Stack overflow while saving FPU context!\n"; + g_panic_abort_details = (char *) "ERROR: Stack overflow while saving coprocessor context!\n"; xt_unhandled_exception(task_sp); } } @@ -821,7 +851,8 @@ RvCoprocSaveArea* pxPortGetCoprocArea(StaticTask_t* task, bool allocate, int cop * @param coreid Current core * @param coproc Coprocessor to save context of * - * @returns Coprocessor former owner's save area + * @returns Coprocessor former owner's save area, can be NULL if there was no owner yet, can be -1 if + * the former owner is the same as the new owner. */ RvCoprocSaveArea* pxPortUpdateCoprocOwner(int coreid, int coproc, StaticTask_t* owner) { @@ -830,8 +861,11 @@ RvCoprocSaveArea* pxPortUpdateCoprocOwner(int coreid, int coproc, StaticTask_t* StaticTask_t** owner_addr = &port_uxCoprocOwner[ coreid ][ coproc ]; /* Atomically exchange former owner with the new one */ StaticTask_t* former = Atomic_SwapPointers_p32((void**) owner_addr, owner); - /* Get the save area of former owner */ - if (former != NULL) { + /* Get the save area of former owner. small optimization here, if the former owner is the new owner, + * return -1. This will simplify the assembly code while making it faster. */ + if (former == owner) { + sa = (void*) -1; + } else if (former != NULL) { /* Allocate coprocessor memory if not available yet */ sa = pxPortGetCoprocArea(former, true, coproc); } diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S b/components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S index 6a99e7ebb9d5..b737e58d7c2a 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S @@ -8,6 +8,8 @@ #include "freertos/FreeRTOSConfig.h" #include "soc/soc_caps.h" #include "riscv/rvruntime-frames.h" +#include "riscv/csr_hwlp.h" +#include "riscv/csr_pie.h" .extern pxCurrentTCBs @@ -33,6 +35,283 @@ #if SOC_CPU_COPROC_NUM > 0 +/** + * @brief Macro to generate a routine that saves a coprocessor's registers in the previous owner's TCB dedicated save area. + * This routine aborts if the coprocessor is used from an ISR, since this is not allowed in ESP-IDF. + * However it is allowed to use these coprocessors in the init process, so no error will be triggered if the + * current TCB is NULL. + * + * @param name The name of the coprocessor, this will be used to generate the label, so it must not contain special characters + * @param coproc_idx Index of the coprocessor in the coprocessor save area, this value can be found in rvruntime definition + * @param enable_coproc Macro that takes a scratch register as a parameter and enables the coprocessor. + * @param save_coproc_regs Macro that takes a frame as a parameter and saves all the coprocessors' registers in that frame. + * @param restore_coproc_regs Macro that takes a frame as a parameter and restores all the coprocessors' registers from that. + * + * Note: macros given as parameters can freely use temporary registers + */ +.macro generate_coprocessor_routine name, coproc_idx, enable_coproc, save_coproc_regs, restore_coproc_regs + + .global rtos_save_\name\()_coproc + .type rtos_save_\name\()_coproc, @function +rtos_save_\name\()_coproc: + /* If we are in an interrupt context, we have to abort. We don't allow using the coprocessors from ISR */ +#if ( configNUM_CORES > 1 ) + csrr a2, mhartid /* a2 = coreID */ + slli a2, a2, 2 /* a2 = coreID * 4 */ + la a1, port_uxInterruptNesting /* a1 = &port_uxInterruptNesting */ + add a1, a1, a2 /* a1 = &port_uxInterruptNesting[coreID] */ + lw a1, 0(a1) /* a1 = port_uxInterruptNesting[coreID] */ +#else /* ( configNUM_CORES <= 1 ) */ + lw a1, (port_uxInterruptNesting) /* a1 = port_uxInterruptNesting */ +#endif /* ( configNUM_CORES > 1 ) */ + /* SP still contains the RvExcFrame address */ + mv a0, sp + bnez a1, vPortCoprocUsedInISR + /* Enable the coprocessor needed by the current task */ + \enable_coproc a1 + mv s0, ra + call rtos_current_tcb + /* If the current TCB is NULL, the coprocessor is used during initialization, even before + * the scheduler started. Consider this a valid usage, it will be disabled as soon as the + * scheduler is started anyway */ + beqz a0, rtos_save_\name\()_coproc_norestore + mv s1, a0 /* s1 = pxCurrentTCBs */ + /* Prepare parameters of pxPortUpdateCoprocOwner */ + mv a2, a0 + li a1, \coproc_idx + csrr a0, mhartid + call pxPortUpdateCoprocOwner + /* If the save area is NULL, no need to save context */ + beqz a0, rtos_save_\name\()_coproc_nosave + /* If the former owner is the current task (new owner), the return value is -1, we can skip restoring the + * coprocessor context and return directly */ + li a1, -1 + beq a0, a1, rtos_save_\name\()_coproc_norestore + /* Save the coprocessor context in the structure */ + lw a0, RV_COPROC_SA+\coproc_idx*4(a0) /* a0 = RvCoprocSaveArea->sa_coprocs[coproc_idx] */ + \save_coproc_regs a0 +rtos_save_\name\()_coproc_nosave: +#if ( configNUM_CORES > 1 ) + /* Pin current task to current core, s1 has pxCurrentTCBs */ + mv a0, s1 + csrr a1, mhartid + call vPortTaskPinToCore +#endif /* configNUM_CORES > 1 */ + /* Check if we have to restore a previous context from the current TCB */ + mv a0, s1 + /* Do not allocate memory for the coprocessor yet, delay this until another task wants to use it. + * This guarantees that if a stack overflow occurs when allocating the coprocessor context on the stack, + * the current task context is flushed and updated in the TCB, generating a correct backtrace + * from the panic handler. */ + li a1, 0 + li a2, \coproc_idx + call pxPortGetCoprocArea + /* Get the enable flags from the coprocessor save area */ + lw a1, RV_COPROC_ENABLE(a0) + /* To avoid having branches below, set the coprocessor enable flag now */ + ori a2, a1, 1 << \coproc_idx + sw a2, RV_COPROC_ENABLE(a0) + /* Check if the former coprocessor enable bit was set */ + andi a2, a1, 1 << \coproc_idx + beqz a2, rtos_save_\name\()_coproc_norestore + /* Enable bit was set, restore the coprocessor context */ + lw a0, RV_COPROC_SA+\coproc_idx*4(a0) /* a0 = RvCoprocSaveArea->sa_coprocs[\coproc_idx] */ + \restore_coproc_regs a0 +rtos_save_\name\()_coproc_norestore: + /* Return from routine via s0, instead of ra */ + jr s0 + .size rtos_save_\name\()_coproc, .-rtos_save_\name\()_coproc + +.endm + + + +#if SOC_CPU_HAS_HWLOOP + +/** + * @brief Macros to enable and disable the hardware loop feature on the current core + */ +.macro hwlp_enable scratch_reg=a0 + li \scratch_reg, 1 + csrw CSR_HWLP_STATE_REG, \scratch_reg +.endm + +/** + * @brief Disable HW Loop CPU feature while returning the former status in the given register + */ +.macro hwlp_disable reg + csrrw \reg, CSR_HWLP_STATE_REG, zero + /* Only keep the lowest two bits */ + andi \reg, \reg, 0b11 + /* If register is 0, HWLP was off */ + beqz \reg, 1f + /* It was ON, return the enable bit in \reg */ + li \reg, 1 << HWLP_COPROC_IDX +1: +.endm + +/** + * @brief Macros to save and restore the hardware loop registers to and from the given frame + */ +.macro hwlp_save_regs frame=sp + csrr a1, CSR_LOOP0_START_ADDR + sw a1, RV_HWLOOP_START0(\frame) + csrr a1, CSR_LOOP0_END_ADDR + sw a1, RV_HWLOOP_END0(\frame) + csrr a1, CSR_LOOP0_COUNT + sw a1, RV_HWLOOP_COUNT0(\frame) + csrr a1, CSR_LOOP1_START_ADDR + sw a1, RV_HWLOOP_START1(\frame) + csrr a1, CSR_LOOP1_END_ADDR + sw a1, RV_HWLOOP_END1(\frame) + csrr a1, CSR_LOOP1_COUNT + sw a1, RV_HWLOOP_COUNT1(\frame) +.endm + +.macro hwlp_restore_regs frame=sp + lw a1, RV_HWLOOP_START0(\frame) + csrw CSR_LOOP0_START_ADDR, a1 + lw a1, RV_HWLOOP_END0(\frame) + csrw CSR_LOOP0_END_ADDR, a1 + lw a1, RV_HWLOOP_COUNT0(\frame) + csrw CSR_LOOP0_COUNT, a1 + lw a1, RV_HWLOOP_START1(\frame) + csrw CSR_LOOP1_START_ADDR, a1 + lw a1, RV_HWLOOP_END1(\frame) + csrw CSR_LOOP1_END_ADDR, a1 + lw a1, RV_HWLOOP_COUNT1(\frame) + csrw CSR_LOOP1_COUNT, a1 +.endm + + + /** + * @brief Restore the HWLP registers contained in the dedicated save area if the given task ever used it. + * This routine sets the HWLP context to clean in any case. + * + * @param a0 StaticTask address for the newly scheduled task + */ +hwlp_restore_if_used: + addi sp, sp, -16 + sw ra, (sp) + /* Check if the HWLP was in use beforehand */ + li a1, 0 + li a2, HWLP_COPROC_IDX + call pxPortGetCoprocArea + /* Get the enable flags from the coprocessor save area */ + lw a1, RV_COPROC_ENABLE(a0) + /* To avoid having branches below, set the coprocessor enable flag now */ + andi a2, a1, 1 << HWLP_COPROC_IDX + beqz a2, _hwlp_restore_never_used + /* Enable bit was set, restore the coprocessor context */ + lw a0, RV_COPROC_SA+HWLP_COPROC_IDX*4(a0) /* a0 = RvCoprocSaveArea->sa_coprocs[HWLP_COPROC_IDX] */ + hwlp_restore_regs a0 +_hwlp_restore_never_used: + /* Clear the context */ + csrwi CSR_HWLP_STATE_REG, HWLP_CLEAN_STATE + lw ra, (sp) + addi sp, sp, 16 + ret + +#endif /* SOC_CPU_HAS_HWLOOP */ + + +#if SOC_CPU_HAS_PIE + +/** + * @brief Macros to enable and disable the PIE coprocessor on the current core + */ +.macro pie_enable scratch_reg=a0 + li \scratch_reg, 1 + csrw CSR_PIE_STATE_REG, \scratch_reg +.endm + +/** + * @brief Disable the PIE coprocessor while returning the former status in the given register + */ +.macro pie_disable reg + csrrw \reg, CSR_PIE_STATE_REG, zero + /* Only keep the lowest two bits, if register is 0, PIE was off */ + andi \reg, \reg, 0b11 + beqz \reg, 1f + /* It was ON, return the enable bit in \reg */ + li \reg, 1 << PIE_COPROC_IDX +1: +.endm + +/** + * @brief Macros to save and restore the PIE coprocessor registers to and from the given frame + */ +.macro pie_save_regs frame=a0 + /* Save the 128-bit Q registers from the frame memory and then frame += 16 */ + esp.vst.128.ip q0, \frame, 16 + esp.vst.128.ip q1, \frame, 16 + esp.vst.128.ip q2, \frame, 16 + esp.vst.128.ip q4, \frame, 16 + esp.vst.128.ip q5, \frame, 16 + esp.vst.128.ip q6, \frame, 16 + esp.vst.128.ip q7, \frame, 16 + /* Save the QACC_H and QACC_L registers, each being 256 bits big */ + esp.st.qacc.l.l.128.ip \frame, 16 + esp.st.qacc.l.h.128.ip \frame, 16 + esp.st.qacc.h.l.128.ip \frame, 16 + esp.st.qacc.h.h.128.ip \frame, 16 + /* UA_STATE register (128 bits) */ + esp.st.ua.state.ip \frame, 16 + /* XACC register (40 bits) */ + esp.st.u.xacc.ip \frame, 8 + /* The following registers will be stored in the same word */ + /* SAR register (6 bits) */ + esp.movx.r.sar a1 + slli a2, a1, 8 + /* SAR_BYTES register (4 bits) */ + esp.movx.r.sar.bytes a1 + slli a1, a1, 4 + or a2, a2, a1 + /* FFT_BIT_WIDTH register (4 bits) */ + esp.movx.r.fft.bit.width a1 + or a2, a2, a1 + sw a2, (\frame) +.endm + + +.macro pie_restore_regs frame=a0 + /* Restore the 128-bit Q registers from the frame memory and then frame += 16 */ + esp.vld.128.ip q0, \frame, 16 + esp.vld.128.ip q1, \frame, 16 + esp.vld.128.ip q2, \frame, 16 + esp.vld.128.ip q4, \frame, 16 + esp.vld.128.ip q5, \frame, 16 + esp.vld.128.ip q6, \frame, 16 + esp.vld.128.ip q7, \frame, 16 + /* Save the QACC_H and QACC_L registers, each being 256 bits big */ + esp.ld.qacc.l.l.128.ip \frame, 16 + esp.ld.qacc.l.h.128.ip \frame, 16 + esp.ld.qacc.h.l.128.ip \frame, 16 + esp.ld.qacc.h.h.128.ip \frame, 16 + /* UA_STATE register (128 bits) */ + esp.ld.ua.state.ip \frame, 16 + /* XACC register (40 bits) */ + esp.ld.xacc.ip \frame, 8 + /* The following registers are stored in the same word */ + lw a2, (\frame) + /* FFT_BIT_WIDTH register (4 bits) */ + andi a1, a2, 0xf + esp.movx.w.sar a1 + /* SAR_BYTES register (4 bits) */ + srli a2, a2, 4 + andi a1, a2, 0xf + esp.movx.w.sar.bytes a1 + /* SAR register (6 bits) */ + srli a2, a2, 4 + andi a1, a2, 0x3f + esp.movx.w.fft.bit.width a1 +.endm + +generate_coprocessor_routine pie, PIE_COPROC_IDX, pie_enable, pie_save_regs, pie_restore_regs + +#endif /* SOC_CPU_HAS_PIE */ + + #if SOC_CPU_HAS_FPU /* Bit to set in mstatus to enable the FPU */ @@ -40,7 +319,7 @@ /* Bit to clear in mstatus to disable the FPU */ #define CSR_MSTATUS_FPU_DISABLE (3 << 13) -.macro save_fpu_regs frame=sp +.macro fpu_save_regs frame=sp fsw ft0, RV_FPU_FT0(\frame) fsw ft1, RV_FPU_FT1(\frame) fsw ft2, RV_FPU_FT2(\frame) @@ -73,9 +352,11 @@ fsw ft9, RV_FPU_FT9 (\frame) fsw ft10, RV_FPU_FT10(\frame) fsw ft11, RV_FPU_FT11(\frame) + csrr a1, fcsr + sw a1, RV_FPU_FCSR(\frame) .endm -.macro restore_fpu_regs frame=sp +.macro fpu_restore_regs frame=sp flw ft0, RV_FPU_FT0(\frame) flw ft1, RV_FPU_FT1(\frame) flw ft2, RV_FPU_FT2(\frame) @@ -108,6 +389,8 @@ flw ft9, RV_FPU_FT9(\frame) flw ft10, RV_FPU_FT10(\frame) flw ft11, RV_FPU_FT11(\frame) + lw a1, RV_FPU_FCSR(\frame) + csrw fcsr, a1 .endm @@ -125,98 +408,17 @@ .macro fpu_enable reg - li \reg, CSR_MSTATUS_FPU_ENABLE + li \reg, CSR_MSTATUS_FPU_ENABLE csrs mstatus, \reg .endm .macro fpu_disable reg - li \reg, CSR_MSTATUS_FPU_DISABLE + li \reg, CSR_MSTATUS_FPU_DISABLE csrc mstatus, \reg .endm - .global vPortTaskPinToCore - .global vPortCoprocUsedInISR - .global pxPortUpdateCoprocOwner - -/** - * @brief Save the current FPU context in the FPU owner's save area - * - * @param sp Interuptee's RvExcFrame address - * - * Note: Since this routine is ONLY meant to be called from _panic_handler routine, - * it is possible to alter `s0-s11` registers - */ - .global rtos_save_fpu_coproc - .type rtos_save_fpu_coproc, @function -rtos_save_fpu_coproc: - /* If we are in an interrupt context, we have to abort. We don't allow using the FPU from ISR */ -#if ( configNUM_CORES > 1 ) - csrr a2, mhartid /* a2 = coreID */ - slli a2, a2, 2 /* a2 = coreID * 4 */ - la a1, port_uxInterruptNesting /* a1 = &port_uxInterruptNesting */ - add a1, a1, a2 /* a1 = &port_uxInterruptNesting[coreID] */ - lw a1, 0(a1) /* a1 = port_uxInterruptNesting[coreID] */ -#else /* ( configNUM_CORES <= 1 ) */ - lw a1, (port_uxInterruptNesting) /* a1 = port_uxInterruptNesting */ -#endif /* ( configNUM_CORES > 1 ) */ - /* SP still contains the RvExcFrame address */ - mv a0, sp - bnez a1, vPortCoprocUsedInISR - /* Enable the FPU needed by the current task */ - fpu_enable a1 - mv s0, ra - call rtos_current_tcb - /* If the current TCB is NULL, the FPU is used during initialization, even before - * the scheduler started. Consider this a valid usage, the FPU will be disabled - * as soon as the scheduler is started anyway*/ - beqz a0, rtos_save_fpu_coproc_norestore - mv s1, a0 /* s1 = pxCurrentTCBs */ - /* Prepare parameters of pxPortUpdateCoprocOwner */ - mv a2, a0 - li a1, FPU_COPROC_IDX - csrr a0, mhartid - call pxPortUpdateCoprocOwner - /* If the save area is NULL, no need to save context */ - beqz a0, rtos_save_fpu_coproc_nosave - /* Save the FPU context in the structure */ - lw a0, RV_COPROC_SA+FPU_COPROC_IDX*4(a0) /* a0 = RvCoprocSaveArea->sa_coprocs[FPU_COPROC_IDX] */ - save_fpu_regs a0 - csrr a1, fcsr - sw a1, RV_FPU_FCSR(a0) -rtos_save_fpu_coproc_nosave: -#if ( configNUM_CORES > 1 ) - /* Pin current task to current core */ - mv a0, s1 - csrr a1, mhartid - call vPortTaskPinToCore -#endif /* configNUM_CORES > 1 */ - /* Check if we have to restore a previous FPU context from the current TCB */ - mv a0, s1 - /* Do not allocate memory for the FPU yet, delay this until another task wants to use it. - * This guarantees that if a stack overflow occurs when allocating FPU context on the stack, - * the current task context is flushed and updated in the TCB, generating a correct backtrace - * from the panic handler. */ - li a1, 0 - li a2, FPU_COPROC_IDX - call pxPortGetCoprocArea - /* Get the enable flags from the coprocessor save area */ - lw a1, RV_COPROC_ENABLE(a0) - /* To avoid having branches below, set the FPU enable flag now */ - ori a2, a1, 1 << FPU_COPROC_IDX - sw a2, RV_COPROC_ENABLE(a0) - /* Check if the former FPU enable bit was set */ - andi a2, a1, 1 << FPU_COPROC_IDX - beqz a2, rtos_save_fpu_coproc_norestore - /* FPU enable bit was set, restore the FPU context */ - lw a0, RV_COPROC_SA+FPU_COPROC_IDX*4(a0) /* a0 = RvCoprocSaveArea->sa_coprocs[FPU_COPROC_IDX] */ - restore_fpu_regs a0 - lw a1, RV_FPU_FCSR(a0) - csrw fcsr, a1 -rtos_save_fpu_coproc_norestore: - /* Return from routine via s0, instead of ra */ - jr s0 - .size rtos_save_fpu_coproc, .-rtos_save_fpu_coproc +generate_coprocessor_routine fpu, FPU_COPROC_IDX, fpu_enable, fpu_save_regs, fpu_restore_regs #endif /* SOC_CPU_HAS_FPU */ @@ -249,37 +451,50 @@ rtos_current_tcb: * TODO: ISR nesting code improvements ? * In the routines below, let's use a0-a5 registers to let the compiler generate * 16-bit instructions. + * @returns Context that should be given to `rtos_int_exit`. On targets that have coprocessors, + * this value is a bitmap where bit i is 1 if coprocessor i is enable, 0 if it is disabled. + * This routine can use the s registers too since they are not used by the caller (yet) */ .global rtos_int_enter .type rtos_int_enter, @function rtos_int_enter: #if ( configNUM_CORES > 1 ) - csrr a5, mhartid /* a5 = coreID */ - slli a5, a5, 2 /* a5 = coreID * 4 */ + csrr s0, mhartid /* s0 = coreID */ + slli s0, s0, 2 /* s0 = coreID * 4 */ la a0, port_xSchedulerRunning /* a0 = &port_xSchedulerRunning */ - add a0, a0, a5 /* a0 = &port_xSchedulerRunning[coreID] */ + add a0, a0, s0 /* a0 = &port_xSchedulerRunning[coreID] */ lw a0, (a0) /* a0 = port_xSchedulerRunning[coreID] */ #else lw a0, port_xSchedulerRunning /* a0 = port_xSchedulerRunning */ #endif /* ( configNUM_CORES > 1 ) */ + /* In case we jump, return value (a0) is correct */ beqz a0, rtos_int_enter_end /* if (port_xSchedulerRunning[coreID] == 0) jump to rtos_int_enter_end */ /* Increment the ISR nesting count */ la a0, port_uxInterruptNesting /* a0 = &port_uxInterruptNesting */ #if ( configNUM_CORES > 1 ) - add a0, a0, a5 /* a0 = &port_uxInterruptNesting[coreID] // a5 already contains coreID * 4 */ + add a0, a0, s0 /* a0 = &port_uxInterruptNesting[coreID] // s0 contains coreID * 4 */ #endif /* ( configNUM_CORES > 1 ) */ lw a1, 0(a0) /* a1 = port_uxInterruptNesting[coreID] */ addi a2, a1, 1 /* a2 = a1 + 1 */ sw a2, 0(a0) /* port_uxInterruptNesting[coreID] = a2 */ /* If we reached here from another low-priority ISR, i.e, port_uxInterruptNesting[coreID] > 0, then skip stack pushing to TCB */ + li a0, 0 /* return 0 in case we are going to branch */ bnez a1, rtos_int_enter_end /* if (port_uxInterruptNesting[coreID] > 0) jump to rtos_int_enter_end */ + li s2, 0 #if SOC_CPU_COPROC_NUM > 0 - /* Disable the FPU to forbid the ISR from using it. We don't need to re-enable it manually since the caller - * will restore `mstatus` before returning from interrupt. */ + /* Disable the coprocessors to forbid the ISR from using it */ +#if SOC_CPU_HAS_PIE + /* The current PIE coprocessor status will be returned in a0 */ + pie_disable a0 + or s2, s2, a0 +#endif /* SOC_CPU_HAS_PIE */ + +#if SOC_CPU_HAS_FPU fpu_disable a0 +#endif /* SOC_CPU_HAS_FPU */ #endif /* SOC_CPU_COPROC_NUM > 0 */ @@ -291,24 +506,48 @@ rtos_int_enter: /* Save the current sp in pxCurrentTCBs[coreID] and load the ISR stack on to sp */ #if ( configNUM_CORES > 1 ) la a0, pxCurrentTCBs /* a0 = &pxCurrentTCBs */ - add a0, a0, a5 /* a0 = &pxCurrentTCBs[coreID] // a5 already contains coreID * 4 */ + add a0, a0, s0 /* a0 = &pxCurrentTCBs[coreID] // s0 already contains coreID * 4 */ lw a0, (a0) /* a0 = pxCurrentTCBs[coreID] */ sw sp, 0(a0) /* pxCurrentTCBs[coreID] = sp */ - la a0, xIsrStackTop /* a0 = &xIsrStackTop */ - add a0, a0, a5 /* a0 = &xIsrStackTop[coreID] // a5 already contains coreID * 4 */ - lw sp, (a0) /* sp = xIsrStackTop[coreID] */ + /* We may need a0 below to call pxPortGetCoprocArea */ + la a1, xIsrStackTop /* a1 = &xIsrStackTop */ + add a1, a1, s0 /* a1 = &xIsrStackTop[coreID] // s0 already contains coreID * 4 */ + lw sp, (a1) /* sp = xIsrStackTop[coreID] */ #else lw a0, pxCurrentTCBs /* a0 = pxCurrentTCBs */ sw sp, 0(a0) /* pxCurrentTCBs[0] = sp */ lw sp, xIsrStackTop /* sp = xIsrStackTop */ #endif /* ( configNUM_CORES > 1 ) */ +#if SOC_CPU_HAS_HWLOOP + /* Check if the current task used the Hardware loop feature, by reading the state */ + csrr a1, CSR_HWLP_STATE_REG + addi a1, a1, -HWLP_DIRTY_STATE + bnez a1, 1f + /* State is dirty! The hardware loop feature was used, save the registers */ + li a1, 1 /* Allocate the save area if not already allocated */ + li a2, HWLP_COPROC_IDX + mv s1, ra + call pxPortGetCoprocArea + mv ra, s1 + /* Set the enable flags from the coprocessor save area */ + lw a1, RV_COPROC_ENABLE(a0) + ori a1, a1, 1 << HWLP_COPROC_IDX + sw a1, RV_COPROC_ENABLE(a0) + /* Get the area where we need to save the HWLP registers */ + lw a0, RV_COPROC_SA+HWLP_COPROC_IDX*4(a0) /* a0 = RvCoprocSaveArea->sa_coprocs[\coproc_idx] */ + hwlp_save_regs a0 + /* Disable the HWLP feature so that ISR cannot use them */ + csrwi CSR_HWLP_STATE_REG, HWLP_CLEAN_STATE +1: +#endif + #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD /* Prepare the parameters for esp_hw_stack_guard_set_bounds(xIsrStackBottom, xIsrStackTop); */ #if ( configNUM_CORES > 1 ) /* Load the xIsrStack for the current core and set the new bounds */ la a0, xIsrStackBottom - add a0, a0, a5 /* a0 = &xIsrStackBottom[coreID] */ + add a0, a0, s0 /* a0 = &xIsrStackBottom[coreID] */ lw a0, (a0) /* a0 = xIsrStackBottom[coreID] */ #else lw a0, xIsrStackBottom @@ -320,6 +559,8 @@ rtos_int_enter: ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1 #endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */ + /* Return the coprocessor context from s2 */ + mv a0, s2 rtos_int_enter_end: ret @@ -327,6 +568,8 @@ rtos_int_enter_end: * @brief Restore the stack pointer of the next task to run. * * @param a0 Former mstatus + * @param a1 Context returned by `rtos_int_enter`. On targets that have coprocessors, this value is a bitmap + * where bit i is 1 if coprocessor i was enable, 0 if it was disabled. * * @returns New mstatus (potentially with coprocessors disabled) */ @@ -334,9 +577,14 @@ rtos_int_enter_end: .type rtos_int_exit, @function rtos_int_exit: /* To speed up this routine and because this current routine is only meant to be called from the interrupt - * handler, let's use callee-saved registers instead of stack space. Registers `s3-s11` are not used by + * handler, let's use callee-saved registers instead of stack space. Registers `s5-s11` are not used by * the caller */ mv s11, a0 +#if SOC_CPU_COPROC_NUM > 0 + /* Save a1 as it contains the bitmap with the enabled coprocessors */ + mv s8, a1 +#endif + #if ( configNUM_CORES > 1 ) csrr a1, mhartid /* a1 = coreID */ slli a1, a1, 2 /* a1 = a1 * 4 */ @@ -366,12 +614,12 @@ isr_skip_decrement: /* If the CPU reached this label, a2 (uxInterruptNesting) is 0 for sure */ /* Schedule the next task if a yield is pending */ - la a0, xPortSwitchFlag /* a0 = &xPortSwitchFlag */ + la s7, xPortSwitchFlag /* s7 = &xPortSwitchFlag */ #if ( configNUM_CORES > 1 ) - add a0, a0, a1 /* a0 = &xPortSwitchFlag[coreID] // a1 already contains coreID * 4 */ + add s7, s7, a1 /* s7 = &xPortSwitchFlag[coreID] // a1 already contains coreID * 4 */ #endif /* ( configNUM_CORES > 1 ) */ - lw a2, 0(a0) /* a2 = xPortSwitchFlag[coreID] */ - beqz a2, no_switch /* if (xPortSwitchFlag[coreID] == 0) jump to no_switch */ + lw a0, 0(s7) /* a0 = xPortSwitchFlag[coreID] */ + beqz a0, no_switch_restore_coproc /* if (xPortSwitchFlag[coreID] == 0) jump to no_switch_restore_coproc */ /* Preserve return address and schedule next task. To speed up the process, and because this current routine * is only meant to be called from the interrupt handle, let's save some speed and space by using callee-saved @@ -379,33 +627,68 @@ isr_skip_decrement: mv s10, ra #if ( SOC_CPU_COPROC_NUM > 0 ) /* In the cases where the newly scheduled task is different from the previously running one, - * we have to disable the coprocessor(s) to let them trigger an exception on first use. - * Else, if the same task is scheduled, do not change the coprocessor(s) state. */ + * we have to disable the coprocessors to let them trigger an exception on first use. + * Else, if the same task is scheduled, restore the former coprocessors state (before the interrupt) */ call rtos_current_tcb + /* Keep former TCB in s9 */ mv s9, a0 +#endif call vTaskSwitchContext +#if ( SOC_CPU_COPROC_NUM == 0 ) + mv ra, s10 /* Restore original return address */ +#endif + /* Clears the switch pending flag (stored in s7) */ + sw zero, 0(s7) /* xPortSwitchFlag[coreID] = 0; */ + +#if ( SOC_CPU_COPROC_NUM > 0 ) + /* If the Task to schedule is NOT the same as the former one (s9), keep the coprocessors disabled */ call rtos_current_tcb - beq a0, s9, rtos_int_exit_no_change - /* Disable the coprocessors in s11 register (former mstatus) */ - li a0, ~CSR_MSTATUS_FPU_DISABLE - and s11, s11, a0 -rtos_int_exit_no_change: -#else /* ( SOC_CPU_COPROC_NUM == 0 ) */ - call vTaskSwitchContext -#endif /* ( SOC_CPU_COPROC_NUM > 0 ) */ - mv ra, s10 + mv ra, s10 /* Restore original return address */ + beq a0, s9, no_switch_restore_coproc + +#if SOC_CPU_HAS_HWLOOP + /* We have to restore the context of the HWLP if the newly scheduled task used it before. In all cases, this + * routine will also clean the state and set it to clean */ + mv s7, ra + /* a0 contains the current TCB address */ + call hwlp_restore_if_used + mv ra, s7 +#endif /* SOC_CPU_HAS_HWLOOP */ - /* Clears the switch pending flag */ - la a0, xPortSwitchFlag /* a0 = &xPortSwitchFlag */ -#if ( configNUM_CORES > 1 ) - /* C routine vTaskSwitchContext may change the temp registers, so we read again */ - csrr a1, mhartid /* a1 = coreID */ - slli a1, a1, 2 /* a1 = a1 * 4 */ - add a0, a0, a1 /* a0 = &xPortSwitchFlag[coreID]; */ -#endif /* ( configNUM_CORES > 1 ) */ - sw zero, 0(a0) /* xPortSwitchFlag[coreID] = 0; */ +#if SOC_CPU_HAS_FPU + /* Disable the FPU in the `mstatus` value to return */ + li a1, ~CSR_MSTATUS_FPU_DISABLE + and s11, s11, a1 +#endif /* SOC_CPU_HAS_FPU */ + j no_switch_restored + +#endif /* ( SOC_CPU_COPROC_NUM > 0 ) */ -no_switch: +no_switch_restore_coproc: + /* We reach here either because there is no switch scheduled or because the TCB that is going to be scheduled + * is the same as the one that has been interrupted. In both cases, we need to restore the coprocessors status */ +#if SOC_CPU_HAS_HWLOOP + /* Check if the ISR altered the state of the HWLP */ + csrr a1, CSR_HWLP_STATE_REG + addi a1, a1, -HWLP_DIRTY_STATE + bnez a1, 1f + /* ISR used the HWLP, restore the HWLP context! */ + mv s7, ra + /* a0 contains the current TCB address */ + call hwlp_restore_if_used + mv ra, s7 +1: + /* Else, the ISR hasn't touched HWLP registers, we don't need to restore the HWLP registers */ +#endif /* SOC_CPU_HAS_HWLOOP */ + +#if SOC_CPU_HAS_PIE + andi a0, s8, 1 << PIE_COPROC_IDX + beqz a0, 2f + pie_enable a0 +2: +#endif /* SOC_CPU_HAS_PIE */ + +no_switch_restored: #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD /* esp_hw_stack_guard_monitor_stop(); pass the scratch registers */ diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h index 109bea6d28b4..14091c9c052b 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h @@ -141,12 +141,9 @@ typedef uint32_t TickType_t; BaseType_t xPortInIsrContext(void); /** - * @brief Asserts if in ISR context + * @brief Assert if in ISR context * * - Asserts on xPortInIsrContext() internally - * - * @note [refactor-todo] Check if this API is still required - * @note [refactor-todo] Check if this should be inlined */ void vPortAssertIfInISR(void); @@ -427,6 +424,9 @@ void vPortTCBPreDeleteHook( void *pxTCB ); #define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMaskFromISR() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(prev_level) vPortClearInterruptMaskFromISR(prev_level) +/** + * @brief Assert if in ISR context + */ #define portASSERT_IF_IN_ISR() vPortAssertIfInISR() /** diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index e1cba7ab3e6e..9722a2c30870 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -8,7 +8,7 @@ * * SPDX-License-Identifier: MIT * - * SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2023-2024 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 @@ -395,7 +395,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, | Coproc Save Area | (CPSA MUST BE FIRST) | ------------------------- | | TLS Variables | - | ------------------------- | <- Start of useable stack + | ------------------------- | <- Start of usable stack | Starting stack frame | | ------------------------- | <- pxTopOfStack on return (which is the tasks current SP) | | | @@ -449,7 +449,8 @@ BaseType_t xPortInIsrContext(void) void vPortAssertIfInISR(void) { - configASSERT(xPortInIsrContext()); + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortInIsrContext() == 0); } BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void) @@ -489,7 +490,7 @@ BaseType_t __attribute__((optimize("-O3"))) xPortEnterCriticalTimeout(portMUX_TY void __attribute__((optimize("-O3"))) vPortExitCritical(portMUX_TYPE *mux) { /* This function may be called in a nested manner. Therefore, we only need - * to reenable interrupts if this is the last call to exit the critical. We + * to re-enable interrupts if this is the last call to exit the critical. We * can use the nesting count to determine whether this is the last exit call. */ spinlock_release(mux); diff --git a/components/freertos/FreeRTOS-Kernel/sbom.yml b/components/freertos/FreeRTOS-Kernel/sbom.yml index f5f9f31eb331..1fc82481f888 100644 --- a/components/freertos/FreeRTOS-Kernel/sbom.yml +++ b/components/freertos/FreeRTOS-Kernel/sbom.yml @@ -4,3 +4,6 @@ cpe: cpe:2.3:o:amazon:freertos:{}:*:*:*:*:*:*:* supplier: 'Organization: Espressif Systems (Shanghai) CO LTD' originator: 'Organization: Amazon Web Services' description: An open-source, real-time operating system (RTOS) with additional features and patches from Espressif. +cve-exclude-list: + - cve: CVE-2024-28115 + reason: Affects only ARMv7-M MPU ports, and ARMv8-M ports with Memory Protected Unit (MPU) support enabled diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index fd5511828ae0..2482826674e8 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -141,6 +141,11 @@ * - If a yield is required on the current core, this macro return pdTRUE * - if a yield is required on the other core, this macro will internally * trigger it. + * + * - In SMP, these macros must be called from a critical section (where the + * kernel locks are taken). + * - In single-core, these macros must be called from a critical section or when + * the scheduler is suspended. */ #if ( configNUMBER_OF_CORES > 1 ) #define taskIS_YIELD_REQUIRED( pxTCB, xYieldEqualPriority ) prvIsYieldRequiredSMP( ( pxTCB ), ( pxTCB )->uxPriority, xYieldEqualPriority ) @@ -177,7 +182,12 @@ #endif /* configNUMBER_OF_CORES > 1 */ /*-----------------------------------------------------------*/ -/* Macros to check if a particular task is a currently running. */ +/* Macros to check if a particular task is a currently running. + * + * - In SMP, these macros must be called from a critical section (where the + * kernel lock is taken). + * - In single-core, these macros must be called from a critical section or when + * the scheduler is suspended */ #if ( configNUMBER_OF_CORES > 1 ) #define taskIS_CURRENTLY_RUNNING( pxTCB ) ( ( ( ( pxTCB ) == pxCurrentTCBs[ 0 ] ) || ( ( pxTCB ) == pxCurrentTCBs[ 1 ] ) ) ? pdTRUE : pdFALSE ) #define taskIS_CURRENTLY_RUNNING_ON_CORE( pxTCB, xCoreID ) ( ( ( pxTCB ) == pxCurrentTCBs[ ( xCoreID ) ] ) ? pdTRUE : pdFALSE ) @@ -193,7 +203,12 @@ /*-----------------------------------------------------------*/ /* Macro to check if a particular task can currently be scheduled (i.e., is - * the scheduler suspended). */ + * the scheduler suspended). + * + * - In SMP, these macros must be called from a critical section (where the + * kernel lock is taken). + * - In single-core, these macros must be called from a critical section or when + * the scheduler is suspended */ #if ( configNUMBER_OF_CORES > 1 ) #define taskCAN_BE_SCHEDULED( pxTCB ) prvCheckTaskCanBeScheduledSMP( pxTCB ) #else @@ -569,6 +584,9 @@ static BaseType_t prvCreateIdleTasks( void ); * Exit: * - Returns pdTRUE if the current core requires yielding * - The other core will be triggered to yield if required + * + * @note This function must be called from a critical section where the kernel + * lock is taken). */ #if ( configNUMBER_OF_CORES > 1 ) @@ -589,6 +607,9 @@ static BaseType_t prvCreateIdleTasks( void ); * - If a task is unpinned, check the scheduler suspension state on both cores. * The task can be scheduled if the scheduler is not suspended on either of * the cores. + * + * @note This function must be called from a critical section (where the kernel + * lock is taken). */ #if ( configNUMBER_OF_CORES > 1 ) @@ -772,6 +793,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskPriority, BaseType_t xYieldEqualPriority ) { + /* This function must be called from a critical section (where the kernel + * lock is taken). */ + configASSERT( uxTaskPriority < configMAX_PRIORITIES ); /* Save core ID as we can no longer be preempted. */ @@ -825,6 +849,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; static BaseType_t prvCheckTaskCanBeScheduledSMP( TCB_t * pxTCB ) { + /* This function must be called from a critical section (where the kernel + * lock is taken). */ + BaseType_t xReturn; if( pxTCB->xCoreID == tskNO_AFFINITY ) @@ -2462,22 +2489,29 @@ void vTaskEndScheduler( void ) void vTaskSuspendAll( void ) { - /* A critical section is not required as the variable is of type + /* For SMP, we need to take the kernel lock here as we are about to access + * kernel data structures. + * + * For single-core, a critical section is not required as the variable is of type * BaseType_t. Please read Richard Barry's reply in the following link to a * post in the FreeRTOS support forum before reporting this as a bug! - * https://goo.gl/wu4acr */ + prvENTER_CRITICAL_SMP_ONLY( &xKernelLock ); + { + /* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that + * do not otherwise exhibit real time behaviour. */ + portSOFTWARE_BARRIER(); - /* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that - * do not otherwise exhibit real time behaviour. */ - portSOFTWARE_BARRIER(); - - /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment - * is used to allow calls to vTaskSuspendAll() to nest. */ - ++uxSchedulerSuspended[ portGET_CORE_ID() ]; + /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment + * is used to allow calls to vTaskSuspendAll() to nest. */ + ++uxSchedulerSuspended[ portGET_CORE_ID() ]; - /* Enforces ordering for ports and optimised compilers that may otherwise place - * the above increment elsewhere. */ - portMEMORY_BARRIER(); + /* Enforces ordering for ports and optimised compilers that may otherwise place + * the above increment elsewhere. */ + portMEMORY_BARRIER(); + } + /* Release the previously taken kernel lock. */ + prvEXIT_CRITICAL_SMP_ONLY( &xKernelLock ); } /*----------------------------------------------------------*/ @@ -5478,7 +5512,7 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configTASKLIST_INCLUDE_COREID == 1 ) { const BaseType_t xCoreID = ( pxTaskStatusArray[ x ].xCoreID == tskNO_AFFINITY ) ? -1 : pxTaskStatusArray[ x ].xCoreID; - sprintf( pcWriteBuffer, "\t%c\t%u\t%d\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( int ) xCoreID, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */ + sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\t%d\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber, ( int ) xCoreID ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */ } #else /* configTASKLIST_INCLUDE_COREID == 1 */ { diff --git a/components/freertos/app_startup.c b/components/freertos/app_startup.c index 7e4439d0b818..c7f811676958 100644 --- a/components/freertos/app_startup.c +++ b/components/freertos/app_startup.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/freertos/esp_additions/idf_additions.c b/components/freertos/esp_additions/idf_additions.c index 4bd428981f6c..ee02e838cc40 100644 --- a/components/freertos/esp_additions/idf_additions.c +++ b/components/freertos/esp_additions/idf_additions.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,6 +21,8 @@ #include "freertos/timers.h" #include "freertos/idf_additions.h" #include "esp_heap_caps.h" +#include "esp_log.h" +#include "freertos/portmacro.h" /* -------------------------------------------- Creation With Memory Caps ------------------------------------------- */ @@ -81,21 +83,128 @@ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + static void prvTaskDeleteWithCapsTask( void * pvParameters ) + { + TaskHandle_t xTaskToDelete = ( TaskHandle_t ) pvParameters; + + /* The task to be deleted must not be running */ + configASSERT( eRunning != eTaskGetState( xTaskToDelete ) ); + + /* Delete the WithCaps task */ + vTaskDeleteWithCaps( xTaskToDelete ); + + /* Delete the temporary clean up task */ + vTaskDelete( NULL ); + } + void vTaskDeleteWithCaps( TaskHandle_t xTaskToDelete ) { - BaseType_t xResult; - StaticTask_t * pxTaskBuffer; - StackType_t * puxStackBuffer; + /* THIS FUNCTION SHOULD NOT BE CALLED FROM AN INTERRUPT CONTEXT. */ + /*TODO: Update it to use portASSERT_IF_IN_ISR() instead. (IDF-10540) */ + vPortAssertIfInISR(); - xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer ); - configASSERT( xResult == pdTRUE ); + TaskHandle_t xCurrentTaskHandle = xTaskGetCurrentTaskHandle(); + configASSERT( xCurrentTaskHandle != NULL ); - /* Delete the task */ - vTaskDelete( xTaskToDelete ); + if( ( xTaskToDelete == NULL ) || ( xTaskToDelete == xCurrentTaskHandle ) ) + { + /* The WithCaps task is deleting itself. While, the task can put itself on the + * xTasksWaitingTermination list via the vTaskDelete() call, the idle + * task will not free the task TCB and stack memories we created statically + * during xTaskCreateWithCaps() or xTaskCreatePinnedToCoreWithCaps(). This + * task will never be rescheduled once it is on the xTasksWaitingTermination + * list and will not be able to clear the memories. Therefore, it will leak memory. + * + * To avoid this, we create a new "temporary clean up" task to delete the current task. + * This task is created at the priority of the task to be deleted with the same core + * affitinty. Its limited purpose is to delete the self-deleting task created WithCaps. + * + * This approach has the following problems - + * 1. Once a WithCaps task deletes itself via vTaskDeleteWithCaps(), it may end up in the + * suspended tasks lists for a short time before being deleted. This can give an incorrect + * picture about the system state. + * + * 2. This approach is wasteful and can be error prone. The temporary clean up task will need + * system resources to get scheduled and cleanup the WithCaps task. It can be a problem if the system + * has several self-deleting WithCaps tasks. + * + * TODO: A better approach could be either - + * + * 1. Delegate memory management to the application/user. This way the kernel needn't bother about freeing + * the memory (like other static memory task creation APIs like xTaskCreateStatic()) (IDF-10521) + * + * 2. Have a post deletion hook/callback from the IDLE task to notify higher layers when it is safe to + * perform activities such as clearing up the TCB and stack memories. (IDF-10522) */ + if( xTaskCreatePinnedToCore( ( TaskFunction_t ) prvTaskDeleteWithCapsTask, "prvTaskDeleteWithCapsTask", configMINIMAL_STACK_SIZE, xCurrentTaskHandle, uxTaskPriorityGet( xTaskToDelete ), NULL, xPortGetCoreID() ) != pdFAIL ) + { + /* Although the current task should get preemted immediately when prvTaskDeleteWithCapsTask is created, + * for safety, we suspend the current task and wait for prvTaskDeleteWithCapsTask to delete it. */ + vTaskSuspend( xTaskToDelete ); + + /* Should never reach here */ + ESP_LOGE( "freertos_additions", "%s: Failed to suspend the task to be deleted", __func__ ); + abort(); + } + else + { + /* Failed to create the task to delete the current task. */ + ESP_LOGE( "freertos_additions", "%s: Failed to create the task to delete the current task", __func__ ); + abort(); + } + } - /* Free the memory buffers */ - heap_caps_free( puxStackBuffer ); - vPortFree( pxTaskBuffer ); + #if ( configNUM_CORES > 1 ) + else if( eRunning == eTaskGetState( xTaskToDelete ) ) + { + /* The WithCaps task is running on another core. + * We suspend the task first and then delete it. */ + vTaskSuspend( xTaskToDelete ); + + /* Wait for the task to be suspended */ + while( eRunning == eTaskGetState( xTaskToDelete ) ) + { + portYIELD_WITHIN_API(); + } + + BaseType_t xResult; + StaticTask_t * pxTaskBuffer; + StackType_t * puxStackBuffer; + + xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer ); + configASSERT( xResult == pdTRUE ); + configASSERT( puxStackBuffer != NULL ); + configASSERT( pxTaskBuffer != NULL ); + + /* Delete the task */ + vTaskDelete( xTaskToDelete ); + + /* Free the memory buffers */ + heap_caps_free( puxStackBuffer ); + vPortFree( pxTaskBuffer ); + } + #endif /* if ( configNUM_CORES > 1 ) */ + else + { + /* The WithCaps task is not running and is being deleted + * from another task's context. */ + configASSERT( eRunning != eTaskGetState( xTaskToDelete ) ); + + BaseType_t xResult; + StaticTask_t * pxTaskBuffer; + StackType_t * puxStackBuffer; + + xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer ); + configASSERT( xResult == pdTRUE ); + configASSERT( puxStackBuffer != NULL ); + configASSERT( pxTaskBuffer != NULL ); + + /* We can delete the task and free the memory buffers. */ + vTaskDelete( xTaskToDelete ); + + /* Free the memory buffers */ + heap_caps_free( puxStackBuffer ); + vPortFree( pxTaskBuffer ); + } /* if( ( xTaskToDelete == NULL ) || ( xTaskToDelete == xCurrentTaskHandle ) ) */ } #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ diff --git a/components/freertos/esp_additions/include/freertos/idf_additions.h b/components/freertos/esp_additions/include/freertos/idf_additions.h index b9fb9c47a081..5e50dd1ba3c5 100644 --- a/components/freertos/esp_additions/include/freertos/idf_additions.h +++ b/components/freertos/esp_additions/include/freertos/idf_additions.h @@ -339,6 +339,11 @@ uint8_t * pxTaskGetStackStart( TaskHandle_t xTask ); * @brief Deletes a task previously created using xTaskCreateWithCaps() or * xTaskCreatePinnedToCoreWithCaps() * + * @note It is recommended to use this API to delete tasks from another task's + * context, rather than self-deletion. When the task is being deleted, it is vital + * to ensure that it is not running on another core. This API must not be called + * from an interrupt context. + * * @param xTaskToDelete A handle to the task to be deleted */ void vTaskDeleteWithCaps( TaskHandle_t xTaskToDelete ); diff --git a/components/freertos/test_apps/.build-test-rules.yml b/components/freertos/test_apps/.build-test-rules.yml index 83c48f535d09..d7bce90918e0 100644 --- a/components/freertos/test_apps/.build-test-rules.yml +++ b/components/freertos/test_apps/.build-test-rules.yml @@ -2,9 +2,9 @@ components/freertos/test_apps/freertos: disable: - - if: IDF_TARGET == "esp32c5" or (CONFIG_NAME == "smp" and IDF_TARGET == "esp32p4") + - if: (CONFIG_NAME == "smp" and IDF_TARGET == "esp32p4") temporary: true - reason: target(s) not supported yet # TODO: [ESP32C5] IDF-8672 + reason: target(s) not supported yet components/freertos/test_apps/orig_inc_path: enable: diff --git a/components/freertos/test_apps/freertos/README.md b/components/freertos/test_apps/freertos/README.md index bf47d80ec649..3a502b1f86f4 100644 --- a/components/freertos/test_apps/freertos/README.md +++ b/components/freertos/test_apps/freertos/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/freertos/test_apps/freertos/misc/test_idf_additions.c b/components/freertos/test_apps/freertos/misc/test_idf_additions.c index aea2ecb2f8ed..ced4941398c6 100644 --- a/components/freertos/test_apps/freertos/misc/test_idf_additions.c +++ b/components/freertos/test_apps/freertos/misc/test_idf_additions.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -43,7 +43,17 @@ static void task_with_caps(void *arg) vTaskSuspend(NULL); } -TEST_CASE("IDF additions: Task creation with memory caps", "[freertos]") +static void task_with_caps_self_delete(void *arg) +{ + /* Wait for the unity task to indicate that this task should delete itself */ + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + /* Although it is not recommended to self-delete a task with memory caps but this + * is done intentionally to test for memory leaks */ + vTaskDeleteWithCaps(NULL); +} + +TEST_CASE("IDF additions: Task creation with memory caps and deletion from another task", "[freertos]") { TaskHandle_t task_handle = NULL; StackType_t *puxStackBuffer; @@ -62,6 +72,57 @@ TEST_CASE("IDF additions: Task creation with memory caps", "[freertos]") vTaskDeleteWithCaps(task_handle); } +TEST_CASE("IDF additions: Task creation with memory caps and self deletion", "[freertos]") +{ + TaskHandle_t task_handle = NULL; + StackType_t *puxStackBuffer; + StaticTask_t *pxTaskBuffer; + + // Create a task with caps + TEST_ASSERT_EQUAL(pdPASS, xTaskCreatePinnedToCoreWithCaps(task_with_caps_self_delete, "task", 4096, (void *)xTaskGetCurrentTaskHandle(), UNITY_FREERTOS_PRIORITY + 1, &task_handle, UNITY_FREERTOS_CPU, OBJECT_MEMORY_CAPS)); + TEST_ASSERT_NOT_EQUAL(NULL, task_handle); + // Get the task's memory + TEST_ASSERT_EQUAL(pdTRUE, xTaskGetStaticBuffers(task_handle, &puxStackBuffer, &pxTaskBuffer)); + TEST_ASSERT(esp_ptr_in_dram(puxStackBuffer)); + TEST_ASSERT(esp_ptr_in_dram(pxTaskBuffer)); + // Notify the task to delete itself + xTaskNotifyGive(task_handle); +} + +#if ( CONFIG_FREERTOS_NUMBER_OF_CORES > 1 ) + +static void task_with_caps_running_on_other_core(void *arg) +{ + /* Notify the unity task that this task is running on the other core */ + xTaskNotifyGive((TaskHandle_t)arg); + + /* We make sure that this task is running on the other core */ + while (1) { + ; + } +} + +TEST_CASE("IDF additions: Task creation with memory caps and deletion from another core", "[freertos]") +{ + TaskHandle_t task_handle = NULL; + StackType_t *puxStackBuffer; + StaticTask_t *pxTaskBuffer; + + // Create a task with caps on the other core + TEST_ASSERT_EQUAL(pdPASS, xTaskCreatePinnedToCoreWithCaps(task_with_caps_running_on_other_core, "task", 4096, (void *)xTaskGetCurrentTaskHandle(), UNITY_FREERTOS_PRIORITY + 1, &task_handle, !UNITY_FREERTOS_CPU, OBJECT_MEMORY_CAPS)); + TEST_ASSERT_NOT_EQUAL(NULL, task_handle); + // Get the task's memory + TEST_ASSERT_EQUAL(pdTRUE, xTaskGetStaticBuffers(task_handle, &puxStackBuffer, &pxTaskBuffer)); + TEST_ASSERT(esp_ptr_in_dram(puxStackBuffer)); + TEST_ASSERT(esp_ptr_in_dram(pxTaskBuffer)); + // Wait for the created task to start running + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + // Delete the task from another core + vTaskDeleteWithCaps(task_handle); +} + +#endif // CONFIG_FREERTOS_NUMBER_OF_CORES > 1 + TEST_CASE("IDF additions: Queue creation with memory caps", "[freertos]") { QueueHandle_t queue_handle; diff --git a/components/freertos/test_apps/freertos/port/test_fpu_in_task.c b/components/freertos/test_apps/freertos/port/test_fpu_in_task.c index 6c52f314d9b4..fe59eb4bc21d 100644 --- a/components/freertos/test_apps/freertos/port/test_fpu_in_task.c +++ b/components/freertos/test_apps/freertos/port/test_fpu_in_task.c @@ -165,7 +165,7 @@ static void unpinned_task(void *arg) TEST_ASSERT_EQUAL(cur_core_num, xTaskGetCoreID(NULL)); #endif #endif // !CONFIG_FREERTOS_UNICORE - // Reenable scheduling/preemption + // Re-enable scheduling/preemption #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) ) vTaskPreemptionEnable(NULL); #else @@ -192,7 +192,7 @@ TEST_CASE("FPU: Usage in unpinned task", "[freertos]") typedef struct { bool negative; TaskHandle_t main; -} ParamsFPU; +} fpu_params_t; /** * @brief Function performing some simple calculation using several FPU registers. @@ -200,7 +200,7 @@ typedef struct { */ void fpu_calculation(void* arg) { - ParamsFPU* p = (ParamsFPU*) arg; + fpu_params_t* p = (fpu_params_t*) arg; const bool negative = p->negative; const float init = negative ? -1.f : 1.f; float f = init; @@ -236,13 +236,13 @@ TEST_CASE("FPU: Unsolicited context switch between tasks using FPU", "[freertos] /* Create two tasks that are on the same core and use the same FPU */ TaskHandle_t unity_task_handle = xTaskGetCurrentTaskHandle(); TaskHandle_t tasks[2]; - ParamsFPU params[2] = { + fpu_params_t params[2] = { { .negative = false, .main = unity_task_handle }, { .negative = true, .main = unity_task_handle }, }; xTaskCreatePinnedToCore(fpu_calculation, "Task1", 2048, params + 0, UNITY_FREERTOS_PRIORITY + 1, &tasks[0], 1); - xTaskCreatePinnedToCore(fpu_calculation, "Task2", 2048, params + 1, UNITY_FREERTOS_PRIORITY + 2, &tasks[2], 1); + xTaskCreatePinnedToCore(fpu_calculation, "Task2", 2048, params + 1, UNITY_FREERTOS_PRIORITY + 1, &tasks[1], 1); ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ulTaskNotifyTake(pdTRUE, portMAX_DELAY); diff --git a/components/freertos/test_apps/freertos/port/test_freertos_isinisrcontext.c b/components/freertos/test_apps/freertos/port/test_freertos_isinisrcontext.c index b3b90552b7be..3c0446f5a75c 100644 --- a/components/freertos/test_apps/freertos/port/test_freertos_isinisrcontext.c +++ b/components/freertos/test_apps/freertos/port/test_freertos_isinisrcontext.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -58,3 +58,20 @@ TEST_CASE("xPortInIsrContext test", "[freertos]") } #endif + +#if !CONFIG_FREERTOS_SMP // TODO: Enable when IDF-10540 is fixed + +static void testint_assert(void) +{ + esp_rom_printf("INT!\n"); + portASSERT_IF_IN_ISR(); +} + +TEST_CASE("port must assert if in ISR context", "[ignore]") +{ + esp_err_t err = esp_register_freertos_tick_hook_for_cpu(testint_assert, xPortGetCoreID()); + TEST_ASSERT_EQUAL_HEX32(ESP_OK, err); + vTaskDelay(100 / portTICK_PERIOD_MS); + esp_deregister_freertos_tick_hook_for_cpu(testint_assert, xPortGetCoreID()); +} +#endif // !CONFIG_FREERTOS_SMP diff --git a/components/freertos/test_apps/freertos/port/test_hwlp.c b/components/freertos/test_apps/freertos/port/test_hwlp.c new file mode 100644 index 000000000000..49347318f569 --- /dev/null +++ b/components/freertos/test_apps/freertos/port/test_hwlp.c @@ -0,0 +1,94 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#include "soc/soc_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "unity.h" + +/** + * On RISC-V targets that have coprocessors, the contexts are saved at the lowest address of the stack, + * which can lead to wrong stack watermark calculation in FreeRTOS in theory. + * As such, the port layer of FreeRTOS will adjust the lowest address of the stack when a coprocessor + * context is saved. + */ +#if SOC_CPU_HAS_HWLOOP + +uint32_t use_hwlp(uint32_t count); + +TEST_CASE("HWLP: Context save does not affect stack watermark", "[freertos]") +{ + /* Force the FreeRTOS port layer to store a HWLP context in the current task. + * So let's use the it and make sure another task, on the SAME CORE, also uses it */ + const TaskHandle_t current_handle = xTaskGetCurrentTaskHandle(); + + /* Get the current stack watermark */ + const UBaseType_t before_watermark = uxTaskGetStackHighWaterMark(current_handle); + + /* Use the HWLP unit, the context will NOT be flushed until a context switch is done */ + use_hwlp(20); + + /* Make sure FreeRTOS switches to another task, even Idle task, so that the current Task saves + * the HWLP current context */ + vTaskDelay(10); + + const UBaseType_t after_watermark = uxTaskGetStackHighWaterMark(current_handle); + + TEST_ASSERT_TRUE(after_watermark > before_watermark / 2); +} + +#if CONFIG_FREERTOS_NUMBER_OF_CORES > 1 + +typedef struct { + uint32_t count; + TaskHandle_t main; +} hwlp_params_t; + +static void calculation(void* arg) +{ + hwlp_params_t* p = (hwlp_params_t*) arg; + const uint32_t count = p->count; + uint32_t result = 0; + int i = 0; + + for (i = 0; i < 50000; i++) { + uint32_t current = use_hwlp(count); + result += current; + + /* Using TEST_ASSERT_TRUE triggers a stack overflow, make sure the count is still correct. + * The function `use_hwlp` should return (count * 16) */ + assert(count * 16 == current); + } + + /* Make sure the result is correct */ + assert(count * 16 * i == result); + + xTaskNotifyGive(p->main); + vTaskDelete(NULL); +} + +TEST_CASE("HWLP: Unsolicited context switch between tasks using HWLP", "[freertos]") +{ + /* Create two tasks that are on the same core and use the same FPU */ + TaskHandle_t unity_task_handle = xTaskGetCurrentTaskHandle(); + TaskHandle_t tasks[2]; + hwlp_params_t params[2] = { + { .count = 1024, .main = unity_task_handle }, + { .count = 2048, .main = unity_task_handle }, + }; + + xTaskCreatePinnedToCore(calculation, "Task1", 2048, params + 0, CONFIG_UNITY_FREERTOS_PRIORITY + 1, &tasks[0], 1); + xTaskCreatePinnedToCore(calculation, "Task2", 2048, params + 1, CONFIG_UNITY_FREERTOS_PRIORITY + 1, &tasks[1], 1); + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); +} + +#endif /* CONFIG_FREERTOS_NUMBER_OF_CORES > 1 */ + +#endif // SOC_CPU_HAS_HWLOOP diff --git a/components/freertos/test_apps/freertos/port/test_hwlp_routines.S b/components/freertos/test_apps/freertos/port/test_hwlp_routines.S new file mode 100644 index 000000000000..80bd95577647 --- /dev/null +++ b/components/freertos/test_apps/freertos/port/test_hwlp_routines.S @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" +#include "soc/soc_caps.h" + +#if SOC_CPU_HAS_HWLOOP + + .text + .align 4 + +/** + * @brief Perform a hardware loop with a given number of iterations + * + * @param a0 Number of iterations + */ + .global use_hwlp + .type use_hwlp, @function +use_hwlp: + /* The toolchain doesn't support HWLP instructions yet, manually set it up */ + la a2, start + csrw 0x7c6, a2 + la a2, end + csrw 0x7c7, a2 + csrw 0x7c8, a0 + li a1, 0 + /* Hardware loops must have at least 8 32-bit instructions or 16 16-bit instructions */ +start: + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 + addi a1, a1, 1 +end: + addi a1, a1, 1 + mv a0, a1 + ret + .size use_hwlp, .-use_hwlp + +#endif /* SOC_CPU_HAS_HWLOOP */ diff --git a/components/freertos/test_apps/freertos/port/test_pie_in_task.c b/components/freertos/test_apps/freertos/port/test_pie_in_task.c new file mode 100644 index 000000000000..aa9bcf658e5d --- /dev/null +++ b/components/freertos/test_apps/freertos/port/test_pie_in_task.c @@ -0,0 +1,258 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#include "soc/soc_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "unity.h" +#include "test_utils.h" + +/* PIE instructions set is currently only supported in GCC compiler */ +#if SOC_CPU_HAS_PIE + +/** + * @brief Performs the signed sum of two 4-word vectors using the PIE. + * + * @param a First vector + * @param b Second vector + * @param dst Destination to store the sum + */ +void pie_vector_signed_add(const int32_t a[4], const int32_t b[4], int32_t dst[4]); + +/* ------------------------------------------------------------------------------------------------------------------ */ + +typedef struct { + int32_t cst; + TaskHandle_t main; + SemaphoreHandle_t sem; +} pie_params_t; + +/* +Test PIE usage from a task context + +Purpose: + - Test that the PIE can be used from a task context + - Test that PIE context is properly saved and restored + - Test that PIE context is cleaned up on task deletion by running multiple iterations +Procedure: + - Create TEST_PINNED_NUM_TASKS tasks pinned to each core + - Start each task + - Each task updates a float variable and then blocks (to allow other tasks to run thus forcing the a PIE context + save and restore). + - Delete each task + - Repeat test for TEST_PINNED_NUM_ITERS iterations +Expected: + - Correct float value calculated by each task + - Each task cleans up its PIE context on deletion +*/ + +#define TEST_PINNED_NUM_TASKS 3 +#define TEST_PINNED_NUM_ITERS 5 + +static void pinned_task(void *arg) +{ + pie_params_t *param = (pie_params_t*) arg; + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + int32_t constant = 42 * param->cst; + int32_t a[4] = { constant, constant, constant, constant }; + int32_t b[4] = { 10, 20, 30, 40 }; + int32_t dst[4] = { 0 }; + + pie_vector_signed_add(a, b, dst); + + for (int i = 0; i < sizeof(a) / sizeof(uint32_t); i++) { + TEST_ASSERT_EQUAL(dst[i], a[i] + b[i]); + } + + // Indicate done and wait to be deleted + xSemaphoreGive((SemaphoreHandle_t)param->sem); + vTaskSuspend(NULL); +} + +TEST_CASE("PIE: Usage in task", "[freertos]") +{ + SemaphoreHandle_t done_sem = xSemaphoreCreateCounting(CONFIG_FREERTOS_NUMBER_OF_CORES * TEST_PINNED_NUM_TASKS, 0); + TEST_ASSERT_NOT_EQUAL(NULL, done_sem); + + for (int iter = 0; iter < TEST_PINNED_NUM_ITERS; iter++) { + TaskHandle_t task_handles[CONFIG_FREERTOS_NUMBER_OF_CORES][TEST_PINNED_NUM_TASKS]; + pie_params_t params[CONFIG_FREERTOS_NUMBER_OF_CORES][TEST_PINNED_NUM_TASKS]; + + // Create test tasks for each core + for (int i = 0; i < CONFIG_FREERTOS_NUMBER_OF_CORES; i++) { + for (int j = 0; j < TEST_PINNED_NUM_TASKS; j++) { + params[i][j] = (pie_params_t) { + .cst = i + j + 1, + .sem = done_sem, + }; + TEST_ASSERT_EQUAL(pdTRUE, xTaskCreatePinnedToCore(pinned_task, "task", 4096, (void *) ¶ms[i][j], UNITY_FREERTOS_PRIORITY + 1, &task_handles[i][j], i)); + } + } + + // Start the created tasks + for (int i = 0; i < CONFIG_FREERTOS_NUMBER_OF_CORES; i++) { + for (int j = 0; j < TEST_PINNED_NUM_TASKS; j++) { + xTaskNotifyGive(task_handles[i][j]); + } + } + + // Wait for the tasks to complete + for (int i = 0; i < CONFIG_FREERTOS_NUMBER_OF_CORES * TEST_PINNED_NUM_TASKS; i++) { + xSemaphoreTake(done_sem, portMAX_DELAY); + } + + // Delete the tasks + for (int i = 0; i < CONFIG_FREERTOS_NUMBER_OF_CORES; i++) { + for (int j = 0; j < TEST_PINNED_NUM_TASKS; j++) { + vTaskDelete(task_handles[i][j]); + } + } + + vTaskDelay(10); // Short delay to allow idle task to be free task memory and FPU contexts + } + + vSemaphoreDelete(done_sem); +} + +/* ------------------------------------------------------------------------------------------------------------------ */ + +/* +Test PIE usage will pin an unpinned task + +Purpose: + - Test that unpinned tasks are automatically pinned to the current core on the task's first use of the PIE + - Test that PIE context is cleaned up on task deletion by running multiple iterations +Procedure: + - Create an unpinned task + - Task disables scheduling/preemption to ensure that it does not switch cores + - Task uses the PIE + - Task checks its core affinity after PIE usage + - Task deletes itself + - Repeat test for TEST_UNPINNED_NUM_ITERS iterations +Expected: + - Task remains unpinned until its first usage of the PIE + - The task becomes pinned to the current core after first use of the PIE + - Each task cleans up its PIE context on deletion +*/ + +#if CONFIG_FREERTOS_NUMBER_OF_CORES > 1 + +#define TEST_UNPINNED_NUM_ITERS 5 + +static void unpinned_task(void *arg) +{ + // Disable scheduling/preemption to make sure current core ID doesn't change +#if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) ) + vTaskPreemptionDisable(NULL); +#else + vTaskSuspendAll(); +#endif + BaseType_t cur_core_num = xPortGetCoreID(); + // Check that the task is unpinned +#if !CONFIG_FREERTOS_UNICORE +#if CONFIG_FREERTOS_SMP + TEST_ASSERT_EQUAL(tskNO_AFFINITY, vTaskCoreAffinityGet(NULL)); +#else + TEST_ASSERT_EQUAL(tskNO_AFFINITY, xTaskGetCoreID(NULL)); +#endif +#endif // !CONFIG_FREERTOS_UNICORE + + int32_t a[4] = { 0, 1, 2, 3}; + int32_t b[4] = { 111, 222, 333, 444 }; + int32_t dst[4] = { 0 }; + + pie_vector_signed_add(a, b, dst); + + for (int i = 0; i < sizeof(a) / sizeof(uint32_t); i++) { + TEST_ASSERT_EQUAL(dst[i], a[i] + b[i]); + } + +#if !CONFIG_FREERTOS_UNICORE +#if CONFIG_FREERTOS_SMP + TEST_ASSERT_EQUAL(1 << cur_core_num, vTaskCoreAffinityGet(NULL)); +#else + TEST_ASSERT_EQUAL(cur_core_num, xTaskGetCoreID(NULL)); +#endif +#endif // !CONFIG_FREERTOS_UNICORE + // Re-enable scheduling/preemption +#if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) ) + vTaskPreemptionEnable(NULL); +#else + xTaskResumeAll(); +#endif + + // Indicate done and self delete + xTaskNotifyGive((TaskHandle_t)arg); + vTaskDelete(NULL); +} + +TEST_CASE("PIE: Usage in unpinned task", "[freertos]") +{ + TaskHandle_t unity_task_handle = xTaskGetCurrentTaskHandle(); + for (int iter = 0; iter < TEST_UNPINNED_NUM_ITERS; iter++) { + // Create unpinned task + xTaskCreate(unpinned_task, "unpin", 4096, (void *)unity_task_handle, UNITY_FREERTOS_PRIORITY + 1, NULL); + // Wait for task to complete + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + vTaskDelay(10); // Short delay to allow task memory to be freed + } +} + +/** + * @brief Function performing some simple calculation using the PIE coprocessor. + * The goal is to be preempted by a task that also uses the PIE on the same core. + */ +static void pie_calculation(void* arg) +{ + pie_params_t* p = (pie_params_t*) arg; + const int32_t cst = p->cst; + int32_t a[4] = { cst, cst, cst, cst }; + int32_t dst[4] = { 0 }; + + for (int i = 0; i < 10; i++) { + pie_vector_signed_add(a, dst, dst); + + /* Give some time to the other to interrupt us before checking `f` value */ + esp_rom_delay_us(1000); + + /* Using TEST_ASSERT_TRUE triggers a stack overflow, make sure the sign is still correct */ + assert((dst[0] < 0 && cst < 0) || (dst[0] > 0 && cst > 0)); + + /* Give the hand back to FreeRTOS to avoid any watchdog error */ + vTaskDelay(2); + } + + /* Make sure the result is correct */ + assert((dst[0] * cst == 10)); + + xTaskNotifyGive(p->main); + vTaskDelete(NULL); +} + +TEST_CASE("PIE: Unsolicited context switch between tasks using the PIE", "[freertos]") +{ + /* Create two tasks that are on the same core and use the same FPU */ + TaskHandle_t unity_task_handle = xTaskGetCurrentTaskHandle(); + TaskHandle_t tasks[2]; + pie_params_t params[2] = { + { .cst = 1, .main = unity_task_handle }, + { .cst = -1, .main = unity_task_handle }, + }; + + xTaskCreatePinnedToCore(pie_calculation, "Task1", 2048, params + 0, UNITY_FREERTOS_PRIORITY + 1, &tasks[0], 1); + xTaskCreatePinnedToCore(pie_calculation, "Task2", 2048, params + 1, UNITY_FREERTOS_PRIORITY + 1, &tasks[1], 1); + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); +} + +#endif /* CONFIG_FREERTOS_NUMBER_OF_CORES > 1 */ + +#endif /* SOC_CPU_HAS_PIE */ diff --git a/components/freertos/test_apps/freertos/port/test_pie_routines.S b/components/freertos/test_apps/freertos/port/test_pie_routines.S new file mode 100644 index 000000000000..7de3a4da28a9 --- /dev/null +++ b/components/freertos/test_apps/freertos/port/test_pie_routines.S @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" +#include "soc/soc_caps.h" + +/* PIE instructions set is currently only supported in GCC compiler */ +#if SOC_CPU_HAS_PIE + + .text + .align 4 + +/** + * @brief Performs the unsigned sum of two 4-word vectors using the PIE. + * + * @param a0 First vector + * @param a1 Second vector + * @param a2 Destination to store the sum + */ + .type pie_vector_unsigned_add, @function + .global pie_vector_unsigned_add +pie_vector_unsigned_add: + esp.vld.128.ip q0, a0, 0 + esp.vld.128.ip q1, a1, 0 + esp.vadd.u32 q2, q0, q1 + esp.vst.128.ip q2, a2, 0 + ret + .size pie_vector_unsigned_add, .-pie_vector_unsigned_add + + +/** + * @brief Performs the signed sum of two 4-word vectors using the PIE. + * + * @param a0 First vector + * @param a1 Second vector + * @param a2 Destination to store the sum + */ + .type pie_vector_signed_add, @function + .global pie_vector_signed_add +pie_vector_signed_add: + esp.vld.128.ip q0, a0, 0 + esp.vld.128.ip q1, a1, 0 + esp.vadd.s32 q2, q0, q1 + esp.vst.128.ip q2, a2, 0 + ret + .size pie_vector_signed_add, .-pie_vector_signed_add + +#endif /* SOC_CPU_HAS_PIE */ diff --git a/components/freertos/test_apps/freertos/port/test_pie_watermark.c b/components/freertos/test_apps/freertos/port/test_pie_watermark.c new file mode 100644 index 000000000000..075b40b34f5d --- /dev/null +++ b/components/freertos/test_apps/freertos/port/test_pie_watermark.c @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#include "soc/soc_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "unity.h" + +#define TASKS_STATUS_ARRAY_LEN 16 + +/** + * On RISC-V targets that have coprocessors, the contexts are saved at the lowest address of the stack, + * which can lead to wrong stack watermark calculation in FreeRTOS in theory. + * As such, the port layer of FreeRTOS will adjust the lowest address of the stack when a coprocessor + * context is saved. + */ +#if SOC_CPU_HAS_PIE + +/** + * @brief Performs the signed sum of two 4-word vectors using the PIE. + * + * @param a First vector + * @param b Second vector + * @param dst Destination to store the sum + */ +void pie_vector_unsigned_add(const uint32_t a[4], const uint32_t b[4], uint32_t dst[4]); + +static void other_task(void* arg) +{ + uint32_t a[4] = { 1, 2, 3, 4}; + uint32_t b[4] = { 42, 43, 44, 45}; + uint32_t dst[4] = { 0 }; + const TaskHandle_t main_task = (TaskHandle_t) arg; + + /* This task must also use the PIE coprocessor to force a PIE context flush on the main task */ + pie_vector_unsigned_add(a, b, dst); + + xTaskNotifyGive(main_task); + vTaskDelete(NULL); +} + +TEST_CASE("PIE: Context save does not affect stack watermark", "[freertos]") +{ + /* Setup some random values */ + uint32_t a[4] = { 0x3f00ffff, 0xffe10045, 0xffe10096, 0x42434546}; + uint32_t b[4] = { 0x42, 0xbb43, 0x6644, 0x845}; + uint32_t dst[4] = { 0 }; + + TaskHandle_t pvCreatedTask; + /* Force the FreeRTOS port layer to store a PIE context in the current task. + * So let's use the PIE and make sure another task, on the SAME CORE, also uses it */ + const int core_id = xPortGetCoreID(); + const TaskHandle_t current_handle = xTaskGetCurrentTaskHandle(); + + /* Get the current stack watermark */ + const UBaseType_t before_watermark = uxTaskGetStackHighWaterMark(current_handle); + + /* Use the PIE unit, the context will NOT be flushed until another task starts using it */ + pie_vector_unsigned_add(a, b, dst); + + xTaskCreatePinnedToCore(other_task, + "OtherTask", + 2048, + (void*) current_handle, + CONFIG_UNITY_FREERTOS_PRIORITY - 1, + &pvCreatedTask, + core_id); + + vTaskDelay(10); + + /* Wait for other task to complete */ + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + const UBaseType_t after_watermark = uxTaskGetStackHighWaterMark(current_handle); + + /* The current task has seen a PIE registers context save, so we have at least 8 16-byte registers saved on the + * stack, which represents 128 bytes. In practice, it may be very different, for example a call to printf would + * result is more than 1KB of additional stack space used. So let's just make sure that the watermark is bigger + * than 50% of the former watermark. */ + TEST_ASSERT_TRUE(after_watermark > before_watermark / 2); +} + +#endif // SOC_CPU_HAS_PIE diff --git a/components/freertos/test_apps/freertos/pytest_freertos.py b/components/freertos/test_apps/freertos/pytest_freertos.py index 6baa6ba7811b..d21d9dad708c 100644 --- a/components/freertos/test_apps/freertos/pytest_freertos.py +++ b/components/freertos/test_apps/freertos/pytest_freertos.py @@ -39,3 +39,13 @@ def test_task_notify_wait_too_high_index_fails(dut: Dut) -> None: dut.expect('assert failed: xTaskGenericNotifyWait', timeout=5) dut.expect('uxIndexToWait < [0-9]+', timeout=5) dut.expect_exact('Rebooting...') + + +@pytest.mark.supported_targets +@pytest.mark.generic +@pytest.mark.parametrize('config', ['default'], indirect=True) +def test_port_must_assert_in_isr(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests.') + dut.write('\"port must assert if in ISR context\"') + dut.expect('assert failed: vPortAssertIfInISR', timeout=5) + dut.expect_exact('Rebooting...') diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index dea07390ad32..b00cdad58ca5 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -7,6 +7,12 @@ set(includes "platform_port/include") # because of the "include_next" directive used by the efuse_hal.h if(NOT ${target} STREQUAL "linux") list(APPEND includes "${target}/include") + + if(CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION) + list(APPEND includes "${target}/beta3/include") + elseif(CONFIG_IDF_TARGET_ESP32C5_MP_VERSION) + list(APPEND includes "${target}/mp/include") + endif() endif() list(APPEND includes "include") @@ -217,6 +223,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "jpeg_hal.c") endif() + if(CONFIG_SOC_PPA_SUPPORTED) + list(APPEND srcs "ppa_hal.c") + endif() + if(CONFIG_SOC_GPSPI_SUPPORTED) list(APPEND srcs "spi_hal.c" @@ -256,6 +266,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "ds_hal.c") endif() + if(CONFIG_SOC_LCDCAM_CAM_SUPPORTED) + list(APPEND srcs "cam_hal.c") + endif() + if(CONFIG_SOC_USB_SERIAL_JTAG_SUPPORTED) list(APPEND srcs "usb_serial_jtag_hal.c") endif() @@ -266,26 +280,27 @@ if(NOT BOOTLOADER_BUILD) "usb_wrap_hal.c") endif() + if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED) + list(APPEND srcs "${target}/touch_sensor_hal.c") + if(CONFIG_SOC_TOUCH_SENSOR_VERSION LESS 3) + list(APPEND srcs "touch_sensor_hal.c") + endif() + endif() + if(${target} STREQUAL "esp32") list(APPEND srcs - "touch_sensor_hal.c" - "esp32/touch_sensor_hal.c" "esp32/gpio_hal_workaround.c") endif() if(${target} STREQUAL "esp32s2") list(APPEND srcs - "touch_sensor_hal.c" "xt_wdt_hal.c" - "esp32s2/cp_dma_hal.c" - "esp32s2/touch_sensor_hal.c") + "esp32s2/cp_dma_hal.c") endif() if(${target} STREQUAL "esp32s3") list(APPEND srcs - "touch_sensor_hal.c" "xt_wdt_hal.c" - "esp32s3/touch_sensor_hal.c" "esp32s3/rtc_cntl_hal.c") endif() diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index bb62c05de93d..1688491f2dbe 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -74,6 +74,10 @@ void adc_hal_digi_init(adc_hal_dma_ctx_t *hal) void adc_hal_digi_deinit() { +#if ADC_LL_POWER_MANAGE_SUPPORTED + adc_ll_set_power_manage(ADC_UNIT_1, ADC_LL_POWER_SW_OFF); + adc_ll_set_power_manage(ADC_UNIT_2, ADC_LL_POWER_SW_OFF); +#endif adc_ll_digi_trigger_disable(); adc_ll_digi_dma_disable(); adc_ll_digi_clear_pattern_table(ADC_UNIT_1); @@ -144,6 +148,9 @@ void adc_hal_digi_controller_config(adc_hal_dma_ctx_t *hal, const adc_hal_digi_c for (int i = 0; i < cfg->adc_pattern_len; i++) { adc_ll_digi_set_pattern_table(pattern_both, i, cfg->adc_pattern[i]); } +#if ADC_LL_POWER_MANAGE_SUPPORTED + adc_ll_set_power_manage(0, ADC_LL_POWER_SW_ON); +#endif #elif (SOC_ADC_DIGI_CONTROLLER_NUM >= 2) uint32_t adc1_pattern_idx = 0; @@ -154,9 +161,15 @@ void adc_hal_digi_controller_config(adc_hal_dma_ctx_t *hal, const adc_hal_digi_c for (int i = 0; i < cfg->adc_pattern_len; i++) { if (cfg->adc_pattern[i].unit == ADC_UNIT_1) { +#if ADC_LL_POWER_MANAGE_SUPPORTED + adc_ll_set_power_manage(ADC_UNIT_1, ADC_LL_POWER_SW_ON); +#endif adc_ll_digi_set_pattern_table(ADC_UNIT_1, adc1_pattern_idx, cfg->adc_pattern[i]); adc1_pattern_idx++; } else if (cfg->adc_pattern[i].unit == ADC_UNIT_2) { +#if ADC_LL_POWER_MANAGE_SUPPORTED + adc_ll_set_power_manage(ADC_UNIT_2, ADC_LL_POWER_SW_ON); +#endif adc_ll_digi_set_pattern_table(ADC_UNIT_2, adc2_pattern_idx, cfg->adc_pattern[i]); adc2_pattern_idx++; } else { diff --git a/components/hal/adc_oneshot_hal.c b/components/hal/adc_oneshot_hal.c index 1a5b56da4ebc..c74079d464ee 100644 --- a/components/hal/adc_oneshot_hal.c +++ b/components/hal/adc_oneshot_hal.c @@ -142,7 +142,7 @@ bool adc_oneshot_hal_convert(adc_oneshot_hal_ctx_t *hal, int *out_raw) } esp_rom_delay_us(read_delay_us); *out_raw = adc_oneshot_ll_get_raw_result(hal->unit); -#if (SOC_ADC_PERIPH_NUM == 2) +#if SOC_ADC_ARBITER_SUPPORTED if (hal->unit == ADC_UNIT_2) { valid = adc_oneshot_ll_raw_check_valid(ADC_UNIT_2, *out_raw); if (!valid) { diff --git a/components/hal/apm_hal.c b/components/hal/apm_hal.c index c57c7486a2fd..cb08dbde4858 100644 --- a/components/hal/apm_hal.c +++ b/components/hal/apm_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,50 @@ #include "hal/apm_ll.h" #include "hal/log.h" +#if CONFIG_IDF_TARGET_ESP32P4 +void apm_hal_hp_peri_access_enable(apm_ll_master_id_t master_id, apm_ll_hp_peri_t hp_peri, + apm_ll_secure_mode_t sec_mode, bool enable) +{ + apm_ll_hp_peri_access_enable(master_id, hp_peri, sec_mode, enable); +} + + +void apm_hal_lp_peri_access_enable(apm_ll_lp_peri_t lp_peri, bool enable) +{ + apm_ll_lp_peri_access_enable(lp_peri, enable); +} + +void apm_hal_peri_region_config(uint32_t regn_num, uint32_t regn_low_addr, uint32_t regn_high_addr) +{ + apm_ll_peri_region_config(regn_num, regn_low_addr, regn_high_addr); +} + +int apm_hal_peri_region_pms(apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode, + uint32_t regn_num, uint32_t regn_pms) +{ + return apm_ll_peri_region_pms(master_id, sec_mode, regn_num, regn_pms); +} + +int apm_hal_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable) +{ + return apm_ll_apm_ctrl_clk_gating_enable(apm_ctrl, enable); +} + +void apm_hal_dma_region_config(uint32_t regn_num, uint32_t regn_low_addr, uint32_t regn_high_addr) +{ + apm_ll_dma_region_set_low_address(regn_num, regn_low_addr); + apm_ll_dma_region_set_high_address(regn_num, regn_high_addr); +} + +void apm_hal_dma_region_pms(apm_hal_dma_region_config_data_t *pms_data) +{ + HAL_ASSERT(pms_data); + + apm_ll_dma_region_r_pms(pms_data->dma_master, pms_data->pms_r_mask); + apm_ll_dma_region_w_pms(pms_data->dma_master, pms_data->pms_w_mask); +} +#else + void apm_tee_hal_set_master_secure_mode(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode) { apm_tee_ll_set_master_secure_mode(apm_ctrl, master_id, sec_mode); @@ -129,3 +173,5 @@ esp_err_t apm_hal_apm_ctrl_get_int_src_num(apm_ctrl_path_t *apm_path) { return apm_ll_apm_ctrl_get_int_src_num(apm_path->apm_ctrl, apm_path->apm_m_path); } + +#endif //CONFIG_IDF_TARGET_ESP32P4 diff --git a/components/hal/cam_hal.c b/components/hal/cam_hal.c new file mode 100644 index 000000000000..101cf3bfcbe9 --- /dev/null +++ b/components/hal/cam_hal.c @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/cam_ll.h" +#include "hal/cam_hal.h" +#include "soc/soc_caps.h" +#include "soc/cam_periph.h" + +/** + * @brief Configure line number to trigger interrupt + * + * @param hal CAM object data pointer + * @param num line number + * + * @return None + */ +static void cam_hal_set_line_int_num(cam_hal_context_t *hal, uint32_t num) +{ + if (num > 0) { + cam_ll_enable_hs_line_int(hal->hw, 1); + cam_ll_set_line_int_num(hal->hw, num); + } else { + cam_ll_enable_hs_line_int(hal->hw, 0); + cam_ll_set_line_int_num(hal->hw, 0); + } +} + +/** + * @brief Configure V-SYNC filter threshold + * + * @param hal CAM object data pointer + * @param num V-SYNC filter threshold + * + * @return None + */ +static void cam_hal_set_vsync_filter_num(cam_hal_context_t *hal, uint32_t num) +{ + if (num > 0) { + cam_ll_enable_vsync_filter(hal->hw, 1); + cam_ll_set_vsync_filter_thres(hal->hw, num); + } else { + cam_ll_enable_vsync_filter(hal->hw, 0); + cam_ll_set_vsync_filter_thres(hal->hw, 0); + } +} + +/** + * @brief Initialize CAM hardware + * + * @param hal CAM object data pointer + * @param config CAM configuration + * + * @return None + */ +void cam_hal_init(cam_hal_context_t *hal, const cam_hal_config_t *config) +{ + memset(hal, 0, sizeof(cam_hal_context_t)); + + hal->hw = CAM_LL_GET_HW(0); + + cam_ll_enable_stop_signal(hal->hw, 0); + cam_ll_swap_dma_data_byte_order(hal->hw, config->byte_swap_en); + cam_ll_reverse_dma_data_bit_order(hal->hw, 0); + cam_ll_enable_vsync_generate_eof(hal->hw, 1); + + cam_hal_set_line_int_num(hal, 0); + cam_hal_set_vsync_filter_num(hal, 0); + + cam_ll_enable_invert_pclk(hal->hw, 0); + cam_ll_set_input_data_width(hal->hw, 8); + cam_ll_enable_invert_de(hal->hw, 0); + cam_ll_enable_invert_vsync(hal->hw, 0); + cam_ll_enable_invert_hsync(hal->hw, 0); + cam_ll_set_vh_de_mode(hal->hw, 0); // Disable vh_de mode default + cam_ll_enable_rgb_yuv_convert(hal->hw, 0); // bypass conv module default +} + +/** + * @brief De-initialize CAM hardware + * + * @note Stop stream before deinit + * @param hal CAM object data pointer + * + * @return None + */ +void cam_hal_deinit(cam_hal_context_t *hal) +{ + cam_ll_stop(hal->hw); + cam_ll_reset(hal->hw); + cam_ll_fifo_reset(hal->hw); +} + +/** + * @brief Start CAM to receive frame data + * + * @param hal CAM object data pointer + * + * @return None + */ +void cam_hal_start_streaming(cam_hal_context_t *hal) +{ + cam_ll_reset(hal->hw); + cam_ll_fifo_reset(hal->hw); + + cam_ll_start(hal->hw); +} + +/** + * @brief Stop CAM receiving frame data + * + * @param hal CAM object data pointer + * + * @return None + */ +void cam_hal_stop_streaming(cam_hal_context_t *hal) +{ + cam_ll_stop(hal->hw); +} diff --git a/components/hal/ecdsa_hal.c b/components/hal/ecdsa_hal.c index 552fb423af06..73302b1f43f1 100644 --- a/components/hal/ecdsa_hal.c +++ b/components/hal/ecdsa_hal.c @@ -9,7 +9,11 @@ #include "hal/ecdsa_hal.h" #include "hal/efuse_hal.h" -#ifdef SOC_KEY_MANAGER_SUPPORTED +#if CONFIG_IDF_TARGET_ESP32C5 +#include "soc/keymng_reg.h" +#endif + +#ifdef SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY #include "hal/key_mgr_hal.h" #endif @@ -19,16 +23,21 @@ static void configure_ecdsa_periph(ecdsa_hal_config_t *conf) { - if (conf->use_km_key == 0) { efuse_hal_set_ecdsa_key(conf->efuse_key_blk); -#if SOC_KEY_MANAGER_SUPPORTED - key_mgr_hal_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_EFUSE_KEY); + +#if CONFIG_IDF_TARGET_ESP32C5 + REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, 1); +#endif + +#if SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY + // Force Key Manager to use eFuse key for XTS-AES operation + key_mgr_ll_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_EFUSE_KEY); #endif } #if SOC_KEY_MANAGER_SUPPORTED else { - key_mgr_hal_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_OWN_KEY); + key_mgr_ll_set_key_usage(ESP_KEY_MGR_ECDSA_KEY, ESP_KEY_MGR_USE_OWN_KEY); } #endif diff --git a/components/hal/efuse_hal.c b/components/hal/efuse_hal.c index 68e06d530a8b..8c15849d8fc4 100644 --- a/components/hal/efuse_hal.c +++ b/components/hal/efuse_hal.c @@ -47,7 +47,7 @@ IRAM_ATTR bool efuse_hal_flash_encryption_enabled(void) return enabled; } -#if SOC_ECDSA_SUPPORTED +#if SOC_EFUSE_ECDSA_KEY void efuse_hal_set_ecdsa_key(int efuse_blk) { efuse_ll_set_ecdsa_key_blk(efuse_blk); diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index 08e93a0c6d04..8f412ea3d6ec 100644 --- a/components/hal/esp32/include/hal/adc_ll.h +++ b/components/hal/esp32/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,6 +31,7 @@ extern "C" { #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) +#define ADC_LL_RTC_GPIO_SUPPORTED (1) /*--------------------------------------------------------------- DMA @@ -229,7 +230,7 @@ static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t } /** - * Set pattern table lenth for digital controller. + * Set pattern table length for digital controller. * The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection, * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the * pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. @@ -564,6 +565,25 @@ static inline void adc_oneshot_ll_disable_all_unit(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + (void)enable; + //For compatibility +} + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + //For compatibility +} + /** * Set ADC module controller. * There are five SAR ADC controllers: diff --git a/components/hal/esp32/include/hal/emac_ll.h b/components/hal/esp32/include/hal/emac_ll.h index b66730acfff7..c858552fb271 100644 --- a/components/hal/esp32/include/hal/emac_ll.h +++ b/components/hal/esp32/include/hal/emac_ll.h @@ -437,6 +437,11 @@ static inline void emac_ll_recv_store_forward_enable(emac_dma_dev_t *dma_regs, b dma_regs->dmaoperation_mode.rx_store_forward = enable; } +static inline bool emac_ll_recv_store_forward_is_enabled(emac_dma_dev_t *dma_regs) +{ + return dma_regs->dmaoperation_mode.rx_store_forward; +} + static inline void emac_ll_flush_recv_frame_enable(emac_dma_dev_t *dma_regs, bool enable) { dma_regs->dmaoperation_mode.dis_flush_recv_frames = !enable; diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 20833e1ddb86..3839e39360c5 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -355,7 +355,7 @@ static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num) { - PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); + PIN_INPUT_ENABLE(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num]); } /** diff --git a/components/hal/esp32/include/hal/mmu_ll.h b/components/hal/esp32/include/hal/mmu_ll.h index 82212d12aed3..fd1171bb2950 100644 --- a/components/hal/esp32/include/hal/mmu_ll.h +++ b/components/hal/esp32/include/hal/mmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,9 @@ extern "C" { #endif #define MMU_LL_PSRAM_ENTRY_START_ID 1152 +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_MMU_PAGE_SIZE) +#define MMU_LL_END_DROM_ENTRY_ID (64 - 1) + /** * Convert MMU virtual address to linear address @@ -302,7 +305,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32/include/hal/rmt_ll.h b/components/hal/esp32/include/hal/rmt_ll.h index 97a9267fcdd0..147c6c089dbe 100644 --- a/components/hal/esp32/include/hal/rmt_ll.h +++ b/components/hal/esp32/include/hal/rmt_ll.h @@ -88,14 +88,33 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->conf_ch[0].conf0.mem_pd = enable; // Only conf0 register of channel0 has `mem_pd` + (void)dev; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->conf_ch[0].conf0.mem_pd = 1; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->conf_ch[0].conf0.mem_pd = 0; } /** @@ -120,7 +139,7 @@ static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable) * @param divider_numerator Numerator part of the divider */ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src, - uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) + uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) { (void)divider_integral; (void)divider_denominator; @@ -485,7 +504,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e * @brief Clear RMT interrupt status by mask * * @param dev Peripheral instance address - * @param mask Interupt status mask + * @param mask Interrupt status mask */ __attribute__((always_inline)) static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask) @@ -631,7 +650,7 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->conf_ch[channel].conf1.idle_out_lv; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { // Only conf0 register of channel0 has `mem_pd` return dev->conf_ch[0].conf0.mem_pd; diff --git a/components/hal/esp32/include/hal/sdio_slave_ll.h b/components/hal/esp32/include/hal/sdio_slave_ll.h index 2c94f217e78d..aa0a001ca648 100644 --- a/components/hal/esp32/include/hal/sdio_slave_ll.h +++ b/components/hal/esp32/include/hal/sdio_slave_ll.h @@ -17,6 +17,7 @@ #pragma once #include "hal/sdio_slave_types.h" +#include "hal/misc.h" #include "soc/slc_struct.h" #include "soc/slc_reg.h" #include "soc/host_struct.h" @@ -514,7 +515,7 @@ static inline void sdio_slave_ll_host_send_int(slc_dev_t *slc, const sdio_slave_ { //use registers in SLC to trigger, rather than write HOST registers directly //other interrupts than tohost interrupts are not supported yet - slc->intvec_tohost.slc0_intvec = (*mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(slc->intvec_tohost, slc0_intvec, *mask); } /** diff --git a/components/hal/esp32/include/hal/touch_sensor_ll.h b/components/hal/esp32/include/hal/touch_sensor_ll.h index c12200fc5235..8d1c945024b1 100644 --- a/components/hal/esp32/include/hal/touch_sensor_ll.h +++ b/components/hal/esp32/include/hal/touch_sensor_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -229,6 +229,7 @@ static inline void touch_ll_get_tie_option(touch_pad_t touch_num, touch_tie_opt_ * * @param mode FSM mode. */ +__attribute__((always_inline)) static inline void touch_ll_set_fsm_mode(touch_fsm_mode_t mode) { SENS.sar_touch_ctrl2.touch_start_fsm_en = 1; @@ -264,6 +265,7 @@ static inline void touch_ll_start_fsm(void) * * @param mode FSM mode. */ +__attribute__((always_inline)) static inline void touch_ll_stop_fsm(void) { RTCCNTL.state0.touch_slp_timer_en = 0; @@ -497,7 +499,8 @@ static inline uint32_t touch_ll_read_raw_data(touch_pad_t touch_num) * @return * - If touch sensors measure done. */ -static inline bool touch_ll_meas_is_done(void) +__attribute__((always_inline)) +static inline bool touch_ll_is_measure_done(void) { return (bool)SENS.sar_touch_ctrl2.touch_meas_done; } diff --git a/components/hal/esp32/include/hal/uart_ll.h b/components/hal/esp32/include/hal/uart_ll.h index 218fd52ccd99..02134517e7a7 100644 --- a/components/hal/esp32/include/hal/uart_ll.h +++ b/components/hal/esp32/include/hal/uart_ll.h @@ -312,7 +312,7 @@ FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_ * * @param hw Beginning address of the peripheral registers. * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return None */ @@ -535,7 +535,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -600,7 +600,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -894,7 +894,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32c2/include/hal/adc_ll.h b/components/hal/esp32c2/include/hal/adc_ll.h index 9427b0e4c421..2e234d740c0b 100644 --- a/components/hal/esp32c2/include/hal/adc_ll.h +++ b/components/hal/esp32c2/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/misc.h" #include "hal/assert.h" #include "hal/adc_types.h" @@ -286,6 +287,29 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.apb_saradc_clk_en = enable; +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.apb_saradc_rst = 1; + SYSTEM.perip_rst_en0.apb_saradc_rst = 0; +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32c2/include/hal/ecc_ll.h b/components/hal/esp32c2/include/hal/ecc_ll.h index 2fcca34ea0f8..58ddd82dd002 100644 --- a/components/hal/esp32c2/include/hal/ecc_ll.h +++ b/components/hal/esp32c2/include/hal/ecc_ll.h @@ -49,6 +49,9 @@ static inline void ecc_ll_reset_register(void) /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance #define ecc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; ecc_ll_reset_register(__VA_ARGS__) +static inline void ecc_ll_power_up(void) {} +static inline void ecc_ll_power_down(void) {} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32c2/include/hal/gdma_ll.h b/components/hal/esp32c2/include/hal/gdma_ll.h index 6bf41c6a50c4..37d7179c689b 100644 --- a/components/hal/esp32c2/include/hal/gdma_ll.h +++ b/components/hal/esp32c2/include/hal/gdma_ll.h @@ -48,6 +48,7 @@ extern "C" { #define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number #define GDMA_LL_AHB_DESC_ALIGNMENT 4 +#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 ///////////////////////////////////// Common ///////////////////////////////////////// diff --git a/components/hal/esp32c2/include/hal/mmu_ll.h b/components/hal/esp32c2/include/hal/mmu_ll.h index 8f1429692b51..15ebd45c6fcf 100644 --- a/components/hal/esp32c2/include/hal/mmu_ll.h +++ b/components/hal/esp32c2/include/hal/mmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,9 @@ extern "C" { #endif +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_MMU_PAGE_SIZE) +#define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1) + /** * Convert MMU virtual address to linear address * @@ -263,7 +266,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32c2/include/hal/uart_ll.h b/components/hal/esp32c2/include/hal/uart_ll.h index 67eda746fe25..7c5e3d12ed01 100644 --- a/components/hal/esp32c2/include/hal/uart_ll.h +++ b/components/hal/esp32c2/include/hal/uart_ll.h @@ -339,7 +339,7 @@ FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_ * * @param hw Beginning address of the peripheral registers. * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return None */ @@ -518,7 +518,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -583,7 +583,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -881,7 +881,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index b780bcebd5ba..779312f4fa9f 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -15,6 +15,7 @@ #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/misc.h" #include "hal/assert.h" #include "hal/adc_types.h" @@ -560,6 +561,29 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.reg_apb_saradc_clk_en = enable; +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.reg_apb_saradc_rst = 1; + SYSTEM.perip_rst_en0.reg_apb_saradc_rst = 0; +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32c3/include/hal/gdma_ll.h b/components/hal/esp32c3/include/hal/gdma_ll.h index a6cb889b7dd2..e11d1fbc49e6 100644 --- a/components/hal/esp32c3/include/hal/gdma_ll.h +++ b/components/hal/esp32c3/include/hal/gdma_ll.h @@ -48,6 +48,7 @@ extern "C" { #define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number #define GDMA_LL_AHB_DESC_ALIGNMENT 4 +#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 ///////////////////////////////////// Common ///////////////////////////////////////// diff --git a/components/hal/esp32c3/include/hal/mmu_ll.h b/components/hal/esp32c3/include/hal/mmu_ll.h index c7618366a936..5fe5fb363c90 100644 --- a/components/hal/esp32c3/include/hal/mmu_ll.h +++ b/components/hal/esp32c3/include/hal/mmu_ll.h @@ -19,6 +19,8 @@ extern "C" { #endif +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - 0x10000) +#define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1) /** * Convert MMU virtual address to linear address * @@ -230,7 +232,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32c3/include/hal/rmt_ll.h b/components/hal/esp32c3/include/hal/rmt_ll.h index b1d8acdc75d9..c76924fedf28 100644 --- a/components/hal/esp32c3/include/hal/rmt_ll.h +++ b/components/hal/esp32c3/include/hal/rmt_ll.h @@ -87,15 +87,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -427,7 +448,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, * * @param dev Peripheral instance address * @param channel RMT TX channel number - * @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data + * @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data */ static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable) { @@ -658,7 +679,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e * @brief Clear RMT interrupt status by mask * * @param dev Peripheral instance address - * @param mask Interupt status mask + * @param mask Interrupt status mask */ __attribute__((always_inline)) static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask) @@ -812,12 +833,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->tx_conf[channel].idle_out_lv; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32c3/include/hal/uart_ll.h b/components/hal/esp32c3/include/hal/uart_ll.h index 9b83168323ed..f9f00ad85a8c 100644 --- a/components/hal/esp32c3/include/hal/uart_ll.h +++ b/components/hal/esp32c3/include/hal/uart_ll.h @@ -342,7 +342,7 @@ FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_ * * @param hw Beginning address of the peripheral registers. * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return None */ @@ -521,7 +521,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -586,7 +586,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -884,7 +884,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h index 118302962181..f57b378e7f45 100644 --- a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h @@ -16,6 +16,7 @@ /* ----------------------------- Macros & Types ----------------------------- */ #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask +#define USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL (1) // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging diff --git a/components/hal/esp32c5/beta3/include/hal/gdma_beta3_ll.h b/components/hal/esp32c5/beta3/include/hal/gdma_beta3_ll.h new file mode 100644 index 000000000000..5a9260eea198 --- /dev/null +++ b/components/hal/esp32c5/beta3/include/hal/gdma_beta3_ll.h @@ -0,0 +1,630 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include /* Required for NULL constant */ +#include +#include +#include "soc/soc_caps.h" +#include "hal/gdma_types.h" +#include "soc/gdma_struct.h" +#include "soc/gdma_reg.h" +#include "soc/soc_etm_source.h" +#include "soc/pcr_struct.h" +#include "soc/retention_periph_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 << (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) << pair_id) + +#define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL) + +#define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5] + +#define GDMA_LL_RX_EVENT_MASK (0x7F) +#define GDMA_LL_TX_EVENT_MASK (0x3F) + +// any "dummy" peripheral ID can be used for M2M mode +#define GDMA_LL_M2M_FREE_PERIPH_ID_MASK (0xFC32) +#define GDMA_LL_INVALID_PERIPH_ID (0x3F) + +#define GDMA_LL_EVENT_TX_FIFO_UDF (1<<5) +#define GDMA_LL_EVENT_TX_FIFO_OVF (1<<4) +#define GDMA_LL_EVENT_RX_FIFO_UDF (1<<6) +#define GDMA_LL_EVENT_RX_FIFO_OVF (1<<5) +#define GDMA_LL_EVENT_TX_TOTAL_EOF (1<<3) +#define GDMA_LL_EVENT_RX_DESC_EMPTY (1<<4) +#define GDMA_LL_EVENT_TX_DESC_ERROR (1<<2) +#define GDMA_LL_EVENT_RX_DESC_ERROR (1<<3) +#define GDMA_LL_EVENT_TX_EOF (1<<1) +#define GDMA_LL_EVENT_TX_DONE (1<<0) +#define GDMA_LL_EVENT_RX_ERR_EOF (1<<2) +#define GDMA_LL_EVENT_RX_SUC_EOF (1<<1) +#define GDMA_LL_EVENT_RX_DONE (1<<0) + +#define GDMA_LL_AHB_GROUP_START_ID 0 // AHB GDMA group ID starts from 0 +#define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups +#define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group + +#define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ + (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH0, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH1, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH2, \ + }}}[group][chan][event] + +#define GDMA_LL_RX_ETM_EVENT_TABLE(group, chan, event) \ + (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH0, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH1, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH2, \ + }}}[group][chan][event] + +#define GDMA_LL_TX_ETM_TASK_TABLE(group, chan, task) \ + (uint32_t[1][3][GDMA_ETM_TASK_MAX]){{{ \ + [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH0, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH1, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH2, \ + }}}[group][chan][task] + +#define GDMA_LL_RX_ETM_TASK_TABLE(group, chan, task) \ + (uint32_t[1][3][GDMA_ETM_TASK_MAX]){{{ \ + [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH0, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH1, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH2, \ + }}}[group][chan][task] + +// Workaround for C5-beta3 only, it can not vectorized channels into an array in gdma_struct.h +#define GDMA_LL_CHANNEL_GET_REG_ADDR(dev, ch) ((volatile gdma_chn_reg_t*[]){&dev->channel0, &dev->channel1, &dev->channel2}[(ch)]) + +#define GDMA_LL_AHB_DESC_ALIGNMENT 4 + +///////////////////////////////////// Common ///////////////////////////////////////// + +/** + * @brief Enable the bus clock for the DMA module + */ +static inline void gdma_ll_enable_bus_clock(int group_id, bool enable) +{ + (void)group_id; + PCR.gdma_conf.gdma_clk_en = enable; +} + +/** + * @brief Reset the DMA module + */ +static inline void gdma_ll_reset_register(int group_id) +{ + (void)group_id; + PCR.gdma_conf.gdma_rst_en = 1; + PCR.gdma_conf.gdma_rst_en = 0; +} + +/** + * @brief Force enable register clock + */ +static inline void gdma_ll_force_enable_reg_clock(gdma_dev_t *dev, bool enable) +{ + dev->misc_conf.clk_en = enable; +} + +///////////////////////////////////// RX ///////////////////////////////////////// +/** + * @brief Get DMA RX channel interrupt status word + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_rx_get_interrupt_status(gdma_dev_t *dev, uint32_t channel, bool raw) +{ + if (raw) { + return dev->in_intr[channel].raw.val; + } else { + return dev->in_intr[channel].st.val; + } +} + +/** + * @brief Enable DMA RX channel interrupt + */ +static inline void gdma_ll_rx_enable_interrupt(gdma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable) +{ + if (enable) { + dev->in_intr[channel].ena.val |= mask; + } else { + dev->in_intr[channel].ena.val &= ~mask; + } +} + +/** + * @brief Clear DMA RX channel interrupt + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_clear_interrupt_status(gdma_dev_t *dev, uint32_t channel, uint32_t mask) +{ + dev->in_intr[channel].clr.val = mask; +} + +/** + * @brief Get DMA RX channel interrupt status register address + */ +static inline volatile void *gdma_ll_rx_get_interrupt_status_reg(gdma_dev_t *dev, uint32_t channel) +{ + return (volatile void *)(&dev->in_intr[channel].st); +} + +/** + * @brief Enable DMA RX channel to check the owner bit in the descriptor, disabled by default + */ +static inline void gdma_ll_rx_enable_owner_check(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_conf1.in_check_owner = enable; +} + +/** + * @brief Enable DMA RX channel burst reading data, disabled by default + */ +static inline void gdma_ll_rx_enable_data_burst(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_conf0.in_data_burst_en = enable; +} + +/** + * @brief Enable DMA RX channel burst reading descriptor link, disabled by default + */ +static inline void gdma_ll_rx_enable_descriptor_burst(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_conf0.indscr_burst_en = enable; +} + +/** + * @brief Reset DMA RX channel FSM and FIFO pointer + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_reset_channel(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_conf0.in_rst = 1; + ch->in.in_conf0.in_rst = 0; +} + +/** + * @brief Check if DMA RX FIFO is full + * @param fifo_level only supports level 1 + */ +static inline bool gdma_ll_rx_is_fifo_full(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->in.infifo_status.val & 0x01; +} + +/** + * @brief Check if DMA RX FIFO is empty + * @param fifo_level only supports level 1 + */ +static inline bool gdma_ll_rx_is_fifo_empty(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->in.infifo_status.val & 0x02; +} + +/** + * @brief Get number of bytes in RX FIFO + * @param fifo_level only supports level 1 + */ +static inline uint32_t gdma_ll_rx_get_fifo_bytes(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->in.infifo_status.infifo_cnt; +} + +/** + * @brief Pop data from DMA RX FIFO + */ +static inline uint32_t gdma_ll_rx_pop_data(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_pop.infifo_pop = 1; + return ch->in.in_pop.infifo_rdata; +} + +/** + * @brief Set the descriptor link base address for RX channel + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_set_desc_addr(gdma_dev_t *dev, uint32_t channel, uint32_t addr) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_link.inlink_addr = addr; +} + +/** + * @brief Start dealing with RX descriptors + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_start(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_link.inlink_start = 1; +} + +/** + * @brief Stop dealing with RX descriptors + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_stop(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_link.inlink_stop = 1; +} + +/** + * @brief Restart a new inlink right after the last descriptor + */ +__attribute__((always_inline)) +static inline void gdma_ll_rx_restart(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_link.inlink_restart = 1; +} + +/** + * @brief Enable DMA RX to return the address of current descriptor when receives error + */ +static inline void gdma_ll_rx_enable_auto_return(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_link.inlink_auto_ret = enable; +} + +/** + * @brief Check if DMA RX descriptor FSM is in IDLE state + */ +static inline bool gdma_ll_rx_is_desc_fsm_idle(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->in.in_link.inlink_park; +} + +/** + * @brief Get RX success EOF descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_rx_get_success_eof_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->in.in_suc_eof_des_addr.val; +} + +/** + * @brief Get RX error EOF descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_rx_get_error_eof_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->in.in_err_eof_des_addr.val; +} + +/** + * @brief Get the pre-fetched RX descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_rx_get_prefetched_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->in.in_dscr.val; +} + +/** + * @brief Set priority for DMA RX channel + */ +static inline void gdma_ll_rx_set_priority(gdma_dev_t *dev, uint32_t channel, uint32_t prio) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_pri.rx_pri = prio; +} + +/** + * @brief Connect DMA RX channel to a given peripheral + */ +static inline void gdma_ll_rx_connect_to_periph(gdma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_peri_sel.peri_in_sel = periph_id; + ch->in.in_conf0.mem_trans_en = (periph == GDMA_TRIG_PERIPH_M2M); +} + +/** + * @brief Disconnect DMA RX channel from peripheral + */ +static inline void gdma_ll_rx_disconnect_from_periph(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_peri_sel.peri_in_sel = GDMA_LL_INVALID_PERIPH_ID; + ch->in.in_conf0.mem_trans_en = false; +} + +/** + * @brief Whether to enable the ETM subsystem for RX channel + * + * @note When ETM_EN is 1, only ETM tasks can be used to configure the transfer direction and enable the channel. + */ +static inline void gdma_ll_rx_enable_etm_task(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->in.in_conf0.in_etm_en = enable; +} + +///////////////////////////////////// TX ///////////////////////////////////////// +/** + * @brief Get DMA TX channel interrupt status word + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_tx_get_interrupt_status(gdma_dev_t *dev, uint32_t channel, bool raw) +{ + if (raw) { + return dev->out_intr[channel].raw.val; + } else { + return dev->out_intr[channel].st.val; + } +} + +/** + * @brief Enable DMA TX channel interrupt + */ +static inline void gdma_ll_tx_enable_interrupt(gdma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable) +{ + if (enable) { + dev->out_intr[channel].ena.val |= mask; + } else { + dev->out_intr[channel].ena.val &= ~mask; + } +} + +/** + * @brief Clear DMA TX channel interrupt + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_clear_interrupt_status(gdma_dev_t *dev, uint32_t channel, uint32_t mask) +{ + dev->out_intr[channel].clr.val = mask; +} + +/** + * @brief Get DMA TX channel interrupt status register address + */ +static inline volatile void *gdma_ll_tx_get_interrupt_status_reg(gdma_dev_t *dev, uint32_t channel) +{ + return (volatile void *)(&dev->out_intr[channel].st); +} + +/** + * @brief Enable DMA TX channel to check the owner bit in the descriptor, disabled by default + */ +static inline void gdma_ll_tx_enable_owner_check(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_conf1.out_check_owner = enable; +} + +/** + * @brief Enable DMA TX channel burst sending data, disabled by default + */ +static inline void gdma_ll_tx_enable_data_burst(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_conf0.out_data_burst_en = enable; +} + +/** + * @brief Enable DMA TX channel burst reading descriptor link, disabled by default + */ +static inline void gdma_ll_tx_enable_descriptor_burst(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_conf0.outdscr_burst_en = enable; +} + +/** + * @brief Set TX channel EOF mode + */ +static inline void gdma_ll_tx_set_eof_mode(gdma_dev_t *dev, uint32_t channel, uint32_t mode) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_conf0.out_eof_mode = mode; +} + +/** + * @brief Enable DMA TX channel automatic write results back to descriptor after all data has been sent out, disabled by default + */ +static inline void gdma_ll_tx_enable_auto_write_back(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_conf0.out_auto_wrback = enable; +} + +/** + * @brief Reset DMA TX channel FSM and FIFO pointer + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_reset_channel(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_conf0.out_rst = 1; + ch->out.out_conf0.out_rst = 0; +} + +/** + * @brief Check if DMA TX FIFO is full + * @param fifo_level only supports level 1 + */ +static inline bool gdma_ll_tx_is_fifo_full(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->out.outfifo_status.val & 0x01; +} + +/** + * @brief Check if DMA TX FIFO is empty + * @param fifo_level only supports level 1 + */ +static inline bool gdma_ll_tx_is_fifo_empty(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->out.outfifo_status.val & 0x02; +} + +/** + * @brief Get number of bytes in TX FIFO + * @param fifo_level only supports level 1 + */ +static inline uint32_t gdma_ll_tx_get_fifo_bytes(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->out.outfifo_status.outfifo_cnt; +} + +/** + * @brief Push data into DMA TX FIFO + */ +static inline void gdma_ll_tx_push_data(gdma_dev_t *dev, uint32_t channel, uint32_t data) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_push.outfifo_wdata = data; + ch->out.out_push.outfifo_push = 1; +} + +/** + * @brief Set the descriptor link base address for TX channel + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_set_desc_addr(gdma_dev_t *dev, uint32_t channel, uint32_t addr) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_link.outlink_addr = addr; +} + +/** + * @brief Start dealing with TX descriptors + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_start(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_link.outlink_start = 1; +} + +/** + * @brief Stop dealing with TX descriptors + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_stop(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_link.outlink_stop = 1; +} + +/** + * @brief Restart a new outlink right after the last descriptor + */ +__attribute__((always_inline)) +static inline void gdma_ll_tx_restart(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_link.outlink_restart = 1; +} + +/** + * @brief Check if DMA TX descriptor FSM is in IDLE state + */ +static inline bool gdma_ll_tx_is_desc_fsm_idle(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->out.out_link.outlink_park; +} + +/** + * @brief Get TX EOF descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_tx_get_eof_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->out.out_eof_des_addr.val; +} + +/** + * @brief Get the pre-fetched TX descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t gdma_ll_tx_get_prefetched_desc_addr(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + return ch->out.out_dscr.val; +} + +/** + * @brief Set priority for DMA TX channel + */ +static inline void gdma_ll_tx_set_priority(gdma_dev_t *dev, uint32_t channel, uint32_t prio) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_pri.tx_pri = prio; +} + +/** + * @brief Connect DMA TX channel to a given peripheral + */ +static inline void gdma_ll_tx_connect_to_periph(gdma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id) +{ + (void)periph; + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_peri_sel.peri_out_sel = periph_id; +} + +/** + * @brief Disconnect DMA TX channel from peripheral + */ +static inline void gdma_ll_tx_disconnect_from_periph(gdma_dev_t *dev, uint32_t channel) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_peri_sel.peri_out_sel = GDMA_LL_INVALID_PERIPH_ID; +} + +/** + * @brief Whether to enable the ETM subsystem for TX channel + * + * @note When ETM_EN is 1, only ETM tasks can be used to configure the transfer direction and enable the channel. + */ +static inline void gdma_ll_tx_enable_etm_task(gdma_dev_t *dev, uint32_t channel, bool enable) +{ + volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); + ch->out.out_conf0.out_etm_en = enable; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c5/include/hal/ecc_ll.h b/components/hal/esp32c5/include/hal/ecc_ll.h index 7e3a7a1073ee..48975e5ec810 100644 --- a/components/hal/esp32c5/include/hal/ecc_ll.h +++ b/components/hal/esp32c5/include/hal/ecc_ll.h @@ -12,6 +12,7 @@ #include "hal/ecc_types.h" #include "soc/ecc_mult_reg.h" #include "soc/pcr_struct.h" +#include "soc/pcr_reg.h" #ifdef __cplusplus extern "C" { @@ -51,6 +52,20 @@ static inline void ecc_ll_reset_register(void) #endif } +static inline void ecc_ll_power_up(void) +{ + /* Power up the ECC peripheral (default state is power-down) */ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD); +} + +static inline void ecc_ll_power_down(void) +{ + /* Power down the ECC peripheral */ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PU); + REG_SET_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); +} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32c5/include/hal/efuse_ll.h b/components/hal/esp32c5/include/hal/efuse_ll.h index 8e283d1a7a0f..414b241bd3a9 100644 --- a/components/hal/esp32c5/include/hal/efuse_ll.h +++ b/components/hal/esp32c5/include/hal/efuse_ll.h @@ -18,6 +18,15 @@ extern "C" { #endif +typedef enum { + EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state. + EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state. + EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state. + EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state. + EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state. + EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state. +} efuse_controller_state_t; + // Always inline these functions even no gcc optimization is applied. /******************* eFuse fields *************************/ @@ -134,6 +143,11 @@ __attribute__((always_inline)) static inline void efuse_ll_rs_bypass_update(void /******************* eFuse control functions *************************/ +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void) +{ + return EFUSE.status.state; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c5/include/hal/gdma_ll.h b/components/hal/esp32c5/include/hal/gdma_ll.h index 55c89bb81f44..4acd0bf59a21 100644 --- a/components/hal/esp32c5/include/hal/gdma_ll.h +++ b/components/hal/esp32c5/include/hal/gdma_ll.h @@ -5,629 +5,9 @@ */ #pragma once -#include /* Required for NULL constant */ -#include -#include -#include "soc/soc_caps.h" -#if SOC_GDMA_SUPPORTED // TODO: [ESP32C5] IDF-8710 -#include "hal/gdma_types.h" -#include "soc/gdma_struct.h" -#include "soc/gdma_reg.h" -#include "soc/soc_etm_source.h" -#include "soc/pcr_struct.h" -#include "soc/retention_periph_defs.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 << (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) << pair_id) - -#define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL) - -#define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5] - -#define GDMA_LL_RX_EVENT_MASK (0x7F) -#define GDMA_LL_TX_EVENT_MASK (0x3F) - -// any "dummy" peripheral ID can be used for M2M mode -#define GDMA_LL_M2M_FREE_PERIPH_ID_MASK (0xFC32) -#define GDMA_LL_INVALID_PERIPH_ID (0x3F) - -#define GDMA_LL_EVENT_TX_FIFO_UDF (1<<5) -#define GDMA_LL_EVENT_TX_FIFO_OVF (1<<4) -#define GDMA_LL_EVENT_RX_FIFO_UDF (1<<6) -#define GDMA_LL_EVENT_RX_FIFO_OVF (1<<5) -#define GDMA_LL_EVENT_TX_TOTAL_EOF (1<<3) -#define GDMA_LL_EVENT_RX_DESC_EMPTY (1<<4) -#define GDMA_LL_EVENT_TX_DESC_ERROR (1<<2) -#define GDMA_LL_EVENT_RX_DESC_ERROR (1<<3) -#define GDMA_LL_EVENT_TX_EOF (1<<1) -#define GDMA_LL_EVENT_TX_DONE (1<<0) -#define GDMA_LL_EVENT_RX_ERR_EOF (1<<2) -#define GDMA_LL_EVENT_RX_SUC_EOF (1<<1) -#define GDMA_LL_EVENT_RX_DONE (1<<0) - -#define GDMA_LL_AHB_GROUP_START_ID 0 // AHB GDMA group ID starts from 0 -#define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups -#define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group - -#define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ - (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ - [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH0, \ - }, \ - { \ - [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH1, \ - }, \ - { \ - [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH2, \ - }}}[group][chan][event] - -#define GDMA_LL_RX_ETM_EVENT_TABLE(group, chan, event) \ - (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ - [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH0, \ - }, \ - { \ - [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH1, \ - }, \ - { \ - [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH2, \ - }}}[group][chan][event] - -#define GDMA_LL_TX_ETM_TASK_TABLE(group, chan, task) \ - (uint32_t[1][3][GDMA_ETM_TASK_MAX]){{{ \ - [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH0, \ - }, \ - { \ - [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH1, \ - }, \ - { \ - [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH2, \ - }}}[group][chan][task] - -#define GDMA_LL_RX_ETM_TASK_TABLE(group, chan, task) \ - (uint32_t[1][3][GDMA_ETM_TASK_MAX]){{{ \ - [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH0, \ - }, \ - { \ - [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH1, \ - }, \ - { \ - [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH2, \ - }}}[group][chan][task] - -// TODO: Workaround for C5-beta3 only. C5-mp can still vectorized channels into an array in gdma_struct.h -#define GDMA_LL_CHANNEL_GET_REG_ADDR(dev, ch) ((volatile gdma_chn_reg_t*[]){&dev->channel0, &dev->channel1, &dev->channel2}[(ch)]) - -#define GDMA_LL_AHB_DESC_ALIGNMENT 4 - -///////////////////////////////////// Common ///////////////////////////////////////// - -/** - * @brief Enable the bus clock for the DMA module - */ -static inline void gdma_ll_enable_bus_clock(int group_id, bool enable) -{ - (void)group_id; - PCR.gdma_conf.gdma_clk_en = enable; -} - -/** - * @brief Reset the DMA module - */ -static inline void gdma_ll_reset_register(int group_id) -{ - (void)group_id; - PCR.gdma_conf.gdma_rst_en = 1; - PCR.gdma_conf.gdma_rst_en = 0; -} - -/** - * @brief Force enable register clock - */ -static inline void gdma_ll_force_enable_reg_clock(gdma_dev_t *dev, bool enable) -{ - dev->misc_conf.clk_en = enable; -} - -///////////////////////////////////// RX ///////////////////////////////////////// -/** - * @brief Get DMA RX channel interrupt status word - */ -__attribute__((always_inline)) -static inline uint32_t gdma_ll_rx_get_interrupt_status(gdma_dev_t *dev, uint32_t channel, bool raw) -{ - if (raw) { - return dev->in_intr[channel].raw.val; - } else { - return dev->in_intr[channel].st.val; - } -} - -/** - * @brief Enable DMA RX channel interrupt - */ -static inline void gdma_ll_rx_enable_interrupt(gdma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable) -{ - if (enable) { - dev->in_intr[channel].ena.val |= mask; - } else { - dev->in_intr[channel].ena.val &= ~mask; - } -} - -/** - * @brief Clear DMA RX channel interrupt - */ -__attribute__((always_inline)) -static inline void gdma_ll_rx_clear_interrupt_status(gdma_dev_t *dev, uint32_t channel, uint32_t mask) -{ - dev->in_intr[channel].clr.val = mask; -} - -/** - * @brief Get DMA RX channel interrupt status register address - */ -static inline volatile void *gdma_ll_rx_get_interrupt_status_reg(gdma_dev_t *dev, uint32_t channel) -{ - return (volatile void *)(&dev->in_intr[channel].st); -} - -/** - * @brief Enable DMA RX channel to check the owner bit in the descriptor, disabled by default - */ -static inline void gdma_ll_rx_enable_owner_check(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_conf1.in_check_owner = enable; -} - -/** - * @brief Enable DMA RX channel burst reading data, disabled by default - */ -static inline void gdma_ll_rx_enable_data_burst(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_conf0.in_data_burst_en = enable; -} - -/** - * @brief Enable DMA RX channel burst reading descriptor link, disabled by default - */ -static inline void gdma_ll_rx_enable_descriptor_burst(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_conf0.indscr_burst_en = enable; -} - -/** - * @brief Reset DMA RX channel FSM and FIFO pointer - */ -__attribute__((always_inline)) -static inline void gdma_ll_rx_reset_channel(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_conf0.in_rst = 1; - ch->in.in_conf0.in_rst = 0; -} - -/** - * @brief Check if DMA RX FIFO is full - * @param fifo_level only supports level 1 - */ -static inline bool gdma_ll_rx_is_fifo_full(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->in.infifo_status.val & 0x01; -} - -/** - * @brief Check if DMA RX FIFO is empty - * @param fifo_level only supports level 1 - */ -static inline bool gdma_ll_rx_is_fifo_empty(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->in.infifo_status.val & 0x02; -} - -/** - * @brief Get number of bytes in RX FIFO - * @param fifo_level only supports level 1 - */ -static inline uint32_t gdma_ll_rx_get_fifo_bytes(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->in.infifo_status.infifo_cnt; -} - -/** - * @brief Pop data from DMA RX FIFO - */ -static inline uint32_t gdma_ll_rx_pop_data(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_pop.infifo_pop = 1; - return ch->in.in_pop.infifo_rdata; -} - -/** - * @brief Set the descriptor link base address for RX channel - */ -__attribute__((always_inline)) -static inline void gdma_ll_rx_set_desc_addr(gdma_dev_t *dev, uint32_t channel, uint32_t addr) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_link.inlink_addr = addr; -} - -/** - * @brief Start dealing with RX descriptors - */ -__attribute__((always_inline)) -static inline void gdma_ll_rx_start(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_link.inlink_start = 1; -} - -/** - * @brief Stop dealing with RX descriptors - */ -__attribute__((always_inline)) -static inline void gdma_ll_rx_stop(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_link.inlink_stop = 1; -} - -/** - * @brief Restart a new inlink right after the last descriptor - */ -__attribute__((always_inline)) -static inline void gdma_ll_rx_restart(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_link.inlink_restart = 1; -} - -/** - * @brief Enable DMA RX to return the address of current descriptor when receives error - */ -static inline void gdma_ll_rx_enable_auto_return(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_link.inlink_auto_ret = enable; -} - -/** - * @brief Check if DMA RX descriptor FSM is in IDLE state - */ -static inline bool gdma_ll_rx_is_desc_fsm_idle(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->in.in_link.inlink_park; -} - -/** - * @brief Get RX success EOF descriptor's address - */ -__attribute__((always_inline)) -static inline uint32_t gdma_ll_rx_get_success_eof_desc_addr(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->in.in_suc_eof_des_addr.val; -} - -/** - * @brief Get RX error EOF descriptor's address - */ -__attribute__((always_inline)) -static inline uint32_t gdma_ll_rx_get_error_eof_desc_addr(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->in.in_err_eof_des_addr.val; -} - -/** - * @brief Get the pre-fetched RX descriptor's address - */ -__attribute__((always_inline)) -static inline uint32_t gdma_ll_rx_get_prefetched_desc_addr(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->in.in_dscr.val; -} - -/** - * @brief Set priority for DMA RX channel - */ -static inline void gdma_ll_rx_set_priority(gdma_dev_t *dev, uint32_t channel, uint32_t prio) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_pri.rx_pri = prio; -} - -/** - * @brief Connect DMA RX channel to a given peripheral - */ -static inline void gdma_ll_rx_connect_to_periph(gdma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_peri_sel.peri_in_sel = periph_id; - ch->in.in_conf0.mem_trans_en = (periph == GDMA_TRIG_PERIPH_M2M); -} - -/** - * @brief Disconnect DMA RX channel from peripheral - */ -static inline void gdma_ll_rx_disconnect_from_periph(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_peri_sel.peri_in_sel = GDMA_LL_INVALID_PERIPH_ID; - ch->in.in_conf0.mem_trans_en = false; -} - -/** - * @brief Whether to enable the ETM subsystem for RX channel - * - * @note When ETM_EN is 1, only ETM tasks can be used to configure the transfer direction and enable the channel. - */ -static inline void gdma_ll_rx_enable_etm_task(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->in.in_conf0.in_etm_en = enable; -} - -///////////////////////////////////// TX ///////////////////////////////////////// -/** - * @brief Get DMA TX channel interrupt status word - */ -__attribute__((always_inline)) -static inline uint32_t gdma_ll_tx_get_interrupt_status(gdma_dev_t *dev, uint32_t channel, bool raw) -{ - if (raw) { - return dev->out_intr[channel].raw.val; - } else { - return dev->out_intr[channel].st.val; - } -} - -/** - * @brief Enable DMA TX channel interrupt - */ -static inline void gdma_ll_tx_enable_interrupt(gdma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable) -{ - if (enable) { - dev->out_intr[channel].ena.val |= mask; - } else { - dev->out_intr[channel].ena.val &= ~mask; - } -} - -/** - * @brief Clear DMA TX channel interrupt - */ -__attribute__((always_inline)) -static inline void gdma_ll_tx_clear_interrupt_status(gdma_dev_t *dev, uint32_t channel, uint32_t mask) -{ - dev->out_intr[channel].clr.val = mask; -} - -/** - * @brief Get DMA TX channel interrupt status register address - */ -static inline volatile void *gdma_ll_tx_get_interrupt_status_reg(gdma_dev_t *dev, uint32_t channel) -{ - return (volatile void *)(&dev->out_intr[channel].st); -} - -/** - * @brief Enable DMA TX channel to check the owner bit in the descriptor, disabled by default - */ -static inline void gdma_ll_tx_enable_owner_check(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_conf1.out_check_owner = enable; -} - -/** - * @brief Enable DMA TX channel burst sending data, disabled by default - */ -static inline void gdma_ll_tx_enable_data_burst(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_conf0.out_data_burst_en = enable; -} - -/** - * @brief Enable DMA TX channel burst reading descriptor link, disabled by default - */ -static inline void gdma_ll_tx_enable_descriptor_burst(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_conf0.outdscr_burst_en = enable; -} - -/** - * @brief Set TX channel EOF mode - */ -static inline void gdma_ll_tx_set_eof_mode(gdma_dev_t *dev, uint32_t channel, uint32_t mode) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_conf0.out_eof_mode = mode; -} - -/** - * @brief Enable DMA TX channel automatic write results back to descriptor after all data has been sent out, disabled by default - */ -static inline void gdma_ll_tx_enable_auto_write_back(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_conf0.out_auto_wrback = enable; -} - -/** - * @brief Reset DMA TX channel FSM and FIFO pointer - */ -__attribute__((always_inline)) -static inline void gdma_ll_tx_reset_channel(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_conf0.out_rst = 1; - ch->out.out_conf0.out_rst = 0; -} - -/** - * @brief Check if DMA TX FIFO is full - * @param fifo_level only supports level 1 - */ -static inline bool gdma_ll_tx_is_fifo_full(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->out.outfifo_status.val & 0x01; -} - -/** - * @brief Check if DMA TX FIFO is empty - * @param fifo_level only supports level 1 - */ -static inline bool gdma_ll_tx_is_fifo_empty(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->out.outfifo_status.val & 0x02; -} - -/** - * @brief Get number of bytes in TX FIFO - * @param fifo_level only supports level 1 - */ -static inline uint32_t gdma_ll_tx_get_fifo_bytes(gdma_dev_t *dev, uint32_t channel, uint32_t fifo_level) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->out.outfifo_status.outfifo_cnt; -} - -/** - * @brief Push data into DMA TX FIFO - */ -static inline void gdma_ll_tx_push_data(gdma_dev_t *dev, uint32_t channel, uint32_t data) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_push.outfifo_wdata = data; - ch->out.out_push.outfifo_push = 1; -} - -/** - * @brief Set the descriptor link base address for TX channel - */ -__attribute__((always_inline)) -static inline void gdma_ll_tx_set_desc_addr(gdma_dev_t *dev, uint32_t channel, uint32_t addr) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_link.outlink_addr = addr; -} - -/** - * @brief Start dealing with TX descriptors - */ -__attribute__((always_inline)) -static inline void gdma_ll_tx_start(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_link.outlink_start = 1; -} - -/** - * @brief Stop dealing with TX descriptors - */ -__attribute__((always_inline)) -static inline void gdma_ll_tx_stop(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_link.outlink_stop = 1; -} - -/** - * @brief Restart a new outlink right after the last descriptor - */ -__attribute__((always_inline)) -static inline void gdma_ll_tx_restart(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_link.outlink_restart = 1; -} - -/** - * @brief Check if DMA TX descriptor FSM is in IDLE state - */ -static inline bool gdma_ll_tx_is_desc_fsm_idle(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->out.out_link.outlink_park; -} - -/** - * @brief Get TX EOF descriptor's address - */ -__attribute__((always_inline)) -static inline uint32_t gdma_ll_tx_get_eof_desc_addr(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->out.out_eof_des_addr.val; -} - -/** - * @brief Get the pre-fetched TX descriptor's address - */ -__attribute__((always_inline)) -static inline uint32_t gdma_ll_tx_get_prefetched_desc_addr(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - return ch->out.out_dscr.val; -} - -/** - * @brief Set priority for DMA TX channel - */ -static inline void gdma_ll_tx_set_priority(gdma_dev_t *dev, uint32_t channel, uint32_t prio) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_pri.tx_pri = prio; -} - -/** - * @brief Connect DMA TX channel to a given peripheral - */ -static inline void gdma_ll_tx_connect_to_periph(gdma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id) -{ - (void)periph; - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_peri_sel.peri_out_sel = periph_id; -} - -/** - * @brief Disconnect DMA TX channel from peripheral - */ -static inline void gdma_ll_tx_disconnect_from_periph(gdma_dev_t *dev, uint32_t channel) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_peri_sel.peri_out_sel = GDMA_LL_INVALID_PERIPH_ID; -} - -/** - * @brief Whether to enable the ETM subsystem for TX channel - * - * @note When ETM_EN is 1, only ETM tasks can be used to configure the transfer direction and enable the channel. - */ -static inline void gdma_ll_tx_enable_etm_task(gdma_dev_t *dev, uint32_t channel, bool enable) -{ - volatile gdma_chn_reg_t *ch = (volatile gdma_chn_reg_t *)GDMA_LL_CHANNEL_GET_REG_ADDR(dev, channel); - ch->out.out_conf0.out_etm_en = enable; -} - -#ifdef __cplusplus -} +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION +#include "hal/gdma_beta3_ll.h" +#else +#include "hal/ahb_dma_ll.h" #endif - -#endif // SOC_GDMA_SUPPORTED diff --git a/components/hal/esp32c5/include/hal/gpio_ll.h b/components/hal/esp32c5/include/hal/gpio_ll.h index 57df8172cd56..b6908c483bff 100644 --- a/components/hal/esp32c5/include/hal/gpio_ll.h +++ b/components/hal/esp32c5/include/hal/gpio_ll.h @@ -22,23 +22,17 @@ #include "soc/gpio_struct.h" #include "soc/lp_aon_struct.h" #include "soc/pmu_struct.h" -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION -#include "soc/lp_io_struct.h" -#include "soc/pcr_struct.h" +#include "soc/io_mux_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/pcr_struct.h" #include "soc/usb_serial_jtag_struct.h" -#include "soc/io_mux_struct.h" #include "hal/gpio_types.h" +#include "hal/assert.h" +#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION +#include "soc/lp_io_struct.h" #elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION #include "soc/lp_gpio_struct.h" -#include "soc/usb_serial_jtag_reg.h" -#include "soc/pcr_struct.h" -#include "soc/clk_tree_defs.h" -#include "soc/io_mux_struct.h" -#include "hal/gpio_types.h" -#include "hal/misc.h" #endif -#include "hal/assert.h" #ifdef __cplusplus extern "C" { @@ -69,15 +63,15 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) { - *pu = IOMUX.gpio[gpio_num].fun_wpu; - *pd = IOMUX.gpio[gpio_num].fun_wpd; - *ie = IOMUX.gpio[gpio_num].fun_ie; + *pu = IO_MUX.gpio[gpio_num].fun_wpu; + *pd = IO_MUX.gpio[gpio_num].fun_wpd; + *ie = IO_MUX.gpio[gpio_num].fun_ie; *oe = (hw->enable.val & (1 << gpio_num)) >> gpio_num; *od = hw->pin[gpio_num].pad_driver; - *drv = IOMUX.gpio[gpio_num].fun_drv; - *fun_sel = IOMUX.gpio[gpio_num].mcu_sel; + *drv = IO_MUX.gpio[gpio_num].fun_drv; + *fun_sel = IO_MUX.gpio[gpio_num].mcu_sel; *sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; - *slp_sel = IOMUX.gpio[gpio_num].slp_sel; + *slp_sel = IO_MUX.gpio[gpio_num].slp_sel; } /** @@ -88,12 +82,7 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, */ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].fun_wpu = 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // REG_SET_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU); - abort(); -#endif + IO_MUX.gpio[gpio_num].fun_wpu = 1; } /** @@ -105,12 +94,16 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].fun_wpu = 0; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU); - abort(); -#endif + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + // Note that esp32C5 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin + // which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead. + // TODO: read the specific efuse with efuse_ll.h + if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; + USB_SERIAL_JTAG.conf0.dp_pullup = 0; + } + IO_MUX.gpio[gpio_num].fun_wpu = 0; } /** @@ -121,12 +114,7 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].fun_wpd = 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // REG_SET_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD); - abort(); -#endif + IO_MUX.gpio[gpio_num].fun_wpd = 1; } /** @@ -138,25 +126,8 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) { - // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value - // USB DP pin is default to PU enabled - // Note that esp32C5 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin - // which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead. - // TODO: read the specific efuse with efuse_ll.h -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { - USB_SERIAL_JTAG.conf0.pad_pull_override = 1; - USB_SERIAL_JTAG.conf0.dp_pullup = 0; - } - IOMUX.gpio[gpio_num].fun_wpd = 0; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { - // SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); - // CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); - // } - // REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD); - abort(); -#endif + + IO_MUX.gpio[gpio_num].fun_wpd = 0; } /** @@ -182,11 +153,7 @@ __attribute__((always_inline)) static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uint32_t *status) { (void)core_id; -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION *status = hw->pcpu_int.procpu_int; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - abort(); -#endif } /** @@ -261,12 +228,7 @@ static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].fun_ie = 0; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].fun_ie = 0; } /** @@ -277,12 +239,7 @@ static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].fun_ie = 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].fun_ie = 1; } /** @@ -293,12 +250,7 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].filter_en = 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_FILTER_EN(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].filter_en = 1; } /** @@ -309,15 +261,9 @@ static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].filter_en = 0; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - PIN_FILTER_DIS(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].filter_en = 0; } -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION /** * @brief Enable GPIO hysteresis * @@ -330,8 +276,8 @@ static inline void gpio_ll_pin_input_hysteresis_enable(gpio_dev_t *hw, uint32_t // We are not going to use the hardware control in IDF for C5. // Therefore, we need to always switch to use software control first. // i.e. Swt hys_sel to 1, so that hys_en determines whether hysteresis is enabled or not - IOMUX.gpio[gpio_num].hys_sel = 1; - IOMUX.gpio[gpio_num].hys_en = 1; + IO_MUX.gpio[gpio_num].hys_sel = 1; + IO_MUX.gpio[gpio_num].hys_en = 1; } /** @@ -342,10 +288,9 @@ static inline void gpio_ll_pin_input_hysteresis_enable(gpio_dev_t *hw, uint32_t */ static inline void gpio_ll_pin_input_hysteresis_disable(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].hys_sel = 1; - IOMUX.gpio[gpio_num].hys_en = 0; + IO_MUX.gpio[gpio_num].hys_sel = 1; + IO_MUX.gpio[gpio_num].hys_en = 0; } -#endif /** * @brief Disable output mode on GPIO. @@ -461,12 +406,7 @@ static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].fun_drv = strength; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, strength, FUN_DRV_S); - abort(); -#endif + IO_MUX.gpio[gpio_num].fun_drv = strength; } /** @@ -478,12 +418,7 @@ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu */ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - *strength = (gpio_drive_cap_t)(IOMUX.gpio[gpio_num].fun_drv); -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // *strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S); - abort(); -#endif + *strength = (gpio_drive_cap_t)(IO_MUX.gpio[gpio_num].fun_drv); } /** @@ -492,6 +427,7 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) { LP_AON.gpio_hold0.gpio_hold0 |= GPIO_HOLD_MASK[gpio_num]; @@ -503,6 +439,7 @@ static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num) { LP_AON.gpio_hold0.gpio_hold0 &= ~GPIO_HOLD_MASK[gpio_num]; @@ -527,7 +464,7 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Set pad input to a peripheral signal through the IO_MUX. * * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number of the pad. @@ -537,7 +474,7 @@ __attribute__((always_inline)) static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) { hw->func_in_sel_cfg[signal_idx].sig_in_sel = 0; - IOMUX.gpio[gpio].fun_ie = 1; + IO_MUX.gpio[gpio].fun_ie = 1; } /** @@ -554,11 +491,10 @@ static inline void gpio_ll_iomux_func_sel(uint32_t pin_name, uint32_t func) USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; } #elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // // Disable USB Serial JTAG if pins 12 or pins 13 needs to select an IOMUX function - // if (pin_name == IO_MUX_GPIO12_REG || pin_name == IO_MUX_GPIO13_REG) { - // CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE); - // } - abort(); + // Disable USB Serial JTAG if pins 13 or pins 14 needs to select an IOMUX function + if (pin_name == IO_MUX_GPIO13_REG || pin_name == IO_MUX_GPIO14_REG) { + USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; + } #endif PIN_FUNC_SELECT(pin_name, func); } @@ -590,19 +526,18 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f if (gpio_num == USB_INT_PHY0_DM_GPIO_NUM || gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; } - IOMUX.gpio[gpio_num].mcu_sel = func; + IO_MUX.gpio[gpio_num].mcu_sel = func; #elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // // Disable USB Serial JTAG if pins 12 or pins 13 needs to select an IOMUX function - // if (gpio_num == USB_INT_PHY0_DM_GPIO_NUM || gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { - // CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE); - // } - // PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func); - abort(); + // Disable USB Serial JTAG if pins 13 or pins 14 needs to select an IOMUX function + if (gpio_num == USB_INT_PHY0_DM_GPIO_NUM || gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { + USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; + } + IO_MUX.gpio[gpio_num].mcu_sel = func; #endif } /** - * @brief Set peripheral output to an GPIO pad through the IOMUX. + * @brief Set peripheral output to an GPIO pad through the IO_MUX. * * @param hw Peripheral GPIO hardware instance address. * @param gpio_num gpio_num GPIO number of the pad. @@ -625,7 +560,6 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) { switch (src) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION case SOC_MOD_CLK_XTAL: PCR.iomux_clk_conf.iomux_func_clk_sel = 0; break; @@ -635,14 +569,6 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) case SOC_MOD_CLK_PLL_F80M: PCR.iomux_clk_conf.iomux_func_clk_sel = 2; break; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - case SOC_MOD_CLK_XTAL: - PCR.iomux_clk_conf.iomux_func_clk_sel = 3; - break; - case SOC_MOD_CLK_PLL_F80M: - PCR.iomux_clk_conf.iomux_func_clk_sel = 1; - break; -#endif default: // Unsupported IO_MUX clock source HAL_ASSERT(false); @@ -694,12 +620,7 @@ static inline void gpio_ll_force_unhold_all(void) */ static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].slp_sel = 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_SEL_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].slp_sel = 1; } /** @@ -711,12 +632,7 @@ static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].slp_sel = 0; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_SEL_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].slp_sel = 0; } /** @@ -727,12 +643,7 @@ static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].mcu_wpu = 0; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_PULLUP_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].mcu_wpu = 0; } /** @@ -743,12 +654,7 @@ static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].mcu_wpu = 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_PULLUP_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].mcu_wpu = 1; } /** @@ -759,12 +665,7 @@ static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].mcu_wpd = 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_PULLDOWN_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].mcu_wpd = 1; } /** @@ -775,12 +676,7 @@ static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].mcu_wpd = 0; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_PULLDOWN_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].mcu_wpd = 0; } /** @@ -791,12 +687,7 @@ static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].mcu_ie = 0; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].mcu_ie = 0; } /** @@ -807,12 +698,7 @@ static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num */ static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].mcu_ie = 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].mcu_ie = 1; } /** @@ -823,12 +709,7 @@ static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].mcu_oe = 0; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_OUTPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].mcu_oe = 0; } /** @@ -839,12 +720,7 @@ static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_nu */ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - IOMUX.gpio[gpio_num].mcu_oe = 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // PIN_SLP_OUTPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); - abort(); -#endif + IO_MUX.gpio[gpio_num].mcu_oe = 1; } #ifdef __cplusplus diff --git a/components/hal/esp32c5/include/hal/gpspi_flash_ll.h b/components/hal/esp32c5/include/hal/gpspi_flash_ll.h index 9bf5f63a10d5..a126254f33ea 100644 --- a/components/hal/esp32c5/include/hal/gpspi_flash_ll.h +++ b/components/hal/esp32c5/include/hal/gpspi_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -406,6 +406,20 @@ static inline void gpspi_flash_ll_set_dummy(spi_dev_t *dev, uint32_t dummy_n) abort(); } +/** + * Set D/Q output level during dummy phase + * + * @param dev Beginning address of the peripheral registers. + * @param out_en whether to enable IO output for dummy phase + * @param out_level dummy output level + */ +static inline void gpspi_flash_ll_set_dummy_out(spi_dev_t *dev, uint32_t out_en, uint32_t out_lev) +{ + dev->ctrl.dummy_out = out_en; + dev->ctrl.q_pol = out_lev; + dev->ctrl.d_pol = out_lev; +} + /** * Set extra hold time of CS after the clocks. * diff --git a/components/hal/esp32c5/include/hal/lp_aon_ll.h b/components/hal/esp32c5/include/hal/lp_aon_ll.h index dc65bb3225ed..e35523713553 100644 --- a/components/hal/esp32c5/include/hal/lp_aon_ll.h +++ b/components/hal/esp32c5/include/hal/lp_aon_ll.h @@ -92,6 +92,24 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp) } } +/** + * @brief Get the flag that marks whether LP CPU is awakened by ETM + * + * @return Return true if lpcore is woken up by soc_etm + */ +static inline bool lp_aon_ll_get_lpcore_etm_wakeup_flag(void) +{ + return REG_GET_BIT(LP_AON_LPCORE_REG, LP_AON_LPCORE_ETM_WAKEUP_FLAG); +} + +/** + * @brief Clear the flag that marks whether LP CPU is awakened by soc_etm + */ +static inline void lp_aon_ll_clear_lpcore_etm_wakeup_flag(void) +{ + REG_SET_BIT(LP_AON_LPCORE_REG, LP_AON_LPCORE_ETM_WAKEUP_FLAG_CLR); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c5/include/hal/lp_timer_ll.h b/components/hal/esp32c5/include/hal/lp_timer_ll.h index 357a89b8a140..49997480b5c4 100644 --- a/components/hal/esp32c5/include/hal/lp_timer_ll.h +++ b/components/hal/esp32c5/include/hal/lp_timer_ll.h @@ -15,6 +15,7 @@ #include "soc/lp_aon_reg.h" #include "hal/assert.h" #include "hal/lp_timer_types.h" +#include "hal/misc.h" #include "esp_attr.h" #ifdef __cplusplus @@ -33,8 +34,8 @@ extern "C" { FORCE_INLINE_ATTR void lp_timer_ll_set_alarm_target(lp_timer_dev_t *dev, uint8_t timer_id, uint64_t value) { #if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - dev->target[timer_id].hi.main_timer_tar_high = (value >> 32) & 0xFFFF; - dev->target[timer_id].lo.main_timer_tar_low = value & 0xFFFFFFFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].hi, main_timer_tar_high, (value >> 32) & 0xFFFF); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].lo, main_timer_tar_low, value & 0xFFFFFFFF); #else HAL_ASSERT(false && "lp_timer not supported yet"); #endif @@ -69,7 +70,7 @@ FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_ FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev, uint8_t buffer_id) { #if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - return dev->counter[buffer_id].lo.main_timer_buf_low; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[buffer_id].lo, main_timer_buf_low); #else HAL_ASSERT(false && "lp_timer not supported yet"); return 0; @@ -87,7 +88,7 @@ FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_high(lp_timer_dev_t *dev, uint8_t buffer_id) { #if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - return dev->counter[buffer_id].hi.main_timer_buf_high; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[buffer_id].hi, main_timer_buf_high); #else HAL_ASSERT(false && "lp_timer not supported yet"); return 0; diff --git a/components/hal/esp32c5/include/hal/mmu_ll.h b/components/hal/esp32c5/include/hal/mmu_ll.h index 69d97db39e84..5ecb06998aa8 100644 --- a/components/hal/esp32c5/include/hal/mmu_ll.h +++ b/components/hal/esp32c5/include/hal/mmu_ll.h @@ -24,6 +24,9 @@ extern "C" { #endif +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_MMU_PAGE_SIZE) +#define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1) + /** * Convert MMU virtual address to linear address * @@ -284,7 +287,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32c5/include/hal/mpi_ll.h b/components/hal/esp32c5/include/hal/mpi_ll.h index 543a5fa60ae6..8ba54a9c11fd 100644 --- a/components/hal/esp32c5/include/hal/mpi_ll.h +++ b/components/hal/esp32c5/include/hal/mpi_ll.h @@ -56,11 +56,15 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words) static inline void mpi_ll_clear_power_control_bit(void) { + /* Power up the MPI peripheral (default is power-down state) */ REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); + REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PD); } static inline void mpi_ll_set_power_control_bit(void) { + /* Power down the MPI peripheral */ + REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PU); REG_SET_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); } diff --git a/components/hal/esp32c5/include/hal/pmu_ll.h b/components/hal/esp32c5/include/hal/pmu_ll.h index 81f98a9c10a0..83793ed62d62 100644 --- a/components/hal/esp32c5/include/hal/pmu_ll.h +++ b/components/hal/esp32c5/include/hal/pmu_ll.h @@ -15,6 +15,7 @@ #include "hal/assert.h" #include "soc/pmu_struct.h" #include "hal/pmu_types.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -488,7 +489,7 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode) FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.hp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, hp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw) @@ -533,27 +534,27 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_reject_cause(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, lp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.modify_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.switch_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -578,12 +579,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target, slow_clk_cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl5.lp_ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_set_modem_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -598,22 +599,22 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_get_modem_wait_target_cycle(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_xtal_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_xtal_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable); } FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_pll_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_pll_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable); } FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -638,12 +639,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t * FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->wakeup.cntl7.ana_wait_target = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl7.ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) diff --git a/components/hal/esp32c5/include/hal/rmt_ll.h b/components/hal/esp32c5/include/hal/rmt_ll.h index f62639604ca7..990f6e56bc1f 100644 --- a/components/hal/esp32c5/include/hal/rmt_ll.h +++ b/components/hal/esp32c5/include/hal/rmt_ll.h @@ -82,15 +82,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -115,7 +136,7 @@ static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable) * @param divider_numerator Numerator part of the divider */ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src, - uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) + uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) { // Formula: rmt_sclk = module_clock_src / (1 + div_num + div_a / div_b) (void)channel; // the source clock is set for all channels @@ -436,7 +457,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, * * @param dev Peripheral instance address * @param channel RMT TX channel number - * @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data + * @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data */ static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable) { @@ -667,7 +688,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e * @brief Clear RMT interrupt status by mask * * @param dev Peripheral instance address - * @param mask Interupt status mask + * @param mask Interrupt status mask */ __attribute__((always_inline)) static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask) @@ -821,12 +842,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32c5/include/hal/uart_ll.h b/components/hal/esp32c5/include/hal/uart_ll.h index ea56ae3e2e98..45abdf70154a 100644 --- a/components/hal/esp32c5/include/hal/uart_ll.h +++ b/components/hal/esp32c5/include/hal/uart_ll.h @@ -112,7 +112,7 @@ FORCE_INLINE_ATTR void lp_uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *sou switch (LP_CLKRST.lpperi.lp_uart_clk_sel) { default: case 0: - *source_clk = (soc_module_clk_t)LP_UART_SCLK_LP_FAST; + *source_clk = (soc_module_clk_t)LP_UART_SCLK_RC_FAST; break; case 1: *source_clk = (soc_module_clk_t)LP_UART_SCLK_XTAL_D2; @@ -130,7 +130,7 @@ static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_ { (void)hw; switch (src_clk) { - case LP_UART_SCLK_LP_FAST: + case LP_UART_SCLK_RC_FAST: LP_CLKRST.lpperi.lp_uart_clk_sel = 0; break; case LP_UART_SCLK_XTAL_D2: @@ -167,12 +167,7 @@ FORCE_INLINE_ATTR void lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, ui // an integer part and a fractional part. hw->clkdiv_sync.clkdiv_int = clk_div >> 4; hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf; -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1); -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // TODO: [ESP32c5] IDF-8633 Not found sclk_div_num for LP_UART - abort(); -#endif uart_ll_update(hw); } @@ -437,12 +432,7 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_fr div_reg.val = hw->clkdiv_sync.val; int sclk_div; if ((hw) == &LP_UART) { -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION sclk_div = HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1; -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - // TODO: [ESP32c5] IDF-8633 Not found sclk_div_num for LP_UART - abort(); -#endif } else { sclk_div = UART_LL_PCR_REG_U32_GET(hw, sclk_conf, sclk_div_num) + 1; } @@ -734,7 +724,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -801,7 +791,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -1132,7 +1122,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32c5/mp/include/hal/ahb_dma_ll.h b/components/hal/esp32c5/mp/include/hal/ahb_dma_ll.h new file mode 100644 index 000000000000..39ecb083b7e1 --- /dev/null +++ b/components/hal/esp32c5/mp/include/hal/ahb_dma_ll.h @@ -0,0 +1,619 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include /* Required for NULL constant */ +#include +#include +#include "soc/soc_caps.h" +#include "hal/gdma_types.h" +#include "soc/ahb_dma_struct.h" +#include "soc/ahb_dma_reg.h" +#include "soc/soc_etm_source.h" +#include "soc/pcr_struct.h" +#include "soc/retention_periph_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 << (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) << pair_id) + +#define AHB_DMA_LL_GET_HW(id) (((id) == 0) ? (&AHB_DMA) : NULL) + +#define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5] + +#define GDMA_LL_RX_EVENT_MASK (0x7F) +#define GDMA_LL_TX_EVENT_MASK (0x3F) + +// any "dummy" peripheral ID can be used for M2M mode +#define AHB_DMA_LL_M2M_FREE_PERIPH_ID_MASK (0xFC31) +#define AHB_DMA_LL_INVALID_PERIPH_ID (0x3F) + +#define GDMA_LL_EVENT_TX_FIFO_UDF (1<<5) +#define GDMA_LL_EVENT_TX_FIFO_OVF (1<<4) +#define GDMA_LL_EVENT_RX_FIFO_UDF (1<<6) +#define GDMA_LL_EVENT_RX_FIFO_OVF (1<<5) +#define GDMA_LL_EVENT_TX_TOTAL_EOF (1<<3) +#define GDMA_LL_EVENT_RX_DESC_EMPTY (1<<4) +#define GDMA_LL_EVENT_TX_DESC_ERROR (1<<2) +#define GDMA_LL_EVENT_RX_DESC_ERROR (1<<3) +#define GDMA_LL_EVENT_TX_EOF (1<<1) +#define GDMA_LL_EVENT_TX_DONE (1<<0) +#define GDMA_LL_EVENT_RX_ERR_EOF (1<<2) +#define GDMA_LL_EVENT_RX_SUC_EOF (1<<1) +#define GDMA_LL_EVENT_RX_DONE (1<<0) + +#define GDMA_LL_AHB_GROUP_START_ID 0 // AHB GDMA group ID starts from 0 +#define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups +#define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group + +#define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ + (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH0, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH1, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH2, \ + }}}[group][chan][event] + +#define GDMA_LL_RX_ETM_EVENT_TABLE(group, chan, event) \ + (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH0, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH1, \ + }, \ + { \ + [GDMA_ETM_EVENT_EOF] = GDMA_EVT_IN_SUC_EOF_CH2, \ + }}}[group][chan][event] + +#define GDMA_LL_TX_ETM_TASK_TABLE(group, chan, task) \ + (uint32_t[1][3][GDMA_ETM_TASK_MAX]){{{ \ + [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH0, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH1, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_OUT_START_CH2, \ + }}}[group][chan][task] + +#define GDMA_LL_RX_ETM_TASK_TABLE(group, chan, task) \ + (uint32_t[1][3][GDMA_ETM_TASK_MAX]){{{ \ + [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH0, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH1, \ + }, \ + { \ + [GDMA_ETM_TASK_START] = GDMA_TASK_IN_START_CH2, \ + }}}[group][chan][task] + +#define GDMA_LL_AHB_DESC_ALIGNMENT 4 + +///////////////////////////////////// Common ///////////////////////////////////////// + +/** + * @brief Enable the bus clock for the DMA module + */ +static inline void gdma_ll_enable_bus_clock(int group_id, bool enable) +{ + (void)group_id; + PCR.gdma_conf.gdma_clk_en = enable; +} + +/** + * @brief Reset the DMA module + */ +static inline void gdma_ll_reset_register(int group_id) +{ + (void)group_id; + PCR.gdma_conf.gdma_rst_en = 1; + PCR.gdma_conf.gdma_rst_en = 0; +} + +/** + * @brief Force enable register clock + */ +static inline void ahb_dma_ll_force_enable_reg_clock(ahb_dma_dev_t *dev, bool enable) +{ + dev->misc_conf.clk_en = enable; +} + +/** + * @brief Disable priority arbitration + * + * @param dev DMA register base address + * @param dis True to disable, false to enable + */ +static inline void ahb_dma_ll_disable_prio_arb(ahb_dma_dev_t *dev, bool dis) +{ + dev->misc_conf.arb_pri_dis = dis; +} + +/** + * @brief Reset DMA FSM + * + * @param dev DMA register base address + */ +static inline void ahb_dma_ll_reset_fsm(ahb_dma_dev_t *dev) +{ + dev->misc_conf.ahbm_rst_inter = 1; + dev->misc_conf.ahbm_rst_inter = 0; +} + +/** + * @brief Preset valid memory range for AHB-DMA + * + * @param dev DMA register base address + */ +static inline void ahb_dma_ll_set_default_memory_range(ahb_dma_dev_t *dev) +{ + // AHB-DMA can access L2MEM, L2ROM, MSPI Flash, MSPI PSRAM + dev->intr_mem_start_addr.val = 0x40800000; + dev->intr_mem_end_addr.val = 0x44000000; +} + +///////////////////////////////////// RX ///////////////////////////////////////// +/** + * @brief Get DMA RX channel interrupt status word + */ +__attribute__((always_inline)) +static inline uint32_t ahb_dma_ll_rx_get_interrupt_status(ahb_dma_dev_t *dev, uint32_t channel, bool raw) +{ + if (raw) { + return dev->in_intr[channel].raw.val; + } else { + return dev->in_intr[channel].st.val; + } +} + +/** + * @brief Enable DMA RX channel interrupt + */ +static inline void ahb_dma_ll_rx_enable_interrupt(ahb_dma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable) +{ + if (enable) { + dev->in_intr[channel].ena.val |= mask; + } else { + dev->in_intr[channel].ena.val &= ~mask; + } +} + +/** + * @brief Clear DMA RX channel interrupt + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_rx_clear_interrupt_status(ahb_dma_dev_t *dev, uint32_t channel, uint32_t mask) +{ + dev->in_intr[channel].clr.val = mask; +} + +/** + * @brief Get DMA RX channel interrupt status register address + */ +static inline volatile void *ahb_dma_ll_rx_get_interrupt_status_reg(ahb_dma_dev_t *dev, uint32_t channel) +{ + return (volatile void *)(&dev->in_intr[channel].st); +} + +/** + * @brief Enable DMA RX channel to check the owner bit in the descriptor, disabled by default + */ +static inline void ahb_dma_ll_rx_enable_owner_check(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].in.in_conf1.in_check_owner_chn = enable; +} + +/** + * @brief Enable DMA RX channel burst reading data, disabled by default + */ +static inline void ahb_dma_ll_rx_enable_data_burst(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + // dev->channel[channel].in.in_conf0.in_data_burst_mode_sel_chn = enable; // single/incr4/incr8/incr16 +} + +/** + * @brief Enable DMA RX channel burst reading descriptor link, disabled by default + */ +static inline void ahb_dma_ll_rx_enable_descriptor_burst(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].in.in_conf0.indscr_burst_en_chn = enable; +} + +/** + * @brief Reset DMA RX channel FSM and FIFO pointer + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_rx_reset_channel(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_conf0.in_rst_chn = 1; + dev->channel[channel].in.in_conf0.in_rst_chn = 0; +} + +/** + * @brief Check if DMA RX FIFO is full + * @param fifo_level only supports level 1 + */ +static inline bool ahb_dma_ll_rx_is_fifo_full(ahb_dma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].in.infifo_status.val & 0x01; +} + +/** + * @brief Check if DMA RX FIFO is empty + * @param fifo_level only supports level 1 + */ +static inline bool ahb_dma_ll_rx_is_fifo_empty(ahb_dma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].in.infifo_status.val & 0x02; +} + +/** + * @brief Get number of bytes in RX FIFO + * @param fifo_level only supports level 1 + */ +static inline uint32_t ahb_dma_ll_rx_get_fifo_bytes(ahb_dma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].in.infifo_status.infifo_cnt_chn; +} + +/** + * @brief Pop data from DMA RX FIFO + */ +static inline uint32_t ahb_dma_ll_rx_pop_data(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_pop.infifo_pop_chn = 1; + return dev->channel[channel].in.in_pop.infifo_rdata_chn; +} + +/** + * @brief Set the descriptor link base address for RX channel + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_rx_set_desc_addr(ahb_dma_dev_t *dev, uint32_t channel, uint32_t addr) +{ + dev->in_link_addr[channel].inlink_addr_chn = addr; +} + +/** + * @brief Start dealing with RX descriptors + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_rx_start(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_link.inlink_start_chn = 1; +} + +/** + * @brief Stop dealing with RX descriptors + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_rx_stop(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_link.inlink_stop_chn = 1; +} + +/** + * @brief Restart a new inlink right after the last descriptor + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_rx_restart(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_link.inlink_restart_chn = 1; +} + +/** + * @brief Enable DMA RX to return the address of current descriptor when receives error + */ +static inline void ahb_dma_ll_rx_enable_auto_return(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].in.in_link.inlink_auto_ret_chn = enable; +} + +/** + * @brief Check if DMA RX descriptor FSM is in IDLE state + */ +static inline bool ahb_dma_ll_rx_is_desc_fsm_idle(ahb_dma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].in.in_link.inlink_park_chn; +} + +/** + * @brief Get RX success EOF descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t ahb_dma_ll_rx_get_success_eof_desc_addr(ahb_dma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].in.in_suc_eof_des_addr.val; +} + +/** + * @brief Get RX error EOF descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t ahb_dma_ll_rx_get_error_eof_desc_addr(ahb_dma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].in.in_err_eof_des_addr.val; +} + +/** + * @brief Get the pre-fetched RX descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t ahb_dma_ll_rx_get_prefetched_desc_addr(ahb_dma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].in.in_dscr.val; +} + +/** + * @brief Set priority for DMA RX channel + */ +static inline void ahb_dma_ll_rx_set_priority(ahb_dma_dev_t *dev, uint32_t channel, uint32_t prio) +{ + dev->channel[channel].in.in_pri.rx_pri_chn = prio; +} + +/** + * @brief Connect DMA RX channel to a given peripheral + */ +static inline void ahb_dma_ll_rx_connect_to_periph(ahb_dma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id) +{ + dev->channel[channel].in.in_peri_sel.peri_in_sel_chn = periph_id; + dev->channel[channel].in.in_conf0.mem_trans_en_chn = (periph == GDMA_TRIG_PERIPH_M2M); +} + +/** + * @brief Disconnect DMA RX channel from peripheral + */ +static inline void ahb_dma_ll_rx_disconnect_from_periph(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].in.in_peri_sel.peri_in_sel_chn = AHB_DMA_LL_INVALID_PERIPH_ID; + dev->channel[channel].in.in_conf0.mem_trans_en_chn = false; +} + +/** + * @brief Whether to enable the ETM subsystem for RX channel + * + * @note When ETM_EN is 1, only ETM tasks can be used to configure the transfer direction and enable the channel. + */ +static inline void ahb_dma_ll_rx_enable_etm_task(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].in.in_conf0.in_etm_en_chn = enable; +} + +///////////////////////////////////// TX ///////////////////////////////////////// +/** + * @brief Get DMA TX channel interrupt status word + */ +__attribute__((always_inline)) +static inline uint32_t ahb_dma_ll_tx_get_interrupt_status(ahb_dma_dev_t *dev, uint32_t channel, bool raw) +{ + if (raw) { + return dev->out_intr[channel].raw.val; + } else { + return dev->out_intr[channel].st.val; + } +} + +/** + * @brief Enable DMA TX channel interrupt + */ +static inline void ahb_dma_ll_tx_enable_interrupt(ahb_dma_dev_t *dev, uint32_t channel, uint32_t mask, bool enable) +{ + if (enable) { + dev->out_intr[channel].ena.val |= mask; + } else { + dev->out_intr[channel].ena.val &= ~mask; + } +} + +/** + * @brief Clear DMA TX channel interrupt + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_tx_clear_interrupt_status(ahb_dma_dev_t *dev, uint32_t channel, uint32_t mask) +{ + dev->out_intr[channel].clr.val = mask; +} + +/** + * @brief Get DMA TX channel interrupt status register address + */ +static inline volatile void *ahb_dma_ll_tx_get_interrupt_status_reg(ahb_dma_dev_t *dev, uint32_t channel) +{ + return (volatile void *)(&dev->out_intr[channel].st); +} + +/** + * @brief Enable DMA TX channel to check the owner bit in the descriptor, disabled by default + */ +static inline void ahb_dma_ll_tx_enable_owner_check(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].out.out_conf1.out_check_owner_chn = enable; +} + +/** + * @brief Enable DMA TX channel burst sending data, disabled by default + */ +static inline void ahb_dma_ll_tx_enable_data_burst(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + // dev->channel[channel].out.out_conf0.out_data_burst_mode_sel_chn = enable; +} + +/** + * @brief Enable DMA TX channel burst reading descriptor link, disabled by default + */ +static inline void ahb_dma_ll_tx_enable_descriptor_burst(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].out.out_conf0.outdscr_burst_en_chn = enable; +} + +/** + * @brief Set TX channel EOF mode + */ +static inline void ahb_dma_ll_tx_set_eof_mode(ahb_dma_dev_t *dev, uint32_t channel, uint32_t mode) +{ + dev->channel[channel].out.out_conf0.out_eof_mode_chn = mode; +} + +/** + * @brief Enable DMA TX channel automatic write results back to descriptor after all data has been sent out, disabled by default + */ +static inline void ahb_dma_ll_tx_enable_auto_write_back(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].out.out_conf0.out_auto_wrback_chn = enable; +} + +/** + * @brief Reset DMA TX channel FSM and FIFO pointer + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_tx_reset_channel(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_conf0.out_rst_chn = 1; + dev->channel[channel].out.out_conf0.out_rst_chn = 0; +} + +/** + * @brief Check if DMA TX FIFO is full + * @param fifo_level only supports level 1 + */ +static inline bool ahb_dma_ll_tx_is_fifo_full(ahb_dma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].out.outfifo_status.val & 0x01; +} + +/** + * @brief Check if DMA TX FIFO is empty + * @param fifo_level only supports level 1 + */ +static inline bool ahb_dma_ll_tx_is_fifo_empty(ahb_dma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].out.outfifo_status.val & 0x02; +} + +/** + * @brief Get number of bytes in TX FIFO + * @param fifo_level only supports level 1 + */ +static inline uint32_t ahb_dma_ll_tx_get_fifo_bytes(ahb_dma_dev_t *dev, uint32_t channel, uint32_t fifo_level) +{ + return dev->channel[channel].out.outfifo_status.outfifo_cnt_chn; +} + +/** + * @brief Push data into DMA TX FIFO + */ +static inline void ahb_dma_ll_tx_push_data(ahb_dma_dev_t *dev, uint32_t channel, uint32_t data) +{ + dev->channel[channel].out.out_push.outfifo_wdata_chn = data; + dev->channel[channel].out.out_push.outfifo_push_chn = 1; +} + +/** + * @brief Set the descriptor link base address for TX channel + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_tx_set_desc_addr(ahb_dma_dev_t *dev, uint32_t channel, uint32_t addr) +{ + dev->out_link_addr[channel].outlink_addr_chn = addr; +} + +/** + * @brief Start dealing with TX descriptors + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_tx_start(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_link.outlink_start_chn = 1; +} + +/** + * @brief Stop dealing with TX descriptors + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_tx_stop(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_link.outlink_stop_chn = 1; +} + +/** + * @brief Restart a new outlink right after the last descriptor + */ +__attribute__((always_inline)) +static inline void ahb_dma_ll_tx_restart(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_link.outlink_restart_chn = 1; +} + +/** + * @brief Check if DMA TX descriptor FSM is in IDLE state + */ +static inline bool ahb_dma_ll_tx_is_desc_fsm_idle(ahb_dma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].out.out_link.outlink_park_chn; +} + +/** + * @brief Get TX EOF descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t ahb_dma_ll_tx_get_eof_desc_addr(ahb_dma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].out.out_eof_des_addr.val; +} + +/** + * @brief Get the pre-fetched TX descriptor's address + */ +__attribute__((always_inline)) +static inline uint32_t ahb_dma_ll_tx_get_prefetched_desc_addr(ahb_dma_dev_t *dev, uint32_t channel) +{ + return dev->channel[channel].out.out_dscr.val; +} + +/** + * @brief Set priority for DMA TX channel + */ +static inline void ahb_dma_ll_tx_set_priority(ahb_dma_dev_t *dev, uint32_t channel, uint32_t prio) +{ + dev->channel[channel].out.out_pri.tx_pri_chn = prio; +} + +/** + * @brief Connect DMA TX channel to a given peripheral + */ +static inline void ahb_dma_ll_tx_connect_to_periph(ahb_dma_dev_t *dev, uint32_t channel, gdma_trigger_peripheral_t periph, int periph_id) +{ + (void)periph; + dev->channel[channel].out.out_peri_sel.peri_out_sel_chn = periph_id; +} + +/** + * @brief Disconnect DMA TX channel from peripheral + */ +static inline void ahb_dma_ll_tx_disconnect_from_periph(ahb_dma_dev_t *dev, uint32_t channel) +{ + dev->channel[channel].out.out_peri_sel.peri_out_sel_chn = AHB_DMA_LL_INVALID_PERIPH_ID; +} + +/** + * @brief Whether to enable the ETM subsystem for TX channel + * + * @note When ETM_EN is 1, only ETM tasks can be used to configure the transfer direction and enable the channel. + */ +static inline void ahb_dma_ll_tx_enable_etm_task(ahb_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->channel[channel].out.out_conf0.out_etm_en_chn = enable; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/adc_ll.h b/components/hal/esp32c6/include/hal/adc_ll.h index d7d689e74a6a..db51a869daa6 100644 --- a/components/hal/esp32c6/include/hal/adc_ll.h +++ b/components/hal/esp32c6/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -59,6 +59,7 @@ extern "C" { #define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 #define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 +#define ADC_LL_POWER_MANAGE_SUPPORTED 1 //ESP32C6 supported to manage power mode /*--------------------------------------------------------------- PWDET (Power Detect) ---------------------------------------------------------------*/ @@ -554,13 +555,33 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + PCR.saradc_conf.saradc_reg_clk_en = enable; +} + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + PCR.saradc_conf.saradc_reg_rst_en = 1; + PCR.saradc_conf.saradc_reg_rst_en = 0; +} + /** * Set ADC module power management. * * @param manage Set ADC power status. */ -static inline void adc_ll_set_power_manage(adc_ll_power_t manage) +static inline void adc_ll_set_power_manage(adc_unit_t adc_n, adc_ll_power_t manage) { + (void) adc_n; /* Bit1 0:Fsm 1: SW mode Bit0 0:SW mode power down 1: SW mode power on */ if (manage == ADC_LL_POWER_SW_ON) { diff --git a/components/hal/esp32c6/include/hal/apm_ll.h b/components/hal/esp32c6/include/hal/apm_ll.h index fc7b3fa4ce58..0288568707ca 100644 --- a/components/hal/esp32c6/include/hal/apm_ll.h +++ b/components/hal/esp32c6/include/hal/apm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,6 @@ #include "soc/hp_apm_reg.h" #include "soc/lp_apm_reg.h" #include "soc/interrupts.h" -#include "hal/assert.h" #ifdef __cplusplus extern "C" { @@ -41,68 +40,68 @@ extern "C" { #define APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION_FILTER_EN_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION_FILTER_EN_REG) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION_FILTER_EN_REG) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION_FILTER_EN_REG) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION_FILTER_EN_REG) : \ + (LP_APM_REGION_FILTER_EN_REG)); \ }) #define TEE_LL_MODE_CTRL_REG(master_id) (TEE_M0_MODE_CTRL_REG + 4 * (master_id)) #define APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ + (LP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num))); \ }) #define APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ + (LP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num))); \ }) #define APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : \ + (LP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num))); \ }) #define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ + (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path))); \ }) #define APM_CTRL_M_REGION_STATUS_CLR (BIT(0)) #define APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ + (LP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path))); \ }) #define APM_LL_TEE_EXCP_INFO0_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ + (LP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path))); \ }) #define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ + (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path))); \ }) #define APM_LL_TEE_EXCP_INFO1_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ + (LP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path))); \ }) #define APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms) ((regn_pms) << (4 * (sec_mode - 1))) @@ -111,24 +110,24 @@ extern "C" { #define APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_INT_EN_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_INT_EN_REG) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_INT_EN_REG) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_INT_EN_REG) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_INT_EN_REG) : \ + (LP_APM_INT_EN_REG)); \ }) #define APM_CTRL_CLK_EN (BIT(0)) #define APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl) \ ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_CLOCK_GATE_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_CLOCK_GATE_REG) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_CLOCK_GATE_REG) : 0)); \ + (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_CLOCK_GATE_REG) : \ + ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_CLOCK_GATE_REG) : \ + (LP_APM_CLOCK_GATE_REG)); \ }) #define APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl) \ ({\ (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_FUNC_CTRL_REG) : \ ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_FUNC_CTRL_REG) : \ - ((LP_APM_CTRL == apm_ctrl) ? (LP_APM_FUNC_CTRL_REG) : 0)); \ + (LP_APM_FUNC_CTRL_REG)); \ }) /** @@ -259,11 +258,6 @@ static inline void apm_ll_apm_ctrl_region_filter_enable(apm_ll_apm_ctrl_t apm_ct static inline void apm_ll_apm_ctrl_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path, bool enable) { - HAL_ASSERT(((apm_ctrl == LP_APM0_CTRL) && (apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || - ((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - if (enable) { REG_SET_BIT(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); } else { @@ -281,10 +275,6 @@ static inline void apm_ll_apm_ctrl_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, static inline void apm_ll_apm_ctrl_set_region_start_address(apm_ll_apm_ctrl_t apm_ctrl, uint32_t regn_num, uint32_t addr) { - HAL_ASSERT((((apm_ctrl == LP_APM0_CTRL) || (apm_ctrl == LP_APM_CTRL)) && (regn_num <= APM_LL_LP_MAX_REGION_NUM)) || - ((apm_ctrl == HP_APM_CTRL) && (regn_num <= APM_LL_HP_MAX_REGION_NUM)) - ); - REG_WRITE(APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num), addr); } @@ -298,10 +288,6 @@ static inline void apm_ll_apm_ctrl_set_region_start_address(apm_ll_apm_ctrl_t ap static inline void apm_ll_apm_ctrl_set_region_end_address(apm_ll_apm_ctrl_t apm_ctrl, uint32_t regn_num, uint32_t addr) { - HAL_ASSERT((((apm_ctrl == LP_APM0_CTRL) || (apm_ctrl == LP_APM_CTRL)) && (regn_num <= APM_LL_LP_MAX_REGION_NUM)) || - ((apm_ctrl == HP_APM_CTRL) && (regn_num <= APM_LL_HP_MAX_REGION_NUM)) - ); - REG_WRITE(APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num), addr); } @@ -316,10 +302,6 @@ static inline void apm_ll_apm_ctrl_set_region_end_address(apm_ll_apm_ctrl_t apm_ static inline void apm_ll_apm_ctrl_sec_mode_region_attr_config(apm_ll_apm_ctrl_t apm_ctrl, uint32_t regn_num, apm_ll_secure_mode_t sec_mode, uint32_t regn_pms) { - HAL_ASSERT((((apm_ctrl == LP_APM0_CTRL) || (apm_ctrl == LP_APM_CTRL)) && (regn_num <= APM_LL_LP_MAX_REGION_NUM)) || - ((apm_ctrl == HP_APM_CTRL) && (regn_num <= APM_LL_HP_MAX_REGION_NUM)) - ); - uint32_t val = 0; val = REG_READ(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num)); val &= ~APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode); @@ -336,11 +318,6 @@ static inline void apm_ll_apm_ctrl_sec_mode_region_attr_config(apm_ll_apm_ctrl_t static inline uint8_t apm_ll_apm_ctrl_exception_status(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) { - HAL_ASSERT(((apm_ctrl == LP_APM0_CTRL) && (apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || - ((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - return REG_READ(APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path)); } @@ -353,11 +330,6 @@ static inline uint8_t apm_ll_apm_ctrl_exception_status(apm_ll_apm_ctrl_t apm_ctr static inline void apm_ll_apm_ctrl_exception_clear(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) { - HAL_ASSERT(((apm_ctrl == LP_APM0_CTRL) && (apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || - ((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - REG_SET_BIT(APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path), APM_CTRL_M_REGION_STATUS_CLR); } @@ -370,11 +342,6 @@ static inline void apm_ll_apm_ctrl_exception_clear(apm_ll_apm_ctrl_t apm_ctrl, */ static inline void apm_ll_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t *excp_info) { - HAL_ASSERT(((excp_info->apm_path.apm_ctrl == LP_APM0_CTRL) && (excp_info->apm_path.apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || - ((excp_info->apm_path.apm_ctrl == HP_APM_CTRL) && (excp_info->apm_path.apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((excp_info->apm_path.apm_ctrl == LP_APM_CTRL) && (excp_info->apm_path.apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - excp_info->excp_id = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), APM_LL_CTRL_EXCEPTION_ID); excp_info->excp_mode = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), @@ -395,11 +362,6 @@ static inline void apm_ll_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t static inline void apm_ll_apm_ctrl_interrupt_enable(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path, bool enable) { - HAL_ASSERT(((apm_ctrl == LP_APM0_CTRL) && (apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || - ((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - if (enable) { REG_SET_BIT(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); } else { @@ -442,25 +404,20 @@ static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) } /** - * @brief Return APM Ctrl interrupt source number. + * @brief Fetch the APM Ctrl interrupt source number. * * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) * @param apm_m_path APM Ctrl access patch(M[0:n]) */ -static inline esp_err_t apm_ll_apm_ctrl_get_int_src_num(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) +static inline int apm_ll_apm_ctrl_get_int_src_num(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) { - HAL_ASSERT(((apm_ctrl == LP_APM0_CTRL) && (apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || - ((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - switch (apm_ctrl) { - case LP_APM0_CTRL : - return (ETS_LP_APM0_INTR_SOURCE); - case HP_APM_CTRL : - return (ETS_HP_APM_M0_INTR_SOURCE + apm_m_path); - case LP_APM_CTRL : - return (ETS_LP_APM_M0_INTR_SOURCE + apm_m_path); + case LP_APM0_CTRL : + return (ETS_LP_APM0_INTR_SOURCE); + case HP_APM_CTRL : + return (ETS_HP_APM_M0_INTR_SOURCE + apm_m_path); + case LP_APM_CTRL : + return (ETS_LP_APM_M0_INTR_SOURCE + apm_m_path); } return -1; diff --git a/components/hal/esp32c6/include/hal/brownout_ll.h b/components/hal/esp32c6/include/hal/brownout_ll.h index 032ada35ac2d..d5d46b333897 100644 --- a/components/hal/esp32c6/include/hal/brownout_ll.h +++ b/components/hal/esp32c6/include/hal/brownout_ll.h @@ -20,6 +20,8 @@ extern "C" { #endif +#define BROWNOUT_DETECTOR_LL_INTERRUPT_MASK (BIT(31)) + /** * @brief power down the flash when a brown out happens. * @@ -123,6 +125,16 @@ static inline void brownout_ll_clear_count(void) LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 0; } +/** + * @brief Get interrupt status register address + * + * @return Register address + */ +static inline volatile void *brownout_ll_intr_get_status_reg(void) +{ + return &LP_ANA_PERI.int_st; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/ecc_ll.h b/components/hal/esp32c6/include/hal/ecc_ll.h index c5e8799dcfb3..cb8b4ca2cd28 100644 --- a/components/hal/esp32c6/include/hal/ecc_ll.h +++ b/components/hal/esp32c6/include/hal/ecc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ #include "hal/ecc_types.h" #include "soc/ecc_mult_reg.h" #include "soc/pcr_struct.h" +#include "soc/pcr_reg.h" #ifdef __cplusplus extern "C" { @@ -41,6 +42,18 @@ static inline void ecc_ll_reset_register(void) PCR.ecc_conf.ecc_rst_en = 0; } +static inline void ecc_ll_power_up(void) +{ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD); +} + +static inline void ecc_ll_power_down(void) +{ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PU); + REG_SET_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); +} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32c6/include/hal/efuse_ll.h b/components/hal/esp32c6/include/hal/efuse_ll.h index fc687bc9decf..c7d5f4a0bbcd 100644 --- a/components/hal/esp32c6/include/hal/efuse_ll.h +++ b/components/hal/esp32c6/include/hal/efuse_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,15 @@ extern "C" { #endif +typedef enum { + EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state. + EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state. + EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state. + EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state. + EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state. + EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state. +} efuse_controller_state_t; + // Always inline these functions even no gcc optimization is applied. /******************* eFuse fields *************************/ @@ -175,6 +184,11 @@ __attribute__((always_inline)) static inline void efuse_ll_set_pwr_off_num(uint1 EFUSE.wr_tim_conf2.pwr_off_num = value; } +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void) +{ + return EFUSE.status.state; +} + /******************* eFuse control functions *************************/ #ifdef __cplusplus diff --git a/components/hal/esp32c6/include/hal/etm_ll.h b/components/hal/esp32c6/include/hal/etm_ll.h index a40dd68b1250..9a46f46a1daf 100644 --- a/components/hal/esp32c6/include/hal/etm_ll.h +++ b/components/hal/esp32c6/include/hal/etm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -98,7 +98,7 @@ static inline bool etm_ll_is_channel_enabled(soc_etm_dev_t *hw, uint32_t chan) */ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, uint32_t event) { - hw->channel[chan].evt_id.evt_id = event; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].eid, evt_id, event); } /** @@ -110,10 +110,10 @@ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, ui */ static inline void etm_ll_channel_set_task(soc_etm_dev_t *hw, uint32_t chan, uint32_t task) { - hw->channel[chan].task_id.task_id = task; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].tid, task_id, task); } -#define etm_ll_is_lpcore_wakeup_triggered() lp_aon_ll_get_lpcore_etm_wakeup_flag() +#define etm_ll_is_lpcore_wakeup_triggered() lp_aon_ll_get_lpcore_etm_wakeup_flag() #define etm_ll_clear_lpcore_wakeup_status() lp_aon_ll_clear_lpcore_etm_wakeup_flag() diff --git a/components/hal/esp32c6/include/hal/gdma_ll.h b/components/hal/esp32c6/include/hal/gdma_ll.h index 78dd95c5c3ab..2a168bb69246 100644 --- a/components/hal/esp32c6/include/hal/gdma_ll.h +++ b/components/hal/esp32c6/include/hal/gdma_ll.h @@ -51,6 +51,7 @@ extern "C" { #define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group #define GDMA_LL_AHB_DESC_ALIGNMENT 4 +#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 #define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ diff --git a/components/hal/esp32c6/include/hal/gpio_etm_ll.h b/components/hal/esp32c6/include/hal/gpio_etm_ll.h index eb311e09dc36..50b98b95a849 100644 --- a/components/hal/esp32c6/include/hal/gpio_etm_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_etm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,15 +22,20 @@ #define GPIO_LL_ETM_TASK_ID_CLR(ch) (GPIO_TASK_CH0_CLEAR + (ch)) #define GPIO_LL_ETM_TASK_ID_TOG(ch) (GPIO_TASK_CH0_TOGGLE + (ch)) +#define GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP 8 +#define GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP 8 + #ifdef __cplusplus extern "C" { #endif /** - * @brief Set which GPIO to be bounded to the event channel + * @brief Set which GPIO to be bound to the event channel + * + * @note Different channels can be bound to one GPIO * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint32_t chan, uint32_t gpio_num) @@ -39,10 +44,10 @@ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint3 } /** - * @brief Wether to enable the event channel + * @brief Whether to enable the event channel * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param enable True to enable, false to disable */ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_t chan, bool enable) @@ -51,12 +56,24 @@ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Set which GPIO to be bounded to the task channel + * @brief Get which GPIO is bound to the event channel + * + * @param dev Register base address + * @param chan GPIO ETM Event channel number + * @return GPIO number + */ +static inline uint32_t gpio_ll_etm_event_channel_get_gpio(gpio_etm_dev_t *dev, uint32_t chan) +{ + return dev->event_chn_cfg[chan].etm_chn_event_sel; +} + +/** + * @brief Set which GPIO to be bound to the task channel * - * @note One channel can be bounded to multiple different GPIOs + * @note One channel can be bound to multiple different GPIOs * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Task channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num, uint32_t chan) @@ -70,7 +87,7 @@ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32 } /** - * @brief Wether to enable the GPIO to be managed by the task channel + * @brief Whether to enable the GPIO to be managed by the task channel * * @param dev Register base address * @param gpio_num GPIO number @@ -101,7 +118,7 @@ static inline bool gpio_ll_etm_is_task_gpio_enabled(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Get the channel number that the GPIO is bounded to + * @brief Get the channel number that the GPIO is bound to * * @param dev Register base address * @param gpio_num GPIO number diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index 0b701fde4314..f227cf6850ca 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -90,6 +90,15 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) { + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + // Note that esp32c6 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin + // which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead. + // TODO: read the specific efuse with efuse_ll.h + if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { + SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); + } REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU); } @@ -113,15 +122,6 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) { - // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value - // USB DP pin is default to PU enabled - // Note that esp32c6 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin - // which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead. - // TODO: read the specific efuse with efuse_ll.h - if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { - SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); - CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); - } REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD); } @@ -395,6 +395,7 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) { LP_AON.gpio_hold0.gpio_hold0 |= GPIO_HOLD_MASK[gpio_num]; @@ -406,6 +407,7 @@ static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num) { LP_AON.gpio_hold0.gpio_hold0 &= ~GPIO_HOLD_MASK[gpio_num]; diff --git a/components/hal/esp32c6/include/hal/gpspi_flash_ll.h b/components/hal/esp32c6/include/hal/gpspi_flash_ll.h index 4206665f6a69..73d64db653b9 100644 --- a/components/hal/esp32c6/include/hal/gpspi_flash_ll.h +++ b/components/hal/esp32c6/include/hal/gpspi_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -366,6 +366,20 @@ static inline void gpspi_flash_ll_set_dummy(spi_dev_t *dev, uint32_t dummy_n) HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user1, usr_dummy_cyclelen, dummy_n - 1); } +/** + * Set D/Q output level during dummy phase + * + * @param dev Beginning address of the peripheral registers. + * @param out_en whether to enable IO output for dummy phase + * @param out_level dummy output level + */ +static inline void gpspi_flash_ll_set_dummy_out(spi_dev_t *dev, uint32_t out_en, uint32_t out_lev) +{ + dev->ctrl.dummy_out = out_en; + dev->ctrl.q_pol = out_lev; + dev->ctrl.d_pol = out_lev; +} + /** * Set extra hold time of CS after the clocks. * diff --git a/components/hal/esp32c6/include/hal/lp_core_ll.h b/components/hal/esp32c6/include/hal/lp_core_ll.h index 7c6c5667ef57..7ac68a963281 100644 --- a/components/hal/esp32c6/include/hal/lp_core_ll.h +++ b/components/hal/esp32c6/include/hal/lp_core_ll.h @@ -12,6 +12,7 @@ #pragma once #include +#include #include "soc/lpperi_struct.h" #include "soc/pmu_struct.h" #include "soc/lp_aon_struct.h" @@ -125,6 +126,16 @@ static inline void lp_core_ll_request_sleep(void) PMU.lp_ext.pwr1.sleep_req = 1; } +/** + * @brief Get which interrupts have triggered on the LP core + * + * @return uint8_t bit mask of triggered LP interrupt sources + */ +static inline uint8_t lp_core_ll_get_triggered_interrupt_srcs(void) +{ + return LPPERI.interrupt_source.lp_interrupt_source; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/lp_timer_ll.h b/components/hal/esp32c6/include/hal/lp_timer_ll.h index 968366febd95..080555bd8999 100644 --- a/components/hal/esp32c6/include/hal/lp_timer_ll.h +++ b/components/hal/esp32c6/include/hal/lp_timer_ll.h @@ -15,6 +15,7 @@ #include "soc/lp_timer_reg.h" #include "soc/lp_aon_reg.h" #include "hal/lp_timer_types.h" +#include "hal/misc.h" #include "esp_attr.h" #ifdef __cplusplus @@ -23,8 +24,8 @@ extern "C" { FORCE_INLINE_ATTR void lp_timer_ll_set_alarm_target(lp_timer_dev_t *dev, uint8_t timer_id, uint64_t value) { - dev->target[timer_id].hi.target_hi = (value >> 32) & 0xFFFF; - dev->target[timer_id].lo.target_lo = value & 0xFFFFFFFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].hi, target_hi, (value >> 32) & 0xFFFF); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].lo, target_lo, value & 0xFFFFFFFF); } FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_t timer_id, bool en) @@ -34,12 +35,12 @@ FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_ FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev, uint8_t buffer_id) { - return dev->counter[buffer_id].lo.counter_lo; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[buffer_id].lo, counter_lo); } FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_high(lp_timer_dev_t *dev, uint8_t buffer_id) { - return dev->counter[buffer_id].hi.counter_hi; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[buffer_id].hi, counter_hi); } FORCE_INLINE_ATTR void lp_timer_ll_counter_snapshot(lp_timer_dev_t *dev) diff --git a/components/hal/esp32c6/include/hal/mmu_ll.h b/components/hal/esp32c6/include/hal/mmu_ll.h index 8637909bde78..0d570f7e87ae 100644 --- a/components/hal/esp32c6/include/hal/mmu_ll.h +++ b/components/hal/esp32c6/include/hal/mmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,9 @@ extern "C" { #endif +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_MMU_PAGE_SIZE) +#define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1) + /** * Convert MMU virtual address to linear address * @@ -275,7 +278,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32c6/include/hal/mpi_ll.h b/components/hal/esp32c6/include/hal/mpi_ll.h index 032ac17b47e8..dbb0af113226 100644 --- a/components/hal/esp32c6/include/hal/mpi_ll.h +++ b/components/hal/esp32c6/include/hal/mpi_ll.h @@ -49,11 +49,15 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words) static inline void mpi_ll_clear_power_control_bit(void) { + /* Power up the MPI peripheral */ REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); + REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PD); } static inline void mpi_ll_set_power_control_bit(void) { + /* Power down the MPI peripheral */ + REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PU); REG_SET_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); } diff --git a/components/hal/esp32c6/include/hal/pmu_ll.h b/components/hal/esp32c6/include/hal/pmu_ll.h index 2470f73247cf..c203ab021f6b 100644 --- a/components/hal/esp32c6/include/hal/pmu_ll.h +++ b/components/hal/esp32c6/include/hal/pmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include "hal/assert.h" #include "soc/pmu_struct.h" #include "hal/pmu_types.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -488,7 +489,7 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode) FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.hp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, hp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw) @@ -541,29 +542,39 @@ FORCE_INLINE_ATTR void pmu_ll_lp_clear_intsts_mask(pmu_dev_t *hw, uint32_t mask) hw->lp_ext.int_clr.val = mask; } +FORCE_INLINE_ATTR void pmu_ll_lp_clear_sw_intr_status(pmu_dev_t *hw) +{ + hw->lp_ext.int_clr.sw_trigger = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_enable_sw_intr(pmu_dev_t *hw, bool enable) +{ + hw->lp_ext.int_ena.sw_trigger = enable; +} + FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, lp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.modify_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.switch_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -588,12 +599,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target, slow_clk_cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl5.lp_ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_set_modem_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -608,22 +619,22 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_get_modem_wait_target_cycle(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_xtal_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_xtal_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable); } FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_pll_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_pll_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable); } FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -648,12 +659,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t * FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->wakeup.cntl7.ana_wait_target = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl7.ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) diff --git a/components/hal/esp32c6/include/hal/rmt_ll.h b/components/hal/esp32c6/include/hal/rmt_ll.h index f2da58d41516..8d1d4afbb7f1 100644 --- a/components/hal/esp32c6/include/hal/rmt_ll.h +++ b/components/hal/esp32c6/include/hal/rmt_ll.h @@ -79,15 +79,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -433,7 +454,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, * * @param dev Peripheral instance address * @param channel RMT TX channel number - * @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data + * @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data */ static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable) { @@ -664,7 +685,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e * @brief Clear RMT interrupt status by mask * * @param dev Peripheral instance address - * @param mask Interupt status mask + * @param mask Interrupt status mask */ __attribute__((always_inline)) static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask) @@ -818,12 +839,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32c6/include/hal/rtc_io_ll.h b/components/hal/esp32c6/include/hal/rtc_io_ll.h index 550d6accf06d..0cd64df36d5d 100644 --- a/components/hal/esp32c6/include/hal/rtc_io_ll.h +++ b/components/hal/esp32c6/include/hal/rtc_io_ll.h @@ -40,6 +40,15 @@ typedef enum { RTCIO_LL_WAKEUP_HIGH_LEVEL = 0x5, /*!< GPIO interrupt type : input high level trigger */ } rtcio_ll_wake_type_t; +typedef enum { + RTCIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */ + RTCIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */ + RTCIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */ + RTCIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */ + RTCIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */ + RTCIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */ +} rtcio_ll_intr_type_t; + typedef enum { RTCIO_LL_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */ RTCIO_LL_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */ @@ -59,11 +68,14 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func) /** * @brief Enable/Disable LP_IO peripheral clock. * - * @param enable true to enable the clock / false to enable the clock + * @param enable true to enable the clock / false to disable the clock */ static inline void _rtcio_ll_enable_io_clock(bool enable) { LPPERI.clk_en.lp_io_ck_en = enable; + while (LPPERI.clk_en.lp_io_ck_en != enable) { + ; + } } #define rtcio_ll_enable_io_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _rtcio_ll_enable_io_clock(__VA_ARGS__) @@ -83,9 +95,6 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) if (func == RTCIO_LL_FUNC_RTC) { // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); - if ((sel_mask & SOC_RTCIO_VALID_RTCIO_MASK) == 0) { - _rtcio_ll_enable_io_clock(true); - } sel_mask |= BIT(rtcio_num); HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); //0:RTC FUNCTION 1,2,3:Reserved @@ -95,9 +104,6 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); sel_mask &= ~BIT(rtcio_num); HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); - if ((sel_mask & SOC_RTCIO_VALID_RTCIO_MASK) == 0) { - _rtcio_ll_enable_io_clock(false); - } } } @@ -316,6 +322,24 @@ static inline void rtcio_ll_wakeup_disable(int rtcio_num) LP_IO.pin[rtcio_num].int_type = RTCIO_LL_WAKEUP_DISABLE; } +/** + * Enable interrupt function and set interrupt type + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param type Interrupt type on high level or low level. + */ + +static inline void rtcio_ll_intr_enable(int rtcio_num, rtcio_ll_intr_type_t type) +{ + LP_IO.pin[rtcio_num].int_type = type; + + /* Work around for HW issue, + need to also enable this clk, so that LP_IO.status.status_interrupt can get updated, + and trigger the interrupt on the LP Core + */ + LP_IO.date.clk_en = 1; +} + /** * Enable rtc io output in deep sleep. * diff --git a/components/hal/esp32c6/include/hal/sdio_slave_ll.h b/components/hal/esp32c6/include/hal/sdio_slave_ll.h index 97c4b544100d..2831edd57bce 100644 --- a/components/hal/esp32c6/include/hal/sdio_slave_ll.h +++ b/components/hal/esp32c6/include/hal/sdio_slave_ll.h @@ -17,6 +17,7 @@ #pragma once #include "hal/sdio_slave_types.h" +#include "hal/misc.h" #include "soc/slc_struct.h" #include "soc/slc_reg.h" #include "soc/host_struct.h" @@ -503,7 +504,7 @@ static inline void sdio_slave_ll_host_send_int(slc_dev_t *slc, const sdio_slave_ { //use registers in SLC to trigger, rather than write HOST registers directly //other interrupts than tohost interrupts are not supported yet - slc->slcintvec_tohost.slc0_tohost_intvec = (*mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(slc->slcintvec_tohost, slc0_tohost_intvec, *mask); } /** diff --git a/components/hal/esp32c6/include/hal/uart_ll.h b/components/hal/esp32c6/include/hal/uart_ll.h index 88759dde2e6d..cbbf308bdc7d 100644 --- a/components/hal/esp32c6/include/hal/uart_ll.h +++ b/components/hal/esp32c6/include/hal/uart_ll.h @@ -61,6 +61,10 @@ extern "C" { #define UART_LL_PCR_REG_GET(hw, reg_suffix, field_suffix) \ (((hw) == &UART0) ? PCR.uart0_##reg_suffix.uart0_##field_suffix : PCR.uart1_##reg_suffix.uart1_##field_suffix) +// UART sleep retention module +#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \ + (uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1) + // Define UART interrupts typedef enum { UART_INTR_RXFIFO_FULL = (0x1 << 0), @@ -704,7 +708,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -771,7 +775,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -1102,7 +1106,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32c6/include/hal/uhci_ll.h b/components/hal/esp32c6/include/hal/uhci_ll.h new file mode 100644 index 000000000000..07d4a40a6835 --- /dev/null +++ b/components/hal/esp32c6/include/hal/uhci_ll.h @@ -0,0 +1,133 @@ +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include "hal/uhci_types.h" +#include "soc/uhci_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UHCI_LL_GET_HW(num) (((num) == 0) ? (&UHCI0) : (NULL)) + +typedef enum { + UHCI_RX_BREAK_CHR_EOF = 0x1, + UHCI_RX_IDLE_EOF = 0x2, + UHCI_RX_LEN_EOF = 0x4, + UHCI_RX_EOF_MAX = 0x7, +} uhci_rxeof_cfg_t; + +static inline void uhci_ll_init(uhci_dev_t *hw) +{ + typeof(hw->conf0) conf0_reg; + hw->conf0.clk_en = 1; + conf0_reg.val = 0; + conf0_reg.clk_en = 1; + hw->conf0.val = conf0_reg.val; + hw->conf1.val = 0; +} + +static inline void uhci_ll_attach_uart_port(uhci_dev_t *hw, int uart_num) +{ + hw->conf0.uart0_ce = (uart_num == 0)? 1: 0; + hw->conf0.uart1_ce = (uart_num == 1)? 1: 0; +} + +static inline void uhci_ll_set_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_char) +{ + if (seper_char->sub_chr_en) { + typeof(hw->esc_conf0) esc_conf0_reg; + esc_conf0_reg.val = hw->esc_conf0.val; + + esc_conf0_reg.seper_char = seper_char->seper_chr; + esc_conf0_reg.seper_esc_char0 = seper_char->sub_chr1; + esc_conf0_reg.seper_esc_char1 = seper_char->sub_chr2; + hw->esc_conf0.val = esc_conf0_reg.val; + hw->escape_conf.tx_c0_esc_en = 1; + hw->escape_conf.rx_c0_esc_en = 1; + } else { + hw->escape_conf.tx_c0_esc_en = 0; + hw->escape_conf.rx_c0_esc_en = 0; + } +} + +static inline void uhci_ll_get_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_chr) +{ + (void)hw; + (void)seper_chr; +} + +static inline void uhci_ll_set_swflow_ctrl_sub_chr(uhci_dev_t *hw, uhci_swflow_ctrl_sub_chr_t *sub_ctr) +{ + typeof(hw->escape_conf) escape_conf_reg; + escape_conf_reg.val = hw->escape_conf.val; + + if (sub_ctr->flow_en == 1) { + typeof(hw->esc_conf2) esc_conf2_reg; + esc_conf2_reg.val = hw->esc_conf2.val; + typeof(hw->esc_conf3) esc_conf3_reg; + esc_conf3_reg.val = hw->esc_conf3.val; + + esc_conf2_reg.esc_seq1 = sub_ctr->xon_chr; + esc_conf2_reg.esc_seq1_char0 = sub_ctr->xon_sub1; + esc_conf2_reg.esc_seq1_char1 = sub_ctr->xon_sub2; + esc_conf3_reg.esc_seq2 = sub_ctr->xoff_chr; + esc_conf3_reg.esc_seq2_char0 = sub_ctr->xoff_sub1; + esc_conf3_reg.esc_seq2_char1 = sub_ctr->xoff_sub2; + escape_conf_reg.tx_11_esc_en = 1; + escape_conf_reg.tx_13_esc_en = 1; + escape_conf_reg.rx_11_esc_en = 1; + escape_conf_reg.rx_13_esc_en = 1; + hw->esc_conf2.val = esc_conf2_reg.val; + hw->esc_conf3.val = esc_conf3_reg.val; + } else { + escape_conf_reg.tx_11_esc_en = 0; + escape_conf_reg.tx_13_esc_en = 0; + escape_conf_reg.rx_11_esc_en = 0; + escape_conf_reg.rx_13_esc_en = 0; + } + hw->escape_conf.val = escape_conf_reg.val; +} + +static inline void uhci_ll_enable_intr(uhci_dev_t *hw, uint32_t intr_mask) +{ + hw->int_ena.val |= intr_mask; +} + +static inline void uhci_ll_disable_intr(uhci_dev_t *hw, uint32_t intr_mask) +{ + hw->int_ena.val &= (~intr_mask); +} + +static inline void uhci_ll_clear_intr(uhci_dev_t *hw, uint32_t intr_mask) +{ + hw->int_clr.val = intr_mask; +} + +static inline uint32_t uhci_ll_get_intr(uhci_dev_t *hw) +{ + return hw->int_st.val; +} + + +static inline void uhci_ll_set_eof_mode(uhci_dev_t *hw, uint32_t eof_mode) +{ + if (eof_mode & UHCI_RX_BREAK_CHR_EOF) { + hw->conf0.uart_rx_brk_eof_en = 1; + } + if (eof_mode & UHCI_RX_IDLE_EOF) { + hw->conf0.uart_idle_eof_en = 1; + } + if (eof_mode & UHCI_RX_LEN_EOF) { + hw->conf0.len_eof_en = 1; + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h index 56b44d0a1ac7..d9aa7e58fa1b 100644 --- a/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h @@ -16,6 +16,7 @@ /* ----------------------------- Macros & Types ----------------------------- */ #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask +#define USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL (1) // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging diff --git a/components/hal/esp32c61/include/hal/cache_ll.h b/components/hal/esp32c61/include/hal/cache_ll.h index 2fe9c67658b3..09306b154117 100644 --- a/components/hal/esp32c61/include/hal/cache_ll.h +++ b/components/hal/esp32c61/include/hal/cache_ll.h @@ -168,7 +168,7 @@ __attribute__((always_inline)) static inline uint32_t cache_ll_get_line_size(uint32_t cache_level, cache_type_t type, uint32_t cache_id) { uint32_t size = 0; - size = Cache_Get_Cache_Line_Size(); + size = Cache_Get_Line_Size(); return size; } diff --git a/components/hal/esp32c61/include/hal/efuse_ll.h b/components/hal/esp32c61/include/hal/efuse_ll.h index 1c5238d2e6cc..c219dc2999b4 100644 --- a/components/hal/esp32c61/include/hal/efuse_ll.h +++ b/components/hal/esp32c61/include/hal/efuse_ll.h @@ -84,6 +84,16 @@ __attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_ver_pkg( return (uint32_t)0; } +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_ecdsa_key_blk(void) +{ + return EFUSE0.conf.cfg_ecdsa_blk; +} + +__attribute__((always_inline)) static inline void efuse_ll_set_ecdsa_key_blk(int efuse_blk) +{ + EFUSE0.conf.cfg_ecdsa_blk = efuse_blk; +} + /******************* eFuse control functions *************************/ __attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void) @@ -137,6 +147,11 @@ __attribute__((always_inline)) static inline void efuse_ll_set_pwr_off_num(uint1 EFUSE0.wr_tim_conf2.pwr_off_num = value; } +__attribute__((always_inline)) static inline void efuse_ll_rs_bypass_update(void) +{ + EFUSE0.wr_tim_conf0_rs_bypass.update = 1; +} + /******************* eFuse control functions *************************/ #ifdef __cplusplus diff --git a/components/hal/esp32c61/include/hal/gpio_ll.h b/components/hal/esp32c61/include/hal/gpio_ll.h index 743b72952ef1..d4c5ac80eb9e 100644 --- a/components/hal/esp32c61/include/hal/gpio_ll.h +++ b/components/hal/esp32c61/include/hal/gpio_ll.h @@ -396,6 +396,7 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) { LP_AON.gpio_hold0.gpio_hold0 |= GPIO_HOLD_MASK[gpio_num]; @@ -407,6 +408,7 @@ static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num) { LP_AON.gpio_hold0.gpio_hold0 &= ~GPIO_HOLD_MASK[gpio_num]; diff --git a/components/hal/esp32c61/include/hal/gpspi_flash_ll.h b/components/hal/esp32c61/include/hal/gpspi_flash_ll.h index f0bfd56982f8..92620c7f750a 100644 --- a/components/hal/esp32c61/include/hal/gpspi_flash_ll.h +++ b/components/hal/esp32c61/include/hal/gpspi_flash_ll.h @@ -368,6 +368,20 @@ static inline void gpspi_flash_ll_set_dummy(spi_dev_t *dev, uint32_t dummy_n) HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user1, usr_dummy_cyclelen, dummy_n - 1); } +/** + * Set D/Q output level during dummy phase + * + * @param dev Beginning address of the peripheral registers. + * @param out_en whether to enable IO output for dummy phase + * @param out_level dummy output level + */ +static inline void gpspi_flash_ll_set_dummy_out(spi_dev_t *dev, uint32_t out_en, uint32_t out_lev) +{ + dev->ctrl.dummy_out = out_en; + dev->ctrl.q_pol = out_lev; + dev->ctrl.d_pol = out_lev; +} + /** * Set extra hold time of CS after the clocks. * diff --git a/components/hal/esp32c61/include/hal/mmu_ll.h b/components/hal/esp32c61/include/hal/mmu_ll.h index f59cf5aa7562..44aac374f6e7 100644 --- a/components/hal/esp32c61/include/hal/mmu_ll.h +++ b/components/hal/esp32c61/include/hal/mmu_ll.h @@ -20,6 +20,9 @@ extern "C" { #endif +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_MMU_PAGE_SIZE) +#define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1) + /** * Convert MMU virtual address to linear address * @@ -277,7 +280,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32c61/include/hal/pmu_ll.h b/components/hal/esp32c61/include/hal/pmu_ll.h index a70c8419b24b..85a8c0d3f91d 100644 --- a/components/hal/esp32c61/include/hal/pmu_ll.h +++ b/components/hal/esp32c61/include/hal/pmu_ll.h @@ -15,6 +15,7 @@ #include "hal/assert.h" #include "soc/pmu_struct.h" #include "hal/pmu_types.h" +#include "hal/misc.h" // TODO: [ESP32C61] IDF-9250, inherit from c6 @@ -490,7 +491,7 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode) FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.hp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, hp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw) @@ -545,27 +546,27 @@ FORCE_INLINE_ATTR void pmu_ll_lp_clear_intsts_mask(pmu_dev_t *hw, uint32_t mask) FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, lp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.modify_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.switch_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -590,12 +591,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target, slow_clk_cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl5.lp_ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_set_modem_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -610,22 +611,22 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_get_modem_wait_target_cycle(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_xtal_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_xtal_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable); } FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_pll_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_pll_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable); } FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -650,12 +651,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t * FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->wakeup.cntl7.ana_wait_target = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl7.ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) diff --git a/components/hal/esp32c61/include/hal/uart_ll.h b/components/hal/esp32c61/include/hal/uart_ll.h index bb7873e317f7..fb2dc72b8582 100644 --- a/components/hal/esp32c61/include/hal/uart_ll.h +++ b/components/hal/esp32c61/include/hal/uart_ll.h @@ -556,7 +556,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -623,7 +623,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -929,7 +929,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index dd9c8113798b..8c02ddd191d2 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,6 +60,7 @@ extern "C" { #define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 #define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 +#define ADC_LL_POWER_MANAGE_SUPPORTED 1 //ESP32H2 supported to manage power mode /*--------------------------------------------------------------- PWDET (Power Detect) ---------------------------------------------------------------*/ @@ -555,13 +556,32 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + PCR.saradc_conf.saradc_reg_clk_en = enable; +} + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + PCR.saradc_conf.saradc_reg_rst_en = 1; + PCR.saradc_conf.saradc_reg_rst_en = 0; +} /** * Set ADC module power management. * * @param manage Set ADC power status. */ -static inline void adc_ll_set_power_manage(adc_ll_power_t manage) +static inline void adc_ll_set_power_manage(adc_unit_t adc_n, adc_ll_power_t manage) { + (void) adc_n; /* Bit1 0:Fsm 1: SW mode Bit0 0:SW mode power down 1: SW mode power on */ if (manage == ADC_LL_POWER_SW_ON) { diff --git a/components/hal/esp32h2/include/hal/apm_ll.h b/components/hal/esp32h2/include/hal/apm_ll.h index b95effad6979..cc0046ce2740 100644 --- a/components/hal/esp32h2/include/hal/apm_ll.h +++ b/components/hal/esp32h2/include/hal/apm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,6 @@ #include "soc/hp_apm_reg.h" #include "soc/lp_apm_reg.h" #include "soc/interrupts.h" -#include "hal/assert.h" #ifdef __cplusplus extern "C" { @@ -39,59 +38,59 @@ extern "C" { #define APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION_FILTER_EN_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION_FILTER_EN_REG) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION_FILTER_EN_REG) : \ + (HP_APM_REGION_FILTER_EN_REG); \ }) #define TEE_LL_MODE_CTRL_REG(master_id) (TEE_M0_MODE_CTRL_REG + 4 * (master_id)) #define APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ + (HP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)); \ }) #define APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ + (HP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)); \ }) #define APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : \ + (HP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)); \ }) #define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ + (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)); \ }) #define APM_CTRL_M_REGION_STATUS_CLR (BIT(0)) #define APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ + (HP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)); \ }) #define APM_LL_TEE_EXCP_INFO0_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ + (HP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)); \ }) #define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ + (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)); \ }) #define APM_LL_TEE_EXCP_INFO1_REG(apm_ctrl, apm_m_path) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ + (HP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)); \ }) #define APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms) ((regn_pms) << (4 * (sec_mode - 1))) @@ -100,21 +99,21 @@ extern "C" { #define APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_INT_EN_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_INT_EN_REG) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_INT_EN_REG) : \ + (HP_APM_INT_EN_REG); \ }) #define APM_CTRL_CLK_EN (BIT(0)) #define APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_CLOCK_GATE_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_CLOCK_GATE_REG) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_CLOCK_GATE_REG) : \ + (HP_APM_CLOCK_GATE_REG); \ }) #define APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl) \ ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_FUNC_CTRL_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_FUNC_CTRL_REG) : 0); \ + (LP_APM_CTRL == apm_ctrl) ? (LP_APM_FUNC_CTRL_REG) : \ + (HP_APM_FUNC_CTRL_REG); \ }) /** @@ -242,10 +241,6 @@ static inline void apm_ll_apm_ctrl_region_filter_enable(apm_ll_apm_ctrl_t apm_ct static inline void apm_ll_apm_ctrl_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path, bool enable) { - HAL_ASSERT(((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - if (enable) { REG_SET_BIT(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); } else { @@ -263,10 +258,6 @@ static inline void apm_ll_apm_ctrl_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, static inline void apm_ll_apm_ctrl_set_region_start_address(apm_ll_apm_ctrl_t apm_ctrl, uint32_t regn_num, uint32_t addr) { - HAL_ASSERT(((apm_ctrl == LP_APM_CTRL) && (regn_num <= APM_LL_LP_MAX_REGION_NUM)) || - ((apm_ctrl == HP_APM_CTRL) && (regn_num <= APM_LL_HP_MAX_REGION_NUM)) - ); - REG_WRITE(APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num), addr); } @@ -280,10 +271,6 @@ static inline void apm_ll_apm_ctrl_set_region_start_address(apm_ll_apm_ctrl_t ap static inline void apm_ll_apm_ctrl_set_region_end_address(apm_ll_apm_ctrl_t apm_ctrl, uint32_t regn_num, uint32_t addr) { - HAL_ASSERT(((apm_ctrl == LP_APM_CTRL) && (regn_num <= APM_LL_LP_MAX_REGION_NUM)) || - ((apm_ctrl == HP_APM_CTRL) && (regn_num <= APM_LL_HP_MAX_REGION_NUM)) - ); - REG_WRITE(APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num), addr); } @@ -298,10 +285,6 @@ static inline void apm_ll_apm_ctrl_set_region_end_address(apm_ll_apm_ctrl_t apm_ static inline void apm_ll_apm_ctrl_sec_mode_region_attr_config(apm_ll_apm_ctrl_t apm_ctrl, uint32_t regn_num, apm_ll_secure_mode_t sec_mode, uint32_t regn_pms) { - HAL_ASSERT(((apm_ctrl == LP_APM_CTRL) && (regn_num <= APM_LL_LP_MAX_REGION_NUM)) || - ((apm_ctrl == HP_APM_CTRL) && (regn_num <= APM_LL_HP_MAX_REGION_NUM)) - ); - uint32_t val = 0; val = REG_READ(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num)); val &= ~APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode); @@ -318,10 +301,6 @@ static inline void apm_ll_apm_ctrl_sec_mode_region_attr_config(apm_ll_apm_ctrl_t static inline uint8_t apm_ll_apm_ctrl_exception_status(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) { - HAL_ASSERT(((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - return REG_READ(APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path)); } @@ -334,10 +313,6 @@ static inline uint8_t apm_ll_apm_ctrl_exception_status(apm_ll_apm_ctrl_t apm_ctr static inline void apm_ll_apm_ctrl_exception_clear(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) { - HAL_ASSERT(((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - REG_SET_BIT(APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path), APM_CTRL_M_REGION_STATUS_CLR); } @@ -350,10 +325,6 @@ static inline void apm_ll_apm_ctrl_exception_clear(apm_ll_apm_ctrl_t apm_ctrl, */ static inline void apm_ll_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t *excp_info) { - HAL_ASSERT(((excp_info->apm_path.apm_ctrl == HP_APM_CTRL) && (excp_info->apm_path.apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((excp_info->apm_path.apm_ctrl == LP_APM_CTRL) && (excp_info->apm_path.apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - excp_info->excp_id = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), APM_LL_CTRL_EXCEPTION_ID); excp_info->excp_mode = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), @@ -374,10 +345,6 @@ static inline void apm_ll_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t static inline void apm_ll_apm_ctrl_interrupt_enable(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path, bool enable) { - HAL_ASSERT(((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - if (enable) { REG_SET_BIT(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); } else { @@ -420,22 +387,18 @@ static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) } /** - * @brief Return APM Ctrl interrupt source number. + * @brief Fetch the APM Ctrl interrupt source number. * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) + * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) * @param apm_m_path APM Ctrl access patch(M[0:n]) */ -static inline esp_err_t apm_ll_apm_ctrl_get_int_src_num(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) +static inline int apm_ll_apm_ctrl_get_int_src_num(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) { - HAL_ASSERT(((apm_ctrl == HP_APM_CTRL) && (apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_ctrl == LP_APM_CTRL) && (apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - switch (apm_ctrl) { - case HP_APM_CTRL : - return (ETS_HP_APM_M0_INTR_SOURCE + apm_m_path); - case LP_APM_CTRL : - return (ETS_LP_APM_M0_INTR_SOURCE); + case HP_APM_CTRL : + return (ETS_HP_APM_M0_INTR_SOURCE + apm_m_path); + case LP_APM_CTRL : + return (ETS_LP_APM_M0_INTR_SOURCE + apm_m_path); } return -1; diff --git a/components/hal/esp32h2/include/hal/brownout_ll.h b/components/hal/esp32h2/include/hal/brownout_ll.h index f0b3d63263e3..5ee9dcb73e7a 100644 --- a/components/hal/esp32h2/include/hal/brownout_ll.h +++ b/components/hal/esp32h2/include/hal/brownout_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,8 @@ extern "C" { #endif +#define BROWNOUT_DETECTOR_LL_INTERRUPT_MASK (BIT(31)) + /** * @brief power down the flash when a brown out happens. * @@ -124,6 +126,16 @@ static inline void brownout_ll_clear_count(void) LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 0; } +/** + * @brief Get interrupt status register address + * + * @return Register address + */ +static inline volatile void *brownout_ll_intr_get_status_reg(void) +{ + return &LP_ANA_PERI.int_st; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/ecc_ll.h b/components/hal/esp32h2/include/hal/ecc_ll.h index 47d4e8b9e6a5..46667692a700 100644 --- a/components/hal/esp32h2/include/hal/ecc_ll.h +++ b/components/hal/esp32h2/include/hal/ecc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ #include "hal/ecc_types.h" #include "soc/ecc_mult_reg.h" #include "soc/pcr_struct.h" +#include "soc/pcr_reg.h" #ifdef __cplusplus extern "C" { @@ -47,6 +48,18 @@ static inline void ecc_ll_reset_register(void) PCR.ecdsa_conf.ecdsa_rst_en = 0; } +static inline void ecc_ll_power_up(void) +{ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD); +} + +static inline void ecc_ll_power_down(void) +{ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PU); + REG_SET_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); +} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32h2/include/hal/etm_ll.h b/components/hal/esp32h2/include/hal/etm_ll.h index 9d341ae2ed76..210933eaba00 100644 --- a/components/hal/esp32h2/include/hal/etm_ll.h +++ b/components/hal/esp32h2/include/hal/etm_ll.h @@ -97,7 +97,7 @@ static inline bool etm_ll_is_channel_enabled(soc_etm_dev_t *hw, uint32_t chan) */ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, uint32_t event) { - hw->channel[chan].evt_id.evt_id = event; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].eid, evt_id, event); } /** @@ -109,7 +109,7 @@ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, ui */ static inline void etm_ll_channel_set_task(soc_etm_dev_t *hw, uint32_t chan, uint32_t task) { - hw->channel[chan].task_id.task_id = task; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].tid, task_id, task); } #ifdef __cplusplus diff --git a/components/hal/esp32h2/include/hal/gdma_ll.h b/components/hal/esp32h2/include/hal/gdma_ll.h index 78dd95c5c3ab..2a168bb69246 100644 --- a/components/hal/esp32h2/include/hal/gdma_ll.h +++ b/components/hal/esp32h2/include/hal/gdma_ll.h @@ -51,6 +51,7 @@ extern "C" { #define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group #define GDMA_LL_AHB_DESC_ALIGNMENT 4 +#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 #define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ diff --git a/components/hal/esp32h2/include/hal/gpio_etm_ll.h b/components/hal/esp32h2/include/hal/gpio_etm_ll.h index 57101ba37fd6..49281c3366ff 100644 --- a/components/hal/esp32h2/include/hal/gpio_etm_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_etm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,15 +22,20 @@ #define GPIO_LL_ETM_TASK_ID_CLR(ch) (GPIO_TASK_CH0_CLEAR + (ch)) #define GPIO_LL_ETM_TASK_ID_TOG(ch) (GPIO_TASK_CH0_TOGGLE + (ch)) +#define GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP 8 +#define GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP 8 + #ifdef __cplusplus extern "C" { #endif /** - * @brief Set which GPIO to be bounded to the event channel + * @brief Set which GPIO to be bound to the event channel + * + * @note Different channels can be bound to one GPIO * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint32_t chan, uint32_t gpio_num) @@ -39,10 +44,10 @@ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint3 } /** - * @brief Wether to enable the event channel + * @brief Whether to enable the event channel * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param enable True to enable, false to disable */ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_t chan, bool enable) @@ -51,12 +56,24 @@ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Set which GPIO to be bounded to the task channel + * @brief Get which GPIO is bound to the event channel + * + * @param dev Register base address + * @param chan GPIO ETM Event channel number + * @return GPIO number + */ +static inline uint32_t gpio_ll_etm_event_channel_get_gpio(gpio_etm_dev_t *dev, uint32_t chan) +{ + return dev->etm_event_chn_cfg[chan].etm_chn_event_sel; +} + +/** + * @brief Set which GPIO to be bound to the task channel * - * @note One channel can be bounded to multiple different GPIOs + * @note One channel can be bound to multiple different GPIOs * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Task channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num, uint32_t chan) @@ -70,7 +87,7 @@ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32 } /** - * @brief Wether to enable the GPIO to be managed by the task channel + * @brief Whether to enable the GPIO to be managed by the task channel * * @param dev Register base address * @param gpio_num GPIO number @@ -101,7 +118,7 @@ static inline bool gpio_ll_etm_is_task_gpio_enabled(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Get the channel number that the GPIO is bounded to + * @brief Get the channel number that the GPIO is bound to * * @param dev Register base address * @param gpio_num GPIO number diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index 96da5be885a9..e78dd6bfbb15 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -90,6 +90,15 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num) { + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + // Note that esp32h2 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin + // which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead. + // TODO: read the specific efuse with efuse_ll.h + if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { + SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); + } REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU); } @@ -113,15 +122,7 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, gpio_num_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_num) { - // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value - // USB DP pin is default to PU enabled - // Note that esp32h2 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin - // which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead. - // TODO: read the specific efuse with efuse_ll.h - if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { - SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE); - CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP); - } + REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD); } @@ -439,6 +440,7 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, gpio_num_t gpio_ * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_en(gpio_dev_t *hw, gpio_num_t gpio_num) { LP_AON.gpio_hold0.gpio_hold0 |= GPIO_HOLD_MASK[gpio_num]; @@ -450,6 +452,7 @@ static inline void gpio_ll_hold_en(gpio_dev_t *hw, gpio_num_t gpio_num) * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_dis(gpio_dev_t *hw, gpio_num_t gpio_num) { LP_AON.gpio_hold0.gpio_hold0 &= ~GPIO_HOLD_MASK[gpio_num]; diff --git a/components/hal/esp32h2/include/hal/gpspi_flash_ll.h b/components/hal/esp32h2/include/hal/gpspi_flash_ll.h index c086401f32cc..124863b7d607 100644 --- a/components/hal/esp32h2/include/hal/gpspi_flash_ll.h +++ b/components/hal/esp32h2/include/hal/gpspi_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -53,9 +53,9 @@ static inline void gpspi_flash_ll_reset(spi_dev_t *dev) dev->clk_gate.mst_clk_sel = 1; dev->dma_conf.val = 0; - // dev->dma_conf.tx_seg_trans_clr_en = 1; - // dev->dma_conf.rx_seg_trans_clr_en = 1; - // dev->dma_conf.dma_seg_trans_en = 0; + dev->dma_conf.slv_tx_seg_trans_clr_en = 1; + dev->dma_conf.slv_rx_seg_trans_clr_en = 1; + dev->dma_conf.dma_slv_seg_trans_en = 0; } /** @@ -79,20 +79,20 @@ static inline bool gpspi_flash_ll_cmd_is_done(const spi_dev_t *dev) */ static inline void gpspi_flash_ll_get_buffer_data(spi_dev_t *dev, void *buffer, uint32_t read_len) { - // if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) { - // // If everything is word-aligned, do a faster memcpy - // memcpy(buffer, (void *)dev->data_buf, read_len); - // } else { - // // Otherwise, slow(er) path copies word by word - // int copy_len = read_len; - // for (int i = 0; i < (read_len + 3) / 4; i++) { - // int word_len = MIN(sizeof(uint32_t), copy_len); - // uint32_t word = dev->data_buf[i]; - // memcpy(buffer, &word, word_len); - // buffer = (void *)((intptr_t)buffer + word_len); - // copy_len -= word_len; - // } - // } + if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) { + // If everything is word-aligned, do a faster memcpy + memcpy(buffer, (void *)dev->data_buf, read_len); + } else { + // Otherwise, slow(er) path copies word by word + int copy_len = read_len; + for (int i = 0; i < (read_len + 3) / 4; i++) { + int word_len = MIN(sizeof(uint32_t), copy_len); + uint32_t word = dev->data_buf[i].buf0; + memcpy(buffer, &word, word_len); + buffer = (void *)((intptr_t)buffer + word_len); + copy_len -= word_len; + } + } } /** @@ -103,7 +103,7 @@ static inline void gpspi_flash_ll_get_buffer_data(spi_dev_t *dev, void *buffer, */ static inline void gpspi_flash_ll_write_word(spi_dev_t *dev, uint32_t word) { - // dev->data_buf[0] = word; + dev->data_buf[0].buf0 = word; } /** @@ -116,15 +116,15 @@ static inline void gpspi_flash_ll_write_word(spi_dev_t *dev, uint32_t word) static inline void gpspi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *buffer, uint32_t length) { // Load data registers, word at a time - // int num_words = (length + 3) / 4; - // for (int i = 0; i < num_words; i++) { - // uint32_t word = 0; - // uint32_t word_len = MIN(length, sizeof(word)); - // memcpy(&word, buffer, word_len); - // dev->data_buf[i] = word; - // length -= word_len; - // buffer = (void *)((intptr_t)buffer + word_len); - // } + int num_words = (length + 3) / 4; + for (int i = 0; i < num_words; i++) { + uint32_t word = 0; + uint32_t word_len = MIN(length, sizeof(word)); + memcpy(&word, buffer, word_len); + dev->data_buf[i].buf0 = word; + length -= word_len; + buffer = (void *)((intptr_t)buffer + word_len); + } } /** @@ -339,8 +339,8 @@ static inline void gpspi_flash_ll_set_addr_bitlen(spi_dev_t *dev, uint32_t bitle static inline void gpspi_flash_ll_set_usr_address(spi_dev_t *dev, uint32_t addr, uint32_t bitlen) { // The blank region should be all ones - // uint32_t padding_ones = (bitlen == 32? 0 : UINT32_MAX >> bitlen); - // dev->addr = (addr << (32 - bitlen)) | padding_ones; + uint32_t padding_ones = (bitlen == 32? 0 : UINT32_MAX >> bitlen); + dev->addr.val = (addr << (32 - bitlen)) | padding_ones; } /** @@ -351,7 +351,7 @@ static inline void gpspi_flash_ll_set_usr_address(spi_dev_t *dev, uint32_t addr, */ static inline void gpspi_flash_ll_set_address(spi_dev_t *dev, uint32_t addr) { - // dev->addr = addr; + dev->addr.val = addr; } /** diff --git a/components/hal/esp32h2/include/hal/lp_timer_ll.h b/components/hal/esp32h2/include/hal/lp_timer_ll.h index f0182585fc6f..c8e6e2a05412 100644 --- a/components/hal/esp32h2/include/hal/lp_timer_ll.h +++ b/components/hal/esp32h2/include/hal/lp_timer_ll.h @@ -14,6 +14,7 @@ #include "soc/lp_timer_struct.h" #include "soc/lp_aon_reg.h" #include "hal/lp_timer_types.h" +#include "hal/misc.h" #include "esp_attr.h" #ifdef __cplusplus @@ -22,8 +23,8 @@ extern "C" { FORCE_INLINE_ATTR void lp_timer_ll_set_alarm_target(lp_timer_dev_t *dev, uint8_t timer_id, uint64_t value) { - dev->target[timer_id].hi.target_hi = (value >> 32) & 0xFFFF; - dev->target[timer_id].lo.target_lo = value & 0xFFFFFFFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].hi, target_hi, (value >> 32) & 0xFFFF); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].lo, target_lo, value & 0xFFFFFFFF); } FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_t timer_id, bool en) @@ -33,12 +34,12 @@ FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_ FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev, uint8_t timer_id) { - return dev->counter[timer_id].lo.counter_lo; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[timer_id].lo, counter_lo); } FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_high(lp_timer_dev_t *dev, uint8_t timer_id) { - return dev->counter[timer_id].hi.counter_hi; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[timer_id].hi, counter_hi); } FORCE_INLINE_ATTR void lp_timer_ll_counter_snapshot(lp_timer_dev_t *dev) diff --git a/components/hal/esp32h2/include/hal/mmu_ll.h b/components/hal/esp32h2/include/hal/mmu_ll.h index f59ca5685aeb..19a975d33bd8 100644 --- a/components/hal/esp32h2/include/hal/mmu_ll.h +++ b/components/hal/esp32h2/include/hal/mmu_ll.h @@ -19,6 +19,8 @@ extern "C" { #endif +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_MMU_PAGE_SIZE) +#define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1) /** * Convert MMU virtual address to linear address @@ -282,7 +284,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32h2/include/hal/mpi_ll.h b/components/hal/esp32h2/include/hal/mpi_ll.h index 0eed1020d9d9..774d2ce96a54 100644 --- a/components/hal/esp32h2/include/hal/mpi_ll.h +++ b/components/hal/esp32h2/include/hal/mpi_ll.h @@ -50,11 +50,15 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words) static inline void mpi_ll_clear_power_control_bit(void) { + /* Power up the MPI peripheral */ REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); + REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PD); } static inline void mpi_ll_set_power_control_bit(void) { + /* Power down the MPI peripheral */ + REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PU); REG_SET_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); } diff --git a/components/hal/esp32h2/include/hal/parlio_ll.h b/components/hal/esp32h2/include/hal/parlio_ll.h index e0236e0f8a7d..ac3f5d747060 100644 --- a/components/hal/esp32h2/include/hal/parlio_ll.h +++ b/components/hal/esp32h2/include/hal/parlio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -326,7 +326,7 @@ static inline void parlio_ll_rx_treat_data_line_as_en(parl_io_dev_t *dev, uint32 } /** - * @brief Wether to enable the RX clock gating + * @brief Whether to enable the RX clock gating * * @param dev Parallel IO register base address * @param en True to enable, False to disable @@ -457,7 +457,7 @@ static inline void parlio_ll_tx_set_trans_bit_len(parl_io_dev_t *dev, uint32_t b } /** - * @brief Wether to enable the TX clock gating + * @brief Whether to enable the TX clock gating * * @note The MSB of TXD will be taken as the gating enable signal * @@ -571,7 +571,7 @@ static inline void parlio_ll_tx_reset_fifo(parl_io_dev_t *dev) __attribute__((always_inline)) static inline void parlio_ll_tx_set_idle_data_value(parl_io_dev_t *dev, uint32_t value) { - dev->tx_genrl_cfg.tx_idle_value = value; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_genrl_cfg, tx_idle_value, value); } /** diff --git a/components/hal/esp32h2/include/hal/pmu_ll.h b/components/hal/esp32h2/include/hal/pmu_ll.h index d666973e2fc8..1272e2fb24e8 100644 --- a/components/hal/esp32h2/include/hal/pmu_ll.h +++ b/components/hal/esp32h2/include/hal/pmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include "hal/assert.h" #include "soc/pmu_struct.h" #include "hal/pmu_types.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -446,7 +447,7 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode) FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->wakeup.cntl3.hp_min_slp_val = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, hp_min_slp_val, cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw) @@ -486,27 +487,27 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_reject_cause(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, lp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.modify_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.switch_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -531,32 +532,32 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target, slow_clk_cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl5.lp_ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_xtal_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_xtal_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable); } FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_pll_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_pll_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable); } FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -581,12 +582,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t * FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->wakeup.cntl7.ana_wait_target = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl7.ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) diff --git a/components/hal/esp32h2/include/hal/rmt_ll.h b/components/hal/esp32h2/include/hal/rmt_ll.h index 707c57ef3ae3..c299ed114ef8 100644 --- a/components/hal/esp32h2/include/hal/rmt_ll.h +++ b/components/hal/esp32h2/include/hal/rmt_ll.h @@ -79,15 +79,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -430,7 +451,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, * * @param dev Peripheral instance address * @param channel RMT TX channel number - * @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data + * @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data */ static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable) { @@ -661,7 +682,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e * @brief Clear RMT interrupt status by mask * * @param dev Peripheral instance address - * @param mask Interupt status mask + * @param mask Interrupt status mask */ __attribute__((always_inline)) static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask) @@ -812,12 +833,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32h2/include/hal/rtc_io_ll.h b/components/hal/esp32h2/include/hal/rtc_io_ll.h index 5899ce63adf0..bfeb758a59b6 100644 --- a/components/hal/esp32h2/include/hal/rtc_io_ll.h +++ b/components/hal/esp32h2/include/hal/rtc_io_ll.h @@ -34,11 +34,14 @@ typedef enum { /** * @brief Enable/Disable LP_IO peripheral clock. * - * @param enable true to enable the clock / false to enable the clock + * @param enable true to enable the clock / false to disable the clock */ static inline void _rtcio_ll_enable_io_clock(bool enable) { LPPERI.clk_en.lp_io_ck_en = enable; + while (LPPERI.clk_en.lp_io_ck_en != enable) { + ; + } } #define rtcio_ll_enable_io_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _rtcio_ll_enable_io_clock(__VA_ARGS__) @@ -56,9 +59,6 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) if (func == RTCIO_LL_FUNC_RTC) { // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); - if ((sel_mask & SOC_RTCIO_VALID_RTCIO_MASK) == 0) { - _rtcio_ll_enable_io_clock(true); - } sel_mask |= BIT(rtcio_num); HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); } else if (func == RTCIO_LL_FUNC_DIGITAL) { @@ -66,9 +66,6 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); sel_mask &= ~BIT(rtcio_num); HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); - if((sel_mask & SOC_RTCIO_VALID_RTCIO_MASK) == 0) { - _rtcio_ll_enable_io_clock(false); - } } } diff --git a/components/hal/esp32h2/include/hal/uart_ll.h b/components/hal/esp32h2/include/hal/uart_ll.h index 9e018b2bdb9e..14cbbfb14f43 100644 --- a/components/hal/esp32h2/include/hal/uart_ll.h +++ b/components/hal/esp32h2/include/hal/uart_ll.h @@ -57,6 +57,10 @@ extern "C" { #define UART_LL_PCR_REG_GET(hw, reg_suffix, field_suffix) \ (((hw) == &UART0) ? PCR.uart0_##reg_suffix.uart0_##field_suffix : PCR.uart1_##reg_suffix.uart1_##field_suffix) +// UART sleep retention module +#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \ + (uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1) + // Define UART interrupts typedef enum { UART_INTR_RXFIFO_FULL = (0x1 << 0), @@ -554,7 +558,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -621,7 +625,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -928,7 +932,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32h2/include/hal/uhci_ll.h b/components/hal/esp32h2/include/hal/uhci_ll.h new file mode 100644 index 000000000000..07d4a40a6835 --- /dev/null +++ b/components/hal/esp32h2/include/hal/uhci_ll.h @@ -0,0 +1,133 @@ +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include "hal/uhci_types.h" +#include "soc/uhci_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UHCI_LL_GET_HW(num) (((num) == 0) ? (&UHCI0) : (NULL)) + +typedef enum { + UHCI_RX_BREAK_CHR_EOF = 0x1, + UHCI_RX_IDLE_EOF = 0x2, + UHCI_RX_LEN_EOF = 0x4, + UHCI_RX_EOF_MAX = 0x7, +} uhci_rxeof_cfg_t; + +static inline void uhci_ll_init(uhci_dev_t *hw) +{ + typeof(hw->conf0) conf0_reg; + hw->conf0.clk_en = 1; + conf0_reg.val = 0; + conf0_reg.clk_en = 1; + hw->conf0.val = conf0_reg.val; + hw->conf1.val = 0; +} + +static inline void uhci_ll_attach_uart_port(uhci_dev_t *hw, int uart_num) +{ + hw->conf0.uart0_ce = (uart_num == 0)? 1: 0; + hw->conf0.uart1_ce = (uart_num == 1)? 1: 0; +} + +static inline void uhci_ll_set_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_char) +{ + if (seper_char->sub_chr_en) { + typeof(hw->esc_conf0) esc_conf0_reg; + esc_conf0_reg.val = hw->esc_conf0.val; + + esc_conf0_reg.seper_char = seper_char->seper_chr; + esc_conf0_reg.seper_esc_char0 = seper_char->sub_chr1; + esc_conf0_reg.seper_esc_char1 = seper_char->sub_chr2; + hw->esc_conf0.val = esc_conf0_reg.val; + hw->escape_conf.tx_c0_esc_en = 1; + hw->escape_conf.rx_c0_esc_en = 1; + } else { + hw->escape_conf.tx_c0_esc_en = 0; + hw->escape_conf.rx_c0_esc_en = 0; + } +} + +static inline void uhci_ll_get_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_chr) +{ + (void)hw; + (void)seper_chr; +} + +static inline void uhci_ll_set_swflow_ctrl_sub_chr(uhci_dev_t *hw, uhci_swflow_ctrl_sub_chr_t *sub_ctr) +{ + typeof(hw->escape_conf) escape_conf_reg; + escape_conf_reg.val = hw->escape_conf.val; + + if (sub_ctr->flow_en == 1) { + typeof(hw->esc_conf2) esc_conf2_reg; + esc_conf2_reg.val = hw->esc_conf2.val; + typeof(hw->esc_conf3) esc_conf3_reg; + esc_conf3_reg.val = hw->esc_conf3.val; + + esc_conf2_reg.esc_seq1 = sub_ctr->xon_chr; + esc_conf2_reg.esc_seq1_char0 = sub_ctr->xon_sub1; + esc_conf2_reg.esc_seq1_char1 = sub_ctr->xon_sub2; + esc_conf3_reg.esc_seq2 = sub_ctr->xoff_chr; + esc_conf3_reg.esc_seq2_char0 = sub_ctr->xoff_sub1; + esc_conf3_reg.esc_seq2_char1 = sub_ctr->xoff_sub2; + escape_conf_reg.tx_11_esc_en = 1; + escape_conf_reg.tx_13_esc_en = 1; + escape_conf_reg.rx_11_esc_en = 1; + escape_conf_reg.rx_13_esc_en = 1; + hw->esc_conf2.val = esc_conf2_reg.val; + hw->esc_conf3.val = esc_conf3_reg.val; + } else { + escape_conf_reg.tx_11_esc_en = 0; + escape_conf_reg.tx_13_esc_en = 0; + escape_conf_reg.rx_11_esc_en = 0; + escape_conf_reg.rx_13_esc_en = 0; + } + hw->escape_conf.val = escape_conf_reg.val; +} + +static inline void uhci_ll_enable_intr(uhci_dev_t *hw, uint32_t intr_mask) +{ + hw->int_ena.val |= intr_mask; +} + +static inline void uhci_ll_disable_intr(uhci_dev_t *hw, uint32_t intr_mask) +{ + hw->int_ena.val &= (~intr_mask); +} + +static inline void uhci_ll_clear_intr(uhci_dev_t *hw, uint32_t intr_mask) +{ + hw->int_clr.val = intr_mask; +} + +static inline uint32_t uhci_ll_get_intr(uhci_dev_t *hw) +{ + return hw->int_st.val; +} + + +static inline void uhci_ll_set_eof_mode(uhci_dev_t *hw, uint32_t eof_mode) +{ + if (eof_mode & UHCI_RX_BREAK_CHR_EOF) { + hw->conf0.uart_rx_brk_eof_en = 1; + } + if (eof_mode & UHCI_RX_IDLE_EOF) { + hw->conf0.uart_idle_eof_en = 1; + } + if (eof_mode & UHCI_RX_LEN_EOF) { + hw->conf0.len_eof_en = 1; + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h index bacbf3d3fbc5..289f0adf18bf 100644 --- a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h @@ -16,6 +16,7 @@ /* ----------------------------- Macros & Types ----------------------------- */ #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask +#define USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL (1) // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging diff --git a/components/hal/esp32p4/clk_tree_hal.c b/components/hal/esp32p4/clk_tree_hal.c index b63375248445..8b21821507db 100644 --- a/components/hal/esp32p4/clk_tree_hal.c +++ b/components/hal/esp32p4/clk_tree_hal.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "esp_attr.h" #include "hal/clk_tree_hal.h" #include "hal/clk_tree_ll.h" #include "hal/assert.h" @@ -70,7 +71,7 @@ uint32_t clk_hal_lp_slow_get_freq_hz(void) } } -uint32_t clk_hal_xtal_get_freq_mhz(void) +IRAM_ATTR uint32_t clk_hal_xtal_get_freq_mhz(void) { uint32_t freq = clk_ll_xtal_load_freq_mhz(); if (freq == 0) { diff --git a/components/hal/esp32p4/include/hal/adc_ll.h b/components/hal/esp32p4/include/hal/adc_ll.h new file mode 100644 index 000000000000..881cfd0c635e --- /dev/null +++ b/components/hal/esp32p4/include/hal/adc_ll.h @@ -0,0 +1,913 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "esp_attr.h" + +#include "soc/adc_periph.h" +#include "soc/adc_struct.h" +#include "soc/clk_tree_defs.h" +#include "soc/hp_sys_clkrst_struct.h" +#include "soc/lpperi_struct.h" +#include "soc/regi2c_saradc.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/adc_types.h" +#include "hal/adc_types_private.h" +#include "hal/regi2c_ctrl.h" +#include "hal/sar_ctrl_ll.h" +#include "soc/lp_adc_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE BIT(31) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) + +#define LP_ADC_FORCE_XPD_SAR_FSM 0 // Use FSM to control power down +#define LP_ADC_FORCE_XPD_SAR_PD 2 // Force power down +#define LP_ADC_FORCE_XPD_SAR_PU 3 // Force power up + +/*--------------------------------------------------------------- + Oneshot +---------------------------------------------------------------*/ +#define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) + +/*--------------------------------------------------------------- + DMA +---------------------------------------------------------------*/ +#define ADC_LL_DIGI_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_FSM_RSTB_WAIT_DEFAULT (8) +#define ADC_LL_FSM_START_WAIT_DEFAULT (5) +#define ADC_LL_FSM_STANDBY_WAIT_DEFAULT (100) +#define ADC_LL_SAMPLE_CYCLE_DEFAULT (2) +#define ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT (1) + +#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 +#define ADC_LL_CLKM_DIV_B_DEFAULT 1 +#define ADC_LL_CLKM_DIV_A_DEFAULT 0 +#define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 +#define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 + +#define ADC_LL_POWER_MANAGE_SUPPORTED 1 //ESP32P4 supported to manage power mode +/*--------------------------------------------------------------- + PWDET (Power Detect) +---------------------------------------------------------------*/ +#define ADC_LL_PWDET_CCT_DEFAULT (4) + +typedef enum { + ADC_LL_CTRL_RTC = 0, ///< For ADC1 and ADC2. Select RTC controller. + ADC_LL_CTRL_ULP = 1, ///< For ADC1 and ADC2. Select ULP controller. + ADC_LL_CTRL_DIG = 2, ///< For ADC1 and ADC2. Select DIG controller. + ADC_LL_CTRL_PWDET = 3, ///< For ADC2. Select PWDET controller. +} adc_ll_controller_t; + +typedef enum { + ADC_LL_POWER_BY_FSM = SAR_CTRL_LL_POWER_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ + ADC_LL_POWER_SW_ON = SAR_CTRL_LL_POWER_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */ + ADC_LL_POWER_SW_OFF = SAR_CTRL_LL_POWER_OFF, /*!< ADC XPD controlled by SW. power off. */ +} adc_ll_power_t; + +/** + * @brief ADC digital controller (DMA mode) work mode. + * + * @note The conversion mode affects the sampling frequency: + * SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once. + * SINGLE_UNIT_2: When the measurement is triggered, only ADC2 is sampled once. + * BOTH_UNIT : When the measurement is triggered, ADC1 and ADC2 are sampled at the same time. + * ALTER_UNIT : When the measurement is triggered, ADC1 or ADC2 samples alternately. + */ +typedef enum { + ADC_LL_DIGI_CONV_ONLY_ADC1 = 0, // Only use ADC1 for conversion + ADC_LL_DIGI_CONV_ONLY_ADC2 = 1, // Only use ADC2 for conversion + ADC_LL_DIGI_CONV_BOTH_UNIT = 2, // Use Both ADC1 and ADC2 for conversion simultaneously + ADC_LL_DIGI_CONV_ALTER_UNIT = 3 // Use both ADC1 and ADC2 for conversion by turn. e.g. ADC1 -> ADC2 -> ADC1 -> ADC2 ..... +} adc_ll_digi_convert_mode_t; + +typedef struct { + union { + struct { + uint8_t atten: 2; + uint8_t channel: 3; + uint8_t unit: 1; + uint8_t reserved: 2; + }; + uint8_t val; + }; +} __attribute__((packed)) adc_ll_digi_pattern_table_t; + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ + +/** + * Set adc fsm interval parameter for digital controller. These values are fixed for same platforms. + * + * @param rst_wait cycles between DIG ADC controller reset ADC sensor and start ADC sensor. + * @param start_wait Delay time after open xpd. + * @param standby_wait Delay time to close xpd. + */ +static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait) +{ + // Internal FSM reset wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.fsm_wait, rstb_wait, rst_wait); + // Internal FSM start wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.fsm_wait, xpd_wait, start_wait); + // Internal FSM standby wait time + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.fsm_wait, standby_wait, standby_wait); +} + +/** + * Set adc sample cycle for digital controller. + * + * @note Normally, please use default value. + * @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor. + * Range: 2 ~ 0xFF. + */ +static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle) +{ + /* Peripheral reg i2c has powered up in rtc_init, write directly */ + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle); +} + +/** + * Set SAR ADC module clock division factor. + * SAR ADC clock divided from digital controller clock. + * + * @param div Division factor. + */ +static inline void adc_ll_digi_set_clk_div(uint32_t div) +{ + /* ADC clock divided from digital controller clock clk */ + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.ctrl_reg, sar_clk_div, div); +} + +/** + * Set adc max conversion number for digital controller. + * If the number of ADC conversion is equal to the maximum, the conversion is stopped. + * + * @param meas_num Max conversion number. Range: 0 ~ 255. + */ +static inline void adc_ll_digi_set_convert_limit_num(uint32_t meas_num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.ctrl2, max_meas_num, meas_num); +} + +/** + * Enable max conversion number detection for digital controller. + * If the number of ADC conversion is equal to the maximum, the conversion is stopped. + * + * @param enable true: enable; false: disable + */ +static inline void adc_ll_digi_convert_limit_enable(bool enable) +{ + ADC.ctrl2.meas_num_limit = enable; +} + +/** + * Set adc conversion mode for digital controller. + * + * @param mode Conversion mode select. + */ +static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode) +{ + if (mode == ADC_LL_DIGI_CONV_ONLY_ADC1) { + ADC.ctrl_reg.work_mode = 0; + ADC.ctrl_reg.sar_sel = 0; + } else if (mode == ADC_LL_DIGI_CONV_ONLY_ADC2) { + ADC.ctrl_reg.work_mode = 0; + ADC.ctrl_reg.sar_sel = 1; + } else if (mode == ADC_LL_DIGI_CONV_BOTH_UNIT) { + ADC.ctrl_reg.work_mode = 1; + } else if (mode == ADC_LL_DIGI_CONV_ALTER_UNIT) { + ADC.ctrl_reg.work_mode = 2; + } + ADC.ctrl_reg.data_sar_sel = 1; +} + +/** + * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock. + * Expression: controller_clk = (APLL or APB) / (div_num + div_a / div_b + 1). + * + * @param div_num Division factor. Range: 0 ~ 255. + * @param div_b Division factor. Range: 1 ~ 63. + * @param div_a Division factor. Range: 0 ~ 63. + */ +static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div_b, uint32_t div_a) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl23, reg_adc_clk_div_num, div_num); + HP_SYS_CLKRST.peri_clk_ctrl23.reg_adc_clk_div_numerator = div_a; + HP_SYS_CLKRST.peri_clk_ctrl23.reg_adc_clk_div_denominator = div_b; +} + +/** + * Enable clock and select clock source for ADC digital controller. + * + * @param clk_src clock source for ADC digital controller. + */ +static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src) +{ + switch (clk_src) { + case ADC_DIGI_CLK_SRC_XTAL: + HP_SYS_CLKRST.peri_clk_ctrl22.reg_adc_clk_src_sel = 0; + break; + case ADC_DIGI_CLK_SRC_RC_FAST: + HP_SYS_CLKRST.peri_clk_ctrl22.reg_adc_clk_src_sel = 1; + break; + case ADC_DIGI_CLK_SRC_PLL_F80M: + HP_SYS_CLKRST.peri_clk_ctrl22.reg_adc_clk_src_sel = 2; + break; + default: + HAL_ASSERT(false && "unsupported clock"); + } + // Enable ADC_CTRL_CLK (i.e. digital domain clock) + ADC.ctrl_reg.sar_clk_gated = 1; +} + +/** + * Disable clock for ADC digital controller. + */ +static inline void adc_ll_digi_controller_clk_disable(void) +{ + ADC.ctrl_reg.sar_clk_gated = 0; +} + +/** + * Reset adc digital controller filter. + * + * @param idx Filter index + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n) +{ + (void)adc_n; + ADC.filter_ctrl0.filter_reset = 1; + ADC.filter_ctrl0.filter_reset = 0; +} + +/** + * Set adc digital controller filter coeff. + * + * @param idx filter index + * @param adc_n adc unit + * @param channel adc channel + * @param coeff filter coeff + */ +static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff) +{ + uint32_t factor_reg_val = 0; + switch (coeff) { + case ADC_DIGI_IIR_FILTER_COEFF_2: + factor_reg_val = 1; + break; + case ADC_DIGI_IIR_FILTER_COEFF_4: + factor_reg_val = 2; + break; + case ADC_DIGI_IIR_FILTER_COEFF_8: + factor_reg_val = 3; + break; + case ADC_DIGI_IIR_FILTER_COEFF_16: + factor_reg_val = 4; + break; + case ADC_DIGI_IIR_FILTER_COEFF_64: + factor_reg_val = 6; + break; + default: + HAL_ASSERT(false); + } + + if (idx == ADC_DIGI_IIR_FILTER_0) { + ADC.filter_ctrl0.filter_channel0 = ((adc_n + 1) << 3) | (channel & 0x7); + ADC.filter_ctrl1.filter_factor0 = factor_reg_val; + } else if (idx == ADC_DIGI_IIR_FILTER_1) { + ADC.filter_ctrl0.filter_channel1 = ((adc_n + 1) << 3) | (channel & 0x7); + ADC.filter_ctrl1.filter_factor1 = factor_reg_val; + } +} + +/** + * Enable adc digital controller filter. + * Filtering the ADC data to obtain smooth data at higher sampling rates. + * + * @param idx filter index + * @param adc_n ADC unit + * @param enable Enable / Disable + */ +static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable) +{ + (void)adc_n; + if (!enable) { + if (idx == ADC_DIGI_IIR_FILTER_0) { + ADC.filter_ctrl0.filter_channel0 = 0xF; + ADC.filter_ctrl1.filter_factor0 = 0; + } else if (idx == ADC_DIGI_IIR_FILTER_1) { + ADC.filter_ctrl0.filter_channel1 = 0xF; + ADC.filter_ctrl1.filter_factor1 = 0; + } + } + //nothing to do to enable, after adc_ll_digi_filter_set_factor, it's enabled. +} + +/** + * Set pattern table length for digital controller. + * The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection, + * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the + * pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. + * + * @param adc_n ADC unit. + * @param patt_len Items range: 1 ~ 16. + */ +static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t patt_len) +{ + if (adc_n == ADC_UNIT_1) { + ADC.ctrl_reg.sar1_patt_len = patt_len - 1; + } else { // adc_n == ADC_UNIT_2 + ADC.ctrl_reg.sar2_patt_len = patt_len - 1; + } +} + +/** + * Set pattern table for digital controller. + * The pattern table that defines the conversion rules for each SAR ADC. Each table has 12 items, in which channel selection, + * resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the + * pattern table one by one. For each controller the scan sequence has at most 12 different rules before repeating itself. + * + * @param adc_n ADC unit. + * @param pattern_index Items index. Range: 0 ~ 11. + * @param pattern Stored conversion rules. + */ +static inline void adc_ll_digi_set_pattern_table(adc_unit_t adc_n, uint32_t pattern_index, adc_digi_pattern_config_t table) +{ + uint32_t tab; + uint8_t index = pattern_index / 4; + uint8_t offset = (pattern_index % 4) * 6; + adc_ll_digi_pattern_table_t pattern = {0}; + + pattern.val = (table.atten & 0x3) | ((table.channel & 0xF) << 2); + if (table.unit == ADC_UNIT_1){ + tab = ADC.sar1_patt_tab[index].sar1_patt_tab; //Read old register value + tab &= (~(0xFC0000 >> offset)); //Clear old data + tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; //Fill in the new data + ADC.sar1_patt_tab[index].sar1_patt_tab = tab; //Write back + } else { + tab = ADC.sar2_patt_tab[index].sar2_patt_tab; //Read old register value + tab &= (~(0xFC0000 >> offset)); //clear old data + tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; //Fill in the new data + ADC.sar2_patt_tab[index].sar2_patt_tab = tab; //Write back + } +} + +/** + * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_clear_pattern_table(adc_unit_t adc_n) +{ + if (adc_n == ADC_UNIT_1) { + ADC.ctrl_reg.sar1_patt_p_clear = 1; + ADC.ctrl_reg.sar1_patt_p_clear = 0; + } else { // adc_n == ADC_UNIT_2 + ADC.ctrl_reg.sar2_patt_p_clear = 1; + ADC.ctrl_reg.sar2_patt_p_clear = 0; + } +} + +/** + * ADC Digital controller output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_ll_digi_output_invert(adc_unit_t adc_n, bool inv_en) +{ + if (adc_n == ADC_UNIT_1) { + ADC.ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert + } else { // adc_n == ADC_UNIT_2 + ADC.ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert + } +} + +/** + * Set the interval clock cycle for the digital controller to trigger the measurement. + * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. + * + * @note The trigger interval should not be smaller than the sampling time of the SAR ADC. + * @param cycle The clock cycle (trigger interval) of the measurement. Range: 30 ~ 4095. + */ +static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle) +{ + ADC.ctrl2.timer_target = cycle; +} + +/** + * Set DMA eof num of adc digital controller. + * If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated. + * + * @param num eof num of DMA. + */ +static inline void adc_ll_digi_dma_set_eof_num(uint32_t num) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(ADC.dma_conf, apb_adc_eof_num, num); +} + +/** + * Enable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_enable(void) +{ + ADC.dma_conf.apb_adc_trans = 1; +} + +/** + * Disable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_disable(void) +{ + ADC.dma_conf.apb_adc_trans = 0; +} + +/** + * Reset adc digital controller. + */ +static inline void adc_ll_digi_reset(void) +{ + ADC.dma_conf.apb_adc_reset_fsm = 1; + ADC.dma_conf.apb_adc_reset_fsm = 0; +} + +/** + * Enable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_enable(void) +{ + ADC.ctrl2.timer_sel = 1; + ADC.ctrl2.timer_en = 1; +} + +/** + * Disable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_disable(void) +{ + ADC.ctrl2.timer_en = 0; +} + +/*--------------------------------------------------------------- + PWDET(Power detect) controller setting +---------------------------------------------------------------*/ + +/** + * Set adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @param cct Range: 0 ~ 7. + */ +static inline void adc_ll_pwdet_set_cct(uint32_t cct) +{ + /* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */ + LP_ADC.meas2_mux.sar2_pwdet_cct = cct; +} + +/** + * Get adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @return cct Range: 0 ~ 7. + */ +static inline uint32_t adc_ll_pwdet_get_cct(void) +{ + /* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */ + return LP_ADC.meas2_mux.sar2_pwdet_cct; +} + +/*--------------------------------------------------------------- + Common setting +---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + HP_SYS_CLKRST.soc_clk_ctrl2.reg_adc_apb_clk_en = enable; + HP_SYS_CLKRST.peri_clk_ctrl23.reg_adc_clk_en = enable; +} +// HP_SYS_CLKRST.soc_clk_ctrl2 are shared registers, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_adc = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_adc = 0; +} +// HP_SYS_CLKRST.hp_rst_en2 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + + + +/** + * Set ADC digital controller power management. + * + * @param adc_n ADC unit. + * @param manage Set ADC power status. + */ +static inline void adc_ll_digi_set_power_manage(adc_unit_t adc_n, adc_ll_power_t manage) +{ + if (adc_n == ADC_UNIT_1) { + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_LL_POWER_SW_ON) { + ADC.ctrl_reg.sar_clk_gated = 1; + ADC.ctrl_reg.xpd_sar1_force = LP_ADC_FORCE_XPD_SAR_PU; + } else if (manage == ADC_LL_POWER_BY_FSM) { + ADC.ctrl_reg.sar_clk_gated = 1; + ADC.ctrl_reg.xpd_sar1_force = LP_ADC_FORCE_XPD_SAR_FSM; + } else if (manage == ADC_LL_POWER_SW_OFF) { + ADC.ctrl_reg.sar_clk_gated = 0; + ADC.ctrl_reg.xpd_sar1_force = LP_ADC_FORCE_XPD_SAR_PD; + } + } else { + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_LL_POWER_SW_ON) { + ADC.ctrl_reg.sar_clk_gated = 1; + ADC.ctrl_reg.xpd_sar2_force = LP_ADC_FORCE_XPD_SAR_PU; + } else if (manage == ADC_LL_POWER_BY_FSM) { + ADC.ctrl_reg.sar_clk_gated = 1; + ADC.ctrl_reg.xpd_sar2_force = LP_ADC_FORCE_XPD_SAR_FSM; + } else if (manage == ADC_LL_POWER_SW_OFF) { + ADC.ctrl_reg.sar_clk_gated = 0; + ADC.ctrl_reg.xpd_sar2_force = LP_ADC_FORCE_XPD_SAR_PD; + } + } +} + +/** + * Set ADC module power management. + * + * @param adc_n ADC unit. + * @param manage Set ADC power status. + */ +static inline void adc_ll_set_power_manage(adc_unit_t adc_n, adc_ll_power_t manage) +{ + adc_ll_digi_set_power_manage(adc_n, manage); + if (adc_n == ADC_UNIT_1) { + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_LL_POWER_SW_ON) { + LPPERI.clk_en.ck_en_lp_adc = 1; + LP_ADC.force_wpd_sar.force_xpd_sar1 = LP_ADC_FORCE_XPD_SAR_PU; + } else if (manage == ADC_LL_POWER_BY_FSM) { + LPPERI.clk_en.ck_en_lp_adc = 1; + LP_ADC.force_wpd_sar.force_xpd_sar1 = LP_ADC_FORCE_XPD_SAR_FSM; + } else if (manage == ADC_LL_POWER_SW_OFF) { + LP_ADC.force_wpd_sar.force_xpd_sar1 = LP_ADC_FORCE_XPD_SAR_PD; + LPPERI.clk_en.ck_en_lp_adc = 0; + } + } else { + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + if (manage == ADC_LL_POWER_SW_ON) { + LPPERI.clk_en.ck_en_lp_adc = 1; + LP_ADC.force_wpd_sar.force_xpd_sar2 = LP_ADC_FORCE_XPD_SAR_PU; + } else if (manage == ADC_LL_POWER_BY_FSM) { + LPPERI.clk_en.ck_en_lp_adc = 1; + LP_ADC.force_wpd_sar.force_xpd_sar2 = LP_ADC_FORCE_XPD_SAR_FSM; + } else if (manage == ADC_LL_POWER_SW_OFF) { + LP_ADC.force_wpd_sar.force_xpd_sar2 = LP_ADC_FORCE_XPD_SAR_PD; + LPPERI.clk_en.ck_en_lp_adc = 0; + } + } +} + + +/** + * Set ADC module controller. + * There are five SAR ADC controllers: + * Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes; + * Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep; + * the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2. + * + * @param adc_n ADC unit. + * @param ctrl ADC controller. + */ +__attribute__((always_inline)) +static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t ctrl) +{ + if (adc_n == ADC_UNIT_1) { + switch (ctrl) { + case ADC_LL_CTRL_RTC: + LP_ADC.meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + case ADC_LL_CTRL_ULP: + LP_ADC.meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas1_ctrl2.meas1_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas1_ctrl2.sar1_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + case ADC_LL_CTRL_DIG: + LP_ADC.meas1_mux.sar1_dig_force = 1; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + default: + break; + } + } else { // adc_n == ADC_UNIT_2 + switch (ctrl) { + case ADC_LL_CTRL_RTC: + LP_ADC.meas2_mux.sar2_rtc_force = 1; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + case ADC_LL_CTRL_ULP: + LP_ADC.meas2_mux.sar2_rtc_force = 0; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas2_ctrl2.meas2_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas2_ctrl2.sar2_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + case ADC_LL_CTRL_DIG: + LP_ADC.meas2_mux.sar2_rtc_force = 0; // 1: Select digital control; 0: Select RTC control. + LP_ADC.meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + LP_ADC.meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + break; + default: + break; + } + } +} + +/*--------------------------------------------------------------- + Oneshot Read +---------------------------------------------------------------*/ + +static inline void adc_ll_vref_output(adc_unit_t adc, adc_channel_t channel, bool en) +{ + abort(); +} + +/** + * Set adc output data format for RTC controller. + * + * @note ESP32P4 RTC controller only support 12bit. + * @param adc_n ADC unit. + * @param bits Output data bits width option. + */ +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) +{ + //ESP32P4 only supports 12bit, leave here for compatibility + HAL_ASSERT(bits == ADC_BITWIDTH_12 || bits == ADC_BITWIDTH_DEFAULT); +} + +/** + * Enable adc channel to start convert. + * + * @note Only one channel can be selected for once measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.meas1_ctrl2.sar1_en_pad = (1 << channel); //only one channel is selected. + } else { // adc_n == ADC_UNIT_2 + LP_ADC.meas2_ctrl2.sar2_en_pad = (1 << ((channel + 2))); //only one channel is selected. + } +} + +/** + * Disable adc channel to start convert. + * + * @note Only one channel can be selected in once measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.meas1_ctrl2.sar1_en_pad = 0; //only one channel is selected. + } else { // adc_n == ADC_UNIT_2 + LP_ADC.meas2_ctrl2.sar2_en_pad = 0; //only one channel is selected. + } +} + +/** + * Start conversion once by software for RTC controller. + * + * @note It may be block to wait conversion idle for ADC1. + * + * @param adc_n ADC unit. + */ +static inline void adc_oneshot_ll_start(adc_unit_t adc_n) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.meas1_ctrl2.meas1_start_sar = 0; + LP_ADC.meas1_ctrl2.meas1_start_sar = 1; + } else { // adc_n == ADC_UNIT_2 + LP_ADC.meas2_ctrl2.meas2_start_sar = 0; + LP_ADC.meas2_ctrl2.meas2_start_sar = 1; + } +} + +/** + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event_mask) +{ + // ADC.int_clr.val |= event_mask; +} + +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event + * + * @return + * -true : The conversion process is finish. + * -false : The conversion process is not finish. + */ +static inline bool adc_oneshot_ll_get_event(uint32_t event) +{ + bool ret = true; + if (event == ADC_LL_EVENT_ADC1_ONESHOT_DONE) { + ret = (bool)LP_ADC.meas1_ctrl2.meas1_done_sar; + } else if (event == ADC_LL_EVENT_ADC2_ONESHOT_DONE) { + ret = (bool)LP_ADC.meas2_ctrl2.meas2_done_sar; + } else { + HAL_ASSERT(false); + } + return ret; +} + +/** + * Get the converted value for each ADCn for RTC controller. + * + * @param adc_n ADC unit. + * @return + * - Converted value. + */ +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) +{ + uint32_t ret_val = 0; + if (adc_n == ADC_UNIT_1) { + ret_val = HAL_FORCE_READ_U32_REG_FIELD(LP_ADC.meas1_ctrl2, meas1_data_sar); + } else { // adc_n == ADC_UNIT_2 + ret_val = HAL_FORCE_READ_U32_REG_FIELD(LP_ADC.meas2_ctrl2, meas2_data_sar); + } + return ret_val; +} + +/** + * Analyze whether the obtained raw data is correct. + * + * @param adc_n ADC unit. + * @param raw ADC raw data input (convert value). + * @return + * - true: raw data is valid + */ +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw) +{ + /* No arbiter, don't need check data */ + return true; +} + +/** + * ADC module RTC output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.reader1_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert + } else { // adc_n == ADC_UNIT_2 + LP_ADC.reader2_ctrl.sar2_data_inv = inv_en; // Enable / Disable ADC data invert + } +} + +/** + * Enable oneshot conversion trigger + * + * @param adc_n ADC unit + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) +{ + (void)adc_n; + //For compatibility +} + +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) +{ + //For compatibility +} + +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ +/** + * ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`. + * + * @param div Division factor. + */ +static inline void adc_ll_set_sar_clk_div(adc_unit_t adc_n, uint32_t div) +{ + if (adc_n == ADC_UNIT_1) { + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ADC.reader1_ctrl, sar1_clk_div, div); + } else { // adc_n == ADC_UNIT_2 + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ADC.reader2_ctrl, sar2_clk_div, div); + } +} + +/** + * Reset RTC controller FSM. + */ +static inline void adc_ll_rtc_reset(void) +{ + LPPERI.reset_en.rst_en_lp_adc = 1; + LPPERI.reset_en.rst_en_lp_adc = 0; +} + + +/** + * Set the attenuation of a particular channel on ADCn. + * + * @note For any given channel, this function must be called before the first time conversion. + * + * The default ADC full-scale voltage is 1.1V. To read higher voltages (up to the pin maximum voltage, + * usually 3.3V) requires setting >0dB signal attenuation for that ADC channel. + * + * When VDD_A is 3.3V: + * + * - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V + * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V + * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V + * - 11dB attenuation (ADC_ATTEN_DB_12) gives full-scale voltage 3.9V (see note below) + * + * @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured + * bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.) + * + * @note At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. + * + * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: + * + * - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV + * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV + * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV + * - 11dB attenuation (ADC_ATTEN_DB_12) between 150 to 2450mV + * + * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. + * + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @param atten The attenuation option. + */ +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) +{ + if (adc_n == ADC_UNIT_1) { + LP_ADC.atten1.sar1_atten = ( LP_ADC.atten1.sar1_atten & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2)); + } else { // adc_n == ADC_UNIT_2 + LP_ADC.atten2.sar2_atten = ( LP_ADC.atten2.sar2_atten & ~(0x3 << ((channel + 2) * 2)) ) | ((atten & 0x3) << ((channel + 2) * 2)); + } +} + +/** + * Get the attenuation of a particular channel on ADCn. + * + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @return atten The attenuation option. + */ +__attribute__((always_inline)) +static inline adc_atten_t adc_ll_get_atten(adc_unit_t adc_n, adc_channel_t channel) +{ + if (adc_n == ADC_UNIT_1) { + return (adc_atten_t)((LP_ADC.atten1.sar1_atten >> (channel * 2)) & 0x3); + } else { + return (adc_atten_t)((LP_ADC.atten2.sar2_atten >> ((channel + 2) * 2)) & 0x3); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/ahb_dma_ll.h b/components/hal/esp32p4/include/hal/ahb_dma_ll.h index b7a4667ed15c..383062c995cb 100644 --- a/components/hal/esp32p4/include/hal/ahb_dma_ll.h +++ b/components/hal/esp32p4/include/hal/ahb_dma_ll.h @@ -57,6 +57,18 @@ static inline void ahb_dma_ll_reset_fsm(ahb_dma_dev_t *dev) dev->misc_conf.ahbm_rst_inter = 0; } +/** + * @brief Preset valid memory range for AHB-DMA + * + * @param dev DMA register base address + */ +static inline void ahb_dma_ll_set_default_memory_range(ahb_dma_dev_t *dev) +{ + // AHB-DMA can access L2MEM, L2ROM, MSPI Flash, MSPI PSRAM + dev->intr_mem_start_addr.val = 0x40000000; + dev->intr_mem_end_addr.val = 0x4FFC0000; +} + ///////////////////////////////////// RX ///////////////////////////////////////// /** * @brief Get DMA RX channel interrupt status word @@ -518,8 +530,8 @@ static inline void ahb_dma_ll_tx_enable_etm_task(ahb_dma_dev_t *dev, uint32_t ch */ static inline void ahb_dma_ll_tx_crc_clear(ahb_dma_dev_t *dev, uint32_t channel) { - dev->out_crc[channel].crc_clear.out_crc_clear_chn_reg = 1; - dev->out_crc[channel].crc_clear.out_crc_clear_chn_reg = 0; + dev->out_crc_arb[channel].crc_clear.out_crc_clear_chn_reg = 1; + dev->out_crc_arb[channel].crc_clear.out_crc_clear_chn_reg = 0; } /** @@ -528,7 +540,7 @@ static inline void ahb_dma_ll_tx_crc_clear(ahb_dma_dev_t *dev, uint32_t channel) static inline void ahb_dma_ll_tx_crc_set_width(ahb_dma_dev_t *dev, uint32_t channel, uint32_t width) { HAL_ASSERT(width <= 32); - dev->out_crc[channel].crc_width.tx_crc_width_chn = (width - 1) / 8; + dev->out_crc_arb[channel].crc_width.tx_crc_width_chn = (width - 1) / 8; } /** @@ -536,7 +548,7 @@ static inline void ahb_dma_ll_tx_crc_set_width(ahb_dma_dev_t *dev, uint32_t chan */ static inline void ahb_dma_ll_tx_crc_set_init_value(ahb_dma_dev_t *dev, uint32_t channel, uint32_t value) { - dev->out_crc[channel].crc_init_data.out_crc_init_data_chn = value; + dev->out_crc_arb[channel].crc_init_data.out_crc_init_data_chn = value; } /** @@ -544,7 +556,7 @@ static inline void ahb_dma_ll_tx_crc_set_init_value(ahb_dma_dev_t *dev, uint32_t */ static inline uint32_t ahb_dma_ll_tx_crc_get_result(ahb_dma_dev_t *dev, uint32_t channel) { - return dev->out_crc[channel].crc_final_result.out_crc_final_result_chn; + return dev->out_crc_arb[channel].crc_final_result.out_crc_final_result_chn; } /** @@ -552,8 +564,8 @@ static inline uint32_t ahb_dma_ll_tx_crc_get_result(ahb_dma_dev_t *dev, uint32_t */ static inline void ahb_dma_ll_tx_crc_latch_config(ahb_dma_dev_t *dev, uint32_t channel) { - dev->out_crc[channel].crc_width.tx_crc_latch_flag_chn = 1; - dev->out_crc[channel].crc_width.tx_crc_latch_flag_chn = 0; + dev->out_crc_arb[channel].crc_width.tx_crc_latch_flag_chn = 1; + dev->out_crc_arb[channel].crc_width.tx_crc_latch_flag_chn = 0; } /** @@ -562,14 +574,14 @@ static inline void ahb_dma_ll_tx_crc_latch_config(ahb_dma_dev_t *dev, uint32_t c static inline void ahb_dma_ll_tx_crc_set_lfsr_data_mask(ahb_dma_dev_t *dev, uint32_t channel, uint32_t crc_bit, uint32_t lfsr_mask, uint32_t data_mask, bool reverse_data_mask) { - dev->out_crc[channel].crc_en_addr.tx_crc_en_addr_chn = crc_bit; - dev->out_crc[channel].crc_en_wr_data.tx_crc_en_wr_data_chn = lfsr_mask; - dev->out_crc[channel].crc_data_en_addr.tx_crc_data_en_addr_chn = crc_bit; + dev->out_crc_arb[channel].crc_en_addr.tx_crc_en_addr_chn = crc_bit; + dev->out_crc_arb[channel].crc_en_wr_data.tx_crc_en_wr_data_chn = lfsr_mask; + dev->out_crc_arb[channel].crc_data_en_addr.tx_crc_data_en_addr_chn = crc_bit; if (reverse_data_mask) { // "& 0xff" because the hardware only support 8-bit data data_mask = hal_utils_bitwise_reverse8(data_mask & 0xFF); } - HAL_FORCE_MODIFY_U32_REG_FIELD(dev->out_crc[channel].crc_data_en_wr_data, tx_crc_data_en_wr_data_chn, data_mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->out_crc_arb[channel].crc_data_en_wr_data, tx_crc_data_en_wr_data_chn, data_mask); } ///////////////////////////////////// CRC-RX ///////////////////////////////////////// @@ -579,8 +591,8 @@ static inline void ahb_dma_ll_tx_crc_set_lfsr_data_mask(ahb_dma_dev_t *dev, uint */ static inline void ahb_dma_ll_rx_crc_clear(ahb_dma_dev_t *dev, uint32_t channel) { - dev->in_crc[channel].crc_clear.in_crc_clear_chn_reg = 1; - dev->in_crc[channel].crc_clear.in_crc_clear_chn_reg = 0; + dev->in_crc_arb[channel].crc_clear.in_crc_clear_chn_reg = 1; + dev->in_crc_arb[channel].crc_clear.in_crc_clear_chn_reg = 0; } /** @@ -589,7 +601,7 @@ static inline void ahb_dma_ll_rx_crc_clear(ahb_dma_dev_t *dev, uint32_t channel) static inline void ahb_dma_ll_rx_crc_set_width(ahb_dma_dev_t *dev, uint32_t channel, uint32_t width) { HAL_ASSERT(width <= 32); - dev->in_crc[channel].crc_width.rx_crc_width_chn = (width - 1) / 8; + dev->in_crc_arb[channel].crc_width.rx_crc_width_chn = (width - 1) / 8; } /** @@ -597,7 +609,7 @@ static inline void ahb_dma_ll_rx_crc_set_width(ahb_dma_dev_t *dev, uint32_t chan */ static inline void ahb_dma_ll_rx_crc_set_init_value(ahb_dma_dev_t *dev, uint32_t channel, uint32_t value) { - dev->in_crc[channel].crc_init_data.in_crc_init_data_chn = value; + dev->in_crc_arb[channel].crc_init_data.in_crc_init_data_chn = value; } /** @@ -605,7 +617,7 @@ static inline void ahb_dma_ll_rx_crc_set_init_value(ahb_dma_dev_t *dev, uint32_t */ static inline uint32_t ahb_dma_ll_rx_crc_get_result(ahb_dma_dev_t *dev, uint32_t channel) { - return dev->in_crc[channel].crc_final_result.in_crc_final_result_chn; + return dev->in_crc_arb[channel].crc_final_result.in_crc_final_result_chn; } /** @@ -613,8 +625,8 @@ static inline uint32_t ahb_dma_ll_rx_crc_get_result(ahb_dma_dev_t *dev, uint32_t */ static inline void ahb_dma_ll_rx_crc_latch_config(ahb_dma_dev_t *dev, uint32_t channel) { - dev->in_crc[channel].crc_width.rx_crc_latch_flag_chn = 1; - dev->in_crc[channel].crc_width.rx_crc_latch_flag_chn = 0; + dev->in_crc_arb[channel].crc_width.rx_crc_latch_flag_chn = 1; + dev->in_crc_arb[channel].crc_width.rx_crc_latch_flag_chn = 0; } /** @@ -623,14 +635,14 @@ static inline void ahb_dma_ll_rx_crc_latch_config(ahb_dma_dev_t *dev, uint32_t c static inline void ahb_dma_ll_rx_crc_set_lfsr_data_mask(ahb_dma_dev_t *dev, uint32_t channel, uint32_t crc_bit, uint32_t lfsr_mask, uint32_t data_mask, bool reverse_data_mask) { - dev->in_crc[channel].crc_en_addr.rx_crc_en_addr_chn = crc_bit; - dev->in_crc[channel].crc_en_wr_data.rx_crc_en_wr_data_chn = lfsr_mask; - dev->in_crc[channel].crc_data_en_addr.rx_crc_data_en_addr_chn = crc_bit; + dev->in_crc_arb[channel].crc_en_addr.rx_crc_en_addr_chn = crc_bit; + dev->in_crc_arb[channel].crc_en_wr_data.rx_crc_en_wr_data_chn = lfsr_mask; + dev->in_crc_arb[channel].crc_data_en_addr.rx_crc_data_en_addr_chn = crc_bit; if (reverse_data_mask) { // "& 0xff" because the hardware only support 8-bit data data_mask = hal_utils_bitwise_reverse8(data_mask & 0xFF); } - HAL_FORCE_MODIFY_U32_REG_FIELD(dev->in_crc[channel].crc_data_en_wr_data, rx_crc_data_en_wr_data_chn, data_mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->in_crc_arb[channel].crc_data_en_wr_data, rx_crc_data_en_wr_data_chn, data_mask); } #ifdef __cplusplus diff --git a/components/hal/esp32p4/include/hal/apm_ll.h b/components/hal/esp32p4/include/hal/apm_ll.h new file mode 100644 index 000000000000..9757e44b7cfa --- /dev/null +++ b/components/hal/esp32p4/include/hal/apm_ll.h @@ -0,0 +1,433 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "hal/assert.h" +#include "soc/dma_pms_reg.h" +#include "soc/hp2lp_peri_pms_reg.h" +#include "soc/hp_peri_pms_reg.h" +#include "soc/lp2hp_peri_pms_reg.h" +#include "soc/lp_peri_pms_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Master Secure Mode + */ +typedef enum { + APM_LL_SECURE_MODE_TEE = 0, /* Trusted execution environment mode (Machine mode). */ + APM_LL_SECURE_MODE_REE = 1, /* Rich execution environment mode (User mode). */ + APM_LL_SECURE_MODE_INV = 2, /* Invalid mode. */ +} apm_ll_secure_mode_t; + +/** + * @brief Bus Masters. + */ +typedef enum { + APM_LL_MASTER_LPCPU = 0, + APM_LL_MASTER_HPCPU0, + APM_LL_MASTER_HPCPU1, + APM_LL_MASTER_DMA, +} apm_ll_master_id_t; + + +/** + * @brief APM Controller + */ +typedef enum { + LP_APM_CTRL = 0, + HP2LP_APM_CTRL, + HP_APM_CTRL, + LP2HP_APM_CTRL, + DMA_APM_CTRL, + MAX_APM_CTRL, +} apm_ll_apm_ctrl_t; + +/** + * @brief HP CPU Peripherals. + */ +typedef enum { + PMS_COREn_XM_PSRAM_ALLOW = 0, + PMS_COREn_XM_FLASH_ALLOW, + PMS_COREn_XM_L2MEM_ALLOW, + PMS_COREn_XM_L2ROM_ALLOW, + PMS_COREn_XM_TRACE0_ALLOW = 6, + PMS_COREn_XM_TRACE1_ALLOW, + PMS_COREn_XM_CPU_BUS_MON_ALLOW, + PMS_COREn_XM_L2MEM_MON_ALLOW, + PMS_COREn_XM_TCM_MON_ALLOW, + PMS_COREn_XM_CACHE_ALLOW, + + PMS_COREn_XM_HP_USBOTG_ALLOW = 32, + PMS_COREn_XM_HP_USBOTG11_ALLOW, + PMS_COREn_XM_HP_USBOTG11_WRAP_ALLOW, + PMS_COREn_XM_HP_GDMA_ALLOW, + PMS_COREn_XM_HP_SDMMC_ALLOW = 37, + PMS_COREn_XM_HP_AHB_PDMA_ALLOW, + PMS_COREn_XM_HP_JPEG_ALLOW, + PMS_COREn_XM_HP_PPA_ALLOW, + PMS_COREn_XM_HP_DMA2D_ALLOW, + PMS_COREn_XM_HP_KEY_MANAGER_ALLOW, + PMS_COREn_XM_HP_AXI_PDMA_ALLOW, + PMS_COREn_XM_HP_FLASH_ALLOW, + PMS_COREn_XM_HP_PSRAM_ALLOW, + PMS_COREn_XM_HP_CRYPTO_ALLOW, + PMS_COREn_XM_HP_GMAC_ALLOW, + PMS_COREn_XM_HP_USB_PHY_ALLOW, + PMS_COREn_XM_HP_CSI_HOST_ALLOW = 50, + PMS_COREn_XM_HP_DSI_HOST_ALLOW, + PMS_COREn_XM_HP_ISP_ALLOW, + PMS_COREn_XM_HP_H264_CORE_ALLOW, + PMS_COREn_XM_HP_RMT_ALLOW, + PMS_COREn_XM_HP_BITSRAMBLER_ALLOW, + PMS_COREn_XM_HP_AXI_ICM_ALLOW, + PMS_COREn_XM_HP_PERI_PMS_ALLOW, + PMS_COREn_XM_LP2HP_PERI_PMS_ALLOW, + PMS_COREn_XM_DMA_PMS_ALLOW, + PMS_COREn_XM_HP_H264_DMA2D_ALLOW = 60, + + PMS_COREn_XM_HP_MCPWM0_ALLOW = 64, + PMS_COREn_XM_HP_MCPWM1_ALLOW, + PMS_COREn_XM_HP_TIMER_GROUP0_ALLOW, + PMS_COREn_XM_HP_TIMER_GROUP1_ALLOW, + PMS_COREn_XM_HP_I2C0_ALLOW, + PMS_COREn_XM_HP_I2C1_ALLOW, + PMS_COREn_XM_HP_I2S0_ALLOW, + PMS_COREn_XM_HP_I2S1_ALLOW, + PMS_COREn_XM_HP_I2S2_ALLOW, + PMS_COREn_XM_HP_PCNT_ALLOW, + PMS_COREn_XM_HP_UART0_ALLOW, + PMS_COREn_XM_HP_UART1_ALLOW, + PMS_COREn_XM_HP_UART2_ALLOW, + PMS_COREn_XM_HP_UART3_ALLOW, + PMS_COREn_XM_HP_UART4_ALLOW, + PMS_COREn_XM_HP_PARLIO_ALLOW269 , + PMS_COREn_XM_HP_GPSPI2_ALLOW270 , + PMS_COREn_XM_HP_GPSPI3_ALLOW271 , + PMS_COREn_XM_HP_USBDEVICE_ALLOW, + PMS_COREn_XM_HP_LEDC_ALLOW, + PMS_COREn_XM_HP_ETM_ALLOW = 85, + PMS_COREn_XM_HP_INTRMTX_ALLOW, + PMS_COREn_XM_HP_TWAI0_ALLOW, + PMS_COREn_XM_HP_TWAI1_ALLOW, + PMS_COREn_XM_HP_TWAI2_ALLOW, + PMS_COREn_XM_HP_I3C_MST_ALLOW, + PMS_COREn_XM_HP_I3C_SLV_ALLOW, + PMS_COREn_XM_HP_LCDCAM_ALLOW, + PMS_COREn_XM_HP_ADC_ALLOW = 94, + PMS_COREn_XM_HP_UHCI_ALLOW, + + PMS_COREn_XM_HP_GPIO_ALLOW = 96, + PMS_COREn_XM_HP_IOMUX_ALLOW, + PMS_COREn_XM_HP_SYSTIMER_ALLOW, + PMS_COREn_XM_HP_SYS_REG_ALLOW, + PMS_COREn_XM_HP_CLKRST_ALLOW, + PMS_COREn_XM_HP_PERI_MAX, +} apm_ll_hp_peri_t; + + +/** + * @brief LP CPU Peripherals. + */ +typedef enum { + PMS_MM_LP_SYSREG_ALLOW = 0, + PMS_MM_LP_AONCLKRST_ALLOW, + PMS_MM_LP_TIMER_ALLOW, + PMS_MM_LP_ANAPERI_ALLOW, + PMS_MM_LP_PMU_ALLOW, + PMS_MM_LP_WDT_ALLOW, + PMS_MM_LP_MAILBOX_ALLOW, + PMS_MM_LP_PERICLKRST_ALLOW = 8, + PMS_MM_LP_UART_ALLOW, + PMS_MM_LP_I2C_ALLOW, + PMS_MM_LP_SPI_ALLOW, + PMS_MM_LP_I2CMST_ALLOW, + PMS_MM_LP_I2S_ALLOW, + PMS_MM_LP_ADC_ALLOW, + PMS_MM_LP_TOUCH_ALLOW, + PMS_MM_LP_IOMUX_ALLOW, + PMS_MM_LP_INTR_ALLOW, + PMS_MM_LP_EFUSE_ALLOW, + PMS_MM_LP_PMS_ALLOW, + PMS_MM_HP2LP_PMS_ALLOW, + PMS_MM_LP_TSENS_ALLOW, + PMS_MM_LP_HUK_ALLOW, + PMS_HP_COREn_MM_LP_SRAM_ALLOW, + PMS_LP_MM_PERI_MAX, +} apm_ll_lp_peri_t; + + +/** + * @brief LP CPU Peripherals. + */ +typedef enum { + PMS_DMA_GDMA_CH0 = 0, + PMS_DMA_GDMA_CH1, + PMS_DMA_GDMA_CH2, + PMS_DMA_GDMA_CH3, + PMS_DMA_AHB_PDMA_ADC, + PMS_DMA_AHB_PDMA_I2S0, + PMS_DMA_AHB_PDMA_I2S1, + PMS_DMA_AHB_PDMA_I2S2, + PMS_DMA_AHB_PDMA_I3C_MST, + PMS_DMA_AHB_PDMA_UHCI0, + PMS_DMA_AHB_PDMA_RMT, + PMS_DMA_AXI_PDMA_LCDCAM, + PMS_DMA_AXI_PDMA_GPSPI2, + PMS_DMA_AXI_PDMA_GPSPI3, + PMS_DMA_AXI_PDMA_PARLIO, + PMS_DMA_AXI_PDMA_AES, + PMS_DMA_AXI_PDMA_SHA, + PMS_DMA_DMA2D_JPEG, + PMS_DMA_USB, + PMS_DMA_GMAC, + PMS_DMA_SDMMC, + PMS_DMA_USBOTG11, + PMS_DMA_TRACE0, + PMS_DMA_TRACE1, + PMS_DMA_L2MEM_MON, + PMS_DMA_TCM_MON, + PMS_DMA_H264, + PMS_DMA_DMA2D_PPA, + PMS_DMA_DMA2D_DUMMY, + PMS_DMA_AHB_PDMA_DUMMY, + PMS_DMA_AXI_PDMA_DUMMY, + PMS_DMA_MAX, +} apm_ll_dma_master_t; + +#define PMS_PERI_MAX_REGION_NUM 2 +#define PMS_DMA_MAX_REGION_NUM 32 + +#define PMS_COREn_XM_PMS_REGn_REG(master_id, sec_mode, hp_peri) \ + ({\ + (PMS_CORE0_MM_HP_PERI_PMS_REG0_REG + (master_id * 0x20) \ + + (sec_mode * 0x10) + ((hp_peri/32) * 0x4) ); \ + }) + +#define PMS_PERI_REGION_LOW_REG(regn_num) \ + ({\ + (PMS_PERI_REGION0_LOW_REG + (regn_num * 8)); \ + }) + + +#define PMS_PERI_REGION_HIGH_REG(regn_num) \ + ({\ + (PMS_PERI_REGION0_HIGH_REG + (regn_num * 8)); \ + }) + +#define PMS_DMA_PMS_R_REG(dma_master) \ + ({\ + (PMS_DMA_GDMA_CH0_R_PMS_REG + (dma_master * 8)); \ + }) + +#define PMS_DMA_PMS_W_REG(dma_master) \ + ({\ + (PMS_DMA_GDMA_CH0_W_PMS_REG + (dma_master * 8)); \ + }) + + +/** + * @brief Configure HP peripherals access permission for the HP CPU0/1. + * + * @param master_id HP CPU0/1 + * @param hp_peri HP peripheral whose access permission to be configured. + * @param enable Permission enable/disable + */ +static inline void apm_ll_hp_peri_access_enable(apm_ll_master_id_t master_id, apm_ll_hp_peri_t hp_peri, + apm_ll_secure_mode_t sec_mode, bool enable) +{ + HAL_ASSERT((master_id > APM_LL_MASTER_LPCPU) && (master_id < APM_LL_MASTER_DMA) + && (hp_peri < PMS_COREn_XM_HP_PERI_MAX) && (sec_mode < APM_LL_SECURE_MODE_INV)); + + if (enable) { + REG_SET_BIT(PMS_COREn_XM_PMS_REGn_REG(master_id, sec_mode, hp_peri), BIT(hp_peri%32)); + } else { + REG_CLR_BIT(PMS_COREn_XM_PMS_REGn_REG(master_id, sec_mode, hp_peri), BIT(hp_peri%32)); + } +} + +/** + * @brief Configure LP peripherals access permission for the LP CPU. + * + * @param lp_peri LP peripheral whose access permission to be configured. + * @param enable Permission enable/disable + */ +static inline void apm_ll_lp_peri_access_enable(apm_ll_lp_peri_t lp_peri, bool enable) +{ + HAL_ASSERT(lp_peri < PMS_LP_MM_PERI_MAX); + + if (enable) { + REG_SET_BIT(PMS_LP_MM_LP_PERI_PMS_REG0_REG, BIT(lp_peri)); + } else { + REG_CLR_BIT(PMS_LP_MM_LP_PERI_PMS_REG0_REG, BIT(lp_peri)); + } +} + +/** + * @brief Configure peripherals configurable address ranges. + * + * @param regn_num Configurable address range number. + * @param regn_low_addr Configurable address range start address. + * @param regn_high_addr Configurable address range end address. + */ +static inline void apm_ll_peri_region_config(uint32_t regn_num, uint32_t regn_low_addr, + uint32_t regn_high_addr) +{ + HAL_ASSERT(regn_num < PMS_PERI_MAX_REGION_NUM); + + REG_WRITE(PMS_PERI_REGION_LOW_REG(regn_num), regn_low_addr); + REG_WRITE(PMS_PERI_REGION_HIGH_REG(regn_num), regn_high_addr); +} + +/** + * @brief Configure peripherals configurable address ranges. + * + * @param master_id LP CPU and HP CPU0/1 + * @param sec_mode CPU privilege mode (Machine/User) which corresponds to (TEE/REE). + * @param regn_num Configurable address range number. + * @param regn_pms Configurable address range permission setting(2-bits field). + * Bit 0: Region 0 permission enable/disable. + * Bit 1: Region 1 permission enable/disable. + * @return Configuration performed successfully? + */ +static inline int apm_ll_peri_region_pms(apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode, + uint32_t regn_num, uint32_t regn_pms) +{ + HAL_ASSERT((master_id < APM_LL_MASTER_DMA) && (sec_mode < APM_LL_SECURE_MODE_INV)); + + regn_pms &= 0x3; + + switch(master_id) { + case APM_LL_MASTER_LPCPU: + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_LP_CORE_REGION_PMS, regn_pms); + break; + case APM_LL_MASTER_HPCPU0: + if (sec_mode) { + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE0_UM_REGION_PMS, regn_pms); + } else { + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE0_MM_REGION_PMS, regn_pms); + } + break; + case APM_LL_MASTER_HPCPU1: + if (sec_mode) { + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE1_UM_REGION_PMS, regn_pms); + } else { + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE1_MM_REGION_PMS, regn_pms); + } + break; + default: + return -1; + } + + return 0; +} + +/** + * @brief Configure APM controller clock gating. + * + * @param apm_ctrl APM controller (LP_PERI/HP_PERI/HP_DMA/LP2HP_PERI/HP2LP_PERI). + * @param enable Permission enable/disable. + * enable: Enable automatic clock gating. + * disable: Keep the clock always on. + */ +static inline int apm_ll_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable) +{ + uint32_t reg = 0; + + HAL_ASSERT(apm_ctrl < MAX_APM_CTRL); + + switch(apm_ctrl) { + case LP_APM_CTRL: + reg = PMS_LP_PERI_PMS_CLK_EN_REG; + break; + case HP2LP_APM_CTRL: + reg = PMS_HP2LP_PERI_PMS_CLK_EN_REG; + break; + case HP_APM_CTRL: + reg = PMS_HP_PERI_PMS_CLK_EN_REG; + break; + case LP2HP_APM_CTRL: + reg = PMS_LP2HP_PERI_PMS_CLK_EN_REG; + break; + case DMA_APM_CTRL: + reg = PMS_DMA_CLK_EN_REG; + break; + default: + return -1; + } + + if (enable) { + REG_CLR_BIT(reg, BIT(0)); + } else { + REG_SET_BIT(reg, BIT(0)); + } + + return 0; +} + +/** + * @brief Configure DMA configurable address range low address. + * + * @param regn_num Configurable DMA address range number. + * @param regn_low_addr Configurable DMA address range start address. + */ +static inline void apm_ll_dma_region_set_low_address(uint32_t regn_num, uint32_t regn_low_addr) +{ + HAL_ASSERT(regn_num < PMS_DMA_MAX_REGION_NUM); + + REG_WRITE((PMS_DMA_REGION0_LOW_REG + (regn_num * 8)), regn_low_addr); +} + +/** + * @brief Configure DMA configurable address range high address. + * + * @param regn_num Configurable DMA address range number. + * @param regn_high_addr Configurable DMA address range end address. + */ +static inline void apm_ll_dma_region_set_high_address(uint32_t regn_num, uint32_t regn_high_addr) +{ + HAL_ASSERT(regn_num < PMS_DMA_MAX_REGION_NUM); + + REG_WRITE((PMS_DMA_REGION0_HIGH_REG + (regn_num * 8)), regn_high_addr); +} + +/** + * @brief Configure DMA configurable address range read permission. + * + * @param dma_master DMA master whose access permission to be configured. + * @param regn_mask 32-bits field, each bit for corresponding DMA configurable address range permission. + * 0: Disable read permission. + * 1: Enable read permission. + */ +static inline void apm_ll_dma_region_r_pms(apm_ll_dma_master_t dma_master, uint32_t regn_mask) +{ + HAL_ASSERT(dma_master < PMS_DMA_MAX); + + REG_WRITE(PMS_DMA_PMS_R_REG(dma_master), regn_mask); +} + +/** + * @brief Configure DMA configurable address range write permission. + * + * @param dma_master DMA master whose access permission to be configured. + * @param regn_mask 32-bits field, each bit for corresponding DMA configurable address range permission. + * 0: Disable write permission. + * 1: Enable write permission. + */ +static inline void apm_ll_dma_region_w_pms(apm_ll_dma_master_t dma_master, uint32_t regn_mask) +{ + HAL_ASSERT(dma_master < PMS_DMA_MAX); + + REG_WRITE(PMS_DMA_PMS_W_REG(dma_master), regn_mask); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/axi_dma_ll.h b/components/hal/esp32p4/include/hal/axi_dma_ll.h index 171b20452771..923dcc66ac48 100644 --- a/components/hal/esp32p4/include/hal/axi_dma_ll.h +++ b/components/hal/esp32p4/include/hal/axi_dma_ll.h @@ -59,6 +59,20 @@ static inline void axi_dma_ll_reset_fsm(axi_dma_dev_t *dev) dev->misc_conf.axim_rst_wr_inter = 0; } +/** + * @brief Preset valid memory range for AXI-DMA + * + * @param dev DMA register base address + */ +static inline void axi_dma_ll_set_default_memory_range(axi_dma_dev_t *dev) +{ + // AXI-DMA can access L2MEM, L2ROM, MSPI Flash, MSPI PSRAM + dev->intr_mem_start_addr.val = 0x4FC00000; + dev->intr_mem_end_addr.val = 0x4FFC0000; + dev->extr_mem_start_addr.val = 0x40000000; + dev->extr_mem_end_addr.val = 0x4C000000; +} + ///////////////////////////////////// RX ///////////////////////////////////////// /** * @brief Get DMA RX channel interrupt status word @@ -111,7 +125,7 @@ static inline void axi_dma_ll_rx_enable_owner_check(axi_dma_dev_t *dev, uint32_t } /** - * @brief Enable DMA RX channel burst reading data, disabled by default + * @brief Enable DMA RX channel burst reading data, always enabled */ static inline void axi_dma_ll_rx_enable_data_burst(axi_dma_dev_t *dev, uint32_t channel, bool enable) { @@ -125,6 +139,16 @@ static inline void axi_dma_ll_rx_enable_descriptor_burst(axi_dma_dev_t *dev, uin dev->in[channel].conf.in_conf0.indscr_burst_en_chn = enable; } +/** + * @brief Set the RX channel burst size + */ +static inline void axi_dma_ll_rx_set_burst_size(axi_dma_dev_t *dev, uint32_t channel, uint32_t sz) +{ + HAL_ASSERT(sz >= 8 && sz <= 128); + int ctz = __builtin_ctz(sz); + dev->in[channel].conf.in_conf0.in_burst_size_sel_chn = ctz - 3; +} + /** * @brief Reset DMA RX channel FSM and FIFO pointer */ @@ -259,6 +283,14 @@ static inline void axi_dma_ll_rx_enable_etm_task(axi_dma_dev_t *dev, uint32_t ch dev->in[channel].conf.in_conf0.in_etm_en_chn = enable; } +/** + * @brief Whether to enable access to ecc or aes memory + */ +static inline void axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(axi_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->in[channel].conf.in_conf0.in_ecc_aes_en_chn = enable; +} + ///////////////////////////////////// TX ///////////////////////////////////////// /** * @brief Get DMA TX channel interrupt status word @@ -311,7 +343,7 @@ static inline void axi_dma_ll_tx_enable_owner_check(axi_dma_dev_t *dev, uint32_t } /** - * @brief Enable DMA TX channel burst sending data, disabled by default + * @brief Enable DMA TX channel burst sending data, always enabled */ static inline void axi_dma_ll_tx_enable_data_burst(axi_dma_dev_t *dev, uint32_t channel, bool enable) { @@ -325,6 +357,16 @@ static inline void axi_dma_ll_tx_enable_descriptor_burst(axi_dma_dev_t *dev, uin dev->out[channel].conf.out_conf0.outdscr_burst_en_chn = enable; } +/** + * @brief Set the TX channel burst size + */ +static inline void axi_dma_ll_tx_set_burst_size(axi_dma_dev_t *dev, uint32_t channel, uint32_t sz) +{ + HAL_ASSERT(sz >= 8 && sz <= 128); + int ctz = __builtin_ctz(sz); + dev->out[channel].conf.out_conf0.out_burst_size_sel_chn = ctz - 3; +} + /** * @brief Set TX channel EOF mode */ @@ -457,6 +499,14 @@ static inline void axi_dma_ll_tx_enable_etm_task(axi_dma_dev_t *dev, uint32_t ch dev->out[channel].conf.out_conf0.out_etm_en_chn = enable; } +/** + * @brief Whether to enable access to ecc or aes memory + */ +static inline void axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(axi_dma_dev_t *dev, uint32_t channel, bool enable) +{ + dev->out[channel].conf.out_conf0.out_ecc_aes_en_chn = enable; +} + ///////////////////////////////////// CRC-TX ///////////////////////////////////////// /** diff --git a/components/hal/esp32p4/include/hal/axi_icm_ll.h b/components/hal/esp32p4/include/hal/axi_icm_ll.h new file mode 100644 index 000000000000..eff188d4cdff --- /dev/null +++ b/components/hal/esp32p4/include/hal/axi_icm_ll.h @@ -0,0 +1,180 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include +#include "hal/assert.h" +#include "soc/icm_sys_qos_struct.h" +#include "soc/icm_sys_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + AXI_ICM_MASTER_CPU = 0, // An aggregate master port for other users, like HP CPU, LP CPU, USB, EMAC, SDMMC, AHB-GDMA, etc + AXI_ICM_MASTER_CACHE = 1, // Cache master port + AXI_ICM_MASTER_DW_GDMA_M0 = 5, // DW-GDMA master port 0 + AXI_ICM_MASTER_DW_GDMA_M1 = 6, // DW-GDMA master port 1 + AXI_ICM_MASTER_GDMA = 8, // AXI-GDMA + AXI_ICM_MASTER_DMA2D = 10, // DMA2D + AXI_ICM_MASTER_H264_M0 = 11, // H264 master port 0 + AXI_ICM_MASTER_H264_M1 = 12, // H264 master port 1 +} axi_icm_ll_master_id_t; + +/** + * @brief Set QoS burstiness for a master port, also enable the regulator + * + * @param mid Master port ID + * @param burstiness Burstiness value. It represents the depth of the token bucket. + */ +static inline void axi_icm_ll_set_qos_burstiness(axi_icm_ll_master_id_t mid, uint32_t burstiness) +{ + HAL_ASSERT(burstiness >= 1 && burstiness <= 256); + // wait for the previous command to finish + while (AXI_ICM_QOS.cmd.reg_axi_cmd_en); + // write data register + // data[23:16] - burstiness, data[0] - enable regulator + AXI_ICM_QOS.data.val = (burstiness - 1) << 16 | 0x1; + // command write operation + AXI_ICM_QOS.cmd.reg_axi_rd_wr_cmd = 1; + // write addr channel + AXI_ICM_QOS.cmd.reg_rd_wr_chan = 1; + // select master port + AXI_ICM_QOS.cmd.reg_axi_master_port = mid; + // set command type: burstiness regulator + AXI_ICM_QOS.cmd.reg_axi_cmd = 0; + // command enable bit + AXI_ICM_QOS.cmd.reg_axi_cmd_en = 1; + // wait for the data to be synced to internal register + while (AXI_ICM_QOS.cmd.reg_axi_cmd_en); +} + +/** + * @brief Set QoS peak and transaction rate for a master port + * + * @note Relationship between "level" and fractional rate: + * level = 0: 1/2 + * level = 1: 1/4 + * ... + * level = 11: 1/4096 + * + * @note if the transaction rate is set to 1/N, every N cycles, the master port can accept one transfer request (offer a token). + * + * @param mid Master port ID + * @param peak_level Peak level, lower value means higher rate + * @param transaction_level Transaction level, lower value means higher rate + */ +static inline void axi_icm_ll_set_qos_peak_transaction_rate(axi_icm_ll_master_id_t mid, uint32_t peak_level, uint32_t transaction_level) +{ + HAL_ASSERT(peak_level < transaction_level && transaction_level <= 11); + while (AXI_ICM_QOS.cmd.reg_axi_cmd_en); + // program data register + // data[31:20] - peak_rate, data[15:4] - transaction_rate + AXI_ICM_QOS.data.val = (0x80000000 >> peak_level) + (0x8000 >> transaction_level); + // command write operation + AXI_ICM_QOS.cmd.reg_axi_rd_wr_cmd = 1; + // write addr channel + AXI_ICM_QOS.cmd.reg_rd_wr_chan = 1; + // select master port + AXI_ICM_QOS.cmd.reg_axi_master_port = mid; + // set command type: peak rate xct rate + AXI_ICM_QOS.cmd.reg_axi_cmd = 1; + // command enable bit + AXI_ICM_QOS.cmd.reg_axi_cmd_en = 1; + // wait for the data to be synced to internal register + while (AXI_ICM_QOS.cmd.reg_axi_cmd_en); +} + +/** + * @brief Set QoS priority for DMA2D master port + * + * @param write_prio Write priority + * @param read_prio Read priority + */ +static inline void axi_icm_ll_set_dma2d_qos_arbiter_prio(uint32_t write_prio, uint32_t read_prio) +{ + AXI_ICM.mst_awqos_reg0.reg_dma2d_awqos = write_prio; + AXI_ICM.mst_arqos_reg0.reg_dma2d_arqos = read_prio; +} + +/** + * @brief Set QoS priority for AXI-GDMA master port + * + * @param write_prio Write priority + * @param read_prio Read priority + */ +static inline void axi_icm_ll_set_gdma_qos_arbiter_prio(uint32_t write_prio, uint32_t read_prio) +{ + AXI_ICM.mst_awqos_reg0.reg_pdma_int_awqos = write_prio; + AXI_ICM.mst_arqos_reg0.reg_axi_pdma_int_arqos = read_prio; +} + +/** + * @brief Set QoS priority for DW_GDMA master port + * + * @param master_port DW_GDMA master port ID + * @param write_prio Write priority + * @param read_prio Read priority + */ +static inline void axi_icm_ll_set_dw_gdma_qos_arbiter_prio(uint32_t master_port, uint32_t write_prio, uint32_t read_prio) +{ + if (master_port == 0) { + AXI_ICM.mst_awqos_reg0.reg_gdma_mst1_awqos = write_prio; + AXI_ICM.mst_arqos_reg0.reg_gdma_mst1_arqos = read_prio; + } else { + AXI_ICM.mst_awqos_reg0.reg_gdma_mst2_awqos = write_prio; + AXI_ICM.mst_arqos_reg0.reg_gdma_mst2_arqos = read_prio; + } +} + +/** + * @brief Set QoS priority for H264 master port + * + * @param master_port H264 master port ID + * @param write_prio Write priority + * @param read_prio Read priority + */ +static inline void axi_icm_ll_set_h264_dma_qos_arbiter_prio(uint32_t master_port, uint32_t write_prio, uint32_t read_prio) +{ + if (master_port == 0) { + AXI_ICM.mst_awqos_reg0.reg_h264_dma2d_m1_awqos = write_prio; + AXI_ICM.mst_arqos_reg0.reg_h264_dma2d_m1_arqos = read_prio; + } else { + AXI_ICM.mst_awqos_reg0.reg_h264_dma2d_m2_awqos = write_prio; + AXI_ICM.mst_arqos_reg0.reg_h264_dma2d_m2_arqos = read_prio; + } +} + +/** + * @brief Set QoS priority for Cache master port + * + * @param write_prio Write priority + * @param read_prio Read priority + */ +static inline void axi_icm_ll_set_cache_qos_arbiter_prio(uint32_t write_prio, uint32_t read_prio) +{ + AXI_ICM.mst_awqos_reg0.reg_cache_awqos = write_prio; + AXI_ICM.mst_arqos_reg0.reg_cache_arqos = read_prio; +} + +/** + * @brief Set QoS priority for CPU master port + * + * @param write_prio Write priority + * @param read_prio Read priority + */ +static inline void axi_icm_ll_set_cpu_qos_arbiter_prio(uint32_t write_prio, uint32_t read_prio) +{ + AXI_ICM.mst_awqos_reg0.reg_cpu_awqos = write_prio; + AXI_ICM.mst_arqos_reg0.reg_cpu_arqos = read_prio; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/brownout_ll.h b/components/hal/esp32p4/include/hal/brownout_ll.h new file mode 100644 index 000000000000..e4b338d8a687 --- /dev/null +++ b/components/hal/esp32p4/include/hal/brownout_ll.h @@ -0,0 +1,128 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/readme.md + ******************************************************************************/ + +#pragma once +#include +#include "soc/lp_analog_peri_struct.h" +#include "hal/regi2c_ctrl.h" +#include "soc/regi2c_brownout.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief power down the flash when a brown out happens. + * + * @param enable true: power down flash. false: not power down + */ +static inline void brownout_ll_enable_flash_power_down(bool enable) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_close_flash_ena = enable; +} + +/** + * @brief power down the RF circuits when a brown out happens + * + * @param enable true: power down. false: not power done. + */ +static inline void brownout_ll_enable_rf_power_down(bool enable) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_pd_rf_ena = enable; +} + +/** + * @brief Enable this to reset brown out + * + * @note: If brown out interrupt is used, this should be disabled. + * + * @param reset_ena true: enable reset. false: disable reset. + * @param reset_wait brown out reset wait cycles + * @param select 1: chip reset, 0: system reset + */ +static inline void brownout_ll_reset_config(bool reset_ena, uint32_t reset_wait, uint8_t select) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_reset_wait = reset_wait; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_reset_ena = reset_ena; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_reset_sel = select; +} +/** + * @brief Set brown out threshold + * + * @param threshold brownout threshold + */ +static inline void brownout_ll_set_threshold(uint8_t threshold) +{ + REGI2C_WRITE_MASK(I2C_BOD, I2C_BOD_THRESHOLD, threshold); +} + +/** + * @brief Set this bit to enable the brown out detection + * + * @param bod_enable true: enable, false: disable + */ +static inline void brownout_ll_bod_enable(bool bod_enable) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_intr_ena = bod_enable; +} + +/** + * @brief configure the waiting cycles before sending an interrupt + * + * @param cycle waiting cycles. + */ +static inline void brownout_ll_set_intr_wait_cycles(uint8_t cycle) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_intr_wait = cycle; +} + +/** + * @brief Enable brown out interrupt + * + * @param enable true: enable, false: disable + */ +static inline void brownout_ll_intr_enable(bool enable) +{ + LP_ANA_PERI.int_ena.bod_mode0_int_ena = enable; +} + +/** + * @brief Enable brownout hardware reset + * + * @param enable + */ +static inline void brownout_ll_ana_reset_enable(bool enable) +{ + LP_ANA_PERI.bod_mode1_cntl.bod_mode1_reset_ena = enable; +} + +/** + * @brief Clear interrupt bits. + */ +__attribute__((always_inline)) +static inline void brownout_ll_intr_clear(void) +{ + LP_ANA_PERI.int_clr.bod_mode0_int_clr = 1; +} + +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 1; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/cache_ll.h b/components/hal/esp32p4/include/hal/cache_ll.h index c2f4bbd2f0a4..5e1a07130eee 100644 --- a/components/hal/esp32p4/include/hal/cache_ll.h +++ b/components/hal/esp32p4/include/hal/cache_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,7 @@ #include #include "soc/cache_reg.h" +#include "soc/cache_struct.h" #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" #include "hal/assert.h" @@ -47,8 +48,10 @@ extern "C" { #define CACHE_LL_DEFAULT_IBUS_MASK (CACHE_BUS_IBUS0 | CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2) #define CACHE_LL_DEFAULT_DBUS_MASK (CACHE_BUS_DBUS0 | CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2) -//TODO: IDF-7515 -#define CACHE_LL_L1_ACCESS_EVENT_MASK (0x3f) +#define CACHE_LL_L1_ACCESS_EVENT_MASK (0x1f) +#define CACHE_LL_L2_ACCESS_EVENT_MASK (1<<6) +#define CACHE_LL_L1_CORE0_EVENT_MASK (1<<0) +#define CACHE_LL_L1_CORE1_EVENT_MASK (1<<1) /*------------------------------------------------------------------------------ * Autoload @@ -1019,27 +1022,29 @@ static inline bool cache_ll_vaddr_to_cache_level_id(uint32_t vaddr_start, uint32 * Interrupt *----------------------------------------------------------------------------*/ /** - * @brief Enable Cache access error interrupt + * @brief Enable L1 Cache access error interrupt * * @param cache_id Cache ID * @param mask Interrupt mask */ static inline void cache_ll_l1_enable_access_error_intr(uint32_t cache_id, uint32_t mask) { + CACHE.l1_cache_acs_fail_int_ena.val |= mask; } /** - * @brief Clear Cache access error interrupt status + * @brief Clear L1 Cache access error interrupt status * * @param cache_id Cache ID * @param mask Interrupt mask */ static inline void cache_ll_l1_clear_access_error_intr(uint32_t cache_id, uint32_t mask) { + CACHE.l1_cache_acs_fail_int_clr.val = mask; } /** - * @brief Get Cache access error interrupt status + * @brief Get L1 Cache access error interrupt status * * @param cache_id Cache ID * @param mask Interrupt mask @@ -1048,7 +1053,42 @@ static inline void cache_ll_l1_clear_access_error_intr(uint32_t cache_id, uint32 */ static inline uint32_t cache_ll_l1_get_access_error_intr_status(uint32_t cache_id, uint32_t mask) { - return 0; + return CACHE.l1_cache_acs_fail_int_st.val & mask; +} + +/** + * @brief Enable L2 Cache access error interrupt + * + * @param cache_id Cache ID + * @param mask Interrupt mask + */ +static inline void cache_ll_l2_enable_access_error_intr(uint32_t cache_id, uint32_t mask) +{ + CACHE.l2_cache_acs_fail_int_ena.val |= mask; +} + +/** + * @brief Clear L2 Cache access error interrupt status + * + * @param cache_id Cache ID + * @param mask Interrupt mask + */ +static inline void cache_ll_l2_clear_access_error_intr(uint32_t cache_id, uint32_t mask) +{ + CACHE.l2_cache_acs_fail_int_clr.val = mask; +} + +/** + * @brief Get L2 Cache access error interrupt status + * + * @param cache_id Cache ID + * @param mask Interrupt mask + * + * @return Status mask + */ +static inline uint32_t cache_ll_l2_get_access_error_intr_status(uint32_t cache_id, uint32_t mask) +{ + return CACHE.l2_cache_acs_fail_int_st.val & mask; } #ifdef __cplusplus diff --git a/components/hal/esp32p4/include/hal/cam_ll.h b/components/hal/esp32p4/include/hal/cam_ll.h new file mode 100644 index 000000000000..a48dba2dc838 --- /dev/null +++ b/components/hal/esp32p4/include/hal/cam_ll.h @@ -0,0 +1,634 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "hal/misc.h" +#include "hal/assert.h" +#include "soc/lcd_cam_struct.h" +#include "soc/hp_sys_clkrst_struct.h" +#include "hal/cam_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CAM_LL_GET_HW(id) (((id) == 0) ? (&LCD_CAM) : NULL) + +#define CAM_LL_CLK_FRAC_DIV_N_MAX 256 // CAM_CLK = CAM_CLK_S / (N + b/a), the N register is 8 bit-width +#define CAM_LL_CLK_FRAC_DIV_AB_MAX 64 // CAM_CLK = CAM_CLK_S / (N + b/a), the a/b register is 6 bit-width + +/** + * @brief Enable the bus clock for CAM module + * + * @param group_id Group ID + * @param enable true to enable, false to disable + */ +static inline void cam_ll_enable_bus_clock(int group_id, bool en) +{ + (void)group_id; + HP_SYS_CLKRST.soc_clk_ctrl3.reg_lcdcam_apb_clk_en = en; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define cam_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; cam_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the CAM module + * + * @param group_id Group ID + */ +static inline void cam_ll_reset_register(int group_id) +{ + (void)group_id; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_lcdcam = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_lcdcam = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define cam_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; cam_ll_reset_register(__VA_ARGS__) + +/** + * @brief Enable clock gating + * + * @param group_id Group ID + * @param en True to enable, False to disable + */ +static inline void cam_ll_enable_clk(int group_id, bool en) +{ + HP_SYS_CLKRST.peri_clk_ctrl119.reg_cam_clk_en = en; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define cam_ll_enable_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; cam_ll_enable_clk(__VA_ARGS__) + +/** + * @brief Get the clock status for the CAM module + * + * @return True when enabled, false when disabled + */ +static inline bool cam_ll_get_clk_status(int group_id) +{ + (void)group_id; + return HP_SYS_CLKRST.peri_clk_ctrl119.reg_cam_clk_en; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define cam_ll_get_clk_status(...) (void)__DECLARE_RCC_ATOMIC_ENV; cam_ll_get_clk_status(__VA_ARGS__) + +/** + * @brief Select clock source for CAM peripheral + * + * @param group_id Group ID + * @param src Clock source + */ +static inline void cam_ll_select_clk_src(int group_id, cam_clock_source_t src) +{ + switch (src) { + case CAM_CLK_SRC_XTAL: + HP_SYS_CLKRST.peri_clk_ctrl119.reg_cam_clk_src_sel = 0; + break; + case CAM_CLK_SRC_PLL160M: + HP_SYS_CLKRST.peri_clk_ctrl119.reg_cam_clk_src_sel = 1; + break; + case CAM_CLK_SRC_APLL: + HP_SYS_CLKRST.peri_clk_ctrl119.reg_cam_clk_src_sel = 2; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define cam_ll_select_clk_src(...) (void)__DECLARE_RCC_ATOMIC_ENV; cam_ll_select_clk_src(__VA_ARGS__) + +/** + * @brief Get the CAM source clock type + * + * @param dev CAM register base address + * @param src The pointer to accept the CAM source clock type + */ +static inline void cam_ll_get_clk_src(lcd_cam_dev_t *dev, cam_clock_source_t *src) +{ + switch (HP_SYS_CLKRST.peri_clk_ctrl119.reg_cam_clk_src_sel) { + case 0: + *src = CAM_CLK_SRC_XTAL; + break; + case 1: + *src = CAM_CLK_SRC_PLL160M; + break; + case 2: + *src = CAM_CLK_SRC_APLL; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/** + * @brief Set clock coefficient of CAM peripheral + * + * @param group_id Group ID + * @param div_num Integer part of the divider + * @param div_a denominator of the divider + * @param div_b numerator of the divider + */ +__attribute__((always_inline)) +static inline void cam_ll_set_group_clock_coeff(int group_id, int div_num, int div_a, int div_b) +{ + // cam_clk = module_clock_src / (div_num + div_b / div_a) + HAL_ASSERT(div_num >= 2 && div_num < CAM_LL_CLK_FRAC_DIV_N_MAX); + + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl120, reg_cam_clk_div_num, div_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl120, reg_cam_clk_div_denominator, div_a); + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl120, reg_cam_clk_div_numerator, div_b); +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define cam_ll_set_group_clock_coeff(...) (void)__DECLARE_RCC_ATOMIC_ENV; cam_ll_set_group_clock_coeff(__VA_ARGS__) + +/** + * @brief Enable stop signal for CAM peripheral + * + * @param dev CAM register base address + * @param en True to stop when GDMA Rx FIFO is full, False to not stop + */ +static inline void cam_ll_enable_stop_signal(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl.cam_stop_en = en; +} + +/** + * @brief Set vsync filter threshold value + * + * @param dev CAM register base address + * @param value Filter threshold value for CAM_VSYNC_SIGNAL, range [0, 7] + */ +static inline void cam_ll_set_vsync_filter_thres(lcd_cam_dev_t *dev, uint32_t value) +{ + dev->cam_ctrl.cam_vsync_filter_thres = value; +} + +/** + * @brief Enable to generate LCD_CAM_CAM_HS_INT + * + * @param dev CAM register base address + * @param en True to enable to generate LCD_CAM_CAM_HS_INT, False to disable + */ +static inline void cam_ll_enable_hs_line_int(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl.cam_line_int_en = en; +} + +/** + * @brief Enable CAM_VSYNC to generate in_suc_eof + * + * @param dev CAM register base address + * @param en True to enable CAM_VSYNC to generate in_suc_eof, False to use LCD_CAM_CAM_REC_DATA_BYTELEN to control in_suc_eof + */ +static inline void cam_ll_enable_vsync_generate_eof(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl.cam_vs_eof_en = en; +} + +/** + * @brief Enable to swap every two 8-bit input data + * + * @param dev CAM register base address + * @param en True to enable invert, False to disable invert + */ +static inline void cam_ll_enable_8bits_data_invert(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_rgb_yuv.cam_conv_8bits_data_inv = en; +} + +/** + * @brief Enable YUV-RGB converter + * + * @param dev CAM register base address + * @param en True to enable converter, False to disable converter + */ +static inline void cam_ll_enable_rgb_yuv_convert(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_rgb_yuv.cam_conv_enable = en; +} + +/** + * @brief Set convert data line width + * + * @param dev CAM register base address + * @param width data line width (8 or 16) + */ +static inline void cam_ll_set_convert_data_width(lcd_cam_dev_t *dev, uint32_t width) +{ + HAL_ASSERT(width == 8 || width == 16); + dev->cam_rgb_yuv.cam_conv_mode_8bits_on = (width == 8) ? 1 : 0; +} + +/** + * @brief Set the color range of input data + * + * @param dev CAM register base address + * @param range Color range + */ +static inline void cam_ll_set_input_color_range(lcd_cam_dev_t *dev, color_range_t range) +{ + if (range == COLOR_RANGE_LIMIT) { + dev->cam_rgb_yuv.cam_conv_data_in_mode = 0; + } else if (range == COLOR_RANGE_FULL) { + dev->cam_rgb_yuv.cam_conv_data_in_mode = 1; + } +} + +/** + * @brief Set the color range of output data + * + * @param dev CAM register base address + * @param range Color range + */ +static inline void cam_ll_set_output_color_range(lcd_cam_dev_t *dev, color_range_t range) +{ + if (range == COLOR_RANGE_LIMIT) { + dev->cam_rgb_yuv.cam_conv_data_out_mode = 0; + } else if (range == COLOR_RANGE_FULL) { + dev->cam_rgb_yuv.cam_conv_data_out_mode = 1; + } +} + +/** + * @brief Set YUV conversion standard + * + * @param dev CAM register base address + * @param std YUV conversion standard + */ +static inline void cam_ll_set_yuv_convert_std(lcd_cam_dev_t *dev, color_conv_std_rgb_yuv_t std) +{ + if (std == COLOR_CONV_STD_RGB_YUV_BT601) { + dev->cam_rgb_yuv.cam_conv_protocol_mode = 0; + } else if (std == COLOR_CONV_STD_RGB_YUV_BT709) { + dev->cam_rgb_yuv.cam_conv_protocol_mode = 1; + } +} + +/** + * @brief Set the converter mode: RGB565 to YUV + * + * @param dev CAM register base address + * @param yuv_sample YUV sample mode + */ +static inline void cam_ll_set_convert_mode_rgb_to_yuv(lcd_cam_dev_t *dev, color_pixel_yuv_format_t yuv_sample) +{ + dev->cam_rgb_yuv.cam_conv_trans_mode = 1; + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; + switch (yuv_sample) { + case COLOR_PIXEL_YUV422: + dev->cam_rgb_yuv.cam_conv_yuv_mode = 0; + break; + case COLOR_PIXEL_YUV420: + dev->cam_rgb_yuv.cam_conv_yuv_mode = 1; + break; + case COLOR_PIXEL_YUV411: + dev->cam_rgb_yuv.cam_conv_yuv_mode = 2; + break; + default: + abort(); + } +} + +/** + * @brief Set the converter mode: YUV to RGB565 + * + * @param dev CAM register base address + * @param yuv_sample YUV sample mode + */ +static inline void cam_ll_set_convert_mode_yuv_to_rgb(lcd_cam_dev_t *dev, color_pixel_yuv_format_t yuv_sample) +{ + dev->cam_rgb_yuv.cam_conv_trans_mode = 0; + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; + switch (yuv_sample) { + case COLOR_PIXEL_YUV422: + dev->cam_rgb_yuv.cam_conv_yuv_mode = 0; + break; + case COLOR_PIXEL_YUV420: + dev->cam_rgb_yuv.cam_conv_yuv_mode = 1; + break; + case COLOR_PIXEL_YUV411: + dev->cam_rgb_yuv.cam_conv_yuv_mode = 2; + break; + default: + abort(); + } +} + +/** + * @brief Set the converter mode: YUV to YUV + * + * @param dev CAM register base address + * @param src_sample Source YUV sample mode + * @param dst_sample Destination YUV sample mode + */ +static inline void cam_ll_set_convert_mode_yuv_to_yuv(lcd_cam_dev_t *dev, color_pixel_yuv_format_t src_sample, color_pixel_yuv_format_t dst_sample) +{ + HAL_ASSERT(src_sample != dst_sample); + dev->cam_rgb_yuv.cam_conv_trans_mode = 1; + switch (src_sample) { + case COLOR_PIXEL_YUV422: + dev->cam_rgb_yuv.cam_conv_yuv_mode = 0; + break; + case COLOR_PIXEL_YUV420: + dev->cam_rgb_yuv.cam_conv_yuv_mode = 1; + break; + case COLOR_PIXEL_YUV411: + dev->cam_rgb_yuv.cam_conv_yuv_mode = 2; + break; + default: + abort(); + } + switch (dst_sample) { + case COLOR_PIXEL_YUV422: + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 0; + break; + case COLOR_PIXEL_YUV420: + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 1; + break; + case COLOR_PIXEL_YUV411: + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 2; + break; + default: + abort(); + } +} + +/** + * @brief Set camera received data byte length + * + * @param dev CAM register base address + * @param length received data byte length, range [0, 0xFFFF] + */ +static inline void cam_ll_set_recv_data_bytelen(lcd_cam_dev_t *dev, uint32_t length) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->cam_ctrl1, cam_rec_data_bytelen, length); +} + +/** + * @brief Set line number to trigger interrupt + * + * @param dev CAM register base address + * @param number line number to trigger hs interrupt, range [0, 0x3F] + */ +static inline void cam_ll_set_line_int_num(lcd_cam_dev_t *dev, uint32_t number) +{ + dev->cam_ctrl1.cam_line_int_num = number; +} + +/** + * @brief Whether to invert the input signal CAM_PCLK + * + * @param dev CAM register base address + * @param en True to invert, False to not invert + */ +static inline void cam_ll_enable_invert_pclk(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl1.cam_clk_inv = en; +} + +/** + * @brief Enable CAM_VSYNC filter function + * + * @param dev CAM register base address + * @param en True to enable, False to bypass + */ +static inline void cam_ll_enable_vsync_filter(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl1.cam_vsync_filter_en = en; +} + +/** + * @brief Set CAM input data width + * + * @param dev CAM register base address + * @param stride 16: The bit number of input data is 9~16. 8: The bit number of input data is 0~8. + */ +static inline void cam_ll_set_input_data_width(lcd_cam_dev_t *dev, uint32_t stride) +{ + switch (stride) { + case 8: + dev->cam_ctrl1.cam_2byte_en = 0; + break; + case 16: + dev->cam_ctrl1.cam_2byte_en = 1; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/** + * @brief Whether to invert CAM_DE + * + * @param dev CAM register base address + * @param en True to invert, False to not invert + */ +static inline void cam_ll_enable_invert_de(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl1.cam_de_inv = en; +} + +/** + * @brief Whether to invert CAM_HSYNC + * + * @param dev CAM register base address + * @param en True to invert, False to not invert + */ +static inline void cam_ll_enable_invert_hsync(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl1.cam_hsync_inv = en; +} + +/** + * @brief Whether to invert CAM_VSYNC + * + * @param dev CAM register base address + * @param en True to invert, False to not invert + */ +static inline void cam_ll_enable_invert_vsync(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl1.cam_vsync_inv = en; +} + +/** + * @brief Enable the mode to control the input control signals + * + * @param dev CAM register base address + * @param mode 1: Input control signals are CAM_DE, CAM_HSYNC and CAM_VSYNC; + * 0: Input control signals are CAM_DE and CAM_VSYNC. CAM_HSYNC and CAM_DE are all 1 the the same time. + */ +static inline void cam_ll_set_vh_de_mode(lcd_cam_dev_t *dev, bool enable) +{ + dev->cam_ctrl1.cam_vh_de_mode_en = enable; +} + +/** + * @brief Get the mode of input control signals + * + * @param dev CAM register base address + * @param en The pointer to accept the vh_de mode status. 1: Input control signals are CAM_DE, CAM_HSYNC and CAM_VSYNC; + * 0: Input control signals are CAM_DE and CAM_VSYNC. CAM_HSYNC and CAM_DE are all 1 the the same time. + */ +static inline void cam_ll_get_vh_de_mode(lcd_cam_dev_t *dev, bool *en) +{ + *en = dev->cam_ctrl1.cam_vh_de_mode_en; +} + +/** + * @brief Set the wire width of CAM output + * + * @param dev CAM register base address + * @param width CAM output wire width + */ +static inline void cam_ll_set_data_wire_width(lcd_cam_dev_t *dev, uint32_t width) +{ + // data line width is same as data stride that set in `cam_ll_set_input_data_width` +} + +/** + * @brief Start the CAM transaction + * + * @param dev CAM register base address + */ +__attribute__((always_inline)) +static inline void cam_ll_start(lcd_cam_dev_t *dev) +{ + dev->cam_ctrl.cam_update_reg = 1; + dev->cam_ctrl1.cam_start = 1; +} + +/** + * @brief Stop the CAM transaction + * + * @param dev CAM register base address + */ +__attribute__((always_inline)) +static inline void cam_ll_stop(lcd_cam_dev_t *dev) +{ + dev->cam_ctrl1.cam_start = 0; + dev->cam_ctrl.cam_update_reg = 1; // self clear +} + +/** + * @brief Whether to reverse the data bit order + * + * @note It acts before the YUV-RGB converter + * + * @param dev CAM register base address + * @param en True to reverse, False to not reverse + */ +__attribute__((always_inline)) +static inline void cam_ll_reverse_dma_data_bit_order(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl.cam_bit_order = en; +} + +/** + * @brief Whether to swap adjacent two bytes + * + * @note This acts before the YUV-RGB converter, mainly to change the data endian. + * {B1,B0},{B3,B2} => {B0,B1}{B2,B3} + * + * @param dev CAM register base address + * @param en True to swap the byte order, False to not swap + */ +__attribute__((always_inline)) +static inline void cam_ll_swap_dma_data_byte_order(lcd_cam_dev_t *dev, bool en) +{ + dev->cam_ctrl.cam_byte_order = en; +} + +/** + * @brief Reset camera module + * + * @param dev CAM register base address + */ +__attribute__((always_inline)) +static inline void cam_ll_reset(lcd_cam_dev_t *dev) +{ + dev->cam_ctrl1.cam_reset = 1; // self clear +} + +/** + * @brief Reset Async RX FIFO + * + * @param dev CAM register base address + */ +__attribute__((always_inline)) +static inline void cam_ll_fifo_reset(lcd_cam_dev_t *dev) +{ + dev->cam_ctrl1.cam_afifo_reset = 1; // self clear +} + +/** + * @brief Enable/disable interrupt by mask + * + * @param dev CAM register base address + * @param mask Interrupt mask + * @param en True to enable interrupt, False to disable interrupt + */ +static inline void cam_ll_enable_interrupt(lcd_cam_dev_t *dev, uint32_t mask, bool en) +{ + if (en) { + dev->lc_dma_int_ena.val |= mask & 0x0c; + } else { + dev->lc_dma_int_ena.val &= ~(mask & 0x0c); + } +} + +/** + * @brief Get interrupt status value + * + * @param dev CAM register base address + * @return Interrupt status value + */ +__attribute__((always_inline)) +static inline uint32_t cam_ll_get_interrupt_status(lcd_cam_dev_t *dev) +{ + return dev->lc_dma_int_st.val & 0x0c; +} + +/** + * @brief Clear interrupt status by mask + * + * @param dev CAM register base address + * @param mask Interrupt status mask + */ +__attribute__((always_inline)) +static inline void cam_ll_clear_interrupt_status(lcd_cam_dev_t *dev, uint32_t mask) +{ + dev->lc_dma_int_clr.val = mask & 0x0c; +} + +/** + * @brief Get address of interrupt status register address + * + * @param dev CAM register base address + * @return Interrupt status register address + */ +static inline volatile void *cam_ll_get_interrupt_status_reg(lcd_cam_dev_t *dev) +{ + return &dev->lc_dma_int_st; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/clk_tree_ll.h b/components/hal/esp32p4/include/hal/clk_tree_ll.h index f504917fe7a1..1dd5efd02126 100644 --- a/components/hal/esp32p4/include/hal/clk_tree_ll.h +++ b/components/hal/esp32p4/include/hal/clk_tree_ll.h @@ -9,6 +9,7 @@ #include #include "soc/clkout_channel.h" #include "soc/soc.h" +#include "soc/chip_revision.h" #include "soc/clk_tree_defs.h" #include "soc/hp_sys_clkrst_reg.h" #include "soc/hp_sys_clkrst_struct.h" @@ -22,6 +23,8 @@ #include "hal/log.h" #include "esp32p4/rom/rtc.h" #include "hal/misc.h" +#include "hal/efuse_hal.h" + #ifdef __cplusplus extern "C" { @@ -309,7 +312,11 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpll_get_freq_mhz(u { uint8_t div = REGI2C_READ_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0); uint8_t ref_div = REGI2C_READ_MASK(I2C_CPLL, I2C_CPLL_OC_REF_DIV); - return xtal_freq_mhz * (div + 4) / (ref_div + 1); + unsigned chip_version = efuse_hal_chip_revision(); + if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) { + return xtal_freq_mhz * (div + 4) / (ref_div + 1); + } else + return xtal_freq_mhz * div / (ref_div + 1); } /** @@ -339,19 +346,39 @@ static inline __attribute__((always_inline)) void clk_ll_cpll_set_config(uint32_ // Currently, only supporting 40MHz XTAL HAL_ASSERT(xtal_freq_mhz == SOC_XTAL_FREQ_40M); - switch (cpll_freq_mhz) { - case CLK_LL_PLL_400M_FREQ_MHZ: - /* Configure 400M CPLL */ - div7_0 = 6; - div_ref = 0; - break; - case CLK_LL_PLL_360M_FREQ_MHZ: - default: - /* Configure 360M CPLL */ - div7_0 = 5; - div_ref = 0; - break; + + unsigned chip_version = efuse_hal_chip_revision(); + if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) { + switch (cpll_freq_mhz) { + case CLK_LL_PLL_400M_FREQ_MHZ: + /* Configure 400M CPLL */ + div7_0 = 6; + div_ref = 0; + break; + case CLK_LL_PLL_360M_FREQ_MHZ: + default: + /* Configure 360M CPLL */ + div7_0 = 5; + div_ref = 0; + break; + } + } else { + /*div7_0 bit2 & bit3 is swapped from ECO1*/ + switch (cpll_freq_mhz) { + case CLK_LL_PLL_400M_FREQ_MHZ: + /* Configure 400M CPLL */ + div7_0 = 10; + div_ref = 0; + break; + case CLK_LL_PLL_360M_FREQ_MHZ: + default: + /* Configure 360M CPLL */ + div7_0 = 9; + div_ref = 0; + break; + } } + uint8_t i2c_cpll_lref = (oc_enb_fcal << I2C_CPLL_OC_ENB_FCAL_LSB) | (dchgp << I2C_CPLL_OC_DCHGP_LSB) | (div_ref); uint8_t i2c_cpll_div_7_0 = div7_0; uint8_t i2c_cpll_dcur = (1 << I2C_CPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_CPLL_OC_DHREF_SEL_LSB) | dcur; diff --git a/components/hal/esp32p4/include/hal/cpu_utility_ll.h b/components/hal/esp32p4/include/hal/cpu_utility_ll.h index 5c6b606488be..f9686b8ceaeb 100644 --- a/components/hal/esp32p4/include/hal/cpu_utility_ll.h +++ b/components/hal/esp32p4/include/hal/cpu_utility_ll.h @@ -11,6 +11,7 @@ #include "soc/pmu_struct.h" #include "soc/hp_system_reg.h" #include "esp_attr.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -29,18 +30,22 @@ FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) FORCE_INLINE_ATTR void cpu_utility_ll_stall_cpu(uint32_t cpu_no) { if (cpu_no == 0) { - PMU.cpu_sw_stall.hpcore0_stall_code = 0x86; + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore0_stall_code, 0x86); + while(!REG_GET_BIT(HP_SYSTEM_CPU_CORESTALLED_ST_REG, HP_SYSTEM_REG_CORE0_CORESTALLED_ST)); } else { - PMU.cpu_sw_stall.hpcore1_stall_code = 0x86; + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore1_stall_code, 0x86); + while(!REG_GET_BIT(HP_SYSTEM_CPU_CORESTALLED_ST_REG, HP_SYSTEM_REG_CORE1_CORESTALLED_ST)); } } FORCE_INLINE_ATTR void cpu_utility_ll_unstall_cpu(uint32_t cpu_no) { if (cpu_no == 0) { - PMU.cpu_sw_stall.hpcore0_stall_code = 0xFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore0_stall_code, 0xFF); + while(REG_GET_BIT(HP_SYSTEM_CPU_CORESTALLED_ST_REG, HP_SYSTEM_REG_CORE0_CORESTALLED_ST)); } else { - PMU.cpu_sw_stall.hpcore1_stall_code = 0xFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore1_stall_code, 0xFF); + while(REG_GET_BIT(HP_SYSTEM_CPU_CORESTALLED_ST_REG, HP_SYSTEM_REG_CORE1_CORESTALLED_ST)); } } #endif // SOC_CPU_CORES_NUM > 1 diff --git a/components/hal/esp32p4/include/hal/dma2d_ll.h b/components/hal/esp32p4/include/hal/dma2d_ll.h index 56209130da2a..8ec6f91ea49e 100644 --- a/components/hal/esp32p4/include/hal/dma2d_ll.h +++ b/components/hal/esp32p4/include/hal/dma2d_ll.h @@ -55,7 +55,7 @@ extern "C" { #define DMA2D_LL_EVENT_TX_EOF (1<<1) #define DMA2D_LL_EVENT_TX_DONE (1<<0) -// Bit masks that are used to indicate availbility of some sub-features in the channels +// Bit masks that are used to indicate availability of some sub-features in the channels #define DMA2D_LL_TX_CHANNEL_SUPPORT_RO_MASK (0U | BIT0) // TX channels that support reorder feature #define DMA2D_LL_TX_CHANNEL_SUPPORT_CSC_MASK (0U | BIT0 | BIT1 | BIT2) // TX channels that support color space conversion feature @@ -479,7 +479,7 @@ static inline void dma2d_ll_rx_enable_reorder(dma2d_dev_t *dev, uint32_t channel reg->in_reorder_en_chn = enable; } -// COLOR SPACE CONVERTION FUNCTION +// COLOR SPACE CONVERSION FUNCTION /** * @brief Configure 2D-DMA RX channel color space conversion parameters @@ -825,6 +825,16 @@ static inline void dma2d_ll_tx_enable_dscr_port(dma2d_dev_t *dev, uint32_t chann dev->out_channel[channel].out_conf0.out_dscr_port_en_chn = enable; } +/** + * @brief Set 2D-DMA TX channel block size in dscr-port mode + */ +__attribute__((always_inline)) +static inline void dma2d_ll_tx_set_dscr_port_block_size(dma2d_dev_t *dev, uint32_t channel, uint32_t blk_h, uint32_t blk_v) +{ + dev->out_channel[channel].out_dscr_port_blk.out_dscr_port_blk_h_chn = blk_h; + dev->out_channel[channel].out_dscr_port_blk.out_dscr_port_blk_v_chn = blk_v; +} + /** * @brief Select 2D-DMA TX channel macro block size */ @@ -973,7 +983,7 @@ static inline void dma2d_ll_tx_enable_reorder(dma2d_dev_t *dev, uint32_t channel dev->out_channel[channel].out_conf0.out_reorder_en_chn = enable; } -// COLOR SPACE CONVERTION FUNCTION +// COLOR SPACE CONVERSION FUNCTION /** * @brief Configure 2D-DMA TX channel color space conversion parameters diff --git a/components/hal/esp32p4/include/hal/dw_gdma_ll.h b/components/hal/esp32p4/include/hal/dw_gdma_ll.h index 021e929cf5bb..efe817b8e37d 100644 --- a/components/hal/esp32p4/include/hal/dw_gdma_ll.h +++ b/components/hal/esp32p4/include/hal/dw_gdma_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -932,7 +932,7 @@ static inline uint32_t dw_gdma_ll_channel_get_dst_periph_status(dw_gdma_dev_t *d /** * @brief Type of DW-DMA link list item */ -typedef struct dw_gdma_link_list_item_t { +struct dw_gdma_link_list_item_t { dmac_chn_sar0_reg_t sar_lo; /*!< Source address low 32 bits */ dmac_chn_sar1_reg_t sar_hi; /*!< Source address high 32 bits */ dmac_chn_dar0_reg_t dar_lo; /*!< Destination address low 32 bits */ @@ -949,8 +949,9 @@ typedef struct dw_gdma_link_list_item_t { dmac_chn_status1_reg_t status_hi; /*!< Channel status high 32 bits */ uint32_t reserved_38; uint32_t reserved_3c; -} dw_gdma_link_list_item_t __attribute__((aligned(DW_GDMA_LL_LINK_LIST_ALIGNMENT))); +} __attribute__((aligned(DW_GDMA_LL_LINK_LIST_ALIGNMENT))); +typedef struct dw_gdma_link_list_item_t dw_gdma_link_list_item_t; ESP_STATIC_ASSERT(sizeof(dw_gdma_link_list_item_t) == DW_GDMA_LL_LINK_LIST_ALIGNMENT, "Invalid size of dw_gdma_link_list_item_t structure"); /** @@ -1111,7 +1112,7 @@ __attribute__((always_inline)) static inline void dw_gdma_ll_lli_set_src_burst_len(dw_gdma_link_list_item_t *lli, uint8_t len) { lli->ctrl_hi.arlen_en = len > 0; - lli->ctrl_hi.arlen = len; + HAL_FORCE_MODIFY_U32_REG_FIELD(lli->ctrl_hi, arlen, len); } /** @@ -1124,7 +1125,7 @@ __attribute__((always_inline)) static inline void dw_gdma_ll_lli_set_dst_burst_len(dw_gdma_link_list_item_t *lli, uint8_t len) { lli->ctrl_hi.awlen_en = len > 0; - lli->ctrl_hi.awlen = len; + HAL_FORCE_MODIFY_U32_REG_FIELD(lli->ctrl_hi, awlen, len); } /** diff --git a/components/hal/esp32p4/include/hal/ecc_ll.h b/components/hal/esp32p4/include/hal/ecc_ll.h index 879a438acd54..92d747afbc42 100644 --- a/components/hal/esp32p4/include/hal/ecc_ll.h +++ b/components/hal/esp32p4/include/hal/ecc_ll.h @@ -56,6 +56,9 @@ static inline void ecc_ll_reset_register(void) /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance #define ecc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; ecc_ll_reset_register(__VA_ARGS__) +static inline void ecc_ll_power_up(void) {} +static inline void ecc_ll_power_down(void) {} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32p4/include/hal/ecdsa_ll.h b/components/hal/esp32p4/include/hal/ecdsa_ll.h index 898ce1fd2756..f3429cf1b28b 100644 --- a/components/hal/esp32p4/include/hal/ecdsa_ll.h +++ b/components/hal/esp32p4/include/hal/ecdsa_ll.h @@ -71,6 +71,16 @@ typedef enum { ECDSA_MODE_SHA_CONTINUE } ecdsa_ll_sha_mode_t; +/** + * @brief Get the state of ECDSA peripheral + * + * @return State of ECDSA + */ +static inline uint32_t ecdsa_ll_get_state(void) +{ + return REG_GET_FIELD(ECDSA_STATE_REG, ECDSA_BUSY); +} + /** * @brief Enable the bus clock for ECDSA peripheral module * @@ -95,6 +105,10 @@ static inline void ecdsa_ll_reset_register(void) // Clear reset on parent crypto, otherwise ECDSA is held in reset HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 0; + + while (ecdsa_ll_get_state() != ECDSA_STATE_IDLE) { + ; + } } /** @@ -273,16 +287,6 @@ static inline void ecdsa_ll_set_stage(ecdsa_ll_stage_t stage) } } -/** - * @brief Get the state of ECDSA peripheral - * - * @return State of ECDSA - */ -static inline uint32_t ecdsa_ll_get_state(void) -{ - return REG_GET_FIELD(ECDSA_STATE_REG, ECDSA_BUSY); -} - /** * @brief Set the SHA type * diff --git a/components/hal/esp32p4/include/hal/efuse_ll.h b/components/hal/esp32p4/include/hal/efuse_ll.h index 3032dd041b8f..c287b964dc64 100644 --- a/components/hal/esp32p4/include/hal/efuse_ll.h +++ b/components/hal/esp32p4/include/hal/efuse_ll.h @@ -16,6 +16,15 @@ extern "C" { #endif +typedef enum { + EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state. + EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state. + EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state. + EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state. + EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state. + EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state. +} efuse_controller_state_t; + // Always inline these functions even no gcc optimization is applied. /******************* eFuse fields *************************/ @@ -130,6 +139,11 @@ __attribute__((always_inline)) static inline void efuse_ll_rs_bypass_update(void EFUSE.wr_tim_conf0_rs_bypass.update = 1; } +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void) +{ + return EFUSE.status.state; +} + /******************* eFuse control functions *************************/ #ifdef __cplusplus diff --git a/components/hal/esp32p4/include/hal/emac_ll.h b/components/hal/esp32p4/include/hal/emac_ll.h index 1f72c86177a0..33a5ed8a5c9c 100644 --- a/components/hal/esp32p4/include/hal/emac_ll.h +++ b/components/hal/esp32p4/include/hal/emac_ll.h @@ -411,6 +411,11 @@ static inline void emac_ll_recv_store_forward_enable(emac_dma_dev_t *dma_regs, b dma_regs->dmaoperation_mode.rx_store_forward = enable; } +static inline bool emac_ll_recv_store_forward_is_enabled(emac_dma_dev_t *dma_regs) +{ + return dma_regs->dmaoperation_mode.rx_store_forward; +} + static inline void emac_ll_flush_recv_frame_enable(emac_dma_dev_t *dma_regs, bool enable) { dma_regs->dmaoperation_mode.dis_flush_recv_frames = !enable; @@ -623,11 +628,11 @@ static inline void emac_ll_clock_enable_mii(void *ext_regs) HP_SYS_CLKRST.peri_clk_ctrl00.reg_emac_rx_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl00.reg_emac_rx_clk_src_sel = 1; // 0-pad_emac_txrx_clk, 1-pad_emac_rx_clk - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_rx_clk_div_num = 0; // 25MHz + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_rx_clk_div_num, 0); // 25MHz HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_src_sel = 1; // 0-pad_emac_txrx_clk, 1-pad_emac_tx_clk - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_div_num = 0; // 25MHz + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_tx_clk_div_num, 0); // 25MHz LP_AON_CLKRST.hp_clk_ctrl.hp_pad_emac_tx_clk_en = 1; LP_AON_CLKRST.hp_clk_ctrl.hp_pad_emac_rx_clk_en = 1; @@ -648,11 +653,11 @@ static inline void emac_ll_clock_enable_rmii_input(void *ext_regs) HP_SYS_CLKRST.peri_clk_ctrl00.reg_emac_rx_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl00.reg_emac_rx_clk_src_sel = 0; // 0-pad_emac_txrx_clk, 1-pad_emac_rx_clk - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_rx_clk_div_num = 1; // set default divider + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_rx_clk_div_num, 1); // set default divider HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_src_sel = 0; // 0-pad_emac_txrx_clk, 1-pad_emac_tx_clk - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_div_num = 1; // set default divider + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_tx_clk_div_num, 1); // set default divider LP_AON_CLKRST.hp_clk_ctrl.hp_pad_emac_tx_clk_en = 0; LP_AON_CLKRST.hp_clk_ctrl.hp_pad_emac_rx_clk_en = 0; @@ -665,8 +670,8 @@ static inline void emac_ll_clock_enable_rmii_input(void *ext_regs) static inline void emac_ll_clock_rmii_rx_tx_div(void *ext_regs, int div) { - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_rx_clk_div_num = div; - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_div_num = div; + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_rx_clk_div_num, div); + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_tx_clk_div_num, div); } /// use a macro to wrap the function, force the caller to use it in a critical section diff --git a/components/hal/esp32p4/include/hal/etm_ll.h b/components/hal/esp32p4/include/hal/etm_ll.h index 6904d170ac74..12e11d64323c 100644 --- a/components/hal/esp32p4/include/hal/etm_ll.h +++ b/components/hal/esp32p4/include/hal/etm_ll.h @@ -106,7 +106,7 @@ static inline bool etm_ll_is_channel_enabled(soc_etm_dev_t *hw, uint32_t chan) */ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, uint32_t event) { - hw->channel[chan].evt_id.evt_id = event; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].eid, evt_id, event); } /** @@ -118,7 +118,7 @@ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, ui */ static inline void etm_ll_channel_set_task(soc_etm_dev_t *hw, uint32_t chan, uint32_t task) { - hw->channel[chan].task_id.task_id = task; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].tid, task_id, task); } /** diff --git a/components/hal/esp32p4/include/hal/gpio_etm_ll.h b/components/hal/esp32p4/include/hal/gpio_etm_ll.h index 57101ba37fd6..49281c3366ff 100644 --- a/components/hal/esp32p4/include/hal/gpio_etm_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_etm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,15 +22,20 @@ #define GPIO_LL_ETM_TASK_ID_CLR(ch) (GPIO_TASK_CH0_CLEAR + (ch)) #define GPIO_LL_ETM_TASK_ID_TOG(ch) (GPIO_TASK_CH0_TOGGLE + (ch)) +#define GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP 8 +#define GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP 8 + #ifdef __cplusplus extern "C" { #endif /** - * @brief Set which GPIO to be bounded to the event channel + * @brief Set which GPIO to be bound to the event channel + * + * @note Different channels can be bound to one GPIO * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint32_t chan, uint32_t gpio_num) @@ -39,10 +44,10 @@ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint3 } /** - * @brief Wether to enable the event channel + * @brief Whether to enable the event channel * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param enable True to enable, false to disable */ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_t chan, bool enable) @@ -51,12 +56,24 @@ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Set which GPIO to be bounded to the task channel + * @brief Get which GPIO is bound to the event channel + * + * @param dev Register base address + * @param chan GPIO ETM Event channel number + * @return GPIO number + */ +static inline uint32_t gpio_ll_etm_event_channel_get_gpio(gpio_etm_dev_t *dev, uint32_t chan) +{ + return dev->etm_event_chn_cfg[chan].etm_chn_event_sel; +} + +/** + * @brief Set which GPIO to be bound to the task channel * - * @note One channel can be bounded to multiple different GPIOs + * @note One channel can be bound to multiple different GPIOs * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Task channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num, uint32_t chan) @@ -70,7 +87,7 @@ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32 } /** - * @brief Wether to enable the GPIO to be managed by the task channel + * @brief Whether to enable the GPIO to be managed by the task channel * * @param dev Register base address * @param gpio_num GPIO number @@ -101,7 +118,7 @@ static inline bool gpio_ll_etm_is_task_gpio_enabled(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Get the channel number that the GPIO is bounded to + * @brief Get the channel number that the GPIO is bound to * * @param dev Register base address * @param gpio_num GPIO number diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index 94a4df39183d..f4111b3f7d55 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -64,15 +64,15 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, { uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); uint32_t bit_mask = 1 << bit_shift; - *pu = IOMUX.gpio[gpio_num].fun_wpu; - *pd = IOMUX.gpio[gpio_num].fun_wpd; - *ie = IOMUX.gpio[gpio_num].fun_ie; + *pu = IO_MUX.gpio[gpio_num].fun_wpu; + *pd = IO_MUX.gpio[gpio_num].fun_wpd; + *ie = IO_MUX.gpio[gpio_num].fun_ie; *oe = (((gpio_num < 32) ? hw->enable.val : hw->enable1.val) & bit_mask) >> bit_shift; *od = hw->pin[gpio_num].pad_driver; - *drv = IOMUX.gpio[gpio_num].fun_drv; - *fun_sel = IOMUX.gpio[gpio_num].mcu_sel; + *drv = IO_MUX.gpio[gpio_num].fun_drv; + *fun_sel = IO_MUX.gpio[gpio_num].mcu_sel; *sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; - *slp_sel = IOMUX.gpio[gpio_num].slp_sel; + *slp_sel = IO_MUX.gpio[gpio_num].slp_sel; } /** @@ -83,7 +83,7 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, */ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].fun_wpu = 1; + IO_MUX.gpio[gpio_num].fun_wpu = 1; } /** @@ -95,7 +95,23 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].fun_wpu = 0; + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + // Note that esp32p4 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin + // which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead. + // TODO: read the specific efuse with efuse_ll.h + + // One more noticeable point is P4 has two internal PHYs connecting to USJ and USB_WRAP(OTG1.1) separately. + // We only consider the default connection here: PHY0 -> USJ, PHY1 -> USB_OTG + if (gpio_num == USB_USJ_INT_PHY_DP_GPIO_NUM) { + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; + USB_SERIAL_JTAG.conf0.dp_pullup = 0; + } else if (gpio_num == USB_OTG_INT_PHY_DP_GPIO_NUM) { + USB_WRAP.otg_conf.pad_pull_override = 1; + USB_WRAP.otg_conf.dp_pullup = 0; + } + + IO_MUX.gpio[gpio_num].fun_wpu = 0; } /** @@ -106,7 +122,7 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].fun_wpd = 1; + IO_MUX.gpio[gpio_num].fun_wpd = 1; } /** @@ -118,22 +134,7 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) { - // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value - // USB DP pin is default to PU enabled - // Note that esp32p4 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin - // which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead. - // TODO: read the specific efuse with efuse_ll.h - - // One more noticeable point is P4 has two internal PHYs connecting to USJ and USB_WRAP(OTG1.1) separately. - // We only consider the default connection here: PHY0 -> USJ, PHY1 -> USB_OTG - if (gpio_num == USB_USJ_INT_PHY_DP_GPIO_NUM) { - USB_SERIAL_JTAG.conf0.pad_pull_override = 1; - USB_SERIAL_JTAG.conf0.dp_pullup = 0; - } else if (gpio_num == USB_OTG_INT_PHY_DP_GPIO_NUM) { - USB_WRAP.otg_conf.pad_pull_override = 1; - USB_WRAP.otg_conf.dp_pullup = 0; - } - IOMUX.gpio[gpio_num].fun_wpd = 0; + IO_MUX.gpio[gpio_num].fun_wpd = 0; } /** @@ -235,7 +236,7 @@ static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].fun_ie = 0; + IO_MUX.gpio[gpio_num].fun_ie = 0; } /** @@ -246,7 +247,7 @@ static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].fun_ie = 1; + IO_MUX.gpio[gpio_num].fun_ie = 1; } /** @@ -257,7 +258,7 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].filter_en = 1; + IO_MUX.gpio[gpio_num].filter_en = 1; } /** @@ -268,7 +269,7 @@ static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].filter_en = 0; + IO_MUX.gpio[gpio_num].filter_en = 0; } /** @@ -451,7 +452,7 @@ static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength) { - IOMUX.gpio[gpio_num].fun_drv = strength; + IO_MUX.gpio[gpio_num].fun_drv = strength; } /** @@ -463,7 +464,7 @@ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu */ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength) { - *strength = (gpio_drive_cap_t)(IOMUX.gpio[gpio_num].fun_drv); + *strength = (gpio_drive_cap_t)(IO_MUX.gpio[gpio_num].fun_drv); } /** @@ -472,6 +473,7 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) { uint64_t bit_mask = 1ULL << gpio_num; @@ -497,6 +499,7 @@ static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number, only support output GPIOs */ +__attribute__((always_inline)) static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num) { uint64_t bit_mask = 1ULL << gpio_num; @@ -547,7 +550,7 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) } /** - * @brief Set pad input to a peripheral signal through the IOMUX. + * @brief Set pad input to a peripheral signal through the IO_MUX. * * @param hw Peripheral GPIO hardware instance address. * @param gpio_num GPIO number of the pad. @@ -557,7 +560,7 @@ __attribute__((always_inline)) static inline void gpio_ll_iomux_in(gpio_dev_t *hw, uint32_t gpio, uint32_t signal_idx) { hw->func_in_sel_cfg[signal_idx].sig_in_sel = 0; - IOMUX.gpio[gpio].fun_ie = 1; + IO_MUX.gpio[gpio].fun_ie = 1; } /** @@ -597,11 +600,11 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f } else if (gpio_num == USB_OTG_INT_PHY_DM_GPIO_NUM || gpio_num == USB_OTG_INT_PHY_DP_GPIO_NUM) { USB_WRAP.otg_conf.usb_pad_enable = 0; } - IOMUX.gpio[gpio_num].mcu_sel = func; + IO_MUX.gpio[gpio_num].mcu_sel = func; } /** - * @brief Set peripheral output to an GPIO pad through the IOMUX. + * @brief Set peripheral output to an GPIO pad through the IO_MUX. * * @param hw Peripheral GPIO hardware instance address. * @param gpio_num gpio_num GPIO number of the pad. @@ -685,7 +688,7 @@ static inline void gpio_ll_force_unhold_all(void) */ static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].slp_sel = 1; + IO_MUX.gpio[gpio_num].slp_sel = 1; } /** @@ -697,7 +700,7 @@ static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].slp_sel = 0; + IO_MUX.gpio[gpio_num].slp_sel = 0; } /** @@ -708,7 +711,7 @@ static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].mcu_wpu = 0; + IO_MUX.gpio[gpio_num].mcu_wpu = 0; } /** @@ -719,7 +722,7 @@ static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].mcu_wpu = 1; + IO_MUX.gpio[gpio_num].mcu_wpu = 1; } /** @@ -730,7 +733,7 @@ static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].mcu_wpd = 1; + IO_MUX.gpio[gpio_num].mcu_wpd = 1; } /** @@ -741,7 +744,7 @@ static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].mcu_wpd = 0; + IO_MUX.gpio[gpio_num].mcu_wpd = 0; } /** @@ -752,7 +755,7 @@ static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].mcu_ie = 0; + IO_MUX.gpio[gpio_num].mcu_ie = 0; } /** @@ -763,7 +766,7 @@ static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num */ static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].mcu_ie = 1; + IO_MUX.gpio[gpio_num].mcu_ie = 1; } /** @@ -774,7 +777,7 @@ static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].mcu_oe = 0; + IO_MUX.gpio[gpio_num].mcu_oe = 0; } /** @@ -785,7 +788,7 @@ static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_nu */ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num) { - IOMUX.gpio[gpio_num].mcu_oe = 1; + IO_MUX.gpio[gpio_num].mcu_oe = 1; } #ifdef __cplusplus diff --git a/components/hal/esp32p4/include/hal/gpspi_flash_ll.h b/components/hal/esp32p4/include/hal/gpspi_flash_ll.h index 05c38d87f295..73d64db653b9 100644 --- a/components/hal/esp32p4/include/hal/gpspi_flash_ll.h +++ b/components/hal/esp32p4/include/hal/gpspi_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,7 +23,6 @@ #include #include #include "hal/misc.h" -//TODO: IDF-7499 #ifdef __cplusplus extern "C" { @@ -33,7 +32,7 @@ extern "C" { #define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) ) #define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 ) -typedef typeof(GPSPI2.clock) gpspi_flash_ll_clock_reg_t; +typedef typeof(GPSPI2.clock.val) gpspi_flash_ll_clock_reg_t; #define GPSPI_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ (80) /*------------------------------------------------------------------------------ @@ -46,18 +45,17 @@ typedef typeof(GPSPI2.clock) gpspi_flash_ll_clock_reg_t; */ static inline void gpspi_flash_ll_reset(spi_dev_t *dev) { - // dev->user.val = 0; - // dev->ctrl.val = 0; - - // dev->clk_gate.clk_en = 1; - // dev->clk_gate.mst_clk_active = 1; - // dev->clk_gate.mst_clk_sel = 1; - - // dev->dma_conf.val = 0; - // dev->dma_conf.tx_seg_trans_clr_en = 1; - // dev->dma_conf.rx_seg_trans_clr_en = 1; - // dev->dma_conf.dma_seg_trans_en = 0; - abort(); //TODO: IDF-7499 + dev->user.val = 0; + dev->ctrl.val = 0; + + dev->clk_gate.clk_en = 1; + dev->clk_gate.mst_clk_active = 1; + dev->clk_gate.mst_clk_sel = 1; + + dev->dma_conf.val = 0; + dev->dma_conf.slv_tx_seg_trans_clr_en = 1; + dev->dma_conf.slv_rx_seg_trans_clr_en = 1; + dev->dma_conf.dma_slv_seg_trans_en = 0; } /** @@ -81,21 +79,20 @@ static inline bool gpspi_flash_ll_cmd_is_done(const spi_dev_t *dev) */ static inline void gpspi_flash_ll_get_buffer_data(spi_dev_t *dev, void *buffer, uint32_t read_len) { - // if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) { - // // If everything is word-aligned, do a faster memcpy - // memcpy(buffer, (void *)dev->data_buf, read_len); - // } else { - // // Otherwise, slow(er) path copies word by word - // int copy_len = read_len; - // for (int i = 0; i < (read_len + 3) / 4; i++) { - // int word_len = MIN(sizeof(uint32_t), copy_len); - // uint32_t word = dev->data_buf[i]; - // memcpy(buffer, &word, word_len); - // buffer = (void *)((intptr_t)buffer + word_len); - // copy_len -= word_len; - // } - // } - abort(); //TODO: IDF-7499 + if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) { + // If everything is word-aligned, do a faster memcpy + memcpy(buffer, (void *)dev->data_buf, read_len); + } else { + // Otherwise, slow(er) path copies word by word + int copy_len = read_len; + for (int i = 0; i < (read_len + 3) / 4; i++) { + int word_len = MIN(sizeof(uint32_t), copy_len); + uint32_t word = dev->data_buf[i].buf; + memcpy(buffer, &word, word_len); + buffer = (void *)((intptr_t)buffer + word_len); + copy_len -= word_len; + } + } } /** @@ -106,8 +103,7 @@ static inline void gpspi_flash_ll_get_buffer_data(spi_dev_t *dev, void *buffer, */ static inline void gpspi_flash_ll_write_word(spi_dev_t *dev, uint32_t word) { - // dev->data_buf[0] = word; - abort(); //TODO: IDF-7499 + dev->data_buf[0].buf = word; } /** @@ -119,17 +115,16 @@ static inline void gpspi_flash_ll_write_word(spi_dev_t *dev, uint32_t word) */ static inline void gpspi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *buffer, uint32_t length) { - // // Load data registers, word at a time - // int num_words = (length + 3) / 4; - // for (int i = 0; i < num_words; i++) { - // uint32_t word = 0; - // uint32_t word_len = MIN(length, sizeof(word)); - // memcpy(&word, buffer, word_len); - // dev->data_buf[i] = word; - // length -= word_len; - // buffer = (void *)((intptr_t)buffer + word_len); - // } - abort(); //TODO: IDF-7499 + // Load data registers, word at a time + int num_words = (length + 3) / 4; + for (int i = 0; i < num_words; i++) { + uint32_t word = 0; + uint32_t word_len = MIN(length, sizeof(word)); + memcpy(&word, buffer, word_len); + dev->data_buf[i].buf = word; + length -= word_len; + buffer = (void *)((intptr_t)buffer + word_len); + } } /** @@ -141,7 +136,6 @@ static inline void gpspi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *bu */ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev, bool pe_ops) { - dev->ctrl.hold_pol = 1; dev->cmd.update = 1; while (dev->cmd.update); dev->cmd.usr = 1; @@ -264,7 +258,7 @@ static inline void gpspi_flash_ll_set_read_mode(spi_dev_t *dev, esp_flash_io_mod */ static inline void gpspi_flash_ll_set_clock(spi_dev_t *dev, gpspi_flash_ll_clock_reg_t *clock_val) { - dev->clock.val = (*clock_val).val; + dev->clock.val = *clock_val; } /** @@ -344,10 +338,9 @@ static inline void gpspi_flash_ll_set_addr_bitlen(spi_dev_t *dev, uint32_t bitle */ static inline void gpspi_flash_ll_set_usr_address(spi_dev_t *dev, uint32_t addr, uint32_t bitlen) { - // // The blank region should be all ones - // uint32_t padding_ones = (bitlen == 32? 0 : UINT32_MAX >> bitlen); - // dev->addr = (addr << (32 - bitlen)) | padding_ones; - abort(); //TODO: IDF-7499 + // The blank region should be all ones + uint32_t padding_ones = (bitlen == 32? 0 : UINT32_MAX >> bitlen); + dev->addr.val = (addr << (32 - bitlen)) | padding_ones; } /** @@ -358,8 +351,7 @@ static inline void gpspi_flash_ll_set_usr_address(spi_dev_t *dev, uint32_t addr, */ static inline void gpspi_flash_ll_set_address(spi_dev_t *dev, uint32_t addr) { - // dev->addr = addr; - abort(); //TODO: IDF-7499 + dev->addr.val = addr; } /** @@ -371,7 +363,7 @@ static inline void gpspi_flash_ll_set_address(spi_dev_t *dev, uint32_t addr) static inline void gpspi_flash_ll_set_dummy(spi_dev_t *dev, uint32_t dummy_n) { dev->user.usr_dummy = dummy_n ? 1 : 0; - dev->user1.usr_dummy_cyclelen = dummy_n - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user1, usr_dummy_cyclelen, dummy_n - 1); } /** diff --git a/components/hal/esp32p4/include/hal/huk_ll.h b/components/hal/esp32p4/include/hal/huk_ll.h index 6fa5b98f2aa8..6b5a50a64fd8 100644 --- a/components/hal/esp32p4/include/hal/huk_ll.h +++ b/components/hal/esp32p4/include/hal/huk_ll.h @@ -58,30 +58,36 @@ static inline void huk_ll_continue(void) /* @bried Enable or Disable the HUK interrupts */ static inline void huk_ll_configure_interrupt(const esp_huk_interrupt_type_t intr, const bool en) { - switch(intr) { - case ESP_HUK_INT_PREP_DONE: - REG_SET_FIELD(HUK_INT_ENA_REG, HUK_PREP_DONE_INT_ENA, en); - case ESP_HUK_INT_PROC_DONE: - REG_SET_FIELD(HUK_INT_ENA_REG, HUK_PROC_DONE_INT_ENA, en); - case ESP_HUK_INT_POST_DONE: - REG_SET_FIELD(HUK_INT_ENA_REG, HUK_POST_DONE_INT_ENA, en); - default: - return; + switch (intr) { + case ESP_HUK_INT_PREP_DONE: + REG_SET_FIELD(HUK_INT_ENA_REG, HUK_PREP_DONE_INT_ENA, en); + break; + case ESP_HUK_INT_PROC_DONE: + REG_SET_FIELD(HUK_INT_ENA_REG, HUK_PROC_DONE_INT_ENA, en); + break; + case ESP_HUK_INT_POST_DONE: + REG_SET_FIELD(HUK_INT_ENA_REG, HUK_POST_DONE_INT_ENA, en); + break; + default: + return; } } /* @bried Clear the HUK interrupts */ static inline void huk_ll_clear_int(const esp_huk_interrupt_type_t intr) { - switch(intr) { - case ESP_HUK_INT_PREP_DONE: - REG_SET_FIELD(HUK_INT_CLR_REG, HUK_PREP_DONE_INT_CLR, 1); - case ESP_HUK_INT_PROC_DONE: - REG_SET_FIELD(HUK_INT_CLR_REG, HUK_PROC_DONE_INT_CLR, 1); - case ESP_HUK_INT_POST_DONE: - REG_SET_FIELD(HUK_INT_CLR_REG, HUK_POST_DONE_INT_CLR, 1); - default: - return; + switch (intr) { + case ESP_HUK_INT_PREP_DONE: + REG_SET_FIELD(HUK_INT_CLR_REG, HUK_PREP_DONE_INT_CLR, 1); + break; + case ESP_HUK_INT_PROC_DONE: + REG_SET_FIELD(HUK_INT_CLR_REG, HUK_PROC_DONE_INT_CLR, 1); + break; + case ESP_HUK_INT_POST_DONE: + REG_SET_FIELD(HUK_INT_CLR_REG, HUK_POST_DONE_INT_CLR, 1); + break; + default: + return; } } @@ -108,7 +114,7 @@ static inline esp_huk_gen_status_t huk_ll_get_gen_status(void) */ static inline uint32_t huk_ll_get_date_info(void) { - // Only the least siginificant 28 bits have desired information + // Only the least significant 28 bits have desired information return (uint32_t)(0x0FFFFFFF & REG_READ(HUK_DATE_REG)); } diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index 2773b0b82cac..8792659fcbba 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -63,14 +63,58 @@ extern "C" { #define ISP_LL_EVENT_TAIL_IDI_FRAME (1<<27) #define ISP_LL_EVENT_HEADER_IDI_FRAME (1<<28) -#define ISP_LL_EVENT_ALL_MASK (0x1FFFFFFF) -#define ISP_LL_EVENT_AF_MASK (ISP_LL_EVENT_AF_FDONE | ISP_LL_EVENT_AF_ENV) +#define ISP_LL_EVENT_ALL_MASK (0x1FFFFFFF) +#define ISP_LL_EVENT_AF_MASK (ISP_LL_EVENT_AF_FDONE | ISP_LL_EVENT_AF_ENV) +#define ISP_LL_EVENT_AWB_MASK (ISP_LL_EVENT_AWB_FDONE) /*--------------------------------------------------------------- AF ---------------------------------------------------------------*/ -#define ISP_LL_AF_WINDOW_MAX_RANGE ((1<<12) - 1) +#define ISP_LL_AF_WINDOW_MAX_RANGE ((1<<12) - 1) +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +#define ISP_LL_BF_DEFAULT_TEMPLATE_VAL 15 + +/*--------------------------------------------------------------- + DVP +---------------------------------------------------------------*/ +#define ISP_LL_DVP_DATA_TYPE_RAW8 0x2A +#define ISP_LL_DVP_DATA_TYPE_RAW10 0x2B +#define ISP_LL_DVP_DATA_TYPE_RAW12 0x2C + +/*--------------------------------------------------------------- + AWB +---------------------------------------------------------------*/ +#define ISP_LL_AWB_WINDOW_MAX_RANGE ((1<<12) - 1) +#define ISP_LL_AWB_LUM_MAX_RANGE ((1<<10) - 1) +#define ISP_LL_AWB_RGB_RATIO_INT_BITS (2) +#define ISP_LL_AWB_RGB_RATIO_FRAC_BITS (8) + +typedef union { + struct { + uint32_t fraction: ISP_LL_AWB_RGB_RATIO_FRAC_BITS; + uint32_t integer: ISP_LL_AWB_RGB_RATIO_INT_BITS; + }; + uint32_t val; +} isp_ll_awb_rgb_ratio_t; + +/*--------------------------------------------------------------- + CCM +---------------------------------------------------------------*/ +#define ISP_LL_CCM_MATRIX_INT_BITS (2) +#define ISP_LL_CCM_MATRIX_FRAC_BITS (10) +#define ISP_LL_CCM_MATRIX_TOT_BITS (ISP_LL_CCM_MATRIX_INT_BITS + ISP_LL_CCM_MATRIX_FRAC_BITS + 1) // including one sign bit + +typedef union { + struct { + uint32_t fraction: ISP_LL_AWB_RGB_RATIO_FRAC_BITS; + uint32_t integer: ISP_LL_AWB_RGB_RATIO_INT_BITS; + uint32_t sign: 1; + }; + uint32_t val; +} isp_ll_ccm_gain_t; /** * @brief Env monitor mode @@ -537,6 +581,7 @@ static inline void isp_ll_af_set_window_range(isp_dev_t *hw, uint32_t window_id, * * @return Window sum */ +__attribute__((always_inline)) static inline uint32_t isp_ll_af_get_window_sum(isp_dev_t *hw, uint32_t window_id) { switch (window_id) { @@ -560,6 +605,7 @@ static inline uint32_t isp_ll_af_get_window_sum(isp_dev_t *hw, uint32_t window_i * * @return Window lum */ +__attribute__((always_inline)) static inline uint32_t isp_ll_af_get_window_lum(isp_dev_t *hw, uint32_t window_id) { switch (window_id) { @@ -659,6 +705,82 @@ static inline void isp_ll_bf_enable(isp_dev_t *hw, bool enable) hw->cntl.bf_en = enable; } +/** + * @brief Set ISP BF sigma value + * + * @param[in] hw Hardware instance address + * @param[in] sigmal_val sigma value + */ +static inline void isp_ll_bf_set_sigma(isp_dev_t *hw, uint32_t sigma_val) +{ + hw->bf_sigma.sigma = sigma_val; +} + +/** + * @brief Set ISP BF padding mode + * + * @param[in] hw Hardware instance address + * @param[in] padding_mode padding mode + */ +static inline void isp_ll_bf_set_padding_mode(isp_dev_t *hw, isp_bf_edge_padding_mode_t padding_mode) +{ + hw->bf_matrix_ctrl.bf_padding_mode = padding_mode; +} + +/** + * @brief Set ISP BF padding data + * + * @param[in] hw Hardware instance address + * @param[in] padding_data padding data + */ +static inline void isp_ll_bf_set_padding_data(isp_dev_t *hw, uint32_t padding_data) +{ + hw->bf_matrix_ctrl.bf_padding_data = padding_data; +} + +/** + * @brief Set ISP BF tail pixen pulse tl + * + * @param[in] hw Hardware instance address + * @param[in] start_pixel start pixel value + */ +static inline void isp_ll_bf_set_padding_line_tail_valid_start_pixel(isp_dev_t *hw, uint32_t start_pixel) +{ + hw->bf_matrix_ctrl.bf_tail_pixen_pulse_tl = start_pixel; +} + +/** + * @brief Set ISP BF tail pixen pulse th + * + * @param[in] hw Hardware instance address + * @param[in] end_pixel end pixel value + */ +static inline void isp_ll_bf_set_padding_line_tail_valid_end_pixel(isp_dev_t *hw, uint32_t end_pixel) +{ + hw->bf_matrix_ctrl.bf_tail_pixen_pulse_th = end_pixel; +} + +/** + * @brief Set ISP BF template + * + * @param[in] hw Hardware instance address + * @param[in] template_arr 2-d array for the template + */ +static inline void isp_ll_bf_set_template(isp_dev_t *hw, uint8_t template_arr[SOC_ISP_BF_TEMPLATE_X_NUMS][SOC_ISP_BF_TEMPLATE_Y_NUMS]) +{ + int cnt = 0; + for (int i = 0; i < SOC_ISP_BF_TEMPLATE_X_NUMS; i++) { + for (int j = 0; j < SOC_ISP_BF_TEMPLATE_Y_NUMS; j++) { + if (i == 2 && j == 2) { + break; + } + hw->bf_gau0.val = (hw->bf_gau0.val & ~(0xf << (28 - cnt * 4))) | ((template_arr[i][j] & 0xf) << (28 - cnt * 4)); + cnt++; + } + } + + hw->bf_gau1.gau_template22 = template_arr[2][2]; +} /*--------------------------------------------------------------- CCM ---------------------------------------------------------------*/ @@ -684,6 +806,25 @@ static inline void isp_ll_ccm_enable(isp_dev_t *hw, bool enable) hw->cntl.ccm_en = enable; } +/** + * @brief Set the Color Correction Matrix + * + * @param[in] hw Hardware instance address + * @param[in] fixed_point_matrix Color Correction Matrix in fixed-point format + */ +static inline void isp_ll_ccm_set_matrix(isp_dev_t *hw, isp_ll_ccm_gain_t fixed_point_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION]) +{ + hw->ccm_coef0.ccm_rr = fixed_point_matrix[0][0].val; + hw->ccm_coef0.ccm_rg = fixed_point_matrix[0][1].val; + hw->ccm_coef1.ccm_rb = fixed_point_matrix[0][2].val; + hw->ccm_coef1.ccm_gr = fixed_point_matrix[1][0].val; + hw->ccm_coef3.ccm_gg = fixed_point_matrix[1][1].val; + hw->ccm_coef3.ccm_gb = fixed_point_matrix[1][2].val; + hw->ccm_coef4.ccm_br = fixed_point_matrix[2][0].val; + hw->ccm_coef4.ccm_bg = fixed_point_matrix[2][1].val; + hw->ccm_coef5.ccm_bb = fixed_point_matrix[2][2].val; +} + /*--------------------------------------------------------------- Color ---------------------------------------------------------------*/ @@ -709,6 +850,130 @@ static inline void isp_ll_color_enable(isp_dev_t *hw, bool enable) hw->cntl.color_en = enable; } +/*--------------------------------------------------------------- + DVP Camera +---------------------------------------------------------------*/ +/** + * @brief Set dvp data color format + * + * @param[in] hw Hardware instance address + * @param[in] format color format, see `color_space_pixel_format_t` + * + * @return true for valid format, false for invalid format + */ +static inline bool isp_ll_dvp_set_data_type(isp_dev_t *hw, color_space_pixel_format_t format) +{ + bool valid = false; + + if (format.color_space == COLOR_SPACE_RAW) { + switch(format.pixel_format) { + case COLOR_PIXEL_RAW8: + hw->cam_conf.cam_data_type = ISP_LL_DVP_DATA_TYPE_RAW8; + valid = true; + break; + case COLOR_PIXEL_RAW10: + hw->cam_conf.cam_data_type = ISP_LL_DVP_DATA_TYPE_RAW10; + valid = true; + break; + case COLOR_PIXEL_RAW12: + hw->cam_conf.cam_data_type = ISP_LL_DVP_DATA_TYPE_RAW12; + valid = true; + break; + default: + break; + } + } + + return valid; +} + +/** + * @brief Enable / Disable 2B mode + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_dvp_enable_2byte_mode(isp_dev_t *hw, bool enable) +{ + if (enable) { + HAL_ASSERT(hw->cam_conf.cam_data_type == ISP_LL_DVP_DATA_TYPE_RAW8); + hw->cam_conf.cam_2byte_mode = 1; + } else { + hw->cam_conf.cam_2byte_mode = 0; + } +} + +/** + * @brief Reset DVP CAM module + * + * @param[in] hw Hardware instance address + */ +static inline void isp_ll_dvp_cam_reset(isp_dev_t *hw) +{ + hw->cam_cntl.cam_reset = 1; + hw->cam_cntl.cam_reset = 0; +} + +/** + * @brief Enable DVP CAM pclk invert + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_cam_enable_pclk_invert(isp_dev_t *hw, bool enable) +{ + hw->cam_cntl.cam_clk_inv = enable; +} + +/** + * @brief Enable DVP CAM de invert + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_cam_enable_de_invert(isp_dev_t *hw, bool enable) +{ + hw->cam_conf.cam_de_inv = enable; +} + +/** + * @brief Enable DVP CAM hsync invert + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_cam_enable_hsync_invert(isp_dev_t *hw, bool enable) +{ + hw->cam_conf.cam_hsync_inv = enable; +} + +/** + * @brief Enable DVP CAM vsync invert + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_cam_enable_vsync_invert(isp_dev_t *hw, bool enable) +{ + hw->cam_conf.cam_vsync_inv = enable; +} + +/** + * @brief Enable DVP CAM + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_cam_enable(isp_dev_t *hw, bool enable) +{ + if (enable) { + hw->cam_cntl.cam_update_reg = 1; + hw->cam_cntl.cam_en = 1; + while (hw->cam_cntl.cam_update_reg); + } else { + hw->cam_cntl.cam_en = 0; + } +} /*--------------------------------------------------------------- INTR ---------------------------------------------------------------*/ @@ -742,6 +1007,18 @@ static inline uint32_t isp_ll_get_intr_status(isp_dev_t *hw) return hw->int_st.val; } +/** + * @brief Get interrupt status reg address + * + * @param[in] hw Hardware instance address + * + * @return Interrupt status reg address + */ +static inline uint32_t isp_ll_get_intr_status_reg_addr(isp_dev_t *hw) +{ + return (uint32_t)&(hw->int_st); +} + /** * @brief Get interrupt raw * @@ -767,6 +1044,164 @@ static inline void isp_ll_clear_intr(isp_dev_t *hw, uint32_t mask) hw->int_clr.val = mask; } +/*--------------------------------------------------------------- + AWB +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable AWB clock + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_awb_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_awb_force_on = enable; +} + +/** + * @brief Enable AWB statistics + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +__attribute__((always_inline)) +static inline void isp_ll_awb_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.awb_en = enable; +} + +/** + * @brief Set AWB sample point + * + * @param[in] hw Hardware instance address + * @param[in] point Sample point + * - 0: Before CCM + * - 1: After CCM + */ +static inline void isp_ll_awb_set_sample_point(isp_dev_t *hw, isp_awb_sample_point_t point) +{ + hw->awb_mode.awb_sample = point; +} + +/** + * @brief Set AWB algorithm mode + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable algorithm mode 1 + */ +static inline void isp_ll_awb_enable_algorithm_mode(isp_dev_t *hw, bool enable) +{ + hw->awb_mode.awb_mode = enable; +} + +/** + * @brief Set AWB window range + * + * @param[in] hw Hardware instance address + * @param[in] top_left_x Top left pixel x axis value + * @param[in] top_left_y Top left pixel y axis value + * @param[in] bottom_right_x Bottom right pixel x axis value + * @param[in] bottom_right_y Bottom right pixel y axis value + */ +static inline void isp_ll_awb_set_window_range(isp_dev_t *hw, uint32_t top_left_x, uint32_t top_left_y, uint32_t bottom_right_x, uint32_t bottom_right_y) +{ + hw->awb_hscale.awb_lpoint = top_left_x; + hw->awb_vscale.awb_tpoint = top_left_y; + hw->awb_hscale.awb_rpoint = bottom_right_x; + hw->awb_vscale.awb_bpoint = bottom_right_y; +} + +/** + * @brief Set AWB luminance range + * + * @param[in] hw Hardware instance address + * @param[in] min Minimum luminance + * @param[in] max Maximum luminance + */ +static inline void isp_ll_awb_set_luminance_range(isp_dev_t *hw, uint32_t min, uint32_t max) +{ + hw->awb_th_lum.awb_min_lum = min; + hw->awb_th_lum.awb_max_lum = max; +} + +/** + * @brief Set AWB R/G ratio range + * + * @param[in] hw Hardware instance address + * @param[in] min Minimum R/G ratio in fixed-point data type + * @param[in] max Maximum R/G ratio in fixed-point data type + */ +static inline void isp_ll_awb_set_rg_ratio_range(isp_dev_t *hw, isp_ll_awb_rgb_ratio_t min, isp_ll_awb_rgb_ratio_t max) +{ + hw->awb_th_rg.awb_min_rg = min.val; + hw->awb_th_rg.awb_max_rg = max.val; +} + +/** + * @brief Set AWB B/G ratio range + * + * @param[in] hw Hardware instance address + * @param[in] min Minimum B/G ratio in fixed-point data type + * @param[in] max Maximum B/G ratio in fixed-point data type + */ +static inline void isp_ll_awb_set_bg_ratio_range(isp_dev_t *hw, isp_ll_awb_rgb_ratio_t min, isp_ll_awb_rgb_ratio_t max) +{ + hw->awb_th_bg.awb_min_bg = min.val; + hw->awb_th_bg.awb_max_bg = max.val; +} + +/** + * @brief Get AWB white patch count + * + * @param[in] hw Hardware instance address + * @return + * - white patch count + */ +__attribute__((always_inline)) +static inline uint32_t isp_ll_awb_get_white_patch_cnt(isp_dev_t *hw) +{ + return hw->awb0_white_cnt.awb0_white_cnt; +} + +/** + * @brief Get AWB accumulated R value of white patches + * + * @param[in] hw Hardware instance address + * @return + * - Accumulated R value of white patches + */ +__attribute__((always_inline)) +static inline uint32_t isp_ll_awb_get_accumulated_r_value(isp_dev_t *hw) +{ + return hw->awb0_acc_r.awb0_acc_r; +} + +/** + * @brief Get AWB accumulated G value of white patches + * + * @param[in] hw Hardware instance address + * @return + * - Accumulated G value of white patches + */ +__attribute__((always_inline)) +static inline uint32_t isp_ll_awb_get_accumulated_g_value(isp_dev_t *hw) +{ + return hw->awb0_acc_g.awb0_acc_g; +} + +/** + * @brief Get AWB accumulated B value of white patches + * + * @param[in] hw Hardware instance address + * @return + * - Accumulated B value of white patches + */ +__attribute__((always_inline)) +static inline uint32_t isp_ll_awb_get_accumulated_b_value(isp_dev_t *hw) +{ + return hw->awb0_acc_b.awb0_acc_b; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/key_mgr_ll.h b/components/hal/esp32p4/include/hal/key_mgr_ll.h index 1d6d05eba57c..15923a67ffa0 100644 --- a/components/hal/esp32p4/include/hal/key_mgr_ll.h +++ b/components/hal/esp32p4/include/hal/key_mgr_ll.h @@ -10,9 +10,7 @@ ******************************************************************************/ #pragma once -#include "soc/soc_caps.h" -#if SOC_KEY_MANAGER_SUPPORTED #include #include #include @@ -21,7 +19,6 @@ #include "hal/key_mgr_types.h" #include "soc/keymng_reg.h" #include "soc/hp_sys_clkrst_struct.h" -#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { @@ -29,29 +26,32 @@ extern "C" { /** * @brief Enable the bus clock for Key Manager peripheral - * + * Note: Please use key_mgr_ll_enable_bus_clock which requires the critical section + * and do not use _key_mgr_ll_enable_bus_clock * @param true to enable, false to disable */ -static inline void key_mgr_ll_enable_bus_clock(bool enable) +static inline void _key_mgr_ll_enable_bus_clock(bool enable) { HP_SYS_CLKRST.soc_clk_ctrl1.reg_key_manager_sys_clk_en = enable; } /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define key_mgr_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; key_mgr_ll_enable_bus_clock(__VA_ARGS__) +#define key_mgr_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _key_mgr_ll_enable_bus_clock(__VA_ARGS__) /** * @brief Enable the peripheral clock for Key Manager * + * Note: Please use key_mgr_ll_enable_peripheral_clock which requires the critical section + * and do not use _key_mgr_ll_enable_peripheral_clock * @param true to enable, false to disable */ -static inline void key_mgr_ll_enable_peripheral_clock(bool enable) +static inline void _key_mgr_ll_enable_peripheral_clock(bool enable) { HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_km_clk_en = enable; } -#define key_mgr_ll_enable_peripheral_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; key_mgr_ll_enable_bus_clock(__VA_ARGS__) +#define key_mgr_ll_enable_peripheral_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _key_mgr_ll_enable_peripheral_clock(__VA_ARGS__) /** * @brief Reset the Key Manager peripheral */ @@ -345,4 +345,3 @@ static inline uint32_t key_mgr_ll_get_date_info(void) #ifdef __cplusplus } #endif -#endif diff --git a/components/hal/esp32p4/include/hal/ldo_ll.h b/components/hal/esp32p4/include/hal/ldo_ll.h index d470107d5cbe..96ae2250f0b5 100644 --- a/components/hal/esp32p4/include/hal/ldo_ll.h +++ b/components/hal/esp32p4/include/hal/ldo_ll.h @@ -42,17 +42,6 @@ extern "C" { #define LDO_LL_EXT_LDO_MUL_VOL_BASE 1000 #define LDO_LL_EXT_LDO_MUL_VOL_STEP 250 -/** - * Trick to be adapted to the LDO register structure - * - * In pmu_ext_ldo_info_t ext_ldo[6] registers: - * - ext_ldo[0] is LDO1 - * - ext_ldo[3] is LDO2 - * - ext_ldo[1] is LDO3 - * - ext_ldo[4] is LDO4 - */ -#define LDO_ID2INDEX(id) (uint8_t[]){0,3,1,4}[id] - /** * LDO ID to real unit ID */ @@ -79,8 +68,8 @@ __attribute__((always_inline)) static inline void ldo_ll_enable(int ldo_id, bool enable) { HAL_ASSERT(ldo_id < LDO_LL_UNIT_NUM); - - PMU.ext_ldo[LDO_ID2INDEX(ldo_id)].pmu_ext_ldo.xpd = enable; + uint8_t index_array[LDO_LL_UNIT_NUM] = {0,3,1,4}; + PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo.xpd = enable; } /** @@ -150,11 +139,12 @@ static inline void ldo_ll_set_output_voltage_mv(int ldo_id, int voltage_mv) * - 0: efuse * - 1: tieh_sel */ - PMU.ext_ldo[LDO_ID2INDEX(ldo_id)].pmu_ext_ldo.tieh_sel = 0; - PMU.ext_ldo[LDO_ID2INDEX(ldo_id)].pmu_ext_ldo.tieh = 0; - PMU.ext_ldo[LDO_ID2INDEX(ldo_id)].pmu_ext_ldo.force_tieh_sel = 1; - PMU.ext_ldo[LDO_ID2INDEX(ldo_id)].pmu_ext_ldo_ana.dref = dref; - PMU.ext_ldo[LDO_ID2INDEX(ldo_id)].pmu_ext_ldo_ana.mul = mul; + uint8_t index_array[LDO_LL_UNIT_NUM] = {0,3,1,4}; + PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo.tieh_sel = 0; + PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo.tieh = 0; + PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo.force_tieh_sel = 1; + PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo_ana.dref = dref; + PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo_ana.mul = mul; } #ifdef __cplusplus diff --git a/components/hal/esp32p4/include/hal/lp_core_ll.h b/components/hal/esp32p4/include/hal/lp_core_ll.h index d67c0c52bbf6..b045f4703cfc 100644 --- a/components/hal/esp32p4/include/hal/lp_core_ll.h +++ b/components/hal/esp32p4/include/hal/lp_core_ll.h @@ -148,6 +148,15 @@ static inline void lp_core_ll_request_sleep(void) PMU.lp_ext.pwr1.sleep_req = 1; } +/** + * @brief Clear the ETM wakeup interrupt sources on the LP core + * + */ +static inline void lp_core_ll_clear_etm_wakeup_status(void) +{ + LP_SYS.sys_ctrl.lp_core_etm_wakeup_flag_clr = 1; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/lp_i2s_ll.h b/components/hal/esp32p4/include/hal/lp_i2s_ll.h index 17f3aba185f5..c25e3c57dfdf 100644 --- a/components/hal/esp32p4/include/hal/lp_i2s_ll.h +++ b/components/hal/esp32p4/include/hal/lp_i2s_ll.h @@ -23,7 +23,7 @@ extern "C" { #endif -#define I2S_LL_GET_HW(num) (((num) == 0)? (&LP_I2S) : NULL) +#define LP_I2S_LL_GET_HW(num) (((num) == 0)? (&LP_I2S) : NULL) #define LP_I2S_LL_EVENT_RX_DONE_INT (1<<0) #define LP_I2S_LL_EVENT_RX_HUNG_INT_INT (1<<1) @@ -146,7 +146,7 @@ static inline void lp_i2s_ll_clk_source_div_num(int id, uint32_t val) * @param a div a * @param b div b */ -static inline void i2s_ll_tx_set_raw_clk_div(int id, uint32_t a, uint32_t b) +static inline void lp_i2s_ll_tx_set_raw_clk_div(int id, uint32_t a, uint32_t b) { if (b <= a / 2) { LPPERI.lp_i2s_rxclk_div_xyz.lp_i2s_rx_clkm_div_yn1 = 0; @@ -297,7 +297,7 @@ static inline void lp_i2s_ll_rx_enable_pdm(lp_i2s_dev_t *hw) /** * @brief Configure LP I2S rx channel bits and bits mode */ -static inline void i2s_ll_rx_set_sample_bit(lp_i2s_dev_t *hw, int chan_bits, int bits_mode) +static inline void lp_i2s_ll_rx_set_sample_bit(lp_i2s_dev_t *hw, int chan_bits, int bits_mode) { hw->rx_conf1.rx_tdm_chan_bits = chan_bits - 1; hw->rx_conf1.rx_bits_mod = bits_mode - 1; diff --git a/components/hal/esp32p4/include/hal/lp_timer_ll.h b/components/hal/esp32p4/include/hal/lp_timer_ll.h index 034d9f5c6872..45e8ad3fa868 100644 --- a/components/hal/esp32p4/include/hal/lp_timer_ll.h +++ b/components/hal/esp32p4/include/hal/lp_timer_ll.h @@ -15,6 +15,7 @@ #include "soc/lp_timer_reg.h" #include "soc/lp_system_reg.h" #include "hal/lp_timer_types.h" +#include "hal/misc.h" #include "esp_attr.h" #ifdef __cplusplus @@ -23,8 +24,8 @@ extern "C" { FORCE_INLINE_ATTR void lp_timer_ll_set_alarm_target(lp_timer_dev_t *dev, uint8_t timer_id, uint64_t value) { - dev->target[timer_id].hi.target_hi = (value >> 32) & 0xFFFF; - dev->target[timer_id].lo.target_lo = value & 0xFFFFFFFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].hi, target_hi, (value >> 32) & 0xFFFF); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].lo, target_lo, value & 0xFFFFFFFF); } FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_t timer_id, bool en) @@ -34,12 +35,12 @@ FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_ FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev, uint8_t timer_id) { - return dev->counter[timer_id].lo.counter_lo; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[timer_id].lo, counter_lo); } FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_high(lp_timer_dev_t *dev, uint8_t timer_id) { - return dev->counter[timer_id].hi.counter_hi; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[timer_id].hi, counter_hi); } FORCE_INLINE_ATTR void lp_timer_ll_counter_snapshot(lp_timer_dev_t *dev) diff --git a/components/hal/esp32p4/include/hal/mipi_dsi_brg_ll.h b/components/hal/esp32p4/include/hal/mipi_dsi_brg_ll.h index 7c399550bbc3..adfdacad7014 100644 --- a/components/hal/esp32p4/include/hal/mipi_dsi_brg_ll.h +++ b/components/hal/esp32p4/include/hal/mipi_dsi_brg_ll.h @@ -14,6 +14,7 @@ #include "hal/lcd_types.h" #define MIPI_DSI_LL_GET_BRG(bus_id) (bus_id == 0 ? &MIPI_DSI_BRIDGE : NULL) +#define MIPI_DSI_LL_EVENT_UNDERRUN (1 << 0) #ifdef __cplusplus extern "C" { @@ -35,6 +36,46 @@ static inline void mipi_dsi_brg_ll_enable(dsi_brg_dev_t *dev, bool en) dev->en.dsi_en = en; } +/** + * @brief Enable DSI bridge interrupt for specific event mask + * + * @param dev Pointer to the DSI bridge controller register base address + * @param mask Event mask + * @param enable True to enable, False to disable + */ +static inline void mipi_dsi_brg_ll_enable_interrupt(dsi_brg_dev_t *dev, uint32_t mask, bool enable) +{ + if (enable) { + dev->int_ena.val |= mask; + } else { + dev->int_ena.val &= ~mask; + } +} + +/** + * @brief Clear DSI bridge interrupt for specific event mask + * + * @param dev Pointer to the DSI bridge controller register base address + * @param mask Event mask + */ +__attribute__((always_inline)) +static inline void mipi_dsi_brg_ll_clear_interrupt_status(dsi_brg_dev_t *dev, uint32_t mask) +{ + dev->int_clr.val = mask; +} + +/** + * @brief Get interrupt status for DSI bridge + * + * @param dev Pointer to the DSI bridge controller register base address + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t mipi_dsi_brg_ll_get_interrupt_status(dsi_brg_dev_t *dev) +{ + return dev->int_st.val; +} + /** * @brief Set the number of 64-bit words in one dma burst transfer * @@ -242,7 +283,7 @@ static inline void mipi_dsi_brg_ll_enable_ref_clock(dsi_brg_dev_t *dev, bool en) * @param dev Pointer to the DSI bridge controller register base address * @param controller Flow controller */ -static inline void mipi_dsi_brg_ll_set_flow_controller(dsi_brg_dev_t* dev, mipi_dsi_ll_flow_controller_t controller) +static inline void mipi_dsi_brg_ll_set_flow_controller(dsi_brg_dev_t *dev, mipi_dsi_ll_flow_controller_t controller) { dev->dma_flow_ctrl.dsi_dma_flow_controller = controller; } @@ -255,9 +296,21 @@ static inline void mipi_dsi_brg_ll_set_flow_controller(dsi_brg_dev_t* dev, mipi_ * @param dev Pointer to the DSI bridge controller register base address * @param number Number of blocks */ -static inline void mipi_dsi_brg_ll_set_multi_block_number(dsi_brg_dev_t* dev, uint32_t number) +static inline void mipi_dsi_brg_ll_set_multi_block_number(dsi_brg_dev_t *dev, uint32_t number) { dev->dma_flow_ctrl.dma_flow_multiblk_num = number; + dev->dma_frame_interval.dma_multiblk_en = number > 1; +} + +/** + * @brief Get the FIFO depth of the DSI bridge + * + * @param dev Pointer to the DSI bridge controller register base address + * @return FIFO depth + */ +static inline uint32_t mipi_dsi_brg_ll_get_fifo_depth(dsi_brg_dev_t *dev) +{ + return dev->fifo_flow_status.raw_buf_depth; } /** @@ -266,7 +319,7 @@ static inline void mipi_dsi_brg_ll_set_multi_block_number(dsi_brg_dev_t* dev, ui * @param dev Pointer to the DSI bridge controller register base address * @param std YUV-RGB conversion standard */ -static inline void mipi_dsi_brg_ll_set_yuv_convert_std(dsi_brg_dev_t* dev, lcd_yuv_conv_std_t std) +static inline void mipi_dsi_brg_ll_set_yuv_convert_std(dsi_brg_dev_t *dev, lcd_yuv_conv_std_t std) { switch (std) { case LCD_YUV_CONV_STD_BT601: diff --git a/components/hal/esp32p4/include/hal/mipi_dsi_ll.h b/components/hal/esp32p4/include/hal/mipi_dsi_ll.h index 6c37ea589b5b..e876817684e4 100644 --- a/components/hal/esp32p4/include/hal/mipi_dsi_ll.h +++ b/components/hal/esp32p4/include/hal/mipi_dsi_ll.h @@ -14,7 +14,8 @@ #include "hal/mipi_dsi_brg_ll.h" #include "hal/mipi_dsi_phy_ll.h" -#define MIPI_DSI_LL_NUM_BUS 1 // 1 MIPI DSI bus +#define MIPI_DSI_LL_NUM_BUS 1 // support only 1 MIPI DSI bus +#define MIPI_DSI_LL_MAX_DATA_LANES 2 // support up to 2 data lanes #ifdef __cplusplus extern "C" { diff --git a/components/hal/esp32p4/include/hal/mipi_dsi_phy_ll.h b/components/hal/esp32p4/include/hal/mipi_dsi_phy_ll.h index b89de14d87dd..9cb2d1e1fbd2 100644 --- a/components/hal/esp32p4/include/hal/mipi_dsi_phy_ll.h +++ b/components/hal/esp32p4/include/hal/mipi_dsi_phy_ll.h @@ -81,12 +81,19 @@ static inline bool mipi_dsi_phy_ll_is_pll_locked(dsi_host_dev_t *dev) * @brief Check if the all active lanes are in the stop state * * @param dev Pointer to the DSI Host controller register base address + * @param num_data_lanes Number of data lanes * @return True if the lanes are all in stop state, False otherwise */ -static inline bool mipi_dsi_phy_ll_are_lanes_stopped(dsi_host_dev_t *dev) +static inline bool mipi_dsi_phy_ll_are_lanes_stopped(dsi_host_dev_t *dev, uint8_t num_data_lanes) { uint32_t status = dev->phy_status.val; - const uint32_t mask = 1 << 2 | 1 << 4 | 1 << 7; + uint32_t mask = 1 << 2; + if (num_data_lanes > 0) { + mask |= 1 << 4; + } + if (num_data_lanes > 1) { + mask |= 1 << 7; + } return (status & mask) == mask; } diff --git a/components/hal/esp32p4/include/hal/mmu_ll.h b/components/hal/esp32p4/include/hal/mmu_ll.h index 5a8c01d330b4..bca29735a645 100644 --- a/components/hal/esp32p4/include/hal/mmu_ll.h +++ b/components/hal/esp32p4/include/hal/mmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,11 +20,12 @@ extern "C" { #endif -///< MMU is per target -#define MMU_LL_MMU_PER_TARGET 1 - #define MMU_LL_FLASH_MMU_ID 0 #define MMU_LL_PSRAM_MMU_ID 1 +#define MMU_LL_FLASH_VADDR_TO_PSRAM_VADDR(flash_vaddr) ((flash_vaddr) + SOC_IRAM_FLASH_PSRAM_OFFSET) +#define MMU_LL_PSRAM_VADDR_TO_FLASH_VADDR(psram_vaddr) ((psram_vaddr) - SOC_IRAM_FLASH_PSRAM_OFFSET) +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - SOC_MMU_PAGE_SIZE) +#define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1) /** * Convert MMU virtual address to linear address @@ -344,7 +345,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h b/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h index 9f2e152698df..6b84ef3c263b 100644 --- a/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h +++ b/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h @@ -18,6 +18,7 @@ #include "soc/soc.h" #include "soc/iomux_mspi_pin_reg.h" #include "soc/iomux_mspi_pin_struct.h" +#include "soc/hp_sys_clkrst_reg.h" #ifdef __cplusplus extern "C" { @@ -71,6 +72,20 @@ typedef enum { MSPI_LL_PIN_MAX, } mspi_ll_pin_t; +/** + * Reset the MSPI clock + */ +__attribute__((always_inline)) +static inline void _mspi_timing_ll_reset_mspi(void) +{ + REG_SET_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_MSPI_AXI); + REG_CLR_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_MSPI_AXI); +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define mspi_timing_ll_reset_mspi(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _mspi_timing_ll_reset_mspi(__VA_ARGS__) + /** * Set all MSPI DQS phase * diff --git a/components/hal/esp32p4/include/hal/parlio_ll.h b/components/hal/esp32p4/include/hal/parlio_ll.h index fe96975c2a46..f863acf27718 100644 --- a/components/hal/esp32p4/include/hal/parlio_ll.h +++ b/components/hal/esp32p4/include/hal/parlio_ll.h @@ -213,13 +213,13 @@ static inline void parlio_ll_rx_set_recv_bit_len(parl_io_dev_t *dev, uint32_t bi * @brief Set the sub mode of the level controlled receive mode * * @param dev Parallel IO register base address - * @param active_level Level of the external enable signal, true for active high, false for active low + * @param active_low_en Level of the external enable signal, true for active low, false for active high */ __attribute__((always_inline)) -static inline void parlio_ll_rx_set_level_recv_mode(parl_io_dev_t *dev, bool active_level) +static inline void parlio_ll_rx_set_level_recv_mode(parl_io_dev_t *dev, bool active_low_en) { dev->rx_mode_cfg.rx_smp_mode_sel = 0; - dev->rx_mode_cfg.rx_ext_en_inv = !active_level; // 0: active low, 1: active high + dev->rx_mode_cfg.rx_ext_en_inv = active_low_en; } /** @@ -359,7 +359,7 @@ static inline void parlio_ll_rx_treat_data_line_as_en(parl_io_dev_t *dev, uint32 } /** - * @brief Wether to enable the RX clock gating + * @brief whether to enable the RX clock gating * * @param dev Parallel IO register base address * @param en True to enable, False to disable @@ -519,7 +519,7 @@ static inline void parlio_ll_tx_set_eof_condition(parl_io_dev_t *dev, parlio_ll_ } /** - * @brief Wether to enable the TX clock gating + * @brief whether to enable the TX clock gating * * @note The MSB of TXD will be taken as the gating enable signal * @@ -589,7 +589,6 @@ static inline void parlio_ll_tx_set_bus_width(parl_io_dev_t *dev, uint32_t width { uint32_t width_sel = 0; switch (width) { - // TODO: check this field (IDF-8284) case 16: width_sel = 4; break; @@ -637,7 +636,7 @@ static inline void parlio_ll_tx_reset_fifo(parl_io_dev_t *dev) __attribute__((always_inline)) static inline void parlio_ll_tx_set_idle_data_value(parl_io_dev_t *dev, uint32_t value) { - dev->tx_genrl_cfg.tx_idle_value = value; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_genrl_cfg, tx_idle_value, value); } /** diff --git a/components/hal/esp32p4/include/hal/pmu_ll.h b/components/hal/esp32p4/include/hal/pmu_ll.h index 057428e13264..0378fbaf4213 100644 --- a/components/hal/esp32p4/include/hal/pmu_ll.h +++ b/components/hal/esp32p4/include/hal/pmu_ll.h @@ -15,6 +15,7 @@ #include "hal/assert.h" #include "soc/pmu_struct.h" #include "hal/pmu_types.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -30,6 +31,16 @@ FORCE_INLINE_ATTR void pmu_ll_lp_clear_intsts_mask(pmu_dev_t *hw, uint32_t mask) hw->lp_ext.int_clr.val = mask; } +FORCE_INLINE_ATTR void pmu_ll_lp_clear_sw_intr_status(pmu_dev_t *hw) +{ + hw->lp_ext.int_clr.hp_sw_trigger = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_enable_sw_intr(pmu_dev_t *hw, bool enable) +{ + hw->lp_ext.int_ena.hp_sw_trigger = enable; +} + FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_power(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t flag) { hw->hp_sys[mode].dig_power.val = flag; @@ -461,7 +472,7 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode) FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.hp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, hp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw) @@ -511,27 +522,27 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_lite_wakeup_cause(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, lp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.modify_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.switch_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -556,32 +567,32 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target, slow_clk_cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl5.lp_ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_xtal_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_xtal_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable); } FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_pll_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_pll_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable); } FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -606,12 +617,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t * FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->wakeup.cntl7.ana_wait_target = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl7.ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_set_lite_wakeup_enable(pmu_dev_t *hw, bool wakeup_en) diff --git a/components/hal/esp32p4/include/hal/ppa_ll.h b/components/hal/esp32p4/include/hal/ppa_ll.h index 7ab8249bbdb1..60facd94fec5 100644 --- a/components/hal/esp32p4/include/hal/ppa_ll.h +++ b/components/hal/esp32p4/include/hal/ppa_ll.h @@ -24,15 +24,12 @@ extern "C" { #define PPA_LL_BLEND0_CLUT_MEM_ADDR_OFFSET 0x400 #define PPA_LL_BLEND1_CLUT_MEM_ADDR_OFFSET 0x800 -/** - * @brief Enumeration of alpha value transformation mode - */ -typedef enum { - PPA_LL_RX_ALPHA_NO_CHANGE, /*!< Do not replace alpha value. If input format does not contain alpha info, alpha value 255 will be used. */ - PPA_LL_RX_ALPHA_FIX_VALUE, /*!< Replace the alpha value in received pixel with a new, fixed alpha value */ - PPA_LL_RX_ALPHA_SCALE, /*!< Scale the alpha value in received pixel to be a new alpha value */ - PPA_LL_RX_ALPHA_INVERT, /*!< Invert the alpha value in received pixel */ -} ppa_ll_rx_alpha_mode_t; +#define PPA_LL_SRM_SCALING_INT_MAX PPA_SR_SCAL_X_INT_V +#define PPA_LL_SRM_SCALING_FRAG_MAX PPA_SR_SCAL_X_FRAG_V + +// TODO: On P4 ECO2, SRM block size needs update +#define PPA_LL_SRM_DEFAULT_BLOCK_SIZE 18 // 18 x 18 block size +#define PPA_LL_SRM_YUV420_BLOCK_SIZE 20 // 20 x 20 block size /** * @brief Enumeration of PPA blending mode @@ -71,13 +68,13 @@ static inline void ppa_ll_reset_register(void) /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance #define ppa_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; ppa_ll_reset_register(__VA_ARGS__) -/////////////////////////// Scaling and Rotating (SR) //////////////////////////////// +///////////////////////// Scaling, Rotating, Mirroring (SRM) ////////////////////////////// /** - * @brief Reset PPA scaling and rotating engine + * @brief Reset PPA scaling-rotating-mirroring engine * * @param dev Peripheral instance address */ -static inline void ppa_ll_sr_reset(ppa_dev_t *dev) +static inline void ppa_ll_srm_reset(ppa_dev_t *dev) { dev->sr_scal_rotate.scal_rotate_rst = 1; dev->sr_scal_rotate.scal_rotate_rst = 0; @@ -90,7 +87,7 @@ static inline void ppa_ll_sr_reset(ppa_dev_t *dev) * @param x_int The integrated part of scaling coefficient in X direction, 0 - 255 * @param x_frag The fragment part of scaling coefficient in X direction, 0 - 15. Corresponding fractional value is x_frag/16. */ -static inline void ppa_ll_sr_set_scaling_x(ppa_dev_t *dev, uint32_t x_int, uint32_t x_frag) +static inline void ppa_ll_srm_set_scaling_x(ppa_dev_t *dev, uint32_t x_int, uint32_t x_frag) { HAL_ASSERT(x_int <= PPA_SR_SCAL_X_INT_V && x_frag <= PPA_SR_SCAL_X_FRAG_V); HAL_FORCE_MODIFY_U32_REG_FIELD(dev->sr_scal_rotate, sr_scal_x_int, x_int); @@ -104,7 +101,7 @@ static inline void ppa_ll_sr_set_scaling_x(ppa_dev_t *dev, uint32_t x_int, uint3 * @param y_int The integrated part of scaling coefficient in Y direction, 0 - 255 * @param y_frag The fragment part of scaling coefficient in Y direction, 0 - 15. Corresponding fractional value is y_frag/16. */ -static inline void ppa_ll_sr_set_scaling_y(ppa_dev_t *dev, uint32_t y_int, uint32_t y_frag) +static inline void ppa_ll_srm_set_scaling_y(ppa_dev_t *dev, uint32_t y_int, uint32_t y_frag) { HAL_ASSERT(y_int <= PPA_SR_SCAL_Y_INT_V && y_frag <= PPA_SR_SCAL_Y_FRAG_V); HAL_FORCE_MODIFY_U32_REG_FIELD(dev->sr_scal_rotate, sr_scal_y_int, y_int); @@ -115,22 +112,22 @@ static inline void ppa_ll_sr_set_scaling_y(ppa_dev_t *dev, uint32_t y_int, uint3 * @brief Set PPA rotation angle (in the counterclockwise direction) * * @param dev Peripheral instance address - * @param angle One of the values in ppa_sr_rotation_angle_t + * @param angle One of the values in ppa_srm_rotation_angle_t */ -static inline void ppa_ll_sr_set_rotation_angle(ppa_dev_t *dev, ppa_sr_rotation_angle_t angle) +static inline void ppa_ll_srm_set_rotation_angle(ppa_dev_t *dev, ppa_srm_rotation_angle_t angle) { uint32_t val = 0; switch (angle) { - case PPA_SR_ROTATION_ANGLE_0: + case PPA_SRM_ROTATION_ANGLE_0: val = 0; break; - case PPA_SR_ROTATION_ANGLE_90: + case PPA_SRM_ROTATION_ANGLE_90: val = 1; break; - case PPA_SR_ROTATION_ANGLE_180: + case PPA_SRM_ROTATION_ANGLE_180: val = 2; break; - case PPA_SR_ROTATION_ANGLE_270: + case PPA_SRM_ROTATION_ANGLE_270: val = 3; break; default: @@ -146,7 +143,7 @@ static inline void ppa_ll_sr_set_rotation_angle(ppa_dev_t *dev, ppa_sr_rotation_ * @param dev Peripheral instance address * @param enable True to enable; False to disable */ -static inline void ppa_ll_sr_enable_mirror_x(ppa_dev_t *dev, bool enable) +static inline void ppa_ll_srm_enable_mirror_x(ppa_dev_t *dev, bool enable) { dev->sr_scal_rotate.sr_mirror_x = enable; } @@ -157,92 +154,92 @@ static inline void ppa_ll_sr_enable_mirror_x(ppa_dev_t *dev, bool enable) * @param dev Peripheral instance address * @param enable True to enable; False to disable */ -static inline void ppa_ll_sr_enable_mirror_y(ppa_dev_t *dev, bool enable) +static inline void ppa_ll_srm_enable_mirror_y(ppa_dev_t *dev, bool enable) { dev->sr_scal_rotate.sr_mirror_y = enable; } /** - * @brief Start PPA scaling and rotating engine to perform PPA SR + * @brief Start PPA scaling and rotating engine to perform PPA SRM * * @param dev Peripheral instance address */ -static inline void ppa_ll_sr_start(ppa_dev_t *dev) +static inline void ppa_ll_srm_start(ppa_dev_t *dev) { dev->sr_scal_rotate.scal_rotate_start = 1; } /** - * @brief Set the source image color mode for PPA Scaling and Rotating engine RX + * @brief Set the source image color mode for PPA Scaling-Rotating-Mirroring engine RX * * @param dev Peripheral instance address - * @param color_mode One of the values in ppa_sr_color_mode_t + * @param color_mode One of the values in ppa_srm_color_mode_t */ -static inline void ppa_ll_sr_set_rx_color_mode(ppa_dev_t *dev, ppa_sr_color_mode_t color_mode) +static inline void ppa_ll_srm_set_rx_color_mode(ppa_dev_t *dev, ppa_srm_color_mode_t color_mode) { uint32_t val = 0; switch (color_mode) { - case PPA_SR_COLOR_MODE_ARGB8888: + case PPA_SRM_COLOR_MODE_ARGB8888: val = 0; break; - case PPA_SR_COLOR_MODE_RGB888: + case PPA_SRM_COLOR_MODE_RGB888: val = 1; break; - case PPA_SR_COLOR_MODE_RGB565: + case PPA_SRM_COLOR_MODE_RGB565: val = 2; break; - case PPA_SR_COLOR_MODE_YUV420: + case PPA_SRM_COLOR_MODE_YUV420: val = 8; break; default: - // Unsupported SR rx color mode + // Unsupported SRM rx color mode abort(); } dev->sr_color_mode.sr_rx_cm = val; } /** - * @brief Set the destination image color mode for PPA Scaling and Rotating engine TX + * @brief Set the destination image color mode for PPA Scaling-Rotating-Mirroring engine TX * * @param dev Peripheral instance address - * @param color_mode One of the values in ppa_sr_color_mode_t + * @param color_mode One of the values in ppa_srm_color_mode_t */ -static inline void ppa_ll_sr_set_tx_color_mode(ppa_dev_t *dev, ppa_sr_color_mode_t color_mode) +static inline void ppa_ll_srm_set_tx_color_mode(ppa_dev_t *dev, ppa_srm_color_mode_t color_mode) { uint32_t val = 0; switch (color_mode) { - case PPA_SR_COLOR_MODE_ARGB8888: + case PPA_SRM_COLOR_MODE_ARGB8888: val = 0; break; - case PPA_SR_COLOR_MODE_RGB888: + case PPA_SRM_COLOR_MODE_RGB888: val = 1; break; - case PPA_SR_COLOR_MODE_RGB565: + case PPA_SRM_COLOR_MODE_RGB565: val = 2; break; - case PPA_SR_COLOR_MODE_YUV420: + case PPA_SRM_COLOR_MODE_YUV420: val = 8; break; default: - // Unsupported SR tx color mode + // Unsupported SRM tx color mode abort(); } dev->sr_color_mode.sr_tx_cm = val; } /** - * @brief Set YUV to RGB protocol when PPA SR pixel color space conversion from RX to TX is YUV to RGB + * @brief Set YUV to RGB protocol when PPA SRM RX pixel color space is YUV * * @param dev Peripheral instance address - * @param std One of the RGB-YUV conversion standards in color_conv_std_rgb_yuv_t + * @param std One of the RGB-YUV conversion standards in ppa_color_conv_std_rgb_yuv_t */ -static inline void ppa_ll_sr_set_yuv2rgb_std(ppa_dev_t *dev, color_conv_std_rgb_yuv_t std) +static inline void ppa_ll_srm_set_rx_yuv2rgb_std(ppa_dev_t *dev, ppa_color_conv_std_rgb_yuv_t std) { switch (std) { - case COLOR_CONV_STD_RGB_YUV_BT601: + case PPA_COLOR_CONV_STD_RGB_YUV_BT601: dev->sr_color_mode.yuv2rgb_protocol = 0; break; - case COLOR_CONV_STD_RGB_YUV_BT709: + case PPA_COLOR_CONV_STD_RGB_YUV_BT709: dev->sr_color_mode.yuv2rgb_protocol = 1; break; default: @@ -252,18 +249,18 @@ static inline void ppa_ll_sr_set_yuv2rgb_std(ppa_dev_t *dev, color_conv_std_rgb_ } /** - * @brief Set RGB to YUV protocol when PPA SR pixel color space conversion from RX to TX is RGB to YUV + * @brief Set RGB to YUV protocol when PPA SRM TX pixel color space is YUV * * @param dev Peripheral instance address - * @param std One of the RGB-YUV conversion standards in color_conv_std_rgb_yuv_t + * @param std One of the RGB-YUV conversion standards in ppa_color_conv_std_rgb_yuv_t */ -static inline void ppa_ll_sr_set_rgb2yuv_std(ppa_dev_t *dev, color_conv_std_rgb_yuv_t std) +static inline void ppa_ll_srm_set_tx_rgb2yuv_std(ppa_dev_t *dev, ppa_color_conv_std_rgb_yuv_t std) { switch (std) { - case COLOR_CONV_STD_RGB_YUV_BT601: + case PPA_COLOR_CONV_STD_RGB_YUV_BT601: dev->sr_color_mode.rgb2yuv_protocol = 0; break; - case COLOR_CONV_STD_RGB_YUV_BT709: + case PPA_COLOR_CONV_STD_RGB_YUV_BT709: dev->sr_color_mode.rgb2yuv_protocol = 1; break; default: @@ -273,18 +270,18 @@ static inline void ppa_ll_sr_set_rgb2yuv_std(ppa_dev_t *dev, color_conv_std_rgb_ } /** - * @brief Set PPA SR YUV input range + * @brief Set PPA SRM YUV input range * * @param dev Peripheral instance address - * @param range One of color range options in color_range_t + * @param range One of color range options in ppa_color_range_t */ -static inline void ppa_ll_sr_set_rx_yuv_range(ppa_dev_t *dev, color_range_t range) +static inline void ppa_ll_srm_set_rx_yuv_range(ppa_dev_t *dev, ppa_color_range_t range) { switch (range) { - case COLOR_RANGE_LIMIT: + case PPA_COLOR_RANGE_LIMIT: dev->sr_color_mode.yuv_rx_range = 0; break; - case COLOR_RANGE_FULL: + case PPA_COLOR_RANGE_FULL: dev->sr_color_mode.yuv_rx_range = 1; break; default: @@ -294,18 +291,18 @@ static inline void ppa_ll_sr_set_rx_yuv_range(ppa_dev_t *dev, color_range_t rang } /** - * @brief Set PPA SR YUV output range + * @brief Set PPA SRM YUV output range * * @param dev Peripheral instance address - * @param range One of color range options in color_range_t + * @param range One of color range options in ppa_color_range_t */ -static inline void ppa_ll_sr_set_tx_yuv_range(ppa_dev_t *dev, color_range_t range) +static inline void ppa_ll_srm_set_tx_yuv_range(ppa_dev_t *dev, ppa_color_range_t range) { switch (range) { - case COLOR_RANGE_LIMIT: + case PPA_COLOR_RANGE_LIMIT: dev->sr_color_mode.yuv_tx_range = 0; break; - case COLOR_RANGE_FULL: + case PPA_COLOR_RANGE_FULL: dev->sr_color_mode.yuv_tx_range = 1; break; default: @@ -315,60 +312,61 @@ static inline void ppa_ll_sr_set_tx_yuv_range(ppa_dev_t *dev, color_range_t rang } /** - * @brief Enable PPA SR input data wrap in RGB (e.g. ARGB becomes BGRA, RGB becomes BGR) + * @brief Enable PPA SRM input data swap in RGB (e.g. ARGB becomes BGRA, RGB becomes BGR) * * @param dev Peripheral instance address * @param enable True to enable; False to disable */ -static inline void ppa_ll_sr_enable_rx_rgb_swap(ppa_dev_t *dev, bool enable) +static inline void ppa_ll_srm_enable_rx_rgb_swap(ppa_dev_t *dev, bool enable) { dev->sr_byte_order.sr_rx_rgb_swap_en = enable; } /** - * @brief Enable PPA SR input data swap in byte (The Byte0 and Byte1 would be swapped while byte 2 and byte 3 would be swappped) + * @brief Enable PPA SRM input data swap in byte (The Byte0 and Byte1 would be swapped while byte 2 and byte 3 would be swappped) * * Only supported when input color mode is ARGB8888 or RGB565. * * @param dev Peripheral instance address * @param enable True to enable; False to disable */ -static inline void ppa_ll_sr_enable_rx_byte_swap(ppa_dev_t *dev, bool enable) +static inline void ppa_ll_srm_enable_rx_byte_swap(ppa_dev_t *dev, bool enable) { dev->sr_byte_order.sr_rx_byte_swap_en = enable; } /** - * @brief Configure PPA SR alpha value transformation mode + * @brief Configure PPA SRM alpha value update mode * * @param dev Peripheral instance address - * @param mode Alpha value transformation mode, one of the values in ppa_ll_rx_alpha_mode_t - * @param val When PPA_LL_RX_ALPHA_FIX_VALUE mode is selected, val is the alpha value to be replaced with (output_alpha = val) - * When PPA_LL_RX_ALPHA_SCALE mode is selected, val/256 is the multiplier to the input alpha value (output_alpha = input_alpha * val / 256) + * @param mode Alpha value update mode, one of the values in ppa_alpha_update_mode_t + * @param val When PPA_ALPHA_FIX_VALUE mode is selected, val is the alpha value to be replaced with (output_alpha = val) + * When PPA_ALPHA_SCALE mode is selected, val/256 is the multiplier to the input alpha value (output_alpha = input_alpha * val / 256) * When other modes are selected, this field is not used */ -static inline void ppa_ll_sr_configure_rx_alpha(ppa_dev_t *dev, ppa_ll_rx_alpha_mode_t mode, uint32_t val) +static inline void ppa_ll_srm_configure_rx_alpha(ppa_dev_t *dev, ppa_alpha_update_mode_t mode, uint32_t val) { switch (mode) { - case PPA_LL_RX_ALPHA_NO_CHANGE: + case PPA_ALPHA_NO_CHANGE: dev->sr_fix_alpha.sr_rx_alpha_mod = 0; dev->sr_fix_alpha.sr_rx_alpha_inv = 0; break; - case PPA_LL_RX_ALPHA_FIX_VALUE: + case PPA_ALPHA_FIX_VALUE: dev->sr_fix_alpha.sr_rx_alpha_mod = 1; HAL_FORCE_MODIFY_U32_REG_FIELD(dev->sr_fix_alpha, sr_rx_fix_alpha, val); dev->sr_fix_alpha.sr_rx_alpha_inv = 0; break; - case PPA_LL_RX_ALPHA_SCALE: + case PPA_ALPHA_SCALE: dev->sr_fix_alpha.sr_rx_alpha_mod = 2; HAL_FORCE_MODIFY_U32_REG_FIELD(dev->sr_fix_alpha, sr_rx_fix_alpha, val); dev->sr_fix_alpha.sr_rx_alpha_inv = 0; break; - case PPA_LL_RX_ALPHA_INVERT: + case PPA_ALPHA_INVERT: dev->sr_fix_alpha.sr_rx_alpha_mod = 0; dev->sr_fix_alpha.sr_rx_alpha_inv = 1; + break; default: - // Unsupported alpha transformation mode + // Unsupported alpha update mode abort(); } } @@ -441,12 +439,12 @@ static inline void ppa_ll_blend_set_rx_bg_color_mode(ppa_dev_t *dev, ppa_blend_c case PPA_BLEND_COLOR_MODE_RGB565: val = 2; break; - case PPA_BLEND_COLOR_MODE_L8: - val = 4; - break; - case PPA_BLEND_COLOR_MODE_L4: - val = 5; - break; + // case PPA_BLEND_COLOR_MODE_L8: + // val = 4; + // break; + // case PPA_BLEND_COLOR_MODE_L4: + // val = 5; + // break; default: // Unsupported blending rx background color mode abort(); @@ -473,12 +471,12 @@ static inline void ppa_ll_blend_set_rx_fg_color_mode(ppa_dev_t *dev, ppa_blend_c case PPA_BLEND_COLOR_MODE_RGB565: val = 2; break; - case PPA_BLEND_COLOR_MODE_L8: - val = 4; - break; - case PPA_BLEND_COLOR_MODE_L4: - val = 5; - break; + // case PPA_BLEND_COLOR_MODE_L8: + // val = 4; + // break; + // case PPA_BLEND_COLOR_MODE_L4: + // val = 5; + // break; case PPA_BLEND_COLOR_MODE_A8: val = 6; break; @@ -567,71 +565,73 @@ static inline void ppa_ll_blend_enable_rx_fg_byte_swap(ppa_dev_t *dev, bool enab } /** - * @brief Configure PPA blending input background alpha value transformation mode + * @brief Configure PPA blending input background alpha value update mode * * @param dev Peripheral instance address - * @param mode Alpha value transformation mode, one of the values in ppa_ll_rx_alpha_mode_t - * @param val When PPA_LL_RX_ALPHA_FIX_VALUE mode is selected, val is the alpha value to be replaced with (output_alpha = val) - * When PPA_LL_RX_ALPHA_SCALE mode is selected, val/256 is the multiplier to the input alpha value (output_alpha = input_alpha * val / 256) + * @param mode Alpha value update mode, one of the values in ppa_alpha_update_mode_t + * @param val When PPA_ALPHA_FIX_VALUE mode is selected, val is the alpha value to be replaced with (output_alpha = val) + * When PPA_ALPHA_SCALE mode is selected, val/256 is the multiplier to the input alpha value (output_alpha = input_alpha * val / 256) * When other modes are selected, this field is not used */ -static inline void ppa_ll_blend_configure_rx_bg_alpha(ppa_dev_t *dev, ppa_ll_rx_alpha_mode_t mode, uint32_t val) +static inline void ppa_ll_blend_configure_rx_bg_alpha(ppa_dev_t *dev, ppa_alpha_update_mode_t mode, uint32_t val) { switch (mode) { - case PPA_LL_RX_ALPHA_NO_CHANGE: + case PPA_ALPHA_NO_CHANGE: dev->blend_fix_alpha.blend0_rx_alpha_mod = 0; dev->blend_fix_alpha.blend0_rx_alpha_inv = 0; break; - case PPA_LL_RX_ALPHA_FIX_VALUE: + case PPA_ALPHA_FIX_VALUE: dev->blend_fix_alpha.blend0_rx_alpha_mod = 1; HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_fix_alpha, blend0_rx_fix_alpha, val); dev->blend_fix_alpha.blend0_rx_alpha_inv = 0; break; - case PPA_LL_RX_ALPHA_SCALE: + case PPA_ALPHA_SCALE: dev->blend_fix_alpha.blend0_rx_alpha_mod = 2; HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_fix_alpha, blend0_rx_fix_alpha, val); dev->blend_fix_alpha.blend0_rx_alpha_inv = 0; break; - case PPA_LL_RX_ALPHA_INVERT: + case PPA_ALPHA_INVERT: dev->blend_fix_alpha.blend0_rx_alpha_mod = 0; dev->blend_fix_alpha.blend0_rx_alpha_inv = 1; + break; default: - // Unsupported alpha transformation mode + // Unsupported alpha update mode abort(); } } /** - * @brief Configure PPA blending input foreground alpha value transformation mode + * @brief Configure PPA blending input foreground alpha value update mode * * @param dev Peripheral instance address - * @param mode Alpha value transformation mode, one of the values in ppa_ll_rx_alpha_mode_t - * @param val When PPA_LL_RX_ALPHA_FIX_VALUE mode is selected, val is the alpha value to be replaced with (output_alpha = val) - * When PPA_LL_RX_ALPHA_SCALE mode is selected, val/256 is the multiplier to the input alpha value (output_alpha = input_alpha * val / 256) + * @param mode Alpha value update mode, one of the values in ppa_alpha_update_mode_t + * @param val When PPA_ALPHA_FIX_VALUE mode is selected, val is the alpha value to be replaced with (output_alpha = val) + * When PPA_ALPHA_SCALE mode is selected, val/256 is the multiplier to the input alpha value (output_alpha = input_alpha * val / 256) * When other modes are selected, this field is not used */ -static inline void ppa_ll_blend_configure_rx_fg_alpha(ppa_dev_t *dev, ppa_ll_rx_alpha_mode_t mode, uint32_t val) +static inline void ppa_ll_blend_configure_rx_fg_alpha(ppa_dev_t *dev, ppa_alpha_update_mode_t mode, uint32_t val) { switch (mode) { - case PPA_LL_RX_ALPHA_NO_CHANGE: + case PPA_ALPHA_NO_CHANGE: dev->blend_fix_alpha.blend1_rx_alpha_mod = 0; dev->blend_fix_alpha.blend1_rx_alpha_inv = 0; break; - case PPA_LL_RX_ALPHA_FIX_VALUE: + case PPA_ALPHA_FIX_VALUE: dev->blend_fix_alpha.blend1_rx_alpha_mod = 1; HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_fix_alpha, blend1_rx_fix_alpha, val); dev->blend_fix_alpha.blend1_rx_alpha_inv = 0; break; - case PPA_LL_RX_ALPHA_SCALE: + case PPA_ALPHA_SCALE: dev->blend_fix_alpha.blend1_rx_alpha_mod = 2; HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_fix_alpha, blend1_rx_fix_alpha, val); dev->blend_fix_alpha.blend1_rx_alpha_inv = 0; break; - case PPA_LL_RX_ALPHA_INVERT: + case PPA_ALPHA_INVERT: dev->blend_fix_alpha.blend1_rx_alpha_mod = 0; dev->blend_fix_alpha.blend1_rx_alpha_inv = 1; + break; default: - // Unsupported alpha transformation mode + // Unsupported alpha update mode abort(); } } @@ -642,12 +642,12 @@ static inline void ppa_ll_blend_configure_rx_fg_alpha(ppa_dev_t *dev, ppa_ll_rx_ * @param dev Peripheral instance address * @param data The fix data to be filled to the image block pixels in ARGB8888 format * @param hb The horizontal width of image block that would be filled in fix pixel filling mode. The unit is pixel. - * @param vb The vertical width of image block that would be filled in fix pixel filling mode. The unit is pixel. + * @param vb The vertical height of image block that would be filled in fix pixel filling mode. The unit is pixel. */ -static inline void ppa_ll_blend_configure_filling_block(ppa_dev_t *dev, uint32_t data, uint32_t hb, uint32_t vb) +static inline void ppa_ll_blend_configure_filling_block(ppa_dev_t *dev, color_pixel_argb8888_data_t *data, uint32_t hb, uint32_t vb) { HAL_ASSERT(hb <= PPA_BLEND_HB_V && vb <= PPA_BLEND_VB_V); - dev->blend_fix_pixel.blend_tx_fix_pixel = data; + dev->blend_fix_pixel.blend_tx_fix_pixel = data->val; dev->blend_tx_size.blend_hb = hb; dev->blend_tx_size.blend_vb = vb; } @@ -658,9 +658,11 @@ static inline void ppa_ll_blend_configure_filling_block(ppa_dev_t *dev, uint32_t * @param dev Peripheral instance address * @param rgb RGB color for A4/A8 mode in RGB888 format */ -static inline void ppa_ll_blend_set_rx_fg_fix_rgb(ppa_dev_t *dev, uint32_t rgb) +static inline void ppa_ll_blend_set_rx_fg_fix_rgb(ppa_dev_t *dev, color_pixel_rgb888_data_t *rgb) { - dev->blend_rgb.val = rgb; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_rgb, blend1_rx_b, rgb->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_rgb, blend1_rx_g, rgb->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_rgb, blend1_rx_r, rgb->r); } /* @@ -678,10 +680,15 @@ static inline void ppa_ll_blend_set_rx_fg_fix_rgb(ppa_dev_t *dev, uint32_t rgb) * @param rgb_thres_low Color-key lower threshold of background in RGB888 format * @param rgb_thres_high Color-key higher threshold of background in RGB888 format */ -static inline void ppa_ll_blend_configure_rx_bg_ck_range(ppa_dev_t *dev, uint32_t rgb_thres_low, uint32_t rgb_thres_high) +static inline void ppa_ll_blend_configure_rx_bg_ck_range(ppa_dev_t *dev, color_pixel_rgb888_data_t *rgb_thres_low, color_pixel_rgb888_data_t *rgb_thres_high) { - dev->ck_bg_low.val = rgb_thres_low; - dev->ck_bg_high.val = rgb_thres_high; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_low, colorkey_bg_b_low, rgb_thres_low->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_low, colorkey_bg_g_low, rgb_thres_low->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_low, colorkey_bg_r_low, rgb_thres_low->r); + + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_high, colorkey_bg_b_high, rgb_thres_high->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_high, colorkey_bg_g_high, rgb_thres_high->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_high, colorkey_bg_r_high, rgb_thres_high->r); } /** @@ -691,10 +698,15 @@ static inline void ppa_ll_blend_configure_rx_bg_ck_range(ppa_dev_t *dev, uint32_ * @param rgb_thres_low Color-key lower threshold of foreground in RGB888 format * @param rgb_thres_high Color-key higher threshold of foreground in RGB888 format */ -static inline void ppa_ll_blend_configure_rx_fg_ck_range(ppa_dev_t *dev, uint32_t rgb_thres_low, uint32_t rgb_thres_high) +static inline void ppa_ll_blend_configure_rx_fg_ck_range(ppa_dev_t *dev, color_pixel_rgb888_data_t *rgb_thres_low, color_pixel_rgb888_data_t *rgb_thres_high) { - dev->ck_fg_low.val = rgb_thres_low; - dev->ck_fg_high.val = rgb_thres_high; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_low, colorkey_fg_b_low, rgb_thres_low->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_low, colorkey_fg_g_low, rgb_thres_low->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_low, colorkey_fg_r_low, rgb_thres_low->r); + + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_high, colorkey_fg_b_high, rgb_thres_high->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_high, colorkey_fg_g_high, rgb_thres_high->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_high, colorkey_fg_r_high, rgb_thres_high->r); } /** @@ -703,9 +715,11 @@ static inline void ppa_ll_blend_configure_rx_fg_ck_range(ppa_dev_t *dev, uint32_ * @param dev Peripheral instance address * @param rgb Default RGB value in RGB888 format */ -static inline void ppa_ll_blend_set_ck_default_rgb(ppa_dev_t *dev, uint32_t rgb) +static inline void ppa_ll_blend_set_ck_default_rgb(ppa_dev_t *dev, color_pixel_rgb888_data_t *rgb) { - dev->ck_default.val = (dev->ck_default.colorkey_fg_bg_reverse << PPA_COLORKEY_FG_BG_REVERSE_S) | rgb; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_default, colorkey_default_b, rgb->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_default, colorkey_default_g, rgb->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_default, colorkey_default_r, rgb->r); } /** diff --git a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h index 438f474d524e..822a4759be4f 100644 --- a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -53,7 +53,7 @@ static inline void psram_ctrlr_ll_set_wr_cmd(uint32_t mspi_id, uint32_t cmd_bitl HAL_ASSERT(cmd_bitlen > 0); SPIMEM2.mem_cache_sctrl.mem_cache_sram_usr_wcmd = 1; SPIMEM2.mem_sram_dwr_cmd.mem_cache_sram_usr_wr_cmd_bitlen = cmd_bitlen - 1; - SPIMEM2.mem_sram_dwr_cmd.mem_cache_sram_usr_wr_cmd_value = cmd_val; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM2.mem_sram_dwr_cmd, mem_cache_sram_usr_wr_cmd_value, cmd_val); } /** @@ -70,7 +70,7 @@ static inline void psram_ctrlr_ll_set_rd_cmd(uint32_t mspi_id, uint32_t cmd_bitl HAL_ASSERT(cmd_bitlen > 0); SPIMEM2.mem_cache_sctrl.mem_cache_sram_usr_rcmd = 1; SPIMEM2.mem_sram_drd_cmd.mem_cache_sram_usr_rd_cmd_bitlen = cmd_bitlen - 1; - SPIMEM2.mem_sram_drd_cmd.mem_cache_sram_usr_rd_cmd_value = cmd_val; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM2.mem_sram_drd_cmd, mem_cache_sram_usr_rd_cmd_value, cmd_val); } /** @@ -501,7 +501,7 @@ static inline void psram_ctrlr_ll_enable_skip_page_corner(uint32_t mspi_id, bool } /** - * @brief Enable spliting transactions + * @brief Enable splitting transactions * * @param mspi_id mspi_id * @param en enable / disable diff --git a/components/hal/esp32p4/include/hal/rmt_ll.h b/components/hal/esp32p4/include/hal/rmt_ll.h index 136dda044ef5..105aa426925e 100644 --- a/components/hal/esp32p4/include/hal/rmt_ll.h +++ b/components/hal/esp32p4/include/hal/rmt_ll.h @@ -85,7 +85,7 @@ static inline void rmt_ll_reset_register(int group_id) * @param divider_numerator Numerator part of the divider */ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src, - uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) + uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) { (void)dev; // Formula: rmt_sclk = module_clock_src / (1 + div_num + div_a / div_b) @@ -143,15 +143,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -463,7 +484,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, * * @param dev Peripheral instance address * @param channel RMT TX channel number - * @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data + * @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data */ static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable) { @@ -706,7 +727,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e * @brief Clear RMT interrupt status by mask * * @param dev Peripheral instance address - * @param mask Interupt status mask + * @param mask Interrupt status mask */ __attribute__((always_inline)) static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask) @@ -860,12 +881,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32p4/include/hal/rtc_io_ll.h b/components/hal/esp32p4/include/hal/rtc_io_ll.h index 763e8f2eeee2..a23bb2ead03f 100644 --- a/components/hal/esp32p4/include/hal/rtc_io_ll.h +++ b/components/hal/esp32p4/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -39,6 +39,15 @@ typedef enum { RTCIO_LL_WAKEUP_HIGH_LEVEL = 0x5, /*!< GPIO interrupt type : input high level trigger */ } rtcio_ll_wake_type_t; +typedef enum { + RTCIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */ + RTCIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */ + RTCIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */ + RTCIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */ + RTCIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */ + RTCIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */ +} rtcio_ll_intr_type_t; + typedef enum { RTCIO_LL_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */ RTCIO_LL_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */ @@ -341,6 +350,17 @@ static inline void rtcio_ll_wakeup_disable(int rtcio_num) LP_GPIO.pin[rtcio_num].int_type = RTCIO_LL_WAKEUP_DISABLE; } +/** + * Enable interrupt function and set interrupt type + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param type Interrupt type on high level or low level. + */ +static inline void rtcio_ll_intr_enable(int rtcio_num, rtcio_ll_intr_type_t type) +{ + LP_GPIO.pin[rtcio_num].int_type = type; +} + /** * @brief Enable RTCIO output in deep sleep. * diff --git a/components/hal/esp32p4/include/hal/sar_ctrl_ll.h b/components/hal/esp32p4/include/hal/sar_ctrl_ll.h index 60f26337cdb5..8c0b02bc6d27 100644 --- a/components/hal/esp32p4/include/hal/sar_ctrl_ll.h +++ b/components/hal/esp32p4/include/hal/sar_ctrl_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ #include #include #include "soc/soc.h" +#include "soc/lp_adc_struct.h" #ifdef __cplusplus extern "C" { @@ -39,6 +40,27 @@ typedef enum { /*--------------------------------------------------------------- SAR power control ---------------------------------------------------------------*/ + +/** + * Set SAR power mode + * + * @param mode See `sar_ctrl_ll_power_t` + */ +__attribute__((always_inline)) +static inline void sar_ctrl_ll_set_power_mode(sar_ctrl_ll_power_t mode) +{ + if (mode == SAR_CTRL_LL_POWER_FSM) { + LP_ADC.force_wpd_sar.force_xpd_sar1 = 0x0; + LP_ADC.force_wpd_sar.force_xpd_sar2 = 0x0; + } else if (mode == SAR_CTRL_LL_POWER_ON) { + LP_ADC.force_wpd_sar.force_xpd_sar1 = 0x3; + LP_ADC.force_wpd_sar.force_xpd_sar2 = 0x3; + } else { + LP_ADC.force_wpd_sar.force_xpd_sar1 = 0x2; + LP_ADC.force_wpd_sar.force_xpd_sar2 = 0x2; + } +} + /** * @brief Set SAR power mode when controlled by PWDET * diff --git a/components/hal/esp32p4/include/hal/spi_ll.h b/components/hal/esp32p4/include/hal/spi_ll.h index 57df0aa8af9b..e45f48454972 100644 --- a/components/hal/esp32p4/include/hal/spi_ll.h +++ b/components/hal/esp32p4/include/hal/spi_ll.h @@ -42,6 +42,7 @@ extern "C" { #define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words #define SPI_LL_SUPPORT_CLK_SRC_PRE_DIV 1 //clock source have divider before peripheral #define SPI_LL_CLK_SRC_PRE_DIV_MAX 512//div1(8bit) * div2(8bit but set const 2) +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized /** * The data structure holding calculated clock configuration. Since the @@ -358,7 +359,7 @@ static inline void spi_ll_slave_reset(spi_dev_t *hw) /** * Reset SPI CPU TX FIFO * - * On P4, this function is not seperated + * On P4, this function is not separated * * @param hw Beginning address of the peripheral registers. */ @@ -371,7 +372,7 @@ static inline void spi_ll_cpu_tx_fifo_reset(spi_dev_t *hw) /** * Reset SPI CPU RX FIFO * - * On P4, this function is not seperated + * On P4, this function is not separated * * @param hw Beginning address of the peripheral registers. */ @@ -760,7 +761,7 @@ static inline void spi_ll_master_set_clock_by_reg(spi_dev_t *hw, const spi_ll_cl * Get the frequency of given dividers. Don't use in app. * * @param fapb APB clock of the system. - * @param pre Pre devider. + * @param pre Pre divider. * @param n Main divider. * * @return Frequency of given dividers. @@ -771,10 +772,10 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n) } /** - * Calculate the nearest frequency avaliable for master. + * Calculate the nearest frequency available for master. * * @param fapb APB clock of the system. - * @param hz Frequncy desired. + * @param hz Frequency desired. * @param duty_cycle Duty cycle desired. * @param out_reg Output address to store the calculated clock configurations for the return frequency. * @@ -854,7 +855,7 @@ static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ * * @param hw Beginning address of the peripheral registers. * @param fapb APB clock of the system. - * @param hz Frequncy desired. + * @param hz Frequency desired. * @param duty_cycle Duty cycle desired. * * @return Actual frequency that is used. @@ -880,6 +881,16 @@ static inline void spi_ll_set_mosi_delay(spi_dev_t *hw, int delay_mode, int dela { } +/** + * Determine and unify the default level of mosi line when bus free + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) +{ + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state +} + /** * Set the miso delay applied to the input signal before the internal peripheral. (Preview) * diff --git a/components/hal/esp32p4/include/hal/spimem_flash_ll.h b/components/hal/esp32p4/include/hal/spimem_flash_ll.h index d91af4839e67..90cdd8ca3eb0 100644 --- a/components/hal/esp32p4/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32p4/include/hal/spimem_flash_ll.h @@ -567,7 +567,7 @@ static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr) { dev->cache_fctrl.cache_usr_addr_4byte = 0; - dev->rd_status.wb_mode = extra_addr; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rd_status, wb_mode, extra_addr); } /** diff --git a/components/hal/esp32p4/include/hal/touch_sensor_hal.h b/components/hal/esp32p4/include/hal/touch_sensor_hal.h new file mode 100644 index 000000000000..bc6d03f503bb --- /dev/null +++ b/components/hal/esp32p4/include/hal/touch_sensor_hal.h @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +// The HAL layer for touch sensor (ESP32-P4 specific part) + +#pragma once + +#include "hal/touch_sensor_ll.h" +#include "hal/touch_sensor_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Sample configurations of the touch sensor + * + */ +typedef struct { + uint32_t div_num; /*!< The division from the source clock to the sampling frequency */ + uint32_t charge_times; /*!< The charge and discharge times of the sample configuration, the read data are positive correlation to the charge_times */ + uint8_t rc_filter_res; /*!< The resistance of the RC filter of the sample configuration, range [0, 3], while 0 = 0K, 1 = 1.5K, 2 = 3K, 3 = 4.5K */ + uint8_t rc_filter_cap; /*!< The capacitance of the RC filter of the sample configuration, range [0, 127], while 0 = 0pF, 1 = 20fF, ..., 127 = 2.54pF */ + uint8_t low_drv; /*!< Low speed touch driver, only effective when high speed driver is disabled */ + uint8_t high_drv; /*!< High speed touch driver */ + uint8_t bias_volt; /*!< The Internal LDO voltage, which decide the bias voltage of the sample wave, range [0,15] */ + bool bypass_shield_output; /*!< Whether to bypass the shield output */ +} touch_hal_sample_config_t; + +/** + * @brief Configurations of the touch sensor controller + * + */ +typedef struct { + uint32_t power_on_wait_ticks; /*!< The waiting time between the channels power on and able to measure, to ensure the data stability */ + uint32_t meas_interval_ticks; /*!< Measurement interval of each channels */ // TODO: Test the supported range + uint32_t timeout_ticks; /*!< The maximum time of measuring one channel, if the time exceeds this value, the timeout interrupt will be triggered. + * Set to '0' to ignore the measurement time limitation, otherwise please set a proper time considering the configurations + * of the sample configurations below. + */ + touch_out_mode_t output_mode; /*!< Touch channel counting mode of the binarized touch output */ + uint32_t sample_cfg_num; /*!< The sample configuration number that used for sampling */ + touch_hal_sample_config_t *sample_cfg; /*!< The array of the sample configuration configurations, the length should be specified in `touch_hal_sample_config_t::sample_cfg_num` */ +} touch_hal_config_t; + +/** + * @brief Configure the touch sensor hardware with the configuration + * + * @param[in] cfg Touch sensor hardware configuration + */ +void touch_hal_config_controller(const touch_hal_config_t *cfg); + +/** + * @brief Save the touch sensor hardware configuration + * @note The saved configurations will be applied before entering deep sleep + * + * @param[in] deep_slp_chan The touch sensor channel that can wake-up the chip from deep sleep + * @param[in] deep_slp_cfg The hardware configuration that takes effect during the deep sleep + */ +void touch_hal_save_sleep_config(int deep_slp_chan, const touch_hal_config_t *deep_slp_cfg); + +/** + * @brief Prepare for the deep sleep + * @note Including apply the deep sleep configuration, clear interrupts, resetting benchmark + */ +void touch_hal_prepare_deep_sleep(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/touch_sensor_ll.h b/components/hal/esp32p4/include/hal/touch_sensor_ll.h index 7f15fad2b579..37280c3b5d2b 100644 --- a/components/hal/esp32p4/include/hal/touch_sensor_ll.h +++ b/components/hal/esp32p4/include/hal/touch_sensor_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,9 @@ #include "hal/assert.h" #include "soc/touch_sensor_periph.h" #include "soc/lp_analog_peri_struct.h" +#include "soc/lp_clkrst_struct.h" +#include "soc/lp_system_struct.h" +#include "soc/lpperi_struct.h" #include "soc/touch_struct.h" #include "soc/pmu_struct.h" #include "soc/soc_caps.h" @@ -27,7 +30,6 @@ extern "C" { #endif -#define TOUCH_LL_READ_RAW 0x0 #define TOUCH_LL_READ_BENCHMARK 0x2 #define TOUCH_LL_READ_SMOOTH 0x3 @@ -35,27 +37,41 @@ extern "C" { #define TOUCH_LL_TIMER_DONE_BY_FSM 0x0 // Interrupt mask -#define TOUCH_LL_INTR_MASK_SCAN_DONE BIT(1) -#define TOUCH_LL_INTR_MASK_DONE BIT(2) -#define TOUCH_LL_INTR_MASK_ACTIVE BIT(3) -#define TOUCH_LL_INTR_MASK_INACTIVE BIT(4) -#define TOUCH_LL_INTR_MASK_TIMEOUT BIT(5) -#define TOUCH_LL_INTR_MASK_APPROACH_DONE BIT(6) +#define TOUCH_LL_INTR_MASK_SCAN_DONE BIT(0) +#define TOUCH_LL_INTR_MASK_DONE BIT(1) +#define TOUCH_LL_INTR_MASK_ACTIVE BIT(2) +#define TOUCH_LL_INTR_MASK_INACTIVE BIT(3) +#define TOUCH_LL_INTR_MASK_TIMEOUT BIT(4) +#define TOUCH_LL_INTR_MASK_PROX_DONE BIT(5) #define TOUCH_LL_INTR_MASK_ALL (0x3F) #define TOUCH_LL_FULL_CHANNEL_MASK ((uint16_t)((1U << SOC_TOUCH_SENSOR_NUM) - 1)) -#define TOUCH_LL_NULL_CHANNEL (15) // Null Channel id. Used for disabling some functions like sleep/approach/waterproof +#define TOUCH_LL_NULL_CHANNEL (15) // Null Channel id. Used for disabling some functions like sleep/proximity/waterproof #define TOUCH_LL_PAD_MEASURE_WAIT_MAX (0x7FFF) // The timer frequency is 8Mhz, the max value is 0xff +#define TOUCH_LL_ACTIVE_THRESH_MAX (0xFFFF) // Max channel active threshold +#define TOUCH_LL_CLK_DIV_MAX (0x08) // Max clock divider value +#define TOUCH_LL_TIMEOUT_MAX (0xFFFF) // Max timeout value /** * Enable/disable clock gate of touch sensor. * * @param enable true/false. */ -static inline void touch_ll_enable_clock(bool enable) +static inline void touch_ll_enable_module_clock(bool enable) { - LP_ANA_PERI.date.clk_en = enable; + LPPERI.clk_en.ck_en_lp_touch = enable; +} + +/** + * Enable/disable clock gate of touch sensor. + * + * @param enable true/false. + */ +static inline void touch_ll_reset_module(void) +{ + LPPERI.reset_en.rst_en_lp_touch = 1; + LPPERI.reset_en.rst_en_lp_touch = 0; } /** @@ -71,14 +87,14 @@ static inline void touch_ll_set_power_on_wait_cycle(uint32_t wait_cycles) /** * Set touch sensor touch sensor charge and discharge times of every measurement on a pad. * - * @param sampler_id The sampler index + * @param sample_cfg_id The sample configuration index * @param charge_times The times of charge and discharge in each measure process of touch channels. - * The timer frequency is 8Mhz. Range: 0 ~ 0xffff. + * The timer frequency is RTC_FAST (about 16M). Range: 0 ~ 0xffff. */ -static inline void touch_ll_set_charge_times(uint8_t sampler_id, uint16_t charge_times) +static inline void touch_ll_set_charge_times(uint8_t sample_cfg_id, uint16_t charge_times) { //The times of charge and discharge in each measure process of touch channels. - switch (sampler_id) { + switch (sample_cfg_id) { case 0: LP_ANA_PERI.touch_work_meas_num.touch_meas_num0 = charge_times; break; @@ -98,9 +114,9 @@ static inline void touch_ll_set_charge_times(uint8_t sampler_id, uint16_t charge * * @param meas_times Pointer to accept times count of charge and discharge. */ -static inline void touch_ll_get_charge_times(uint8_t sampler_id, uint16_t *charge_times) +static inline void touch_ll_get_charge_times(uint8_t sample_cfg_id, uint16_t *charge_times) { - switch (sampler_id) { + switch (sample_cfg_id) { case 0: *charge_times = LP_ANA_PERI.touch_work_meas_num.touch_meas_num0; break; @@ -140,21 +156,21 @@ static inline void touch_ll_get_measure_interval_ticks(uint16_t *interval_ticks) } /** - * Set touch sensor FSM mode. - * The measurement action can be triggered by the hardware timer, as well as by the software instruction. + * Enable touch sensor FSM timer trigger (continuous) mode or software trigger (oneshot) mode. * - * @param mode FSM mode. - * TOUCH_FSM_MODE_TIMER: the FSM will trigger scanning repeatedly under the control of the hardware timer - * TOUCH_FSM_MODE_SW: the FSM will trigger scanning once under the control of the software + * @param enable Enable FSM timer mode. + * True: the FSM will trigger scanning repeatedly under the control of the hardware timer (continuous mode) + * False: the FSM will trigger scanning once under the control of the software (continuous mode) */ -static inline void touch_ll_set_fsm_mode(touch_fsm_mode_t mode) +__attribute__((always_inline)) +static inline void touch_ll_enable_fsm_timer(bool enable) { // FSM controlled by timer or software - LP_ANA_PERI.touch_mux0.touch_fsm_en = mode; - // Start by timer or software - LP_ANA_PERI.touch_mux0.touch_start_force = mode; - // Stop by timer or software - LP_ANA_PERI.touch_mux0.touch_done_force = mode; + LP_ANA_PERI.touch_mux0.touch_fsm_en = enable; + // Set 0 to stop by timer, otherwise by software + LP_ANA_PERI.touch_mux0.touch_done_force = !enable; + // Set 0 to start by timer, otherwise by software + LP_ANA_PERI.touch_mux0.touch_start_force = !enable; } /** @@ -182,18 +198,23 @@ static inline bool touch_ll_is_fsm_using_timer(void) /** * Touch timer trigger measurement and always wait measurement done. * Force done for touch timer ensures that the timer always can get the measurement done signal. + * @note The `force done` signal should last as least one slow clock tick */ +__attribute__((always_inline)) static inline void touch_ll_force_done_curr_measurement(void) { - if (touch_ll_is_fsm_using_timer()) { - LP_ANA_PERI.touch_mux0.touch_done_force = TOUCH_LL_TIMER_FORCE_DONE_BY_SW; - LP_ANA_PERI.touch_mux0.touch_done_en = 1; - LP_ANA_PERI.touch_mux0.touch_done_en = 0; - LP_ANA_PERI.touch_mux0.touch_done_force = TOUCH_LL_TIMER_DONE_BY_FSM; - } else { - LP_ANA_PERI.touch_mux0.touch_done_en = 1; - LP_ANA_PERI.touch_mux0.touch_done_en = 0; - } + // Enable event tick first + LP_AON_CLKRST.lp_clk_en.etm_event_tick_en = 1; + // Set `force done` signal + PMU.touch_pwr_cntl.force_done = 1; + // Force done signal should last at least one slow clock tick, wait until tick interrupt triggers + LP_SYS.int_clr.slow_clk_tick_int_clr = 1; + while(LP_SYS.int_clr.slow_clk_tick_int_clr); + while(!LP_SYS.int_raw.slow_clk_tick_int_raw); + // Clear `force done` signal + PMU.touch_pwr_cntl.force_done = 0; + // Disable event tick + LP_AON_CLKRST.lp_clk_en.etm_event_tick_en = 0; } /** @@ -203,6 +224,7 @@ static inline void touch_ll_force_done_curr_measurement(void) * The timer should be triggered * @param is_sleep Whether in sleep state */ +__attribute__((always_inline)) static inline void touch_ll_start_fsm_repeated_timer(bool is_sleep) { /** @@ -210,11 +232,7 @@ static inline void touch_ll_start_fsm_repeated_timer(bool is_sleep) * Force done for touch timer ensures that the timer always can get the measurement done signal. */ touch_ll_force_done_curr_measurement(); - if (is_sleep) { - PMU.touch_pwr_cntl.sleep_timer_en = 1; - } else { - LP_ANA_PERI.touch_mux0.touch_start_en = 1; - } + PMU.touch_pwr_cntl.sleep_timer_en = 1; } /** @@ -222,21 +240,31 @@ static inline void touch_ll_start_fsm_repeated_timer(bool is_sleep) * The measurement action can be triggered by the hardware timer, as well as by the software instruction. * @param is_sleep Whether in sleep state */ +__attribute__((always_inline)) static inline void touch_ll_stop_fsm_repeated_timer(bool is_sleep) { - if (is_sleep) { - PMU.touch_pwr_cntl.sleep_timer_en = 0; - } else { - LP_ANA_PERI.touch_mux0.touch_start_en = 0; - } + PMU.touch_pwr_cntl.sleep_timer_en = 0; touch_ll_force_done_curr_measurement(); } /** - * Start touch sensor FSM once by software - * @note Every trigger means measuring one channel, not scanning all enabled channels + * Is the FSM repeated timer enabled. + * @note when the timer is enabled, RTC clock should not be power down + * + * @return + * - true: enabled + * - true: disabled */ -static inline void touch_ll_start_fsm_once(void) +static inline bool touch_ll_is_fsm_repeated_timer_enabled(void) +{ + return (bool)(PMU.touch_pwr_cntl.sleep_timer_en); +} + +/** + * Enable the touch sensor FSM start signal from software + */ +__attribute__((always_inline)) +static inline void touch_ll_trigger_oneshot_measurement(void) { /* Trigger once measurement */ LP_ANA_PERI.touch_mux0.touch_start_en = 1; @@ -245,7 +273,8 @@ static inline void touch_ll_start_fsm_once(void) static inline void touch_ll_measure_channel_once(uint16_t chan_mask) { - LP_ANA_PERI.touch_mux1.touch_start = chan_mask; + // Channel shift workaround + LP_ANA_PERI.touch_mux1.touch_start = chan_mask << 1; } /** @@ -255,13 +284,34 @@ static inline void touch_ll_measure_channel_once(uint16_t chan_mask) * * @note If set "TOUCH_PAD_THRESHOLD_MAX", the touch is never be triggered. * @param touch_num The touch pad id - * @param sampler_id The sampler index + * @param sample_cfg_id The sample configuration index * @param thresh The threshold of charge cycles */ -static inline void touch_ll_set_chan_active_threshold(uint32_t touch_num, uint8_t sampler_id, uint32_t thresh) +static inline void touch_ll_set_chan_active_threshold(uint32_t touch_num, uint8_t sample_cfg_id, uint32_t thresh) { - HAL_ASSERT(sampler_id < SOC_TOUCH_SAMPLER_NUM); - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ANA_PERI.touch_padx_thn[touch_num].thn[sampler_id], threshold, thresh); + HAL_ASSERT(sample_cfg_id < SOC_TOUCH_SAMPLE_CFG_NUM); + // Channel shift workaround + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ANA_PERI.touch_padx_thn[touch_num + 1].thresh[sample_cfg_id], threshold, thresh); // codespell:ignore +} + +/** + * @brief Enable or disable the channel that will be scanned. + * @note The shield channel should not be enabled to scan here + * + * @param chan_mask The channel mask to be enabled or disabled + * @param enable Enable or disable the channel mask + */ +__attribute__((always_inline)) +static inline void touch_ll_enable_scan_mask(uint16_t chan_mask, bool enable) +{ + // Channel shift workaround: the lowest bit takes no effect + uint16_t mask = (chan_mask << 1) & TOUCH_PAD_BIT_MASK_ALL; + uint16_t prev_mask = LP_ANA_PERI.touch_scan_ctrl1.touch_scan_pad_map; + if (enable) { + LP_ANA_PERI.touch_scan_ctrl1.touch_scan_pad_map = prev_mask | mask; + } else { + LP_ANA_PERI.touch_scan_ctrl1.touch_scan_pad_map = prev_mask & (~mask); + } } /** @@ -278,7 +328,8 @@ static inline void touch_ll_set_chan_active_threshold(uint32_t touch_num, uint8_ */ static inline void touch_ll_set_channel_mask(uint16_t enable_mask) { - uint16_t mask = enable_mask & TOUCH_PAD_BIT_MASK_ALL; + // Channel shift workaround: the lowest bit takes no effect + uint16_t mask = (enable_mask << 1) & TOUCH_PAD_BIT_MASK_ALL; LP_ANA_PERI.touch_scan_ctrl1.touch_scan_pad_map = mask; LP_ANA_PERI.touch_filter2.touch_outen = mask; } @@ -288,10 +339,12 @@ static inline void touch_ll_set_channel_mask(uint16_t enable_mask) * * @param chan_mask The channel mask that needs to power on */ -static inline void touch_ll_channel_power_on(uint16_t chan_mask) +__attribute__((always_inline)) +static inline void touch_ll_channel_sw_measure_mask(uint16_t chan_mask) { - uint32_t curr_mask = LP_ANA_PERI.touch_mux1.touch_xpd; - LP_ANA_PERI.touch_mux1.touch_xpd = chan_mask | curr_mask; + // Channel shift workaround + LP_ANA_PERI.touch_mux1.touch_xpd = chan_mask << 1; + LP_ANA_PERI.touch_mux1.touch_start = chan_mask << 1; } /** @@ -302,20 +355,8 @@ static inline void touch_ll_channel_power_on(uint16_t chan_mask) static inline void touch_ll_channel_power_off(uint16_t chan_mask) { uint32_t curr_mask = LP_ANA_PERI.touch_mux1.touch_xpd; - LP_ANA_PERI.touch_mux1.touch_xpd = (~chan_mask) & curr_mask; -} - -/** - * @brief Start channel by mask - * @note Only start the specified channels - * - * @param chan_mask The channel mask that needs to start - */ -static inline void touch_ll_channel_start(uint16_t chan_mask) -{ - uint32_t curr_mask = LP_ANA_PERI.touch_mux1.touch_start; - LP_ANA_PERI.touch_mux1.touch_start = chan_mask | curr_mask; - LP_ANA_PERI.touch_mux1.touch_start = (~chan_mask) & curr_mask; + // Channel shift workaround + LP_ANA_PERI.touch_mux1.touch_xpd = (~(chan_mask << 1)) & curr_mask; } /** @@ -323,9 +364,11 @@ static inline void touch_ll_channel_start(uint16_t chan_mask) * * @param active_mask The touch channel status. e.g. Touch1 trigger status is `status_mask & (BIT1)`. */ +__attribute__((always_inline)) static inline void touch_ll_get_active_channel_mask(uint32_t *active_mask) { - *active_mask = LP_TOUCH.chn_status.pad_active; + // Channel shift workaround + *active_mask = (LP_TOUCH.chn_status.pad_active >> 1); } /** @@ -342,22 +385,23 @@ static inline void touch_ll_clear_active_channel_status(void) * Get the data of the touch channel according to the types * * @param touch_num touch pad index - * @param sampler_id The sampler index + * @param sample_cfg_id The sample configuration index * @param type data type - * 0/1: TOUCH_LL_READ_RAW, the raw data of the touch channel + * 0/1: not work * 2: TOUCH_LL_READ_BENCHMARK, benchmark value of touch channel, * the benchmark value is the maximum during the first measurement period * 3: TOUCH_LL_READ_SMOOTH, the smoothed data that obtained by filtering the raw data. * @param data pointer to the data */ __attribute__((always_inline)) -static inline void touch_ll_read_chan_data(uint32_t touch_num, uint8_t sampler_id, uint8_t type, uint32_t *data) +static inline void touch_ll_read_chan_data(uint32_t touch_num, uint8_t sample_cfg_id, uint8_t type, uint32_t *data) { - HAL_ASSERT(sampler_id < SOC_TOUCH_SAMPLER_NUM); - HAL_ASSERT(type <= TOUCH_LL_READ_SMOOTH); - LP_ANA_PERI.touch_mux0.touch_freq_sel = sampler_id + 1; + HAL_ASSERT(sample_cfg_id < SOC_TOUCH_SAMPLE_CFG_NUM); + HAL_ASSERT(type == TOUCH_LL_READ_BENCHMARK || type == TOUCH_LL_READ_SMOOTH); + LP_ANA_PERI.touch_mux0.touch_freq_sel = sample_cfg_id; LP_ANA_PERI.touch_mux0.touch_data_sel = type; - *data = LP_TOUCH.chn_data[touch_num - 1].pad_data; + // Channel shift workaround + *data = LP_TOUCH.chn_data[touch_num + 1].pad_data; } /** @@ -366,12 +410,17 @@ static inline void touch_ll_read_chan_data(uint32_t touch_num, uint8_t sampler_i * @return * - If touch sensors measure done. */ -static inline bool touch_ll_is_measure_done(uint32_t *touch_num) +__attribute__((always_inline)) +static inline bool touch_ll_is_measure_done(void) { - *touch_num = (uint32_t)(LP_TOUCH.chn_status.scan_curr); return (bool)LP_TOUCH.chn_status.meas_done; } +static inline uint32_t touch_ll_get_current_measure_channel(void) +{ + // Channel shift workaround + return (uint32_t)(LP_TOUCH.chn_status.scan_curr - 1); +} /** * Select the counting mode of the binarized touch out wave * @@ -384,26 +433,36 @@ static inline void touch_ll_set_out_mode(touch_out_mode_t mode) LP_ANA_PERI.touch_work.touch_out_sel = mode; } +/** + * @brief Enable/disable the touch sensor output gate + * + * @param enable set true to enable the output gate, false to disable it + */ +static inline void touch_ll_enable_out_gate(bool enable) +{ + LP_ANA_PERI.touch_work.touch_out_gate = enable; +} + /** * @brief Set the clock division of the sampling frequency * - * @param sampler_id The sampler index + * @param sample_cfg_id The sample configuration index * @param div_num Division number */ -static inline void touch_ll_set_clock_div(uint8_t sampler_id, uint32_t div_num) +static inline void touch_ll_set_clock_div(uint8_t sample_cfg_id, uint32_t div_num) { - switch (sampler_id) { + switch (sample_cfg_id) { case 0: - LP_ANA_PERI.touch_work.div_num0 = div_num; + LP_ANA_PERI.touch_work.div_num0 = div_num - 1; break; case 1: - LP_ANA_PERI.touch_work.div_num1 = div_num; + LP_ANA_PERI.touch_work.div_num1 = div_num - 1; break; case 2: - LP_ANA_PERI.touch_work.div_num2 = div_num; + LP_ANA_PERI.touch_work.div_num2 = div_num - 1; break; default: - // invalid sampler_id + // invalid sample_cfg_id abort(); } } @@ -434,7 +493,8 @@ static inline void touch_ll_set_idle_channel_connect(touch_pad_conn_type_t type) __attribute__((always_inline)) static inline uint32_t touch_ll_get_current_meas_channel(void) { - return (uint32_t)(LP_TOUCH.chn_status.scan_curr); + // Channel shift workaround + return (uint32_t)(LP_TOUCH.chn_status.scan_curr - 1); } /** @@ -466,9 +526,10 @@ static inline void touch_ll_intr_disable(uint32_t int_mask) * * @param int_mask Pad mask to clear interrupts */ -static inline void touch_ll_intr_clear_all(void) +__attribute__((always_inline)) +static inline void touch_ll_intr_clear(touch_pad_intr_mask_t int_mask) { - LP_TOUCH.int_clr.val = TOUCH_LL_INTR_MASK_ALL; + LP_TOUCH.int_clr.val = int_mask; } /** @@ -476,6 +537,7 @@ static inline void touch_ll_intr_clear_all(void) * * @return type interrupt type */ +__attribute__((always_inline)) static inline uint32_t touch_ll_get_intr_status_mask(void) { uint32_t intr_st = LP_TOUCH.int_st.val; @@ -508,56 +570,68 @@ static inline void touch_ll_timeout_disable(void) } /** - * Set the engaged sampler number + * Set the engaged sample configuration number * - * @param sampler_num The enabled sampler number, range 0~3. - * 0/1 means only one sampler enabled, which can not support frequency hopping + * @param sample_cfg_num The enabled sample configuration number, range 0~3. + * 0/1 means only one sample configuration enabled, which can not support frequency hopping */ -static inline void touch_ll_sampler_set_engaged_num(uint8_t sampler_num) +static inline void touch_ll_sample_cfg_set_engaged_num(uint8_t sample_cfg_num) { - HAL_ASSERT(sampler_num < SOC_TOUCH_SAMPLER_NUM); - LP_ANA_PERI.touch_scan_ctrl2.freq_scan_en = !!sampler_num; - LP_ANA_PERI.touch_scan_ctrl2.freq_scan_cnt_limit = sampler_num ? sampler_num : 1; + HAL_ASSERT(sample_cfg_num <= SOC_TOUCH_SAMPLE_CFG_NUM); + LP_ANA_PERI.touch_scan_ctrl2.freq_scan_en = !!sample_cfg_num; + LP_ANA_PERI.touch_scan_ctrl2.freq_scan_cnt_limit = sample_cfg_num ? sample_cfg_num : 1; } /** * Set capacitance and resistance of the RC filter of the sampling frequency. * - * @param sampler_id The sampler index + * @param sample_cfg_id The sample configuration index * @param cap Capacitance of the RC filter. * @param res Resistance of the RC filter. */ -static inline void touch_ll_sampler_set_rc_filter(uint8_t sampler_id, uint32_t cap, uint32_t res) +static inline void touch_ll_sample_cfg_set_rc_filter(uint8_t sample_cfg_id, uint32_t cap, uint32_t res) { - HAL_ASSERT(sampler_id < SOC_TOUCH_SAMPLER_NUM); - LP_ANA_PERI.touch_freq_scan_para[sampler_id].touch_freq_dcap_lpf = cap; - LP_ANA_PERI.touch_freq_scan_para[sampler_id].touch_freq_dres_lpf = res; + HAL_ASSERT(sample_cfg_id < SOC_TOUCH_SAMPLE_CFG_NUM); + LP_ANA_PERI.touch_freq_scan_para[sample_cfg_id].touch_freq_dcap_lpf = cap; + LP_ANA_PERI.touch_freq_scan_para[sample_cfg_id].touch_freq_dres_lpf = res; } /** * @brief Set the driver of the sampling frequency * - * @param sampler_id The sampler index + * @param sample_cfg_id The sample configuration index * @param ls_drv Low speed touch driver * @param hs_drv High speed touch driver */ -static inline void touch_ll_sampler_set_driver(uint8_t sampler_id, uint32_t ls_drv, uint32_t hs_drv) +static inline void touch_ll_sample_cfg_set_driver(uint8_t sample_cfg_id, uint32_t ls_drv, uint32_t hs_drv) { - HAL_ASSERT(sampler_id < SOC_TOUCH_SAMPLER_NUM); - LP_ANA_PERI.touch_freq_scan_para[sampler_id].touch_freq_drv_ls = ls_drv; - LP_ANA_PERI.touch_freq_scan_para[sampler_id].touch_freq_drv_hs = hs_drv; + HAL_ASSERT(sample_cfg_id < SOC_TOUCH_SAMPLE_CFG_NUM); + LP_ANA_PERI.touch_freq_scan_para[sample_cfg_id].touch_freq_drv_ls = ls_drv; + LP_ANA_PERI.touch_freq_scan_para[sample_cfg_id].touch_freq_drv_hs = hs_drv; +} + +/** + * Bypass the shield channel output for the specify sample configuration + * + * @param sample_cfg_id The sample configuration index + * @param enable Set true to bypass the shield channel output for the current channel + */ +static inline void touch_ll_sample_cfg_bypass_shield_output(uint8_t sample_cfg_id, bool enable) +{ + HAL_ASSERT(sample_cfg_id < SOC_TOUCH_SAMPLE_CFG_NUM); + LP_ANA_PERI.touch_freq_scan_para[sample_cfg_id].touch_bypass_shield = enable; } /** * Set the touch internal LDO bias voltage of the sampling frequency * - * @param sampler_id The sampler index + * @param sample_cfg_id The sample configuration index * @param bias_volt LDO bias voltage */ -static inline void touch_ll_sampler_set_bias_voltage(uint8_t sampler_id, uint32_t bias_volt) +static inline void touch_ll_sample_cfg_set_bias_voltage(uint8_t sample_cfg_id, uint32_t bias_volt) { - HAL_ASSERT(sampler_id < SOC_TOUCH_SAMPLER_NUM); - LP_ANA_PERI.touch_freq_scan_para[sampler_id].touch_freq_dbias = bias_volt; + HAL_ASSERT(sample_cfg_id < SOC_TOUCH_SAMPLE_CFG_NUM); + LP_ANA_PERI.touch_freq_scan_para[sample_cfg_id].touch_freq_dbias = bias_volt; } /** @@ -581,6 +655,7 @@ static inline void touch_ll_set_internal_loop_capacitance(int cap) * @note If call this API, make sure enable clock gate(`touch_ll_clkgate`) first. * @param chan_mask touch channel mask */ +__attribute__((always_inline)) static inline void touch_ll_reset_chan_benchmark(uint32_t chan_mask) { LP_ANA_PERI.touch_clr.touch_channel_clr = chan_mask; @@ -620,39 +695,23 @@ static inline void touch_ll_filter_set_debounce(uint32_t dbc_cnt) } /** - * Set the positive noise threshold coefficient. Higher = More noise resistance. - * The benchmark will update to the new value if the touch data is within (benchmark + active_threshold * pos_coeff) - * + * Set the denoise coefficient regarding the denoise level. * - * @param pos_noise_thresh Range [-1 ~ 3]. The coefficient is -1: always; 0: 4/8; 1: 3/8; 2: 2/8; 3: 1; - * -1: the benchmark will always update to the new touch data without considering the positive noise threshold + * @param denoise_lvl Range [0 ~ 4]. 0 = no noise resistance, otherwise higher denoise_lvl means more noise resistance. */ -static inline void touch_ll_filter_set_pos_noise_thresh(int pos_noise_thresh) +static inline void touch_ll_filter_set_denoise_level(int denoise_lvl) { - bool always_update = pos_noise_thresh < 0; + HAL_ASSERT(denoise_lvl >= 0 && denoise_lvl <= 4); + bool always_update = denoise_lvl == 0; + // Map denoise level to actual noise threshold coefficients + uint32_t noise_thresh = denoise_lvl == 4 ? 3 : 3 - denoise_lvl; + LP_ANA_PERI.touch_filter2.touch_bypass_noise_thres = always_update; - LP_ANA_PERI.touch_filter1.touch_noise_thres = always_update ? 0 : pos_noise_thresh; -} + LP_ANA_PERI.touch_filter1.touch_noise_thres = always_update ? 0 : noise_thresh; -/** - * Set the negative noise threshold coefficient. Higher = More noise resistance. - * The benchmark will update to the new value if the touch data is greater than (benchmark - active_threshold * neg_coeff) - * - * @param neg_noise_thresh Range [-2 ~ 3]. The coefficient is -2: never; -1: always; 0: 4/8; 1: 3/8; 2: 2/8; 3: 1; - * -1: the benchmark will always update to the new touch data without considering the negative noise threshold - * -2: the benchmark will never update to the new touch data with negative growth - * @param neg_noise_limit Only when neg_noise_thresh >= 0, if the touch data keep blow the negative threshold for mare than neg_noise_limit ticks, - * the benchmark will still update to the new value. - * It is normally used for updating the benchmark at the first scanning - */ -static inline void touch_ll_filter_set_neg_noise_thresh(int neg_noise_thresh, uint8_t neg_noise_limit) -{ - bool always_update = neg_noise_thresh == -1; - bool stop_update = neg_noise_thresh == -2; - LP_ANA_PERI.touch_filter2.touch_bypass_neg_noise_thres = always_update; - LP_ANA_PERI.touch_filter1.touch_neg_noise_disupdate_baseline_en = stop_update; - LP_ANA_PERI.touch_filter1.touch_neg_noise_thres = always_update || stop_update ? 0 : neg_noise_thresh; - LP_ANA_PERI.touch_filter1.touch_neg_noise_limit = always_update || stop_update ? 5 : neg_noise_limit; // 5 is the default value + LP_ANA_PERI.touch_filter2.touch_bypass_nn_thres = always_update; + LP_ANA_PERI.touch_filter1.touch_nn_thres = always_update ? 0 : noise_thresh; + LP_ANA_PERI.touch_filter1.touch_nn_limit = 5; // 5 is the default value } /** @@ -696,10 +755,10 @@ static inline void touch_ll_filter_enable(bool enable) */ static inline void touch_ll_force_update_benchmark(uint32_t benchmark) { - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ANA_PERI.touch_filter3, touch_baseline_sw, benchmark); - LP_ANA_PERI.touch_filter3.touch_update_baseline_sw = 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ANA_PERI.touch_filter3, touch_benchmark_sw, benchmark); + LP_ANA_PERI.touch_filter3.touch_update_benchmark_sw = 1; // waiting for update - while (LP_ANA_PERI.touch_filter3.touch_update_baseline_sw); + while (LP_ANA_PERI.touch_filter3.touch_update_benchmark_sw); } /************************ Waterproof register setting ************************/ @@ -711,7 +770,8 @@ static inline void touch_ll_force_update_benchmark(uint32_t benchmark) */ static inline void touch_ll_waterproof_set_guard_chan(uint32_t pad_num) { - LP_ANA_PERI.touch_scan_ctrl2.touch_out_ring = pad_num; + // Channel shift workaround + LP_ANA_PERI.touch_scan_ctrl2.touch_out_ring = pad_num == TOUCH_LL_NULL_CHANNEL ? TOUCH_LL_NULL_CHANNEL : pad_num + 1; } /** @@ -734,7 +794,8 @@ static inline void touch_ll_waterproof_enable(bool enable) */ static inline void touch_ll_waterproof_set_shield_chan_mask(uint32_t mask) { - LP_ANA_PERI.touch_mux0.touch_bufsel = (mask & TOUCH_LL_FULL_CHANNEL_MASK); + // Channel shift workaround + LP_ANA_PERI.touch_mux0.touch_bufsel = mask << 1; } /** @@ -750,63 +811,76 @@ static inline void touch_ll_waterproof_set_shield_driver(touch_pad_shield_driver /************************ Approach register setting ************************/ /** - * Set the approach channel to the specific touch channel - * To disable the approach channel, point this pad to `TOUCH_LL_NULL_CHANNEL` + * Set the proximity sensing channel to the specific touch channel + * To disable the proximity channel, point this pad to `TOUCH_LL_NULL_CHANNEL` * - * @param aprch_chan approach channel. - * @param touch_num The touch channel that supposed to be used as approach channel + * @param prox_chan proximity sensing channel. + * @param touch_num The touch channel that supposed to be used as proximity sensing channel */ -static inline void touch_ll_set_approach_channel(uint8_t aprch_chan, uint32_t touch_num) +static inline void touch_ll_set_proximity_sensing_channel(uint8_t prox_chan, uint32_t touch_num) { - switch (aprch_chan) { + switch (prox_chan) { case 0: - LP_ANA_PERI.touch_approach.touch_approach_pad0 = touch_num; + // Channel shift workaround + LP_ANA_PERI.touch_approach.touch_approach_pad0 = touch_num + 1; break; case 1: - LP_ANA_PERI.touch_approach.touch_approach_pad1 = touch_num; + // Channel shift workaround + LP_ANA_PERI.touch_approach.touch_approach_pad1 = touch_num + 1; break; case 2: - LP_ANA_PERI.touch_approach.touch_approach_pad2 = touch_num; + // Channel shift workaround + LP_ANA_PERI.touch_approach.touch_approach_pad2 = touch_num + 1; break; default: - // invalid approach channel + // invalid proximity channel abort(); } } /** - * Set cumulative measurement times for approach channel. + * Set the total scan times of the proximity sensing channel. + * + * @param scan_times The total scan times of the proximity sensing channel + */ +static inline void touch_ll_proximity_set_total_scan_times(uint32_t scan_times) +{ + LP_ANA_PERI.touch_filter1.touch_approach_limit = scan_times; +} + +/** + * Set charge times for each sample configuration in proximity sensing mode. * - * @param sampler_id The sampler index - * @param times The cumulative number of measurement cycles. + * @param sample_cfg_id The sample configuration index + * @param charge_times The charge and discharge times. */ -static inline void touch_ll_approach_set_measure_times(uint8_t sampler_id, uint32_t times) +static inline void touch_ll_proximity_set_charge_times(uint8_t sample_cfg_id, uint32_t charge_times) { - switch (sampler_id) { + switch (sample_cfg_id) { case 0: - LP_ANA_PERI.touch_approach_work_meas_num.touch_approach_meas_num0 = times; + LP_ANA_PERI.touch_approach_work_meas_num.touch_approach_meas_num0 = charge_times; break; case 1: - LP_ANA_PERI.touch_approach_work_meas_num.touch_approach_meas_num1 = times; + LP_ANA_PERI.touch_approach_work_meas_num.touch_approach_meas_num1 = charge_times; break; case 2: - LP_ANA_PERI.touch_approach_work_meas_num.touch_approach_meas_num2 = times; + LP_ANA_PERI.touch_approach_work_meas_num.touch_approach_meas_num2 = charge_times; break; default: - // invalid sampler_id + // invalid sample_cfg_id abort(); } } /** - * Read current cumulative measurement times for approach channel. + * Read current cumulative measurement times for proximity sensing channel. * - * @param aprch_chan approach channel. + * @param prox_chan proximity sensing channel. * @param cnt The cumulative number of measurement cycles. */ -static inline void touch_ll_approach_read_measure_cnt(uint8_t aprch_chan, uint32_t *cnt) +static inline void touch_ll_proximity_read_measure_cnt(uint8_t prox_chan, uint32_t *cnt) { - switch (aprch_chan) { + switch (prox_chan) { case 0: *cnt = HAL_FORCE_READ_U32_REG_FIELD(LP_TOUCH.aprch_ch_data, approach_pad0_cnt); break; @@ -823,19 +897,18 @@ static inline void touch_ll_approach_read_measure_cnt(uint8_t aprch_chan, uint32 } /** - * Check if the touch sensor channel is the approach channel. + * Check if the touch sensor channel is the proximity sensing channel. * * @param touch_num The touch sensor channel number. */ -static inline bool touch_ll_is_approach_channel(uint32_t touch_num) +static inline bool touch_ll_is_proximity_sensing_channel(uint32_t touch_num) { if ((LP_ANA_PERI.touch_approach.touch_approach_pad0 != touch_num) && (LP_ANA_PERI.touch_approach.touch_approach_pad1 != touch_num) && (LP_ANA_PERI.touch_approach.touch_approach_pad2 != touch_num)) { return false; - } else { - return true; } + return true; } /************** sleep channel setting ***********************/ @@ -848,7 +921,8 @@ static inline bool touch_ll_is_approach_channel(uint32_t touch_num) */ static inline void touch_ll_sleep_set_channel_num(uint32_t touch_num) { - LP_ANA_PERI.touch_slp0.touch_slp_pad = touch_num; + // Channel shift workaround + LP_ANA_PERI.touch_slp0.touch_slp_pad = touch_num + 1; } /** @@ -869,9 +943,9 @@ static inline void touch_ll_sleep_get_channel_num(uint32_t *touch_num) * * @note In general, the touch threshold during sleep can use the threshold parameter parameters before sleep. */ -static inline void touch_ll_sleep_set_threshold(uint8_t sampler_id, uint32_t touch_thresh) +static inline void touch_ll_sleep_set_threshold(uint8_t sample_cfg_id, uint32_t touch_thresh) { - switch (sampler_id) { + switch (sample_cfg_id) { case 0: HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ANA_PERI.touch_slp0, touch_slp_th0, touch_thresh); break; @@ -882,15 +956,15 @@ static inline void touch_ll_sleep_set_threshold(uint8_t sampler_id, uint32_t tou HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ANA_PERI.touch_slp1, touch_slp_th2, touch_thresh); break; default: - // invalid sampler_id + // invalid sample_cfg_id abort(); } } /** - * Enable approach function for sleep channel. + * Enable proximity sensing function for sleep channel. */ -static inline void touch_ll_sleep_enable_approach(bool enable) +static inline void touch_ll_sleep_enable_proximity_sensing(bool enable) { LP_ANA_PERI.touch_approach.touch_slp_approach_en = enable; } @@ -898,7 +972,7 @@ static inline void touch_ll_sleep_enable_approach(bool enable) /** * Get the data of the touch channel according to the types * - * @param sampler_id The sampler index + * @param sample_cfg_id The sample configuration index * @param type data type * 0/1: TOUCH_LL_READ_RAW, the raw data of the touch channel * 2: TOUCH_LL_READ_BENCHMARK, benchmark value of touch channel, @@ -907,10 +981,10 @@ static inline void touch_ll_sleep_enable_approach(bool enable) * @param smooth_data pointer to smoothed data */ __attribute__((always_inline)) -static inline void touch_ll_sleep_read_chan_data(uint8_t type, uint8_t sampler_id, uint32_t *data) +static inline void touch_ll_sleep_read_chan_data(uint8_t type, uint8_t sample_cfg_id, uint32_t *data) { HAL_ASSERT(type <= TOUCH_LL_READ_SMOOTH); - LP_ANA_PERI.touch_mux0.touch_freq_sel = sampler_id + 1; + LP_ANA_PERI.touch_mux0.touch_freq_sel = sample_cfg_id + 1; LP_ANA_PERI.touch_mux0.touch_data_sel = type; *data = HAL_FORCE_READ_U32_REG_FIELD(LP_TOUCH.slp_ch_data, slp_data); } @@ -935,12 +1009,33 @@ static inline void touch_ll_sleep_read_debounce(uint32_t *debounce) } /** - * Read approach count of touch sensor for sleep channel. - * @param approach_cnt Pointer to accept touch sensor approach count value. + * Read proximity count of touch sensor for sleep channel. + * @param prox_cnt Pointer to accept touch sensor proximity count value. + */ +static inline void touch_ll_sleep_read_proximity_cnt(uint32_t *prox_cnt) +{ + *prox_cnt = HAL_FORCE_READ_U32_REG_FIELD(LP_TOUCH.aprch_ch_data, slp_approach_cnt); +} + +/** + * @brief Enable or disable the internal capacitor, mainly for debug + * + * @param enable enable or disable the internal capacitor + */ +static inline void touch_ll_enable_internal_capacitor(bool enable) +{ + LP_ANA_PERI.touch_ana_para.touch_touch_en_cal = enable; +} + +/** + * @brief Set the internal capacitor, mainly for debug + * @note Only take effect when the internal capacitor is enabled + * + * @param cap the capacitor value */ -static inline void touch_ll_sleep_read_approach_cnt(uint32_t *approach_cnt) +static inline void touch_ll_set_internal_capacitor(uint32_t cap) { - *approach_cnt = HAL_FORCE_READ_U32_REG_FIELD(LP_TOUCH.aprch_ch_data, slp_approach_cnt); + LP_ANA_PERI.touch_ana_para.touch_touch_dcap_cal = cap; } #ifdef __cplusplus diff --git a/components/hal/esp32p4/include/hal/uart_ll.h b/components/hal/esp32p4/include/hal/uart_ll.h index e3f5a40d6ee6..70560c235d7b 100644 --- a/components/hal/esp32p4/include/hal/uart_ll.h +++ b/components/hal/esp32p4/include/hal/uart_ll.h @@ -45,6 +45,13 @@ extern "C" { #define UART_LL_FSM_IDLE (0x0) #define UART_LL_FSM_TX_WAIT_SEND (0xf) +// UART sleep retention module +#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \ + (uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : \ + (uart_num == UART_NUM_2) ? SLEEP_RETENTION_MODULE_UART2 : \ + (uart_num == UART_NUM_3) ? SLEEP_RETENTION_MODULE_UART3 : \ + (uart_num == UART_NUM_4) ? SLEEP_RETENTION_MODULE_UART4 : -1) + // Define UART interrupts typedef enum { UART_INTR_RXFIFO_FULL = (0x1 << 0), @@ -817,7 +824,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -884,7 +891,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -1215,7 +1222,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32p4/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32p4/include/hal/usb_serial_jtag_ll.h index 029e36352613..f6b13b9a797c 100644 --- a/components/hal/esp32p4/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32p4/include/hal/usb_serial_jtag_ll.h @@ -14,17 +14,188 @@ #include "soc/usb_serial_jtag_struct.h" #include "hal/usb_serial_jtag_types.h" -// This header is temporarily disabled until USJ is supported on the P4 (IDF-7496) #if SOC_USB_SERIAL_JTAG_SUPPORTED /* ----------------------------- Macros & Types ----------------------------- */ #define USB_SERIAL_JTAG_LL_SELECT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask + +// Define USB_SERIAL_JTAG interrupts +// Note the hardware has more interrupts, but they're only useful for debugging +// the hardware. +typedef enum { + USB_SERIAL_JTAG_INTR_SOF = (1 << 1), + USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT = (1 << 2), + USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY = (1 << 3), + USB_SERIAL_JTAG_INTR_TOKEN_REC_IN_EP1 = (1 << 8), + USB_SERIAL_JTAG_INTR_BUS_RESET = (1 << 9), + USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), +} usb_serial_jtag_ll_intr_t; + #ifdef __cplusplus extern "C" { #endif +/* ----------------------------- USJ Peripheral ----------------------------- */ + +/** + * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. + * + * @param mask The bitmap of the interrupts need to be enabled. + * + * @return None + */ +static inline void usb_serial_jtag_ll_ena_intr_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_ena.val |= mask; +} + +/** + * @brief Disable the USB_SERIAL_JTAG interrupt based on the given mask. + * + * @param mask The bitmap of the interrupts need to be disabled. + * + * @return None + */ +static inline void usb_serial_jtag_ll_disable_intr_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_ena.val &= (~mask); +} + +/** + * @brief Get the USB_SERIAL_JTAG interrupt status. + * + * @return The USB_SERIAL_JTAG interrupt status. + */ +static inline uint32_t usb_serial_jtag_ll_get_intsts_mask(void) +{ + return USB_SERIAL_JTAG.int_st.val; +} + +/** + * @brief Get the USB_SERIAL_JTAG raw interrupt status. + * + * @return The USB_SERIAL_JTAG raw interrupt status. + */ +static inline __attribute__((always_inline)) uint32_t usb_serial_jtag_ll_get_intraw_mask(void) +{ + return USB_SERIAL_JTAG.int_raw.val; +} + +/** + * @brief Clear the USB_SERIAL_JTAG interrupt status based on the given mask. + * + * @param mask The bitmap of the interrupts need to be cleared. + * + * @return None + */ +static inline __attribute__((always_inline)) void usb_serial_jtag_ll_clr_intsts_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_clr.val = mask; +} + +/** + * @brief Get status of enabled interrupt. + * + * @return interrupt enable value + */ +static inline uint32_t usb_serial_jtag_ll_get_intr_ena_status(void) +{ + return USB_SERIAL_JTAG.int_ena.val; +} + +/** + * @brief Read the bytes from the USB_SERIAL_JTAG rxfifo. + * + * @param buf The data buffer. + * @param rd_len The data length needs to be read. + * + * @return amount of bytes read + */ +static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len) +{ + int i; + for (i = 0; i < (int)rd_len; i++) { + if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break; + buf[i] = USB_SERIAL_JTAG.ep1.rdwr_byte; + } + return i; +} + +/** + * @brief Write byte to the USB_SERIAL_JTAG txfifo. Only writes bytes as long / if there + * is room in the buffer. + * + * @param buf The data buffer. + * @param wr_len The data length needs to be written. + * + * @return Amount of bytes actually written. May be less than wr_len. + */ +static inline int usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint32_t wr_len) +{ + int i; + for (i = 0; i < (int)wr_len; i++) { + if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break; + USB_SERIAL_JTAG.ep1.rdwr_byte = buf[i]; + } + return i; +} + +/** + * @brief Returns 1 if the USB_SERIAL_JTAG rxfifo has data available. + * + * @return 0 if no data available, 1 if data available + */ +static inline int usb_serial_jtag_ll_rxfifo_data_available(void) +{ + return USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail; +} + +/** + * @brief Returns 1 if the USB_SERIAL_JTAG txfifo has room. + * + * @return 0 if no data available, 1 if data available + */ +static inline int usb_serial_jtag_ll_txfifo_writable(void) +{ + return USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free; +} + +/** + * @brief Flushes the TX buffer, that is, make it available for the + * host to pick up. + * + * @note When fifo is full (with 64 byte), HW will flush the buffer automatically, + * if this function is called directly after, this effectively turns into a + * no-op. Because a 64-byte packet will be interpreted as a not-complete USB + * transaction, you need to transfer either more data or a zero-length packet + * for the data to actually end up at the program listening to the CDC-ACM + * serial port. To send a zero-length packet, call + * usb_serial_jtag_ll_txfifo_flush() again when + * usb_serial_jtag_ll_txfifo_writable() returns true. + * + * @return na + */ +static inline void usb_serial_jtag_ll_txfifo_flush(void) +{ + USB_SERIAL_JTAG.ep1_conf.wr_done=1; +} + +/** + * @brief Enable USJ JTAG bridge + * + * If enabled, USJ is disconnected from internal JTAG interface. JTAG interface + * is routed through GPIO matrix instead. + * + * @param enable Enable USJ JTAG bridge + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable; +} + /* ---------------------------- USB PHY Control ---------------------------- */ /** diff --git a/components/hal/esp32p4/include/hal/usb_wrap_ll.h b/components/hal/esp32p4/include/hal/usb_wrap_ll.h index 5e6b94236680..113a56fe771f 100644 --- a/components/hal/esp32p4/include/hal/usb_wrap_ll.h +++ b/components/hal/esp32p4/include/hal/usb_wrap_ll.h @@ -12,6 +12,7 @@ #include "soc/lp_system_struct.h" #include "soc/lp_clkrst_struct.h" #include "soc/hp_sys_clkrst_struct.h" +#include "soc/hp_system_struct.h" // For HP_SYSTEM domain #include "soc/usb_wrap_struct.h" #include "hal/usb_wrap_types.h" @@ -262,6 +263,14 @@ FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void) // P_AON_CLKRST.hp_usb_clkrst_ctrlx are shared registers, so this function must be used in an atomic way #define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_reset_register(__VA_ARGS__) +/* ------------------------------- HP System ------------------------------- */ + +FORCE_INLINE_ATTR void usb_wrap_ll_enable_precise_detection(void) +{ + // Enable VBUS precise detection + HP_SYSTEM.sys_usbotg20_ctrl.sys_otg_suspendm = 1; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/pau_hal.c b/components/hal/esp32p4/pau_hal.c index 38b98ba4e1e4..2852d99a9250 100644 --- a/components/hal/esp32p4/pau_hal.c +++ b/components/hal/esp32p4/pau_hal.c @@ -20,6 +20,10 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_ pau_ll_set_regdma_link2_addr(hal->dev, (*link_addr)[2]); /* The link 3 of REGDMA is reserved, PMU state switching will not use * REGDMA link 3 */ + + // When light sleep (PD_TOP), the PAU will power down. so need use LP_SYS_BACKUP_DMA_CFG2_REG + // to store recover link address. We always use link0 as the default retention entry. + lp_sys_ll_set_pau_link_addr((uint32_t)(*link_addr)[0]); } void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) diff --git a/components/hal/esp32p4/touch_sensor_hal.c b/components/hal/esp32p4/touch_sensor_hal.c new file mode 100644 index 000000000000..450e3ab89ba2 --- /dev/null +++ b/components/hal/esp32p4/touch_sensor_hal.c @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/soc_pins.h" +#include "hal/touch_sensor_ll.h" +#include "hal/touch_sensor_hal.h" +#include "hal/touch_sensor_types.h" +#include "soc/soc_caps.h" + +typedef struct { + int deep_slp_chan; + touch_hal_config_t slp_cfg; + bool apply_slp_cfg; +} touch_hal_deep_sleep_obj_t; + +static touch_hal_deep_sleep_obj_t s_touch_slp_obj = { + .deep_slp_chan = -1, + .apply_slp_cfg = false, +}; + +void touch_hal_config_controller(const touch_hal_config_t *cfg) +{ + HAL_ASSERT(cfg); + touch_ll_sleep_set_channel_num(TOUCH_LL_NULL_CHANNEL); + touch_ll_set_out_mode(cfg->output_mode); + touch_ll_set_power_on_wait_cycle(cfg->power_on_wait_ticks); + touch_ll_set_measure_interval_ticks(cfg->meas_interval_ticks); + if (cfg->timeout_ticks) { + touch_ll_timeout_enable(cfg->timeout_ticks); + } else { + touch_ll_timeout_disable(); + } + + touch_ll_sample_cfg_set_engaged_num(cfg->sample_cfg_num); + for (int i = 0; i < cfg->sample_cfg_num; i++) { + touch_ll_set_clock_div(i, cfg->sample_cfg[i].div_num); + touch_ll_set_charge_times(i, cfg->sample_cfg[i].charge_times); + touch_ll_sample_cfg_set_rc_filter(i, cfg->sample_cfg[i].rc_filter_cap, cfg->sample_cfg[i].rc_filter_res); + touch_ll_sample_cfg_set_driver(i, cfg->sample_cfg[i].low_drv, cfg->sample_cfg[i].high_drv); + touch_ll_sample_cfg_bypass_shield_output(i, cfg->sample_cfg[i].bypass_shield_output); + touch_ll_sample_cfg_set_bias_voltage(i, cfg->sample_cfg[i].bias_volt); + } +} + +void touch_hal_save_sleep_config(int deep_slp_chan, const touch_hal_config_t *deep_slp_cfg) +{ + s_touch_slp_obj.deep_slp_chan = deep_slp_chan; + /* If particular deep sleep configuration is given, save it and apply it before entering the deep sleep */ + if (deep_slp_chan >= 0 && deep_slp_cfg) { + s_touch_slp_obj.apply_slp_cfg = true; + memcpy(&s_touch_slp_obj.slp_cfg, deep_slp_cfg, sizeof(touch_hal_config_t)); + } else { + s_touch_slp_obj.apply_slp_cfg = false; + } +} + +//This function will only be called when the chip is going to deep sleep. +static void s_touch_hal_apply_sleep_config(void) +{ + /* Apply the particular configuration for deep sleep */ + if (s_touch_slp_obj.apply_slp_cfg) { + touch_hal_config_controller(&s_touch_slp_obj.slp_cfg); + } + /* Whether to enable touch sensor wake-up the chip from deep sleep */ + if (s_touch_slp_obj.deep_slp_chan >= 0) { + touch_ll_sleep_set_channel_num(s_touch_slp_obj.deep_slp_chan); + touch_ll_set_channel_mask(BIT(s_touch_slp_obj.deep_slp_chan)); + } else { + touch_ll_sleep_set_channel_num(TOUCH_LL_NULL_CHANNEL); + } +} + +void touch_hal_prepare_deep_sleep(void) +{ + s_touch_hal_apply_sleep_config(); + touch_ll_sleep_reset_benchmark(); + touch_ll_intr_clear(TOUCH_LL_INTR_MASK_ALL); +} diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index 1344a64970d4..d0b558cc6191 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,8 @@ #include "soc/clk_tree_defs.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_saradc.h" +#include "soc/system_reg.h" +#include "soc/dport_reg.h" #ifdef __cplusplus extern "C" { @@ -40,6 +42,7 @@ extern "C" { #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) +#define ADC_LL_RTC_GPIO_SUPPORTED (1) /*--------------------------------------------------------------- DMA @@ -917,6 +920,32 @@ static inline void adc_oneshot_ll_disable_all_unit(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); + reg_val = reg_val & (~DPORT_APB_SARADC_CLK_EN); + reg_val = reg_val | (enable << DPORT_APB_SARADC_CLK_EN_S); + WRITE_PERI_REG(DPORT_PERIP_CLK_EN0_REG, reg_val); +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_APB_SARADC_RST); + CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_APB_SARADC_RST); +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32s2/include/hal/mmu_ll.h b/components/hal/esp32s2/include/hal/mmu_ll.h index 396942e5d0ae..7c166c5cca62 100644 --- a/components/hal/esp32s2/include/hal/mmu_ll.h +++ b/components/hal/esp32s2/include/hal/mmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,9 @@ extern "C" { #endif +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - 0x10000) +#define MMU_LL_END_DROM_ENTRY_ID (192 - 1) + /** * Convert MMU virtual address to linear address * @@ -249,7 +252,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32s2/include/hal/rmt_ll.h b/components/hal/esp32s2/include/hal/rmt_ll.h index 00730fec0c21..98eb39dfe054 100644 --- a/components/hal/esp32s2/include/hal/rmt_ll.h +++ b/components/hal/esp32s2/include/hal/rmt_ll.h @@ -90,15 +90,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->apb_conf.mem_force_pu = !enable; - dev->apb_conf.mem_force_pd = enable; + dev->apb_conf.mem_force_pu = 1; + dev->apb_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->apb_conf.mem_force_pd = 1; + dev->apb_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->apb_conf.mem_force_pd = 0; + dev->apb_conf.mem_force_pu = 0; } /** @@ -423,7 +444,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, * * @param dev Peripheral instance address * @param channel RMT TX channel number - * @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data + * @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data */ static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable) { @@ -628,7 +649,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e * @brief Clear RMT interrupt status by mask * * @param dev Peripheral instance address - * @param mask Interupt status mask + * @param mask Interrupt status mask */ __attribute__((always_inline)) static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask) @@ -774,12 +795,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->conf_ch[channel].conf1.idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->apb_conf.mem_force_pd) || !(dev->apb_conf.mem_force_pu); + return dev->apb_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32s2/include/hal/touch_sensor_hal.h b/components/hal/esp32s2/include/hal/touch_sensor_hal.h index 5f0c266018d1..b42532c78f9d 100644 --- a/components/hal/esp32s2/include/hal/touch_sensor_hal.h +++ b/components/hal/esp32s2/include/hal/touch_sensor_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,7 @@ extern "C" { /** * Reset the whole of touch module. * - * @note Call this funtion after `touch_pad_fsm_stop`, + * @note Call this function after `touch_pad_fsm_stop`, */ #define touch_hal_reset() touch_ll_reset() @@ -385,7 +385,7 @@ void touch_hal_denoise_enable(void); #define touch_hal_waterproof_get_guard_pad(pad_num) touch_ll_waterproof_get_guard_pad(pad_num) /** - * Set max equivalent capacitance for sheild channel. + * Set max equivalent capacitance for shield channel. * The equivalent capacitance of the shielded channel can be calculated * from the reading of denoise channel. * @@ -394,7 +394,7 @@ void touch_hal_denoise_enable(void); #define touch_hal_waterproof_set_sheild_driver(driver_level) touch_ll_waterproof_set_sheild_driver(driver_level) /** - * Get max equivalent capacitance for sheild channel. + * Get max equivalent capacitance for shield channel. * The equivalent capacitance of the shielded channel can be calculated * from the reading of denoise channel. * @@ -551,12 +551,12 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable); /** * Enable proximity function for sleep pad. */ -#define touch_hal_sleep_enable_approach() touch_ll_sleep_enable_approach() +#define touch_hal_sleep_enable_approach() touch_ll_sleep_enable_proximity_sensing() /** * Disable proximity function for sleep pad. */ -#define touch_hal_sleep_disable_approach() touch_ll_sleep_disable_approach() +#define touch_hal_sleep_disable_approach() touch_ll_sleep_disable_proximity_sensing() /** * Read benchmark of touch sensor for sleep pad. diff --git a/components/hal/esp32s2/include/hal/touch_sensor_ll.h b/components/hal/esp32s2/include/hal/touch_sensor_ll.h index 656b79099f34..0cc5069d2f27 100644 --- a/components/hal/esp32s2/include/hal/touch_sensor_ll.h +++ b/components/hal/esp32s2/include/hal/touch_sensor_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -214,6 +214,7 @@ static inline void touch_ll_get_tie_option(touch_pad_t touch_num, touch_tie_opt_ * * @param mode FSM mode. */ +__attribute__((always_inline)) static inline void touch_ll_set_fsm_mode(touch_fsm_mode_t mode) { RTCCNTL.touch_ctrl2.touch_start_force = mode; @@ -280,6 +281,7 @@ static inline void touch_ll_start_fsm(void) * Stop touch sensor FSM timer. * The measurement action can be triggered by the hardware timer, as well as by the software instruction. */ +__attribute__((always_inline)) static inline void touch_ll_stop_fsm(void) { RTCCNTL.touch_ctrl2.touch_start_en = 0; //stop touch fsm @@ -416,7 +418,8 @@ static inline uint32_t IRAM_ATTR touch_ll_read_raw_data(touch_pad_t touch_num) * @return * - If touch sensors measure done. */ -static inline bool touch_ll_meas_is_done(void) +__attribute__((always_inline)) +static inline bool touch_ll_is_measure_done(void) { return (bool)SENS.sar_touch_chn_st.touch_meas_done; } @@ -555,22 +558,23 @@ static inline void touch_ll_intr_clear(touch_pad_intr_mask_t int_mask) */ static inline uint32_t touch_ll_read_intr_status_mask(void) { - uint32_t intr_st = RTCCNTL.int_st.val; + typeof(RTCCNTL.int_st) intr_st; + intr_st.val = RTCCNTL.int_st.val; uint32_t intr_msk = 0; - if (intr_st & RTC_CNTL_TOUCH_DONE_INT_ST_M) { + if (intr_st.rtc_touch_done) { intr_msk |= TOUCH_PAD_INTR_MASK_DONE; } - if (intr_st & RTC_CNTL_TOUCH_ACTIVE_INT_ST_M) { + if (intr_st.rtc_touch_active) { intr_msk |= TOUCH_PAD_INTR_MASK_ACTIVE; } - if (intr_st & RTC_CNTL_TOUCH_INACTIVE_INT_ST_M) { + if (intr_st.rtc_touch_inactive) { intr_msk |= TOUCH_PAD_INTR_MASK_INACTIVE; } - if (intr_st & RTC_CNTL_TOUCH_SCAN_DONE_INT_ST_M) { + if (intr_st.rtc_touch_scan_done) { intr_msk |= TOUCH_PAD_INTR_MASK_SCAN_DONE; } - if (intr_st & RTC_CNTL_TOUCH_TIMEOUT_INT_ST_M) { + if (intr_st.rtc_touch_timeout) { intr_msk |= TOUCH_PAD_INTR_MASK_TIMEOUT; } return (intr_msk & TOUCH_PAD_INTR_MASK_ALL); @@ -909,7 +913,7 @@ static inline void touch_ll_waterproof_get_guard_pad(touch_pad_t *pad_num) } /** - * Set max equivalent capacitance for sheild channel. + * Set max equivalent capacitance for shield channel. * The equivalent capacitance of the shielded channel can be calculated * from the reading of denoise channel. * @@ -921,7 +925,7 @@ static inline void touch_ll_waterproof_set_sheild_driver(touch_pad_shield_driver } /** - * Get max equivalent capacitance for sheild channel. + * Get max equivalent capacitance for shield channel. * The equivalent capacitance of the shielded channel can be calculated * from the reading of denoise channel. * @@ -1084,7 +1088,7 @@ static inline void touch_ll_sleep_get_threshold(uint32_t *touch_thres) /** * Enable proximity function for sleep pad. */ -static inline void touch_ll_sleep_enable_approach(void) +static inline void touch_ll_sleep_enable_proximity_sensing(void) { RTCCNTL.touch_slp_thres.touch_slp_approach_en = 1; } @@ -1092,7 +1096,7 @@ static inline void touch_ll_sleep_enable_approach(void) /** * Disable proximity function for sleep pad. */ -static inline void touch_ll_sleep_disable_approach(void) +static inline void touch_ll_sleep_disable_proximity_sensing(void) { RTCCNTL.touch_slp_thres.touch_slp_approach_en = 0; } @@ -1100,7 +1104,7 @@ static inline void touch_ll_sleep_disable_approach(void) /** * Get proximity function status for sleep pad. */ -static inline bool touch_ll_sleep_get_approach_status(void) +static inline bool touch_ll_sleep_is_proximity_enabled(void) { return (bool)RTCCNTL.touch_slp_thres.touch_slp_approach_en; } @@ -1157,11 +1161,11 @@ static inline void touch_ll_sleep_read_debounce(uint32_t *debounce) /** * Read proximity count of touch sensor for sleep pad. - * @param proximity_cnt Pointer to accept touch sensor proximity count value. + * @param prox_cnt Pointer to accept touch sensor proximity count value. */ -static inline void touch_ll_sleep_read_proximity_cnt(uint32_t *approach_cnt) +static inline void touch_ll_sleep_read_proximity_cnt(uint32_t *prox_cnt) { - *approach_cnt = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_touch_appr_status, touch_slp_approach_cnt); + *prox_cnt = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_touch_appr_status, touch_slp_approach_cnt); } /** diff --git a/components/hal/esp32s2/include/hal/uart_ll.h b/components/hal/esp32s2/include/hal/uart_ll.h index 601cafeeeeda..4dfbeb954327 100644 --- a/components/hal/esp32s2/include/hal/uart_ll.h +++ b/components/hal/esp32s2/include/hal/uart_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -298,7 +298,7 @@ FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_ * * @param hw Beginning address of the peripheral registers. * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return None */ @@ -476,7 +476,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -541,7 +541,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -832,7 +832,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32s2/touch_sensor_hal.c b/components/hal/esp32s2/touch_sensor_hal.c index 04deb1c92520..78bc17819e00 100644 --- a/components/hal/esp32s2/touch_sensor_hal.c +++ b/components/hal/esp32s2/touch_sensor_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -53,7 +53,7 @@ void touch_hal_deinit(void) touch_pad_t prox_pad[SOC_TOUCH_PROXIMITY_CHANNEL_NUM] = {[0 ... (SOC_TOUCH_PROXIMITY_CHANNEL_NUM - 1)] = 0}; touch_ll_proximity_set_channel_num((const touch_pad_t *)prox_pad); touch_ll_sleep_set_channel_num(0); - touch_ll_sleep_disable_approach(); + touch_ll_sleep_disable_proximity_sensing(); touch_ll_reset(); // Reset the touch sensor FSM. } @@ -152,7 +152,7 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable) void touch_hal_sleep_channel_get_config(touch_pad_sleep_channel_t *slp_config) { touch_ll_sleep_get_channel_num(&slp_config->touch_num); - slp_config->en_proximity = touch_ll_sleep_get_approach_status(); + slp_config->en_proximity = touch_ll_sleep_is_proximity_enabled(); } void touch_hal_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times) diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index 7e0f405e1fc9..ec8180c04866 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ #include "soc/rtc_cntl_reg.h" #include "soc/regi2c_defs.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_saradc.h" @@ -43,6 +44,7 @@ extern "C" { #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) +#define ADC_LL_RTC_GPIO_SUPPORTED (1) /*--------------------------------------------------------------- DMA @@ -611,6 +613,29 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ + +/** + * @brief Enable the ADC clock + * @param enable true to enable, false to disable + */ +static inline void adc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.apb_saradc_clk_en = enable; +} +// SYSTEM.perip_clk_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset ADC module + */ +static inline void adc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.apb_saradc_rst = 1; + SYSTEM.perip_rst_en0.apb_saradc_rst = 0; +} +// SYSTEM.perip_rst_en0 is a shared register, so this function must be used in an atomic way +#define adc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; adc_ll_reset_register(__VA_ARGS__) + /** * Set ADC module power management. * diff --git a/components/hal/esp32s3/include/hal/gdma_ll.h b/components/hal/esp32s3/include/hal/gdma_ll.h index 951145e85f8b..33c5c934eb5e 100644 --- a/components/hal/esp32s3/include/hal/gdma_ll.h +++ b/components/hal/esp32s3/include/hal/gdma_ll.h @@ -62,6 +62,9 @@ extern "C" { #define GDMA_LL_AHB_DESC_ALIGNMENT 4 +#define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size +#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 + ///////////////////////////////////// Common ///////////////////////////////////////// /** @@ -177,20 +180,20 @@ static inline void gdma_ll_rx_reset_channel(gdma_dev_t *dev, uint32_t channel) } /** - * @brief Set DMA RX channel memory block size based on the alignment requirement - * @param align Supported value: 16/32/64 + * @brief Set DMA RX channel memory block size based on the burst requirement + * @param burst_sz Supported value: 16/32/64 */ -static inline void gdma_ll_rx_set_ext_mem_block_size(gdma_dev_t *dev, uint32_t channel, uint8_t align) +static inline void gdma_ll_rx_set_burst_size(gdma_dev_t *dev, uint32_t channel, uint32_t burst_sz) { uint32_t block_size = 0; - switch (align) { - case 64: // 64 Bytes alignment + switch (burst_sz) { + case 64: block_size = GDMA_LL_EXT_MEM_BK_SIZE_64B; break; - case 32: // 32 Bytes alignment + case 32: block_size = GDMA_LL_EXT_MEM_BK_SIZE_32B; break; - case 16: // 16 Bytes alignment + case 16: block_size = GDMA_LL_EXT_MEM_BK_SIZE_16B; break; default: @@ -461,20 +464,20 @@ static inline void gdma_ll_tx_reset_channel(gdma_dev_t *dev, uint32_t channel) } /** - * @brief Set DMA TX channel memory block size based on the alignment requirement - * @param align Supported value: 16/32/64 + * @brief Set DMA TX channel memory block size based on the burst requirement + * @param burst_sz Supported value: 16/32/64 */ -static inline void gdma_ll_tx_set_ext_mem_block_size(gdma_dev_t *dev, uint32_t channel, uint8_t align) +static inline void gdma_ll_tx_set_burst_size(gdma_dev_t *dev, uint32_t channel, uint32_t burst_sz) { uint32_t block_size = 0; - switch (align) { - case 64: // 64 Bytes alignment + switch (burst_sz) { + case 64: block_size = GDMA_LL_EXT_MEM_BK_SIZE_64B; break; - case 32: // 32 Bytes alignment + case 32: block_size = GDMA_LL_EXT_MEM_BK_SIZE_32B; break; - case 16: // 16 Bytes alignment + case 16: block_size = GDMA_LL_EXT_MEM_BK_SIZE_16B; break; default: diff --git a/components/hal/esp32s3/include/hal/mmu_ll.h b/components/hal/esp32s3/include/hal/mmu_ll.h index 1188df3d5f96..8877c31402a7 100644 --- a/components/hal/esp32s3/include/hal/mmu_ll.h +++ b/components/hal/esp32s3/include/hal/mmu_ll.h @@ -19,6 +19,8 @@ extern "C" { #endif +#define MMU_LL_END_DROM_ENTRY_VADDR (SOC_DRAM_FLASH_ADDRESS_HIGH - 0x10000) +#define MMU_LL_END_DROM_ENTRY_ID (SOC_MMU_ENTRY_NUM - 1) /** * Convert MMU virtual address to linear address * @@ -230,7 +232,7 @@ static inline void mmu_ll_unmap_all(uint32_t mmu_id) * @param mmu_id MMU ID * @param entry_id MMU entry ID * - * @return Ture for MMU entry is valid; False for invalid + * @return True for MMU entry is valid; False for invalid */ static inline bool mmu_ll_check_entry_valid(uint32_t mmu_id, uint32_t entry_id) { diff --git a/components/hal/esp32s3/include/hal/rmt_ll.h b/components/hal/esp32s3/include/hal/rmt_ll.h index 7d5dcf5eecf1..e999add0260e 100644 --- a/components/hal/esp32s3/include/hal/rmt_ll.h +++ b/components/hal/esp32s3/include/hal/rmt_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -87,15 +87,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -453,7 +474,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, * * @param dev Peripheral instance address * @param channel RMT TX channel number - * @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data + * @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data */ static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable) { @@ -696,7 +717,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e * @brief Clear RMT interrupt status by mask * * @param dev Peripheral instance address - * @param mask Interupt status mask + * @param mask Interrupt status mask */ __attribute__((always_inline)) static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask) @@ -850,12 +871,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32s3/include/hal/rtc_io_ll.h b/components/hal/esp32s3/include/hal/rtc_io_ll.h index 1a988c000cb8..86d483b217a5 100644 --- a/components/hal/esp32s3/include/hal/rtc_io_ll.h +++ b/components/hal/esp32s3/include/hal/rtc_io_ll.h @@ -19,6 +19,7 @@ #include "soc/io_mux_reg.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "soc/sens_struct.h" #ifdef __cplusplus extern "C" { @@ -27,7 +28,7 @@ extern "C" { #define RTCIO_LL_PIN_FUNC 0 typedef enum { - RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controled by RTC module. */ + RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */ RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */ } rtcio_ll_func_t; diff --git a/components/hal/esp32s3/include/hal/touch_sensor_hal.h b/components/hal/esp32s3/include/hal/touch_sensor_hal.h index 603c437f166e..c80f624fde1a 100644 --- a/components/hal/esp32s3/include/hal/touch_sensor_hal.h +++ b/components/hal/esp32s3/include/hal/touch_sensor_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,7 @@ extern "C" { /** * Reset the whole of touch module. * - * @note Call this funtion after `touch_pad_fsm_stop`, + * @note Call this function after `touch_pad_fsm_stop`, */ #define touch_hal_reset() touch_ll_reset() @@ -385,7 +385,7 @@ void touch_hal_denoise_enable(void); #define touch_hal_waterproof_get_guard_pad(pad_num) touch_ll_waterproof_get_guard_pad(pad_num) /** - * Set max equivalent capacitance for sheild channel. + * Set max equivalent capacitance for shield channel. * The equivalent capacitance of the shielded channel can be calculated * from the reading of denoise channel. * @@ -394,7 +394,7 @@ void touch_hal_denoise_enable(void); #define touch_hal_waterproof_set_sheild_driver(driver_level) touch_ll_waterproof_set_sheild_driver(driver_level) /** - * Get max equivalent capacitance for sheild channel. + * Get max equivalent capacitance for shield channel. * The equivalent capacitance of the shielded channel can be calculated * from the reading of denoise channel. * @@ -551,12 +551,12 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable); /** * Enable proximity function for sleep pad. */ -#define touch_hal_sleep_enable_approach() touch_ll_sleep_enable_approach() +#define touch_hal_sleep_enable_approach() touch_ll_sleep_enable_proximity_sensing() /** * Disable proximity function for sleep pad. */ -#define touch_hal_sleep_disable_approach() touch_ll_sleep_disable_approach() +#define touch_hal_sleep_disable_approach() touch_ll_sleep_disable_proximity_sensing() /** * Read benchmark of touch sensor for sleep pad. diff --git a/components/hal/esp32s3/include/hal/touch_sensor_ll.h b/components/hal/esp32s3/include/hal/touch_sensor_ll.h index 0cb69edc5412..d3dde4edd356 100644 --- a/components/hal/esp32s3/include/hal/touch_sensor_ll.h +++ b/components/hal/esp32s3/include/hal/touch_sensor_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -168,11 +168,18 @@ static inline void touch_ll_get_voltage_attenuation(touch_volt_atten_t *atten) */ static inline void touch_ll_set_slope(touch_pad_t touch_num, touch_cnt_slope_t slope) { +#define PAD_SLOP_MASK(val, num) ((val) << (29 - (num) * 3)) + uint32_t curr_slop = 0; if (touch_num < TOUCH_PAD_NUM10) { - SET_PERI_REG_BITS(RTC_CNTL_TOUCH_DAC_REG, RTC_CNTL_TOUCH_PAD0_DAC_V, slope, (RTC_CNTL_TOUCH_PAD0_DAC_S - touch_num * 3)); + curr_slop = RTCCNTL.touch_dac.val; + curr_slop &= ~PAD_SLOP_MASK(0x07, touch_num); // clear the old value + RTCCNTL.touch_dac.val = curr_slop | PAD_SLOP_MASK(slope, touch_num); } else { - SET_PERI_REG_BITS(RTC_CNTL_TOUCH_DAC1_REG, RTC_CNTL_TOUCH_PAD10_DAC_V, slope, (RTC_CNTL_TOUCH_PAD10_DAC_S - (touch_num - TOUCH_PAD_NUM10) * 3)); + curr_slop = RTCCNTL.touch_dac1.val; + curr_slop &= ~PAD_SLOP_MASK(0x07, touch_num - TOUCH_PAD_NUM10); // clear the old value + RTCCNTL.touch_dac1.val = curr_slop | PAD_SLOP_MASK(slope, touch_num - TOUCH_PAD_NUM10); } +#undef PAD_SLOP_MASK } /** @@ -188,9 +195,9 @@ static inline void touch_ll_set_slope(touch_pad_t touch_num, touch_cnt_slope_t s static inline void touch_ll_get_slope(touch_pad_t touch_num, touch_cnt_slope_t *slope) { if (touch_num < TOUCH_PAD_NUM10) { - *slope = (touch_cnt_slope_t)(GET_PERI_REG_BITS2(RTC_CNTL_TOUCH_DAC_REG, RTC_CNTL_TOUCH_PAD0_DAC_V, (RTC_CNTL_TOUCH_PAD0_DAC_S - touch_num * 3))); + *slope = (touch_cnt_slope_t)((RTCCNTL.touch_dac.val >> (29 - touch_num * 3)) & 0x07); } else { - *slope = (touch_cnt_slope_t)(GET_PERI_REG_BITS2(RTC_CNTL_TOUCH_DAC1_REG, RTC_CNTL_TOUCH_PAD10_DAC_V, (RTC_CNTL_TOUCH_PAD10_DAC_S - (touch_num - TOUCH_PAD_NUM10) * 3))); + *slope = (touch_cnt_slope_t)((RTCCNTL.touch_dac1.val >> (29 - (touch_num - TOUCH_PAD_NUM10) * 3)) & 0x07); } } @@ -222,6 +229,7 @@ static inline void touch_ll_get_tie_option(touch_pad_t touch_num, touch_tie_opt_ * * @param mode FSM mode. */ +__attribute__((always_inline)) static inline void touch_ll_set_fsm_mode(touch_fsm_mode_t mode) { RTCCNTL.touch_ctrl2.touch_start_force = mode; @@ -288,6 +296,7 @@ static inline void touch_ll_start_fsm(void) * Stop touch sensor FSM timer. * The measurement action can be triggered by the hardware timer, as well as by the software instruction. */ +__attribute__((always_inline)) static inline void touch_ll_stop_fsm(void) { RTCCNTL.touch_ctrl2.touch_start_en = 0; //stop touch fsm @@ -424,7 +433,8 @@ static inline uint32_t IRAM_ATTR touch_ll_read_raw_data(touch_pad_t touch_num) * @return * - If touch sensors measure done. */ -static inline bool touch_ll_meas_is_done(void) +__attribute__((always_inline)) +static inline bool touch_ll_is_measure_done(void) { return (bool)SENS.sar_touch_chn_st.touch_meas_done; } @@ -572,25 +582,26 @@ static inline void touch_ll_intr_clear(touch_pad_intr_mask_t int_mask) */ static inline uint32_t touch_ll_read_intr_status_mask(void) { - uint32_t intr_st = RTCCNTL.int_st.val; + typeof(RTCCNTL.int_st) intr_st; + intr_st.val = RTCCNTL.int_st.val; uint32_t intr_msk = 0; - if (intr_st & RTC_CNTL_TOUCH_DONE_INT_ST_M) { + if (intr_st.rtc_touch_done) { intr_msk |= TOUCH_PAD_INTR_MASK_DONE; } - if (intr_st & RTC_CNTL_TOUCH_ACTIVE_INT_ST_M) { + if (intr_st.rtc_touch_active) { intr_msk |= TOUCH_PAD_INTR_MASK_ACTIVE; } - if (intr_st & RTC_CNTL_TOUCH_INACTIVE_INT_ST_M) { + if (intr_st.rtc_touch_inactive) { intr_msk |= TOUCH_PAD_INTR_MASK_INACTIVE; } - if (intr_st & RTC_CNTL_TOUCH_SCAN_DONE_INT_ST_M) { + if (intr_st.rtc_touch_scan_done) { intr_msk |= TOUCH_PAD_INTR_MASK_SCAN_DONE; } - if (intr_st & RTC_CNTL_TOUCH_TIMEOUT_INT_ST_M) { + if (intr_st.rtc_touch_timeout) { intr_msk |= TOUCH_PAD_INTR_MASK_TIMEOUT; } - if (intr_st & RTC_CNTL_TOUCH_APPROACH_LOOP_DONE_INT_ST_M) { + if (intr_st.rtc_touch_approach_loop_done) { intr_msk |= TOUCH_PAD_INTR_MASK_PROXI_MEAS_DONE; } return (intr_msk & TOUCH_PAD_INTR_MASK_ALL); @@ -929,7 +940,7 @@ static inline void touch_ll_waterproof_get_guard_pad(touch_pad_t *pad_num) } /** - * Set max equivalent capacitance for sheild channel. + * Set max equivalent capacitance for shield channel. * The equivalent capacitance of the shielded channel can be calculated * from the reading of denoise channel. * @@ -941,7 +952,7 @@ static inline void touch_ll_waterproof_set_sheild_driver(touch_pad_shield_driver } /** - * Get max equivalent capacitance for sheild channel. + * Get max equivalent capacitance for shield channel. * The equivalent capacitance of the shielded channel can be calculated * from the reading of denoise channel. * @@ -1104,7 +1115,7 @@ static inline void touch_ll_sleep_get_threshold(uint32_t *touch_thres) /** * Enable proximity function for sleep pad. */ -static inline void touch_ll_sleep_enable_approach(void) +static inline void touch_ll_sleep_enable_proximity_sensing(void) { RTCCNTL.touch_slp_thres.touch_slp_approach_en = 1; } @@ -1112,7 +1123,7 @@ static inline void touch_ll_sleep_enable_approach(void) /** * Disable proximity function for sleep pad. */ -static inline void touch_ll_sleep_disable_approach(void) +static inline void touch_ll_sleep_disable_proximity_sensing(void) { RTCCNTL.touch_slp_thres.touch_slp_approach_en = 0; } @@ -1120,7 +1131,7 @@ static inline void touch_ll_sleep_disable_approach(void) /** * Get proximity function status for sleep pad. */ -static inline bool touch_ll_sleep_get_approach_status(void) +static inline bool touch_ll_sleep_is_proximity_enabled(void) { return (bool)RTCCNTL.touch_slp_thres.touch_slp_approach_en; } @@ -1177,11 +1188,11 @@ static inline void touch_ll_sleep_read_debounce(uint32_t *debounce) /** * Read proximity count of touch sensor for sleep pad. - * @param proximity_cnt Pointer to accept touch sensor proximity count value. + * @param prox_cnt Pointer to accept touch sensor proximity count value. */ -static inline void touch_ll_sleep_read_proximity_cnt(uint32_t *approach_cnt) +static inline void touch_ll_sleep_read_proximity_cnt(uint32_t *prox_cnt) { - *approach_cnt = SENS.sar_touch_appr_status.touch_slp_approach_cnt; + *prox_cnt = SENS.sar_touch_appr_status.touch_slp_approach_cnt; } /** diff --git a/components/hal/esp32s3/include/hal/uart_ll.h b/components/hal/esp32s3/include/hal/uart_ll.h index 1924c2411119..3dd538ec5057 100644 --- a/components/hal/esp32s3/include/hal/uart_ll.h +++ b/components/hal/esp32s3/include/hal/uart_ll.h @@ -326,7 +326,7 @@ FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_ * * @param hw Beginning address of the peripheral registers. * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return None */ @@ -505,7 +505,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num } /** - * @brief Configure the transmiter to send break chars. + * @brief Configure the transmitter to send break chars. * * @param hw Beginning address of the peripheral registers. * @param break_num The number of the break chars need to be send. @@ -569,7 +569,7 @@ FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont * @brief Configure the software flow control. * * @param hw Beginning address of the peripheral registers. - * @param flow_ctrl The UART sofware flow control settings. + * @param flow_ctrl The UART software flow control settings. * @param sw_flow_ctrl_en Set true to enable software flow control, otherwise set it false. * * @return None. @@ -860,7 +860,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * @brief Configure TX signal loop back to RX module, just for the testing purposes * * @param hw Beginning address of the peripheral registers. - * @param loop_back_en Set ture to enable the loop back function, else set it false. + * @param loop_back_en Set true to enable the loop back function, else set it false. * * @return None */ diff --git a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h index a3b8c90733a1..8a1addeb11ed 100644 --- a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h @@ -18,6 +18,7 @@ #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask #define USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY +#define USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL (1) // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging diff --git a/components/hal/esp32s3/touch_sensor_hal.c b/components/hal/esp32s3/touch_sensor_hal.c index 9b92bd2bc36e..83dcc05cd560 100644 --- a/components/hal/esp32s3/touch_sensor_hal.c +++ b/components/hal/esp32s3/touch_sensor_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -53,7 +53,7 @@ void touch_hal_deinit(void) touch_pad_t prox_pad[SOC_TOUCH_PROXIMITY_CHANNEL_NUM] = {[0 ... (SOC_TOUCH_PROXIMITY_CHANNEL_NUM - 1)] = 0}; touch_ll_proximity_set_channel_num((const touch_pad_t *)prox_pad); touch_ll_sleep_set_channel_num(0); - touch_ll_sleep_disable_approach(); + touch_ll_sleep_disable_proximity_sensing(); touch_ll_reset(); // Reset the touch sensor FSM. } @@ -152,7 +152,7 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable) void touch_hal_sleep_channel_get_config(touch_pad_sleep_channel_t *slp_config) { touch_ll_sleep_get_channel_num(&slp_config->touch_num); - slp_config->en_proximity = touch_ll_sleep_get_approach_status(); + slp_config->en_proximity = touch_ll_sleep_is_proximity_enabled(); } void touch_hal_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times) diff --git a/components/hal/gdma_hal_ahb_v1.c b/components/hal/gdma_hal_ahb_v1.c index 6964b9879057..08130d25ce35 100644 --- a/components/hal/gdma_hal_ahb_v1.c +++ b/components/hal/gdma_hal_ahb_v1.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -91,16 +91,16 @@ void gdma_ahb_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channe } } -#if SOC_AHB_GDMA_SUPPORT_PSRAM -void gdma_ahb_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align) +#if GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE +void gdma_ahb_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz) { if (dir == GDMA_CHANNEL_DIRECTION_RX) { - gdma_ll_rx_set_ext_mem_block_size(hal->dev, chan_id, align); + gdma_ll_rx_set_burst_size(hal->dev, chan_id, burst_sz); } else { - gdma_ll_tx_set_ext_mem_block_size(hal->dev, chan_id, align); + gdma_ll_tx_set_burst_size(hal->dev, chan_id, burst_sz); } } -#endif +#endif // GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE void gdma_ahb_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back) { @@ -193,8 +193,8 @@ void gdma_ahb_hal_init(gdma_hal_context_t *hal, const gdma_hal_config_t *config) #if SOC_GDMA_SUPPORT_ETM hal->enable_etm_task = gdma_ahb_hal_enable_etm_task; #endif -#if SOC_AHB_GDMA_SUPPORT_PSRAM - hal->set_ext_mem_align = gdma_ahb_hal_set_ext_mem_align; -#endif // SOC_AHB_GDMA_SUPPORT_PSRAM +#if GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE + hal->set_burst_size = gdma_ahb_hal_set_burst_size; +#endif // GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE hal->priv_data = &gdma_ahb_hal_priv_data; } diff --git a/components/hal/gdma_hal_ahb_v2.c b/components/hal/gdma_hal_ahb_v2.c index 2b4f7a9e90fb..b24b39b9d5ca 100644 --- a/components/hal/gdma_hal_ahb_v2.c +++ b/components/hal/gdma_hal_ahb_v2.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -102,6 +102,17 @@ void gdma_ahb_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channe } } +#if GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE +void gdma_ahb_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz) +{ + if (dir == GDMA_CHANNEL_DIRECTION_RX) { + ahb_dma_ll_rx_set_burst_size(hal->ahb_dma_dev, chan_id, burst_sz); + } else { + ahb_dma_ll_tx_set_burst_size(hal->ahb_dma_dev, chan_id, burst_sz); + } +} +#endif // GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE + void gdma_ahb_hal_enable_intr(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t intr_event_mask, bool en_or_dis) { if (dir == GDMA_CHANNEL_DIRECTION_RX) { @@ -244,4 +255,8 @@ void gdma_ahb_hal_init(gdma_hal_context_t *hal, const gdma_hal_config_t *config) #if SOC_GDMA_SUPPORT_ETM hal->enable_etm_task = gdma_ahb_hal_enable_etm_task; #endif // SOC_GDMA_SUPPORT_ETM +#if GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE + hal->set_burst_size = gdma_ahb_hal_set_burst_size; +#endif // GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE + ahb_dma_ll_set_default_memory_range(hal->ahb_dma_dev); } diff --git a/components/hal/gdma_hal_axi.c b/components/hal/gdma_hal_axi.c index 67e3aeae404d..9596808900bf 100644 --- a/components/hal/gdma_hal_axi.c +++ b/components/hal/gdma_hal_axi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -102,6 +102,15 @@ void gdma_axi_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channe } } +void gdma_axi_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz) +{ + if (dir == GDMA_CHANNEL_DIRECTION_RX) { + axi_dma_ll_rx_set_burst_size(hal->axi_dma_dev, chan_id, burst_sz); + } else { + axi_dma_ll_tx_set_burst_size(hal->axi_dma_dev, chan_id, burst_sz); + } +} + void gdma_axi_hal_enable_intr(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t intr_event_mask, bool en_or_dis) { if (dir == GDMA_CHANNEL_DIRECTION_RX) { @@ -151,6 +160,15 @@ uint32_t gdma_axi_hal_get_eof_desc_addr(gdma_hal_context_t *hal, int chan_id, gd } } +void gdma_axi_hal_enable_access_encrypt_mem(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis) +{ + if (dir == GDMA_CHANNEL_DIRECTION_RX) { + axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(hal->axi_dma_dev, chan_id, en_or_dis); + } else { + axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(hal->axi_dma_dev, chan_id, en_or_dis); + } +} + #if SOC_GDMA_SUPPORT_CRC void gdma_axi_hal_clear_crc(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir) { @@ -236,6 +254,8 @@ void gdma_axi_hal_init(gdma_hal_context_t *hal, const gdma_hal_config_t *config) hal->read_intr_status = gdma_axi_hal_read_intr_status; hal->get_intr_status_reg = gdma_axi_hal_get_intr_status_reg; hal->get_eof_desc_addr = gdma_axi_hal_get_eof_desc_addr; + hal->set_burst_size = gdma_axi_hal_set_burst_size; + hal->enable_access_encrypt_mem = gdma_axi_hal_enable_access_encrypt_mem; #if SOC_GDMA_SUPPORT_CRC hal->clear_crc = gdma_axi_hal_clear_crc; hal->set_crc_poly = gdma_axi_hal_set_crc_poly; @@ -244,4 +264,5 @@ void gdma_axi_hal_init(gdma_hal_context_t *hal, const gdma_hal_config_t *config) #if SOC_GDMA_SUPPORT_ETM hal->enable_etm_task = gdma_axi_hal_enable_etm_task; #endif // SOC_GDMA_SUPPORT_ETM + axi_dma_ll_set_default_memory_range(hal->axi_dma_dev); } diff --git a/components/hal/gdma_hal_top.c b/components/hal/gdma_hal_top.c index e3c882b2a23b..eb0c8fb0dcc3 100644 --- a/components/hal/gdma_hal_top.c +++ b/components/hal/gdma_hal_top.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -53,10 +53,10 @@ void gdma_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channel_di hal->enable_burst(hal, chan_id, dir, en_data_burst, en_desc_burst); } -void gdma_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align) +void gdma_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz) { - if (hal->set_ext_mem_align) { - hal->set_ext_mem_align(hal, chan_id, dir, align); + if (hal->set_burst_size) { + hal->set_burst_size(hal, chan_id, dir, burst_sz); } } @@ -90,6 +90,13 @@ uint32_t gdma_hal_get_eof_desc_addr(gdma_hal_context_t *hal, int chan_id, gdma_c return hal->get_eof_desc_addr(hal, chan_id, dir, is_success); } +void gdma_hal_enable_access_encrypt_mem(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis) +{ + if (hal->enable_access_encrypt_mem) { + hal->enable_access_encrypt_mem(hal, chan_id, dir, en_or_dis); + } +} + #if SOC_GDMA_SUPPORT_CRC void gdma_hal_clear_crc(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir) { diff --git a/components/hal/hal_utils.c b/components/hal/hal_utils.c index 68ea4bb60ad9..9e4aa794ce65 100644 --- a/components/hal/hal_utils.c +++ b/components/hal/hal_utils.c @@ -7,6 +7,14 @@ #include "hal/hal_utils.h" #include "hal/assert.h" +#ifndef BIT +#define BIT(n) (1UL << (n)) +#endif + +#ifndef BIT_MASK +#define BIT_MASK(n) (BIT(n) - 1) +#endif + __attribute__((always_inline)) static inline uint32_t _sub_abs(uint32_t a, uint32_t b) { @@ -131,3 +139,56 @@ uint32_t hal_utils_calc_clk_div_integer(const hal_utils_clk_info_t *clk_info, ui // Return the actual frequency return clk_info->src_freq_hz / div_integ; } + +typedef union { + struct { + uint32_t mantissa: 23; + uint32_t exponent: 8; + uint32_t sign: 1; + }; + uint32_t val; +} hal_utils_ieee754_float_t; + +int hal_utils_float_to_fixed_point_32b(float flt, const hal_utils_fixed_point_t *fp_cfg, uint32_t *fp_out) +{ + int ret = 0; + uint32_t output = 0; + const hal_utils_ieee754_float_t *f = (const hal_utils_ieee754_float_t *)&flt; + if (fp_cfg->int_bit + fp_cfg->frac_bit > 31) { + // Not supported + return -3; + } + + if (f->val == 0) { // Zero case + *fp_out = 0; + return 0; + } + if (f->exponent != 0xFF) { // Normal case + int real_exp = (int)f->exponent - 127; + uint32_t real_mant = f->mantissa | BIT(23); // Add the hidden bit + // Overflow check + if (real_exp >= (int)fp_cfg->int_bit) { + ret = -1; + } + // Determine sign + output |= f->sign << (fp_cfg->int_bit + fp_cfg->frac_bit); + // Determine integer and fraction part + int shift = 23 - fp_cfg->frac_bit - real_exp; + output |= shift >= 0 ? real_mant >> shift : real_mant << -shift; + } else { + if (f->mantissa && f->mantissa < BIT(23) - 1) { // NaN (Not-a-Number) case + return -2; + } else { // Infinity or Largest Number case + output = f->sign ? ~(uint32_t)0 : BIT(31) - 1; + ret = -1; + } + } + + if (ret != 0 && fp_cfg->saturation) { + *fp_out = (f->sign << (fp_cfg->int_bit + fp_cfg->frac_bit)) | + (BIT_MASK(fp_cfg->int_bit + fp_cfg->frac_bit)); + } else { + *fp_out = output; + } + return ret; +} diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index 063e3ab3c429..b37689afe880 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -191,7 +191,7 @@ typedef struct { }; } adc_digi_output_data_t; -#elif CONFIG_IDF_TARGET_ESP32S3 +#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4 /** * @brief ADC digital controller (DMA mode) output data format. * Used to analyze the acquired ADC (DMA) data. diff --git a/components/hal/include/hal/apm_hal.h b/components/hal/include/hal/apm_hal.h index 16d32d534fdf..94898df37c9e 100644 --- a/components/hal/include/hal/apm_hal.h +++ b/components/hal/include/hal/apm_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,93 @@ extern "C" { #if SOC_APM_SUPPORTED #include "hal/apm_ll.h" +#if CONFIG_IDF_TARGET_ESP32P4 + +/** + * @brief DMA configurable region configuration data. + */ +typedef struct { + apm_ll_dma_master_t dma_master; /* DMA master whose access permission to be configured.*/ + uint32_t pms_r_mask; /* Read permission mask. */ + uint32_t pms_w_mask; /* Write permission mask. */ +} apm_hal_dma_region_config_data_t; + +/** + * @brief Configure HP peripherals access permission for the HP CPU0/1. + * + * @param master_id HP CPU0/1 + * @param hp_peri HP peripheral whose access permission to be configured. + * @param enable Permission enable/disable + */ +void apm_hal_hp_peri_access_enable(apm_ll_master_id_t master_id, apm_ll_hp_peri_t hp_peri, + apm_ll_secure_mode_t sec_mode, bool enable); + +/** + * @brief Configure LP peripherals access permission for the LP CPU. + * + * @param lp_peri LP peripheral whose access permission to be configured. + * @param enable Permission enable/disable + */ +void apm_hal_lp_peri_access_enable(apm_ll_lp_peri_t lp_peri, bool enable); + +/** + * @brief Configure peripherals configurable address ranges. + * + * @param regn_num Configurable address range number. + * @param regn_low_addr Configurable address range start address. + * @param regn_high_addr Configurable address range end address. + */ +void apm_hal_peri_region_config(uint32_t regn_num, uint32_t regn_low_addr, + uint32_t regn_high_addr); + +/** + * @brief Configure peripherals configurable address ranges. + * + * @param master_id LP CPU and HP CPU0/1 + * @param sec_mode CPU privilege mode (Machine/User) which corresponds to (TEE/REE). + * @param regn_num Configurable address range number. + * @param regn_pms Configurable address range permission setting(2-bits field). + * Bit 0: Region 0 permission enable/disable. + * Bit 1: Region 1 permission enable/disable. + * @return Configuration performed successfully? + */ +int apm_hal_peri_region_pms(apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode, + uint32_t regn_num, uint32_t regn_pms); + +/** + * @brief Configure APM controller clock gating. + * + * @param apm_ctrl APM controller (LP_PERI/HP_PERI/HP_DMA/LP2HP_PERI/HP2LP_PERI). + * @param enable Permission enable/disable. + * enable: Enable automatic clock gating. + * disable: Keep the clock always on. + * @return Clock gating set successfully? + */ +int apm_hal_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable); + +/** + * @brief Configure DMA configurable address range low address. + * + * @param regn_num Configurable DMA address range number. + * @param regn_low_addr Configurable DMA address range start address. + * @param regn_high_addr Configurable DMA address range end address. + */ +void apm_hal_dma_region_config(uint32_t regn_num, uint32_t regn_low_addr, uint32_t regn_high_addr); + +/** + * @brief Configure DMA configurable address range read permission. + * + * @param pms_data DMA configurable region configuration data. + * @param dma_master DMA master whose access permission to be configured. + * @param regn_mask 32-bits field, each bit for corresponding DMA configurable address range permission. + * 0: Disable read permission. + * 1: Enable read permission. + */ +void apm_hal_dma_region_pms(apm_hal_dma_region_config_data_t *pms_data); + + +#else + /** * @brief Region configuration data. */ @@ -151,13 +238,19 @@ void apm_hal_apm_ctrl_master_sec_mode_config(apm_ctrl_secure_mode_config_t *sec_ void apm_hal_apm_ctrl_reset_event_enable(bool enable); /** - * @brief Returns APM Ctrl access path interrupt source number. + * @brief Fetch the APM Ctrl access path interrupt source number. * * @param apm_path APM controller and access path to be configured + * + * @return + * - valid interrupt source number on success + * - -1: invalid interrupt source */ -esp_err_t apm_hal_apm_ctrl_get_int_src_num(apm_ctrl_path_t *apm_path); +int apm_hal_apm_ctrl_get_int_src_num(apm_ctrl_path_t *apm_path); -#endif +#endif //CONFIG_IDF_TARGET_ESP32P4 + +#endif //SOC_APM_SUPPORTED #ifdef __cplusplus } diff --git a/components/hal/include/hal/cache_hal.h b/components/hal/include/hal/cache_hal.h index 5a4f0b86aa76..28753e6e9c46 100644 --- a/components/hal/include/hal/cache_hal.h +++ b/components/hal/include/hal/cache_hal.h @@ -9,6 +9,7 @@ #include #include +#include "soc/soc_caps.h" #include "hal/cache_types.h" #ifdef __cplusplus diff --git a/components/hal/include/hal/cam_ctlr_types.h b/components/hal/include/hal/cam_ctlr_types.h new file mode 100644 index 000000000000..65ba68c29d6c --- /dev/null +++ b/components/hal/include/hal/cam_ctlr_types.h @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc_caps.h" +#include "hal/color_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Camera Controller Color Type + */ +typedef enum { + CAM_CTLR_COLOR_RAW8 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW8), ///< RAW8 + CAM_CTLR_COLOR_RAW10 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW10), ///< RAW10 + CAM_CTLR_COLOR_RAW12 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW12), ///< RAW12 + CAM_CTLR_COLOR_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), ///< RGB565 + CAM_CTLR_COLOR_RGB666 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB666), ///< RGB666 + CAM_CTLR_COLOR_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), ///< RGB888 + CAM_CTLR_COLOR_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), ///< YUV420 + CAM_CTLR_COLOR_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), ///< YUV422 + CAM_CTLR_COLOR_GRAY4 = COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY4), ///< GRAY4 + CAM_CTLR_COLOR_GRAY8 = COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY8), ///< GRAY8 +} cam_ctlr_color_t; + +/** + * @brief Camera Controller Data Width + */ +typedef enum { + CAM_CTLR_DATA_WIDTH_8 = 8, ///< 8-bit data width + CAM_CTLR_DATA_WIDTH_10 = 10, ///< 10-bit data width + CAM_CTLR_DATA_WIDTH_12 = 12, ////< 12-bit data width + CAM_CTLR_DATA_WIDTH_16 = 16, ///< 16-bit data width +} cam_ctlr_data_width_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/cam_hal.h b/components/hal/include/hal/cam_hal.h new file mode 100644 index 000000000000..2b1c9229b6ca --- /dev/null +++ b/components/hal/include/hal/cam_hal.h @@ -0,0 +1,73 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "hal/cam_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lcd_cam_dev_t cam_dev_t; // CAM SOC layer handle + +/** + * @brief CAM hardware interface object data + */ +typedef struct cam_hal_context { + cam_dev_t *hw; /*!< Beginning address of the CAM peripheral registers. */ +} cam_hal_context_t; + +/** + * @brief CAM HAL driver configuration + */ +typedef struct cam_hal_config { + int port; /*!< CAM port */ + bool byte_swap_en; /*!< CAM enable byte swap */ +} cam_hal_config_t; + +/** + * @brief Initialize CAM hardware + * + * @param hal CAM object data pointer + * @param config CAM configuration + * + * @return None + */ +void cam_hal_init(cam_hal_context_t *hal, const cam_hal_config_t *config); + +/** + * @brief De-initialize CAM hardware + * + * @param hal CAM object data pointer + * + * @return None + */ +void cam_hal_deinit(cam_hal_context_t *hal); + +/** + * @brief Start CAM to receive frame data + * + * @param hal CAM object data pointer + * + * @return None + */ +void cam_hal_start_streaming(cam_hal_context_t *hal); + +/** + * @brief Stop CAM receiving frame data + * + * @param hal CAM object data pointer + * + * @return None + */ +void cam_hal_stop_streaming(cam_hal_context_t *hal); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/cam_types.h b/components/hal/include/hal/cam_types.h new file mode 100644 index 000000000000..32e22f22a69b --- /dev/null +++ b/components/hal/include/hal/cam_types.h @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc_caps.h" +#include "soc/clk_tree_defs.h" +#include "hal/color_types.h" +#include "hal/cam_ctlr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_LCDCAM_CAM_DATA_WIDTH_MAX +#define CAP_DVP_PERIPH_NUM SOC_LCDCAM_CAM_PERIPH_NUM /*!< DVP port number */ +#define CAM_DVP_DATA_SIG_NUM SOC_LCDCAM_CAM_DATA_WIDTH_MAX /*!< DVP data bus width of CAM */ +#else +#define CAP_DVP_PERIPH_NUM 0 /*!< Default value */ +#define CAM_DVP_DATA_SIG_NUM 0 /*!< Default value */ +#endif + +#if SOC_LCDCAM_CAM_SUPPORTED +typedef soc_periph_cam_clk_src_t cam_clock_source_t; /*!< Clock source type of CAM */ +#else +typedef int cam_clock_source_t; /*!< Default type */ +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/color_types.h b/components/hal/include/hal/color_types.h index e129bd09db6d..4f2e82614c78 100644 --- a/components/hal/include/hal/color_types.h +++ b/components/hal/include/hal/color_types.h @@ -150,6 +150,44 @@ typedef enum { COLOR_RGB_ELEMENT_ORDER_BGR, /*!< RGB element order: BGR */ } color_rgb_element_order_t; +/*--------------------------------------------------------------- + Data Structure for Color Pixel Unit +---------------------------------------------------------------*/ + +/** + * @brief Data structure for ARGB8888 pixel unit + */ +typedef union { + struct { + uint32_t b: 8; /*!< B component [0, 255] */ + uint32_t g: 8; /*!< G component [0, 255] */ + uint32_t r: 8; /*!< R component [0, 255] */ + uint32_t a: 8; /*!< A component [0, 255] */ + }; + uint32_t val; /*!< 32-bit ARGB8888 value */ +} color_pixel_argb8888_data_t; + +/** + * @brief Data structure for RGB888 pixel unit + */ +typedef struct { + uint8_t b; /*!< B component [0, 255] */ + uint8_t g; /*!< G component [0, 255] */ + uint8_t r; /*!< R component [0, 255] */ +} color_pixel_rgb888_data_t; + +/** + * @brief Data structure for RGB565 pixel unit + */ +typedef union { + struct { + uint16_t b: 5; /*!< B component [0, 31] */ + uint16_t g: 6; /*!< G component [0, 63] */ + uint16_t r: 5; /*!< R component [0, 31] */ + }; + uint16_t val; /*!< 16-bit RGB565 value */ +} color_pixel_rgb565_data_t; + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/dma2d_types.h b/components/hal/include/hal/dma2d_types.h index 835fcf139ca0..b66c791deb4a 100644 --- a/components/hal/include/hal/dma2d_types.h +++ b/components/hal/include/hal/dma2d_types.h @@ -31,7 +31,7 @@ struct dma2d_descriptor_align8_s { uint32_t dma2d_en : 1; /*!< Whether to enable 2D functionality */ uint32_t suc_eof : 1; /*!< Whether the descriptor is the last one in the link */ uint32_t owner : 1; /*!< Who is allowed to access the buffer that this descriptor points to, select DMA2D_DESCRIPTOR_BUFFER_OWNER_CPU or DMA2D_DESCRIPTOR_BUFFER_OWNER_DMA - When owner is chosen to be DMA, after DMA finishs with the descriptor, it will clear this bit + When owner is chosen to be DMA, after DMA finishes with the descriptor, it will clear this bit For data transfer, the bit won't be cleared unless DMA2D_OUT_AUTO_WRBACK is enabled */ }; /*!< Descriptor Word 0 */ struct { @@ -104,7 +104,7 @@ typedef enum { DMA2D_TRIG_PERIPH_M2M, /*!< 2D-DMA trigger peripheral: M2M */ DMA2D_TRIG_PERIPH_JPEG_ENCODER, /*!< 2D-DMA trigger peripheral: JPEG Encoder */ DMA2D_TRIG_PERIPH_JPEG_DECODER, /*!< 2D-DMA trigger peripheral: JPEG Decoder */ - DMA2D_TRIG_PERIPH_PPA_SR, /*!< 2D-DMA trigger peripheral: PPA SR engine */ + DMA2D_TRIG_PERIPH_PPA_SRM, /*!< 2D-DMA trigger peripheral: PPA SRM engine */ DMA2D_TRIG_PERIPH_PPA_BLEND, /*!< 2D-DMA trigger peripheral: PPA Blending engine */ } dma2d_trigger_peripheral_t; @@ -118,9 +118,11 @@ typedef enum { /** * @brief Enumeration of 2D-DMA data burst length options + * + * Starting from 1, saving 0 for special purpose (upper layer could use 0 to be a default burst length) */ typedef enum { - DMA2D_DATA_BURST_LENGTH_8, /*!< 2D-DMA block size: 8 bytes */ + DMA2D_DATA_BURST_LENGTH_8 = 1, /*!< 2D-DMA block size: 8 bytes */ DMA2D_DATA_BURST_LENGTH_16, /*!< 2D-DMA block size: 16 bytes */ DMA2D_DATA_BURST_LENGTH_32, /*!< 2D-DMA block size: 32 bytes */ DMA2D_DATA_BURST_LENGTH_64, /*!< 2D-DMA block size: 64 bytes */ @@ -174,6 +176,10 @@ typedef enum { // B = 1.164 *(Y - 16) + 2.114 *(Cb - 128) // //*********************BT709***********************************// +// R/G/B [0 ... 255] +// Y [16 ... 235] +// Cb/Cr [16 ... 240] + // 256 * Q = A[9:0] * x + B[10:0] * y + C[9:0] * z + D[17:0] #define DMA2D_COLOR_SPACE_CONV_PARAM_RGB2YUV_BT601 \ diff --git a/components/hal/include/hal/dma_types.h b/components/hal/include/hal/dma_types.h index 435ac5cd96fa..03146740aa00 100644 --- a/components/hal/include/hal/dma_types.h +++ b/components/hal/include/hal/dma_types.h @@ -58,6 +58,7 @@ ESP_STATIC_ASSERT(sizeof(dma_descriptor_align8_t) == 16, "dma_descriptor_align8_ #define DMA_DESCRIPTOR_BUFFER_MAX_SIZE (4095) /*!< Maximum size of the buffer that can be attached to descriptor */ #define DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED (4095-3) /*!< Maximum size of the buffer that can be attached to descriptor, and aligned to 4B */ #define DMA_DESCRIPTOR_BUFFER_MAX_SIZE_16B_ALIGNED (4095-15) /*!< Maximum size of the buffer that can be attached to descriptor, and aligned to 16B */ +#define DMA_DESCRIPTOR_BUFFER_MAX_SIZE_64B_ALIGNED (4095-63) /*!< Maximum size of the buffer that can be attached to descriptor, and aligned to 64B */ /** * Get the number of DMA descriptors required for a given buffer size. diff --git a/components/hal/include/hal/efuse_hal.h b/components/hal/include/hal/efuse_hal.h index 240c1ab1350c..ce4aaf1eee09 100644 --- a/components/hal/include/hal/efuse_hal.h +++ b/components/hal/include/hal/efuse_hal.h @@ -61,7 +61,7 @@ uint32_t efuse_hal_get_major_chip_version(void); */ uint32_t efuse_hal_get_minor_chip_version(void); -#if SOC_ECDSA_SUPPORTED +#if SOC_EFUSE_ECDSA_KEY /** * @brief Set the efuse block that should be used as ECDSA private key * diff --git a/components/hal/include/hal/emac_hal.h b/components/hal/include/hal/emac_hal.h index 2b0a1273ea68..70b5e86478be 100644 --- a/components/hal/include/hal/emac_hal.h +++ b/components/hal/include/hal/emac_hal.h @@ -6,8 +6,6 @@ #pragma once - - #include #include #include "esp_assert.h" @@ -29,15 +27,28 @@ extern "C" { #if CONFIG_IDF_TARGET_ESP32P4 // Descriptor must be 64B aligned for ESP32P4 due to cache arrangement -#define DMA_DESC_SIZE 64 -// ESP32P4 EMAC interface clock configuration is shared among other modules in registers -#define EMAC_IF_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#define EMAC_HAL_DMA_DESC_SIZE (64) #else -#define DMA_DESC_SIZE 32 -#define EMAC_IF_RCC_ATOMIC() +#define EMAC_HAL_DMA_DESC_SIZE (32) #endif +/* DMA descriptor control bits */ +#define EMAC_HAL_TDES0_INTR_ON_COMPLET (1 << 30) +#define EMAC_HAL_TDES0_CRC_APPEND_DISABLE (1 << 27) +#define EMAC_HAL_TDES0_PAD_DISABLE (1 << 26) +#define EMAC_HAL_TDES0_TX_TS_ENABLE (1 << 25) +#define EMAC_HAL_TDES0_CRC_REPLACE_CTRL (1 << 24) +#define EMAC_HAL_TDES0_IP_CRC_INSERT_HDR (1 << 22) +#define EMAC_HAL_TDES0_IP_CRC_INSERT_HDR_PAYLOAD (2 << 22) +#define EMAC_HAL_TDES0_IP_CRC_INSERT_HDR_PAYLOAD_PSEUDO (3 << 22) +#define EMAC_HAL_TDES0_VLAN_REMOVE (1 << 18) +#define EMAC_HAL_TDES0_VLAN_INSERT (2 << 18) +#define EMAC_HAL_TDES0_VLAN_REPLACE (3 << 18) + +#define EMAC_HAL_TDES0_IP_CRC_INSERT_DISABLE_MASK (3 << 22) +#define EMAC_HAL_TDES0_VLAN_INSERT_DISABLE_MASK (3 << 18) + /** * @brief Ethernet DMA TX Descriptor * @@ -65,7 +76,7 @@ typedef struct { uint32_t TransmitEndRing : 1; /*!< Descriptor list reached its final descriptor */ uint32_t ChecksumInsertControl : 2; /*!< Control checksum calculation and insertion */ uint32_t CRCReplacementControl : 1; /*!< Control CRC replace */ - uint32_t TransmitTimestampEnable : 1; /*!< Enable IEEE1588 harware timestamping */ + uint32_t TransmitTimestampEnable : 1; /*!< Enable IEEE1588 hardware timestamping */ uint32_t DisablePad : 1; /*!< Control add padding when frame short than 64 bytes */ uint32_t DisableCRC : 1; /*!< Control append CRC to the end of frame */ uint32_t FirstSegment : 1; /*!< Buffer contains the first segment of a frame */ @@ -91,25 +102,12 @@ typedef struct { uint32_t TimeStampLow; /*!< Transmit Frame Timestamp Low */ uint32_t TimeStampHigh; /*!< Transmit Frame Timestamp High */ -#if CONFIG_IDF_TARGET_ESP32P4 -// TODO: must be 64B aligned for ESP32P4 (due to cache arrangement) -// Could be better optimized (EMAC DMA block supports 32/64/128)? - uint32_t Reserved8; - uint32_t Reserved9; - uint32_t Reserved10; - uint32_t Reserved11; - uint32_t Reserved12; - uint32_t Reserved13; - uint32_t Reserved14; - uint32_t Reserved15; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + // descriptor must be aligned (due to cache arrangement) + uint8_t CacheAlign[EMAC_HAL_DMA_DESC_SIZE - 32]; // 32 is size of EMAC DMA descriptor without alignment #endif } eth_dma_tx_descriptor_t; -#define EMAC_DMATXDESC_CHECKSUM_BYPASS 0 /*!< Checksum engine bypass */ -#define EMAC_DMATXDESC_CHECKSUM_IPV4HEADER 1 /*!< IPv4 header checksum insertion */ -#define EMAC_DMATXDESC_CHECKSUM_TCPUDPICMPSEGMENT 2 /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */ -#define EMAC_DMATXDESC_CHECKSUM_TCPUDPICMPFULL 3 /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */ - -ASSERT_TYPE_SIZE(eth_dma_tx_descriptor_t, DMA_DESC_SIZE); +ASSERT_TYPE_SIZE(eth_dma_tx_descriptor_t, EMAC_HAL_DMA_DESC_SIZE); /** * @brief Ethernet DMA RX Descriptor @@ -182,21 +180,13 @@ typedef struct { uint32_t TimeStampLow; /*!< Receive frame timestamp low */ uint32_t TimeStampHigh; /*!< Receive frame timestamp high */ -#if CONFIG_IDF_TARGET_ESP32P4 -// TODO: must be 64B aligned for ESP32P4 (due to cache arrangement) -// Could be better optimized (EMAC DMA block supports 32/64/128)? - uint32_t Reserved8; - uint32_t Reserved9; - uint32_t Reserved10; - uint32_t Reserved11; - uint32_t Reserved12; - uint32_t Reserved13; - uint32_t Reserved14; - uint32_t Reserved15; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + // descriptor must be aligned (due to cache arrangement) + uint8_t CacheAlign[EMAC_HAL_DMA_DESC_SIZE - 32]; // 32 is size of EMAC DMA descriptor without alignment #endif } eth_dma_rx_descriptor_t; -ASSERT_TYPE_SIZE(eth_dma_rx_descriptor_t, DMA_DESC_SIZE); +ASSERT_TYPE_SIZE(eth_dma_rx_descriptor_t, EMAC_HAL_DMA_DESC_SIZE); typedef struct emac_mac_dev_s *emac_mac_soc_regs_t; typedef struct emac_dma_dev_s *emac_dma_soc_regs_t; @@ -278,72 +268,10 @@ void emac_hal_start(emac_hal_context_t *hal); * @return * - ESP_OK: succeed * - ESP_ERR_INVALID_STATE: previous frame transmission/reception is not completed. When this error occurs, - * wait and reapeat the EMAC stop again. + * wait and repeat the EMAC stop again. */ esp_err_t emac_hal_stop(emac_hal_context_t *hal); -/** - * @brief Transmit data from buffer over EMAC - * - * @param[in] hal EMAC HAL context infostructure - * @param[in] buf buffer to be transmitted - * @param[in] length length of the buffer - * @return number of transmitted bytes when success - */ -uint32_t emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t length); - -/** - * @brief Transmit data from multiple buffers over EMAC in single Ethernet frame. Data will be joint into - * single frame in order in which the buffers are stored in input array. - * - * @param[in] hal EMAC HAL context infostructure - * @param[in] buffs array of pointers to buffers to be transmitted - * @param[in] lengths array of lengths of the buffers - * @param[in] inbuffs_cnt number of buffers (i.e. input arrays size) - * @return number of transmitted bytes when success - * - * @pre @p lengths array must have the same size as @p buffs array and their elements need to be stored in the same - * order, i.e. lengths[1] is a length assocaited with data buffer referenced at buffs[1] position. - */ -uint32_t emac_hal_transmit_multiple_buf_frame(emac_hal_context_t *hal, uint8_t **buffs, uint32_t *lengths, uint32_t inbuffs_cnt); - -/** - * @brief Allocate buffer with size equal to actually received Ethernet frame size. - * - * @param[in] hal EMAC HAL context infostructure - * @param[in, out] size as an input defines maximum size of buffer to be allocated. As an output, indicates actual size of received - * Ethernet frame which is waiting to be processed. Returned size may be 0 when there is no waiting frame. - * - * @note If maximum allowed size of buffer to be allocated is less than actual size of received Ethernet frame, the buffer - * is allocated with that limit and the frame will be truncated by emac_hal_receive_frame. - * - * @return Pointer to allocated buffer - * NULL when allocation fails or when there is no waiting Ethernet frame - */ -uint8_t *emac_hal_alloc_recv_buf(emac_hal_context_t *hal, uint32_t *size); - -/** - * @brief Copy received Ethernet frame from EMAC DMA memory space to application. - * - * @param[in] hal EMAC HAL context infostructure - * @param[in] buf buffer into which the Ethernet frame is to be copied - * @param[in] size buffer size. When buffer was allocated by ::emac_hal_alloc_recv_buf, this parameter needs to be set - * to EMAC_HAL_BUF_SIZE_AUTO - * @param[out] frames_remain number of frames remaining to be processed - * @param[out] free_desc muber of free DMA Rx descriptors - * - * @return number of copied bytes when success - * 0 when there is no waiting Ethernet frame or on error - * - * @note FCS field is never copied - * @note If buffer size is less than actual size of received Ethernet frame, the frame will be truncated. - * @note When this function is called with EMAC_HAL_BUF_SIZE_AUTO size parameter, buffer needs to be allocated by - * ::emac_hal_alloc_recv_buf function at first. - */ -uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t size, uint32_t *frames_remain, uint32_t *free_desc); - -uint32_t emac_hal_flush_recv_frame(emac_hal_context_t *hal, uint32_t *frames_remain, uint32_t *free_desc); - void emac_hal_enable_flow_ctrl(emac_hal_context_t *hal, bool enable); #define emac_hal_get_intr_enable_status(hal) emac_ll_get_intr_enable_status((hal)->dma_regs) diff --git a/components/hal/include/hal/gdma_hal.h b/components/hal/include/hal/gdma_hal.h index 1eca5ebf3c6b..228d9af83e9b 100644 --- a/components/hal/include/hal/gdma_hal.h +++ b/components/hal/include/hal/gdma_hal.h @@ -80,13 +80,14 @@ struct gdma_hal_context_t { void (*connect_peri)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, gdma_trigger_peripheral_t periph, int periph_sub_id); /// Connect the channel to a peripheral void (*disconnect_peri)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir); /// Disconnect the channel from a peripheral void (*enable_burst)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_data_burst, bool en_desc_burst); /// Enable burst mode - void (*set_ext_mem_align)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align); /// Set the alignment of the external memory void (*set_strategy)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back); /// Set some misc strategy of the channel behaviour + void (*set_burst_size)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz); /// Set burst transfer size uint32_t (*get_intr_status_reg)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir); // Get the interrupt status register address void (*enable_intr)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t intr_event_mask, bool en_or_dis); /// Enable the channel interrupt void (*clear_intr)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t intr_event_mask); /// Clear the channel interrupt uint32_t (*read_intr_status)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool raw); /// Read the channel interrupt status uint32_t (*get_eof_desc_addr)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool is_success); /// Get the address of the descriptor with success/error EOF flag set + void (*enable_access_encrypt_mem)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis); /// Enable the access to the encrypted memory #if SOC_GDMA_SUPPORT_CRC void (*clear_crc)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir); /// Clear the CRC interim results void (*set_crc_poly)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, const gdma_hal_crc_config_t *config); /// Set the CRC polynomial @@ -115,7 +116,7 @@ void gdma_hal_disconnect_peri(gdma_hal_context_t *hal, int chan_id, gdma_channel void gdma_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_data_burst, bool en_desc_burst); -void gdma_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align); +void gdma_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz); void gdma_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back); @@ -129,6 +130,8 @@ uint32_t gdma_hal_read_intr_status(gdma_hal_context_t *hal, int chan_id, gdma_ch uint32_t gdma_hal_get_eof_desc_addr(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool is_success); +void gdma_hal_enable_access_encrypt_mem(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis); + #if SOC_GDMA_SUPPORT_CRC void gdma_hal_build_parallel_crc_matrix(int crc_width, uint32_t crc_poly_hex, int data_width, uint32_t *lfsr_transform_matrix, uint32_t *data_transform_matrix); diff --git a/components/hal/include/hal/gdma_hal_ahb.h b/components/hal/include/hal/gdma_hal_ahb.h index e2de69b9e992..03782e251ee1 100644 --- a/components/hal/include/hal/gdma_hal_ahb.h +++ b/components/hal/include/hal/gdma_hal_ahb.h @@ -28,7 +28,7 @@ void gdma_ahb_hal_disconnect_peri(gdma_hal_context_t *hal, int chan_id, gdma_cha void gdma_ahb_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_data_burst, bool en_desc_burst); -void gdma_ahb_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align); +void gdma_ahb_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz); void gdma_ahb_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back); diff --git a/components/hal/include/hal/gdma_hal_axi.h b/components/hal/include/hal/gdma_hal_axi.h index e9cb68b708c2..e7705217f3fb 100644 --- a/components/hal/include/hal/gdma_hal_axi.h +++ b/components/hal/include/hal/gdma_hal_axi.h @@ -28,7 +28,7 @@ void gdma_axi_hal_disconnect_peri(gdma_hal_context_t *hal, int chan_id, gdma_cha void gdma_axi_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_data_burst, bool en_desc_burst); -void gdma_axi_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align); +void gdma_axi_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz); void gdma_axi_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back); diff --git a/components/hal/include/hal/hal_utils.h b/components/hal/include/hal/hal_utils.h index b95931c252bc..f5860da57377 100644 --- a/components/hal/include/hal/hal_utils.h +++ b/components/hal/include/hal/hal_utils.h @@ -7,6 +7,7 @@ #pragma once #include +#include #ifdef __cplusplus extern "C" { @@ -148,6 +149,38 @@ static inline uint32_t hal_utils_calc_lcm(uint32_t a, uint32_t b) return (a * b / hal_utils_gcd(a, b)); } +/** + * @brief Fixed-point data configuration + * + */ +typedef struct { + uint32_t int_bit; /*!< Integer bit of the fixed point */ + uint32_t frac_bit; /*!< Fractional bit of the fixed point */ + bool saturation; /*!< Whether to limit the value to the maximum when fixed-point data overflow. + * When set true, the value will be limited to the maximum when the float type data is out of range. + * When set false, the function will return false when the float type data is out of range. + */ +} hal_utils_fixed_point_t; + +/** + * @brief Convert the float type to fixed point type + * @note The supported data format: + * - [input] float (IEEE 754): + * sign(1bit) + exponent(8bit) + mantissa(23bit) (32 bit in total) + * - [output] fixed-point: + * sign(1bit) + integer(int_bit) + fraction(frac_bit) (less or equal to 32 bit) + * + * @param[in] flt IEEE 754 float type data + * @param[in] fp_cfg Fixed-point data configuration + * @param[out] fp_out The output fixed-point data + * @return + * 0: Success + * -1: Fixed point data overflow, `fp_out` will still be assigned + * -2: Float is NaN + * -3: Invalid configuration + */ +int hal_utils_float_to_fixed_point_32b(float flt, const hal_utils_fixed_point_t *fp_cfg, uint32_t *fp_out); + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/isp_hal.h b/components/hal/include/hal/isp_hal.h index 80ea6db9de58..d8566a9ec497 100644 --- a/components/hal/include/hal/isp_hal.h +++ b/components/hal/include/hal/isp_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,18 +13,34 @@ #pragma once #include +#include #include "hal/isp_types.h" +#include "hal/hal_utils.h" #ifdef __cplusplus extern "C" { #endif +/** + * @brief BF configurations + */ +typedef struct { + isp_bf_edge_padding_mode_t padding_mode; ///< BF edge padding mode + uint8_t padding_data; ///< BF edge padding pixel data + uint8_t bf_template[ISP_BF_TEMPLATE_X_NUMS][ISP_BF_TEMPLATE_Y_NUMS]; ///< BF template data + uint8_t denoising_level; ///< BF denoising level, from 2 to 20, the bigger the better denoising performance, but the worse detailed + uint8_t padding_line_tail_valid_start_pixel; ///< BF edge padding line tail valid start pixel + uint8_t padding_line_tail_valid_end_pixel; ///< BF edge padding line tail valid end pixel +} isp_hal_bf_cfg_t; /** - * Context that should be maintained by both the driver and the HAL + * @brief Context that should be maintained by both the driver and the HAL */ typedef struct { void *hw; ///< Beginning address of the ISP registers + + /* BF */ + isp_hal_bf_cfg_t bf_cfg; ///< BF configurations } isp_hal_context_t; /** @@ -46,17 +62,9 @@ void isp_hal_init(isp_hal_context_t *hal, int isp_id); * * @param[in] hal Context of the HAL layer * @param[in] window_id Window ID - * @param[in] window Window info, see `isp_af_window_t` + * @param[in] window Window info, see `isp_window_t` */ -void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_af_window_t *window); - -/** - * @brief Get AF oneshot result - * - * @param[in] hal Context of the HAL layer - * @param[out] out_res AF result - */ -void isp_hal_af_get_oneshot_result(const isp_hal_context_t *hal, isp_af_result_t *out_res); +void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_window_t *window); /*--------------------------------------------------------------- INTR @@ -69,6 +77,79 @@ void isp_hal_af_get_oneshot_result(const isp_hal_context_t *hal, isp_af_result_t */ uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask); +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +/** + * @brief Configure ISP BF registers + * + * @param[in] hal Context of the HAL layer + * @param[in] config BF config, set NULL to de-config the ISP BF + */ +void isp_hal_bf_config(isp_hal_context_t *hal, isp_hal_bf_cfg_t *config); + +/*--------------------------------------------------------------- + Color Correction Matrix +---------------------------------------------------------------*/ +/** + * @brief Set Color Correction Matrix + * + * @param[in] hal Context of the HAL layer + * @param[in] saturation Whether to enable saturation when float data overflow + * @param[in] flt_matrix 3x3 RGB correction matrix + * @return + * - true Set success + * - false Invalid argument + */ +bool isp_hal_ccm_set_matrix(const isp_hal_context_t *hal, bool saturation, const float flt_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION]); + +/*--------------------------------------------------------------- + AWB +---------------------------------------------------------------*/ +/** + * @brief Set the window of the AWB + * + * @param[in] hal Context of the HAL layer + * @param[in] win Pointer to the window of the AWB + * @return + * - true Set success + * - false Invalid arg + */ +bool isp_hal_awb_set_window_range(const isp_hal_context_t *hal, const isp_window_t *win); + +/** + * @brief Set the luminance range of the white patch + * + * @param[in] hal Context of the HAL layer + * @param[in] lum_min Minimum luminance + * @param[in] lum_max Maximum luminance + * @return + * - true Set success + * - false Invalid arg + */ +bool isp_hal_awb_set_luminance_range(const isp_hal_context_t *hal, uint32_t lum_min, uint32_t lum_max); + +/** + * @brief Set the R/G ratio of the white patch + * + * @param[in] hal Context of the HAL layer + * @param[in] rg_ratio_range Range of Red to Green ratio + * @return + * - true Set success + * - false Invalid arg + */ +bool isp_hal_awb_set_rg_ratio_range(const isp_hal_context_t *hal, float rg_min, float rg_max); + +/** + * @brief Set the B/R ratio of the white patch + * + * @param[in] hal Context of the HAL layer + * @param[in] bg_ratio_range Range of Blue to Green ratio + * @return + * - true Set success + * - false Invalid arg + */ +bool isp_hal_awb_set_bg_ratio_range(const isp_hal_context_t *hal, float bg_min, float bg_max); #ifdef __cplusplus } diff --git a/components/hal/include/hal/isp_types.h b/components/hal/include/hal/isp_types.h index cbbb2fd00c77..d36b8a09fc48 100644 --- a/components/hal/include/hal/isp_types.h +++ b/components/hal/include/hal/isp_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,6 +23,24 @@ typedef soc_periph_isp_clk_src_t isp_clk_src_t; ///< Clock source type of typedef int isp_clk_src_t; ///< Default type #endif +/** + * @brief ISP coordinate type + * + */ +typedef struct { + uint32_t x; ///< X coordinate of the point + uint32_t y; ///< Y coordinate of the point +} isp_coordinate_t; + +/** + * @brief ISP window type + * + */ +typedef struct { + isp_coordinate_t top_left; ///< The top left point coordinate + isp_coordinate_t btm_right; ///< The bottom right point coordinate +} isp_window_t; + /** * @brief ISP Input Source */ @@ -45,28 +63,65 @@ typedef enum { ISP_COLOR_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), ///< YUV420 } isp_color_t; +/*--------------------------------------------------------------- + DVP +---------------------------------------------------------------*/ +#if SOC_ISP_DVP_DATA_WIDTH_MAX +#define ISP_DVP_DATA_SIG_NUM SOC_ISP_DVP_DATA_WIDTH_MAX // The ISP DVP data signal number +#else +#define ISP_DVP_DATA_SIG_NUM 0 +#endif + /*--------------------------------------------------------------- AF ---------------------------------------------------------------*/ +#if SOC_ISP_AF_WINDOW_NUMS +#define ISP_AF_WINDOW_NUM SOC_ISP_AF_WINDOW_NUMS // The AF window number for sampling +#else +#define ISP_AF_WINDOW_NUM 0 +#endif + +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +#if SOC_ISP_BF_SUPPORTED +#define ISP_BF_TEMPLATE_X_NUMS SOC_ISP_BF_TEMPLATE_X_NUMS // BF template x field nums +#define ISP_BF_TEMPLATE_Y_NUMS SOC_ISP_BF_TEMPLATE_Y_NUMS // BF template y field nums +#else +#define ISP_BF_TEMPLATE_X_NUMS 0 +#define ISP_BF_TEMPLATE_Y_NUMS 0 +#endif + /** - * @brief ISP AF window + * @brief ISP BF edge padding mode */ -typedef struct { - uint32_t top_left_x; ///< Top left x axis value - uint32_t top_left_y; ///< Top left y axis value - uint32_t bottom_right_x; ///< Bottom right x axis value - uint32_t bottom_right_y; ///< Bottom right y axis value -} isp_af_window_t; +typedef enum { + ISP_BF_EDGE_PADDING_MODE_SRND_DATA, ///< Fill BF edge padding data with surrounding pixel data + ISP_BF_EDGE_PADDING_MODE_CUSTOM_DATA, ///< Fill BF edge padding data with custom pixel data +} isp_bf_edge_padding_mode_t; + +/*--------------------------------------------------------------- + CCM +---------------------------------------------------------------*/ +#if SOC_ISP_CCM_SUPPORTED +#define ISP_CCM_DIMENSION SOC_ISP_CCM_DIMENSION ///< ISP Color Correction Matrix dimension +#else +#define ISP_CCM_DIMENSION 0 ///< Not support CCM +#endif + +/*--------------------------------------------------------------- + AWB +---------------------------------------------------------------*/ /** - * @brief ISP AF result + * @brief ISP AWB sample point in the ISP pipeline + * */ -typedef struct { -#if SOC_ISP_SUPPORTED - int definition[SOC_ISP_AF_WINDOW_NUMS]; ///< Definition, it refers how clear and sharp an image is - int luminance[SOC_ISP_AF_WINDOW_NUMS]; ///< Luminance, it refers how luminant an image is -#endif -} isp_af_result_t; +typedef enum { + ISP_AWB_SAMPLE_POINT_BEFORE_CCM, ///< Sample AWB data before CCM (Color Correction Matrix) + ISP_AWB_SAMPLE_POINT_AFTER_CCM, ///< Sample AWB data after CCM (Color Correction Matrix) +} isp_awb_sample_point_t; + #ifdef __cplusplus } diff --git a/components/hal/include/hal/key_mgr_types.h b/components/hal/include/hal/key_mgr_types.h index 82064e58d4a0..31ea39aeb4dc 100644 --- a/components/hal/include/hal/key_mgr_types.h +++ b/components/hal/include/hal/key_mgr_types.h @@ -5,9 +5,6 @@ */ #pragma once -#include "soc/soc_caps.h" - -#if SOC_KEY_MANAGER_SUPPORTED #include #include #include @@ -24,7 +21,7 @@ extern "C" { */ typedef enum { ESP_KEY_MGR_STATE_IDLE = 0, /* Key Manager is idle */ - ESP_KEY_MGR_STATE_LOAD = 1, /* Key Manager is ready to recieve input */ + ESP_KEY_MGR_STATE_LOAD = 1, /* Key Manager is ready to receive input */ ESP_KEY_MGR_STATE_GAIN = 2, /* Key Manager is ready to provide output */ ESP_KEY_MGR_STATE_BUSY = 3, /* Key Manager is busy */ } esp_key_mgr_state_t; @@ -114,5 +111,3 @@ typedef struct WORD_ALIGNED_ATTR PACKED_ATTR { #ifdef __cplusplus } #endif - -#endif diff --git a/components/hal/include/hal/lp_core_types.h b/components/hal/include/hal/lp_core_types.h new file mode 100644 index 000000000000..046840a7e14c --- /dev/null +++ b/components/hal/include/hal/lp_core_types.h @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_LP_CORE_SUPPORTED + +#if SOC_LP_CORE_SUPPORT_ETM +/** + * @brief LP-Core event types enum + */ +typedef enum { + LP_CORE_EVENT_ERR_INTR, /*!< Exception triggered on LP-Core */ + LP_CORE_EVENT_START_INTR, /*!< LP-Core clock has been turned on */ + LP_CORE_EVENT_MAX, /*!< Maximum number of LP-Core events */ +} lp_core_etm_event_type_t; + +/** + * @brief LP-Core task types enum + */ +typedef enum { + LP_CORE_TASK_WAKEUP_CPU, /*!< LP-Core wake-up task */ + LP_CORE_TASK_MAX, /*!< Maximum number of LP-Core tasks */ +} lp_core_etm_task_type_t; + +#endif //SOC_LP_CORE_SUPPORT_ETM + +#endif //SOC_LP_CORE_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/mipi_csi_types.h b/components/hal/include/hal/mipi_csi_types.h index 5614a43b21a9..9458bc6ddb74 100644 --- a/components/hal/include/hal/mipi_csi_types.h +++ b/components/hal/include/hal/mipi_csi_types.h @@ -10,6 +10,7 @@ #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" #include "hal/color_types.h" +#include "hal/cam_ctlr_types.h" #ifdef __cplusplus extern "C" { @@ -24,20 +25,6 @@ typedef soc_periph_mipi_csi_phy_clk_src_t mipi_csi_phy_clock_source_t; typedef int mipi_csi_phy_clock_source_t; #endif // SOC_MIPI_CSI_SUPPORTED -/** - * @brief MIPI CSI Color Type - */ -typedef enum { - MIPI_CSI_COLOR_RAW8 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW8), ///< RAW8 - MIPI_CSI_COLOR_RAW10 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW10), ///< RAW10 - MIPI_CSI_COLOR_RAW12 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW12), ///< RAW12 - MIPI_CSI_COLOR_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), ///< RGB565 - MIPI_CSI_COLOR_RGB666 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB666), ///< RGB666 - MIPI_CSI_COLOR_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), ///< RGB888 - MIPI_CSI_COLOR_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), ///< YUV420 - MIPI_CSI_COLOR_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), ///< YUV422 -} mipi_csi_color_t; - #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/ppa_hal.h b/components/hal/include/hal/ppa_hal.h new file mode 100644 index 000000000000..1cbfc3000523 --- /dev/null +++ b/components/hal/include/hal/ppa_hal.h @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The HAL is not public api, don't use in application code. + * See readme.md in soc/README.md + ******************************************************************************/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ppa_dev_t *ppa_soc_handle_t; // PPA SOC layer handle + +/** + * Context that should be maintained by both the driver and the HAL + */ +typedef struct { + ppa_soc_handle_t dev; // PPA SOC layer handle (i.e. register base address) +} ppa_hal_context_t; + +/** + * @brief Init the PPA hal. This function should be called first before other hal layer function is called + * + * @param hal Context of the HAL layer + */ +void ppa_hal_init(ppa_hal_context_t *hal); + +/** + * @brief De-init the PPA hal + * + * @param hal Context of the HAL layer + */ +void ppa_hal_deinit(ppa_hal_context_t *hal); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/ppa_types.h b/components/hal/include/hal/ppa_types.h index 1be3e6c9e80c..67741433c5c0 100644 --- a/components/hal/include/hal/ppa_types.h +++ b/components/hal/include/hal/ppa_types.h @@ -8,6 +8,7 @@ #include #include "hal/color_types.h" +#include "hal/dma2d_types.h" #ifdef __cplusplus extern "C" { @@ -17,43 +18,99 @@ extern "C" { * @brief Enumeration of engines in PPA modules */ typedef enum { - PPA_ENGINE_TYPE_SR, /*!< PPA Scaling and Rotating (SR) engine, used to perform scale_and_rotate */ + PPA_ENGINE_TYPE_SRM, /*!< PPA Scaling-Rotating-Mirroring (SRM) engine, used to perform scale, rotate, mirror */ PPA_ENGINE_TYPE_BLEND, /*!< PPA Blending engine, used to perform blend or fill */ } ppa_engine_type_t; /** - * @brief Enumeration of PPA Scaling and Rotating available rotation angle (in the counterclockwise direction) + * @brief Enumeration of PPA Scaling-Rotating-Mirroring available rotation angle (in the counterclockwise direction) */ typedef enum { - PPA_SR_ROTATION_ANGLE_0, /*!< Picture does no rotation */ - PPA_SR_ROTATION_ANGLE_90, /*!< Picture rotates 90 degrees CCW */ - PPA_SR_ROTATION_ANGLE_180, /*!< Picture rotates 180 degrees CCW */ - PPA_SR_ROTATION_ANGLE_270, /*!< Picture rotates 270 degrees CCW */ -} ppa_sr_rotation_angle_t; + PPA_SRM_ROTATION_ANGLE_0, /*!< Picture does no rotation */ + PPA_SRM_ROTATION_ANGLE_90, /*!< Picture rotates 90 degrees CCW */ + PPA_SRM_ROTATION_ANGLE_180, /*!< Picture rotates 180 degrees CCW */ + PPA_SRM_ROTATION_ANGLE_270, /*!< Picture rotates 270 degrees CCW */ +} ppa_srm_rotation_angle_t; /** - * @brief Enumeration of PPA Scaling and Rotating available color mode + * @brief Enumeration of PPA Scaling-Rotating-Mirroring available color mode */ typedef enum { - PPA_SR_COLOR_MODE_ARGB8888 = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888), /*!< PPA SR color mode: ARGB8888 */ - PPA_SR_COLOR_MODE_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), /*!< PPA SR color mode: RGB888 */ - PPA_SR_COLOR_MODE_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), /*!< PPA SR color mode: RGB565 */ - PPA_SR_COLOR_MODE_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), /*!< PPA SR color mode: YUV420 */ -} ppa_sr_color_mode_t; + PPA_SRM_COLOR_MODE_ARGB8888 = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888), /*!< PPA SRM color mode: ARGB8888 */ + PPA_SRM_COLOR_MODE_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), /*!< PPA SRM color mode: RGB888 */ + PPA_SRM_COLOR_MODE_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), /*!< PPA SRM color mode: RGB565 */ + PPA_SRM_COLOR_MODE_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), /*!< PPA SRM color mode: YUV420 */ + PPA_SRM_COLOR_MODE_YUV444 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV444), /*!< PPA SRM color mode: YUV444 (limited range only)*/ + // YUV444 not supported by PPA hardware, but we can use 2D-DMA to do conversion before sending into and after coming out from the PPA module + // If in_pic is YUV444, then TX DMA channel could do DMA2D_CSC_TX_YUV444_TO_RGB888_601/709, so PPA in_color_mode is RGB888 + // If out_pic is YUV444, then RX DMA channel could do DMA2D_CSC_RX_YUV420_TO_YUV444, so PPA out_color_mode is YUV420 + // TODO: P4 ECO2 supports YUV422 + // PPA_SRM_COLOR_MODE_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), /*!< PPA SRM color mode: YUV422 (input only, limited range only) */ +} ppa_srm_color_mode_t; /** - * @brief Enumeration of PPA Blending available color mode + * @brief Enumeration of PPA blend available color mode */ typedef enum { - PPA_BLEND_COLOR_MODE_ARGB8888 = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888), /*!< PPA Blending color mode: ARGB8888 */ - PPA_BLEND_COLOR_MODE_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), /*!< PPA Blending color mode: RGB888 */ - PPA_BLEND_COLOR_MODE_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), /*!< PPA Blending color mode: RGB565 */ - PPA_BLEND_COLOR_MODE_L8 = COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L8), /*!< PPA Blending color mode: L8, only available on blending inputs */ - PPA_BLEND_COLOR_MODE_L4 = COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L4), /*!< PPA Blending color mode: L4, only available on blending inputs */ - PPA_BLEND_COLOR_MODE_A8 = COLOR_TYPE_ID(COLOR_SPACE_ALPHA, COLOR_PIXEL_A8), /*!< PPA Blending color mode: A8, only available on blending foreground input */ - PPA_BLEND_COLOR_MODE_A4 = COLOR_TYPE_ID(COLOR_SPACE_ALPHA, COLOR_PIXEL_A4), /*!< PPA Blending color mode: A4, only available on blending foreground input */ + PPA_BLEND_COLOR_MODE_ARGB8888 = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888), /*!< PPA blend color mode: ARGB8888 */ + PPA_BLEND_COLOR_MODE_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), /*!< PPA blend color mode: RGB888 */ + PPA_BLEND_COLOR_MODE_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), /*!< PPA blend color mode: RGB565 */ + PPA_BLEND_COLOR_MODE_A8 = COLOR_TYPE_ID(COLOR_SPACE_ALPHA, COLOR_PIXEL_A8), /*!< PPA blend color mode: A8, only available on blend foreground input */ + PPA_BLEND_COLOR_MODE_A4 = COLOR_TYPE_ID(COLOR_SPACE_ALPHA, COLOR_PIXEL_A4), /*!< PPA blend color mode: A4, only available on blend foreground input */ + // TODO: Support CLUT to support L4/L8 color mode + // PPA_BLEND_COLOR_MODE_L8 = COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L8), /*!< PPA blend color mode: L8, only available on blend inputs */ + // PPA_BLEND_COLOR_MODE_L4 = COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L4), /*!< PPA blend color mode: L4, only available on blend inputs */ } ppa_blend_color_mode_t; +/** + * @brief Enumeration of PPA fill available color mode + */ +typedef enum { + PPA_FILL_COLOR_MODE_ARGB8888 = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888), /*!< PPA fill color mode: ARGB8888 */ + PPA_FILL_COLOR_MODE_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), /*!< PPA fill color mode: RGB888 */ + PPA_FILL_COLOR_MODE_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), /*!< PPA fill color mode: RGB565 */ +} ppa_fill_color_mode_t; + +/** + * @brief Enumeration of PPA alpha compositing update mode + */ +typedef enum { + PPA_ALPHA_NO_CHANGE = 0, /*!< Do not replace alpha value (A' = A). + If input format does not contain alpha info, alpha value 255 will be used. */ + PPA_ALPHA_FIX_VALUE, /*!< Replace the alpha value in received pixel with a new, fixed alpha value (A' = val) */ + PPA_ALPHA_SCALE, /*!< Scale the alpha value in received pixel to be a new alpha value (A' = (A * val) >> 8). + If input format does not contain alpha info, A' = (255 * val) >> 8. */ + PPA_ALPHA_INVERT, /*!< Invert the alpha value in received pixel (A' = 255 - A). + If input format does not contain alpha info, A' = 0, i.e. a layer with 0% opacity. */ +} ppa_alpha_update_mode_t; + +/** + * @brief Enumeration of PPA supported color conversion standard between RGB and YUV (determines the YUV<->RGB conversion equation) + */ +typedef enum { + PPA_COLOR_CONV_STD_RGB_YUV_BT601 = COLOR_CONV_STD_RGB_YUV_BT601, /*!< YUV<->RGB conversion standard: BT.601 */ + PPA_COLOR_CONV_STD_RGB_YUV_BT709 = COLOR_CONV_STD_RGB_YUV_BT709, /*!< YUV<->RGB conversion standard: BT.709 */ +} ppa_color_conv_std_rgb_yuv_t; + +/** + * @brief Enumeration of PPA supported color range (determines the YUV<->RGB conversion equation) + */ +typedef enum { + PPA_COLOR_RANGE_LIMIT = COLOR_RANGE_LIMIT, /*!< Limited color range, 16 is the darkest black and 235 is the brightest white */ + PPA_COLOR_RANGE_FULL = COLOR_RANGE_FULL, /*!< Full color range, 0 is the darkest black and 255 is the brightest white */ +} ppa_color_range_t; + +/** + * @brief Enumeration of PPA supported data burst length + */ +typedef enum { + PPA_DATA_BURST_LENGTH_8 = DMA2D_DATA_BURST_LENGTH_8, /*!< Data burst length: 8 bytes */ + PPA_DATA_BURST_LENGTH_16 = DMA2D_DATA_BURST_LENGTH_16, /*!< Data burst length: 16 bytes */ + PPA_DATA_BURST_LENGTH_32 = DMA2D_DATA_BURST_LENGTH_32, /*!< Data burst length: 32 bytes */ + PPA_DATA_BURST_LENGTH_64 = DMA2D_DATA_BURST_LENGTH_64, /*!< Data burst length: 64 bytes */ + PPA_DATA_BURST_LENGTH_128 = DMA2D_DATA_BURST_LENGTH_128, /*!< Data burst length: 128 bytes */ +} ppa_data_burst_length_t; + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/rtc_io_hal.h b/components/hal/include/hal/rtc_io_hal.h index 67b2201bcaa4..086bec8c0d1a 100644 --- a/components/hal/include/hal/rtc_io_hal.h +++ b/components/hal/include/hal/rtc_io_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,6 +31,14 @@ extern "C" { #endif #if SOC_RTCIO_PIN_COUNT > 0 + +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT +/** + * Enable rtcio module clock. + */ +#define rtcio_hal_enable_io_clock(enable) rtcio_ll_output_enable(enable) +#endif + /** * Select the rtcio function. * diff --git a/components/hal/include/hal/touch_sensor_hal.h b/components/hal/include/hal/touch_sensor_hal.h index 08da29daae29..be45ca89ab6a 100644 --- a/components/hal/include/hal/touch_sensor_hal.h +++ b/components/hal/include/hal/touch_sensor_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -194,7 +194,7 @@ void touch_hal_get_meas_mode(touch_pad_t touch_num, touch_hal_meas_mode_t *meas) * @return * - If touch sensors measure done. */ -#define touch_hal_meas_is_done() touch_ll_meas_is_done() +#define touch_hal_meas_is_done() touch_ll_is_measure_done() /** * Initialize touch module. diff --git a/components/hal/include/hal/touch_sensor_types.h b/components/hal/include/hal/touch_sensor_types.h index 55291090cb66..dac11762f3e6 100644 --- a/components/hal/include/hal/touch_sensor_types.h +++ b/components/hal/include/hal/touch_sensor_types.h @@ -275,7 +275,7 @@ typedef enum { TOUCH_PAD_SMOOTH_MAX, } touch_smooth_mode_t; -#if CONFIG_IDF_TARGET_ESP32P4 +#if SOC_TOUCH_SENSOR_VERSION == 3 /** * @brief Touch channel counting mode of the binarized touch output * @@ -283,9 +283,11 @@ typedef enum { typedef enum { TOUCH_PAD_OUT_AS_DATA, /*!< Counting the output of touch channel as data. * The value will be smaller than actual value but more sensitive when the frequency of touch_out is close to the source clock + * Normally we treat the output as data when it is lower than the sample clock */ TOUCH_PAD_OUT_AS_CLOCK, /*!< Counting the output of touch channel as clock. * The value is accurate but less sensitive when the frequency of touch_out is close to the source clock + * Normally we treat the output as clock when it is higher than the sample clock */ } touch_out_mode_t; #endif diff --git a/components/hal/include/hal/twai_types.h b/components/hal/include/hal/twai_types.h index 7f3789fe2b7d..d22c50d3ff15 100644 --- a/components/hal/include/hal/twai_types.h +++ b/components/hal/include/hal/twai_types.h @@ -27,6 +27,7 @@ extern "C" { #define TWAI_ERR_PASS_THRESH 128 /**< Error counter threshold for error passive */ /** @cond */ //Doxy command to hide preprocessor definitions from docs + /** * @brief TWAI Message flags * diff --git a/components/hal/include/hal/usb_dwc_hal.h b/components/hal/include/hal/usb_dwc_hal.h index 9b2a2c3bc30b..33ac57be75e4 100644 --- a/components/hal/include/hal/usb_dwc_hal.h +++ b/components/hal/include/hal/usb_dwc_hal.h @@ -205,7 +205,7 @@ typedef struct { * - The peripheral must have been reset and clock un-gated * - The USB PHY (internal or external) and associated GPIOs must already be configured * - GPIO pins configured - * - Interrupt allocated but DISABLED (in case of an unknown interupt state) + * - Interrupt allocated but DISABLED (in case of an unknown interrupt state) * Exit: * - Checks to see if DWC_OTG is alive, and if HW version/config is correct * - HAl context initialized @@ -290,7 +290,7 @@ static inline void usb_dwc_hal_port_init(usb_dwc_hal_context_t *hal) /** * @brief Deinitialize the host port * - * - Will disable the host port's interrupts preventing further port aand channel events from ocurring + * - Will disable the host port's interrupts preventing further port aand channel events from occurring * * @param hal Context of the HAL layer */ @@ -333,7 +333,6 @@ static inline void usb_dwc_hal_port_toggle_power(usb_dwc_hal_context_t *hal, boo */ static inline void usb_dwc_hal_port_toggle_reset(usb_dwc_hal_context_t *hal, bool enable) { - HAL_ASSERT(hal->channels.num_allocd == 0); //Cannot reset if there are still allocated channels usb_dwc_ll_hprt_set_port_reset(hal->dev, enable); } @@ -447,7 +446,7 @@ static inline void usb_dwc_hal_port_periodic_enable(usb_dwc_hal_context_t *hal) /** * @brief Disable periodic scheduling * - * Disabling periodic scheduling will save a bit of DMA bandwith (as the controller will no longer fetch the schedule + * Disabling periodic scheduling will save a bit of DMA bandwidth (as the controller will no longer fetch the schedule * from the frame list). * * @note Before disabling periodic scheduling, it is the user's responsibility to ensure that all periodic channels have @@ -505,17 +504,17 @@ static inline usb_dwc_speed_t usb_dwc_hal_port_get_conn_speed(usb_dwc_hal_contex * @brief Disable the debounce lock * * This function must be called after calling usb_dwc_hal_port_check_if_connected() and will allow connection/disconnection - * events to occur again. Any pending connection or disconenction interrupts are cleared. + * events to occur again. Any pending connection or disconnection interrupts are cleared. * * @param hal Context of the HAL layer */ static inline void usb_dwc_hal_disable_debounce_lock(usb_dwc_hal_context_t *hal) { hal->flags.dbnc_lock_enabled = 0; - //Clear Conenction and disconenction interrupt in case it triggered again + //Clear Connection and disconnection interrupt in case it triggered again usb_dwc_ll_gintsts_clear_intrs(hal->dev, USB_DWC_LL_INTR_CORE_DISCONNINT); usb_dwc_ll_hprt_intr_clear(hal->dev, USB_DWC_LL_INTR_HPRT_PRTCONNDET); - //Reenable the hprt (connection) and disconnection interrupts + //Re-enable the hprt (connection) and disconnection interrupts usb_dwc_ll_gintmsk_en_intrs(hal->dev, USB_DWC_LL_INTR_CORE_PRTINT | USB_DWC_LL_INTR_CORE_DISCONNINT); } @@ -672,10 +671,10 @@ bool usb_dwc_hal_chan_request_halt(usb_dwc_hal_chan_t *chan_obj); /** * @brief Indicate that a channel is halted after a port error * - * When a port error occurs (e.g., discconect, overcurrent): + * When a port error occurs (e.g., disconnect, overcurrent): * - Any previously active channels will remain active (i.e., they will not receive a channel interrupt) * - Attempting to disable them using usb_dwc_hal_chan_request_halt() will NOT generate an interrupt for ISOC channels - * (probalby something to do with the periodic scheduling) + * (probably something to do with the periodic scheduling) * * However, the channel's enable bit can be left as 1 since after a port error, a soft reset will be done anyways. * This function simply updates the channels internal state variable to indicate it is halted (thus allowing it to be diff --git a/components/hal/isp_hal.c b/components/hal/isp_hal.c index 6fb72413a999..37e69fd772d7 100644 --- a/components/hal/isp_hal.c +++ b/components/hal/isp_hal.c @@ -1,16 +1,20 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include #include +#include #include "sdkconfig.h" #include "soc/soc_caps.h" #include "hal/assert.h" #include "hal/log.h" #include "hal/isp_hal.h" #include "hal/isp_ll.h" +#include "hal/isp_types.h" +#include "hal/hal_utils.h" /** * ISP HAL layer @@ -22,31 +26,37 @@ void isp_hal_init(isp_hal_context_t *hal, int isp_id) isp_ll_init(hal->hw); } - /*--------------------------------------------------------------- AF ---------------------------------------------------------------*/ -void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_af_window_t *window) +void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_window_t *window) { - isp_ll_af_set_window_range(hal->hw, window_id, window->top_left_x, window->top_left_y, window->bottom_right_x, window->bottom_right_y); + isp_ll_af_set_window_range(hal->hw, window_id, window->top_left.x, window->top_left.y, window->btm_right.x, window->btm_right.y); } -void isp_hal_af_get_oneshot_result(const isp_hal_context_t *hal, isp_af_result_t *out_res) +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +void isp_hal_bf_config(isp_hal_context_t *hal, isp_hal_bf_cfg_t *config) { - isp_ll_clear_intr(hal->hw, ISP_LL_EVENT_AF_FDONE); - isp_ll_af_manual_update(hal->hw); - - while (!(isp_ll_get_intr_raw(hal->hw) & ISP_LL_EVENT_AF_FDONE)) { - ; - } - - for (int i = 0; i < SOC_ISP_AF_WINDOW_NUMS; i++) { - out_res->definition[i] = isp_ll_af_get_window_sum(hal->hw, i); - out_res->luminance[i] = isp_ll_af_get_window_lum(hal->hw, i); + if (config) { + isp_ll_bf_set_sigma(hal->hw, config->denoising_level); + isp_ll_bf_set_padding_mode(hal->hw, config->padding_mode); + isp_ll_bf_set_padding_data(hal->hw, config->padding_data); + isp_ll_bf_set_padding_line_tail_valid_start_pixel(hal->hw, config->padding_line_tail_valid_start_pixel); + isp_ll_bf_set_padding_line_tail_valid_end_pixel(hal->hw, config->padding_line_tail_valid_end_pixel); + isp_ll_bf_set_template(hal->hw, config->bf_template); + } else { + isp_ll_bf_set_sigma(hal->hw, 0); + isp_ll_bf_set_padding_mode(hal->hw, 0); + isp_ll_bf_set_padding_data(hal->hw, 0); + isp_ll_bf_set_padding_line_tail_valid_start_pixel(hal->hw, 0); + isp_ll_bf_set_padding_line_tail_valid_end_pixel(hal->hw, 0); + uint8_t default_template[SOC_ISP_BF_TEMPLATE_X_NUMS][SOC_ISP_BF_TEMPLATE_Y_NUMS] = {}; + memset(default_template, SOC_ISP_BF_TEMPLATE_X_NUMS, sizeof(default_template)); + isp_ll_bf_set_template(hal->hw, default_template); } } - - /*--------------------------------------------------------------- INTR, put in iram ---------------------------------------------------------------*/ @@ -60,3 +70,96 @@ uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t m return triggered_events; } + +/*--------------------------------------------------------------- + Color Correction Matrix +---------------------------------------------------------------*/ +bool isp_hal_ccm_set_matrix(const isp_hal_context_t *hal, bool saturation, const float flt_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION]) +{ + isp_ll_ccm_gain_t fp_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION] = {}; + hal_utils_fixed_point_t fp_cfg = { + .int_bit = ISP_LL_CCM_MATRIX_INT_BITS, + .frac_bit = ISP_LL_CCM_MATRIX_FRAC_BITS, + .saturation = saturation, + }; + int err_level = saturation ? -1 : 0; + /* Transfer the float type to fixed point */ + for (int i = 0; i < ISP_CCM_DIMENSION; i++) { + for (int j = 0; j < ISP_CCM_DIMENSION; j++) { + if (hal_utils_float_to_fixed_point_32b(flt_matrix[i][j], &fp_cfg, &fp_matrix[i][j].val) < err_level) { + return false; + } + } + } + isp_ll_ccm_set_matrix(hal->hw, fp_matrix); + return true; +} + +/*--------------------------------------------------------------- + AWB +---------------------------------------------------------------*/ +bool isp_hal_awb_set_window_range(const isp_hal_context_t *hal, const isp_window_t *win) +{ + if (win->top_left.x > win->btm_right.x || + win->top_left.y > win->btm_right.y || + win->btm_right.x > ISP_LL_AWB_WINDOW_MAX_RANGE || + win->btm_right.y > ISP_LL_AWB_WINDOW_MAX_RANGE) { + return false; + } + isp_ll_awb_set_window_range(hal->hw, win->top_left.x, win->top_left.y, + win->btm_right.x, win->btm_right.y); + return true; +} + +bool isp_hal_awb_set_luminance_range(const isp_hal_context_t *hal, uint32_t lum_min, uint32_t lum_max) +{ + if (lum_min > lum_max || lum_max > ISP_LL_AWB_LUM_MAX_RANGE) { + return false; + } + isp_ll_awb_set_luminance_range(hal->hw, lum_min, lum_max); + return true; +} + +bool isp_hal_awb_set_rg_ratio_range(const isp_hal_context_t *hal, float rg_min, float rg_max) +{ + // Convert to fixed point + isp_ll_awb_rgb_ratio_t fp_rg_min = {}; + isp_ll_awb_rgb_ratio_t fp_rg_max = {}; + hal_utils_fixed_point_t fp_cfg = { + .int_bit = ISP_LL_AWB_RGB_RATIO_INT_BITS, + .frac_bit = ISP_LL_AWB_RGB_RATIO_FRAC_BITS, + .saturation = false, + }; + if (hal_utils_float_to_fixed_point_32b(rg_min, &fp_cfg, &fp_rg_min.val) != 0) { + return false; + } + if (hal_utils_float_to_fixed_point_32b(rg_max, &fp_cfg, &fp_rg_max.val) != 0) { + return false; + } + + // Set AWB white patch R/G ratio range + isp_ll_awb_set_rg_ratio_range(hal->hw, fp_rg_min, fp_rg_max); + return true; +} + +bool isp_hal_awb_set_bg_ratio_range(const isp_hal_context_t *hal, float bg_min, float bg_max) +{ + // Convert to fixed point + isp_ll_awb_rgb_ratio_t fp_bg_min = {}; + isp_ll_awb_rgb_ratio_t fp_bg_max = {}; + hal_utils_fixed_point_t fp_cfg = { + .int_bit = ISP_LL_AWB_RGB_RATIO_INT_BITS, + .frac_bit = ISP_LL_AWB_RGB_RATIO_FRAC_BITS, + .saturation = false, + }; + if (hal_utils_float_to_fixed_point_32b(bg_min, &fp_cfg, &fp_bg_min.val) != 0) { + return false; + } + if (hal_utils_float_to_fixed_point_32b(bg_max, &fp_cfg, &fp_bg_max.val) != 0) { + return false; + } + + // Set AWB white patch B/G ratio range + isp_ll_awb_set_bg_ratio_range(hal->hw, fp_bg_min, fp_bg_max); + return true; +} diff --git a/components/hal/linker.lf b/components/hal/linker.lf index ed8d9f00f5a4..b2d5f76a76cc 100644 --- a/components/hal/linker.lf +++ b/components/hal/linker.lf @@ -24,5 +24,3 @@ entries: spi_flash_hal_gpspi (noflash) if SOC_PMU_SUPPORTED = y: pmu_hal (noflash) - if SOC_CLK_MPLL_SUPPORTED = y: - clk_tree_hal: clk_hal_xtal_get_freq_mhz (noflash) diff --git a/components/hal/mmu_hal.c b/components/hal/mmu_hal.c index b3ee49181541..e3c9c87c4e0d 100644 --- a/components/hal/mmu_hal.c +++ b/components/hal/mmu_hal.c @@ -12,6 +12,7 @@ #include "hal/assert.h" #include "hal/mmu_hal.h" #include "hal/mmu_ll.h" +#include "soc/soc_caps.h" #include "rom/cache.h" void mmu_hal_init(void) @@ -26,7 +27,7 @@ void mmu_hal_init(void) void mmu_hal_unmap_all(void) { -#if MMU_LL_MMU_PER_TARGET +#if SOC_MMU_PER_EXT_MEM_TARGET mmu_ll_unmap_all(MMU_LL_FLASH_MMU_ID); mmu_ll_unmap_all(MMU_LL_PSRAM_MMU_ID); #else diff --git a/components/hal/ppa_hal.c b/components/hal/ppa_hal.c new file mode 100644 index 000000000000..a2cd073fe83d --- /dev/null +++ b/components/hal/ppa_hal.c @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "hal/ppa_hal.h" +#include "hal/ppa_ll.h" + +void ppa_hal_init(ppa_hal_context_t *hal) +{ + hal->dev = PPA_LL_GET_HW; +} + +void ppa_hal_deinit(ppa_hal_context_t *hal) +{ + hal->dev = NULL; +} diff --git a/components/hal/rmt_hal.c b/components/hal/rmt_hal.c index d83e5952dacc..7290d36b1f2f 100644 --- a/components/hal/rmt_hal.c +++ b/components/hal/rmt_hal.c @@ -10,9 +10,9 @@ void rmt_hal_init(rmt_hal_context_t *hal) { hal->regs = &RMT; - rmt_ll_power_down_mem(hal->regs, false); // turn on RMTMEM power domain + rmt_ll_mem_power_by_pmu(hal->regs); rmt_ll_enable_mem_access_nonfifo(hal->regs, true); // APB access the RMTMEM in nonfifo mode - rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events + rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interrupt events rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events #if SOC_RMT_SUPPORT_TX_SYNCHRO rmt_ll_tx_clear_sync_group(hal->regs); @@ -21,9 +21,9 @@ void rmt_hal_init(rmt_hal_context_t *hal) void rmt_hal_deinit(rmt_hal_context_t *hal) { - rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events + rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interrupt events rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events - rmt_ll_power_down_mem(hal->regs, true); // turn off RMTMEM power domain + rmt_ll_mem_force_power_off(hal->regs); // power off RMTMEM power domain forcefully hal->regs = NULL; } diff --git a/components/hal/spi_flash_hal_common.inc b/components/hal/spi_flash_hal_common.inc index 942edf96f69d..65f5af0e7ba3 100644 --- a/components/hal/spi_flash_hal_common.inc +++ b/components/hal/spi_flash_hal_common.inc @@ -101,6 +101,7 @@ esp_err_t spi_flash_hal_configure_host_io_mode( return ESP_ERR_NOT_SUPPORTED; } +#ifndef GPSPI_BUILD #if SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT // The CONTROL_DUMMY_OUTPUT feature is used to control M7-M0 bits. spi_flash_ll_set_dummy_out(dev, (conf_required? 1: 0), 1); @@ -129,6 +130,9 @@ esp_err_t spi_flash_hal_configure_host_io_mode( spi_flash_ll_set_extra_address(dev, 0); } #endif +#else + gpspi_flash_ll_set_dummy_out(dev, (conf_required? 1: 0), 1); +#endif if (command >= 0x100) { spi_flash_ll_set_command(dev, command, 16); diff --git a/components/hal/test_apps/crypto/main/CMakeLists.txt b/components/hal/test_apps/crypto/main/CMakeLists.txt index 6c1febef204c..3f7585a3aaf0 100644 --- a/components/hal/test_apps/crypto/main/CMakeLists.txt +++ b/components/hal/test_apps/crypto/main/CMakeLists.txt @@ -68,7 +68,7 @@ if(CONFIG_SOC_SHA_SUPPORTED) endif() idf_component_register(SRCS ${srcs} - PRIV_REQUIRES efuse mbedtls esp_mm + PRIV_REQUIRES efuse mbedtls esp_mm bootloader_support REQUIRES test_utils unity WHOLE_ARCHIVE PRIV_INCLUDE_DIRS "${priv_include_dirs}" diff --git a/components/hal/test_apps/crypto/main/ecc/test_ecc.c b/components/hal/test_apps/crypto/main/ecc/test_ecc.c index a6bc8c3fdcb5..fcf72814f24a 100644 --- a/components/hal/test_apps/crypto/main/ecc/test_ecc.c +++ b/components/hal/test_apps/crypto/main/ecc/test_ecc.c @@ -46,6 +46,7 @@ static void ecc_enable_and_reset(void) { ECC_RCC_ATOMIC() { ecc_ll_enable_bus_clock(true); + ecc_ll_power_up(); ecc_ll_reset_register(); } } @@ -54,6 +55,7 @@ static void ecc_disable(void) { ECC_RCC_ATOMIC() { ecc_ll_enable_bus_clock(false); + ecc_ll_power_down(); } } diff --git a/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c index d0777dc817bd..2a7e1d4239bf 100644 --- a/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c +++ b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c @@ -34,6 +34,7 @@ static void ecdsa_enable_and_reset(void) ECC_RCC_ATOMIC() { ecc_ll_enable_bus_clock(true); + ecc_ll_power_up(); ecc_ll_reset_register(); } @@ -55,6 +56,7 @@ static void ecdsa_disable(void) ECC_RCC_ATOMIC() { ecc_ll_enable_bus_clock(false); + ecc_ll_power_down(); } ECDSA_RCC_ATOMIC() { diff --git a/components/hal/test_apps/hal_utils/main/CMakeLists.txt b/components/hal/test_apps/hal_utils/main/CMakeLists.txt index 09293d7c0e0f..927a3601977a 100644 --- a/components/hal/test_apps/hal_utils/main/CMakeLists.txt +++ b/components/hal/test_apps/hal_utils/main/CMakeLists.txt @@ -1,4 +1,5 @@ idf_component_register(SRCS "test_app_main.c" + "test_fmt_convert.c" "test_calc_clk_div.c" "test_hal_utils_misc.c" INCLUDE_DIRS "." diff --git a/components/hal/test_apps/hal_utils/main/test_fmt_convert.c b/components/hal/test_apps/hal_utils/main/test_fmt_convert.c new file mode 100644 index 000000000000..04670cb6d21d --- /dev/null +++ b/components/hal/test_apps/hal_utils/main/test_fmt_convert.c @@ -0,0 +1,94 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "unity.h" +#include "hal/hal_utils.h" + +#ifndef BIT +#define BIT(n) (1UL << (n)) +#endif + +TEST_CASE("test_float_to_fixed_point", "[fmt_convert]") +{ + float f_nan = NAN; + float f_inf = INFINITY; + float f0 = 100.9f; + float f_zero = 0; + float f_precise = 0.5f; + float f_int = 2.0f; + float f_frac = 1.0f / 3.0f; + float f_dec = 1.453f; + float f_neg = -1.25f; + uint32_t out = 0; + hal_utils_fixed_point_t fp_cfg = { + .int_bit = 24, + .frac_bit = 8, + .saturation = false, + }; + + // Invalid arguments case + TEST_ASSERT_EQUAL_INT(-3, hal_utils_float_to_fixed_point_32b(f_dec, &fp_cfg, &out)); + printf("Invalid arguments case passed!\n"); + fp_cfg.int_bit = 2; + + // Overflow case + TEST_ASSERT_EQUAL_INT(-1, hal_utils_float_to_fixed_point_32b(f0, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(0x64E6, out); // integ: 0x64 = 100, frac: 0xE6 / 0x100 = 0.8984375 + printf("Overflow case passed!\n"); + + // Not-a-Number case + TEST_ASSERT_EQUAL_INT(-2, hal_utils_float_to_fixed_point_32b(f_nan, &fp_cfg, &out)); + printf("Not-a-Number case passed!\n"); + + // Infinity case + TEST_ASSERT_EQUAL_INT(-1, hal_utils_float_to_fixed_point_32b(f_inf, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(BIT(31) - 1, out); + printf("Infinity case passed!\n"); + + fp_cfg.saturation = true; + // Limit overflow case + TEST_ASSERT_EQUAL_INT(-1, hal_utils_float_to_fixed_point_32b(f0, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(BIT(10) - 1, out); // Limit to the maximum value, integ: 0x03 = 3 | frac: 0xff / 0x100 = 0.99609375 + printf("Limit overflow case passed!\n"); + + // Zero case + TEST_ASSERT_EQUAL_INT(0, hal_utils_float_to_fixed_point_32b(f_zero, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(0, out); // Special case, 0 = 0 + printf("Zero case passed!\n"); + + // Precision case + TEST_ASSERT_EQUAL_INT(0, hal_utils_float_to_fixed_point_32b(f_precise, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(BIT(7), out); // frac: 0x80 / 0x100 = 0.5 + printf("Precision case passed!\n"); + + // Integer case + TEST_ASSERT_EQUAL_INT(0, hal_utils_float_to_fixed_point_32b(f_int, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(BIT(9), out); // integ: 2 | frac: 0x00 / 0x100 = 0 + printf("Integer case passed!\n"); + + // Fraction case + TEST_ASSERT_EQUAL_INT(0, hal_utils_float_to_fixed_point_32b(f_frac, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(0x055, out); // 0x55 / 0x100 = 0.33203125 + printf("Fraction case passed!\n"); + + // Decimal case + TEST_ASSERT_EQUAL_INT(0, hal_utils_float_to_fixed_point_32b(f_dec, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(0x173, out); // integ: 0x01 = 1, frac: 0x73 / 0x100 = 0.44921875 + printf("Decimal case passed!\n"); + + // Negative case + TEST_ASSERT_EQUAL_INT(0, hal_utils_float_to_fixed_point_32b(f_neg, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(BIT(10) | BIT(8) | (BIT(6)), out); // sign: 1 | integ: 1 | frac: 0x40 / 0x100 = 0.25 + printf("Negative case passed!\n"); + + fp_cfg.int_bit = 8; + // Integer bits case + TEST_ASSERT_EQUAL_INT(0, hal_utils_float_to_fixed_point_32b(f0, &fp_cfg, &out)); + TEST_ASSERT_EQUAL_UINT32(0x64E6, out); // integ: 0x64 = 100, frac: 0xE6 / 0x100 = 0.8984375 + printf("Integer bits case passed!\n"); +} diff --git a/components/heap/heap_caps_base.c b/components/heap/heap_caps_base.c index a4598785d9d8..e89479070086 100644 --- a/components/heap/heap_caps_base.c +++ b/components/heap/heap_caps_base.c @@ -23,6 +23,12 @@ #define CALL_HOOK(hook, ...) {} #endif +//This is normally provided by the heap-memalign-hw component. +extern void esp_heap_adjust_alignment_to_hw(size_t *p_alignment, size_t *p_size, uint32_t *p_caps); + +//Default alignment the multiheap allocator / tlsf will align 'unaligned' memory to, in bytes +#define UNALIGNED_MEM_ALIGNMENT_BYTES 4 + /* This takes a memory chunk in a region that can be addressed as both DRAM as well as IRAM. It will convert it to IRAM in such a way that it can be later freed. It assumes both the address as well as the length to be word-aligned. @@ -66,14 +72,26 @@ HEAP_IRAM_ATTR void heap_caps_free( void *ptr) CALL_HOOK(esp_heap_trace_free_hook, ptr); } +HEAP_IRAM_ATTR static inline void *aligned_or_unaligned_alloc(multi_heap_handle_t heap, size_t size, size_t alignment, size_t offset) { + if (alignment<=UNALIGNED_MEM_ALIGNMENT_BYTES) { //alloc and friends align to 32-bit by default + return multi_heap_malloc(heap, size); + } else { + return multi_heap_aligned_alloc_offs(heap, size, alignment, offset); + } +} + /* -This function should not be called directly as it does not -check for failure / call heap_caps_alloc_failed() +This function should not be called directly as it does not check for failure / call heap_caps_alloc_failed() +Note that this function does 'unaligned' alloc calls if alignment <= UNALIGNED_MEM_ALIGNMENT_BYTES (=4) as the +allocator will align to that value by default. */ -HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_malloc_base( size_t size, uint32_t caps) +HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_aligned_alloc_base(size_t alignment, size_t size, uint32_t caps) { void *ret = NULL; + // Alignment, size and caps may need to be modified because of hardware requirements. + esp_heap_adjust_alignment_to_hw(&alignment, &size, &caps); + // remove block owner size to HEAP_SIZE_MAX rather than adding the block owner size // to size to prevent overflows. if (size == 0 || size > MULTI_HEAP_REMOVE_BLOCK_OWNER_SIZE(HEAP_SIZE_MAX) ) { @@ -118,7 +136,8 @@ HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_malloc_base( size_t size, uint32_t //This is special, insofar that what we're going to get back is a DRAM address. If so, //we need to 'invert' it (lowest address in DRAM == highest address in IRAM and vice-versa) and //add a pointer to the DRAM equivalent before the address we're going to return. - ret = multi_heap_malloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size) + 4); // int overflow checked above + ret = aligned_or_unaligned_alloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size) + 4, + alignment, MULTI_HEAP_BLOCK_OWNER_SIZE()); // int overflow checked above if (ret != NULL) { MULTI_HEAP_SET_BLOCK_OWNER(ret); ret = MULTI_HEAP_ADD_BLOCK_OWNER_OFFSET(ret); @@ -128,7 +147,8 @@ HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_malloc_base( size_t size, uint32_t } } else { //Just try to alloc, nothing special. - ret = multi_heap_malloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size)); + ret = aligned_or_unaligned_alloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size), + alignment, MULTI_HEAP_BLOCK_OWNER_SIZE()); if (ret != NULL) { MULTI_HEAP_SET_BLOCK_OWNER(ret); ret = MULTI_HEAP_ADD_BLOCK_OWNER_OFFSET(ret); @@ -145,6 +165,11 @@ HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_malloc_base( size_t size, uint32_t return NULL; } +//Wrapper for heap_caps_aligned_alloc_base as that can also do unaligned allocs. +HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_malloc_base( size_t size, uint32_t caps) { + return heap_caps_aligned_alloc_base(UNALIGNED_MEM_ALIGNMENT_BYTES, size, caps); +} + /* This function should not be called directly as it does not check for failure / call heap_caps_alloc_failed() @@ -155,8 +180,12 @@ HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_realloc_base( void *ptr, size_t siz heap_t *heap = NULL; void *dram_ptr = NULL; + //See if memory needs alignment because of hardware reasons. + size_t alignment = UNALIGNED_MEM_ALIGNMENT_BYTES; + esp_heap_adjust_alignment_to_hw(&alignment, &size, &caps); + if (ptr == NULL) { - return heap_caps_malloc_base(size, caps); + return heap_caps_aligned_alloc_base(alignment, size, caps); } if (size == 0) { @@ -200,7 +229,9 @@ HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_realloc_base( void *ptr, size_t siz // requested ones? bool compatible_caps = (caps & get_all_caps(heap)) == caps; - if (compatible_caps && !ptr_in_diram_case) { + //Note we don't try realloc() on memory that needs to be aligned, that is handled + //by the fallthrough code. + if (compatible_caps && !ptr_in_diram_case && alignment<=UNALIGNED_MEM_ALIGNMENT_BYTES) { // try to reallocate this memory within the same heap // (which will resize the block if it can) void *r = multi_heap_realloc(heap->heap, ptr, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size)); @@ -214,7 +245,7 @@ HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_realloc_base( void *ptr, size_t siz // if we couldn't do that, try to see if we can reallocate // in a different heap with requested capabilities. - void *new_p = heap_caps_malloc_base(size, caps); + void *new_p = heap_caps_aligned_alloc_base(alignment, size, caps); if (new_p != NULL) { size_t old_size = 0; @@ -256,34 +287,3 @@ HEAP_IRAM_ATTR void *heap_caps_calloc_base( size_t n, size_t size, uint32_t caps } return result; } - -HEAP_IRAM_ATTR void *heap_caps_aligned_alloc_base(size_t alignment, size_t size, uint32_t caps) -{ - for (int prio = 0; prio < SOC_MEMORY_TYPE_NO_PRIOS; prio++) { - //Iterate over heaps and check capabilities at this priority - heap_t *heap; - SLIST_FOREACH(heap, ®istered_heaps, next) { - if (heap->heap == NULL) { - continue; - } - if ((heap->caps[prio] & caps) != 0) { - //Heap has at least one of the caps requested. If caps has other bits set that this prio - //doesn't cover, see if they're available in other prios. - if ((get_all_caps(heap) & caps) == caps) { - // Just try to alloc, nothing special. Provide the size of the block owner - // as an offset to prevent a miscalculation of the alignment. - void *ret = multi_heap_aligned_alloc_offs(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size), alignment, MULTI_HEAP_BLOCK_OWNER_SIZE()); - if (ret != NULL) { - MULTI_HEAP_SET_BLOCK_OWNER(ret); - ret = MULTI_HEAP_ADD_BLOCK_OWNER_OFFSET(ret); - CALL_HOOK(esp_heap_trace_alloc_hook, ret, size, caps); - return ret; - } - } - } - } - } - - //Nothing usable found. - return NULL; -} diff --git a/components/heap/include/esp_heap_caps.h b/components/heap/include/esp_heap_caps.h index 4d590204e59a..e875e4badd08 100644 --- a/components/heap/include/esp_heap_caps.h +++ b/components/heap/include/esp_heap_caps.h @@ -43,6 +43,9 @@ extern "C" { #define MALLOC_CAP_RETENTION (1<<14) ///< Memory must be able to accessed by retention DMA #define MALLOC_CAP_RTCRAM (1<<15) ///< Memory must be in RTC fast memory #define MALLOC_CAP_TCM (1<<16) ///< Memory must be in TCM memory +#define MALLOC_CAP_DMA_DESC_AHB (1<<17) ///< Memory must be capable of containing AHB DMA descriptors +#define MALLOC_CAP_DMA_DESC_AXI (1<<18) ///< Memory must be capable of containing AXI DMA descriptors +#define MALLOC_CAP_CACHE_ALIGNED (1<<19) ///< Memory must be aligned to the cache line size of any intermediate caches #define MALLOC_CAP_INVALID (1<<31) ///< Memory can't be used / list end marker @@ -385,7 +388,7 @@ void *heap_caps_malloc_prefer( size_t size, size_t num, ... ); * * @param ptr Pointer to previously allocated memory, or NULL for a new allocation. * @param size Size of the new buffer requested, or 0 to free the buffer. - * @param num Number of variable paramters + * @param num Number of variable parameters * * @return Pointer to a new buffer of size 'size', or NULL if allocation failed. */ @@ -396,7 +399,7 @@ void *heap_caps_realloc_prefer( void *ptr, size_t size, size_t num, ... ); * * @param n Number of continuing chunks of memory to allocate * @param size Size, in bytes, of a chunk of memory to allocate - * @param num Number of variable paramters + * @param num Number of variable parameters * * @return A pointer to the memory allocated on success, NULL on failure */ diff --git a/components/heap/port/esp32c5/memory_layout.c b/components/heap/port/esp32c5/memory_layout.c index 6ba81dbd370a..b7b00b804eeb 100644 --- a/components/heap/port/esp32c5/memory_layout.c +++ b/components/heap/port/esp32c5/memory_layout.c @@ -45,11 +45,11 @@ enum { /** * Defined the attributes and allocation priority of each memory on the chip, * The heap allocator will traverse all types of memory types in column High Priority Matching and match the specified caps at first, - * if no memory caps matched or the allocation is failed, it will go to columns Medium Priorty Matching and Low Priority Matching + * if no memory caps matched or the allocation is failed, it will go to columns Medium Priority Matching and Low Priority Matching * in turn to continue matching. */ const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { - /* Mem Type Name High Priority Matching Medium Priorty Matching Low Priority Matching */ + /* Mem Type Name High Priority Matching Medium Priority Matching Low Priority Matching */ [SOC_MEMORY_TYPE_RAM] = { "RAM", { ESP32C5_MEM_COMMON_CAPS | MALLOC_CAP_DMA, 0, 0 }}, [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, ESP32C5_MEM_COMMON_CAPS, 0 }}, #if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION @@ -70,23 +70,16 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor /** * Register the shared buffer area of the last memory block into the heap during heap initialization */ -#define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) +#define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) const soc_memory_region_t soc_memory_regions[] = { #if CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - { SOC_EXTRAM_DATA_LOW, (SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW),SOC_MEMORY_TYPE_SPIRAM, 0}, //SPI SRAM, if available + { SOC_EXTRAM_DATA_LOW, (SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW), SOC_MEMORY_TYPE_SPIRAM, 0, false}, //SPI SRAM, if available #endif - { 0x40800000, 0x20000, SOC_MEMORY_TYPE_RAM, 0x40800000, false}, //D/IRAM level0, can be used as trace memory - { 0x40820000, 0x20000, SOC_MEMORY_TYPE_RAM, 0x40820000, false}, //D/IRAM level1, can be used as trace memory -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - { 0x40840000, 0x20000, SOC_MEMORY_TYPE_RAM, 0x40840000, false}, //D/IRAM level2, can be used as trace memory - { 0x40860000, (APP_USABLE_DRAM_END-0x40860000), SOC_MEMORY_TYPE_RAM, 0x40860000, false}, //D/IRAM level3, can be used as trace memory -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - { 0x40840000, (APP_USABLE_DRAM_END-0x40840000), SOC_MEMORY_TYPE_RAM, 0x40840000, false}, //D/IRAM level3, can be used as trace memory -#endif - { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH-APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_RAM, APP_USABLE_DRAM_END, true}, //D/IRAM level3, can be used as trace memory (ROM reserved area) + { SOC_DIRAM_DRAM_LOW, (APP_USABLE_DRAM_END - SOC_DIRAM_DRAM_LOW), SOC_MEMORY_TYPE_RAM, SOC_DIRAM_IRAM_LOW, false}, //D/IRAM, can be used as trace memory + { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH - APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_RAM, APP_USABLE_DRAM_END, true}, //D/IRAM, can be used as trace memory (ROM reserved area) #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP - { 0x50000000, 0x4000, SOC_MEMORY_TYPE_RTCRAM, 0, false}, //LPRAM + { SOC_RTC_DATA_LOW, (SOC_RTC_DATA_HIGH - SOC_RTC_DATA_LOW), SOC_MEMORY_TYPE_RTCRAM, 0, false}, //LPRAM #endif }; @@ -109,7 +102,6 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code); #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP -// TODO: IDF-6019 check reserved lp mem region SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data); #endif @@ -118,5 +110,5 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_reserved_start, (intptr_t)&_rtc_reserv #ifdef CONFIG_SPIRAM /* Reserve the whole possible SPIRAM region here, spiram.c will add some or all of this * memory to heap depending on the actual SPIRAM chip size. */ -SOC_RESERVE_MEMORY_REGION(SOC_DROM_LOW, SOC_DROM_HIGH, extram_data_region); +SOC_RESERVE_MEMORY_REGION(SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_data_region); #endif diff --git a/components/heap/port/esp32c6/memory_layout.c b/components/heap/port/esp32c6/memory_layout.c index 755e09b0b582..3c0aceb7b0d1 100644 --- a/components/heap/port/esp32c6/memory_layout.c +++ b/components/heap/port/esp32c6/memory_layout.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -42,11 +42,11 @@ enum { /** * Defined the attributes and allocation priority of each memory on the chip, * The heap allocator will traverse all types of memory types in column High Priority Matching and match the specified caps at first, - * if no memory caps matched or the allocation is failed, it will go to columns Medium Priorty Matching and Low Priority Matching + * if no memory caps matched or the allocation is failed, it will go to columns Medium Priority Matching and Low Priority Matching * in turn to continue matching. */ const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { - /* Mem Type Name High Priority Matching Medium Priorty Matching Low Priority Matching */ + /* Mem Type Name High Priority Matching Medium Priority Matching Low Priority Matching */ [SOC_MEMORY_TYPE_RAM] = { "RAM", { ESP32C6_MEM_COMMON_CAPS | MALLOC_CAP_DMA, 0, 0 }}, [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, ESP32C6_MEM_COMMON_CAPS, 0 }}, }; @@ -96,7 +96,6 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code); #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP -// TODO: IDF-6019 check reserved lp mem region SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data); #endif diff --git a/components/heap/port/esp32h2/memory_layout.c b/components/heap/port/esp32h2/memory_layout.c index 5a562df7f2c2..224e2ec454d2 100644 --- a/components/heap/port/esp32h2/memory_layout.c +++ b/components/heap/port/esp32h2/memory_layout.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,11 +40,11 @@ enum { /** * Defined the attributes and allocation priority of each memory on the chip, * The heap allocator will traverse all types of memory types in column High Priority Matching and match the specified caps at first, - * if no memory caps matched or the allocation is failed, it will go to columns Medium Priorty Matching and Low Priority Matching + * if no memory caps matched or the allocation is failed, it will go to columns Medium Priority Matching and Low Priority Matching * in turn to continue matching. */ const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { - /* Mem Type Name High Priority Matching Medium Priorty Matching Low Priority Matching */ + /* Mem Type Name High Priority Matching Medium Priority Matching Low Priority Matching */ [SOC_MEMORY_TYPE_RAM] = { "RAM", { ESP32H2_MEM_COMMON_CAPS | MALLOC_CAP_DMA, 0, 0 }}, [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, ESP32H2_MEM_COMMON_CAPS, 0 }}, }; @@ -95,7 +95,6 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code); #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP -// TODO: IDF-6019 check reserved lp mem region SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data); #endif diff --git a/components/heap/test_apps/.build-test-rules.yml b/components/heap/test_apps/.build-test-rules.yml index a55adfc17640..a90d37a1f286 100644 --- a/components/heap/test_apps/.build-test-rules.yml +++ b/components/heap/test_apps/.build-test-rules.yml @@ -2,10 +2,8 @@ components/heap/test_apps/heap_tests: disable: - - if: IDF_TARGET == "linux" - if: IDF_TARGET == "esp32c5" - temporary: true - reason: not support yet # TODO: [ESP32C5] IDF-9641 + - if: IDF_TARGET == "linux" - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 - if: CONFIG_NAME == "psram_all_ext" and SOC_SPIRAM_SUPPORTED != 1 # These 3 configs are build only for non-nightly, buildig for a single target is sufficient diff --git a/components/heap/test_apps/heap_tests/main/CMakeLists.txt b/components/heap/test_apps/heap_tests/main/CMakeLists.txt index 1803d9f1931e..69af24fd9438 100644 --- a/components/heap/test_apps/heap_tests/main/CMakeLists.txt +++ b/components/heap/test_apps/heap_tests/main/CMakeLists.txt @@ -1,5 +1,6 @@ set(src_test "test_heap_main.c" "test_aligned_alloc_caps.c" + "test_heap_align_hw.c" "test_allocator_timings.c" "test_corruption_check.c" "test_diram.c" @@ -13,5 +14,5 @@ set(src_test "test_heap_main.c" idf_component_register(SRCS ${src_test} INCLUDE_DIRS "." - REQUIRES unity esp_psram spi_flash + REQUIRES unity esp_psram spi_flash esp_mm WHOLE_ARCHIVE) diff --git a/components/heap/test_apps/heap_tests/main/test_heap_align_hw.c b/components/heap/test_apps/heap_tests/main/test_heap_align_hw.c new file mode 100644 index 000000000000..a3fa60cfaae9 --- /dev/null +++ b/components/heap/test_apps/heap_tests/main/test_heap_align_hw.c @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#include +#include "inttypes.h" +#include "esp_log.h" +#include "esp_attr.h" +#include "unity.h" +#include "esp_private/esp_cache_private.h" +#include "esp_memory_utils.h" +#include "hal/cache_ll.h" +#include "hal/cache_hal.h" + +TEST_CASE("test heap_caps_malloc_prefer for dma memory", "[hw-align]") +{ + void *ptr = NULL; + ptr = heap_caps_malloc_prefer(40, 1, MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(ptr); + TEST_ASSERT(esp_ptr_dma_capable(ptr)); + + free(ptr); +} + +TEST_CASE("test heap_caps_calloc_prefer for dma memory", "[hw-align]") +{ + void *ptr = NULL; + ptr = heap_caps_calloc_prefer(40, 1, 1, MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(ptr); + TEST_ASSERT(esp_ptr_dma_capable(ptr)); + + free(ptr); +} + +#include "esp_private/heap_align_hw.h" + +#define TEST_ALLOC_COUNT 100 +static bool test_alignment(uint32_t caps, int expected_alignment) { + bool ret=true; + + void *mem[TEST_ALLOC_COUNT]; + size_t size[TEST_ALLOC_COUNT]; + + //First, check if we can allocate memory with these caps anyway. + void *tst=heap_caps_malloc(1, caps); + if (!tst) return true; + free(tst); + + //Step 1: generate sizes and allocate memory. + for (int i=0; i8?int_cache_size:8); + test_alignment(MALLOC_CAP_DMA|MALLOC_CAP_SPIRAM, ext_cache_size); +} diff --git a/components/idf_test/include/esp32p4/idf_performance_target.h b/components/idf_test/include/esp32p4/idf_performance_target.h index a312d550f977..90ad9b1e3a57 100644 --- a/components/idf_test/include/esp32p4/idf_performance_target.h +++ b/components/idf_test/include/esp32p4/idf_performance_target.h @@ -10,3 +10,11 @@ /* Solicited yields (portYIELD() or taskYIELD()) take longer on esp32p4. TODO: IDF-2809 */ #define IDF_PERFORMANCE_MAX_SCHEDULING_TIME 3200 + +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64 10 +#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3 10 diff --git a/components/ieee802154/driver/esp_ieee802154_debug.c b/components/ieee802154/driver/esp_ieee802154_debug.c index c8472c831594..0dbfd4bc5902 100644 --- a/components/ieee802154/driver/esp_ieee802154_debug.c +++ b/components/ieee802154/driver/esp_ieee802154_debug.c @@ -12,7 +12,6 @@ #if CONFIG_IEEE802154_DEBUG ieee802154_probe_info_t g_ieee802154_probe; -#define TAG "ieee802154_debug" #if CONFIG_IEEE802154_RECORD_EVENT static char *ieee802154_get_event_string(ieee802154_ll_event_t events) @@ -176,7 +175,7 @@ static char *ieee80154_tx_abort_reason_string[] = { void ieee802154_assert_print(void) { #if CONFIG_IEEE802154_RECORD_EVENT - ESP_EARLY_LOGW(TAG, "Print the record event, current event index: %d", g_ieee802154_probe.event_index); + ESP_EARLY_LOGW(IEEE802154_TAG, "Print the record event, current event index: %d", g_ieee802154_probe.event_index); for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_EVENT_SIZE; i++) { char event_log[200] = { 0 }; char abort_log[100] = { 0 }; @@ -191,49 +190,49 @@ void ieee802154_assert_print(void) snprintf(abort_log, 100, "tx abort reason: %4x, %20s", g_ieee802154_probe.event[i].abort_reason.tx, ieee80154_tx_abort_reason_string[g_ieee802154_probe.event[i].abort_reason.tx]); } - ESP_EARLY_LOGW(TAG, "%s %s", event_log, abort_log); + ESP_EARLY_LOGW(IEEE802154_TAG, "%s %s", event_log, abort_log); } - ESP_EARLY_LOGW(TAG,"Print the record event done.\n"); + ESP_EARLY_LOGW(IEEE802154_TAG,"Print the record event done."); #endif // CONFIG_IEEE802154_RECORD_EVENT #if CONFIG_IEEE802154_RECORD_STATE - ESP_EARLY_LOGW(TAG, "Print the record state, current state index: %d", g_ieee802154_probe.state_index); + ESP_EARLY_LOGW(IEEE802154_TAG, "Print the record state, current state index: %d", g_ieee802154_probe.state_index); for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_STATE_SIZE; i++) { - ESP_EARLY_LOGW(TAG, "index %2d: line:%5s, state:%10s, timestamp: %lld", + ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: line:%5s, state:%10s, timestamp: %lld", i, g_ieee802154_probe.state[i].line_str, ieee802154_state_string[g_ieee802154_probe.state[i].state], g_ieee802154_probe.state[i].timestamp); } - ESP_EARLY_LOGW(TAG,"Print the record state done.\n"); + ESP_EARLY_LOGW(IEEE802154_TAG,"Print the record state done."); #endif // CONFIG_IEEE802154_RECORD_STATE #if CONFIG_IEEE802154_RECORD_CMD - ESP_EARLY_LOGW(TAG, "Print the record cmd, current cmd index: %d", g_ieee802154_probe.cmd_index); + ESP_EARLY_LOGW(IEEE802154_TAG, "Print the record cmd, current cmd index: %d", g_ieee802154_probe.cmd_index); for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_CMD_SIZE; i++) { - ESP_EARLY_LOGW(TAG, "index %2d: line:%5s, cmd:%10s, timestamp: %lld", + ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: line:%5s, cmd:%10s, timestamp: %lld", i, g_ieee802154_probe.cmd[i].line_str, ieee802154_get_cmd_string(g_ieee802154_probe.cmd[i].cmd), g_ieee802154_probe.cmd[i].timestamp); } - ESP_EARLY_LOGW(TAG,"Print the record cmd done.\n"); + ESP_EARLY_LOGW(IEEE802154_TAG,"Print the record cmd done."); #endif // CONFIG_IEEE802154_RECORD_CMD #if CONFIG_IEEE802154_RECORD_ABORT - ESP_EARLY_LOGW(TAG, "Print the record abort, current abort index: %d", g_ieee802154_probe.abort_index); + ESP_EARLY_LOGW(IEEE802154_TAG, "Print the record abort, current abort index: %d", g_ieee802154_probe.abort_index); for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_ABORT_SIZE; i++) { if (g_ieee802154_probe.abort[i].is_tx_abort) { - ESP_EARLY_LOGW(TAG, "index %2d: tx abort: %4x, %15s, timestamp: %lld", + ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: tx abort: %4x, %15s, timestamp: %lld", i, g_ieee802154_probe.abort[i].abort_reason.tx, ieee80154_tx_abort_reason_string[g_ieee802154_probe.abort[i].abort_reason.tx], g_ieee802154_probe.abort[i].timestamp); } else { - ESP_EARLY_LOGW(TAG, "index %2d: rx abort: %4x, %15s, timestamp: %lld", + ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: rx abort: %4x, %15s, timestamp: %lld", i, g_ieee802154_probe.abort[i].abort_reason.rx, ieee80154_rx_abort_reason_string[g_ieee802154_probe.abort[i].abort_reason.rx], g_ieee802154_probe.abort[i].timestamp); } } - ESP_EARLY_LOGW(TAG,"Print the record abort done.\n"); + ESP_EARLY_LOGW(IEEE802154_TAG,"Print the record abort done."); #endif // CONFIG_IEEE802154_RECORD_ABORT } #endif // CONFIG_IEEE802154_ASSERT @@ -330,43 +329,43 @@ void ieee802154_txrx_statistic_print(void) uint64_t rx_success_nums = s_ieee802154_txrx_statistic.rx.done_nums - s_ieee802154_txrx_statistic.rx.abort.tx_ack_coex_break_nums; - ESP_LOGW(TAG, "+--------------------+-----------------------------------+--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-10s%-15llu%9.2f%%|%-25s%-15llu%9.2f%%|", "", "Done:", s_ieee802154_txrx_statistic.tx.done_nums, tx_done_ratio*100, "Success:", tx_success_nums, tx_success_ratio*100); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_direct_num:", tx_direct_num, tx_direct_num_ratio*100); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_deferred_num:", s_ieee802154_txrx_statistic.tx.deferred_nums, tx_deferred_num_ratio*100); - ESP_LOGW(TAG, "+ +-----------------------------------+--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "rx_ack_coex_break:", s_ieee802154_txrx_statistic.tx.abort.rx_ack_coex_break_nums, tx_abort_rx_ack_coex_break_ratio*100); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "rx_ack_timeout:", s_ieee802154_txrx_statistic.tx.abort.rx_ack_timeout_nums, tx_abort_rx_ack_timeout_ratio*100); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-5s%-15llu|%-10s%-15llu%9.2f%%|%-25s%-15llu%9.2f%%|", "TX:", s_ieee802154_txrx_statistic.tx.nums, "Abort", tx_abort_nums, tx_abort_ratio*100, "tx_coex_break:", s_ieee802154_txrx_statistic.tx.abort.tx_coex_break_nums, tx_abort_tx_coex_break_ratio*100); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_security_error:", s_ieee802154_txrx_statistic.tx.abort.tx_security_error_nums, tx_abort_tx_security_error_ratio*100); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "cca_failed:", s_ieee802154_txrx_statistic.tx.abort.cca_failed_nums, tx_abort_cca_failed_ratio*100); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "cca_busy:", s_ieee802154_txrx_statistic.tx.abort.cca_busy_nums, tx_abort_cca_busy_ratio*100); - ESP_LOGW(TAG, "+--------------------+-----------------------------------+--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-10s%-25llu|%-25s%-25llu|", "", "Done:", s_ieee802154_txrx_statistic.rx.done_nums, "Success:", rx_success_nums); - ESP_LOGW(TAG, "+ +-----------------------------------+--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "tx_ack_coex_break:", s_ieee802154_txrx_statistic.rx.abort.tx_ack_coex_break_nums); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "sfd_timeout:", s_ieee802154_txrx_statistic.rx.abort.sfd_timeout_nums); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "crc_error:", s_ieee802154_txrx_statistic.rx.abort.crc_error_nums); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-10s%-25llu|%-25s%-25llu|", "RX", "Abort", rx_abort_nums, "filter_fail:", s_ieee802154_txrx_statistic.rx.abort.filter_fail_nums); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "no_rss:", s_ieee802154_txrx_statistic.rx.abort.no_rss_nums); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "rx_coex_break:", s_ieee802154_txrx_statistic.rx.abort.rx_coex_break_nums); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "rx_restart:", s_ieee802154_txrx_statistic.rx.abort.rx_restart_nums); - ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); - ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "ed_abort:", s_ieee802154_txrx_statistic.rx.abort.ed_abort_nums); - ESP_LOGW(TAG, "+--------------------+-----------------------------------+--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "+--------------------+-----------------------------------+--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-10s%-15llu%9.2f%%|%-25s%-15llu%9.2f%%|", "", "Done:", s_ieee802154_txrx_statistic.tx.done_nums, tx_done_ratio*100, "Success:", tx_success_nums, tx_success_ratio*100); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_direct_num:", tx_direct_num, tx_direct_num_ratio*100); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_deferred_num:", s_ieee802154_txrx_statistic.tx.deferred_nums, tx_deferred_num_ratio*100); + ESP_LOGW(IEEE802154_TAG, "+ +-----------------------------------+--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "rx_ack_coex_break:", s_ieee802154_txrx_statistic.tx.abort.rx_ack_coex_break_nums, tx_abort_rx_ack_coex_break_ratio*100); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "rx_ack_timeout:", s_ieee802154_txrx_statistic.tx.abort.rx_ack_timeout_nums, tx_abort_rx_ack_timeout_ratio*100); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-5s%-15llu|%-10s%-15llu%9.2f%%|%-25s%-15llu%9.2f%%|", "TX:", s_ieee802154_txrx_statistic.tx.nums, "Abort", tx_abort_nums, tx_abort_ratio*100, "tx_coex_break:", s_ieee802154_txrx_statistic.tx.abort.tx_coex_break_nums, tx_abort_tx_coex_break_ratio*100); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_security_error:", s_ieee802154_txrx_statistic.tx.abort.tx_security_error_nums, tx_abort_tx_security_error_ratio*100); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "cca_failed:", s_ieee802154_txrx_statistic.tx.abort.cca_failed_nums, tx_abort_cca_failed_ratio*100); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "cca_busy:", s_ieee802154_txrx_statistic.tx.abort.cca_busy_nums, tx_abort_cca_busy_ratio*100); + ESP_LOGW(IEEE802154_TAG, "+--------------------+-----------------------------------+--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-10s%-25llu|%-25s%-25llu|", "", "Done:", s_ieee802154_txrx_statistic.rx.done_nums, "Success:", rx_success_nums); + ESP_LOGW(IEEE802154_TAG, "+ +-----------------------------------+--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "tx_ack_coex_break:", s_ieee802154_txrx_statistic.rx.abort.tx_ack_coex_break_nums); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "sfd_timeout:", s_ieee802154_txrx_statistic.rx.abort.sfd_timeout_nums); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "crc_error:", s_ieee802154_txrx_statistic.rx.abort.crc_error_nums); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-10s%-25llu|%-25s%-25llu|", "RX", "Abort", rx_abort_nums, "filter_fail:", s_ieee802154_txrx_statistic.rx.abort.filter_fail_nums); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "no_rss:", s_ieee802154_txrx_statistic.rx.abort.no_rss_nums); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "rx_coex_break:", s_ieee802154_txrx_statistic.rx.abort.rx_coex_break_nums); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "rx_restart:", s_ieee802154_txrx_statistic.rx.abort.rx_restart_nums); + ESP_LOGW(IEEE802154_TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(IEEE802154_TAG, "|%-20s|%-35s|%-25s%-25llu|", "", "", "ed_abort:", s_ieee802154_txrx_statistic.rx.abort.ed_abort_nums); + ESP_LOGW(IEEE802154_TAG, "+--------------------+-----------------------------------+--------------------------------------------------+"); } #endif // CONFIG_IEEE802154_TXRX_STATISTIC diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index 9d18f7ea6d1c..d893cceef6e4 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -5,6 +5,7 @@ */ #include +#include "sdkconfig.h" #include "freertos/portmacro.h" #include "soc/periph_defs.h" #include "soc/soc.h" @@ -26,7 +27,7 @@ #include "esp_attr.h" #include "esp_phy_init.h" -#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_PM_ENABLE #include "esp_pm.h" #include "esp_private/esp_clk.h" #include "esp_private/sleep_retention.h" @@ -36,7 +37,7 @@ #else #define IEEE802154_LINK_OWNER ENTRY(0) | ENTRY(2) #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG -#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE +#endif // CONFIG_PM_ENABLE static bool s_rf_closed = true; #define CCA_DETECTION_TIME 8 @@ -62,6 +63,8 @@ static uint8_t *s_tx_frame = NULL; static uint8_t s_rx_frame[CONFIG_IEEE802154_RX_BUFFER_SIZE + 1][IEEE802154_RX_FRAME_SIZE]; static esp_ieee802154_frame_info_t s_rx_frame_info[CONFIG_IEEE802154_RX_BUFFER_SIZE + 1]; +static bool s_needs_next_operation = false; + static uint8_t s_rx_index = 0; static uint8_t s_enh_ack_frame[128]; static uint8_t s_recent_rx_frame_info_index; @@ -70,7 +73,7 @@ static intr_handle_t s_ieee802154_isr_handle = NULL; static esp_err_t ieee802154_sleep_init(void); static esp_err_t ieee802154_sleep_deinit(void); -static void next_operation(void); +#define NEEDS_NEXT_OPT(a) do {s_needs_next_operation = a;} while(0) static esp_err_t ieee802154_transmit_internal(const uint8_t *frame, bool cca); #if !CONFIG_IEEE802154_TEST @@ -84,10 +87,10 @@ static pending_tx_t s_pending_tx = { 0 }; static void ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info) { // If the RX done packet is written in the stub buffer, drop it silently. - if (s_rx_index == CONFIG_IEEE802154_RX_BUFFER_SIZE) { - esp_rom_printf("receive buffer full, drop the current frame.\n"); - } else { + if (s_rx_index != CONFIG_IEEE802154_RX_BUFFER_SIZE) { // Otherwise, post it to the upper layer. + // Ignore bit8 for the frame length, due to the max frame length is 127 based 802.15.4 spec. + data[0] = data[0] & 0x7f; frame_info->process = true; esp_ieee802154_receive_done(data, frame_info); } @@ -97,7 +100,6 @@ static void ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, e { if (ack && ack_frame_info) { if (s_rx_index == CONFIG_IEEE802154_RX_BUFFER_SIZE) { - esp_rom_printf("receive buffer full, drop the current ack frame.\n"); esp_ieee802154_transmit_failed(frame, ESP_IEEE802154_TX_ERR_NO_ACK); } else { ack_frame_info->process = true; @@ -163,7 +165,6 @@ IEEE802154_STATIC void set_next_rx_buffer(void) { uint8_t* next_rx_buffer = NULL; uint8_t index = 0; - if (s_rx_index != CONFIG_IEEE802154_RX_BUFFER_SIZE && s_rx_frame_info[s_rx_index].process == false) { // If buffer is not full, and current index is empty, set it to hardware. next_rx_buffer = s_rx_frame[s_rx_index]; @@ -186,8 +187,10 @@ IEEE802154_STATIC void set_next_rx_buffer(void) if (!next_rx_buffer) { s_rx_index = CONFIG_IEEE802154_RX_BUFFER_SIZE; next_rx_buffer = s_rx_frame[CONFIG_IEEE802154_RX_BUFFER_SIZE]; +#if CONFIG_IEEE802154_DEBUG + ESP_EARLY_LOGW(IEEE802154_TAG, "Rx buffer full."); +#endif } - ieee802154_ll_set_rx_addr(next_rx_buffer); } @@ -354,6 +357,8 @@ static IRAM_ATTR void next_operation(void) if (s_pending_tx.frame) { // Here the driver needs to recover the setting of rx aborts, see function `ieee802154_transmit`. ieee802154_ll_enable_rx_abort_events(BIT(IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT - 1) | BIT(IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK - 1)); + // Clear the RX abort event again for avoiding the risk if there are still some rx abort events created after last isr process. + ieee802154_ll_clear_events(IEEE802154_EVENT_RX_ABORT); ieee802154_transmit_internal(s_pending_tx.frame, s_pending_tx.cca); s_pending_tx.frame = NULL; } else @@ -375,7 +380,7 @@ static void isr_handle_timer0_done(void) #if !CONFIG_IEEE802154_TEST if (s_ieee802154_state == IEEE802154_STATE_RX_ACK) { esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK); - next_operation(); + NEEDS_NEXT_OPT(true); } #else esp_ieee802154_timer0_done(); @@ -393,23 +398,19 @@ static void isr_handle_timer1_done(void) static IRAM_ATTR void isr_handle_tx_done(void) { event_end_process(); - if (s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK) { - ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); - next_operation(); - } else { - if (s_ieee802154_state == IEEE802154_STATE_TEST_TX) { - ieee802154_transmit_done(s_tx_frame, NULL, NULL); - next_operation(); - } else if (s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA) { - if (ieee802154_frame_is_ack_required(s_tx_frame) && ieee802154_ll_get_rx_auto_ack()) { - ieee802154_set_state(IEEE802154_STATE_RX_ACK); + if (s_ieee802154_state == IEEE802154_STATE_TEST_TX) { + ieee802154_transmit_done(s_tx_frame, NULL, NULL); + NEEDS_NEXT_OPT(true); + } else if (s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA) { + if (ieee802154_frame_is_ack_required(s_tx_frame) && ieee802154_ll_get_rx_auto_ack()) { + ieee802154_set_state(IEEE802154_STATE_RX_ACK); #if !CONFIG_IEEE802154_TEST - receive_ack_timeout_timer_start(200000); // 200ms for receive ack timeout + receive_ack_timeout_timer_start(200000); // 200ms for receive ack timeout #endif - } else { - ieee802154_transmit_done(s_tx_frame, NULL, NULL); - next_operation(); - } + NEEDS_NEXT_OPT(false); + } else { + ieee802154_transmit_done(s_tx_frame, NULL, NULL); + NEEDS_NEXT_OPT(true); } } } @@ -425,6 +426,7 @@ static IRAM_ATTR void isr_handle_rx_done(void) // auto tx ack only works for the frame with version 0b00 and 0b01 s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]); ieee802154_set_state(IEEE802154_STATE_TX_ACK); + NEEDS_NEXT_OPT(false); } else if (ieee802154_frame_is_ack_required(s_rx_frame[s_rx_index]) && ieee802154_frame_get_version(s_rx_frame[s_rx_index]) == IEEE802154_FRAME_VERSION_2 && ieee802154_ll_get_tx_enhance_ack()) { s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]); @@ -438,15 +440,16 @@ static IRAM_ATTR void isr_handle_rx_done(void) ieee802154_ll_enhack_generate_done_notify(); ieee802154_set_state(IEEE802154_STATE_TX_ENH_ACK); #endif + NEEDS_NEXT_OPT(false); } else { // Stop current process if generator returns errors. ieee802154_set_cmd(IEEE802154_CMD_STOP); ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); - next_operation(); + NEEDS_NEXT_OPT(true); } } else { ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); - next_operation(); + NEEDS_NEXT_OPT(true); } } } @@ -454,7 +457,7 @@ static IRAM_ATTR void isr_handle_rx_done(void) static IRAM_ATTR void isr_handle_ack_tx_done(void) { ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); - next_operation(); + NEEDS_NEXT_OPT(true); } static IRAM_ATTR void isr_handle_ack_rx_done(void) @@ -463,10 +466,10 @@ static IRAM_ATTR void isr_handle_ack_rx_done(void) ieee802154_ll_disable_events(IEEE802154_EVENT_TIMER0_OVERFLOW); ieee802154_rx_frame_info_update(); ieee802154_transmit_done(s_tx_frame, (uint8_t *)&s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); - next_operation(); + NEEDS_NEXT_OPT(true); } -static IRAM_ATTR void isr_handle_rx_abort(void) +static IRAM_ATTR void isr_handle_rx_phase_rx_abort(void) { event_end_process(); uint32_t rx_status = ieee802154_ll_get_rx_status(); @@ -484,11 +487,6 @@ static IRAM_ATTR void isr_handle_rx_abort(void) case IEEE802154_RX_ABORT_BY_NO_RSS: case IEEE802154_RX_ABORT_BY_UNEXPECTED_ACK: case IEEE802154_RX_ABORT_BY_RX_RESTART: - IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX); -#if CONFIG_IEEE802154_TEST - esp_ieee802154_receive_failed(rx_status); -#endif - break; case IEEE802154_RX_ABORT_BY_COEX_BREAK: IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX); #if CONFIG_IEEE802154_TEST @@ -501,6 +499,38 @@ static IRAM_ATTR void isr_handle_rx_abort(void) esp_ieee802154_ed_failed(rx_status); break; case IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT: + case IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK: + case IEEE802154_RX_ABORT_BY_ENHACK_SECURITY_ERROR: + return; + default: + IEEE802154_ASSERT(false); + } + NEEDS_NEXT_OPT(true); +} + +static IRAM_ATTR void isr_handle_tx_ack_phase_rx_abort(void) +{ + event_end_process(); +#if CONFIG_IEEE802154_TEST + uint32_t rx_status = ieee802154_ll_get_rx_status(); +#endif + ieee802154_ll_rx_abort_reason_t rx_abort_reason = ieee802154_ll_get_rx_abort_reason(); + switch (rx_abort_reason) { + case IEEE802154_RX_ABORT_BY_RX_STOP: + case IEEE802154_RX_ABORT_BY_TX_ACK_STOP: + case IEEE802154_RX_ABORT_BY_ED_STOP: + case IEEE802154_RX_ABORT_BY_SFD_TIMEOUT: + case IEEE802154_RX_ABORT_BY_CRC_ERROR: + case IEEE802154_RX_ABORT_BY_INVALID_LEN: + case IEEE802154_RX_ABORT_BY_FILTER_FAIL: + case IEEE802154_RX_ABORT_BY_NO_RSS: + case IEEE802154_RX_ABORT_BY_UNEXPECTED_ACK: + case IEEE802154_RX_ABORT_BY_RX_RESTART: + case IEEE802154_RX_ABORT_BY_COEX_BREAK: + case IEEE802154_RX_ABORT_BY_ED_ABORT: + case IEEE802154_RX_ABORT_BY_ED_COEX_REJECT: + return; + case IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT: case IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK: IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); #if !CONFIG_IEEE802154_TEST @@ -520,7 +550,7 @@ static IRAM_ATTR void isr_handle_rx_abort(void) default: IEEE802154_ASSERT(false); } - next_operation(); + NEEDS_NEXT_OPT(true); } static IRAM_ATTR void isr_handle_tx_abort(void) @@ -542,12 +572,14 @@ static IRAM_ATTR void isr_handle_tx_abort(void) case IEEE802154_TX_ABORT_BY_RX_ACK_RESTART: IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_INVALID_ACK); + NEEDS_NEXT_OPT(false); break; + // The above events are only used in test mode. case IEEE802154_TX_ABORT_BY_RX_ACK_TIMEOUT: IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK); ieee802154_ll_disable_events(IEEE802154_EVENT_TIMER0_OVERFLOW); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK); - next_operation(); + NEEDS_NEXT_OPT(true); break; case IEEE802154_TX_ABORT_BY_TX_COEX_BREAK: #if CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE @@ -556,22 +588,22 @@ static IRAM_ATTR void isr_handle_tx_abort(void) IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA); IEEE802154_TX_BREAK_COEX_NUMS_UPDATE(); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_COEXIST); - next_operation(); + NEEDS_NEXT_OPT(true); break; case IEEE802154_TX_ABORT_BY_TX_SECURITY_ERROR: IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_SECURITY); - next_operation(); + NEEDS_NEXT_OPT(true); break; case IEEE802154_TX_ABORT_BY_CCA_FAILED: IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_CCA); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_ABORT); - next_operation(); + NEEDS_NEXT_OPT(true); break; case IEEE802154_TX_ABORT_BY_CCA_BUSY: IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_CCA); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_CCA_BUSY); - next_operation(); + NEEDS_NEXT_OPT(true); break; default: IEEE802154_ASSERT(false); @@ -587,17 +619,33 @@ static IRAM_ATTR void isr_handle_ed_done(void) esp_ieee802154_energy_detect_done(ieee802154_ll_get_ed_rss()); } - next_operation(); + NEEDS_NEXT_OPT(true); +} + +IEEE802154_STATIC IRAM_ATTR void ieee802154_enter_critical(void) +{ + portENTER_CRITICAL(&s_ieee802154_spinlock); +} + +IEEE802154_STATIC IRAM_ATTR void ieee802154_exit_critical(void) +{ + portEXIT_CRITICAL(&s_ieee802154_spinlock); } static void ieee802154_isr(void *arg) { + ieee802154_enter_critical(); ieee802154_ll_events events = ieee802154_ll_get_events(); IEEE802154_PROBE(events); ieee802154_ll_clear_events(events); + if (events & IEEE802154_EVENT_RX_ABORT) { + // First phase rx abort process, will clear RX_ABORT event in second. + isr_handle_rx_phase_rx_abort(); + } + if (events & IEEE802154_EVENT_RX_SFD_DONE) { // IEEE802154_STATE_TX && IEEE802154_STATE_TX_CCA && IEEE802154_STATE_TX_ENH_ACK for isr processing delay IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); @@ -618,7 +666,7 @@ static void ieee802154_isr(void *arg) } if (events & IEEE802154_EVENT_TX_DONE) { - IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX); isr_handle_tx_done(); @@ -652,8 +700,8 @@ static void ieee802154_isr(void *arg) } if (events & IEEE802154_EVENT_RX_ABORT) { - isr_handle_rx_abort(); - + // Second phase rx abort process, clears RX_ABORT event. + isr_handle_tx_ack_phase_rx_abort(); events &= (uint16_t)(~IEEE802154_EVENT_RX_ABORT); } @@ -688,20 +736,14 @@ static void ieee802154_isr(void *arg) events &= (uint16_t)(~IEEE802154_EVENT_TIMER1_OVERFLOW); } + if (s_needs_next_operation) { + next_operation(); + s_needs_next_operation = false; + } // all events should be handled IEEE802154_ASSERT(events == 0); - -} - -IEEE802154_STATIC IRAM_ATTR void ieee802154_enter_critical(void) -{ - portENTER_CRITICAL(&s_ieee802154_spinlock); -} - -IEEE802154_STATIC IRAM_ATTR void ieee802154_exit_critical(void) -{ - portEXIT_CRITICAL(&s_ieee802154_spinlock); + ieee802154_exit_critical(); } void ieee802154_enable(void) @@ -815,6 +857,7 @@ static inline esp_err_t ieee802154_transmit_internal(const uint8_t *frame, bool esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca) { + ESP_RETURN_ON_FALSE(frame[0] <= 127, ESP_ERR_INVALID_ARG, IEEE802154_TAG, "Invalid frame length."); #if !CONFIG_IEEE802154_TEST ieee802154_enter_critical(); if ((s_ieee802154_state == IEEE802154_STATE_RX && ieee802154_ll_is_current_rx_frame()) @@ -843,6 +886,7 @@ static inline bool is_target_time_expired(uint32_t target, uint32_t now) esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time) { + ESP_RETURN_ON_FALSE(frame[0] <= 127, ESP_ERR_INVALID_ARG, IEEE802154_TAG, "Invalid frame length."); uint32_t tx_target_time; uint32_t current_time; IEEE802154_RF_ENABLE(); @@ -901,11 +945,11 @@ esp_err_t ieee802154_receive_at(uint32_t time) uint32_t rx_target_time = time - IEEE802154_RX_RAMPUP_TIME_US; uint32_t current_time; IEEE802154_RF_ENABLE(); + ieee802154_enter_critical(); rx_init(); IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_RX_AT); set_next_rx_buffer(); ieee802154_set_state(IEEE802154_STATE_RX); - ieee802154_enter_critical(); ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL1, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_RX_START); current_time = (uint32_t)esp_timer_get_time(); ieee802154_timer0_set_threshold((is_target_time_expired(rx_target_time, current_time) ? 0 : (rx_target_time - current_time))); //uint: 1us @@ -914,24 +958,27 @@ esp_err_t ieee802154_receive_at(uint32_t time) return ESP_OK; } -#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_PM_ENABLE static esp_err_t ieee802154_sleep_retention_init(void *arg) { + esp_err_t err = ESP_OK; +#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE #define N_REGS_IEEE802154() (((IEEE802154_MAC_DATE_REG - IEEE802154_REG_BASE) / 4) + 1) const static sleep_retention_entries_config_t ieee802154_mac_regs_retention[] = { [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_IEEE802154_LINK(0x00), IEEE802154_REG_BASE, IEEE802154_REG_BASE, N_REGS_IEEE802154(), 0, 0), .owner = IEEE802154_LINK_OWNER }, }; - esp_err_t err = sleep_retention_entries_create(ieee802154_mac_regs_retention, ARRAY_SIZE(ieee802154_mac_regs_retention), REGDMA_LINK_PRI_IEEE802154, SLEEP_RETENTION_MODULE_802154_MAC); + err = sleep_retention_entries_create(ieee802154_mac_regs_retention, ARRAY_SIZE(ieee802154_mac_regs_retention), REGDMA_LINK_PRI_IEEE802154, SLEEP_RETENTION_MODULE_802154_MAC); ESP_RETURN_ON_ERROR(err, IEEE802154_TAG, "failed to allocate memory for ieee802154 mac retention"); ESP_LOGD(IEEE802154_TAG, "ieee802154 mac sleep retention initialization"); +#endif return err; } -#endif +#endif // CONFIG_PM_ENABLE static esp_err_t ieee802154_sleep_init(void) { esp_err_t err = ESP_OK; -#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_PM_ENABLE sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = ieee802154_sleep_retention_init, .arg = NULL } }, .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) | BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) @@ -945,14 +992,14 @@ static esp_err_t ieee802154_sleep_init(void) sleep_modem_register_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, sleep_modem_mac_bb_power_up_prepare); #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD -#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE +#endif // CONFIG_PM_ENABLE return err; } static esp_err_t ieee802154_sleep_deinit(void) { esp_err_t err = ESP_OK; -#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_PM_ENABLE err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_802154_MAC); if (err == ESP_OK) { err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_802154_MAC); @@ -961,7 +1008,7 @@ static esp_err_t ieee802154_sleep_deinit(void) sleep_modem_unregister_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, sleep_modem_mac_bb_power_up_prepare); #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD -#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE +#endif // CONFIG_PM_ENABLE return err; } diff --git a/components/ieee802154/driver/esp_ieee802154_frame.c b/components/ieee802154/driver/esp_ieee802154_frame.c index 8a6468be65ba..e32e338ae0e6 100644 --- a/components/ieee802154/driver/esp_ieee802154_frame.c +++ b/components/ieee802154/driver/esp_ieee802154_frame.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,8 +9,7 @@ #include "esp_attr.h" #include "esp_ieee802154_dev.h" #include "esp_ieee802154_frame.h" - -static const char *TAG = "ieee802154 frame"; +#include "esp_ieee802154_util.h" IEEE802154_STATIC IEEE802154_INLINE bool is_security_enabled(const uint8_t *frame) { @@ -59,7 +58,7 @@ IEEE802154_STATIC bool is_dst_panid_present(const uint8_t *frame) uint8_t src_mode = src_addr_mode(frame); bool panid_compression = is_panid_compression(frame); - if (dst_mode != IEEE802154_FRAME_DST_MODE_NONE) { // dest address is present/short/extented + if (dst_mode != IEEE802154_FRAME_DST_MODE_NONE) { // dest address is present/short/extended if ((src_mode == IEEE802154_FRAME_SRC_MODE_NONE && panid_compression) || (dst_mode == IEEE802154_FRAME_DST_MODE_EXT && src_mode == IEEE802154_FRAME_SRC_MODE_EXT && panid_compression)) { dst_panid_present = false; @@ -163,12 +162,12 @@ IEEE802154_STATIC IRAM_ATTR uint8_t ieee802154_frame_address_size(const uint8_t IEEE802154_STATIC uint8_t ieee802154_frame_security_header_offset(const uint8_t *frame) { - ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, TAG, "invalid frame type"); + ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, IEEE802154_TAG, "invalid frame type"); uint8_t offset = ieee802154_frame_address_offset(frame); uint8_t address_size = ieee802154_frame_address_size(frame); - ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, TAG, "invalid offset"); - ESP_RETURN_ON_FALSE_ISR(address_size != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, TAG, "invalid offset"); + ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_TAG, "invalid offset"); + ESP_RETURN_ON_FALSE_ISR(address_size != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_TAG, "invalid offset"); offset += address_size; @@ -177,12 +176,12 @@ IEEE802154_STATIC uint8_t ieee802154_frame_security_header_offset(const uint8_t IEEE802154_STATIC uint8_t ieee802154_frame_get_security_field_len(const uint8_t *frame) { - ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_OFFSET, TAG, "invalid frame type"); + ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_TAG, "invalid frame type"); uint8_t security_field_len = 0; uint8_t offset = ieee802154_frame_security_header_offset(frame); - ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, TAG, "invalid offset"); + ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_TAG, "invalid offset"); security_field_len += IEEE802154_FRAME_SE_HEAD_SIZE; uint8_t security_header = frame[offset]; @@ -315,13 +314,13 @@ bool IEEE802154_INLINE ieee802154_frame_is_ack_required(const uint8_t *frame) uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr) { - ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, TAG, "invalid frame type"); + ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, IEEE802154_TAG, "invalid frame type"); uint8_t offset = ieee802154_frame_address_offset(frame); uint8_t dst_mode = dst_addr_mode(frame); uint8_t addr_size; - ESP_RETURN_ON_FALSE_ISR(dst_mode == IEEE802154_FRAME_DST_MODE_SHORT || dst_mode == IEEE802154_FRAME_DST_MODE_EXT, dst_mode, TAG, "invalid address mode"); + ESP_RETURN_ON_FALSE_ISR(dst_mode == IEEE802154_FRAME_DST_MODE_SHORT || dst_mode == IEEE802154_FRAME_DST_MODE_EXT, dst_mode, IEEE802154_TAG, "invalid address mode"); addr_size = (dst_mode == IEEE802154_FRAME_DST_MODE_SHORT) ? IEEE802154_FRAME_SHORT_ADDR_SIZE : IEEE802154_FRAME_EXT_ADDR_SIZE; @@ -336,14 +335,14 @@ uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr) uint8_t ieee802154_frame_get_src_addr(const uint8_t *frame, uint8_t *addr) { - ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, TAG, "invalid frame type"); + ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, IEEE802154_TAG, "invalid frame type"); uint8_t offset = ieee802154_frame_address_offset(frame); uint8_t dst_mode = dst_addr_mode(frame); uint8_t src_mode = src_addr_mode(frame); uint8_t addr_size; - ESP_RETURN_ON_FALSE_ISR(src_mode == IEEE802154_FRAME_SRC_MODE_SHORT || src_mode == IEEE802154_FRAME_SRC_MODE_EXT, src_mode, TAG, "invalid address mode"); + ESP_RETURN_ON_FALSE_ISR(src_mode == IEEE802154_FRAME_SRC_MODE_SHORT || src_mode == IEEE802154_FRAME_SRC_MODE_EXT, src_mode, IEEE802154_TAG, "invalid address mode"); addr_size = (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT) ? IEEE802154_FRAME_SHORT_ADDR_SIZE : IEEE802154_FRAME_EXT_ADDR_SIZE; diff --git a/components/ieee802154/driver/esp_ieee802154_timer.c b/components/ieee802154/driver/esp_ieee802154_timer.c index fb564cbcb58b..e2bff1a59be1 100644 --- a/components/ieee802154/driver/esp_ieee802154_timer.c +++ b/components/ieee802154/driver/esp_ieee802154_timer.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,8 +8,7 @@ #include "hal/ieee802154_ll.h" #include "esp_check.h" #include "esp_ieee802154_timer.h" - -static const char *TAG = "ieee802154_timer"; +#include "esp_ieee802154_util.h" void ieee802154_timer0_start(void) { @@ -23,7 +22,7 @@ void ieee802154_timer0_stop(void) esp_err_t ieee802154_timer0_set_threshold(uint32_t value) { - ESP_RETURN_ON_FALSE((value < IEEE802154_TIMER0_THRESHOLD), ESP_ERR_INVALID_ARG, TAG, "invalid timer0 threshold\r\n"); + ESP_RETURN_ON_FALSE((value < IEEE802154_TIMER0_THRESHOLD), ESP_ERR_INVALID_ARG, IEEE802154_TAG, "invalid timer0 threshold"); ieee802154_ll_timer0_set_threshold(value); @@ -47,7 +46,7 @@ void ieee802154_timer1_stop(void) esp_err_t ieee802154_timer1_set_threshold(uint32_t value) { - ESP_RETURN_ON_FALSE((value < IEEE802154_TIMER1_THRESHOLD), ESP_ERR_INVALID_ARG, TAG, "invalid timer1 threshold\r\n"); + ESP_RETURN_ON_FALSE((value < IEEE802154_TIMER1_THRESHOLD), ESP_ERR_INVALID_ARG, IEEE802154_TAG, "invalid timer1 threshold"); ieee802154_ll_timer1_set_threshold(value); diff --git a/components/ieee802154/include/esp_ieee802154.h b/components/ieee802154/include/esp_ieee802154.h index 27db5ca49b27..51adf6ce00bb 100644 --- a/components/ieee802154/include/esp_ieee802154.h +++ b/components/ieee802154/include/esp_ieee802154.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -136,8 +136,12 @@ esp_err_t esp_ieee802154_receive(void); * |-----------------------------------------------------------------------| * @param[in] cca Perform CCA before transmission if it's true, otherwise transmit the frame directly. * + * @note During transmission, the hardware calculates the FCS, and send it over the air right after the MAC payload, + * so you just need to prepare the length, mac header and mac payload content. + * * @return * - ESP_OK on success. + * - ESP_ERR_INVALID_ARG on an invalid frame. * - ESP_FAIL on failure due to invalid state. * */ @@ -477,6 +481,10 @@ esp_err_t esp_ieee802154_receive_handle_done(const uint8_t *frame); * |-----------------------------------------------------------------------| * @param[in] frame_info More information of the received frame, refer to esp_ieee802154_frame_info_t. * + * @note During receiving, the hardware calculates the FCS of the received frame, and may drop it if the FCS doesn't match, only the valid + * frames will be received and notified by esp_ieee802154_receive_done(). Please note that the FCS field is replaced by RSSI and LQI + * value of the received frame. + * */ extern void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info); @@ -547,6 +555,7 @@ esp_err_t esp_ieee802154_receive_at(uint32_t time); * * @return * - ESP_OK on success. + * - ESP_ERR_INVALID_ARG on an invalid frame. * - ESP_FAIL on failure due to invalid state. * */ diff --git a/components/ieee802154/private_include/esp_ieee802154_dev.h b/components/ieee802154/private_include/esp_ieee802154_dev.h index 6dada29c56ca..9eddc87a3ff4 100644 --- a/components/ieee802154/private_include/esp_ieee802154_dev.h +++ b/components/ieee802154/private_include/esp_ieee802154_dev.h @@ -19,8 +19,6 @@ extern "C" { #endif -#define IEEE802154_TAG "ieee802154" - // These three macros are in microseconds, used for transmit_at #define IEEE802154_ED_TRIG_TX_RAMPUP_TIME_US 256 #define IEEE802154_TX_RAMPUP_TIME_US 98 @@ -95,6 +93,7 @@ esp_err_t ieee802154_mac_deinit(void); * * @return * - ESP_OK on success. + * - ESP_ERR_INVALID_ARG on an invalid frame. * - ESP_FAIL on failure due to invalid state. * */ @@ -132,6 +131,7 @@ esp_err_t ieee802154_receive_handle_done(const uint8_t* frame); * * @return * - ESP_OK on success. + * - ESP_ERR_INVALID_ARG on an invalid frame. * - ESP_FAIL on failure due to invalid state. * * Note: The transmit result will be reported via esp_ieee802154_transmit_done() diff --git a/components/ieee802154/private_include/esp_ieee802154_util.h b/components/ieee802154/private_include/esp_ieee802154_util.h index 44ca5980619b..7949e5286da6 100644 --- a/components/ieee802154/private_include/esp_ieee802154_util.h +++ b/components/ieee802154/private_include/esp_ieee802154_util.h @@ -17,6 +17,8 @@ extern "C" { #endif +#define IEEE802154_TAG "ieee802154" + #if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE #define IEEE802154_RF_ENABLE() ieee802154_rf_enable() #define IEEE802154_RF_DISABLE() ieee802154_rf_disable() diff --git a/components/json/cJSON b/components/json/cJSON index 87d8f0961a01..acc76239bee0 160000 --- a/components/json/cJSON +++ b/components/json/cJSON @@ -1 +1 @@ -Subproject commit 87d8f0961a01bf09bef98ff89bae9fdec42181ee +Subproject commit acc76239bee01d8e9c858ae2cab296704e52d916 diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index d0526fd4badd..448588615353 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -102,6 +102,10 @@ if(CONFIG_LWIP_ENABLE) "port/sockets_ext.c" "port/freertos/sys_arch.c") + if(CONFIG_LWIP_NETIF_API) + list(APPEND srcs "port/if_index.c") + endif() + if(CONFIG_LWIP_PPP_SUPPORT) list(APPEND srcs "lwip/src/netif/ppp/auth.c" diff --git a/components/lwip/apps/dhcpserver/dhcpserver.c b/components/lwip/apps/dhcpserver/dhcpserver.c index 112bdf070b41..b65168064349 100644 --- a/components/lwip/apps/dhcpserver/dhcpserver.c +++ b/components/lwip/apps/dhcpserver/dhcpserver.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1006,7 +1006,7 @@ static s16_t parse_msg(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len) dhcps->client_address.addr = dhcps->client_address_plus.addr; } - if (flag == false) { // search the fisrt unused ip + if (flag == false) { // search the first unused ip if (first_address.addr < pdhcps_pool->ip.addr) { flag = true; } else { @@ -1399,7 +1399,7 @@ static void kill_oldest_dhcps_pool(dhcps_t *dhcps) assert(pre != NULL && pre->pnext != NULL); // Expect the list to have at least 2 nodes p = pre->pnext; minpre = pre; - minp = p; + minp = pre; while (p != NULL) { pdhcps_pool = p->pnode; @@ -1413,8 +1413,11 @@ static void kill_oldest_dhcps_pool(dhcps_t *dhcps) pre = p; p = p->pnext; } - - minpre->pnext = minp->pnext; + if (minp == dhcps->plist) { + dhcps->plist = minp->pnext; + } else { + minpre->pnext = minp->pnext; + } free(minp->pnode); minp->pnode = NULL; free(minp); diff --git a/components/lwip/port/if_index.c b/components/lwip/port/if_index.c new file mode 100644 index 000000000000..d7dcf25e7175 --- /dev/null +++ b/components/lwip/port/if_index.c @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "lwip/if_api.h" + +unsigned int if_nametoindex(const char *ifname) +{ + return lwip_if_nametoindex(ifname); +} + +char *if_indextoname(unsigned int ifindex, char *ifname) +{ + return lwip_if_indextoname(ifindex, ifname); +} diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 86d49803fdf4..ad0ca7151dab 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -200,6 +200,9 @@ endif() if(SHA_PERIPHERAL_TYPE STREQUAL "dma" OR AES_PERIPHERAL_TYPE STREQUAL "dma") target_link_libraries(mbedcrypto PRIVATE idf::esp_mm) if(CONFIG_SOC_SHA_GDMA OR CONFIG_SOC_AES_GDMA) + if(CONFIG_SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT) + target_link_libraries(mbedcrypto PRIVATE idf::bootloader_support) + endif() target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/crypto_shared_gdma/esp_crypto_shared_gdma.c") endif() endif() diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index 09bba150d0d8..72aa687352a4 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 09bba150d0d822aad2e58d71723f5407da5c21e0 +Subproject commit 72aa687352a469044cbb946f3fdb261430e41ce1 diff --git a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c index bcf18069b4f4..c5231d5a7a75 100644 --- a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c +++ b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c @@ -8,7 +8,6 @@ #include "esp_attr.h" #include "esp_cache.h" #include "esp_check.h" -#include "esp_dma_utils.h" #include "esp_err.h" #include "esp_heap_caps.h" #include "esp_intr_alloc.h" @@ -16,6 +15,8 @@ #include "esp_memory_utils.h" #include "esp_private/esp_cache_private.h" #include "esp_private/periph_ctrl.h" +#include "soc/soc_caps.h" +#include "sdkconfig.h" #if CONFIG_PM_ENABLE #include "esp_pm.h" @@ -36,10 +37,19 @@ #include "aes/esp_aes_gcm.h" #endif +#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT +#include "esp_flash_encrypt.h" +#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ + /* Max size of each chunk to process when output buffer is in unaligned external ram must be a multiple of block size */ +#if (CONFIG_IDF_TARGET_ESP32P4 && CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE) +/* As P4 has larger memory than other targets, thus we can support a larger chunk write size */ +#define AES_MAX_CHUNK_WRITE_SIZE 8*1024 +#else #define AES_MAX_CHUNK_WRITE_SIZE 1600 +#endif /* Input over this length will yield and wait for interrupt instead of busy-waiting, 30000 bytes is approx 0.5 ms */ @@ -163,6 +173,26 @@ static int esp_aes_dma_wait_complete(bool use_intr, crypto_dma_desc_t *output_de return 0; } +static inline size_t get_cache_line_size(const void *addr) +{ + esp_err_t ret = ESP_FAIL; + size_t cache_line_size = 0; + +#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE) + if (esp_ptr_external_ram(addr)) { + ret = esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &cache_line_size); + } else +#endif + { + ret = esp_cache_get_alignment(MALLOC_CAP_DMA, &cache_line_size); + } + + if (ret != ESP_OK) { + return 0; + } + + return cache_line_size; +} /* Output buffers in external ram needs to be 16-byte aligned and DMA can't access input in the iCache mem range, reallocate them into internal memory and encrypt in chunks to avoid @@ -176,14 +206,32 @@ static int esp_aes_process_dma_ext_ram(esp_aes_context *ctx, const unsigned char size_t chunk_len; int ret = 0; int offset = 0; + uint32_t input_heap_caps = MALLOC_CAP_DMA; + uint32_t output_heap_caps = MALLOC_CAP_DMA; unsigned char *input_buf = NULL; unsigned char *output_buf = NULL; const unsigned char *dma_input; chunk_len = MIN(AES_MAX_CHUNK_WRITE_SIZE, len); - if (realloc_input) { - input_buf = heap_caps_malloc(chunk_len, MALLOC_CAP_DMA); + size_t input_alignment = 1; + size_t output_alignment = 1; +/* When AES-DMA operations are carried out using external memory with external memory encryption enabled, + we need to make sure that the addresses and the sizes of the buffers on which the DMA operates are 16 byte-aligned. */ +#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT + if (esp_flash_encryption_enabled()) { + if (esp_ptr_external_ram(input) || esp_ptr_external_ram(output) || esp_ptr_in_drom(input) || esp_ptr_in_drom(output)) { + input_alignment = MAX(get_cache_line_size(input), SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT); + output_alignment = MAX(get_cache_line_size(output), SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT); + + input_heap_caps = MALLOC_CAP_8BIT | (esp_ptr_external_ram(input) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + output_heap_caps = MALLOC_CAP_8BIT | (esp_ptr_external_ram(output) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + } + } +#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ + + if (realloc_input) { + input_buf = heap_caps_aligned_alloc(input_alignment, chunk_len, input_heap_caps); if (input_buf == NULL) { mbedtls_platform_zeroize(output, len); ESP_LOGE(TAG, "Failed to allocate memory"); @@ -192,8 +240,7 @@ static int esp_aes_process_dma_ext_ram(esp_aes_context *ctx, const unsigned char } if (realloc_output) { - output_buf = heap_caps_malloc(chunk_len, MALLOC_CAP_DMA); - + output_buf = heap_caps_aligned_alloc(output_alignment, chunk_len, output_heap_caps); if (output_buf == NULL) { mbedtls_platform_zeroize(output, len); ESP_LOGE(TAG, "Failed to allocate memory"); @@ -275,37 +322,10 @@ static inline void dma_desc_append(crypto_dma_desc_t **head, crypto_dma_desc_t * static inline void *aes_dma_calloc(size_t num, size_t size, uint32_t caps, size_t *actual_size) { - void *ptr = NULL; - esp_dma_mem_info_t dma_mem_info = { - .extra_heap_caps = caps, - .dma_alignment_bytes = DMA_DESC_MEM_ALIGN_SIZE, - }; - esp_dma_capable_calloc(num, size, &dma_mem_info, &ptr, actual_size); - return ptr; + return heap_caps_aligned_calloc(DMA_DESC_MEM_ALIGN_SIZE, num, size, caps | MALLOC_CAP_DMA | MALLOC_CAP_8BIT); } -static inline size_t get_cache_line_size(const void *addr) -{ - esp_err_t ret = ESP_FAIL; - size_t cache_line_size = 0; - -#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE) - if (esp_ptr_external_ram(addr)) { - ret = esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &cache_line_size); - } else -#endif - { - ret = esp_cache_get_alignment(MALLOC_CAP_DMA, &cache_line_size); - } - - if (ret != ESP_OK) { - return 0; - } - - return cache_line_size; -} - -static inline esp_err_t dma_desc_link(crypto_dma_desc_t *dmadesc, size_t crypto_dma_desc_num, size_t cache_line_size) +static inline esp_err_t dma_desc_link(crypto_dma_desc_t *dmadesc, size_t crypto_dma_desc_num) { esp_err_t ret = ESP_OK; for (int i = 0; i < crypto_dma_desc_num; i++) { @@ -314,7 +334,8 @@ static inline esp_err_t dma_desc_link(crypto_dma_desc_t *dmadesc, size_t crypto_ #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE /* Write back both input buffers and output buffers to clear any cache dirty bit if set If we want to remove `ESP_CACHE_MSYNC_FLAG_UNALIGNED` aligned flag then we need to pass - cache msync size = ALIGN_UP(dma_desc.size, cache_line_size), instead of dma_desc.size + cache msync size = ALIGN_UP(dma_desc.size, cache_line_size), where cache_line_size is the + the cache line size coressponding to the buffer that is being synced, instead of dma_desc.size Keeping the `ESP_CACHE_MSYNC_FLAG_UNALIGNED` flag just because it should not look like we are syncing extra bytes due to ALIGN_UP'ed size but just the number of bytes that are needed in the operation. */ @@ -323,7 +344,7 @@ static inline esp_err_t dma_desc_link(crypto_dma_desc_t *dmadesc, size_t crypto_ return ret; } } - ret = esp_cache_msync(dmadesc, ALIGN_UP(crypto_dma_desc_num * sizeof(crypto_dma_desc_t), cache_line_size), ESP_CACHE_MSYNC_FLAG_DIR_C2M); + ret = esp_cache_msync(dmadesc, crypto_dma_desc_num * sizeof(crypto_dma_desc_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); #else } #endif @@ -404,7 +425,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le dma_descs_needed = (unaligned_start_bytes ? 1 : 0) + dma_desc_get_required_num(aligned_block_bytes, max_desc_size) + (unaligned_end_bytes ? 1 : 0); /* Allocate memory for DMA descriptors of total size aligned up to a multiple of cache line size */ - dma_descriptors = (crypto_dma_desc_t *) aes_dma_calloc(dma_descs_needed, sizeof(crypto_dma_desc_t), MALLOC_CAP_DMA, NULL); + dma_descriptors = (crypto_dma_desc_t *) aes_dma_calloc(dma_descs_needed, sizeof(crypto_dma_desc_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL, NULL); if (dma_descriptors == NULL) { ESP_LOGE(TAG, "Failed to allocate memory for the array of DMA descriptors"); return ESP_FAIL; @@ -413,7 +434,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le size_t populated_dma_descs = 0; if (unaligned_start_bytes) { - start_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS, NULL); + start_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS | (esp_ptr_external_ram(buffer) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_INTERNAL) , NULL); if (start_alignment_stream_buffer == NULL) { ESP_LOGE(TAG, "Failed to allocate memory for start alignment buffer"); return ESP_FAIL; @@ -435,7 +456,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le } if (unaligned_end_bytes) { - end_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS, NULL); + end_alignment_stream_buffer = aes_dma_calloc(alignment_buffer_size, sizeof(uint8_t), AES_DMA_ALLOC_CAPS | (esp_ptr_external_ram(buffer) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_INTERNAL), NULL); if (end_alignment_stream_buffer == NULL) { ESP_LOGE(TAG, "Failed to allocate memory for end alignment buffer"); return ESP_FAIL; @@ -450,7 +471,7 @@ static esp_err_t generate_descriptor_list(const uint8_t *buffer, const size_t le populated_dma_descs += (unaligned_end_bytes ? 1 : 0); } - if (dma_desc_link(dma_descriptors, dma_descs_needed, cache_line_size) != ESP_OK) { + if (dma_desc_link(dma_descriptors, dma_descs_needed) != ESP_OK) { ESP_LOGE(TAG, "DMA descriptors cache sync C2M failed"); return ESP_FAIL; } @@ -499,6 +520,20 @@ int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsign return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; } +#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT + if (esp_flash_encryption_enabled()) { + if (esp_ptr_external_ram(input) || esp_ptr_external_ram(output) || esp_ptr_in_drom(input) || esp_ptr_in_drom(output)) { + if (((intptr_t)(input) & (SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT - 1)) != 0) { + input_needs_realloc = true; + } + + if (((intptr_t)(output) & (SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT - 1)) != 0) { + output_needs_realloc = true; + } + } + } +#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ + /* DMA cannot access memory in the iCache range, copy input to internal ram */ if (!s_check_dma_capable(input)) { input_needs_realloc = true; @@ -581,7 +616,8 @@ int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsign } #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - if (esp_cache_msync(output_desc, ALIGN_UP(output_dma_desc_num * sizeof(crypto_dma_desc_t), output_cache_line_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C) != ESP_OK) { + size_t output_desc_cache_line_size = get_cache_line_size(output_desc); + if (esp_cache_msync(output_desc, ALIGN_UP(output_dma_desc_num * sizeof(crypto_dma_desc_t), output_desc_cache_line_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C) != ESP_OK) { ESP_LOGE(TAG, "Output DMA descriptor cache sync M2C failed"); ret = -1; goto cleanup; @@ -800,7 +836,8 @@ int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, un } #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - if (esp_cache_msync(output_desc, ALIGN_UP(output_dma_desc_num * sizeof(crypto_dma_desc_t), output_cache_line_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C) != ESP_OK) { + size_t output_desc_cache_line_size = get_cache_line_size(output_desc); + if (esp_cache_msync(output_desc, ALIGN_UP(output_dma_desc_num * sizeof(crypto_dma_desc_t), output_desc_cache_line_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C) != ESP_OK) { ESP_LOGE(TAG, "Output DMA descriptor cache sync M2C failed"); ret = -1; goto cleanup; diff --git a/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c b/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c index 059ebb738a50..e906b9ac6fc2 100644 --- a/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c +++ b/components/mbedtls/port/crypto_shared_gdma/esp_crypto_shared_gdma.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,13 @@ #include "esp_cache.h" #include "esp_crypto_dma.h" #include "esp_crypto_lock.h" +#include "esp_memory_utils.h" #include "soc/soc_caps.h" +#include "sdkconfig.h" + +#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT +#include "esp_flash_encrypt.h" +#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ #if SOC_AHB_GDMA_VERSION == 1 #include "hal/gdma_ll.h" @@ -67,12 +73,6 @@ static esp_err_t crypto_shared_gdma_init(void) .direction = GDMA_CHANNEL_DIRECTION_RX, }; - gdma_transfer_ability_t transfer_ability = { - .sram_trans_align = 1, - .psram_trans_align = 16, - }; - - ret = crypto_shared_gdma_new_channel(&channel_config_tx, &tx_channel); if (ret != ESP_OK) { goto err; @@ -84,9 +84,13 @@ static esp_err_t crypto_shared_gdma_init(void) goto err; } - - gdma_set_transfer_ability(tx_channel, &transfer_ability); - gdma_set_transfer_ability(rx_channel, &transfer_ability); + gdma_transfer_config_t transfer_cfg = { + .max_data_burst_size = 16, + .access_ext_mem = true, // crypto peripheral may want to access PSRAM + }; + gdma_config_transfer(tx_channel, &transfer_cfg); + transfer_cfg.max_data_burst_size = 0; + gdma_config_transfer(rx_channel, &transfer_cfg); gdma_connect(rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_AES, 0)); gdma_connect(tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_AES, 0)); @@ -140,6 +144,22 @@ esp_err_t esp_crypto_shared_gdma_start(const lldesc_t *input, const lldesc_t *ou return ESP_OK; } +/* The external memory ecc-aes access must be enabled when there exists + at least one buffer in the DMA descriptors that resides in external memory. */ +#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT +static bool check_dma_descs_need_ext_mem_ecc_aes_access(const crypto_dma_desc_t *dmadesc) +{ + crypto_dma_desc_t* desc = (crypto_dma_desc_t*) dmadesc; + while (desc) { + if (esp_ptr_in_drom(desc->buffer) || esp_ptr_external_ram(desc->buffer)) { + return true; + } + desc = desc->next; + } + return false; +} +#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ + esp_err_t esp_crypto_shared_gdma_start_axi_ahb(const crypto_dma_desc_t *input, const crypto_dma_desc_t *output, gdma_trigger_peripheral_t peripheral) { int rx_ch_id = 0; @@ -173,6 +193,23 @@ esp_err_t esp_crypto_shared_gdma_start_axi_ahb(const crypto_dma_desc_t *input, c axi_dma_ll_rx_reset_channel(&AXI_DMA, rx_ch_id); #endif /* SOC_AHB_GDMA_VERSION */ +/* When GDMA operations are carried out using external memory with external memory encryption enabled, + we need to enable AXI-DMA's AES-ECC mean access bit. */ +#if (SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT) + if (esp_flash_encryption_enabled()) { + int tx_ch_id = 0; + gdma_get_channel_id(tx_channel, &tx_ch_id); + + if (check_dma_descs_need_ext_mem_ecc_aes_access(input) || check_dma_descs_need_ext_mem_ecc_aes_access(output)) { + axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(&AXI_DMA, rx_ch_id, true); + axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(&AXI_DMA, tx_ch_id, true); + } else { + axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(&AXI_DMA, rx_ch_id, false); + axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(&AXI_DMA, tx_ch_id, false); + } + } +#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ + gdma_start(tx_channel, (intptr_t)input); gdma_start(rx_channel, (intptr_t)output); @@ -184,7 +221,7 @@ bool esp_crypto_shared_gdma_done(void) { int rx_ch_id = 0; gdma_get_channel_id(rx_channel, &rx_ch_id); - while(1) { + while (1) { if ((axi_dma_ll_rx_get_interrupt_status(&AXI_DMA, rx_ch_id, true) & 1)) { break; } diff --git a/components/mbedtls/port/ecc/ecc_alt.c b/components/mbedtls/port/ecc/ecc_alt.c index ad3c1d63e9cf..ef0b76fe05af 100644 --- a/components/mbedtls/port/ecc/ecc_alt.c +++ b/components/mbedtls/port/ecc/ecc_alt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,11 +11,6 @@ #include "mbedtls/ecp.h" #include "mbedtls/platform_util.h" -#define ECP_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECP_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - #if defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) #define MAX_SIZE 32 // 256 bits @@ -94,8 +89,9 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, #endif } - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); + if (grp == NULL || pt == NULL) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } /* Must use affine coordinates */ if( mbedtls_mpi_cmp_int( &pt->MBEDTLS_PRIVATE(Z), 1 ) != 0 ) diff --git a/components/mbedtls/port/ecc/esp_ecc.c b/components/mbedtls/port/ecc/esp_ecc.c index b9fe0a8871ac..0cb4e72e9cb0 100644 --- a/components/mbedtls/port/ecc/esp_ecc.c +++ b/components/mbedtls/port/ecc/esp_ecc.c @@ -19,6 +19,7 @@ static void esp_ecc_acquire_hardware(void) ECC_RCC_ATOMIC() { ecc_ll_enable_bus_clock(true); + ecc_ll_power_up(); ecc_ll_reset_register(); } } @@ -27,6 +28,7 @@ static void esp_ecc_release_hardware(void) { ECC_RCC_ATOMIC() { ecc_ll_enable_bus_clock(false); + ecc_ll_power_down(); } esp_crypto_ecc_lock_release(); diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index 2e6e0a6dd4ae..e28ee3aada8c 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -35,6 +35,7 @@ static void esp_ecdsa_acquire_hardware(void) ECC_RCC_ATOMIC() { ecc_ll_enable_bus_clock(true); + ecc_ll_power_up(); ecc_ll_reset_register(); } @@ -57,6 +58,7 @@ static void esp_ecdsa_release_hardware(void) ECC_RCC_ATOMIC() { ecc_ll_enable_bus_clock(false); + ecc_ll_power_down(); } #ifdef SOC_ECDSA_USES_MPI diff --git a/components/mbedtls/port/sha/dma/sha.c b/components/mbedtls/port/sha/dma/sha.c index 38775dfbfb6f..25c66fde4fd8 100644 --- a/components/mbedtls/port/sha/dma/sha.c +++ b/components/mbedtls/port/sha/dma/sha.c @@ -29,7 +29,6 @@ #include #include -#include "esp_dma_utils.h" #include "esp_private/esp_crypto_lock_internal.h" #include "esp_private/esp_cache_private.h" #include "esp_log.h" @@ -53,6 +52,11 @@ #include "hal/sha_ll.h" #include "soc/soc_caps.h" #include "esp_sha_dma_priv.h" +#include "sdkconfig.h" + +#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT +#include "esp_flash_encrypt.h" +#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ #if SOC_SHA_GDMA #define SHA_LOCK() esp_crypto_sha_aes_lock_acquire() @@ -168,6 +172,63 @@ static void esp_sha_block_mode(esp_sha_type sha_type, const uint8_t *input, uint static DRAM_ATTR crypto_dma_desc_t s_dma_descr_input; static DRAM_ATTR crypto_dma_desc_t s_dma_descr_buf; +static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen, + const void *buf, uint32_t buf_len, bool is_first_block); + +#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT +static esp_err_t esp_sha_dma_process_ext(esp_sha_type sha_type, const void *input, uint32_t ilen, + const void *buf, uint32_t buf_len, bool is_first_block, + bool realloc_input, bool realloc_buf) +{ + int ret = ESP_FAIL; + void *input_copy = NULL; + void *buf_copy = NULL; + + const void *dma_input = NULL; + const void *dma_buf = NULL; + + uint32_t heap_caps = 0; + + if (realloc_input) { + heap_caps = MALLOC_CAP_8BIT | (esp_ptr_external_ram(input) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + input_copy = heap_caps_aligned_alloc(SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT, ilen, heap_caps); + if (input_copy == NULL) { + ESP_LOGE(TAG, "Failed to allocate aligned SPIRAM memory"); + return ret; + } + memcpy(input_copy, input, ilen); + dma_input = input_copy; + } else { + dma_input = input; + } + + if (realloc_buf) { + heap_caps = MALLOC_CAP_8BIT | (esp_ptr_external_ram(buf) ? MALLOC_CAP_SPIRAM : MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + buf_copy = heap_caps_aligned_alloc(SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT, buf_len, heap_caps); + if (buf_copy == NULL) { + ESP_LOGE(TAG, "Failed to allocate aligned internal memory"); + return ret; + } + memcpy(buf_copy, buf, buf_len); + dma_buf = buf_copy; + } else { + dma_buf = buf; + } + + ret = esp_sha_dma_process(sha_type, dma_input, ilen, dma_buf, buf_len, is_first_block); + + if (realloc_input) { + free(input_copy); + } + + if (realloc_buf) { + free(buf_copy); + } + + return ret; +} +#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ + /* Performs SHA on multiple blocks at a time */ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen, const void *buf, uint32_t buf_len, bool is_first_block) @@ -179,6 +240,29 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u memset(&s_dma_descr_input, 0, sizeof(crypto_dma_desc_t)); memset(&s_dma_descr_buf, 0, sizeof(crypto_dma_desc_t)); +/* When SHA-DMA operations are carried out using external memory with external memory encryption enabled, + we need to make sure that the addresses and the sizes of the buffers on which the DMA operates are 16 byte-aligned. */ +#ifdef SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT + if (esp_flash_encryption_enabled()) { + if (esp_ptr_external_ram(input) || esp_ptr_external_ram(buf) || esp_ptr_in_drom(input) || esp_ptr_in_drom(buf)) { + bool input_needs_realloc = false; + bool buf_needs_realloc = false; + + if (ilen && ((intptr_t)(input) & (SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT - 1)) != 0) { + input_needs_realloc = true; + } + + if (buf_len && ((intptr_t)(buf) & (SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT - 1)) != 0) { + buf_needs_realloc = true; + } + + if (input_needs_realloc || buf_needs_realloc) { + return esp_sha_dma_process_ext(sha_type, input, ilen, buf, buf_len, is_first_block, input_needs_realloc, buf_needs_realloc); + } + } + } +#endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ + /* DMA descriptor for Memory to DMA-SHA transfer */ if (ilen) { s_dma_descr_input.dw0.length = ilen; @@ -188,7 +272,7 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u s_dma_descr_input.buffer = (void *) input; dma_descr_head = &s_dma_descr_input; } - /* Check after input to overide head if there is any buf*/ + /* Check after input to override head if there is any buf*/ if (buf_len) { s_dma_descr_buf.dw0.length = buf_len; s_dma_descr_buf.dw0.size = buf_len; diff --git a/components/mqtt/test_apps/test_mqtt/main/CMakeLists.txt b/components/mqtt/test_apps/test_mqtt/main/CMakeLists.txt index 7a0662480422..0647fe29f135 100644 --- a/components/mqtt/test_apps/test_mqtt/main/CMakeLists.txt +++ b/components/mqtt/test_apps/test_mqtt/main/CMakeLists.txt @@ -5,4 +5,4 @@ if(CONFIG_MQTT_PROTOCOL_5) endif() idf_component_register(SRCS "${srcs}" - PRIV_REQUIRES cmock test_utils mqtt nvs_flash app_update esp_eth esp_netif spi_flash common) + PRIV_REQUIRES cmock test_utils mqtt nvs_flash app_update spi_flash common) diff --git a/components/mqtt/test_apps/test_mqtt5/main/CMakeLists.txt b/components/mqtt/test_apps/test_mqtt5/main/CMakeLists.txt index f152df9c24ac..d33a86ceb8d9 100644 --- a/components/mqtt/test_apps/test_mqtt5/main/CMakeLists.txt +++ b/components/mqtt/test_apps/test_mqtt5/main/CMakeLists.txt @@ -1,4 +1,4 @@ set(srcs test_mqtt5_client_broker.c test_mqtt5.c) idf_component_register(SRCS "${srcs}" - PRIV_REQUIRES cmock test_utils mqtt nvs_flash app_update esp_eth esp_netif spi_flash common) + PRIV_REQUIRES cmock test_utils mqtt nvs_flash app_update spi_flash common) diff --git a/components/newlib/CMakeLists.txt b/components/newlib/CMakeLists.txt index df29489badea..b837b6672a77 100644 --- a/components/newlib/CMakeLists.txt +++ b/components/newlib/CMakeLists.txt @@ -5,9 +5,6 @@ if(${target} STREQUAL "linux") endif() set(include_dirs "platform_include") -if(CMAKE_C_COMPILER_ID MATCHES "Clang") # TODO LLVM-330 - list(APPEND include_dirs "clang_include") -endif() if(BOOTLOADER_BUILD) # Bootloader builds need the platform_include directory (for assert.h), but nothing else diff --git a/components/newlib/Kconfig b/components/newlib/Kconfig index c00ab0cc035f..98e63e8c0345 100644 --- a/components/newlib/Kconfig +++ b/components/newlib/Kconfig @@ -59,7 +59,7 @@ menu "Newlib" For more details about "nano" formatting option, please see newlib readme file, search for '--enable-newlib-nano-formatted-io': - https://sourceware.org/newlib/README + https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/README;hb=HEAD If this option is enabled and the ROM contains functions from newlib-nano, the build system will use functions available in ROM, reducing the application binary size. diff --git a/components/newlib/clang_include/sys/dirent.h b/components/newlib/platform_include/sys/dirent.h similarity index 92% rename from components/newlib/clang_include/sys/dirent.h rename to components/newlib/platform_include/sys/dirent.h index 444dad2ddf5c..2643ddc9544f 100644 --- a/components/newlib/clang_include/sys/dirent.h +++ b/components/newlib/platform_include/sys/dirent.h @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ - +#ifdef __clang__ // TODO LLVM-330 #pragma once #include @@ -63,3 +63,8 @@ int alphasort(const struct dirent **d1, const struct dirent **d2); #ifdef __cplusplus } #endif + +#else // __clang__ TODO: IDF-10675 +#include_next +#include +#endif // __clang__ diff --git a/components/newlib/test_apps/newlib/main/test_newlib.c b/components/newlib/test_apps/newlib/main/test_newlib.c index 4939fd028e2c..48cd9d0992e6 100644 --- a/components/newlib/test_apps/newlib/main/test_newlib.c +++ b/components/newlib/test_apps/newlib/main/test_newlib.c @@ -131,7 +131,7 @@ static bool fn_in_rom(void *fn) /* Older chips have newlib nano in rom as well, but this is not linked in due to us now using 64 bit time_t and the ROM code was compiled for 32 bit. */ -#define PRINTF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && (CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4)) +#define PRINTF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && CONFIG_IDF_TARGET_ESP32C2) #define SSCANF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && CONFIG_IDF_TARGET_ESP32C2) TEST_CASE("check if ROM or Flash is used for functions", "[newlib]") @@ -230,3 +230,10 @@ TEST_CASE("newlib: rom and toolchain localtime func gives the same result", "[ne printf("%s\n", test_result); TEST_ASSERT_EQUAL_STRING("2020-03-12 15:00:00 EDT (tm_isdst = 1)", test_result); } + +TEST_CASE("newlib: printf float as expected", "[newlib]") +{ + const float val = 1.23; + int len = printf("test printf float val is %1.2f\n", val); + TEST_ASSERT_EQUAL_INT(30, len); +} diff --git a/components/nvs_flash/test_apps/main/partition_plaintext.bin b/components/nvs_flash/test_apps/main/partition_plaintext.bin deleted file mode 100644 index 76fe7122269f..000000000000 Binary files a/components/nvs_flash/test_apps/main/partition_plaintext.bin and /dev/null differ diff --git a/components/nvs_flash/test_apps/main/test_nvs.c b/components/nvs_flash/test_apps/main/test_nvs.c index 4c4f4ef7edc8..688722fe9ffb 100644 --- a/components/nvs_flash/test_apps/main/test_nvs.c +++ b/components/nvs_flash/test_apps/main/test_nvs.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #include #include #include +#include #include #include @@ -16,6 +17,7 @@ #include "esp_log.h" #include "esp_partition.h" #include "esp_system.h" +#include "spi_flash_mmap.h" #include "nvs.h" #include "nvs_flash.h" @@ -587,6 +589,7 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena extern const char nvs_key_start[] asm("_binary_encryption_keys_bin_start"); extern const char nvs_key_end[] asm("_binary_encryption_keys_bin_end"); extern const char nvs_data_sch0_start[] asm("_binary_partition_encrypted_bin_start"); + extern const char nvs_data_sch0_end[] asm("_binary_partition_encrypted_bin_end"); const esp_partition_t* key_part = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL); @@ -600,15 +603,24 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena ESP_ERROR_CHECK( esp_partition_write(key_part, i, nvs_key_start + i, SPI_FLASH_SEC_SIZE) ); } - for (int i = 0; i < nvs_part->size; i+= SPI_FLASH_SEC_SIZE) { + const int content_size = nvs_data_sch0_end - nvs_data_sch0_start - 1; + TEST_ASSERT_TRUE((content_size % SPI_FLASH_SEC_SIZE) == 0); + + const int size_to_write = MIN(content_size, nvs_part->size); + for (int i = 0; i < size_to_write; i+= SPI_FLASH_SEC_SIZE) { ESP_ERROR_CHECK( esp_partition_write(nvs_part, i, nvs_data_sch0_start + i, SPI_FLASH_SEC_SIZE) ); } err = nvs_flash_read_security_cfg(key_part, &xts_cfg); #elif CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC extern const char nvs_data_sch1_start[] asm("_binary_partition_encrypted_hmac_bin_start"); + extern const char nvs_data_sch1_end[] asm("_binary_partition_encrypted_hmac_bin_end"); + + const int content_size = nvs_data_sch1_end - nvs_data_sch1_start - 1; + TEST_ASSERT_TRUE((content_size % SPI_FLASH_SEC_SIZE) == 0); - for (int i = 0; i < nvs_part->size; i+= SPI_FLASH_SEC_SIZE) { + const int size_to_write = MIN(content_size, nvs_part->size); + for (int i = 0; i < size_to_write; i+= SPI_FLASH_SEC_SIZE) { ESP_ERROR_CHECK( esp_partition_write(nvs_part, i, nvs_data_sch1_start + i, SPI_FLASH_SEC_SIZE) ); } diff --git a/components/openthread/CMakeLists.txt b/components/openthread/CMakeLists.txt index eb3d3dc33941..a4579556029e 100644 --- a/components/openthread/CMakeLists.txt +++ b/components/openthread/CMakeLists.txt @@ -111,7 +111,9 @@ if(CONFIG_OPENTHREAD_ENABLED) "openthread/src/core/thread/mesh_forwarder_ftd.cpp" "openthread/src/core/thread/mesh_forwarder_mtd.cpp" "openthread/src/core/thread/mle.cpp" + "openthread/src/core/thread/mle_router.cpp" "openthread/src/core/thread/mle_types.cpp" + "openthread/src/core/thread/neighbor.cpp" "openthread/src/core/thread/neighbor_table.cpp" "openthread/src/core/thread/network_data.cpp" "openthread/src/core/thread/network_data_leader.cpp" @@ -235,9 +237,9 @@ execute_process( string(TIMESTAMP OT_BUILD_TIMESTAMP " %Y-%m-%d %H:%M:%S UTC" UTC) string(CONCAT OT_FULL_VERSION_STRING - "openthread-esp32/" + "${CONFIG_OPENTHREAD_PACKAGE_NAME}/" "${IDF_VERSION_FOR_OPENTHREAD_PACKAGE}-${OPENTHREAD_VERSION}\; " - "${CONFIG_IDF_TARGET}\; ${OT_BUILD_TIMESTAMP}") + "${CONFIG_OPENTHREAD_PLATFORM_INFO}\; ${OT_BUILD_TIMESTAMP}") idf_component_register(SRC_DIRS "${src_dirs}" EXCLUDE_SRCS "${exclude_srcs}" @@ -264,6 +266,8 @@ if(CONFIG_OPENTHREAD_ENABLED OR CONFIG_OPENTHREAD_SPINEL_ONLY) PUBLIC "OPENTHREAD_CONFIG_FILE=\"openthread-core-esp32x-${CONFIG_FILE_TYPE}-config.h\"" "${device_type}" + "OPENTHREAD_PROJECT_LIB_CONFIG_FILE=\"openthread-core-esp32x-${CONFIG_FILE_TYPE}-config.h\"" + "${device_type}" PRIVATE "PACKAGE_VERSION=\"${IDF_VERSION_FOR_OPENTHREAD_PACKAGE}-${OPENTHREAD_VERSION}\"" "OPENTHREAD_BUILD_DATETIME=\"${OT_BUILD_TIMESTAMP}\"" diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index 558f093f6cfd..0b90b78b015d 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -170,10 +170,26 @@ menu "OpenThread" Select this to enable SPI connection to host. endchoice + menu "OpenThread version message" + depends on OPENTHREAD_ENABLED + + config OPENTHREAD_PACKAGE_NAME + string "OpenThread package name" + default "openthread-esp32" + help + The OpenThread package name. + + config OPENTHREAD_PLATFORM_INFO + string "platform information" + default IDF_TARGET + help + The OpenThread platform information. + endmenu + config OPENTHREAD_NCP_VENDOR_HOOK bool "Enable vendor command for RCP" depends on OPENTHREAD_RADIO - default n + default y help Select this to enable OpenThread NCP vendor commands. @@ -206,7 +222,6 @@ menu "OpenThread" int "The size of max commissioning joiner entries" depends on OPENTHREAD_COMMISSIONER default 2 - range 2 50 config OPENTHREAD_JOINER bool "Enable Joiner" @@ -228,7 +243,6 @@ menu "OpenThread" int "Specifies number of service entries in the SRP client service pool" depends on OPENTHREAD_SRP_CLIENT default 5 - range 2 20 help Set the max buffer size of service entries in the SRP client service pool. @@ -257,14 +271,12 @@ menu "OpenThread" int "The number of openthread message buffers" depends on OPENTHREAD_ENABLED default 65 - range 10 100 if !OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT - range 10 8191 if OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT config OPENTHREAD_SPINEL_RX_FRAME_BUFFER_SIZE int "The size of openthread spinel rx frame buffer" depends on OPENTHREAD_ENABLED || OPENTHREAD_SPINEL_ONLY - default 1024 - range 512 8192 + default 1024 if OPENTHREAD_MTD || OPENTHREAD_RADIO + default 2048 if OPENTHREAD_FTD || OPENTHREAD_SPINEL_ONLY config OPENTHREAD_MAC_MAX_CSMA_BACKOFFS_DIRECT int "Maximum backoffs times before declaring a channel access failure." @@ -278,13 +290,11 @@ menu "OpenThread" int "The size of max MLE children entries" depends on OPENTHREAD_ENABLED default 10 - range 5 50 config OPENTHREAD_TMF_ADDR_CACHE_ENTRIES int "The size of max TMF address cache entries" depends on OPENTHREAD_ENABLED default 20 - range 5 50 config OPENTHREAD_DNS64_CLIENT bool "Use dns64 client" @@ -303,8 +313,7 @@ menu "OpenThread" config OPENTHREAD_UART_BUFFER_SIZE int "The uart received buffer size of openthread" depends on OPENTHREAD_ENABLED - default 768 - range 128 1024 + default 2048 help Set the OpenThread UART buffer size. @@ -377,7 +386,7 @@ menu "OpenThread" default n help Select this option to enable the radio statistics feature, you can use radio command to print some radio - Statistics informations. + Statistics information. config OPENTHREAD_SPINEL_ONLY bool "Enable OpenThread External Radio Spinel feature" @@ -386,11 +395,11 @@ menu "OpenThread" Select this option to enable the OpenThread Radio Spinel for external protocol stack, such as Zigbee. config OPENTHREAD_RX_ON_WHEN_IDLE - bool "Enable OpenThread radio capibility rx on when idle" + bool "Enable OpenThread radio capability rx on when idle" default y if !ESP_COEX_SW_COEXIST_ENABLE default n if ESP_COEX_SW_COEXIST_ENABLE help - Select this option to enable OpenThread radio capibility rx on when idle. Do not support this feature when + Select this option to enable OpenThread radio capability rx on when idle. Do not support this feature when SW coexistence is enabled. menu "Thread Address Query Config" @@ -398,19 +407,16 @@ menu "OpenThread" int "Timeout value (in seconds) for a address notification response after sending an address query." depends on OPENTHREAD_FTD || OPENTHREAD_MTD default 3 - range 1 10 config OPENTHREAD_ADDRESS_QUERY_RETRY_DELAY int "Initial retry delay for address query (in seconds)." depends on OPENTHREAD_FTD || OPENTHREAD_MTD default 15 - range 1 120 config OPENTHREAD_ADDRESS_QUERY_MAX_RETRY_DELAY int "Maximum retry delay for address query (in seconds)." depends on OPENTHREAD_FTD || OPENTHREAD_MTD default 120 - range OPENTHREAD_ADDRESS_QUERY_RETRY_DELAY 960 endmenu endmenu diff --git a/components/openthread/include/esp_openthread_border_router.h b/components/openthread/include/esp_openthread_border_router.h index 3a6c6e963872..de4b8ee6048b 100644 --- a/components/openthread/include/esp_openthread_border_router.h +++ b/components/openthread/include/esp_openthread_border_router.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,7 +67,7 @@ esp_netif_t *esp_openthread_get_backbone_netif(void); void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_handler handler); /** - * @brief Deinitializes the conneciton to RCP. + * @brief Deinitializes the connection to RCP. * * @return * - ESP_OK on success @@ -77,7 +77,7 @@ void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_hand esp_err_t esp_openthread_rcp_deinit(void); /** - * @brief Initializes the conneciton to RCP. + * @brief Initializes the connection to RCP. * * @return * - ESP_OK on success @@ -86,6 +86,21 @@ esp_err_t esp_openthread_rcp_deinit(void); */ esp_err_t esp_openthread_rcp_init(void); +/** + * @brief Sets the meshcop(e) instance name. + * + * @note This function can only be called before `esp_openthread_border_router_init`. + * If `instance_name` is NULL, then the service will use the hostname as instance name. + * + * @param[in] instance_name The instance name, can be `NULL`. + * + * @return + * - ESP_OK on success + * - ESP_FAIL if fail to initialize RCP + * + */ +esp_err_t esp_openthread_set_meshcop_instance_name(const char *instance_name); + #ifdef __cplusplus } #endif diff --git a/components/openthread/include/esp_openthread_lock.h b/components/openthread/include/esp_openthread_lock.h index 19f504541a6e..c2ad28fad99f 100644 --- a/components/openthread/include/esp_openthread_lock.h +++ b/components/openthread/include/esp_openthread_lock.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -35,10 +35,10 @@ void esp_openthread_lock_deinit(void); /** * @brief This function acquires the OpenThread API lock. * - * @note Every OT APIs that takes an otInstance argument MUST be protected with this API lock - * except that the call site is in OT callbacks. + * @note Every Openthread APIs that takes an otInstance argument MUST be protected with this API lock + * except that the call site is in Openthread callbacks. * - * @param[in] block_ticks The maxinum number of RTOS ticks to wait for the lock. + * @param[in] block_ticks The maximum number of RTOS ticks to wait for the lock. * * @return * - True on lock acquired @@ -63,7 +63,7 @@ void esp_openthread_lock_release(void); * * @note Please use esp_openthread_lock_acquire() for normal cases. * - * @param[in] block_ticks The maxinum number of RTOS ticks to wait for the lock. + * @param[in] block_ticks The maximum number of RTOS ticks to wait for the lock. * * @return * - True on lock acquired @@ -75,6 +75,9 @@ bool esp_openthread_task_switching_lock_acquire(TickType_t block_ticks); /** * @brief This function releases the OpenThread API task switching lock. * + * @note This API must be called after `esp_openthread_task_switching_lock_acquire` or + * `esp_openthread_lock_acquire` and will cause a crash if the current task is not the task switching lock holder. + * This error could be caused by calling OpenThread APIs without locking OpenThread stack. */ void esp_openthread_task_switching_lock_release(void); diff --git a/components/openthread/include/esp_openthread_netif_glue.h b/components/openthread/include/esp_openthread_netif_glue.h index 404e9f1f5c71..3d70c8a7f74d 100644 --- a/components/openthread/include/esp_openthread_netif_glue.h +++ b/components/openthread/include/esp_openthread_netif_glue.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,7 @@ extern "C" { #endif /** -* @brief Default configuration reference of OT esp-netif +* @brief Default configuration reference of OpenThread esp-netif */ #define ESP_NETIF_INHERENT_DEFAULT_OPENTHREAD() \ { \ @@ -67,6 +67,15 @@ void esp_openthread_netif_glue_deinit(void); */ esp_netif_t *esp_openthread_get_netif(void); +/** + * @brief This function register a handler for meshcop-e service publish event and remove event. + * + * @param[in] handler The handler. + * @param[in] for_publish The usage of handler, true for publish event and false for remove event. + * + */ +void esp_openthread_register_meshcop_e_handler(esp_event_handler_t handler, bool for_publish); + #ifdef __cplusplus } #endif diff --git a/components/openthread/include/esp_openthread_types.h b/components/openthread/include/esp_openthread_types.h index 28595d3fa003..03095940194c 100644 --- a/components/openthread/include/esp_openthread_types.h +++ b/components/openthread/include/esp_openthread_types.h @@ -44,6 +44,8 @@ typedef enum { OPENTHREAD_EVENT_TREL_REMOVE_IP6, /*!< OpenThread stack removed TREL IPv6 address */ OPENTHREAD_EVENT_TREL_MULTICAST_GROUP_JOIN, /*!< OpenThread stack joined TREL IPv6 multicast group */ OPENTHREAD_EVENT_SET_DNS_SERVER, /*!< OpenThread stack set DNS server >*/ + OPENTHREAD_EVENT_PUBLISH_MESHCOP_E, /*!< OpenThread stack start to publish meshcop-e service >*/ + OPENTHREAD_EVENT_REMOVE_MESHCOP_E, /*!< OpenThread stack start to remove meshcop-e service >*/ } esp_openthread_event_t; /** diff --git a/components/openthread/lib b/components/openthread/lib index fcee30db4b73..203c78501e9a 160000 --- a/components/openthread/lib +++ b/components/openthread/lib @@ -1 +1 @@ -Subproject commit fcee30db4b7342de4df9105bdd049a09d2d63187 +Subproject commit 203c78501e9a6ea9ca3a929e6f9b6b9691ef16ee diff --git a/components/openthread/openthread b/components/openthread/openthread index 456c44828448..f32c18bc0840 160000 --- a/components/openthread/openthread +++ b/components/openthread/openthread @@ -1 +1 @@ -Subproject commit 456c448284486abe2a9118a9fdaa468fe2383fcd +Subproject commit f32c18bc0840f400182456e58ae3900fc2fb4af7 diff --git a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h index 609c01112c4a..aa8882f2341d 100644 --- a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h @@ -14,7 +14,7 @@ * The platform-specific string to insert into the OpenThread version string. * */ -#define OPENTHREAD_CONFIG_PLATFORM_INFO CONFIG_IDF_TARGET +#define OPENTHREAD_CONFIG_PLATFORM_INFO CONFIG_OPENTHREAD_PLATFORM_INFO /** * @def OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT @@ -317,7 +317,7 @@ * Define to the full name of this package. * */ -#define PACKAGE_NAME "openthread-esp32" +#define PACKAGE_NAME CONFIG_OPENTHREAD_PACKAGE_NAME /** * @def PACKAGE_STRING @@ -355,13 +355,13 @@ #define OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS 3 /** - * @def OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE + * @def OPENTHREAD_LIB_SPINEL_RX_FRAME_BUFFER_SIZE * * Specifies the rx frame buffer size used by `SpinelInterface` in RCP host code. This is applicable/used when * `RadioSpinel` platform is used. * */ -#define OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE CONFIG_OPENTHREAD_SPINEL_RX_FRAME_BUFFER_SIZE +#define OPENTHREAD_LIB_SPINEL_RX_FRAME_BUFFER_SIZE CONFIG_OPENTHREAD_SPINEL_RX_FRAME_BUFFER_SIZE /** * @def OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE @@ -632,4 +632,8 @@ #define OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT CONFIG_OPENTHREAD_MAC_MAX_CSMA_BACKOFFS_DIRECT #endif +#ifndef OPENTHREAD_CONFIG_THREAD_VERSION +#define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_4 +#endif + #define OPENTHREAD_FTD 1 diff --git a/components/openthread/private_include/openthread-core-esp32x-mtd-config.h b/components/openthread/private_include/openthread-core-esp32x-mtd-config.h index 40ac95b9ebd6..f21c9ce01eaa 100644 --- a/components/openthread/private_include/openthread-core-esp32x-mtd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-mtd-config.h @@ -14,7 +14,7 @@ * The platform-specific string to insert into the OpenThread version string. * */ -#define OPENTHREAD_CONFIG_PLATFORM_INFO CONFIG_IDF_TARGET +#define OPENTHREAD_CONFIG_PLATFORM_INFO CONFIG_OPENTHREAD_PLATFORM_INFO /** * @def OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT @@ -131,7 +131,7 @@ * Define to the full name of this package. * */ -#define PACKAGE_NAME "openthread-esp32" +#define PACKAGE_NAME CONFIG_OPENTHREAD_PACKAGE_NAME /** * @def PACKAGE_STRING @@ -169,13 +169,13 @@ #define OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS 3 /** - * @def OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE + * @def OPENTHREAD_LIB_SPINEL_RX_FRAME_BUFFER_SIZE * * Specifies the rx frame buffer size used by `SpinelInterface` in RCP host code. This is applicable/used when * `RadioSpinel` platform is used. * */ -#define OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE 1024 +#define OPENTHREAD_LIB_SPINEL_RX_FRAME_BUFFER_SIZE CONFIG_OPENTHREAD_SPINEL_RX_FRAME_BUFFER_SIZE /** * @def OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE diff --git a/components/openthread/private_include/openthread-core-esp32x-radio-config.h b/components/openthread/private_include/openthread-core-esp32x-radio-config.h index cd8ad1590924..8a954c86d3b0 100644 --- a/components/openthread/private_include/openthread-core-esp32x-radio-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-radio-config.h @@ -13,7 +13,7 @@ * The platform-specific string to insert into the OpenThread version string. * */ -#define OPENTHREAD_CONFIG_PLATFORM_INFO CONFIG_IDF_TARGET +#define OPENTHREAD_CONFIG_PLATFORM_INFO CONFIG_OPENTHREAD_PLATFORM_INFO /** * @def OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT @@ -112,7 +112,7 @@ * Define to the full name of this package. * */ -#define PACKAGE_NAME "openthread-esp32" +#define PACKAGE_NAME CONFIG_OPENTHREAD_PACKAGE_NAME /** * @def PACKAGE_STRING @@ -142,13 +142,13 @@ #define OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS 3 /** - * @def OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE + * @def OPENTHREAD_LIB_SPINEL_RX_FRAME_BUFFER_SIZE * * Specifies the rx frame buffer size used by `SpinelInterface` in RCP host code. This is applicable/used when * `RadioSpinel` platform is used. * */ -#define OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE 1024 +#define OPENTHREAD_LIB_SPINEL_RX_FRAME_BUFFER_SIZE CONFIG_OPENTHREAD_SPINEL_RX_FRAME_BUFFER_SIZE /** * @def OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE diff --git a/components/openthread/private_include/openthread-core-esp32x-spinel-config.h b/components/openthread/private_include/openthread-core-esp32x-spinel-config.h index 68d5b8240a35..3c9def784040 100644 --- a/components/openthread/private_include/openthread-core-esp32x-spinel-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-spinel-config.h @@ -6,6 +6,23 @@ #pragma once +#include "sdkconfig.h" +/** + * @def OPENTHREAD_CONFIG_PLATFORM_INFO + * + * The platform-specific string to insert into the OpenThread version string. + * + */ +#define OPENTHREAD_CONFIG_PLATFORM_INFO CONFIG_OPENTHREAD_PLATFORM_INFO + +/** + * @def PACKAGE_NAME + * + * Define to the full name of this package. + * + */ +#define PACKAGE_NAME CONFIG_OPENTHREAD_PACKAGE_NAME + /** * @def OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE * @@ -25,9 +42,11 @@ */ #ifndef OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT // TZ-567: Set OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT to 3 after adding rcp failure notification mechanism -#define OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT 0 +#define OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT 3 #endif +#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE 1 + /** * @def OPENTHREAD_SPINEL_CONFIG_RCP_CUSTOM_RESTORATION * @@ -39,13 +58,13 @@ #endif /** - * @def OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE + * @def OPENTHREAD_LIB_SPINEL_RX_FRAME_BUFFER_SIZE * * Specifies the rx frame buffer size used by `SpinelInterface` in RCP host code. This is applicable/used when * `RadioSpinel` platform is used. * */ -#define OPENTHREAD_CONFIG_PLATFORM_RADIO_SPINEL_RX_FRAME_BUFFER_SIZE CONFIG_OPENTHREAD_SPINEL_RX_FRAME_BUFFER_SIZE +#define OPENTHREAD_LIB_SPINEL_RX_FRAME_BUFFER_SIZE CONFIG_OPENTHREAD_SPINEL_RX_FRAME_BUFFER_SIZE /** * @def OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT diff --git a/components/openthread/sbom_openthread.yml b/components/openthread/sbom_openthread.yml index 0748bffc639d..7738bbe0a2ef 100644 --- a/components/openthread/sbom_openthread.yml +++ b/components/openthread/sbom_openthread.yml @@ -5,4 +5,4 @@ supplier: 'Organization: Espressif Systems (Shanghai) CO LTD' originator: 'Organization: Google LLC' description: OpenThread released by Google is an open-source implementation of the Thread networking url: https://github.com/espressif/openthread -hash: 456c448284486abe2a9118a9fdaa468fe2383fcd +hash: f32c18bc0840f400182456e58ae3900fc2fb4af7 diff --git a/components/openthread/src/esp_openthread.cpp b/components/openthread/src/esp_openthread.cpp index 60eba6153df2..87c7b4986ecd 100644 --- a/components/openthread/src/esp_openthread.cpp +++ b/components/openthread/src/esp_openthread.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -129,7 +129,7 @@ esp_err_t esp_openthread_auto_start(otOperationalDatasetTlvs *datasetTlvs) memcpy(dataset.mMeshLocalPrefix.m8, prefix.mPrefix.mFields.m8, sizeof(dataset.mMeshLocalPrefix.m8)); dataset.mComponents.mIsMeshLocalPrefixPresent = true; } else { - ESP_LOGE("Falied to parse mesh local prefix", CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX); + ESP_LOGE("Failed to parse mesh local prefix", CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX); } // Network Key @@ -213,13 +213,3 @@ esp_err_t esp_openthread_deinit(void) otInstanceFinalize(esp_openthread_get_instance()); return esp_openthread_platform_deinit(); } - -static void stub_task(void *context) -{ - // this is a empty function used for ot-task signal pending -} - -void otTaskletsSignalPending(otInstance *aInstance) -{ - esp_openthread_task_queue_post(stub_task, NULL); -} diff --git a/components/openthread/src/esp_openthread_cli.c b/components/openthread/src/esp_openthread_cli.c index 6ce998a43059..b2a76a4df0c1 100644 --- a/components/openthread/src/esp_openthread_cli.c +++ b/components/openthread/src/esp_openthread_cli.c @@ -99,8 +99,11 @@ static void ot_cli_loop(void *context) printf("Internal error: %s\n", esp_err_to_name(err)); } } else { - esp_openthread_cli_input(line); - xTaskNotifyWait(0, 0, NULL, portMAX_DELAY); + if (esp_openthread_cli_input(line) == ESP_OK) { + xTaskNotifyWait(0, 0, NULL, portMAX_DELAY); + } else { + printf("Openthread task is busy, failed to run command: %s\n", line); + } } linenoiseHistoryAdd(line); } diff --git a/components/openthread/src/esp_openthread_lock.c b/components/openthread/src/esp_openthread_lock.c index ba7c63d4115f..7e35da6c21bf 100644 --- a/components/openthread/src/esp_openthread_lock.c +++ b/components/openthread/src/esp_openthread_lock.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -45,6 +45,11 @@ void esp_openthread_task_switching_lock_release(void) { ESP_RETURN_ON_FALSE(s_openthread_task_mutex, , OT_PLAT_LOG_TAG, "Failed to release the lock because the mutex is not ready"); + if (xSemaphoreGetMutexHolder(s_openthread_task_mutex) != xTaskGetCurrentTaskHandle()) { + ESP_LOGE(OT_PLAT_LOG_TAG, "Task %s is attempting to release the OpenThread task switching lock but never acquired it.", + pcTaskGetName(xTaskGetCurrentTaskHandle())); + assert(false); + } xSemaphoreGiveRecursive(s_openthread_task_mutex); } diff --git a/components/openthread/src/esp_openthread_lwip_netif.c b/components/openthread/src/esp_openthread_lwip_netif.c index 29be440ae093..94c8e16861e2 100644 --- a/components/openthread/src/esp_openthread_lwip_netif.c +++ b/components/openthread/src/esp_openthread_lwip_netif.c @@ -23,6 +23,12 @@ #define OPENTHREAD_IP6_MTU 1280 +#if CONFIG_OPENTHREAD_BORDER_ROUTER +#if CONFIG_LWIP_IPV6_NUM_ADDRESSES != 12 +#error CONFIG_LWIP_IPV6_NUM_ADDRESSES should be set to 12, please configure it using `idf.py menuconfig` +#endif +#endif + static err_t openthread_netif_init(struct netif *netif); static void openthread_netif_input(void *h, void *buffer, size_t len, void *eb); diff --git a/components/openthread/src/esp_openthread_netif_glue.c b/components/openthread/src/esp_openthread_netif_glue.c index 608a3218fa35..e7184698682c 100644 --- a/components/openthread/src/esp_openthread_netif_glue.c +++ b/components/openthread/src/esp_openthread_netif_glue.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -203,6 +203,33 @@ static esp_err_t openthread_netif_transmit(void *handle, void *buffer, size_t le return error; } +static esp_event_handler_t meshcop_e_publish_handler = NULL; +static void esp_openthread_meshcop_e_publish_handler(void *args, esp_event_base_t base, int32_t event_id, void *data) +{ + if (meshcop_e_publish_handler) { + meshcop_e_publish_handler(args, base, event_id, data); + } +} + +static esp_event_handler_t meshcop_e_remove_handler = NULL; +static void esp_openthread_meshcop_e_remove_handler(void *args, esp_event_base_t base, int32_t event_id, void *data) +{ + if (meshcop_e_remove_handler) { + meshcop_e_remove_handler(args, base, event_id, data); + } +} + +void esp_openthread_register_meshcop_e_handler(esp_event_handler_t handler, bool for_publish) +{ + if (for_publish) { + meshcop_e_publish_handler = handler; + } else if (!for_publish) { + meshcop_e_remove_handler = handler; + } else { + ESP_ERROR_CHECK(ESP_FAIL); + } +} + static esp_err_t register_openthread_event_handlers(esp_netif_t *esp_netif) { ESP_RETURN_ON_ERROR( @@ -229,6 +256,12 @@ static esp_err_t register_openthread_event_handlers(esp_netif_t *esp_netif) ESP_RETURN_ON_ERROR(esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_MULTICAST_GROUP_LEAVE, esp_netif_action_leave_ip6_multicast_group, esp_netif), OT_PLAT_LOG_TAG, "OpenThread interface leave ip6 multicast group event register failed"); + ESP_RETURN_ON_ERROR(esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_PUBLISH_MESHCOP_E, + esp_openthread_meshcop_e_publish_handler, NULL), + OT_PLAT_LOG_TAG, "OpenThread publish meshcop-e service event register failed"); + ESP_RETURN_ON_ERROR(esp_event_handler_register(OPENTHREAD_EVENT, OPENTHREAD_EVENT_REMOVE_MESHCOP_E, + esp_openthread_meshcop_e_remove_handler, NULL), + OT_PLAT_LOG_TAG, "OpenThread remove meshcop-e service event register failed"); return ESP_OK; } @@ -244,6 +277,8 @@ static void unregister_openthread_event_handlers(void) esp_netif_action_join_ip6_multicast_group); esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_MULTICAST_GROUP_LEAVE, esp_netif_action_leave_ip6_multicast_group); + esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_PUBLISH_MESHCOP_E, esp_openthread_meshcop_e_publish_handler); + esp_event_handler_unregister(OPENTHREAD_EVENT, OPENTHREAD_EVENT_REMOVE_MESHCOP_E, esp_openthread_meshcop_e_remove_handler); } static esp_err_t openthread_netif_post_attach(esp_netif_t *esp_netif, void *args) @@ -285,7 +320,7 @@ void *esp_openthread_netif_glue_init(const esp_openthread_platform_config_t *con otIp6SetAddressCallback(instance, process_thread_address, instance); otIp6SetReceiveCallback(instance, process_thread_receive, instance); otIp6SetReceiveFilterEnabled(instance, true); - otIcmp6SetEchoMode(instance, OT_ICMP6_ECHO_HANDLER_DISABLED); + otIcmp6SetEchoMode(instance, OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY); s_openthread_netif_glue.event_fd = eventfd(0, 0); if (s_openthread_netif_glue.event_fd < 0) { diff --git a/components/openthread/src/esp_openthread_platform.cpp b/components/openthread/src/esp_openthread_platform.cpp index f6f29e278e57..3e73ef362a5a 100644 --- a/components/openthread/src/esp_openthread_platform.cpp +++ b/components/openthread/src/esp_openthread_platform.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,7 +34,7 @@ static esp_openthread_platform_workflow_t *s_workflow_list = NULL; esp_err_t esp_openthread_platform_workflow_register(esp_openthread_update_func update_func, esp_openthread_process_func process_func, const char *name) { - uint8_t name_len = strnlen(name, WORKFLOW_MAX_NAMELEN); + uint8_t name_len = strnlen(name, WORKFLOW_MAX_NAMELEN - 1); esp_openthread_platform_workflow_t *current_workflow = s_workflow_list; esp_openthread_platform_workflow_t *before_workflow = NULL; esp_openthread_platform_workflow_t *add_workflow = @@ -42,6 +42,7 @@ esp_err_t esp_openthread_platform_workflow_register(esp_openthread_update_func u ESP_RETURN_ON_FALSE(add_workflow != NULL, ESP_ERR_NO_MEM, OT_PLAT_LOG_TAG, "Failed to alloc memory for esp_openthread_workflow"); strncpy(add_workflow->name, name, name_len); + add_workflow->name[name_len] = '\0'; add_workflow->update_func = update_func; add_workflow->process_func = process_func; add_workflow->next = NULL; diff --git a/components/openthread/src/esp_openthread_task_queue.c b/components/openthread/src/esp_openthread_task_queue.c index 4acfaad722b8..9d9bf87e6f31 100644 --- a/components/openthread/src/esp_openthread_task_queue.c +++ b/components/openthread/src/esp_openthread_task_queue.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,11 +15,14 @@ #include "freertos/FreeRTOS.h" #include "freertos/portmacro.h" #include "freertos/queue.h" +#include "openthread/tasklet.h" static QueueHandle_t s_task_queue = NULL; static int s_task_queue_event_fd = -1; static const char *task_queue_workflow = "task_queue"; +#define OT_TASK_QUEUE_SENDING_WAIT_TIME pdMS_TO_TICKS(100) + typedef struct { esp_openthread_task_t task; void *arg; @@ -37,6 +40,14 @@ esp_err_t esp_openthread_task_queue_init(const esp_openthread_platform_config_t &esp_openthread_task_queue_process, task_queue_workflow); } +void otTaskletsSignalPending(otInstance *aInstance) +{ + uint64_t val = 1; + ssize_t ret; + ret = write(s_task_queue_event_fd, &val, sizeof(val)); + assert(ret == sizeof(val)); +} + esp_err_t IRAM_ATTR esp_openthread_task_queue_post(esp_openthread_task_t task, void *arg) { task_storage_t task_storage = { @@ -51,7 +62,7 @@ esp_err_t IRAM_ATTR esp_openthread_task_queue_post(esp_openthread_task_t task, v ESP_RETURN_ON_FALSE_ISR(xQueueSendFromISR(s_task_queue, &task_storage, &task_woken), ESP_FAIL, OT_PLAT_LOG_TAG, "Failed to post task to OpenThread task queue"); } else { - ESP_RETURN_ON_FALSE(xQueueSend(s_task_queue, &task_storage, portMAX_DELAY), ESP_FAIL, OT_PLAT_LOG_TAG, + ESP_RETURN_ON_FALSE(xQueueSend(s_task_queue, &task_storage, OT_TASK_QUEUE_SENDING_WAIT_TIME), ESP_FAIL, OT_PLAT_LOG_TAG, "Failed to post task to OpenThread task queue"); } ret = write(s_task_queue_event_fd, &val, sizeof(val)); diff --git a/components/openthread/src/port/esp_openthread_radio.c b/components/openthread/src/port/esp_openthread_radio.c index 07041438b275..4276809c5285 100644 --- a/components/openthread/src/port/esp_openthread_radio.c +++ b/components/openthread/src/port/esp_openthread_radio.c @@ -64,10 +64,13 @@ static otRadioFrame s_ack_frame; static int s_ed_power; static esp_ieee802154_tx_error_t s_tx_error; static int s_radio_event_fd = -1; -static bool s_diag_mode = false; static const char *s_radio_workflow = "radio"; static uint8_t s_txrx_events; +#if CONFIG_OPENTHREAD_DIAG +static bool s_diag_mode = false; +#endif + #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT static otRadioIeInfo s_transmit_ie_info; #endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT @@ -113,7 +116,7 @@ static inline bool get_event(uint8_t event) esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *config) { ESP_RETURN_ON_FALSE(s_radio_event_fd == -1, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, - "Radio was initalized already!"); + "Radio was initialized already!"); s_radio_event_fd = eventfd(0, EFD_SUPPORT_ISR); @@ -165,7 +168,7 @@ esp_err_t esp_openthread_radio_process(otInstance *aInstance, const esp_openthre if (get_event(EVENT_TX_DONE)) { clr_event(EVENT_TX_DONE); -#if OPENTHREAD_CONFIG_DIAG_ENABLE +#if CONFIG_OPENTHREAD_DIAG if (otPlatDiagModeGet()) { otPlatDiagRadioTransmitDone(aInstance, &s_transmit_frame, OT_ERROR_NONE); } else @@ -183,7 +186,7 @@ esp_err_t esp_openthread_radio_process(otInstance *aInstance, const esp_openthre if (get_event(EVENT_TX_FAILED)) { clr_event(EVENT_TX_FAILED); -#if OPENTHREAD_CONFIG_DIAG_ENABLE +#if CONFIG_OPENTHREAD_DIAG if (otPlatDiagModeGet()) { otPlatDiagRadioTransmitDone(aInstance, &s_transmit_frame, OT_ERROR_CHANNEL_ACCESS_FAILURE); } else @@ -219,7 +222,7 @@ esp_err_t esp_openthread_radio_process(otInstance *aInstance, const esp_openthre while (atomic_load(&s_recv_queue.used)) { if (s_receive_frame[s_recv_queue.head].mPsdu != NULL) { -#if OPENTHREAD_CONFIG_DIAG_ENABLE +#if CONFIG_OPENTHREAD_DIAG if (otPlatDiagModeGet()) { otPlatDiagRadioReceiveDone(aInstance, &s_receive_frame[s_recv_queue.head], OT_ERROR_NONE); } else @@ -302,7 +305,7 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) { esp_ieee802154_set_channel(aFrame->mChannel); - aFrame->mPsdu[-1] = aFrame->mLength; // lenth locates one byte before the psdu (esp_openthread_radio_tx_psdu); + aFrame->mPsdu[-1] = aFrame->mLength; // length locates one byte before the psdu (esp_openthread_radio_tx_psdu); if (otMacFrameIsSecurityEnabled(aFrame) && !aFrame->mInfo.mTxInfo.mIsSecurityProcessed) { if (!s_transmit_frame.mInfo.mTxInfo.mIsARetx) { @@ -447,6 +450,15 @@ int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance) return ESP_RECEIVE_SENSITIVITY; } +#if CONFIG_OPENTHREAD_DIAG + +void otPlatDiagSetOutputCallback(otInstance *aInstance, otPlatDiagOutputCallback aCallback, void *aContext) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aCallback); + OT_UNUSED_VARIABLE(aContext); +} + void otPlatDiagModeSet(bool mode) { s_diag_mode = mode; @@ -479,6 +491,8 @@ void otPlatDiagAlarmCallback(otInstance *aInstance) OT_UNUSED_VARIABLE(aInstance); } +#endif // CONFIG_OPENTHREAD_DIAG + #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKeyId, const otMacKeyMaterial *aPrevKey, const otMacKeyMaterial *aCurrKey, const otMacKeyMaterial *aNextKey, otRadioKeyType aKeyType) diff --git a/components/openthread/src/port/esp_openthread_radio_spinel.cpp b/components/openthread/src/port/esp_openthread_radio_spinel.cpp index a926138f9a5a..34eccebc8ad5 100644 --- a/components/openthread/src/port/esp_openthread_radio_spinel.cpp +++ b/components/openthread/src/port/esp_openthread_radio_spinel.cpp @@ -6,6 +6,7 @@ #include "esp_openthread_radio.h" +#include "link_raw.h" #include "sdkconfig.h" #include "esp_check.h" #include "esp_err.h" @@ -23,9 +24,11 @@ #include "openthread/platform/diag.h" #include "openthread/platform/radio.h" #include "platform/exit_code.h" +#include "spinel_driver.hpp" using ot::Spinel::RadioSpinel; using esp::openthread::SpinelInterfaceAdapter; +using ot::Spinel::SpinelDriver; #if CONFIG_OPENTHREAD_RADIO_SPINEL_UART // CONFIG_OPENTHREAD_RADIO_SPINEL_UART using esp::openthread::UartSpinelInterface; @@ -35,7 +38,17 @@ using esp::openthread::SpiSpinelInterface; static SpinelInterfaceAdapter s_spinel_interface; #endif +static SpinelDriver s_spinel_driver; static RadioSpinel s_radio; +static otRadioCaps s_radio_caps = (OT_RADIO_CAPS_ENERGY_SCAN | +#if CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE + OT_RADIO_CAPS_RX_ON_WHEN_IDLE | +#endif + OT_RADIO_CAPS_TRANSMIT_SEC | + OT_RADIO_CAPS_RECEIVE_TIMING | + OT_RADIO_CAPS_TRANSMIT_TIMING | + OT_RADIO_CAPS_ACK_TIMEOUT | + OT_RADIO_CAPS_SLEEP_TO_TX); static const char *radiospinel_workflow = "radio_spinel"; @@ -60,7 +73,7 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf #if CONFIG_OPENTHREAD_DIAG callbacks.mDiagReceiveDone = otPlatDiagRadioReceiveDone; callbacks.mDiagTransmitDone = otPlatDiagRadioTransmitDone; -#endif // OPENTHREAD_CONFIG_DIAG_ENABLE +#endif // CONFIG_OPENTHREAD_DIAG callbacks.mEnergyScanDone = otPlatRadioEnergyScanDone; callbacks.mReceiveDone = otPlatRadioReceiveDone; callbacks.mTransmitDone = otPlatRadioTxDone; @@ -70,14 +83,15 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf esp_openthread_radio_config_set(&config->radio_config); #if CONFIG_OPENTHREAD_RADIO_SPINEL_UART // CONFIG_OPENTHREAD_RADIO_SPINEL_UART ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().Enable(config->radio_config.radio_uart_config), OT_PLAT_LOG_TAG, - "Spinel interface init falied"); + "Spinel interface init failed"); #else // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().Enable(config->radio_config.radio_spi_config), OT_PLAT_LOG_TAG, "Spinel interface init failed"); #endif - s_radio.Init(s_spinel_interface.GetSpinelInterface(), /*reset_radio=*/true, /*skip_rcp_compatibility_check=*/false, iidList, ot::Spinel::kSpinelHeaderMaxNumIid); + s_spinel_driver.Init(s_spinel_interface.GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid); + s_radio.Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver, s_radio_caps); #if CONFIG_OPENTHREAD_RADIO_SPINEL_SPI // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI - ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().AfterRadioInit(), OT_PLAT_LOG_TAG, "Spinel interface init falied"); + ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().AfterRadioInit(), OT_PLAT_LOG_TAG, "Spinel interface init failed"); #endif return esp_openthread_platform_workflow_register(&esp_openthread_radio_update, &esp_openthread_radio_process, radiospinel_workflow); @@ -106,7 +120,7 @@ esp_err_t esp_openthread_rcp_init(void) const esp_openthread_radio_config_t *radio_config = esp_openthread_radio_config_get(); #if CONFIG_OPENTHREAD_RADIO_SPINEL_UART ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().Enable(radio_config->radio_uart_config), OT_PLAT_LOG_TAG, - "Spinel interface init falied"); + "Spinel interface init failed"); #else // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().Enable(radio_config->radio_spi_config), OT_PLAT_LOG_TAG, "Spinel interface init failed"); @@ -128,6 +142,7 @@ void esp_openthread_radio_deinit(void) esp_err_t esp_openthread_radio_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop) { + s_spinel_driver.Process((void *)mainloop); s_radio.Process((void *)mainloop); return ESP_OK; @@ -211,7 +226,8 @@ int8_t otPlatRadioGetRssi(otInstance *instance) otRadioCaps otPlatRadioGetCaps(otInstance *instance) { - return s_radio.GetRadioCaps(); + s_radio_caps = s_radio.GetRadioCaps(); + return s_radio_caps; } bool otPlatRadioGetPromiscuous(otInstance *instance) @@ -319,7 +335,7 @@ void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCoun SuccessOrDie(s_radio.SetMacFrameCounter(aMacFrameCounter, true)); } -#if OPENTHREAD_CONFIG_DIAG_ENABLE +#if CONFIG_OPENTHREAD_DIAG otError otPlatDiagProcess(otInstance *instance, int argc, char *argv[], char *output, size_t output_max_len) { // deliver the platform specific diags commands to radio only ncp. @@ -331,12 +347,19 @@ otError otPlatDiagProcess(otInstance *instance, int argc, char *argv[], char *ou cur += snprintf(cur, static_cast(end - cur), "%s ", argv[index]); } - return s_radio.PlatDiagProcess(cmd, output, output_max_len); + return s_radio.PlatDiagProcess(cmd); +} + +void otPlatDiagSetOutputCallback(otInstance *aInstance, otPlatDiagOutputCallback aCallback, void *aContext) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aCallback); + OT_UNUSED_VARIABLE(aContext); } void otPlatDiagModeSet(bool aMode) { - SuccessOrExit(s_radio.PlatDiagProcess(aMode ? "start" : "stop", NULL, 0)); + SuccessOrExit(s_radio.PlatDiagProcess(aMode ? "start" : "stop")); s_radio.SetDiagEnabled(aMode); exit: @@ -353,7 +376,7 @@ void otPlatDiagTxPowerSet(int8_t tx_power) char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; snprintf(cmd, sizeof(cmd), "power %d", tx_power); - SuccessOrExit(s_radio.PlatDiagProcess(cmd, NULL, 0)); + SuccessOrExit(s_radio.PlatDiagProcess(cmd)); exit: return; @@ -364,7 +387,7 @@ void otPlatDiagChannelSet(uint8_t channel) char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; snprintf(cmd, sizeof(cmd), "channel %d", channel); - SuccessOrExit(s_radio.PlatDiagProcess(cmd, NULL, 0)); + SuccessOrExit(s_radio.PlatDiagProcess(cmd)); exit: return; @@ -378,13 +401,13 @@ void otPlatDiagAlarmCallback(otInstance *instance) { } +#endif // CONFIG_OPENTHREAD_DIAG + const char *otPlatRadioGetVersionString(otInstance *aInstance) { return s_radio.GetVersion(); } -#endif // OPENTHREAD_CONFIG_DIAG_ENABLE - uint64_t otPlatRadioGetNow(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); diff --git a/components/openthread/src/port/esp_openthread_uart.c b/components/openthread/src/port/esp_openthread_uart.c index fc33cd1f93ba..19070a7a228b 100644 --- a/components/openthread/src/port/esp_openthread_uart.c +++ b/components/openthread/src/port/esp_openthread_uart.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,7 @@ #include "esp_openthread_common_macro.h" #include "esp_openthread_platform.h" #include "esp_openthread_types.h" +#include "esp_vfs.h" #include "esp_vfs_dev.h" #include "common/logging.hpp" #include "driver/uart.h" @@ -62,6 +63,17 @@ otError otPlatUartSend(const uint8_t *buf, uint16_t buf_length) esp_err_t esp_openthread_uart_init_port(const esp_openthread_uart_config_t *config) { +#ifndef CONFIG_ESP_CONSOLE_UART + // If UART console is used, UART vfs devices should be registered during startup. + // Otherwise we need to register them here. + DIR *uart_dir = opendir("/dev/uart"); + if (!uart_dir) { + // If UART vfs devices are registered, we will failed to open the directory + uart_vfs_dev_register(); + } else { + closedir(uart_dir); + } +#endif ESP_RETURN_ON_ERROR(uart_param_config(config->port, &config->uart_config), OT_PLAT_LOG_TAG, "uart_param_config failed"); ESP_RETURN_ON_ERROR( @@ -91,7 +103,6 @@ esp_err_t esp_openthread_host_cli_usb_init(const esp_openthread_platform_config_ ret = usb_serial_jtag_driver_install((usb_serial_jtag_driver_config_t *)&config->host_config.host_usb_config); usb_serial_jtag_vfs_use_driver(); - uart_vfs_dev_register(); return ret; } #endif diff --git a/components/openthread/src/port/esp_openthread_udp.c b/components/openthread/src/port/esp_openthread_udp.c index 852c0a920a03..fd118b2a0f7f 100644 --- a/components/openthread/src/port/esp_openthread_udp.c +++ b/components/openthread/src/port/esp_openthread_udp.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ #include "esp_openthread_task_queue.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "lwip/err.h" #include "lwip/ip6.h" #include "lwip/ip6_addr.h" #include "lwip/ip_addr.h" @@ -40,24 +41,19 @@ typedef struct { } udp_recv_task_t; typedef struct { - TaskHandle_t source_task; otUdpSocket *socket; struct udp_pcb *pcb_ret; } udp_new_task_t; typedef struct { - TaskHandle_t source_task; struct udp_pcb *pcb; ip_addr_t addr; uint16_t port; - err_t ret; } udp_bind_connect_task_t; typedef struct { - TaskHandle_t source_task; struct udp_pcb *pcb; uint8_t netif_index; - esp_err_t err; } udp_bind_netif_task_t; typedef struct { @@ -78,13 +74,6 @@ typedef struct { ip6_addr_t addr; } udp_multicast_join_leave_task_t; -static void wait_for_task_notification(void) -{ - esp_openthread_task_switching_lock_release(); - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - esp_openthread_task_switching_lock_acquire(portMAX_DELAY); -} - static ip_addr_t map_openthread_addr_to_lwip_addr(const otIp6Address *address) { ip_addr_t addr; @@ -185,23 +174,25 @@ static void handle_udp_recv(void *ctx, struct udp_pcb *pcb, struct pbuf *p, cons } } -static void udp_new_task(void *ctx) +static esp_err_t udp_new_task(void *ctx) { udp_new_task_t *task = (udp_new_task_t *)ctx; - task->pcb_ret = udp_new(); + ESP_RETURN_ON_FALSE(task->pcb_ret != NULL, ESP_ERR_NO_MEM, OT_PLAT_LOG_TAG, "Failed to create a new UDP pcb"); udp_recv(task->pcb_ret, handle_udp_recv, task->socket); - xTaskNotifyGive(task->source_task); + return ESP_OK; } otError otPlatUdpSocket(otUdpSocket *udp_socket) { otError error = OT_ERROR_NONE; + esp_err_t err = ESP_OK; - udp_new_task_t task = { .source_task = xTaskGetCurrentTaskHandle(), .socket = udp_socket }; - tcpip_callback(udp_new_task, &task); - wait_for_task_notification(); - VerifyOrExit(task.pcb_ret != NULL, error = OT_ERROR_FAILED); + udp_new_task_t task = {.socket = udp_socket }; + esp_openthread_task_switching_lock_release(); + err = esp_netif_tcpip_exec(udp_new_task, &task); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); + VerifyOrExit(err == ESP_OK, error = OT_ERROR_FAILED); udp_socket->mHandle = task.pcb_ret; exit: @@ -220,24 +211,25 @@ otError otPlatUdpClose(otUdpSocket *udp_socket) struct udp_pcb *pcb = (struct udp_pcb *)udp_socket->mHandle; if (pcb) { + esp_openthread_task_switching_lock_release(); tcpip_callback(udp_close_task, pcb); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); } return OT_ERROR_NONE; } -static void udp_bind_task(void *ctx) +static esp_err_t udp_bind_task(void *ctx) { udp_bind_connect_task_t *task = (udp_bind_connect_task_t *)ctx; - - task->ret = udp_bind(task->pcb, &task->addr, task->port); - xTaskNotifyGive(task->source_task); + err_t ret = udp_bind(task->pcb, &task->addr, task->port); + return (ret == ERR_OK) ? ESP_OK : ESP_FAIL; } otError otPlatUdpBind(otUdpSocket *udp_socket) { + esp_err_t err = ESP_OK; udp_bind_connect_task_t task = { - .source_task = xTaskGetCurrentTaskHandle(), .pcb = (struct udp_pcb *)udp_socket->mHandle, .port = udp_socket->mSockName.mPort, }; @@ -247,17 +239,18 @@ otError otPlatUdpBind(otUdpSocket *udp_socket) task.addr.type = IPADDR_TYPE_ANY; #endif memcpy(ip_2_ip6(&task.addr)->addr, udp_socket->mSockName.mAddress.mFields.m8, sizeof(ip_2_ip6(&task.addr)->addr)); - tcpip_callback(udp_bind_task, &task); - wait_for_task_notification(); + esp_openthread_task_switching_lock_release(); + err = esp_netif_tcpip_exec(udp_bind_task, &task); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); - return task.ret == ERR_OK ? OT_ERROR_NONE : OT_ERROR_FAILED; + return err == ESP_OK ? OT_ERROR_NONE : OT_ERROR_FAILED; } -static void udp_bind_netif_task(void *ctx) +static esp_err_t udp_bind_netif_task(void *ctx) { udp_bind_netif_task_t *task = (udp_bind_netif_task_t *)ctx; udp_bind_netif(task->pcb, netif_get_by_index(task->netif_index)); - xTaskNotifyGive(task->source_task); + return ESP_OK; } static uint8_t get_netif_index(otNetifIdentifier netif_identifier) @@ -276,34 +269,30 @@ static uint8_t get_netif_index(otNetifIdentifier netif_identifier) otError otPlatUdpBindToNetif(otUdpSocket *udp_socket, otNetifIdentifier netif_identifier) { - otError err = OT_ERROR_NONE; + esp_err_t err = ESP_OK; udp_bind_netif_task_t task = { - .source_task = xTaskGetCurrentTaskHandle(), .pcb = (struct udp_pcb *)udp_socket->mHandle, .netif_index = get_netif_index(netif_identifier), - .err = ESP_OK, }; - tcpip_callback(udp_bind_netif_task, &task); - wait_for_task_notification(); - if (task.err != ESP_OK) { - err = OT_ERROR_FAILED; - } - return err; + esp_openthread_task_switching_lock_release(); + err = esp_netif_tcpip_exec(udp_bind_netif_task, &task); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); + + return err == ESP_OK ? OT_ERROR_NONE : OT_ERROR_FAILED; } -static void udp_connect_task(void *ctx) +static esp_err_t udp_connect_task(void *ctx) { udp_bind_connect_task_t *task = (udp_bind_connect_task_t *)ctx; - - task->ret = udp_connect(task->pcb, &task->addr, task->port); - xTaskNotifyGive(task->source_task); + err_t ret = udp_connect(task->pcb, &task->addr, task->port); + return (ret == ERR_OK) ? ESP_OK : ESP_FAIL; } otError otPlatUdpConnect(otUdpSocket *udp_socket) { + esp_err_t err = ESP_OK; udp_bind_connect_task_t task = { - .source_task = xTaskGetCurrentTaskHandle(), .pcb = (struct udp_pcb *)udp_socket->mHandle, .port = udp_socket->mPeerName.mPort, }; @@ -312,10 +301,11 @@ otError otPlatUdpConnect(otUdpSocket *udp_socket) if (ip_addr_isany_val(task.addr) && task.port == 0) { return OT_ERROR_NONE; } - tcpip_callback(udp_connect_task, &task); - wait_for_task_notification(); + esp_openthread_task_switching_lock_release(); + err = esp_netif_tcpip_exec(udp_connect_task, &task); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); - return task.ret == ERR_OK ? OT_ERROR_NONE : OT_ERROR_FAILED; + return err == ESP_OK ? OT_ERROR_NONE : OT_ERROR_FAILED; } static bool is_link_local(const otIp6Address *address) @@ -419,7 +409,9 @@ otError otPlatUdpSend(otUdpSocket *udp_socket, otMessage *message, const otMessa // If the destination address is a openthread mesh local address, set the netif OT. task->netif_index = get_netif_index(OT_NETIF_THREAD); } + esp_openthread_task_switching_lock_release(); tcpip_callback(udp_send_task, task); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); exit: return error; @@ -458,7 +450,9 @@ otError otPlatUdpJoinMulticastGroup(otUdpSocket *socket, otNetifIdentifier netif task->netif_index = get_netif_index(netif_id); task->addr.zone = task->netif_index; memcpy(task->addr.addr, addr->mFields.m8, sizeof(task->addr.addr)); + esp_openthread_task_switching_lock_release(); tcpip_callback(udp_multicast_join_leave_task, task); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); exit: return error; @@ -475,7 +469,9 @@ otError otPlatUdpLeaveMulticastGroup(otUdpSocket *socket, otNetifIdentifier neti task->netif_index = get_netif_index(netif_id); task->addr.zone = task->netif_index; memcpy(task->addr.addr, addr->mFields.m8, sizeof(task->addr.addr)); + esp_openthread_task_switching_lock_release(); tcpip_callback(udp_multicast_join_leave_task, task); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); exit: return error; diff --git a/components/openthread/src/port/esp_spi_spinel_interface.cpp b/components/openthread/src/port/esp_spi_spinel_interface.cpp index b89eff6779f7..e19acd915277 100644 --- a/components/openthread/src/port/esp_spi_spinel_interface.cpp +++ b/components/openthread/src/port/esp_spi_spinel_interface.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -266,8 +266,8 @@ otError SpiSpinelInterface::WaitForFrame(uint64_t timeout_us) otError SpiSpinelInterface::HardwareReset(void) { if (mRcpFailureHandler) { - mRcpFailureHandler(); ConductSPITransaction(true, 0, 0); // clear + mRcpFailureHandler(); } return OT_ERROR_NONE; } diff --git a/components/openthread/src/port/esp_uart_spinel_interface.cpp b/components/openthread/src/port/esp_uart_spinel_interface.cpp index 2cfa42d5e42f..6f683fdee4ab 100644 --- a/components/openthread/src/port/esp_uart_spinel_interface.cpp +++ b/components/openthread/src/port/esp_uart_spinel_interface.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -295,8 +295,8 @@ esp_err_t UartSpinelInterface::TryRecoverUart(void) otError UartSpinelInterface::HardwareReset(void) { if (mRcpFailureHandler) { - mRcpFailureHandler(); TryRecoverUart(); + mRcpFailureHandler(); } return OT_ERROR_NONE; } diff --git a/components/openthread/src/spinel/esp_radio_spinel.cpp b/components/openthread/src/spinel/esp_radio_spinel.cpp index 2b7bcfdf16bc..fbf794046df9 100644 --- a/components/openthread/src/spinel/esp_radio_spinel.cpp +++ b/components/openthread/src/spinel/esp_radio_spinel.cpp @@ -12,17 +12,33 @@ #include "esp_radio_spinel.h" #include "esp_radio_spinel_adapter.hpp" #include "esp_radio_spinel_uart_interface.hpp" +#include "spinel_driver.hpp" + +#define SPINEL_VENDOR_PROPERTY_BIT_PENDINGMODE BIT(0) +#define SPINEL_VENDOR_PROPERTY_BIT_COORDINATOR BIT(1) +static esp_ieee802154_pending_mode_t s_spinel_vendor_property_pendingmode[ot::Spinel::kSpinelHeaderMaxNumIid] = {ESP_IEEE802154_AUTO_PENDING_DISABLE}; +static bool s_spinel_vendor_property_coordinator[ot::Spinel::kSpinelHeaderMaxNumIid] = {false}; +static uint64_t s_spinel_vendor_property_mask[ot::Spinel::kSpinelHeaderMaxNumIid] = {0}; using ot::Spinel::RadioSpinel; using ot::Spinel::RadioSpinelCallbacks; using esp::radio_spinel::SpinelInterfaceAdapter; using esp::radio_spinel::UartSpinelInterface; +using ot::Spinel::SpinelDriver; static SpinelInterfaceAdapter s_spinel_interface[ot::Spinel::kSpinelHeaderMaxNumIid]; static RadioSpinel s_radio[ot::Spinel::kSpinelHeaderMaxNumIid]; static esp_radio_spinel_callbacks_t s_esp_radio_spinel_callbacks[ot::Spinel::kSpinelHeaderMaxNumIid]; +static SpinelDriver s_spinel_driver[ot::Spinel::kSpinelHeaderMaxNumIid]; otRadioFrame s_transmit_frame; +static otRadioCaps s_radio_caps = (OT_RADIO_CAPS_ENERGY_SCAN | + OT_RADIO_CAPS_TRANSMIT_SEC | + OT_RADIO_CAPS_RECEIVE_TIMING | + OT_RADIO_CAPS_TRANSMIT_TIMING | + OT_RADIO_CAPS_ACK_TIMEOUT | + OT_RADIO_CAPS_SLEEP_TO_TX); + static esp_radio_spinel_idx_t get_index_from_instance(otInstance *instance) { // TZ-563: Implement the function to get the esp radio spinel idx from otInstance for multipan rcp @@ -35,6 +51,22 @@ static otInstance* get_instance_from_index(esp_radio_spinel_idx_t idx) return nullptr; } +static void esp_radio_spinel_restore_vendor_properities(void *context) +{ + esp_radio_spinel_idx_t idx = get_index_from_instance((otInstance*)context); + if (s_spinel_vendor_property_mask[idx] & SPINEL_VENDOR_PROPERTY_BIT_PENDINGMODE) { + if (esp_radio_spinel_set_pending_mode(s_spinel_vendor_property_pendingmode[idx], idx) != ESP_OK) { + ESP_LOGE(ESP_SPINEL_LOG_TAG, "Fail to restore pendingmode: %d", idx); + } + } + + if (s_spinel_vendor_property_mask[idx] & SPINEL_VENDOR_PROPERTY_BIT_COORDINATOR) { + if (esp_radio_spinel_set_pan_coord(s_spinel_vendor_property_coordinator[idx], idx) != ESP_OK) { + ESP_LOGE(ESP_SPINEL_LOG_TAG, "Fail to restore coordinator: %d", idx); + } + } +} + void ReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError) { esp_radio_spinel_idx_t idx = get_index_from_instance(aInstance); @@ -213,7 +245,10 @@ void esp_radio_spinel_init(esp_radio_spinel_idx_t idx) // Multipan is not currently supported iidList[0] = 0; - s_radio[idx].Init(s_spinel_interface[idx].GetSpinelInterface(), /*reset_radio=*/true, /*skip_rcp_compatibility_check=*/false, iidList, ot::Spinel::kSpinelHeaderMaxNumIid); + s_spinel_driver[idx].Init(s_spinel_interface[idx].GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid); + s_radio[idx].Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver[idx], s_radio_caps); + otInstance *instance = get_instance_from_index(idx); + s_radio[idx].SetVendorRestorePropertiesCallback(esp_radio_spinel_restore_vendor_properities, instance); } esp_err_t esp_radio_spinel_enable(esp_radio_spinel_idx_t idx) @@ -222,11 +257,6 @@ esp_err_t esp_radio_spinel_enable(esp_radio_spinel_idx_t idx) return (s_radio[idx].Enable(instance) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL; } -esp_err_t esp_radio_spinel_set_pending_mode(esp_ieee802154_pending_mode_t pending_mode, esp_radio_spinel_idx_t idx) -{ - return (s_radio[idx].Set(SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE, SPINEL_DATATYPE_INT32_S, static_cast(pending_mode)) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL; -} - esp_err_t esp_radio_spinel_get_eui64(uint8_t *eui64, esp_radio_spinel_idx_t idx) { return (s_radio[idx].GetIeeeEui64(eui64) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL; @@ -249,11 +279,6 @@ esp_err_t esp_radio_spinel_set_extended_address(uint8_t *ext_address, esp_radio_ return (s_radio[idx].SetExtendedAddress(aExtAddress) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL; } -esp_err_t esp_radio_spinel_set_pan_coord(bool enable, esp_radio_spinel_idx_t idx) -{ - return (s_radio[idx].Set(SPINEL_PROP_VENDOR_ESP_SET_COORDINATOR, SPINEL_DATATYPE_BOOL_S, enable) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL; -} - esp_err_t esp_radio_spinel_receive(uint8_t channel, esp_radio_spinel_idx_t idx) { return (s_radio[idx].Receive(channel) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL; @@ -302,6 +327,24 @@ esp_err_t esp_radio_spinel_set_promiscuous_mode(bool enable, esp_radio_spinel_id return (s_radio[idx].SetPromiscuous(enable) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL; } +/*------------------------------------------------Vendor Property Set-------------------------------------------------------*/ +esp_err_t esp_radio_spinel_set_pending_mode(esp_ieee802154_pending_mode_t pending_mode, esp_radio_spinel_idx_t idx) +{ + s_spinel_vendor_property_pendingmode[idx] = pending_mode; + s_spinel_vendor_property_mask[idx] |= SPINEL_VENDOR_PROPERTY_BIT_PENDINGMODE; + return (s_radio[idx].Set(SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE, SPINEL_DATATYPE_INT32_S, static_cast(pending_mode)) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_radio_spinel_set_pan_coord(bool enable, esp_radio_spinel_idx_t idx) +{ + s_spinel_vendor_property_coordinator[idx] = enable; + s_spinel_vendor_property_mask[idx] |= SPINEL_VENDOR_PROPERTY_BIT_COORDINATOR; + return (s_radio[idx].Set(SPINEL_PROP_VENDOR_ESP_SET_COORDINATOR, SPINEL_DATATYPE_BOOL_S, enable) == OT_ERROR_NONE) ? ESP_OK : ESP_FAIL; +} + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + void esp_radio_spinel_radio_update(esp_radio_spinel_mainloop_context_t *mainloop_context, esp_radio_spinel_idx_t idx) { s_spinel_interface[idx].GetSpinelInterface().UpdateFdSet(static_cast(mainloop_context)); @@ -309,6 +352,7 @@ void esp_radio_spinel_radio_update(esp_radio_spinel_mainloop_context_t *mainloop void esp_radio_spinel_radio_process(esp_radio_spinel_mainloop_context_t *mainloop_context, esp_radio_spinel_idx_t idx) { + s_spinel_driver[idx].Process((void *)mainloop_context); s_radio[idx].Process(static_cast(mainloop_context)); } @@ -354,3 +398,29 @@ esp_err_t esp_radio_spinel_rcp_version_get(char *running_rcp_version, esp_radio_ strcpy(running_rcp_version, rcp_version); return ESP_OK; } + +esp_err_t esp_radio_spinel_set_rcp_ready(esp_radio_spinel_idx_t idx) +{ + s_spinel_driver[idx].SetCoprocessorReady(); + return ESP_OK; +} + +namespace ot { +namespace Spinel { + +otError RadioSpinel::VendorHandleValueIs(spinel_prop_key_t aPropKey) +{ + otError error = OT_ERROR_NONE; + + switch (aPropKey) + { + default: + ESP_LOGW(ESP_SPINEL_LOG_TAG, "Not Implemented!"); + error = OT_ERROR_NOT_FOUND; + break; + } + return error; +} + +} // namespace Spinel +} // namespace ot diff --git a/components/openthread/src/spinel/esp_radio_spinel_uart_interface.cpp b/components/openthread/src/spinel/esp_radio_spinel_uart_interface.cpp index d07a67065b18..b01ef694c278 100644 --- a/components/openthread/src/spinel/esp_radio_spinel_uart_interface.cpp +++ b/components/openthread/src/spinel/esp_radio_spinel_uart_interface.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ #include "esp_openthread_common_macro.h" #include "openthread/platform/time.h" #include "hdlc.hpp" +#include "core/common/code_utils.hpp" namespace esp { namespace radio_spinel { @@ -276,8 +277,8 @@ esp_err_t UartSpinelInterface::TryRecoverUart(void) otError UartSpinelInterface::HardwareReset(void) { if (mRcpFailureHandler) { - mRcpFailureHandler(); TryRecoverUart(); + mRcpFailureHandler(); } return OT_ERROR_NONE; } diff --git a/components/protocomm/include/transports/protocomm_ble.h b/components/protocomm/include/transports/protocomm_ble.h index 51aec06e99f9..cbc7c81bd52a 100644 --- a/components/protocomm/include/transports/protocomm_ble.h +++ b/components/protocomm/include/transports/protocomm_ble.h @@ -41,6 +41,7 @@ typedef enum { * (29 - (BLE device name length) - 2). */ #define MAX_BLE_MANUFACTURER_DATA_LEN 29 +#define BLE_ADDR_LEN 6 /** * @brief This structure maps handler required by protocomm layer to * UUIDs which are used to uniquely identify BLE characteristics @@ -137,6 +138,10 @@ typedef struct protocomm_ble_config { */ unsigned ble_link_encryption:1; + /** + * BLE address + */ + uint8_t *ble_addr; } protocomm_ble_config_t; /** diff --git a/components/protocomm/src/simple_ble/simple_ble.c b/components/protocomm/src/simple_ble/simple_ble.c index 79100f2db627..ac33cf2409fa 100644 --- a/components/protocomm/src/simple_ble/simple_ble.c +++ b/components/protocomm/src/simple_ble/simple_ble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -49,12 +49,24 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param switch (event) { case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: adv_config_done &= (~adv_config_flag); + + if (g_ble_cfg_p->ble_addr) { + esp_ble_gap_set_rand_addr(g_ble_cfg_p->ble_addr); + g_ble_cfg_p->adv_params.own_addr_type = BLE_ADDR_TYPE_RANDOM; + } + if (adv_config_done == 0) { esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params); } break; case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: adv_config_done &= (~scan_rsp_config_flag); + + if (g_ble_cfg_p->ble_addr) { + esp_ble_gap_set_rand_addr(g_ble_cfg_p->ble_addr); + g_ble_cfg_p->adv_params.own_addr_type = BLE_ADDR_TYPE_RANDOM; + } + if (adv_config_done == 0) { esp_ble_gap_start_advertising(&g_ble_cfg_p->adv_params); } @@ -187,7 +199,7 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_ simple_ble_cfg_t *simple_ble_init(void) { - simple_ble_cfg_t *ble_cfg_p = (simple_ble_cfg_t *) malloc(sizeof(simple_ble_cfg_t)); + simple_ble_cfg_t *ble_cfg_p = (simple_ble_cfg_t *) calloc(1, sizeof(simple_ble_cfg_t)); if (ble_cfg_p == NULL) { ESP_LOGE(TAG, "No memory for simple_ble_cfg_t"); return NULL; diff --git a/components/protocomm/src/simple_ble/simple_ble.h b/components/protocomm/src/simple_ble/simple_ble.h index 06d2bfa7b2bb..259225de8308 100644 --- a/components/protocomm/src/simple_ble/simple_ble.h +++ b/components/protocomm/src/simple_ble/simple_ble.h @@ -51,6 +51,9 @@ typedef struct { unsigned ble_bonding:1; /** BLE Secure Connection flag */ unsigned ble_sm_sc:1; + /** BLE Address */ + uint8_t *ble_addr; + } simple_ble_cfg_t; diff --git a/components/protocomm/src/transports/protocomm_ble.c b/components/protocomm/src/transports/protocomm_ble.c index 322c6086411e..6fedd85abb92 100644 --- a/components/protocomm/src/transports/protocomm_ble.c +++ b/components/protocomm/src/transports/protocomm_ble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -103,6 +103,7 @@ static esp_ble_adv_params_t adv_params = { static char *protocomm_ble_device_name = NULL; static uint8_t *protocomm_ble_mfg_data = NULL; static size_t protocomm_ble_mfg_data_len; +static uint8_t *protocomm_ble_addr = NULL; static void hexdump(const char *msg, uint8_t *buf, int len) { @@ -524,6 +525,10 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con protocomm_ble_mfg_data_len = config->manufacturer_data_len; } + if (config->ble_addr != NULL) { + protocomm_ble_addr = config->ble_addr; + } + protoble_internal = (_protocomm_ble_internal_t *) calloc(1, sizeof(_protocomm_ble_internal_t)); if (protoble_internal == NULL) { ESP_LOGE(TAG, "Error allocating internal protocomm structure"); @@ -594,6 +599,10 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con ble_config->ble_bonding = config->ble_bonding; ble_config->ble_sm_sc = config->ble_sm_sc; + if (config->ble_addr != NULL) { + ble_config->ble_addr = protocomm_ble_addr; + } + if (ble_config->gatt_db_count == -1) { ESP_LOGE(TAG, "Invalid GATT database count"); simple_ble_deinit(); diff --git a/components/protocomm/src/transports/protocomm_nimble.c b/components/protocomm/src/transports/protocomm_nimble.c index 1f6e55657831..8aa2e4ec6def 100644 --- a/components/protocomm/src/transports/protocomm_nimble.c +++ b/components/protocomm/src/transports/protocomm_nimble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -79,6 +79,7 @@ static struct ble_hs_adv_fields adv_data, resp_data; static uint8_t *protocomm_ble_mfg_data; static size_t protocomm_ble_mfg_data_len; +static uint8_t *protocomm_ble_addr; /********************************************************************** * Maintain database of uuid_name addresses to free memory afterwards * **********************************************************************/ @@ -130,6 +131,8 @@ typedef struct { unsigned ble_sm_sc:1; /** BLE Link Encryption flag */ unsigned ble_link_encryption:1; + /** BLE address */ + uint8_t *ble_addr; } simple_ble_cfg_t; static simple_ble_cfg_t *ble_cfg_p; @@ -461,10 +464,25 @@ simple_ble_on_sync(void) { int rc; - rc = ble_hs_util_ensure_addr(0); - if (rc != 0) { - ESP_LOGE(TAG, "Error loading address"); - return; + if (protocomm_ble_addr) { + rc = ble_hs_id_set_rnd(protocomm_ble_addr); + if (rc != 0) { + ESP_LOGE(TAG,"Error in setting address"); + return; + } + + rc = ble_hs_util_ensure_addr(1); + if (rc != 0) { + ESP_LOGE(TAG,"Error loading address"); + return; + } + } + else { + rc = ble_hs_util_ensure_addr(0); + if (rc != 0) { + ESP_LOGE(TAG, "Error loading address"); + return; + } } /* Figure out address to use while advertising (no privacy for now) */ @@ -727,7 +745,7 @@ ble_gatt_add_primary_svcs(struct ble_gatt_svc_def *gatt_db_svcs, int char_count) gatt_db_svcs->type = BLE_GATT_SVC_TYPE_PRIMARY; /* Allocate (number of characteristics + 1) memory for characteristics, the - * addtional characteristic consist of all 0s indicating end of + * additional characteristic consist of all 0s indicating end of * characteristics */ gatt_db_svcs->characteristics = (struct ble_gatt_chr_def *) calloc((char_count + 1), sizeof(struct ble_gatt_chr_def)); @@ -781,7 +799,7 @@ populate_gatt_db(struct ble_gatt_svc_def **gatt_db_svcs, const protocomm_ble_con rc = ble_gatt_add_char_dsc((void *) (*gatt_db_svcs)->characteristics, i, BLE_GATT_UUID_CHAR_DSC); if (rc != 0) { - ESP_LOGE(TAG, "Error adding GATT Discriptor !!"); + ESP_LOGE(TAG, "Error adding GATT Descriptor !!"); return rc; } } @@ -813,6 +831,11 @@ static void protocomm_ble_cleanup(void) protocomm_ble_mfg_data = NULL; protocomm_ble_mfg_data_len = 0; } + + if (protocomm_ble_addr) { + free(protocomm_ble_addr); + protocomm_ble_addr = NULL; + } } static void free_gatt_ble_misc_memory(simple_ble_cfg_t *ble_config) @@ -970,6 +993,10 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con ble_config->ble_bonding = config->ble_bonding; ble_config->ble_sm_sc = config->ble_sm_sc; + if (config->ble_addr != NULL) { + protocomm_ble_addr = config->ble_addr; + } + if (populate_gatt_db(&ble_config->gatt_db, config) != 0) { ESP_LOGE(TAG, "Error populating GATT Database"); free_gatt_ble_misc_memory(ble_config); diff --git a/components/pthread/pthread_local_storage.c b/components/pthread/pthread_local_storage.c index 19cb73a98d88..80b562edb533 100644 --- a/components/pthread/pthread_local_storage.c +++ b/components/pthread/pthread_local_storage.c @@ -147,7 +147,9 @@ static void pthread_cleanup_thread_specific_data_callback(int index, void *v_tls free(tls); } -/* this function called from pthread_task_func for "early" cleanup of TLS in a pthread */ +/* this function called from pthread_task_func for "early" cleanup of TLS in a pthread + and from pthread_join/pthread_detach for cleanup of TLS after pthread exit +*/ void pthread_internal_local_storage_destructor_callback(TaskHandle_t handle) { void *tls = pvTaskGetThreadLocalStoragePointer(handle, PTHREAD_TLS_INDEX); @@ -157,9 +159,9 @@ void pthread_internal_local_storage_destructor_callback(TaskHandle_t handle) calling it again... */ #if !defined(CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS) - vTaskSetThreadLocalStoragePointer(NULL, PTHREAD_TLS_INDEX, NULL); + vTaskSetThreadLocalStoragePointer(handle, PTHREAD_TLS_INDEX, NULL); #else - vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, + vTaskSetThreadLocalStoragePointerAndDelCallback(handle, PTHREAD_TLS_INDEX, NULL, NULL); diff --git a/components/riscv/include/esp_private/interrupt_clic.h b/components/riscv/include/esp_private/interrupt_clic.h index 8628e4761ad8..095cff6af2f3 100644 --- a/components/riscv/include/esp_private/interrupt_clic.h +++ b/components/riscv/include/esp_private/interrupt_clic.h @@ -46,6 +46,27 @@ extern "C" { #define MTVT_CSR 0x307 +#if CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION + +/** + * The ESP32-P4 and the beta version of the ESP32-C5 implement a non-standard version of the CLIC: + * - The interrupt threshold is configured via a memory-mapped register instead of a CSR + * - The mintstatus CSR is at 0x346 instead of 0xFB1 as per the official specification + */ +#define INTTHRESH_STANDARD 0 +#define MINTSTATUS_CSR 0x346 + +#elif CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 + +/* The ESP32-C5 (MP) and C61 use the standard CLIC specification, for example, it defines the mintthresh CSR */ +#define INTTHRESH_STANDARD 1 +#define MINTSTATUS_CSR 0xFB1 +#define MINTTHRESH_CSR 0x347 + +#else + #error "Check the implementation of the CLIC on this target." +#endif + /** * @brief Convert a priority level from 8-bit to NLBITS and NLBITS to 8-bit * @@ -58,12 +79,33 @@ extern "C" { /* Align the level to the left, and put 1 in the lowest bits */ #define NLBITS_TO_BYTE(level) (((level) << NLBITS_SHIFT) | ((1 << NLBITS_SHIFT) - 1)) +/** + * @brief In the minstatus CSR, the `mil` field is present from bit 24 to bit 31 (included) + */ +#define MINTSTATUS_MIL_S 24 +#define MINTSTATUS_MIL_V 0xFF + -/* Helper macro to translate absolute interrupt level to CLIC interrupt threshold bits in the mintthresh reg */ -#define CLIC_INT_THRESH(intlevel) (NLBITS_TO_BYTE(intlevel) << CLIC_CPU_INT_THRESH_S) +#if INTTHRESH_STANDARD + /* Helper macro to translate absolute interrupt level to CLIC interrupt threshold bits in the mintthresh reg */ + #define CLIC_INT_THRESH(intlevel) (NLBITS_TO_BYTE(intlevel)) + + /* Helper macro to translate a CLIC interrupt threshold bits to an absolute interrupt level */ + #define CLIC_THRESH_TO_INT(intlevel) (BYTE_TO_NLBITS((intlevel))) + + /* Helper macro to translate a CLIC status threshold bits to an absolute interrupt level */ + #define CLIC_STATUS_TO_INT(status) (BYTE_TO_NLBITS((status >> MINTSTATUS_MIL_S) & MINTSTATUS_MIL_V)) +#else + /* For the non-standard intthresh implementation the threshold is stored in the upper 8 bits of CLIC_CPU_INT_THRESH reg */ + /* Helper macro to translate absolute interrupt level to CLIC interrupt threshold bits in the mintthresh reg */ + #define CLIC_INT_THRESH(intlevel) (NLBITS_TO_BYTE(intlevel) << CLIC_CPU_INT_THRESH_S) + + /* Helper macro to translate a CLIC interrupt threshold bits to an absolute interrupt level */ + #define CLIC_THRESH_TO_INT(intlevel) (BYTE_TO_NLBITS((intlevel >> CLIC_CPU_INT_THRESH_S) & CLIC_CPU_INT_THRESH_V)) -/* Helper macro to translate a CLIC interrupt threshold bits to an absolute interrupt level */ -#define CLIC_THRESH_TO_INT(intlevel) (BYTE_TO_NLBITS((intlevel >> CLIC_CPU_INT_THRESH_S) & CLIC_CPU_INT_THRESH_V)) + /* Helper macro to translate a CLIC status threshold bits to an absolute interrupt level */ + #define CLIC_STATUS_TO_INT(status) (BYTE_TO_NLBITS((status >> MINTSTATUS_MIL_S) & MINTSTATUS_MIL_V)) +#endif //INTTHRESH_STANDARD /* Helper macro to set interrupt level RVHAL_EXCM_LEVEL. Used during critical sections */ #define RVHAL_EXCM_LEVEL_CLIC (CLIC_INT_THRESH(RVHAL_EXCM_LEVEL - 1)) @@ -72,26 +114,7 @@ extern "C" { #define RVHAL_INTR_ENABLE_THRESH_CLIC (CLIC_INT_THRESH(RVHAL_INTR_ENABLE_THRESH)) -#if CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - -/** - * The ESP32-P4 and the beta version of the ESP32-C5 implement a non-standard version of the CLIC: - * - The interrupt threshold is configured via a memory-mapped register instead of a CSR - * - The mintstatus CSR is at 0x346 instead of 0xFB1 as per the official specification - */ -#define INTTHRESH_STANDARD 0 -#define MINTSTATUS_CSR 0x346 - -#elif CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 - -/* The ESP32-C5 (MP) and C61 use the standard CLIC specification, for example, it defines the mintthresh CSR */ -#define INTTHRESH_STANDARD 1 -#define MINTSTATUS_CSR 0xFB1 -#define MINTTHRESH_CSR 0x347 -#else - #error "Check the implementation of the CLIC on this target." -#endif FORCE_INLINE_ATTR void assert_valid_rv_int_num(int rv_int_num) @@ -140,7 +163,7 @@ FORCE_INLINE_ATTR uint32_t rv_utils_get_interrupt_level(void) { const uint32_t mintstatus = RV_READ_CSR(MINTSTATUS_CSR); /* Extract the level from this field */ - return CLIC_THRESH_TO_INT(mintstatus); + return CLIC_STATUS_TO_INT(mintstatus); } /** diff --git a/components/riscv/include/esp_private/panic_reason.h b/components/riscv/include/esp_private/panic_reason.h index 252f6de9c0b2..fdbee96fa306 100644 --- a/components/riscv/include/esp_private/panic_reason.h +++ b/components/riscv/include/esp_private/panic_reason.h @@ -19,4 +19,6 @@ #define PANIC_RSN_CACHEERR 3 -#define MCAUSE_ILLEGAL_INSTRUCTION 2 +#define MCAUSE_ILLIGAL_INSTRUCTION_ACCESS 1 +#define MCAUSE_ILLEGAL_INSTRUCTION 2 +#define MCAUSE_LOAD_ACCESS_FAULT 5 diff --git a/components/riscv/include/riscv/csr_hwlp.h b/components/riscv/include/riscv/csr_hwlp.h new file mode 100644 index 000000000000..83a44ea4413b --- /dev/null +++ b/components/riscv/include/riscv/csr_hwlp.h @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc_caps.h" + +#if SOC_CPU_HAS_HWLOOP + +/* CSR 0x7F1 lowest 2 bits describe the following states: + * 00: OFF + * 01: Initial + * 10: Clean + * 11: Dirty + */ +#define CSR_HWLP_STATE_REG 0x7F1 + +#define HWLP_OFF_STATE 0 +#define HWLP_INITIAL_STATE 1 +#define HWLP_CLEAN_STATE 2 +#define HWLP_DIRTY_STATE 3 + +#define CSR_LOOP0_START_ADDR 0x7C6 +#define CSR_LOOP0_END_ADDR 0x7C7 +#define CSR_LOOP0_COUNT 0x7C8 +#define CSR_LOOP1_START_ADDR 0x7C9 +#define CSR_LOOP1_END_ADDR 0x7CA +#define CSR_LOOP1_COUNT 0x7CB + +#endif /* SOC_CPU_HAS_HWLOOP */ diff --git a/components/riscv/include/riscv/csr_pie.h b/components/riscv/include/riscv/csr_pie.h new file mode 100644 index 000000000000..59b5c8f25d73 --- /dev/null +++ b/components/riscv/include/riscv/csr_pie.h @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc_caps.h" + +#if SOC_CPU_HAS_PIE + +/* CSR lowest 2 bits describe the following states: + * 00: OFF + * 01: Initial + * 10: Clean + * 11: Dirty + */ +#define CSR_PIE_STATE_REG 0x7F2 + +#endif /* SOC_CPU_HAS_PIE */ diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index 716fee6e80b5..c0d3a64b2f03 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.h @@ -14,6 +14,7 @@ #include "esp_attr.h" #include "riscv/csr.h" #include "riscv/interrupt.h" +#include "riscv/csr_pie.h" #ifdef __cplusplus extern "C" { @@ -168,6 +169,27 @@ FORCE_INLINE_ATTR void rv_utils_disable_fpu(void) #endif /* SOC_CPU_HAS_FPU */ +/* ------------------------------------------------- PIE Related ---------------------------------------------------- + * + * ------------------------------------------------------------------------------------------------------------------ */ + +#if SOC_CPU_HAS_PIE + +FORCE_INLINE_ATTR void rv_utils_enable_pie(void) +{ + RV_WRITE_CSR(CSR_PIE_STATE_REG, 1); +} + + +FORCE_INLINE_ATTR void rv_utils_disable_pie(void) +{ + RV_WRITE_CSR(CSR_PIE_STATE_REG, 0); +} + +#endif /* SOC_CPU_HAS_FPU */ + + + /* -------------------------------------------------- Memory Ports ----------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ */ diff --git a/components/riscv/include/riscv/rvruntime-frames.h b/components/riscv/include/riscv/rvruntime-frames.h index e218d6a5ad3e..45f013b0e5ff 100644 --- a/components/riscv/include/riscv/rvruntime-frames.h +++ b/components/riscv/include/riscv/rvruntime-frames.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -86,7 +86,21 @@ STRUCT_END(RvExcFrame) #if SOC_CPU_COPROC_NUM > 0 +/* Define the default size of each coprocessor save area */ +#define RV_COPROC0_SIZE 0 +#define RV_COPROC1_SIZE 0 +#define RV_COPROC2_SIZE 0 +/* And the alignment for each of them */ +#define RV_COPROC0_ALIGN 4 +#define RV_COPROC1_ALIGN 4 +#define RV_COPROC2_ALIGN 4 + + #if SOC_CPU_HAS_FPU + +/* Floating-Point Unit coprocessor is now considered coprocessor 0 */ +#define FPU_COPROC_IDX 0 + /** * @brief Floating-Point Unit save area */ @@ -126,29 +140,97 @@ STRUCT_FIELD (long, 4, RV_FPU_FT11, ft11) STRUCT_FIELD (long, 4, RV_FPU_FCSR, fcsr) /* fcsr special register */ STRUCT_END(RvFPUSaveArea) -/* Floating-Point Unit coprocessor is now considered coprocessor 0 */ -#define FPU_COPROC_IDX 0 -/* PIE/AIA coprocessor is coprocessor 1 */ -#define PIE_COPROC_IDX 1 - -/* Define the size of each coprocessor save area */ +/* Redefine the coprocessor area size previously defined to 0 */ +#undef RV_COPROC0_SIZE #if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) -#define RV_COPROC0_SIZE RvFPUSaveAreaSize -#define RV_COPROC1_SIZE 0 // PIE/AIA coprocessor area + #define RV_COPROC0_SIZE RvFPUSaveAreaSize #else -#define RV_COPROC0_SIZE sizeof(RvFPUSaveArea) -#define RV_COPROC1_SIZE 0 // PIE/AIA coprocessor area + #define RV_COPROC0_SIZE sizeof(RvFPUSaveArea) #endif /* defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) */ #endif /* SOC_CPU_HAS_FPU */ + +#if SOC_CPU_HAS_HWLOOP + +/* Hardware Loop extension is "coprocessor" 1 */ +#define HWLP_COPROC_IDX 1 + +/** + * @brief Hardware loop save area + */ +STRUCT_BEGIN +STRUCT_FIELD (long, 4, RV_HWLOOP_START0, start0) +STRUCT_FIELD (long, 4, RV_HWLOOP_END0, end0) +STRUCT_FIELD (long, 4, RV_HWLOOP_COUNT0, count0) +STRUCT_FIELD (long, 4, RV_HWLOOP_START1, start1) +STRUCT_FIELD (long, 4, RV_HWLOOP_END1, end1) +STRUCT_FIELD (long, 4, RV_HWLOOP_COUNT1, count1) +STRUCT_END(RvHWLPSaveArea) + +/* Redefine the coprocessor area size previously defined to 0 */ +#undef RV_COPROC1_SIZE +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) + #define RV_COPROC1_SIZE RvHWLPSaveAreaSize +#else + #define RV_COPROC1_SIZE sizeof(RvHWLPSaveArea) +#endif /* defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) */ + +#endif /* SOC_CPU_HAS_HWLOOP */ + + + +#if SOC_CPU_HAS_PIE + +/* PIE/AIA coprocessor is now considered coprocessor 2 */ +#define PIE_COPROC_IDX 2 + +/** + * @brief PIE save area + */ +STRUCT_BEGIN +STRUCT_AFIELD (long, 4, RV_PIE_Q0, q0, 4) +STRUCT_AFIELD (long, 4, RV_PIE_Q1, q1, 4) +STRUCT_AFIELD (long, 4, RV_PIE_Q2, q2, 4) +STRUCT_AFIELD (long, 4, RV_PIE_Q3, q3, 4) +STRUCT_AFIELD (long, 4, RV_PIE_Q4, q4, 4) +STRUCT_AFIELD (long, 4, RV_PIE_Q5, q5, 4) +STRUCT_AFIELD (long, 4, RV_PIE_Q6, q6, 4) +STRUCT_AFIELD (long, 4, RV_PIE_Q7, q7, 4) +STRUCT_AFIELD (long, 4, RV_PIE_QACC_L_L, qacc_l_l, 4) +STRUCT_AFIELD (long, 4, RV_PIE_QACC_L_H, qacc_l_h, 4) +STRUCT_AFIELD (long, 4, RV_PIE_QACC_H_L, qacc_h_l, 4) +STRUCT_AFIELD (long, 4, RV_PIE_QACC_H_H, qacc_h_h, 4) +STRUCT_AFIELD (long, 4, RV_PIE_UA_STATE, ua_state, 4) +STRUCT_FIELD (long, 4, RV_PIE_XACC, xacc) +/* This register contains SAR, SAR_BYTES and FFT_BIT_WIDTH in this order (from top to low) */ +STRUCT_FIELD (long, 4, RV_PIE_MISC, misc) +STRUCT_END(RvPIESaveArea) + +/* Redefine the coprocessor area size previously defined to 0 */ +#undef RV_COPROC2_SIZE + +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) + #define RV_COPROC2_SIZE RvPIESaveAreaSize +#else + #define RV_COPROC2_SIZE sizeof(RvPIESaveArea) +#endif /* defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) */ + +/* The PIE save area structure must be aligned on 16 bytes */ +#undef RV_COPROC2_ALIGN +#define RV_COPROC2_ALIGN 16 + +#endif /* SOC_CPU_HAS_PIE */ + + + /** * @brief Coprocessors save area, containing each coprocessor save area */ STRUCT_BEGIN /* Enable bitmap: BIT(i) represents coprocessor i, 1 is used, 0 else */ STRUCT_FIELD (long, 4, RV_COPROC_ENABLE, sa_enable) -/* Address of the original lowest stack address, convenient when the stack needs to re-initialized */ +/* Address of the original lowest stack address, convenient when the stack needs to be re-initialized */ STRUCT_FIELD (void*, 4, RV_COPROC_TCB_STACK, sa_tcbstack) /* Address of the pool of memory used to allocate coprocessors save areas */ STRUCT_FIELD (long, 4, RV_COPROC_ALLOCATOR, sa_allocator) diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S index 0b46681416bc..058877f8ed69 100644 --- a/components/riscv/vectors.S +++ b/components/riscv/vectors.S @@ -25,11 +25,11 @@ /* EXT_ILL CSR reasons are stored as follows: * - Bit 0: FPU core instruction (Load/Store instructions NOT concerned) - * - Bit 1: Low-power core + * - Bit 1: Hardware Loop instructions * - Bit 2: PIE core */ - .equ EXT_ILL_RSN_FPU, 1 - .equ EXT_ILL_RSN_LP, 2 - .equ EXT_ILL_RSN_PIE, 4 + .equ EXT_ILL_RSN_FPU, 1 + .equ EXT_ILL_RSN_HWLP, 2 + .equ EXT_ILL_RSN_PIE, 4 #endif /* SOC_CPU_COPROC_NUM > 0 */ /* Macro which first allocates space on the stack to save general @@ -166,12 +166,19 @@ _panic_handler: /* In case this is due to a coprocessor, set ra right now to simplify the logic below */ la ra, _return_from_exception /* EXT_ILL CSR should contain the reason for the Illegal Instruction */ - csrr a0, EXT_ILL_CSR - mv a2, a0 + csrrw a0, EXT_ILL_CSR, zero + + /* Hardware loop cannot be treated lazily, so we should never end here if a HWLP instruction is used */ +#if SOC_CPU_HAS_PIE + /* Check if the PIE bit is set. */ + andi a1, a0, EXT_ILL_RSN_PIE + bnez a1, rtos_save_pie_coproc +#endif /* SOC_CPU_HAS_PIE */ + +#if SOC_CPU_HAS_FPU /* Check if the FPU bit is set. When targets have the FPU reason bug (SOC_CPU_HAS_FPU_EXT_ILL_BUG), * it is possible that another bit is set even if the reason is an FPU instruction. * For example, bit 1 can be set and bit 0 won't, even if the reason is an FPU instruction. */ -#if SOC_CPU_HAS_FPU andi a1, a0, EXT_ILL_RSN_FPU bnez a1, rtos_save_fpu_coproc #if SOC_CPU_HAS_FPU_EXT_ILL_BUG @@ -202,8 +209,6 @@ _panic_handler_not_fpu: #endif /* SOC_CPU_HAS_FPU_EXT_ILL_BUG */ #endif /* SOC_CPU_HAS_FPU */ - /* Need to check the other coprocessors reason now, instruction is in register a2 */ - /* Ignore LP and PIE for now, continue the exception */ _panic_handler_not_coproc: #endif /* ( SOC_CPU_COPROC_NUM > 0 ) */ @@ -298,9 +303,11 @@ _interrupt_handler: /* Save SP former value */ sw a0, RV_STK_SP(sp) - /* Notify the RTOS that an interrupt ocurred, it will save the current stack pointer - * in the running TCB, no need to pass it as a parameter */ + /* Notify the RTOS that an interrupt occurred, it will save the current stack pointer + * in the running TCB, no need to pass it as a parameter + * Returns an abstract context in a0, needs to be passed to `rtos_int_exit` */ call rtos_int_enter + mv s4, a0 /* If this is a non-nested interrupt, SP now points to the interrupt stack */ /* Before dispatch c handler, restore interrupt to enable nested intr */ @@ -366,6 +373,7 @@ _interrupt_handler: /* The RTOS will restore the current TCB stack pointer. This routine will preserve s1 and s2. * Returns the new `mstatus` value. */ mv a0, s2 /* a0 = mstatus */ + mv a1, s4 /* a1 = abstract context returned by `rtos_int_enter` */ call rtos_int_exit /* Restore the rest of the registers. diff --git a/components/sdmmc/include/sdmmc_cmd.h b/components/sdmmc/include/sdmmc_cmd.h index c4d7194f12d2..0510defd7bd6 100644 --- a/components/sdmmc/include/sdmmc_cmd.h +++ b/components/sdmmc/include/sdmmc_cmd.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,10 @@ extern "C" { #endif +/** Call `sdmmc_io_read_bytes`, `sdmmc_io_write_bytes`, `sdmmc_io_read_blocks` or `sdmmc_io_write_bocks` APIs with + * address ORed by this flag to send CMD53 with OP Code clear (fixed address) */ +#define SDMMC_IO_FIXED_ADDR BIT(31) + /** * Probe and initialize SD/MMC card using given host * @@ -196,6 +200,9 @@ esp_err_t sdmmc_io_write_byte(sdmmc_card_t* card, uint32_t function, * This function performs read operation using CMD53 in byte mode. * For block mode, see sdmmc_io_read_blocks. * + * By default OP Code is set (incrementing address). To send CMD53 without this bit, OR the argument `addr` with + * `SDMMC_IO_FIXED_ADDR`. + * * @param card pointer to card information structure previously initialized * using sdmmc_card_init * @param function IO function number @@ -218,6 +225,9 @@ esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function, * This function performs write operation using CMD53 in byte mode. * For block mode, see sdmmc_io_write_blocks. * + * By default OP Code is set (incrementing address). To send CMD53 without this bit, OR the argument `addr` with + * `SDMMC_IO_FIXED_ADDR`. + * * @param card pointer to card information structure previously initialized * using sdmmc_card_init * @param function IO function number @@ -239,6 +249,9 @@ esp_err_t sdmmc_io_write_bytes(sdmmc_card_t* card, uint32_t function, * This function performs read operation using CMD53 in block mode. * For byte mode, see sdmmc_io_read_bytes. * + * By default OP Code is set (incrementing address). To send CMD53 without this bit, OR the argument `addr` with + * `SDMMC_IO_FIXED_ADDR`. + * * @param card pointer to card information structure previously initialized * using sdmmc_card_init * @param function IO function number @@ -261,6 +274,9 @@ esp_err_t sdmmc_io_read_blocks(sdmmc_card_t* card, uint32_t function, * This function performs write operation using CMD53 in block mode. * For byte mode, see sdmmc_io_write_bytes. * + * By default OP Code is set (incrementing address). To send CMD53 without this bit, OR the argument `addr` with + * `SDMMC_IO_FIXED_ADDR`. + * * @param card pointer to card information structure previously initialized * using sdmmc_card_init * @param function IO function number diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index 08e5cf3d1c4a..fb18a9d69629 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -408,7 +408,11 @@ esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src, #ifdef SOC_SDMMC_PSRAM_DMA_CAPABLE dma_mem_info.extra_heap_caps |= MALLOC_CAP_SPIRAM; #endif - if (esp_dma_is_buffer_alignment_satisfied(src, block_size * block_count, dma_mem_info)) { + if (esp_dma_is_buffer_alignment_satisfied(src, block_size * block_count, dma_mem_info) + #if !SOC_SDMMC_PSRAM_DMA_CAPABLE + && !esp_ptr_external_ram(src) + #endif + ) { err = sdmmc_write_sectors_dma(card, src, start_block, block_count, block_size * block_count); } else { // SDMMC peripheral needs DMA-capable buffers. Split the write into @@ -531,7 +535,11 @@ esp_err_t sdmmc_read_sectors(sdmmc_card_t* card, void* dst, size_t block_size = card->csd.sector_size; esp_dma_mem_info_t dma_mem_info; card->host.get_dma_info(card->host.slot, &dma_mem_info); - if (esp_dma_is_buffer_alignment_satisfied(dst, block_size * block_count, dma_mem_info)) { + if (esp_dma_is_buffer_alignment_satisfied(dst, block_size * block_count, dma_mem_info) + #if !SOC_SDMMC_PSRAM_DMA_CAPABLE + && !esp_ptr_external_ram(dst) + #endif + ) { err = sdmmc_read_sectors_dma(card, dst, start_block, block_count, block_size * block_count); } else { // SDMMC peripheral needs DMA-capable buffers. Split the read into diff --git a/components/sdmmc/sdmmc_io.c b/components/sdmmc/sdmmc_io.c index 80a3cc26c918..74ab6dd73551 100644 --- a/components/sdmmc/sdmmc_io.c +++ b/components/sdmmc/sdmmc_io.c @@ -336,6 +336,17 @@ esp_err_t sdmmc_io_rw_extended(sdmmc_card_t* card, int func, esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function, uint32_t addr, void* dst, size_t size) { + uint32_t arg = SD_ARG_CMD53_READ; + bool incr_addr = true; + //Extract and unset the bit used to indicate the OP Code + if (addr & SDMMC_IO_FIXED_ADDR) { + addr &= ~SDMMC_IO_FIXED_ADDR; + incr_addr = false; + } + if (incr_addr) { + arg |= SD_ARG_CMD53_INCREMENT; + } + /* host quirk: SDIO transfer with length not divisible by 4 bytes * has to be split into two transfers: one with aligned length, * the other one for the remaining 1-3 bytes. @@ -347,15 +358,15 @@ esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function, // Note: sdmmc_io_rw_extended has an internal timeout, // typically SDMMC_DEFAULT_CMD_TIMEOUT_MS - esp_err_t err = sdmmc_io_rw_extended(card, function, addr, - SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT, - pc_dst, will_transfer); + esp_err_t err = sdmmc_io_rw_extended(card, function, addr, arg, pc_dst, will_transfer); if (unlikely(err != ESP_OK)) { return err; } pc_dst += will_transfer; size -= will_transfer; - addr += will_transfer; + if (incr_addr) { + addr += will_transfer; + } } return ESP_OK; } @@ -363,24 +374,34 @@ esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function, esp_err_t sdmmc_io_write_bytes(sdmmc_card_t* card, uint32_t function, uint32_t addr, const void* src, size_t size) { + uint32_t arg = SD_ARG_CMD53_WRITE; + bool incr_addr = true; + //Extract and unset the bit used to indicate the OP Code + if (addr & SDMMC_IO_FIXED_ADDR) { + addr &= ~SDMMC_IO_FIXED_ADDR; + incr_addr = false; + } + if (incr_addr) { + arg |= SD_ARG_CMD53_INCREMENT; + } + /* same host quirk as in sdmmc_io_read_bytes */ const uint8_t *pc_src = (const uint8_t*) src; - while (size > 0) { size_t size_aligned = size & (~3); size_t will_transfer = size_aligned > 0 ? size_aligned : size; // Note: sdmmc_io_rw_extended has an internal timeout, // typically SDMMC_DEFAULT_CMD_TIMEOUT_MS - esp_err_t err = sdmmc_io_rw_extended(card, function, addr, - SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT, - (void*) pc_src, will_transfer); + esp_err_t err = sdmmc_io_rw_extended(card, function, addr, arg, (void*) pc_src, will_transfer); if (unlikely(err != ESP_OK)) { return err; } pc_src += will_transfer; size -= will_transfer; - addr += will_transfer; + if (incr_addr) { + addr += will_transfer; + } } return ESP_OK; } @@ -388,27 +409,37 @@ esp_err_t sdmmc_io_write_bytes(sdmmc_card_t* card, uint32_t function, esp_err_t sdmmc_io_read_blocks(sdmmc_card_t* card, uint32_t function, uint32_t addr, void* dst, size_t size) { + uint32_t arg = SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE; + //Extract and unset the bit used to indicate the OP Code (inverted logic) + if (addr & SDMMC_IO_FIXED_ADDR) { + arg &= ~SD_ARG_CMD53_INCREMENT; + addr &= ~SDMMC_IO_FIXED_ADDR; + } + esp_dma_mem_info_t dma_mem_info; card->host.get_dma_info(card->host.slot, &dma_mem_info); if (unlikely(!esp_dma_is_buffer_alignment_satisfied(dst, size, dma_mem_info))) { return ESP_ERR_INVALID_ARG; } - return sdmmc_io_rw_extended(card, function, addr, - SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE, - dst, size); + return sdmmc_io_rw_extended(card, function, addr, arg, dst, size); } esp_err_t sdmmc_io_write_blocks(sdmmc_card_t* card, uint32_t function, uint32_t addr, const void* src, size_t size) { + uint32_t arg = SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE; + //Extract and unset the bit used to indicate the OP Code (inverted logic) + if (addr & SDMMC_IO_FIXED_ADDR) { + arg &= ~SD_ARG_CMD53_INCREMENT; + addr &= ~SDMMC_IO_FIXED_ADDR; + } + esp_dma_mem_info_t dma_mem_info; card->host.get_dma_info(card->host.slot, &dma_mem_info); if (unlikely(!esp_dma_is_buffer_alignment_satisfied(src, size, dma_mem_info))) { return ESP_ERR_INVALID_ARG; } - return sdmmc_io_rw_extended(card, function, addr, - SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE, - (void*) src, size); + return sdmmc_io_rw_extended(card, function, addr, arg, (void*) src, size); } esp_err_t sdmmc_io_enable_int(sdmmc_card_t* card) diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index 6f64fe017e24..b3a53fb77984 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -39,6 +39,10 @@ if(CONFIG_SOC_DEDICATED_GPIO_SUPPORTED) list(APPEND srcs "${target_folder}/dedic_gpio_periph.c") endif() +if(CONFIG_SOC_EMAC_SUPPORTED) + list(APPEND srcs "${target_folder}/emac_periph.c") +endif() + if(CONFIG_SOC_GDMA_SUPPORTED) list(APPEND srcs "${target_folder}/gdma_periph.c") endif() @@ -152,6 +156,10 @@ if(CONFIG_SOC_PAU_SUPPORTED) list(APPEND srcs "${target_folder}/system_retention_periph.c") endif() +if(CONFIG_SOC_LCDCAM_CAM_SUPPORTED) + list(APPEND srcs "${target_folder}/cam_periph.c") +endif() + idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} LDFRAGMENTS "linker.lf") diff --git a/components/soc/esp32/emac_periph.c b/components/soc/esp32/emac_periph.c new file mode 100644 index 000000000000..a33327011596 --- /dev/null +++ b/components/soc/esp32/emac_periph.c @@ -0,0 +1,224 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "soc/emac_periph.h" +#include "soc/io_mux_reg.h" + +const emac_io_info_t emac_io_idx = { + .mdc_idx = EMAC_MDC_O_IDX, + .mdo_idx = EMAC_MDO_O_IDX, + .mdi_idx = EMAC_MDI_I_IDX, + .mii_tx_clk_i_idx = SIG_GPIO_OUT_IDX, // indicates EMAC signal cannot be connected via GPIO Matrix on the target + .mii_tx_en_o_idx = SIG_GPIO_OUT_IDX, + .mii_txd0_o_idx = SIG_GPIO_OUT_IDX, + .mii_txd1_o_idx = SIG_GPIO_OUT_IDX, + .mii_txd2_o_idx = SIG_GPIO_OUT_IDX, + .mii_txd3_o_idx = SIG_GPIO_OUT_IDX, + .mii_rx_clk_i_idx = SIG_GPIO_OUT_IDX, + .mii_rx_dv_i_idx = SIG_GPIO_OUT_IDX, + .mii_rxd0_i_idx = SIG_GPIO_OUT_IDX, + .mii_rxd1_i_idx = SIG_GPIO_OUT_IDX, + .mii_rxd2_i_idx = SIG_GPIO_OUT_IDX, + .mii_rxd3_i_idx = SIG_GPIO_OUT_IDX, + .mii_col_i_idx = SIG_GPIO_OUT_IDX, + .mii_crs_i_idx = SIG_GPIO_OUT_IDX, + .mii_tx_er_o_idx = SIG_GPIO_OUT_IDX, + .mii_rx_er_i_idx = SIG_GPIO_OUT_IDX +}; + +static const emac_iomux_info_t emac_rmii_iomux_clki[] = { + [0] = { + .gpio_num = 0, + .func = FUNC_GPIO0_EMAC_TX_CLK, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, // indicates end of list + } +}; + +static const emac_iomux_info_t emac_rmii_iomux_clko[] = { + [0] = { + .gpio_num = 16, + .func = FUNC_GPIO16_EMAC_CLK_OUT, + }, + [1] = { + .gpio_num = 17, + .func = FUNC_GPIO17_EMAC_CLK_OUT_180, + }, + [2] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_rmii_mii_iomux_tx_en[] = { + [0] = { + .gpio_num = 21, + .func = FUNC_GPIO21_EMAC_TX_EN, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_rmii_mii_iomux_txd0[] = { + [0] = { + .gpio_num = 19, + .func = FUNC_GPIO19_EMAC_TXD0, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_rmii_mii_iomux_txd1[] = { + [0] = { + .gpio_num = 22, + .func = FUNC_GPIO22_EMAC_TXD1, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_rmii_mii_iomux_crs_dv[] = { + [0] = { + .gpio_num = 27, + .func = FUNC_GPIO27_EMAC_RX_DV, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_rmii_mii_iomux_rxd0[] = { + [0] = { + .gpio_num = 25, + .func = FUNC_GPIO25_EMAC_RXD0, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_rmii_mii_iomux_rxd1[] = { + [0] = { + .gpio_num = 26, + .func = FUNC_GPIO26_EMAC_RXD1, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_rmii_mii_iomux_tx_er[] = { + [0] = { + .gpio_num = 4, + .func = FUNC_GPIO4_EMAC_TX_ER, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_rmii_mii_iomux_rx_er[] = { + [0] = { + .gpio_num = 13, + .func = FUNC_MTCK_EMAC_RX_ER, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +// MII Specific +static const emac_iomux_info_t emac_mii_iomux_clk_tx[] = { + [0] = { + .gpio_num = 0, + .func = FUNC_GPIO0_EMAC_TX_CLK, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_mii_iomux_txd2[] = { + [0] = { + .gpio_num = 14, + .func = FUNC_MTMS_EMAC_TXD2, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_mii_iomux_txd3[] = { + [0] = { + .gpio_num = 12, + .func = FUNC_MTDI_EMAC_TXD3, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_mii_iomux_clk_rx[] = { + [0] = { + .gpio_num = 5, + .func = FUNC_GPIO5_EMAC_RX_CLK, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_mii_iomux_rxd2[] = { + [0] = { + .gpio_num = 1, + .func = FUNC_U0TXD_EMAC_RXD2, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +static const emac_iomux_info_t emac_mii_iomux_rxd3[] = { + [0] = { + .gpio_num = 15, + .func = FUNC_MTDO_EMAC_RXD3, + }, + [1] = { + .gpio_num = GPIO_NUM_MAX, + } +}; + +const emac_rmii_iomux_info_t emac_rmii_iomux_pins = { + .clki = emac_rmii_iomux_clki, + .clko = emac_rmii_iomux_clko, + .tx_en = emac_rmii_mii_iomux_tx_en, + .txd0 = emac_rmii_mii_iomux_txd0, + .txd1 = emac_rmii_mii_iomux_txd1, + .crs_dv = emac_rmii_mii_iomux_crs_dv, + .rxd0 = emac_rmii_mii_iomux_rxd0, + .rxd1 = emac_rmii_mii_iomux_rxd1, + .tx_er = emac_rmii_mii_iomux_tx_er, + .rx_er = emac_rmii_mii_iomux_rx_er, +}; + +const emac_mii_iomux_info_t emac_mii_iomux_pins = { + .clk_tx = emac_mii_iomux_clk_tx, + .tx_en = emac_rmii_mii_iomux_tx_en, + .txd0 = emac_rmii_mii_iomux_txd0, + .txd1 = emac_rmii_mii_iomux_txd1, + .txd2 = emac_mii_iomux_txd2, + .txd3 = emac_mii_iomux_txd3, + .clk_rx = emac_mii_iomux_clk_rx, + .rx_dv = emac_rmii_mii_iomux_crs_dv, + .rxd0 = emac_rmii_mii_iomux_rxd0, + .rxd1 = emac_rmii_mii_iomux_rxd1, + .rxd2 = emac_mii_iomux_rxd2, + .rxd3 = emac_mii_iomux_rxd3, + .tx_er = emac_rmii_mii_iomux_tx_er, + .rx_er = emac_rmii_mii_iomux_rx_er, +}; diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index 3723989bc711..ebe9974fb033 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -187,6 +187,10 @@ config SOC_LP_PERIPH_SHARE_INTERRUPT bool default y +config SOC_PM_SUPPORTED + bool + default y + config SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL int default 5 @@ -699,7 +703,7 @@ config SOC_TOUCH_SENSOR_NUM int default 10 -config SOC_TOUCH_SAMPLER_NUM +config SOC_TOUCH_SAMPLE_CFG_NUM int default 1 diff --git a/components/soc/esp32/include/soc/ext_mem_defs.h b/components/soc/esp32/include/soc/ext_mem_defs.h index 40054fa7cb45..b4bebe97024a 100644 --- a/components/soc/esp32/include/soc/ext_mem_defs.h +++ b/components/soc/esp32/include/soc/ext_mem_defs.h @@ -34,9 +34,6 @@ extern "C" { #define SOC_DRAM_FLASH_ADDRESS_LOW SOC_DROM0_CACHE_ADDRESS_LOW #define SOC_DRAM_FLASH_ADDRESS_HIGH SOC_DROM0_CACHE_ADDRESS_HIGH -#define SOC_DRAM_PSRAM_ADDRESS_LOW SOC_DRAM1_CACHE_ADDRESS_LOW -#define SOC_DRAM_PSRAM_ADDRESS_HIGH SOC_DRAM1_CACHE_ADDRESS_HIGH - #define SOC_BUS_SIZE(bus_name) (bus_name##_ADDRESS_HIGH - bus_name##_ADDRESS_LOW) #define SOC_ADDRESS_IN_BUS(bus_name, vaddr) ((vaddr) >= bus_name##_ADDRESS_LOW && (vaddr) < bus_name##_ADDRESS_HIGH) #define SOC_ADDRESS_IN_IRAM0_CACHE(vaddr) SOC_ADDRESS_IN_BUS(SOC_IRAM0_CACHE, vaddr) diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index b1c18246f4ea..0519bc04c88e 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -104,6 +104,7 @@ #define SOC_LIGHT_SLEEP_SUPPORTED 1 #define SOC_DEEP_SLEEP_SUPPORTED 1 #define SOC_LP_PERIPH_SHARE_INTERRUPT 1 // LP peripherals sharing the same interrupt source +#define SOC_PM_SUPPORTED 1 #if SOC_CAPS_ECO_VER < 200 #define SOC_DPORT_WORKAROUND 1 @@ -325,7 +326,7 @@ #define SOC_TOUCH_SENSOR_VERSION (1U) /*!> 3)) +#define SOC_SLEEP_SYSTIMER_STALL_WORKAROUND 1 +#define SOC_SLEEP_TGWDT_STOP_WORKAROUND 1 + /*-------------------------- RTCIO CAPS --------------------------------------*/ /* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported * for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */ diff --git a/components/soc/esp32c3/uart_periph.c b/components/soc/esp32c3/uart_periph.c index d4262c6776f5..73eb978cbe7d 100644 --- a/components/soc/esp32c3/uart_periph.c +++ b/components/soc/esp32c3/uart_periph.c @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "soc/uart_periph.h" @@ -49,7 +41,6 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { } }, .irq = ETS_UART0_INTR_SOURCE, - .module = PERIPH_UART0_MODULE, }, { @@ -83,6 +74,5 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { }, }, .irq = ETS_UART1_INTR_SOURCE, - .module = PERIPH_UART1_MODULE, }, }; diff --git a/components/soc/esp32c5/beta3/gdma_periph.c b/components/soc/esp32c5/beta3/gdma_periph.c index 943e9bad3d2c..490061820104 100644 --- a/components/soc/esp32c5/beta3/gdma_periph.c +++ b/components/soc/esp32c5/beta3/gdma_periph.c @@ -49,7 +49,7 @@ static const regdma_entries_config_t gdma_g0p0_regs_retention[] = { g0p0_regs_map0[0], g0p0_regs_map0[1], \ g0p0_regs_map0[2], g0p0_regs_map0[3]), \ .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GDMA_LINK(0x00), \ + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GDMA_LINK(0x01), \ G0P0_RETENTION_MAP_BASE_1, G0P0_RETENTION_MAP_BASE_1, \ G0P0_RETENTION_REGS_CNT_1, 0, 0, \ g0p0_regs_map1[0], g0p0_regs_map1[1], \ @@ -76,7 +76,7 @@ static const regdma_entries_config_t gdma_g0p1_regs_retention[] = { g0p1_regs_map0[0], g0p1_regs_map0[1], \ g0p1_regs_map0[2], g0p1_regs_map0[3]), \ .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GDMA_LINK(0x00), \ + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GDMA_LINK(0x01), \ G0P1_RETENTION_MAP_BASE_1, G0P1_RETENTION_MAP_BASE_1, \ G0P1_RETENTION_REGS_CNT_1, 0, 0, \ g0p1_regs_map1[0], g0p1_regs_map1[1], \ @@ -103,7 +103,7 @@ static const regdma_entries_config_t gdma_g0p2_regs_retention[] = { g0p2_regs_map0[0], g0p2_regs_map0[1], \ g0p2_regs_map0[2], g0p2_regs_map0[3]), \ .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GDMA_LINK(0x00), \ + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GDMA_LINK(0x01), \ G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \ G0P2_RETENTION_REGS_CNT_1, 0, 0, \ g0p2_regs_map1[0], g0p2_regs_map1[1], \ @@ -111,7 +111,7 @@ static const regdma_entries_config_t gdma_g0p2_regs_retention[] = { .owner = ENTRY(0) | ENTRY(2) }, }; -const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_PAIRS_PER_GROUP_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX] = { +const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_NUM_GROUPS_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX] = { [0] = { [0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)}, [1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)}, diff --git a/components/soc/esp32c5/beta3/gpio_periph.c b/components/soc/esp32c5/beta3/gpio_periph.c index 417b781b6b8c..00d0ebeaa9e8 100644 --- a/components/soc/esp32c5/beta3/gpio_periph.c +++ b/components/soc/esp32c5/beta3/gpio_periph.c @@ -6,36 +6,6 @@ #include "soc/gpio_periph.h" -const uint32_t GPIO_PIN_MUX_REG[] = { - IO_MUX_GPIO0_REG, - IO_MUX_GPIO1_REG, - IO_MUX_GPIO2_REG, - IO_MUX_GPIO3_REG, - IO_MUX_GPIO4_REG, - IO_MUX_GPIO5_REG, - IO_MUX_GPIO6_REG, - IO_MUX_GPIO7_REG, - IO_MUX_GPIO8_REG, - IO_MUX_GPIO9_REG, - IO_MUX_GPIO10_REG, - IO_MUX_GPIO11_REG, - IO_MUX_GPIO12_REG, - IO_MUX_GPIO13_REG, - IO_MUX_GPIO14_REG, - IO_MUX_GPIO15_REG, - IO_MUX_GPIO16_REG, - IO_MUX_GPIO17_REG, - IO_MUX_GPIO18_REG, - IO_MUX_GPIO19_REG, - IO_MUX_GPIO20_REG, - IO_MUX_GPIO21_REG, - IO_MUX_GPIO22_REG, - IO_MUX_GPIO23_REG, - IO_MUX_GPIO24_REG, - IO_MUX_GPIO25_REG, - IO_MUX_GPIO26_REG, -}; - _Static_assert(sizeof(GPIO_PIN_MUX_REG) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_PIN_MUX_REG"); const uint32_t GPIO_HOLD_MASK[] = { diff --git a/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in index ec09df500b99..fdfe6872e2b6 100644 --- a/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in @@ -143,6 +143,10 @@ config SOC_BT_SUPPORTED bool default y +config SOC_PM_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_40M bool default y @@ -251,14 +255,6 @@ config SOC_GPIO_SUPPORT_PIN_HYS_FILTER bool default y -config SOC_GPIO_ETM_EVENTS_PER_GROUP - int - default 8 - -config SOC_GPIO_ETM_TASKS_PER_GROUP - int - default 8 - config SOC_GPIO_SUPPORT_RTC_INDEPENDENT bool default y @@ -575,6 +571,10 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS int default 2 +config SOC_EFUSE_ECDSA_KEY + bool + default y + config SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS int default 3 @@ -635,6 +635,10 @@ config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND bool default y +config SOC_UART_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_COEX_HW_PTI bool default y diff --git a/components/soc/esp32c5/beta3/include/soc/clk_tree_defs.h b/components/soc/esp32c5/beta3/include/soc/clk_tree_defs.h index 42e7115ba34a..d65e8583d22d 100644 --- a/components/soc/esp32c5/beta3/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c5/beta3/include/soc/clk_tree_defs.h @@ -19,7 +19,7 @@ extern "C" { * * 2) External 40/48MHz Crystal Clock: XTAL * - * 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referrred as SOSC in TRM or reg. description) + * 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description) * * This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock * can be computed in runtime through calibration. @@ -250,15 +250,15 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of LP_UART */ -#define SOC_LP_UART_CLKS {SOC_MOD_CLK_RTC_FAST, SOC_MOD_CLK_XTAL_D2} +#define SOC_LP_UART_CLKS {SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL_D2} /** * @brief Type of LP_UART clock source */ typedef enum { - LP_UART_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock is LP(RTC)_FAST */ + LP_UART_SCLK_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< LP_UART source clock is RC_FAST */ LP_UART_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock is XTAL_D2 */ - LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock default choice is LP(RTC)_FAST */ + LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock default choice is RC_FAST */ } soc_periph_lp_uart_clk_src_t; //////////////////////////////////////////////////MCPWM///////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32c5/beta3/include/soc/io_mux_struct.h b/components/soc/esp32c5/beta3/include/soc/io_mux_struct.h index ace0a983de22..fdab268dfe10 100644 --- a/components/soc/esp32c5/beta3/include/soc/io_mux_struct.h +++ b/components/soc/esp32c5/beta3/include/soc/io_mux_struct.h @@ -34,7 +34,7 @@ typedef union { uint32_t reserved_15:17; }; uint32_t val; -} iomux_pin_ctrl_reg_t; +} io_mux_pin_ctrl_reg_t; /** Type of gpio register * IO MUX Configure Register for pad XTAL_32K_P @@ -102,13 +102,13 @@ typedef union { uint32_t hys_en:1; /** hys_sel : R/W; bitpos: [17]; default: 0; * Select enabling signals of the pad from software and efuse hardware. 1: Select - * enabling siganl from slftware. 0: Select enabling signal from efuse hardware. + * enabling signal from slftware. 0: Select enabling signal from efuse hardware. */ uint32_t hys_sel:1; uint32_t reserved_18:14; }; uint32_t val; -} iomux_gpio_reg_t; +} io_mux_gpio_reg_t; /** Type of date register * IO MUX Version Control Register @@ -122,20 +122,20 @@ typedef union { uint32_t reserved_28:4; }; uint32_t val; -} iomux_date_reg_t; +} io_mux_date_reg_t; -typedef struct iomux_dev_t { - volatile iomux_pin_ctrl_reg_t pin_ctrl; - volatile iomux_gpio_reg_t gpio[27]; +typedef struct io_mux_dev_t { + volatile io_mux_pin_ctrl_reg_t pin_ctrl; + volatile io_mux_gpio_reg_t gpio[27]; uint32_t reserved_070[35]; - volatile iomux_date_reg_t date; -} iomux_dev_t; + volatile io_mux_date_reg_t date; +} io_mux_dev_t; -extern iomux_dev_t IOMUX; +extern io_mux_dev_t IO_MUX; #ifndef __cplusplus -_Static_assert(sizeof(iomux_dev_t) == 0x100, "Invalid size of iomux_dev_t structure"); +_Static_assert(sizeof(io_mux_dev_t) == 0x100, "Invalid size of io_mux_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h b/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h index 2ef044eb4021..47b33960179a 100644 --- a/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h +++ b/components/soc/esp32c5/beta3/include/soc/retention_periph_defs.h @@ -18,24 +18,29 @@ typedef enum periph_retention_module { /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2, - - /* modem module, which includes WiFi, BLE and 802.15.4 */ - SLEEP_RETENTION_MODULE_WIFI_MAC = 10, - SLEEP_RETENTION_MODULE_WIFI_BB = 11, - SLEEP_RETENTION_MODULE_BLE_MAC = 12, - SLEEP_RETENTION_MODULE_BT_BB = 13, - SLEEP_RETENTION_MODULE_802154_MAC = 14, - /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, - * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_SYS_PERIPH = 16, - - SLEEP_RETENTION_MODULE_ADC = 17, - - SLEEP_RETENTION_MODULE_GDMA_CH0 = 24, - SLEEP_RETENTION_MODULE_GDMA_CH1 = 25, - SLEEP_RETENTION_MODULE_GDMA_CH2 = 26, + * TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_SYS_PERIPH = 3, + /* Timer Group by target*/ + SLEEP_RETENTION_MODULE_TG0_WDT = 4, + SLEEP_RETENTION_MODULE_TG1_WDT = 5, + SLEEP_RETENTION_MODULE_TG0_TIMER = 6, + SLEEP_RETENTION_MODULE_TG1_TIMER = 7, + /* GDMA by channel */ + SLEEP_RETENTION_MODULE_GDMA_CH0 = 8, + SLEEP_RETENTION_MODULE_GDMA_CH1 = 9, + SLEEP_RETENTION_MODULE_GDMA_CH2 = 10, + /* MISC Peripherals */ + SLEEP_RETENTION_MODULE_ADC = 11, + SLEEP_RETENTION_MODULE_I2C0 = 12, + SLEEP_RETENTION_MODULE_RMT0 = 13, + /* Modem module, which includes WiFi, BLE and 802.15.4 */ + SLEEP_RETENTION_MODULE_WIFI_MAC = 26, + SLEEP_RETENTION_MODULE_WIFI_BB = 27, + SLEEP_RETENTION_MODULE_BLE_MAC = 28, + SLEEP_RETENTION_MODULE_BT_BB = 29, + SLEEP_RETENTION_MODULE_802154_MAC = 30, SLEEP_RETENTION_MODULE_MAX = 31 } periph_retention_module_t; @@ -43,26 +48,45 @@ typedef enum periph_retention_module_bitmap { /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM), SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM), - + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), + /* Timer Group by target*/ + SLEEP_RETENTION_MODULE_BM_TASK_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT), + SLEEP_RETENTION_MODULE_BM_INT_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT), + SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER), + SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER), + /* GDMA by channel */ + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), + SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), + SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), + /* MISC Peripherals */ + SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC), + SLEEP_RETENTION_MODULE_BM_I2C0 = BIT(SLEEP_RETENTION_MODULE_I2C0), + SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0), /* modem module, which includes WiFi, BLE and 802.15.4 */ SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC), SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB), SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC), SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB), SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC), - - /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, - * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), - - SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC), - - SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), - SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), - SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1 } periph_retention_module_bitmap_t; +#define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM \ + | SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM \ + | SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \ + | SLEEP_RETENTION_MODULE_BM_TASK_WDT \ + | SLEEP_RETENTION_MODULE_BM_INT_WDT \ + | SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH0 \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH1 \ + | SLEEP_RETENTION_MODULE_BM_GDMA_CH2 \ + | SLEEP_RETENTION_MODULE_BM_ADC \ + | SLEEP_RETENTION_MODULE_BM_I2C0 \ + | SLEEP_RETENTION_MODULE_BM_RMT0) + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c5/beta3/include/soc/soc_caps.h b/components/soc/esp32c5/beta3/include/soc/soc_caps.h index 74df08b4f3f6..de79e2fbada2 100644 --- a/components/soc/esp32c5/beta3/include/soc/soc_caps.h +++ b/components/soc/esp32c5/beta3/include/soc/soc_caps.h @@ -81,6 +81,7 @@ #define SOC_MODEM_CLOCK_SUPPORTED 1 // TODO: [ESP32C5] IDF-8845 need check, it is opened because pll has been used on beta3 #define SOC_BT_SUPPORTED 1 #define SOC_PHY_SUPPORTED 1 +#define SOC_PM_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 @@ -193,8 +194,6 @@ // GPIO peripheral has the ETM extension // #define SOC_GPIO_SUPPORT_ETM 1 -#define SOC_GPIO_ETM_EVENTS_PER_GROUP 8 -#define SOC_GPIO_ETM_TASKS_PER_GROUP 8 // Target has the full LP IO subsystem // On ESP32-C5, Digital IOs have their own registers to control pullup/down capability, independent of LP registers. @@ -445,6 +444,7 @@ // #define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1) #define SOC_TIMER_GROUP_TOTAL_TIMERS (2) // #define SOC_TIMER_SUPPORT_ETM (1) +// #define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1) /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ // #define SOC_MWDT_SUPPORT_XTAL (1) @@ -463,7 +463,7 @@ // #define SOC_EFUSE_DIS_DIRECT_BOOT 1 // #define SOC_EFUSE_SOFT_DIS_JTAG 1 // #define SOC_EFUSE_DIS_ICACHE 1 -// #define SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK 1 // XTS-AES key purpose not supported for this block +#define SOC_EFUSE_ECDSA_KEY 1 /*-------------------------- Secure Boot CAPS----------------------------*/ // #define SOC_SECURE_BOOT_V2_RSA 1 @@ -497,6 +497,8 @@ // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) +#define SOC_UART_SUPPORT_SLEEP_RETENTION (1) /*!< Support back up registers before sleep */ + /*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/ #define SOC_COEX_HW_PTI (1) diff --git a/components/soc/esp32c5/beta3/include/soc/system_periph_retention.h b/components/soc/esp32c5/beta3/include/soc/system_periph_retention.h index b0cafd51bfda..23c82b295388 100644 --- a/components/soc/esp32c5/beta3/include/soc/system_periph_retention.h +++ b/components/soc/esp32c5/beta3/include/soc/system_periph_retention.h @@ -48,16 +48,6 @@ extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LI #define TEE_APM_HIGH_PRI_RETENTION_LINK_LEN 1 extern const regdma_entries_config_t tee_apm_highpri_regs_retention[TEE_APM_HIGH_PRI_RETENTION_LINK_LEN]; -/** - * @brief Provide access to uart configuration registers retention - * context definition. - * - * This is an internal function of the sleep retention driver, and is not - * useful for external use. - */ -#define UART_RETENTION_LINK_LEN 3 -extern const regdma_entries_config_t uart_regs_retention[UART_RETENTION_LINK_LEN]; - /** * @brief Provide access to timer group configuration registers retention * context definition. diff --git a/components/soc/esp32c5/beta3/ld/esp32c5.peripherals.ld b/components/soc/esp32c5/beta3/ld/esp32c5.peripherals.ld index 14d416ccc3e6..54c687aff33c 100644 --- a/components/soc/esp32c5/beta3/ld/esp32c5.peripherals.ld +++ b/components/soc/esp32c5/beta3/ld/esp32c5.peripherals.ld @@ -41,7 +41,7 @@ PROVIDE ( DS = 0x6008C000 ); PROVIDE ( HMAC = 0x6008D000 ); PROVIDE ( ECDSA = 0x6008E000 ); -PROVIDE ( IOMUX = 0x60090000 ); +PROVIDE ( IO_MUX = 0x60090000 ); PROVIDE ( GPIO = 0x60091000 ); PROVIDE ( GPIO_EXT = 0x60091f00 ); PROVIDE ( SDM = 0x60091f00 ); diff --git a/components/soc/esp32c5/beta3/system_retention_periph.c b/components/soc/esp32c5/beta3/system_retention_periph.c index 08848b4c7574..52822f92720e 100644 --- a/components/soc/esp32c5/beta3/system_retention_periph.c +++ b/components/soc/esp32c5/beta3/system_retention_periph.c @@ -44,31 +44,6 @@ const regdma_entries_config_t tee_apm_highpri_regs_retention[] = { }; _Static_assert((ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN) && (ARRAY_SIZE(tee_apm_highpri_regs_retention) == TEE_APM_HIGH_PRI_RETENTION_LINK_LEN), "Inconsistent TEE_APM retention link length definitions"); -/* UART0 Registers Context */ -#define N_REGS_UART() (((UART_ID_REG(0) - UART_INT_RAW_REG(0)) / 4) + 1) -const regdma_entries_config_t uart_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ - /* Note: uart register should set update reg to make the configuration take effect */ - [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } -}; -_Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions"); - -/* Timergroup Registers Context */ -#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) -const regdma_entries_config_t tg_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } -}; -_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions"); - /* IO MUX Registers Context */ #define N_REGS_IOMUX_0() (((IO_MUX_GPIO26_REG - REG_IO_MUX_BASE) / 4) + 1) #define N_REGS_IOMUX_1() (((GPIO_FUNC30_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) diff --git a/components/soc/esp32c5/beta3/timer_periph.c b/components/soc/esp32c5/beta3/timer_periph.c index 4273eec72e67..7036e7ca81ae 100644 --- a/components/soc/esp32c5/beta3/timer_periph.c +++ b/components/soc/esp32c5/beta3/timer_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,3 +22,71 @@ const timer_group_signal_conn_t timer_group_periph_signals = { } } }; + +#if SOC_TIMER_SUPPORT_SLEEP_RETENTION +#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG + +static const regdma_entries_config_t tg0_wdt_regs_retention[] = { + /*Timer group backup. should get of write project firstly. wdt used by RTOS.*/ + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +static const regdma_entries_config_t tg1_wdt_regs_retention[] = { + /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +/* Registers in retention context: + * TIMG_T0CONFIG_REG + * TIMG_T0ALARMLO_REG + * TIMG_T0ALARMHI_REG + * TIMG_INT_ENA_TIMERS_REG + * TIMG_REGCLK_REG + */ +#define N_REGS_TG_TIMER_CFG 5 +static const uint32_t tg_timer_regs_map[4] = {0x10000031, 0x80000000, 0, 0}; + +const regdma_entries_config_t tg0_timer_regs_retention[] = { + [0] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \ + tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2) + }, + [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +const regdma_entries_config_t tg1_timer_regs_retention[] = { + [0] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \ + tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2) + }, + [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = { + [0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, + [1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, +}; + +const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = { + [0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)}, + [1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)}, +}; +#endif diff --git a/components/soc/esp32c5/beta3/uart_periph.c b/components/soc/esp32c5/beta3/uart_periph.c index 154038a7b655..49af724e2697 100644 --- a/components/soc/esp32c5/beta3/uart_periph.c +++ b/components/soc/esp32c5/beta3/uart_periph.c @@ -5,6 +5,7 @@ */ #include "soc/uart_periph.h" +#include "soc/uart_reg.h" /* Bunch of constants for every UART peripheral: GPIO signals, irqs, hw addr of registers etc @@ -41,7 +42,6 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { } }, .irq = ETS_UART0_INTR_SOURCE, - .module = PERIPH_UART0_MODULE, }, { // HP UART1 @@ -75,7 +75,6 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { }, }, .irq = ETS_UART1_INTR_SOURCE, - .module = PERIPH_UART1_MODULE, }, { // LP UART0 @@ -109,6 +108,44 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { }, }, .irq = ETS_LP_UART_INTR_SOURCE, - .module = PERIPH_LP_UART0_MODULE, + }, +}; + +/** + * UART registers to be saved during sleep retention + * + * Reset TXFIFO and RXFIFO + * UART registers require set the reg_update bit to make the configuration take effect + */ +#define N_REGS_UART(uart_num) (((UART_ID_REG(uart_num) - UART_INT_RAW_REG(uart_num)) / 4) + 1) +#define UART_SLEEP_RETENTION_ENTRIES(uart_num) { \ + [0] = {.config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), \ + UART_INT_RAW_REG(uart_num), UART_INT_RAW_REG(uart_num), \ + N_REGS_UART(uart_num), 0, 0 \ + ), \ + .owner = ENTRY(0) | ENTRY(2) }, \ + [1] = {.config = REGDMA_LINK_WRITE_INIT(REGDMA_UART_LINK(0x01), \ + UART_REG_UPDATE_REG(uart_num), UART_REG_UPDATE, \ + UART_REG_UPDATE_M, 1, 0 \ + ), \ + .owner = ENTRY(0) | ENTRY(2) }, \ + [2] = {.config = REGDMA_LINK_WAIT_INIT(REGDMA_UART_LINK(0x02), \ + UART_REG_UPDATE_REG(uart_num), 0x0, \ + UART_REG_UPDATE_M, 1, 0 \ + ), \ + .owner = ENTRY(0) | ENTRY(2) }, \ +} + +static const regdma_entries_config_t uart0_regdma_entries[] = UART_SLEEP_RETENTION_ENTRIES(0); +static const regdma_entries_config_t uart1_regdma_entries[] = UART_SLEEP_RETENTION_ENTRIES(1); + +const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = { + [0] = { + .regdma_entry_array = uart0_regdma_entries, + .array_size = ARRAY_SIZE(uart0_regdma_entries), + }, + [1] = { + .regdma_entry_array = uart1_regdma_entries, + .array_size = ARRAY_SIZE(uart1_regdma_entries), }, }; diff --git a/components/soc/esp32c5/mp/gdma_periph.c b/components/soc/esp32c5/mp/gdma_periph.c new file mode 100644 index 000000000000..9385a76ed59f --- /dev/null +++ b/components/soc/esp32c5/mp/gdma_periph.c @@ -0,0 +1,143 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/gdma_periph.h" +#include "soc/ahb_dma_reg.h" + +const gdma_signal_conn_t gdma_periph_signals = { + .groups = { + [0] = { + .module = PERIPH_GDMA_MODULE, + .pairs = { + [0] = { + .rx_irq_id = ETS_DMA_IN_CH0_INTR_SOURCE, + .tx_irq_id = ETS_DMA_OUT_CH0_INTR_SOURCE, + }, + [1] = { + .rx_irq_id = ETS_DMA_IN_CH1_INTR_SOURCE, + .tx_irq_id = ETS_DMA_OUT_CH1_INTR_SOURCE, + }, + [2] = { + .rx_irq_id = ETS_DMA_IN_CH2_INTR_SOURCE, + .tx_irq_id = ETS_DMA_OUT_CH2_INTR_SOURCE, + } + } + } + } +}; + +#if SOC_GDMA_SUPPORT_SLEEP_RETENTION +/* GDMA Channel (Group0, Pair0) Registers Context + Include: GDMA_MISC_CONF_REG + GDMA_IN_INT_ENA_CH0_REG / GDMA_OUT_INT_ENA_CH0_REG / GDMA_IN_PERI_SEL_CH0_REG / GDMA_OUT_PERI_SEL_CH0_REG + GDMA_IN_CONF0_CH0_REG / GDMA_IN_CONF1_CH0_REG / GDMA_IN_LINK_CH0_REG / GDMA_IN_PRI_CH0_REG + GDMA_OUT_CONF0_CH0_REG / GDMA_OUT_CONF1_CH0_REG / GDMA_OUT_LINK_CH0_REG /GDMA_OUT_PRI_CH0_REG + + AHB_DMA_TX_CH_ARB_WEIGH_CH0_REG / AHB_DMA_TX_ARB_WEIGH_OPT_DIR_CH0_REG + AHB_DMA_RX_CH_ARB_WEIGH_CH0_REG / AHB_DMA_RX_ARB_WEIGH_OPT_DIR_CH0_REG + AHB_DMA_IN_LINK_ADDR_CH0_REG / AHB_DMA_OUT_LINK_ADDR_CH0_REG + AHB_DMA_INTR_MEM_START_ADDR_REG / AHB_DMA_INTR_MEM_END_ADDR_REG + AHB_DMA_ARB_TIMEOUT_TX_REG / AHB_DMA_ARB_TIMEOUT_RX_REG + AHB_DMA_WEIGHT_EN_TX_REG / AHB_DMA_WEIGHT_EN_RX_REG +*/ +#define G0P0_RETENTION_REGS_CNT_0 13 +#define G0P0_RETENTION_MAP_BASE_0 (REG_AHB_DMA_BASE + 0x8) +#define G0P0_RETENTION_REGS_CNT_1 12 +#define G0P0_RETENTION_MAP_BASE_1 (REG_AHB_DMA_BASE + 0x2dc) +static const uint32_t g0p0_regs_map0[4] = {0x4c801001, 0x604c0060, 0x0, 0x0}; +static const uint32_t g0p0_regs_map1[4] = {0xc0000003, 0xfc900000, 0x0, 0x0}; +static const regdma_entries_config_t gdma_g0p0_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_AHB_DMA_LINK(0x00), \ + G0P0_RETENTION_MAP_BASE_0, G0P0_RETENTION_MAP_BASE_0, \ + G0P0_RETENTION_REGS_CNT_0, 0, 0, \ + g0p0_regs_map0[0], g0p0_regs_map0[1], \ + g0p0_regs_map0[2], g0p0_regs_map0[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, \ + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_AHB_DMA_LINK(0x01), \ + G0P0_RETENTION_MAP_BASE_1, G0P0_RETENTION_MAP_BASE_1, \ + G0P0_RETENTION_REGS_CNT_1, 0, 0, \ + g0p0_regs_map1[0], g0p0_regs_map1[1], \ + g0p0_regs_map1[2], g0p0_regs_map1[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +/* GDMA Channel (Group0, Pair1) Registers Context + Include: GDMA_MISC_CONF_REG + GDMA_IN_INT_ENA_CH1_REG / GDMA_OUT_INT_ENA_CH1_REG / GDMA_IN_PERI_SEL_CH1_REG / GDMA_OUT_PERI_SEL_CH1_REG + GDMA_IN_CONF0_CH1_REG / GDMA_IN_CONF1_CH1_REG / GDMA_IN_LINK_CH1_REG / GDMA_IN_PRI_CH1_REG + GDMA_OUT_CONF0_CH1_REG / GDMA_OUT_CONF1_CH1_REG / GDMA_OUT_LINK_CH1_REG /GDMA_OUT_PRI_CH1_REG + + AHB_DMA_TX_CH_ARB_WEIGH_CH1_REG / AHB_DMA_TX_ARB_WEIGH_OPT_DIR_CH1_REG + AHB_DMA_RX_CH_ARB_WEIGH_CH1_REG / AHB_DMA_RX_ARB_WEIGH_OPT_DIR_CH1_REG + AHB_DMA_IN_LINK_ADDR_CH1_REG / AHB_DMA_OUT_LINK_ADDR_CH1_REG + AHB_DMA_INTR_MEM_START_ADDR_REG / AHB_DMA_INTR_MEM_END_ADDR_REG + AHB_DMA_ARB_TIMEOUT_TX_REG / AHB_DMA_ARB_TIMEOUT_RX_REG + AHB_DMA_WEIGHT_EN_TX_REG / AHB_DMA_WEIGHT_EN_RX_REG +*/ +#define G0P1_RETENTION_REGS_CNT_0 13 +#define G0P1_RETENTION_MAP_BASE_0 (REG_AHB_DMA_BASE + 0x18) +#define G0P1_RETENTION_REGS_CNT_1 12 +#define G0P1_RETENTION_MAP_BASE_1 (REG_AHB_DMA_BASE + 0x304) +static const uint32_t g0p1_regs_map0[4] = {0x81001, 0x0, 0xc00604c0, 0x604}; +static const uint32_t g0p1_regs_map1[4] = {0xc0000003, 0x3f4800, 0x0, 0x0}; +static const regdma_entries_config_t gdma_g0p1_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_AHB_DMA_LINK(0x00), \ + G0P1_RETENTION_MAP_BASE_0, G0P1_RETENTION_MAP_BASE_0, \ + G0P1_RETENTION_REGS_CNT_0, 0, 0, \ + g0p1_regs_map0[0], g0p1_regs_map0[1], \ + g0p1_regs_map0[2], g0p1_regs_map0[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_AHB_DMA_LINK(0x01), \ + G0P1_RETENTION_MAP_BASE_1, G0P1_RETENTION_MAP_BASE_1, \ + G0P1_RETENTION_REGS_CNT_1, 0, 0, \ + g0p1_regs_map1[0], g0p1_regs_map1[1], \ + g0p1_regs_map1[2], g0p1_regs_map1[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +/* GDMA Channel (Group0, Pair2) Registers Context + Include: GDMA_MISC_CONF_REG + GDMA_IN_INT_ENA_CH2_REG / GDMA_OUT_INT_ENA_CH2_REG + + GDMA_IN_PERI_SEL_CH2_REG / GDMA_OUT_PERI_SEL_CH2_REG + GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG + GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG + AHB_DMA_TX_CH_ARB_WEIGH_CH2_REG / AHB_DMA_TX_ARB_WEIGH_OPT_DIR_CH2_REG + AHB_DMA_RX_CH_ARB_WEIGH_CH2_REG / AHB_DMA_RX_ARB_WEIGH_OPT_DIR_CH2_REG + AHB_DMA_IN_LINK_ADDR_CH2_REG / AHB_DMA_OUT_LINK_ADDR_CH2_REG + AHB_DMA_INTR_MEM_START_ADDR_REG / AHB_DMA_INTR_MEM_END_ADDR_REG + AHB_DMA_ARB_TIMEOUT_TX_REG / AHB_DMA_ARB_TIMEOUT_RX_REG + AHB_DMA_WEIGHT_EN_TX_REG / AHB_DMA_WEIGHT_EN_RX_REG +*/ +#define G0P2_RETENTION_REGS_CNT_0 3 +#define G0P2_RETENTION_MAP_BASE_0 (REG_AHB_DMA_BASE + 0x28) +#define G0P2_RETENTION_REGS_CNT_1 22 +#define G0P2_RETENTION_MAP_BASE_1 (REG_AHB_DMA_BASE + 0x1f0) +static const uint32_t g0p2_regs_map0[4] = {0x9001, 0x0, 0x0, 0x0}; +static const uint32_t g0p2_regs_map1[4] = {0x13001813, 0x18, 0x18000, 0x7f26000}; +static const regdma_entries_config_t gdma_g0p2_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_AHB_DMA_LINK(0x00), \ + G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \ + G0P2_RETENTION_REGS_CNT_0, 0, 0, \ + g0p2_regs_map0[0], g0p2_regs_map0[1], \ + g0p2_regs_map0[2], g0p2_regs_map0[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_AHB_DMA_LINK(0x01), \ + G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \ + G0P2_RETENTION_REGS_CNT_1, 0, 0, \ + g0p2_regs_map1[0], g0p2_regs_map1[1], \ + g0p2_regs_map1[2], g0p2_regs_map1[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_NUM_GROUPS_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX] = { + [0] = { + [0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)}, + [1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)}, + [2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)} + } +}; +#endif diff --git a/components/soc/esp32c5/mp/gpio_periph.c b/components/soc/esp32c5/mp/gpio_periph.c index bd23783dd96b..1d1d4969723f 100644 --- a/components/soc/esp32c5/mp/gpio_periph.c +++ b/components/soc/esp32c5/mp/gpio_periph.c @@ -6,38 +6,6 @@ #include "soc/gpio_periph.h" -const uint32_t GPIO_PIN_MUX_REG[] = { - IO_MUX_GPIO0_REG, - IO_MUX_GPIO1_REG, - IO_MUX_GPIO2_REG, - IO_MUX_GPIO3_REG, - IO_MUX_GPIO4_REG, - IO_MUX_GPIO5_REG, - IO_MUX_GPIO6_REG, - IO_MUX_GPIO7_REG, - IO_MUX_GPIO8_REG, - IO_MUX_GPIO9_REG, - IO_MUX_GPIO10_REG, - IO_MUX_GPIO11_REG, - IO_MUX_GPIO12_REG, - IO_MUX_GPIO13_REG, - IO_MUX_GPIO14_REG, - IO_MUX_GPIO15_REG, - IO_MUX_GPIO16_REG, - IO_MUX_GPIO17_REG, - IO_MUX_GPIO18_REG, - IO_MUX_GPIO19_REG, - IO_MUX_GPIO20_REG, - IO_MUX_GPIO21_REG, - IO_MUX_GPIO22_REG, - IO_MUX_GPIO23_REG, - IO_MUX_GPIO24_REG, - IO_MUX_GPIO25_REG, - IO_MUX_GPIO26_REG, - IO_MUX_GPIO27_REG, - IO_MUX_GPIO28_REG, -}; - _Static_assert(sizeof(GPIO_PIN_MUX_REG) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_PIN_MUX_REG"); const uint32_t GPIO_HOLD_MASK[] = { diff --git a/components/soc/esp32c5/mp/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/mp/include/soc/Kconfig.soc_caps.in index 347785282fda..8b61d088e9fa 100644 --- a/components/soc/esp32c5/mp/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/mp/include/soc/Kconfig.soc_caps.in @@ -7,10 +7,22 @@ config SOC_UART_SUPPORTED bool default y +config SOC_GDMA_SUPPORTED + bool + default y + +config SOC_AHB_GDMA_SUPPORTED + bool + default y + config SOC_GPTIMER_SUPPORTED bool default y +config SOC_ASYNC_MEMCPY_SUPPORTED + bool + default y + config SOC_SUPPORTS_SECURE_DL_MODE bool default y @@ -39,6 +51,10 @@ config SOC_FLASH_ENC_SUPPORTED bool default y +config SOC_LP_PERIPHERALS_SUPPORTED + bool + default y + config SOC_SPI_FLASH_SUPPORTED bool default y @@ -111,17 +127,57 @@ config SOC_CPU_IDRAM_SPLIT_USING_PMP bool default y +config SOC_DMA_CAN_ACCESS_FLASH + bool + default y + +config SOC_AHB_GDMA_VERSION + int + default 2 + +config SOC_GDMA_NUM_GROUPS_MAX + int + default 1 + +config SOC_GDMA_PAIRS_PER_GROUP_MAX + int + default 3 + +config SOC_GPIO_PORT + int + default 1 + config SOC_GPIO_PIN_COUNT int default 29 +config SOC_GPIO_SUPPORT_PIN_HYS_FILTER + bool + default y + +config SOC_GPIO_SUPPORT_RTC_INDEPENDENT + bool + default y + config SOC_GPIO_IN_RANGE_MAX int - default 30 + default 28 config SOC_GPIO_OUT_RANGE_MAX int - default 30 + default 28 + +config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK + int + default 0 + +config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK + hex + default 0x0000000001FFFF00 + +config SOC_GPIO_SUPPORT_FORCE_HOLD + bool + default y config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP bool @@ -295,6 +351,10 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS int default 2 +config SOC_EFUSE_ECDSA_KEY + bool + default y + config SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS int default 3 @@ -331,10 +391,26 @@ config SOC_LP_UART_FIFO_LEN int default 16 +config SOC_UART_BITRATE_MAX + int + default 5000000 + config SOC_UART_SUPPORT_XTAL_CLK bool default y +config SOC_UART_SUPPORT_WAKEUP_INT + bool + default y + +config SOC_UART_HAS_LP_UART + bool + default y + +config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND + bool + default y + config SOC_PM_SUPPORT_MODEM_PD bool default y diff --git a/components/soc/esp32c5/mp/include/soc/ahb_dma_struct.h b/components/soc/esp32c5/mp/include/soc/ahb_dma_struct.h index 3da3d5fee3f1..dce94fc8501e 100644 --- a/components/soc/esp32c5/mp/include/soc/ahb_dma_struct.h +++ b/components/soc/esp32c5/mp/include/soc/ahb_dma_struct.h @@ -1132,139 +1132,84 @@ typedef union { uint32_t val; } ahb_dma_out_peri_sel_chn_reg_t; +typedef struct { + volatile ahb_dma_in_int_raw_chn_reg_t raw; + volatile ahb_dma_in_int_st_chn_reg_t st; + volatile ahb_dma_in_int_ena_chn_reg_t ena; + volatile ahb_dma_in_int_clr_chn_reg_t clr; +} ahb_dma_in_int_chn_reg_t; + +typedef struct { + volatile ahb_dma_out_int_raw_chn_reg_t raw; + volatile ahb_dma_out_int_st_chn_reg_t st; + volatile ahb_dma_out_int_ena_chn_reg_t ena; + volatile ahb_dma_out_int_clr_chn_reg_t clr; +} ahb_dma_out_int_chn_reg_t; + +typedef struct { + volatile ahb_dma_in_conf0_chn_reg_t in_conf0; + volatile ahb_dma_in_conf1_chn_reg_t in_conf1; + volatile ahb_dma_infifo_status_chn_reg_t infifo_status; + volatile ahb_dma_in_pop_chn_reg_t in_pop; + volatile ahb_dma_in_link_chn_reg_t in_link; + volatile ahb_dma_in_state_chn_reg_t in_state; + volatile ahb_dma_in_suc_eof_des_addr_chn_reg_t in_suc_eof_des_addr; + volatile ahb_dma_in_err_eof_des_addr_chn_reg_t in_err_eof_des_addr; + volatile ahb_dma_in_dscr_chn_reg_t in_dscr; + volatile ahb_dma_in_dscr_bf0_chn_reg_t in_dscr_bf0; + volatile ahb_dma_in_dscr_bf1_chn_reg_t in_dscr_bf1; + volatile ahb_dma_in_pri_chn_reg_t in_pri; + volatile ahb_dma_in_peri_sel_chn_reg_t in_peri_sel; +} ahb_dma_in_chn_reg_t; + +typedef struct { + volatile ahb_dma_out_conf0_chn_reg_t out_conf0; + volatile ahb_dma_out_conf1_chn_reg_t out_conf1; + volatile ahb_dma_outfifo_status_chn_reg_t outfifo_status; + volatile ahb_dma_out_push_chn_reg_t out_push; + volatile ahb_dma_out_link_chn_reg_t out_link; + volatile ahb_dma_out_state_chn_reg_t out_state; + volatile ahb_dma_out_eof_des_addr_chn_reg_t out_eof_des_addr; + volatile ahb_dma_out_eof_bfr_des_addr_chn_reg_t out_eof_bfr_des_addr; + volatile ahb_dma_out_dscr_chn_reg_t out_dscr; + volatile ahb_dma_out_dscr_bf0_chn_reg_t out_dscr_bf0; + volatile ahb_dma_out_dscr_bf1_chn_reg_t out_dscr_bf1; + volatile ahb_dma_out_pri_chn_reg_t out_pri; + volatile ahb_dma_out_peri_sel_chn_reg_t out_peri_sel; +} ahb_dma_out_chn_reg_t; + +typedef struct { + volatile ahb_dma_in_chn_reg_t in; + uint32_t reserved_in[11]; + volatile ahb_dma_out_chn_reg_t out; + uint32_t reserved_out[11]; +} ahb_dma_chn_reg_t; + +typedef struct { + uint32_t reserved[8]; + ahb_dma_rx_ch_arb_weigh_chn_reg_t ch_arb_weigh; + ahb_dma_rx_arb_weigh_opt_dir_chn_reg_t arb_weigh_opt; +} ahb_dma_in_crc_arb_chn_reg_t; + +typedef struct { + uint32_t reserved[8]; + ahb_dma_tx_ch_arb_weigh_chn_reg_t ch_arb_weigh; + ahb_dma_tx_arb_weigh_opt_dir_chn_reg_t arb_weigh_opt; +} ahb_dma_out_crc_arb_chn_reg_t; typedef struct { - volatile ahb_dma_in_int_raw_chn_reg_t in_int_raw_ch0; - volatile ahb_dma_in_int_st_chn_reg_t in_int_st_ch0; - volatile ahb_dma_in_int_ena_chn_reg_t in_int_ena_ch0; - volatile ahb_dma_in_int_clr_chn_reg_t in_int_clr_ch0; - volatile ahb_dma_in_int_raw_chn_reg_t in_int_raw_ch1; - volatile ahb_dma_in_int_st_chn_reg_t in_int_st_ch1; - volatile ahb_dma_in_int_ena_chn_reg_t in_int_ena_ch1; - volatile ahb_dma_in_int_clr_chn_reg_t in_int_clr_ch1; - volatile ahb_dma_in_int_raw_chn_reg_t in_int_raw_ch2; - volatile ahb_dma_in_int_st_chn_reg_t in_int_st_ch2; - volatile ahb_dma_in_int_ena_chn_reg_t in_int_ena_ch2; - volatile ahb_dma_in_int_clr_chn_reg_t in_int_clr_ch2; - volatile ahb_dma_out_int_raw_chn_reg_t out_int_raw_ch0; - volatile ahb_dma_out_int_st_chn_reg_t out_int_st_ch0; - volatile ahb_dma_out_int_ena_chn_reg_t out_int_ena_ch0; - volatile ahb_dma_out_int_clr_chn_reg_t out_int_clr_ch0; - volatile ahb_dma_out_int_raw_chn_reg_t out_int_raw_ch1; - volatile ahb_dma_out_int_st_chn_reg_t out_int_st_ch1; - volatile ahb_dma_out_int_ena_chn_reg_t out_int_ena_ch1; - volatile ahb_dma_out_int_clr_chn_reg_t out_int_clr_ch1; - volatile ahb_dma_out_int_raw_chn_reg_t out_int_raw_ch2; - volatile ahb_dma_out_int_st_chn_reg_t out_int_st_ch2; - volatile ahb_dma_out_int_ena_chn_reg_t out_int_ena_ch2; - volatile ahb_dma_out_int_clr_chn_reg_t out_int_clr_ch2; + volatile ahb_dma_in_int_chn_reg_t in_intr[3]; + volatile ahb_dma_out_int_chn_reg_t out_intr[3]; volatile ahb_dma_ahb_test_reg_t ahb_test; volatile ahb_dma_misc_conf_reg_t misc_conf; volatile ahb_dma_date_reg_t date; uint32_t reserved_06c; - volatile ahb_dma_in_conf0_chn_reg_t in_conf0_ch0; - volatile ahb_dma_in_conf1_chn_reg_t in_conf1_ch0; - volatile ahb_dma_infifo_status_chn_reg_t infifo_status_ch0; - volatile ahb_dma_in_pop_chn_reg_t in_pop_ch0; - volatile ahb_dma_in_link_chn_reg_t in_link_ch0; - volatile ahb_dma_in_state_chn_reg_t in_state_ch0; - volatile ahb_dma_in_suc_eof_des_addr_chn_reg_t in_suc_eof_des_addr_ch0; - volatile ahb_dma_in_err_eof_des_addr_chn_reg_t in_err_eof_des_addr_ch0; - volatile ahb_dma_in_dscr_chn_reg_t in_dscr_ch0; - volatile ahb_dma_in_dscr_bf0_chn_reg_t in_dscr_bf0_ch0; - volatile ahb_dma_in_dscr_bf1_chn_reg_t in_dscr_bf1_ch0; - volatile ahb_dma_in_pri_chn_reg_t in_pri_ch0; - volatile ahb_dma_in_peri_sel_chn_reg_t in_peri_sel_ch0; - uint32_t reserved_0a4[11]; - volatile ahb_dma_out_conf0_ch0_reg_t out_conf0_ch0; - volatile ahb_dma_out_conf1_chn_reg_t out_conf1_ch0; - volatile ahb_dma_outfifo_status_chn_reg_t outfifo_status_ch0; - volatile ahb_dma_out_push_chn_reg_t out_push_ch0; - volatile ahb_dma_out_link_chn_reg_t out_link_ch0; - volatile ahb_dma_out_state_chn_reg_t out_state_ch0; - volatile ahb_dma_out_eof_des_addr_chn_reg_t out_eof_des_addr_ch0; - volatile ahb_dma_out_eof_bfr_des_addr_chn_reg_t out_eof_bfr_des_addr_ch0; - volatile ahb_dma_out_dscr_chn_reg_t out_dscr_ch0; - volatile ahb_dma_out_dscr_bf0_chn_reg_t out_dscr_bf0_ch0; - volatile ahb_dma_out_dscr_bf1_chn_reg_t out_dscr_bf1_ch0; - volatile ahb_dma_out_pri_chn_reg_t out_pri_ch0; - volatile ahb_dma_out_peri_sel_chn_reg_t out_peri_sel_ch0; - uint32_t reserved_104[11]; - volatile ahb_dma_in_conf0_chn_reg_t in_conf0_ch1; - volatile ahb_dma_in_conf1_chn_reg_t in_conf1_ch1; - volatile ahb_dma_infifo_status_chn_reg_t infifo_status_ch1; - volatile ahb_dma_in_pop_chn_reg_t in_pop_ch1; - volatile ahb_dma_in_link_chn_reg_t in_link_ch1; - volatile ahb_dma_in_state_chn_reg_t in_state_ch1; - volatile ahb_dma_in_suc_eof_des_addr_chn_reg_t in_suc_eof_des_addr_ch1; - volatile ahb_dma_in_err_eof_des_addr_chn_reg_t in_err_eof_des_addr_ch1; - volatile ahb_dma_in_dscr_chn_reg_t in_dscr_ch1; - volatile ahb_dma_in_dscr_bf0_chn_reg_t in_dscr_bf0_ch1; - volatile ahb_dma_in_dscr_bf1_chn_reg_t in_dscr_bf1_ch1; - volatile ahb_dma_in_pri_chn_reg_t in_pri_ch1; - volatile ahb_dma_in_peri_sel_chn_reg_t in_peri_sel_ch1; - uint32_t reserved_164[11]; - volatile ahb_dma_out_conf0_chn_reg_t out_conf0_ch1; - volatile ahb_dma_out_conf1_chn_reg_t out_conf1_ch1; - volatile ahb_dma_outfifo_status_chn_reg_t outfifo_status_ch1; - volatile ahb_dma_out_push_chn_reg_t out_push_ch1; - volatile ahb_dma_out_link_chn_reg_t out_link_ch1; - volatile ahb_dma_out_state_chn_reg_t out_state_ch1; - volatile ahb_dma_out_eof_des_addr_chn_reg_t out_eof_des_addr_ch1; - volatile ahb_dma_out_eof_bfr_des_addr_chn_reg_t out_eof_bfr_des_addr_ch1; - volatile ahb_dma_out_dscr_chn_reg_t out_dscr_ch1; - volatile ahb_dma_out_dscr_bf0_chn_reg_t out_dscr_bf0_ch1; - volatile ahb_dma_out_dscr_bf1_chn_reg_t out_dscr_bf1_ch1; - volatile ahb_dma_out_pri_chn_reg_t out_pri_ch1; - volatile ahb_dma_out_peri_sel_chn_reg_t out_peri_sel_ch1; - uint32_t reserved_1c4[11]; - volatile ahb_dma_in_conf0_chn_reg_t in_conf0_ch2; - volatile ahb_dma_in_conf1_chn_reg_t in_conf1_ch2; - volatile ahb_dma_infifo_status_chn_reg_t infifo_status_ch2; - volatile ahb_dma_in_pop_chn_reg_t in_pop_ch2; - volatile ahb_dma_in_link_chn_reg_t in_link_ch2; - volatile ahb_dma_in_state_chn_reg_t in_state_ch2; - volatile ahb_dma_in_suc_eof_des_addr_chn_reg_t in_suc_eof_des_addr_ch2; - volatile ahb_dma_in_err_eof_des_addr_chn_reg_t in_err_eof_des_addr_ch2; - volatile ahb_dma_in_dscr_chn_reg_t in_dscr_ch2; - volatile ahb_dma_in_dscr_bf0_chn_reg_t in_dscr_bf0_ch2; - volatile ahb_dma_in_dscr_bf1_chn_reg_t in_dscr_bf1_ch2; - volatile ahb_dma_in_pri_chn_reg_t in_pri_ch2; - volatile ahb_dma_in_peri_sel_chn_reg_t in_peri_sel_ch2; - uint32_t reserved_224[11]; - volatile ahb_dma_out_conf0_chn_reg_t out_conf0_ch2; - volatile ahb_dma_out_conf1_chn_reg_t out_conf1_ch2; - volatile ahb_dma_outfifo_status_chn_reg_t outfifo_status_ch2; - volatile ahb_dma_out_push_chn_reg_t out_push_ch2; - volatile ahb_dma_out_link_chn_reg_t out_link_ch2; - volatile ahb_dma_out_state_chn_reg_t out_state_ch2; - volatile ahb_dma_out_eof_des_addr_chn_reg_t out_eof_des_addr_ch2; - volatile ahb_dma_out_eof_bfr_des_addr_chn_reg_t out_eof_bfr_des_addr_ch2; - volatile ahb_dma_out_dscr_chn_reg_t out_dscr_ch2; - volatile ahb_dma_out_dscr_bf0_chn_reg_t out_dscr_bf0_ch2; - volatile ahb_dma_out_dscr_bf1_chn_reg_t out_dscr_bf1_ch2; - volatile ahb_dma_out_pri_chn_reg_t out_pri_ch2; - volatile ahb_dma_out_peri_sel_chn_reg_t out_peri_sel_ch2; - uint32_t reserved_284[22]; - volatile ahb_dma_tx_ch_arb_weigh_chn_reg_t tx_ch_arb_weigh_ch0; - volatile ahb_dma_tx_arb_weigh_opt_dir_chn_reg_t tx_arb_weigh_opt_dir_ch0; - uint32_t reserved_2e4[8]; - volatile ahb_dma_tx_ch_arb_weigh_chn_reg_t tx_ch_arb_weigh_ch1; - volatile ahb_dma_tx_arb_weigh_opt_dir_chn_reg_t tx_arb_weigh_opt_dir_ch1; - uint32_t reserved_30c[8]; - volatile ahb_dma_tx_ch_arb_weigh_chn_reg_t tx_ch_arb_weigh_ch2; - volatile ahb_dma_tx_arb_weigh_opt_dir_chn_reg_t tx_arb_weigh_opt_dir_ch2; - uint32_t reserved_334[8]; - volatile ahb_dma_rx_ch_arb_weigh_chn_reg_t rx_ch_arb_weigh_ch0; - volatile ahb_dma_rx_arb_weigh_opt_dir_chn_reg_t rx_arb_weigh_opt_dir_ch0; - uint32_t reserved_35c[8]; - volatile ahb_dma_rx_ch_arb_weigh_chn_reg_t rx_ch_arb_weigh_ch1; - volatile ahb_dma_rx_arb_weigh_opt_dir_chn_reg_t rx_arb_weigh_opt_dir_ch1; - uint32_t reserved_384[8]; - volatile ahb_dma_rx_ch_arb_weigh_chn_reg_t rx_ch_arb_weigh_ch2; - volatile ahb_dma_rx_arb_weigh_opt_dir_chn_reg_t rx_arb_weigh_opt_dir_ch2; - volatile ahb_dma_in_link_addr_chn_reg_t in_link_addr_chn[3]; - volatile ahb_dma_out_link_addr_chn_reg_t out_link_addr_chn[3]; + volatile ahb_dma_chn_reg_t channel[3]; + uint32_t reserved_2b0[3]; + volatile ahb_dma_out_crc_arb_chn_reg_t out_crc_arb[3]; + volatile ahb_dma_in_crc_arb_chn_reg_t in_crc_arb[3]; + volatile ahb_dma_in_link_addr_chn_reg_t in_link_addr[3]; + volatile ahb_dma_out_link_addr_chn_reg_t out_link_addr[3]; volatile ahb_dma_intr_mem_start_addr_reg_t intr_mem_start_addr; volatile ahb_dma_intr_mem_end_addr_reg_t intr_mem_end_addr; volatile ahb_dma_arb_timeout_tx_reg_t arb_timeout_tx; diff --git a/components/soc/esp32c5/mp/include/soc/clk_tree_defs.h b/components/soc/esp32c5/mp/include/soc/clk_tree_defs.h index 1872aedd81d6..a1ff04231660 100644 --- a/components/soc/esp32c5/mp/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c5/mp/include/soc/clk_tree_defs.h @@ -247,23 +247,39 @@ typedef enum { // TODO: [ESP32C5] IDF-8727 (inherit from C6) ///////////////////////////////////////////////////UART///////////////////////////////////////////////////////////////// +/** + * @brief Array initializer for all supported clock sources of UART + */ +#define SOC_UART_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST} + /** * @brief Type of UART clock source, reserved for the legacy UART driver */ -typedef enum { // TODO: [ESP32C5] IDF-8722 (inherit from C6) +typedef enum { UART_SCLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock is PLL_F80M */ UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */ UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */ +#if SOC_CLK_TREE_SUPPORTED UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */ +#else + UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< UART source clock default choice is XTAL for FPGA environment*/ +#endif } soc_periph_uart_clk_src_legacy_t; +/** + * @brief Array initializer for all supported clock sources of LP_UART + */ +#define SOC_LP_UART_CLKS {SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL_D2} + /** * @brief Type of LP_UART clock source */ -typedef enum { // TODO: [ESP32C5] IDF-8633 (inherit from C6) - LP_UART_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock is LP(RTC)_FAST */ +typedef enum { + LP_UART_SCLK_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< LP_UART source clock is RC_FAST */ LP_UART_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock is XTAL_D2 */ - LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock default choice is LP(RTC)_FAST */ + + //TODO: IDF-10034 + LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock default choice is XTAL_D2 */ } soc_periph_lp_uart_clk_src_t; //////////////////////////////////////////////////MCPWM///////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32c5/mp/include/soc/gdma_channel.h b/components/soc/esp32c5/mp/include/soc/gdma_channel.h index e69de29bb2d1..7322d9ffe791 100644 --- a/components/soc/esp32c5/mp/include/soc/gdma_channel.h +++ b/components/soc/esp32c5/mp/include/soc/gdma_channel.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +// The following macros have a format SOC_[periph][instance_id] to make it work with `GDMA_MAKE_TRIGGER` +#define SOC_GDMA_TRIG_PERIPH_M2M0 (-1) +#define SOC_GDMA_TRIG_PERIPH_SPI2 (1) +#define SOC_GDMA_TRIG_PERIPH_UHCI0 (2) +#define SOC_GDMA_TRIG_PERIPH_I2S0 (3) +#define SOC_GDMA_TRIG_PERIPH_AES0 (6) +#define SOC_GDMA_TRIG_PERIPH_SHA0 (7) +#define SOC_GDMA_TRIG_PERIPH_ADC0 (8) +#define SOC_GDMA_TRIG_PERIPH_PARLIO0 (9) + +// On which system bus is the DMA instance of the peripheral connection mounted +#define SOC_GDMA_BUS_ANY (-1) +#define SOC_GDMA_BUS_AHB (0) + +#define SOC_GDMA_TRIG_PERIPH_M2M0_BUS SOC_GDMA_BUS_ANY +#define SOC_GDMA_TRIG_PERIPH_SPI2_BUS SOC_GDMA_BUS_AHB +#define SOC_GDMA_TRIG_PERIPH_UHCI0_BUS SOC_GDMA_BUS_AHB +#define SOC_GDMA_TRIG_PERIPH_I2S0_BUS SOC_GDMA_BUS_AHB +#define SOC_GDMA_TRIG_PERIPH_AES0_BUS SOC_GDMA_BUS_AHB +#define SOC_GDMA_TRIG_PERIPH_SHA0_BUS SOC_GDMA_BUS_AHB +#define SOC_GDMA_TRIG_PERIPH_ADC0_BUS SOC_GDMA_BUS_AHB +#define SOC_GDMA_TRIG_PERIPH_PARLIO0_BUS SOC_GDMA_BUS_AHB diff --git a/components/soc/esp32c5/mp/include/soc/gpio_pins.h b/components/soc/esp32c5/mp/include/soc/gpio_pins.h index c630ae47649b..268506ce391a 100644 --- a/components/soc/esp32c5/mp/include/soc/gpio_pins.h +++ b/components/soc/esp32c5/mp/include/soc/gpio_pins.h @@ -11,8 +11,8 @@ extern "C" { #endif -#define GPIO_MATRIX_CONST_ONE_INPUT (0x38) -#define GPIO_MATRIX_CONST_ZERO_INPUT (0x3C) +#define GPIO_MATRIX_CONST_ONE_INPUT (0x40) +#define GPIO_MATRIX_CONST_ZERO_INPUT (0x50) #ifdef __cplusplus } diff --git a/components/soc/esp32c5/mp/include/soc/io_mux_reg.h b/components/soc/esp32c5/mp/include/soc/io_mux_reg.h index c8bec06285ec..1a9dec1b88a9 100644 --- a/components/soc/esp32c5/mp/include/soc/io_mux_reg.h +++ b/components/soc/esp32c5/mp/include/soc/io_mux_reg.h @@ -95,6 +95,36 @@ extern "C" { #define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN) #define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN) +#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_U_PAD_XTAL_32K_P +#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_U_PAD_XTAL_32K_N +#define IO_MUX_GPIO2_REG PERIPHS_IO_MUX_U_PAD_MTMS +#define IO_MUX_GPIO3_REG PERIPHS_IO_MUX_U_PAD_MTDI +#define IO_MUX_GPIO4_REG PERIPHS_IO_MUX_U_PAD_MTCK +#define IO_MUX_GPIO5_REG PERIPHS_IO_MUX_U_PAD_MTDO +#define IO_MUX_GPIO6_REG PERIPHS_IO_MUX_U_PAD_GPIO6 +#define IO_MUX_GPIO7_REG PERIPHS_IO_MUX_U_PAD_GPIO7 +#define IO_MUX_GPIO8_REG PERIPHS_IO_MUX_U_PAD_GPIO8 +#define IO_MUX_GPIO9_REG PERIPHS_IO_MUX_U_PAD_GPIO9 +#define IO_MUX_GPIO10_REG PERIPHS_IO_MUX_U_PAD_GPIO10 +#define IO_MUX_GPIO11_REG PERIPHS_IO_MUX_U_PAD_U0TXD +#define IO_MUX_GPIO12_REG PERIPHS_IO_MUX_U_PAD_U0RXD +#define IO_MUX_GPIO13_REG PERIPHS_IO_MUX_U_PAD_GPIO13 +#define IO_MUX_GPIO14_REG PERIPHS_IO_MUX_U_PAD_GPIO14 +#define IO_MUX_GPIO15_REG PERIPHS_IO_MUX_U_PAD_SPICS1 +#define IO_MUX_GPIO16_REG PERIPHS_IO_MUX_U_PAD_SPICS0 +#define IO_MUX_GPIO17_REG PERIPHS_IO_MUX_U_PAD_SPIQ +#define IO_MUX_GPIO18_REG PERIPHS_IO_MUX_U_PAD_SPIWP +#define IO_MUX_GPIO19_REG PERIPHS_IO_MUX_U_PAD_VDD_SPI +#define IO_MUX_GPIO20_REG PERIPHS_IO_MUX_U_PAD_SPIHD +#define IO_MUX_GPIO21_REG PERIPHS_IO_MUX_U_PAD_SPICLK +#define IO_MUX_GPIO22_REG PERIPHS_IO_MUX_U_PAD_SPID +#define IO_MUX_GPIO23_REG PERIPHS_IO_MUX_U_PAD_GPIO23 +#define IO_MUX_GPIO24_REG PERIPHS_IO_MUX_U_PAD_GPIO24 +#define IO_MUX_GPIO25_REG PERIPHS_IO_MUX_U_PAD_GPIO25 +#define IO_MUX_GPIO26_REG PERIPHS_IO_MUX_U_PAD_GPIO26 +#define IO_MUX_GPIO27_REG PERIPHS_IO_MUX_U_PAD_GPIO27 +#define IO_MUX_GPIO28_REG PERIPHS_IO_MUX_U_PAD_GPIO28 + #define PIN_FUNC_GPIO 1 #define GPIO_PAD_PULLUP(num) do{PIN_PULLDWN_DIS(IOMUX_REG_GPIO##num);PIN_PULLUP_EN(IOMUX_REG_GPIO##num);}while(0) @@ -102,21 +132,21 @@ extern "C" { #define GPIO_PAD_SET_DRV(num, drv) PIN_SET_DRV(IOMUX_REG_GPIO##num, drv) // TODO: [ESP32C5] IDF-8698 need check -#define SPI_HD_GPIO_NUM 22 -#define SPI_WP_GPIO_NUM 20 -#define SPI_CS0_GPIO_NUM 18 -#define SPI_CLK_GPIO_NUM 23 -#define SPI_D_GPIO_NUM 24 -#define SPI_Q_GPIO_NUM 19 +#define SPI_HD_GPIO_NUM 20 +#define SPI_WP_GPIO_NUM 18 +#define SPI_CS0_GPIO_NUM 16 +#define SPI_CLK_GPIO_NUM 21 +#define SPI_D_GPIO_NUM 22 +#define SPI_Q_GPIO_NUM 17 -#define USB_INT_PHY0_DM_GPIO_NUM 25 -#define USB_INT_PHY0_DP_GPIO_NUM 26 +#define USB_INT_PHY0_DM_GPIO_NUM 13 +#define USB_INT_PHY0_DP_GPIO_NUM 14 #define EXT_OSC_SLOW_GPIO_NUM 0 #define MAX_RTC_GPIO_NUM 8 -#define MAX_PAD_GPIO_NUM 26 -#define MAX_GPIO_NUM 30 +#define MAX_PAD_GPIO_NUM 28 +#define MAX_GPIO_NUM 32 #define DIG_IO_HOLD_BIT_SHIFT 32 #define REG_IO_MUX_BASE DR_REG_IO_MUX_BASE @@ -137,4107 +167,127 @@ extern "C" { // definitions above are inherited from previous version of code, should double check // definitions below are generated from pin_txt.csv -#define PERIPHS_IO_MUX_XTAL_32K_P_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_XTAL_32K_P_GPIO0_0 0 -#define FUNC_XTAL_32K_P_GPIO0 1 - -#define PERIPHS_IO_MUX_XTAL_32K_N_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_XTAL_32K_N_GPIO1_0 0 -#define FUNC_XTAL_32K_N_GPIO1 1 - -// Strapping: Boot Mode select -#define PERIPHS_IO_MUX_MTMS_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_MTMS_MTMS 0 -#define FUNC_MTMS_GPIO2 1 -#define FUNC_MTMS_FSPIQ 2 - -// Strapping: Boot Mode select -#define PERIPHS_IO_MUX_MTDI_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_MTDI_MTDI 0 -#define FUNC_MTDI_GPIO3 1 - -#define PERIPHS_IO_MUX_MTCK_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_MTCK_MTCK 0 -#define FUNC_MTCK_GPIO4 1 -#define FUNC_MTCK_FSPIHD 2 - -#define PERIPHS_IO_MUX_MTDO_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_MTDO_MTDO 0 -#define FUNC_MTDO_GPIO5 1 -#define FUNC_MTDO_FSPIWP 2 - -#define PERIPHS_IO_MUX_GPIO6_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO6_GPIO6_0 0 -#define FUNC_GPIO6_GPIO6 1 -#define FUNC_GPIO6_FSPICLK 2 - -// Strapping: JTAG sel -#define PERIPHS_IO_MUX_GPIO7_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO7_GPIO7_0 0 -#define FUNC_GPIO7_GPIO7 1 -#define FUNC_GPIO7_FSPID 2 - -#define PERIPHS_IO_MUX_GPIO8_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO8_GPIO8_0 0 -#define FUNC_GPIO8_GPIO8 1 - -#define PERIPHS_IO_MUX_GPIO9_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO9_GPIO9_0 0 -#define FUNC_GPIO9_GPIO9 1 - -#define PERIPHS_IO_MUX_GPIO10_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO10_GPIO10_0 0 -#define FUNC_GPIO10_GPIO10 1 -#define FUNC_GPIO10_FSPICS0 2 - -#define PERIPHS_IO_MUX_U0TXD_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_U0TXD_U0TXD 0 -#define FUNC_U0TXD_GPIO11 1 - -#define PERIPHS_IO_MUX_U0RXD_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_U0RXD_U0RXD 0 -#define FUNC_U0RXD_GPIO12 1 - -#define PERIPHS_IO_MUX_GPIO13_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO13_GPIO13_0 0 -#define FUNC_GPIO13_GPIO13 1 - -#define PERIPHS_IO_MUX_GPIO14_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO14_GPIO14_0 0 -#define FUNC_GPIO14_GPIO14 1 - -#define PERIPHS_IO_MUX_SPICS1_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_SPICS1_SPICS1 0 -#define FUNC_SPICS1_GPIO15 1 - -#define PERIPHS_IO_MUX_SPICS0_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_SPICS0_SPICS0 0 -#define FUNC_SPICS0_GPIO16 1 - -#define PERIPHS_IO_MUX_SPIQ_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_SPIQ_SPIQ 0 -#define FUNC_SPIQ_GPIO17 1 - -#define PERIPHS_IO_MUX_SPIWP_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_SPIWP_SPIWP 0 -#define FUNC_SPIWP_GPIO18 1 - -#define PERIPHS_IO_MUX_VDD_SPI_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_VDD_SPI_GPIO19_0 0 -#define FUNC_VDD_SPI_GPIO19 1 - -#define PERIPHS_IO_MUX_SPIHD_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_SPIHD_SPIHD 0 -#define FUNC_SPIHD_GPIO20 1 - -#define PERIPHS_IO_MUX_SPICLK_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_SPICLK_SPICLK 0 -#define FUNC_SPICLK_GPIO21 1 - -#define PERIPHS_IO_MUX_SPID_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_SPID_SPID 0 -#define FUNC_SPID_GPIO22 1 - -#define PERIPHS_IO_MUX_GPIO23_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO23_GPIO23_0 0 -#define FUNC_GPIO23_GPIO23 1 - -#define PERIPHS_IO_MUX_GPIO24_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO24_GPIO24_0 0 -#define FUNC_GPIO24_GPIO24 1 - -#define PERIPHS_IO_MUX_GPIO25_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO25_GPIO25_0 0 -#define FUNC_GPIO25_GPIO25 1 - -// Strapping: Boot Mode select (analog mode) -#define PERIPHS_IO_MUX_GPIO26_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO26_GPIO26_0 0 -#define FUNC_GPIO26_GPIO26 1 - -// Strapping: Boot Mode select -#define PERIPHS_IO_MUX_GPIO27_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO27_GPIO27_0 0 -#define FUNC_GPIO27_GPIO27 1 - -// Strapping: Boot Mode select -#define PERIPHS_IO_MUX_GPIO28_U (REG_IO_MUX_BASE + 0x0) -#define FUNC_GPIO28_GPIO28_0 0 -#define FUNC_GPIO28_GPIO28 1 - - -/** IO_MUX_GPIO0_REG register - * IO MUX configuration register for GPIO0 - */ -#define IO_MUX_GPIO0_REG (DR_REG_IO_MUX_BASE + 0x0) -/** IO_MUX_GPIO0_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO0 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO0_MCU_OE (BIT(0)) -#define IO_MUX_GPIO0_MCU_OE_M (IO_MUX_GPIO0_MCU_OE_V << IO_MUX_GPIO0_MCU_OE_S) -#define IO_MUX_GPIO0_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO0_MCU_OE_S 0 -/** IO_MUX_GPIO0_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO0.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO0_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO0_SLP_SEL_M (IO_MUX_GPIO0_SLP_SEL_V << IO_MUX_GPIO0_SLP_SEL_S) -#define IO_MUX_GPIO0_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO0_SLP_SEL_S 1 -/** IO_MUX_GPIO0_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO0 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO0_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO0_MCU_WPD_M (IO_MUX_GPIO0_MCU_WPD_V << IO_MUX_GPIO0_MCU_WPD_S) -#define IO_MUX_GPIO0_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO0_MCU_WPD_S 2 -/** IO_MUX_GPIO0_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO0 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO0_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO0_MCU_WPU_M (IO_MUX_GPIO0_MCU_WPU_V << IO_MUX_GPIO0_MCU_WPU_S) -#define IO_MUX_GPIO0_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO0_MCU_WPU_S 3 -/** IO_MUX_GPIO0_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO0 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO0_MCU_IE (BIT(4)) -#define IO_MUX_GPIO0_MCU_IE_M (IO_MUX_GPIO0_MCU_IE_V << IO_MUX_GPIO0_MCU_IE_S) -#define IO_MUX_GPIO0_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO0_MCU_IE_S 4 -/** IO_MUX_GPIO0_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO0 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO0_MCU_DRV 0x00000003U -#define IO_MUX_GPIO0_MCU_DRV_M (IO_MUX_GPIO0_MCU_DRV_V << IO_MUX_GPIO0_MCU_DRV_S) -#define IO_MUX_GPIO0_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO0_MCU_DRV_S 5 -/** IO_MUX_GPIO0_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO0.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO0_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO0_FUN_WPD_M (IO_MUX_GPIO0_FUN_WPD_V << IO_MUX_GPIO0_FUN_WPD_S) -#define IO_MUX_GPIO0_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO0_FUN_WPD_S 7 -/** IO_MUX_GPIO0_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO0.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO0_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO0_FUN_WPU_M (IO_MUX_GPIO0_FUN_WPU_V << IO_MUX_GPIO0_FUN_WPU_S) -#define IO_MUX_GPIO0_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO0_FUN_WPU_S 8 -/** IO_MUX_GPIO0_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO0.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO0_FUN_IE (BIT(9)) -#define IO_MUX_GPIO0_FUN_IE_M (IO_MUX_GPIO0_FUN_IE_V << IO_MUX_GPIO0_FUN_IE_S) -#define IO_MUX_GPIO0_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO0_FUN_IE_S 9 -/** IO_MUX_GPIO0_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO0. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO0_FUN_DRV 0x00000003U -#define IO_MUX_GPIO0_FUN_DRV_M (IO_MUX_GPIO0_FUN_DRV_V << IO_MUX_GPIO0_FUN_DRV_S) -#define IO_MUX_GPIO0_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO0_FUN_DRV_S 10 -/** IO_MUX_GPIO0_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO0_MCU_SEL 0x00000007U -#define IO_MUX_GPIO0_MCU_SEL_M (IO_MUX_GPIO0_MCU_SEL_V << IO_MUX_GPIO0_MCU_SEL_S) -#define IO_MUX_GPIO0_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO0_MCU_SEL_S 12 -/** IO_MUX_GPIO0_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO0_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO0_FILTER_EN_M (IO_MUX_GPIO0_FILTER_EN_V << IO_MUX_GPIO0_FILTER_EN_S) -#define IO_MUX_GPIO0_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO0_FILTER_EN_S 15 -/** IO_MUX_GPIO0_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO0_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO0_HYS_EN (BIT(16)) -#define IO_MUX_GPIO0_HYS_EN_M (IO_MUX_GPIO0_HYS_EN_V << IO_MUX_GPIO0_HYS_EN_S) -#define IO_MUX_GPIO0_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO0_HYS_EN_S 16 -/** IO_MUX_GPIO0_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO0. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO0_HYS_EN\\ - */ -#define IO_MUX_GPIO0_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO0_HYS_SEL_M (IO_MUX_GPIO0_HYS_SEL_V << IO_MUX_GPIO0_HYS_SEL_S) -#define IO_MUX_GPIO0_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO0_HYS_SEL_S 17 - -/** IO_MUX_GPIO1_REG register - * IO MUX configuration register for GPIO1 - */ -#define IO_MUX_GPIO1_REG (DR_REG_IO_MUX_BASE + 0x4) -/** IO_MUX_GPIO1_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO1 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO1_MCU_OE (BIT(0)) -#define IO_MUX_GPIO1_MCU_OE_M (IO_MUX_GPIO1_MCU_OE_V << IO_MUX_GPIO1_MCU_OE_S) -#define IO_MUX_GPIO1_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO1_MCU_OE_S 0 -/** IO_MUX_GPIO1_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO1.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO1_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO1_SLP_SEL_M (IO_MUX_GPIO1_SLP_SEL_V << IO_MUX_GPIO1_SLP_SEL_S) -#define IO_MUX_GPIO1_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO1_SLP_SEL_S 1 -/** IO_MUX_GPIO1_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO1 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO1_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO1_MCU_WPD_M (IO_MUX_GPIO1_MCU_WPD_V << IO_MUX_GPIO1_MCU_WPD_S) -#define IO_MUX_GPIO1_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO1_MCU_WPD_S 2 -/** IO_MUX_GPIO1_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO1 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO1_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO1_MCU_WPU_M (IO_MUX_GPIO1_MCU_WPU_V << IO_MUX_GPIO1_MCU_WPU_S) -#define IO_MUX_GPIO1_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO1_MCU_WPU_S 3 -/** IO_MUX_GPIO1_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO1 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO1_MCU_IE (BIT(4)) -#define IO_MUX_GPIO1_MCU_IE_M (IO_MUX_GPIO1_MCU_IE_V << IO_MUX_GPIO1_MCU_IE_S) -#define IO_MUX_GPIO1_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO1_MCU_IE_S 4 -/** IO_MUX_GPIO1_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO1 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO1_MCU_DRV 0x00000003U -#define IO_MUX_GPIO1_MCU_DRV_M (IO_MUX_GPIO1_MCU_DRV_V << IO_MUX_GPIO1_MCU_DRV_S) -#define IO_MUX_GPIO1_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO1_MCU_DRV_S 5 -/** IO_MUX_GPIO1_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO1_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO1_FUN_WPD_M (IO_MUX_GPIO1_FUN_WPD_V << IO_MUX_GPIO1_FUN_WPD_S) -#define IO_MUX_GPIO1_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO1_FUN_WPD_S 7 -/** IO_MUX_GPIO1_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO1_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO1_FUN_WPU_M (IO_MUX_GPIO1_FUN_WPU_V << IO_MUX_GPIO1_FUN_WPU_S) -#define IO_MUX_GPIO1_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO1_FUN_WPU_S 8 -/** IO_MUX_GPIO1_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO1_FUN_IE (BIT(9)) -#define IO_MUX_GPIO1_FUN_IE_M (IO_MUX_GPIO1_FUN_IE_V << IO_MUX_GPIO1_FUN_IE_S) -#define IO_MUX_GPIO1_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO1_FUN_IE_S 9 -/** IO_MUX_GPIO1_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO1. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO1_FUN_DRV 0x00000003U -#define IO_MUX_GPIO1_FUN_DRV_M (IO_MUX_GPIO1_FUN_DRV_V << IO_MUX_GPIO1_FUN_DRV_S) -#define IO_MUX_GPIO1_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO1_FUN_DRV_S 10 -/** IO_MUX_GPIO1_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO1_MCU_SEL 0x00000007U -#define IO_MUX_GPIO1_MCU_SEL_M (IO_MUX_GPIO1_MCU_SEL_V << IO_MUX_GPIO1_MCU_SEL_S) -#define IO_MUX_GPIO1_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO1_MCU_SEL_S 12 -/** IO_MUX_GPIO1_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO1_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO1_FILTER_EN_M (IO_MUX_GPIO1_FILTER_EN_V << IO_MUX_GPIO1_FILTER_EN_S) -#define IO_MUX_GPIO1_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO1_FILTER_EN_S 15 -/** IO_MUX_GPIO1_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO1_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO1_HYS_EN (BIT(16)) -#define IO_MUX_GPIO1_HYS_EN_M (IO_MUX_GPIO1_HYS_EN_V << IO_MUX_GPIO1_HYS_EN_S) -#define IO_MUX_GPIO1_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO1_HYS_EN_S 16 -/** IO_MUX_GPIO1_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO1. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO1_HYS_EN\\ - */ -#define IO_MUX_GPIO1_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO1_HYS_SEL_M (IO_MUX_GPIO1_HYS_SEL_V << IO_MUX_GPIO1_HYS_SEL_S) -#define IO_MUX_GPIO1_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO1_HYS_SEL_S 17 - -/** IO_MUX_GPIO2_REG register - * IO MUX configuration register for GPIO2 - */ -#define IO_MUX_GPIO2_REG (DR_REG_IO_MUX_BASE + 0x8) -/** IO_MUX_GPIO2_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO2 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO2_MCU_OE (BIT(0)) -#define IO_MUX_GPIO2_MCU_OE_M (IO_MUX_GPIO2_MCU_OE_V << IO_MUX_GPIO2_MCU_OE_S) -#define IO_MUX_GPIO2_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO2_MCU_OE_S 0 -/** IO_MUX_GPIO2_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO2.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO2_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO2_SLP_SEL_M (IO_MUX_GPIO2_SLP_SEL_V << IO_MUX_GPIO2_SLP_SEL_S) -#define IO_MUX_GPIO2_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO2_SLP_SEL_S 1 -/** IO_MUX_GPIO2_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO2 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO2_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO2_MCU_WPD_M (IO_MUX_GPIO2_MCU_WPD_V << IO_MUX_GPIO2_MCU_WPD_S) -#define IO_MUX_GPIO2_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO2_MCU_WPD_S 2 -/** IO_MUX_GPIO2_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO2 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO2_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO2_MCU_WPU_M (IO_MUX_GPIO2_MCU_WPU_V << IO_MUX_GPIO2_MCU_WPU_S) -#define IO_MUX_GPIO2_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO2_MCU_WPU_S 3 -/** IO_MUX_GPIO2_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO2 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO2_MCU_IE (BIT(4)) -#define IO_MUX_GPIO2_MCU_IE_M (IO_MUX_GPIO2_MCU_IE_V << IO_MUX_GPIO2_MCU_IE_S) -#define IO_MUX_GPIO2_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO2_MCU_IE_S 4 -/** IO_MUX_GPIO2_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO2 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO2_MCU_DRV 0x00000003U -#define IO_MUX_GPIO2_MCU_DRV_M (IO_MUX_GPIO2_MCU_DRV_V << IO_MUX_GPIO2_MCU_DRV_S) -#define IO_MUX_GPIO2_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO2_MCU_DRV_S 5 -/** IO_MUX_GPIO2_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO2.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO2_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO2_FUN_WPD_M (IO_MUX_GPIO2_FUN_WPD_V << IO_MUX_GPIO2_FUN_WPD_S) -#define IO_MUX_GPIO2_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO2_FUN_WPD_S 7 -/** IO_MUX_GPIO2_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO2.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO2_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO2_FUN_WPU_M (IO_MUX_GPIO2_FUN_WPU_V << IO_MUX_GPIO2_FUN_WPU_S) -#define IO_MUX_GPIO2_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO2_FUN_WPU_S 8 -/** IO_MUX_GPIO2_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO2.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO2_FUN_IE (BIT(9)) -#define IO_MUX_GPIO2_FUN_IE_M (IO_MUX_GPIO2_FUN_IE_V << IO_MUX_GPIO2_FUN_IE_S) -#define IO_MUX_GPIO2_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO2_FUN_IE_S 9 -/** IO_MUX_GPIO2_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO2. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO2_FUN_DRV 0x00000003U -#define IO_MUX_GPIO2_FUN_DRV_M (IO_MUX_GPIO2_FUN_DRV_V << IO_MUX_GPIO2_FUN_DRV_S) -#define IO_MUX_GPIO2_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO2_FUN_DRV_S 10 -/** IO_MUX_GPIO2_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO2_MCU_SEL 0x00000007U -#define IO_MUX_GPIO2_MCU_SEL_M (IO_MUX_GPIO2_MCU_SEL_V << IO_MUX_GPIO2_MCU_SEL_S) -#define IO_MUX_GPIO2_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO2_MCU_SEL_S 12 -/** IO_MUX_GPIO2_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO2_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO2_FILTER_EN_M (IO_MUX_GPIO2_FILTER_EN_V << IO_MUX_GPIO2_FILTER_EN_S) -#define IO_MUX_GPIO2_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO2_FILTER_EN_S 15 -/** IO_MUX_GPIO2_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO2_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO2_HYS_EN (BIT(16)) -#define IO_MUX_GPIO2_HYS_EN_M (IO_MUX_GPIO2_HYS_EN_V << IO_MUX_GPIO2_HYS_EN_S) -#define IO_MUX_GPIO2_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO2_HYS_EN_S 16 -/** IO_MUX_GPIO2_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO2. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO2_HYS_EN\\ - */ -#define IO_MUX_GPIO2_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO2_HYS_SEL_M (IO_MUX_GPIO2_HYS_SEL_V << IO_MUX_GPIO2_HYS_SEL_S) -#define IO_MUX_GPIO2_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO2_HYS_SEL_S 17 - -/** IO_MUX_GPIO3_REG register - * IO MUX configuration register for GPIO3 - */ -#define IO_MUX_GPIO3_REG (DR_REG_IO_MUX_BASE + 0xc) -/** IO_MUX_GPIO3_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO3 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO3_MCU_OE (BIT(0)) -#define IO_MUX_GPIO3_MCU_OE_M (IO_MUX_GPIO3_MCU_OE_V << IO_MUX_GPIO3_MCU_OE_S) -#define IO_MUX_GPIO3_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO3_MCU_OE_S 0 -/** IO_MUX_GPIO3_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO3.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO3_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO3_SLP_SEL_M (IO_MUX_GPIO3_SLP_SEL_V << IO_MUX_GPIO3_SLP_SEL_S) -#define IO_MUX_GPIO3_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO3_SLP_SEL_S 1 -/** IO_MUX_GPIO3_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO3 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO3_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO3_MCU_WPD_M (IO_MUX_GPIO3_MCU_WPD_V << IO_MUX_GPIO3_MCU_WPD_S) -#define IO_MUX_GPIO3_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO3_MCU_WPD_S 2 -/** IO_MUX_GPIO3_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO3 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO3_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO3_MCU_WPU_M (IO_MUX_GPIO3_MCU_WPU_V << IO_MUX_GPIO3_MCU_WPU_S) -#define IO_MUX_GPIO3_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO3_MCU_WPU_S 3 -/** IO_MUX_GPIO3_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO3 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO3_MCU_IE (BIT(4)) -#define IO_MUX_GPIO3_MCU_IE_M (IO_MUX_GPIO3_MCU_IE_V << IO_MUX_GPIO3_MCU_IE_S) -#define IO_MUX_GPIO3_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO3_MCU_IE_S 4 -/** IO_MUX_GPIO3_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO3 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO3_MCU_DRV 0x00000003U -#define IO_MUX_GPIO3_MCU_DRV_M (IO_MUX_GPIO3_MCU_DRV_V << IO_MUX_GPIO3_MCU_DRV_S) -#define IO_MUX_GPIO3_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO3_MCU_DRV_S 5 -/** IO_MUX_GPIO3_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO3.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO3_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO3_FUN_WPD_M (IO_MUX_GPIO3_FUN_WPD_V << IO_MUX_GPIO3_FUN_WPD_S) -#define IO_MUX_GPIO3_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO3_FUN_WPD_S 7 -/** IO_MUX_GPIO3_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO3.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO3_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO3_FUN_WPU_M (IO_MUX_GPIO3_FUN_WPU_V << IO_MUX_GPIO3_FUN_WPU_S) -#define IO_MUX_GPIO3_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO3_FUN_WPU_S 8 -/** IO_MUX_GPIO3_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO3.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO3_FUN_IE (BIT(9)) -#define IO_MUX_GPIO3_FUN_IE_M (IO_MUX_GPIO3_FUN_IE_V << IO_MUX_GPIO3_FUN_IE_S) -#define IO_MUX_GPIO3_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO3_FUN_IE_S 9 -/** IO_MUX_GPIO3_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO3. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO3_FUN_DRV 0x00000003U -#define IO_MUX_GPIO3_FUN_DRV_M (IO_MUX_GPIO3_FUN_DRV_V << IO_MUX_GPIO3_FUN_DRV_S) -#define IO_MUX_GPIO3_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO3_FUN_DRV_S 10 -/** IO_MUX_GPIO3_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO3_MCU_SEL 0x00000007U -#define IO_MUX_GPIO3_MCU_SEL_M (IO_MUX_GPIO3_MCU_SEL_V << IO_MUX_GPIO3_MCU_SEL_S) -#define IO_MUX_GPIO3_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO3_MCU_SEL_S 12 -/** IO_MUX_GPIO3_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO3_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO3_FILTER_EN_M (IO_MUX_GPIO3_FILTER_EN_V << IO_MUX_GPIO3_FILTER_EN_S) -#define IO_MUX_GPIO3_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO3_FILTER_EN_S 15 -/** IO_MUX_GPIO3_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO3_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO3_HYS_EN (BIT(16)) -#define IO_MUX_GPIO3_HYS_EN_M (IO_MUX_GPIO3_HYS_EN_V << IO_MUX_GPIO3_HYS_EN_S) -#define IO_MUX_GPIO3_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO3_HYS_EN_S 16 -/** IO_MUX_GPIO3_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO3. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO3_HYS_EN\\ - */ -#define IO_MUX_GPIO3_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO3_HYS_SEL_M (IO_MUX_GPIO3_HYS_SEL_V << IO_MUX_GPIO3_HYS_SEL_S) -#define IO_MUX_GPIO3_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO3_HYS_SEL_S 17 - -/** IO_MUX_GPIO4_REG register - * IO MUX configuration register for GPIO4 - */ -#define IO_MUX_GPIO4_REG (DR_REG_IO_MUX_BASE + 0x10) -/** IO_MUX_GPIO4_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO4 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO4_MCU_OE (BIT(0)) -#define IO_MUX_GPIO4_MCU_OE_M (IO_MUX_GPIO4_MCU_OE_V << IO_MUX_GPIO4_MCU_OE_S) -#define IO_MUX_GPIO4_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO4_MCU_OE_S 0 -/** IO_MUX_GPIO4_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO4.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO4_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO4_SLP_SEL_M (IO_MUX_GPIO4_SLP_SEL_V << IO_MUX_GPIO4_SLP_SEL_S) -#define IO_MUX_GPIO4_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO4_SLP_SEL_S 1 -/** IO_MUX_GPIO4_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO4 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO4_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO4_MCU_WPD_M (IO_MUX_GPIO4_MCU_WPD_V << IO_MUX_GPIO4_MCU_WPD_S) -#define IO_MUX_GPIO4_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO4_MCU_WPD_S 2 -/** IO_MUX_GPIO4_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO4 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO4_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO4_MCU_WPU_M (IO_MUX_GPIO4_MCU_WPU_V << IO_MUX_GPIO4_MCU_WPU_S) -#define IO_MUX_GPIO4_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO4_MCU_WPU_S 3 -/** IO_MUX_GPIO4_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO4 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO4_MCU_IE (BIT(4)) -#define IO_MUX_GPIO4_MCU_IE_M (IO_MUX_GPIO4_MCU_IE_V << IO_MUX_GPIO4_MCU_IE_S) -#define IO_MUX_GPIO4_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO4_MCU_IE_S 4 -/** IO_MUX_GPIO4_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO4 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO4_MCU_DRV 0x00000003U -#define IO_MUX_GPIO4_MCU_DRV_M (IO_MUX_GPIO4_MCU_DRV_V << IO_MUX_GPIO4_MCU_DRV_S) -#define IO_MUX_GPIO4_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO4_MCU_DRV_S 5 -/** IO_MUX_GPIO4_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO4.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO4_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO4_FUN_WPD_M (IO_MUX_GPIO4_FUN_WPD_V << IO_MUX_GPIO4_FUN_WPD_S) -#define IO_MUX_GPIO4_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO4_FUN_WPD_S 7 -/** IO_MUX_GPIO4_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO4.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO4_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO4_FUN_WPU_M (IO_MUX_GPIO4_FUN_WPU_V << IO_MUX_GPIO4_FUN_WPU_S) -#define IO_MUX_GPIO4_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO4_FUN_WPU_S 8 -/** IO_MUX_GPIO4_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO4.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO4_FUN_IE (BIT(9)) -#define IO_MUX_GPIO4_FUN_IE_M (IO_MUX_GPIO4_FUN_IE_V << IO_MUX_GPIO4_FUN_IE_S) -#define IO_MUX_GPIO4_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO4_FUN_IE_S 9 -/** IO_MUX_GPIO4_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO4. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO4_FUN_DRV 0x00000003U -#define IO_MUX_GPIO4_FUN_DRV_M (IO_MUX_GPIO4_FUN_DRV_V << IO_MUX_GPIO4_FUN_DRV_S) -#define IO_MUX_GPIO4_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO4_FUN_DRV_S 10 -/** IO_MUX_GPIO4_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO4_MCU_SEL 0x00000007U -#define IO_MUX_GPIO4_MCU_SEL_M (IO_MUX_GPIO4_MCU_SEL_V << IO_MUX_GPIO4_MCU_SEL_S) -#define IO_MUX_GPIO4_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO4_MCU_SEL_S 12 -/** IO_MUX_GPIO4_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO4_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO4_FILTER_EN_M (IO_MUX_GPIO4_FILTER_EN_V << IO_MUX_GPIO4_FILTER_EN_S) -#define IO_MUX_GPIO4_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO4_FILTER_EN_S 15 -/** IO_MUX_GPIO4_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO4_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO4_HYS_EN (BIT(16)) -#define IO_MUX_GPIO4_HYS_EN_M (IO_MUX_GPIO4_HYS_EN_V << IO_MUX_GPIO4_HYS_EN_S) -#define IO_MUX_GPIO4_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO4_HYS_EN_S 16 -/** IO_MUX_GPIO4_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO4. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO4_HYS_EN\\ - */ -#define IO_MUX_GPIO4_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO4_HYS_SEL_M (IO_MUX_GPIO4_HYS_SEL_V << IO_MUX_GPIO4_HYS_SEL_S) -#define IO_MUX_GPIO4_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO4_HYS_SEL_S 17 - -/** IO_MUX_GPIO5_REG register - * IO MUX configuration register for GPIO5 - */ -#define IO_MUX_GPIO5_REG (DR_REG_IO_MUX_BASE + 0x14) -/** IO_MUX_GPIO5_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO5 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO5_MCU_OE (BIT(0)) -#define IO_MUX_GPIO5_MCU_OE_M (IO_MUX_GPIO5_MCU_OE_V << IO_MUX_GPIO5_MCU_OE_S) -#define IO_MUX_GPIO5_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO5_MCU_OE_S 0 -/** IO_MUX_GPIO5_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO5.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO5_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO5_SLP_SEL_M (IO_MUX_GPIO5_SLP_SEL_V << IO_MUX_GPIO5_SLP_SEL_S) -#define IO_MUX_GPIO5_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO5_SLP_SEL_S 1 -/** IO_MUX_GPIO5_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO5 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO5_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO5_MCU_WPD_M (IO_MUX_GPIO5_MCU_WPD_V << IO_MUX_GPIO5_MCU_WPD_S) -#define IO_MUX_GPIO5_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO5_MCU_WPD_S 2 -/** IO_MUX_GPIO5_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO5 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO5_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO5_MCU_WPU_M (IO_MUX_GPIO5_MCU_WPU_V << IO_MUX_GPIO5_MCU_WPU_S) -#define IO_MUX_GPIO5_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO5_MCU_WPU_S 3 -/** IO_MUX_GPIO5_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO5 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO5_MCU_IE (BIT(4)) -#define IO_MUX_GPIO5_MCU_IE_M (IO_MUX_GPIO5_MCU_IE_V << IO_MUX_GPIO5_MCU_IE_S) -#define IO_MUX_GPIO5_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO5_MCU_IE_S 4 -/** IO_MUX_GPIO5_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO5 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO5_MCU_DRV 0x00000003U -#define IO_MUX_GPIO5_MCU_DRV_M (IO_MUX_GPIO5_MCU_DRV_V << IO_MUX_GPIO5_MCU_DRV_S) -#define IO_MUX_GPIO5_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO5_MCU_DRV_S 5 -/** IO_MUX_GPIO5_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO5.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO5_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO5_FUN_WPD_M (IO_MUX_GPIO5_FUN_WPD_V << IO_MUX_GPIO5_FUN_WPD_S) -#define IO_MUX_GPIO5_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO5_FUN_WPD_S 7 -/** IO_MUX_GPIO5_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO5.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO5_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO5_FUN_WPU_M (IO_MUX_GPIO5_FUN_WPU_V << IO_MUX_GPIO5_FUN_WPU_S) -#define IO_MUX_GPIO5_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO5_FUN_WPU_S 8 -/** IO_MUX_GPIO5_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO5.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO5_FUN_IE (BIT(9)) -#define IO_MUX_GPIO5_FUN_IE_M (IO_MUX_GPIO5_FUN_IE_V << IO_MUX_GPIO5_FUN_IE_S) -#define IO_MUX_GPIO5_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO5_FUN_IE_S 9 -/** IO_MUX_GPIO5_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO5. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO5_FUN_DRV 0x00000003U -#define IO_MUX_GPIO5_FUN_DRV_M (IO_MUX_GPIO5_FUN_DRV_V << IO_MUX_GPIO5_FUN_DRV_S) -#define IO_MUX_GPIO5_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO5_FUN_DRV_S 10 -/** IO_MUX_GPIO5_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO5_MCU_SEL 0x00000007U -#define IO_MUX_GPIO5_MCU_SEL_M (IO_MUX_GPIO5_MCU_SEL_V << IO_MUX_GPIO5_MCU_SEL_S) -#define IO_MUX_GPIO5_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO5_MCU_SEL_S 12 -/** IO_MUX_GPIO5_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO5_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO5_FILTER_EN_M (IO_MUX_GPIO5_FILTER_EN_V << IO_MUX_GPIO5_FILTER_EN_S) -#define IO_MUX_GPIO5_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO5_FILTER_EN_S 15 -/** IO_MUX_GPIO5_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO5_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO5_HYS_EN (BIT(16)) -#define IO_MUX_GPIO5_HYS_EN_M (IO_MUX_GPIO5_HYS_EN_V << IO_MUX_GPIO5_HYS_EN_S) -#define IO_MUX_GPIO5_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO5_HYS_EN_S 16 -/** IO_MUX_GPIO5_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO5. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO5_HYS_EN\\ - */ -#define IO_MUX_GPIO5_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO5_HYS_SEL_M (IO_MUX_GPIO5_HYS_SEL_V << IO_MUX_GPIO5_HYS_SEL_S) -#define IO_MUX_GPIO5_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO5_HYS_SEL_S 17 - -/** IO_MUX_GPIO6_REG register - * IO MUX configuration register for GPIO6 - */ -#define IO_MUX_GPIO6_REG (DR_REG_IO_MUX_BASE + 0x18) -/** IO_MUX_GPIO6_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO6 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO6_MCU_OE (BIT(0)) -#define IO_MUX_GPIO6_MCU_OE_M (IO_MUX_GPIO6_MCU_OE_V << IO_MUX_GPIO6_MCU_OE_S) -#define IO_MUX_GPIO6_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO6_MCU_OE_S 0 -/** IO_MUX_GPIO6_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO6.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO6_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO6_SLP_SEL_M (IO_MUX_GPIO6_SLP_SEL_V << IO_MUX_GPIO6_SLP_SEL_S) -#define IO_MUX_GPIO6_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO6_SLP_SEL_S 1 -/** IO_MUX_GPIO6_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO6 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO6_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO6_MCU_WPD_M (IO_MUX_GPIO6_MCU_WPD_V << IO_MUX_GPIO6_MCU_WPD_S) -#define IO_MUX_GPIO6_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO6_MCU_WPD_S 2 -/** IO_MUX_GPIO6_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO6 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO6_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO6_MCU_WPU_M (IO_MUX_GPIO6_MCU_WPU_V << IO_MUX_GPIO6_MCU_WPU_S) -#define IO_MUX_GPIO6_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO6_MCU_WPU_S 3 -/** IO_MUX_GPIO6_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO6 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO6_MCU_IE (BIT(4)) -#define IO_MUX_GPIO6_MCU_IE_M (IO_MUX_GPIO6_MCU_IE_V << IO_MUX_GPIO6_MCU_IE_S) -#define IO_MUX_GPIO6_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO6_MCU_IE_S 4 -/** IO_MUX_GPIO6_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO6 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO6_MCU_DRV 0x00000003U -#define IO_MUX_GPIO6_MCU_DRV_M (IO_MUX_GPIO6_MCU_DRV_V << IO_MUX_GPIO6_MCU_DRV_S) -#define IO_MUX_GPIO6_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO6_MCU_DRV_S 5 -/** IO_MUX_GPIO6_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO6.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO6_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO6_FUN_WPD_M (IO_MUX_GPIO6_FUN_WPD_V << IO_MUX_GPIO6_FUN_WPD_S) -#define IO_MUX_GPIO6_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO6_FUN_WPD_S 7 -/** IO_MUX_GPIO6_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO6.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO6_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO6_FUN_WPU_M (IO_MUX_GPIO6_FUN_WPU_V << IO_MUX_GPIO6_FUN_WPU_S) -#define IO_MUX_GPIO6_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO6_FUN_WPU_S 8 -/** IO_MUX_GPIO6_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO6.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO6_FUN_IE (BIT(9)) -#define IO_MUX_GPIO6_FUN_IE_M (IO_MUX_GPIO6_FUN_IE_V << IO_MUX_GPIO6_FUN_IE_S) -#define IO_MUX_GPIO6_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO6_FUN_IE_S 9 -/** IO_MUX_GPIO6_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO6. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO6_FUN_DRV 0x00000003U -#define IO_MUX_GPIO6_FUN_DRV_M (IO_MUX_GPIO6_FUN_DRV_V << IO_MUX_GPIO6_FUN_DRV_S) -#define IO_MUX_GPIO6_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO6_FUN_DRV_S 10 -/** IO_MUX_GPIO6_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO6_MCU_SEL 0x00000007U -#define IO_MUX_GPIO6_MCU_SEL_M (IO_MUX_GPIO6_MCU_SEL_V << IO_MUX_GPIO6_MCU_SEL_S) -#define IO_MUX_GPIO6_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO6_MCU_SEL_S 12 -/** IO_MUX_GPIO6_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO6_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO6_FILTER_EN_M (IO_MUX_GPIO6_FILTER_EN_V << IO_MUX_GPIO6_FILTER_EN_S) -#define IO_MUX_GPIO6_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO6_FILTER_EN_S 15 -/** IO_MUX_GPIO6_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO6_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO6_HYS_EN (BIT(16)) -#define IO_MUX_GPIO6_HYS_EN_M (IO_MUX_GPIO6_HYS_EN_V << IO_MUX_GPIO6_HYS_EN_S) -#define IO_MUX_GPIO6_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO6_HYS_EN_S 16 -/** IO_MUX_GPIO6_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO6. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO6_HYS_EN\\ - */ -#define IO_MUX_GPIO6_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO6_HYS_SEL_M (IO_MUX_GPIO6_HYS_SEL_V << IO_MUX_GPIO6_HYS_SEL_S) -#define IO_MUX_GPIO6_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO6_HYS_SEL_S 17 - -/** IO_MUX_GPIO7_REG register - * IO MUX configuration register for GPIO7 - */ -#define IO_MUX_GPIO7_REG (DR_REG_IO_MUX_BASE + 0x1c) -/** IO_MUX_GPIO7_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO7 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO7_MCU_OE (BIT(0)) -#define IO_MUX_GPIO7_MCU_OE_M (IO_MUX_GPIO7_MCU_OE_V << IO_MUX_GPIO7_MCU_OE_S) -#define IO_MUX_GPIO7_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO7_MCU_OE_S 0 -/** IO_MUX_GPIO7_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO7.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO7_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO7_SLP_SEL_M (IO_MUX_GPIO7_SLP_SEL_V << IO_MUX_GPIO7_SLP_SEL_S) -#define IO_MUX_GPIO7_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO7_SLP_SEL_S 1 -/** IO_MUX_GPIO7_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO7 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO7_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO7_MCU_WPD_M (IO_MUX_GPIO7_MCU_WPD_V << IO_MUX_GPIO7_MCU_WPD_S) -#define IO_MUX_GPIO7_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO7_MCU_WPD_S 2 -/** IO_MUX_GPIO7_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO7 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO7_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO7_MCU_WPU_M (IO_MUX_GPIO7_MCU_WPU_V << IO_MUX_GPIO7_MCU_WPU_S) -#define IO_MUX_GPIO7_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO7_MCU_WPU_S 3 -/** IO_MUX_GPIO7_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO7 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO7_MCU_IE (BIT(4)) -#define IO_MUX_GPIO7_MCU_IE_M (IO_MUX_GPIO7_MCU_IE_V << IO_MUX_GPIO7_MCU_IE_S) -#define IO_MUX_GPIO7_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO7_MCU_IE_S 4 -/** IO_MUX_GPIO7_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO7 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO7_MCU_DRV 0x00000003U -#define IO_MUX_GPIO7_MCU_DRV_M (IO_MUX_GPIO7_MCU_DRV_V << IO_MUX_GPIO7_MCU_DRV_S) -#define IO_MUX_GPIO7_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO7_MCU_DRV_S 5 -/** IO_MUX_GPIO7_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO7.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO7_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO7_FUN_WPD_M (IO_MUX_GPIO7_FUN_WPD_V << IO_MUX_GPIO7_FUN_WPD_S) -#define IO_MUX_GPIO7_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO7_FUN_WPD_S 7 -/** IO_MUX_GPIO7_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO7.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO7_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO7_FUN_WPU_M (IO_MUX_GPIO7_FUN_WPU_V << IO_MUX_GPIO7_FUN_WPU_S) -#define IO_MUX_GPIO7_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO7_FUN_WPU_S 8 -/** IO_MUX_GPIO7_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO7.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO7_FUN_IE (BIT(9)) -#define IO_MUX_GPIO7_FUN_IE_M (IO_MUX_GPIO7_FUN_IE_V << IO_MUX_GPIO7_FUN_IE_S) -#define IO_MUX_GPIO7_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO7_FUN_IE_S 9 -/** IO_MUX_GPIO7_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO7. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO7_FUN_DRV 0x00000003U -#define IO_MUX_GPIO7_FUN_DRV_M (IO_MUX_GPIO7_FUN_DRV_V << IO_MUX_GPIO7_FUN_DRV_S) -#define IO_MUX_GPIO7_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO7_FUN_DRV_S 10 -/** IO_MUX_GPIO7_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO7_MCU_SEL 0x00000007U -#define IO_MUX_GPIO7_MCU_SEL_M (IO_MUX_GPIO7_MCU_SEL_V << IO_MUX_GPIO7_MCU_SEL_S) -#define IO_MUX_GPIO7_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO7_MCU_SEL_S 12 -/** IO_MUX_GPIO7_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO7_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO7_FILTER_EN_M (IO_MUX_GPIO7_FILTER_EN_V << IO_MUX_GPIO7_FILTER_EN_S) -#define IO_MUX_GPIO7_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO7_FILTER_EN_S 15 -/** IO_MUX_GPIO7_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO7_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO7_HYS_EN (BIT(16)) -#define IO_MUX_GPIO7_HYS_EN_M (IO_MUX_GPIO7_HYS_EN_V << IO_MUX_GPIO7_HYS_EN_S) -#define IO_MUX_GPIO7_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO7_HYS_EN_S 16 -/** IO_MUX_GPIO7_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO7. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO7_HYS_EN\\ - */ -#define IO_MUX_GPIO7_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO7_HYS_SEL_M (IO_MUX_GPIO7_HYS_SEL_V << IO_MUX_GPIO7_HYS_SEL_S) -#define IO_MUX_GPIO7_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO7_HYS_SEL_S 17 - -/** IO_MUX_GPIO8_REG register - * IO MUX configuration register for GPIO8 - */ -#define IO_MUX_GPIO8_REG (DR_REG_IO_MUX_BASE + 0x20) -/** IO_MUX_GPIO8_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO8 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO8_MCU_OE (BIT(0)) -#define IO_MUX_GPIO8_MCU_OE_M (IO_MUX_GPIO8_MCU_OE_V << IO_MUX_GPIO8_MCU_OE_S) -#define IO_MUX_GPIO8_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO8_MCU_OE_S 0 -/** IO_MUX_GPIO8_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO8.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO8_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO8_SLP_SEL_M (IO_MUX_GPIO8_SLP_SEL_V << IO_MUX_GPIO8_SLP_SEL_S) -#define IO_MUX_GPIO8_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO8_SLP_SEL_S 1 -/** IO_MUX_GPIO8_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO8 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO8_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO8_MCU_WPD_M (IO_MUX_GPIO8_MCU_WPD_V << IO_MUX_GPIO8_MCU_WPD_S) -#define IO_MUX_GPIO8_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO8_MCU_WPD_S 2 -/** IO_MUX_GPIO8_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO8 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO8_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO8_MCU_WPU_M (IO_MUX_GPIO8_MCU_WPU_V << IO_MUX_GPIO8_MCU_WPU_S) -#define IO_MUX_GPIO8_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO8_MCU_WPU_S 3 -/** IO_MUX_GPIO8_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO8 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO8_MCU_IE (BIT(4)) -#define IO_MUX_GPIO8_MCU_IE_M (IO_MUX_GPIO8_MCU_IE_V << IO_MUX_GPIO8_MCU_IE_S) -#define IO_MUX_GPIO8_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO8_MCU_IE_S 4 -/** IO_MUX_GPIO8_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO8 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO8_MCU_DRV 0x00000003U -#define IO_MUX_GPIO8_MCU_DRV_M (IO_MUX_GPIO8_MCU_DRV_V << IO_MUX_GPIO8_MCU_DRV_S) -#define IO_MUX_GPIO8_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO8_MCU_DRV_S 5 -/** IO_MUX_GPIO8_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO8.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO8_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO8_FUN_WPD_M (IO_MUX_GPIO8_FUN_WPD_V << IO_MUX_GPIO8_FUN_WPD_S) -#define IO_MUX_GPIO8_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO8_FUN_WPD_S 7 -/** IO_MUX_GPIO8_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO8.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO8_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO8_FUN_WPU_M (IO_MUX_GPIO8_FUN_WPU_V << IO_MUX_GPIO8_FUN_WPU_S) -#define IO_MUX_GPIO8_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO8_FUN_WPU_S 8 -/** IO_MUX_GPIO8_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO8.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO8_FUN_IE (BIT(9)) -#define IO_MUX_GPIO8_FUN_IE_M (IO_MUX_GPIO8_FUN_IE_V << IO_MUX_GPIO8_FUN_IE_S) -#define IO_MUX_GPIO8_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO8_FUN_IE_S 9 -/** IO_MUX_GPIO8_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO8. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO8_FUN_DRV 0x00000003U -#define IO_MUX_GPIO8_FUN_DRV_M (IO_MUX_GPIO8_FUN_DRV_V << IO_MUX_GPIO8_FUN_DRV_S) -#define IO_MUX_GPIO8_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO8_FUN_DRV_S 10 -/** IO_MUX_GPIO8_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO8_MCU_SEL 0x00000007U -#define IO_MUX_GPIO8_MCU_SEL_M (IO_MUX_GPIO8_MCU_SEL_V << IO_MUX_GPIO8_MCU_SEL_S) -#define IO_MUX_GPIO8_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO8_MCU_SEL_S 12 -/** IO_MUX_GPIO8_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO8_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO8_FILTER_EN_M (IO_MUX_GPIO8_FILTER_EN_V << IO_MUX_GPIO8_FILTER_EN_S) -#define IO_MUX_GPIO8_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO8_FILTER_EN_S 15 -/** IO_MUX_GPIO8_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO8_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO8_HYS_EN (BIT(16)) -#define IO_MUX_GPIO8_HYS_EN_M (IO_MUX_GPIO8_HYS_EN_V << IO_MUX_GPIO8_HYS_EN_S) -#define IO_MUX_GPIO8_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO8_HYS_EN_S 16 -/** IO_MUX_GPIO8_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO8. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO8_HYS_EN\\ - */ -#define IO_MUX_GPIO8_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO8_HYS_SEL_M (IO_MUX_GPIO8_HYS_SEL_V << IO_MUX_GPIO8_HYS_SEL_S) -#define IO_MUX_GPIO8_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO8_HYS_SEL_S 17 - -/** IO_MUX_GPIO9_REG register - * IO MUX configuration register for GPIO9 - */ -#define IO_MUX_GPIO9_REG (DR_REG_IO_MUX_BASE + 0x24) -/** IO_MUX_GPIO9_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO9 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO9_MCU_OE (BIT(0)) -#define IO_MUX_GPIO9_MCU_OE_M (IO_MUX_GPIO9_MCU_OE_V << IO_MUX_GPIO9_MCU_OE_S) -#define IO_MUX_GPIO9_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO9_MCU_OE_S 0 -/** IO_MUX_GPIO9_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO9.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO9_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO9_SLP_SEL_M (IO_MUX_GPIO9_SLP_SEL_V << IO_MUX_GPIO9_SLP_SEL_S) -#define IO_MUX_GPIO9_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO9_SLP_SEL_S 1 -/** IO_MUX_GPIO9_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO9 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO9_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO9_MCU_WPD_M (IO_MUX_GPIO9_MCU_WPD_V << IO_MUX_GPIO9_MCU_WPD_S) -#define IO_MUX_GPIO9_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO9_MCU_WPD_S 2 -/** IO_MUX_GPIO9_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO9 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO9_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO9_MCU_WPU_M (IO_MUX_GPIO9_MCU_WPU_V << IO_MUX_GPIO9_MCU_WPU_S) -#define IO_MUX_GPIO9_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO9_MCU_WPU_S 3 -/** IO_MUX_GPIO9_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO9 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO9_MCU_IE (BIT(4)) -#define IO_MUX_GPIO9_MCU_IE_M (IO_MUX_GPIO9_MCU_IE_V << IO_MUX_GPIO9_MCU_IE_S) -#define IO_MUX_GPIO9_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO9_MCU_IE_S 4 -/** IO_MUX_GPIO9_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO9 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO9_MCU_DRV 0x00000003U -#define IO_MUX_GPIO9_MCU_DRV_M (IO_MUX_GPIO9_MCU_DRV_V << IO_MUX_GPIO9_MCU_DRV_S) -#define IO_MUX_GPIO9_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO9_MCU_DRV_S 5 -/** IO_MUX_GPIO9_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO9.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO9_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO9_FUN_WPD_M (IO_MUX_GPIO9_FUN_WPD_V << IO_MUX_GPIO9_FUN_WPD_S) -#define IO_MUX_GPIO9_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO9_FUN_WPD_S 7 -/** IO_MUX_GPIO9_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO9.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO9_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO9_FUN_WPU_M (IO_MUX_GPIO9_FUN_WPU_V << IO_MUX_GPIO9_FUN_WPU_S) -#define IO_MUX_GPIO9_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO9_FUN_WPU_S 8 -/** IO_MUX_GPIO9_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO9.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO9_FUN_IE (BIT(9)) -#define IO_MUX_GPIO9_FUN_IE_M (IO_MUX_GPIO9_FUN_IE_V << IO_MUX_GPIO9_FUN_IE_S) -#define IO_MUX_GPIO9_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO9_FUN_IE_S 9 -/** IO_MUX_GPIO9_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO9. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO9_FUN_DRV 0x00000003U -#define IO_MUX_GPIO9_FUN_DRV_M (IO_MUX_GPIO9_FUN_DRV_V << IO_MUX_GPIO9_FUN_DRV_S) -#define IO_MUX_GPIO9_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO9_FUN_DRV_S 10 -/** IO_MUX_GPIO9_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO9_MCU_SEL 0x00000007U -#define IO_MUX_GPIO9_MCU_SEL_M (IO_MUX_GPIO9_MCU_SEL_V << IO_MUX_GPIO9_MCU_SEL_S) -#define IO_MUX_GPIO9_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO9_MCU_SEL_S 12 -/** IO_MUX_GPIO9_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO9_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO9_FILTER_EN_M (IO_MUX_GPIO9_FILTER_EN_V << IO_MUX_GPIO9_FILTER_EN_S) -#define IO_MUX_GPIO9_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO9_FILTER_EN_S 15 -/** IO_MUX_GPIO9_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO9_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO9_HYS_EN (BIT(16)) -#define IO_MUX_GPIO9_HYS_EN_M (IO_MUX_GPIO9_HYS_EN_V << IO_MUX_GPIO9_HYS_EN_S) -#define IO_MUX_GPIO9_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO9_HYS_EN_S 16 -/** IO_MUX_GPIO9_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO9. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO9_HYS_EN\\ - */ -#define IO_MUX_GPIO9_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO9_HYS_SEL_M (IO_MUX_GPIO9_HYS_SEL_V << IO_MUX_GPIO9_HYS_SEL_S) -#define IO_MUX_GPIO9_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO9_HYS_SEL_S 17 - -/** IO_MUX_GPIO10_REG register - * IO MUX configuration register for GPIO10 - */ -#define IO_MUX_GPIO10_REG (DR_REG_IO_MUX_BASE + 0x28) -/** IO_MUX_GPIO10_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO10 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO10_MCU_OE (BIT(0)) -#define IO_MUX_GPIO10_MCU_OE_M (IO_MUX_GPIO10_MCU_OE_V << IO_MUX_GPIO10_MCU_OE_S) -#define IO_MUX_GPIO10_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO10_MCU_OE_S 0 -/** IO_MUX_GPIO10_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO10.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO10_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO10_SLP_SEL_M (IO_MUX_GPIO10_SLP_SEL_V << IO_MUX_GPIO10_SLP_SEL_S) -#define IO_MUX_GPIO10_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO10_SLP_SEL_S 1 -/** IO_MUX_GPIO10_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO10 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO10_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO10_MCU_WPD_M (IO_MUX_GPIO10_MCU_WPD_V << IO_MUX_GPIO10_MCU_WPD_S) -#define IO_MUX_GPIO10_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO10_MCU_WPD_S 2 -/** IO_MUX_GPIO10_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO10 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO10_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO10_MCU_WPU_M (IO_MUX_GPIO10_MCU_WPU_V << IO_MUX_GPIO10_MCU_WPU_S) -#define IO_MUX_GPIO10_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO10_MCU_WPU_S 3 -/** IO_MUX_GPIO10_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO10 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO10_MCU_IE (BIT(4)) -#define IO_MUX_GPIO10_MCU_IE_M (IO_MUX_GPIO10_MCU_IE_V << IO_MUX_GPIO10_MCU_IE_S) -#define IO_MUX_GPIO10_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO10_MCU_IE_S 4 -/** IO_MUX_GPIO10_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO10 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO10_MCU_DRV 0x00000003U -#define IO_MUX_GPIO10_MCU_DRV_M (IO_MUX_GPIO10_MCU_DRV_V << IO_MUX_GPIO10_MCU_DRV_S) -#define IO_MUX_GPIO10_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO10_MCU_DRV_S 5 -/** IO_MUX_GPIO10_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO10.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO10_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO10_FUN_WPD_M (IO_MUX_GPIO10_FUN_WPD_V << IO_MUX_GPIO10_FUN_WPD_S) -#define IO_MUX_GPIO10_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO10_FUN_WPD_S 7 -/** IO_MUX_GPIO10_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO10.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO10_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO10_FUN_WPU_M (IO_MUX_GPIO10_FUN_WPU_V << IO_MUX_GPIO10_FUN_WPU_S) -#define IO_MUX_GPIO10_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO10_FUN_WPU_S 8 -/** IO_MUX_GPIO10_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO10.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO10_FUN_IE (BIT(9)) -#define IO_MUX_GPIO10_FUN_IE_M (IO_MUX_GPIO10_FUN_IE_V << IO_MUX_GPIO10_FUN_IE_S) -#define IO_MUX_GPIO10_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO10_FUN_IE_S 9 -/** IO_MUX_GPIO10_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO10. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO10_FUN_DRV 0x00000003U -#define IO_MUX_GPIO10_FUN_DRV_M (IO_MUX_GPIO10_FUN_DRV_V << IO_MUX_GPIO10_FUN_DRV_S) -#define IO_MUX_GPIO10_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO10_FUN_DRV_S 10 -/** IO_MUX_GPIO10_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO10_MCU_SEL 0x00000007U -#define IO_MUX_GPIO10_MCU_SEL_M (IO_MUX_GPIO10_MCU_SEL_V << IO_MUX_GPIO10_MCU_SEL_S) -#define IO_MUX_GPIO10_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO10_MCU_SEL_S 12 -/** IO_MUX_GPIO10_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO10_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO10_FILTER_EN_M (IO_MUX_GPIO10_FILTER_EN_V << IO_MUX_GPIO10_FILTER_EN_S) -#define IO_MUX_GPIO10_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO10_FILTER_EN_S 15 -/** IO_MUX_GPIO10_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO10_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO10_HYS_EN (BIT(16)) -#define IO_MUX_GPIO10_HYS_EN_M (IO_MUX_GPIO10_HYS_EN_V << IO_MUX_GPIO10_HYS_EN_S) -#define IO_MUX_GPIO10_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO10_HYS_EN_S 16 -/** IO_MUX_GPIO10_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO10. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO10_HYS_EN\\ - */ -#define IO_MUX_GPIO10_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO10_HYS_SEL_M (IO_MUX_GPIO10_HYS_SEL_V << IO_MUX_GPIO10_HYS_SEL_S) -#define IO_MUX_GPIO10_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO10_HYS_SEL_S 17 - -/** IO_MUX_GPIO11_REG register - * IO MUX configuration register for GPIO11 - */ -#define IO_MUX_GPIO11_REG (DR_REG_IO_MUX_BASE + 0x2c) -/** IO_MUX_GPIO11_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO11 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO11_MCU_OE (BIT(0)) -#define IO_MUX_GPIO11_MCU_OE_M (IO_MUX_GPIO11_MCU_OE_V << IO_MUX_GPIO11_MCU_OE_S) -#define IO_MUX_GPIO11_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO11_MCU_OE_S 0 -/** IO_MUX_GPIO11_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO11.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO11_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO11_SLP_SEL_M (IO_MUX_GPIO11_SLP_SEL_V << IO_MUX_GPIO11_SLP_SEL_S) -#define IO_MUX_GPIO11_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO11_SLP_SEL_S 1 -/** IO_MUX_GPIO11_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO11 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO11_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO11_MCU_WPD_M (IO_MUX_GPIO11_MCU_WPD_V << IO_MUX_GPIO11_MCU_WPD_S) -#define IO_MUX_GPIO11_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO11_MCU_WPD_S 2 -/** IO_MUX_GPIO11_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO11 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO11_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO11_MCU_WPU_M (IO_MUX_GPIO11_MCU_WPU_V << IO_MUX_GPIO11_MCU_WPU_S) -#define IO_MUX_GPIO11_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO11_MCU_WPU_S 3 -/** IO_MUX_GPIO11_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO11 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO11_MCU_IE (BIT(4)) -#define IO_MUX_GPIO11_MCU_IE_M (IO_MUX_GPIO11_MCU_IE_V << IO_MUX_GPIO11_MCU_IE_S) -#define IO_MUX_GPIO11_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO11_MCU_IE_S 4 -/** IO_MUX_GPIO11_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO11 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO11_MCU_DRV 0x00000003U -#define IO_MUX_GPIO11_MCU_DRV_M (IO_MUX_GPIO11_MCU_DRV_V << IO_MUX_GPIO11_MCU_DRV_S) -#define IO_MUX_GPIO11_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO11_MCU_DRV_S 5 -/** IO_MUX_GPIO11_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO11.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO11_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO11_FUN_WPD_M (IO_MUX_GPIO11_FUN_WPD_V << IO_MUX_GPIO11_FUN_WPD_S) -#define IO_MUX_GPIO11_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO11_FUN_WPD_S 7 -/** IO_MUX_GPIO11_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO11.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO11_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO11_FUN_WPU_M (IO_MUX_GPIO11_FUN_WPU_V << IO_MUX_GPIO11_FUN_WPU_S) -#define IO_MUX_GPIO11_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO11_FUN_WPU_S 8 -/** IO_MUX_GPIO11_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO11.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO11_FUN_IE (BIT(9)) -#define IO_MUX_GPIO11_FUN_IE_M (IO_MUX_GPIO11_FUN_IE_V << IO_MUX_GPIO11_FUN_IE_S) -#define IO_MUX_GPIO11_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO11_FUN_IE_S 9 -/** IO_MUX_GPIO11_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO11. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO11_FUN_DRV 0x00000003U -#define IO_MUX_GPIO11_FUN_DRV_M (IO_MUX_GPIO11_FUN_DRV_V << IO_MUX_GPIO11_FUN_DRV_S) -#define IO_MUX_GPIO11_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO11_FUN_DRV_S 10 -/** IO_MUX_GPIO11_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO11_MCU_SEL 0x00000007U -#define IO_MUX_GPIO11_MCU_SEL_M (IO_MUX_GPIO11_MCU_SEL_V << IO_MUX_GPIO11_MCU_SEL_S) -#define IO_MUX_GPIO11_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO11_MCU_SEL_S 12 -/** IO_MUX_GPIO11_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO11_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO11_FILTER_EN_M (IO_MUX_GPIO11_FILTER_EN_V << IO_MUX_GPIO11_FILTER_EN_S) -#define IO_MUX_GPIO11_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO11_FILTER_EN_S 15 -/** IO_MUX_GPIO11_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO11_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO11_HYS_EN (BIT(16)) -#define IO_MUX_GPIO11_HYS_EN_M (IO_MUX_GPIO11_HYS_EN_V << IO_MUX_GPIO11_HYS_EN_S) -#define IO_MUX_GPIO11_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO11_HYS_EN_S 16 -/** IO_MUX_GPIO11_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO11. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO11_HYS_EN\\ - */ -#define IO_MUX_GPIO11_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO11_HYS_SEL_M (IO_MUX_GPIO11_HYS_SEL_V << IO_MUX_GPIO11_HYS_SEL_S) -#define IO_MUX_GPIO11_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO11_HYS_SEL_S 17 - -/** IO_MUX_GPIO12_REG register - * IO MUX configuration register for GPIO12 - */ -#define IO_MUX_GPIO12_REG (DR_REG_IO_MUX_BASE + 0x30) -/** IO_MUX_GPIO12_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO12 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO12_MCU_OE (BIT(0)) -#define IO_MUX_GPIO12_MCU_OE_M (IO_MUX_GPIO12_MCU_OE_V << IO_MUX_GPIO12_MCU_OE_S) -#define IO_MUX_GPIO12_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO12_MCU_OE_S 0 -/** IO_MUX_GPIO12_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO12.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO12_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO12_SLP_SEL_M (IO_MUX_GPIO12_SLP_SEL_V << IO_MUX_GPIO12_SLP_SEL_S) -#define IO_MUX_GPIO12_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO12_SLP_SEL_S 1 -/** IO_MUX_GPIO12_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO12 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO12_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO12_MCU_WPD_M (IO_MUX_GPIO12_MCU_WPD_V << IO_MUX_GPIO12_MCU_WPD_S) -#define IO_MUX_GPIO12_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO12_MCU_WPD_S 2 -/** IO_MUX_GPIO12_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO12 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO12_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO12_MCU_WPU_M (IO_MUX_GPIO12_MCU_WPU_V << IO_MUX_GPIO12_MCU_WPU_S) -#define IO_MUX_GPIO12_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO12_MCU_WPU_S 3 -/** IO_MUX_GPIO12_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO12 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO12_MCU_IE (BIT(4)) -#define IO_MUX_GPIO12_MCU_IE_M (IO_MUX_GPIO12_MCU_IE_V << IO_MUX_GPIO12_MCU_IE_S) -#define IO_MUX_GPIO12_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO12_MCU_IE_S 4 -/** IO_MUX_GPIO12_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO12 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO12_MCU_DRV 0x00000003U -#define IO_MUX_GPIO12_MCU_DRV_M (IO_MUX_GPIO12_MCU_DRV_V << IO_MUX_GPIO12_MCU_DRV_S) -#define IO_MUX_GPIO12_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO12_MCU_DRV_S 5 -/** IO_MUX_GPIO12_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO12.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO12_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO12_FUN_WPD_M (IO_MUX_GPIO12_FUN_WPD_V << IO_MUX_GPIO12_FUN_WPD_S) -#define IO_MUX_GPIO12_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO12_FUN_WPD_S 7 -/** IO_MUX_GPIO12_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO12.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO12_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO12_FUN_WPU_M (IO_MUX_GPIO12_FUN_WPU_V << IO_MUX_GPIO12_FUN_WPU_S) -#define IO_MUX_GPIO12_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO12_FUN_WPU_S 8 -/** IO_MUX_GPIO12_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO12.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO12_FUN_IE (BIT(9)) -#define IO_MUX_GPIO12_FUN_IE_M (IO_MUX_GPIO12_FUN_IE_V << IO_MUX_GPIO12_FUN_IE_S) -#define IO_MUX_GPIO12_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO12_FUN_IE_S 9 -/** IO_MUX_GPIO12_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO12. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO12_FUN_DRV 0x00000003U -#define IO_MUX_GPIO12_FUN_DRV_M (IO_MUX_GPIO12_FUN_DRV_V << IO_MUX_GPIO12_FUN_DRV_S) -#define IO_MUX_GPIO12_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO12_FUN_DRV_S 10 -/** IO_MUX_GPIO12_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO12_MCU_SEL 0x00000007U -#define IO_MUX_GPIO12_MCU_SEL_M (IO_MUX_GPIO12_MCU_SEL_V << IO_MUX_GPIO12_MCU_SEL_S) -#define IO_MUX_GPIO12_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO12_MCU_SEL_S 12 -/** IO_MUX_GPIO12_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO12_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO12_FILTER_EN_M (IO_MUX_GPIO12_FILTER_EN_V << IO_MUX_GPIO12_FILTER_EN_S) -#define IO_MUX_GPIO12_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO12_FILTER_EN_S 15 -/** IO_MUX_GPIO12_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO12_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO12_HYS_EN (BIT(16)) -#define IO_MUX_GPIO12_HYS_EN_M (IO_MUX_GPIO12_HYS_EN_V << IO_MUX_GPIO12_HYS_EN_S) -#define IO_MUX_GPIO12_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO12_HYS_EN_S 16 -/** IO_MUX_GPIO12_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO12. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO12_HYS_EN\\ - */ -#define IO_MUX_GPIO12_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO12_HYS_SEL_M (IO_MUX_GPIO12_HYS_SEL_V << IO_MUX_GPIO12_HYS_SEL_S) -#define IO_MUX_GPIO12_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO12_HYS_SEL_S 17 - -/** IO_MUX_GPIO13_REG register - * IO MUX configuration register for GPIO13 - */ -#define IO_MUX_GPIO13_REG (DR_REG_IO_MUX_BASE + 0x34) -/** IO_MUX_GPIO13_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO13 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO13_MCU_OE (BIT(0)) -#define IO_MUX_GPIO13_MCU_OE_M (IO_MUX_GPIO13_MCU_OE_V << IO_MUX_GPIO13_MCU_OE_S) -#define IO_MUX_GPIO13_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO13_MCU_OE_S 0 -/** IO_MUX_GPIO13_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO13.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO13_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO13_SLP_SEL_M (IO_MUX_GPIO13_SLP_SEL_V << IO_MUX_GPIO13_SLP_SEL_S) -#define IO_MUX_GPIO13_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO13_SLP_SEL_S 1 -/** IO_MUX_GPIO13_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO13 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO13_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO13_MCU_WPD_M (IO_MUX_GPIO13_MCU_WPD_V << IO_MUX_GPIO13_MCU_WPD_S) -#define IO_MUX_GPIO13_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO13_MCU_WPD_S 2 -/** IO_MUX_GPIO13_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO13 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO13_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO13_MCU_WPU_M (IO_MUX_GPIO13_MCU_WPU_V << IO_MUX_GPIO13_MCU_WPU_S) -#define IO_MUX_GPIO13_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO13_MCU_WPU_S 3 -/** IO_MUX_GPIO13_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO13 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO13_MCU_IE (BIT(4)) -#define IO_MUX_GPIO13_MCU_IE_M (IO_MUX_GPIO13_MCU_IE_V << IO_MUX_GPIO13_MCU_IE_S) -#define IO_MUX_GPIO13_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO13_MCU_IE_S 4 -/** IO_MUX_GPIO13_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO13 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO13_MCU_DRV 0x00000003U -#define IO_MUX_GPIO13_MCU_DRV_M (IO_MUX_GPIO13_MCU_DRV_V << IO_MUX_GPIO13_MCU_DRV_S) -#define IO_MUX_GPIO13_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO13_MCU_DRV_S 5 -/** IO_MUX_GPIO13_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO13.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO13_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO13_FUN_WPD_M (IO_MUX_GPIO13_FUN_WPD_V << IO_MUX_GPIO13_FUN_WPD_S) -#define IO_MUX_GPIO13_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO13_FUN_WPD_S 7 -/** IO_MUX_GPIO13_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO13.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO13_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO13_FUN_WPU_M (IO_MUX_GPIO13_FUN_WPU_V << IO_MUX_GPIO13_FUN_WPU_S) -#define IO_MUX_GPIO13_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO13_FUN_WPU_S 8 -/** IO_MUX_GPIO13_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO13.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO13_FUN_IE (BIT(9)) -#define IO_MUX_GPIO13_FUN_IE_M (IO_MUX_GPIO13_FUN_IE_V << IO_MUX_GPIO13_FUN_IE_S) -#define IO_MUX_GPIO13_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO13_FUN_IE_S 9 -/** IO_MUX_GPIO13_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO13. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO13_FUN_DRV 0x00000003U -#define IO_MUX_GPIO13_FUN_DRV_M (IO_MUX_GPIO13_FUN_DRV_V << IO_MUX_GPIO13_FUN_DRV_S) -#define IO_MUX_GPIO13_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO13_FUN_DRV_S 10 -/** IO_MUX_GPIO13_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO13_MCU_SEL 0x00000007U -#define IO_MUX_GPIO13_MCU_SEL_M (IO_MUX_GPIO13_MCU_SEL_V << IO_MUX_GPIO13_MCU_SEL_S) -#define IO_MUX_GPIO13_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO13_MCU_SEL_S 12 -/** IO_MUX_GPIO13_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO13_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO13_FILTER_EN_M (IO_MUX_GPIO13_FILTER_EN_V << IO_MUX_GPIO13_FILTER_EN_S) -#define IO_MUX_GPIO13_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO13_FILTER_EN_S 15 -/** IO_MUX_GPIO13_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO13_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO13_HYS_EN (BIT(16)) -#define IO_MUX_GPIO13_HYS_EN_M (IO_MUX_GPIO13_HYS_EN_V << IO_MUX_GPIO13_HYS_EN_S) -#define IO_MUX_GPIO13_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO13_HYS_EN_S 16 -/** IO_MUX_GPIO13_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO13. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO13_HYS_EN\\ - */ -#define IO_MUX_GPIO13_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO13_HYS_SEL_M (IO_MUX_GPIO13_HYS_SEL_V << IO_MUX_GPIO13_HYS_SEL_S) -#define IO_MUX_GPIO13_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO13_HYS_SEL_S 17 - -/** IO_MUX_GPIO14_REG register - * IO MUX configuration register for GPIO14 - */ -#define IO_MUX_GPIO14_REG (DR_REG_IO_MUX_BASE + 0x38) -/** IO_MUX_GPIO14_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO14 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO14_MCU_OE (BIT(0)) -#define IO_MUX_GPIO14_MCU_OE_M (IO_MUX_GPIO14_MCU_OE_V << IO_MUX_GPIO14_MCU_OE_S) -#define IO_MUX_GPIO14_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO14_MCU_OE_S 0 -/** IO_MUX_GPIO14_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO14.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO14_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO14_SLP_SEL_M (IO_MUX_GPIO14_SLP_SEL_V << IO_MUX_GPIO14_SLP_SEL_S) -#define IO_MUX_GPIO14_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO14_SLP_SEL_S 1 -/** IO_MUX_GPIO14_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO14 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO14_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO14_MCU_WPD_M (IO_MUX_GPIO14_MCU_WPD_V << IO_MUX_GPIO14_MCU_WPD_S) -#define IO_MUX_GPIO14_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO14_MCU_WPD_S 2 -/** IO_MUX_GPIO14_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO14 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO14_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO14_MCU_WPU_M (IO_MUX_GPIO14_MCU_WPU_V << IO_MUX_GPIO14_MCU_WPU_S) -#define IO_MUX_GPIO14_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO14_MCU_WPU_S 3 -/** IO_MUX_GPIO14_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO14 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO14_MCU_IE (BIT(4)) -#define IO_MUX_GPIO14_MCU_IE_M (IO_MUX_GPIO14_MCU_IE_V << IO_MUX_GPIO14_MCU_IE_S) -#define IO_MUX_GPIO14_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO14_MCU_IE_S 4 -/** IO_MUX_GPIO14_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO14 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO14_MCU_DRV 0x00000003U -#define IO_MUX_GPIO14_MCU_DRV_M (IO_MUX_GPIO14_MCU_DRV_V << IO_MUX_GPIO14_MCU_DRV_S) -#define IO_MUX_GPIO14_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO14_MCU_DRV_S 5 -/** IO_MUX_GPIO14_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO14.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO14_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO14_FUN_WPD_M (IO_MUX_GPIO14_FUN_WPD_V << IO_MUX_GPIO14_FUN_WPD_S) -#define IO_MUX_GPIO14_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO14_FUN_WPD_S 7 -/** IO_MUX_GPIO14_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO14.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO14_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO14_FUN_WPU_M (IO_MUX_GPIO14_FUN_WPU_V << IO_MUX_GPIO14_FUN_WPU_S) -#define IO_MUX_GPIO14_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO14_FUN_WPU_S 8 -/** IO_MUX_GPIO14_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO14.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO14_FUN_IE (BIT(9)) -#define IO_MUX_GPIO14_FUN_IE_M (IO_MUX_GPIO14_FUN_IE_V << IO_MUX_GPIO14_FUN_IE_S) -#define IO_MUX_GPIO14_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO14_FUN_IE_S 9 -/** IO_MUX_GPIO14_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO14. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO14_FUN_DRV 0x00000003U -#define IO_MUX_GPIO14_FUN_DRV_M (IO_MUX_GPIO14_FUN_DRV_V << IO_MUX_GPIO14_FUN_DRV_S) -#define IO_MUX_GPIO14_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO14_FUN_DRV_S 10 -/** IO_MUX_GPIO14_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO14_MCU_SEL 0x00000007U -#define IO_MUX_GPIO14_MCU_SEL_M (IO_MUX_GPIO14_MCU_SEL_V << IO_MUX_GPIO14_MCU_SEL_S) -#define IO_MUX_GPIO14_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO14_MCU_SEL_S 12 -/** IO_MUX_GPIO14_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO14_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO14_FILTER_EN_M (IO_MUX_GPIO14_FILTER_EN_V << IO_MUX_GPIO14_FILTER_EN_S) -#define IO_MUX_GPIO14_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO14_FILTER_EN_S 15 -/** IO_MUX_GPIO14_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO14_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO14_HYS_EN (BIT(16)) -#define IO_MUX_GPIO14_HYS_EN_M (IO_MUX_GPIO14_HYS_EN_V << IO_MUX_GPIO14_HYS_EN_S) -#define IO_MUX_GPIO14_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO14_HYS_EN_S 16 -/** IO_MUX_GPIO14_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO14. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO14_HYS_EN\\ - */ -#define IO_MUX_GPIO14_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO14_HYS_SEL_M (IO_MUX_GPIO14_HYS_SEL_V << IO_MUX_GPIO14_HYS_SEL_S) -#define IO_MUX_GPIO14_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO14_HYS_SEL_S 17 - -/** IO_MUX_GPIO15_REG register - * IO MUX configuration register for GPIO15 - */ -#define IO_MUX_GPIO15_REG (DR_REG_IO_MUX_BASE + 0x3c) -/** IO_MUX_GPIO15_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO15 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO15_MCU_OE (BIT(0)) -#define IO_MUX_GPIO15_MCU_OE_M (IO_MUX_GPIO15_MCU_OE_V << IO_MUX_GPIO15_MCU_OE_S) -#define IO_MUX_GPIO15_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO15_MCU_OE_S 0 -/** IO_MUX_GPIO15_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO15.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO15_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO15_SLP_SEL_M (IO_MUX_GPIO15_SLP_SEL_V << IO_MUX_GPIO15_SLP_SEL_S) -#define IO_MUX_GPIO15_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO15_SLP_SEL_S 1 -/** IO_MUX_GPIO15_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO15 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO15_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO15_MCU_WPD_M (IO_MUX_GPIO15_MCU_WPD_V << IO_MUX_GPIO15_MCU_WPD_S) -#define IO_MUX_GPIO15_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO15_MCU_WPD_S 2 -/** IO_MUX_GPIO15_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO15 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO15_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO15_MCU_WPU_M (IO_MUX_GPIO15_MCU_WPU_V << IO_MUX_GPIO15_MCU_WPU_S) -#define IO_MUX_GPIO15_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO15_MCU_WPU_S 3 -/** IO_MUX_GPIO15_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO15 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO15_MCU_IE (BIT(4)) -#define IO_MUX_GPIO15_MCU_IE_M (IO_MUX_GPIO15_MCU_IE_V << IO_MUX_GPIO15_MCU_IE_S) -#define IO_MUX_GPIO15_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO15_MCU_IE_S 4 -/** IO_MUX_GPIO15_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO15 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO15_MCU_DRV 0x00000003U -#define IO_MUX_GPIO15_MCU_DRV_M (IO_MUX_GPIO15_MCU_DRV_V << IO_MUX_GPIO15_MCU_DRV_S) -#define IO_MUX_GPIO15_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO15_MCU_DRV_S 5 -/** IO_MUX_GPIO15_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO15.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO15_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO15_FUN_WPD_M (IO_MUX_GPIO15_FUN_WPD_V << IO_MUX_GPIO15_FUN_WPD_S) -#define IO_MUX_GPIO15_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO15_FUN_WPD_S 7 -/** IO_MUX_GPIO15_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO15.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO15_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO15_FUN_WPU_M (IO_MUX_GPIO15_FUN_WPU_V << IO_MUX_GPIO15_FUN_WPU_S) -#define IO_MUX_GPIO15_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO15_FUN_WPU_S 8 -/** IO_MUX_GPIO15_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO15.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO15_FUN_IE (BIT(9)) -#define IO_MUX_GPIO15_FUN_IE_M (IO_MUX_GPIO15_FUN_IE_V << IO_MUX_GPIO15_FUN_IE_S) -#define IO_MUX_GPIO15_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO15_FUN_IE_S 9 -/** IO_MUX_GPIO15_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO15. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO15_FUN_DRV 0x00000003U -#define IO_MUX_GPIO15_FUN_DRV_M (IO_MUX_GPIO15_FUN_DRV_V << IO_MUX_GPIO15_FUN_DRV_S) -#define IO_MUX_GPIO15_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO15_FUN_DRV_S 10 -/** IO_MUX_GPIO15_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO15_MCU_SEL 0x00000007U -#define IO_MUX_GPIO15_MCU_SEL_M (IO_MUX_GPIO15_MCU_SEL_V << IO_MUX_GPIO15_MCU_SEL_S) -#define IO_MUX_GPIO15_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO15_MCU_SEL_S 12 -/** IO_MUX_GPIO15_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO15_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO15_FILTER_EN_M (IO_MUX_GPIO15_FILTER_EN_V << IO_MUX_GPIO15_FILTER_EN_S) -#define IO_MUX_GPIO15_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO15_FILTER_EN_S 15 -/** IO_MUX_GPIO15_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO15_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO15_HYS_EN (BIT(16)) -#define IO_MUX_GPIO15_HYS_EN_M (IO_MUX_GPIO15_HYS_EN_V << IO_MUX_GPIO15_HYS_EN_S) -#define IO_MUX_GPIO15_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO15_HYS_EN_S 16 -/** IO_MUX_GPIO15_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO15. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO15_HYS_EN\\ - */ -#define IO_MUX_GPIO15_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO15_HYS_SEL_M (IO_MUX_GPIO15_HYS_SEL_V << IO_MUX_GPIO15_HYS_SEL_S) -#define IO_MUX_GPIO15_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO15_HYS_SEL_S 17 - -/** IO_MUX_GPIO16_REG register - * IO MUX configuration register for GPIO16 - */ -#define IO_MUX_GPIO16_REG (DR_REG_IO_MUX_BASE + 0x40) -/** IO_MUX_GPIO16_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO16 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO16_MCU_OE (BIT(0)) -#define IO_MUX_GPIO16_MCU_OE_M (IO_MUX_GPIO16_MCU_OE_V << IO_MUX_GPIO16_MCU_OE_S) -#define IO_MUX_GPIO16_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO16_MCU_OE_S 0 -/** IO_MUX_GPIO16_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO16.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO16_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO16_SLP_SEL_M (IO_MUX_GPIO16_SLP_SEL_V << IO_MUX_GPIO16_SLP_SEL_S) -#define IO_MUX_GPIO16_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO16_SLP_SEL_S 1 -/** IO_MUX_GPIO16_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO16 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO16_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO16_MCU_WPD_M (IO_MUX_GPIO16_MCU_WPD_V << IO_MUX_GPIO16_MCU_WPD_S) -#define IO_MUX_GPIO16_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO16_MCU_WPD_S 2 -/** IO_MUX_GPIO16_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO16 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO16_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO16_MCU_WPU_M (IO_MUX_GPIO16_MCU_WPU_V << IO_MUX_GPIO16_MCU_WPU_S) -#define IO_MUX_GPIO16_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO16_MCU_WPU_S 3 -/** IO_MUX_GPIO16_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO16 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO16_MCU_IE (BIT(4)) -#define IO_MUX_GPIO16_MCU_IE_M (IO_MUX_GPIO16_MCU_IE_V << IO_MUX_GPIO16_MCU_IE_S) -#define IO_MUX_GPIO16_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO16_MCU_IE_S 4 -/** IO_MUX_GPIO16_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO16 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO16_MCU_DRV 0x00000003U -#define IO_MUX_GPIO16_MCU_DRV_M (IO_MUX_GPIO16_MCU_DRV_V << IO_MUX_GPIO16_MCU_DRV_S) -#define IO_MUX_GPIO16_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO16_MCU_DRV_S 5 -/** IO_MUX_GPIO16_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO16.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO16_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO16_FUN_WPD_M (IO_MUX_GPIO16_FUN_WPD_V << IO_MUX_GPIO16_FUN_WPD_S) -#define IO_MUX_GPIO16_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO16_FUN_WPD_S 7 -/** IO_MUX_GPIO16_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO16.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO16_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO16_FUN_WPU_M (IO_MUX_GPIO16_FUN_WPU_V << IO_MUX_GPIO16_FUN_WPU_S) -#define IO_MUX_GPIO16_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO16_FUN_WPU_S 8 -/** IO_MUX_GPIO16_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO16.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO16_FUN_IE (BIT(9)) -#define IO_MUX_GPIO16_FUN_IE_M (IO_MUX_GPIO16_FUN_IE_V << IO_MUX_GPIO16_FUN_IE_S) -#define IO_MUX_GPIO16_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO16_FUN_IE_S 9 -/** IO_MUX_GPIO16_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO16. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO16_FUN_DRV 0x00000003U -#define IO_MUX_GPIO16_FUN_DRV_M (IO_MUX_GPIO16_FUN_DRV_V << IO_MUX_GPIO16_FUN_DRV_S) -#define IO_MUX_GPIO16_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO16_FUN_DRV_S 10 -/** IO_MUX_GPIO16_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO16_MCU_SEL 0x00000007U -#define IO_MUX_GPIO16_MCU_SEL_M (IO_MUX_GPIO16_MCU_SEL_V << IO_MUX_GPIO16_MCU_SEL_S) -#define IO_MUX_GPIO16_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO16_MCU_SEL_S 12 -/** IO_MUX_GPIO16_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO16_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO16_FILTER_EN_M (IO_MUX_GPIO16_FILTER_EN_V << IO_MUX_GPIO16_FILTER_EN_S) -#define IO_MUX_GPIO16_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO16_FILTER_EN_S 15 -/** IO_MUX_GPIO16_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO16_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO16_HYS_EN (BIT(16)) -#define IO_MUX_GPIO16_HYS_EN_M (IO_MUX_GPIO16_HYS_EN_V << IO_MUX_GPIO16_HYS_EN_S) -#define IO_MUX_GPIO16_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO16_HYS_EN_S 16 -/** IO_MUX_GPIO16_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO16. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO16_HYS_EN\\ - */ -#define IO_MUX_GPIO16_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO16_HYS_SEL_M (IO_MUX_GPIO16_HYS_SEL_V << IO_MUX_GPIO16_HYS_SEL_S) -#define IO_MUX_GPIO16_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO16_HYS_SEL_S 17 - -/** IO_MUX_GPIO17_REG register - * IO MUX configuration register for GPIO17 - */ -#define IO_MUX_GPIO17_REG (DR_REG_IO_MUX_BASE + 0x44) -/** IO_MUX_GPIO17_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO17 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO17_MCU_OE (BIT(0)) -#define IO_MUX_GPIO17_MCU_OE_M (IO_MUX_GPIO17_MCU_OE_V << IO_MUX_GPIO17_MCU_OE_S) -#define IO_MUX_GPIO17_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO17_MCU_OE_S 0 -/** IO_MUX_GPIO17_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO17.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO17_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO17_SLP_SEL_M (IO_MUX_GPIO17_SLP_SEL_V << IO_MUX_GPIO17_SLP_SEL_S) -#define IO_MUX_GPIO17_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO17_SLP_SEL_S 1 -/** IO_MUX_GPIO17_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO17 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO17_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO17_MCU_WPD_M (IO_MUX_GPIO17_MCU_WPD_V << IO_MUX_GPIO17_MCU_WPD_S) -#define IO_MUX_GPIO17_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO17_MCU_WPD_S 2 -/** IO_MUX_GPIO17_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO17 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO17_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO17_MCU_WPU_M (IO_MUX_GPIO17_MCU_WPU_V << IO_MUX_GPIO17_MCU_WPU_S) -#define IO_MUX_GPIO17_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO17_MCU_WPU_S 3 -/** IO_MUX_GPIO17_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO17 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO17_MCU_IE (BIT(4)) -#define IO_MUX_GPIO17_MCU_IE_M (IO_MUX_GPIO17_MCU_IE_V << IO_MUX_GPIO17_MCU_IE_S) -#define IO_MUX_GPIO17_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO17_MCU_IE_S 4 -/** IO_MUX_GPIO17_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO17 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO17_MCU_DRV 0x00000003U -#define IO_MUX_GPIO17_MCU_DRV_M (IO_MUX_GPIO17_MCU_DRV_V << IO_MUX_GPIO17_MCU_DRV_S) -#define IO_MUX_GPIO17_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO17_MCU_DRV_S 5 -/** IO_MUX_GPIO17_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO17.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO17_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO17_FUN_WPD_M (IO_MUX_GPIO17_FUN_WPD_V << IO_MUX_GPIO17_FUN_WPD_S) -#define IO_MUX_GPIO17_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO17_FUN_WPD_S 7 -/** IO_MUX_GPIO17_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO17.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO17_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO17_FUN_WPU_M (IO_MUX_GPIO17_FUN_WPU_V << IO_MUX_GPIO17_FUN_WPU_S) -#define IO_MUX_GPIO17_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO17_FUN_WPU_S 8 -/** IO_MUX_GPIO17_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO17.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO17_FUN_IE (BIT(9)) -#define IO_MUX_GPIO17_FUN_IE_M (IO_MUX_GPIO17_FUN_IE_V << IO_MUX_GPIO17_FUN_IE_S) -#define IO_MUX_GPIO17_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO17_FUN_IE_S 9 -/** IO_MUX_GPIO17_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO17. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO17_FUN_DRV 0x00000003U -#define IO_MUX_GPIO17_FUN_DRV_M (IO_MUX_GPIO17_FUN_DRV_V << IO_MUX_GPIO17_FUN_DRV_S) -#define IO_MUX_GPIO17_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO17_FUN_DRV_S 10 -/** IO_MUX_GPIO17_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO17_MCU_SEL 0x00000007U -#define IO_MUX_GPIO17_MCU_SEL_M (IO_MUX_GPIO17_MCU_SEL_V << IO_MUX_GPIO17_MCU_SEL_S) -#define IO_MUX_GPIO17_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO17_MCU_SEL_S 12 -/** IO_MUX_GPIO17_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO17_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO17_FILTER_EN_M (IO_MUX_GPIO17_FILTER_EN_V << IO_MUX_GPIO17_FILTER_EN_S) -#define IO_MUX_GPIO17_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO17_FILTER_EN_S 15 -/** IO_MUX_GPIO17_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO17_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO17_HYS_EN (BIT(16)) -#define IO_MUX_GPIO17_HYS_EN_M (IO_MUX_GPIO17_HYS_EN_V << IO_MUX_GPIO17_HYS_EN_S) -#define IO_MUX_GPIO17_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO17_HYS_EN_S 16 -/** IO_MUX_GPIO17_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO17. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO17_HYS_EN\\ - */ -#define IO_MUX_GPIO17_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO17_HYS_SEL_M (IO_MUX_GPIO17_HYS_SEL_V << IO_MUX_GPIO17_HYS_SEL_S) -#define IO_MUX_GPIO17_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO17_HYS_SEL_S 17 - -/** IO_MUX_GPIO18_REG register - * IO MUX configuration register for GPIO18 - */ -#define IO_MUX_GPIO18_REG (DR_REG_IO_MUX_BASE + 0x48) -/** IO_MUX_GPIO18_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO18 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO18_MCU_OE (BIT(0)) -#define IO_MUX_GPIO18_MCU_OE_M (IO_MUX_GPIO18_MCU_OE_V << IO_MUX_GPIO18_MCU_OE_S) -#define IO_MUX_GPIO18_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO18_MCU_OE_S 0 -/** IO_MUX_GPIO18_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO18.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO18_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO18_SLP_SEL_M (IO_MUX_GPIO18_SLP_SEL_V << IO_MUX_GPIO18_SLP_SEL_S) -#define IO_MUX_GPIO18_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO18_SLP_SEL_S 1 -/** IO_MUX_GPIO18_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO18 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO18_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO18_MCU_WPD_M (IO_MUX_GPIO18_MCU_WPD_V << IO_MUX_GPIO18_MCU_WPD_S) -#define IO_MUX_GPIO18_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO18_MCU_WPD_S 2 -/** IO_MUX_GPIO18_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO18 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO18_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO18_MCU_WPU_M (IO_MUX_GPIO18_MCU_WPU_V << IO_MUX_GPIO18_MCU_WPU_S) -#define IO_MUX_GPIO18_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO18_MCU_WPU_S 3 -/** IO_MUX_GPIO18_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO18 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO18_MCU_IE (BIT(4)) -#define IO_MUX_GPIO18_MCU_IE_M (IO_MUX_GPIO18_MCU_IE_V << IO_MUX_GPIO18_MCU_IE_S) -#define IO_MUX_GPIO18_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO18_MCU_IE_S 4 -/** IO_MUX_GPIO18_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO18 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO18_MCU_DRV 0x00000003U -#define IO_MUX_GPIO18_MCU_DRV_M (IO_MUX_GPIO18_MCU_DRV_V << IO_MUX_GPIO18_MCU_DRV_S) -#define IO_MUX_GPIO18_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO18_MCU_DRV_S 5 -/** IO_MUX_GPIO18_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO18.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO18_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO18_FUN_WPD_M (IO_MUX_GPIO18_FUN_WPD_V << IO_MUX_GPIO18_FUN_WPD_S) -#define IO_MUX_GPIO18_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO18_FUN_WPD_S 7 -/** IO_MUX_GPIO18_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO18.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO18_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO18_FUN_WPU_M (IO_MUX_GPIO18_FUN_WPU_V << IO_MUX_GPIO18_FUN_WPU_S) -#define IO_MUX_GPIO18_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO18_FUN_WPU_S 8 -/** IO_MUX_GPIO18_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO18.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO18_FUN_IE (BIT(9)) -#define IO_MUX_GPIO18_FUN_IE_M (IO_MUX_GPIO18_FUN_IE_V << IO_MUX_GPIO18_FUN_IE_S) -#define IO_MUX_GPIO18_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO18_FUN_IE_S 9 -/** IO_MUX_GPIO18_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO18. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO18_FUN_DRV 0x00000003U -#define IO_MUX_GPIO18_FUN_DRV_M (IO_MUX_GPIO18_FUN_DRV_V << IO_MUX_GPIO18_FUN_DRV_S) -#define IO_MUX_GPIO18_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO18_FUN_DRV_S 10 -/** IO_MUX_GPIO18_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO18_MCU_SEL 0x00000007U -#define IO_MUX_GPIO18_MCU_SEL_M (IO_MUX_GPIO18_MCU_SEL_V << IO_MUX_GPIO18_MCU_SEL_S) -#define IO_MUX_GPIO18_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO18_MCU_SEL_S 12 -/** IO_MUX_GPIO18_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO18_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO18_FILTER_EN_M (IO_MUX_GPIO18_FILTER_EN_V << IO_MUX_GPIO18_FILTER_EN_S) -#define IO_MUX_GPIO18_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO18_FILTER_EN_S 15 -/** IO_MUX_GPIO18_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO18_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO18_HYS_EN (BIT(16)) -#define IO_MUX_GPIO18_HYS_EN_M (IO_MUX_GPIO18_HYS_EN_V << IO_MUX_GPIO18_HYS_EN_S) -#define IO_MUX_GPIO18_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO18_HYS_EN_S 16 -/** IO_MUX_GPIO18_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO18. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO18_HYS_EN\\ - */ -#define IO_MUX_GPIO18_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO18_HYS_SEL_M (IO_MUX_GPIO18_HYS_SEL_V << IO_MUX_GPIO18_HYS_SEL_S) -#define IO_MUX_GPIO18_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO18_HYS_SEL_S 17 - -/** IO_MUX_GPIO19_REG register - * IO MUX configuration register for GPIO19 - */ -#define IO_MUX_GPIO19_REG (DR_REG_IO_MUX_BASE + 0x4c) -/** IO_MUX_GPIO19_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO19 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO19_MCU_OE (BIT(0)) -#define IO_MUX_GPIO19_MCU_OE_M (IO_MUX_GPIO19_MCU_OE_V << IO_MUX_GPIO19_MCU_OE_S) -#define IO_MUX_GPIO19_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO19_MCU_OE_S 0 -/** IO_MUX_GPIO19_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO19.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO19_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO19_SLP_SEL_M (IO_MUX_GPIO19_SLP_SEL_V << IO_MUX_GPIO19_SLP_SEL_S) -#define IO_MUX_GPIO19_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO19_SLP_SEL_S 1 -/** IO_MUX_GPIO19_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO19 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO19_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO19_MCU_WPD_M (IO_MUX_GPIO19_MCU_WPD_V << IO_MUX_GPIO19_MCU_WPD_S) -#define IO_MUX_GPIO19_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO19_MCU_WPD_S 2 -/** IO_MUX_GPIO19_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO19 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO19_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO19_MCU_WPU_M (IO_MUX_GPIO19_MCU_WPU_V << IO_MUX_GPIO19_MCU_WPU_S) -#define IO_MUX_GPIO19_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO19_MCU_WPU_S 3 -/** IO_MUX_GPIO19_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO19 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO19_MCU_IE (BIT(4)) -#define IO_MUX_GPIO19_MCU_IE_M (IO_MUX_GPIO19_MCU_IE_V << IO_MUX_GPIO19_MCU_IE_S) -#define IO_MUX_GPIO19_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO19_MCU_IE_S 4 -/** IO_MUX_GPIO19_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO19 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO19_MCU_DRV 0x00000003U -#define IO_MUX_GPIO19_MCU_DRV_M (IO_MUX_GPIO19_MCU_DRV_V << IO_MUX_GPIO19_MCU_DRV_S) -#define IO_MUX_GPIO19_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO19_MCU_DRV_S 5 -/** IO_MUX_GPIO19_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO19.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO19_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO19_FUN_WPD_M (IO_MUX_GPIO19_FUN_WPD_V << IO_MUX_GPIO19_FUN_WPD_S) -#define IO_MUX_GPIO19_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO19_FUN_WPD_S 7 -/** IO_MUX_GPIO19_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO19.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO19_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO19_FUN_WPU_M (IO_MUX_GPIO19_FUN_WPU_V << IO_MUX_GPIO19_FUN_WPU_S) -#define IO_MUX_GPIO19_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO19_FUN_WPU_S 8 -/** IO_MUX_GPIO19_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO19.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO19_FUN_IE (BIT(9)) -#define IO_MUX_GPIO19_FUN_IE_M (IO_MUX_GPIO19_FUN_IE_V << IO_MUX_GPIO19_FUN_IE_S) -#define IO_MUX_GPIO19_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO19_FUN_IE_S 9 -/** IO_MUX_GPIO19_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO19. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO19_FUN_DRV 0x00000003U -#define IO_MUX_GPIO19_FUN_DRV_M (IO_MUX_GPIO19_FUN_DRV_V << IO_MUX_GPIO19_FUN_DRV_S) -#define IO_MUX_GPIO19_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO19_FUN_DRV_S 10 -/** IO_MUX_GPIO19_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO19_MCU_SEL 0x00000007U -#define IO_MUX_GPIO19_MCU_SEL_M (IO_MUX_GPIO19_MCU_SEL_V << IO_MUX_GPIO19_MCU_SEL_S) -#define IO_MUX_GPIO19_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO19_MCU_SEL_S 12 -/** IO_MUX_GPIO19_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO19_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO19_FILTER_EN_M (IO_MUX_GPIO19_FILTER_EN_V << IO_MUX_GPIO19_FILTER_EN_S) -#define IO_MUX_GPIO19_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO19_FILTER_EN_S 15 -/** IO_MUX_GPIO19_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO19_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO19_HYS_EN (BIT(16)) -#define IO_MUX_GPIO19_HYS_EN_M (IO_MUX_GPIO19_HYS_EN_V << IO_MUX_GPIO19_HYS_EN_S) -#define IO_MUX_GPIO19_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO19_HYS_EN_S 16 -/** IO_MUX_GPIO19_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO19. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO19_HYS_EN\\ - */ -#define IO_MUX_GPIO19_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO19_HYS_SEL_M (IO_MUX_GPIO19_HYS_SEL_V << IO_MUX_GPIO19_HYS_SEL_S) -#define IO_MUX_GPIO19_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO19_HYS_SEL_S 17 - -/** IO_MUX_GPIO20_REG register - * IO MUX configuration register for GPIO20 - */ -#define IO_MUX_GPIO20_REG (DR_REG_IO_MUX_BASE + 0x50) -/** IO_MUX_GPIO20_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO20 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO20_MCU_OE (BIT(0)) -#define IO_MUX_GPIO20_MCU_OE_M (IO_MUX_GPIO20_MCU_OE_V << IO_MUX_GPIO20_MCU_OE_S) -#define IO_MUX_GPIO20_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO20_MCU_OE_S 0 -/** IO_MUX_GPIO20_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO20.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO20_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO20_SLP_SEL_M (IO_MUX_GPIO20_SLP_SEL_V << IO_MUX_GPIO20_SLP_SEL_S) -#define IO_MUX_GPIO20_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO20_SLP_SEL_S 1 -/** IO_MUX_GPIO20_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO20 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO20_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO20_MCU_WPD_M (IO_MUX_GPIO20_MCU_WPD_V << IO_MUX_GPIO20_MCU_WPD_S) -#define IO_MUX_GPIO20_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO20_MCU_WPD_S 2 -/** IO_MUX_GPIO20_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO20 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO20_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO20_MCU_WPU_M (IO_MUX_GPIO20_MCU_WPU_V << IO_MUX_GPIO20_MCU_WPU_S) -#define IO_MUX_GPIO20_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO20_MCU_WPU_S 3 -/** IO_MUX_GPIO20_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO20 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO20_MCU_IE (BIT(4)) -#define IO_MUX_GPIO20_MCU_IE_M (IO_MUX_GPIO20_MCU_IE_V << IO_MUX_GPIO20_MCU_IE_S) -#define IO_MUX_GPIO20_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO20_MCU_IE_S 4 -/** IO_MUX_GPIO20_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO20 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO20_MCU_DRV 0x00000003U -#define IO_MUX_GPIO20_MCU_DRV_M (IO_MUX_GPIO20_MCU_DRV_V << IO_MUX_GPIO20_MCU_DRV_S) -#define IO_MUX_GPIO20_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO20_MCU_DRV_S 5 -/** IO_MUX_GPIO20_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO20.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO20_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO20_FUN_WPD_M (IO_MUX_GPIO20_FUN_WPD_V << IO_MUX_GPIO20_FUN_WPD_S) -#define IO_MUX_GPIO20_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO20_FUN_WPD_S 7 -/** IO_MUX_GPIO20_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO20.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO20_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO20_FUN_WPU_M (IO_MUX_GPIO20_FUN_WPU_V << IO_MUX_GPIO20_FUN_WPU_S) -#define IO_MUX_GPIO20_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO20_FUN_WPU_S 8 -/** IO_MUX_GPIO20_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO20.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO20_FUN_IE (BIT(9)) -#define IO_MUX_GPIO20_FUN_IE_M (IO_MUX_GPIO20_FUN_IE_V << IO_MUX_GPIO20_FUN_IE_S) -#define IO_MUX_GPIO20_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO20_FUN_IE_S 9 -/** IO_MUX_GPIO20_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO20. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO20_FUN_DRV 0x00000003U -#define IO_MUX_GPIO20_FUN_DRV_M (IO_MUX_GPIO20_FUN_DRV_V << IO_MUX_GPIO20_FUN_DRV_S) -#define IO_MUX_GPIO20_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO20_FUN_DRV_S 10 -/** IO_MUX_GPIO20_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO20_MCU_SEL 0x00000007U -#define IO_MUX_GPIO20_MCU_SEL_M (IO_MUX_GPIO20_MCU_SEL_V << IO_MUX_GPIO20_MCU_SEL_S) -#define IO_MUX_GPIO20_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO20_MCU_SEL_S 12 -/** IO_MUX_GPIO20_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO20_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO20_FILTER_EN_M (IO_MUX_GPIO20_FILTER_EN_V << IO_MUX_GPIO20_FILTER_EN_S) -#define IO_MUX_GPIO20_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO20_FILTER_EN_S 15 -/** IO_MUX_GPIO20_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO20_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO20_HYS_EN (BIT(16)) -#define IO_MUX_GPIO20_HYS_EN_M (IO_MUX_GPIO20_HYS_EN_V << IO_MUX_GPIO20_HYS_EN_S) -#define IO_MUX_GPIO20_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO20_HYS_EN_S 16 -/** IO_MUX_GPIO20_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO20. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO20_HYS_EN\\ - */ -#define IO_MUX_GPIO20_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO20_HYS_SEL_M (IO_MUX_GPIO20_HYS_SEL_V << IO_MUX_GPIO20_HYS_SEL_S) -#define IO_MUX_GPIO20_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO20_HYS_SEL_S 17 - -/** IO_MUX_GPIO21_REG register - * IO MUX configuration register for GPIO21 - */ -#define IO_MUX_GPIO21_REG (DR_REG_IO_MUX_BASE + 0x54) -/** IO_MUX_GPIO21_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO21 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO21_MCU_OE (BIT(0)) -#define IO_MUX_GPIO21_MCU_OE_M (IO_MUX_GPIO21_MCU_OE_V << IO_MUX_GPIO21_MCU_OE_S) -#define IO_MUX_GPIO21_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO21_MCU_OE_S 0 -/** IO_MUX_GPIO21_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO21.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO21_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO21_SLP_SEL_M (IO_MUX_GPIO21_SLP_SEL_V << IO_MUX_GPIO21_SLP_SEL_S) -#define IO_MUX_GPIO21_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO21_SLP_SEL_S 1 -/** IO_MUX_GPIO21_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO21 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO21_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO21_MCU_WPD_M (IO_MUX_GPIO21_MCU_WPD_V << IO_MUX_GPIO21_MCU_WPD_S) -#define IO_MUX_GPIO21_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO21_MCU_WPD_S 2 -/** IO_MUX_GPIO21_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO21 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO21_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO21_MCU_WPU_M (IO_MUX_GPIO21_MCU_WPU_V << IO_MUX_GPIO21_MCU_WPU_S) -#define IO_MUX_GPIO21_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO21_MCU_WPU_S 3 -/** IO_MUX_GPIO21_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO21 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO21_MCU_IE (BIT(4)) -#define IO_MUX_GPIO21_MCU_IE_M (IO_MUX_GPIO21_MCU_IE_V << IO_MUX_GPIO21_MCU_IE_S) -#define IO_MUX_GPIO21_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO21_MCU_IE_S 4 -/** IO_MUX_GPIO21_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO21 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO21_MCU_DRV 0x00000003U -#define IO_MUX_GPIO21_MCU_DRV_M (IO_MUX_GPIO21_MCU_DRV_V << IO_MUX_GPIO21_MCU_DRV_S) -#define IO_MUX_GPIO21_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO21_MCU_DRV_S 5 -/** IO_MUX_GPIO21_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO21.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO21_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO21_FUN_WPD_M (IO_MUX_GPIO21_FUN_WPD_V << IO_MUX_GPIO21_FUN_WPD_S) -#define IO_MUX_GPIO21_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO21_FUN_WPD_S 7 -/** IO_MUX_GPIO21_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO21.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO21_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO21_FUN_WPU_M (IO_MUX_GPIO21_FUN_WPU_V << IO_MUX_GPIO21_FUN_WPU_S) -#define IO_MUX_GPIO21_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO21_FUN_WPU_S 8 -/** IO_MUX_GPIO21_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO21.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO21_FUN_IE (BIT(9)) -#define IO_MUX_GPIO21_FUN_IE_M (IO_MUX_GPIO21_FUN_IE_V << IO_MUX_GPIO21_FUN_IE_S) -#define IO_MUX_GPIO21_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO21_FUN_IE_S 9 -/** IO_MUX_GPIO21_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO21. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO21_FUN_DRV 0x00000003U -#define IO_MUX_GPIO21_FUN_DRV_M (IO_MUX_GPIO21_FUN_DRV_V << IO_MUX_GPIO21_FUN_DRV_S) -#define IO_MUX_GPIO21_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO21_FUN_DRV_S 10 -/** IO_MUX_GPIO21_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO21_MCU_SEL 0x00000007U -#define IO_MUX_GPIO21_MCU_SEL_M (IO_MUX_GPIO21_MCU_SEL_V << IO_MUX_GPIO21_MCU_SEL_S) -#define IO_MUX_GPIO21_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO21_MCU_SEL_S 12 -/** IO_MUX_GPIO21_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO21_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO21_FILTER_EN_M (IO_MUX_GPIO21_FILTER_EN_V << IO_MUX_GPIO21_FILTER_EN_S) -#define IO_MUX_GPIO21_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO21_FILTER_EN_S 15 -/** IO_MUX_GPIO21_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO21_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO21_HYS_EN (BIT(16)) -#define IO_MUX_GPIO21_HYS_EN_M (IO_MUX_GPIO21_HYS_EN_V << IO_MUX_GPIO21_HYS_EN_S) -#define IO_MUX_GPIO21_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO21_HYS_EN_S 16 -/** IO_MUX_GPIO21_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO21. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO21_HYS_EN\\ - */ -#define IO_MUX_GPIO21_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO21_HYS_SEL_M (IO_MUX_GPIO21_HYS_SEL_V << IO_MUX_GPIO21_HYS_SEL_S) -#define IO_MUX_GPIO21_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO21_HYS_SEL_S 17 - -/** IO_MUX_GPIO22_REG register - * IO MUX configuration register for GPIO22 - */ -#define IO_MUX_GPIO22_REG (DR_REG_IO_MUX_BASE + 0x58) -/** IO_MUX_GPIO22_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO22 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO22_MCU_OE (BIT(0)) -#define IO_MUX_GPIO22_MCU_OE_M (IO_MUX_GPIO22_MCU_OE_V << IO_MUX_GPIO22_MCU_OE_S) -#define IO_MUX_GPIO22_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO22_MCU_OE_S 0 -/** IO_MUX_GPIO22_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO22.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO22_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO22_SLP_SEL_M (IO_MUX_GPIO22_SLP_SEL_V << IO_MUX_GPIO22_SLP_SEL_S) -#define IO_MUX_GPIO22_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO22_SLP_SEL_S 1 -/** IO_MUX_GPIO22_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO22 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO22_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO22_MCU_WPD_M (IO_MUX_GPIO22_MCU_WPD_V << IO_MUX_GPIO22_MCU_WPD_S) -#define IO_MUX_GPIO22_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO22_MCU_WPD_S 2 -/** IO_MUX_GPIO22_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO22 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO22_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO22_MCU_WPU_M (IO_MUX_GPIO22_MCU_WPU_V << IO_MUX_GPIO22_MCU_WPU_S) -#define IO_MUX_GPIO22_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO22_MCU_WPU_S 3 -/** IO_MUX_GPIO22_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO22 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO22_MCU_IE (BIT(4)) -#define IO_MUX_GPIO22_MCU_IE_M (IO_MUX_GPIO22_MCU_IE_V << IO_MUX_GPIO22_MCU_IE_S) -#define IO_MUX_GPIO22_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO22_MCU_IE_S 4 -/** IO_MUX_GPIO22_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO22 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO22_MCU_DRV 0x00000003U -#define IO_MUX_GPIO22_MCU_DRV_M (IO_MUX_GPIO22_MCU_DRV_V << IO_MUX_GPIO22_MCU_DRV_S) -#define IO_MUX_GPIO22_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO22_MCU_DRV_S 5 -/** IO_MUX_GPIO22_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO22.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO22_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO22_FUN_WPD_M (IO_MUX_GPIO22_FUN_WPD_V << IO_MUX_GPIO22_FUN_WPD_S) -#define IO_MUX_GPIO22_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO22_FUN_WPD_S 7 -/** IO_MUX_GPIO22_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO22.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO22_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO22_FUN_WPU_M (IO_MUX_GPIO22_FUN_WPU_V << IO_MUX_GPIO22_FUN_WPU_S) -#define IO_MUX_GPIO22_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO22_FUN_WPU_S 8 -/** IO_MUX_GPIO22_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO22.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO22_FUN_IE (BIT(9)) -#define IO_MUX_GPIO22_FUN_IE_M (IO_MUX_GPIO22_FUN_IE_V << IO_MUX_GPIO22_FUN_IE_S) -#define IO_MUX_GPIO22_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO22_FUN_IE_S 9 -/** IO_MUX_GPIO22_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO22. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO22_FUN_DRV 0x00000003U -#define IO_MUX_GPIO22_FUN_DRV_M (IO_MUX_GPIO22_FUN_DRV_V << IO_MUX_GPIO22_FUN_DRV_S) -#define IO_MUX_GPIO22_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO22_FUN_DRV_S 10 -/** IO_MUX_GPIO22_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO22_MCU_SEL 0x00000007U -#define IO_MUX_GPIO22_MCU_SEL_M (IO_MUX_GPIO22_MCU_SEL_V << IO_MUX_GPIO22_MCU_SEL_S) -#define IO_MUX_GPIO22_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO22_MCU_SEL_S 12 -/** IO_MUX_GPIO22_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO22_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO22_FILTER_EN_M (IO_MUX_GPIO22_FILTER_EN_V << IO_MUX_GPIO22_FILTER_EN_S) -#define IO_MUX_GPIO22_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO22_FILTER_EN_S 15 -/** IO_MUX_GPIO22_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO22_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO22_HYS_EN (BIT(16)) -#define IO_MUX_GPIO22_HYS_EN_M (IO_MUX_GPIO22_HYS_EN_V << IO_MUX_GPIO22_HYS_EN_S) -#define IO_MUX_GPIO22_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO22_HYS_EN_S 16 -/** IO_MUX_GPIO22_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO22. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO22_HYS_EN\\ - */ -#define IO_MUX_GPIO22_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO22_HYS_SEL_M (IO_MUX_GPIO22_HYS_SEL_V << IO_MUX_GPIO22_HYS_SEL_S) -#define IO_MUX_GPIO22_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO22_HYS_SEL_S 17 - -/** IO_MUX_GPIO23_REG register - * IO MUX configuration register for GPIO23 - */ -#define IO_MUX_GPIO23_REG (DR_REG_IO_MUX_BASE + 0x5c) -/** IO_MUX_GPIO23_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO23 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO23_MCU_OE (BIT(0)) -#define IO_MUX_GPIO23_MCU_OE_M (IO_MUX_GPIO23_MCU_OE_V << IO_MUX_GPIO23_MCU_OE_S) -#define IO_MUX_GPIO23_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO23_MCU_OE_S 0 -/** IO_MUX_GPIO23_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO23.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO23_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO23_SLP_SEL_M (IO_MUX_GPIO23_SLP_SEL_V << IO_MUX_GPIO23_SLP_SEL_S) -#define IO_MUX_GPIO23_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO23_SLP_SEL_S 1 -/** IO_MUX_GPIO23_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO23 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO23_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO23_MCU_WPD_M (IO_MUX_GPIO23_MCU_WPD_V << IO_MUX_GPIO23_MCU_WPD_S) -#define IO_MUX_GPIO23_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO23_MCU_WPD_S 2 -/** IO_MUX_GPIO23_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO23 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO23_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO23_MCU_WPU_M (IO_MUX_GPIO23_MCU_WPU_V << IO_MUX_GPIO23_MCU_WPU_S) -#define IO_MUX_GPIO23_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO23_MCU_WPU_S 3 -/** IO_MUX_GPIO23_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO23 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO23_MCU_IE (BIT(4)) -#define IO_MUX_GPIO23_MCU_IE_M (IO_MUX_GPIO23_MCU_IE_V << IO_MUX_GPIO23_MCU_IE_S) -#define IO_MUX_GPIO23_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO23_MCU_IE_S 4 -/** IO_MUX_GPIO23_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO23 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO23_MCU_DRV 0x00000003U -#define IO_MUX_GPIO23_MCU_DRV_M (IO_MUX_GPIO23_MCU_DRV_V << IO_MUX_GPIO23_MCU_DRV_S) -#define IO_MUX_GPIO23_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO23_MCU_DRV_S 5 -/** IO_MUX_GPIO23_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO23.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO23_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO23_FUN_WPD_M (IO_MUX_GPIO23_FUN_WPD_V << IO_MUX_GPIO23_FUN_WPD_S) -#define IO_MUX_GPIO23_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO23_FUN_WPD_S 7 -/** IO_MUX_GPIO23_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO23.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO23_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO23_FUN_WPU_M (IO_MUX_GPIO23_FUN_WPU_V << IO_MUX_GPIO23_FUN_WPU_S) -#define IO_MUX_GPIO23_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO23_FUN_WPU_S 8 -/** IO_MUX_GPIO23_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO23.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO23_FUN_IE (BIT(9)) -#define IO_MUX_GPIO23_FUN_IE_M (IO_MUX_GPIO23_FUN_IE_V << IO_MUX_GPIO23_FUN_IE_S) -#define IO_MUX_GPIO23_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO23_FUN_IE_S 9 -/** IO_MUX_GPIO23_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO23. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO23_FUN_DRV 0x00000003U -#define IO_MUX_GPIO23_FUN_DRV_M (IO_MUX_GPIO23_FUN_DRV_V << IO_MUX_GPIO23_FUN_DRV_S) -#define IO_MUX_GPIO23_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO23_FUN_DRV_S 10 -/** IO_MUX_GPIO23_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO23_MCU_SEL 0x00000007U -#define IO_MUX_GPIO23_MCU_SEL_M (IO_MUX_GPIO23_MCU_SEL_V << IO_MUX_GPIO23_MCU_SEL_S) -#define IO_MUX_GPIO23_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO23_MCU_SEL_S 12 -/** IO_MUX_GPIO23_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO23_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO23_FILTER_EN_M (IO_MUX_GPIO23_FILTER_EN_V << IO_MUX_GPIO23_FILTER_EN_S) -#define IO_MUX_GPIO23_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO23_FILTER_EN_S 15 -/** IO_MUX_GPIO23_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO23_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO23_HYS_EN (BIT(16)) -#define IO_MUX_GPIO23_HYS_EN_M (IO_MUX_GPIO23_HYS_EN_V << IO_MUX_GPIO23_HYS_EN_S) -#define IO_MUX_GPIO23_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO23_HYS_EN_S 16 -/** IO_MUX_GPIO23_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO23. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO23_HYS_EN\\ - */ -#define IO_MUX_GPIO23_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO23_HYS_SEL_M (IO_MUX_GPIO23_HYS_SEL_V << IO_MUX_GPIO23_HYS_SEL_S) -#define IO_MUX_GPIO23_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO23_HYS_SEL_S 17 - -/** IO_MUX_GPIO24_REG register - * IO MUX configuration register for GPIO24 - */ -#define IO_MUX_GPIO24_REG (DR_REG_IO_MUX_BASE + 0x60) -/** IO_MUX_GPIO24_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO24 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO24_MCU_OE (BIT(0)) -#define IO_MUX_GPIO24_MCU_OE_M (IO_MUX_GPIO24_MCU_OE_V << IO_MUX_GPIO24_MCU_OE_S) -#define IO_MUX_GPIO24_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO24_MCU_OE_S 0 -/** IO_MUX_GPIO24_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO24.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO24_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO24_SLP_SEL_M (IO_MUX_GPIO24_SLP_SEL_V << IO_MUX_GPIO24_SLP_SEL_S) -#define IO_MUX_GPIO24_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO24_SLP_SEL_S 1 -/** IO_MUX_GPIO24_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO24 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO24_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO24_MCU_WPD_M (IO_MUX_GPIO24_MCU_WPD_V << IO_MUX_GPIO24_MCU_WPD_S) -#define IO_MUX_GPIO24_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO24_MCU_WPD_S 2 -/** IO_MUX_GPIO24_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO24 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO24_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO24_MCU_WPU_M (IO_MUX_GPIO24_MCU_WPU_V << IO_MUX_GPIO24_MCU_WPU_S) -#define IO_MUX_GPIO24_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO24_MCU_WPU_S 3 -/** IO_MUX_GPIO24_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO24 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO24_MCU_IE (BIT(4)) -#define IO_MUX_GPIO24_MCU_IE_M (IO_MUX_GPIO24_MCU_IE_V << IO_MUX_GPIO24_MCU_IE_S) -#define IO_MUX_GPIO24_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO24_MCU_IE_S 4 -/** IO_MUX_GPIO24_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO24 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO24_MCU_DRV 0x00000003U -#define IO_MUX_GPIO24_MCU_DRV_M (IO_MUX_GPIO24_MCU_DRV_V << IO_MUX_GPIO24_MCU_DRV_S) -#define IO_MUX_GPIO24_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO24_MCU_DRV_S 5 -/** IO_MUX_GPIO24_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO24.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO24_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO24_FUN_WPD_M (IO_MUX_GPIO24_FUN_WPD_V << IO_MUX_GPIO24_FUN_WPD_S) -#define IO_MUX_GPIO24_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO24_FUN_WPD_S 7 -/** IO_MUX_GPIO24_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO24.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO24_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO24_FUN_WPU_M (IO_MUX_GPIO24_FUN_WPU_V << IO_MUX_GPIO24_FUN_WPU_S) -#define IO_MUX_GPIO24_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO24_FUN_WPU_S 8 -/** IO_MUX_GPIO24_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO24.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO24_FUN_IE (BIT(9)) -#define IO_MUX_GPIO24_FUN_IE_M (IO_MUX_GPIO24_FUN_IE_V << IO_MUX_GPIO24_FUN_IE_S) -#define IO_MUX_GPIO24_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO24_FUN_IE_S 9 -/** IO_MUX_GPIO24_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO24. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO24_FUN_DRV 0x00000003U -#define IO_MUX_GPIO24_FUN_DRV_M (IO_MUX_GPIO24_FUN_DRV_V << IO_MUX_GPIO24_FUN_DRV_S) -#define IO_MUX_GPIO24_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO24_FUN_DRV_S 10 -/** IO_MUX_GPIO24_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO24_MCU_SEL 0x00000007U -#define IO_MUX_GPIO24_MCU_SEL_M (IO_MUX_GPIO24_MCU_SEL_V << IO_MUX_GPIO24_MCU_SEL_S) -#define IO_MUX_GPIO24_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO24_MCU_SEL_S 12 -/** IO_MUX_GPIO24_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO24_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO24_FILTER_EN_M (IO_MUX_GPIO24_FILTER_EN_V << IO_MUX_GPIO24_FILTER_EN_S) -#define IO_MUX_GPIO24_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO24_FILTER_EN_S 15 -/** IO_MUX_GPIO24_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO24_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO24_HYS_EN (BIT(16)) -#define IO_MUX_GPIO24_HYS_EN_M (IO_MUX_GPIO24_HYS_EN_V << IO_MUX_GPIO24_HYS_EN_S) -#define IO_MUX_GPIO24_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO24_HYS_EN_S 16 -/** IO_MUX_GPIO24_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO24. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO24_HYS_EN\\ - */ -#define IO_MUX_GPIO24_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO24_HYS_SEL_M (IO_MUX_GPIO24_HYS_SEL_V << IO_MUX_GPIO24_HYS_SEL_S) -#define IO_MUX_GPIO24_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO24_HYS_SEL_S 17 - -/** IO_MUX_GPIO25_REG register - * IO MUX configuration register for GPIO25 - */ -#define IO_MUX_GPIO25_REG (DR_REG_IO_MUX_BASE + 0x64) -/** IO_MUX_GPIO25_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO25 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO25_MCU_OE (BIT(0)) -#define IO_MUX_GPIO25_MCU_OE_M (IO_MUX_GPIO25_MCU_OE_V << IO_MUX_GPIO25_MCU_OE_S) -#define IO_MUX_GPIO25_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO25_MCU_OE_S 0 -/** IO_MUX_GPIO25_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO25.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO25_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO25_SLP_SEL_M (IO_MUX_GPIO25_SLP_SEL_V << IO_MUX_GPIO25_SLP_SEL_S) -#define IO_MUX_GPIO25_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO25_SLP_SEL_S 1 -/** IO_MUX_GPIO25_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO25 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO25_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO25_MCU_WPD_M (IO_MUX_GPIO25_MCU_WPD_V << IO_MUX_GPIO25_MCU_WPD_S) -#define IO_MUX_GPIO25_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO25_MCU_WPD_S 2 -/** IO_MUX_GPIO25_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO25 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO25_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO25_MCU_WPU_M (IO_MUX_GPIO25_MCU_WPU_V << IO_MUX_GPIO25_MCU_WPU_S) -#define IO_MUX_GPIO25_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO25_MCU_WPU_S 3 -/** IO_MUX_GPIO25_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO25 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO25_MCU_IE (BIT(4)) -#define IO_MUX_GPIO25_MCU_IE_M (IO_MUX_GPIO25_MCU_IE_V << IO_MUX_GPIO25_MCU_IE_S) -#define IO_MUX_GPIO25_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO25_MCU_IE_S 4 -/** IO_MUX_GPIO25_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO25 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO25_MCU_DRV 0x00000003U -#define IO_MUX_GPIO25_MCU_DRV_M (IO_MUX_GPIO25_MCU_DRV_V << IO_MUX_GPIO25_MCU_DRV_S) -#define IO_MUX_GPIO25_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO25_MCU_DRV_S 5 -/** IO_MUX_GPIO25_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO25.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO25_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO25_FUN_WPD_M (IO_MUX_GPIO25_FUN_WPD_V << IO_MUX_GPIO25_FUN_WPD_S) -#define IO_MUX_GPIO25_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO25_FUN_WPD_S 7 -/** IO_MUX_GPIO25_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO25.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO25_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO25_FUN_WPU_M (IO_MUX_GPIO25_FUN_WPU_V << IO_MUX_GPIO25_FUN_WPU_S) -#define IO_MUX_GPIO25_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO25_FUN_WPU_S 8 -/** IO_MUX_GPIO25_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO25.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO25_FUN_IE (BIT(9)) -#define IO_MUX_GPIO25_FUN_IE_M (IO_MUX_GPIO25_FUN_IE_V << IO_MUX_GPIO25_FUN_IE_S) -#define IO_MUX_GPIO25_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO25_FUN_IE_S 9 -/** IO_MUX_GPIO25_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO25. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO25_FUN_DRV 0x00000003U -#define IO_MUX_GPIO25_FUN_DRV_M (IO_MUX_GPIO25_FUN_DRV_V << IO_MUX_GPIO25_FUN_DRV_S) -#define IO_MUX_GPIO25_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO25_FUN_DRV_S 10 -/** IO_MUX_GPIO25_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO25_MCU_SEL 0x00000007U -#define IO_MUX_GPIO25_MCU_SEL_M (IO_MUX_GPIO25_MCU_SEL_V << IO_MUX_GPIO25_MCU_SEL_S) -#define IO_MUX_GPIO25_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO25_MCU_SEL_S 12 -/** IO_MUX_GPIO25_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO25_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO25_FILTER_EN_M (IO_MUX_GPIO25_FILTER_EN_V << IO_MUX_GPIO25_FILTER_EN_S) -#define IO_MUX_GPIO25_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO25_FILTER_EN_S 15 -/** IO_MUX_GPIO25_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO25_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO25_HYS_EN (BIT(16)) -#define IO_MUX_GPIO25_HYS_EN_M (IO_MUX_GPIO25_HYS_EN_V << IO_MUX_GPIO25_HYS_EN_S) -#define IO_MUX_GPIO25_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO25_HYS_EN_S 16 -/** IO_MUX_GPIO25_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO25. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO25_HYS_EN\\ - */ -#define IO_MUX_GPIO25_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO25_HYS_SEL_M (IO_MUX_GPIO25_HYS_SEL_V << IO_MUX_GPIO25_HYS_SEL_S) -#define IO_MUX_GPIO25_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO25_HYS_SEL_S 17 - -/** IO_MUX_GPIO26_REG register - * IO MUX configuration register for GPIO26 - */ -#define IO_MUX_GPIO26_REG (DR_REG_IO_MUX_BASE + 0x68) -/** IO_MUX_GPIO26_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO26 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO26_MCU_OE (BIT(0)) -#define IO_MUX_GPIO26_MCU_OE_M (IO_MUX_GPIO26_MCU_OE_V << IO_MUX_GPIO26_MCU_OE_S) -#define IO_MUX_GPIO26_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO26_MCU_OE_S 0 -/** IO_MUX_GPIO26_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO26.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO26_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO26_SLP_SEL_M (IO_MUX_GPIO26_SLP_SEL_V << IO_MUX_GPIO26_SLP_SEL_S) -#define IO_MUX_GPIO26_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO26_SLP_SEL_S 1 -/** IO_MUX_GPIO26_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO26 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO26_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO26_MCU_WPD_M (IO_MUX_GPIO26_MCU_WPD_V << IO_MUX_GPIO26_MCU_WPD_S) -#define IO_MUX_GPIO26_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO26_MCU_WPD_S 2 -/** IO_MUX_GPIO26_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO26 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO26_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO26_MCU_WPU_M (IO_MUX_GPIO26_MCU_WPU_V << IO_MUX_GPIO26_MCU_WPU_S) -#define IO_MUX_GPIO26_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO26_MCU_WPU_S 3 -/** IO_MUX_GPIO26_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO26 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO26_MCU_IE (BIT(4)) -#define IO_MUX_GPIO26_MCU_IE_M (IO_MUX_GPIO26_MCU_IE_V << IO_MUX_GPIO26_MCU_IE_S) -#define IO_MUX_GPIO26_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO26_MCU_IE_S 4 -/** IO_MUX_GPIO26_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO26 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO26_MCU_DRV 0x00000003U -#define IO_MUX_GPIO26_MCU_DRV_M (IO_MUX_GPIO26_MCU_DRV_V << IO_MUX_GPIO26_MCU_DRV_S) -#define IO_MUX_GPIO26_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO26_MCU_DRV_S 5 -/** IO_MUX_GPIO26_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO26.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO26_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO26_FUN_WPD_M (IO_MUX_GPIO26_FUN_WPD_V << IO_MUX_GPIO26_FUN_WPD_S) -#define IO_MUX_GPIO26_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO26_FUN_WPD_S 7 -/** IO_MUX_GPIO26_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO26.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO26_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO26_FUN_WPU_M (IO_MUX_GPIO26_FUN_WPU_V << IO_MUX_GPIO26_FUN_WPU_S) -#define IO_MUX_GPIO26_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO26_FUN_WPU_S 8 -/** IO_MUX_GPIO26_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO26.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO26_FUN_IE (BIT(9)) -#define IO_MUX_GPIO26_FUN_IE_M (IO_MUX_GPIO26_FUN_IE_V << IO_MUX_GPIO26_FUN_IE_S) -#define IO_MUX_GPIO26_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO26_FUN_IE_S 9 -/** IO_MUX_GPIO26_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO26. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO26_FUN_DRV 0x00000003U -#define IO_MUX_GPIO26_FUN_DRV_M (IO_MUX_GPIO26_FUN_DRV_V << IO_MUX_GPIO26_FUN_DRV_S) -#define IO_MUX_GPIO26_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO26_FUN_DRV_S 10 -/** IO_MUX_GPIO26_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO26_MCU_SEL 0x00000007U -#define IO_MUX_GPIO26_MCU_SEL_M (IO_MUX_GPIO26_MCU_SEL_V << IO_MUX_GPIO26_MCU_SEL_S) -#define IO_MUX_GPIO26_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO26_MCU_SEL_S 12 -/** IO_MUX_GPIO26_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO26_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO26_FILTER_EN_M (IO_MUX_GPIO26_FILTER_EN_V << IO_MUX_GPIO26_FILTER_EN_S) -#define IO_MUX_GPIO26_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO26_FILTER_EN_S 15 -/** IO_MUX_GPIO26_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO26_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO26_HYS_EN (BIT(16)) -#define IO_MUX_GPIO26_HYS_EN_M (IO_MUX_GPIO26_HYS_EN_V << IO_MUX_GPIO26_HYS_EN_S) -#define IO_MUX_GPIO26_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO26_HYS_EN_S 16 -/** IO_MUX_GPIO26_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO26. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO26_HYS_EN\\ - */ -#define IO_MUX_GPIO26_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO26_HYS_SEL_M (IO_MUX_GPIO26_HYS_SEL_V << IO_MUX_GPIO26_HYS_SEL_S) -#define IO_MUX_GPIO26_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO26_HYS_SEL_S 17 - -/** IO_MUX_GPIO27_REG register - * IO MUX configuration register for GPIO27 - */ -#define IO_MUX_GPIO27_REG (DR_REG_IO_MUX_BASE + 0x6c) -/** IO_MUX_GPIO27_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO27 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO27_MCU_OE (BIT(0)) -#define IO_MUX_GPIO27_MCU_OE_M (IO_MUX_GPIO27_MCU_OE_V << IO_MUX_GPIO27_MCU_OE_S) -#define IO_MUX_GPIO27_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO27_MCU_OE_S 0 -/** IO_MUX_GPIO27_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO27.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO27_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO27_SLP_SEL_M (IO_MUX_GPIO27_SLP_SEL_V << IO_MUX_GPIO27_SLP_SEL_S) -#define IO_MUX_GPIO27_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO27_SLP_SEL_S 1 -/** IO_MUX_GPIO27_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO27 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO27_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO27_MCU_WPD_M (IO_MUX_GPIO27_MCU_WPD_V << IO_MUX_GPIO27_MCU_WPD_S) -#define IO_MUX_GPIO27_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO27_MCU_WPD_S 2 -/** IO_MUX_GPIO27_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO27 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO27_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO27_MCU_WPU_M (IO_MUX_GPIO27_MCU_WPU_V << IO_MUX_GPIO27_MCU_WPU_S) -#define IO_MUX_GPIO27_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO27_MCU_WPU_S 3 -/** IO_MUX_GPIO27_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO27 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO27_MCU_IE (BIT(4)) -#define IO_MUX_GPIO27_MCU_IE_M (IO_MUX_GPIO27_MCU_IE_V << IO_MUX_GPIO27_MCU_IE_S) -#define IO_MUX_GPIO27_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO27_MCU_IE_S 4 -/** IO_MUX_GPIO27_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO27 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO27_MCU_DRV 0x00000003U -#define IO_MUX_GPIO27_MCU_DRV_M (IO_MUX_GPIO27_MCU_DRV_V << IO_MUX_GPIO27_MCU_DRV_S) -#define IO_MUX_GPIO27_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO27_MCU_DRV_S 5 -/** IO_MUX_GPIO27_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO27.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO27_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO27_FUN_WPD_M (IO_MUX_GPIO27_FUN_WPD_V << IO_MUX_GPIO27_FUN_WPD_S) -#define IO_MUX_GPIO27_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO27_FUN_WPD_S 7 -/** IO_MUX_GPIO27_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO27.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO27_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO27_FUN_WPU_M (IO_MUX_GPIO27_FUN_WPU_V << IO_MUX_GPIO27_FUN_WPU_S) -#define IO_MUX_GPIO27_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO27_FUN_WPU_S 8 -/** IO_MUX_GPIO27_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO27.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO27_FUN_IE (BIT(9)) -#define IO_MUX_GPIO27_FUN_IE_M (IO_MUX_GPIO27_FUN_IE_V << IO_MUX_GPIO27_FUN_IE_S) -#define IO_MUX_GPIO27_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO27_FUN_IE_S 9 -/** IO_MUX_GPIO27_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO27. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO27_FUN_DRV 0x00000003U -#define IO_MUX_GPIO27_FUN_DRV_M (IO_MUX_GPIO27_FUN_DRV_V << IO_MUX_GPIO27_FUN_DRV_S) -#define IO_MUX_GPIO27_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO27_FUN_DRV_S 10 -/** IO_MUX_GPIO27_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO27_MCU_SEL 0x00000007U -#define IO_MUX_GPIO27_MCU_SEL_M (IO_MUX_GPIO27_MCU_SEL_V << IO_MUX_GPIO27_MCU_SEL_S) -#define IO_MUX_GPIO27_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO27_MCU_SEL_S 12 -/** IO_MUX_GPIO27_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO27_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO27_FILTER_EN_M (IO_MUX_GPIO27_FILTER_EN_V << IO_MUX_GPIO27_FILTER_EN_S) -#define IO_MUX_GPIO27_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO27_FILTER_EN_S 15 -/** IO_MUX_GPIO27_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO27_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO27_HYS_EN (BIT(16)) -#define IO_MUX_GPIO27_HYS_EN_M (IO_MUX_GPIO27_HYS_EN_V << IO_MUX_GPIO27_HYS_EN_S) -#define IO_MUX_GPIO27_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO27_HYS_EN_S 16 -/** IO_MUX_GPIO27_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO27. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO27_HYS_EN\\ - */ -#define IO_MUX_GPIO27_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO27_HYS_SEL_M (IO_MUX_GPIO27_HYS_SEL_V << IO_MUX_GPIO27_HYS_SEL_S) -#define IO_MUX_GPIO27_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO27_HYS_SEL_S 17 - -/** IO_MUX_GPIO28_REG register - * IO MUX configuration register for GPIO28 - */ -#define IO_MUX_GPIO28_REG (DR_REG_IO_MUX_BASE + 0x70) -/** IO_MUX_GPIO28_MCU_OE : R/W; bitpos: [0]; default: 0; - * Configures whether or not to enable the output of GPIO28 in sleep mode. - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO28_MCU_OE (BIT(0)) -#define IO_MUX_GPIO28_MCU_OE_M (IO_MUX_GPIO28_MCU_OE_V << IO_MUX_GPIO28_MCU_OE_S) -#define IO_MUX_GPIO28_MCU_OE_V 0x00000001U -#define IO_MUX_GPIO28_MCU_OE_S 0 -/** IO_MUX_GPIO28_SLP_SEL : R/W; bitpos: [1]; default: 0; - * Configures whether or not to enter sleep mode for GPIO28.\\ - * 0: Not enter\\ - * 1: Enter\\ - */ -#define IO_MUX_GPIO28_SLP_SEL (BIT(1)) -#define IO_MUX_GPIO28_SLP_SEL_M (IO_MUX_GPIO28_SLP_SEL_V << IO_MUX_GPIO28_SLP_SEL_S) -#define IO_MUX_GPIO28_SLP_SEL_V 0x00000001U -#define IO_MUX_GPIO28_SLP_SEL_S 1 -/** IO_MUX_GPIO28_MCU_WPD : R/W; bitpos: [2]; default: 0; - * Configure whether or not to enable pull-down resistor of GPIO28 in sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO28_MCU_WPD (BIT(2)) -#define IO_MUX_GPIO28_MCU_WPD_M (IO_MUX_GPIO28_MCU_WPD_V << IO_MUX_GPIO28_MCU_WPD_S) -#define IO_MUX_GPIO28_MCU_WPD_V 0x00000001U -#define IO_MUX_GPIO28_MCU_WPD_S 2 -/** IO_MUX_GPIO28_MCU_WPU : R/W; bitpos: [3]; default: 0; - * Configures whether or not to enable pull-up resistor of GPIO28 during sleep mode. \\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO28_MCU_WPU (BIT(3)) -#define IO_MUX_GPIO28_MCU_WPU_M (IO_MUX_GPIO28_MCU_WPU_V << IO_MUX_GPIO28_MCU_WPU_S) -#define IO_MUX_GPIO28_MCU_WPU_V 0x00000001U -#define IO_MUX_GPIO28_MCU_WPU_S 3 -/** IO_MUX_GPIO28_MCU_IE : R/W; bitpos: [4]; default: 0; - * Configures whether or not to enable the input of GPIO28 during sleep mode.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO28_MCU_IE (BIT(4)) -#define IO_MUX_GPIO28_MCU_IE_M (IO_MUX_GPIO28_MCU_IE_V << IO_MUX_GPIO28_MCU_IE_S) -#define IO_MUX_GPIO28_MCU_IE_V 0x00000001U -#define IO_MUX_GPIO28_MCU_IE_S 4 -/** IO_MUX_GPIO28_MCU_DRV : R/W; bitpos: [6:5]; default: 0; - * Configures the drive strength of GPIO28 during sleep mode. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO28_MCU_DRV 0x00000003U -#define IO_MUX_GPIO28_MCU_DRV_M (IO_MUX_GPIO28_MCU_DRV_V << IO_MUX_GPIO28_MCU_DRV_S) -#define IO_MUX_GPIO28_MCU_DRV_V 0x00000003U -#define IO_MUX_GPIO28_MCU_DRV_S 5 -/** IO_MUX_GPIO28_FUN_WPD : R/W; bitpos: [7]; default: 0; - * Configures whether or not to enable pull-down resistor of GPIO28.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO28_FUN_WPD (BIT(7)) -#define IO_MUX_GPIO28_FUN_WPD_M (IO_MUX_GPIO28_FUN_WPD_V << IO_MUX_GPIO28_FUN_WPD_S) -#define IO_MUX_GPIO28_FUN_WPD_V 0x00000001U -#define IO_MUX_GPIO28_FUN_WPD_S 7 -/** IO_MUX_GPIO28_FUN_WPU : R/W; bitpos: [8]; default: 0; - * Configures whether or not enable pull-up resistor of GPIO28.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO28_FUN_WPU (BIT(8)) -#define IO_MUX_GPIO28_FUN_WPU_M (IO_MUX_GPIO28_FUN_WPU_V << IO_MUX_GPIO28_FUN_WPU_S) -#define IO_MUX_GPIO28_FUN_WPU_V 0x00000001U -#define IO_MUX_GPIO28_FUN_WPU_S 8 -/** IO_MUX_GPIO28_FUN_IE : R/W; bitpos: [9]; default: 0; - * Configures whether or not to enable input of GPIO28.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO28_FUN_IE (BIT(9)) -#define IO_MUX_GPIO28_FUN_IE_M (IO_MUX_GPIO28_FUN_IE_V << IO_MUX_GPIO28_FUN_IE_S) -#define IO_MUX_GPIO28_FUN_IE_V 0x00000001U -#define IO_MUX_GPIO28_FUN_IE_S 9 -/** IO_MUX_GPIO28_FUN_DRV : R/W; bitpos: [11:10]; default: 2; - * Configures the drive strength of GPIO28. \\ - * 0: ~5 mA\\ - * 1: ~10 mA\\ - * 2: ~20 mA\\ - * 3: ~40 mA\\ - */ -#define IO_MUX_GPIO28_FUN_DRV 0x00000003U -#define IO_MUX_GPIO28_FUN_DRV_M (IO_MUX_GPIO28_FUN_DRV_V << IO_MUX_GPIO28_FUN_DRV_S) -#define IO_MUX_GPIO28_FUN_DRV_V 0x00000003U -#define IO_MUX_GPIO28_FUN_DRV_S 10 -/** IO_MUX_GPIO28_MCU_SEL : R/W; bitpos: [14:12]; default: 1; - * Configures to select IO MUX function for this signal. \\ - * 0: Select Function 0\\ - * 1: Select Function 1\\ - * ......\\ - */ -#define IO_MUX_GPIO28_MCU_SEL 0x00000007U -#define IO_MUX_GPIO28_MCU_SEL_M (IO_MUX_GPIO28_MCU_SEL_V << IO_MUX_GPIO28_MCU_SEL_S) -#define IO_MUX_GPIO28_MCU_SEL_V 0x00000007U -#define IO_MUX_GPIO28_MCU_SEL_S 12 -/** IO_MUX_GPIO28_FILTER_EN : R/W; bitpos: [15]; default: 0; - * Configures whether or not to enable filter for pin input signals.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO28_FILTER_EN (BIT(15)) -#define IO_MUX_GPIO28_FILTER_EN_M (IO_MUX_GPIO28_FILTER_EN_V << IO_MUX_GPIO28_FILTER_EN_S) -#define IO_MUX_GPIO28_FILTER_EN_V 0x00000001U -#define IO_MUX_GPIO28_FILTER_EN_S 15 -/** IO_MUX_GPIO28_HYS_EN : R/W; bitpos: [16]; default: 0; - * Configures whether or not to enable the hysteresis function of the pin when - * IO_MUX_GPIO28_HYS_SEL is set to 1.\\ - * 0: Disable\\ - * 1: Enable\\ - */ -#define IO_MUX_GPIO28_HYS_EN (BIT(16)) -#define IO_MUX_GPIO28_HYS_EN_M (IO_MUX_GPIO28_HYS_EN_V << IO_MUX_GPIO28_HYS_EN_S) -#define IO_MUX_GPIO28_HYS_EN_V 0x00000001U -#define IO_MUX_GPIO28_HYS_EN_S 16 -/** IO_MUX_GPIO28_HYS_SEL : R/W; bitpos: [17]; default: 0; - * Configures to choose the signal for enabling the hysteresis function for GPIO28. \\ - * 0: Choose the output enable signal of eFuse\\ - * 1: Choose the output enable signal of IO_MUX_GPIO28_HYS_EN\\ - */ -#define IO_MUX_GPIO28_HYS_SEL (BIT(17)) -#define IO_MUX_GPIO28_HYS_SEL_M (IO_MUX_GPIO28_HYS_SEL_V << IO_MUX_GPIO28_HYS_SEL_S) -#define IO_MUX_GPIO28_HYS_SEL_V 0x00000001U -#define IO_MUX_GPIO28_HYS_SEL_S 17 +#define PERIPHS_IO_MUX_U_PAD_XTAL_32K_P (REG_IO_MUX_BASE + 0x0) +#define FUNC_XTAL_32K_P_GPIO0 1 +#define FUNC_XTAL_32K_P_GPIO0_0 0 + +#define PERIPHS_IO_MUX_U_PAD_XTAL_32K_N (REG_IO_MUX_BASE + 0x4) +#define FUNC_XTAL_32K_N_GPIO1 1 +#define FUNC_XTAL_32K_N_GPIO1_0 0 + +#define PERIPHS_IO_MUX_U_PAD_MTMS (REG_IO_MUX_BASE + 0x8) +#define FUNC_MTMS_FSPIQ 2 +#define FUNC_MTMS_GPIO2 1 +#define FUNC_MTMS_MTMS 0 + +#define PERIPHS_IO_MUX_U_PAD_MTDI (REG_IO_MUX_BASE + 0xC) +#define FUNC_MTDI_GPIO3 1 +#define FUNC_MTDI_MTDI 0 + +#define PERIPHS_IO_MUX_U_PAD_MTCK (REG_IO_MUX_BASE + 0x10) +#define FUNC_MTCK_FSPIHD 2 +#define FUNC_MTCK_GPIO4 1 +#define FUNC_MTCK_MTCK 0 + +#define PERIPHS_IO_MUX_U_PAD_MTDO (REG_IO_MUX_BASE + 0x14) +#define FUNC_MTDO_FSPIWP 2 +#define FUNC_MTDO_GPIO5 1 +#define FUNC_MTDO_MTDO 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO6 (REG_IO_MUX_BASE + 0x18) +#define FUNC_GPIO6_FSPICLK 2 +#define FUNC_GPIO6_GPIO6 1 +#define FUNC_GPIO6_GPIO6_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO7 (REG_IO_MUX_BASE + 0x1C) +#define FUNC_GPIO7_FSPID 2 +#define FUNC_GPIO7_GPIO7 1 +#define FUNC_GPIO7_GPIO7_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO8 (REG_IO_MUX_BASE + 0x20) +#define FUNC_GPIO8_GPIO8 1 +#define FUNC_GPIO8_GPIO8_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO9 (REG_IO_MUX_BASE + 0x24) +#define FUNC_GPIO9_GPIO9 1 +#define FUNC_GPIO9_GPIO9_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO10 (REG_IO_MUX_BASE + 0x28) +#define FUNC_GPIO10_FSPICS0 2 +#define FUNC_GPIO10_GPIO10 1 +#define FUNC_GPIO10_GPIO10_0 0 + +#define PERIPHS_IO_MUX_U_PAD_U0TXD (REG_IO_MUX_BASE + 0x2C) +#define FUNC_U0TXD_GPIO11 1 +#define FUNC_U0TXD_U0TXD 0 + +#define PERIPHS_IO_MUX_U_PAD_U0RXD (REG_IO_MUX_BASE + 0x30) +#define FUNC_U0RXD_GPIO12 1 +#define FUNC_U0RXD_U0RXD 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO13 (REG_IO_MUX_BASE + 0x34) +#define FUNC_GPIO13_GPIO13 1 +#define FUNC_GPIO13_GPIO13_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO14 (REG_IO_MUX_BASE + 0x38) +#define FUNC_GPIO14_GPIO14 1 +#define FUNC_GPIO14_GPIO14_0 0 + +#define PERIPHS_IO_MUX_U_PAD_SPICS1 (REG_IO_MUX_BASE + 0x3C) +#define FUNC_SPICS1_GPIO15 1 +#define FUNC_SPICS1_SPICS1 0 + +#define PERIPHS_IO_MUX_U_PAD_SPICS0 (REG_IO_MUX_BASE + 0x40) +#define FUNC_SPICS0_GPIO16 1 +#define FUNC_SPICS0_SPICS0 0 + +#define PERIPHS_IO_MUX_U_PAD_SPIQ (REG_IO_MUX_BASE + 0x44) +#define FUNC_SPIQ_GPIO17 1 +#define FUNC_SPIQ_SPIQ 0 + +#define PERIPHS_IO_MUX_U_PAD_SPIWP (REG_IO_MUX_BASE + 0x48) +#define FUNC_SPIWP_GPIO18 1 +#define FUNC_SPIWP_SPIWP 0 + +#define PERIPHS_IO_MUX_U_PAD_VDD_SPI (REG_IO_MUX_BASE + 0x4C) +#define FUNC_VDD_SPI_GPIO19 1 +#define FUNC_VDD_SPI_GPIO19_0 0 + +#define PERIPHS_IO_MUX_U_PAD_SPIHD (REG_IO_MUX_BASE + 0x50) +#define FUNC_SPIHD_GPIO20 1 +#define FUNC_SPIHD_SPIHD 0 + +#define PERIPHS_IO_MUX_U_PAD_SPICLK (REG_IO_MUX_BASE + 0x54) +#define FUNC_SPICLK_GPIO21 1 +#define FUNC_SPICLK_SPICLK 0 + +#define PERIPHS_IO_MUX_U_PAD_SPID (REG_IO_MUX_BASE + 0x58) +#define FUNC_SPID_GPIO22 1 +#define FUNC_SPID_SPID 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO23 (REG_IO_MUX_BASE + 0x5C) +#define FUNC_GPIO23_GPIO23 1 +#define FUNC_GPIO23_GPIO23_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO24 (REG_IO_MUX_BASE + 0x60) +#define FUNC_GPIO24_GPIO24 1 +#define FUNC_GPIO24_GPIO24_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO25 (REG_IO_MUX_BASE + 0x64) +#define FUNC_GPIO25_GPIO25 1 +#define FUNC_GPIO25_GPIO25_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO26 (REG_IO_MUX_BASE + 0x68) +#define FUNC_GPIO26_GPIO26 1 +#define FUNC_GPIO26_GPIO26_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO27 (REG_IO_MUX_BASE + 0x6C) +#define FUNC_GPIO27_GPIO27 1 +#define FUNC_GPIO27_GPIO27_0 0 + +#define PERIPHS_IO_MUX_U_PAD_GPIO28 (REG_IO_MUX_BASE + 0x70) +#define FUNC_GPIO28_GPIO28 1 +#define FUNC_GPIO28_GPIO28_0 0 /** IO_MUX_DATE_REG register * Version control register diff --git a/components/soc/esp32c5/mp/include/soc/io_mux_struct.h b/components/soc/esp32c5/mp/include/soc/io_mux_struct.h index bc32968ea04d..2acfae5d3fd5 100644 --- a/components/soc/esp32c5/mp/include/soc/io_mux_struct.h +++ b/components/soc/esp32c5/mp/include/soc/io_mux_struct.h @@ -134,7 +134,7 @@ typedef struct { volatile io_mux_date_reg_t date; } io_mux_dev_t; -extern io_mux_dev_t IOMUX; +extern io_mux_dev_t IO_MUX; #ifndef __cplusplus _Static_assert(sizeof(io_mux_dev_t) == 0x200, "Invalid size of io_mux_dev_t structure"); diff --git a/components/soc/esp32c5/mp/include/soc/lp_uart_struct.h b/components/soc/esp32c5/mp/include/soc/lp_uart_struct.h index ad53ed0d9d8f..316b3bc1b3fe 100644 --- a/components/soc/esp32c5/mp/include/soc/lp_uart_struct.h +++ b/components/soc/esp32c5/mp/include/soc/lp_uart_struct.h @@ -844,7 +844,22 @@ typedef union { */ typedef union { struct { - uint32_t reserved_0:24; + /** sclk_div_b : R/W; bitpos: [5:0]; default: 0; + * The denominator of the frequency divider factor. + * Only available to LP UART instance + */ + uint32_t sclk_div_b:6; + /** sclk_div_a : R/W; bitpos: [11:6]; default: 0; + * The numerator of the frequency divider factor. + * Only available to LP UART instance + */ + uint32_t sclk_div_a:6; + /** sclk_div_num : R/W; bitpos: [19:12]; default: 1; + * The integral part of the frequency divider factor. + * Only available to LP UART instance + */ + uint32_t sclk_div_num:8; + uint32_t reserved_20:4; /** tx_sclk_en : R/W; bitpos: [24]; default: 1; * Configures whether or not to enable LP UART TX clock.\\ * 0: Disable\\ diff --git a/components/soc/esp32c5/mp/include/soc/reg_base.h b/components/soc/esp32c5/mp/include/soc/reg_base.h index bfd38466861f..a7b52e5797d6 100644 --- a/components/soc/esp32c5/mp/include/soc/reg_base.h +++ b/components/soc/esp32c5/mp/include/soc/reg_base.h @@ -63,6 +63,7 @@ #define DR_REG_PCR_BASE 0x60096000 #define DR_REG_TEE_BASE 0x60098000 #define DR_REG_HP_APM_BASE 0x60099000 +#define DR_REG_LP_APM0_BASE 0x60099800 #define DR_REG_MISC_BASE 0x6009F000 /** diff --git a/components/soc/esp32c5/mp/include/soc/retention_periph_defs.h b/components/soc/esp32c5/mp/include/soc/retention_periph_defs.h new file mode 100644 index 000000000000..2ef044eb4021 --- /dev/null +++ b/components/soc/esp32c5/mp/include/soc/retention_periph_defs.h @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum periph_retention_module { + SLEEP_RETENTION_MODULE_MIN = 0, + /* clock module, which includes system and modem */ + SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, + SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2, + + /* modem module, which includes WiFi, BLE and 802.15.4 */ + SLEEP_RETENTION_MODULE_WIFI_MAC = 10, + SLEEP_RETENTION_MODULE_WIFI_BB = 11, + SLEEP_RETENTION_MODULE_BLE_MAC = 12, + SLEEP_RETENTION_MODULE_BT_BB = 13, + SLEEP_RETENTION_MODULE_802154_MAC = 14, + + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_SYS_PERIPH = 16, + + SLEEP_RETENTION_MODULE_ADC = 17, + + SLEEP_RETENTION_MODULE_GDMA_CH0 = 24, + SLEEP_RETENTION_MODULE_GDMA_CH1 = 25, + SLEEP_RETENTION_MODULE_GDMA_CH2 = 26, + + SLEEP_RETENTION_MODULE_MAX = 31 +} periph_retention_module_t; + +typedef enum periph_retention_module_bitmap { + /* clock module, which includes system and modem */ + SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM), + SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM), + + /* modem module, which includes WiFi, BLE and 802.15.4 */ + SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC), + SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB), + SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC), + SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB), + SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC), + + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), + + SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC), + + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), + SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), + SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), + SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1 +} periph_retention_module_bitmap_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c5/mp/include/soc/sha_reg.h b/components/soc/esp32c5/mp/include/soc/sha_reg.h index d49c15e26711..ab9f346e774c 100644 --- a/components/soc/esp32c5/mp/include/soc/sha_reg.h +++ b/components/soc/esp32c5/mp/include/soc/sha_reg.h @@ -172,150 +172,6 @@ extern "C" { #define SHA_M_MEM (DR_REG_SHA_BASE + 0x80) #define SHA_M_MEM_SIZE_BYTES 64 -/** SHA_3_MODE_REG register - * Initial configuration register 0. - */ -#define SHA_3_MODE_REG (DR_REG_SHA_BASE + 0x800) -/** SHA_3_MODE : R/W; bitpos: [2:0]; default: 0; - * Sha3 mode - */ -#define SHA_3_MODE 0x00000007U -#define SHA_3_MODE_M (SHA_3_MODE_V << SHA_3_MODE_S) -#define SHA_3_MODE_V 0x00000007U -#define SHA_3_MODE_S 0 - -/** SHA_3_CLEAN_M_REG register - * Initial configuration register 1. - */ -#define SHA_3_CLEAN_M_REG (DR_REG_SHA_BASE + 0x804) -/** SHA_3_CLEAN_M : WO; bitpos: [0]; default: 0; - * Clean Message. - */ -#define SHA_3_CLEAN_M (BIT(0)) -#define SHA_3_CLEAN_M_M (SHA_3_CLEAN_M_V << SHA_3_CLEAN_M_S) -#define SHA_3_CLEAN_M_V 0x00000001U -#define SHA_3_CLEAN_M_S 0 - -/** SHA_3_DMA_BLOCK_NUM_REG register - * DMA configuration register 0. - */ -#define SHA_3_DMA_BLOCK_NUM_REG (DR_REG_SHA_BASE + 0x80c) -/** SHA_3_DMA_BLOCK_NUM : R/W; bitpos: [5:0]; default: 0; - * DMA-SHA3 block number. - */ -#define SHA_3_DMA_BLOCK_NUM 0x0000003FU -#define SHA_3_DMA_BLOCK_NUM_M (SHA_3_DMA_BLOCK_NUM_V << SHA_3_DMA_BLOCK_NUM_S) -#define SHA_3_DMA_BLOCK_NUM_V 0x0000003FU -#define SHA_3_DMA_BLOCK_NUM_S 0 - -/** SHA_3_START_REG register - * Typical SHA3 configuration register 0. - */ -#define SHA_3_START_REG (DR_REG_SHA_BASE + 0x810) -/** SHA_3_START : WO; bitpos: [0]; default: 0; - * Start typical sha3. - */ -#define SHA_3_START (BIT(0)) -#define SHA_3_START_M (SHA_3_START_V << SHA_3_START_S) -#define SHA_3_START_V 0x00000001U -#define SHA_3_START_S 0 - -/** SHA_3_CONTINUE_REG register - * Typical SHA3 configuration register 1. - */ -#define SHA_3_CONTINUE_REG (DR_REG_SHA_BASE + 0x814) -/** SHA_3_CONTINUE : WO; bitpos: [0]; default: 0; - * Continue typical sha3. - */ -#define SHA_3_CONTINUE (BIT(0)) -#define SHA_3_CONTINUE_M (SHA_3_CONTINUE_V << SHA_3_CONTINUE_S) -#define SHA_3_CONTINUE_V 0x00000001U -#define SHA_3_CONTINUE_S 0 - -/** SHA_3_BUSY_REG register - * Busy register. - */ -#define SHA_3_BUSY_REG (DR_REG_SHA_BASE + 0x818) -/** SHA_3_BUSY_REG : RO; bitpos: [0]; default: 0; - * Sha3 busy state. 1'b0: idle. 1'b1: busy. - */ -#define SHA_3_BUSY_REG (BIT(0)) -#define SHA_3_BUSY_REG_M (SHA_3_BUSY_REG_V << SHA_3_BUSY_REG_S) -#define SHA_3_BUSY_REG_V 0x00000001U -#define SHA_3_BUSY_REG_S 0 - -/** SHA_3_DMA_START_REG register - * DMA configuration register 1. - */ -#define SHA_3_DMA_START_REG (DR_REG_SHA_BASE + 0x81c) -/** SHA_3_DMA_START : WO; bitpos: [0]; default: 0; - * Start dma-sha3. - */ -#define SHA_3_DMA_START (BIT(0)) -#define SHA_3_DMA_START_M (SHA_3_DMA_START_V << SHA_3_DMA_START_S) -#define SHA_3_DMA_START_V 0x00000001U -#define SHA_3_DMA_START_S 0 - -/** SHA_3_DMA_CONTINUE_REG register - * DMA configuration register 2. - */ -#define SHA_3_DMA_CONTINUE_REG (DR_REG_SHA_BASE + 0x820) -/** SHA_3_DMA_CONTINUE : WO; bitpos: [0]; default: 0; - * Continue dma-sha3. - */ -#define SHA_3_DMA_CONTINUE (BIT(0)) -#define SHA_3_DMA_CONTINUE_M (SHA_3_DMA_CONTINUE_V << SHA_3_DMA_CONTINUE_S) -#define SHA_3_DMA_CONTINUE_V 0x00000001U -#define SHA_3_DMA_CONTINUE_S 0 - -/** SHA_3_CLEAR_INT_REG register - * Interrupt clear register. - */ -#define SHA_3_CLEAR_INT_REG (DR_REG_SHA_BASE + 0x824) -/** SHA_3_CLEAR_INT : WO; bitpos: [0]; default: 0; - * Clear sha3 interrupt. - */ -#define SHA_3_CLEAR_INT (BIT(0)) -#define SHA_3_CLEAR_INT_M (SHA_3_CLEAR_INT_V << SHA_3_CLEAR_INT_S) -#define SHA_3_CLEAR_INT_V 0x00000001U -#define SHA_3_CLEAR_INT_S 0 - -/** SHA_3_INT_ENA_REG register - * Interrupt enable register. - */ -#define SHA_3_INT_ENA_REG (DR_REG_SHA_BASE + 0x828) -/** SHA_3_INT_ENA : R/W; bitpos: [0]; default: 0; - * Sha3 interrupt enable register. 1'b0: disable(default). 1'b1:enable - */ -#define SHA_3_INT_ENA (BIT(0)) -#define SHA_3_INT_ENA_M (SHA_3_INT_ENA_V << SHA_3_INT_ENA_S) -#define SHA_3_INT_ENA_V 0x00000001U -#define SHA_3_INT_ENA_S 0 - -/** SHA_3_SHAKE_LENGTH_REG register - * DMA configuration register 3. - */ -#define SHA_3_SHAKE_LENGTH_REG (DR_REG_SHA_BASE + 0x82c) -/** SHA_3_SHAKE_LENGTH : WO; bitpos: [10:0]; default: 50; - * SHAKE output hash word length - */ -#define SHA_3_SHAKE_LENGTH 0x000007FFU -#define SHA_3_SHAKE_LENGTH_M (SHA_3_SHAKE_LENGTH_V << SHA_3_SHAKE_LENGTH_S) -#define SHA_3_SHAKE_LENGTH_V 0x000007FFU -#define SHA_3_SHAKE_LENGTH_S 0 - -/** SHA_3_M_OUT_MEM register - * Sha3 hash reg which contains intermediate hash or finial hash. - */ -#define SHA_3_M_OUT_MEM (DR_REG_SHA_BASE + 0x900) -#define SHA_3_M_OUT_MEM_SIZE_BYTES 200 - -/** SHA_3_M_MEM register - * Sha3 message reg which contains message. - */ -#define SHA_3_M_MEM (DR_REG_SHA_BASE + 0xa00) -#define SHA_3_M_MEM_SIZE_BYTES 200 - #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c5/mp/include/soc/sha_struct.h b/components/soc/esp32c5/mp/include/soc/sha_struct.h index db2cb97f4432..bc2cd2cef2cd 100644 --- a/components/soc/esp32c5/mp/include/soc/sha_struct.h +++ b/components/soc/esp32c5/mp/include/soc/sha_struct.h @@ -127,118 +127,6 @@ typedef union { uint32_t val; } sha_t_length_reg_t; -/** Type of mode register - * Initial configuration register 0. - */ -typedef union { - struct { - /** mode : R/W; bitpos: [2:0]; default: 0; - * Sha3 mode - */ - uint32_t mode:3; - uint32_t reserved_3:29; - }; - uint32_t val; -} sha_3_mode_reg_t; - -/** Type of clean_m register - * Initial configuration register 1. - */ -typedef union { - struct { - /** clean_m : WO; bitpos: [0]; default: 0; - * Clean Message. - */ - uint32_t clean_m:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} sha_3_clean_m_reg_t; - -/** Type of dma_block_num register - * DMA configuration register 0. - */ -typedef union { - struct { - /** dma_block_num : R/W; bitpos: [5:0]; default: 0; - * DMA-SHA3 block number. - */ - uint32_t dma_block_num:6; - uint32_t reserved_6:26; - }; - uint32_t val; -} sha_3_dma_block_num_reg_t; - -/** Type of start register - * Typical SHA3 configuration register 0. - */ -typedef union { - struct { - /** start : WO; bitpos: [0]; default: 0; - * Start typical sha3. - */ - uint32_t start:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} sha_3_start_reg_t; - -/** Type of continue register - * Typical SHA3 configuration register 1. - */ -typedef union { - struct { - /** conti : WO; bitpos: [0]; default: 0; - * Continue typical sha3. - */ - uint32_t conti:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} sha_3_continue_reg_t; - -/** Type of dma_start register - * DMA configuration register 1. - */ -typedef union { - struct { - /** dma_start : WO; bitpos: [0]; default: 0; - * Start dma-sha3. - */ - uint32_t dma_start:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} sha_3_dma_start_reg_t; - -/** Type of dma_continue register - * DMA configuration register 2. - */ -typedef union { - struct { - /** dma_continue : WO; bitpos: [0]; default: 0; - * Continue dma-sha3. - */ - uint32_t dma_continue:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} sha_3_dma_continue_reg_t; - -/** Type of shake_length register - * DMA configuration register 3. - */ -typedef union { - struct { - /** shake_length : WO; bitpos: [10:0]; default: 50; - * SHAKE output hash word length - */ - uint32_t shake_length:11; - uint32_t reserved_11:21; - }; - uint32_t val; -} sha_3_shake_length_reg_t; - /** Group: Status Registers */ /** Type of busy register @@ -306,52 +194,6 @@ typedef union { /** Group: memory type */ -/** Group: Status Register */ -/** Type of busy register - * Busy register. - */ -typedef union { - struct { - /** busy_reg : RO; bitpos: [0]; default: 0; - * Sha3 busy state. 1'b0: idle. 1'b1: busy. - */ - uint32_t busy_reg:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} sha_3_busy_reg_t; - - -/** Group: Interrupt Register */ -/** Type of clear_int register - * Interrupt clear register. - */ -typedef union { - struct { - /** clear_int : WO; bitpos: [0]; default: 0; - * Clear sha3 interrupt. - */ - uint32_t clear_int:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} sha_3_clear_int_reg_t; - -/** Type of int_ena register - * Interrupt enable register. - */ -typedef union { - struct { - /** int_ena : R/W; bitpos: [0]; default: 0; - * Sha3 interrupt enable register. 1'b0: disable(default). 1'b1:enable - */ - uint32_t int_ena:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} sha_3_int_ena_reg_t; - - typedef struct { volatile sha_mode_reg_t mode; volatile sha_t_string_reg_t t_string; @@ -368,29 +210,12 @@ typedef struct { uint32_t reserved_030[4]; volatile uint32_t h[16]; volatile uint32_t m[16]; - uint32_t reserved_0c0[464]; - volatile sha_3_mode_reg_t mode_3; - volatile sha_3_clean_m_reg_t clean_m_3; - uint32_t reserved_808; - volatile sha_3_dma_block_num_reg_t dma_block_num_3; - volatile sha_3_start_reg_t start_3; - volatile sha_3_continue_reg_t continue_3; - volatile sha_3_busy_reg_t busy_3; - volatile sha_3_dma_start_reg_t dma_start_3; - volatile sha_3_dma_continue_reg_t dma_continue_3; - volatile sha_3_clear_int_reg_t clear_int_3; - volatile sha_3_int_ena_reg_t int_ena_3; - volatile sha_3_shake_length_reg_t shake_length_3; - uint32_t reserved_830[52]; - volatile uint32_t m_out_3[50]; - uint32_t reserved_9c8[14]; - volatile uint32_t m_3[50]; } sha_dev_t; extern sha_dev_t SHA; #ifndef __cplusplus -_Static_assert(sizeof(sha_dev_t) == 0xac8, "Invalid size of sha_dev_t structure"); +_Static_assert(sizeof(sha_dev_t) == 0xc0, "Invalid size of sha_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32c5/mp/include/soc/soc.h b/components/soc/esp32c5/mp/include/soc/soc.h index 3cf20c4c3ac6..5c3ac9c8e9c8 100644 --- a/components/soc/esp32c5/mp/include/soc/soc.h +++ b/components/soc/esp32c5/mp/include/soc/soc.h @@ -208,7 +208,7 @@ #define SOC_DEBUG_HIGH 0x28000000 // Start (highest address) of ROM boot stack, only relevant during early boot -#define SOC_ROM_STACK_START 0x4085c8d0 +#define SOC_ROM_STACK_START 0x4085e9a0 #define SOC_ROM_STACK_SIZE 0x2000 //On RISC-V CPUs, the interrupt sources are all external interrupts, whose type, source and priority are configured by SW. diff --git a/components/soc/esp32c5/mp/include/soc/soc_caps.h b/components/soc/esp32c5/mp/include/soc/soc_caps.h index e63311e1e9db..b49d69e530b7 100644 --- a/components/soc/esp32c5/mp/include/soc/soc_caps.h +++ b/components/soc/esp32c5/mp/include/soc/soc_caps.h @@ -19,16 +19,16 @@ /*-------------------------- COMMON CAPS ---------------------------------------*/ // #define SOC_ADC_SUPPORTED 1 // TODO: [ESP32C5] IDF-8701 // #define SOC_DEDICATED_GPIO_SUPPORTED 1 // TODO: [ESP32C5] IDF-8725 -#define SOC_UART_SUPPORTED 1 // TODO: [ESP32C5] IDF-8722 -// #define SOC_GDMA_SUPPORTED 1 // TODO: [ESP32C5] IDF-8710 -// #define SOC_AHB_GDMA_SUPPORTED 1 // TODO: [ESP32C5] IDF-8710 +#define SOC_UART_SUPPORTED 1 +#define SOC_GDMA_SUPPORTED 1 +#define SOC_AHB_GDMA_SUPPORTED 1 #define SOC_GPTIMER_SUPPORTED 1 // #define SOC_PCNT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8683 // #define SOC_MCPWM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8709 // #define SOC_TWAI_SUPPORTED 1 // TODO: [ESP32C5] IDF-8691 // #define SOC_ETM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8693 // #define SOC_PARLIO_SUPPORTED 1 // TODO: [ESP32C5] IDF-8685, IDF-8686 -// #define SOC_ASYNC_MEMCPY_SUPPORTED 1 // TODO: [ESP32C5] IDF-8716 +#define SOC_ASYNC_MEMCPY_SUPPORTED 1 // #define SOC_USB_SERIAL_JTAG_SUPPORTED 1 // TODO: [ESP32C5] IDF-8721 // #define SOC_TEMP_SENSOR_SUPPORTED 1 // TODO: [ESP32C5] IDF-8727 // #define SOC_WIFI_SUPPORTED 1 // TODO: [ESP32C5] IDF-8851 @@ -55,12 +55,12 @@ #define SOC_FLASH_ENC_SUPPORTED 1 // TODO: [ESP32C5] IDF-8622 // #define SOC_SECURE_BOOT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8623 // #define SOC_BOD_SUPPORTED 1 // TODO: [ESP32C5] IDF-8647 -// #define SOC_APM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8614 +// #define SOC_APM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8614, IDF-8615 // #define SOC_PMU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8667 // #define SOC_PAU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 // #define SOC_LP_TIMER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8636 // #define SOC_LP_AON_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 -// #define SOC_LP_PERIPHERALS_SUPPORTED 1 // TODO: [ESP32C5] IDF-8695, IDF-8723, IDF-8719 +#define SOC_LP_PERIPHERALS_SUPPORTED 1 // #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32C5] IDF-8634 // #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32C5] IDF-8633 // #define SOC_CLK_TREE_SUPPORTED 1 // TODO: [ESP32C5] IDF-8642 @@ -72,6 +72,7 @@ // #define SOC_KEY_MANAGER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8621 // #define SOC_HUK_SUPPORTED 1 // TODO: [ESP32C5] IDF-8617 // #define SOC_MODEM_CLOCK_SUPPORTED 1 // TODO: [ESP32C5] IDF-8845 +// #define SOC_PM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8643 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 @@ -163,48 +164,50 @@ See TRM DS chapter for more details */ // #define SOC_DS_KEY_CHECK_MAX_WAIT_US (1100) +/*-------------------------- DMA Common CAPS ----------------------------------------*/ +#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */ + /*-------------------------- GDMA CAPS -------------------------------------*/ -// #define SOC_AHB_GDMA_VERSION 1U -// #define SOC_GDMA_NUM_GROUPS_MAX 1U -// #define SOC_GDMA_PAIRS_PER_GROUP_MAX 3 -// #define SOC_GDMA_SUPPORT_ETM 1 // Support ETM submodule +#define SOC_AHB_GDMA_VERSION 2 +#define SOC_GDMA_NUM_GROUPS_MAX 1U +#define SOC_GDMA_PAIRS_PER_GROUP_MAX 3 +// #define SOC_GDMA_SUPPORT_ETM 1 // Support ETM submodule TODO: IDF-9224 +// #define SOC_GDMA_SUPPORT_SLEEP_RETENTION 1 // TODO: IDF-9225 /*-------------------------- ETM CAPS --------------------------------------*/ // #define SOC_ETM_GROUPS 1U // Number of ETM groups // #define SOC_ETM_CHANNELS_PER_GROUP 50 // Number of ETM channels in the group /*-------------------------- GPIO CAPS ---------------------------------------*/ -// TODO: [ESP32C5] IDF-8717 // ESP32-C5 has 1 GPIO peripheral -// #define SOC_GPIO_PORT 1U +#define SOC_GPIO_PORT 1U #define SOC_GPIO_PIN_COUNT 29 // #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1 // #define SOC_GPIO_FLEX_GLITCH_FILTER_NUM 8 +#define SOC_GPIO_SUPPORT_PIN_HYS_FILTER 1 // GPIO peripheral has the ETM extension // #define SOC_GPIO_SUPPORT_ETM 1 -// #define SOC_GPIO_ETM_EVENTS_PER_GROUP 8 -// #define SOC_GPIO_ETM_TASKS_PER_GROUP 8 // Target has the full LP IO subsystem // On ESP32-C5, Digital IOs have their own registers to control pullup/down capability, independent of LP registers. -// #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) +#define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) // GPIO0~7 on ESP32C5 can support chip deep sleep wakeup -// #define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) +// #define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) // TODO: [ESP32C5] IDF-8719 #define SOC_GPIO_VALID_GPIO_MASK ((1U<= bus_name##_ADDRESS_LOW && (vaddr) < bus_name##_ADDRESS_HIGH) diff --git a/components/soc/esp32p4/include/soc/gpio_sig_map.h b/components/soc/esp32p4/include/soc/gpio_sig_map.h index d0653170fdd1..00aba01a22d9 100644 --- a/components/soc/esp32p4/include/soc/gpio_sig_map.h +++ b/components/soc/esp32p4/include/soc/gpio_sig_map.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -207,12 +207,12 @@ #define TWAI0_STANDBY_PAD_OUT_IDX 105 #define PWM1_CAP2_PAD_IN_IDX 106 #define TWAI1_STANDBY_PAD_OUT_IDX 106 -#define GMII_MDI_PAD_IN_IDX 107 +#define MII_MDI_PAD_IN_IDX 107 #define TWAI2_STANDBY_PAD_OUT_IDX 107 -#define GMAC_PHY_COL_PAD_IN_IDX 108 -#define GMII_MDC_PAD_OUT_IDX 108 -#define GMAC_PHY_CRS_PAD_IN_IDX 109 -#define GMII_MDO_PAD_OUT_IDX 109 +#define EMAC_PHY_COL_PAD_IN_IDX 108 +#define MII_MDC_PAD_OUT_IDX 108 +#define EMAC_PHY_CRS_PAD_IN_IDX 109 +#define MII_MDO_PAD_OUT_IDX 109 #define USB_OTG11_IDDIG_PAD_IN_IDX 110 #define USB_SRP_DISCHRGVBUS_PAD_OUT_IDX 110 #define USB_OTG11_AVALID_PAD_IN_IDX 111 @@ -339,21 +339,21 @@ #define LCD_DATA_OUT_PAD_OUT22_IDX 176 #define CAM_DATA_IN_PAD_IN15_IDX 177 #define LCD_DATA_OUT_PAD_OUT23_IDX 177 -#define GMAC_PHY_RXDV_PAD_IN_IDX 178 -#define GMAC_PHY_TXEN_PAD_OUT_IDX 178 -#define GMAC_PHY_RXD0_PAD_IN_IDX 179 -#define GMAC_PHY_TXD0_PAD_OUT_IDX 179 -#define GMAC_PHY_RXD1_PAD_IN_IDX 180 -#define GMAC_PHY_TXD1_PAD_OUT_IDX 180 -#define GMAC_PHY_RXD2_PAD_IN_IDX 181 -#define GMAC_PHY_TXD2_PAD_OUT_IDX 181 -#define GMAC_PHY_RXD3_PAD_IN_IDX 182 -#define GMAC_PHY_TXD3_PAD_OUT_IDX 182 -#define GMAC_PHY_RXER_PAD_IN_IDX 183 -#define GMAC_PHY_TXER_PAD_OUT_IDX 183 -#define GMAC_RX_CLK_PAD_IN_IDX 184 +#define EMAC_PHY_RXDV_PAD_IN_IDX 178 +#define EMAC_PHY_TXEN_PAD_OUT_IDX 178 +#define EMAC_PHY_RXD0_PAD_IN_IDX 179 +#define EMAC_PHY_TXD0_PAD_OUT_IDX 179 +#define EMAC_PHY_RXD1_PAD_IN_IDX 180 +#define EMAC_PHY_TXD1_PAD_OUT_IDX 180 +#define EMAC_PHY_RXD2_PAD_IN_IDX 181 +#define EMAC_PHY_TXD2_PAD_OUT_IDX 181 +#define EMAC_PHY_RXD3_PAD_IN_IDX 182 +#define EMAC_PHY_TXD3_PAD_OUT_IDX 182 +#define EMAC_PHY_RXER_PAD_IN_IDX 183 +#define EMAC_PHY_TXER_PAD_OUT_IDX 183 +#define EMAC_RX_CLK_PAD_IN_IDX 184 #define DBG_CH0_CLK_IDX 184 -#define GMAC_TX_CLK_PAD_IN_IDX 185 +#define EMAC_TX_CLK_PAD_IN_IDX 185 #define DBG_CH1_CLK_IDX 185 #define PARLIO_RX_CLK_PAD_IN_IDX 186 #define PARLIO_RX_CLK_PAD_OUT_IDX 186 diff --git a/components/soc/esp32p4/include/soc/hp2lp_peri_pms_reg.h b/components/soc/esp32p4/include/soc/hp2lp_peri_pms_reg.h index 29586b4b6877..903bfc178b53 100644 --- a/components/soc/esp32p4/include/soc/hp2lp_peri_pms_reg.h +++ b/components/soc/esp32p4/include/soc/hp2lp_peri_pms_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,740 +11,958 @@ extern "C" { #endif -/** TEE_HP2LP_TEE_PMS_DATE_REG register - * NA +/** PMS_HP2LP_PERI_PMS_DATE_REG register + * Version control register */ -#define TEE_HP2LP_TEE_PMS_DATE_REG (DR_REG_TEE_BASE + 0x0) -/** TEE_TEE_DATE : R/W; bitpos: [31:0]; default: 2294790; - * NA +#define PMS_HP2LP_PERI_PMS_DATE_REG (DR_REG_HP2LP_PERI_PMS_BASE + 0x0) +/** PMS_HP2LP_PERI_PMS_DATE : R/W; bitpos: [31:0]; default: 2294790; + * Version control register */ -#define TEE_TEE_DATE 0xFFFFFFFFU -#define TEE_TEE_DATE_M (TEE_TEE_DATE_V << TEE_TEE_DATE_S) -#define TEE_TEE_DATE_V 0xFFFFFFFFU -#define TEE_TEE_DATE_S 0 +#define PMS_HP2LP_PERI_PMS_DATE 0xFFFFFFFFU +#define PMS_HP2LP_PERI_PMS_DATE_M (PMS_HP2LP_PERI_PMS_DATE_V << PMS_HP2LP_PERI_PMS_DATE_S) +#define PMS_HP2LP_PERI_PMS_DATE_V 0xFFFFFFFFU +#define PMS_HP2LP_PERI_PMS_DATE_S 0 -/** TEE_PMS_CLK_EN_REG register - * NA - */ -#define TEE_PMS_CLK_EN_REG (DR_REG_TEE_BASE + 0x4) -/** TEE_REG_CLK_EN : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CLK_EN (BIT(0)) -#define TEE_REG_CLK_EN_M (TEE_REG_CLK_EN_V << TEE_REG_CLK_EN_S) -#define TEE_REG_CLK_EN_V 0x00000001U -#define TEE_REG_CLK_EN_S 0 +/** PMS_HP2LP_PERI_PMS_CLK_EN_REG register + * Clock gating register + */ +#define PMS_HP2LP_PERI_PMS_CLK_EN_REG (DR_REG_HP2LP_PERI_PMS_BASE + 0x4) +/** PMS_HP2LP_PERI_PMS_CLK_EN : R/W; bitpos: [0]; default: 1; + * Configures whether to keep the clock always on. + * 0: Enable automatic clock gating + * 1: Keep the clock always on + */ +#define PMS_HP2LP_PERI_PMS_CLK_EN (BIT(0)) +#define PMS_HP2LP_PERI_PMS_CLK_EN_M (PMS_HP2LP_PERI_PMS_CLK_EN_V << PMS_HP2LP_PERI_PMS_CLK_EN_S) +#define PMS_HP2LP_PERI_PMS_CLK_EN_V 0x00000001U +#define PMS_HP2LP_PERI_PMS_CLK_EN_S 0 -/** TEE_HP_CORE0_MM_PMS_REG0_REG register - * NA - */ -#define TEE_HP_CORE0_MM_PMS_REG0_REG (DR_REG_TEE_BASE + 0x8) -/** TEE_REG_HP_CORE0_MM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_SYSREG_ALLOW (BIT(0)) -#define TEE_REG_HP_CORE0_MM_LP_SYSREG_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_SYSREG_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_SYSREG_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_SYSREG_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_SYSREG_ALLOW_S 0 -/** TEE_REG_HP_CORE0_MM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_AONCLKRST_ALLOW (BIT(1)) -#define TEE_REG_HP_CORE0_MM_LP_AONCLKRST_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_AONCLKRST_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_AONCLKRST_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_AONCLKRST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_AONCLKRST_ALLOW_S 1 -/** TEE_REG_HP_CORE0_MM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_TIMER_ALLOW (BIT(2)) -#define TEE_REG_HP_CORE0_MM_LP_TIMER_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_TIMER_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_TIMER_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_TIMER_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_TIMER_ALLOW_S 2 -/** TEE_REG_HP_CORE0_MM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_ANAPERI_ALLOW (BIT(3)) -#define TEE_REG_HP_CORE0_MM_LP_ANAPERI_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_ANAPERI_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_ANAPERI_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_ANAPERI_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_ANAPERI_ALLOW_S 3 -/** TEE_REG_HP_CORE0_MM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_PMU_ALLOW (BIT(4)) -#define TEE_REG_HP_CORE0_MM_LP_PMU_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_PMU_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_PMU_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_PMU_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_PMU_ALLOW_S 4 -/** TEE_REG_HP_CORE0_MM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_WDT_ALLOW (BIT(5)) -#define TEE_REG_HP_CORE0_MM_LP_WDT_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_WDT_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_WDT_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_WDT_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_WDT_ALLOW_S 5 -/** TEE_REG_HP_CORE0_MM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_MAILBOX_ALLOW (BIT(6)) -#define TEE_REG_HP_CORE0_MM_LP_MAILBOX_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_MAILBOX_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_MAILBOX_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_MAILBOX_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_MAILBOX_ALLOW_S 6 -/** TEE_REG_HP_CORE0_MM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_RTC_ALLOW (BIT(7)) -#define TEE_REG_HP_CORE0_MM_LP_RTC_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_RTC_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_RTC_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_RTC_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_RTC_ALLOW_S 7 -/** TEE_REG_HP_CORE0_MM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_PERICLKRST_ALLOW (BIT(8)) -#define TEE_REG_HP_CORE0_MM_LP_PERICLKRST_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_PERICLKRST_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_PERICLKRST_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_PERICLKRST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_PERICLKRST_ALLOW_S 8 -/** TEE_REG_HP_CORE0_MM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_UART_ALLOW (BIT(9)) -#define TEE_REG_HP_CORE0_MM_LP_UART_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_UART_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_UART_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_UART_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_UART_ALLOW_S 9 -/** TEE_REG_HP_CORE0_MM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_I2C_ALLOW (BIT(10)) -#define TEE_REG_HP_CORE0_MM_LP_I2C_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_I2C_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_I2C_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_I2C_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_I2C_ALLOW_S 10 -/** TEE_REG_HP_CORE0_MM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_SPI_ALLOW (BIT(11)) -#define TEE_REG_HP_CORE0_MM_LP_SPI_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_SPI_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_SPI_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_SPI_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_SPI_ALLOW_S 11 -/** TEE_REG_HP_CORE0_MM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_I2CMST_ALLOW (BIT(12)) -#define TEE_REG_HP_CORE0_MM_LP_I2CMST_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_I2CMST_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_I2CMST_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_I2CMST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_I2CMST_ALLOW_S 12 -/** TEE_REG_HP_CORE0_MM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_I2S_ALLOW (BIT(13)) -#define TEE_REG_HP_CORE0_MM_LP_I2S_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_I2S_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_I2S_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_I2S_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_I2S_ALLOW_S 13 -/** TEE_REG_HP_CORE0_MM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_ADC_ALLOW (BIT(14)) -#define TEE_REG_HP_CORE0_MM_LP_ADC_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_ADC_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_ADC_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_ADC_ALLOW_S 14 -/** TEE_REG_HP_CORE0_MM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_TOUCH_ALLOW (BIT(15)) -#define TEE_REG_HP_CORE0_MM_LP_TOUCH_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_TOUCH_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_TOUCH_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_TOUCH_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_TOUCH_ALLOW_S 15 -/** TEE_REG_HP_CORE0_MM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_IOMUX_ALLOW (BIT(16)) -#define TEE_REG_HP_CORE0_MM_LP_IOMUX_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_IOMUX_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_IOMUX_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_IOMUX_ALLOW_S 16 -/** TEE_REG_HP_CORE0_MM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_INTR_ALLOW (BIT(17)) -#define TEE_REG_HP_CORE0_MM_LP_INTR_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_INTR_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_INTR_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_INTR_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_INTR_ALLOW_S 17 -/** TEE_REG_HP_CORE0_MM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_EFUSE_ALLOW (BIT(18)) -#define TEE_REG_HP_CORE0_MM_LP_EFUSE_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_EFUSE_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_EFUSE_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_EFUSE_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_EFUSE_ALLOW_S 18 -/** TEE_REG_HP_CORE0_MM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_PMS_ALLOW (BIT(19)) -#define TEE_REG_HP_CORE0_MM_LP_PMS_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_PMS_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_PMS_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_PMS_ALLOW_S 19 -/** TEE_REG_HP_CORE0_MM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_HP2LP_PMS_ALLOW (BIT(20)) -#define TEE_REG_HP_CORE0_MM_HP2LP_PMS_ALLOW_M (TEE_REG_HP_CORE0_MM_HP2LP_PMS_ALLOW_V << TEE_REG_HP_CORE0_MM_HP2LP_PMS_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_HP2LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_HP2LP_PMS_ALLOW_S 20 -/** TEE_REG_HP_CORE0_MM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_TSENS_ALLOW (BIT(21)) -#define TEE_REG_HP_CORE0_MM_LP_TSENS_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_TSENS_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_TSENS_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_TSENS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_TSENS_ALLOW_S 21 -/** TEE_REG_HP_CORE0_MM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_HUK_ALLOW (BIT(22)) -#define TEE_REG_HP_CORE0_MM_LP_HUK_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_HUK_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_HUK_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_HUK_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_HUK_ALLOW_S 22 -/** TEE_REG_HP_CORE0_MM_LP_TCM_RAM_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_MM_LP_TCM_RAM_ALLOW (BIT(23)) -#define TEE_REG_HP_CORE0_MM_LP_TCM_RAM_ALLOW_M (TEE_REG_HP_CORE0_MM_LP_TCM_RAM_ALLOW_V << TEE_REG_HP_CORE0_MM_LP_TCM_RAM_ALLOW_S) -#define TEE_REG_HP_CORE0_MM_LP_TCM_RAM_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_MM_LP_TCM_RAM_ALLOW_S 23 +/** PMS_HP_CORE0_MM_PMS_REG0_REG register + * Permission control register0 for HP CPU0 in machine mode + */ +#define PMS_HP_CORE0_MM_PMS_REG0_REG (DR_REG_HP2LP_PERI_PMS_BASE + 0x8) +/** PMS_HP_CORE0_MM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP System + * Registers. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_SYSREG_ALLOW (BIT(0)) +#define PMS_HP_CORE0_MM_LP_SYSREG_ALLOW_M (PMS_HP_CORE0_MM_LP_SYSREG_ALLOW_V << PMS_HP_CORE0_MM_LP_SYSREG_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_SYSREG_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_SYSREG_ALLOW_S 0 +/** PMS_HP_CORE0_MM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP_AONCLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_AONCLKRST_ALLOW (BIT(1)) +#define PMS_HP_CORE0_MM_LP_AONCLKRST_ALLOW_M (PMS_HP_CORE0_MM_LP_AONCLKRST_ALLOW_V << PMS_HP_CORE0_MM_LP_AONCLKRST_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_AONCLKRST_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_AONCLKRST_ALLOW_S 1 +/** PMS_HP_CORE0_MM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_TIMER_ALLOW (BIT(2)) +#define PMS_HP_CORE0_MM_LP_TIMER_ALLOW_M (PMS_HP_CORE0_MM_LP_TIMER_ALLOW_V << PMS_HP_CORE0_MM_LP_TIMER_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_TIMER_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_TIMER_ALLOW_S 2 +/** PMS_HP_CORE0_MM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP ANAPERI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_ANAPERI_ALLOW (BIT(3)) +#define PMS_HP_CORE0_MM_LP_ANAPERI_ALLOW_M (PMS_HP_CORE0_MM_LP_ANAPERI_ALLOW_V << PMS_HP_CORE0_MM_LP_ANAPERI_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_ANAPERI_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_ANAPERI_ALLOW_S 3 +/** PMS_HP_CORE0_MM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP PMU. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_PMU_ALLOW (BIT(4)) +#define PMS_HP_CORE0_MM_LP_PMU_ALLOW_M (PMS_HP_CORE0_MM_LP_PMU_ALLOW_V << PMS_HP_CORE0_MM_LP_PMU_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_PMU_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_PMU_ALLOW_S 4 +/** PMS_HP_CORE0_MM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP WDT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_WDT_ALLOW (BIT(5)) +#define PMS_HP_CORE0_MM_LP_WDT_ALLOW_M (PMS_HP_CORE0_MM_LP_WDT_ALLOW_V << PMS_HP_CORE0_MM_LP_WDT_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_WDT_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_WDT_ALLOW_S 5 +/** PMS_HP_CORE0_MM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP Mailbox + * Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_MAILBOX_ALLOW (BIT(6)) +#define PMS_HP_CORE0_MM_LP_MAILBOX_ALLOW_M (PMS_HP_CORE0_MM_LP_MAILBOX_ALLOW_V << PMS_HP_CORE0_MM_LP_MAILBOX_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_MAILBOX_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_MAILBOX_ALLOW_S 6 +/** PMS_HP_CORE0_MM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP RTC. + * 0: Not allowed + * 1: Allow + */ +#define PMS_HP_CORE0_MM_LP_RTC_ALLOW (BIT(7)) +#define PMS_HP_CORE0_MM_LP_RTC_ALLOW_M (PMS_HP_CORE0_MM_LP_RTC_ALLOW_V << PMS_HP_CORE0_MM_LP_RTC_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_RTC_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_RTC_ALLOW_S 7 +/** PMS_HP_CORE0_MM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP PERICLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_PERICLKRST_ALLOW (BIT(8)) +#define PMS_HP_CORE0_MM_LP_PERICLKRST_ALLOW_M (PMS_HP_CORE0_MM_LP_PERICLKRST_ALLOW_V << PMS_HP_CORE0_MM_LP_PERICLKRST_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_PERICLKRST_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_PERICLKRST_ALLOW_S 8 +/** PMS_HP_CORE0_MM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP UART. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_UART_ALLOW (BIT(9)) +#define PMS_HP_CORE0_MM_LP_UART_ALLOW_M (PMS_HP_CORE0_MM_LP_UART_ALLOW_V << PMS_HP_CORE0_MM_LP_UART_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_UART_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_UART_ALLOW_S 9 +/** PMS_HP_CORE0_MM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP I2C. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_I2C_ALLOW (BIT(10)) +#define PMS_HP_CORE0_MM_LP_I2C_ALLOW_M (PMS_HP_CORE0_MM_LP_I2C_ALLOW_V << PMS_HP_CORE0_MM_LP_I2C_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_I2C_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_I2C_ALLOW_S 10 +/** PMS_HP_CORE0_MM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP SPI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_SPI_ALLOW (BIT(11)) +#define PMS_HP_CORE0_MM_LP_SPI_ALLOW_M (PMS_HP_CORE0_MM_LP_SPI_ALLOW_V << PMS_HP_CORE0_MM_LP_SPI_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_SPI_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_SPI_ALLOW_S 11 +/** PMS_HP_CORE0_MM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP I2C master. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_I2CMST_ALLOW (BIT(12)) +#define PMS_HP_CORE0_MM_LP_I2CMST_ALLOW_M (PMS_HP_CORE0_MM_LP_I2CMST_ALLOW_V << PMS_HP_CORE0_MM_LP_I2CMST_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_I2CMST_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_I2CMST_ALLOW_S 12 +/** PMS_HP_CORE0_MM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_I2S_ALLOW (BIT(13)) +#define PMS_HP_CORE0_MM_LP_I2S_ALLOW_M (PMS_HP_CORE0_MM_LP_I2S_ALLOW_V << PMS_HP_CORE0_MM_LP_I2S_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_I2S_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_I2S_ALLOW_S 13 +/** PMS_HP_CORE0_MM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_ADC_ALLOW (BIT(14)) +#define PMS_HP_CORE0_MM_LP_ADC_ALLOW_M (PMS_HP_CORE0_MM_LP_ADC_ALLOW_V << PMS_HP_CORE0_MM_LP_ADC_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_ADC_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_ADC_ALLOW_S 14 +/** PMS_HP_CORE0_MM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP touch + * sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_TOUCH_ALLOW (BIT(15)) +#define PMS_HP_CORE0_MM_LP_TOUCH_ALLOW_M (PMS_HP_CORE0_MM_LP_TOUCH_ALLOW_V << PMS_HP_CORE0_MM_LP_TOUCH_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_TOUCH_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_TOUCH_ALLOW_S 15 +/** PMS_HP_CORE0_MM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_IOMUX_ALLOW (BIT(16)) +#define PMS_HP_CORE0_MM_LP_IOMUX_ALLOW_M (PMS_HP_CORE0_MM_LP_IOMUX_ALLOW_V << PMS_HP_CORE0_MM_LP_IOMUX_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_IOMUX_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_IOMUX_ALLOW_S 16 +/** PMS_HP_CORE0_MM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP INTR. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_INTR_ALLOW (BIT(17)) +#define PMS_HP_CORE0_MM_LP_INTR_ALLOW_M (PMS_HP_CORE0_MM_LP_INTR_ALLOW_V << PMS_HP_CORE0_MM_LP_INTR_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_INTR_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_INTR_ALLOW_S 17 +/** PMS_HP_CORE0_MM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP eFuse. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_EFUSE_ALLOW (BIT(18)) +#define PMS_HP_CORE0_MM_LP_EFUSE_ALLOW_M (PMS_HP_CORE0_MM_LP_EFUSE_ALLOW_V << PMS_HP_CORE0_MM_LP_EFUSE_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_EFUSE_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_EFUSE_ALLOW_S 18 +/** PMS_HP_CORE0_MM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access + * LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_PMS_ALLOW (BIT(19)) +#define PMS_HP_CORE0_MM_LP_PMS_ALLOW_M (PMS_HP_CORE0_MM_LP_PMS_ALLOW_V << PMS_HP_CORE0_MM_LP_PMS_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_PMS_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_PMS_ALLOW_S 19 +/** PMS_HP_CORE0_MM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access + * HP2LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_HP2LP_PMS_ALLOW (BIT(20)) +#define PMS_HP_CORE0_MM_HP2LP_PMS_ALLOW_M (PMS_HP_CORE0_MM_HP2LP_PMS_ALLOW_V << PMS_HP_CORE0_MM_HP2LP_PMS_ALLOW_S) +#define PMS_HP_CORE0_MM_HP2LP_PMS_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_HP2LP_PMS_ALLOW_S 20 +/** PMS_HP_CORE0_MM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP temperature + * sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_TSENS_ALLOW (BIT(21)) +#define PMS_HP_CORE0_MM_LP_TSENS_ALLOW_M (PMS_HP_CORE0_MM_LP_TSENS_ALLOW_V << PMS_HP_CORE0_MM_LP_TSENS_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_TSENS_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_TSENS_ALLOW_S 21 +/** PMS_HP_CORE0_MM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to LP HUK. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_HUK_ALLOW (BIT(22)) +#define PMS_HP_CORE0_MM_LP_HUK_ALLOW_M (PMS_HP_CORE0_MM_LP_HUK_ALLOW_V << PMS_HP_CORE0_MM_LP_HUK_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_HUK_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_HUK_ALLOW_S 22 +/** PMS_HP_CORE0_MM_LP_SRAM_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access LP SRAM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_MM_LP_SRAM_ALLOW (BIT(23)) +#define PMS_HP_CORE0_MM_LP_SRAM_ALLOW_M (PMS_HP_CORE0_MM_LP_SRAM_ALLOW_V << PMS_HP_CORE0_MM_LP_SRAM_ALLOW_S) +#define PMS_HP_CORE0_MM_LP_SRAM_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_MM_LP_SRAM_ALLOW_S 23 -/** TEE_HP_CORE0_UM_PMS_REG0_REG register - * NA - */ -#define TEE_HP_CORE0_UM_PMS_REG0_REG (DR_REG_TEE_BASE + 0xc) -/** TEE_REG_HP_CORE0_UM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_SYSREG_ALLOW (BIT(0)) -#define TEE_REG_HP_CORE0_UM_LP_SYSREG_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_SYSREG_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_SYSREG_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_SYSREG_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_SYSREG_ALLOW_S 0 -/** TEE_REG_HP_CORE0_UM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_AONCLKRST_ALLOW (BIT(1)) -#define TEE_REG_HP_CORE0_UM_LP_AONCLKRST_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_AONCLKRST_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_AONCLKRST_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_AONCLKRST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_AONCLKRST_ALLOW_S 1 -/** TEE_REG_HP_CORE0_UM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_TIMER_ALLOW (BIT(2)) -#define TEE_REG_HP_CORE0_UM_LP_TIMER_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_TIMER_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_TIMER_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_TIMER_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_TIMER_ALLOW_S 2 -/** TEE_REG_HP_CORE0_UM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_ANAPERI_ALLOW (BIT(3)) -#define TEE_REG_HP_CORE0_UM_LP_ANAPERI_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_ANAPERI_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_ANAPERI_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_ANAPERI_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_ANAPERI_ALLOW_S 3 -/** TEE_REG_HP_CORE0_UM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_PMU_ALLOW (BIT(4)) -#define TEE_REG_HP_CORE0_UM_LP_PMU_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_PMU_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_PMU_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_PMU_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_PMU_ALLOW_S 4 -/** TEE_REG_HP_CORE0_UM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_WDT_ALLOW (BIT(5)) -#define TEE_REG_HP_CORE0_UM_LP_WDT_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_WDT_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_WDT_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_WDT_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_WDT_ALLOW_S 5 -/** TEE_REG_HP_CORE0_UM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_MAILBOX_ALLOW (BIT(6)) -#define TEE_REG_HP_CORE0_UM_LP_MAILBOX_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_MAILBOX_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_MAILBOX_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_MAILBOX_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_MAILBOX_ALLOW_S 6 -/** TEE_REG_HP_CORE0_UM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_RTC_ALLOW (BIT(7)) -#define TEE_REG_HP_CORE0_UM_LP_RTC_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_RTC_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_RTC_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_RTC_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_RTC_ALLOW_S 7 -/** TEE_REG_HP_CORE0_UM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_PERICLKRST_ALLOW (BIT(8)) -#define TEE_REG_HP_CORE0_UM_LP_PERICLKRST_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_PERICLKRST_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_PERICLKRST_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_PERICLKRST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_PERICLKRST_ALLOW_S 8 -/** TEE_REG_HP_CORE0_UM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_UART_ALLOW (BIT(9)) -#define TEE_REG_HP_CORE0_UM_LP_UART_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_UART_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_UART_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_UART_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_UART_ALLOW_S 9 -/** TEE_REG_HP_CORE0_UM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_I2C_ALLOW (BIT(10)) -#define TEE_REG_HP_CORE0_UM_LP_I2C_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_I2C_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_I2C_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_I2C_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_I2C_ALLOW_S 10 -/** TEE_REG_HP_CORE0_UM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_SPI_ALLOW (BIT(11)) -#define TEE_REG_HP_CORE0_UM_LP_SPI_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_SPI_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_SPI_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_SPI_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_SPI_ALLOW_S 11 -/** TEE_REG_HP_CORE0_UM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_I2CMST_ALLOW (BIT(12)) -#define TEE_REG_HP_CORE0_UM_LP_I2CMST_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_I2CMST_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_I2CMST_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_I2CMST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_I2CMST_ALLOW_S 12 -/** TEE_REG_HP_CORE0_UM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_I2S_ALLOW (BIT(13)) -#define TEE_REG_HP_CORE0_UM_LP_I2S_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_I2S_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_I2S_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_I2S_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_I2S_ALLOW_S 13 -/** TEE_REG_HP_CORE0_UM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_ADC_ALLOW (BIT(14)) -#define TEE_REG_HP_CORE0_UM_LP_ADC_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_ADC_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_ADC_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_ADC_ALLOW_S 14 -/** TEE_REG_HP_CORE0_UM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_TOUCH_ALLOW (BIT(15)) -#define TEE_REG_HP_CORE0_UM_LP_TOUCH_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_TOUCH_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_TOUCH_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_TOUCH_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_TOUCH_ALLOW_S 15 -/** TEE_REG_HP_CORE0_UM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_IOMUX_ALLOW (BIT(16)) -#define TEE_REG_HP_CORE0_UM_LP_IOMUX_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_IOMUX_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_IOMUX_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_IOMUX_ALLOW_S 16 -/** TEE_REG_HP_CORE0_UM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_INTR_ALLOW (BIT(17)) -#define TEE_REG_HP_CORE0_UM_LP_INTR_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_INTR_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_INTR_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_INTR_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_INTR_ALLOW_S 17 -/** TEE_REG_HP_CORE0_UM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_EFUSE_ALLOW (BIT(18)) -#define TEE_REG_HP_CORE0_UM_LP_EFUSE_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_EFUSE_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_EFUSE_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_EFUSE_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_EFUSE_ALLOW_S 18 -/** TEE_REG_HP_CORE0_UM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_PMS_ALLOW (BIT(19)) -#define TEE_REG_HP_CORE0_UM_LP_PMS_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_PMS_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_PMS_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_PMS_ALLOW_S 19 -/** TEE_REG_HP_CORE0_UM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_HP2LP_PMS_ALLOW (BIT(20)) -#define TEE_REG_HP_CORE0_UM_HP2LP_PMS_ALLOW_M (TEE_REG_HP_CORE0_UM_HP2LP_PMS_ALLOW_V << TEE_REG_HP_CORE0_UM_HP2LP_PMS_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_HP2LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_HP2LP_PMS_ALLOW_S 20 -/** TEE_REG_HP_CORE0_UM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_TSENS_ALLOW (BIT(21)) -#define TEE_REG_HP_CORE0_UM_LP_TSENS_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_TSENS_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_TSENS_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_TSENS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_TSENS_ALLOW_S 21 -/** TEE_REG_HP_CORE0_UM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_HUK_ALLOW (BIT(22)) -#define TEE_REG_HP_CORE0_UM_LP_HUK_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_HUK_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_HUK_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_HUK_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_HUK_ALLOW_S 22 -/** TEE_REG_HP_CORE0_UM_LP_TCM_RAM_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE0_UM_LP_TCM_RAM_ALLOW (BIT(23)) -#define TEE_REG_HP_CORE0_UM_LP_TCM_RAM_ALLOW_M (TEE_REG_HP_CORE0_UM_LP_TCM_RAM_ALLOW_V << TEE_REG_HP_CORE0_UM_LP_TCM_RAM_ALLOW_S) -#define TEE_REG_HP_CORE0_UM_LP_TCM_RAM_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE0_UM_LP_TCM_RAM_ALLOW_S 23 +/** PMS_HP_CORE0_UM_PMS_REG0_REG register + * Permission control register0 for HP CPU0 in user mode + */ +#define PMS_HP_CORE0_UM_PMS_REG0_REG (DR_REG_HP2LP_PERI_PMS_BASE + 0xc) +/** PMS_HP_CORE0_UM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP System + * Registers. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_SYSREG_ALLOW (BIT(0)) +#define PMS_HP_CORE0_UM_LP_SYSREG_ALLOW_M (PMS_HP_CORE0_UM_LP_SYSREG_ALLOW_V << PMS_HP_CORE0_UM_LP_SYSREG_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_SYSREG_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_SYSREG_ALLOW_S 0 +/** PMS_HP_CORE0_UM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP_AONCLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_AONCLKRST_ALLOW (BIT(1)) +#define PMS_HP_CORE0_UM_LP_AONCLKRST_ALLOW_M (PMS_HP_CORE0_UM_LP_AONCLKRST_ALLOW_V << PMS_HP_CORE0_UM_LP_AONCLKRST_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_AONCLKRST_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_AONCLKRST_ALLOW_S 1 +/** PMS_HP_CORE0_UM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_TIMER_ALLOW (BIT(2)) +#define PMS_HP_CORE0_UM_LP_TIMER_ALLOW_M (PMS_HP_CORE0_UM_LP_TIMER_ALLOW_V << PMS_HP_CORE0_UM_LP_TIMER_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_TIMER_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_TIMER_ALLOW_S 2 +/** PMS_HP_CORE0_UM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP ANAPERI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_ANAPERI_ALLOW (BIT(3)) +#define PMS_HP_CORE0_UM_LP_ANAPERI_ALLOW_M (PMS_HP_CORE0_UM_LP_ANAPERI_ALLOW_V << PMS_HP_CORE0_UM_LP_ANAPERI_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_ANAPERI_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_ANAPERI_ALLOW_S 3 +/** PMS_HP_CORE0_UM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP PMU. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_PMU_ALLOW (BIT(4)) +#define PMS_HP_CORE0_UM_LP_PMU_ALLOW_M (PMS_HP_CORE0_UM_LP_PMU_ALLOW_V << PMS_HP_CORE0_UM_LP_PMU_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_PMU_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_PMU_ALLOW_S 4 +/** PMS_HP_CORE0_UM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP WDT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_WDT_ALLOW (BIT(5)) +#define PMS_HP_CORE0_UM_LP_WDT_ALLOW_M (PMS_HP_CORE0_UM_LP_WDT_ALLOW_V << PMS_HP_CORE0_UM_LP_WDT_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_WDT_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_WDT_ALLOW_S 5 +/** PMS_HP_CORE0_UM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP Mailbox + * Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_MAILBOX_ALLOW (BIT(6)) +#define PMS_HP_CORE0_UM_LP_MAILBOX_ALLOW_M (PMS_HP_CORE0_UM_LP_MAILBOX_ALLOW_V << PMS_HP_CORE0_UM_LP_MAILBOX_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_MAILBOX_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_MAILBOX_ALLOW_S 6 +/** PMS_HP_CORE0_UM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP RTC. + * 0: Not allowed + * 1: Allow + */ +#define PMS_HP_CORE0_UM_LP_RTC_ALLOW (BIT(7)) +#define PMS_HP_CORE0_UM_LP_RTC_ALLOW_M (PMS_HP_CORE0_UM_LP_RTC_ALLOW_V << PMS_HP_CORE0_UM_LP_RTC_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_RTC_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_RTC_ALLOW_S 7 +/** PMS_HP_CORE0_UM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP PERICLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_PERICLKRST_ALLOW (BIT(8)) +#define PMS_HP_CORE0_UM_LP_PERICLKRST_ALLOW_M (PMS_HP_CORE0_UM_LP_PERICLKRST_ALLOW_V << PMS_HP_CORE0_UM_LP_PERICLKRST_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_PERICLKRST_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_PERICLKRST_ALLOW_S 8 +/** PMS_HP_CORE0_UM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP UART. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_UART_ALLOW (BIT(9)) +#define PMS_HP_CORE0_UM_LP_UART_ALLOW_M (PMS_HP_CORE0_UM_LP_UART_ALLOW_V << PMS_HP_CORE0_UM_LP_UART_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_UART_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_UART_ALLOW_S 9 +/** PMS_HP_CORE0_UM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP I2C. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_I2C_ALLOW (BIT(10)) +#define PMS_HP_CORE0_UM_LP_I2C_ALLOW_M (PMS_HP_CORE0_UM_LP_I2C_ALLOW_V << PMS_HP_CORE0_UM_LP_I2C_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_I2C_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_I2C_ALLOW_S 10 +/** PMS_HP_CORE0_UM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP SPI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_SPI_ALLOW (BIT(11)) +#define PMS_HP_CORE0_UM_LP_SPI_ALLOW_M (PMS_HP_CORE0_UM_LP_SPI_ALLOW_V << PMS_HP_CORE0_UM_LP_SPI_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_SPI_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_SPI_ALLOW_S 11 +/** PMS_HP_CORE0_UM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP I2C master. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_I2CMST_ALLOW (BIT(12)) +#define PMS_HP_CORE0_UM_LP_I2CMST_ALLOW_M (PMS_HP_CORE0_UM_LP_I2CMST_ALLOW_V << PMS_HP_CORE0_UM_LP_I2CMST_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_I2CMST_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_I2CMST_ALLOW_S 12 +/** PMS_HP_CORE0_UM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_I2S_ALLOW (BIT(13)) +#define PMS_HP_CORE0_UM_LP_I2S_ALLOW_M (PMS_HP_CORE0_UM_LP_I2S_ALLOW_V << PMS_HP_CORE0_UM_LP_I2S_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_I2S_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_I2S_ALLOW_S 13 +/** PMS_HP_CORE0_UM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_ADC_ALLOW (BIT(14)) +#define PMS_HP_CORE0_UM_LP_ADC_ALLOW_M (PMS_HP_CORE0_UM_LP_ADC_ALLOW_V << PMS_HP_CORE0_UM_LP_ADC_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_ADC_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_ADC_ALLOW_S 14 +/** PMS_HP_CORE0_UM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP touch sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_TOUCH_ALLOW (BIT(15)) +#define PMS_HP_CORE0_UM_LP_TOUCH_ALLOW_M (PMS_HP_CORE0_UM_LP_TOUCH_ALLOW_V << PMS_HP_CORE0_UM_LP_TOUCH_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_TOUCH_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_TOUCH_ALLOW_S 15 +/** PMS_HP_CORE0_UM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_IOMUX_ALLOW (BIT(16)) +#define PMS_HP_CORE0_UM_LP_IOMUX_ALLOW_M (PMS_HP_CORE0_UM_LP_IOMUX_ALLOW_V << PMS_HP_CORE0_UM_LP_IOMUX_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_IOMUX_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_IOMUX_ALLOW_S 16 +/** PMS_HP_CORE0_UM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP INTR. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_INTR_ALLOW (BIT(17)) +#define PMS_HP_CORE0_UM_LP_INTR_ALLOW_M (PMS_HP_CORE0_UM_LP_INTR_ALLOW_V << PMS_HP_CORE0_UM_LP_INTR_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_INTR_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_INTR_ALLOW_S 17 +/** PMS_HP_CORE0_UM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP eFuse. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_EFUSE_ALLOW (BIT(18)) +#define PMS_HP_CORE0_UM_LP_EFUSE_ALLOW_M (PMS_HP_CORE0_UM_LP_EFUSE_ALLOW_V << PMS_HP_CORE0_UM_LP_EFUSE_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_EFUSE_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_EFUSE_ALLOW_S 18 +/** PMS_HP_CORE0_UM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_PMS_ALLOW (BIT(19)) +#define PMS_HP_CORE0_UM_LP_PMS_ALLOW_M (PMS_HP_CORE0_UM_LP_PMS_ALLOW_V << PMS_HP_CORE0_UM_LP_PMS_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_PMS_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_PMS_ALLOW_S 19 +/** PMS_HP_CORE0_UM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access + * HP2LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_HP2LP_PMS_ALLOW (BIT(20)) +#define PMS_HP_CORE0_UM_HP2LP_PMS_ALLOW_M (PMS_HP_CORE0_UM_HP2LP_PMS_ALLOW_V << PMS_HP_CORE0_UM_HP2LP_PMS_ALLOW_S) +#define PMS_HP_CORE0_UM_HP2LP_PMS_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_HP2LP_PMS_ALLOW_S 20 +/** PMS_HP_CORE0_UM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP temperature + * sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_TSENS_ALLOW (BIT(21)) +#define PMS_HP_CORE0_UM_LP_TSENS_ALLOW_M (PMS_HP_CORE0_UM_LP_TSENS_ALLOW_V << PMS_HP_CORE0_UM_LP_TSENS_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_TSENS_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_TSENS_ALLOW_S 21 +/** PMS_HP_CORE0_UM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU0 in user mode has permission to LP HUK. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_HUK_ALLOW (BIT(22)) +#define PMS_HP_CORE0_UM_LP_HUK_ALLOW_M (PMS_HP_CORE0_UM_LP_HUK_ALLOW_V << PMS_HP_CORE0_UM_LP_HUK_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_HUK_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_HUK_ALLOW_S 22 +/** PMS_HP_CORE0_UM_LP_SRAM_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access LP SRAM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE0_UM_LP_SRAM_ALLOW (BIT(23)) +#define PMS_HP_CORE0_UM_LP_SRAM_ALLOW_M (PMS_HP_CORE0_UM_LP_SRAM_ALLOW_V << PMS_HP_CORE0_UM_LP_SRAM_ALLOW_S) +#define PMS_HP_CORE0_UM_LP_SRAM_ALLOW_V 0x00000001U +#define PMS_HP_CORE0_UM_LP_SRAM_ALLOW_S 23 -/** TEE_HP_CORE1_MM_PMS_REG0_REG register - * NA - */ -#define TEE_HP_CORE1_MM_PMS_REG0_REG (DR_REG_TEE_BASE + 0x10) -/** TEE_REG_HP_CORE1_MM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_SYSREG_ALLOW (BIT(0)) -#define TEE_REG_HP_CORE1_MM_LP_SYSREG_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_SYSREG_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_SYSREG_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_SYSREG_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_SYSREG_ALLOW_S 0 -/** TEE_REG_HP_CORE1_MM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_AONCLKRST_ALLOW (BIT(1)) -#define TEE_REG_HP_CORE1_MM_LP_AONCLKRST_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_AONCLKRST_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_AONCLKRST_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_AONCLKRST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_AONCLKRST_ALLOW_S 1 -/** TEE_REG_HP_CORE1_MM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_TIMER_ALLOW (BIT(2)) -#define TEE_REG_HP_CORE1_MM_LP_TIMER_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_TIMER_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_TIMER_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_TIMER_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_TIMER_ALLOW_S 2 -/** TEE_REG_HP_CORE1_MM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_ANAPERI_ALLOW (BIT(3)) -#define TEE_REG_HP_CORE1_MM_LP_ANAPERI_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_ANAPERI_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_ANAPERI_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_ANAPERI_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_ANAPERI_ALLOW_S 3 -/** TEE_REG_HP_CORE1_MM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_PMU_ALLOW (BIT(4)) -#define TEE_REG_HP_CORE1_MM_LP_PMU_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_PMU_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_PMU_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_PMU_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_PMU_ALLOW_S 4 -/** TEE_REG_HP_CORE1_MM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_WDT_ALLOW (BIT(5)) -#define TEE_REG_HP_CORE1_MM_LP_WDT_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_WDT_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_WDT_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_WDT_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_WDT_ALLOW_S 5 -/** TEE_REG_HP_CORE1_MM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_MAILBOX_ALLOW (BIT(6)) -#define TEE_REG_HP_CORE1_MM_LP_MAILBOX_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_MAILBOX_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_MAILBOX_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_MAILBOX_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_MAILBOX_ALLOW_S 6 -/** TEE_REG_HP_CORE1_MM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_RTC_ALLOW (BIT(7)) -#define TEE_REG_HP_CORE1_MM_LP_RTC_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_RTC_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_RTC_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_RTC_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_RTC_ALLOW_S 7 -/** TEE_REG_HP_CORE1_MM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_PERICLKRST_ALLOW (BIT(8)) -#define TEE_REG_HP_CORE1_MM_LP_PERICLKRST_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_PERICLKRST_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_PERICLKRST_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_PERICLKRST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_PERICLKRST_ALLOW_S 8 -/** TEE_REG_HP_CORE1_MM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_UART_ALLOW (BIT(9)) -#define TEE_REG_HP_CORE1_MM_LP_UART_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_UART_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_UART_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_UART_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_UART_ALLOW_S 9 -/** TEE_REG_HP_CORE1_MM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_I2C_ALLOW (BIT(10)) -#define TEE_REG_HP_CORE1_MM_LP_I2C_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_I2C_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_I2C_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_I2C_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_I2C_ALLOW_S 10 -/** TEE_REG_HP_CORE1_MM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_SPI_ALLOW (BIT(11)) -#define TEE_REG_HP_CORE1_MM_LP_SPI_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_SPI_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_SPI_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_SPI_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_SPI_ALLOW_S 11 -/** TEE_REG_HP_CORE1_MM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_I2CMST_ALLOW (BIT(12)) -#define TEE_REG_HP_CORE1_MM_LP_I2CMST_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_I2CMST_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_I2CMST_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_I2CMST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_I2CMST_ALLOW_S 12 -/** TEE_REG_HP_CORE1_MM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_I2S_ALLOW (BIT(13)) -#define TEE_REG_HP_CORE1_MM_LP_I2S_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_I2S_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_I2S_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_I2S_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_I2S_ALLOW_S 13 -/** TEE_REG_HP_CORE1_MM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_ADC_ALLOW (BIT(14)) -#define TEE_REG_HP_CORE1_MM_LP_ADC_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_ADC_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_ADC_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_ADC_ALLOW_S 14 -/** TEE_REG_HP_CORE1_MM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_TOUCH_ALLOW (BIT(15)) -#define TEE_REG_HP_CORE1_MM_LP_TOUCH_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_TOUCH_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_TOUCH_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_TOUCH_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_TOUCH_ALLOW_S 15 -/** TEE_REG_HP_CORE1_MM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_IOMUX_ALLOW (BIT(16)) -#define TEE_REG_HP_CORE1_MM_LP_IOMUX_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_IOMUX_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_IOMUX_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_IOMUX_ALLOW_S 16 -/** TEE_REG_HP_CORE1_MM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_INTR_ALLOW (BIT(17)) -#define TEE_REG_HP_CORE1_MM_LP_INTR_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_INTR_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_INTR_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_INTR_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_INTR_ALLOW_S 17 -/** TEE_REG_HP_CORE1_MM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_EFUSE_ALLOW (BIT(18)) -#define TEE_REG_HP_CORE1_MM_LP_EFUSE_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_EFUSE_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_EFUSE_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_EFUSE_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_EFUSE_ALLOW_S 18 -/** TEE_REG_HP_CORE1_MM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_PMS_ALLOW (BIT(19)) -#define TEE_REG_HP_CORE1_MM_LP_PMS_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_PMS_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_PMS_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_PMS_ALLOW_S 19 -/** TEE_REG_HP_CORE1_MM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_HP2LP_PMS_ALLOW (BIT(20)) -#define TEE_REG_HP_CORE1_MM_HP2LP_PMS_ALLOW_M (TEE_REG_HP_CORE1_MM_HP2LP_PMS_ALLOW_V << TEE_REG_HP_CORE1_MM_HP2LP_PMS_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_HP2LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_HP2LP_PMS_ALLOW_S 20 -/** TEE_REG_HP_CORE1_MM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_TSENS_ALLOW (BIT(21)) -#define TEE_REG_HP_CORE1_MM_LP_TSENS_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_TSENS_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_TSENS_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_TSENS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_TSENS_ALLOW_S 21 -/** TEE_REG_HP_CORE1_MM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_HUK_ALLOW (BIT(22)) -#define TEE_REG_HP_CORE1_MM_LP_HUK_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_HUK_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_HUK_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_HUK_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_HUK_ALLOW_S 22 -/** TEE_REG_HP_CORE1_MM_LP_TCM_RAM_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_MM_LP_TCM_RAM_ALLOW (BIT(23)) -#define TEE_REG_HP_CORE1_MM_LP_TCM_RAM_ALLOW_M (TEE_REG_HP_CORE1_MM_LP_TCM_RAM_ALLOW_V << TEE_REG_HP_CORE1_MM_LP_TCM_RAM_ALLOW_S) -#define TEE_REG_HP_CORE1_MM_LP_TCM_RAM_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_MM_LP_TCM_RAM_ALLOW_S 23 +/** PMS_HP_CORE1_MM_PMS_REG0_REG register + * Permission control register0 for HP CPU1 in machine mode + */ +#define PMS_HP_CORE1_MM_PMS_REG0_REG (DR_REG_HP2LP_PERI_PMS_BASE + 0x10) +/** PMS_HP_CORE1_MM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP System + * Registers. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_SYSREG_ALLOW (BIT(0)) +#define PMS_HP_CORE1_MM_LP_SYSREG_ALLOW_M (PMS_HP_CORE1_MM_LP_SYSREG_ALLOW_V << PMS_HP_CORE1_MM_LP_SYSREG_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_SYSREG_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_SYSREG_ALLOW_S 0 +/** PMS_HP_CORE1_MM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP_AONCLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_AONCLKRST_ALLOW (BIT(1)) +#define PMS_HP_CORE1_MM_LP_AONCLKRST_ALLOW_M (PMS_HP_CORE1_MM_LP_AONCLKRST_ALLOW_V << PMS_HP_CORE1_MM_LP_AONCLKRST_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_AONCLKRST_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_AONCLKRST_ALLOW_S 1 +/** PMS_HP_CORE1_MM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_TIMER_ALLOW (BIT(2)) +#define PMS_HP_CORE1_MM_LP_TIMER_ALLOW_M (PMS_HP_CORE1_MM_LP_TIMER_ALLOW_V << PMS_HP_CORE1_MM_LP_TIMER_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_TIMER_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_TIMER_ALLOW_S 2 +/** PMS_HP_CORE1_MM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP ANAPERI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_ANAPERI_ALLOW (BIT(3)) +#define PMS_HP_CORE1_MM_LP_ANAPERI_ALLOW_M (PMS_HP_CORE1_MM_LP_ANAPERI_ALLOW_V << PMS_HP_CORE1_MM_LP_ANAPERI_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_ANAPERI_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_ANAPERI_ALLOW_S 3 +/** PMS_HP_CORE1_MM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP PMU. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_PMU_ALLOW (BIT(4)) +#define PMS_HP_CORE1_MM_LP_PMU_ALLOW_M (PMS_HP_CORE1_MM_LP_PMU_ALLOW_V << PMS_HP_CORE1_MM_LP_PMU_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_PMU_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_PMU_ALLOW_S 4 +/** PMS_HP_CORE1_MM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP WDT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_WDT_ALLOW (BIT(5)) +#define PMS_HP_CORE1_MM_LP_WDT_ALLOW_M (PMS_HP_CORE1_MM_LP_WDT_ALLOW_V << PMS_HP_CORE1_MM_LP_WDT_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_WDT_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_WDT_ALLOW_S 5 +/** PMS_HP_CORE1_MM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP Mailbox + * Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_MAILBOX_ALLOW (BIT(6)) +#define PMS_HP_CORE1_MM_LP_MAILBOX_ALLOW_M (PMS_HP_CORE1_MM_LP_MAILBOX_ALLOW_V << PMS_HP_CORE1_MM_LP_MAILBOX_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_MAILBOX_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_MAILBOX_ALLOW_S 6 +/** PMS_HP_CORE1_MM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP RTC. + * 0: Not allowed + * 1: Allow + */ +#define PMS_HP_CORE1_MM_LP_RTC_ALLOW (BIT(7)) +#define PMS_HP_CORE1_MM_LP_RTC_ALLOW_M (PMS_HP_CORE1_MM_LP_RTC_ALLOW_V << PMS_HP_CORE1_MM_LP_RTC_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_RTC_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_RTC_ALLOW_S 7 +/** PMS_HP_CORE1_MM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP PERICLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_PERICLKRST_ALLOW (BIT(8)) +#define PMS_HP_CORE1_MM_LP_PERICLKRST_ALLOW_M (PMS_HP_CORE1_MM_LP_PERICLKRST_ALLOW_V << PMS_HP_CORE1_MM_LP_PERICLKRST_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_PERICLKRST_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_PERICLKRST_ALLOW_S 8 +/** PMS_HP_CORE1_MM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP UART. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_UART_ALLOW (BIT(9)) +#define PMS_HP_CORE1_MM_LP_UART_ALLOW_M (PMS_HP_CORE1_MM_LP_UART_ALLOW_V << PMS_HP_CORE1_MM_LP_UART_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_UART_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_UART_ALLOW_S 9 +/** PMS_HP_CORE1_MM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP I2C. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_I2C_ALLOW (BIT(10)) +#define PMS_HP_CORE1_MM_LP_I2C_ALLOW_M (PMS_HP_CORE1_MM_LP_I2C_ALLOW_V << PMS_HP_CORE1_MM_LP_I2C_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_I2C_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_I2C_ALLOW_S 10 +/** PMS_HP_CORE1_MM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP SPI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_SPI_ALLOW (BIT(11)) +#define PMS_HP_CORE1_MM_LP_SPI_ALLOW_M (PMS_HP_CORE1_MM_LP_SPI_ALLOW_V << PMS_HP_CORE1_MM_LP_SPI_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_SPI_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_SPI_ALLOW_S 11 +/** PMS_HP_CORE1_MM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP I2C master. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_I2CMST_ALLOW (BIT(12)) +#define PMS_HP_CORE1_MM_LP_I2CMST_ALLOW_M (PMS_HP_CORE1_MM_LP_I2CMST_ALLOW_V << PMS_HP_CORE1_MM_LP_I2CMST_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_I2CMST_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_I2CMST_ALLOW_S 12 +/** PMS_HP_CORE1_MM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_I2S_ALLOW (BIT(13)) +#define PMS_HP_CORE1_MM_LP_I2S_ALLOW_M (PMS_HP_CORE1_MM_LP_I2S_ALLOW_V << PMS_HP_CORE1_MM_LP_I2S_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_I2S_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_I2S_ALLOW_S 13 +/** PMS_HP_CORE1_MM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_ADC_ALLOW (BIT(14)) +#define PMS_HP_CORE1_MM_LP_ADC_ALLOW_M (PMS_HP_CORE1_MM_LP_ADC_ALLOW_V << PMS_HP_CORE1_MM_LP_ADC_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_ADC_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_ADC_ALLOW_S 14 +/** PMS_HP_CORE1_MM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP touch + * sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_TOUCH_ALLOW (BIT(15)) +#define PMS_HP_CORE1_MM_LP_TOUCH_ALLOW_M (PMS_HP_CORE1_MM_LP_TOUCH_ALLOW_V << PMS_HP_CORE1_MM_LP_TOUCH_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_TOUCH_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_TOUCH_ALLOW_S 15 +/** PMS_HP_CORE1_MM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_IOMUX_ALLOW (BIT(16)) +#define PMS_HP_CORE1_MM_LP_IOMUX_ALLOW_M (PMS_HP_CORE1_MM_LP_IOMUX_ALLOW_V << PMS_HP_CORE1_MM_LP_IOMUX_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_IOMUX_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_IOMUX_ALLOW_S 16 +/** PMS_HP_CORE1_MM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP INTR. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_INTR_ALLOW (BIT(17)) +#define PMS_HP_CORE1_MM_LP_INTR_ALLOW_M (PMS_HP_CORE1_MM_LP_INTR_ALLOW_V << PMS_HP_CORE1_MM_LP_INTR_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_INTR_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_INTR_ALLOW_S 17 +/** PMS_HP_CORE1_MM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP eFuse. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_EFUSE_ALLOW (BIT(18)) +#define PMS_HP_CORE1_MM_LP_EFUSE_ALLOW_M (PMS_HP_CORE1_MM_LP_EFUSE_ALLOW_V << PMS_HP_CORE1_MM_LP_EFUSE_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_EFUSE_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_EFUSE_ALLOW_S 18 +/** PMS_HP_CORE1_MM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access + * LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_PMS_ALLOW (BIT(19)) +#define PMS_HP_CORE1_MM_LP_PMS_ALLOW_M (PMS_HP_CORE1_MM_LP_PMS_ALLOW_V << PMS_HP_CORE1_MM_LP_PMS_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_PMS_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_PMS_ALLOW_S 19 +/** PMS_HP_CORE1_MM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access + * HP2LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_HP2LP_PMS_ALLOW (BIT(20)) +#define PMS_HP_CORE1_MM_HP2LP_PMS_ALLOW_M (PMS_HP_CORE1_MM_HP2LP_PMS_ALLOW_V << PMS_HP_CORE1_MM_HP2LP_PMS_ALLOW_S) +#define PMS_HP_CORE1_MM_HP2LP_PMS_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_HP2LP_PMS_ALLOW_S 20 +/** PMS_HP_CORE1_MM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP temperature + * sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_TSENS_ALLOW (BIT(21)) +#define PMS_HP_CORE1_MM_LP_TSENS_ALLOW_M (PMS_HP_CORE1_MM_LP_TSENS_ALLOW_V << PMS_HP_CORE1_MM_LP_TSENS_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_TSENS_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_TSENS_ALLOW_S 21 +/** PMS_HP_CORE1_MM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to LP HUK. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_HUK_ALLOW (BIT(22)) +#define PMS_HP_CORE1_MM_LP_HUK_ALLOW_M (PMS_HP_CORE1_MM_LP_HUK_ALLOW_V << PMS_HP_CORE1_MM_LP_HUK_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_HUK_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_HUK_ALLOW_S 22 +/** PMS_HP_CORE1_MM_LP_SRAM_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access LP SRAM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_MM_LP_SRAM_ALLOW (BIT(23)) +#define PMS_HP_CORE1_MM_LP_SRAM_ALLOW_M (PMS_HP_CORE1_MM_LP_SRAM_ALLOW_V << PMS_HP_CORE1_MM_LP_SRAM_ALLOW_S) +#define PMS_HP_CORE1_MM_LP_SRAM_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_MM_LP_SRAM_ALLOW_S 23 -/** TEE_HP_CORE1_UM_PMS_REG0_REG register - * NA - */ -#define TEE_HP_CORE1_UM_PMS_REG0_REG (DR_REG_TEE_BASE + 0x14) -/** TEE_REG_HP_CORE1_UM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_SYSREG_ALLOW (BIT(0)) -#define TEE_REG_HP_CORE1_UM_LP_SYSREG_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_SYSREG_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_SYSREG_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_SYSREG_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_SYSREG_ALLOW_S 0 -/** TEE_REG_HP_CORE1_UM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_AONCLKRST_ALLOW (BIT(1)) -#define TEE_REG_HP_CORE1_UM_LP_AONCLKRST_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_AONCLKRST_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_AONCLKRST_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_AONCLKRST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_AONCLKRST_ALLOW_S 1 -/** TEE_REG_HP_CORE1_UM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_TIMER_ALLOW (BIT(2)) -#define TEE_REG_HP_CORE1_UM_LP_TIMER_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_TIMER_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_TIMER_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_TIMER_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_TIMER_ALLOW_S 2 -/** TEE_REG_HP_CORE1_UM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_ANAPERI_ALLOW (BIT(3)) -#define TEE_REG_HP_CORE1_UM_LP_ANAPERI_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_ANAPERI_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_ANAPERI_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_ANAPERI_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_ANAPERI_ALLOW_S 3 -/** TEE_REG_HP_CORE1_UM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_PMU_ALLOW (BIT(4)) -#define TEE_REG_HP_CORE1_UM_LP_PMU_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_PMU_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_PMU_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_PMU_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_PMU_ALLOW_S 4 -/** TEE_REG_HP_CORE1_UM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_WDT_ALLOW (BIT(5)) -#define TEE_REG_HP_CORE1_UM_LP_WDT_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_WDT_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_WDT_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_WDT_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_WDT_ALLOW_S 5 -/** TEE_REG_HP_CORE1_UM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_MAILBOX_ALLOW (BIT(6)) -#define TEE_REG_HP_CORE1_UM_LP_MAILBOX_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_MAILBOX_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_MAILBOX_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_MAILBOX_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_MAILBOX_ALLOW_S 6 -/** TEE_REG_HP_CORE1_UM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_RTC_ALLOW (BIT(7)) -#define TEE_REG_HP_CORE1_UM_LP_RTC_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_RTC_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_RTC_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_RTC_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_RTC_ALLOW_S 7 -/** TEE_REG_HP_CORE1_UM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_PERICLKRST_ALLOW (BIT(8)) -#define TEE_REG_HP_CORE1_UM_LP_PERICLKRST_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_PERICLKRST_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_PERICLKRST_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_PERICLKRST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_PERICLKRST_ALLOW_S 8 -/** TEE_REG_HP_CORE1_UM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_UART_ALLOW (BIT(9)) -#define TEE_REG_HP_CORE1_UM_LP_UART_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_UART_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_UART_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_UART_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_UART_ALLOW_S 9 -/** TEE_REG_HP_CORE1_UM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_I2C_ALLOW (BIT(10)) -#define TEE_REG_HP_CORE1_UM_LP_I2C_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_I2C_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_I2C_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_I2C_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_I2C_ALLOW_S 10 -/** TEE_REG_HP_CORE1_UM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_SPI_ALLOW (BIT(11)) -#define TEE_REG_HP_CORE1_UM_LP_SPI_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_SPI_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_SPI_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_SPI_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_SPI_ALLOW_S 11 -/** TEE_REG_HP_CORE1_UM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_I2CMST_ALLOW (BIT(12)) -#define TEE_REG_HP_CORE1_UM_LP_I2CMST_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_I2CMST_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_I2CMST_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_I2CMST_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_I2CMST_ALLOW_S 12 -/** TEE_REG_HP_CORE1_UM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_I2S_ALLOW (BIT(13)) -#define TEE_REG_HP_CORE1_UM_LP_I2S_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_I2S_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_I2S_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_I2S_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_I2S_ALLOW_S 13 -/** TEE_REG_HP_CORE1_UM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_ADC_ALLOW (BIT(14)) -#define TEE_REG_HP_CORE1_UM_LP_ADC_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_ADC_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_ADC_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_ADC_ALLOW_S 14 -/** TEE_REG_HP_CORE1_UM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_TOUCH_ALLOW (BIT(15)) -#define TEE_REG_HP_CORE1_UM_LP_TOUCH_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_TOUCH_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_TOUCH_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_TOUCH_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_TOUCH_ALLOW_S 15 -/** TEE_REG_HP_CORE1_UM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_IOMUX_ALLOW (BIT(16)) -#define TEE_REG_HP_CORE1_UM_LP_IOMUX_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_IOMUX_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_IOMUX_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_IOMUX_ALLOW_S 16 -/** TEE_REG_HP_CORE1_UM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_INTR_ALLOW (BIT(17)) -#define TEE_REG_HP_CORE1_UM_LP_INTR_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_INTR_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_INTR_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_INTR_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_INTR_ALLOW_S 17 -/** TEE_REG_HP_CORE1_UM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_EFUSE_ALLOW (BIT(18)) -#define TEE_REG_HP_CORE1_UM_LP_EFUSE_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_EFUSE_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_EFUSE_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_EFUSE_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_EFUSE_ALLOW_S 18 -/** TEE_REG_HP_CORE1_UM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_PMS_ALLOW (BIT(19)) -#define TEE_REG_HP_CORE1_UM_LP_PMS_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_PMS_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_PMS_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_PMS_ALLOW_S 19 -/** TEE_REG_HP_CORE1_UM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_HP2LP_PMS_ALLOW (BIT(20)) -#define TEE_REG_HP_CORE1_UM_HP2LP_PMS_ALLOW_M (TEE_REG_HP_CORE1_UM_HP2LP_PMS_ALLOW_V << TEE_REG_HP_CORE1_UM_HP2LP_PMS_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_HP2LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_HP2LP_PMS_ALLOW_S 20 -/** TEE_REG_HP_CORE1_UM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_TSENS_ALLOW (BIT(21)) -#define TEE_REG_HP_CORE1_UM_LP_TSENS_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_TSENS_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_TSENS_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_TSENS_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_TSENS_ALLOW_S 21 -/** TEE_REG_HP_CORE1_UM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_HUK_ALLOW (BIT(22)) -#define TEE_REG_HP_CORE1_UM_LP_HUK_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_HUK_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_HUK_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_HUK_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_HUK_ALLOW_S 22 -/** TEE_REG_HP_CORE1_UM_LP_TCM_RAM_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_HP_CORE1_UM_LP_TCM_RAM_ALLOW (BIT(23)) -#define TEE_REG_HP_CORE1_UM_LP_TCM_RAM_ALLOW_M (TEE_REG_HP_CORE1_UM_LP_TCM_RAM_ALLOW_V << TEE_REG_HP_CORE1_UM_LP_TCM_RAM_ALLOW_S) -#define TEE_REG_HP_CORE1_UM_LP_TCM_RAM_ALLOW_V 0x00000001U -#define TEE_REG_HP_CORE1_UM_LP_TCM_RAM_ALLOW_S 23 +/** PMS_HP_CORE1_UM_PMS_REG0_REG register + * Permission control register0 for HP CPU1 in user mode + */ +#define PMS_HP_CORE1_UM_PMS_REG0_REG (DR_REG_HP2LP_PERI_PMS_BASE + 0x14) +/** PMS_HP_CORE1_UM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP System + * Registers. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_SYSREG_ALLOW (BIT(0)) +#define PMS_HP_CORE1_UM_LP_SYSREG_ALLOW_M (PMS_HP_CORE1_UM_LP_SYSREG_ALLOW_V << PMS_HP_CORE1_UM_LP_SYSREG_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_SYSREG_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_SYSREG_ALLOW_S 0 +/** PMS_HP_CORE1_UM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP_AONCLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_AONCLKRST_ALLOW (BIT(1)) +#define PMS_HP_CORE1_UM_LP_AONCLKRST_ALLOW_M (PMS_HP_CORE1_UM_LP_AONCLKRST_ALLOW_V << PMS_HP_CORE1_UM_LP_AONCLKRST_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_AONCLKRST_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_AONCLKRST_ALLOW_S 1 +/** PMS_HP_CORE1_UM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_TIMER_ALLOW (BIT(2)) +#define PMS_HP_CORE1_UM_LP_TIMER_ALLOW_M (PMS_HP_CORE1_UM_LP_TIMER_ALLOW_V << PMS_HP_CORE1_UM_LP_TIMER_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_TIMER_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_TIMER_ALLOW_S 2 +/** PMS_HP_CORE1_UM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP ANAPERI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_ANAPERI_ALLOW (BIT(3)) +#define PMS_HP_CORE1_UM_LP_ANAPERI_ALLOW_M (PMS_HP_CORE1_UM_LP_ANAPERI_ALLOW_V << PMS_HP_CORE1_UM_LP_ANAPERI_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_ANAPERI_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_ANAPERI_ALLOW_S 3 +/** PMS_HP_CORE1_UM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP PMU. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_PMU_ALLOW (BIT(4)) +#define PMS_HP_CORE1_UM_LP_PMU_ALLOW_M (PMS_HP_CORE1_UM_LP_PMU_ALLOW_V << PMS_HP_CORE1_UM_LP_PMU_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_PMU_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_PMU_ALLOW_S 4 +/** PMS_HP_CORE1_UM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP WDT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_WDT_ALLOW (BIT(5)) +#define PMS_HP_CORE1_UM_LP_WDT_ALLOW_M (PMS_HP_CORE1_UM_LP_WDT_ALLOW_V << PMS_HP_CORE1_UM_LP_WDT_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_WDT_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_WDT_ALLOW_S 5 +/** PMS_HP_CORE1_UM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP Mailbox + * Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_MAILBOX_ALLOW (BIT(6)) +#define PMS_HP_CORE1_UM_LP_MAILBOX_ALLOW_M (PMS_HP_CORE1_UM_LP_MAILBOX_ALLOW_V << PMS_HP_CORE1_UM_LP_MAILBOX_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_MAILBOX_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_MAILBOX_ALLOW_S 6 +/** PMS_HP_CORE1_UM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP RTC. + * 0: Not allowed + * 1: Allow + */ +#define PMS_HP_CORE1_UM_LP_RTC_ALLOW (BIT(7)) +#define PMS_HP_CORE1_UM_LP_RTC_ALLOW_M (PMS_HP_CORE1_UM_LP_RTC_ALLOW_V << PMS_HP_CORE1_UM_LP_RTC_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_RTC_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_RTC_ALLOW_S 7 +/** PMS_HP_CORE1_UM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP PERICLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_PERICLKRST_ALLOW (BIT(8)) +#define PMS_HP_CORE1_UM_LP_PERICLKRST_ALLOW_M (PMS_HP_CORE1_UM_LP_PERICLKRST_ALLOW_V << PMS_HP_CORE1_UM_LP_PERICLKRST_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_PERICLKRST_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_PERICLKRST_ALLOW_S 8 +/** PMS_HP_CORE1_UM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP UART. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_UART_ALLOW (BIT(9)) +#define PMS_HP_CORE1_UM_LP_UART_ALLOW_M (PMS_HP_CORE1_UM_LP_UART_ALLOW_V << PMS_HP_CORE1_UM_LP_UART_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_UART_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_UART_ALLOW_S 9 +/** PMS_HP_CORE1_UM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP I2C. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_I2C_ALLOW (BIT(10)) +#define PMS_HP_CORE1_UM_LP_I2C_ALLOW_M (PMS_HP_CORE1_UM_LP_I2C_ALLOW_V << PMS_HP_CORE1_UM_LP_I2C_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_I2C_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_I2C_ALLOW_S 10 +/** PMS_HP_CORE1_UM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP SPI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_SPI_ALLOW (BIT(11)) +#define PMS_HP_CORE1_UM_LP_SPI_ALLOW_M (PMS_HP_CORE1_UM_LP_SPI_ALLOW_V << PMS_HP_CORE1_UM_LP_SPI_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_SPI_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_SPI_ALLOW_S 11 +/** PMS_HP_CORE1_UM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP I2C master. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_I2CMST_ALLOW (BIT(12)) +#define PMS_HP_CORE1_UM_LP_I2CMST_ALLOW_M (PMS_HP_CORE1_UM_LP_I2CMST_ALLOW_V << PMS_HP_CORE1_UM_LP_I2CMST_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_I2CMST_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_I2CMST_ALLOW_S 12 +/** PMS_HP_CORE1_UM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_I2S_ALLOW (BIT(13)) +#define PMS_HP_CORE1_UM_LP_I2S_ALLOW_M (PMS_HP_CORE1_UM_LP_I2S_ALLOW_V << PMS_HP_CORE1_UM_LP_I2S_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_I2S_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_I2S_ALLOW_S 13 +/** PMS_HP_CORE1_UM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_ADC_ALLOW (BIT(14)) +#define PMS_HP_CORE1_UM_LP_ADC_ALLOW_M (PMS_HP_CORE1_UM_LP_ADC_ALLOW_V << PMS_HP_CORE1_UM_LP_ADC_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_ADC_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_ADC_ALLOW_S 14 +/** PMS_HP_CORE1_UM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP touch sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_TOUCH_ALLOW (BIT(15)) +#define PMS_HP_CORE1_UM_LP_TOUCH_ALLOW_M (PMS_HP_CORE1_UM_LP_TOUCH_ALLOW_V << PMS_HP_CORE1_UM_LP_TOUCH_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_TOUCH_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_TOUCH_ALLOW_S 15 +/** PMS_HP_CORE1_UM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_IOMUX_ALLOW (BIT(16)) +#define PMS_HP_CORE1_UM_LP_IOMUX_ALLOW_M (PMS_HP_CORE1_UM_LP_IOMUX_ALLOW_V << PMS_HP_CORE1_UM_LP_IOMUX_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_IOMUX_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_IOMUX_ALLOW_S 16 +/** PMS_HP_CORE1_UM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP INTR. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_INTR_ALLOW (BIT(17)) +#define PMS_HP_CORE1_UM_LP_INTR_ALLOW_M (PMS_HP_CORE1_UM_LP_INTR_ALLOW_V << PMS_HP_CORE1_UM_LP_INTR_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_INTR_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_INTR_ALLOW_S 17 +/** PMS_HP_CORE1_UM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP eFuse. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_EFUSE_ALLOW (BIT(18)) +#define PMS_HP_CORE1_UM_LP_EFUSE_ALLOW_M (PMS_HP_CORE1_UM_LP_EFUSE_ALLOW_V << PMS_HP_CORE1_UM_LP_EFUSE_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_EFUSE_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_EFUSE_ALLOW_S 18 +/** PMS_HP_CORE1_UM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_PMS_ALLOW (BIT(19)) +#define PMS_HP_CORE1_UM_LP_PMS_ALLOW_M (PMS_HP_CORE1_UM_LP_PMS_ALLOW_V << PMS_HP_CORE1_UM_LP_PMS_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_PMS_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_PMS_ALLOW_S 19 +/** PMS_HP_CORE1_UM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access + * HP2LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_HP2LP_PMS_ALLOW (BIT(20)) +#define PMS_HP_CORE1_UM_HP2LP_PMS_ALLOW_M (PMS_HP_CORE1_UM_HP2LP_PMS_ALLOW_V << PMS_HP_CORE1_UM_HP2LP_PMS_ALLOW_S) +#define PMS_HP_CORE1_UM_HP2LP_PMS_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_HP2LP_PMS_ALLOW_S 20 +/** PMS_HP_CORE1_UM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP temperature + * sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_TSENS_ALLOW (BIT(21)) +#define PMS_HP_CORE1_UM_LP_TSENS_ALLOW_M (PMS_HP_CORE1_UM_LP_TSENS_ALLOW_V << PMS_HP_CORE1_UM_LP_TSENS_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_TSENS_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_TSENS_ALLOW_S 21 +/** PMS_HP_CORE1_UM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU1 in user mode has permission to LP HUK. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_HUK_ALLOW (BIT(22)) +#define PMS_HP_CORE1_UM_LP_HUK_ALLOW_M (PMS_HP_CORE1_UM_LP_HUK_ALLOW_V << PMS_HP_CORE1_UM_LP_HUK_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_HUK_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_HUK_ALLOW_S 22 +/** PMS_HP_CORE1_UM_LP_SRAM_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access LP SRAM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_HP_CORE1_UM_LP_SRAM_ALLOW (BIT(23)) +#define PMS_HP_CORE1_UM_LP_SRAM_ALLOW_M (PMS_HP_CORE1_UM_LP_SRAM_ALLOW_V << PMS_HP_CORE1_UM_LP_SRAM_ALLOW_S) +#define PMS_HP_CORE1_UM_LP_SRAM_ALLOW_V 0x00000001U +#define PMS_HP_CORE1_UM_LP_SRAM_ALLOW_S 23 -/** TEE_REGDMA_PERI_PMS_REG register - * NA - */ -#define TEE_REGDMA_PERI_PMS_REG (DR_REG_TEE_BASE + 0x18) -/** TEE_REG_REGDMA_PERI_LP_RAM_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_REGDMA_PERI_LP_RAM_ALLOW (BIT(0)) -#define TEE_REG_REGDMA_PERI_LP_RAM_ALLOW_M (TEE_REG_REGDMA_PERI_LP_RAM_ALLOW_V << TEE_REG_REGDMA_PERI_LP_RAM_ALLOW_S) -#define TEE_REG_REGDMA_PERI_LP_RAM_ALLOW_V 0x00000001U -#define TEE_REG_REGDMA_PERI_LP_RAM_ALLOW_S 0 -/** TEE_REG_REGDMA_PERI_LP_PERI_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_REGDMA_PERI_LP_PERI_ALLOW (BIT(1)) -#define TEE_REG_REGDMA_PERI_LP_PERI_ALLOW_M (TEE_REG_REGDMA_PERI_LP_PERI_ALLOW_V << TEE_REG_REGDMA_PERI_LP_PERI_ALLOW_S) -#define TEE_REG_REGDMA_PERI_LP_PERI_ALLOW_V 0x00000001U -#define TEE_REG_REGDMA_PERI_LP_PERI_ALLOW_S 1 +/** PMS_REGDMA_LP_PERI_PMS_REG register + * LP Peripheral Permission register for REGDMA + */ +#define PMS_REGDMA_LP_PERI_PMS_REG (DR_REG_HP2LP_PERI_PMS_BASE + 0x18) +/** PMS_REGDMA_PERI_LP_SRAM_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether REGDMA has permission to access LP SRAM. + * 0: Not allowed + * 1: Allow + */ +#define PMS_REGDMA_PERI_LP_SRAM_ALLOW (BIT(0)) +#define PMS_REGDMA_PERI_LP_SRAM_ALLOW_M (PMS_REGDMA_PERI_LP_SRAM_ALLOW_V << PMS_REGDMA_PERI_LP_SRAM_ALLOW_S) +#define PMS_REGDMA_PERI_LP_SRAM_ALLOW_V 0x00000001U +#define PMS_REGDMA_PERI_LP_SRAM_ALLOW_S 0 +/** PMS_REGDMA_PERI_LP_PERI_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether REGDMA has permission to access all LP peripherals. + * 0: Not allowed + * 1: Allow + */ +#define PMS_REGDMA_PERI_LP_PERI_ALLOW (BIT(1)) +#define PMS_REGDMA_PERI_LP_PERI_ALLOW_M (PMS_REGDMA_PERI_LP_PERI_ALLOW_V << PMS_REGDMA_PERI_LP_PERI_ALLOW_S) +#define PMS_REGDMA_PERI_LP_PERI_ALLOW_V 0x00000001U +#define PMS_REGDMA_PERI_LP_PERI_ALLOW_S 1 #ifdef __cplusplus } diff --git a/components/soc/esp32p4/include/soc/hp2lp_peri_pms_struct.h b/components/soc/esp32p4/include/soc/hp2lp_peri_pms_struct.h index 3eb67ccc92dd..0e65b4e64bcc 100644 --- a/components/soc/esp32p4/include/soc/hp2lp_peri_pms_struct.h +++ b/components/soc/esp32p4/include/soc/hp2lp_peri_pms_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,502 +10,397 @@ extern "C" { #endif -/** Group: TEE HP2LP TEE PMS DATE REG */ -/** Type of hp2lp_tee_pms_date register - * NA +/** Group: Version Control Registers */ +/** Type of hp2lp_peri_pms_date register + * Version control register */ typedef union { struct { - /** tee_date : R/W; bitpos: [31:0]; default: 2294790; - * NA + /** hp2lp_peri_pms_date : R/W; bitpos: [31:0]; default: 2294790; + * Version control register */ - uint32_t tee_date:32; + uint32_t hp2lp_peri_pms_date:32; }; uint32_t val; -} tee_hp2lp_tee_pms_date_reg_t; +} pms_hp2lp_peri_pms_date_reg_t; -/** Group: TEE PMS CLK EN REG */ -/** Type of pms_clk_en register - * NA +/** Group: Clock Gating Registers */ +/** Type of hp2lp_peri_pms_clk_en register + * Clock gating register */ typedef union { struct { - /** reg_clk_en : R/W; bitpos: [0]; default: 1; - * NA + /** hp2lp_peri_pms_clk_en : R/W; bitpos: [0]; default: 1; + * Configures whether to keep the clock always on. + * 0: Enable automatic clock gating + * 1: Keep the clock always on */ - uint32_t reg_clk_en:1; + uint32_t hp2lp_peri_pms_clk_en:1; uint32_t reserved_1:31; }; uint32_t val; -} tee_pms_clk_en_reg_t; +} pms_hp2lp_peri_pms_clk_en_reg_t; -/** Group: TEE HP CORE0 MM PMS REG0 REG */ -/** Type of hp_core0_mm_pms_reg0 register - * NA +/** Group: HP CPU Permission Control Registers */ +/** Type of hp_coren_mm_pms_reg0 register + * Permission control register0 for HP CPUn in machine mode */ typedef union { struct { - /** reg_hp_core0_mm_lp_sysreg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_sysreg_allow:1; - /** reg_hp_core0_mm_lp_aonclkrst_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_aonclkrst_allow:1; - /** reg_hp_core0_mm_lp_timer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_timer_allow:1; - /** reg_hp_core0_mm_lp_anaperi_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_anaperi_allow:1; - /** reg_hp_core0_mm_lp_pmu_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_pmu_allow:1; - /** reg_hp_core0_mm_lp_wdt_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_wdt_allow:1; - /** reg_hp_core0_mm_lp_mailbox_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_mailbox_allow:1; - /** reg_hp_core0_mm_lp_rtc_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_rtc_allow:1; - /** reg_hp_core0_mm_lp_periclkrst_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_periclkrst_allow:1; - /** reg_hp_core0_mm_lp_uart_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_uart_allow:1; - /** reg_hp_core0_mm_lp_i2c_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_i2c_allow:1; - /** reg_hp_core0_mm_lp_spi_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_spi_allow:1; - /** reg_hp_core0_mm_lp_i2cmst_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_i2cmst_allow:1; - /** reg_hp_core0_mm_lp_i2s_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_i2s_allow:1; - /** reg_hp_core0_mm_lp_adc_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_adc_allow:1; - /** reg_hp_core0_mm_lp_touch_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_touch_allow:1; - /** reg_hp_core0_mm_lp_iomux_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_iomux_allow:1; - /** reg_hp_core0_mm_lp_intr_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_intr_allow:1; - /** reg_hp_core0_mm_lp_efuse_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_efuse_allow:1; - /** reg_hp_core0_mm_lp_pms_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_pms_allow:1; - /** reg_hp_core0_mm_hp2lp_pms_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_hp2lp_pms_allow:1; - /** reg_hp_core0_mm_lp_tsens_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_tsens_allow:1; - /** reg_hp_core0_mm_lp_huk_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_huk_allow:1; - /** reg_hp_core0_mm_lp_tcm_ram_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_hp_core0_mm_lp_tcm_ram_allow:1; + /** hp_coren_mm_lp_sysreg_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP System + * Registers. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_sysreg_allow:1; + /** hp_coren_mm_lp_aonclkrst_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP_AONCLKRST. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_aonclkrst_allow:1; + /** hp_coren_mm_lp_timer_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP timer. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_timer_allow:1; + /** hp_coren_mm_lp_anaperi_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP ANAPERI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_anaperi_allow:1; + /** hp_coren_mm_lp_pmu_allow : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP PMU. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_pmu_allow:1; + /** hp_coren_mm_lp_wdt_allow : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP WDT. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_wdt_allow:1; + /** hp_coren_mm_lp_mailbox_allow : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP Mailbox + * Controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_mailbox_allow:1; + /** hp_coren_mm_lp_rtc_allow : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP RTC. + * 0: Not allowed + * 1: Allow + */ + uint32_t hp_coren_mm_lp_rtc_allow:1; + /** hp_coren_mm_lp_periclkrst_allow : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP PERICLKRST. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_periclkrst_allow:1; + /** hp_coren_mm_lp_uart_allow : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP UART. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_uart_allow:1; + /** hp_coren_mm_lp_i2c_allow : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP I2C. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_i2c_allow:1; + /** hp_coren_mm_lp_spi_allow : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP SPI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_spi_allow:1; + /** hp_coren_mm_lp_i2cmst_allow : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP I2C master. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_i2cmst_allow:1; + /** hp_coren_mm_lp_i2s_allow : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_i2s_allow:1; + /** hp_coren_mm_lp_adc_allow : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP ADC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_adc_allow:1; + /** hp_coren_mm_lp_touch_allow : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP touch + * sensor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_touch_allow:1; + /** hp_coren_mm_lp_iomux_allow : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP IO MUX. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_iomux_allow:1; + /** hp_coren_mm_lp_intr_allow : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP INTR. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_intr_allow:1; + /** hp_coren_mm_lp_efuse_allow : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP eFuse. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_efuse_allow:1; + /** hp_coren_mm_lp_pms_allow : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access + * LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_pms_allow:1; + /** hp_coren_mm_hp2lp_pms_allow : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access + * HP2LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_hp2lp_pms_allow:1; + /** hp_coren_mm_lp_tsens_allow : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP temperature + * sensor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_tsens_allow:1; + /** hp_coren_mm_lp_huk_allow : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPUn in machine mode has permission to LP HUK. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_huk_allow:1; + /** hp_coren_mm_lp_sram_allow : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access LP SRAM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_mm_lp_sram_allow:1; uint32_t reserved_24:8; }; uint32_t val; -} tee_hp_core0_mm_pms_reg0_reg_t; +} pms_hp_coren_mm_pms_reg0_reg_t; - -/** Group: TEE HP CORE0 UM PMS REG0 REG */ -/** Type of hp_core0_um_pms_reg0 register - * NA +/** Type of hp_coren_um_pms_reg0 register + * Permission control register0 for HP CPUn in user mode */ typedef union { struct { - /** reg_hp_core0_um_lp_sysreg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_sysreg_allow:1; - /** reg_hp_core0_um_lp_aonclkrst_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_aonclkrst_allow:1; - /** reg_hp_core0_um_lp_timer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_timer_allow:1; - /** reg_hp_core0_um_lp_anaperi_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_anaperi_allow:1; - /** reg_hp_core0_um_lp_pmu_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_pmu_allow:1; - /** reg_hp_core0_um_lp_wdt_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_wdt_allow:1; - /** reg_hp_core0_um_lp_mailbox_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_mailbox_allow:1; - /** reg_hp_core0_um_lp_rtc_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_rtc_allow:1; - /** reg_hp_core0_um_lp_periclkrst_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_periclkrst_allow:1; - /** reg_hp_core0_um_lp_uart_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_uart_allow:1; - /** reg_hp_core0_um_lp_i2c_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_i2c_allow:1; - /** reg_hp_core0_um_lp_spi_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_spi_allow:1; - /** reg_hp_core0_um_lp_i2cmst_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_i2cmst_allow:1; - /** reg_hp_core0_um_lp_i2s_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_i2s_allow:1; - /** reg_hp_core0_um_lp_adc_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_adc_allow:1; - /** reg_hp_core0_um_lp_touch_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_touch_allow:1; - /** reg_hp_core0_um_lp_iomux_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_iomux_allow:1; - /** reg_hp_core0_um_lp_intr_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_intr_allow:1; - /** reg_hp_core0_um_lp_efuse_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_efuse_allow:1; - /** reg_hp_core0_um_lp_pms_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_pms_allow:1; - /** reg_hp_core0_um_hp2lp_pms_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_hp2lp_pms_allow:1; - /** reg_hp_core0_um_lp_tsens_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_tsens_allow:1; - /** reg_hp_core0_um_lp_huk_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_huk_allow:1; - /** reg_hp_core0_um_lp_tcm_ram_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_hp_core0_um_lp_tcm_ram_allow:1; + /** hp_coren_um_lp_sysreg_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP System + * Registers. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_sysreg_allow:1; + /** hp_coren_um_lp_aonclkrst_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP_AONCLKRST. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_aonclkrst_allow:1; + /** hp_coren_um_lp_timer_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP timer. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_timer_allow:1; + /** hp_coren_um_lp_anaperi_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP ANAPERI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_anaperi_allow:1; + /** hp_coren_um_lp_pmu_allow : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP PMU. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_pmu_allow:1; + /** hp_coren_um_lp_wdt_allow : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP WDT. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_wdt_allow:1; + /** hp_coren_um_lp_mailbox_allow : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP Mailbox + * Controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_mailbox_allow:1; + /** hp_coren_um_lp_rtc_allow : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP RTC. + * 0: Not allowed + * 1: Allow + */ + uint32_t hp_coren_um_lp_rtc_allow:1; + /** hp_coren_um_lp_periclkrst_allow : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP PERICLKRST. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_periclkrst_allow:1; + /** hp_coren_um_lp_uart_allow : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP UART. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_uart_allow:1; + /** hp_coren_um_lp_i2c_allow : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP I2C. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_i2c_allow:1; + /** hp_coren_um_lp_spi_allow : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP SPI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_spi_allow:1; + /** hp_coren_um_lp_i2cmst_allow : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP I2C master. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_i2cmst_allow:1; + /** hp_coren_um_lp_i2s_allow : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_i2s_allow:1; + /** hp_coren_um_lp_adc_allow : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP ADC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_adc_allow:1; + /** hp_coren_um_lp_touch_allow : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP touch sensor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_touch_allow:1; + /** hp_coren_um_lp_iomux_allow : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP IO MUX. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_iomux_allow:1; + /** hp_coren_um_lp_intr_allow : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP INTR. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_intr_allow:1; + /** hp_coren_um_lp_efuse_allow : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP eFuse. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_efuse_allow:1; + /** hp_coren_um_lp_pms_allow : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_pms_allow:1; + /** hp_coren_um_hp2lp_pms_allow : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPUn in user mode has permission to access + * HP2LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_hp2lp_pms_allow:1; + /** hp_coren_um_lp_tsens_allow : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP temperature + * sensor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_tsens_allow:1; + /** hp_coren_um_lp_huk_allow : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPUn in user mode has permission to LP HUK. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_huk_allow:1; + /** hp_coren_um_lp_sram_allow : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPUn in user mode has permission to access LP SRAM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t hp_coren_um_lp_sram_allow:1; uint32_t reserved_24:8; }; uint32_t val; -} tee_hp_core0_um_pms_reg0_reg_t; +} pms_hp_coren_um_pms_reg0_reg_t; -/** Group: TEE HP CORE1 MM PMS REG0 REG */ -/** Type of hp_core1_mm_pms_reg0 register - * NA +/** Group: TEE Peripheral Permission Control Register */ +/** Type of regdma_lp_peri_pms register + * LP Peripheral Permission register for REGDMA */ typedef union { struct { - /** reg_hp_core1_mm_lp_sysreg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_sysreg_allow:1; - /** reg_hp_core1_mm_lp_aonclkrst_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_aonclkrst_allow:1; - /** reg_hp_core1_mm_lp_timer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_timer_allow:1; - /** reg_hp_core1_mm_lp_anaperi_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_anaperi_allow:1; - /** reg_hp_core1_mm_lp_pmu_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_pmu_allow:1; - /** reg_hp_core1_mm_lp_wdt_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_wdt_allow:1; - /** reg_hp_core1_mm_lp_mailbox_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_mailbox_allow:1; - /** reg_hp_core1_mm_lp_rtc_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_rtc_allow:1; - /** reg_hp_core1_mm_lp_periclkrst_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_periclkrst_allow:1; - /** reg_hp_core1_mm_lp_uart_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_uart_allow:1; - /** reg_hp_core1_mm_lp_i2c_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_i2c_allow:1; - /** reg_hp_core1_mm_lp_spi_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_spi_allow:1; - /** reg_hp_core1_mm_lp_i2cmst_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_i2cmst_allow:1; - /** reg_hp_core1_mm_lp_i2s_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_i2s_allow:1; - /** reg_hp_core1_mm_lp_adc_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_adc_allow:1; - /** reg_hp_core1_mm_lp_touch_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_touch_allow:1; - /** reg_hp_core1_mm_lp_iomux_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_iomux_allow:1; - /** reg_hp_core1_mm_lp_intr_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_intr_allow:1; - /** reg_hp_core1_mm_lp_efuse_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_efuse_allow:1; - /** reg_hp_core1_mm_lp_pms_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_pms_allow:1; - /** reg_hp_core1_mm_hp2lp_pms_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_hp2lp_pms_allow:1; - /** reg_hp_core1_mm_lp_tsens_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_tsens_allow:1; - /** reg_hp_core1_mm_lp_huk_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_huk_allow:1; - /** reg_hp_core1_mm_lp_tcm_ram_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_hp_core1_mm_lp_tcm_ram_allow:1; - uint32_t reserved_24:8; - }; - uint32_t val; -} tee_hp_core1_mm_pms_reg0_reg_t; - - -/** Group: TEE HP CORE1 UM PMS REG0 REG */ -/** Type of hp_core1_um_pms_reg0 register - * NA - */ -typedef union { - struct { - /** reg_hp_core1_um_lp_sysreg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_sysreg_allow:1; - /** reg_hp_core1_um_lp_aonclkrst_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_aonclkrst_allow:1; - /** reg_hp_core1_um_lp_timer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_timer_allow:1; - /** reg_hp_core1_um_lp_anaperi_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_anaperi_allow:1; - /** reg_hp_core1_um_lp_pmu_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_pmu_allow:1; - /** reg_hp_core1_um_lp_wdt_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_wdt_allow:1; - /** reg_hp_core1_um_lp_mailbox_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_mailbox_allow:1; - /** reg_hp_core1_um_lp_rtc_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_rtc_allow:1; - /** reg_hp_core1_um_lp_periclkrst_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_periclkrst_allow:1; - /** reg_hp_core1_um_lp_uart_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_uart_allow:1; - /** reg_hp_core1_um_lp_i2c_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_i2c_allow:1; - /** reg_hp_core1_um_lp_spi_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_spi_allow:1; - /** reg_hp_core1_um_lp_i2cmst_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_i2cmst_allow:1; - /** reg_hp_core1_um_lp_i2s_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_i2s_allow:1; - /** reg_hp_core1_um_lp_adc_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_adc_allow:1; - /** reg_hp_core1_um_lp_touch_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_touch_allow:1; - /** reg_hp_core1_um_lp_iomux_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_iomux_allow:1; - /** reg_hp_core1_um_lp_intr_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_intr_allow:1; - /** reg_hp_core1_um_lp_efuse_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_efuse_allow:1; - /** reg_hp_core1_um_lp_pms_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_pms_allow:1; - /** reg_hp_core1_um_hp2lp_pms_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_hp2lp_pms_allow:1; - /** reg_hp_core1_um_lp_tsens_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_tsens_allow:1; - /** reg_hp_core1_um_lp_huk_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_huk_allow:1; - /** reg_hp_core1_um_lp_tcm_ram_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_hp_core1_um_lp_tcm_ram_allow:1; - uint32_t reserved_24:8; - }; - uint32_t val; -} tee_hp_core1_um_pms_reg0_reg_t; - - -/** Group: TEE REGDMA PERI PMS REG */ -/** Type of regdma_peri_pms register - * NA - */ -typedef union { - struct { - /** reg_regdma_peri_lp_ram_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_regdma_peri_lp_ram_allow:1; - /** reg_regdma_peri_lp_peri_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_regdma_peri_lp_peri_allow:1; + /** regdma_peri_lp_sram_allow : R/W; bitpos: [0]; default: 1; + * Configures whether REGDMA has permission to access LP SRAM. + * 0: Not allowed + * 1: Allow + */ + uint32_t regdma_peri_lp_sram_allow:1; + /** regdma_peri_lp_peri_allow : R/W; bitpos: [1]; default: 1; + * Configures whether REGDMA has permission to access all LP peripherals. + * 0: Not allowed + * 1: Allow + */ + uint32_t regdma_peri_lp_peri_allow:1; uint32_t reserved_2:30; }; uint32_t val; -} tee_regdma_peri_pms_reg_t; +} pms_regdma_lp_peri_pms_reg_t; typedef struct { - volatile tee_hp2lp_tee_pms_date_reg_t hp2lp_tee_pms_date; - volatile tee_pms_clk_en_reg_t pms_clk_en; - volatile tee_hp_core0_mm_pms_reg0_reg_t hp_core0_mm_pms_reg0; - volatile tee_hp_core0_um_pms_reg0_reg_t hp_core0_um_pms_reg0; - volatile tee_hp_core1_mm_pms_reg0_reg_t hp_core1_mm_pms_reg0; - volatile tee_hp_core1_um_pms_reg0_reg_t hp_core1_um_pms_reg0; - volatile tee_regdma_peri_pms_reg_t regdma_peri_pms; -} tee_dev_t; + volatile pms_hp2lp_peri_pms_date_reg_t hp2lp_peri_pms_date; + volatile pms_hp2lp_peri_pms_clk_en_reg_t hp2lp_peri_pms_clk_en; + volatile pms_hp_coren_mm_pms_reg0_reg_t hp_core0_mm_pms_reg0; + volatile pms_hp_coren_um_pms_reg0_reg_t hp_core0_um_pms_reg0; + volatile pms_hp_coren_mm_pms_reg0_reg_t hp_core1_mm_pms_reg0; + volatile pms_hp_coren_um_pms_reg0_reg_t hp_core1_um_pms_reg0; + volatile pms_regdma_lp_peri_pms_reg_t regdma_lp_peri_pms; +} hp2lp_peri_pms_dev_t; +extern hp2lp_peri_pms_dev_t HP2LP_PERI_PMS; #ifndef __cplusplus -_Static_assert(sizeof(tee_dev_t) == 0x1c, "Invalid size of tee_dev_t structure"); +_Static_assert(sizeof(hp2lp_peri_pms_dev_t) == 0x1c, "Invalid size of hp2lp_peri_pms_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/hp_peri_pms_reg.h b/components/soc/esp32p4/include/soc/hp_peri_pms_reg.h index 31eeb620ddff..a097d8e43f12 100644 --- a/components/soc/esp32p4/include/soc/hp_peri_pms_reg.h +++ b/components/soc/esp32p4/include/soc/hp_peri_pms_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,2193 +11,2882 @@ extern "C" { #endif -/** TEE_PMS_DATE_REG register - * NA +/** PMS_HP_PERI_PMS_DATE_REG register + * Version control register */ -#define TEE_PMS_DATE_REG (DR_REG_TEE_BASE + 0x0) -/** TEE_TEE_DATE : R/W; bitpos: [31:0]; default: 2294537; - * NA +#define PMS_HP_PERI_PMS_DATE_REG (DR_REG_HP_PERI_PMS_BASE + 0x0) +/** PMS_HP_PERI_PMS_DATE : R/W; bitpos: [31:0]; default: 2294537; + * Version control register. */ -#define TEE_TEE_DATE 0xFFFFFFFFU -#define TEE_TEE_DATE_M (TEE_TEE_DATE_V << TEE_TEE_DATE_S) -#define TEE_TEE_DATE_V 0xFFFFFFFFU -#define TEE_TEE_DATE_S 0 +#define PMS_HP_PERI_PMS_DATE 0xFFFFFFFFU +#define PMS_HP_PERI_PMS_DATE_M (PMS_HP_PERI_PMS_DATE_V << PMS_HP_PERI_PMS_DATE_S) +#define PMS_HP_PERI_PMS_DATE_V 0xFFFFFFFFU +#define PMS_HP_PERI_PMS_DATE_S 0 -/** TEE_PMS_CLK_EN_REG register - * NA - */ -#define TEE_PMS_CLK_EN_REG (DR_REG_TEE_BASE + 0x4) -/** TEE_REG_CLK_EN : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CLK_EN (BIT(0)) -#define TEE_REG_CLK_EN_M (TEE_REG_CLK_EN_V << TEE_REG_CLK_EN_S) -#define TEE_REG_CLK_EN_V 0x00000001U -#define TEE_REG_CLK_EN_S 0 +/** PMS_HP_PERI_PMS_CLK_EN_REG register + * Clock gating register + */ +#define PMS_HP_PERI_PMS_CLK_EN_REG (DR_REG_HP_PERI_PMS_BASE + 0x4) +/** PMS_HP_PERI_PMS_CLK_EN : R/W; bitpos: [0]; default: 1; + * Configures whether to keep the clock always on. + * 0: Enable automatic clock gating + * 1: Keep the clock always on + */ +#define PMS_HP_PERI_PMS_CLK_EN (BIT(0)) +#define PMS_HP_PERI_PMS_CLK_EN_M (PMS_HP_PERI_PMS_CLK_EN_V << PMS_HP_PERI_PMS_CLK_EN_S) +#define PMS_HP_PERI_PMS_CLK_EN_V 0x00000001U +#define PMS_HP_PERI_PMS_CLK_EN_S 0 -/** TEE_CORE0_MM_PMS_REG0_REG register - * NA - */ -#define TEE_CORE0_MM_PMS_REG0_REG (DR_REG_TEE_BASE + 0x8) -/** TEE_REG_CORE0_MM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_PSRAM_ALLOW (BIT(0)) -#define TEE_REG_CORE0_MM_PSRAM_ALLOW_M (TEE_REG_CORE0_MM_PSRAM_ALLOW_V << TEE_REG_CORE0_MM_PSRAM_ALLOW_S) -#define TEE_REG_CORE0_MM_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_PSRAM_ALLOW_S 0 -/** TEE_REG_CORE0_MM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_FLASH_ALLOW (BIT(1)) -#define TEE_REG_CORE0_MM_FLASH_ALLOW_M (TEE_REG_CORE0_MM_FLASH_ALLOW_V << TEE_REG_CORE0_MM_FLASH_ALLOW_S) -#define TEE_REG_CORE0_MM_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_FLASH_ALLOW_S 1 -/** TEE_REG_CORE0_MM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_L2MEM_ALLOW (BIT(2)) -#define TEE_REG_CORE0_MM_L2MEM_ALLOW_M (TEE_REG_CORE0_MM_L2MEM_ALLOW_V << TEE_REG_CORE0_MM_L2MEM_ALLOW_S) -#define TEE_REG_CORE0_MM_L2MEM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_L2MEM_ALLOW_S 2 -/** TEE_REG_CORE0_MM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_L2ROM_ALLOW (BIT(3)) -#define TEE_REG_CORE0_MM_L2ROM_ALLOW_M (TEE_REG_CORE0_MM_L2ROM_ALLOW_V << TEE_REG_CORE0_MM_L2ROM_ALLOW_S) -#define TEE_REG_CORE0_MM_L2ROM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_L2ROM_ALLOW_S 3 -/** TEE_REG_CORE0_MM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_TRACE0_ALLOW (BIT(6)) -#define TEE_REG_CORE0_MM_TRACE0_ALLOW_M (TEE_REG_CORE0_MM_TRACE0_ALLOW_V << TEE_REG_CORE0_MM_TRACE0_ALLOW_S) -#define TEE_REG_CORE0_MM_TRACE0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_TRACE0_ALLOW_S 6 -/** TEE_REG_CORE0_MM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_TRACE1_ALLOW (BIT(7)) -#define TEE_REG_CORE0_MM_TRACE1_ALLOW_M (TEE_REG_CORE0_MM_TRACE1_ALLOW_V << TEE_REG_CORE0_MM_TRACE1_ALLOW_S) -#define TEE_REG_CORE0_MM_TRACE1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_TRACE1_ALLOW_S 7 -/** TEE_REG_CORE0_MM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_CPU_BUS_MON_ALLOW (BIT(8)) -#define TEE_REG_CORE0_MM_CPU_BUS_MON_ALLOW_M (TEE_REG_CORE0_MM_CPU_BUS_MON_ALLOW_V << TEE_REG_CORE0_MM_CPU_BUS_MON_ALLOW_S) -#define TEE_REG_CORE0_MM_CPU_BUS_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_CPU_BUS_MON_ALLOW_S 8 -/** TEE_REG_CORE0_MM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_L2MEM_MON_ALLOW (BIT(9)) -#define TEE_REG_CORE0_MM_L2MEM_MON_ALLOW_M (TEE_REG_CORE0_MM_L2MEM_MON_ALLOW_V << TEE_REG_CORE0_MM_L2MEM_MON_ALLOW_S) -#define TEE_REG_CORE0_MM_L2MEM_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_L2MEM_MON_ALLOW_S 9 -/** TEE_REG_CORE0_MM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_TCM_MON_ALLOW (BIT(10)) -#define TEE_REG_CORE0_MM_TCM_MON_ALLOW_M (TEE_REG_CORE0_MM_TCM_MON_ALLOW_V << TEE_REG_CORE0_MM_TCM_MON_ALLOW_S) -#define TEE_REG_CORE0_MM_TCM_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_TCM_MON_ALLOW_S 10 -/** TEE_REG_CORE0_MM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_CACHE_ALLOW (BIT(11)) -#define TEE_REG_CORE0_MM_CACHE_ALLOW_M (TEE_REG_CORE0_MM_CACHE_ALLOW_V << TEE_REG_CORE0_MM_CACHE_ALLOW_S) -#define TEE_REG_CORE0_MM_CACHE_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_CACHE_ALLOW_S 11 +/** PMS_CORE0_MM_HP_PERI_PMS_REG0_REG register + * Permission control register0 for HP CPU0 in machine mode + */ +#define PMS_CORE0_MM_HP_PERI_PMS_REG0_REG (DR_REG_HP_PERI_PMS_BASE + 0x8) +/** PMS_CORE0_MM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access external RAM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_PSRAM_ALLOW (BIT(0)) +#define PMS_CORE0_MM_PSRAM_ALLOW_M (PMS_CORE0_MM_PSRAM_ALLOW_V << PMS_CORE0_MM_PSRAM_ALLOW_S) +#define PMS_CORE0_MM_PSRAM_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_PSRAM_ALLOW_S 0 +/** PMS_CORE0_MM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access external flash + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_FLASH_ALLOW (BIT(1)) +#define PMS_CORE0_MM_FLASH_ALLOW_M (PMS_CORE0_MM_FLASH_ALLOW_V << PMS_CORE0_MM_FLASH_ALLOW_S) +#define PMS_CORE0_MM_FLASH_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_FLASH_ALLOW_S 1 +/** PMS_CORE0_MM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP L2MEM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_L2MEM_ALLOW (BIT(2)) +#define PMS_CORE0_MM_L2MEM_ALLOW_M (PMS_CORE0_MM_L2MEM_ALLOW_V << PMS_CORE0_MM_L2MEM_ALLOW_S) +#define PMS_CORE0_MM_L2MEM_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_L2MEM_ALLOW_S 2 +/** PMS_CORE0_MM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP ROM without + * going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_L2ROM_ALLOW (BIT(3)) +#define PMS_CORE0_MM_L2ROM_ALLOW_M (PMS_CORE0_MM_L2ROM_ALLOW_V << PMS_CORE0_MM_L2ROM_ALLOW_S) +#define PMS_CORE0_MM_L2ROM_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_L2ROM_ALLOW_S 3 +/** PMS_CORE0_MM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access TRACE0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_TRACE0_ALLOW (BIT(6)) +#define PMS_CORE0_MM_TRACE0_ALLOW_M (PMS_CORE0_MM_TRACE0_ALLOW_V << PMS_CORE0_MM_TRACE0_ALLOW_S) +#define PMS_CORE0_MM_TRACE0_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_TRACE0_ALLOW_S 6 +/** PMS_CORE0_MM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access TRACE1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_TRACE1_ALLOW (BIT(7)) +#define PMS_CORE0_MM_TRACE1_ALLOW_M (PMS_CORE0_MM_TRACE1_ALLOW_V << PMS_CORE0_MM_TRACE1_ALLOW_S) +#define PMS_CORE0_MM_TRACE1_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_TRACE1_ALLOW_S 7 +/** PMS_CORE0_MM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access CPU bus + * monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_CPU_BUS_MON_ALLOW (BIT(8)) +#define PMS_CORE0_MM_CPU_BUS_MON_ALLOW_M (PMS_CORE0_MM_CPU_BUS_MON_ALLOW_V << PMS_CORE0_MM_CPU_BUS_MON_ALLOW_S) +#define PMS_CORE0_MM_CPU_BUS_MON_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_CPU_BUS_MON_ALLOW_S 8 +/** PMS_CORE0_MM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access L2MEM monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_L2MEM_MON_ALLOW (BIT(9)) +#define PMS_CORE0_MM_L2MEM_MON_ALLOW_M (PMS_CORE0_MM_L2MEM_MON_ALLOW_V << PMS_CORE0_MM_L2MEM_MON_ALLOW_S) +#define PMS_CORE0_MM_L2MEM_MON_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_L2MEM_MON_ALLOW_S 9 +/** PMS_CORE0_MM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access TCM monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_TCM_MON_ALLOW (BIT(10)) +#define PMS_CORE0_MM_TCM_MON_ALLOW_M (PMS_CORE0_MM_TCM_MON_ALLOW_V << PMS_CORE0_MM_TCM_MON_ALLOW_S) +#define PMS_CORE0_MM_TCM_MON_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_TCM_MON_ALLOW_S 10 +/** PMS_CORE0_MM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_CACHE_ALLOW (BIT(11)) +#define PMS_CORE0_MM_CACHE_ALLOW_M (PMS_CORE0_MM_CACHE_ALLOW_V << PMS_CORE0_MM_CACHE_ALLOW_S) +#define PMS_CORE0_MM_CACHE_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_CACHE_ALLOW_S 11 -/** TEE_CORE0_MM_PMS_REG1_REG register - * NA - */ -#define TEE_CORE0_MM_PMS_REG1_REG (DR_REG_TEE_BASE + 0xc) -/** TEE_REG_CORE0_MM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_USBOTG_ALLOW (BIT(0)) -#define TEE_REG_CORE0_MM_HP_USBOTG_ALLOW_M (TEE_REG_CORE0_MM_HP_USBOTG_ALLOW_V << TEE_REG_CORE0_MM_HP_USBOTG_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_USBOTG_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_USBOTG_ALLOW_S 0 -/** TEE_REG_CORE0_MM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_USBOTG11_ALLOW (BIT(1)) -#define TEE_REG_CORE0_MM_HP_USBOTG11_ALLOW_M (TEE_REG_CORE0_MM_HP_USBOTG11_ALLOW_V << TEE_REG_CORE0_MM_HP_USBOTG11_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_USBOTG11_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_USBOTG11_ALLOW_S 1 -/** TEE_REG_CORE0_MM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) -#define TEE_REG_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_M (TEE_REG_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_V << TEE_REG_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_S 2 -/** TEE_REG_CORE0_MM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_GDMA_ALLOW (BIT(3)) -#define TEE_REG_CORE0_MM_HP_GDMA_ALLOW_M (TEE_REG_CORE0_MM_HP_GDMA_ALLOW_V << TEE_REG_CORE0_MM_HP_GDMA_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_GDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_GDMA_ALLOW_S 3 -/** TEE_REG_CORE0_MM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_REGDMA_ALLOW (BIT(4)) -#define TEE_REG_CORE0_MM_HP_REGDMA_ALLOW_M (TEE_REG_CORE0_MM_HP_REGDMA_ALLOW_V << TEE_REG_CORE0_MM_HP_REGDMA_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_REGDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_REGDMA_ALLOW_S 4 -/** TEE_REG_CORE0_MM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_SDMMC_ALLOW (BIT(5)) -#define TEE_REG_CORE0_MM_HP_SDMMC_ALLOW_M (TEE_REG_CORE0_MM_HP_SDMMC_ALLOW_V << TEE_REG_CORE0_MM_HP_SDMMC_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_SDMMC_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_SDMMC_ALLOW_S 5 -/** TEE_REG_CORE0_MM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_AHB_PDMA_ALLOW (BIT(6)) -#define TEE_REG_CORE0_MM_HP_AHB_PDMA_ALLOW_M (TEE_REG_CORE0_MM_HP_AHB_PDMA_ALLOW_V << TEE_REG_CORE0_MM_HP_AHB_PDMA_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_AHB_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_AHB_PDMA_ALLOW_S 6 -/** TEE_REG_CORE0_MM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_JPEG_ALLOW (BIT(7)) -#define TEE_REG_CORE0_MM_HP_JPEG_ALLOW_M (TEE_REG_CORE0_MM_HP_JPEG_ALLOW_V << TEE_REG_CORE0_MM_HP_JPEG_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_JPEG_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_JPEG_ALLOW_S 7 -/** TEE_REG_CORE0_MM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_PPA_ALLOW (BIT(8)) -#define TEE_REG_CORE0_MM_HP_PPA_ALLOW_M (TEE_REG_CORE0_MM_HP_PPA_ALLOW_V << TEE_REG_CORE0_MM_HP_PPA_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_PPA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_PPA_ALLOW_S 8 -/** TEE_REG_CORE0_MM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_DMA2D_ALLOW (BIT(9)) -#define TEE_REG_CORE0_MM_HP_DMA2D_ALLOW_M (TEE_REG_CORE0_MM_HP_DMA2D_ALLOW_V << TEE_REG_CORE0_MM_HP_DMA2D_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_DMA2D_ALLOW_S 9 -/** TEE_REG_CORE0_MM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_KEY_MANAGER_ALLOW (BIT(10)) -#define TEE_REG_CORE0_MM_HP_KEY_MANAGER_ALLOW_M (TEE_REG_CORE0_MM_HP_KEY_MANAGER_ALLOW_V << TEE_REG_CORE0_MM_HP_KEY_MANAGER_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_KEY_MANAGER_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_KEY_MANAGER_ALLOW_S 10 -/** TEE_REG_CORE0_MM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_AXI_PDMA_ALLOW (BIT(11)) -#define TEE_REG_CORE0_MM_HP_AXI_PDMA_ALLOW_M (TEE_REG_CORE0_MM_HP_AXI_PDMA_ALLOW_V << TEE_REG_CORE0_MM_HP_AXI_PDMA_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_AXI_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_AXI_PDMA_ALLOW_S 11 -/** TEE_REG_CORE0_MM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_FLASH_ALLOW (BIT(12)) -#define TEE_REG_CORE0_MM_HP_FLASH_ALLOW_M (TEE_REG_CORE0_MM_HP_FLASH_ALLOW_V << TEE_REG_CORE0_MM_HP_FLASH_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_FLASH_ALLOW_S 12 -/** TEE_REG_CORE0_MM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_PSRAM_ALLOW (BIT(13)) -#define TEE_REG_CORE0_MM_HP_PSRAM_ALLOW_M (TEE_REG_CORE0_MM_HP_PSRAM_ALLOW_V << TEE_REG_CORE0_MM_HP_PSRAM_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_PSRAM_ALLOW_S 13 -/** TEE_REG_CORE0_MM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_CRYPTO_ALLOW (BIT(14)) -#define TEE_REG_CORE0_MM_HP_CRYPTO_ALLOW_M (TEE_REG_CORE0_MM_HP_CRYPTO_ALLOW_V << TEE_REG_CORE0_MM_HP_CRYPTO_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_CRYPTO_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_CRYPTO_ALLOW_S 14 -/** TEE_REG_CORE0_MM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_GMAC_ALLOW (BIT(15)) -#define TEE_REG_CORE0_MM_HP_GMAC_ALLOW_M (TEE_REG_CORE0_MM_HP_GMAC_ALLOW_V << TEE_REG_CORE0_MM_HP_GMAC_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_GMAC_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_GMAC_ALLOW_S 15 -/** TEE_REG_CORE0_MM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_USB_PHY_ALLOW (BIT(16)) -#define TEE_REG_CORE0_MM_HP_USB_PHY_ALLOW_M (TEE_REG_CORE0_MM_HP_USB_PHY_ALLOW_V << TEE_REG_CORE0_MM_HP_USB_PHY_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_USB_PHY_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_USB_PHY_ALLOW_S 16 -/** TEE_REG_CORE0_MM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_PVT_ALLOW (BIT(17)) -#define TEE_REG_CORE0_MM_HP_PVT_ALLOW_M (TEE_REG_CORE0_MM_HP_PVT_ALLOW_V << TEE_REG_CORE0_MM_HP_PVT_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_PVT_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_PVT_ALLOW_S 17 -/** TEE_REG_CORE0_MM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_CSI_HOST_ALLOW (BIT(18)) -#define TEE_REG_CORE0_MM_HP_CSI_HOST_ALLOW_M (TEE_REG_CORE0_MM_HP_CSI_HOST_ALLOW_V << TEE_REG_CORE0_MM_HP_CSI_HOST_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_CSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_CSI_HOST_ALLOW_S 18 -/** TEE_REG_CORE0_MM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_DSI_HOST_ALLOW (BIT(19)) -#define TEE_REG_CORE0_MM_HP_DSI_HOST_ALLOW_M (TEE_REG_CORE0_MM_HP_DSI_HOST_ALLOW_V << TEE_REG_CORE0_MM_HP_DSI_HOST_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_DSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_DSI_HOST_ALLOW_S 19 -/** TEE_REG_CORE0_MM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_ISP_ALLOW (BIT(20)) -#define TEE_REG_CORE0_MM_HP_ISP_ALLOW_M (TEE_REG_CORE0_MM_HP_ISP_ALLOW_V << TEE_REG_CORE0_MM_HP_ISP_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_ISP_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_ISP_ALLOW_S 20 -/** TEE_REG_CORE0_MM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_H264_CORE_ALLOW (BIT(21)) -#define TEE_REG_CORE0_MM_HP_H264_CORE_ALLOW_M (TEE_REG_CORE0_MM_HP_H264_CORE_ALLOW_V << TEE_REG_CORE0_MM_HP_H264_CORE_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_H264_CORE_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_H264_CORE_ALLOW_S 21 -/** TEE_REG_CORE0_MM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_RMT_ALLOW (BIT(22)) -#define TEE_REG_CORE0_MM_HP_RMT_ALLOW_M (TEE_REG_CORE0_MM_HP_RMT_ALLOW_V << TEE_REG_CORE0_MM_HP_RMT_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_RMT_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_RMT_ALLOW_S 22 -/** TEE_REG_CORE0_MM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_BITSRAMBLER_ALLOW (BIT(23)) -#define TEE_REG_CORE0_MM_HP_BITSRAMBLER_ALLOW_M (TEE_REG_CORE0_MM_HP_BITSRAMBLER_ALLOW_V << TEE_REG_CORE0_MM_HP_BITSRAMBLER_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_BITSRAMBLER_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_BITSRAMBLER_ALLOW_S 23 -/** TEE_REG_CORE0_MM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_AXI_ICM_ALLOW (BIT(24)) -#define TEE_REG_CORE0_MM_HP_AXI_ICM_ALLOW_M (TEE_REG_CORE0_MM_HP_AXI_ICM_ALLOW_V << TEE_REG_CORE0_MM_HP_AXI_ICM_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_AXI_ICM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_AXI_ICM_ALLOW_S 24 -/** TEE_REG_CORE0_MM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_PERI_PMS_ALLOW (BIT(25)) -#define TEE_REG_CORE0_MM_HP_PERI_PMS_ALLOW_M (TEE_REG_CORE0_MM_HP_PERI_PMS_ALLOW_V << TEE_REG_CORE0_MM_HP_PERI_PMS_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_PERI_PMS_ALLOW_S 25 -/** TEE_REG_CORE0_MM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_LP2HP_PERI_PMS_ALLOW (BIT(26)) -#define TEE_REG_CORE0_MM_LP2HP_PERI_PMS_ALLOW_M (TEE_REG_CORE0_MM_LP2HP_PERI_PMS_ALLOW_V << TEE_REG_CORE0_MM_LP2HP_PERI_PMS_ALLOW_S) -#define TEE_REG_CORE0_MM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_LP2HP_PERI_PMS_ALLOW_S 26 -/** TEE_REG_CORE0_MM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_DMA_PMS_ALLOW (BIT(27)) -#define TEE_REG_CORE0_MM_DMA_PMS_ALLOW_M (TEE_REG_CORE0_MM_DMA_PMS_ALLOW_V << TEE_REG_CORE0_MM_DMA_PMS_ALLOW_S) -#define TEE_REG_CORE0_MM_DMA_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_DMA_PMS_ALLOW_S 27 -/** TEE_REG_CORE0_MM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_H264_DMA2D_ALLOW (BIT(28)) -#define TEE_REG_CORE0_MM_HP_H264_DMA2D_ALLOW_M (TEE_REG_CORE0_MM_HP_H264_DMA2D_ALLOW_V << TEE_REG_CORE0_MM_HP_H264_DMA2D_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_H264_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_H264_DMA2D_ALLOW_S 28 +/** PMS_CORE0_MM_HP_PERI_PMS_REG1_REG register + * Permission control register1 for HP CPU0 in machine mode + */ +#define PMS_CORE0_MM_HP_PERI_PMS_REG1_REG (DR_REG_HP_PERI_PMS_BASE + 0xc) +/** PMS_CORE0_MM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP high-speed + * USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_USBOTG_ALLOW (BIT(0)) +#define PMS_CORE0_MM_HP_USBOTG_ALLOW_M (PMS_CORE0_MM_HP_USBOTG_ALLOW_V << PMS_CORE0_MM_HP_USBOTG_ALLOW_S) +#define PMS_CORE0_MM_HP_USBOTG_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_USBOTG_ALLOW_S 0 +/** PMS_CORE0_MM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP full-speed + * USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_USBOTG11_ALLOW (BIT(1)) +#define PMS_CORE0_MM_HP_USBOTG11_ALLOW_M (PMS_CORE0_MM_HP_USBOTG11_ALLOW_V << PMS_CORE0_MM_HP_USBOTG11_ALLOW_S) +#define PMS_CORE0_MM_HP_USBOTG11_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_USBOTG11_ALLOW_S 1 +/** PMS_CORE0_MM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP full-speed + * USB 2.0 OTG's wrap. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) +#define PMS_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_M (PMS_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_V << PMS_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_S) +#define PMS_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_USBOTG11_WRAP_ALLOW_S 2 +/** PMS_CORE0_MM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP DW-GDMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_GDMA_ALLOW (BIT(3)) +#define PMS_CORE0_MM_HP_GDMA_ALLOW_M (PMS_CORE0_MM_HP_GDMA_ALLOW_V << PMS_CORE0_MM_HP_GDMA_ALLOW_S) +#define PMS_CORE0_MM_HP_GDMA_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_GDMA_ALLOW_S 3 +/** PMS_CORE0_MM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP GDMA (DW + * GDMA). + * 0: Not allowed + * 1: Allow + */ +#define PMS_CORE0_MM_HP_REGDMA_ALLOW (BIT(4)) +#define PMS_CORE0_MM_HP_REGDMA_ALLOW_M (PMS_CORE0_MM_HP_REGDMA_ALLOW_V << PMS_CORE0_MM_HP_REGDMA_ALLOW_S) +#define PMS_CORE0_MM_HP_REGDMA_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_REGDMA_ALLOW_S 4 +/** PMS_CORE0_MM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP SDMMC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_SDMMC_ALLOW (BIT(5)) +#define PMS_CORE0_MM_HP_SDMMC_ALLOW_M (PMS_CORE0_MM_HP_SDMMC_ALLOW_V << PMS_CORE0_MM_HP_SDMMC_ALLOW_S) +#define PMS_CORE0_MM_HP_SDMMC_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_SDMMC_ALLOW_S 5 +/** PMS_CORE0_MM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access GDMA-AHB. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_AHB_PDMA_ALLOW (BIT(6)) +#define PMS_CORE0_MM_HP_AHB_PDMA_ALLOW_M (PMS_CORE0_MM_HP_AHB_PDMA_ALLOW_V << PMS_CORE0_MM_HP_AHB_PDMA_ALLOW_S) +#define PMS_CORE0_MM_HP_AHB_PDMA_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_AHB_PDMA_ALLOW_S 6 +/** PMS_CORE0_MM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP JPEG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_JPEG_ALLOW (BIT(7)) +#define PMS_CORE0_MM_HP_JPEG_ALLOW_M (PMS_CORE0_MM_HP_JPEG_ALLOW_V << PMS_CORE0_MM_HP_JPEG_ALLOW_S) +#define PMS_CORE0_MM_HP_JPEG_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_JPEG_ALLOW_S 7 +/** PMS_CORE0_MM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP PPA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_PPA_ALLOW (BIT(8)) +#define PMS_CORE0_MM_HP_PPA_ALLOW_M (PMS_CORE0_MM_HP_PPA_ALLOW_V << PMS_CORE0_MM_HP_PPA_ALLOW_S) +#define PMS_CORE0_MM_HP_PPA_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_PPA_ALLOW_S 8 +/** PMS_CORE0_MM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_DMA2D_ALLOW (BIT(9)) +#define PMS_CORE0_MM_HP_DMA2D_ALLOW_M (PMS_CORE0_MM_HP_DMA2D_ALLOW_V << PMS_CORE0_MM_HP_DMA2D_ALLOW_S) +#define PMS_CORE0_MM_HP_DMA2D_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_DMA2D_ALLOW_S 9 +/** PMS_CORE0_MM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP key manager. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_KEY_MANAGER_ALLOW (BIT(10)) +#define PMS_CORE0_MM_HP_KEY_MANAGER_ALLOW_M (PMS_CORE0_MM_HP_KEY_MANAGER_ALLOW_V << PMS_CORE0_MM_HP_KEY_MANAGER_ALLOW_S) +#define PMS_CORE0_MM_HP_KEY_MANAGER_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_KEY_MANAGER_ALLOW_S 10 +/** PMS_CORE0_MM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP GDMA-AXI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_AXI_PDMA_ALLOW (BIT(11)) +#define PMS_CORE0_MM_HP_AXI_PDMA_ALLOW_M (PMS_CORE0_MM_HP_AXI_PDMA_ALLOW_V << PMS_CORE0_MM_HP_AXI_PDMA_ALLOW_S) +#define PMS_CORE0_MM_HP_AXI_PDMA_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_AXI_PDMA_ALLOW_S 11 +/** PMS_CORE0_MM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP flash MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_FLASH_ALLOW (BIT(12)) +#define PMS_CORE0_MM_HP_FLASH_ALLOW_M (PMS_CORE0_MM_HP_FLASH_ALLOW_V << PMS_CORE0_MM_HP_FLASH_ALLOW_S) +#define PMS_CORE0_MM_HP_FLASH_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_FLASH_ALLOW_S 12 +/** PMS_CORE0_MM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP PSRAM MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_PSRAM_ALLOW (BIT(13)) +#define PMS_CORE0_MM_HP_PSRAM_ALLOW_M (PMS_CORE0_MM_HP_PSRAM_ALLOW_V << PMS_CORE0_MM_HP_PSRAM_ALLOW_S) +#define PMS_CORE0_MM_HP_PSRAM_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_PSRAM_ALLOW_S 13 +/** PMS_CORE0_MM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP CRYPTO + * (including AES/SHA/RSA/HMAC Accelerators). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_CRYPTO_ALLOW (BIT(14)) +#define PMS_CORE0_MM_HP_CRYPTO_ALLOW_M (PMS_CORE0_MM_HP_CRYPTO_ALLOW_V << PMS_CORE0_MM_HP_CRYPTO_ALLOW_S) +#define PMS_CORE0_MM_HP_CRYPTO_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_CRYPTO_ALLOW_S 14 +/** PMS_CORE0_MM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP EMAC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_GMAC_ALLOW (BIT(15)) +#define PMS_CORE0_MM_HP_GMAC_ALLOW_M (PMS_CORE0_MM_HP_GMAC_ALLOW_V << PMS_CORE0_MM_HP_GMAC_ALLOW_S) +#define PMS_CORE0_MM_HP_GMAC_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_GMAC_ALLOW_S 15 +/** PMS_CORE0_MM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP high-speed + * USB 2.0 OTG PHY. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_USB_PHY_ALLOW (BIT(16)) +#define PMS_CORE0_MM_HP_USB_PHY_ALLOW_M (PMS_CORE0_MM_HP_USB_PHY_ALLOW_V << PMS_CORE0_MM_HP_USB_PHY_ALLOW_S) +#define PMS_CORE0_MM_HP_USB_PHY_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_USB_PHY_ALLOW_S 16 +/** PMS_CORE0_MM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP PVT. + * 0: Not allowed + * 1: Allow + */ +#define PMS_CORE0_MM_HP_PVT_ALLOW (BIT(17)) +#define PMS_CORE0_MM_HP_PVT_ALLOW_M (PMS_CORE0_MM_HP_PVT_ALLOW_V << PMS_CORE0_MM_HP_PVT_ALLOW_S) +#define PMS_CORE0_MM_HP_PVT_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_PVT_ALLOW_S 17 +/** PMS_CORE0_MM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP MIPI CSI + * host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_CSI_HOST_ALLOW (BIT(18)) +#define PMS_CORE0_MM_HP_CSI_HOST_ALLOW_M (PMS_CORE0_MM_HP_CSI_HOST_ALLOW_V << PMS_CORE0_MM_HP_CSI_HOST_ALLOW_S) +#define PMS_CORE0_MM_HP_CSI_HOST_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_CSI_HOST_ALLOW_S 18 +/** PMS_CORE0_MM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP MIPI DSI + * host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_DSI_HOST_ALLOW (BIT(19)) +#define PMS_CORE0_MM_HP_DSI_HOST_ALLOW_M (PMS_CORE0_MM_HP_DSI_HOST_ALLOW_V << PMS_CORE0_MM_HP_DSI_HOST_ALLOW_S) +#define PMS_CORE0_MM_HP_DSI_HOST_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_DSI_HOST_ALLOW_S 19 +/** PMS_CORE0_MM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP ISP (Image + * Signal Processor). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_ISP_ALLOW (BIT(20)) +#define PMS_CORE0_MM_HP_ISP_ALLOW_M (PMS_CORE0_MM_HP_ISP_ALLOW_V << PMS_CORE0_MM_HP_ISP_ALLOW_S) +#define PMS_CORE0_MM_HP_ISP_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_ISP_ALLOW_S 20 +/** PMS_CORE0_MM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP H264 + * Encoder. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_H264_CORE_ALLOW (BIT(21)) +#define PMS_CORE0_MM_HP_H264_CORE_ALLOW_M (PMS_CORE0_MM_HP_H264_CORE_ALLOW_V << PMS_CORE0_MM_HP_H264_CORE_ALLOW_S) +#define PMS_CORE0_MM_HP_H264_CORE_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_H264_CORE_ALLOW_S 21 +/** PMS_CORE0_MM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP RMT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_RMT_ALLOW (BIT(22)) +#define PMS_CORE0_MM_HP_RMT_ALLOW_M (PMS_CORE0_MM_HP_RMT_ALLOW_V << PMS_CORE0_MM_HP_RMT_ALLOW_S) +#define PMS_CORE0_MM_HP_RMT_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_RMT_ALLOW_S 22 +/** PMS_CORE0_MM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP bit + * scrambler. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_BITSRAMBLER_ALLOW (BIT(23)) +#define PMS_CORE0_MM_HP_BITSRAMBLER_ALLOW_M (PMS_CORE0_MM_HP_BITSRAMBLER_ALLOW_V << PMS_CORE0_MM_HP_BITSRAMBLER_ALLOW_S) +#define PMS_CORE0_MM_HP_BITSRAMBLER_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_BITSRAMBLER_ALLOW_S 23 +/** PMS_CORE0_MM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP AXI ICM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_AXI_ICM_ALLOW (BIT(24)) +#define PMS_CORE0_MM_HP_AXI_ICM_ALLOW_M (PMS_CORE0_MM_HP_AXI_ICM_ALLOW_V << PMS_CORE0_MM_HP_AXI_ICM_ALLOW_S) +#define PMS_CORE0_MM_HP_AXI_ICM_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_AXI_ICM_ALLOW_S 24 +/** PMS_CORE0_MM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access + * HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_PERI_PMS_ALLOW (BIT(25)) +#define PMS_CORE0_MM_HP_PERI_PMS_ALLOW_M (PMS_CORE0_MM_HP_PERI_PMS_ALLOW_V << PMS_CORE0_MM_HP_PERI_PMS_ALLOW_S) +#define PMS_CORE0_MM_HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_PERI_PMS_ALLOW_S 25 +/** PMS_CORE0_MM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access + * LP2HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_LP2HP_PERI_PMS_ALLOW (BIT(26)) +#define PMS_CORE0_MM_LP2HP_PERI_PMS_ALLOW_M (PMS_CORE0_MM_LP2HP_PERI_PMS_ALLOW_V << PMS_CORE0_MM_LP2HP_PERI_PMS_ALLOW_S) +#define PMS_CORE0_MM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_LP2HP_PERI_PMS_ALLOW_S 26 +/** PMS_CORE0_MM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP_DMA_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_DMA_PMS_ALLOW (BIT(27)) +#define PMS_CORE0_MM_DMA_PMS_ALLOW_M (PMS_CORE0_MM_DMA_PMS_ALLOW_V << PMS_CORE0_MM_DMA_PMS_ALLOW_S) +#define PMS_CORE0_MM_DMA_PMS_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_DMA_PMS_ALLOW_S 27 +/** PMS_CORE0_MM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_H264_DMA2D_ALLOW (BIT(28)) +#define PMS_CORE0_MM_HP_H264_DMA2D_ALLOW_M (PMS_CORE0_MM_HP_H264_DMA2D_ALLOW_V << PMS_CORE0_MM_HP_H264_DMA2D_ALLOW_S) +#define PMS_CORE0_MM_HP_H264_DMA2D_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_H264_DMA2D_ALLOW_S 28 -/** TEE_CORE0_MM_PMS_REG2_REG register - * NA - */ -#define TEE_CORE0_MM_PMS_REG2_REG (DR_REG_TEE_BASE + 0x10) -/** TEE_REG_CORE0_MM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_MCPWM0_ALLOW (BIT(0)) -#define TEE_REG_CORE0_MM_HP_MCPWM0_ALLOW_M (TEE_REG_CORE0_MM_HP_MCPWM0_ALLOW_V << TEE_REG_CORE0_MM_HP_MCPWM0_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_MCPWM0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_MCPWM0_ALLOW_S 0 -/** TEE_REG_CORE0_MM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_MCPWM1_ALLOW (BIT(1)) -#define TEE_REG_CORE0_MM_HP_MCPWM1_ALLOW_M (TEE_REG_CORE0_MM_HP_MCPWM1_ALLOW_V << TEE_REG_CORE0_MM_HP_MCPWM1_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_MCPWM1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_MCPWM1_ALLOW_S 1 -/** TEE_REG_CORE0_MM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_TIMER_GROUP0_ALLOW (BIT(2)) -#define TEE_REG_CORE0_MM_HP_TIMER_GROUP0_ALLOW_M (TEE_REG_CORE0_MM_HP_TIMER_GROUP0_ALLOW_V << TEE_REG_CORE0_MM_HP_TIMER_GROUP0_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_TIMER_GROUP0_ALLOW_S 2 -/** TEE_REG_CORE0_MM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_TIMER_GROUP1_ALLOW (BIT(3)) -#define TEE_REG_CORE0_MM_HP_TIMER_GROUP1_ALLOW_M (TEE_REG_CORE0_MM_HP_TIMER_GROUP1_ALLOW_V << TEE_REG_CORE0_MM_HP_TIMER_GROUP1_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_TIMER_GROUP1_ALLOW_S 3 -/** TEE_REG_CORE0_MM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_I2C0_ALLOW (BIT(4)) -#define TEE_REG_CORE0_MM_HP_I2C0_ALLOW_M (TEE_REG_CORE0_MM_HP_I2C0_ALLOW_V << TEE_REG_CORE0_MM_HP_I2C0_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_I2C0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_I2C0_ALLOW_S 4 -/** TEE_REG_CORE0_MM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_I2C1_ALLOW (BIT(5)) -#define TEE_REG_CORE0_MM_HP_I2C1_ALLOW_M (TEE_REG_CORE0_MM_HP_I2C1_ALLOW_V << TEE_REG_CORE0_MM_HP_I2C1_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_I2C1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_I2C1_ALLOW_S 5 -/** TEE_REG_CORE0_MM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_I2S0_ALLOW (BIT(6)) -#define TEE_REG_CORE0_MM_HP_I2S0_ALLOW_M (TEE_REG_CORE0_MM_HP_I2S0_ALLOW_V << TEE_REG_CORE0_MM_HP_I2S0_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_I2S0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_I2S0_ALLOW_S 6 -/** TEE_REG_CORE0_MM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_I2S1_ALLOW (BIT(7)) -#define TEE_REG_CORE0_MM_HP_I2S1_ALLOW_M (TEE_REG_CORE0_MM_HP_I2S1_ALLOW_V << TEE_REG_CORE0_MM_HP_I2S1_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_I2S1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_I2S1_ALLOW_S 7 -/** TEE_REG_CORE0_MM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_I2S2_ALLOW (BIT(8)) -#define TEE_REG_CORE0_MM_HP_I2S2_ALLOW_M (TEE_REG_CORE0_MM_HP_I2S2_ALLOW_V << TEE_REG_CORE0_MM_HP_I2S2_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_I2S2_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_I2S2_ALLOW_S 8 -/** TEE_REG_CORE0_MM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_PCNT_ALLOW (BIT(9)) -#define TEE_REG_CORE0_MM_HP_PCNT_ALLOW_M (TEE_REG_CORE0_MM_HP_PCNT_ALLOW_V << TEE_REG_CORE0_MM_HP_PCNT_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_PCNT_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_PCNT_ALLOW_S 9 -/** TEE_REG_CORE0_MM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_UART0_ALLOW (BIT(10)) -#define TEE_REG_CORE0_MM_HP_UART0_ALLOW_M (TEE_REG_CORE0_MM_HP_UART0_ALLOW_V << TEE_REG_CORE0_MM_HP_UART0_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_UART0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_UART0_ALLOW_S 10 -/** TEE_REG_CORE0_MM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_UART1_ALLOW (BIT(11)) -#define TEE_REG_CORE0_MM_HP_UART1_ALLOW_M (TEE_REG_CORE0_MM_HP_UART1_ALLOW_V << TEE_REG_CORE0_MM_HP_UART1_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_UART1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_UART1_ALLOW_S 11 -/** TEE_REG_CORE0_MM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_UART2_ALLOW (BIT(12)) -#define TEE_REG_CORE0_MM_HP_UART2_ALLOW_M (TEE_REG_CORE0_MM_HP_UART2_ALLOW_V << TEE_REG_CORE0_MM_HP_UART2_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_UART2_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_UART2_ALLOW_S 12 -/** TEE_REG_CORE0_MM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_UART3_ALLOW (BIT(13)) -#define TEE_REG_CORE0_MM_HP_UART3_ALLOW_M (TEE_REG_CORE0_MM_HP_UART3_ALLOW_V << TEE_REG_CORE0_MM_HP_UART3_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_UART3_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_UART3_ALLOW_S 13 -/** TEE_REG_CORE0_MM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_UART4_ALLOW (BIT(14)) -#define TEE_REG_CORE0_MM_HP_UART4_ALLOW_M (TEE_REG_CORE0_MM_HP_UART4_ALLOW_V << TEE_REG_CORE0_MM_HP_UART4_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_UART4_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_UART4_ALLOW_S 14 -/** TEE_REG_CORE0_MM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_PARLIO_ALLOW (BIT(15)) -#define TEE_REG_CORE0_MM_HP_PARLIO_ALLOW_M (TEE_REG_CORE0_MM_HP_PARLIO_ALLOW_V << TEE_REG_CORE0_MM_HP_PARLIO_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_PARLIO_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_PARLIO_ALLOW_S 15 -/** TEE_REG_CORE0_MM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_GPSPI2_ALLOW (BIT(16)) -#define TEE_REG_CORE0_MM_HP_GPSPI2_ALLOW_M (TEE_REG_CORE0_MM_HP_GPSPI2_ALLOW_V << TEE_REG_CORE0_MM_HP_GPSPI2_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_GPSPI2_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_GPSPI2_ALLOW_S 16 -/** TEE_REG_CORE0_MM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_GPSPI3_ALLOW (BIT(17)) -#define TEE_REG_CORE0_MM_HP_GPSPI3_ALLOW_M (TEE_REG_CORE0_MM_HP_GPSPI3_ALLOW_V << TEE_REG_CORE0_MM_HP_GPSPI3_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_GPSPI3_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_GPSPI3_ALLOW_S 17 -/** TEE_REG_CORE0_MM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_USBDEVICE_ALLOW (BIT(18)) -#define TEE_REG_CORE0_MM_HP_USBDEVICE_ALLOW_M (TEE_REG_CORE0_MM_HP_USBDEVICE_ALLOW_V << TEE_REG_CORE0_MM_HP_USBDEVICE_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_USBDEVICE_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_USBDEVICE_ALLOW_S 18 -/** TEE_REG_CORE0_MM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_LEDC_ALLOW (BIT(19)) -#define TEE_REG_CORE0_MM_HP_LEDC_ALLOW_M (TEE_REG_CORE0_MM_HP_LEDC_ALLOW_V << TEE_REG_CORE0_MM_HP_LEDC_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_LEDC_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_LEDC_ALLOW_S 19 -/** TEE_REG_CORE0_MM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_ETM_ALLOW (BIT(21)) -#define TEE_REG_CORE0_MM_HP_ETM_ALLOW_M (TEE_REG_CORE0_MM_HP_ETM_ALLOW_V << TEE_REG_CORE0_MM_HP_ETM_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_ETM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_ETM_ALLOW_S 21 -/** TEE_REG_CORE0_MM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_INTRMTX_ALLOW (BIT(22)) -#define TEE_REG_CORE0_MM_HP_INTRMTX_ALLOW_M (TEE_REG_CORE0_MM_HP_INTRMTX_ALLOW_V << TEE_REG_CORE0_MM_HP_INTRMTX_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_INTRMTX_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_INTRMTX_ALLOW_S 22 -/** TEE_REG_CORE0_MM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_TWAI0_ALLOW (BIT(23)) -#define TEE_REG_CORE0_MM_HP_TWAI0_ALLOW_M (TEE_REG_CORE0_MM_HP_TWAI0_ALLOW_V << TEE_REG_CORE0_MM_HP_TWAI0_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_TWAI0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_TWAI0_ALLOW_S 23 -/** TEE_REG_CORE0_MM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_TWAI1_ALLOW (BIT(24)) -#define TEE_REG_CORE0_MM_HP_TWAI1_ALLOW_M (TEE_REG_CORE0_MM_HP_TWAI1_ALLOW_V << TEE_REG_CORE0_MM_HP_TWAI1_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_TWAI1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_TWAI1_ALLOW_S 24 -/** TEE_REG_CORE0_MM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_TWAI2_ALLOW (BIT(25)) -#define TEE_REG_CORE0_MM_HP_TWAI2_ALLOW_M (TEE_REG_CORE0_MM_HP_TWAI2_ALLOW_V << TEE_REG_CORE0_MM_HP_TWAI2_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_TWAI2_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_TWAI2_ALLOW_S 25 -/** TEE_REG_CORE0_MM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_I3C_MST_ALLOW (BIT(26)) -#define TEE_REG_CORE0_MM_HP_I3C_MST_ALLOW_M (TEE_REG_CORE0_MM_HP_I3C_MST_ALLOW_V << TEE_REG_CORE0_MM_HP_I3C_MST_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_I3C_MST_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_I3C_MST_ALLOW_S 26 -/** TEE_REG_CORE0_MM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_I3C_SLV_ALLOW (BIT(27)) -#define TEE_REG_CORE0_MM_HP_I3C_SLV_ALLOW_M (TEE_REG_CORE0_MM_HP_I3C_SLV_ALLOW_V << TEE_REG_CORE0_MM_HP_I3C_SLV_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_I3C_SLV_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_I3C_SLV_ALLOW_S 27 -/** TEE_REG_CORE0_MM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_LCDCAM_ALLOW (BIT(28)) -#define TEE_REG_CORE0_MM_HP_LCDCAM_ALLOW_M (TEE_REG_CORE0_MM_HP_LCDCAM_ALLOW_V << TEE_REG_CORE0_MM_HP_LCDCAM_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_LCDCAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_LCDCAM_ALLOW_S 28 -/** TEE_REG_CORE0_MM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_ADC_ALLOW (BIT(30)) -#define TEE_REG_CORE0_MM_HP_ADC_ALLOW_M (TEE_REG_CORE0_MM_HP_ADC_ALLOW_V << TEE_REG_CORE0_MM_HP_ADC_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_ADC_ALLOW_S 30 -/** TEE_REG_CORE0_MM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_UHCI_ALLOW (BIT(31)) -#define TEE_REG_CORE0_MM_HP_UHCI_ALLOW_M (TEE_REG_CORE0_MM_HP_UHCI_ALLOW_V << TEE_REG_CORE0_MM_HP_UHCI_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_UHCI_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_UHCI_ALLOW_S 31 +/** PMS_CORE0_MM_HP_PERI_PMS_REG2_REG register + * Permission control register2 for HP CPU0 in machine mode + */ +#define PMS_CORE0_MM_HP_PERI_PMS_REG2_REG (DR_REG_HP_PERI_PMS_BASE + 0x10) +/** PMS_CORE0_MM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP MCPWM0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_MCPWM0_ALLOW (BIT(0)) +#define PMS_CORE0_MM_HP_MCPWM0_ALLOW_M (PMS_CORE0_MM_HP_MCPWM0_ALLOW_V << PMS_CORE0_MM_HP_MCPWM0_ALLOW_S) +#define PMS_CORE0_MM_HP_MCPWM0_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_MCPWM0_ALLOW_S 0 +/** PMS_CORE0_MM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP MCPWM1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_MCPWM1_ALLOW (BIT(1)) +#define PMS_CORE0_MM_HP_MCPWM1_ALLOW_M (PMS_CORE0_MM_HP_MCPWM1_ALLOW_V << PMS_CORE0_MM_HP_MCPWM1_ALLOW_S) +#define PMS_CORE0_MM_HP_MCPWM1_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_MCPWM1_ALLOW_S 1 +/** PMS_CORE0_MM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP timer + * group0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_TIMER_GROUP0_ALLOW (BIT(2)) +#define PMS_CORE0_MM_HP_TIMER_GROUP0_ALLOW_M (PMS_CORE0_MM_HP_TIMER_GROUP0_ALLOW_V << PMS_CORE0_MM_HP_TIMER_GROUP0_ALLOW_S) +#define PMS_CORE0_MM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_TIMER_GROUP0_ALLOW_S 2 +/** PMS_CORE0_MM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP timer group1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_TIMER_GROUP1_ALLOW (BIT(3)) +#define PMS_CORE0_MM_HP_TIMER_GROUP1_ALLOW_M (PMS_CORE0_MM_HP_TIMER_GROUP1_ALLOW_V << PMS_CORE0_MM_HP_TIMER_GROUP1_ALLOW_S) +#define PMS_CORE0_MM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_TIMER_GROUP1_ALLOW_S 3 +/** PMS_CORE0_MM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP I2C0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_I2C0_ALLOW (BIT(4)) +#define PMS_CORE0_MM_HP_I2C0_ALLOW_M (PMS_CORE0_MM_HP_I2C0_ALLOW_V << PMS_CORE0_MM_HP_I2C0_ALLOW_S) +#define PMS_CORE0_MM_HP_I2C0_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_I2C0_ALLOW_S 4 +/** PMS_CORE0_MM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP I2C1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_I2C1_ALLOW (BIT(5)) +#define PMS_CORE0_MM_HP_I2C1_ALLOW_M (PMS_CORE0_MM_HP_I2C1_ALLOW_V << PMS_CORE0_MM_HP_I2C1_ALLOW_S) +#define PMS_CORE0_MM_HP_I2C1_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_I2C1_ALLOW_S 5 +/** PMS_CORE0_MM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP I2S0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_I2S0_ALLOW (BIT(6)) +#define PMS_CORE0_MM_HP_I2S0_ALLOW_M (PMS_CORE0_MM_HP_I2S0_ALLOW_V << PMS_CORE0_MM_HP_I2S0_ALLOW_S) +#define PMS_CORE0_MM_HP_I2S0_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_I2S0_ALLOW_S 6 +/** PMS_CORE0_MM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP I2S1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_I2S1_ALLOW (BIT(7)) +#define PMS_CORE0_MM_HP_I2S1_ALLOW_M (PMS_CORE0_MM_HP_I2S1_ALLOW_V << PMS_CORE0_MM_HP_I2S1_ALLOW_S) +#define PMS_CORE0_MM_HP_I2S1_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_I2S1_ALLOW_S 7 +/** PMS_CORE0_MM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP I2S2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_I2S2_ALLOW (BIT(8)) +#define PMS_CORE0_MM_HP_I2S2_ALLOW_M (PMS_CORE0_MM_HP_I2S2_ALLOW_V << PMS_CORE0_MM_HP_I2S2_ALLOW_S) +#define PMS_CORE0_MM_HP_I2S2_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_I2S2_ALLOW_S 8 +/** PMS_CORE0_MM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP PCNT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_PCNT_ALLOW (BIT(9)) +#define PMS_CORE0_MM_HP_PCNT_ALLOW_M (PMS_CORE0_MM_HP_PCNT_ALLOW_V << PMS_CORE0_MM_HP_PCNT_ALLOW_S) +#define PMS_CORE0_MM_HP_PCNT_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_PCNT_ALLOW_S 9 +/** PMS_CORE0_MM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP UART0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_UART0_ALLOW (BIT(10)) +#define PMS_CORE0_MM_HP_UART0_ALLOW_M (PMS_CORE0_MM_HP_UART0_ALLOW_V << PMS_CORE0_MM_HP_UART0_ALLOW_S) +#define PMS_CORE0_MM_HP_UART0_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_UART0_ALLOW_S 10 +/** PMS_CORE0_MM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP UART1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_UART1_ALLOW (BIT(11)) +#define PMS_CORE0_MM_HP_UART1_ALLOW_M (PMS_CORE0_MM_HP_UART1_ALLOW_V << PMS_CORE0_MM_HP_UART1_ALLOW_S) +#define PMS_CORE0_MM_HP_UART1_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_UART1_ALLOW_S 11 +/** PMS_CORE0_MM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP UART2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_UART2_ALLOW (BIT(12)) +#define PMS_CORE0_MM_HP_UART2_ALLOW_M (PMS_CORE0_MM_HP_UART2_ALLOW_V << PMS_CORE0_MM_HP_UART2_ALLOW_S) +#define PMS_CORE0_MM_HP_UART2_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_UART2_ALLOW_S 12 +/** PMS_CORE0_MM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP UART3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_UART3_ALLOW (BIT(13)) +#define PMS_CORE0_MM_HP_UART3_ALLOW_M (PMS_CORE0_MM_HP_UART3_ALLOW_V << PMS_CORE0_MM_HP_UART3_ALLOW_S) +#define PMS_CORE0_MM_HP_UART3_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_UART3_ALLOW_S 13 +/** PMS_CORE0_MM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP UART4. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_UART4_ALLOW (BIT(14)) +#define PMS_CORE0_MM_HP_UART4_ALLOW_M (PMS_CORE0_MM_HP_UART4_ALLOW_V << PMS_CORE0_MM_HP_UART4_ALLOW_S) +#define PMS_CORE0_MM_HP_UART4_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_UART4_ALLOW_S 14 +/** PMS_CORE0_MM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP PARLIO. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_PARLIO_ALLOW (BIT(15)) +#define PMS_CORE0_MM_HP_PARLIO_ALLOW_M (PMS_CORE0_MM_HP_PARLIO_ALLOW_V << PMS_CORE0_MM_HP_PARLIO_ALLOW_S) +#define PMS_CORE0_MM_HP_PARLIO_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_PARLIO_ALLOW_S 15 +/** PMS_CORE0_MM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP GP-SPI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_GPSPI2_ALLOW (BIT(16)) +#define PMS_CORE0_MM_HP_GPSPI2_ALLOW_M (PMS_CORE0_MM_HP_GPSPI2_ALLOW_V << PMS_CORE0_MM_HP_GPSPI2_ALLOW_S) +#define PMS_CORE0_MM_HP_GPSPI2_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_GPSPI2_ALLOW_S 16 +/** PMS_CORE0_MM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP GP-SPI3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_GPSPI3_ALLOW (BIT(17)) +#define PMS_CORE0_MM_HP_GPSPI3_ALLOW_M (PMS_CORE0_MM_HP_GPSPI3_ALLOW_V << PMS_CORE0_MM_HP_GPSPI3_ALLOW_S) +#define PMS_CORE0_MM_HP_GPSPI3_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_GPSPI3_ALLOW_S 17 +/** PMS_CORE0_MM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP USB + * Serial/JTAG Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_USBDEVICE_ALLOW (BIT(18)) +#define PMS_CORE0_MM_HP_USBDEVICE_ALLOW_M (PMS_CORE0_MM_HP_USBDEVICE_ALLOW_V << PMS_CORE0_MM_HP_USBDEVICE_ALLOW_S) +#define PMS_CORE0_MM_HP_USBDEVICE_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_USBDEVICE_ALLOW_S 18 +/** PMS_CORE0_MM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP LEDC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_LEDC_ALLOW (BIT(19)) +#define PMS_CORE0_MM_HP_LEDC_ALLOW_M (PMS_CORE0_MM_HP_LEDC_ALLOW_V << PMS_CORE0_MM_HP_LEDC_ALLOW_S) +#define PMS_CORE0_MM_HP_LEDC_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_LEDC_ALLOW_S 19 +/** PMS_CORE0_MM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP ETM (Event + * Task Matrix). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_ETM_ALLOW (BIT(21)) +#define PMS_CORE0_MM_HP_ETM_ALLOW_M (PMS_CORE0_MM_HP_ETM_ALLOW_V << PMS_CORE0_MM_HP_ETM_ALLOW_S) +#define PMS_CORE0_MM_HP_ETM_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_ETM_ALLOW_S 21 +/** PMS_CORE0_MM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP interrupt + * matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_INTRMTX_ALLOW (BIT(22)) +#define PMS_CORE0_MM_HP_INTRMTX_ALLOW_M (PMS_CORE0_MM_HP_INTRMTX_ALLOW_V << PMS_CORE0_MM_HP_INTRMTX_ALLOW_S) +#define PMS_CORE0_MM_HP_INTRMTX_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_INTRMTX_ALLOW_S 22 +/** PMS_CORE0_MM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP TWAI0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_TWAI0_ALLOW (BIT(23)) +#define PMS_CORE0_MM_HP_TWAI0_ALLOW_M (PMS_CORE0_MM_HP_TWAI0_ALLOW_V << PMS_CORE0_MM_HP_TWAI0_ALLOW_S) +#define PMS_CORE0_MM_HP_TWAI0_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_TWAI0_ALLOW_S 23 +/** PMS_CORE0_MM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP TWAI1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_TWAI1_ALLOW (BIT(24)) +#define PMS_CORE0_MM_HP_TWAI1_ALLOW_M (PMS_CORE0_MM_HP_TWAI1_ALLOW_V << PMS_CORE0_MM_HP_TWAI1_ALLOW_S) +#define PMS_CORE0_MM_HP_TWAI1_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_TWAI1_ALLOW_S 24 +/** PMS_CORE0_MM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP TWAI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_TWAI2_ALLOW (BIT(25)) +#define PMS_CORE0_MM_HP_TWAI2_ALLOW_M (PMS_CORE0_MM_HP_TWAI2_ALLOW_V << PMS_CORE0_MM_HP_TWAI2_ALLOW_S) +#define PMS_CORE0_MM_HP_TWAI2_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_TWAI2_ALLOW_S 25 +/** PMS_CORE0_MM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP I3C master + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_I3C_MST_ALLOW (BIT(26)) +#define PMS_CORE0_MM_HP_I3C_MST_ALLOW_M (PMS_CORE0_MM_HP_I3C_MST_ALLOW_V << PMS_CORE0_MM_HP_I3C_MST_ALLOW_S) +#define PMS_CORE0_MM_HP_I3C_MST_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_I3C_MST_ALLOW_S 26 +/** PMS_CORE0_MM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP I3C slave + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_I3C_SLV_ALLOW (BIT(27)) +#define PMS_CORE0_MM_HP_I3C_SLV_ALLOW_M (PMS_CORE0_MM_HP_I3C_SLV_ALLOW_V << PMS_CORE0_MM_HP_I3C_SLV_ALLOW_S) +#define PMS_CORE0_MM_HP_I3C_SLV_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_I3C_SLV_ALLOW_S 27 +/** PMS_CORE0_MM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP LCD_CAM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_LCDCAM_ALLOW (BIT(28)) +#define PMS_CORE0_MM_HP_LCDCAM_ALLOW_M (PMS_CORE0_MM_HP_LCDCAM_ALLOW_V << PMS_CORE0_MM_HP_LCDCAM_ALLOW_S) +#define PMS_CORE0_MM_HP_LCDCAM_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_LCDCAM_ALLOW_S 28 +/** PMS_CORE0_MM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_ADC_ALLOW (BIT(30)) +#define PMS_CORE0_MM_HP_ADC_ALLOW_M (PMS_CORE0_MM_HP_ADC_ALLOW_V << PMS_CORE0_MM_HP_ADC_ALLOW_S) +#define PMS_CORE0_MM_HP_ADC_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_ADC_ALLOW_S 30 +/** PMS_CORE0_MM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP UHCI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_UHCI_ALLOW (BIT(31)) +#define PMS_CORE0_MM_HP_UHCI_ALLOW_M (PMS_CORE0_MM_HP_UHCI_ALLOW_V << PMS_CORE0_MM_HP_UHCI_ALLOW_S) +#define PMS_CORE0_MM_HP_UHCI_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_UHCI_ALLOW_S 31 -/** TEE_CORE0_MM_PMS_REG3_REG register - * NA - */ -#define TEE_CORE0_MM_PMS_REG3_REG (DR_REG_TEE_BASE + 0x14) -/** TEE_REG_CORE0_MM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_GPIO_ALLOW (BIT(0)) -#define TEE_REG_CORE0_MM_HP_GPIO_ALLOW_M (TEE_REG_CORE0_MM_HP_GPIO_ALLOW_V << TEE_REG_CORE0_MM_HP_GPIO_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_GPIO_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_GPIO_ALLOW_S 0 -/** TEE_REG_CORE0_MM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_IOMUX_ALLOW (BIT(1)) -#define TEE_REG_CORE0_MM_HP_IOMUX_ALLOW_M (TEE_REG_CORE0_MM_HP_IOMUX_ALLOW_V << TEE_REG_CORE0_MM_HP_IOMUX_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_IOMUX_ALLOW_S 1 -/** TEE_REG_CORE0_MM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_SYSTIMER_ALLOW (BIT(2)) -#define TEE_REG_CORE0_MM_HP_SYSTIMER_ALLOW_M (TEE_REG_CORE0_MM_HP_SYSTIMER_ALLOW_V << TEE_REG_CORE0_MM_HP_SYSTIMER_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_SYSTIMER_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_SYSTIMER_ALLOW_S 2 -/** TEE_REG_CORE0_MM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_SYS_REG_ALLOW (BIT(3)) -#define TEE_REG_CORE0_MM_HP_SYS_REG_ALLOW_M (TEE_REG_CORE0_MM_HP_SYS_REG_ALLOW_V << TEE_REG_CORE0_MM_HP_SYS_REG_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_SYS_REG_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_SYS_REG_ALLOW_S 3 -/** TEE_REG_CORE0_MM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE0_MM_HP_CLKRST_ALLOW (BIT(4)) -#define TEE_REG_CORE0_MM_HP_CLKRST_ALLOW_M (TEE_REG_CORE0_MM_HP_CLKRST_ALLOW_V << TEE_REG_CORE0_MM_HP_CLKRST_ALLOW_S) -#define TEE_REG_CORE0_MM_HP_CLKRST_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_MM_HP_CLKRST_ALLOW_S 4 +/** PMS_CORE0_MM_HP_PERI_PMS_REG3_REG register + * Permission control register3 for HP CPU0 in machine mode + */ +#define PMS_CORE0_MM_HP_PERI_PMS_REG3_REG (DR_REG_HP_PERI_PMS_BASE + 0x14) +/** PMS_CORE0_MM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP GPIO Matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_GPIO_ALLOW (BIT(0)) +#define PMS_CORE0_MM_HP_GPIO_ALLOW_M (PMS_CORE0_MM_HP_GPIO_ALLOW_V << PMS_CORE0_MM_HP_GPIO_ALLOW_S) +#define PMS_CORE0_MM_HP_GPIO_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_GPIO_ALLOW_S 0 +/** PMS_CORE0_MM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_IOMUX_ALLOW (BIT(1)) +#define PMS_CORE0_MM_HP_IOMUX_ALLOW_M (PMS_CORE0_MM_HP_IOMUX_ALLOW_V << PMS_CORE0_MM_HP_IOMUX_ALLOW_S) +#define PMS_CORE0_MM_HP_IOMUX_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_IOMUX_ALLOW_S 1 +/** PMS_CORE0_MM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP system + * timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_SYSTIMER_ALLOW (BIT(2)) +#define PMS_CORE0_MM_HP_SYSTIMER_ALLOW_M (PMS_CORE0_MM_HP_SYSTIMER_ALLOW_V << PMS_CORE0_MM_HP_SYSTIMER_ALLOW_S) +#define PMS_CORE0_MM_HP_SYSTIMER_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_SYSTIMER_ALLOW_S 2 +/** PMS_CORE0_MM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP system + * register. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_SYS_REG_ALLOW (BIT(3)) +#define PMS_CORE0_MM_HP_SYS_REG_ALLOW_M (PMS_CORE0_MM_HP_SYS_REG_ALLOW_V << PMS_CORE0_MM_HP_SYS_REG_ALLOW_S) +#define PMS_CORE0_MM_HP_SYS_REG_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_SYS_REG_ALLOW_S 3 +/** PMS_CORE0_MM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU0 in machine mode has permission to access HP_SYS_CLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_MM_HP_CLKRST_ALLOW (BIT(4)) +#define PMS_CORE0_MM_HP_CLKRST_ALLOW_M (PMS_CORE0_MM_HP_CLKRST_ALLOW_V << PMS_CORE0_MM_HP_CLKRST_ALLOW_S) +#define PMS_CORE0_MM_HP_CLKRST_ALLOW_V 0x00000001U +#define PMS_CORE0_MM_HP_CLKRST_ALLOW_S 4 -/** TEE_CORE0_UM_PMS_REG0_REG register - * NA - */ -#define TEE_CORE0_UM_PMS_REG0_REG (DR_REG_TEE_BASE + 0x18) -/** TEE_REG_CORE0_UM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_PSRAM_ALLOW (BIT(0)) -#define TEE_REG_CORE0_UM_PSRAM_ALLOW_M (TEE_REG_CORE0_UM_PSRAM_ALLOW_V << TEE_REG_CORE0_UM_PSRAM_ALLOW_S) -#define TEE_REG_CORE0_UM_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_PSRAM_ALLOW_S 0 -/** TEE_REG_CORE0_UM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_FLASH_ALLOW (BIT(1)) -#define TEE_REG_CORE0_UM_FLASH_ALLOW_M (TEE_REG_CORE0_UM_FLASH_ALLOW_V << TEE_REG_CORE0_UM_FLASH_ALLOW_S) -#define TEE_REG_CORE0_UM_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_FLASH_ALLOW_S 1 -/** TEE_REG_CORE0_UM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_L2MEM_ALLOW (BIT(2)) -#define TEE_REG_CORE0_UM_L2MEM_ALLOW_M (TEE_REG_CORE0_UM_L2MEM_ALLOW_V << TEE_REG_CORE0_UM_L2MEM_ALLOW_S) -#define TEE_REG_CORE0_UM_L2MEM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_L2MEM_ALLOW_S 2 -/** TEE_REG_CORE0_UM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_L2ROM_ALLOW (BIT(3)) -#define TEE_REG_CORE0_UM_L2ROM_ALLOW_M (TEE_REG_CORE0_UM_L2ROM_ALLOW_V << TEE_REG_CORE0_UM_L2ROM_ALLOW_S) -#define TEE_REG_CORE0_UM_L2ROM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_L2ROM_ALLOW_S 3 -/** TEE_REG_CORE0_UM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_TRACE0_ALLOW (BIT(6)) -#define TEE_REG_CORE0_UM_TRACE0_ALLOW_M (TEE_REG_CORE0_UM_TRACE0_ALLOW_V << TEE_REG_CORE0_UM_TRACE0_ALLOW_S) -#define TEE_REG_CORE0_UM_TRACE0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_TRACE0_ALLOW_S 6 -/** TEE_REG_CORE0_UM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_TRACE1_ALLOW (BIT(7)) -#define TEE_REG_CORE0_UM_TRACE1_ALLOW_M (TEE_REG_CORE0_UM_TRACE1_ALLOW_V << TEE_REG_CORE0_UM_TRACE1_ALLOW_S) -#define TEE_REG_CORE0_UM_TRACE1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_TRACE1_ALLOW_S 7 -/** TEE_REG_CORE0_UM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_CPU_BUS_MON_ALLOW (BIT(8)) -#define TEE_REG_CORE0_UM_CPU_BUS_MON_ALLOW_M (TEE_REG_CORE0_UM_CPU_BUS_MON_ALLOW_V << TEE_REG_CORE0_UM_CPU_BUS_MON_ALLOW_S) -#define TEE_REG_CORE0_UM_CPU_BUS_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_CPU_BUS_MON_ALLOW_S 8 -/** TEE_REG_CORE0_UM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_L2MEM_MON_ALLOW (BIT(9)) -#define TEE_REG_CORE0_UM_L2MEM_MON_ALLOW_M (TEE_REG_CORE0_UM_L2MEM_MON_ALLOW_V << TEE_REG_CORE0_UM_L2MEM_MON_ALLOW_S) -#define TEE_REG_CORE0_UM_L2MEM_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_L2MEM_MON_ALLOW_S 9 -/** TEE_REG_CORE0_UM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_TCM_MON_ALLOW (BIT(10)) -#define TEE_REG_CORE0_UM_TCM_MON_ALLOW_M (TEE_REG_CORE0_UM_TCM_MON_ALLOW_V << TEE_REG_CORE0_UM_TCM_MON_ALLOW_S) -#define TEE_REG_CORE0_UM_TCM_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_TCM_MON_ALLOW_S 10 -/** TEE_REG_CORE0_UM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_CACHE_ALLOW (BIT(11)) -#define TEE_REG_CORE0_UM_CACHE_ALLOW_M (TEE_REG_CORE0_UM_CACHE_ALLOW_V << TEE_REG_CORE0_UM_CACHE_ALLOW_S) -#define TEE_REG_CORE0_UM_CACHE_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_CACHE_ALLOW_S 11 +/** PMS_CORE0_UM_HP_PERI_PMS_REG0_REG register + * Permission control register0 for HP CPU0 in user mode + */ +#define PMS_CORE0_UM_HP_PERI_PMS_REG0_REG (DR_REG_HP_PERI_PMS_BASE + 0x18) +/** PMS_CORE0_UM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access external RAM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_PSRAM_ALLOW (BIT(0)) +#define PMS_CORE0_UM_PSRAM_ALLOW_M (PMS_CORE0_UM_PSRAM_ALLOW_V << PMS_CORE0_UM_PSRAM_ALLOW_S) +#define PMS_CORE0_UM_PSRAM_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_PSRAM_ALLOW_S 0 +/** PMS_CORE0_UM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access external flash + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_FLASH_ALLOW (BIT(1)) +#define PMS_CORE0_UM_FLASH_ALLOW_M (PMS_CORE0_UM_FLASH_ALLOW_V << PMS_CORE0_UM_FLASH_ALLOW_S) +#define PMS_CORE0_UM_FLASH_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_FLASH_ALLOW_S 1 +/** PMS_CORE0_UM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP L2MEM without + * going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_L2MEM_ALLOW (BIT(2)) +#define PMS_CORE0_UM_L2MEM_ALLOW_M (PMS_CORE0_UM_L2MEM_ALLOW_V << PMS_CORE0_UM_L2MEM_ALLOW_S) +#define PMS_CORE0_UM_L2MEM_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_L2MEM_ALLOW_S 2 +/** PMS_CORE0_UM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP ROM without + * going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_L2ROM_ALLOW (BIT(3)) +#define PMS_CORE0_UM_L2ROM_ALLOW_M (PMS_CORE0_UM_L2ROM_ALLOW_V << PMS_CORE0_UM_L2ROM_ALLOW_S) +#define PMS_CORE0_UM_L2ROM_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_L2ROM_ALLOW_S 3 +/** PMS_CORE0_UM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access TRACE0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_TRACE0_ALLOW (BIT(6)) +#define PMS_CORE0_UM_TRACE0_ALLOW_M (PMS_CORE0_UM_TRACE0_ALLOW_V << PMS_CORE0_UM_TRACE0_ALLOW_S) +#define PMS_CORE0_UM_TRACE0_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_TRACE0_ALLOW_S 6 +/** PMS_CORE0_UM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access TRACE1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_TRACE1_ALLOW (BIT(7)) +#define PMS_CORE0_UM_TRACE1_ALLOW_M (PMS_CORE0_UM_TRACE1_ALLOW_V << PMS_CORE0_UM_TRACE1_ALLOW_S) +#define PMS_CORE0_UM_TRACE1_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_TRACE1_ALLOW_S 7 +/** PMS_CORE0_UM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access CPU bus monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_CPU_BUS_MON_ALLOW (BIT(8)) +#define PMS_CORE0_UM_CPU_BUS_MON_ALLOW_M (PMS_CORE0_UM_CPU_BUS_MON_ALLOW_V << PMS_CORE0_UM_CPU_BUS_MON_ALLOW_S) +#define PMS_CORE0_UM_CPU_BUS_MON_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_CPU_BUS_MON_ALLOW_S 8 +/** PMS_CORE0_UM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access L2MEM monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_L2MEM_MON_ALLOW (BIT(9)) +#define PMS_CORE0_UM_L2MEM_MON_ALLOW_M (PMS_CORE0_UM_L2MEM_MON_ALLOW_V << PMS_CORE0_UM_L2MEM_MON_ALLOW_S) +#define PMS_CORE0_UM_L2MEM_MON_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_L2MEM_MON_ALLOW_S 9 +/** PMS_CORE0_UM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access TCM monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_TCM_MON_ALLOW (BIT(10)) +#define PMS_CORE0_UM_TCM_MON_ALLOW_M (PMS_CORE0_UM_TCM_MON_ALLOW_V << PMS_CORE0_UM_TCM_MON_ALLOW_S) +#define PMS_CORE0_UM_TCM_MON_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_TCM_MON_ALLOW_S 10 +/** PMS_CORE0_UM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_CACHE_ALLOW (BIT(11)) +#define PMS_CORE0_UM_CACHE_ALLOW_M (PMS_CORE0_UM_CACHE_ALLOW_V << PMS_CORE0_UM_CACHE_ALLOW_S) +#define PMS_CORE0_UM_CACHE_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_CACHE_ALLOW_S 11 -/** TEE_CORE0_UM_PMS_REG1_REG register - * NA - */ -#define TEE_CORE0_UM_PMS_REG1_REG (DR_REG_TEE_BASE + 0x1c) -/** TEE_REG_CORE0_UM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_USBOTG_ALLOW (BIT(0)) -#define TEE_REG_CORE0_UM_HP_USBOTG_ALLOW_M (TEE_REG_CORE0_UM_HP_USBOTG_ALLOW_V << TEE_REG_CORE0_UM_HP_USBOTG_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_USBOTG_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_USBOTG_ALLOW_S 0 -/** TEE_REG_CORE0_UM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_USBOTG11_ALLOW (BIT(1)) -#define TEE_REG_CORE0_UM_HP_USBOTG11_ALLOW_M (TEE_REG_CORE0_UM_HP_USBOTG11_ALLOW_V << TEE_REG_CORE0_UM_HP_USBOTG11_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_USBOTG11_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_USBOTG11_ALLOW_S 1 -/** TEE_REG_CORE0_UM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) -#define TEE_REG_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_M (TEE_REG_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_V << TEE_REG_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_S 2 -/** TEE_REG_CORE0_UM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_GDMA_ALLOW (BIT(3)) -#define TEE_REG_CORE0_UM_HP_GDMA_ALLOW_M (TEE_REG_CORE0_UM_HP_GDMA_ALLOW_V << TEE_REG_CORE0_UM_HP_GDMA_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_GDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_GDMA_ALLOW_S 3 -/** TEE_REG_CORE0_UM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_REGDMA_ALLOW (BIT(4)) -#define TEE_REG_CORE0_UM_HP_REGDMA_ALLOW_M (TEE_REG_CORE0_UM_HP_REGDMA_ALLOW_V << TEE_REG_CORE0_UM_HP_REGDMA_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_REGDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_REGDMA_ALLOW_S 4 -/** TEE_REG_CORE0_UM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_SDMMC_ALLOW (BIT(5)) -#define TEE_REG_CORE0_UM_HP_SDMMC_ALLOW_M (TEE_REG_CORE0_UM_HP_SDMMC_ALLOW_V << TEE_REG_CORE0_UM_HP_SDMMC_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_SDMMC_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_SDMMC_ALLOW_S 5 -/** TEE_REG_CORE0_UM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_AHB_PDMA_ALLOW (BIT(6)) -#define TEE_REG_CORE0_UM_HP_AHB_PDMA_ALLOW_M (TEE_REG_CORE0_UM_HP_AHB_PDMA_ALLOW_V << TEE_REG_CORE0_UM_HP_AHB_PDMA_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_AHB_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_AHB_PDMA_ALLOW_S 6 -/** TEE_REG_CORE0_UM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_JPEG_ALLOW (BIT(7)) -#define TEE_REG_CORE0_UM_HP_JPEG_ALLOW_M (TEE_REG_CORE0_UM_HP_JPEG_ALLOW_V << TEE_REG_CORE0_UM_HP_JPEG_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_JPEG_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_JPEG_ALLOW_S 7 -/** TEE_REG_CORE0_UM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_PPA_ALLOW (BIT(8)) -#define TEE_REG_CORE0_UM_HP_PPA_ALLOW_M (TEE_REG_CORE0_UM_HP_PPA_ALLOW_V << TEE_REG_CORE0_UM_HP_PPA_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_PPA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_PPA_ALLOW_S 8 -/** TEE_REG_CORE0_UM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_DMA2D_ALLOW (BIT(9)) -#define TEE_REG_CORE0_UM_HP_DMA2D_ALLOW_M (TEE_REG_CORE0_UM_HP_DMA2D_ALLOW_V << TEE_REG_CORE0_UM_HP_DMA2D_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_DMA2D_ALLOW_S 9 -/** TEE_REG_CORE0_UM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_KEY_MANAGER_ALLOW (BIT(10)) -#define TEE_REG_CORE0_UM_HP_KEY_MANAGER_ALLOW_M (TEE_REG_CORE0_UM_HP_KEY_MANAGER_ALLOW_V << TEE_REG_CORE0_UM_HP_KEY_MANAGER_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_KEY_MANAGER_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_KEY_MANAGER_ALLOW_S 10 -/** TEE_REG_CORE0_UM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_AXI_PDMA_ALLOW (BIT(11)) -#define TEE_REG_CORE0_UM_HP_AXI_PDMA_ALLOW_M (TEE_REG_CORE0_UM_HP_AXI_PDMA_ALLOW_V << TEE_REG_CORE0_UM_HP_AXI_PDMA_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_AXI_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_AXI_PDMA_ALLOW_S 11 -/** TEE_REG_CORE0_UM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_FLASH_ALLOW (BIT(12)) -#define TEE_REG_CORE0_UM_HP_FLASH_ALLOW_M (TEE_REG_CORE0_UM_HP_FLASH_ALLOW_V << TEE_REG_CORE0_UM_HP_FLASH_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_FLASH_ALLOW_S 12 -/** TEE_REG_CORE0_UM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_PSRAM_ALLOW (BIT(13)) -#define TEE_REG_CORE0_UM_HP_PSRAM_ALLOW_M (TEE_REG_CORE0_UM_HP_PSRAM_ALLOW_V << TEE_REG_CORE0_UM_HP_PSRAM_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_PSRAM_ALLOW_S 13 -/** TEE_REG_CORE0_UM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_CRYPTO_ALLOW (BIT(14)) -#define TEE_REG_CORE0_UM_HP_CRYPTO_ALLOW_M (TEE_REG_CORE0_UM_HP_CRYPTO_ALLOW_V << TEE_REG_CORE0_UM_HP_CRYPTO_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_CRYPTO_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_CRYPTO_ALLOW_S 14 -/** TEE_REG_CORE0_UM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_GMAC_ALLOW (BIT(15)) -#define TEE_REG_CORE0_UM_HP_GMAC_ALLOW_M (TEE_REG_CORE0_UM_HP_GMAC_ALLOW_V << TEE_REG_CORE0_UM_HP_GMAC_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_GMAC_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_GMAC_ALLOW_S 15 -/** TEE_REG_CORE0_UM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_USB_PHY_ALLOW (BIT(16)) -#define TEE_REG_CORE0_UM_HP_USB_PHY_ALLOW_M (TEE_REG_CORE0_UM_HP_USB_PHY_ALLOW_V << TEE_REG_CORE0_UM_HP_USB_PHY_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_USB_PHY_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_USB_PHY_ALLOW_S 16 -/** TEE_REG_CORE0_UM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_PVT_ALLOW (BIT(17)) -#define TEE_REG_CORE0_UM_HP_PVT_ALLOW_M (TEE_REG_CORE0_UM_HP_PVT_ALLOW_V << TEE_REG_CORE0_UM_HP_PVT_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_PVT_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_PVT_ALLOW_S 17 -/** TEE_REG_CORE0_UM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_CSI_HOST_ALLOW (BIT(18)) -#define TEE_REG_CORE0_UM_HP_CSI_HOST_ALLOW_M (TEE_REG_CORE0_UM_HP_CSI_HOST_ALLOW_V << TEE_REG_CORE0_UM_HP_CSI_HOST_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_CSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_CSI_HOST_ALLOW_S 18 -/** TEE_REG_CORE0_UM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_DSI_HOST_ALLOW (BIT(19)) -#define TEE_REG_CORE0_UM_HP_DSI_HOST_ALLOW_M (TEE_REG_CORE0_UM_HP_DSI_HOST_ALLOW_V << TEE_REG_CORE0_UM_HP_DSI_HOST_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_DSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_DSI_HOST_ALLOW_S 19 -/** TEE_REG_CORE0_UM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_ISP_ALLOW (BIT(20)) -#define TEE_REG_CORE0_UM_HP_ISP_ALLOW_M (TEE_REG_CORE0_UM_HP_ISP_ALLOW_V << TEE_REG_CORE0_UM_HP_ISP_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_ISP_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_ISP_ALLOW_S 20 -/** TEE_REG_CORE0_UM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_H264_CORE_ALLOW (BIT(21)) -#define TEE_REG_CORE0_UM_HP_H264_CORE_ALLOW_M (TEE_REG_CORE0_UM_HP_H264_CORE_ALLOW_V << TEE_REG_CORE0_UM_HP_H264_CORE_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_H264_CORE_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_H264_CORE_ALLOW_S 21 -/** TEE_REG_CORE0_UM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_RMT_ALLOW (BIT(22)) -#define TEE_REG_CORE0_UM_HP_RMT_ALLOW_M (TEE_REG_CORE0_UM_HP_RMT_ALLOW_V << TEE_REG_CORE0_UM_HP_RMT_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_RMT_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_RMT_ALLOW_S 22 -/** TEE_REG_CORE0_UM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_BITSRAMBLER_ALLOW (BIT(23)) -#define TEE_REG_CORE0_UM_HP_BITSRAMBLER_ALLOW_M (TEE_REG_CORE0_UM_HP_BITSRAMBLER_ALLOW_V << TEE_REG_CORE0_UM_HP_BITSRAMBLER_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_BITSRAMBLER_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_BITSRAMBLER_ALLOW_S 23 -/** TEE_REG_CORE0_UM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_AXI_ICM_ALLOW (BIT(24)) -#define TEE_REG_CORE0_UM_HP_AXI_ICM_ALLOW_M (TEE_REG_CORE0_UM_HP_AXI_ICM_ALLOW_V << TEE_REG_CORE0_UM_HP_AXI_ICM_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_AXI_ICM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_AXI_ICM_ALLOW_S 24 -/** TEE_REG_CORE0_UM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_PERI_PMS_ALLOW (BIT(25)) -#define TEE_REG_CORE0_UM_HP_PERI_PMS_ALLOW_M (TEE_REG_CORE0_UM_HP_PERI_PMS_ALLOW_V << TEE_REG_CORE0_UM_HP_PERI_PMS_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_PERI_PMS_ALLOW_S 25 -/** TEE_REG_CORE0_UM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_LP2HP_PERI_PMS_ALLOW (BIT(26)) -#define TEE_REG_CORE0_UM_LP2HP_PERI_PMS_ALLOW_M (TEE_REG_CORE0_UM_LP2HP_PERI_PMS_ALLOW_V << TEE_REG_CORE0_UM_LP2HP_PERI_PMS_ALLOW_S) -#define TEE_REG_CORE0_UM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_LP2HP_PERI_PMS_ALLOW_S 26 -/** TEE_REG_CORE0_UM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_DMA_PMS_ALLOW (BIT(27)) -#define TEE_REG_CORE0_UM_DMA_PMS_ALLOW_M (TEE_REG_CORE0_UM_DMA_PMS_ALLOW_V << TEE_REG_CORE0_UM_DMA_PMS_ALLOW_S) -#define TEE_REG_CORE0_UM_DMA_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_DMA_PMS_ALLOW_S 27 -/** TEE_REG_CORE0_UM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_H264_DMA2D_ALLOW (BIT(28)) -#define TEE_REG_CORE0_UM_HP_H264_DMA2D_ALLOW_M (TEE_REG_CORE0_UM_HP_H264_DMA2D_ALLOW_V << TEE_REG_CORE0_UM_HP_H264_DMA2D_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_H264_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_H264_DMA2D_ALLOW_S 28 +/** PMS_CORE0_UM_HP_PERI_PMS_REG1_REG register + * Permission control register1 for HP CPU0 in user mode + */ +#define PMS_CORE0_UM_HP_PERI_PMS_REG1_REG (DR_REG_HP_PERI_PMS_BASE + 0x1c) +/** PMS_CORE0_UM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP high-speed USB + * 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_USBOTG_ALLOW (BIT(0)) +#define PMS_CORE0_UM_HP_USBOTG_ALLOW_M (PMS_CORE0_UM_HP_USBOTG_ALLOW_V << PMS_CORE0_UM_HP_USBOTG_ALLOW_S) +#define PMS_CORE0_UM_HP_USBOTG_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_USBOTG_ALLOW_S 0 +/** PMS_CORE0_UM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP full-speed USB + * 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_USBOTG11_ALLOW (BIT(1)) +#define PMS_CORE0_UM_HP_USBOTG11_ALLOW_M (PMS_CORE0_UM_HP_USBOTG11_ALLOW_V << PMS_CORE0_UM_HP_USBOTG11_ALLOW_S) +#define PMS_CORE0_UM_HP_USBOTG11_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_USBOTG11_ALLOW_S 1 +/** PMS_CORE0_UM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP full-speed USB + * 2.0 OTG's wrap. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) +#define PMS_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_M (PMS_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_V << PMS_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_S) +#define PMS_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_USBOTG11_WRAP_ALLOW_S 2 +/** PMS_CORE0_UM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP DW-GDMA. + * 0: Not allowed + * 1: Allowed + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_GDMA_ALLOW (BIT(3)) +#define PMS_CORE0_UM_HP_GDMA_ALLOW_M (PMS_CORE0_UM_HP_GDMA_ALLOW_V << PMS_CORE0_UM_HP_GDMA_ALLOW_S) +#define PMS_CORE0_UM_HP_GDMA_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_GDMA_ALLOW_S 3 +/** PMS_CORE0_UM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP regdma. + * 0: Not allowed + * 1: Allow + */ +#define PMS_CORE0_UM_HP_REGDMA_ALLOW (BIT(4)) +#define PMS_CORE0_UM_HP_REGDMA_ALLOW_M (PMS_CORE0_UM_HP_REGDMA_ALLOW_V << PMS_CORE0_UM_HP_REGDMA_ALLOW_S) +#define PMS_CORE0_UM_HP_REGDMA_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_REGDMA_ALLOW_S 4 +/** PMS_CORE0_UM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP SDMMC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_SDMMC_ALLOW (BIT(5)) +#define PMS_CORE0_UM_HP_SDMMC_ALLOW_M (PMS_CORE0_UM_HP_SDMMC_ALLOW_V << PMS_CORE0_UM_HP_SDMMC_ALLOW_S) +#define PMS_CORE0_UM_HP_SDMMC_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_SDMMC_ALLOW_S 5 +/** PMS_CORE0_UM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access GDMA-AHB. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_AHB_PDMA_ALLOW (BIT(6)) +#define PMS_CORE0_UM_HP_AHB_PDMA_ALLOW_M (PMS_CORE0_UM_HP_AHB_PDMA_ALLOW_V << PMS_CORE0_UM_HP_AHB_PDMA_ALLOW_S) +#define PMS_CORE0_UM_HP_AHB_PDMA_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_AHB_PDMA_ALLOW_S 6 +/** PMS_CORE0_UM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP JPEG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_JPEG_ALLOW (BIT(7)) +#define PMS_CORE0_UM_HP_JPEG_ALLOW_M (PMS_CORE0_UM_HP_JPEG_ALLOW_V << PMS_CORE0_UM_HP_JPEG_ALLOW_S) +#define PMS_CORE0_UM_HP_JPEG_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_JPEG_ALLOW_S 7 +/** PMS_CORE0_UM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP PPA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_PPA_ALLOW (BIT(8)) +#define PMS_CORE0_UM_HP_PPA_ALLOW_M (PMS_CORE0_UM_HP_PPA_ALLOW_V << PMS_CORE0_UM_HP_PPA_ALLOW_S) +#define PMS_CORE0_UM_HP_PPA_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_PPA_ALLOW_S 8 +/** PMS_CORE0_UM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_DMA2D_ALLOW (BIT(9)) +#define PMS_CORE0_UM_HP_DMA2D_ALLOW_M (PMS_CORE0_UM_HP_DMA2D_ALLOW_V << PMS_CORE0_UM_HP_DMA2D_ALLOW_S) +#define PMS_CORE0_UM_HP_DMA2D_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_DMA2D_ALLOW_S 9 +/** PMS_CORE0_UM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP key manager. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_KEY_MANAGER_ALLOW (BIT(10)) +#define PMS_CORE0_UM_HP_KEY_MANAGER_ALLOW_M (PMS_CORE0_UM_HP_KEY_MANAGER_ALLOW_V << PMS_CORE0_UM_HP_KEY_MANAGER_ALLOW_S) +#define PMS_CORE0_UM_HP_KEY_MANAGER_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_KEY_MANAGER_ALLOW_S 10 +/** PMS_CORE0_UM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP GDMA-AXI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_AXI_PDMA_ALLOW (BIT(11)) +#define PMS_CORE0_UM_HP_AXI_PDMA_ALLOW_M (PMS_CORE0_UM_HP_AXI_PDMA_ALLOW_V << PMS_CORE0_UM_HP_AXI_PDMA_ALLOW_S) +#define PMS_CORE0_UM_HP_AXI_PDMA_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_AXI_PDMA_ALLOW_S 11 +/** PMS_CORE0_UM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP flash MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_FLASH_ALLOW (BIT(12)) +#define PMS_CORE0_UM_HP_FLASH_ALLOW_M (PMS_CORE0_UM_HP_FLASH_ALLOW_V << PMS_CORE0_UM_HP_FLASH_ALLOW_S) +#define PMS_CORE0_UM_HP_FLASH_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_FLASH_ALLOW_S 12 +/** PMS_CORE0_UM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP PSRAM MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_PSRAM_ALLOW (BIT(13)) +#define PMS_CORE0_UM_HP_PSRAM_ALLOW_M (PMS_CORE0_UM_HP_PSRAM_ALLOW_V << PMS_CORE0_UM_HP_PSRAM_ALLOW_S) +#define PMS_CORE0_UM_HP_PSRAM_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_PSRAM_ALLOW_S 13 +/** PMS_CORE0_UM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP CRYPTO. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_CRYPTO_ALLOW (BIT(14)) +#define PMS_CORE0_UM_HP_CRYPTO_ALLOW_M (PMS_CORE0_UM_HP_CRYPTO_ALLOW_V << PMS_CORE0_UM_HP_CRYPTO_ALLOW_S) +#define PMS_CORE0_UM_HP_CRYPTO_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_CRYPTO_ALLOW_S 14 +/** PMS_CORE0_UM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP EMAC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_GMAC_ALLOW (BIT(15)) +#define PMS_CORE0_UM_HP_GMAC_ALLOW_M (PMS_CORE0_UM_HP_GMAC_ALLOW_V << PMS_CORE0_UM_HP_GMAC_ALLOW_S) +#define PMS_CORE0_UM_HP_GMAC_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_GMAC_ALLOW_S 15 +/** PMS_CORE0_UM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP high-speed USB + * 2.0 OTG PHY. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_USB_PHY_ALLOW (BIT(16)) +#define PMS_CORE0_UM_HP_USB_PHY_ALLOW_M (PMS_CORE0_UM_HP_USB_PHY_ALLOW_V << PMS_CORE0_UM_HP_USB_PHY_ALLOW_S) +#define PMS_CORE0_UM_HP_USB_PHY_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_USB_PHY_ALLOW_S 16 +/** PMS_CORE0_UM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP PVT. + * 0: Not allowed + * 1: Allow + */ +#define PMS_CORE0_UM_HP_PVT_ALLOW (BIT(17)) +#define PMS_CORE0_UM_HP_PVT_ALLOW_M (PMS_CORE0_UM_HP_PVT_ALLOW_V << PMS_CORE0_UM_HP_PVT_ALLOW_S) +#define PMS_CORE0_UM_HP_PVT_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_PVT_ALLOW_S 17 +/** PMS_CORE0_UM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP MIPI CSI host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_CSI_HOST_ALLOW (BIT(18)) +#define PMS_CORE0_UM_HP_CSI_HOST_ALLOW_M (PMS_CORE0_UM_HP_CSI_HOST_ALLOW_V << PMS_CORE0_UM_HP_CSI_HOST_ALLOW_S) +#define PMS_CORE0_UM_HP_CSI_HOST_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_CSI_HOST_ALLOW_S 18 +/** PMS_CORE0_UM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP MIPI DSI host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_DSI_HOST_ALLOW (BIT(19)) +#define PMS_CORE0_UM_HP_DSI_HOST_ALLOW_M (PMS_CORE0_UM_HP_DSI_HOST_ALLOW_V << PMS_CORE0_UM_HP_DSI_HOST_ALLOW_S) +#define PMS_CORE0_UM_HP_DSI_HOST_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_DSI_HOST_ALLOW_S 19 +/** PMS_CORE0_UM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP ISP. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_ISP_ALLOW (BIT(20)) +#define PMS_CORE0_UM_HP_ISP_ALLOW_M (PMS_CORE0_UM_HP_ISP_ALLOW_V << PMS_CORE0_UM_HP_ISP_ALLOW_S) +#define PMS_CORE0_UM_HP_ISP_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_ISP_ALLOW_S 20 +/** PMS_CORE0_UM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP H264 Encoder. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_H264_CORE_ALLOW (BIT(21)) +#define PMS_CORE0_UM_HP_H264_CORE_ALLOW_M (PMS_CORE0_UM_HP_H264_CORE_ALLOW_V << PMS_CORE0_UM_HP_H264_CORE_ALLOW_S) +#define PMS_CORE0_UM_HP_H264_CORE_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_H264_CORE_ALLOW_S 21 +/** PMS_CORE0_UM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP RMT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_RMT_ALLOW (BIT(22)) +#define PMS_CORE0_UM_HP_RMT_ALLOW_M (PMS_CORE0_UM_HP_RMT_ALLOW_V << PMS_CORE0_UM_HP_RMT_ALLOW_S) +#define PMS_CORE0_UM_HP_RMT_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_RMT_ALLOW_S 22 +/** PMS_CORE0_UM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP bit scrambler. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_BITSRAMBLER_ALLOW (BIT(23)) +#define PMS_CORE0_UM_HP_BITSRAMBLER_ALLOW_M (PMS_CORE0_UM_HP_BITSRAMBLER_ALLOW_V << PMS_CORE0_UM_HP_BITSRAMBLER_ALLOW_S) +#define PMS_CORE0_UM_HP_BITSRAMBLER_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_BITSRAMBLER_ALLOW_S 23 +/** PMS_CORE0_UM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP AXI ICM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_AXI_ICM_ALLOW (BIT(24)) +#define PMS_CORE0_UM_HP_AXI_ICM_ALLOW_M (PMS_CORE0_UM_HP_AXI_ICM_ALLOW_V << PMS_CORE0_UM_HP_AXI_ICM_ALLOW_S) +#define PMS_CORE0_UM_HP_AXI_ICM_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_AXI_ICM_ALLOW_S 24 +/** PMS_CORE0_UM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_PERI_PMS_ALLOW (BIT(25)) +#define PMS_CORE0_UM_HP_PERI_PMS_ALLOW_M (PMS_CORE0_UM_HP_PERI_PMS_ALLOW_V << PMS_CORE0_UM_HP_PERI_PMS_ALLOW_S) +#define PMS_CORE0_UM_HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_PERI_PMS_ALLOW_S 25 +/** PMS_CORE0_UM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access + * LP2HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_LP2HP_PERI_PMS_ALLOW (BIT(26)) +#define PMS_CORE0_UM_LP2HP_PERI_PMS_ALLOW_M (PMS_CORE0_UM_LP2HP_PERI_PMS_ALLOW_V << PMS_CORE0_UM_LP2HP_PERI_PMS_ALLOW_S) +#define PMS_CORE0_UM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_LP2HP_PERI_PMS_ALLOW_S 26 +/** PMS_CORE0_UM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP_DMA_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_DMA_PMS_ALLOW (BIT(27)) +#define PMS_CORE0_UM_DMA_PMS_ALLOW_M (PMS_CORE0_UM_DMA_PMS_ALLOW_V << PMS_CORE0_UM_DMA_PMS_ALLOW_S) +#define PMS_CORE0_UM_DMA_PMS_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_DMA_PMS_ALLOW_S 27 +/** PMS_CORE0_UM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_H264_DMA2D_ALLOW (BIT(28)) +#define PMS_CORE0_UM_HP_H264_DMA2D_ALLOW_M (PMS_CORE0_UM_HP_H264_DMA2D_ALLOW_V << PMS_CORE0_UM_HP_H264_DMA2D_ALLOW_S) +#define PMS_CORE0_UM_HP_H264_DMA2D_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_H264_DMA2D_ALLOW_S 28 -/** TEE_CORE0_UM_PMS_REG2_REG register - * NA - */ -#define TEE_CORE0_UM_PMS_REG2_REG (DR_REG_TEE_BASE + 0x20) -/** TEE_REG_CORE0_UM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_MCPWM0_ALLOW (BIT(0)) -#define TEE_REG_CORE0_UM_HP_MCPWM0_ALLOW_M (TEE_REG_CORE0_UM_HP_MCPWM0_ALLOW_V << TEE_REG_CORE0_UM_HP_MCPWM0_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_MCPWM0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_MCPWM0_ALLOW_S 0 -/** TEE_REG_CORE0_UM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_MCPWM1_ALLOW (BIT(1)) -#define TEE_REG_CORE0_UM_HP_MCPWM1_ALLOW_M (TEE_REG_CORE0_UM_HP_MCPWM1_ALLOW_V << TEE_REG_CORE0_UM_HP_MCPWM1_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_MCPWM1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_MCPWM1_ALLOW_S 1 -/** TEE_REG_CORE0_UM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_TIMER_GROUP0_ALLOW (BIT(2)) -#define TEE_REG_CORE0_UM_HP_TIMER_GROUP0_ALLOW_M (TEE_REG_CORE0_UM_HP_TIMER_GROUP0_ALLOW_V << TEE_REG_CORE0_UM_HP_TIMER_GROUP0_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_TIMER_GROUP0_ALLOW_S 2 -/** TEE_REG_CORE0_UM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_TIMER_GROUP1_ALLOW (BIT(3)) -#define TEE_REG_CORE0_UM_HP_TIMER_GROUP1_ALLOW_M (TEE_REG_CORE0_UM_HP_TIMER_GROUP1_ALLOW_V << TEE_REG_CORE0_UM_HP_TIMER_GROUP1_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_TIMER_GROUP1_ALLOW_S 3 -/** TEE_REG_CORE0_UM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_I2C0_ALLOW (BIT(4)) -#define TEE_REG_CORE0_UM_HP_I2C0_ALLOW_M (TEE_REG_CORE0_UM_HP_I2C0_ALLOW_V << TEE_REG_CORE0_UM_HP_I2C0_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_I2C0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_I2C0_ALLOW_S 4 -/** TEE_REG_CORE0_UM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_I2C1_ALLOW (BIT(5)) -#define TEE_REG_CORE0_UM_HP_I2C1_ALLOW_M (TEE_REG_CORE0_UM_HP_I2C1_ALLOW_V << TEE_REG_CORE0_UM_HP_I2C1_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_I2C1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_I2C1_ALLOW_S 5 -/** TEE_REG_CORE0_UM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_I2S0_ALLOW (BIT(6)) -#define TEE_REG_CORE0_UM_HP_I2S0_ALLOW_M (TEE_REG_CORE0_UM_HP_I2S0_ALLOW_V << TEE_REG_CORE0_UM_HP_I2S0_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_I2S0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_I2S0_ALLOW_S 6 -/** TEE_REG_CORE0_UM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_I2S1_ALLOW (BIT(7)) -#define TEE_REG_CORE0_UM_HP_I2S1_ALLOW_M (TEE_REG_CORE0_UM_HP_I2S1_ALLOW_V << TEE_REG_CORE0_UM_HP_I2S1_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_I2S1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_I2S1_ALLOW_S 7 -/** TEE_REG_CORE0_UM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_I2S2_ALLOW (BIT(8)) -#define TEE_REG_CORE0_UM_HP_I2S2_ALLOW_M (TEE_REG_CORE0_UM_HP_I2S2_ALLOW_V << TEE_REG_CORE0_UM_HP_I2S2_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_I2S2_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_I2S2_ALLOW_S 8 -/** TEE_REG_CORE0_UM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_PCNT_ALLOW (BIT(9)) -#define TEE_REG_CORE0_UM_HP_PCNT_ALLOW_M (TEE_REG_CORE0_UM_HP_PCNT_ALLOW_V << TEE_REG_CORE0_UM_HP_PCNT_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_PCNT_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_PCNT_ALLOW_S 9 -/** TEE_REG_CORE0_UM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_UART0_ALLOW (BIT(10)) -#define TEE_REG_CORE0_UM_HP_UART0_ALLOW_M (TEE_REG_CORE0_UM_HP_UART0_ALLOW_V << TEE_REG_CORE0_UM_HP_UART0_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_UART0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_UART0_ALLOW_S 10 -/** TEE_REG_CORE0_UM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_UART1_ALLOW (BIT(11)) -#define TEE_REG_CORE0_UM_HP_UART1_ALLOW_M (TEE_REG_CORE0_UM_HP_UART1_ALLOW_V << TEE_REG_CORE0_UM_HP_UART1_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_UART1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_UART1_ALLOW_S 11 -/** TEE_REG_CORE0_UM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_UART2_ALLOW (BIT(12)) -#define TEE_REG_CORE0_UM_HP_UART2_ALLOW_M (TEE_REG_CORE0_UM_HP_UART2_ALLOW_V << TEE_REG_CORE0_UM_HP_UART2_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_UART2_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_UART2_ALLOW_S 12 -/** TEE_REG_CORE0_UM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_UART3_ALLOW (BIT(13)) -#define TEE_REG_CORE0_UM_HP_UART3_ALLOW_M (TEE_REG_CORE0_UM_HP_UART3_ALLOW_V << TEE_REG_CORE0_UM_HP_UART3_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_UART3_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_UART3_ALLOW_S 13 -/** TEE_REG_CORE0_UM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_UART4_ALLOW (BIT(14)) -#define TEE_REG_CORE0_UM_HP_UART4_ALLOW_M (TEE_REG_CORE0_UM_HP_UART4_ALLOW_V << TEE_REG_CORE0_UM_HP_UART4_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_UART4_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_UART4_ALLOW_S 14 -/** TEE_REG_CORE0_UM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_PARLIO_ALLOW (BIT(15)) -#define TEE_REG_CORE0_UM_HP_PARLIO_ALLOW_M (TEE_REG_CORE0_UM_HP_PARLIO_ALLOW_V << TEE_REG_CORE0_UM_HP_PARLIO_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_PARLIO_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_PARLIO_ALLOW_S 15 -/** TEE_REG_CORE0_UM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_GPSPI2_ALLOW (BIT(16)) -#define TEE_REG_CORE0_UM_HP_GPSPI2_ALLOW_M (TEE_REG_CORE0_UM_HP_GPSPI2_ALLOW_V << TEE_REG_CORE0_UM_HP_GPSPI2_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_GPSPI2_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_GPSPI2_ALLOW_S 16 -/** TEE_REG_CORE0_UM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_GPSPI3_ALLOW (BIT(17)) -#define TEE_REG_CORE0_UM_HP_GPSPI3_ALLOW_M (TEE_REG_CORE0_UM_HP_GPSPI3_ALLOW_V << TEE_REG_CORE0_UM_HP_GPSPI3_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_GPSPI3_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_GPSPI3_ALLOW_S 17 -/** TEE_REG_CORE0_UM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_USBDEVICE_ALLOW (BIT(18)) -#define TEE_REG_CORE0_UM_HP_USBDEVICE_ALLOW_M (TEE_REG_CORE0_UM_HP_USBDEVICE_ALLOW_V << TEE_REG_CORE0_UM_HP_USBDEVICE_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_USBDEVICE_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_USBDEVICE_ALLOW_S 18 -/** TEE_REG_CORE0_UM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_LEDC_ALLOW (BIT(19)) -#define TEE_REG_CORE0_UM_HP_LEDC_ALLOW_M (TEE_REG_CORE0_UM_HP_LEDC_ALLOW_V << TEE_REG_CORE0_UM_HP_LEDC_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_LEDC_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_LEDC_ALLOW_S 19 -/** TEE_REG_CORE0_UM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_ETM_ALLOW (BIT(21)) -#define TEE_REG_CORE0_UM_HP_ETM_ALLOW_M (TEE_REG_CORE0_UM_HP_ETM_ALLOW_V << TEE_REG_CORE0_UM_HP_ETM_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_ETM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_ETM_ALLOW_S 21 -/** TEE_REG_CORE0_UM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_INTRMTX_ALLOW (BIT(22)) -#define TEE_REG_CORE0_UM_HP_INTRMTX_ALLOW_M (TEE_REG_CORE0_UM_HP_INTRMTX_ALLOW_V << TEE_REG_CORE0_UM_HP_INTRMTX_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_INTRMTX_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_INTRMTX_ALLOW_S 22 -/** TEE_REG_CORE0_UM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_TWAI0_ALLOW (BIT(23)) -#define TEE_REG_CORE0_UM_HP_TWAI0_ALLOW_M (TEE_REG_CORE0_UM_HP_TWAI0_ALLOW_V << TEE_REG_CORE0_UM_HP_TWAI0_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_TWAI0_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_TWAI0_ALLOW_S 23 -/** TEE_REG_CORE0_UM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_TWAI1_ALLOW (BIT(24)) -#define TEE_REG_CORE0_UM_HP_TWAI1_ALLOW_M (TEE_REG_CORE0_UM_HP_TWAI1_ALLOW_V << TEE_REG_CORE0_UM_HP_TWAI1_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_TWAI1_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_TWAI1_ALLOW_S 24 -/** TEE_REG_CORE0_UM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_TWAI2_ALLOW (BIT(25)) -#define TEE_REG_CORE0_UM_HP_TWAI2_ALLOW_M (TEE_REG_CORE0_UM_HP_TWAI2_ALLOW_V << TEE_REG_CORE0_UM_HP_TWAI2_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_TWAI2_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_TWAI2_ALLOW_S 25 -/** TEE_REG_CORE0_UM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_I3C_MST_ALLOW (BIT(26)) -#define TEE_REG_CORE0_UM_HP_I3C_MST_ALLOW_M (TEE_REG_CORE0_UM_HP_I3C_MST_ALLOW_V << TEE_REG_CORE0_UM_HP_I3C_MST_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_I3C_MST_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_I3C_MST_ALLOW_S 26 -/** TEE_REG_CORE0_UM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_I3C_SLV_ALLOW (BIT(27)) -#define TEE_REG_CORE0_UM_HP_I3C_SLV_ALLOW_M (TEE_REG_CORE0_UM_HP_I3C_SLV_ALLOW_V << TEE_REG_CORE0_UM_HP_I3C_SLV_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_I3C_SLV_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_I3C_SLV_ALLOW_S 27 -/** TEE_REG_CORE0_UM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_LCDCAM_ALLOW (BIT(28)) -#define TEE_REG_CORE0_UM_HP_LCDCAM_ALLOW_M (TEE_REG_CORE0_UM_HP_LCDCAM_ALLOW_V << TEE_REG_CORE0_UM_HP_LCDCAM_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_LCDCAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_LCDCAM_ALLOW_S 28 -/** TEE_REG_CORE0_UM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_ADC_ALLOW (BIT(30)) -#define TEE_REG_CORE0_UM_HP_ADC_ALLOW_M (TEE_REG_CORE0_UM_HP_ADC_ALLOW_V << TEE_REG_CORE0_UM_HP_ADC_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_ADC_ALLOW_S 30 -/** TEE_REG_CORE0_UM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_UHCI_ALLOW (BIT(31)) -#define TEE_REG_CORE0_UM_HP_UHCI_ALLOW_M (TEE_REG_CORE0_UM_HP_UHCI_ALLOW_V << TEE_REG_CORE0_UM_HP_UHCI_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_UHCI_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_UHCI_ALLOW_S 31 +/** PMS_CORE0_UM_HP_PERI_PMS_REG2_REG register + * Permission control register2 for HP CPU0 in user mode + */ +#define PMS_CORE0_UM_HP_PERI_PMS_REG2_REG (DR_REG_HP_PERI_PMS_BASE + 0x20) +/** PMS_CORE0_UM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP MCPWM0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_MCPWM0_ALLOW (BIT(0)) +#define PMS_CORE0_UM_HP_MCPWM0_ALLOW_M (PMS_CORE0_UM_HP_MCPWM0_ALLOW_V << PMS_CORE0_UM_HP_MCPWM0_ALLOW_S) +#define PMS_CORE0_UM_HP_MCPWM0_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_MCPWM0_ALLOW_S 0 +/** PMS_CORE0_UM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP MCPWM1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_MCPWM1_ALLOW (BIT(1)) +#define PMS_CORE0_UM_HP_MCPWM1_ALLOW_M (PMS_CORE0_UM_HP_MCPWM1_ALLOW_V << PMS_CORE0_UM_HP_MCPWM1_ALLOW_S) +#define PMS_CORE0_UM_HP_MCPWM1_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_MCPWM1_ALLOW_S 1 +/** PMS_CORE0_UM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP timer group0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_TIMER_GROUP0_ALLOW (BIT(2)) +#define PMS_CORE0_UM_HP_TIMER_GROUP0_ALLOW_M (PMS_CORE0_UM_HP_TIMER_GROUP0_ALLOW_V << PMS_CORE0_UM_HP_TIMER_GROUP0_ALLOW_S) +#define PMS_CORE0_UM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_TIMER_GROUP0_ALLOW_S 2 +/** PMS_CORE0_UM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP timer group1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_TIMER_GROUP1_ALLOW (BIT(3)) +#define PMS_CORE0_UM_HP_TIMER_GROUP1_ALLOW_M (PMS_CORE0_UM_HP_TIMER_GROUP1_ALLOW_V << PMS_CORE0_UM_HP_TIMER_GROUP1_ALLOW_S) +#define PMS_CORE0_UM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_TIMER_GROUP1_ALLOW_S 3 +/** PMS_CORE0_UM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP I2C0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_I2C0_ALLOW (BIT(4)) +#define PMS_CORE0_UM_HP_I2C0_ALLOW_M (PMS_CORE0_UM_HP_I2C0_ALLOW_V << PMS_CORE0_UM_HP_I2C0_ALLOW_S) +#define PMS_CORE0_UM_HP_I2C0_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_I2C0_ALLOW_S 4 +/** PMS_CORE0_UM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP I2C1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_I2C1_ALLOW (BIT(5)) +#define PMS_CORE0_UM_HP_I2C1_ALLOW_M (PMS_CORE0_UM_HP_I2C1_ALLOW_V << PMS_CORE0_UM_HP_I2C1_ALLOW_S) +#define PMS_CORE0_UM_HP_I2C1_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_I2C1_ALLOW_S 5 +/** PMS_CORE0_UM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP I2S0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_I2S0_ALLOW (BIT(6)) +#define PMS_CORE0_UM_HP_I2S0_ALLOW_M (PMS_CORE0_UM_HP_I2S0_ALLOW_V << PMS_CORE0_UM_HP_I2S0_ALLOW_S) +#define PMS_CORE0_UM_HP_I2S0_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_I2S0_ALLOW_S 6 +/** PMS_CORE0_UM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP I2S1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_I2S1_ALLOW (BIT(7)) +#define PMS_CORE0_UM_HP_I2S1_ALLOW_M (PMS_CORE0_UM_HP_I2S1_ALLOW_V << PMS_CORE0_UM_HP_I2S1_ALLOW_S) +#define PMS_CORE0_UM_HP_I2S1_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_I2S1_ALLOW_S 7 +/** PMS_CORE0_UM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP I2S2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_I2S2_ALLOW (BIT(8)) +#define PMS_CORE0_UM_HP_I2S2_ALLOW_M (PMS_CORE0_UM_HP_I2S2_ALLOW_V << PMS_CORE0_UM_HP_I2S2_ALLOW_S) +#define PMS_CORE0_UM_HP_I2S2_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_I2S2_ALLOW_S 8 +/** PMS_CORE0_UM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP PCNT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_PCNT_ALLOW (BIT(9)) +#define PMS_CORE0_UM_HP_PCNT_ALLOW_M (PMS_CORE0_UM_HP_PCNT_ALLOW_V << PMS_CORE0_UM_HP_PCNT_ALLOW_S) +#define PMS_CORE0_UM_HP_PCNT_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_PCNT_ALLOW_S 9 +/** PMS_CORE0_UM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP UART0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_UART0_ALLOW (BIT(10)) +#define PMS_CORE0_UM_HP_UART0_ALLOW_M (PMS_CORE0_UM_HP_UART0_ALLOW_V << PMS_CORE0_UM_HP_UART0_ALLOW_S) +#define PMS_CORE0_UM_HP_UART0_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_UART0_ALLOW_S 10 +/** PMS_CORE0_UM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP UART1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_UART1_ALLOW (BIT(11)) +#define PMS_CORE0_UM_HP_UART1_ALLOW_M (PMS_CORE0_UM_HP_UART1_ALLOW_V << PMS_CORE0_UM_HP_UART1_ALLOW_S) +#define PMS_CORE0_UM_HP_UART1_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_UART1_ALLOW_S 11 +/** PMS_CORE0_UM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP UART2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_UART2_ALLOW (BIT(12)) +#define PMS_CORE0_UM_HP_UART2_ALLOW_M (PMS_CORE0_UM_HP_UART2_ALLOW_V << PMS_CORE0_UM_HP_UART2_ALLOW_S) +#define PMS_CORE0_UM_HP_UART2_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_UART2_ALLOW_S 12 +/** PMS_CORE0_UM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP UART3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_UART3_ALLOW (BIT(13)) +#define PMS_CORE0_UM_HP_UART3_ALLOW_M (PMS_CORE0_UM_HP_UART3_ALLOW_V << PMS_CORE0_UM_HP_UART3_ALLOW_S) +#define PMS_CORE0_UM_HP_UART3_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_UART3_ALLOW_S 13 +/** PMS_CORE0_UM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP UART4. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_UART4_ALLOW (BIT(14)) +#define PMS_CORE0_UM_HP_UART4_ALLOW_M (PMS_CORE0_UM_HP_UART4_ALLOW_V << PMS_CORE0_UM_HP_UART4_ALLOW_S) +#define PMS_CORE0_UM_HP_UART4_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_UART4_ALLOW_S 14 +/** PMS_CORE0_UM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP PARLIO. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_PARLIO_ALLOW (BIT(15)) +#define PMS_CORE0_UM_HP_PARLIO_ALLOW_M (PMS_CORE0_UM_HP_PARLIO_ALLOW_V << PMS_CORE0_UM_HP_PARLIO_ALLOW_S) +#define PMS_CORE0_UM_HP_PARLIO_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_PARLIO_ALLOW_S 15 +/** PMS_CORE0_UM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP GP-SPI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_GPSPI2_ALLOW (BIT(16)) +#define PMS_CORE0_UM_HP_GPSPI2_ALLOW_M (PMS_CORE0_UM_HP_GPSPI2_ALLOW_V << PMS_CORE0_UM_HP_GPSPI2_ALLOW_S) +#define PMS_CORE0_UM_HP_GPSPI2_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_GPSPI2_ALLOW_S 16 +/** PMS_CORE0_UM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP GP-SPI3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_GPSPI3_ALLOW (BIT(17)) +#define PMS_CORE0_UM_HP_GPSPI3_ALLOW_M (PMS_CORE0_UM_HP_GPSPI3_ALLOW_V << PMS_CORE0_UM_HP_GPSPI3_ALLOW_S) +#define PMS_CORE0_UM_HP_GPSPI3_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_GPSPI3_ALLOW_S 17 +/** PMS_CORE0_UM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP USB/Serial JTAG + * Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_USBDEVICE_ALLOW (BIT(18)) +#define PMS_CORE0_UM_HP_USBDEVICE_ALLOW_M (PMS_CORE0_UM_HP_USBDEVICE_ALLOW_V << PMS_CORE0_UM_HP_USBDEVICE_ALLOW_S) +#define PMS_CORE0_UM_HP_USBDEVICE_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_USBDEVICE_ALLOW_S 18 +/** PMS_CORE0_UM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP LEDC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_LEDC_ALLOW (BIT(19)) +#define PMS_CORE0_UM_HP_LEDC_ALLOW_M (PMS_CORE0_UM_HP_LEDC_ALLOW_V << PMS_CORE0_UM_HP_LEDC_ALLOW_S) +#define PMS_CORE0_UM_HP_LEDC_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_LEDC_ALLOW_S 19 +/** PMS_CORE0_UM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP ETM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_ETM_ALLOW (BIT(21)) +#define PMS_CORE0_UM_HP_ETM_ALLOW_M (PMS_CORE0_UM_HP_ETM_ALLOW_V << PMS_CORE0_UM_HP_ETM_ALLOW_S) +#define PMS_CORE0_UM_HP_ETM_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_ETM_ALLOW_S 21 +/** PMS_CORE0_UM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP interrupt + * matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_INTRMTX_ALLOW (BIT(22)) +#define PMS_CORE0_UM_HP_INTRMTX_ALLOW_M (PMS_CORE0_UM_HP_INTRMTX_ALLOW_V << PMS_CORE0_UM_HP_INTRMTX_ALLOW_S) +#define PMS_CORE0_UM_HP_INTRMTX_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_INTRMTX_ALLOW_S 22 +/** PMS_CORE0_UM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP TWAI0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_TWAI0_ALLOW (BIT(23)) +#define PMS_CORE0_UM_HP_TWAI0_ALLOW_M (PMS_CORE0_UM_HP_TWAI0_ALLOW_V << PMS_CORE0_UM_HP_TWAI0_ALLOW_S) +#define PMS_CORE0_UM_HP_TWAI0_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_TWAI0_ALLOW_S 23 +/** PMS_CORE0_UM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP TWAI1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_TWAI1_ALLOW (BIT(24)) +#define PMS_CORE0_UM_HP_TWAI1_ALLOW_M (PMS_CORE0_UM_HP_TWAI1_ALLOW_V << PMS_CORE0_UM_HP_TWAI1_ALLOW_S) +#define PMS_CORE0_UM_HP_TWAI1_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_TWAI1_ALLOW_S 24 +/** PMS_CORE0_UM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP TWAI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_TWAI2_ALLOW (BIT(25)) +#define PMS_CORE0_UM_HP_TWAI2_ALLOW_M (PMS_CORE0_UM_HP_TWAI2_ALLOW_V << PMS_CORE0_UM_HP_TWAI2_ALLOW_S) +#define PMS_CORE0_UM_HP_TWAI2_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_TWAI2_ALLOW_S 25 +/** PMS_CORE0_UM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP I3C master + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_I3C_MST_ALLOW (BIT(26)) +#define PMS_CORE0_UM_HP_I3C_MST_ALLOW_M (PMS_CORE0_UM_HP_I3C_MST_ALLOW_V << PMS_CORE0_UM_HP_I3C_MST_ALLOW_S) +#define PMS_CORE0_UM_HP_I3C_MST_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_I3C_MST_ALLOW_S 26 +/** PMS_CORE0_UM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP I3C slave + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_I3C_SLV_ALLOW (BIT(27)) +#define PMS_CORE0_UM_HP_I3C_SLV_ALLOW_M (PMS_CORE0_UM_HP_I3C_SLV_ALLOW_V << PMS_CORE0_UM_HP_I3C_SLV_ALLOW_S) +#define PMS_CORE0_UM_HP_I3C_SLV_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_I3C_SLV_ALLOW_S 27 +/** PMS_CORE0_UM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP LCD_CAM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_LCDCAM_ALLOW (BIT(28)) +#define PMS_CORE0_UM_HP_LCDCAM_ALLOW_M (PMS_CORE0_UM_HP_LCDCAM_ALLOW_V << PMS_CORE0_UM_HP_LCDCAM_ALLOW_S) +#define PMS_CORE0_UM_HP_LCDCAM_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_LCDCAM_ALLOW_S 28 +/** PMS_CORE0_UM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_ADC_ALLOW (BIT(30)) +#define PMS_CORE0_UM_HP_ADC_ALLOW_M (PMS_CORE0_UM_HP_ADC_ALLOW_V << PMS_CORE0_UM_HP_ADC_ALLOW_S) +#define PMS_CORE0_UM_HP_ADC_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_ADC_ALLOW_S 30 +/** PMS_CORE0_UM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP UHCI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_UHCI_ALLOW (BIT(31)) +#define PMS_CORE0_UM_HP_UHCI_ALLOW_M (PMS_CORE0_UM_HP_UHCI_ALLOW_V << PMS_CORE0_UM_HP_UHCI_ALLOW_S) +#define PMS_CORE0_UM_HP_UHCI_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_UHCI_ALLOW_S 31 -/** TEE_CORE0_UM_PMS_REG3_REG register - * NA - */ -#define TEE_CORE0_UM_PMS_REG3_REG (DR_REG_TEE_BASE + 0x24) -/** TEE_REG_CORE0_UM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_GPIO_ALLOW (BIT(0)) -#define TEE_REG_CORE0_UM_HP_GPIO_ALLOW_M (TEE_REG_CORE0_UM_HP_GPIO_ALLOW_V << TEE_REG_CORE0_UM_HP_GPIO_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_GPIO_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_GPIO_ALLOW_S 0 -/** TEE_REG_CORE0_UM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_IOMUX_ALLOW (BIT(1)) -#define TEE_REG_CORE0_UM_HP_IOMUX_ALLOW_M (TEE_REG_CORE0_UM_HP_IOMUX_ALLOW_V << TEE_REG_CORE0_UM_HP_IOMUX_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_IOMUX_ALLOW_S 1 -/** TEE_REG_CORE0_UM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_SYSTIMER_ALLOW (BIT(2)) -#define TEE_REG_CORE0_UM_HP_SYSTIMER_ALLOW_M (TEE_REG_CORE0_UM_HP_SYSTIMER_ALLOW_V << TEE_REG_CORE0_UM_HP_SYSTIMER_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_SYSTIMER_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_SYSTIMER_ALLOW_S 2 -/** TEE_REG_CORE0_UM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_SYS_REG_ALLOW (BIT(3)) -#define TEE_REG_CORE0_UM_HP_SYS_REG_ALLOW_M (TEE_REG_CORE0_UM_HP_SYS_REG_ALLOW_V << TEE_REG_CORE0_UM_HP_SYS_REG_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_SYS_REG_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_SYS_REG_ALLOW_S 3 -/** TEE_REG_CORE0_UM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE0_UM_HP_CLKRST_ALLOW (BIT(4)) -#define TEE_REG_CORE0_UM_HP_CLKRST_ALLOW_M (TEE_REG_CORE0_UM_HP_CLKRST_ALLOW_V << TEE_REG_CORE0_UM_HP_CLKRST_ALLOW_S) -#define TEE_REG_CORE0_UM_HP_CLKRST_ALLOW_V 0x00000001U -#define TEE_REG_CORE0_UM_HP_CLKRST_ALLOW_S 4 +/** PMS_CORE0_UM_HP_PERI_PMS_REG3_REG register + * Permission control register3 for HP CPU0 in user mode + */ +#define PMS_CORE0_UM_HP_PERI_PMS_REG3_REG (DR_REG_HP_PERI_PMS_BASE + 0x24) +/** PMS_CORE0_UM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP GPIO Matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_GPIO_ALLOW (BIT(0)) +#define PMS_CORE0_UM_HP_GPIO_ALLOW_M (PMS_CORE0_UM_HP_GPIO_ALLOW_V << PMS_CORE0_UM_HP_GPIO_ALLOW_S) +#define PMS_CORE0_UM_HP_GPIO_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_GPIO_ALLOW_S 0 +/** PMS_CORE0_UM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_IOMUX_ALLOW (BIT(1)) +#define PMS_CORE0_UM_HP_IOMUX_ALLOW_M (PMS_CORE0_UM_HP_IOMUX_ALLOW_V << PMS_CORE0_UM_HP_IOMUX_ALLOW_S) +#define PMS_CORE0_UM_HP_IOMUX_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_IOMUX_ALLOW_S 1 +/** PMS_CORE0_UM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP system timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_SYSTIMER_ALLOW (BIT(2)) +#define PMS_CORE0_UM_HP_SYSTIMER_ALLOW_M (PMS_CORE0_UM_HP_SYSTIMER_ALLOW_V << PMS_CORE0_UM_HP_SYSTIMER_ALLOW_S) +#define PMS_CORE0_UM_HP_SYSTIMER_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_SYSTIMER_ALLOW_S 2 +/** PMS_CORE0_UM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP system + * register. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_SYS_REG_ALLOW (BIT(3)) +#define PMS_CORE0_UM_HP_SYS_REG_ALLOW_M (PMS_CORE0_UM_HP_SYS_REG_ALLOW_V << PMS_CORE0_UM_HP_SYS_REG_ALLOW_S) +#define PMS_CORE0_UM_HP_SYS_REG_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_SYS_REG_ALLOW_S 3 +/** PMS_CORE0_UM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU0 in user mode has permission to access HP_SYS_CLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE0_UM_HP_CLKRST_ALLOW (BIT(4)) +#define PMS_CORE0_UM_HP_CLKRST_ALLOW_M (PMS_CORE0_UM_HP_CLKRST_ALLOW_V << PMS_CORE0_UM_HP_CLKRST_ALLOW_S) +#define PMS_CORE0_UM_HP_CLKRST_ALLOW_V 0x00000001U +#define PMS_CORE0_UM_HP_CLKRST_ALLOW_S 4 -/** TEE_CORE1_MM_PMS_REG0_REG register - * NA - */ -#define TEE_CORE1_MM_PMS_REG0_REG (DR_REG_TEE_BASE + 0x28) -/** TEE_REG_CORE1_MM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_PSRAM_ALLOW (BIT(0)) -#define TEE_REG_CORE1_MM_PSRAM_ALLOW_M (TEE_REG_CORE1_MM_PSRAM_ALLOW_V << TEE_REG_CORE1_MM_PSRAM_ALLOW_S) -#define TEE_REG_CORE1_MM_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_PSRAM_ALLOW_S 0 -/** TEE_REG_CORE1_MM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_FLASH_ALLOW (BIT(1)) -#define TEE_REG_CORE1_MM_FLASH_ALLOW_M (TEE_REG_CORE1_MM_FLASH_ALLOW_V << TEE_REG_CORE1_MM_FLASH_ALLOW_S) -#define TEE_REG_CORE1_MM_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_FLASH_ALLOW_S 1 -/** TEE_REG_CORE1_MM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_L2MEM_ALLOW (BIT(2)) -#define TEE_REG_CORE1_MM_L2MEM_ALLOW_M (TEE_REG_CORE1_MM_L2MEM_ALLOW_V << TEE_REG_CORE1_MM_L2MEM_ALLOW_S) -#define TEE_REG_CORE1_MM_L2MEM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_L2MEM_ALLOW_S 2 -/** TEE_REG_CORE1_MM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_L2ROM_ALLOW (BIT(3)) -#define TEE_REG_CORE1_MM_L2ROM_ALLOW_M (TEE_REG_CORE1_MM_L2ROM_ALLOW_V << TEE_REG_CORE1_MM_L2ROM_ALLOW_S) -#define TEE_REG_CORE1_MM_L2ROM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_L2ROM_ALLOW_S 3 -/** TEE_REG_CORE1_MM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_TRACE0_ALLOW (BIT(6)) -#define TEE_REG_CORE1_MM_TRACE0_ALLOW_M (TEE_REG_CORE1_MM_TRACE0_ALLOW_V << TEE_REG_CORE1_MM_TRACE0_ALLOW_S) -#define TEE_REG_CORE1_MM_TRACE0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_TRACE0_ALLOW_S 6 -/** TEE_REG_CORE1_MM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_TRACE1_ALLOW (BIT(7)) -#define TEE_REG_CORE1_MM_TRACE1_ALLOW_M (TEE_REG_CORE1_MM_TRACE1_ALLOW_V << TEE_REG_CORE1_MM_TRACE1_ALLOW_S) -#define TEE_REG_CORE1_MM_TRACE1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_TRACE1_ALLOW_S 7 -/** TEE_REG_CORE1_MM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_CPU_BUS_MON_ALLOW (BIT(8)) -#define TEE_REG_CORE1_MM_CPU_BUS_MON_ALLOW_M (TEE_REG_CORE1_MM_CPU_BUS_MON_ALLOW_V << TEE_REG_CORE1_MM_CPU_BUS_MON_ALLOW_S) -#define TEE_REG_CORE1_MM_CPU_BUS_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_CPU_BUS_MON_ALLOW_S 8 -/** TEE_REG_CORE1_MM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_L2MEM_MON_ALLOW (BIT(9)) -#define TEE_REG_CORE1_MM_L2MEM_MON_ALLOW_M (TEE_REG_CORE1_MM_L2MEM_MON_ALLOW_V << TEE_REG_CORE1_MM_L2MEM_MON_ALLOW_S) -#define TEE_REG_CORE1_MM_L2MEM_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_L2MEM_MON_ALLOW_S 9 -/** TEE_REG_CORE1_MM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_TCM_MON_ALLOW (BIT(10)) -#define TEE_REG_CORE1_MM_TCM_MON_ALLOW_M (TEE_REG_CORE1_MM_TCM_MON_ALLOW_V << TEE_REG_CORE1_MM_TCM_MON_ALLOW_S) -#define TEE_REG_CORE1_MM_TCM_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_TCM_MON_ALLOW_S 10 -/** TEE_REG_CORE1_MM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_CACHE_ALLOW (BIT(11)) -#define TEE_REG_CORE1_MM_CACHE_ALLOW_M (TEE_REG_CORE1_MM_CACHE_ALLOW_V << TEE_REG_CORE1_MM_CACHE_ALLOW_S) -#define TEE_REG_CORE1_MM_CACHE_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_CACHE_ALLOW_S 11 +/** PMS_CORE1_MM_HP_PERI_PMS_REG0_REG register + * Permission control register0 for HP CPU1 in machine mode + */ +#define PMS_CORE1_MM_HP_PERI_PMS_REG0_REG (DR_REG_HP_PERI_PMS_BASE + 0x28) +/** PMS_CORE1_MM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access external RAM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_PSRAM_ALLOW (BIT(0)) +#define PMS_CORE1_MM_PSRAM_ALLOW_M (PMS_CORE1_MM_PSRAM_ALLOW_V << PMS_CORE1_MM_PSRAM_ALLOW_S) +#define PMS_CORE1_MM_PSRAM_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_PSRAM_ALLOW_S 0 +/** PMS_CORE1_MM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access external flash + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_FLASH_ALLOW (BIT(1)) +#define PMS_CORE1_MM_FLASH_ALLOW_M (PMS_CORE1_MM_FLASH_ALLOW_V << PMS_CORE1_MM_FLASH_ALLOW_S) +#define PMS_CORE1_MM_FLASH_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_FLASH_ALLOW_S 1 +/** PMS_CORE1_MM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP L2MEM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_L2MEM_ALLOW (BIT(2)) +#define PMS_CORE1_MM_L2MEM_ALLOW_M (PMS_CORE1_MM_L2MEM_ALLOW_V << PMS_CORE1_MM_L2MEM_ALLOW_S) +#define PMS_CORE1_MM_L2MEM_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_L2MEM_ALLOW_S 2 +/** PMS_CORE1_MM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP ROM without + * going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_L2ROM_ALLOW (BIT(3)) +#define PMS_CORE1_MM_L2ROM_ALLOW_M (PMS_CORE1_MM_L2ROM_ALLOW_V << PMS_CORE1_MM_L2ROM_ALLOW_S) +#define PMS_CORE1_MM_L2ROM_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_L2ROM_ALLOW_S 3 +/** PMS_CORE1_MM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access TRACE0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_TRACE0_ALLOW (BIT(6)) +#define PMS_CORE1_MM_TRACE0_ALLOW_M (PMS_CORE1_MM_TRACE0_ALLOW_V << PMS_CORE1_MM_TRACE0_ALLOW_S) +#define PMS_CORE1_MM_TRACE0_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_TRACE0_ALLOW_S 6 +/** PMS_CORE1_MM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access TRACE1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_TRACE1_ALLOW (BIT(7)) +#define PMS_CORE1_MM_TRACE1_ALLOW_M (PMS_CORE1_MM_TRACE1_ALLOW_V << PMS_CORE1_MM_TRACE1_ALLOW_S) +#define PMS_CORE1_MM_TRACE1_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_TRACE1_ALLOW_S 7 +/** PMS_CORE1_MM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access CPU bus + * monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_CPU_BUS_MON_ALLOW (BIT(8)) +#define PMS_CORE1_MM_CPU_BUS_MON_ALLOW_M (PMS_CORE1_MM_CPU_BUS_MON_ALLOW_V << PMS_CORE1_MM_CPU_BUS_MON_ALLOW_S) +#define PMS_CORE1_MM_CPU_BUS_MON_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_CPU_BUS_MON_ALLOW_S 8 +/** PMS_CORE1_MM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access L2MEM monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_L2MEM_MON_ALLOW (BIT(9)) +#define PMS_CORE1_MM_L2MEM_MON_ALLOW_M (PMS_CORE1_MM_L2MEM_MON_ALLOW_V << PMS_CORE1_MM_L2MEM_MON_ALLOW_S) +#define PMS_CORE1_MM_L2MEM_MON_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_L2MEM_MON_ALLOW_S 9 +/** PMS_CORE1_MM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access TCM monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_TCM_MON_ALLOW (BIT(10)) +#define PMS_CORE1_MM_TCM_MON_ALLOW_M (PMS_CORE1_MM_TCM_MON_ALLOW_V << PMS_CORE1_MM_TCM_MON_ALLOW_S) +#define PMS_CORE1_MM_TCM_MON_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_TCM_MON_ALLOW_S 10 +/** PMS_CORE1_MM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_CACHE_ALLOW (BIT(11)) +#define PMS_CORE1_MM_CACHE_ALLOW_M (PMS_CORE1_MM_CACHE_ALLOW_V << PMS_CORE1_MM_CACHE_ALLOW_S) +#define PMS_CORE1_MM_CACHE_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_CACHE_ALLOW_S 11 -/** TEE_CORE1_MM_PMS_REG1_REG register - * NA - */ -#define TEE_CORE1_MM_PMS_REG1_REG (DR_REG_TEE_BASE + 0x2c) -/** TEE_REG_CORE1_MM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_USBOTG_ALLOW (BIT(0)) -#define TEE_REG_CORE1_MM_HP_USBOTG_ALLOW_M (TEE_REG_CORE1_MM_HP_USBOTG_ALLOW_V << TEE_REG_CORE1_MM_HP_USBOTG_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_USBOTG_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_USBOTG_ALLOW_S 0 -/** TEE_REG_CORE1_MM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_USBOTG11_ALLOW (BIT(1)) -#define TEE_REG_CORE1_MM_HP_USBOTG11_ALLOW_M (TEE_REG_CORE1_MM_HP_USBOTG11_ALLOW_V << TEE_REG_CORE1_MM_HP_USBOTG11_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_USBOTG11_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_USBOTG11_ALLOW_S 1 -/** TEE_REG_CORE1_MM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) -#define TEE_REG_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_M (TEE_REG_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_V << TEE_REG_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_S 2 -/** TEE_REG_CORE1_MM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_GDMA_ALLOW (BIT(3)) -#define TEE_REG_CORE1_MM_HP_GDMA_ALLOW_M (TEE_REG_CORE1_MM_HP_GDMA_ALLOW_V << TEE_REG_CORE1_MM_HP_GDMA_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_GDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_GDMA_ALLOW_S 3 -/** TEE_REG_CORE1_MM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_REGDMA_ALLOW (BIT(4)) -#define TEE_REG_CORE1_MM_HP_REGDMA_ALLOW_M (TEE_REG_CORE1_MM_HP_REGDMA_ALLOW_V << TEE_REG_CORE1_MM_HP_REGDMA_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_REGDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_REGDMA_ALLOW_S 4 -/** TEE_REG_CORE1_MM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_SDMMC_ALLOW (BIT(5)) -#define TEE_REG_CORE1_MM_HP_SDMMC_ALLOW_M (TEE_REG_CORE1_MM_HP_SDMMC_ALLOW_V << TEE_REG_CORE1_MM_HP_SDMMC_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_SDMMC_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_SDMMC_ALLOW_S 5 -/** TEE_REG_CORE1_MM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_AHB_PDMA_ALLOW (BIT(6)) -#define TEE_REG_CORE1_MM_HP_AHB_PDMA_ALLOW_M (TEE_REG_CORE1_MM_HP_AHB_PDMA_ALLOW_V << TEE_REG_CORE1_MM_HP_AHB_PDMA_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_AHB_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_AHB_PDMA_ALLOW_S 6 -/** TEE_REG_CORE1_MM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_JPEG_ALLOW (BIT(7)) -#define TEE_REG_CORE1_MM_HP_JPEG_ALLOW_M (TEE_REG_CORE1_MM_HP_JPEG_ALLOW_V << TEE_REG_CORE1_MM_HP_JPEG_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_JPEG_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_JPEG_ALLOW_S 7 -/** TEE_REG_CORE1_MM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_PPA_ALLOW (BIT(8)) -#define TEE_REG_CORE1_MM_HP_PPA_ALLOW_M (TEE_REG_CORE1_MM_HP_PPA_ALLOW_V << TEE_REG_CORE1_MM_HP_PPA_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_PPA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_PPA_ALLOW_S 8 -/** TEE_REG_CORE1_MM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_DMA2D_ALLOW (BIT(9)) -#define TEE_REG_CORE1_MM_HP_DMA2D_ALLOW_M (TEE_REG_CORE1_MM_HP_DMA2D_ALLOW_V << TEE_REG_CORE1_MM_HP_DMA2D_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_DMA2D_ALLOW_S 9 -/** TEE_REG_CORE1_MM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_KEY_MANAGER_ALLOW (BIT(10)) -#define TEE_REG_CORE1_MM_HP_KEY_MANAGER_ALLOW_M (TEE_REG_CORE1_MM_HP_KEY_MANAGER_ALLOW_V << TEE_REG_CORE1_MM_HP_KEY_MANAGER_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_KEY_MANAGER_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_KEY_MANAGER_ALLOW_S 10 -/** TEE_REG_CORE1_MM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_AXI_PDMA_ALLOW (BIT(11)) -#define TEE_REG_CORE1_MM_HP_AXI_PDMA_ALLOW_M (TEE_REG_CORE1_MM_HP_AXI_PDMA_ALLOW_V << TEE_REG_CORE1_MM_HP_AXI_PDMA_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_AXI_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_AXI_PDMA_ALLOW_S 11 -/** TEE_REG_CORE1_MM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_FLASH_ALLOW (BIT(12)) -#define TEE_REG_CORE1_MM_HP_FLASH_ALLOW_M (TEE_REG_CORE1_MM_HP_FLASH_ALLOW_V << TEE_REG_CORE1_MM_HP_FLASH_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_FLASH_ALLOW_S 12 -/** TEE_REG_CORE1_MM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_PSRAM_ALLOW (BIT(13)) -#define TEE_REG_CORE1_MM_HP_PSRAM_ALLOW_M (TEE_REG_CORE1_MM_HP_PSRAM_ALLOW_V << TEE_REG_CORE1_MM_HP_PSRAM_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_PSRAM_ALLOW_S 13 -/** TEE_REG_CORE1_MM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_CRYPTO_ALLOW (BIT(14)) -#define TEE_REG_CORE1_MM_HP_CRYPTO_ALLOW_M (TEE_REG_CORE1_MM_HP_CRYPTO_ALLOW_V << TEE_REG_CORE1_MM_HP_CRYPTO_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_CRYPTO_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_CRYPTO_ALLOW_S 14 -/** TEE_REG_CORE1_MM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_GMAC_ALLOW (BIT(15)) -#define TEE_REG_CORE1_MM_HP_GMAC_ALLOW_M (TEE_REG_CORE1_MM_HP_GMAC_ALLOW_V << TEE_REG_CORE1_MM_HP_GMAC_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_GMAC_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_GMAC_ALLOW_S 15 -/** TEE_REG_CORE1_MM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_USB_PHY_ALLOW (BIT(16)) -#define TEE_REG_CORE1_MM_HP_USB_PHY_ALLOW_M (TEE_REG_CORE1_MM_HP_USB_PHY_ALLOW_V << TEE_REG_CORE1_MM_HP_USB_PHY_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_USB_PHY_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_USB_PHY_ALLOW_S 16 -/** TEE_REG_CORE1_MM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_PVT_ALLOW (BIT(17)) -#define TEE_REG_CORE1_MM_HP_PVT_ALLOW_M (TEE_REG_CORE1_MM_HP_PVT_ALLOW_V << TEE_REG_CORE1_MM_HP_PVT_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_PVT_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_PVT_ALLOW_S 17 -/** TEE_REG_CORE1_MM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_CSI_HOST_ALLOW (BIT(18)) -#define TEE_REG_CORE1_MM_HP_CSI_HOST_ALLOW_M (TEE_REG_CORE1_MM_HP_CSI_HOST_ALLOW_V << TEE_REG_CORE1_MM_HP_CSI_HOST_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_CSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_CSI_HOST_ALLOW_S 18 -/** TEE_REG_CORE1_MM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_DSI_HOST_ALLOW (BIT(19)) -#define TEE_REG_CORE1_MM_HP_DSI_HOST_ALLOW_M (TEE_REG_CORE1_MM_HP_DSI_HOST_ALLOW_V << TEE_REG_CORE1_MM_HP_DSI_HOST_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_DSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_DSI_HOST_ALLOW_S 19 -/** TEE_REG_CORE1_MM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_ISP_ALLOW (BIT(20)) -#define TEE_REG_CORE1_MM_HP_ISP_ALLOW_M (TEE_REG_CORE1_MM_HP_ISP_ALLOW_V << TEE_REG_CORE1_MM_HP_ISP_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_ISP_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_ISP_ALLOW_S 20 -/** TEE_REG_CORE1_MM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_H264_CORE_ALLOW (BIT(21)) -#define TEE_REG_CORE1_MM_HP_H264_CORE_ALLOW_M (TEE_REG_CORE1_MM_HP_H264_CORE_ALLOW_V << TEE_REG_CORE1_MM_HP_H264_CORE_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_H264_CORE_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_H264_CORE_ALLOW_S 21 -/** TEE_REG_CORE1_MM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_RMT_ALLOW (BIT(22)) -#define TEE_REG_CORE1_MM_HP_RMT_ALLOW_M (TEE_REG_CORE1_MM_HP_RMT_ALLOW_V << TEE_REG_CORE1_MM_HP_RMT_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_RMT_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_RMT_ALLOW_S 22 -/** TEE_REG_CORE1_MM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_BITSRAMBLER_ALLOW (BIT(23)) -#define TEE_REG_CORE1_MM_HP_BITSRAMBLER_ALLOW_M (TEE_REG_CORE1_MM_HP_BITSRAMBLER_ALLOW_V << TEE_REG_CORE1_MM_HP_BITSRAMBLER_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_BITSRAMBLER_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_BITSRAMBLER_ALLOW_S 23 -/** TEE_REG_CORE1_MM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_AXI_ICM_ALLOW (BIT(24)) -#define TEE_REG_CORE1_MM_HP_AXI_ICM_ALLOW_M (TEE_REG_CORE1_MM_HP_AXI_ICM_ALLOW_V << TEE_REG_CORE1_MM_HP_AXI_ICM_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_AXI_ICM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_AXI_ICM_ALLOW_S 24 -/** TEE_REG_CORE1_MM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_PERI_PMS_ALLOW (BIT(25)) -#define TEE_REG_CORE1_MM_HP_PERI_PMS_ALLOW_M (TEE_REG_CORE1_MM_HP_PERI_PMS_ALLOW_V << TEE_REG_CORE1_MM_HP_PERI_PMS_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_PERI_PMS_ALLOW_S 25 -/** TEE_REG_CORE1_MM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_LP2HP_PERI_PMS_ALLOW (BIT(26)) -#define TEE_REG_CORE1_MM_LP2HP_PERI_PMS_ALLOW_M (TEE_REG_CORE1_MM_LP2HP_PERI_PMS_ALLOW_V << TEE_REG_CORE1_MM_LP2HP_PERI_PMS_ALLOW_S) -#define TEE_REG_CORE1_MM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_LP2HP_PERI_PMS_ALLOW_S 26 -/** TEE_REG_CORE1_MM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_DMA_PMS_ALLOW (BIT(27)) -#define TEE_REG_CORE1_MM_DMA_PMS_ALLOW_M (TEE_REG_CORE1_MM_DMA_PMS_ALLOW_V << TEE_REG_CORE1_MM_DMA_PMS_ALLOW_S) -#define TEE_REG_CORE1_MM_DMA_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_DMA_PMS_ALLOW_S 27 -/** TEE_REG_CORE1_MM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_H264_DMA2D_ALLOW (BIT(28)) -#define TEE_REG_CORE1_MM_HP_H264_DMA2D_ALLOW_M (TEE_REG_CORE1_MM_HP_H264_DMA2D_ALLOW_V << TEE_REG_CORE1_MM_HP_H264_DMA2D_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_H264_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_H264_DMA2D_ALLOW_S 28 +/** PMS_CORE1_MM_HP_PERI_PMS_REG1_REG register + * Permission control register1 for HP CPU1 in machine mode + */ +#define PMS_CORE1_MM_HP_PERI_PMS_REG1_REG (DR_REG_HP_PERI_PMS_BASE + 0x2c) +/** PMS_CORE1_MM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP high-speed + * USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_USBOTG_ALLOW (BIT(0)) +#define PMS_CORE1_MM_HP_USBOTG_ALLOW_M (PMS_CORE1_MM_HP_USBOTG_ALLOW_V << PMS_CORE1_MM_HP_USBOTG_ALLOW_S) +#define PMS_CORE1_MM_HP_USBOTG_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_USBOTG_ALLOW_S 0 +/** PMS_CORE1_MM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP full-speed + * USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_USBOTG11_ALLOW (BIT(1)) +#define PMS_CORE1_MM_HP_USBOTG11_ALLOW_M (PMS_CORE1_MM_HP_USBOTG11_ALLOW_V << PMS_CORE1_MM_HP_USBOTG11_ALLOW_S) +#define PMS_CORE1_MM_HP_USBOTG11_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_USBOTG11_ALLOW_S 1 +/** PMS_CORE1_MM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP full-speed + * USB 2.0 OTG's wrap. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) +#define PMS_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_M (PMS_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_V << PMS_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_S) +#define PMS_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_USBOTG11_WRAP_ALLOW_S 2 +/** PMS_CORE1_MM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP DW-GDMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_GDMA_ALLOW (BIT(3)) +#define PMS_CORE1_MM_HP_GDMA_ALLOW_M (PMS_CORE1_MM_HP_GDMA_ALLOW_V << PMS_CORE1_MM_HP_GDMA_ALLOW_S) +#define PMS_CORE1_MM_HP_GDMA_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_GDMA_ALLOW_S 3 +/** PMS_CORE1_MM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP GDMA (DW + * GDMA). + * 0: Not allowed + * 1: Allow + */ +#define PMS_CORE1_MM_HP_REGDMA_ALLOW (BIT(4)) +#define PMS_CORE1_MM_HP_REGDMA_ALLOW_M (PMS_CORE1_MM_HP_REGDMA_ALLOW_V << PMS_CORE1_MM_HP_REGDMA_ALLOW_S) +#define PMS_CORE1_MM_HP_REGDMA_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_REGDMA_ALLOW_S 4 +/** PMS_CORE1_MM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP SDMMC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_SDMMC_ALLOW (BIT(5)) +#define PMS_CORE1_MM_HP_SDMMC_ALLOW_M (PMS_CORE1_MM_HP_SDMMC_ALLOW_V << PMS_CORE1_MM_HP_SDMMC_ALLOW_S) +#define PMS_CORE1_MM_HP_SDMMC_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_SDMMC_ALLOW_S 5 +/** PMS_CORE1_MM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access GDMA-AHB. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_AHB_PDMA_ALLOW (BIT(6)) +#define PMS_CORE1_MM_HP_AHB_PDMA_ALLOW_M (PMS_CORE1_MM_HP_AHB_PDMA_ALLOW_V << PMS_CORE1_MM_HP_AHB_PDMA_ALLOW_S) +#define PMS_CORE1_MM_HP_AHB_PDMA_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_AHB_PDMA_ALLOW_S 6 +/** PMS_CORE1_MM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP JPEG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_JPEG_ALLOW (BIT(7)) +#define PMS_CORE1_MM_HP_JPEG_ALLOW_M (PMS_CORE1_MM_HP_JPEG_ALLOW_V << PMS_CORE1_MM_HP_JPEG_ALLOW_S) +#define PMS_CORE1_MM_HP_JPEG_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_JPEG_ALLOW_S 7 +/** PMS_CORE1_MM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP PPA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_PPA_ALLOW (BIT(8)) +#define PMS_CORE1_MM_HP_PPA_ALLOW_M (PMS_CORE1_MM_HP_PPA_ALLOW_V << PMS_CORE1_MM_HP_PPA_ALLOW_S) +#define PMS_CORE1_MM_HP_PPA_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_PPA_ALLOW_S 8 +/** PMS_CORE1_MM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_DMA2D_ALLOW (BIT(9)) +#define PMS_CORE1_MM_HP_DMA2D_ALLOW_M (PMS_CORE1_MM_HP_DMA2D_ALLOW_V << PMS_CORE1_MM_HP_DMA2D_ALLOW_S) +#define PMS_CORE1_MM_HP_DMA2D_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_DMA2D_ALLOW_S 9 +/** PMS_CORE1_MM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP key manager. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_KEY_MANAGER_ALLOW (BIT(10)) +#define PMS_CORE1_MM_HP_KEY_MANAGER_ALLOW_M (PMS_CORE1_MM_HP_KEY_MANAGER_ALLOW_V << PMS_CORE1_MM_HP_KEY_MANAGER_ALLOW_S) +#define PMS_CORE1_MM_HP_KEY_MANAGER_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_KEY_MANAGER_ALLOW_S 10 +/** PMS_CORE1_MM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP GDMA-AXI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_AXI_PDMA_ALLOW (BIT(11)) +#define PMS_CORE1_MM_HP_AXI_PDMA_ALLOW_M (PMS_CORE1_MM_HP_AXI_PDMA_ALLOW_V << PMS_CORE1_MM_HP_AXI_PDMA_ALLOW_S) +#define PMS_CORE1_MM_HP_AXI_PDMA_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_AXI_PDMA_ALLOW_S 11 +/** PMS_CORE1_MM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP flash MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_FLASH_ALLOW (BIT(12)) +#define PMS_CORE1_MM_HP_FLASH_ALLOW_M (PMS_CORE1_MM_HP_FLASH_ALLOW_V << PMS_CORE1_MM_HP_FLASH_ALLOW_S) +#define PMS_CORE1_MM_HP_FLASH_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_FLASH_ALLOW_S 12 +/** PMS_CORE1_MM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP PSRAM MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_PSRAM_ALLOW (BIT(13)) +#define PMS_CORE1_MM_HP_PSRAM_ALLOW_M (PMS_CORE1_MM_HP_PSRAM_ALLOW_V << PMS_CORE1_MM_HP_PSRAM_ALLOW_S) +#define PMS_CORE1_MM_HP_PSRAM_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_PSRAM_ALLOW_S 13 +/** PMS_CORE1_MM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP CRYPTO + * (including AES/SHA/RSA/HMAC Accelerators). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_CRYPTO_ALLOW (BIT(14)) +#define PMS_CORE1_MM_HP_CRYPTO_ALLOW_M (PMS_CORE1_MM_HP_CRYPTO_ALLOW_V << PMS_CORE1_MM_HP_CRYPTO_ALLOW_S) +#define PMS_CORE1_MM_HP_CRYPTO_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_CRYPTO_ALLOW_S 14 +/** PMS_CORE1_MM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP EMAC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_GMAC_ALLOW (BIT(15)) +#define PMS_CORE1_MM_HP_GMAC_ALLOW_M (PMS_CORE1_MM_HP_GMAC_ALLOW_V << PMS_CORE1_MM_HP_GMAC_ALLOW_S) +#define PMS_CORE1_MM_HP_GMAC_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_GMAC_ALLOW_S 15 +/** PMS_CORE1_MM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP high-speed + * USB 2.0 OTG PHY. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_USB_PHY_ALLOW (BIT(16)) +#define PMS_CORE1_MM_HP_USB_PHY_ALLOW_M (PMS_CORE1_MM_HP_USB_PHY_ALLOW_V << PMS_CORE1_MM_HP_USB_PHY_ALLOW_S) +#define PMS_CORE1_MM_HP_USB_PHY_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_USB_PHY_ALLOW_S 16 +/** PMS_CORE1_MM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP PVT. + * 0: Not allowed + * 1: Allow + */ +#define PMS_CORE1_MM_HP_PVT_ALLOW (BIT(17)) +#define PMS_CORE1_MM_HP_PVT_ALLOW_M (PMS_CORE1_MM_HP_PVT_ALLOW_V << PMS_CORE1_MM_HP_PVT_ALLOW_S) +#define PMS_CORE1_MM_HP_PVT_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_PVT_ALLOW_S 17 +/** PMS_CORE1_MM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP MIPI CSI + * host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_CSI_HOST_ALLOW (BIT(18)) +#define PMS_CORE1_MM_HP_CSI_HOST_ALLOW_M (PMS_CORE1_MM_HP_CSI_HOST_ALLOW_V << PMS_CORE1_MM_HP_CSI_HOST_ALLOW_S) +#define PMS_CORE1_MM_HP_CSI_HOST_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_CSI_HOST_ALLOW_S 18 +/** PMS_CORE1_MM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP MIPI DSI + * host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_DSI_HOST_ALLOW (BIT(19)) +#define PMS_CORE1_MM_HP_DSI_HOST_ALLOW_M (PMS_CORE1_MM_HP_DSI_HOST_ALLOW_V << PMS_CORE1_MM_HP_DSI_HOST_ALLOW_S) +#define PMS_CORE1_MM_HP_DSI_HOST_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_DSI_HOST_ALLOW_S 19 +/** PMS_CORE1_MM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP ISP (Image + * Signal Processor). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_ISP_ALLOW (BIT(20)) +#define PMS_CORE1_MM_HP_ISP_ALLOW_M (PMS_CORE1_MM_HP_ISP_ALLOW_V << PMS_CORE1_MM_HP_ISP_ALLOW_S) +#define PMS_CORE1_MM_HP_ISP_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_ISP_ALLOW_S 20 +/** PMS_CORE1_MM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP H264 + * Encoder. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_H264_CORE_ALLOW (BIT(21)) +#define PMS_CORE1_MM_HP_H264_CORE_ALLOW_M (PMS_CORE1_MM_HP_H264_CORE_ALLOW_V << PMS_CORE1_MM_HP_H264_CORE_ALLOW_S) +#define PMS_CORE1_MM_HP_H264_CORE_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_H264_CORE_ALLOW_S 21 +/** PMS_CORE1_MM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP RMT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_RMT_ALLOW (BIT(22)) +#define PMS_CORE1_MM_HP_RMT_ALLOW_M (PMS_CORE1_MM_HP_RMT_ALLOW_V << PMS_CORE1_MM_HP_RMT_ALLOW_S) +#define PMS_CORE1_MM_HP_RMT_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_RMT_ALLOW_S 22 +/** PMS_CORE1_MM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP bit + * scrambler. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_BITSRAMBLER_ALLOW (BIT(23)) +#define PMS_CORE1_MM_HP_BITSRAMBLER_ALLOW_M (PMS_CORE1_MM_HP_BITSRAMBLER_ALLOW_V << PMS_CORE1_MM_HP_BITSRAMBLER_ALLOW_S) +#define PMS_CORE1_MM_HP_BITSRAMBLER_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_BITSRAMBLER_ALLOW_S 23 +/** PMS_CORE1_MM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP AXI ICM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_AXI_ICM_ALLOW (BIT(24)) +#define PMS_CORE1_MM_HP_AXI_ICM_ALLOW_M (PMS_CORE1_MM_HP_AXI_ICM_ALLOW_V << PMS_CORE1_MM_HP_AXI_ICM_ALLOW_S) +#define PMS_CORE1_MM_HP_AXI_ICM_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_AXI_ICM_ALLOW_S 24 +/** PMS_CORE1_MM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access + * HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_PERI_PMS_ALLOW (BIT(25)) +#define PMS_CORE1_MM_HP_PERI_PMS_ALLOW_M (PMS_CORE1_MM_HP_PERI_PMS_ALLOW_V << PMS_CORE1_MM_HP_PERI_PMS_ALLOW_S) +#define PMS_CORE1_MM_HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_PERI_PMS_ALLOW_S 25 +/** PMS_CORE1_MM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access + * LP2HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_LP2HP_PERI_PMS_ALLOW (BIT(26)) +#define PMS_CORE1_MM_LP2HP_PERI_PMS_ALLOW_M (PMS_CORE1_MM_LP2HP_PERI_PMS_ALLOW_V << PMS_CORE1_MM_LP2HP_PERI_PMS_ALLOW_S) +#define PMS_CORE1_MM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_LP2HP_PERI_PMS_ALLOW_S 26 +/** PMS_CORE1_MM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP_DMA_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_DMA_PMS_ALLOW (BIT(27)) +#define PMS_CORE1_MM_DMA_PMS_ALLOW_M (PMS_CORE1_MM_DMA_PMS_ALLOW_V << PMS_CORE1_MM_DMA_PMS_ALLOW_S) +#define PMS_CORE1_MM_DMA_PMS_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_DMA_PMS_ALLOW_S 27 +/** PMS_CORE1_MM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_H264_DMA2D_ALLOW (BIT(28)) +#define PMS_CORE1_MM_HP_H264_DMA2D_ALLOW_M (PMS_CORE1_MM_HP_H264_DMA2D_ALLOW_V << PMS_CORE1_MM_HP_H264_DMA2D_ALLOW_S) +#define PMS_CORE1_MM_HP_H264_DMA2D_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_H264_DMA2D_ALLOW_S 28 -/** TEE_CORE1_MM_PMS_REG2_REG register - * NA - */ -#define TEE_CORE1_MM_PMS_REG2_REG (DR_REG_TEE_BASE + 0x30) -/** TEE_REG_CORE1_MM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_MCPWM0_ALLOW (BIT(0)) -#define TEE_REG_CORE1_MM_HP_MCPWM0_ALLOW_M (TEE_REG_CORE1_MM_HP_MCPWM0_ALLOW_V << TEE_REG_CORE1_MM_HP_MCPWM0_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_MCPWM0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_MCPWM0_ALLOW_S 0 -/** TEE_REG_CORE1_MM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_MCPWM1_ALLOW (BIT(1)) -#define TEE_REG_CORE1_MM_HP_MCPWM1_ALLOW_M (TEE_REG_CORE1_MM_HP_MCPWM1_ALLOW_V << TEE_REG_CORE1_MM_HP_MCPWM1_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_MCPWM1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_MCPWM1_ALLOW_S 1 -/** TEE_REG_CORE1_MM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_TIMER_GROUP0_ALLOW (BIT(2)) -#define TEE_REG_CORE1_MM_HP_TIMER_GROUP0_ALLOW_M (TEE_REG_CORE1_MM_HP_TIMER_GROUP0_ALLOW_V << TEE_REG_CORE1_MM_HP_TIMER_GROUP0_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_TIMER_GROUP0_ALLOW_S 2 -/** TEE_REG_CORE1_MM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_TIMER_GROUP1_ALLOW (BIT(3)) -#define TEE_REG_CORE1_MM_HP_TIMER_GROUP1_ALLOW_M (TEE_REG_CORE1_MM_HP_TIMER_GROUP1_ALLOW_V << TEE_REG_CORE1_MM_HP_TIMER_GROUP1_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_TIMER_GROUP1_ALLOW_S 3 -/** TEE_REG_CORE1_MM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_I2C0_ALLOW (BIT(4)) -#define TEE_REG_CORE1_MM_HP_I2C0_ALLOW_M (TEE_REG_CORE1_MM_HP_I2C0_ALLOW_V << TEE_REG_CORE1_MM_HP_I2C0_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_I2C0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_I2C0_ALLOW_S 4 -/** TEE_REG_CORE1_MM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_I2C1_ALLOW (BIT(5)) -#define TEE_REG_CORE1_MM_HP_I2C1_ALLOW_M (TEE_REG_CORE1_MM_HP_I2C1_ALLOW_V << TEE_REG_CORE1_MM_HP_I2C1_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_I2C1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_I2C1_ALLOW_S 5 -/** TEE_REG_CORE1_MM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_I2S0_ALLOW (BIT(6)) -#define TEE_REG_CORE1_MM_HP_I2S0_ALLOW_M (TEE_REG_CORE1_MM_HP_I2S0_ALLOW_V << TEE_REG_CORE1_MM_HP_I2S0_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_I2S0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_I2S0_ALLOW_S 6 -/** TEE_REG_CORE1_MM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_I2S1_ALLOW (BIT(7)) -#define TEE_REG_CORE1_MM_HP_I2S1_ALLOW_M (TEE_REG_CORE1_MM_HP_I2S1_ALLOW_V << TEE_REG_CORE1_MM_HP_I2S1_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_I2S1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_I2S1_ALLOW_S 7 -/** TEE_REG_CORE1_MM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_I2S2_ALLOW (BIT(8)) -#define TEE_REG_CORE1_MM_HP_I2S2_ALLOW_M (TEE_REG_CORE1_MM_HP_I2S2_ALLOW_V << TEE_REG_CORE1_MM_HP_I2S2_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_I2S2_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_I2S2_ALLOW_S 8 -/** TEE_REG_CORE1_MM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_PCNT_ALLOW (BIT(9)) -#define TEE_REG_CORE1_MM_HP_PCNT_ALLOW_M (TEE_REG_CORE1_MM_HP_PCNT_ALLOW_V << TEE_REG_CORE1_MM_HP_PCNT_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_PCNT_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_PCNT_ALLOW_S 9 -/** TEE_REG_CORE1_MM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_UART0_ALLOW (BIT(10)) -#define TEE_REG_CORE1_MM_HP_UART0_ALLOW_M (TEE_REG_CORE1_MM_HP_UART0_ALLOW_V << TEE_REG_CORE1_MM_HP_UART0_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_UART0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_UART0_ALLOW_S 10 -/** TEE_REG_CORE1_MM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_UART1_ALLOW (BIT(11)) -#define TEE_REG_CORE1_MM_HP_UART1_ALLOW_M (TEE_REG_CORE1_MM_HP_UART1_ALLOW_V << TEE_REG_CORE1_MM_HP_UART1_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_UART1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_UART1_ALLOW_S 11 -/** TEE_REG_CORE1_MM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_UART2_ALLOW (BIT(12)) -#define TEE_REG_CORE1_MM_HP_UART2_ALLOW_M (TEE_REG_CORE1_MM_HP_UART2_ALLOW_V << TEE_REG_CORE1_MM_HP_UART2_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_UART2_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_UART2_ALLOW_S 12 -/** TEE_REG_CORE1_MM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_UART3_ALLOW (BIT(13)) -#define TEE_REG_CORE1_MM_HP_UART3_ALLOW_M (TEE_REG_CORE1_MM_HP_UART3_ALLOW_V << TEE_REG_CORE1_MM_HP_UART3_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_UART3_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_UART3_ALLOW_S 13 -/** TEE_REG_CORE1_MM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_UART4_ALLOW (BIT(14)) -#define TEE_REG_CORE1_MM_HP_UART4_ALLOW_M (TEE_REG_CORE1_MM_HP_UART4_ALLOW_V << TEE_REG_CORE1_MM_HP_UART4_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_UART4_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_UART4_ALLOW_S 14 -/** TEE_REG_CORE1_MM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_PARLIO_ALLOW (BIT(15)) -#define TEE_REG_CORE1_MM_HP_PARLIO_ALLOW_M (TEE_REG_CORE1_MM_HP_PARLIO_ALLOW_V << TEE_REG_CORE1_MM_HP_PARLIO_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_PARLIO_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_PARLIO_ALLOW_S 15 -/** TEE_REG_CORE1_MM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_GPSPI2_ALLOW (BIT(16)) -#define TEE_REG_CORE1_MM_HP_GPSPI2_ALLOW_M (TEE_REG_CORE1_MM_HP_GPSPI2_ALLOW_V << TEE_REG_CORE1_MM_HP_GPSPI2_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_GPSPI2_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_GPSPI2_ALLOW_S 16 -/** TEE_REG_CORE1_MM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_GPSPI3_ALLOW (BIT(17)) -#define TEE_REG_CORE1_MM_HP_GPSPI3_ALLOW_M (TEE_REG_CORE1_MM_HP_GPSPI3_ALLOW_V << TEE_REG_CORE1_MM_HP_GPSPI3_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_GPSPI3_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_GPSPI3_ALLOW_S 17 -/** TEE_REG_CORE1_MM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_USBDEVICE_ALLOW (BIT(18)) -#define TEE_REG_CORE1_MM_HP_USBDEVICE_ALLOW_M (TEE_REG_CORE1_MM_HP_USBDEVICE_ALLOW_V << TEE_REG_CORE1_MM_HP_USBDEVICE_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_USBDEVICE_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_USBDEVICE_ALLOW_S 18 -/** TEE_REG_CORE1_MM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_LEDC_ALLOW (BIT(19)) -#define TEE_REG_CORE1_MM_HP_LEDC_ALLOW_M (TEE_REG_CORE1_MM_HP_LEDC_ALLOW_V << TEE_REG_CORE1_MM_HP_LEDC_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_LEDC_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_LEDC_ALLOW_S 19 -/** TEE_REG_CORE1_MM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_ETM_ALLOW (BIT(21)) -#define TEE_REG_CORE1_MM_HP_ETM_ALLOW_M (TEE_REG_CORE1_MM_HP_ETM_ALLOW_V << TEE_REG_CORE1_MM_HP_ETM_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_ETM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_ETM_ALLOW_S 21 -/** TEE_REG_CORE1_MM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_INTRMTX_ALLOW (BIT(22)) -#define TEE_REG_CORE1_MM_HP_INTRMTX_ALLOW_M (TEE_REG_CORE1_MM_HP_INTRMTX_ALLOW_V << TEE_REG_CORE1_MM_HP_INTRMTX_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_INTRMTX_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_INTRMTX_ALLOW_S 22 -/** TEE_REG_CORE1_MM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_TWAI0_ALLOW (BIT(23)) -#define TEE_REG_CORE1_MM_HP_TWAI0_ALLOW_M (TEE_REG_CORE1_MM_HP_TWAI0_ALLOW_V << TEE_REG_CORE1_MM_HP_TWAI0_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_TWAI0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_TWAI0_ALLOW_S 23 -/** TEE_REG_CORE1_MM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_TWAI1_ALLOW (BIT(24)) -#define TEE_REG_CORE1_MM_HP_TWAI1_ALLOW_M (TEE_REG_CORE1_MM_HP_TWAI1_ALLOW_V << TEE_REG_CORE1_MM_HP_TWAI1_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_TWAI1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_TWAI1_ALLOW_S 24 -/** TEE_REG_CORE1_MM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_TWAI2_ALLOW (BIT(25)) -#define TEE_REG_CORE1_MM_HP_TWAI2_ALLOW_M (TEE_REG_CORE1_MM_HP_TWAI2_ALLOW_V << TEE_REG_CORE1_MM_HP_TWAI2_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_TWAI2_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_TWAI2_ALLOW_S 25 -/** TEE_REG_CORE1_MM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_I3C_MST_ALLOW (BIT(26)) -#define TEE_REG_CORE1_MM_HP_I3C_MST_ALLOW_M (TEE_REG_CORE1_MM_HP_I3C_MST_ALLOW_V << TEE_REG_CORE1_MM_HP_I3C_MST_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_I3C_MST_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_I3C_MST_ALLOW_S 26 -/** TEE_REG_CORE1_MM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_I3C_SLV_ALLOW (BIT(27)) -#define TEE_REG_CORE1_MM_HP_I3C_SLV_ALLOW_M (TEE_REG_CORE1_MM_HP_I3C_SLV_ALLOW_V << TEE_REG_CORE1_MM_HP_I3C_SLV_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_I3C_SLV_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_I3C_SLV_ALLOW_S 27 -/** TEE_REG_CORE1_MM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_LCDCAM_ALLOW (BIT(28)) -#define TEE_REG_CORE1_MM_HP_LCDCAM_ALLOW_M (TEE_REG_CORE1_MM_HP_LCDCAM_ALLOW_V << TEE_REG_CORE1_MM_HP_LCDCAM_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_LCDCAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_LCDCAM_ALLOW_S 28 -/** TEE_REG_CORE1_MM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_ADC_ALLOW (BIT(30)) -#define TEE_REG_CORE1_MM_HP_ADC_ALLOW_M (TEE_REG_CORE1_MM_HP_ADC_ALLOW_V << TEE_REG_CORE1_MM_HP_ADC_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_ADC_ALLOW_S 30 -/** TEE_REG_CORE1_MM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_UHCI_ALLOW (BIT(31)) -#define TEE_REG_CORE1_MM_HP_UHCI_ALLOW_M (TEE_REG_CORE1_MM_HP_UHCI_ALLOW_V << TEE_REG_CORE1_MM_HP_UHCI_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_UHCI_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_UHCI_ALLOW_S 31 +/** PMS_CORE1_MM_HP_PERI_PMS_REG2_REG register + * Permission control register2 for HP CPU1 in machine mode + */ +#define PMS_CORE1_MM_HP_PERI_PMS_REG2_REG (DR_REG_HP_PERI_PMS_BASE + 0x30) +/** PMS_CORE1_MM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP MCPWM0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_MCPWM0_ALLOW (BIT(0)) +#define PMS_CORE1_MM_HP_MCPWM0_ALLOW_M (PMS_CORE1_MM_HP_MCPWM0_ALLOW_V << PMS_CORE1_MM_HP_MCPWM0_ALLOW_S) +#define PMS_CORE1_MM_HP_MCPWM0_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_MCPWM0_ALLOW_S 0 +/** PMS_CORE1_MM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP MCPWM1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_MCPWM1_ALLOW (BIT(1)) +#define PMS_CORE1_MM_HP_MCPWM1_ALLOW_M (PMS_CORE1_MM_HP_MCPWM1_ALLOW_V << PMS_CORE1_MM_HP_MCPWM1_ALLOW_S) +#define PMS_CORE1_MM_HP_MCPWM1_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_MCPWM1_ALLOW_S 1 +/** PMS_CORE1_MM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP timer + * group0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_TIMER_GROUP0_ALLOW (BIT(2)) +#define PMS_CORE1_MM_HP_TIMER_GROUP0_ALLOW_M (PMS_CORE1_MM_HP_TIMER_GROUP0_ALLOW_V << PMS_CORE1_MM_HP_TIMER_GROUP0_ALLOW_S) +#define PMS_CORE1_MM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_TIMER_GROUP0_ALLOW_S 2 +/** PMS_CORE1_MM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP timer group1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_TIMER_GROUP1_ALLOW (BIT(3)) +#define PMS_CORE1_MM_HP_TIMER_GROUP1_ALLOW_M (PMS_CORE1_MM_HP_TIMER_GROUP1_ALLOW_V << PMS_CORE1_MM_HP_TIMER_GROUP1_ALLOW_S) +#define PMS_CORE1_MM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_TIMER_GROUP1_ALLOW_S 3 +/** PMS_CORE1_MM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP I2C0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_I2C0_ALLOW (BIT(4)) +#define PMS_CORE1_MM_HP_I2C0_ALLOW_M (PMS_CORE1_MM_HP_I2C0_ALLOW_V << PMS_CORE1_MM_HP_I2C0_ALLOW_S) +#define PMS_CORE1_MM_HP_I2C0_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_I2C0_ALLOW_S 4 +/** PMS_CORE1_MM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP I2C1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_I2C1_ALLOW (BIT(5)) +#define PMS_CORE1_MM_HP_I2C1_ALLOW_M (PMS_CORE1_MM_HP_I2C1_ALLOW_V << PMS_CORE1_MM_HP_I2C1_ALLOW_S) +#define PMS_CORE1_MM_HP_I2C1_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_I2C1_ALLOW_S 5 +/** PMS_CORE1_MM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP I2S0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_I2S0_ALLOW (BIT(6)) +#define PMS_CORE1_MM_HP_I2S0_ALLOW_M (PMS_CORE1_MM_HP_I2S0_ALLOW_V << PMS_CORE1_MM_HP_I2S0_ALLOW_S) +#define PMS_CORE1_MM_HP_I2S0_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_I2S0_ALLOW_S 6 +/** PMS_CORE1_MM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP I2S1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_I2S1_ALLOW (BIT(7)) +#define PMS_CORE1_MM_HP_I2S1_ALLOW_M (PMS_CORE1_MM_HP_I2S1_ALLOW_V << PMS_CORE1_MM_HP_I2S1_ALLOW_S) +#define PMS_CORE1_MM_HP_I2S1_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_I2S1_ALLOW_S 7 +/** PMS_CORE1_MM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP I2S2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_I2S2_ALLOW (BIT(8)) +#define PMS_CORE1_MM_HP_I2S2_ALLOW_M (PMS_CORE1_MM_HP_I2S2_ALLOW_V << PMS_CORE1_MM_HP_I2S2_ALLOW_S) +#define PMS_CORE1_MM_HP_I2S2_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_I2S2_ALLOW_S 8 +/** PMS_CORE1_MM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP PCNT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_PCNT_ALLOW (BIT(9)) +#define PMS_CORE1_MM_HP_PCNT_ALLOW_M (PMS_CORE1_MM_HP_PCNT_ALLOW_V << PMS_CORE1_MM_HP_PCNT_ALLOW_S) +#define PMS_CORE1_MM_HP_PCNT_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_PCNT_ALLOW_S 9 +/** PMS_CORE1_MM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP UART0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_UART0_ALLOW (BIT(10)) +#define PMS_CORE1_MM_HP_UART0_ALLOW_M (PMS_CORE1_MM_HP_UART0_ALLOW_V << PMS_CORE1_MM_HP_UART0_ALLOW_S) +#define PMS_CORE1_MM_HP_UART0_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_UART0_ALLOW_S 10 +/** PMS_CORE1_MM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP UART1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_UART1_ALLOW (BIT(11)) +#define PMS_CORE1_MM_HP_UART1_ALLOW_M (PMS_CORE1_MM_HP_UART1_ALLOW_V << PMS_CORE1_MM_HP_UART1_ALLOW_S) +#define PMS_CORE1_MM_HP_UART1_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_UART1_ALLOW_S 11 +/** PMS_CORE1_MM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP UART2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_UART2_ALLOW (BIT(12)) +#define PMS_CORE1_MM_HP_UART2_ALLOW_M (PMS_CORE1_MM_HP_UART2_ALLOW_V << PMS_CORE1_MM_HP_UART2_ALLOW_S) +#define PMS_CORE1_MM_HP_UART2_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_UART2_ALLOW_S 12 +/** PMS_CORE1_MM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP UART3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_UART3_ALLOW (BIT(13)) +#define PMS_CORE1_MM_HP_UART3_ALLOW_M (PMS_CORE1_MM_HP_UART3_ALLOW_V << PMS_CORE1_MM_HP_UART3_ALLOW_S) +#define PMS_CORE1_MM_HP_UART3_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_UART3_ALLOW_S 13 +/** PMS_CORE1_MM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP UART4. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_UART4_ALLOW (BIT(14)) +#define PMS_CORE1_MM_HP_UART4_ALLOW_M (PMS_CORE1_MM_HP_UART4_ALLOW_V << PMS_CORE1_MM_HP_UART4_ALLOW_S) +#define PMS_CORE1_MM_HP_UART4_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_UART4_ALLOW_S 14 +/** PMS_CORE1_MM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP PARLIO. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_PARLIO_ALLOW (BIT(15)) +#define PMS_CORE1_MM_HP_PARLIO_ALLOW_M (PMS_CORE1_MM_HP_PARLIO_ALLOW_V << PMS_CORE1_MM_HP_PARLIO_ALLOW_S) +#define PMS_CORE1_MM_HP_PARLIO_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_PARLIO_ALLOW_S 15 +/** PMS_CORE1_MM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP GP-SPI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_GPSPI2_ALLOW (BIT(16)) +#define PMS_CORE1_MM_HP_GPSPI2_ALLOW_M (PMS_CORE1_MM_HP_GPSPI2_ALLOW_V << PMS_CORE1_MM_HP_GPSPI2_ALLOW_S) +#define PMS_CORE1_MM_HP_GPSPI2_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_GPSPI2_ALLOW_S 16 +/** PMS_CORE1_MM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP GP-SPI3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_GPSPI3_ALLOW (BIT(17)) +#define PMS_CORE1_MM_HP_GPSPI3_ALLOW_M (PMS_CORE1_MM_HP_GPSPI3_ALLOW_V << PMS_CORE1_MM_HP_GPSPI3_ALLOW_S) +#define PMS_CORE1_MM_HP_GPSPI3_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_GPSPI3_ALLOW_S 17 +/** PMS_CORE1_MM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP USB + * Serial/JTAG Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_USBDEVICE_ALLOW (BIT(18)) +#define PMS_CORE1_MM_HP_USBDEVICE_ALLOW_M (PMS_CORE1_MM_HP_USBDEVICE_ALLOW_V << PMS_CORE1_MM_HP_USBDEVICE_ALLOW_S) +#define PMS_CORE1_MM_HP_USBDEVICE_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_USBDEVICE_ALLOW_S 18 +/** PMS_CORE1_MM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP LEDC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_LEDC_ALLOW (BIT(19)) +#define PMS_CORE1_MM_HP_LEDC_ALLOW_M (PMS_CORE1_MM_HP_LEDC_ALLOW_V << PMS_CORE1_MM_HP_LEDC_ALLOW_S) +#define PMS_CORE1_MM_HP_LEDC_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_LEDC_ALLOW_S 19 +/** PMS_CORE1_MM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP ETM (Event + * Task Matrix). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_ETM_ALLOW (BIT(21)) +#define PMS_CORE1_MM_HP_ETM_ALLOW_M (PMS_CORE1_MM_HP_ETM_ALLOW_V << PMS_CORE1_MM_HP_ETM_ALLOW_S) +#define PMS_CORE1_MM_HP_ETM_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_ETM_ALLOW_S 21 +/** PMS_CORE1_MM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP interrupt + * matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_INTRMTX_ALLOW (BIT(22)) +#define PMS_CORE1_MM_HP_INTRMTX_ALLOW_M (PMS_CORE1_MM_HP_INTRMTX_ALLOW_V << PMS_CORE1_MM_HP_INTRMTX_ALLOW_S) +#define PMS_CORE1_MM_HP_INTRMTX_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_INTRMTX_ALLOW_S 22 +/** PMS_CORE1_MM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP TWAI0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_TWAI0_ALLOW (BIT(23)) +#define PMS_CORE1_MM_HP_TWAI0_ALLOW_M (PMS_CORE1_MM_HP_TWAI0_ALLOW_V << PMS_CORE1_MM_HP_TWAI0_ALLOW_S) +#define PMS_CORE1_MM_HP_TWAI0_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_TWAI0_ALLOW_S 23 +/** PMS_CORE1_MM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP TWAI1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_TWAI1_ALLOW (BIT(24)) +#define PMS_CORE1_MM_HP_TWAI1_ALLOW_M (PMS_CORE1_MM_HP_TWAI1_ALLOW_V << PMS_CORE1_MM_HP_TWAI1_ALLOW_S) +#define PMS_CORE1_MM_HP_TWAI1_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_TWAI1_ALLOW_S 24 +/** PMS_CORE1_MM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP TWAI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_TWAI2_ALLOW (BIT(25)) +#define PMS_CORE1_MM_HP_TWAI2_ALLOW_M (PMS_CORE1_MM_HP_TWAI2_ALLOW_V << PMS_CORE1_MM_HP_TWAI2_ALLOW_S) +#define PMS_CORE1_MM_HP_TWAI2_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_TWAI2_ALLOW_S 25 +/** PMS_CORE1_MM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP I3C master + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_I3C_MST_ALLOW (BIT(26)) +#define PMS_CORE1_MM_HP_I3C_MST_ALLOW_M (PMS_CORE1_MM_HP_I3C_MST_ALLOW_V << PMS_CORE1_MM_HP_I3C_MST_ALLOW_S) +#define PMS_CORE1_MM_HP_I3C_MST_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_I3C_MST_ALLOW_S 26 +/** PMS_CORE1_MM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP I3C slave + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_I3C_SLV_ALLOW (BIT(27)) +#define PMS_CORE1_MM_HP_I3C_SLV_ALLOW_M (PMS_CORE1_MM_HP_I3C_SLV_ALLOW_V << PMS_CORE1_MM_HP_I3C_SLV_ALLOW_S) +#define PMS_CORE1_MM_HP_I3C_SLV_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_I3C_SLV_ALLOW_S 27 +/** PMS_CORE1_MM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP LCD_CAM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_LCDCAM_ALLOW (BIT(28)) +#define PMS_CORE1_MM_HP_LCDCAM_ALLOW_M (PMS_CORE1_MM_HP_LCDCAM_ALLOW_V << PMS_CORE1_MM_HP_LCDCAM_ALLOW_S) +#define PMS_CORE1_MM_HP_LCDCAM_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_LCDCAM_ALLOW_S 28 +/** PMS_CORE1_MM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_ADC_ALLOW (BIT(30)) +#define PMS_CORE1_MM_HP_ADC_ALLOW_M (PMS_CORE1_MM_HP_ADC_ALLOW_V << PMS_CORE1_MM_HP_ADC_ALLOW_S) +#define PMS_CORE1_MM_HP_ADC_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_ADC_ALLOW_S 30 +/** PMS_CORE1_MM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP UHCI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_UHCI_ALLOW (BIT(31)) +#define PMS_CORE1_MM_HP_UHCI_ALLOW_M (PMS_CORE1_MM_HP_UHCI_ALLOW_V << PMS_CORE1_MM_HP_UHCI_ALLOW_S) +#define PMS_CORE1_MM_HP_UHCI_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_UHCI_ALLOW_S 31 -/** TEE_CORE1_MM_PMS_REG3_REG register - * NA - */ -#define TEE_CORE1_MM_PMS_REG3_REG (DR_REG_TEE_BASE + 0x34) -/** TEE_REG_CORE1_MM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_GPIO_ALLOW (BIT(0)) -#define TEE_REG_CORE1_MM_HP_GPIO_ALLOW_M (TEE_REG_CORE1_MM_HP_GPIO_ALLOW_V << TEE_REG_CORE1_MM_HP_GPIO_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_GPIO_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_GPIO_ALLOW_S 0 -/** TEE_REG_CORE1_MM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_IOMUX_ALLOW (BIT(1)) -#define TEE_REG_CORE1_MM_HP_IOMUX_ALLOW_M (TEE_REG_CORE1_MM_HP_IOMUX_ALLOW_V << TEE_REG_CORE1_MM_HP_IOMUX_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_IOMUX_ALLOW_S 1 -/** TEE_REG_CORE1_MM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_SYSTIMER_ALLOW (BIT(2)) -#define TEE_REG_CORE1_MM_HP_SYSTIMER_ALLOW_M (TEE_REG_CORE1_MM_HP_SYSTIMER_ALLOW_V << TEE_REG_CORE1_MM_HP_SYSTIMER_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_SYSTIMER_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_SYSTIMER_ALLOW_S 2 -/** TEE_REG_CORE1_MM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_SYS_REG_ALLOW (BIT(3)) -#define TEE_REG_CORE1_MM_HP_SYS_REG_ALLOW_M (TEE_REG_CORE1_MM_HP_SYS_REG_ALLOW_V << TEE_REG_CORE1_MM_HP_SYS_REG_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_SYS_REG_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_SYS_REG_ALLOW_S 3 -/** TEE_REG_CORE1_MM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE1_MM_HP_CLKRST_ALLOW (BIT(4)) -#define TEE_REG_CORE1_MM_HP_CLKRST_ALLOW_M (TEE_REG_CORE1_MM_HP_CLKRST_ALLOW_V << TEE_REG_CORE1_MM_HP_CLKRST_ALLOW_S) -#define TEE_REG_CORE1_MM_HP_CLKRST_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_MM_HP_CLKRST_ALLOW_S 4 +/** PMS_CORE1_MM_HP_PERI_PMS_REG3_REG register + * Permission control register3 for HP CPU1 in machine mode + */ +#define PMS_CORE1_MM_HP_PERI_PMS_REG3_REG (DR_REG_HP_PERI_PMS_BASE + 0x34) +/** PMS_CORE1_MM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP GPIO Matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_GPIO_ALLOW (BIT(0)) +#define PMS_CORE1_MM_HP_GPIO_ALLOW_M (PMS_CORE1_MM_HP_GPIO_ALLOW_V << PMS_CORE1_MM_HP_GPIO_ALLOW_S) +#define PMS_CORE1_MM_HP_GPIO_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_GPIO_ALLOW_S 0 +/** PMS_CORE1_MM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_IOMUX_ALLOW (BIT(1)) +#define PMS_CORE1_MM_HP_IOMUX_ALLOW_M (PMS_CORE1_MM_HP_IOMUX_ALLOW_V << PMS_CORE1_MM_HP_IOMUX_ALLOW_S) +#define PMS_CORE1_MM_HP_IOMUX_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_IOMUX_ALLOW_S 1 +/** PMS_CORE1_MM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP system + * timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_SYSTIMER_ALLOW (BIT(2)) +#define PMS_CORE1_MM_HP_SYSTIMER_ALLOW_M (PMS_CORE1_MM_HP_SYSTIMER_ALLOW_V << PMS_CORE1_MM_HP_SYSTIMER_ALLOW_S) +#define PMS_CORE1_MM_HP_SYSTIMER_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_SYSTIMER_ALLOW_S 2 +/** PMS_CORE1_MM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP system + * register. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_SYS_REG_ALLOW (BIT(3)) +#define PMS_CORE1_MM_HP_SYS_REG_ALLOW_M (PMS_CORE1_MM_HP_SYS_REG_ALLOW_V << PMS_CORE1_MM_HP_SYS_REG_ALLOW_S) +#define PMS_CORE1_MM_HP_SYS_REG_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_SYS_REG_ALLOW_S 3 +/** PMS_CORE1_MM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU1 in machine mode has permission to access HP_SYS_CLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_MM_HP_CLKRST_ALLOW (BIT(4)) +#define PMS_CORE1_MM_HP_CLKRST_ALLOW_M (PMS_CORE1_MM_HP_CLKRST_ALLOW_V << PMS_CORE1_MM_HP_CLKRST_ALLOW_S) +#define PMS_CORE1_MM_HP_CLKRST_ALLOW_V 0x00000001U +#define PMS_CORE1_MM_HP_CLKRST_ALLOW_S 4 -/** TEE_CORE1_UM_PMS_REG0_REG register - * NA - */ -#define TEE_CORE1_UM_PMS_REG0_REG (DR_REG_TEE_BASE + 0x38) -/** TEE_REG_CORE1_UM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_PSRAM_ALLOW (BIT(0)) -#define TEE_REG_CORE1_UM_PSRAM_ALLOW_M (TEE_REG_CORE1_UM_PSRAM_ALLOW_V << TEE_REG_CORE1_UM_PSRAM_ALLOW_S) -#define TEE_REG_CORE1_UM_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_PSRAM_ALLOW_S 0 -/** TEE_REG_CORE1_UM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_FLASH_ALLOW (BIT(1)) -#define TEE_REG_CORE1_UM_FLASH_ALLOW_M (TEE_REG_CORE1_UM_FLASH_ALLOW_V << TEE_REG_CORE1_UM_FLASH_ALLOW_S) -#define TEE_REG_CORE1_UM_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_FLASH_ALLOW_S 1 -/** TEE_REG_CORE1_UM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_L2MEM_ALLOW (BIT(2)) -#define TEE_REG_CORE1_UM_L2MEM_ALLOW_M (TEE_REG_CORE1_UM_L2MEM_ALLOW_V << TEE_REG_CORE1_UM_L2MEM_ALLOW_S) -#define TEE_REG_CORE1_UM_L2MEM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_L2MEM_ALLOW_S 2 -/** TEE_REG_CORE1_UM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_L2ROM_ALLOW (BIT(3)) -#define TEE_REG_CORE1_UM_L2ROM_ALLOW_M (TEE_REG_CORE1_UM_L2ROM_ALLOW_V << TEE_REG_CORE1_UM_L2ROM_ALLOW_S) -#define TEE_REG_CORE1_UM_L2ROM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_L2ROM_ALLOW_S 3 -/** TEE_REG_CORE1_UM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_TRACE0_ALLOW (BIT(6)) -#define TEE_REG_CORE1_UM_TRACE0_ALLOW_M (TEE_REG_CORE1_UM_TRACE0_ALLOW_V << TEE_REG_CORE1_UM_TRACE0_ALLOW_S) -#define TEE_REG_CORE1_UM_TRACE0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_TRACE0_ALLOW_S 6 -/** TEE_REG_CORE1_UM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_TRACE1_ALLOW (BIT(7)) -#define TEE_REG_CORE1_UM_TRACE1_ALLOW_M (TEE_REG_CORE1_UM_TRACE1_ALLOW_V << TEE_REG_CORE1_UM_TRACE1_ALLOW_S) -#define TEE_REG_CORE1_UM_TRACE1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_TRACE1_ALLOW_S 7 -/** TEE_REG_CORE1_UM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_CPU_BUS_MON_ALLOW (BIT(8)) -#define TEE_REG_CORE1_UM_CPU_BUS_MON_ALLOW_M (TEE_REG_CORE1_UM_CPU_BUS_MON_ALLOW_V << TEE_REG_CORE1_UM_CPU_BUS_MON_ALLOW_S) -#define TEE_REG_CORE1_UM_CPU_BUS_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_CPU_BUS_MON_ALLOW_S 8 -/** TEE_REG_CORE1_UM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_L2MEM_MON_ALLOW (BIT(9)) -#define TEE_REG_CORE1_UM_L2MEM_MON_ALLOW_M (TEE_REG_CORE1_UM_L2MEM_MON_ALLOW_V << TEE_REG_CORE1_UM_L2MEM_MON_ALLOW_S) -#define TEE_REG_CORE1_UM_L2MEM_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_L2MEM_MON_ALLOW_S 9 -/** TEE_REG_CORE1_UM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_TCM_MON_ALLOW (BIT(10)) -#define TEE_REG_CORE1_UM_TCM_MON_ALLOW_M (TEE_REG_CORE1_UM_TCM_MON_ALLOW_V << TEE_REG_CORE1_UM_TCM_MON_ALLOW_S) -#define TEE_REG_CORE1_UM_TCM_MON_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_TCM_MON_ALLOW_S 10 -/** TEE_REG_CORE1_UM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_CACHE_ALLOW (BIT(11)) -#define TEE_REG_CORE1_UM_CACHE_ALLOW_M (TEE_REG_CORE1_UM_CACHE_ALLOW_V << TEE_REG_CORE1_UM_CACHE_ALLOW_S) -#define TEE_REG_CORE1_UM_CACHE_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_CACHE_ALLOW_S 11 +/** PMS_CORE1_UM_HP_PERI_PMS_REG0_REG register + * Permission control register0 for HP CPU1 in user mode + */ +#define PMS_CORE1_UM_HP_PERI_PMS_REG0_REG (DR_REG_HP_PERI_PMS_BASE + 0x38) +/** PMS_CORE1_UM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access external RAM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_PSRAM_ALLOW (BIT(0)) +#define PMS_CORE1_UM_PSRAM_ALLOW_M (PMS_CORE1_UM_PSRAM_ALLOW_V << PMS_CORE1_UM_PSRAM_ALLOW_S) +#define PMS_CORE1_UM_PSRAM_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_PSRAM_ALLOW_S 0 +/** PMS_CORE1_UM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access external flash + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_FLASH_ALLOW (BIT(1)) +#define PMS_CORE1_UM_FLASH_ALLOW_M (PMS_CORE1_UM_FLASH_ALLOW_V << PMS_CORE1_UM_FLASH_ALLOW_S) +#define PMS_CORE1_UM_FLASH_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_FLASH_ALLOW_S 1 +/** PMS_CORE1_UM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP L2MEM without + * going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_L2MEM_ALLOW (BIT(2)) +#define PMS_CORE1_UM_L2MEM_ALLOW_M (PMS_CORE1_UM_L2MEM_ALLOW_V << PMS_CORE1_UM_L2MEM_ALLOW_S) +#define PMS_CORE1_UM_L2MEM_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_L2MEM_ALLOW_S 2 +/** PMS_CORE1_UM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP ROM without + * going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_L2ROM_ALLOW (BIT(3)) +#define PMS_CORE1_UM_L2ROM_ALLOW_M (PMS_CORE1_UM_L2ROM_ALLOW_V << PMS_CORE1_UM_L2ROM_ALLOW_S) +#define PMS_CORE1_UM_L2ROM_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_L2ROM_ALLOW_S 3 +/** PMS_CORE1_UM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access TRACE0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_TRACE0_ALLOW (BIT(6)) +#define PMS_CORE1_UM_TRACE0_ALLOW_M (PMS_CORE1_UM_TRACE0_ALLOW_V << PMS_CORE1_UM_TRACE0_ALLOW_S) +#define PMS_CORE1_UM_TRACE0_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_TRACE0_ALLOW_S 6 +/** PMS_CORE1_UM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access TRACE1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_TRACE1_ALLOW (BIT(7)) +#define PMS_CORE1_UM_TRACE1_ALLOW_M (PMS_CORE1_UM_TRACE1_ALLOW_V << PMS_CORE1_UM_TRACE1_ALLOW_S) +#define PMS_CORE1_UM_TRACE1_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_TRACE1_ALLOW_S 7 +/** PMS_CORE1_UM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access CPU bus monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_CPU_BUS_MON_ALLOW (BIT(8)) +#define PMS_CORE1_UM_CPU_BUS_MON_ALLOW_M (PMS_CORE1_UM_CPU_BUS_MON_ALLOW_V << PMS_CORE1_UM_CPU_BUS_MON_ALLOW_S) +#define PMS_CORE1_UM_CPU_BUS_MON_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_CPU_BUS_MON_ALLOW_S 8 +/** PMS_CORE1_UM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access L2MEM monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_L2MEM_MON_ALLOW (BIT(9)) +#define PMS_CORE1_UM_L2MEM_MON_ALLOW_M (PMS_CORE1_UM_L2MEM_MON_ALLOW_V << PMS_CORE1_UM_L2MEM_MON_ALLOW_S) +#define PMS_CORE1_UM_L2MEM_MON_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_L2MEM_MON_ALLOW_S 9 +/** PMS_CORE1_UM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access TCM monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_TCM_MON_ALLOW (BIT(10)) +#define PMS_CORE1_UM_TCM_MON_ALLOW_M (PMS_CORE1_UM_TCM_MON_ALLOW_V << PMS_CORE1_UM_TCM_MON_ALLOW_S) +#define PMS_CORE1_UM_TCM_MON_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_TCM_MON_ALLOW_S 10 +/** PMS_CORE1_UM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_CACHE_ALLOW (BIT(11)) +#define PMS_CORE1_UM_CACHE_ALLOW_M (PMS_CORE1_UM_CACHE_ALLOW_V << PMS_CORE1_UM_CACHE_ALLOW_S) +#define PMS_CORE1_UM_CACHE_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_CACHE_ALLOW_S 11 -/** TEE_CORE1_UM_PMS_REG1_REG register - * NA - */ -#define TEE_CORE1_UM_PMS_REG1_REG (DR_REG_TEE_BASE + 0x3c) -/** TEE_REG_CORE1_UM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_USBOTG_ALLOW (BIT(0)) -#define TEE_REG_CORE1_UM_HP_USBOTG_ALLOW_M (TEE_REG_CORE1_UM_HP_USBOTG_ALLOW_V << TEE_REG_CORE1_UM_HP_USBOTG_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_USBOTG_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_USBOTG_ALLOW_S 0 -/** TEE_REG_CORE1_UM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_USBOTG11_ALLOW (BIT(1)) -#define TEE_REG_CORE1_UM_HP_USBOTG11_ALLOW_M (TEE_REG_CORE1_UM_HP_USBOTG11_ALLOW_V << TEE_REG_CORE1_UM_HP_USBOTG11_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_USBOTG11_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_USBOTG11_ALLOW_S 1 -/** TEE_REG_CORE1_UM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) -#define TEE_REG_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_M (TEE_REG_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_V << TEE_REG_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_S 2 -/** TEE_REG_CORE1_UM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_GDMA_ALLOW (BIT(3)) -#define TEE_REG_CORE1_UM_HP_GDMA_ALLOW_M (TEE_REG_CORE1_UM_HP_GDMA_ALLOW_V << TEE_REG_CORE1_UM_HP_GDMA_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_GDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_GDMA_ALLOW_S 3 -/** TEE_REG_CORE1_UM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_REGDMA_ALLOW (BIT(4)) -#define TEE_REG_CORE1_UM_HP_REGDMA_ALLOW_M (TEE_REG_CORE1_UM_HP_REGDMA_ALLOW_V << TEE_REG_CORE1_UM_HP_REGDMA_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_REGDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_REGDMA_ALLOW_S 4 -/** TEE_REG_CORE1_UM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_SDMMC_ALLOW (BIT(5)) -#define TEE_REG_CORE1_UM_HP_SDMMC_ALLOW_M (TEE_REG_CORE1_UM_HP_SDMMC_ALLOW_V << TEE_REG_CORE1_UM_HP_SDMMC_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_SDMMC_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_SDMMC_ALLOW_S 5 -/** TEE_REG_CORE1_UM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_AHB_PDMA_ALLOW (BIT(6)) -#define TEE_REG_CORE1_UM_HP_AHB_PDMA_ALLOW_M (TEE_REG_CORE1_UM_HP_AHB_PDMA_ALLOW_V << TEE_REG_CORE1_UM_HP_AHB_PDMA_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_AHB_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_AHB_PDMA_ALLOW_S 6 -/** TEE_REG_CORE1_UM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_JPEG_ALLOW (BIT(7)) -#define TEE_REG_CORE1_UM_HP_JPEG_ALLOW_M (TEE_REG_CORE1_UM_HP_JPEG_ALLOW_V << TEE_REG_CORE1_UM_HP_JPEG_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_JPEG_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_JPEG_ALLOW_S 7 -/** TEE_REG_CORE1_UM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_PPA_ALLOW (BIT(8)) -#define TEE_REG_CORE1_UM_HP_PPA_ALLOW_M (TEE_REG_CORE1_UM_HP_PPA_ALLOW_V << TEE_REG_CORE1_UM_HP_PPA_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_PPA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_PPA_ALLOW_S 8 -/** TEE_REG_CORE1_UM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_DMA2D_ALLOW (BIT(9)) -#define TEE_REG_CORE1_UM_HP_DMA2D_ALLOW_M (TEE_REG_CORE1_UM_HP_DMA2D_ALLOW_V << TEE_REG_CORE1_UM_HP_DMA2D_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_DMA2D_ALLOW_S 9 -/** TEE_REG_CORE1_UM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_KEY_MANAGER_ALLOW (BIT(10)) -#define TEE_REG_CORE1_UM_HP_KEY_MANAGER_ALLOW_M (TEE_REG_CORE1_UM_HP_KEY_MANAGER_ALLOW_V << TEE_REG_CORE1_UM_HP_KEY_MANAGER_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_KEY_MANAGER_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_KEY_MANAGER_ALLOW_S 10 -/** TEE_REG_CORE1_UM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_AXI_PDMA_ALLOW (BIT(11)) -#define TEE_REG_CORE1_UM_HP_AXI_PDMA_ALLOW_M (TEE_REG_CORE1_UM_HP_AXI_PDMA_ALLOW_V << TEE_REG_CORE1_UM_HP_AXI_PDMA_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_AXI_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_AXI_PDMA_ALLOW_S 11 -/** TEE_REG_CORE1_UM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_FLASH_ALLOW (BIT(12)) -#define TEE_REG_CORE1_UM_HP_FLASH_ALLOW_M (TEE_REG_CORE1_UM_HP_FLASH_ALLOW_V << TEE_REG_CORE1_UM_HP_FLASH_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_FLASH_ALLOW_S 12 -/** TEE_REG_CORE1_UM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_PSRAM_ALLOW (BIT(13)) -#define TEE_REG_CORE1_UM_HP_PSRAM_ALLOW_M (TEE_REG_CORE1_UM_HP_PSRAM_ALLOW_V << TEE_REG_CORE1_UM_HP_PSRAM_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_PSRAM_ALLOW_S 13 -/** TEE_REG_CORE1_UM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_CRYPTO_ALLOW (BIT(14)) -#define TEE_REG_CORE1_UM_HP_CRYPTO_ALLOW_M (TEE_REG_CORE1_UM_HP_CRYPTO_ALLOW_V << TEE_REG_CORE1_UM_HP_CRYPTO_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_CRYPTO_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_CRYPTO_ALLOW_S 14 -/** TEE_REG_CORE1_UM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_GMAC_ALLOW (BIT(15)) -#define TEE_REG_CORE1_UM_HP_GMAC_ALLOW_M (TEE_REG_CORE1_UM_HP_GMAC_ALLOW_V << TEE_REG_CORE1_UM_HP_GMAC_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_GMAC_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_GMAC_ALLOW_S 15 -/** TEE_REG_CORE1_UM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_USB_PHY_ALLOW (BIT(16)) -#define TEE_REG_CORE1_UM_HP_USB_PHY_ALLOW_M (TEE_REG_CORE1_UM_HP_USB_PHY_ALLOW_V << TEE_REG_CORE1_UM_HP_USB_PHY_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_USB_PHY_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_USB_PHY_ALLOW_S 16 -/** TEE_REG_CORE1_UM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_PVT_ALLOW (BIT(17)) -#define TEE_REG_CORE1_UM_HP_PVT_ALLOW_M (TEE_REG_CORE1_UM_HP_PVT_ALLOW_V << TEE_REG_CORE1_UM_HP_PVT_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_PVT_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_PVT_ALLOW_S 17 -/** TEE_REG_CORE1_UM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_CSI_HOST_ALLOW (BIT(18)) -#define TEE_REG_CORE1_UM_HP_CSI_HOST_ALLOW_M (TEE_REG_CORE1_UM_HP_CSI_HOST_ALLOW_V << TEE_REG_CORE1_UM_HP_CSI_HOST_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_CSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_CSI_HOST_ALLOW_S 18 -/** TEE_REG_CORE1_UM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_DSI_HOST_ALLOW (BIT(19)) -#define TEE_REG_CORE1_UM_HP_DSI_HOST_ALLOW_M (TEE_REG_CORE1_UM_HP_DSI_HOST_ALLOW_V << TEE_REG_CORE1_UM_HP_DSI_HOST_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_DSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_DSI_HOST_ALLOW_S 19 -/** TEE_REG_CORE1_UM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_ISP_ALLOW (BIT(20)) -#define TEE_REG_CORE1_UM_HP_ISP_ALLOW_M (TEE_REG_CORE1_UM_HP_ISP_ALLOW_V << TEE_REG_CORE1_UM_HP_ISP_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_ISP_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_ISP_ALLOW_S 20 -/** TEE_REG_CORE1_UM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_H264_CORE_ALLOW (BIT(21)) -#define TEE_REG_CORE1_UM_HP_H264_CORE_ALLOW_M (TEE_REG_CORE1_UM_HP_H264_CORE_ALLOW_V << TEE_REG_CORE1_UM_HP_H264_CORE_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_H264_CORE_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_H264_CORE_ALLOW_S 21 -/** TEE_REG_CORE1_UM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_RMT_ALLOW (BIT(22)) -#define TEE_REG_CORE1_UM_HP_RMT_ALLOW_M (TEE_REG_CORE1_UM_HP_RMT_ALLOW_V << TEE_REG_CORE1_UM_HP_RMT_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_RMT_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_RMT_ALLOW_S 22 -/** TEE_REG_CORE1_UM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_BITSRAMBLER_ALLOW (BIT(23)) -#define TEE_REG_CORE1_UM_HP_BITSRAMBLER_ALLOW_M (TEE_REG_CORE1_UM_HP_BITSRAMBLER_ALLOW_V << TEE_REG_CORE1_UM_HP_BITSRAMBLER_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_BITSRAMBLER_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_BITSRAMBLER_ALLOW_S 23 -/** TEE_REG_CORE1_UM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_AXI_ICM_ALLOW (BIT(24)) -#define TEE_REG_CORE1_UM_HP_AXI_ICM_ALLOW_M (TEE_REG_CORE1_UM_HP_AXI_ICM_ALLOW_V << TEE_REG_CORE1_UM_HP_AXI_ICM_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_AXI_ICM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_AXI_ICM_ALLOW_S 24 -/** TEE_REG_CORE1_UM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_PERI_PMS_ALLOW (BIT(25)) -#define TEE_REG_CORE1_UM_HP_PERI_PMS_ALLOW_M (TEE_REG_CORE1_UM_HP_PERI_PMS_ALLOW_V << TEE_REG_CORE1_UM_HP_PERI_PMS_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_PERI_PMS_ALLOW_S 25 -/** TEE_REG_CORE1_UM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_LP2HP_PERI_PMS_ALLOW (BIT(26)) -#define TEE_REG_CORE1_UM_LP2HP_PERI_PMS_ALLOW_M (TEE_REG_CORE1_UM_LP2HP_PERI_PMS_ALLOW_V << TEE_REG_CORE1_UM_LP2HP_PERI_PMS_ALLOW_S) -#define TEE_REG_CORE1_UM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_LP2HP_PERI_PMS_ALLOW_S 26 -/** TEE_REG_CORE1_UM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_DMA_PMS_ALLOW (BIT(27)) -#define TEE_REG_CORE1_UM_DMA_PMS_ALLOW_M (TEE_REG_CORE1_UM_DMA_PMS_ALLOW_V << TEE_REG_CORE1_UM_DMA_PMS_ALLOW_S) -#define TEE_REG_CORE1_UM_DMA_PMS_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_DMA_PMS_ALLOW_S 27 -/** TEE_REG_CORE1_UM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_H264_DMA2D_ALLOW (BIT(28)) -#define TEE_REG_CORE1_UM_HP_H264_DMA2D_ALLOW_M (TEE_REG_CORE1_UM_HP_H264_DMA2D_ALLOW_V << TEE_REG_CORE1_UM_HP_H264_DMA2D_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_H264_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_H264_DMA2D_ALLOW_S 28 +/** PMS_CORE1_UM_HP_PERI_PMS_REG1_REG register + * Permission control register1 for HP CPU1 in user mode + */ +#define PMS_CORE1_UM_HP_PERI_PMS_REG1_REG (DR_REG_HP_PERI_PMS_BASE + 0x3c) +/** PMS_CORE1_UM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP high-speed USB + * 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_USBOTG_ALLOW (BIT(0)) +#define PMS_CORE1_UM_HP_USBOTG_ALLOW_M (PMS_CORE1_UM_HP_USBOTG_ALLOW_V << PMS_CORE1_UM_HP_USBOTG_ALLOW_S) +#define PMS_CORE1_UM_HP_USBOTG_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_USBOTG_ALLOW_S 0 +/** PMS_CORE1_UM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP full-speed USB + * 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_USBOTG11_ALLOW (BIT(1)) +#define PMS_CORE1_UM_HP_USBOTG11_ALLOW_M (PMS_CORE1_UM_HP_USBOTG11_ALLOW_V << PMS_CORE1_UM_HP_USBOTG11_ALLOW_S) +#define PMS_CORE1_UM_HP_USBOTG11_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_USBOTG11_ALLOW_S 1 +/** PMS_CORE1_UM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP full-speed USB + * 2.0 OTG's wrap. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) +#define PMS_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_M (PMS_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_V << PMS_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_S) +#define PMS_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_USBOTG11_WRAP_ALLOW_S 2 +/** PMS_CORE1_UM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP DW-GDMA. + * 0: Not allowed + * 1: Allowed + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_GDMA_ALLOW (BIT(3)) +#define PMS_CORE1_UM_HP_GDMA_ALLOW_M (PMS_CORE1_UM_HP_GDMA_ALLOW_V << PMS_CORE1_UM_HP_GDMA_ALLOW_S) +#define PMS_CORE1_UM_HP_GDMA_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_GDMA_ALLOW_S 3 +/** PMS_CORE1_UM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP regdma. + * 0: Not allowed + * 1: Allow + */ +#define PMS_CORE1_UM_HP_REGDMA_ALLOW (BIT(4)) +#define PMS_CORE1_UM_HP_REGDMA_ALLOW_M (PMS_CORE1_UM_HP_REGDMA_ALLOW_V << PMS_CORE1_UM_HP_REGDMA_ALLOW_S) +#define PMS_CORE1_UM_HP_REGDMA_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_REGDMA_ALLOW_S 4 +/** PMS_CORE1_UM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP SDMMC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_SDMMC_ALLOW (BIT(5)) +#define PMS_CORE1_UM_HP_SDMMC_ALLOW_M (PMS_CORE1_UM_HP_SDMMC_ALLOW_V << PMS_CORE1_UM_HP_SDMMC_ALLOW_S) +#define PMS_CORE1_UM_HP_SDMMC_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_SDMMC_ALLOW_S 5 +/** PMS_CORE1_UM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access GDMA-AHB. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_AHB_PDMA_ALLOW (BIT(6)) +#define PMS_CORE1_UM_HP_AHB_PDMA_ALLOW_M (PMS_CORE1_UM_HP_AHB_PDMA_ALLOW_V << PMS_CORE1_UM_HP_AHB_PDMA_ALLOW_S) +#define PMS_CORE1_UM_HP_AHB_PDMA_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_AHB_PDMA_ALLOW_S 6 +/** PMS_CORE1_UM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP JPEG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_JPEG_ALLOW (BIT(7)) +#define PMS_CORE1_UM_HP_JPEG_ALLOW_M (PMS_CORE1_UM_HP_JPEG_ALLOW_V << PMS_CORE1_UM_HP_JPEG_ALLOW_S) +#define PMS_CORE1_UM_HP_JPEG_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_JPEG_ALLOW_S 7 +/** PMS_CORE1_UM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP PPA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_PPA_ALLOW (BIT(8)) +#define PMS_CORE1_UM_HP_PPA_ALLOW_M (PMS_CORE1_UM_HP_PPA_ALLOW_V << PMS_CORE1_UM_HP_PPA_ALLOW_S) +#define PMS_CORE1_UM_HP_PPA_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_PPA_ALLOW_S 8 +/** PMS_CORE1_UM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_DMA2D_ALLOW (BIT(9)) +#define PMS_CORE1_UM_HP_DMA2D_ALLOW_M (PMS_CORE1_UM_HP_DMA2D_ALLOW_V << PMS_CORE1_UM_HP_DMA2D_ALLOW_S) +#define PMS_CORE1_UM_HP_DMA2D_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_DMA2D_ALLOW_S 9 +/** PMS_CORE1_UM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP key manager. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_KEY_MANAGER_ALLOW (BIT(10)) +#define PMS_CORE1_UM_HP_KEY_MANAGER_ALLOW_M (PMS_CORE1_UM_HP_KEY_MANAGER_ALLOW_V << PMS_CORE1_UM_HP_KEY_MANAGER_ALLOW_S) +#define PMS_CORE1_UM_HP_KEY_MANAGER_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_KEY_MANAGER_ALLOW_S 10 +/** PMS_CORE1_UM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP GDMA-AXI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_AXI_PDMA_ALLOW (BIT(11)) +#define PMS_CORE1_UM_HP_AXI_PDMA_ALLOW_M (PMS_CORE1_UM_HP_AXI_PDMA_ALLOW_V << PMS_CORE1_UM_HP_AXI_PDMA_ALLOW_S) +#define PMS_CORE1_UM_HP_AXI_PDMA_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_AXI_PDMA_ALLOW_S 11 +/** PMS_CORE1_UM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP flash MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_FLASH_ALLOW (BIT(12)) +#define PMS_CORE1_UM_HP_FLASH_ALLOW_M (PMS_CORE1_UM_HP_FLASH_ALLOW_V << PMS_CORE1_UM_HP_FLASH_ALLOW_S) +#define PMS_CORE1_UM_HP_FLASH_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_FLASH_ALLOW_S 12 +/** PMS_CORE1_UM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP PSRAM MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_PSRAM_ALLOW (BIT(13)) +#define PMS_CORE1_UM_HP_PSRAM_ALLOW_M (PMS_CORE1_UM_HP_PSRAM_ALLOW_V << PMS_CORE1_UM_HP_PSRAM_ALLOW_S) +#define PMS_CORE1_UM_HP_PSRAM_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_PSRAM_ALLOW_S 13 +/** PMS_CORE1_UM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP CRYPTO. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_CRYPTO_ALLOW (BIT(14)) +#define PMS_CORE1_UM_HP_CRYPTO_ALLOW_M (PMS_CORE1_UM_HP_CRYPTO_ALLOW_V << PMS_CORE1_UM_HP_CRYPTO_ALLOW_S) +#define PMS_CORE1_UM_HP_CRYPTO_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_CRYPTO_ALLOW_S 14 +/** PMS_CORE1_UM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP EMAC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_GMAC_ALLOW (BIT(15)) +#define PMS_CORE1_UM_HP_GMAC_ALLOW_M (PMS_CORE1_UM_HP_GMAC_ALLOW_V << PMS_CORE1_UM_HP_GMAC_ALLOW_S) +#define PMS_CORE1_UM_HP_GMAC_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_GMAC_ALLOW_S 15 +/** PMS_CORE1_UM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP high-speed USB + * 2.0 OTG PHY. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_USB_PHY_ALLOW (BIT(16)) +#define PMS_CORE1_UM_HP_USB_PHY_ALLOW_M (PMS_CORE1_UM_HP_USB_PHY_ALLOW_V << PMS_CORE1_UM_HP_USB_PHY_ALLOW_S) +#define PMS_CORE1_UM_HP_USB_PHY_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_USB_PHY_ALLOW_S 16 +/** PMS_CORE1_UM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP PVT. + * 0: Not allowed + * 1: Allow + */ +#define PMS_CORE1_UM_HP_PVT_ALLOW (BIT(17)) +#define PMS_CORE1_UM_HP_PVT_ALLOW_M (PMS_CORE1_UM_HP_PVT_ALLOW_V << PMS_CORE1_UM_HP_PVT_ALLOW_S) +#define PMS_CORE1_UM_HP_PVT_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_PVT_ALLOW_S 17 +/** PMS_CORE1_UM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP MIPI CSI host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_CSI_HOST_ALLOW (BIT(18)) +#define PMS_CORE1_UM_HP_CSI_HOST_ALLOW_M (PMS_CORE1_UM_HP_CSI_HOST_ALLOW_V << PMS_CORE1_UM_HP_CSI_HOST_ALLOW_S) +#define PMS_CORE1_UM_HP_CSI_HOST_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_CSI_HOST_ALLOW_S 18 +/** PMS_CORE1_UM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP MIPI DSI host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_DSI_HOST_ALLOW (BIT(19)) +#define PMS_CORE1_UM_HP_DSI_HOST_ALLOW_M (PMS_CORE1_UM_HP_DSI_HOST_ALLOW_V << PMS_CORE1_UM_HP_DSI_HOST_ALLOW_S) +#define PMS_CORE1_UM_HP_DSI_HOST_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_DSI_HOST_ALLOW_S 19 +/** PMS_CORE1_UM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP ISP. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_ISP_ALLOW (BIT(20)) +#define PMS_CORE1_UM_HP_ISP_ALLOW_M (PMS_CORE1_UM_HP_ISP_ALLOW_V << PMS_CORE1_UM_HP_ISP_ALLOW_S) +#define PMS_CORE1_UM_HP_ISP_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_ISP_ALLOW_S 20 +/** PMS_CORE1_UM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP H264 Encoder. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_H264_CORE_ALLOW (BIT(21)) +#define PMS_CORE1_UM_HP_H264_CORE_ALLOW_M (PMS_CORE1_UM_HP_H264_CORE_ALLOW_V << PMS_CORE1_UM_HP_H264_CORE_ALLOW_S) +#define PMS_CORE1_UM_HP_H264_CORE_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_H264_CORE_ALLOW_S 21 +/** PMS_CORE1_UM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP RMT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_RMT_ALLOW (BIT(22)) +#define PMS_CORE1_UM_HP_RMT_ALLOW_M (PMS_CORE1_UM_HP_RMT_ALLOW_V << PMS_CORE1_UM_HP_RMT_ALLOW_S) +#define PMS_CORE1_UM_HP_RMT_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_RMT_ALLOW_S 22 +/** PMS_CORE1_UM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP bit scrambler. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_BITSRAMBLER_ALLOW (BIT(23)) +#define PMS_CORE1_UM_HP_BITSRAMBLER_ALLOW_M (PMS_CORE1_UM_HP_BITSRAMBLER_ALLOW_V << PMS_CORE1_UM_HP_BITSRAMBLER_ALLOW_S) +#define PMS_CORE1_UM_HP_BITSRAMBLER_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_BITSRAMBLER_ALLOW_S 23 +/** PMS_CORE1_UM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP AXI ICM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_AXI_ICM_ALLOW (BIT(24)) +#define PMS_CORE1_UM_HP_AXI_ICM_ALLOW_M (PMS_CORE1_UM_HP_AXI_ICM_ALLOW_V << PMS_CORE1_UM_HP_AXI_ICM_ALLOW_S) +#define PMS_CORE1_UM_HP_AXI_ICM_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_AXI_ICM_ALLOW_S 24 +/** PMS_CORE1_UM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_PERI_PMS_ALLOW (BIT(25)) +#define PMS_CORE1_UM_HP_PERI_PMS_ALLOW_M (PMS_CORE1_UM_HP_PERI_PMS_ALLOW_V << PMS_CORE1_UM_HP_PERI_PMS_ALLOW_S) +#define PMS_CORE1_UM_HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_PERI_PMS_ALLOW_S 25 +/** PMS_CORE1_UM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access + * LP2HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_LP2HP_PERI_PMS_ALLOW (BIT(26)) +#define PMS_CORE1_UM_LP2HP_PERI_PMS_ALLOW_M (PMS_CORE1_UM_LP2HP_PERI_PMS_ALLOW_V << PMS_CORE1_UM_LP2HP_PERI_PMS_ALLOW_S) +#define PMS_CORE1_UM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_LP2HP_PERI_PMS_ALLOW_S 26 +/** PMS_CORE1_UM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP_DMA_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_DMA_PMS_ALLOW (BIT(27)) +#define PMS_CORE1_UM_DMA_PMS_ALLOW_M (PMS_CORE1_UM_DMA_PMS_ALLOW_V << PMS_CORE1_UM_DMA_PMS_ALLOW_S) +#define PMS_CORE1_UM_DMA_PMS_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_DMA_PMS_ALLOW_S 27 +/** PMS_CORE1_UM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_H264_DMA2D_ALLOW (BIT(28)) +#define PMS_CORE1_UM_HP_H264_DMA2D_ALLOW_M (PMS_CORE1_UM_HP_H264_DMA2D_ALLOW_V << PMS_CORE1_UM_HP_H264_DMA2D_ALLOW_S) +#define PMS_CORE1_UM_HP_H264_DMA2D_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_H264_DMA2D_ALLOW_S 28 -/** TEE_CORE1_UM_PMS_REG2_REG register - * NA - */ -#define TEE_CORE1_UM_PMS_REG2_REG (DR_REG_TEE_BASE + 0x40) -/** TEE_REG_CORE1_UM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_MCPWM0_ALLOW (BIT(0)) -#define TEE_REG_CORE1_UM_HP_MCPWM0_ALLOW_M (TEE_REG_CORE1_UM_HP_MCPWM0_ALLOW_V << TEE_REG_CORE1_UM_HP_MCPWM0_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_MCPWM0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_MCPWM0_ALLOW_S 0 -/** TEE_REG_CORE1_UM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_MCPWM1_ALLOW (BIT(1)) -#define TEE_REG_CORE1_UM_HP_MCPWM1_ALLOW_M (TEE_REG_CORE1_UM_HP_MCPWM1_ALLOW_V << TEE_REG_CORE1_UM_HP_MCPWM1_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_MCPWM1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_MCPWM1_ALLOW_S 1 -/** TEE_REG_CORE1_UM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_TIMER_GROUP0_ALLOW (BIT(2)) -#define TEE_REG_CORE1_UM_HP_TIMER_GROUP0_ALLOW_M (TEE_REG_CORE1_UM_HP_TIMER_GROUP0_ALLOW_V << TEE_REG_CORE1_UM_HP_TIMER_GROUP0_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_TIMER_GROUP0_ALLOW_S 2 -/** TEE_REG_CORE1_UM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_TIMER_GROUP1_ALLOW (BIT(3)) -#define TEE_REG_CORE1_UM_HP_TIMER_GROUP1_ALLOW_M (TEE_REG_CORE1_UM_HP_TIMER_GROUP1_ALLOW_V << TEE_REG_CORE1_UM_HP_TIMER_GROUP1_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_TIMER_GROUP1_ALLOW_S 3 -/** TEE_REG_CORE1_UM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_I2C0_ALLOW (BIT(4)) -#define TEE_REG_CORE1_UM_HP_I2C0_ALLOW_M (TEE_REG_CORE1_UM_HP_I2C0_ALLOW_V << TEE_REG_CORE1_UM_HP_I2C0_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_I2C0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_I2C0_ALLOW_S 4 -/** TEE_REG_CORE1_UM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_I2C1_ALLOW (BIT(5)) -#define TEE_REG_CORE1_UM_HP_I2C1_ALLOW_M (TEE_REG_CORE1_UM_HP_I2C1_ALLOW_V << TEE_REG_CORE1_UM_HP_I2C1_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_I2C1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_I2C1_ALLOW_S 5 -/** TEE_REG_CORE1_UM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_I2S0_ALLOW (BIT(6)) -#define TEE_REG_CORE1_UM_HP_I2S0_ALLOW_M (TEE_REG_CORE1_UM_HP_I2S0_ALLOW_V << TEE_REG_CORE1_UM_HP_I2S0_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_I2S0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_I2S0_ALLOW_S 6 -/** TEE_REG_CORE1_UM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_I2S1_ALLOW (BIT(7)) -#define TEE_REG_CORE1_UM_HP_I2S1_ALLOW_M (TEE_REG_CORE1_UM_HP_I2S1_ALLOW_V << TEE_REG_CORE1_UM_HP_I2S1_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_I2S1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_I2S1_ALLOW_S 7 -/** TEE_REG_CORE1_UM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_I2S2_ALLOW (BIT(8)) -#define TEE_REG_CORE1_UM_HP_I2S2_ALLOW_M (TEE_REG_CORE1_UM_HP_I2S2_ALLOW_V << TEE_REG_CORE1_UM_HP_I2S2_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_I2S2_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_I2S2_ALLOW_S 8 -/** TEE_REG_CORE1_UM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_PCNT_ALLOW (BIT(9)) -#define TEE_REG_CORE1_UM_HP_PCNT_ALLOW_M (TEE_REG_CORE1_UM_HP_PCNT_ALLOW_V << TEE_REG_CORE1_UM_HP_PCNT_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_PCNT_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_PCNT_ALLOW_S 9 -/** TEE_REG_CORE1_UM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_UART0_ALLOW (BIT(10)) -#define TEE_REG_CORE1_UM_HP_UART0_ALLOW_M (TEE_REG_CORE1_UM_HP_UART0_ALLOW_V << TEE_REG_CORE1_UM_HP_UART0_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_UART0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_UART0_ALLOW_S 10 -/** TEE_REG_CORE1_UM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_UART1_ALLOW (BIT(11)) -#define TEE_REG_CORE1_UM_HP_UART1_ALLOW_M (TEE_REG_CORE1_UM_HP_UART1_ALLOW_V << TEE_REG_CORE1_UM_HP_UART1_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_UART1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_UART1_ALLOW_S 11 -/** TEE_REG_CORE1_UM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_UART2_ALLOW (BIT(12)) -#define TEE_REG_CORE1_UM_HP_UART2_ALLOW_M (TEE_REG_CORE1_UM_HP_UART2_ALLOW_V << TEE_REG_CORE1_UM_HP_UART2_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_UART2_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_UART2_ALLOW_S 12 -/** TEE_REG_CORE1_UM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_UART3_ALLOW (BIT(13)) -#define TEE_REG_CORE1_UM_HP_UART3_ALLOW_M (TEE_REG_CORE1_UM_HP_UART3_ALLOW_V << TEE_REG_CORE1_UM_HP_UART3_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_UART3_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_UART3_ALLOW_S 13 -/** TEE_REG_CORE1_UM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_UART4_ALLOW (BIT(14)) -#define TEE_REG_CORE1_UM_HP_UART4_ALLOW_M (TEE_REG_CORE1_UM_HP_UART4_ALLOW_V << TEE_REG_CORE1_UM_HP_UART4_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_UART4_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_UART4_ALLOW_S 14 -/** TEE_REG_CORE1_UM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_PARLIO_ALLOW (BIT(15)) -#define TEE_REG_CORE1_UM_HP_PARLIO_ALLOW_M (TEE_REG_CORE1_UM_HP_PARLIO_ALLOW_V << TEE_REG_CORE1_UM_HP_PARLIO_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_PARLIO_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_PARLIO_ALLOW_S 15 -/** TEE_REG_CORE1_UM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_GPSPI2_ALLOW (BIT(16)) -#define TEE_REG_CORE1_UM_HP_GPSPI2_ALLOW_M (TEE_REG_CORE1_UM_HP_GPSPI2_ALLOW_V << TEE_REG_CORE1_UM_HP_GPSPI2_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_GPSPI2_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_GPSPI2_ALLOW_S 16 -/** TEE_REG_CORE1_UM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_GPSPI3_ALLOW (BIT(17)) -#define TEE_REG_CORE1_UM_HP_GPSPI3_ALLOW_M (TEE_REG_CORE1_UM_HP_GPSPI3_ALLOW_V << TEE_REG_CORE1_UM_HP_GPSPI3_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_GPSPI3_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_GPSPI3_ALLOW_S 17 -/** TEE_REG_CORE1_UM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_USBDEVICE_ALLOW (BIT(18)) -#define TEE_REG_CORE1_UM_HP_USBDEVICE_ALLOW_M (TEE_REG_CORE1_UM_HP_USBDEVICE_ALLOW_V << TEE_REG_CORE1_UM_HP_USBDEVICE_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_USBDEVICE_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_USBDEVICE_ALLOW_S 18 -/** TEE_REG_CORE1_UM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_LEDC_ALLOW (BIT(19)) -#define TEE_REG_CORE1_UM_HP_LEDC_ALLOW_M (TEE_REG_CORE1_UM_HP_LEDC_ALLOW_V << TEE_REG_CORE1_UM_HP_LEDC_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_LEDC_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_LEDC_ALLOW_S 19 -/** TEE_REG_CORE1_UM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_ETM_ALLOW (BIT(21)) -#define TEE_REG_CORE1_UM_HP_ETM_ALLOW_M (TEE_REG_CORE1_UM_HP_ETM_ALLOW_V << TEE_REG_CORE1_UM_HP_ETM_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_ETM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_ETM_ALLOW_S 21 -/** TEE_REG_CORE1_UM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_INTRMTX_ALLOW (BIT(22)) -#define TEE_REG_CORE1_UM_HP_INTRMTX_ALLOW_M (TEE_REG_CORE1_UM_HP_INTRMTX_ALLOW_V << TEE_REG_CORE1_UM_HP_INTRMTX_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_INTRMTX_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_INTRMTX_ALLOW_S 22 -/** TEE_REG_CORE1_UM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_TWAI0_ALLOW (BIT(23)) -#define TEE_REG_CORE1_UM_HP_TWAI0_ALLOW_M (TEE_REG_CORE1_UM_HP_TWAI0_ALLOW_V << TEE_REG_CORE1_UM_HP_TWAI0_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_TWAI0_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_TWAI0_ALLOW_S 23 -/** TEE_REG_CORE1_UM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_TWAI1_ALLOW (BIT(24)) -#define TEE_REG_CORE1_UM_HP_TWAI1_ALLOW_M (TEE_REG_CORE1_UM_HP_TWAI1_ALLOW_V << TEE_REG_CORE1_UM_HP_TWAI1_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_TWAI1_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_TWAI1_ALLOW_S 24 -/** TEE_REG_CORE1_UM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_TWAI2_ALLOW (BIT(25)) -#define TEE_REG_CORE1_UM_HP_TWAI2_ALLOW_M (TEE_REG_CORE1_UM_HP_TWAI2_ALLOW_V << TEE_REG_CORE1_UM_HP_TWAI2_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_TWAI2_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_TWAI2_ALLOW_S 25 -/** TEE_REG_CORE1_UM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_I3C_MST_ALLOW (BIT(26)) -#define TEE_REG_CORE1_UM_HP_I3C_MST_ALLOW_M (TEE_REG_CORE1_UM_HP_I3C_MST_ALLOW_V << TEE_REG_CORE1_UM_HP_I3C_MST_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_I3C_MST_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_I3C_MST_ALLOW_S 26 -/** TEE_REG_CORE1_UM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_I3C_SLV_ALLOW (BIT(27)) -#define TEE_REG_CORE1_UM_HP_I3C_SLV_ALLOW_M (TEE_REG_CORE1_UM_HP_I3C_SLV_ALLOW_V << TEE_REG_CORE1_UM_HP_I3C_SLV_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_I3C_SLV_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_I3C_SLV_ALLOW_S 27 -/** TEE_REG_CORE1_UM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_LCDCAM_ALLOW (BIT(28)) -#define TEE_REG_CORE1_UM_HP_LCDCAM_ALLOW_M (TEE_REG_CORE1_UM_HP_LCDCAM_ALLOW_V << TEE_REG_CORE1_UM_HP_LCDCAM_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_LCDCAM_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_LCDCAM_ALLOW_S 28 -/** TEE_REG_CORE1_UM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_ADC_ALLOW (BIT(30)) -#define TEE_REG_CORE1_UM_HP_ADC_ALLOW_M (TEE_REG_CORE1_UM_HP_ADC_ALLOW_V << TEE_REG_CORE1_UM_HP_ADC_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_ADC_ALLOW_S 30 -/** TEE_REG_CORE1_UM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_UHCI_ALLOW (BIT(31)) -#define TEE_REG_CORE1_UM_HP_UHCI_ALLOW_M (TEE_REG_CORE1_UM_HP_UHCI_ALLOW_V << TEE_REG_CORE1_UM_HP_UHCI_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_UHCI_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_UHCI_ALLOW_S 31 +/** PMS_CORE1_UM_HP_PERI_PMS_REG2_REG register + * Permission control register2 for HP CPU1 in user mode + */ +#define PMS_CORE1_UM_HP_PERI_PMS_REG2_REG (DR_REG_HP_PERI_PMS_BASE + 0x40) +/** PMS_CORE1_UM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP MCPWM0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_MCPWM0_ALLOW (BIT(0)) +#define PMS_CORE1_UM_HP_MCPWM0_ALLOW_M (PMS_CORE1_UM_HP_MCPWM0_ALLOW_V << PMS_CORE1_UM_HP_MCPWM0_ALLOW_S) +#define PMS_CORE1_UM_HP_MCPWM0_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_MCPWM0_ALLOW_S 0 +/** PMS_CORE1_UM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP MCPWM1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_MCPWM1_ALLOW (BIT(1)) +#define PMS_CORE1_UM_HP_MCPWM1_ALLOW_M (PMS_CORE1_UM_HP_MCPWM1_ALLOW_V << PMS_CORE1_UM_HP_MCPWM1_ALLOW_S) +#define PMS_CORE1_UM_HP_MCPWM1_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_MCPWM1_ALLOW_S 1 +/** PMS_CORE1_UM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP timer group0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_TIMER_GROUP0_ALLOW (BIT(2)) +#define PMS_CORE1_UM_HP_TIMER_GROUP0_ALLOW_M (PMS_CORE1_UM_HP_TIMER_GROUP0_ALLOW_V << PMS_CORE1_UM_HP_TIMER_GROUP0_ALLOW_S) +#define PMS_CORE1_UM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_TIMER_GROUP0_ALLOW_S 2 +/** PMS_CORE1_UM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP timer group1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_TIMER_GROUP1_ALLOW (BIT(3)) +#define PMS_CORE1_UM_HP_TIMER_GROUP1_ALLOW_M (PMS_CORE1_UM_HP_TIMER_GROUP1_ALLOW_V << PMS_CORE1_UM_HP_TIMER_GROUP1_ALLOW_S) +#define PMS_CORE1_UM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_TIMER_GROUP1_ALLOW_S 3 +/** PMS_CORE1_UM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP I2C0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_I2C0_ALLOW (BIT(4)) +#define PMS_CORE1_UM_HP_I2C0_ALLOW_M (PMS_CORE1_UM_HP_I2C0_ALLOW_V << PMS_CORE1_UM_HP_I2C0_ALLOW_S) +#define PMS_CORE1_UM_HP_I2C0_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_I2C0_ALLOW_S 4 +/** PMS_CORE1_UM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP I2C1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_I2C1_ALLOW (BIT(5)) +#define PMS_CORE1_UM_HP_I2C1_ALLOW_M (PMS_CORE1_UM_HP_I2C1_ALLOW_V << PMS_CORE1_UM_HP_I2C1_ALLOW_S) +#define PMS_CORE1_UM_HP_I2C1_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_I2C1_ALLOW_S 5 +/** PMS_CORE1_UM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP I2S0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_I2S0_ALLOW (BIT(6)) +#define PMS_CORE1_UM_HP_I2S0_ALLOW_M (PMS_CORE1_UM_HP_I2S0_ALLOW_V << PMS_CORE1_UM_HP_I2S0_ALLOW_S) +#define PMS_CORE1_UM_HP_I2S0_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_I2S0_ALLOW_S 6 +/** PMS_CORE1_UM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP I2S1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_I2S1_ALLOW (BIT(7)) +#define PMS_CORE1_UM_HP_I2S1_ALLOW_M (PMS_CORE1_UM_HP_I2S1_ALLOW_V << PMS_CORE1_UM_HP_I2S1_ALLOW_S) +#define PMS_CORE1_UM_HP_I2S1_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_I2S1_ALLOW_S 7 +/** PMS_CORE1_UM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP I2S2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_I2S2_ALLOW (BIT(8)) +#define PMS_CORE1_UM_HP_I2S2_ALLOW_M (PMS_CORE1_UM_HP_I2S2_ALLOW_V << PMS_CORE1_UM_HP_I2S2_ALLOW_S) +#define PMS_CORE1_UM_HP_I2S2_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_I2S2_ALLOW_S 8 +/** PMS_CORE1_UM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP PCNT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_PCNT_ALLOW (BIT(9)) +#define PMS_CORE1_UM_HP_PCNT_ALLOW_M (PMS_CORE1_UM_HP_PCNT_ALLOW_V << PMS_CORE1_UM_HP_PCNT_ALLOW_S) +#define PMS_CORE1_UM_HP_PCNT_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_PCNT_ALLOW_S 9 +/** PMS_CORE1_UM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP UART0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_UART0_ALLOW (BIT(10)) +#define PMS_CORE1_UM_HP_UART0_ALLOW_M (PMS_CORE1_UM_HP_UART0_ALLOW_V << PMS_CORE1_UM_HP_UART0_ALLOW_S) +#define PMS_CORE1_UM_HP_UART0_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_UART0_ALLOW_S 10 +/** PMS_CORE1_UM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP UART1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_UART1_ALLOW (BIT(11)) +#define PMS_CORE1_UM_HP_UART1_ALLOW_M (PMS_CORE1_UM_HP_UART1_ALLOW_V << PMS_CORE1_UM_HP_UART1_ALLOW_S) +#define PMS_CORE1_UM_HP_UART1_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_UART1_ALLOW_S 11 +/** PMS_CORE1_UM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP UART2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_UART2_ALLOW (BIT(12)) +#define PMS_CORE1_UM_HP_UART2_ALLOW_M (PMS_CORE1_UM_HP_UART2_ALLOW_V << PMS_CORE1_UM_HP_UART2_ALLOW_S) +#define PMS_CORE1_UM_HP_UART2_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_UART2_ALLOW_S 12 +/** PMS_CORE1_UM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP UART3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_UART3_ALLOW (BIT(13)) +#define PMS_CORE1_UM_HP_UART3_ALLOW_M (PMS_CORE1_UM_HP_UART3_ALLOW_V << PMS_CORE1_UM_HP_UART3_ALLOW_S) +#define PMS_CORE1_UM_HP_UART3_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_UART3_ALLOW_S 13 +/** PMS_CORE1_UM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP UART4. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_UART4_ALLOW (BIT(14)) +#define PMS_CORE1_UM_HP_UART4_ALLOW_M (PMS_CORE1_UM_HP_UART4_ALLOW_V << PMS_CORE1_UM_HP_UART4_ALLOW_S) +#define PMS_CORE1_UM_HP_UART4_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_UART4_ALLOW_S 14 +/** PMS_CORE1_UM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP PARLIO. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_PARLIO_ALLOW (BIT(15)) +#define PMS_CORE1_UM_HP_PARLIO_ALLOW_M (PMS_CORE1_UM_HP_PARLIO_ALLOW_V << PMS_CORE1_UM_HP_PARLIO_ALLOW_S) +#define PMS_CORE1_UM_HP_PARLIO_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_PARLIO_ALLOW_S 15 +/** PMS_CORE1_UM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP GP-SPI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_GPSPI2_ALLOW (BIT(16)) +#define PMS_CORE1_UM_HP_GPSPI2_ALLOW_M (PMS_CORE1_UM_HP_GPSPI2_ALLOW_V << PMS_CORE1_UM_HP_GPSPI2_ALLOW_S) +#define PMS_CORE1_UM_HP_GPSPI2_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_GPSPI2_ALLOW_S 16 +/** PMS_CORE1_UM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP GP-SPI3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_GPSPI3_ALLOW (BIT(17)) +#define PMS_CORE1_UM_HP_GPSPI3_ALLOW_M (PMS_CORE1_UM_HP_GPSPI3_ALLOW_V << PMS_CORE1_UM_HP_GPSPI3_ALLOW_S) +#define PMS_CORE1_UM_HP_GPSPI3_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_GPSPI3_ALLOW_S 17 +/** PMS_CORE1_UM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP USB/Serial JTAG + * Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_USBDEVICE_ALLOW (BIT(18)) +#define PMS_CORE1_UM_HP_USBDEVICE_ALLOW_M (PMS_CORE1_UM_HP_USBDEVICE_ALLOW_V << PMS_CORE1_UM_HP_USBDEVICE_ALLOW_S) +#define PMS_CORE1_UM_HP_USBDEVICE_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_USBDEVICE_ALLOW_S 18 +/** PMS_CORE1_UM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP LEDC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_LEDC_ALLOW (BIT(19)) +#define PMS_CORE1_UM_HP_LEDC_ALLOW_M (PMS_CORE1_UM_HP_LEDC_ALLOW_V << PMS_CORE1_UM_HP_LEDC_ALLOW_S) +#define PMS_CORE1_UM_HP_LEDC_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_LEDC_ALLOW_S 19 +/** PMS_CORE1_UM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP ETM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_ETM_ALLOW (BIT(21)) +#define PMS_CORE1_UM_HP_ETM_ALLOW_M (PMS_CORE1_UM_HP_ETM_ALLOW_V << PMS_CORE1_UM_HP_ETM_ALLOW_S) +#define PMS_CORE1_UM_HP_ETM_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_ETM_ALLOW_S 21 +/** PMS_CORE1_UM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP interrupt + * matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_INTRMTX_ALLOW (BIT(22)) +#define PMS_CORE1_UM_HP_INTRMTX_ALLOW_M (PMS_CORE1_UM_HP_INTRMTX_ALLOW_V << PMS_CORE1_UM_HP_INTRMTX_ALLOW_S) +#define PMS_CORE1_UM_HP_INTRMTX_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_INTRMTX_ALLOW_S 22 +/** PMS_CORE1_UM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP TWAI0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_TWAI0_ALLOW (BIT(23)) +#define PMS_CORE1_UM_HP_TWAI0_ALLOW_M (PMS_CORE1_UM_HP_TWAI0_ALLOW_V << PMS_CORE1_UM_HP_TWAI0_ALLOW_S) +#define PMS_CORE1_UM_HP_TWAI0_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_TWAI0_ALLOW_S 23 +/** PMS_CORE1_UM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP TWAI1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_TWAI1_ALLOW (BIT(24)) +#define PMS_CORE1_UM_HP_TWAI1_ALLOW_M (PMS_CORE1_UM_HP_TWAI1_ALLOW_V << PMS_CORE1_UM_HP_TWAI1_ALLOW_S) +#define PMS_CORE1_UM_HP_TWAI1_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_TWAI1_ALLOW_S 24 +/** PMS_CORE1_UM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP TWAI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_TWAI2_ALLOW (BIT(25)) +#define PMS_CORE1_UM_HP_TWAI2_ALLOW_M (PMS_CORE1_UM_HP_TWAI2_ALLOW_V << PMS_CORE1_UM_HP_TWAI2_ALLOW_S) +#define PMS_CORE1_UM_HP_TWAI2_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_TWAI2_ALLOW_S 25 +/** PMS_CORE1_UM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP I3C master + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_I3C_MST_ALLOW (BIT(26)) +#define PMS_CORE1_UM_HP_I3C_MST_ALLOW_M (PMS_CORE1_UM_HP_I3C_MST_ALLOW_V << PMS_CORE1_UM_HP_I3C_MST_ALLOW_S) +#define PMS_CORE1_UM_HP_I3C_MST_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_I3C_MST_ALLOW_S 26 +/** PMS_CORE1_UM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP I3C slave + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_I3C_SLV_ALLOW (BIT(27)) +#define PMS_CORE1_UM_HP_I3C_SLV_ALLOW_M (PMS_CORE1_UM_HP_I3C_SLV_ALLOW_V << PMS_CORE1_UM_HP_I3C_SLV_ALLOW_S) +#define PMS_CORE1_UM_HP_I3C_SLV_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_I3C_SLV_ALLOW_S 27 +/** PMS_CORE1_UM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP LCD_CAM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_LCDCAM_ALLOW (BIT(28)) +#define PMS_CORE1_UM_HP_LCDCAM_ALLOW_M (PMS_CORE1_UM_HP_LCDCAM_ALLOW_V << PMS_CORE1_UM_HP_LCDCAM_ALLOW_S) +#define PMS_CORE1_UM_HP_LCDCAM_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_LCDCAM_ALLOW_S 28 +/** PMS_CORE1_UM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_ADC_ALLOW (BIT(30)) +#define PMS_CORE1_UM_HP_ADC_ALLOW_M (PMS_CORE1_UM_HP_ADC_ALLOW_V << PMS_CORE1_UM_HP_ADC_ALLOW_S) +#define PMS_CORE1_UM_HP_ADC_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_ADC_ALLOW_S 30 +/** PMS_CORE1_UM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP UHCI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_UHCI_ALLOW (BIT(31)) +#define PMS_CORE1_UM_HP_UHCI_ALLOW_M (PMS_CORE1_UM_HP_UHCI_ALLOW_V << PMS_CORE1_UM_HP_UHCI_ALLOW_S) +#define PMS_CORE1_UM_HP_UHCI_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_UHCI_ALLOW_S 31 -/** TEE_CORE1_UM_PMS_REG3_REG register - * NA - */ -#define TEE_CORE1_UM_PMS_REG3_REG (DR_REG_TEE_BASE + 0x44) -/** TEE_REG_CORE1_UM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_GPIO_ALLOW (BIT(0)) -#define TEE_REG_CORE1_UM_HP_GPIO_ALLOW_M (TEE_REG_CORE1_UM_HP_GPIO_ALLOW_V << TEE_REG_CORE1_UM_HP_GPIO_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_GPIO_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_GPIO_ALLOW_S 0 -/** TEE_REG_CORE1_UM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_IOMUX_ALLOW (BIT(1)) -#define TEE_REG_CORE1_UM_HP_IOMUX_ALLOW_M (TEE_REG_CORE1_UM_HP_IOMUX_ALLOW_V << TEE_REG_CORE1_UM_HP_IOMUX_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_IOMUX_ALLOW_S 1 -/** TEE_REG_CORE1_UM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_SYSTIMER_ALLOW (BIT(2)) -#define TEE_REG_CORE1_UM_HP_SYSTIMER_ALLOW_M (TEE_REG_CORE1_UM_HP_SYSTIMER_ALLOW_V << TEE_REG_CORE1_UM_HP_SYSTIMER_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_SYSTIMER_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_SYSTIMER_ALLOW_S 2 -/** TEE_REG_CORE1_UM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_SYS_REG_ALLOW (BIT(3)) -#define TEE_REG_CORE1_UM_HP_SYS_REG_ALLOW_M (TEE_REG_CORE1_UM_HP_SYS_REG_ALLOW_V << TEE_REG_CORE1_UM_HP_SYS_REG_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_SYS_REG_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_SYS_REG_ALLOW_S 3 -/** TEE_REG_CORE1_UM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_CORE1_UM_HP_CLKRST_ALLOW (BIT(4)) -#define TEE_REG_CORE1_UM_HP_CLKRST_ALLOW_M (TEE_REG_CORE1_UM_HP_CLKRST_ALLOW_V << TEE_REG_CORE1_UM_HP_CLKRST_ALLOW_S) -#define TEE_REG_CORE1_UM_HP_CLKRST_ALLOW_V 0x00000001U -#define TEE_REG_CORE1_UM_HP_CLKRST_ALLOW_S 4 +/** PMS_CORE1_UM_HP_PERI_PMS_REG3_REG register + * Permission control register3 for HP CPU1 in user mode + */ +#define PMS_CORE1_UM_HP_PERI_PMS_REG3_REG (DR_REG_HP_PERI_PMS_BASE + 0x44) +/** PMS_CORE1_UM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP GPIO Matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_GPIO_ALLOW (BIT(0)) +#define PMS_CORE1_UM_HP_GPIO_ALLOW_M (PMS_CORE1_UM_HP_GPIO_ALLOW_V << PMS_CORE1_UM_HP_GPIO_ALLOW_S) +#define PMS_CORE1_UM_HP_GPIO_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_GPIO_ALLOW_S 0 +/** PMS_CORE1_UM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_IOMUX_ALLOW (BIT(1)) +#define PMS_CORE1_UM_HP_IOMUX_ALLOW_M (PMS_CORE1_UM_HP_IOMUX_ALLOW_V << PMS_CORE1_UM_HP_IOMUX_ALLOW_S) +#define PMS_CORE1_UM_HP_IOMUX_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_IOMUX_ALLOW_S 1 +/** PMS_CORE1_UM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP system timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_SYSTIMER_ALLOW (BIT(2)) +#define PMS_CORE1_UM_HP_SYSTIMER_ALLOW_M (PMS_CORE1_UM_HP_SYSTIMER_ALLOW_V << PMS_CORE1_UM_HP_SYSTIMER_ALLOW_S) +#define PMS_CORE1_UM_HP_SYSTIMER_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_SYSTIMER_ALLOW_S 2 +/** PMS_CORE1_UM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP system + * register. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_SYS_REG_ALLOW (BIT(3)) +#define PMS_CORE1_UM_HP_SYS_REG_ALLOW_M (PMS_CORE1_UM_HP_SYS_REG_ALLOW_V << PMS_CORE1_UM_HP_SYS_REG_ALLOW_S) +#define PMS_CORE1_UM_HP_SYS_REG_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_SYS_REG_ALLOW_S 3 +/** PMS_CORE1_UM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPU1 in user mode has permission to access HP_SYS_CLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_CORE1_UM_HP_CLKRST_ALLOW (BIT(4)) +#define PMS_CORE1_UM_HP_CLKRST_ALLOW_M (PMS_CORE1_UM_HP_CLKRST_ALLOW_V << PMS_CORE1_UM_HP_CLKRST_ALLOW_S) +#define PMS_CORE1_UM_HP_CLKRST_ALLOW_V 0x00000001U +#define PMS_CORE1_UM_HP_CLKRST_ALLOW_S 4 -/** TEE_REGDMA_PERI_PMS_REG register - * NA - */ -#define TEE_REGDMA_PERI_PMS_REG (DR_REG_TEE_BASE + 0x48) -/** TEE_REG_REGDMA_PERI_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_REGDMA_PERI_ALLOW (BIT(0)) -#define TEE_REG_REGDMA_PERI_ALLOW_M (TEE_REG_REGDMA_PERI_ALLOW_V << TEE_REG_REGDMA_PERI_ALLOW_S) -#define TEE_REG_REGDMA_PERI_ALLOW_V 0x00000001U -#define TEE_REG_REGDMA_PERI_ALLOW_S 0 +/** PMS_REGDMA_PERI_PMS_REG register + * Permission register for REGDMA + */ +#define PMS_REGDMA_PERI_PMS_REG (DR_REG_HP_PERI_PMS_BASE + 0x48) +/** PMS_REGDMA_PERI_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether REGDMA has permission to access all HP peripheral (including CPU + * peripherals). + * 0: Not allowed + * 1: Allow + */ +#define PMS_REGDMA_PERI_ALLOW (BIT(0)) +#define PMS_REGDMA_PERI_ALLOW_M (PMS_REGDMA_PERI_ALLOW_V << PMS_REGDMA_PERI_ALLOW_S) +#define PMS_REGDMA_PERI_ALLOW_V 0x00000001U +#define PMS_REGDMA_PERI_ALLOW_S 0 #ifdef __cplusplus } diff --git a/components/soc/esp32p4/include/soc/hp_peri_pms_struct.h b/components/soc/esp32p4/include/soc/hp_peri_pms_struct.h index 85149ae67399..41091e040ea0 100644 --- a/components/soc/esp32p4/include/soc/hp_peri_pms_struct.h +++ b/components/soc/esp32p4/include/soc/hp_peri_pms_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,1462 +10,1104 @@ extern "C" { #endif -/** Group: TEE PMS DATE REG */ -/** Type of pms_date register - * NA +/** Group: TEE HP Peripheral Version Control Registers */ +/** Type of hp_peri_pms_date register + * Version control register */ typedef union { struct { - /** tee_date : R/W; bitpos: [31:0]; default: 2294537; - * NA + /** hp_peri_pms_date : R/W; bitpos: [31:0]; default: 2294537; + * Version control register. */ - uint32_t tee_date:32; + uint32_t hp_peri_pms_date:32; }; uint32_t val; -} tee_pms_date_reg_t; +} pms_hp_peri_pms_date_reg_t; -/** Group: TEE PMS CLK EN REG */ -/** Type of pms_clk_en register - * NA +/** Group: Clock Gating Registers */ +/** Type of hp_peri_pms_clk_en register + * Clock gating register */ typedef union { struct { - /** reg_clk_en : R/W; bitpos: [0]; default: 1; - * NA + /** hp_peri_pms_clk_en : R/W; bitpos: [0]; default: 1; + * Configures whether to keep the clock always on. + * 0: Enable automatic clock gating + * 1: Keep the clock always on */ - uint32_t reg_clk_en:1; + uint32_t hp_peri_pms_clk_en:1; uint32_t reserved_1:31; }; uint32_t val; -} tee_pms_clk_en_reg_t; +} pms_hp_peri_pms_clk_en_reg_t; -/** Group: TEE CORE0 MM PMS REG0 REG */ -/** Type of core0_mm_pms_reg0 register - * NA +/** Group: HP CPU Permission Control Registers */ +/** Type of coren_mm_hp_peri_pms_reg0 register + * Permission control register0 for HP CPUn in machine mode */ typedef union { struct { - /** reg_core0_mm_psram_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core0_mm_psram_allow:1; - /** reg_core0_mm_flash_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core0_mm_flash_allow:1; - /** reg_core0_mm_l2mem_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core0_mm_l2mem_allow:1; - /** reg_core0_mm_l2rom_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core0_mm_l2rom_allow:1; + /** coren_mm_psram_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access external RAM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_psram_allow:1; + /** coren_mm_flash_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access external flash + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_flash_allow:1; + /** coren_mm_l2mem_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP L2MEM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_l2mem_allow:1; + /** coren_mm_l2rom_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP ROM without + * going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_l2rom_allow:1; uint32_t reserved_4:2; - /** reg_core0_mm_trace0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core0_mm_trace0_allow:1; - /** reg_core0_mm_trace1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core0_mm_trace1_allow:1; - /** reg_core0_mm_cpu_bus_mon_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core0_mm_cpu_bus_mon_allow:1; - /** reg_core0_mm_l2mem_mon_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core0_mm_l2mem_mon_allow:1; - /** reg_core0_mm_tcm_mon_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core0_mm_tcm_mon_allow:1; - /** reg_core0_mm_cache_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core0_mm_cache_allow:1; + /** coren_mm_trace0_allow : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access TRACE0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_trace0_allow:1; + /** coren_mm_trace1_allow : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access TRACE1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_trace1_allow:1; + /** coren_mm_cpu_bus_mon_allow : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access CPU bus + * monitor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_cpu_bus_mon_allow:1; + /** coren_mm_l2mem_mon_allow : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access L2MEM monitor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_l2mem_mon_allow:1; + /** coren_mm_tcm_mon_allow : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access TCM monitor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_tcm_mon_allow:1; + /** coren_mm_cache_allow : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_cache_allow:1; uint32_t reserved_12:20; }; uint32_t val; -} tee_core0_mm_pms_reg0_reg_t; - +} pms_coren_mm_hp_peri_pms_reg0_reg_t; -/** Group: TEE CORE0 MM PMS REG1 REG */ -/** Type of core0_mm_pms_reg1 register - * NA +/** Type of coren_mm_hp_peri_pms_reg1 register + * Permission control register1 for HP CPUn in machine mode */ typedef union { struct { - /** reg_core0_mm_hp_usbotg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_usbotg_allow:1; - /** reg_core0_mm_hp_usbotg11_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_usbotg11_allow:1; - /** reg_core0_mm_hp_usbotg11_wrap_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_usbotg11_wrap_allow:1; - /** reg_core0_mm_hp_gdma_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_gdma_allow:1; - /** reg_core0_mm_hp_regdma_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_regdma_allow:1; - /** reg_core0_mm_hp_sdmmc_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_sdmmc_allow:1; - /** reg_core0_mm_hp_ahb_pdma_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_ahb_pdma_allow:1; - /** reg_core0_mm_hp_jpeg_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_jpeg_allow:1; - /** reg_core0_mm_hp_ppa_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_ppa_allow:1; - /** reg_core0_mm_hp_dma2d_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_dma2d_allow:1; - /** reg_core0_mm_hp_key_manager_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_key_manager_allow:1; - /** reg_core0_mm_hp_axi_pdma_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_axi_pdma_allow:1; - /** reg_core0_mm_hp_flash_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_flash_allow:1; - /** reg_core0_mm_hp_psram_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_psram_allow:1; - /** reg_core0_mm_hp_crypto_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_crypto_allow:1; - /** reg_core0_mm_hp_gmac_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_gmac_allow:1; - /** reg_core0_mm_hp_usb_phy_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_usb_phy_allow:1; - /** reg_core0_mm_hp_pvt_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_pvt_allow:1; - /** reg_core0_mm_hp_csi_host_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_csi_host_allow:1; - /** reg_core0_mm_hp_dsi_host_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_dsi_host_allow:1; - /** reg_core0_mm_hp_isp_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_isp_allow:1; - /** reg_core0_mm_hp_h264_core_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_h264_core_allow:1; - /** reg_core0_mm_hp_rmt_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_rmt_allow:1; - /** reg_core0_mm_hp_bitsrambler_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_bitsrambler_allow:1; - /** reg_core0_mm_hp_axi_icm_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_axi_icm_allow:1; - /** reg_core0_mm_hp_peri_pms_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_peri_pms_allow:1; - /** reg_core0_mm_lp2hp_peri_pms_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_core0_mm_lp2hp_peri_pms_allow:1; - /** reg_core0_mm_dma_pms_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_core0_mm_dma_pms_allow:1; - /** reg_core0_mm_hp_h264_dma2d_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_h264_dma2d_allow:1; + /** coren_mm_hp_usbotg_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP high-speed + * USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_usbotg_allow:1; + /** coren_mm_hp_usbotg11_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP full-speed + * USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_usbotg11_allow:1; + /** coren_mm_hp_usbotg11_wrap_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP full-speed + * USB 2.0 OTG's wrap. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_usbotg11_wrap_allow:1; + /** coren_mm_hp_gdma_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP DW-GDMA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_gdma_allow:1; + /** coren_mm_hp_regdma_allow : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP GDMA (DW + * GDMA). + * 0: Not allowed + * 1: Allow + */ + uint32_t coren_mm_hp_regdma_allow:1; + /** coren_mm_hp_sdmmc_allow : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP SDMMC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_sdmmc_allow:1; + /** coren_mm_hp_ahb_pdma_allow : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access GDMA-AHB. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_ahb_pdma_allow:1; + /** coren_mm_hp_jpeg_allow : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP JPEG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_jpeg_allow:1; + /** coren_mm_hp_ppa_allow : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP PPA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_ppa_allow:1; + /** coren_mm_hp_dma2d_allow : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_dma2d_allow:1; + /** coren_mm_hp_key_manager_allow : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP key manager. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_key_manager_allow:1; + /** coren_mm_hp_axi_pdma_allow : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP GDMA-AXI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_axi_pdma_allow:1; + /** coren_mm_hp_flash_allow : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP flash MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_flash_allow:1; + /** coren_mm_hp_psram_allow : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP PSRAM MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_psram_allow:1; + /** coren_mm_hp_crypto_allow : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP CRYPTO + * (including AES/SHA/RSA/HMAC Accelerators). + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_crypto_allow:1; + /** coren_mm_hp_gmac_allow : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP EMAC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_gmac_allow:1; + /** coren_mm_hp_usb_phy_allow : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP high-speed + * USB 2.0 OTG PHY. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_usb_phy_allow:1; + /** coren_mm_hp_pvt_allow : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP PVT. + * 0: Not allowed + * 1: Allow + */ + uint32_t coren_mm_hp_pvt_allow:1; + /** coren_mm_hp_csi_host_allow : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP MIPI CSI + * host. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_csi_host_allow:1; + /** coren_mm_hp_dsi_host_allow : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP MIPI DSI + * host. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_dsi_host_allow:1; + /** coren_mm_hp_isp_allow : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP ISP (Image + * Signal Processor). + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_isp_allow:1; + /** coren_mm_hp_h264_core_allow : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP H264 + * Encoder. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_h264_core_allow:1; + /** coren_mm_hp_rmt_allow : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP RMT. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_rmt_allow:1; + /** coren_mm_hp_bitsrambler_allow : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP bit + * scrambler. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_bitsrambler_allow:1; + /** coren_mm_hp_axi_icm_allow : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP AXI ICM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_axi_icm_allow:1; + /** coren_mm_hp_peri_pms_allow : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access + * HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_peri_pms_allow:1; + /** coren_mm_lp2hp_peri_pms_allow : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access + * LP2HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_lp2hp_peri_pms_allow:1; + /** coren_mm_dma_pms_allow : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP_DMA_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_dma_pms_allow:1; + /** coren_mm_hp_h264_dma2d_allow : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_h264_dma2d_allow:1; uint32_t reserved_29:3; }; uint32_t val; -} tee_core0_mm_pms_reg1_reg_t; - +} pms_coren_mm_hp_peri_pms_reg1_reg_t; -/** Group: TEE CORE0 MM PMS REG2 REG */ -/** Type of core0_mm_pms_reg2 register - * NA +/** Type of coren_mm_hp_peri_pms_reg2 register + * Permission control register2 for HP CPUn in machine mode */ typedef union { struct { - /** reg_core0_mm_hp_mcpwm0_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_mcpwm0_allow:1; - /** reg_core0_mm_hp_mcpwm1_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_mcpwm1_allow:1; - /** reg_core0_mm_hp_timer_group0_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_timer_group0_allow:1; - /** reg_core0_mm_hp_timer_group1_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_timer_group1_allow:1; - /** reg_core0_mm_hp_i2c0_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_i2c0_allow:1; - /** reg_core0_mm_hp_i2c1_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_i2c1_allow:1; - /** reg_core0_mm_hp_i2s0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_i2s0_allow:1; - /** reg_core0_mm_hp_i2s1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_i2s1_allow:1; - /** reg_core0_mm_hp_i2s2_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_i2s2_allow:1; - /** reg_core0_mm_hp_pcnt_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_pcnt_allow:1; - /** reg_core0_mm_hp_uart0_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_uart0_allow:1; - /** reg_core0_mm_hp_uart1_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_uart1_allow:1; - /** reg_core0_mm_hp_uart2_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_uart2_allow:1; - /** reg_core0_mm_hp_uart3_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_uart3_allow:1; - /** reg_core0_mm_hp_uart4_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_uart4_allow:1; - /** reg_core0_mm_hp_parlio_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_parlio_allow:1; - /** reg_core0_mm_hp_gpspi2_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_gpspi2_allow:1; - /** reg_core0_mm_hp_gpspi3_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_gpspi3_allow:1; - /** reg_core0_mm_hp_usbdevice_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_usbdevice_allow:1; - /** reg_core0_mm_hp_ledc_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_ledc_allow:1; + /** coren_mm_hp_mcpwm0_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP MCPWM0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_mcpwm0_allow:1; + /** coren_mm_hp_mcpwm1_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP MCPWM1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_mcpwm1_allow:1; + /** coren_mm_hp_timer_group0_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP timer + * group0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_timer_group0_allow:1; + /** coren_mm_hp_timer_group1_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP timer group1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_timer_group1_allow:1; + /** coren_mm_hp_i2c0_allow : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP I2C0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_i2c0_allow:1; + /** coren_mm_hp_i2c1_allow : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP I2C1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_i2c1_allow:1; + /** coren_mm_hp_i2s0_allow : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP I2S0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_i2s0_allow:1; + /** coren_mm_hp_i2s1_allow : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP I2S1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_i2s1_allow:1; + /** coren_mm_hp_i2s2_allow : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP I2S2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_i2s2_allow:1; + /** coren_mm_hp_pcnt_allow : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP PCNT. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_pcnt_allow:1; + /** coren_mm_hp_uart0_allow : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP UART0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_uart0_allow:1; + /** coren_mm_hp_uart1_allow : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP UART1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_uart1_allow:1; + /** coren_mm_hp_uart2_allow : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP UART2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_uart2_allow:1; + /** coren_mm_hp_uart3_allow : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP UART3. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_uart3_allow:1; + /** coren_mm_hp_uart4_allow : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP UART4. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_uart4_allow:1; + /** coren_mm_hp_parlio_allow : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP PARLIO. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_parlio_allow:1; + /** coren_mm_hp_gpspi2_allow : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP GP-SPI2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_gpspi2_allow:1; + /** coren_mm_hp_gpspi3_allow : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP GP-SPI3. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_gpspi3_allow:1; + /** coren_mm_hp_usbdevice_allow : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP USB + * Serial/JTAG Controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_usbdevice_allow:1; + /** coren_mm_hp_ledc_allow : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP LEDC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_ledc_allow:1; uint32_t reserved_20:1; - /** reg_core0_mm_hp_etm_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_etm_allow:1; - /** reg_core0_mm_hp_intrmtx_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_intrmtx_allow:1; - /** reg_core0_mm_hp_twai0_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_twai0_allow:1; - /** reg_core0_mm_hp_twai1_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_twai1_allow:1; - /** reg_core0_mm_hp_twai2_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_twai2_allow:1; - /** reg_core0_mm_hp_i3c_mst_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_i3c_mst_allow:1; - /** reg_core0_mm_hp_i3c_slv_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_i3c_slv_allow:1; - /** reg_core0_mm_hp_lcdcam_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_lcdcam_allow:1; + /** coren_mm_hp_etm_allow : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP ETM (Event + * Task Matrix). + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_etm_allow:1; + /** coren_mm_hp_intrmtx_allow : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP interrupt + * matrix. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_intrmtx_allow:1; + /** coren_mm_hp_twai0_allow : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP TWAI0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_twai0_allow:1; + /** coren_mm_hp_twai1_allow : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP TWAI1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_twai1_allow:1; + /** coren_mm_hp_twai2_allow : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP TWAI2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_twai2_allow:1; + /** coren_mm_hp_i3c_mst_allow : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP I3C master + * controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_i3c_mst_allow:1; + /** coren_mm_hp_i3c_slv_allow : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP I3C slave + * controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_i3c_slv_allow:1; + /** coren_mm_hp_lcdcam_allow : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP LCD_CAM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_lcdcam_allow:1; uint32_t reserved_29:1; - /** reg_core0_mm_hp_adc_allow : R/W; bitpos: [30]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_adc_allow:1; - /** reg_core0_mm_hp_uhci_allow : R/W; bitpos: [31]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_uhci_allow:1; + /** coren_mm_hp_adc_allow : R/W; bitpos: [30]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP ADC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_adc_allow:1; + /** coren_mm_hp_uhci_allow : R/W; bitpos: [31]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP UHCI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_uhci_allow:1; }; uint32_t val; -} tee_core0_mm_pms_reg2_reg_t; - +} pms_coren_mm_hp_peri_pms_reg2_reg_t; -/** Group: TEE CORE0 MM PMS REG3 REG */ -/** Type of core0_mm_pms_reg3 register - * NA +/** Type of coren_mm_hp_peri_pms_reg3 register + * Permission control register3 for HP CPUn in machine mode */ typedef union { struct { - /** reg_core0_mm_hp_gpio_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_gpio_allow:1; - /** reg_core0_mm_hp_iomux_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_iomux_allow:1; - /** reg_core0_mm_hp_systimer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_systimer_allow:1; - /** reg_core0_mm_hp_sys_reg_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_sys_reg_allow:1; - /** reg_core0_mm_hp_clkrst_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core0_mm_hp_clkrst_allow:1; + /** coren_mm_hp_gpio_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP GPIO Matrix. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_gpio_allow:1; + /** coren_mm_hp_iomux_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP IO MUX. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_iomux_allow:1; + /** coren_mm_hp_systimer_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP system + * timer. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_systimer_allow:1; + /** coren_mm_hp_sys_reg_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP system + * register. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_sys_reg_allow:1; + /** coren_mm_hp_clkrst_allow : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPUn in machine mode has permission to access HP_SYS_CLKRST. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_mm_hp_clkrst_allow:1; uint32_t reserved_5:27; }; uint32_t val; -} tee_core0_mm_pms_reg3_reg_t; - +} pms_coren_mm_hp_peri_pms_reg3_reg_t; -/** Group: TEE CORE0 UM PMS REG0 REG */ -/** Type of core0_um_pms_reg0 register - * NA +/** Type of coren_um_hp_peri_pms_reg0 register + * Permission control register0 for HP CPUn in user mode */ typedef union { struct { - /** reg_core0_um_psram_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core0_um_psram_allow:1; - /** reg_core0_um_flash_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core0_um_flash_allow:1; - /** reg_core0_um_l2mem_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core0_um_l2mem_allow:1; - /** reg_core0_um_l2rom_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core0_um_l2rom_allow:1; + /** coren_um_psram_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in user mode has permission to access external RAM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_psram_allow:1; + /** coren_um_flash_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in user mode has permission to access external flash + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_flash_allow:1; + /** coren_um_l2mem_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP L2MEM without + * going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_l2mem_allow:1; + /** coren_um_l2rom_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP ROM without + * going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_l2rom_allow:1; uint32_t reserved_4:2; - /** reg_core0_um_trace0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core0_um_trace0_allow:1; - /** reg_core0_um_trace1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core0_um_trace1_allow:1; - /** reg_core0_um_cpu_bus_mon_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core0_um_cpu_bus_mon_allow:1; - /** reg_core0_um_l2mem_mon_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core0_um_l2mem_mon_allow:1; - /** reg_core0_um_tcm_mon_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core0_um_tcm_mon_allow:1; - /** reg_core0_um_cache_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core0_um_cache_allow:1; + /** coren_um_trace0_allow : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPUn in user mode has permission to access TRACE0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_trace0_allow:1; + /** coren_um_trace1_allow : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPUn in user mode has permission to access TRACE1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_trace1_allow:1; + /** coren_um_cpu_bus_mon_allow : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPUn in user mode has permission to access CPU bus monitor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_cpu_bus_mon_allow:1; + /** coren_um_l2mem_mon_allow : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPUn in user mode has permission to access L2MEM monitor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_l2mem_mon_allow:1; + /** coren_um_tcm_mon_allow : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPUn in user mode has permission to access TCM monitor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_tcm_mon_allow:1; + /** coren_um_cache_allow : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPUn in user mode has permission to access cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_cache_allow:1; uint32_t reserved_12:20; }; uint32_t val; -} tee_core0_um_pms_reg0_reg_t; +} pms_coren_um_hp_peri_pms_reg0_reg_t; - -/** Group: TEE CORE0 UM PMS REG1 REG */ -/** Type of core0_um_pms_reg1 register - * NA +/** Type of coren_um_hp_peri_pms_reg1 register + * Permission control register1 for HP CPUn in user mode */ typedef union { struct { - /** reg_core0_um_hp_usbotg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_usbotg_allow:1; - /** reg_core0_um_hp_usbotg11_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_usbotg11_allow:1; - /** reg_core0_um_hp_usbotg11_wrap_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_usbotg11_wrap_allow:1; - /** reg_core0_um_hp_gdma_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_gdma_allow:1; - /** reg_core0_um_hp_regdma_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_regdma_allow:1; - /** reg_core0_um_hp_sdmmc_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_sdmmc_allow:1; - /** reg_core0_um_hp_ahb_pdma_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_ahb_pdma_allow:1; - /** reg_core0_um_hp_jpeg_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_jpeg_allow:1; - /** reg_core0_um_hp_ppa_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_ppa_allow:1; - /** reg_core0_um_hp_dma2d_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_dma2d_allow:1; - /** reg_core0_um_hp_key_manager_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_key_manager_allow:1; - /** reg_core0_um_hp_axi_pdma_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_axi_pdma_allow:1; - /** reg_core0_um_hp_flash_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_flash_allow:1; - /** reg_core0_um_hp_psram_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_psram_allow:1; - /** reg_core0_um_hp_crypto_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_crypto_allow:1; - /** reg_core0_um_hp_gmac_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_gmac_allow:1; - /** reg_core0_um_hp_usb_phy_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_usb_phy_allow:1; - /** reg_core0_um_hp_pvt_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_pvt_allow:1; - /** reg_core0_um_hp_csi_host_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_csi_host_allow:1; - /** reg_core0_um_hp_dsi_host_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_dsi_host_allow:1; - /** reg_core0_um_hp_isp_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_isp_allow:1; - /** reg_core0_um_hp_h264_core_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_h264_core_allow:1; - /** reg_core0_um_hp_rmt_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_rmt_allow:1; - /** reg_core0_um_hp_bitsrambler_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_bitsrambler_allow:1; - /** reg_core0_um_hp_axi_icm_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_axi_icm_allow:1; - /** reg_core0_um_hp_peri_pms_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_peri_pms_allow:1; - /** reg_core0_um_lp2hp_peri_pms_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_core0_um_lp2hp_peri_pms_allow:1; - /** reg_core0_um_dma_pms_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_core0_um_dma_pms_allow:1; - /** reg_core0_um_hp_h264_dma2d_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_h264_dma2d_allow:1; + /** coren_um_hp_usbotg_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP high-speed USB + * 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_usbotg_allow:1; + /** coren_um_hp_usbotg11_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP full-speed USB + * 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_usbotg11_allow:1; + /** coren_um_hp_usbotg11_wrap_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP full-speed USB + * 2.0 OTG's wrap. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_usbotg11_wrap_allow:1; + /** coren_um_hp_gdma_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP DW-GDMA. + * 0: Not allowed + * 1: Allowed + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_gdma_allow:1; + /** coren_um_hp_regdma_allow : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP regdma. + * 0: Not allowed + * 1: Allow + */ + uint32_t coren_um_hp_regdma_allow:1; + /** coren_um_hp_sdmmc_allow : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP SDMMC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_sdmmc_allow:1; + /** coren_um_hp_ahb_pdma_allow : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPUn in user mode has permission to access GDMA-AHB. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_ahb_pdma_allow:1; + /** coren_um_hp_jpeg_allow : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP JPEG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_jpeg_allow:1; + /** coren_um_hp_ppa_allow : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP PPA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_ppa_allow:1; + /** coren_um_hp_dma2d_allow : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_dma2d_allow:1; + /** coren_um_hp_key_manager_allow : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP key manager. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_key_manager_allow:1; + /** coren_um_hp_axi_pdma_allow : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP GDMA-AXI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_axi_pdma_allow:1; + /** coren_um_hp_flash_allow : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP flash MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_flash_allow:1; + /** coren_um_hp_psram_allow : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP PSRAM MSPI + * controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_psram_allow:1; + /** coren_um_hp_crypto_allow : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP CRYPTO. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_crypto_allow:1; + /** coren_um_hp_gmac_allow : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP EMAC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_gmac_allow:1; + /** coren_um_hp_usb_phy_allow : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP high-speed USB + * 2.0 OTG PHY. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_usb_phy_allow:1; + /** coren_um_hp_pvt_allow : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP PVT. + * 0: Not allowed + * 1: Allow + */ + uint32_t coren_um_hp_pvt_allow:1; + /** coren_um_hp_csi_host_allow : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP MIPI CSI host. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_csi_host_allow:1; + /** coren_um_hp_dsi_host_allow : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP MIPI DSI host. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_dsi_host_allow:1; + /** coren_um_hp_isp_allow : R/W; bitpos: [20]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP ISP. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_isp_allow:1; + /** coren_um_hp_h264_core_allow : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP H264 Encoder. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_h264_core_allow:1; + /** coren_um_hp_rmt_allow : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP RMT. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_rmt_allow:1; + /** coren_um_hp_bitsrambler_allow : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP bit scrambler. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_bitsrambler_allow:1; + /** coren_um_hp_axi_icm_allow : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP AXI ICM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_axi_icm_allow:1; + /** coren_um_hp_peri_pms_allow : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_peri_pms_allow:1; + /** coren_um_lp2hp_peri_pms_allow : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPUn in user mode has permission to access + * LP2HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_lp2hp_peri_pms_allow:1; + /** coren_um_dma_pms_allow : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP_DMA_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_dma_pms_allow:1; + /** coren_um_hp_h264_dma2d_allow : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPUn in user mode has permission to access 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_h264_dma2d_allow:1; uint32_t reserved_29:3; }; uint32_t val; -} tee_core0_um_pms_reg1_reg_t; - +} pms_coren_um_hp_peri_pms_reg1_reg_t; -/** Group: TEE CORE0 UM PMS REG2 REG */ -/** Type of core0_um_pms_reg2 register - * NA +/** Type of coren_um_hp_peri_pms_reg2 register + * Permission control register2 for HP CPUn in user mode */ typedef union { struct { - /** reg_core0_um_hp_mcpwm0_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_mcpwm0_allow:1; - /** reg_core0_um_hp_mcpwm1_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_mcpwm1_allow:1; - /** reg_core0_um_hp_timer_group0_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_timer_group0_allow:1; - /** reg_core0_um_hp_timer_group1_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_timer_group1_allow:1; - /** reg_core0_um_hp_i2c0_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_i2c0_allow:1; - /** reg_core0_um_hp_i2c1_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_i2c1_allow:1; - /** reg_core0_um_hp_i2s0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_i2s0_allow:1; - /** reg_core0_um_hp_i2s1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_i2s1_allow:1; - /** reg_core0_um_hp_i2s2_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_i2s2_allow:1; - /** reg_core0_um_hp_pcnt_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_pcnt_allow:1; - /** reg_core0_um_hp_uart0_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_uart0_allow:1; - /** reg_core0_um_hp_uart1_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_uart1_allow:1; - /** reg_core0_um_hp_uart2_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_uart2_allow:1; - /** reg_core0_um_hp_uart3_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_uart3_allow:1; - /** reg_core0_um_hp_uart4_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_uart4_allow:1; - /** reg_core0_um_hp_parlio_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_parlio_allow:1; - /** reg_core0_um_hp_gpspi2_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_gpspi2_allow:1; - /** reg_core0_um_hp_gpspi3_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_gpspi3_allow:1; - /** reg_core0_um_hp_usbdevice_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_usbdevice_allow:1; - /** reg_core0_um_hp_ledc_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_ledc_allow:1; + /** coren_um_hp_mcpwm0_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP MCPWM0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_mcpwm0_allow:1; + /** coren_um_hp_mcpwm1_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP MCPWM1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_mcpwm1_allow:1; + /** coren_um_hp_timer_group0_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP timer group0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_timer_group0_allow:1; + /** coren_um_hp_timer_group1_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP timer group1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_timer_group1_allow:1; + /** coren_um_hp_i2c0_allow : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP I2C0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_i2c0_allow:1; + /** coren_um_hp_i2c1_allow : R/W; bitpos: [5]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP I2C1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_i2c1_allow:1; + /** coren_um_hp_i2s0_allow : R/W; bitpos: [6]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP I2S0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_i2s0_allow:1; + /** coren_um_hp_i2s1_allow : R/W; bitpos: [7]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP I2S1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_i2s1_allow:1; + /** coren_um_hp_i2s2_allow : R/W; bitpos: [8]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP I2S2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_i2s2_allow:1; + /** coren_um_hp_pcnt_allow : R/W; bitpos: [9]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP PCNT. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_pcnt_allow:1; + /** coren_um_hp_uart0_allow : R/W; bitpos: [10]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP UART0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_uart0_allow:1; + /** coren_um_hp_uart1_allow : R/W; bitpos: [11]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP UART1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_uart1_allow:1; + /** coren_um_hp_uart2_allow : R/W; bitpos: [12]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP UART2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_uart2_allow:1; + /** coren_um_hp_uart3_allow : R/W; bitpos: [13]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP UART3. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_uart3_allow:1; + /** coren_um_hp_uart4_allow : R/W; bitpos: [14]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP UART4. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_uart4_allow:1; + /** coren_um_hp_parlio_allow : R/W; bitpos: [15]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP PARLIO. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_parlio_allow:1; + /** coren_um_hp_gpspi2_allow : R/W; bitpos: [16]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP GP-SPI2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_gpspi2_allow:1; + /** coren_um_hp_gpspi3_allow : R/W; bitpos: [17]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP GP-SPI3. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_gpspi3_allow:1; + /** coren_um_hp_usbdevice_allow : R/W; bitpos: [18]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP USB/Serial JTAG + * Controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_usbdevice_allow:1; + /** coren_um_hp_ledc_allow : R/W; bitpos: [19]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP LEDC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_ledc_allow:1; uint32_t reserved_20:1; - /** reg_core0_um_hp_etm_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_etm_allow:1; - /** reg_core0_um_hp_intrmtx_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_intrmtx_allow:1; - /** reg_core0_um_hp_twai0_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_twai0_allow:1; - /** reg_core0_um_hp_twai1_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_twai1_allow:1; - /** reg_core0_um_hp_twai2_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_twai2_allow:1; - /** reg_core0_um_hp_i3c_mst_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_i3c_mst_allow:1; - /** reg_core0_um_hp_i3c_slv_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_i3c_slv_allow:1; - /** reg_core0_um_hp_lcdcam_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_lcdcam_allow:1; + /** coren_um_hp_etm_allow : R/W; bitpos: [21]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP ETM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_etm_allow:1; + /** coren_um_hp_intrmtx_allow : R/W; bitpos: [22]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP interrupt + * matrix. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_intrmtx_allow:1; + /** coren_um_hp_twai0_allow : R/W; bitpos: [23]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP TWAI0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_twai0_allow:1; + /** coren_um_hp_twai1_allow : R/W; bitpos: [24]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP TWAI1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_twai1_allow:1; + /** coren_um_hp_twai2_allow : R/W; bitpos: [25]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP TWAI2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_twai2_allow:1; + /** coren_um_hp_i3c_mst_allow : R/W; bitpos: [26]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP I3C master + * controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_i3c_mst_allow:1; + /** coren_um_hp_i3c_slv_allow : R/W; bitpos: [27]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP I3C slave + * controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_i3c_slv_allow:1; + /** coren_um_hp_lcdcam_allow : R/W; bitpos: [28]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP LCD_CAM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_lcdcam_allow:1; uint32_t reserved_29:1; - /** reg_core0_um_hp_adc_allow : R/W; bitpos: [30]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_adc_allow:1; - /** reg_core0_um_hp_uhci_allow : R/W; bitpos: [31]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_uhci_allow:1; - }; - uint32_t val; -} tee_core0_um_pms_reg2_reg_t; - - -/** Group: TEE CORE0 UM PMS REG3 REG */ -/** Type of core0_um_pms_reg3 register - * NA - */ -typedef union { - struct { - /** reg_core0_um_hp_gpio_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_gpio_allow:1; - /** reg_core0_um_hp_iomux_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_iomux_allow:1; - /** reg_core0_um_hp_systimer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_systimer_allow:1; - /** reg_core0_um_hp_sys_reg_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_sys_reg_allow:1; - /** reg_core0_um_hp_clkrst_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core0_um_hp_clkrst_allow:1; - uint32_t reserved_5:27; - }; - uint32_t val; -} tee_core0_um_pms_reg3_reg_t; - - -/** Group: TEE CORE1 MM PMS REG0 REG */ -/** Type of core1_mm_pms_reg0 register - * NA - */ -typedef union { - struct { - /** reg_core1_mm_psram_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core1_mm_psram_allow:1; - /** reg_core1_mm_flash_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core1_mm_flash_allow:1; - /** reg_core1_mm_l2mem_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core1_mm_l2mem_allow:1; - /** reg_core1_mm_l2rom_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core1_mm_l2rom_allow:1; - uint32_t reserved_4:2; - /** reg_core1_mm_trace0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core1_mm_trace0_allow:1; - /** reg_core1_mm_trace1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core1_mm_trace1_allow:1; - /** reg_core1_mm_cpu_bus_mon_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core1_mm_cpu_bus_mon_allow:1; - /** reg_core1_mm_l2mem_mon_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core1_mm_l2mem_mon_allow:1; - /** reg_core1_mm_tcm_mon_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core1_mm_tcm_mon_allow:1; - /** reg_core1_mm_cache_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core1_mm_cache_allow:1; - uint32_t reserved_12:20; + /** coren_um_hp_adc_allow : R/W; bitpos: [30]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP ADC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_adc_allow:1; + /** coren_um_hp_uhci_allow : R/W; bitpos: [31]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP UHCI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_uhci_allow:1; }; uint32_t val; -} tee_core1_mm_pms_reg0_reg_t; +} pms_coren_um_hp_peri_pms_reg2_reg_t; - -/** Group: TEE CORE1 MM PMS REG1 REG */ -/** Type of core1_mm_pms_reg1 register - * NA +/** Type of coren_um_hp_peri_pms_reg3 register + * Permission control register3 for HP CPUn in user mode */ typedef union { struct { - /** reg_core1_mm_hp_usbotg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_usbotg_allow:1; - /** reg_core1_mm_hp_usbotg11_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_usbotg11_allow:1; - /** reg_core1_mm_hp_usbotg11_wrap_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_usbotg11_wrap_allow:1; - /** reg_core1_mm_hp_gdma_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_gdma_allow:1; - /** reg_core1_mm_hp_regdma_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_regdma_allow:1; - /** reg_core1_mm_hp_sdmmc_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_sdmmc_allow:1; - /** reg_core1_mm_hp_ahb_pdma_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_ahb_pdma_allow:1; - /** reg_core1_mm_hp_jpeg_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_jpeg_allow:1; - /** reg_core1_mm_hp_ppa_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_ppa_allow:1; - /** reg_core1_mm_hp_dma2d_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_dma2d_allow:1; - /** reg_core1_mm_hp_key_manager_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_key_manager_allow:1; - /** reg_core1_mm_hp_axi_pdma_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_axi_pdma_allow:1; - /** reg_core1_mm_hp_flash_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_flash_allow:1; - /** reg_core1_mm_hp_psram_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_psram_allow:1; - /** reg_core1_mm_hp_crypto_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_crypto_allow:1; - /** reg_core1_mm_hp_gmac_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_gmac_allow:1; - /** reg_core1_mm_hp_usb_phy_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_usb_phy_allow:1; - /** reg_core1_mm_hp_pvt_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_pvt_allow:1; - /** reg_core1_mm_hp_csi_host_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_csi_host_allow:1; - /** reg_core1_mm_hp_dsi_host_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_dsi_host_allow:1; - /** reg_core1_mm_hp_isp_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_isp_allow:1; - /** reg_core1_mm_hp_h264_core_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_h264_core_allow:1; - /** reg_core1_mm_hp_rmt_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_rmt_allow:1; - /** reg_core1_mm_hp_bitsrambler_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_bitsrambler_allow:1; - /** reg_core1_mm_hp_axi_icm_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_axi_icm_allow:1; - /** reg_core1_mm_hp_peri_pms_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_peri_pms_allow:1; - /** reg_core1_mm_lp2hp_peri_pms_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_core1_mm_lp2hp_peri_pms_allow:1; - /** reg_core1_mm_dma_pms_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_core1_mm_dma_pms_allow:1; - /** reg_core1_mm_hp_h264_dma2d_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_h264_dma2d_allow:1; - uint32_t reserved_29:3; - }; - uint32_t val; -} tee_core1_mm_pms_reg1_reg_t; - - -/** Group: TEE CORE1 MM PMS REG2 REG */ -/** Type of core1_mm_pms_reg2 register - * NA - */ -typedef union { - struct { - /** reg_core1_mm_hp_mcpwm0_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_mcpwm0_allow:1; - /** reg_core1_mm_hp_mcpwm1_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_mcpwm1_allow:1; - /** reg_core1_mm_hp_timer_group0_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_timer_group0_allow:1; - /** reg_core1_mm_hp_timer_group1_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_timer_group1_allow:1; - /** reg_core1_mm_hp_i2c0_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_i2c0_allow:1; - /** reg_core1_mm_hp_i2c1_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_i2c1_allow:1; - /** reg_core1_mm_hp_i2s0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_i2s0_allow:1; - /** reg_core1_mm_hp_i2s1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_i2s1_allow:1; - /** reg_core1_mm_hp_i2s2_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_i2s2_allow:1; - /** reg_core1_mm_hp_pcnt_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_pcnt_allow:1; - /** reg_core1_mm_hp_uart0_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_uart0_allow:1; - /** reg_core1_mm_hp_uart1_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_uart1_allow:1; - /** reg_core1_mm_hp_uart2_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_uart2_allow:1; - /** reg_core1_mm_hp_uart3_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_uart3_allow:1; - /** reg_core1_mm_hp_uart4_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_uart4_allow:1; - /** reg_core1_mm_hp_parlio_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_parlio_allow:1; - /** reg_core1_mm_hp_gpspi2_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_gpspi2_allow:1; - /** reg_core1_mm_hp_gpspi3_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_gpspi3_allow:1; - /** reg_core1_mm_hp_usbdevice_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_usbdevice_allow:1; - /** reg_core1_mm_hp_ledc_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_ledc_allow:1; - uint32_t reserved_20:1; - /** reg_core1_mm_hp_etm_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_etm_allow:1; - /** reg_core1_mm_hp_intrmtx_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_intrmtx_allow:1; - /** reg_core1_mm_hp_twai0_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_twai0_allow:1; - /** reg_core1_mm_hp_twai1_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_twai1_allow:1; - /** reg_core1_mm_hp_twai2_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_twai2_allow:1; - /** reg_core1_mm_hp_i3c_mst_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_i3c_mst_allow:1; - /** reg_core1_mm_hp_i3c_slv_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_i3c_slv_allow:1; - /** reg_core1_mm_hp_lcdcam_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_lcdcam_allow:1; - uint32_t reserved_29:1; - /** reg_core1_mm_hp_adc_allow : R/W; bitpos: [30]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_adc_allow:1; - /** reg_core1_mm_hp_uhci_allow : R/W; bitpos: [31]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_uhci_allow:1; - }; - uint32_t val; -} tee_core1_mm_pms_reg2_reg_t; - - -/** Group: TEE CORE1 MM PMS REG3 REG */ -/** Type of core1_mm_pms_reg3 register - * NA - */ -typedef union { - struct { - /** reg_core1_mm_hp_gpio_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_gpio_allow:1; - /** reg_core1_mm_hp_iomux_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_iomux_allow:1; - /** reg_core1_mm_hp_systimer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_systimer_allow:1; - /** reg_core1_mm_hp_sys_reg_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_sys_reg_allow:1; - /** reg_core1_mm_hp_clkrst_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core1_mm_hp_clkrst_allow:1; - uint32_t reserved_5:27; - }; - uint32_t val; -} tee_core1_mm_pms_reg3_reg_t; - - -/** Group: TEE CORE1 UM PMS REG0 REG */ -/** Type of core1_um_pms_reg0 register - * NA - */ -typedef union { - struct { - /** reg_core1_um_psram_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core1_um_psram_allow:1; - /** reg_core1_um_flash_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core1_um_flash_allow:1; - /** reg_core1_um_l2mem_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core1_um_l2mem_allow:1; - /** reg_core1_um_l2rom_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core1_um_l2rom_allow:1; - uint32_t reserved_4:2; - /** reg_core1_um_trace0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core1_um_trace0_allow:1; - /** reg_core1_um_trace1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core1_um_trace1_allow:1; - /** reg_core1_um_cpu_bus_mon_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core1_um_cpu_bus_mon_allow:1; - /** reg_core1_um_l2mem_mon_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core1_um_l2mem_mon_allow:1; - /** reg_core1_um_tcm_mon_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core1_um_tcm_mon_allow:1; - /** reg_core1_um_cache_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core1_um_cache_allow:1; - uint32_t reserved_12:20; - }; - uint32_t val; -} tee_core1_um_pms_reg0_reg_t; - - -/** Group: TEE CORE1 UM PMS REG1 REG */ -/** Type of core1_um_pms_reg1 register - * NA - */ -typedef union { - struct { - /** reg_core1_um_hp_usbotg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_usbotg_allow:1; - /** reg_core1_um_hp_usbotg11_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_usbotg11_allow:1; - /** reg_core1_um_hp_usbotg11_wrap_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_usbotg11_wrap_allow:1; - /** reg_core1_um_hp_gdma_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_gdma_allow:1; - /** reg_core1_um_hp_regdma_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_regdma_allow:1; - /** reg_core1_um_hp_sdmmc_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_sdmmc_allow:1; - /** reg_core1_um_hp_ahb_pdma_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_ahb_pdma_allow:1; - /** reg_core1_um_hp_jpeg_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_jpeg_allow:1; - /** reg_core1_um_hp_ppa_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_ppa_allow:1; - /** reg_core1_um_hp_dma2d_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_dma2d_allow:1; - /** reg_core1_um_hp_key_manager_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_key_manager_allow:1; - /** reg_core1_um_hp_axi_pdma_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_axi_pdma_allow:1; - /** reg_core1_um_hp_flash_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_flash_allow:1; - /** reg_core1_um_hp_psram_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_psram_allow:1; - /** reg_core1_um_hp_crypto_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_crypto_allow:1; - /** reg_core1_um_hp_gmac_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_gmac_allow:1; - /** reg_core1_um_hp_usb_phy_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_usb_phy_allow:1; - /** reg_core1_um_hp_pvt_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_pvt_allow:1; - /** reg_core1_um_hp_csi_host_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_csi_host_allow:1; - /** reg_core1_um_hp_dsi_host_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_dsi_host_allow:1; - /** reg_core1_um_hp_isp_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_isp_allow:1; - /** reg_core1_um_hp_h264_core_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_h264_core_allow:1; - /** reg_core1_um_hp_rmt_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_rmt_allow:1; - /** reg_core1_um_hp_bitsrambler_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_bitsrambler_allow:1; - /** reg_core1_um_hp_axi_icm_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_axi_icm_allow:1; - /** reg_core1_um_hp_peri_pms_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_peri_pms_allow:1; - /** reg_core1_um_lp2hp_peri_pms_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_core1_um_lp2hp_peri_pms_allow:1; - /** reg_core1_um_dma_pms_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_core1_um_dma_pms_allow:1; - /** reg_core1_um_hp_h264_dma2d_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_h264_dma2d_allow:1; - uint32_t reserved_29:3; - }; - uint32_t val; -} tee_core1_um_pms_reg1_reg_t; - - -/** Group: TEE CORE1 UM PMS REG2 REG */ -/** Type of core1_um_pms_reg2 register - * NA - */ -typedef union { - struct { - /** reg_core1_um_hp_mcpwm0_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_mcpwm0_allow:1; - /** reg_core1_um_hp_mcpwm1_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_mcpwm1_allow:1; - /** reg_core1_um_hp_timer_group0_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_timer_group0_allow:1; - /** reg_core1_um_hp_timer_group1_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_timer_group1_allow:1; - /** reg_core1_um_hp_i2c0_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_i2c0_allow:1; - /** reg_core1_um_hp_i2c1_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_i2c1_allow:1; - /** reg_core1_um_hp_i2s0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_i2s0_allow:1; - /** reg_core1_um_hp_i2s1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_i2s1_allow:1; - /** reg_core1_um_hp_i2s2_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_i2s2_allow:1; - /** reg_core1_um_hp_pcnt_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_pcnt_allow:1; - /** reg_core1_um_hp_uart0_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_uart0_allow:1; - /** reg_core1_um_hp_uart1_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_uart1_allow:1; - /** reg_core1_um_hp_uart2_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_uart2_allow:1; - /** reg_core1_um_hp_uart3_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_uart3_allow:1; - /** reg_core1_um_hp_uart4_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_uart4_allow:1; - /** reg_core1_um_hp_parlio_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_parlio_allow:1; - /** reg_core1_um_hp_gpspi2_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_gpspi2_allow:1; - /** reg_core1_um_hp_gpspi3_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_gpspi3_allow:1; - /** reg_core1_um_hp_usbdevice_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_usbdevice_allow:1; - /** reg_core1_um_hp_ledc_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_ledc_allow:1; - uint32_t reserved_20:1; - /** reg_core1_um_hp_etm_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_etm_allow:1; - /** reg_core1_um_hp_intrmtx_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_intrmtx_allow:1; - /** reg_core1_um_hp_twai0_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_twai0_allow:1; - /** reg_core1_um_hp_twai1_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_twai1_allow:1; - /** reg_core1_um_hp_twai2_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_twai2_allow:1; - /** reg_core1_um_hp_i3c_mst_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_i3c_mst_allow:1; - /** reg_core1_um_hp_i3c_slv_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_i3c_slv_allow:1; - /** reg_core1_um_hp_lcdcam_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_lcdcam_allow:1; - uint32_t reserved_29:1; - /** reg_core1_um_hp_adc_allow : R/W; bitpos: [30]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_adc_allow:1; - /** reg_core1_um_hp_uhci_allow : R/W; bitpos: [31]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_uhci_allow:1; - }; - uint32_t val; -} tee_core1_um_pms_reg2_reg_t; - - -/** Group: TEE CORE1 UM PMS REG3 REG */ -/** Type of core1_um_pms_reg3 register - * NA - */ -typedef union { - struct { - /** reg_core1_um_hp_gpio_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_gpio_allow:1; - /** reg_core1_um_hp_iomux_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_iomux_allow:1; - /** reg_core1_um_hp_systimer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_systimer_allow:1; - /** reg_core1_um_hp_sys_reg_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_sys_reg_allow:1; - /** reg_core1_um_hp_clkrst_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_core1_um_hp_clkrst_allow:1; + /** coren_um_hp_gpio_allow : R/W; bitpos: [0]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP GPIO Matrix. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_gpio_allow:1; + /** coren_um_hp_iomux_allow : R/W; bitpos: [1]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP IO MUX. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_iomux_allow:1; + /** coren_um_hp_systimer_allow : R/W; bitpos: [2]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP system timer. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_systimer_allow:1; + /** coren_um_hp_sys_reg_allow : R/W; bitpos: [3]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP system + * register. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_sys_reg_allow:1; + /** coren_um_hp_clkrst_allow : R/W; bitpos: [4]; default: 1; + * Configures whether HP CPUn in user mode has permission to access HP_SYS_CLKRST. + * 0: Not allowed + * 1: Allowed + */ + uint32_t coren_um_hp_clkrst_allow:1; uint32_t reserved_5:27; }; uint32_t val; -} tee_core1_um_pms_reg3_reg_t; +} pms_coren_um_hp_peri_pms_reg3_reg_t; -/** Group: TEE REGDMA PERI PMS REG */ +/** Group: TEE Peripheral Permission Control Registers */ /** Type of regdma_peri_pms register - * NA + * Permission register for REGDMA */ typedef union { struct { - /** reg_regdma_peri_allow : R/W; bitpos: [0]; default: 1; - * NA + /** regdma_peri_allow : R/W; bitpos: [0]; default: 1; + * Configures whether REGDMA has permission to access all HP peripheral (including CPU + * peripherals). + * 0: Not allowed + * 1: Allow */ - uint32_t reg_regdma_peri_allow:1; + uint32_t regdma_peri_allow:1; uint32_t reserved_1:31; }; uint32_t val; -} tee_regdma_peri_pms_reg_t; +} pms_regdma_peri_pms_reg_t; typedef struct { - volatile tee_pms_date_reg_t pms_date; - volatile tee_pms_clk_en_reg_t pms_clk_en; - volatile tee_core0_mm_pms_reg0_reg_t core0_mm_pms_reg0; - volatile tee_core0_mm_pms_reg1_reg_t core0_mm_pms_reg1; - volatile tee_core0_mm_pms_reg2_reg_t core0_mm_pms_reg2; - volatile tee_core0_mm_pms_reg3_reg_t core0_mm_pms_reg3; - volatile tee_core0_um_pms_reg0_reg_t core0_um_pms_reg0; - volatile tee_core0_um_pms_reg1_reg_t core0_um_pms_reg1; - volatile tee_core0_um_pms_reg2_reg_t core0_um_pms_reg2; - volatile tee_core0_um_pms_reg3_reg_t core0_um_pms_reg3; - volatile tee_core1_mm_pms_reg0_reg_t core1_mm_pms_reg0; - volatile tee_core1_mm_pms_reg1_reg_t core1_mm_pms_reg1; - volatile tee_core1_mm_pms_reg2_reg_t core1_mm_pms_reg2; - volatile tee_core1_mm_pms_reg3_reg_t core1_mm_pms_reg3; - volatile tee_core1_um_pms_reg0_reg_t core1_um_pms_reg0; - volatile tee_core1_um_pms_reg1_reg_t core1_um_pms_reg1; - volatile tee_core1_um_pms_reg2_reg_t core1_um_pms_reg2; - volatile tee_core1_um_pms_reg3_reg_t core1_um_pms_reg3; - volatile tee_regdma_peri_pms_reg_t regdma_peri_pms; -} tee_dev_t; + volatile pms_hp_peri_pms_date_reg_t hp_peri_pms_date; + volatile pms_hp_peri_pms_clk_en_reg_t hp_peri_pms_clk_en; + volatile pms_coren_mm_hp_peri_pms_reg0_reg_t core0_mm_hp_peri_pms_reg0; + volatile pms_coren_mm_hp_peri_pms_reg1_reg_t core0_mm_hp_peri_pms_reg1; + volatile pms_coren_mm_hp_peri_pms_reg2_reg_t core0_mm_hp_peri_pms_reg2; + volatile pms_coren_mm_hp_peri_pms_reg3_reg_t core0_mm_hp_peri_pms_reg3; + volatile pms_coren_um_hp_peri_pms_reg0_reg_t core0_um_hp_peri_pms_reg0; + volatile pms_coren_um_hp_peri_pms_reg1_reg_t core0_um_hp_peri_pms_reg1; + volatile pms_coren_um_hp_peri_pms_reg2_reg_t core0_um_hp_peri_pms_reg2; + volatile pms_coren_um_hp_peri_pms_reg3_reg_t core0_um_hp_peri_pms_reg3; + volatile pms_coren_mm_hp_peri_pms_reg0_reg_t core1_mm_hp_peri_pms_reg0; + volatile pms_coren_mm_hp_peri_pms_reg1_reg_t core1_mm_hp_peri_pms_reg1; + volatile pms_coren_mm_hp_peri_pms_reg2_reg_t core1_mm_hp_peri_pms_reg2; + volatile pms_coren_mm_hp_peri_pms_reg3_reg_t core1_mm_hp_peri_pms_reg3; + volatile pms_coren_um_hp_peri_pms_reg0_reg_t core1_um_hp_peri_pms_reg0; + volatile pms_coren_um_hp_peri_pms_reg1_reg_t core1_um_hp_peri_pms_reg1; + volatile pms_coren_um_hp_peri_pms_reg2_reg_t core1_um_hp_peri_pms_reg2; + volatile pms_coren_um_hp_peri_pms_reg3_reg_t core1_um_hp_peri_pms_reg3; + volatile pms_regdma_peri_pms_reg_t regdma_peri_pms; +} hp_peri_pms_dev_t; +extern hp_peri_pms_dev_t HP_PERI_PMS; #ifndef __cplusplus -_Static_assert(sizeof(tee_dev_t) == 0x4c, "Invalid size of tee_dev_t structure"); +_Static_assert(sizeof(hp_peri_pms_dev_t) == 0x4c, "Invalid size of hp_peri_pms_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/icm_sys_qos_reg.h b/components/soc/esp32p4/include/soc/icm_sys_qos_reg.h index 9b428ae86058..09bf4eb269f4 100644 --- a/components/soc/esp32p4/include/soc/icm_sys_qos_reg.h +++ b/components/soc/esp32p4/include/soc/icm_sys_qos_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ extern "C" { /** ICM_VERID_FILEDS_REG register * NA */ -#define ICM_VERID_FILEDS_REG (DR_REG_ICM_BASE + 0x0) +#define ICM_VERID_FILEDS_REG (DR_REG_AXI_ICM_QOS_BASE + 0x0) /** ICM_REG_VERID : RO; bitpos: [31:0]; default: 875574314; * NA */ @@ -26,7 +26,7 @@ extern "C" { /** ICM_HW_CFG_REG_REG register * NA */ -#define ICM_HW_CFG_REG_REG (DR_REG_ICM_BASE + 0x4) +#define ICM_HW_CFG_REG_REG (DR_REG_AXI_ICM_QOS_BASE + 0x4) /** ICM_REG_AXI_HWCFG_QOS_SUPPORT : RO; bitpos: [0]; default: 1; * NA */ @@ -108,7 +108,7 @@ extern "C" { /** ICM_CMD_REG register * NA */ -#define ICM_CMD_REG (DR_REG_ICM_BASE + 0x8) +#define ICM_CMD_REG (DR_REG_AXI_ICM_QOS_BASE + 0x8) /** ICM_REG_AXI_CMD : R/W; bitpos: [2:0]; default: 0; * NA */ @@ -162,7 +162,7 @@ extern "C" { /** ICM_DATA_REG register * NA */ -#define ICM_DATA_REG (DR_REG_ICM_BASE + 0xc) +#define ICM_DATA_REG (DR_REG_AXI_ICM_QOS_BASE + 0xc) /** ICM_REG_DATA : R/W; bitpos: [31:0]; default: 0; * NA */ diff --git a/components/soc/esp32p4/include/soc/icm_sys_qos_struct.h b/components/soc/esp32p4/include/soc/icm_sys_qos_struct.h index dbfb2098c7f9..0752139bae1d 100644 --- a/components/soc/esp32p4/include/soc/icm_sys_qos_struct.h +++ b/components/soc/esp32p4/include/soc/icm_sys_qos_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,7 +10,7 @@ extern "C" { #endif -/** Group: ICM AXI VERID FILEDS REG */ +/** Group: ICM AXI VERID FIELDS REG */ /** Type of verid_fileds register * NA */ @@ -144,11 +144,13 @@ typedef struct { volatile icm_hw_cfg_reg_reg_t hw_cfg_reg; volatile icm_cmd_reg_t cmd; volatile icm_data_reg_t data; -} icm_dev_t; +} axi_icm_qos_dev_t; + +extern axi_icm_qos_dev_t AXI_ICM_QOS; #ifndef __cplusplus -_Static_assert(sizeof(icm_dev_t) == 0x10, "Invalid size of icm_dev_t structure"); +_Static_assert(sizeof(axi_icm_qos_dev_t) == 0x10, "Invalid size of axi_icm_qos_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/icm_sys_reg.h b/components/soc/esp32p4/include/soc/icm_sys_reg.h index 8a06b1f0febf..f347868df905 100644 --- a/components/soc/esp32p4/include/soc/icm_sys_reg.h +++ b/components/soc/esp32p4/include/soc/icm_sys_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ extern "C" { /** ICM_VER_DATE_REG register * NA */ -#define ICM_VER_DATE_REG (DR_REG_ICM_BASE + 0x0) +#define ICM_VER_DATE_REG (DR_REG_AXI_ICM_BASE + 0x0) /** ICM_REG_VER_DATE : R/W; bitpos: [31:0]; default: 539165204; * NA */ @@ -26,7 +26,7 @@ extern "C" { /** ICM_CLK_EN_REG register * NA */ -#define ICM_CLK_EN_REG (DR_REG_ICM_BASE + 0x4) +#define ICM_CLK_EN_REG (DR_REG_AXI_ICM_BASE + 0x4) /** ICM_REG_CLK_EN : R/W; bitpos: [0]; default: 0; * NA */ @@ -38,7 +38,7 @@ extern "C" { /** ICM_DLOCK_STATUS_REG register * NA */ -#define ICM_DLOCK_STATUS_REG (DR_REG_ICM_BASE + 0x8) +#define ICM_DLOCK_STATUS_REG (DR_REG_AXI_ICM_BASE + 0x8) /** ICM_REG_DLOCK_MST : RO; bitpos: [3:0]; default: 0; * Lowest numbered deadlocked master */ @@ -71,7 +71,7 @@ extern "C" { /** ICM_INT_RAW_REG register * NA */ -#define ICM_INT_RAW_REG (DR_REG_ICM_BASE + 0xc) +#define ICM_INT_RAW_REG (DR_REG_AXI_ICM_BASE + 0xc) /** ICM_REG_DLOCK_INT_RAW : R/WTC/SS; bitpos: [0]; default: 0; * NA */ @@ -97,7 +97,7 @@ extern "C" { /** ICM_INT_ST_REG register * NA */ -#define ICM_INT_ST_REG (DR_REG_ICM_BASE + 0x10) +#define ICM_INT_ST_REG (DR_REG_AXI_ICM_BASE + 0x10) /** ICM_REG_DLOCK_INT_ST : RO; bitpos: [0]; default: 0; * NA */ @@ -123,7 +123,7 @@ extern "C" { /** ICM_INT_ENA_REG register * NA */ -#define ICM_INT_ENA_REG (DR_REG_ICM_BASE + 0x14) +#define ICM_INT_ENA_REG (DR_REG_AXI_ICM_BASE + 0x14) /** ICM_REG_DLOCK_INT_ENA : R/W; bitpos: [0]; default: 1; * NA */ @@ -149,7 +149,7 @@ extern "C" { /** ICM_INT_CLR_REG register * NA */ -#define ICM_INT_CLR_REG (DR_REG_ICM_BASE + 0x18) +#define ICM_INT_CLR_REG (DR_REG_AXI_ICM_BASE + 0x18) /** ICM_REG_DLOCK_INT_CLR : WT; bitpos: [0]; default: 0; * NA */ @@ -175,7 +175,7 @@ extern "C" { /** ICM_MST_ARB_PRIORITY_REG0_REG register * NA */ -#define ICM_MST_ARB_PRIORITY_REG0_REG (DR_REG_ICM_BASE + 0x1c) +#define ICM_MST_ARB_PRIORITY_REG0_REG (DR_REG_AXI_ICM_BASE + 0x1c) /** ICM_REG_CPU_PRIORITY : R/W; bitpos: [3:0]; default: 0; * CPU arbitration priority for command channels between masters connected to sys_icm */ @@ -241,7 +241,7 @@ extern "C" { /** ICM_SLV_ARB_PRIORITY_REG register * NA */ -#define ICM_SLV_ARB_PRIORITY_REG (DR_REG_ICM_BASE + 0x24) +#define ICM_SLV_ARB_PRIORITY_REG (DR_REG_AXI_ICM_BASE + 0x24) /** ICM_REG_L2MEM_PRIORITY : R/W; bitpos: [5:3]; default: 0; * L2MEM arbitration priority for response channels between slaves connected to sys_icm */ @@ -285,7 +285,7 @@ extern "C" { /** ICM_MST_ARQOS_REG0_REG register * NA */ -#define ICM_MST_ARQOS_REG0_REG (DR_REG_ICM_BASE + 0x28) +#define ICM_MST_ARQOS_REG0_REG (DR_REG_AXI_ICM_BASE + 0x28) /** ICM_REG_CPU_ARQOS : R/W; bitpos: [3:0]; default: 0; * NA */ @@ -346,7 +346,7 @@ extern "C" { /** ICM_MST_AWQOS_REG0_REG register * NA */ -#define ICM_MST_AWQOS_REG0_REG (DR_REG_ICM_BASE + 0x30) +#define ICM_MST_AWQOS_REG0_REG (DR_REG_AXI_ICM_BASE + 0x30) /** ICM_REG_CPU_AWQOS : R/W; bitpos: [3:0]; default: 0; * NA */ @@ -407,7 +407,7 @@ extern "C" { /** ICM_SYS_ADDRHOLE_ADDR_REG register * icm sys addr hole address registers */ -#define ICM_SYS_ADDRHOLE_ADDR_REG (DR_REG_ICM_BASE + 0x38) +#define ICM_SYS_ADDRHOLE_ADDR_REG (DR_REG_AXI_ICM_BASE + 0x38) /** ICM_REG_ICM_SYS_ADDRHOLE_ADDR : RO; bitpos: [31:0]; default: 0; * NA */ @@ -419,9 +419,9 @@ extern "C" { /** ICM_SYS_ADDRHOLE_INFO_REG register * NA */ -#define ICM_SYS_ADDRHOLE_INFO_REG (DR_REG_ICM_BASE + 0x3c) +#define ICM_SYS_ADDRHOLE_INFO_REG (DR_REG_AXI_ICM_BASE + 0x3c) /** ICM_REG_ICM_SYS_ADDRHOLE_ID : RO; bitpos: [7:0]; default: 0; - * master id = 4-bit CID + 4-bit UID(refer to related IP) . CID is used to verfiy + * master id = 4-bit CID + 4-bit UID(refer to related IP) . CID is used to verify * master in icm. CID: 4'h1: cache, 4'h5 gdma mst1, 4'h6: gdma mst2, 4'h8: axi pdma, * 4'ha: dma2d, 4'hb: h264 mst1, 4'hc: h264 mst2. */ @@ -448,7 +448,7 @@ extern "C" { /** ICM_CPU_ADDRHOLE_ADDR_REG register * icm cpu addr hole address registers */ -#define ICM_CPU_ADDRHOLE_ADDR_REG (DR_REG_ICM_BASE + 0x40) +#define ICM_CPU_ADDRHOLE_ADDR_REG (DR_REG_AXI_ICM_BASE + 0x40) /** ICM_REG_ICM_CPU_ADDRHOLE_ADDR : RO; bitpos: [31:0]; default: 0; * It is illegall access address if reg_icm_cpu_addrhole_secure is 1. Otherwise, it * the address without permission to access. @@ -461,7 +461,7 @@ extern "C" { /** ICM_CPU_ADDRHOLE_INFO_REG register * NA */ -#define ICM_CPU_ADDRHOLE_INFO_REG (DR_REG_ICM_BASE + 0x44) +#define ICM_CPU_ADDRHOLE_INFO_REG (DR_REG_AXI_ICM_BASE + 0x44) /** ICM_REG_ICM_CPU_ADDRHOLE_ID : RO; bitpos: [4:0]; default: 0; * master id: 5'h0: hp core0, 5'h1:hp core1, 5'h2:lp core, 5'h3:usb otg11, 5'h4: * regdma, 5'h5: gmac, 5'h5 sdmmc, 5'h7: usbotg20, 5'h8: trace0, 5'h9: trace1, 5'ha @@ -489,7 +489,7 @@ extern "C" { /** ICM_DLOCK_TIMEOUT_REG register * NA */ -#define ICM_DLOCK_TIMEOUT_REG (DR_REG_ICM_BASE + 0x48) +#define ICM_DLOCK_TIMEOUT_REG (DR_REG_AXI_ICM_BASE + 0x48) /** ICM_REG_DLOCK_TIMEOUT : R/W; bitpos: [12:0]; default: 2048; * if no response until reg_dlock_timeout bus clock cycle, deadlock will happen */ @@ -501,7 +501,7 @@ extern "C" { /** ICM_RDN_ECO_CS_REG register * NA */ -#define ICM_RDN_ECO_CS_REG (DR_REG_ICM_BASE + 0x50) +#define ICM_RDN_ECO_CS_REG (DR_REG_AXI_ICM_BASE + 0x50) /** ICM_REG_RDN_ECO_EN : R/W; bitpos: [0]; default: 0; * NA */ @@ -520,7 +520,7 @@ extern "C" { /** ICM_RDN_ECO_LOW_REG register * NA */ -#define ICM_RDN_ECO_LOW_REG (DR_REG_ICM_BASE + 0x54) +#define ICM_RDN_ECO_LOW_REG (DR_REG_AXI_ICM_BASE + 0x54) /** ICM_RDN_ECO_LOW : R/W; bitpos: [31:0]; default: 0; * NA */ @@ -532,7 +532,7 @@ extern "C" { /** ICM_RDN_ECO_HIGH_REG register * NA */ -#define ICM_RDN_ECO_HIGH_REG (DR_REG_ICM_BASE + 0x58) +#define ICM_RDN_ECO_HIGH_REG (DR_REG_AXI_ICM_BASE + 0x58) /** ICM_RDN_ECO_HIGH : R/W; bitpos: [31:0]; default: 4294967295; * NA */ diff --git a/components/soc/esp32p4/include/soc/icm_sys_struct.h b/components/soc/esp32p4/include/soc/icm_sys_struct.h index 77b80c57b6dc..887ae885aac3 100644 --- a/components/soc/esp32p4/include/soc/icm_sys_struct.h +++ b/components/soc/esp32p4/include/soc/icm_sys_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -373,7 +373,7 @@ typedef union { typedef union { struct { /** reg_icm_sys_addrhole_id : RO; bitpos: [7:0]; default: 0; - * master id = 4-bit CID + 4-bit UID(refer to related IP) . CID is used to verfiy + * master id = 4-bit CID + 4-bit UID(refer to related IP) . CID is used to verify * master in icm. CID: 4'h1: cache, 4'h5 gdma mst1, 4'h6: gdma mst2, 4'h8: axi pdma, * 4'ha: dma2d, 4'hb: h264 mst1, 4'hc: h264 mst2. */ @@ -508,11 +508,12 @@ typedef struct { volatile icm_rdn_eco_cs_reg_t rdn_eco_cs; volatile icm_rdn_eco_low_reg_t rdn_eco_low; volatile icm_rdn_eco_high_reg_t rdn_eco_high; -} icm_dev_t; +} axi_icm_dev_t; +extern axi_icm_dev_t AXI_ICM; #ifndef __cplusplus -_Static_assert(sizeof(icm_dev_t) == 0x5c, "Invalid size of icm_dev_t structure"); +_Static_assert(sizeof(axi_icm_dev_t) == 0x5c, "Invalid size of axi_icm_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/interrupts.h b/components/soc/esp32p4/include/soc/interrupts.h index 76d65315f288..78bde5055e83 100644 --- a/components/soc/esp32p4/include/soc/interrupts.h +++ b/components/soc/esp32p4/include/soc/interrupts.h @@ -38,7 +38,7 @@ typedef enum { ETS_LP_SYSREG_INTR_SOURCE, ETS_LP_HUK_INTR_SOURCE, ETS_SYS_ICM_INTR_SOURCE, - ETS_USB_DEVICE_INTR_SOURCE, + ETS_USB_SERIAL_JTAG_INTR_SOURCE, ETS_SDIO_HOST_INTR_SOURCE, ETS_DW_GDMA_INTR_SOURCE, ETS_SPI2_INTR_SOURCE, diff --git a/components/soc/esp32p4/include/soc/io_mux_reg.h b/components/soc/esp32p4/include/soc/io_mux_reg.h index b4bbe739c2c1..85eed690983d 100644 --- a/components/soc/esp32p4/include/soc/io_mux_reg.h +++ b/components/soc/esp32p4/include/soc/io_mux_reg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -154,20 +154,21 @@ #define GPIO_PAD_SET_DRV(num, drv) PIN_SET_DRV(IOMUX_REG_GPIO##num, drv) // TODO: IDF-7499, IDF-7495 -// Pins defined here are all wrong (Ln153-164). On P4, these pins are individual pins, don't use normal GPIO pins anymore. +// SPI pins defined here are all wrong. On P4, these pins are individual pins, don't use normal GPIO pins anymore. // Please check iomux_mspi_pin_struct/reg.h -#define SPI_CS1_GPIO_NUM 26 -#define SPI_HD_GPIO_NUM 27 -#define SPI_WP_GPIO_NUM 28 -#define SPI_CS0_GPIO_NUM 29 -#define SPI_CLK_GPIO_NUM 30 -#define SPI_Q_GPIO_NUM 31 -#define SPI_D_GPIO_NUM 32 -#define SPI_D4_GPIO_NUM 33 -#define SPI_D5_GPIO_NUM 34 -#define SPI_D6_GPIO_NUM 35 -#define SPI_D7_GPIO_NUM 36 -#define SPI_DQS_GPIO_NUM 37 +#include "soc/gpio_num.h" +#define SPI_CS1_GPIO_NUM GPIO_NUM_MAX +#define SPI_HD_GPIO_NUM GPIO_NUM_MAX +#define SPI_WP_GPIO_NUM GPIO_NUM_MAX +#define SPI_CS0_GPIO_NUM GPIO_NUM_MAX +#define SPI_CLK_GPIO_NUM GPIO_NUM_MAX +#define SPI_Q_GPIO_NUM GPIO_NUM_MAX +#define SPI_D_GPIO_NUM GPIO_NUM_MAX +#define SPI_D4_GPIO_NUM GPIO_NUM_MAX +#define SPI_D5_GPIO_NUM GPIO_NUM_MAX +#define SPI_D6_GPIO_NUM GPIO_NUM_MAX +#define SPI_D7_GPIO_NUM GPIO_NUM_MAX +#define SPI_DQS_GPIO_NUM GPIO_NUM_MAX #define SD_CLK_GPIO_NUM 43 #define SD_CMD_GPIO_NUM 44 @@ -331,63 +332,63 @@ #define PERIPHS_IO_MUX_U_PAD_GPIO28 (REG_IO_MUX_BASE + 0x74) #define FUNC_GPIO28_DBG_PSRAM_D_PAD 4 -#define FUNC_GPIO28_GMAC_PHY_RXDV_PAD 3 +#define FUNC_GPIO28_EMAC_PHY_RXDV_PAD 3 #define FUNC_GPIO28_SPI2_CS_PAD 2 #define FUNC_GPIO28_GPIO28 1 #define FUNC_GPIO28_GPIO28_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO29 (REG_IO_MUX_BASE + 0x78) #define FUNC_GPIO29_DBG_PSRAM_Q_PAD 4 -#define FUNC_GPIO29_GMAC_PHY_RXD0_PAD 3 +#define FUNC_GPIO29_EMAC_PHY_RXD0_PAD 3 #define FUNC_GPIO29_SPI2_D_PAD 2 #define FUNC_GPIO29_GPIO29 1 #define FUNC_GPIO29_GPIO29_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO30 (REG_IO_MUX_BASE + 0x7C) #define FUNC_GPIO30_DBG_PSRAM_WP_PAD 4 -#define FUNC_GPIO30_GMAC_PHY_RXD1_PAD 3 +#define FUNC_GPIO30_EMAC_PHY_RXD1_PAD 3 #define FUNC_GPIO30_SPI2_CK_PAD 2 #define FUNC_GPIO30_GPIO30 1 #define FUNC_GPIO30_GPIO30_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO31 (REG_IO_MUX_BASE + 0x80) #define FUNC_GPIO31_DBG_PSRAM_HOLD_PAD 4 -#define FUNC_GPIO31_GMAC_PHY_RXER_PAD 3 +#define FUNC_GPIO31_EMAC_PHY_RXER_PAD 3 #define FUNC_GPIO31_SPI2_Q_PAD 2 #define FUNC_GPIO31_GPIO31 1 #define FUNC_GPIO31_GPIO31_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO32 (REG_IO_MUX_BASE + 0x84) #define FUNC_GPIO32_DBG_PSRAM_DQ4_PAD 4 -#define FUNC_GPIO32_GMAC_RMII_CLK_PAD 3 +#define FUNC_GPIO32_EMAC_RMII_CLK_PAD 3 #define FUNC_GPIO32_SPI2_HOLD_PAD 2 #define FUNC_GPIO32_GPIO32 1 #define FUNC_GPIO32_GPIO32_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO33 (REG_IO_MUX_BASE + 0x88) #define FUNC_GPIO33_DBG_PSRAM_DQ5_PAD 4 -#define FUNC_GPIO33_GMAC_PHY_TXEN_PAD 3 +#define FUNC_GPIO33_EMAC_PHY_TXEN_PAD 3 #define FUNC_GPIO33_SPI2_WP_PAD 2 #define FUNC_GPIO33_GPIO33 1 #define FUNC_GPIO33_GPIO33_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO34 (REG_IO_MUX_BASE + 0x8C) #define FUNC_GPIO34_DBG_PSRAM_DQ6_PAD 4 -#define FUNC_GPIO34_GMAC_PHY_TXD0_PAD 3 +#define FUNC_GPIO34_EMAC_PHY_TXD0_PAD 3 #define FUNC_GPIO34_SPI2_IO4_PAD 2 #define FUNC_GPIO34_GPIO34 1 #define FUNC_GPIO34_GPIO34_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO35 (REG_IO_MUX_BASE + 0x90) #define FUNC_GPIO35_DBG_PSRAM_DQ7_PAD 4 -#define FUNC_GPIO35_GMAC_PHY_TXD1_PAD 3 +#define FUNC_GPIO35_EMAC_PHY_TXD1_PAD 3 #define FUNC_GPIO35_SPI2_IO5_PAD 2 #define FUNC_GPIO35_GPIO35 1 #define FUNC_GPIO35_GPIO35_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO36 (REG_IO_MUX_BASE + 0x94) #define FUNC_GPIO36_DBG_PSRAM_DQS_0_PAD 4 -#define FUNC_GPIO36_GMAC_PHY_TXER_PAD 3 +#define FUNC_GPIO36_EMAC_PHY_TXER_PAD 3 #define FUNC_GPIO36_SPI2_IO6_PAD 2 #define FUNC_GPIO36_GPIO36 1 #define FUNC_GPIO36_GPIO36_0 0 @@ -411,99 +412,99 @@ #define PERIPHS_IO_MUX_U_PAD_GPIO40 (REG_IO_MUX_BASE + 0xA4) #define FUNC_GPIO40_DBG_PSRAM_DQ9_PAD 4 -#define FUNC_GPIO40_GMAC_PHY_TXEN_PAD 3 +#define FUNC_GPIO40_EMAC_PHY_TXEN_PAD 3 #define FUNC_GPIO40_BIST_PAD 2 #define FUNC_GPIO40_GPIO40 1 #define FUNC_GPIO40_SD1_CDATA1_PAD 0 #define PERIPHS_IO_MUX_U_PAD_GPIO41 (REG_IO_MUX_BASE + 0xA8) #define FUNC_GPIO41_DBG_PSRAM_DQ10_PAD 4 -#define FUNC_GPIO41_GMAC_PHY_TXD0_PAD 3 +#define FUNC_GPIO41_EMAC_PHY_TXD0_PAD 3 #define FUNC_GPIO41_BIST_PAD 2 #define FUNC_GPIO41_GPIO41 1 #define FUNC_GPIO41_SD1_CDATA2_PAD 0 #define PERIPHS_IO_MUX_U_PAD_GPIO42 (REG_IO_MUX_BASE + 0xAC) #define FUNC_GPIO42_DBG_PSRAM_DQ11_PAD 4 -#define FUNC_GPIO42_GMAC_PHY_TXD1_PAD 3 +#define FUNC_GPIO42_EMAC_PHY_TXD1_PAD 3 #define FUNC_GPIO42_BIST_PAD 2 #define FUNC_GPIO42_GPIO42 1 #define FUNC_GPIO42_SD1_CDATA3_PAD 0 #define PERIPHS_IO_MUX_U_PAD_GPIO43 (REG_IO_MUX_BASE + 0xB0) #define FUNC_GPIO43_DBG_PSRAM_DQ12_PAD 4 -#define FUNC_GPIO43_GMAC_PHY_TXER_PAD 3 +#define FUNC_GPIO43_EMAC_PHY_TXER_PAD 3 #define FUNC_GPIO43_BIST_PAD 2 #define FUNC_GPIO43_GPIO43 1 #define FUNC_GPIO43_SD1_CCLK_PAD 0 #define PERIPHS_IO_MUX_U_PAD_GPIO44 (REG_IO_MUX_BASE + 0xB4) #define FUNC_GPIO44_DBG_PSRAM_DQ13_PAD 4 -#define FUNC_GPIO44_GMAC_RMII_CLK_PAD 3 +#define FUNC_GPIO44_EMAC_RMII_CLK_PAD 3 #define FUNC_GPIO44_BIST_PAD 2 #define FUNC_GPIO44_GPIO44 1 #define FUNC_GPIO44_SD1_CCMD_PAD 0 #define PERIPHS_IO_MUX_U_PAD_GPIO45 (REG_IO_MUX_BASE + 0xB8) #define FUNC_GPIO45_DBG_PSRAM_DQ14_PAD 4 -#define FUNC_GPIO45_GMAC_PHY_RXDV_PAD 3 +#define FUNC_GPIO45_EMAC_PHY_RXDV_PAD 3 #define FUNC_GPIO45_BIST_PAD 2 #define FUNC_GPIO45_GPIO45 1 #define FUNC_GPIO45_SD1_CDATA4_PAD 0 #define PERIPHS_IO_MUX_U_PAD_GPIO46 (REG_IO_MUX_BASE + 0xBC) #define FUNC_GPIO46_DBG_PSRAM_DQ15_PAD 4 -#define FUNC_GPIO46_GMAC_PHY_RXD0_PAD 3 +#define FUNC_GPIO46_EMAC_PHY_RXD0_PAD 3 #define FUNC_GPIO46_BIST_PAD 2 #define FUNC_GPIO46_GPIO46 1 #define FUNC_GPIO46_SD1_CDATA5_PAD 0 #define PERIPHS_IO_MUX_U_PAD_GPIO47 (REG_IO_MUX_BASE + 0xC0) #define FUNC_GPIO47_DBG_PSRAM_DQS_1_PAD 4 -#define FUNC_GPIO47_GMAC_PHY_RXD1_PAD 3 +#define FUNC_GPIO47_EMAC_PHY_RXD1_PAD 3 #define FUNC_GPIO47_BIST_PAD 2 #define FUNC_GPIO47_GPIO47 1 #define FUNC_GPIO47_SD1_CDATA6_PAD 0 #define PERIPHS_IO_MUX_U_PAD_GPIO48 (REG_IO_MUX_BASE + 0xC4) -#define FUNC_GPIO48_GMAC_PHY_RXER_PAD 3 +#define FUNC_GPIO48_EMAC_PHY_RXER_PAD 3 #define FUNC_GPIO48_BIST_PAD 2 #define FUNC_GPIO48_GPIO48 1 #define FUNC_GPIO48_SD1_CDATA7_PAD 0 #define PERIPHS_IO_MUX_U_PAD_GPIO49 (REG_IO_MUX_BASE + 0xC8) #define FUNC_GPIO49_DBG_FLASH_CS_PAD 4 -#define FUNC_GPIO49_GMAC_PHY_TXEN_PAD 3 +#define FUNC_GPIO49_EMAC_PHY_TXEN_PAD 3 #define FUNC_GPIO49_GPIO49 1 #define FUNC_GPIO49_GPIO49_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO50 (REG_IO_MUX_BASE + 0xCC) #define FUNC_GPIO50_DBG_FLASH_Q_PAD 4 -#define FUNC_GPIO50_GMAC_RMII_CLK_PAD 3 +#define FUNC_GPIO50_EMAC_RMII_CLK_PAD 3 #define FUNC_GPIO50_GPIO50 1 #define FUNC_GPIO50_GPIO50_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO51 (REG_IO_MUX_BASE + 0xD0) #define FUNC_GPIO51_DBG_FLASH_WP_PAD 4 -#define FUNC_GPIO51_GMAC_PHY_RXDV_PAD 3 +#define FUNC_GPIO51_EMAC_PHY_RXDV_PAD 3 #define FUNC_GPIO51_GPIO51 1 #define FUNC_GPIO51_GPIO51_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO52 (REG_IO_MUX_BASE + 0xD4) #define FUNC_GPIO52_DBG_FLASH_HOLD_PAD 4 -#define FUNC_GPIO52_GMAC_PHY_RXD0_PAD 3 +#define FUNC_GPIO52_EMAC_PHY_RXD0_PAD 3 #define FUNC_GPIO52_GPIO52 1 #define FUNC_GPIO52_GPIO52_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO53 (REG_IO_MUX_BASE + 0xD8) #define FUNC_GPIO53_DBG_FLASH_CK_PAD 4 -#define FUNC_GPIO53_GMAC_PHY_RXD1_PAD 3 +#define FUNC_GPIO53_EMAC_PHY_RXD1_PAD 3 #define FUNC_GPIO53_GPIO53 1 #define FUNC_GPIO53_GPIO53_0 0 #define PERIPHS_IO_MUX_U_PAD_GPIO54 (REG_IO_MUX_BASE + 0xDC) #define FUNC_GPIO54_DBG_FLASH_D_PAD 4 -#define FUNC_GPIO54_GMAC_PHY_RXER_PAD 3 +#define FUNC_GPIO54_EMAC_PHY_RXER_PAD 3 #define FUNC_GPIO54_GPIO54 1 #define FUNC_GPIO54_GPIO54_0 0 diff --git a/components/soc/esp32p4/include/soc/io_mux_struct.h b/components/soc/esp32p4/include/soc/io_mux_struct.h index 5ddbc746b9c9..150d0d5c1e35 100644 --- a/components/soc/esp32p4/include/soc/io_mux_struct.h +++ b/components/soc/esp32p4/include/soc/io_mux_struct.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,7 @@ extern "C" { #endif /** Type of GPIO register - * IOMUX gpio configuration register + * IO MUX gpio configuration register */ typedef union { struct { @@ -36,7 +36,7 @@ typedef union { */ uint32_t mcu_ie:1; /** mcu_drv : R/W; bitpos: [5:6]; default: 0; - * select drive strenth on sleep mode + * select drive strength on sleep mode */ uint32_t mcu_drv:2; /** fun_wpd : R/W; bitpos: [7]; default: 0; @@ -52,7 +52,7 @@ typedef union { */ uint32_t fun_ie:1; /** fun_drv : R/W; bitpos: [10:11]; default: 2; - * select drive strenth, 0:5mA, 1:10mA, 2:20mA, 3:40mA + * select drive strength, 0:5mA, 1:10mA, 2:20mA, 3:40mA */ uint32_t fun_drv:2; /** mcu_sel : R/W; bitpos: [12:14]; default: 0; @@ -66,10 +66,10 @@ typedef union { uint32_t reserved16 :16; }; uint32_t val; -} iomux_gpio_reg_t; +} io_mux_gpio_reg_t; /** Type of date register - * IOMUX version register + * IO_MUX version register */ typedef union { struct { @@ -80,20 +80,20 @@ typedef union { uint32_t reserved_28:4; }; uint32_t val; -} iomux_date_reg_t; +} io_mux_date_reg_t; -typedef struct iomux_dev_t { +typedef struct io_mux_dev_t { uint32_t reserved_0; - volatile iomux_gpio_reg_t gpio[57]; + volatile io_mux_gpio_reg_t gpio[57]; uint32_t reserved_e8[7]; - volatile iomux_date_reg_t date; -} iomux_dev_t; + volatile io_mux_date_reg_t date; +} io_mux_dev_t; -extern iomux_dev_t IOMUX; +extern io_mux_dev_t IO_MUX; #ifndef __cplusplus -_Static_assert(sizeof(iomux_dev_t) == 0x108, "Invalid size of iomux_dev_t structure"); +_Static_assert(sizeof(io_mux_dev_t) == 0x108, "Invalid size of io_mux_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/lp2hp_peri_pms_reg.h b/components/soc/esp32p4/include/soc/lp2hp_peri_pms_reg.h index 57d17419a70d..ba58a6cfde6d 100644 --- a/components/soc/esp32p4/include/soc/lp2hp_peri_pms_reg.h +++ b/components/soc/esp32p4/include/soc/lp2hp_peri_pms_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,567 +11,748 @@ extern "C" { #endif -/** TEE_LP2HP_PMS_DATE_REG register - * NA +/** PMS_LP2HP_PERI_PMS_DATE_REG register + * Version control register */ -#define TEE_LP2HP_PMS_DATE_REG (DR_REG_TEE_BASE + 0x0) -/** TEE_TEE_DATE : R/W; bitpos: [31:0]; default: 2294790; - * NA +#define PMS_LP2HP_PERI_PMS_DATE_REG (DR_REG_LP2HP_PERI_PMS_BASE + 0x0) +/** PMS_LP2HP_PERI_PMS_DATE : R/W; bitpos: [31:0]; default: 2294790; + * Version control register. */ -#define TEE_TEE_DATE 0xFFFFFFFFU -#define TEE_TEE_DATE_M (TEE_TEE_DATE_V << TEE_TEE_DATE_S) -#define TEE_TEE_DATE_V 0xFFFFFFFFU -#define TEE_TEE_DATE_S 0 +#define PMS_LP2HP_PERI_PMS_DATE 0xFFFFFFFFU +#define PMS_LP2HP_PERI_PMS_DATE_M (PMS_LP2HP_PERI_PMS_DATE_V << PMS_LP2HP_PERI_PMS_DATE_S) +#define PMS_LP2HP_PERI_PMS_DATE_V 0xFFFFFFFFU +#define PMS_LP2HP_PERI_PMS_DATE_S 0 -/** TEE_PMS_CLK_EN_REG register - * NA - */ -#define TEE_PMS_CLK_EN_REG (DR_REG_TEE_BASE + 0x4) -/** TEE_REG_CLK_EN : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CLK_EN (BIT(0)) -#define TEE_REG_CLK_EN_M (TEE_REG_CLK_EN_V << TEE_REG_CLK_EN_S) -#define TEE_REG_CLK_EN_V 0x00000001U -#define TEE_REG_CLK_EN_S 0 +/** PMS_LP2HP_PERI_PMS_CLK_EN_REG register + * Clock gating register + */ +#define PMS_LP2HP_PERI_PMS_CLK_EN_REG (DR_REG_LP2HP_PERI_PMS_BASE + 0x4) +/** PMS_LP2HP_PERI_PMS_CLK_EN : R/W; bitpos: [0]; default: 1; + * Configures whether to keep the clock always on. + * 0: Enable automatic clock gating. + * 1: Keep the clock always on. + */ +#define PMS_LP2HP_PERI_PMS_CLK_EN (BIT(0)) +#define PMS_LP2HP_PERI_PMS_CLK_EN_M (PMS_LP2HP_PERI_PMS_CLK_EN_V << PMS_LP2HP_PERI_PMS_CLK_EN_S) +#define PMS_LP2HP_PERI_PMS_CLK_EN_V 0x00000001U +#define PMS_LP2HP_PERI_PMS_CLK_EN_S 0 -/** TEE_LP_MM_PMS_REG0_REG register - * NA - */ -#define TEE_LP_MM_PMS_REG0_REG (DR_REG_TEE_BASE + 0x8) -/** TEE_REG_LP_MM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_PSRAM_ALLOW (BIT(0)) -#define TEE_REG_LP_MM_PSRAM_ALLOW_M (TEE_REG_LP_MM_PSRAM_ALLOW_V << TEE_REG_LP_MM_PSRAM_ALLOW_S) -#define TEE_REG_LP_MM_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_PSRAM_ALLOW_S 0 -/** TEE_REG_LP_MM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_FLASH_ALLOW (BIT(1)) -#define TEE_REG_LP_MM_FLASH_ALLOW_M (TEE_REG_LP_MM_FLASH_ALLOW_V << TEE_REG_LP_MM_FLASH_ALLOW_S) -#define TEE_REG_LP_MM_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_FLASH_ALLOW_S 1 -/** TEE_REG_LP_MM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_L2MEM_ALLOW (BIT(2)) -#define TEE_REG_LP_MM_L2MEM_ALLOW_M (TEE_REG_LP_MM_L2MEM_ALLOW_V << TEE_REG_LP_MM_L2MEM_ALLOW_S) -#define TEE_REG_LP_MM_L2MEM_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_L2MEM_ALLOW_S 2 -/** TEE_REG_LP_MM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_L2ROM_ALLOW (BIT(3)) -#define TEE_REG_LP_MM_L2ROM_ALLOW_M (TEE_REG_LP_MM_L2ROM_ALLOW_V << TEE_REG_LP_MM_L2ROM_ALLOW_S) -#define TEE_REG_LP_MM_L2ROM_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_L2ROM_ALLOW_S 3 -/** TEE_REG_LP_MM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_TRACE0_ALLOW (BIT(6)) -#define TEE_REG_LP_MM_TRACE0_ALLOW_M (TEE_REG_LP_MM_TRACE0_ALLOW_V << TEE_REG_LP_MM_TRACE0_ALLOW_S) -#define TEE_REG_LP_MM_TRACE0_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_TRACE0_ALLOW_S 6 -/** TEE_REG_LP_MM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_TRACE1_ALLOW (BIT(7)) -#define TEE_REG_LP_MM_TRACE1_ALLOW_M (TEE_REG_LP_MM_TRACE1_ALLOW_V << TEE_REG_LP_MM_TRACE1_ALLOW_S) -#define TEE_REG_LP_MM_TRACE1_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_TRACE1_ALLOW_S 7 -/** TEE_REG_LP_MM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_CPU_BUS_MON_ALLOW (BIT(8)) -#define TEE_REG_LP_MM_CPU_BUS_MON_ALLOW_M (TEE_REG_LP_MM_CPU_BUS_MON_ALLOW_V << TEE_REG_LP_MM_CPU_BUS_MON_ALLOW_S) -#define TEE_REG_LP_MM_CPU_BUS_MON_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_CPU_BUS_MON_ALLOW_S 8 -/** TEE_REG_LP_MM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_L2MEM_MON_ALLOW (BIT(9)) -#define TEE_REG_LP_MM_L2MEM_MON_ALLOW_M (TEE_REG_LP_MM_L2MEM_MON_ALLOW_V << TEE_REG_LP_MM_L2MEM_MON_ALLOW_S) -#define TEE_REG_LP_MM_L2MEM_MON_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_L2MEM_MON_ALLOW_S 9 -/** TEE_REG_LP_MM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_TCM_MON_ALLOW (BIT(10)) -#define TEE_REG_LP_MM_TCM_MON_ALLOW_M (TEE_REG_LP_MM_TCM_MON_ALLOW_V << TEE_REG_LP_MM_TCM_MON_ALLOW_S) -#define TEE_REG_LP_MM_TCM_MON_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_TCM_MON_ALLOW_S 10 -/** TEE_REG_LP_MM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_CACHE_ALLOW (BIT(11)) -#define TEE_REG_LP_MM_CACHE_ALLOW_M (TEE_REG_LP_MM_CACHE_ALLOW_V << TEE_REG_LP_MM_CACHE_ALLOW_S) -#define TEE_REG_LP_MM_CACHE_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_CACHE_ALLOW_S 11 +/** PMS_LP_MM_PMS_REG0_REG register + * Permission control register0 for the LP CPU in machine mode + */ +#define PMS_LP_MM_PMS_REG0_REG (DR_REG_LP2HP_PERI_PMS_BASE + 0x8) +/** PMS_LP_MM_PSRAM_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access external RAM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_PSRAM_ALLOW (BIT(0)) +#define PMS_LP_MM_PSRAM_ALLOW_M (PMS_LP_MM_PSRAM_ALLOW_V << PMS_LP_MM_PSRAM_ALLOW_S) +#define PMS_LP_MM_PSRAM_ALLOW_V 0x00000001U +#define PMS_LP_MM_PSRAM_ALLOW_S 0 +/** PMS_LP_MM_FLASH_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access external + * flash without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_FLASH_ALLOW (BIT(1)) +#define PMS_LP_MM_FLASH_ALLOW_M (PMS_LP_MM_FLASH_ALLOW_V << PMS_LP_MM_FLASH_ALLOW_S) +#define PMS_LP_MM_FLASH_ALLOW_V 0x00000001U +#define PMS_LP_MM_FLASH_ALLOW_S 1 +/** PMS_LP_MM_L2MEM_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP L2M2M + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_L2MEM_ALLOW (BIT(2)) +#define PMS_LP_MM_L2MEM_ALLOW_M (PMS_LP_MM_L2MEM_ALLOW_V << PMS_LP_MM_L2MEM_ALLOW_S) +#define PMS_LP_MM_L2MEM_ALLOW_V 0x00000001U +#define PMS_LP_MM_L2MEM_ALLOW_S 2 +/** PMS_LP_MM_L2ROM_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP ROM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_L2ROM_ALLOW (BIT(3)) +#define PMS_LP_MM_L2ROM_ALLOW_M (PMS_LP_MM_L2ROM_ALLOW_V << PMS_LP_MM_L2ROM_ALLOW_S) +#define PMS_LP_MM_L2ROM_ALLOW_V 0x00000001U +#define PMS_LP_MM_L2ROM_ALLOW_S 3 +/** PMS_LP_MM_TRACE0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access TRACE0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_TRACE0_ALLOW (BIT(6)) +#define PMS_LP_MM_TRACE0_ALLOW_M (PMS_LP_MM_TRACE0_ALLOW_V << PMS_LP_MM_TRACE0_ALLOW_S) +#define PMS_LP_MM_TRACE0_ALLOW_V 0x00000001U +#define PMS_LP_MM_TRACE0_ALLOW_S 6 +/** PMS_LP_MM_TRACE1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access TRACE1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_TRACE1_ALLOW (BIT(7)) +#define PMS_LP_MM_TRACE1_ALLOW_M (PMS_LP_MM_TRACE1_ALLOW_V << PMS_LP_MM_TRACE1_ALLOW_S) +#define PMS_LP_MM_TRACE1_ALLOW_V 0x00000001U +#define PMS_LP_MM_TRACE1_ALLOW_S 7 +/** PMS_LP_MM_CPU_BUS_MON_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access CPU bus + * monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_CPU_BUS_MON_ALLOW (BIT(8)) +#define PMS_LP_MM_CPU_BUS_MON_ALLOW_M (PMS_LP_MM_CPU_BUS_MON_ALLOW_V << PMS_LP_MM_CPU_BUS_MON_ALLOW_S) +#define PMS_LP_MM_CPU_BUS_MON_ALLOW_V 0x00000001U +#define PMS_LP_MM_CPU_BUS_MON_ALLOW_S 8 +/** PMS_LP_MM_L2MEM_MON_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access L2MEM + * monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_L2MEM_MON_ALLOW (BIT(9)) +#define PMS_LP_MM_L2MEM_MON_ALLOW_M (PMS_LP_MM_L2MEM_MON_ALLOW_V << PMS_LP_MM_L2MEM_MON_ALLOW_S) +#define PMS_LP_MM_L2MEM_MON_ALLOW_V 0x00000001U +#define PMS_LP_MM_L2MEM_MON_ALLOW_S 9 +/** PMS_LP_MM_TCM_MON_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access TCM monitor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_TCM_MON_ALLOW (BIT(10)) +#define PMS_LP_MM_TCM_MON_ALLOW_M (PMS_LP_MM_TCM_MON_ALLOW_V << PMS_LP_MM_TCM_MON_ALLOW_S) +#define PMS_LP_MM_TCM_MON_ALLOW_V 0x00000001U +#define PMS_LP_MM_TCM_MON_ALLOW_S 10 +/** PMS_LP_MM_CACHE_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access cache. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_CACHE_ALLOW (BIT(11)) +#define PMS_LP_MM_CACHE_ALLOW_M (PMS_LP_MM_CACHE_ALLOW_V << PMS_LP_MM_CACHE_ALLOW_S) +#define PMS_LP_MM_CACHE_ALLOW_V 0x00000001U +#define PMS_LP_MM_CACHE_ALLOW_S 11 -/** TEE_LP_MM_PMS_REG1_REG register - * NA - */ -#define TEE_LP_MM_PMS_REG1_REG (DR_REG_TEE_BASE + 0x30) -/** TEE_REG_LP_MM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_USBOTG_ALLOW (BIT(0)) -#define TEE_REG_LP_MM_HP_USBOTG_ALLOW_M (TEE_REG_LP_MM_HP_USBOTG_ALLOW_V << TEE_REG_LP_MM_HP_USBOTG_ALLOW_S) -#define TEE_REG_LP_MM_HP_USBOTG_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_USBOTG_ALLOW_S 0 -/** TEE_REG_LP_MM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_USBOTG11_ALLOW (BIT(1)) -#define TEE_REG_LP_MM_HP_USBOTG11_ALLOW_M (TEE_REG_LP_MM_HP_USBOTG11_ALLOW_V << TEE_REG_LP_MM_HP_USBOTG11_ALLOW_S) -#define TEE_REG_LP_MM_HP_USBOTG11_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_USBOTG11_ALLOW_S 1 -/** TEE_REG_LP_MM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) -#define TEE_REG_LP_MM_HP_USBOTG11_WRAP_ALLOW_M (TEE_REG_LP_MM_HP_USBOTG11_WRAP_ALLOW_V << TEE_REG_LP_MM_HP_USBOTG11_WRAP_ALLOW_S) -#define TEE_REG_LP_MM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_USBOTG11_WRAP_ALLOW_S 2 -/** TEE_REG_LP_MM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_GDMA_ALLOW (BIT(3)) -#define TEE_REG_LP_MM_HP_GDMA_ALLOW_M (TEE_REG_LP_MM_HP_GDMA_ALLOW_V << TEE_REG_LP_MM_HP_GDMA_ALLOW_S) -#define TEE_REG_LP_MM_HP_GDMA_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_GDMA_ALLOW_S 3 -/** TEE_REG_LP_MM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_REGDMA_ALLOW (BIT(4)) -#define TEE_REG_LP_MM_HP_REGDMA_ALLOW_M (TEE_REG_LP_MM_HP_REGDMA_ALLOW_V << TEE_REG_LP_MM_HP_REGDMA_ALLOW_S) -#define TEE_REG_LP_MM_HP_REGDMA_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_REGDMA_ALLOW_S 4 -/** TEE_REG_LP_MM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_SDMMC_ALLOW (BIT(5)) -#define TEE_REG_LP_MM_HP_SDMMC_ALLOW_M (TEE_REG_LP_MM_HP_SDMMC_ALLOW_V << TEE_REG_LP_MM_HP_SDMMC_ALLOW_S) -#define TEE_REG_LP_MM_HP_SDMMC_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_SDMMC_ALLOW_S 5 -/** TEE_REG_LP_MM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_AHB_PDMA_ALLOW (BIT(6)) -#define TEE_REG_LP_MM_HP_AHB_PDMA_ALLOW_M (TEE_REG_LP_MM_HP_AHB_PDMA_ALLOW_V << TEE_REG_LP_MM_HP_AHB_PDMA_ALLOW_S) -#define TEE_REG_LP_MM_HP_AHB_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_AHB_PDMA_ALLOW_S 6 -/** TEE_REG_LP_MM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_JPEG_ALLOW (BIT(7)) -#define TEE_REG_LP_MM_HP_JPEG_ALLOW_M (TEE_REG_LP_MM_HP_JPEG_ALLOW_V << TEE_REG_LP_MM_HP_JPEG_ALLOW_S) -#define TEE_REG_LP_MM_HP_JPEG_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_JPEG_ALLOW_S 7 -/** TEE_REG_LP_MM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_PPA_ALLOW (BIT(8)) -#define TEE_REG_LP_MM_HP_PPA_ALLOW_M (TEE_REG_LP_MM_HP_PPA_ALLOW_V << TEE_REG_LP_MM_HP_PPA_ALLOW_S) -#define TEE_REG_LP_MM_HP_PPA_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_PPA_ALLOW_S 8 -/** TEE_REG_LP_MM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_DMA2D_ALLOW (BIT(9)) -#define TEE_REG_LP_MM_HP_DMA2D_ALLOW_M (TEE_REG_LP_MM_HP_DMA2D_ALLOW_V << TEE_REG_LP_MM_HP_DMA2D_ALLOW_S) -#define TEE_REG_LP_MM_HP_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_DMA2D_ALLOW_S 9 -/** TEE_REG_LP_MM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_KEY_MANAGER_ALLOW (BIT(10)) -#define TEE_REG_LP_MM_HP_KEY_MANAGER_ALLOW_M (TEE_REG_LP_MM_HP_KEY_MANAGER_ALLOW_V << TEE_REG_LP_MM_HP_KEY_MANAGER_ALLOW_S) -#define TEE_REG_LP_MM_HP_KEY_MANAGER_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_KEY_MANAGER_ALLOW_S 10 -/** TEE_REG_LP_MM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_AXI_PDMA_ALLOW (BIT(11)) -#define TEE_REG_LP_MM_HP_AXI_PDMA_ALLOW_M (TEE_REG_LP_MM_HP_AXI_PDMA_ALLOW_V << TEE_REG_LP_MM_HP_AXI_PDMA_ALLOW_S) -#define TEE_REG_LP_MM_HP_AXI_PDMA_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_AXI_PDMA_ALLOW_S 11 -/** TEE_REG_LP_MM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_FLASH_ALLOW (BIT(12)) -#define TEE_REG_LP_MM_HP_FLASH_ALLOW_M (TEE_REG_LP_MM_HP_FLASH_ALLOW_V << TEE_REG_LP_MM_HP_FLASH_ALLOW_S) -#define TEE_REG_LP_MM_HP_FLASH_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_FLASH_ALLOW_S 12 -/** TEE_REG_LP_MM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_PSRAM_ALLOW (BIT(13)) -#define TEE_REG_LP_MM_HP_PSRAM_ALLOW_M (TEE_REG_LP_MM_HP_PSRAM_ALLOW_V << TEE_REG_LP_MM_HP_PSRAM_ALLOW_S) -#define TEE_REG_LP_MM_HP_PSRAM_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_PSRAM_ALLOW_S 13 -/** TEE_REG_LP_MM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_CRYPTO_ALLOW (BIT(14)) -#define TEE_REG_LP_MM_HP_CRYPTO_ALLOW_M (TEE_REG_LP_MM_HP_CRYPTO_ALLOW_V << TEE_REG_LP_MM_HP_CRYPTO_ALLOW_S) -#define TEE_REG_LP_MM_HP_CRYPTO_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_CRYPTO_ALLOW_S 14 -/** TEE_REG_LP_MM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_GMAC_ALLOW (BIT(15)) -#define TEE_REG_LP_MM_HP_GMAC_ALLOW_M (TEE_REG_LP_MM_HP_GMAC_ALLOW_V << TEE_REG_LP_MM_HP_GMAC_ALLOW_S) -#define TEE_REG_LP_MM_HP_GMAC_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_GMAC_ALLOW_S 15 -/** TEE_REG_LP_MM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_USB_PHY_ALLOW (BIT(16)) -#define TEE_REG_LP_MM_HP_USB_PHY_ALLOW_M (TEE_REG_LP_MM_HP_USB_PHY_ALLOW_V << TEE_REG_LP_MM_HP_USB_PHY_ALLOW_S) -#define TEE_REG_LP_MM_HP_USB_PHY_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_USB_PHY_ALLOW_S 16 -/** TEE_REG_LP_MM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_PVT_ALLOW (BIT(17)) -#define TEE_REG_LP_MM_HP_PVT_ALLOW_M (TEE_REG_LP_MM_HP_PVT_ALLOW_V << TEE_REG_LP_MM_HP_PVT_ALLOW_S) -#define TEE_REG_LP_MM_HP_PVT_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_PVT_ALLOW_S 17 -/** TEE_REG_LP_MM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_CSI_HOST_ALLOW (BIT(18)) -#define TEE_REG_LP_MM_HP_CSI_HOST_ALLOW_M (TEE_REG_LP_MM_HP_CSI_HOST_ALLOW_V << TEE_REG_LP_MM_HP_CSI_HOST_ALLOW_S) -#define TEE_REG_LP_MM_HP_CSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_CSI_HOST_ALLOW_S 18 -/** TEE_REG_LP_MM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_DSI_HOST_ALLOW (BIT(19)) -#define TEE_REG_LP_MM_HP_DSI_HOST_ALLOW_M (TEE_REG_LP_MM_HP_DSI_HOST_ALLOW_V << TEE_REG_LP_MM_HP_DSI_HOST_ALLOW_S) -#define TEE_REG_LP_MM_HP_DSI_HOST_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_DSI_HOST_ALLOW_S 19 -/** TEE_REG_LP_MM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_ISP_ALLOW (BIT(20)) -#define TEE_REG_LP_MM_HP_ISP_ALLOW_M (TEE_REG_LP_MM_HP_ISP_ALLOW_V << TEE_REG_LP_MM_HP_ISP_ALLOW_S) -#define TEE_REG_LP_MM_HP_ISP_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_ISP_ALLOW_S 20 -/** TEE_REG_LP_MM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_H264_CORE_ALLOW (BIT(21)) -#define TEE_REG_LP_MM_HP_H264_CORE_ALLOW_M (TEE_REG_LP_MM_HP_H264_CORE_ALLOW_V << TEE_REG_LP_MM_HP_H264_CORE_ALLOW_S) -#define TEE_REG_LP_MM_HP_H264_CORE_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_H264_CORE_ALLOW_S 21 -/** TEE_REG_LP_MM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_RMT_ALLOW (BIT(22)) -#define TEE_REG_LP_MM_HP_RMT_ALLOW_M (TEE_REG_LP_MM_HP_RMT_ALLOW_V << TEE_REG_LP_MM_HP_RMT_ALLOW_S) -#define TEE_REG_LP_MM_HP_RMT_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_RMT_ALLOW_S 22 -/** TEE_REG_LP_MM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_BITSRAMBLER_ALLOW (BIT(23)) -#define TEE_REG_LP_MM_HP_BITSRAMBLER_ALLOW_M (TEE_REG_LP_MM_HP_BITSRAMBLER_ALLOW_V << TEE_REG_LP_MM_HP_BITSRAMBLER_ALLOW_S) -#define TEE_REG_LP_MM_HP_BITSRAMBLER_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_BITSRAMBLER_ALLOW_S 23 -/** TEE_REG_LP_MM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_AXI_ICM_ALLOW (BIT(24)) -#define TEE_REG_LP_MM_HP_AXI_ICM_ALLOW_M (TEE_REG_LP_MM_HP_AXI_ICM_ALLOW_V << TEE_REG_LP_MM_HP_AXI_ICM_ALLOW_S) -#define TEE_REG_LP_MM_HP_AXI_ICM_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_AXI_ICM_ALLOW_S 24 -/** TEE_REG_LP_MM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_PERI_PMS_ALLOW (BIT(25)) -#define TEE_REG_LP_MM_HP_PERI_PMS_ALLOW_M (TEE_REG_LP_MM_HP_PERI_PMS_ALLOW_V << TEE_REG_LP_MM_HP_PERI_PMS_ALLOW_S) -#define TEE_REG_LP_MM_HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_PERI_PMS_ALLOW_S 25 -/** TEE_REG_LP_MM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP2HP_PERI_PMS_ALLOW (BIT(26)) -#define TEE_REG_LP_MM_LP2HP_PERI_PMS_ALLOW_M (TEE_REG_LP_MM_LP2HP_PERI_PMS_ALLOW_V << TEE_REG_LP_MM_LP2HP_PERI_PMS_ALLOW_S) -#define TEE_REG_LP_MM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP2HP_PERI_PMS_ALLOW_S 26 -/** TEE_REG_LP_MM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_DMA_PMS_ALLOW (BIT(27)) -#define TEE_REG_LP_MM_DMA_PMS_ALLOW_M (TEE_REG_LP_MM_DMA_PMS_ALLOW_V << TEE_REG_LP_MM_DMA_PMS_ALLOW_S) -#define TEE_REG_LP_MM_DMA_PMS_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_DMA_PMS_ALLOW_S 27 -/** TEE_REG_LP_MM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_H264_DMA2D_ALLOW (BIT(28)) -#define TEE_REG_LP_MM_HP_H264_DMA2D_ALLOW_M (TEE_REG_LP_MM_HP_H264_DMA2D_ALLOW_V << TEE_REG_LP_MM_HP_H264_DMA2D_ALLOW_S) -#define TEE_REG_LP_MM_HP_H264_DMA2D_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_H264_DMA2D_ALLOW_S 28 +/** PMS_LP_MM_PMS_REG1_REG register + * Permission control register1 for the LP CPU in machine mode + */ +#define PMS_LP_MM_PMS_REG1_REG (DR_REG_LP2HP_PERI_PMS_BASE + 0x30) +/** PMS_LP_MM_HP_USBOTG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * high-speed USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_USBOTG_ALLOW (BIT(0)) +#define PMS_LP_MM_HP_USBOTG_ALLOW_M (PMS_LP_MM_HP_USBOTG_ALLOW_V << PMS_LP_MM_HP_USBOTG_ALLOW_S) +#define PMS_LP_MM_HP_USBOTG_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_USBOTG_ALLOW_S 0 +/** PMS_LP_MM_HP_USBOTG11_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * full-speed USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_USBOTG11_ALLOW (BIT(1)) +#define PMS_LP_MM_HP_USBOTG11_ALLOW_M (PMS_LP_MM_HP_USBOTG11_ALLOW_V << PMS_LP_MM_HP_USBOTG11_ALLOW_S) +#define PMS_LP_MM_HP_USBOTG11_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_USBOTG11_ALLOW_S 1 +/** PMS_LP_MM_HP_USBOTG11_WRAP_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * full-speed USB 2.0 OTG's wrap. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_USBOTG11_WRAP_ALLOW (BIT(2)) +#define PMS_LP_MM_HP_USBOTG11_WRAP_ALLOW_M (PMS_LP_MM_HP_USBOTG11_WRAP_ALLOW_V << PMS_LP_MM_HP_USBOTG11_WRAP_ALLOW_S) +#define PMS_LP_MM_HP_USBOTG11_WRAP_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_USBOTG11_WRAP_ALLOW_S 2 +/** PMS_LP_MM_HP_GDMA_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP DW-GDMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_GDMA_ALLOW (BIT(3)) +#define PMS_LP_MM_HP_GDMA_ALLOW_M (PMS_LP_MM_HP_GDMA_ALLOW_V << PMS_LP_MM_HP_GDMA_ALLOW_S) +#define PMS_LP_MM_HP_GDMA_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_GDMA_ALLOW_S 3 +/** PMS_LP_MM_HP_REGDMA_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GDMA (DW + * GDMA). + * 0: Not allowed + * 1: Allow + */ +#define PMS_LP_MM_HP_REGDMA_ALLOW (BIT(4)) +#define PMS_LP_MM_HP_REGDMA_ALLOW_M (PMS_LP_MM_HP_REGDMA_ALLOW_V << PMS_LP_MM_HP_REGDMA_ALLOW_S) +#define PMS_LP_MM_HP_REGDMA_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_REGDMA_ALLOW_S 4 +/** PMS_LP_MM_HP_SDMMC_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP SDMMC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_SDMMC_ALLOW (BIT(5)) +#define PMS_LP_MM_HP_SDMMC_ALLOW_M (PMS_LP_MM_HP_SDMMC_ALLOW_V << PMS_LP_MM_HP_SDMMC_ALLOW_S) +#define PMS_LP_MM_HP_SDMMC_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_SDMMC_ALLOW_S 5 +/** PMS_LP_MM_HP_AHB_PDMA_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access GDMA-AHB. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_AHB_PDMA_ALLOW (BIT(6)) +#define PMS_LP_MM_HP_AHB_PDMA_ALLOW_M (PMS_LP_MM_HP_AHB_PDMA_ALLOW_V << PMS_LP_MM_HP_AHB_PDMA_ALLOW_S) +#define PMS_LP_MM_HP_AHB_PDMA_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_AHB_PDMA_ALLOW_S 6 +/** PMS_LP_MM_HP_JPEG_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP JPEG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_JPEG_ALLOW (BIT(7)) +#define PMS_LP_MM_HP_JPEG_ALLOW_M (PMS_LP_MM_HP_JPEG_ALLOW_V << PMS_LP_MM_HP_JPEG_ALLOW_S) +#define PMS_LP_MM_HP_JPEG_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_JPEG_ALLOW_S 7 +/** PMS_LP_MM_HP_PPA_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PPA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_PPA_ALLOW (BIT(8)) +#define PMS_LP_MM_HP_PPA_ALLOW_M (PMS_LP_MM_HP_PPA_ALLOW_V << PMS_LP_MM_HP_PPA_ALLOW_S) +#define PMS_LP_MM_HP_PPA_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_PPA_ALLOW_S 8 +/** PMS_LP_MM_HP_DMA2D_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_DMA2D_ALLOW (BIT(9)) +#define PMS_LP_MM_HP_DMA2D_ALLOW_M (PMS_LP_MM_HP_DMA2D_ALLOW_V << PMS_LP_MM_HP_DMA2D_ALLOW_S) +#define PMS_LP_MM_HP_DMA2D_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_DMA2D_ALLOW_S 9 +/** PMS_LP_MM_HP_KEY_MANAGER_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP key + * manager. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_KEY_MANAGER_ALLOW (BIT(10)) +#define PMS_LP_MM_HP_KEY_MANAGER_ALLOW_M (PMS_LP_MM_HP_KEY_MANAGER_ALLOW_V << PMS_LP_MM_HP_KEY_MANAGER_ALLOW_S) +#define PMS_LP_MM_HP_KEY_MANAGER_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_KEY_MANAGER_ALLOW_S 10 +/** PMS_LP_MM_HP_AXI_PDMA_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GDMA-AXI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_AXI_PDMA_ALLOW (BIT(11)) +#define PMS_LP_MM_HP_AXI_PDMA_ALLOW_M (PMS_LP_MM_HP_AXI_PDMA_ALLOW_V << PMS_LP_MM_HP_AXI_PDMA_ALLOW_S) +#define PMS_LP_MM_HP_AXI_PDMA_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_AXI_PDMA_ALLOW_S 11 +/** PMS_LP_MM_HP_FLASH_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP flash + * MSPI controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_FLASH_ALLOW (BIT(12)) +#define PMS_LP_MM_HP_FLASH_ALLOW_M (PMS_LP_MM_HP_FLASH_ALLOW_V << PMS_LP_MM_HP_FLASH_ALLOW_S) +#define PMS_LP_MM_HP_FLASH_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_FLASH_ALLOW_S 12 +/** PMS_LP_MM_HP_PSRAM_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PSRAM + * MSPI controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_PSRAM_ALLOW (BIT(13)) +#define PMS_LP_MM_HP_PSRAM_ALLOW_M (PMS_LP_MM_HP_PSRAM_ALLOW_V << PMS_LP_MM_HP_PSRAM_ALLOW_S) +#define PMS_LP_MM_HP_PSRAM_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_PSRAM_ALLOW_S 13 +/** PMS_LP_MM_HP_CRYPTO_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP CRYPTO. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_CRYPTO_ALLOW (BIT(14)) +#define PMS_LP_MM_HP_CRYPTO_ALLOW_M (PMS_LP_MM_HP_CRYPTO_ALLOW_V << PMS_LP_MM_HP_CRYPTO_ALLOW_S) +#define PMS_LP_MM_HP_CRYPTO_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_CRYPTO_ALLOW_S 14 +/** PMS_LP_MM_HP_GMAC_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP EMAC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_GMAC_ALLOW (BIT(15)) +#define PMS_LP_MM_HP_GMAC_ALLOW_M (PMS_LP_MM_HP_GMAC_ALLOW_V << PMS_LP_MM_HP_GMAC_ALLOW_S) +#define PMS_LP_MM_HP_GMAC_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_GMAC_ALLOW_S 15 +/** PMS_LP_MM_HP_USB_PHY_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * high-speed USB 2.0 OTG PHY. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_USB_PHY_ALLOW (BIT(16)) +#define PMS_LP_MM_HP_USB_PHY_ALLOW_M (PMS_LP_MM_HP_USB_PHY_ALLOW_V << PMS_LP_MM_HP_USB_PHY_ALLOW_S) +#define PMS_LP_MM_HP_USB_PHY_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_USB_PHY_ALLOW_S 16 +/** PMS_LP_MM_HP_PVT_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PVT. + * 0: Not allowed + * 1: Allow + */ +#define PMS_LP_MM_HP_PVT_ALLOW (BIT(17)) +#define PMS_LP_MM_HP_PVT_ALLOW_M (PMS_LP_MM_HP_PVT_ALLOW_V << PMS_LP_MM_HP_PVT_ALLOW_S) +#define PMS_LP_MM_HP_PVT_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_PVT_ALLOW_S 17 +/** PMS_LP_MM_HP_CSI_HOST_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP MIPI CSI + * host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_CSI_HOST_ALLOW (BIT(18)) +#define PMS_LP_MM_HP_CSI_HOST_ALLOW_M (PMS_LP_MM_HP_CSI_HOST_ALLOW_V << PMS_LP_MM_HP_CSI_HOST_ALLOW_S) +#define PMS_LP_MM_HP_CSI_HOST_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_CSI_HOST_ALLOW_S 18 +/** PMS_LP_MM_HP_DSI_HOST_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP MIPI DSI + * host. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_DSI_HOST_ALLOW (BIT(19)) +#define PMS_LP_MM_HP_DSI_HOST_ALLOW_M (PMS_LP_MM_HP_DSI_HOST_ALLOW_V << PMS_LP_MM_HP_DSI_HOST_ALLOW_S) +#define PMS_LP_MM_HP_DSI_HOST_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_DSI_HOST_ALLOW_S 19 +/** PMS_LP_MM_HP_ISP_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP ISP. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_ISP_ALLOW (BIT(20)) +#define PMS_LP_MM_HP_ISP_ALLOW_M (PMS_LP_MM_HP_ISP_ALLOW_V << PMS_LP_MM_HP_ISP_ALLOW_S) +#define PMS_LP_MM_HP_ISP_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_ISP_ALLOW_S 20 +/** PMS_LP_MM_HP_H264_CORE_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP H264 + * Encoder. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_H264_CORE_ALLOW (BIT(21)) +#define PMS_LP_MM_HP_H264_CORE_ALLOW_M (PMS_LP_MM_HP_H264_CORE_ALLOW_V << PMS_LP_MM_HP_H264_CORE_ALLOW_S) +#define PMS_LP_MM_HP_H264_CORE_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_H264_CORE_ALLOW_S 21 +/** PMS_LP_MM_HP_RMT_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP RMT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_RMT_ALLOW (BIT(22)) +#define PMS_LP_MM_HP_RMT_ALLOW_M (PMS_LP_MM_HP_RMT_ALLOW_V << PMS_LP_MM_HP_RMT_ALLOW_S) +#define PMS_LP_MM_HP_RMT_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_RMT_ALLOW_S 22 +/** PMS_LP_MM_HP_BITSRAMBLER_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP bit + * scrambler. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_BITSRAMBLER_ALLOW (BIT(23)) +#define PMS_LP_MM_HP_BITSRAMBLER_ALLOW_M (PMS_LP_MM_HP_BITSRAMBLER_ALLOW_V << PMS_LP_MM_HP_BITSRAMBLER_ALLOW_S) +#define PMS_LP_MM_HP_BITSRAMBLER_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_BITSRAMBLER_ALLOW_S 23 +/** PMS_LP_MM_HP_AXI_ICM_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP AXI ICM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_AXI_ICM_ALLOW (BIT(24)) +#define PMS_LP_MM_HP_AXI_ICM_ALLOW_M (PMS_LP_MM_HP_AXI_ICM_ALLOW_V << PMS_LP_MM_HP_AXI_ICM_ALLOW_S) +#define PMS_LP_MM_HP_AXI_ICM_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_AXI_ICM_ALLOW_S 24 +/** PMS_LP_MM_HP_PERI_PMS_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access + * HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_PERI_PMS_ALLOW (BIT(25)) +#define PMS_LP_MM_HP_PERI_PMS_ALLOW_M (PMS_LP_MM_HP_PERI_PMS_ALLOW_V << PMS_LP_MM_HP_PERI_PMS_ALLOW_S) +#define PMS_LP_MM_HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_PERI_PMS_ALLOW_S 25 +/** PMS_LP_MM_LP2HP_PERI_PMS_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access + * LP2HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP2HP_PERI_PMS_ALLOW (BIT(26)) +#define PMS_LP_MM_LP2HP_PERI_PMS_ALLOW_M (PMS_LP_MM_LP2HP_PERI_PMS_ALLOW_V << PMS_LP_MM_LP2HP_PERI_PMS_ALLOW_S) +#define PMS_LP_MM_LP2HP_PERI_PMS_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP2HP_PERI_PMS_ALLOW_S 26 +/** PMS_LP_MM_DMA_PMS_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access + * HP_DMA_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_DMA_PMS_ALLOW (BIT(27)) +#define PMS_LP_MM_DMA_PMS_ALLOW_M (PMS_LP_MM_DMA_PMS_ALLOW_V << PMS_LP_MM_DMA_PMS_ALLOW_S) +#define PMS_LP_MM_DMA_PMS_ALLOW_V 0x00000001U +#define PMS_LP_MM_DMA_PMS_ALLOW_S 27 +/** PMS_LP_MM_HP_H264_DMA2D_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_H264_DMA2D_ALLOW (BIT(28)) +#define PMS_LP_MM_HP_H264_DMA2D_ALLOW_M (PMS_LP_MM_HP_H264_DMA2D_ALLOW_V << PMS_LP_MM_HP_H264_DMA2D_ALLOW_S) +#define PMS_LP_MM_HP_H264_DMA2D_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_H264_DMA2D_ALLOW_S 28 -/** TEE_LP_MM_PMS_REG2_REG register - * NA - */ -#define TEE_LP_MM_PMS_REG2_REG (DR_REG_TEE_BASE + 0xa4) -/** TEE_REG_LP_MM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_MCPWM0_ALLOW (BIT(0)) -#define TEE_REG_LP_MM_HP_MCPWM0_ALLOW_M (TEE_REG_LP_MM_HP_MCPWM0_ALLOW_V << TEE_REG_LP_MM_HP_MCPWM0_ALLOW_S) -#define TEE_REG_LP_MM_HP_MCPWM0_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_MCPWM0_ALLOW_S 0 -/** TEE_REG_LP_MM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_MCPWM1_ALLOW (BIT(1)) -#define TEE_REG_LP_MM_HP_MCPWM1_ALLOW_M (TEE_REG_LP_MM_HP_MCPWM1_ALLOW_V << TEE_REG_LP_MM_HP_MCPWM1_ALLOW_S) -#define TEE_REG_LP_MM_HP_MCPWM1_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_MCPWM1_ALLOW_S 1 -/** TEE_REG_LP_MM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_TIMER_GROUP0_ALLOW (BIT(2)) -#define TEE_REG_LP_MM_HP_TIMER_GROUP0_ALLOW_M (TEE_REG_LP_MM_HP_TIMER_GROUP0_ALLOW_V << TEE_REG_LP_MM_HP_TIMER_GROUP0_ALLOW_S) -#define TEE_REG_LP_MM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_TIMER_GROUP0_ALLOW_S 2 -/** TEE_REG_LP_MM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_TIMER_GROUP1_ALLOW (BIT(3)) -#define TEE_REG_LP_MM_HP_TIMER_GROUP1_ALLOW_M (TEE_REG_LP_MM_HP_TIMER_GROUP1_ALLOW_V << TEE_REG_LP_MM_HP_TIMER_GROUP1_ALLOW_S) -#define TEE_REG_LP_MM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_TIMER_GROUP1_ALLOW_S 3 -/** TEE_REG_LP_MM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_I2C0_ALLOW (BIT(4)) -#define TEE_REG_LP_MM_HP_I2C0_ALLOW_M (TEE_REG_LP_MM_HP_I2C0_ALLOW_V << TEE_REG_LP_MM_HP_I2C0_ALLOW_S) -#define TEE_REG_LP_MM_HP_I2C0_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_I2C0_ALLOW_S 4 -/** TEE_REG_LP_MM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_I2C1_ALLOW (BIT(5)) -#define TEE_REG_LP_MM_HP_I2C1_ALLOW_M (TEE_REG_LP_MM_HP_I2C1_ALLOW_V << TEE_REG_LP_MM_HP_I2C1_ALLOW_S) -#define TEE_REG_LP_MM_HP_I2C1_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_I2C1_ALLOW_S 5 -/** TEE_REG_LP_MM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_I2S0_ALLOW (BIT(6)) -#define TEE_REG_LP_MM_HP_I2S0_ALLOW_M (TEE_REG_LP_MM_HP_I2S0_ALLOW_V << TEE_REG_LP_MM_HP_I2S0_ALLOW_S) -#define TEE_REG_LP_MM_HP_I2S0_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_I2S0_ALLOW_S 6 -/** TEE_REG_LP_MM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_I2S1_ALLOW (BIT(7)) -#define TEE_REG_LP_MM_HP_I2S1_ALLOW_M (TEE_REG_LP_MM_HP_I2S1_ALLOW_V << TEE_REG_LP_MM_HP_I2S1_ALLOW_S) -#define TEE_REG_LP_MM_HP_I2S1_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_I2S1_ALLOW_S 7 -/** TEE_REG_LP_MM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_I2S2_ALLOW (BIT(8)) -#define TEE_REG_LP_MM_HP_I2S2_ALLOW_M (TEE_REG_LP_MM_HP_I2S2_ALLOW_V << TEE_REG_LP_MM_HP_I2S2_ALLOW_S) -#define TEE_REG_LP_MM_HP_I2S2_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_I2S2_ALLOW_S 8 -/** TEE_REG_LP_MM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_PCNT_ALLOW (BIT(9)) -#define TEE_REG_LP_MM_HP_PCNT_ALLOW_M (TEE_REG_LP_MM_HP_PCNT_ALLOW_V << TEE_REG_LP_MM_HP_PCNT_ALLOW_S) -#define TEE_REG_LP_MM_HP_PCNT_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_PCNT_ALLOW_S 9 -/** TEE_REG_LP_MM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_UART0_ALLOW (BIT(10)) -#define TEE_REG_LP_MM_HP_UART0_ALLOW_M (TEE_REG_LP_MM_HP_UART0_ALLOW_V << TEE_REG_LP_MM_HP_UART0_ALLOW_S) -#define TEE_REG_LP_MM_HP_UART0_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_UART0_ALLOW_S 10 -/** TEE_REG_LP_MM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_UART1_ALLOW (BIT(11)) -#define TEE_REG_LP_MM_HP_UART1_ALLOW_M (TEE_REG_LP_MM_HP_UART1_ALLOW_V << TEE_REG_LP_MM_HP_UART1_ALLOW_S) -#define TEE_REG_LP_MM_HP_UART1_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_UART1_ALLOW_S 11 -/** TEE_REG_LP_MM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_UART2_ALLOW (BIT(12)) -#define TEE_REG_LP_MM_HP_UART2_ALLOW_M (TEE_REG_LP_MM_HP_UART2_ALLOW_V << TEE_REG_LP_MM_HP_UART2_ALLOW_S) -#define TEE_REG_LP_MM_HP_UART2_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_UART2_ALLOW_S 12 -/** TEE_REG_LP_MM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_UART3_ALLOW (BIT(13)) -#define TEE_REG_LP_MM_HP_UART3_ALLOW_M (TEE_REG_LP_MM_HP_UART3_ALLOW_V << TEE_REG_LP_MM_HP_UART3_ALLOW_S) -#define TEE_REG_LP_MM_HP_UART3_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_UART3_ALLOW_S 13 -/** TEE_REG_LP_MM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_UART4_ALLOW (BIT(14)) -#define TEE_REG_LP_MM_HP_UART4_ALLOW_M (TEE_REG_LP_MM_HP_UART4_ALLOW_V << TEE_REG_LP_MM_HP_UART4_ALLOW_S) -#define TEE_REG_LP_MM_HP_UART4_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_UART4_ALLOW_S 14 -/** TEE_REG_LP_MM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_PARLIO_ALLOW (BIT(15)) -#define TEE_REG_LP_MM_HP_PARLIO_ALLOW_M (TEE_REG_LP_MM_HP_PARLIO_ALLOW_V << TEE_REG_LP_MM_HP_PARLIO_ALLOW_S) -#define TEE_REG_LP_MM_HP_PARLIO_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_PARLIO_ALLOW_S 15 -/** TEE_REG_LP_MM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_GPSPI2_ALLOW (BIT(16)) -#define TEE_REG_LP_MM_HP_GPSPI2_ALLOW_M (TEE_REG_LP_MM_HP_GPSPI2_ALLOW_V << TEE_REG_LP_MM_HP_GPSPI2_ALLOW_S) -#define TEE_REG_LP_MM_HP_GPSPI2_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_GPSPI2_ALLOW_S 16 -/** TEE_REG_LP_MM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_GPSPI3_ALLOW (BIT(17)) -#define TEE_REG_LP_MM_HP_GPSPI3_ALLOW_M (TEE_REG_LP_MM_HP_GPSPI3_ALLOW_V << TEE_REG_LP_MM_HP_GPSPI3_ALLOW_S) -#define TEE_REG_LP_MM_HP_GPSPI3_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_GPSPI3_ALLOW_S 17 -/** TEE_REG_LP_MM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_USBDEVICE_ALLOW (BIT(18)) -#define TEE_REG_LP_MM_HP_USBDEVICE_ALLOW_M (TEE_REG_LP_MM_HP_USBDEVICE_ALLOW_V << TEE_REG_LP_MM_HP_USBDEVICE_ALLOW_S) -#define TEE_REG_LP_MM_HP_USBDEVICE_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_USBDEVICE_ALLOW_S 18 -/** TEE_REG_LP_MM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_LEDC_ALLOW (BIT(19)) -#define TEE_REG_LP_MM_HP_LEDC_ALLOW_M (TEE_REG_LP_MM_HP_LEDC_ALLOW_V << TEE_REG_LP_MM_HP_LEDC_ALLOW_S) -#define TEE_REG_LP_MM_HP_LEDC_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_LEDC_ALLOW_S 19 -/** TEE_REG_LP_MM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_ETM_ALLOW (BIT(21)) -#define TEE_REG_LP_MM_HP_ETM_ALLOW_M (TEE_REG_LP_MM_HP_ETM_ALLOW_V << TEE_REG_LP_MM_HP_ETM_ALLOW_S) -#define TEE_REG_LP_MM_HP_ETM_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_ETM_ALLOW_S 21 -/** TEE_REG_LP_MM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_INTRMTX_ALLOW (BIT(22)) -#define TEE_REG_LP_MM_HP_INTRMTX_ALLOW_M (TEE_REG_LP_MM_HP_INTRMTX_ALLOW_V << TEE_REG_LP_MM_HP_INTRMTX_ALLOW_S) -#define TEE_REG_LP_MM_HP_INTRMTX_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_INTRMTX_ALLOW_S 22 -/** TEE_REG_LP_MM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_TWAI0_ALLOW (BIT(23)) -#define TEE_REG_LP_MM_HP_TWAI0_ALLOW_M (TEE_REG_LP_MM_HP_TWAI0_ALLOW_V << TEE_REG_LP_MM_HP_TWAI0_ALLOW_S) -#define TEE_REG_LP_MM_HP_TWAI0_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_TWAI0_ALLOW_S 23 -/** TEE_REG_LP_MM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_TWAI1_ALLOW (BIT(24)) -#define TEE_REG_LP_MM_HP_TWAI1_ALLOW_M (TEE_REG_LP_MM_HP_TWAI1_ALLOW_V << TEE_REG_LP_MM_HP_TWAI1_ALLOW_S) -#define TEE_REG_LP_MM_HP_TWAI1_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_TWAI1_ALLOW_S 24 -/** TEE_REG_LP_MM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_TWAI2_ALLOW (BIT(25)) -#define TEE_REG_LP_MM_HP_TWAI2_ALLOW_M (TEE_REG_LP_MM_HP_TWAI2_ALLOW_V << TEE_REG_LP_MM_HP_TWAI2_ALLOW_S) -#define TEE_REG_LP_MM_HP_TWAI2_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_TWAI2_ALLOW_S 25 -/** TEE_REG_LP_MM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_I3C_MST_ALLOW (BIT(26)) -#define TEE_REG_LP_MM_HP_I3C_MST_ALLOW_M (TEE_REG_LP_MM_HP_I3C_MST_ALLOW_V << TEE_REG_LP_MM_HP_I3C_MST_ALLOW_S) -#define TEE_REG_LP_MM_HP_I3C_MST_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_I3C_MST_ALLOW_S 26 -/** TEE_REG_LP_MM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_I3C_SLV_ALLOW (BIT(27)) -#define TEE_REG_LP_MM_HP_I3C_SLV_ALLOW_M (TEE_REG_LP_MM_HP_I3C_SLV_ALLOW_V << TEE_REG_LP_MM_HP_I3C_SLV_ALLOW_S) -#define TEE_REG_LP_MM_HP_I3C_SLV_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_I3C_SLV_ALLOW_S 27 -/** TEE_REG_LP_MM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_LCDCAM_ALLOW (BIT(28)) -#define TEE_REG_LP_MM_HP_LCDCAM_ALLOW_M (TEE_REG_LP_MM_HP_LCDCAM_ALLOW_V << TEE_REG_LP_MM_HP_LCDCAM_ALLOW_S) -#define TEE_REG_LP_MM_HP_LCDCAM_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_LCDCAM_ALLOW_S 28 -/** TEE_REG_LP_MM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_ADC_ALLOW (BIT(30)) -#define TEE_REG_LP_MM_HP_ADC_ALLOW_M (TEE_REG_LP_MM_HP_ADC_ALLOW_V << TEE_REG_LP_MM_HP_ADC_ALLOW_S) -#define TEE_REG_LP_MM_HP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_ADC_ALLOW_S 30 -/** TEE_REG_LP_MM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_UHCI_ALLOW (BIT(31)) -#define TEE_REG_LP_MM_HP_UHCI_ALLOW_M (TEE_REG_LP_MM_HP_UHCI_ALLOW_V << TEE_REG_LP_MM_HP_UHCI_ALLOW_S) -#define TEE_REG_LP_MM_HP_UHCI_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_UHCI_ALLOW_S 31 +/** PMS_LP_MM_PMS_REG2_REG register + * Permission control register2 for the LP CPU in machine mode + */ +#define PMS_LP_MM_PMS_REG2_REG (DR_REG_LP2HP_PERI_PMS_BASE + 0xa4) +/** PMS_LP_MM_HP_MCPWM0_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP MCPWM0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_MCPWM0_ALLOW (BIT(0)) +#define PMS_LP_MM_HP_MCPWM0_ALLOW_M (PMS_LP_MM_HP_MCPWM0_ALLOW_V << PMS_LP_MM_HP_MCPWM0_ALLOW_S) +#define PMS_LP_MM_HP_MCPWM0_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_MCPWM0_ALLOW_S 0 +/** PMS_LP_MM_HP_MCPWM1_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP MCPWM1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_MCPWM1_ALLOW (BIT(1)) +#define PMS_LP_MM_HP_MCPWM1_ALLOW_M (PMS_LP_MM_HP_MCPWM1_ALLOW_V << PMS_LP_MM_HP_MCPWM1_ALLOW_S) +#define PMS_LP_MM_HP_MCPWM1_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_MCPWM1_ALLOW_S 1 +/** PMS_LP_MM_HP_TIMER_GROUP0_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP timer + * group0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_TIMER_GROUP0_ALLOW (BIT(2)) +#define PMS_LP_MM_HP_TIMER_GROUP0_ALLOW_M (PMS_LP_MM_HP_TIMER_GROUP0_ALLOW_V << PMS_LP_MM_HP_TIMER_GROUP0_ALLOW_S) +#define PMS_LP_MM_HP_TIMER_GROUP0_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_TIMER_GROUP0_ALLOW_S 2 +/** PMS_LP_MM_HP_TIMER_GROUP1_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP timer + * group1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_TIMER_GROUP1_ALLOW (BIT(3)) +#define PMS_LP_MM_HP_TIMER_GROUP1_ALLOW_M (PMS_LP_MM_HP_TIMER_GROUP1_ALLOW_V << PMS_LP_MM_HP_TIMER_GROUP1_ALLOW_S) +#define PMS_LP_MM_HP_TIMER_GROUP1_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_TIMER_GROUP1_ALLOW_S 3 +/** PMS_LP_MM_HP_I2C0_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2C0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_I2C0_ALLOW (BIT(4)) +#define PMS_LP_MM_HP_I2C0_ALLOW_M (PMS_LP_MM_HP_I2C0_ALLOW_V << PMS_LP_MM_HP_I2C0_ALLOW_S) +#define PMS_LP_MM_HP_I2C0_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_I2C0_ALLOW_S 4 +/** PMS_LP_MM_HP_I2C1_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2C1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_I2C1_ALLOW (BIT(5)) +#define PMS_LP_MM_HP_I2C1_ALLOW_M (PMS_LP_MM_HP_I2C1_ALLOW_V << PMS_LP_MM_HP_I2C1_ALLOW_S) +#define PMS_LP_MM_HP_I2C1_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_I2C1_ALLOW_S 5 +/** PMS_LP_MM_HP_I2S0_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2S0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_I2S0_ALLOW (BIT(6)) +#define PMS_LP_MM_HP_I2S0_ALLOW_M (PMS_LP_MM_HP_I2S0_ALLOW_V << PMS_LP_MM_HP_I2S0_ALLOW_S) +#define PMS_LP_MM_HP_I2S0_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_I2S0_ALLOW_S 6 +/** PMS_LP_MM_HP_I2S1_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2S1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_I2S1_ALLOW (BIT(7)) +#define PMS_LP_MM_HP_I2S1_ALLOW_M (PMS_LP_MM_HP_I2S1_ALLOW_V << PMS_LP_MM_HP_I2S1_ALLOW_S) +#define PMS_LP_MM_HP_I2S1_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_I2S1_ALLOW_S 7 +/** PMS_LP_MM_HP_I2S2_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2S2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_I2S2_ALLOW (BIT(8)) +#define PMS_LP_MM_HP_I2S2_ALLOW_M (PMS_LP_MM_HP_I2S2_ALLOW_V << PMS_LP_MM_HP_I2S2_ALLOW_S) +#define PMS_LP_MM_HP_I2S2_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_I2S2_ALLOW_S 8 +/** PMS_LP_MM_HP_PCNT_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PCNT. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_PCNT_ALLOW (BIT(9)) +#define PMS_LP_MM_HP_PCNT_ALLOW_M (PMS_LP_MM_HP_PCNT_ALLOW_V << PMS_LP_MM_HP_PCNT_ALLOW_S) +#define PMS_LP_MM_HP_PCNT_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_PCNT_ALLOW_S 9 +/** PMS_LP_MM_HP_UART0_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_UART0_ALLOW (BIT(10)) +#define PMS_LP_MM_HP_UART0_ALLOW_M (PMS_LP_MM_HP_UART0_ALLOW_V << PMS_LP_MM_HP_UART0_ALLOW_S) +#define PMS_LP_MM_HP_UART0_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_UART0_ALLOW_S 10 +/** PMS_LP_MM_HP_UART1_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_UART1_ALLOW (BIT(11)) +#define PMS_LP_MM_HP_UART1_ALLOW_M (PMS_LP_MM_HP_UART1_ALLOW_V << PMS_LP_MM_HP_UART1_ALLOW_S) +#define PMS_LP_MM_HP_UART1_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_UART1_ALLOW_S 11 +/** PMS_LP_MM_HP_UART2_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_UART2_ALLOW (BIT(12)) +#define PMS_LP_MM_HP_UART2_ALLOW_M (PMS_LP_MM_HP_UART2_ALLOW_V << PMS_LP_MM_HP_UART2_ALLOW_S) +#define PMS_LP_MM_HP_UART2_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_UART2_ALLOW_S 12 +/** PMS_LP_MM_HP_UART3_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_UART3_ALLOW (BIT(13)) +#define PMS_LP_MM_HP_UART3_ALLOW_M (PMS_LP_MM_HP_UART3_ALLOW_V << PMS_LP_MM_HP_UART3_ALLOW_S) +#define PMS_LP_MM_HP_UART3_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_UART3_ALLOW_S 13 +/** PMS_LP_MM_HP_UART4_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART4. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_UART4_ALLOW (BIT(14)) +#define PMS_LP_MM_HP_UART4_ALLOW_M (PMS_LP_MM_HP_UART4_ALLOW_V << PMS_LP_MM_HP_UART4_ALLOW_S) +#define PMS_LP_MM_HP_UART4_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_UART4_ALLOW_S 14 +/** PMS_LP_MM_HP_PARLIO_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PARLIO. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_PARLIO_ALLOW (BIT(15)) +#define PMS_LP_MM_HP_PARLIO_ALLOW_M (PMS_LP_MM_HP_PARLIO_ALLOW_V << PMS_LP_MM_HP_PARLIO_ALLOW_S) +#define PMS_LP_MM_HP_PARLIO_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_PARLIO_ALLOW_S 15 +/** PMS_LP_MM_HP_GPSPI2_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GP-SPI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_GPSPI2_ALLOW (BIT(16)) +#define PMS_LP_MM_HP_GPSPI2_ALLOW_M (PMS_LP_MM_HP_GPSPI2_ALLOW_V << PMS_LP_MM_HP_GPSPI2_ALLOW_S) +#define PMS_LP_MM_HP_GPSPI2_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_GPSPI2_ALLOW_S 16 +/** PMS_LP_MM_HP_GPSPI3_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GP-SPI3. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_GPSPI3_ALLOW (BIT(17)) +#define PMS_LP_MM_HP_GPSPI3_ALLOW_M (PMS_LP_MM_HP_GPSPI3_ALLOW_V << PMS_LP_MM_HP_GPSPI3_ALLOW_S) +#define PMS_LP_MM_HP_GPSPI3_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_GPSPI3_ALLOW_S 17 +/** PMS_LP_MM_HP_USBDEVICE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * USB/Serial JTAG Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_USBDEVICE_ALLOW (BIT(18)) +#define PMS_LP_MM_HP_USBDEVICE_ALLOW_M (PMS_LP_MM_HP_USBDEVICE_ALLOW_V << PMS_LP_MM_HP_USBDEVICE_ALLOW_S) +#define PMS_LP_MM_HP_USBDEVICE_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_USBDEVICE_ALLOW_S 18 +/** PMS_LP_MM_HP_LEDC_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP LEDC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_LEDC_ALLOW (BIT(19)) +#define PMS_LP_MM_HP_LEDC_ALLOW_M (PMS_LP_MM_HP_LEDC_ALLOW_V << PMS_LP_MM_HP_LEDC_ALLOW_S) +#define PMS_LP_MM_HP_LEDC_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_LEDC_ALLOW_S 19 +/** PMS_LP_MM_HP_ETM_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP ETM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_ETM_ALLOW (BIT(21)) +#define PMS_LP_MM_HP_ETM_ALLOW_M (PMS_LP_MM_HP_ETM_ALLOW_V << PMS_LP_MM_HP_ETM_ALLOW_S) +#define PMS_LP_MM_HP_ETM_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_ETM_ALLOW_S 21 +/** PMS_LP_MM_HP_INTRMTX_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP interrupt + * matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_INTRMTX_ALLOW (BIT(22)) +#define PMS_LP_MM_HP_INTRMTX_ALLOW_M (PMS_LP_MM_HP_INTRMTX_ALLOW_V << PMS_LP_MM_HP_INTRMTX_ALLOW_S) +#define PMS_LP_MM_HP_INTRMTX_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_INTRMTX_ALLOW_S 22 +/** PMS_LP_MM_HP_TWAI0_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP TWAI0. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_TWAI0_ALLOW (BIT(23)) +#define PMS_LP_MM_HP_TWAI0_ALLOW_M (PMS_LP_MM_HP_TWAI0_ALLOW_V << PMS_LP_MM_HP_TWAI0_ALLOW_S) +#define PMS_LP_MM_HP_TWAI0_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_TWAI0_ALLOW_S 23 +/** PMS_LP_MM_HP_TWAI1_ALLOW : R/W; bitpos: [24]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP TWAI1. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_TWAI1_ALLOW (BIT(24)) +#define PMS_LP_MM_HP_TWAI1_ALLOW_M (PMS_LP_MM_HP_TWAI1_ALLOW_V << PMS_LP_MM_HP_TWAI1_ALLOW_S) +#define PMS_LP_MM_HP_TWAI1_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_TWAI1_ALLOW_S 24 +/** PMS_LP_MM_HP_TWAI2_ALLOW : R/W; bitpos: [25]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP TWAI2. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_TWAI2_ALLOW (BIT(25)) +#define PMS_LP_MM_HP_TWAI2_ALLOW_M (PMS_LP_MM_HP_TWAI2_ALLOW_V << PMS_LP_MM_HP_TWAI2_ALLOW_S) +#define PMS_LP_MM_HP_TWAI2_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_TWAI2_ALLOW_S 25 +/** PMS_LP_MM_HP_I3C_MST_ALLOW : R/W; bitpos: [26]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I3C + * master controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_I3C_MST_ALLOW (BIT(26)) +#define PMS_LP_MM_HP_I3C_MST_ALLOW_M (PMS_LP_MM_HP_I3C_MST_ALLOW_V << PMS_LP_MM_HP_I3C_MST_ALLOW_S) +#define PMS_LP_MM_HP_I3C_MST_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_I3C_MST_ALLOW_S 26 +/** PMS_LP_MM_HP_I3C_SLV_ALLOW : R/W; bitpos: [27]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I3C slave + * controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_I3C_SLV_ALLOW (BIT(27)) +#define PMS_LP_MM_HP_I3C_SLV_ALLOW_M (PMS_LP_MM_HP_I3C_SLV_ALLOW_V << PMS_LP_MM_HP_I3C_SLV_ALLOW_S) +#define PMS_LP_MM_HP_I3C_SLV_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_I3C_SLV_ALLOW_S 27 +/** PMS_LP_MM_HP_LCDCAM_ALLOW : R/W; bitpos: [28]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP LCD_CAM. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_LCDCAM_ALLOW (BIT(28)) +#define PMS_LP_MM_HP_LCDCAM_ALLOW_M (PMS_LP_MM_HP_LCDCAM_ALLOW_V << PMS_LP_MM_HP_LCDCAM_ALLOW_S) +#define PMS_LP_MM_HP_LCDCAM_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_LCDCAM_ALLOW_S 28 +/** PMS_LP_MM_HP_ADC_ALLOW : R/W; bitpos: [30]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_ADC_ALLOW (BIT(30)) +#define PMS_LP_MM_HP_ADC_ALLOW_M (PMS_LP_MM_HP_ADC_ALLOW_V << PMS_LP_MM_HP_ADC_ALLOW_S) +#define PMS_LP_MM_HP_ADC_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_ADC_ALLOW_S 30 +/** PMS_LP_MM_HP_UHCI_ALLOW : R/W; bitpos: [31]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UHCI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_UHCI_ALLOW (BIT(31)) +#define PMS_LP_MM_HP_UHCI_ALLOW_M (PMS_LP_MM_HP_UHCI_ALLOW_V << PMS_LP_MM_HP_UHCI_ALLOW_S) +#define PMS_LP_MM_HP_UHCI_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_UHCI_ALLOW_S 31 -/** TEE_LP_MM_PMS_REG3_REG register - * NA - */ -#define TEE_LP_MM_PMS_REG3_REG (DR_REG_TEE_BASE + 0x11c) -/** TEE_REG_LP_MM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_GPIO_ALLOW (BIT(0)) -#define TEE_REG_LP_MM_HP_GPIO_ALLOW_M (TEE_REG_LP_MM_HP_GPIO_ALLOW_V << TEE_REG_LP_MM_HP_GPIO_ALLOW_S) -#define TEE_REG_LP_MM_HP_GPIO_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_GPIO_ALLOW_S 0 -/** TEE_REG_LP_MM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_IOMUX_ALLOW (BIT(1)) -#define TEE_REG_LP_MM_HP_IOMUX_ALLOW_M (TEE_REG_LP_MM_HP_IOMUX_ALLOW_V << TEE_REG_LP_MM_HP_IOMUX_ALLOW_S) -#define TEE_REG_LP_MM_HP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_IOMUX_ALLOW_S 1 -/** TEE_REG_LP_MM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_SYSTIMER_ALLOW (BIT(2)) -#define TEE_REG_LP_MM_HP_SYSTIMER_ALLOW_M (TEE_REG_LP_MM_HP_SYSTIMER_ALLOW_V << TEE_REG_LP_MM_HP_SYSTIMER_ALLOW_S) -#define TEE_REG_LP_MM_HP_SYSTIMER_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_SYSTIMER_ALLOW_S 2 -/** TEE_REG_LP_MM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_SYS_REG_ALLOW (BIT(3)) -#define TEE_REG_LP_MM_HP_SYS_REG_ALLOW_M (TEE_REG_LP_MM_HP_SYS_REG_ALLOW_V << TEE_REG_LP_MM_HP_SYS_REG_ALLOW_S) -#define TEE_REG_LP_MM_HP_SYS_REG_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_SYS_REG_ALLOW_S 3 -/** TEE_REG_LP_MM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP_CLKRST_ALLOW (BIT(4)) -#define TEE_REG_LP_MM_HP_CLKRST_ALLOW_M (TEE_REG_LP_MM_HP_CLKRST_ALLOW_V << TEE_REG_LP_MM_HP_CLKRST_ALLOW_S) -#define TEE_REG_LP_MM_HP_CLKRST_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP_CLKRST_ALLOW_S 4 +/** PMS_LP_MM_PMS_REG3_REG register + * Permission control register3 for the LP CPU in machine mode + */ +#define PMS_LP_MM_PMS_REG3_REG (DR_REG_LP2HP_PERI_PMS_BASE + 0x11c) +/** PMS_LP_MM_HP_GPIO_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GPIO + * Matrix. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_GPIO_ALLOW (BIT(0)) +#define PMS_LP_MM_HP_GPIO_ALLOW_M (PMS_LP_MM_HP_GPIO_ALLOW_V << PMS_LP_MM_HP_GPIO_ALLOW_S) +#define PMS_LP_MM_HP_GPIO_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_GPIO_ALLOW_S 0 +/** PMS_LP_MM_HP_IOMUX_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_IOMUX_ALLOW (BIT(1)) +#define PMS_LP_MM_HP_IOMUX_ALLOW_M (PMS_LP_MM_HP_IOMUX_ALLOW_V << PMS_LP_MM_HP_IOMUX_ALLOW_S) +#define PMS_LP_MM_HP_IOMUX_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_IOMUX_ALLOW_S 1 +/** PMS_LP_MM_HP_SYSTIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP system + * timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_SYSTIMER_ALLOW (BIT(2)) +#define PMS_LP_MM_HP_SYSTIMER_ALLOW_M (PMS_LP_MM_HP_SYSTIMER_ALLOW_V << PMS_LP_MM_HP_SYSTIMER_ALLOW_S) +#define PMS_LP_MM_HP_SYSTIMER_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_SYSTIMER_ALLOW_S 2 +/** PMS_LP_MM_HP_SYS_REG_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP system + * register. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_SYS_REG_ALLOW (BIT(3)) +#define PMS_LP_MM_HP_SYS_REG_ALLOW_M (PMS_LP_MM_HP_SYS_REG_ALLOW_V << PMS_LP_MM_HP_SYS_REG_ALLOW_S) +#define PMS_LP_MM_HP_SYS_REG_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_SYS_REG_ALLOW_S 3 +/** PMS_LP_MM_HP_CLKRST_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access + * HP_SYS_CLKRST. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP_CLKRST_ALLOW (BIT(4)) +#define PMS_LP_MM_HP_CLKRST_ALLOW_M (PMS_LP_MM_HP_CLKRST_ALLOW_V << PMS_LP_MM_HP_CLKRST_ALLOW_S) +#define PMS_LP_MM_HP_CLKRST_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP_CLKRST_ALLOW_S 4 #ifdef __cplusplus } diff --git a/components/soc/esp32p4/include/soc/lp2hp_peri_pms_struct.h b/components/soc/esp32p4/include/soc/lp2hp_peri_pms_struct.h index 59ee73ee1c1d..8f852dc7aea5 100644 --- a/components/soc/esp32p4/include/soc/lp2hp_peri_pms_struct.h +++ b/components/soc/esp32p4/include/soc/lp2hp_peri_pms_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,398 +10,574 @@ extern "C" { #endif -/** Group: TEE LP2HP PMS DATE REG */ -/** Type of lp2hp_pms_date register - * NA +/** Group: Version Control Registers */ +/** Type of lp2hp_peri_pms_date register + * Version control register */ typedef union { struct { - /** tee_date : R/W; bitpos: [31:0]; default: 2294790; - * NA + /** lp2hp_peri_pms_date : R/W; bitpos: [31:0]; default: 2294790; + * Version control register. */ - uint32_t tee_date:32; + uint32_t lp2hp_peri_pms_date:32; }; uint32_t val; -} tee_lp2hp_pms_date_reg_t; +} pms_lp2hp_peri_pms_date_reg_t; -/** Group: TEE PMS CLK EN REG */ -/** Type of pms_clk_en register - * NA +/** Group: Clock Gating Registers */ +/** Type of lp2hp_peri_pms_clk_en register + * Clock gating register */ typedef union { struct { - /** reg_clk_en : R/W; bitpos: [0]; default: 1; - * NA + /** lp2hp_peri_pms_clk_en : R/W; bitpos: [0]; default: 1; + * Configures whether to keep the clock always on. + * 0: Enable automatic clock gating. + * 1: Keep the clock always on. */ - uint32_t reg_clk_en:1; + uint32_t lp2hp_peri_pms_clk_en:1; uint32_t reserved_1:31; }; uint32_t val; -} tee_pms_clk_en_reg_t; +} pms_lp2hp_peri_pms_clk_en_reg_t; -/** Group: TEE LP MM PMS REG0 REG */ +/** Group: LP CPU Permission Control Registers */ /** Type of lp_mm_pms_reg0 register - * NA + * Permission control register0 for the LP CPU in machine mode */ typedef union { struct { - /** reg_lp_mm_psram_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_lp_mm_psram_allow:1; - /** reg_lp_mm_flash_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_lp_mm_flash_allow:1; - /** reg_lp_mm_l2mem_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_lp_mm_l2mem_allow:1; - /** reg_lp_mm_l2rom_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_lp_mm_l2rom_allow:1; + /** lp_mm_psram_allow : R/W; bitpos: [0]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access external RAM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_psram_allow:1; + /** lp_mm_flash_allow : R/W; bitpos: [1]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access external + * flash without going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_flash_allow:1; + /** lp_mm_l2mem_allow : R/W; bitpos: [2]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP L2M2M + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_l2mem_allow:1; + /** lp_mm_l2rom_allow : R/W; bitpos: [3]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP ROM + * without going through cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_l2rom_allow:1; uint32_t reserved_4:2; - /** reg_lp_mm_trace0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_lp_mm_trace0_allow:1; - /** reg_lp_mm_trace1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_lp_mm_trace1_allow:1; - /** reg_lp_mm_cpu_bus_mon_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_lp_mm_cpu_bus_mon_allow:1; - /** reg_lp_mm_l2mem_mon_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_lp_mm_l2mem_mon_allow:1; - /** reg_lp_mm_tcm_mon_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_lp_mm_tcm_mon_allow:1; - /** reg_lp_mm_cache_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_lp_mm_cache_allow:1; + /** lp_mm_trace0_allow : R/W; bitpos: [6]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access TRACE0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_trace0_allow:1; + /** lp_mm_trace1_allow : R/W; bitpos: [7]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access TRACE1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_trace1_allow:1; + /** lp_mm_cpu_bus_mon_allow : R/W; bitpos: [8]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access CPU bus + * monitor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_cpu_bus_mon_allow:1; + /** lp_mm_l2mem_mon_allow : R/W; bitpos: [9]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access L2MEM + * monitor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_l2mem_mon_allow:1; + /** lp_mm_tcm_mon_allow : R/W; bitpos: [10]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access TCM monitor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_tcm_mon_allow:1; + /** lp_mm_cache_allow : R/W; bitpos: [11]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access cache. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_cache_allow:1; uint32_t reserved_12:20; }; uint32_t val; -} tee_lp_mm_pms_reg0_reg_t; +} pms_lp_mm_pms_reg0_reg_t; - -/** Group: TEE LP MM PMS REG1 REG */ /** Type of lp_mm_pms_reg1 register - * NA + * Permission control register1 for the LP CPU in machine mode */ typedef union { struct { - /** reg_lp_mm_hp_usbotg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_usbotg_allow:1; - /** reg_lp_mm_hp_usbotg11_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_usbotg11_allow:1; - /** reg_lp_mm_hp_usbotg11_wrap_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_usbotg11_wrap_allow:1; - /** reg_lp_mm_hp_gdma_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_gdma_allow:1; - /** reg_lp_mm_hp_regdma_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_regdma_allow:1; - /** reg_lp_mm_hp_sdmmc_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_sdmmc_allow:1; - /** reg_lp_mm_hp_ahb_pdma_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_ahb_pdma_allow:1; - /** reg_lp_mm_hp_jpeg_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_jpeg_allow:1; - /** reg_lp_mm_hp_ppa_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_ppa_allow:1; - /** reg_lp_mm_hp_dma2d_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_dma2d_allow:1; - /** reg_lp_mm_hp_key_manager_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_key_manager_allow:1; - /** reg_lp_mm_hp_axi_pdma_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_axi_pdma_allow:1; - /** reg_lp_mm_hp_flash_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_flash_allow:1; - /** reg_lp_mm_hp_psram_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_psram_allow:1; - /** reg_lp_mm_hp_crypto_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_crypto_allow:1; - /** reg_lp_mm_hp_gmac_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_gmac_allow:1; - /** reg_lp_mm_hp_usb_phy_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_usb_phy_allow:1; - /** reg_lp_mm_hp_pvt_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_pvt_allow:1; - /** reg_lp_mm_hp_csi_host_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_csi_host_allow:1; - /** reg_lp_mm_hp_dsi_host_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_dsi_host_allow:1; - /** reg_lp_mm_hp_isp_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_isp_allow:1; - /** reg_lp_mm_hp_h264_core_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_h264_core_allow:1; - /** reg_lp_mm_hp_rmt_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_rmt_allow:1; - /** reg_lp_mm_hp_bitsrambler_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_bitsrambler_allow:1; - /** reg_lp_mm_hp_axi_icm_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_axi_icm_allow:1; - /** reg_lp_mm_hp_peri_pms_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_peri_pms_allow:1; - /** reg_lp_mm_lp2hp_peri_pms_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp2hp_peri_pms_allow:1; - /** reg_lp_mm_dma_pms_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_lp_mm_dma_pms_allow:1; - /** reg_lp_mm_hp_h264_dma2d_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_h264_dma2d_allow:1; + /** lp_mm_hp_usbotg_allow : R/W; bitpos: [0]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * high-speed USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_usbotg_allow:1; + /** lp_mm_hp_usbotg11_allow : R/W; bitpos: [1]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * full-speed USB 2.0 OTG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_usbotg11_allow:1; + /** lp_mm_hp_usbotg11_wrap_allow : R/W; bitpos: [2]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * full-speed USB 2.0 OTG's wrap. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_usbotg11_wrap_allow:1; + /** lp_mm_hp_gdma_allow : R/W; bitpos: [3]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP DW-GDMA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_gdma_allow:1; + /** lp_mm_hp_regdma_allow : R/W; bitpos: [4]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GDMA (DW + * GDMA). + * 0: Not allowed + * 1: Allow + */ + uint32_t lp_mm_hp_regdma_allow:1; + /** lp_mm_hp_sdmmc_allow : R/W; bitpos: [5]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP SDMMC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_sdmmc_allow:1; + /** lp_mm_hp_ahb_pdma_allow : R/W; bitpos: [6]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access GDMA-AHB. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_ahb_pdma_allow:1; + /** lp_mm_hp_jpeg_allow : R/W; bitpos: [7]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP JPEG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_jpeg_allow:1; + /** lp_mm_hp_ppa_allow : R/W; bitpos: [8]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PPA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_ppa_allow:1; + /** lp_mm_hp_dma2d_allow : R/W; bitpos: [9]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_dma2d_allow:1; + /** lp_mm_hp_key_manager_allow : R/W; bitpos: [10]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP key + * manager. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_key_manager_allow:1; + /** lp_mm_hp_axi_pdma_allow : R/W; bitpos: [11]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GDMA-AXI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_axi_pdma_allow:1; + /** lp_mm_hp_flash_allow : R/W; bitpos: [12]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP flash + * MSPI controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_flash_allow:1; + /** lp_mm_hp_psram_allow : R/W; bitpos: [13]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PSRAM + * MSPI controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_psram_allow:1; + /** lp_mm_hp_crypto_allow : R/W; bitpos: [14]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP CRYPTO. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_crypto_allow:1; + /** lp_mm_hp_gmac_allow : R/W; bitpos: [15]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP EMAC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_gmac_allow:1; + /** lp_mm_hp_usb_phy_allow : R/W; bitpos: [16]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * high-speed USB 2.0 OTG PHY. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_usb_phy_allow:1; + /** lp_mm_hp_pvt_allow : R/W; bitpos: [17]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PVT. + * 0: Not allowed + * 1: Allow + */ + uint32_t lp_mm_hp_pvt_allow:1; + /** lp_mm_hp_csi_host_allow : R/W; bitpos: [18]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP MIPI CSI + * host. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_csi_host_allow:1; + /** lp_mm_hp_dsi_host_allow : R/W; bitpos: [19]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP MIPI DSI + * host. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_dsi_host_allow:1; + /** lp_mm_hp_isp_allow : R/W; bitpos: [20]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP ISP. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_isp_allow:1; + /** lp_mm_hp_h264_core_allow : R/W; bitpos: [21]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP H264 + * Encoder. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_h264_core_allow:1; + /** lp_mm_hp_rmt_allow : R/W; bitpos: [22]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP RMT. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_rmt_allow:1; + /** lp_mm_hp_bitsrambler_allow : R/W; bitpos: [23]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP bit + * scrambler. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_bitsrambler_allow:1; + /** lp_mm_hp_axi_icm_allow : R/W; bitpos: [24]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP AXI ICM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_axi_icm_allow:1; + /** lp_mm_hp_peri_pms_allow : R/W; bitpos: [25]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access + * HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_peri_pms_allow:1; + /** lp_mm_lp2hp_peri_pms_allow : R/W; bitpos: [26]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access + * LP2HP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp2hp_peri_pms_allow:1; + /** lp_mm_dma_pms_allow : R/W; bitpos: [27]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access + * HP_DMA_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_dma_pms_allow:1; + /** lp_mm_hp_h264_dma2d_allow : R/W; bitpos: [28]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access 2D-DMA. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_h264_dma2d_allow:1; uint32_t reserved_29:3; }; uint32_t val; -} tee_lp_mm_pms_reg1_reg_t; - +} pms_lp_mm_pms_reg1_reg_t; -/** Group: TEE LP MM PMS REG2 REG */ /** Type of lp_mm_pms_reg2 register - * NA + * Permission control register2 for the LP CPU in machine mode */ typedef union { struct { - /** reg_lp_mm_hp_mcpwm0_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_mcpwm0_allow:1; - /** reg_lp_mm_hp_mcpwm1_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_mcpwm1_allow:1; - /** reg_lp_mm_hp_timer_group0_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_timer_group0_allow:1; - /** reg_lp_mm_hp_timer_group1_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_timer_group1_allow:1; - /** reg_lp_mm_hp_i2c0_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_i2c0_allow:1; - /** reg_lp_mm_hp_i2c1_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_i2c1_allow:1; - /** reg_lp_mm_hp_i2s0_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_i2s0_allow:1; - /** reg_lp_mm_hp_i2s1_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_i2s1_allow:1; - /** reg_lp_mm_hp_i2s2_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_i2s2_allow:1; - /** reg_lp_mm_hp_pcnt_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_pcnt_allow:1; - /** reg_lp_mm_hp_uart0_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_uart0_allow:1; - /** reg_lp_mm_hp_uart1_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_uart1_allow:1; - /** reg_lp_mm_hp_uart2_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_uart2_allow:1; - /** reg_lp_mm_hp_uart3_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_uart3_allow:1; - /** reg_lp_mm_hp_uart4_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_uart4_allow:1; - /** reg_lp_mm_hp_parlio_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_parlio_allow:1; - /** reg_lp_mm_hp_gpspi2_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_gpspi2_allow:1; - /** reg_lp_mm_hp_gpspi3_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_gpspi3_allow:1; - /** reg_lp_mm_hp_usbdevice_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_usbdevice_allow:1; - /** reg_lp_mm_hp_ledc_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_ledc_allow:1; + /** lp_mm_hp_mcpwm0_allow : R/W; bitpos: [0]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP MCPWM0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_mcpwm0_allow:1; + /** lp_mm_hp_mcpwm1_allow : R/W; bitpos: [1]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP MCPWM1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_mcpwm1_allow:1; + /** lp_mm_hp_timer_group0_allow : R/W; bitpos: [2]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP timer + * group0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_timer_group0_allow:1; + /** lp_mm_hp_timer_group1_allow : R/W; bitpos: [3]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP timer + * group1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_timer_group1_allow:1; + /** lp_mm_hp_i2c0_allow : R/W; bitpos: [4]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2C0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_i2c0_allow:1; + /** lp_mm_hp_i2c1_allow : R/W; bitpos: [5]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2C1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_i2c1_allow:1; + /** lp_mm_hp_i2s0_allow : R/W; bitpos: [6]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2S0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_i2s0_allow:1; + /** lp_mm_hp_i2s1_allow : R/W; bitpos: [7]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2S1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_i2s1_allow:1; + /** lp_mm_hp_i2s2_allow : R/W; bitpos: [8]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I2S2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_i2s2_allow:1; + /** lp_mm_hp_pcnt_allow : R/W; bitpos: [9]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PCNT. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_pcnt_allow:1; + /** lp_mm_hp_uart0_allow : R/W; bitpos: [10]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_uart0_allow:1; + /** lp_mm_hp_uart1_allow : R/W; bitpos: [11]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_uart1_allow:1; + /** lp_mm_hp_uart2_allow : R/W; bitpos: [12]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_uart2_allow:1; + /** lp_mm_hp_uart3_allow : R/W; bitpos: [13]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART3. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_uart3_allow:1; + /** lp_mm_hp_uart4_allow : R/W; bitpos: [14]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UART4. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_uart4_allow:1; + /** lp_mm_hp_parlio_allow : R/W; bitpos: [15]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP PARLIO. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_parlio_allow:1; + /** lp_mm_hp_gpspi2_allow : R/W; bitpos: [16]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GP-SPI2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_gpspi2_allow:1; + /** lp_mm_hp_gpspi3_allow : R/W; bitpos: [17]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GP-SPI3. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_gpspi3_allow:1; + /** lp_mm_hp_usbdevice_allow : R/W; bitpos: [18]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP + * USB/Serial JTAG Controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_usbdevice_allow:1; + /** lp_mm_hp_ledc_allow : R/W; bitpos: [19]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP LEDC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_ledc_allow:1; uint32_t reserved_20:1; - /** reg_lp_mm_hp_etm_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_etm_allow:1; - /** reg_lp_mm_hp_intrmtx_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_intrmtx_allow:1; - /** reg_lp_mm_hp_twai0_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_twai0_allow:1; - /** reg_lp_mm_hp_twai1_allow : R/W; bitpos: [24]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_twai1_allow:1; - /** reg_lp_mm_hp_twai2_allow : R/W; bitpos: [25]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_twai2_allow:1; - /** reg_lp_mm_hp_i3c_mst_allow : R/W; bitpos: [26]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_i3c_mst_allow:1; - /** reg_lp_mm_hp_i3c_slv_allow : R/W; bitpos: [27]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_i3c_slv_allow:1; - /** reg_lp_mm_hp_lcdcam_allow : R/W; bitpos: [28]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_lcdcam_allow:1; + /** lp_mm_hp_etm_allow : R/W; bitpos: [21]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP ETM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_etm_allow:1; + /** lp_mm_hp_intrmtx_allow : R/W; bitpos: [22]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP interrupt + * matrix. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_intrmtx_allow:1; + /** lp_mm_hp_twai0_allow : R/W; bitpos: [23]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP TWAI0. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_twai0_allow:1; + /** lp_mm_hp_twai1_allow : R/W; bitpos: [24]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP TWAI1. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_twai1_allow:1; + /** lp_mm_hp_twai2_allow : R/W; bitpos: [25]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP TWAI2. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_twai2_allow:1; + /** lp_mm_hp_i3c_mst_allow : R/W; bitpos: [26]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I3C + * master controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_i3c_mst_allow:1; + /** lp_mm_hp_i3c_slv_allow : R/W; bitpos: [27]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP I3C slave + * controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_i3c_slv_allow:1; + /** lp_mm_hp_lcdcam_allow : R/W; bitpos: [28]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP LCD_CAM. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_lcdcam_allow:1; uint32_t reserved_29:1; - /** reg_lp_mm_hp_adc_allow : R/W; bitpos: [30]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_adc_allow:1; - /** reg_lp_mm_hp_uhci_allow : R/W; bitpos: [31]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_uhci_allow:1; + /** lp_mm_hp_adc_allow : R/W; bitpos: [30]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP ADC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_adc_allow:1; + /** lp_mm_hp_uhci_allow : R/W; bitpos: [31]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP UHCI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_uhci_allow:1; }; uint32_t val; -} tee_lp_mm_pms_reg2_reg_t; +} pms_lp_mm_pms_reg2_reg_t; - -/** Group: TEE LP MM PMS REG3 REG */ /** Type of lp_mm_pms_reg3 register - * NA + * Permission control register3 for the LP CPU in machine mode */ typedef union { struct { - /** reg_lp_mm_hp_gpio_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_gpio_allow:1; - /** reg_lp_mm_hp_iomux_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_iomux_allow:1; - /** reg_lp_mm_hp_systimer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_systimer_allow:1; - /** reg_lp_mm_hp_sys_reg_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_sys_reg_allow:1; - /** reg_lp_mm_hp_clkrst_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp_clkrst_allow:1; + /** lp_mm_hp_gpio_allow : R/W; bitpos: [0]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP GPIO + * Matrix. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_gpio_allow:1; + /** lp_mm_hp_iomux_allow : R/W; bitpos: [1]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP IO MUX. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_iomux_allow:1; + /** lp_mm_hp_systimer_allow : R/W; bitpos: [2]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP system + * timer. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_systimer_allow:1; + /** lp_mm_hp_sys_reg_allow : R/W; bitpos: [3]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access HP system + * register. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_sys_reg_allow:1; + /** lp_mm_hp_clkrst_allow : R/W; bitpos: [4]; default: 1; + * Configures whether the LP CPU in machine mode has permission to access + * HP_SYS_CLKRST. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp_clkrst_allow:1; uint32_t reserved_5:27; }; uint32_t val; -} tee_lp_mm_pms_reg3_reg_t; +} pms_lp_mm_pms_reg3_reg_t; typedef struct { - volatile tee_lp2hp_pms_date_reg_t lp2hp_pms_date; - volatile tee_pms_clk_en_reg_t pms_clk_en; - volatile tee_lp_mm_pms_reg0_reg_t lp_mm_pms_reg0; + volatile pms_lp2hp_peri_pms_date_reg_t lp2hp_peri_pms_date; + volatile pms_lp2hp_peri_pms_clk_en_reg_t lp2hp_peri_pms_clk_en; + volatile pms_lp_mm_pms_reg0_reg_t lp_mm_pms_reg0; uint32_t reserved_00c[9]; - volatile tee_lp_mm_pms_reg1_reg_t lp_mm_pms_reg1; + volatile pms_lp_mm_pms_reg1_reg_t lp_mm_pms_reg1; uint32_t reserved_034[28]; - volatile tee_lp_mm_pms_reg2_reg_t lp_mm_pms_reg2; + volatile pms_lp_mm_pms_reg2_reg_t lp_mm_pms_reg2; uint32_t reserved_0a8[29]; - volatile tee_lp_mm_pms_reg3_reg_t lp_mm_pms_reg3; -} tee_dev_t; + volatile pms_lp_mm_pms_reg3_reg_t lp_mm_pms_reg3; +} lp2hp_peri_pms_dev_t; +extern lp2hp_peri_pms_dev_t LP2HP_PERI_PMS; #ifndef __cplusplus -_Static_assert(sizeof(tee_dev_t) == 0x120, "Invalid size of tee_dev_t structure"); +_Static_assert(sizeof(lp2hp_peri_pms_dev_t) == 0x120, "Invalid size of lp2hp_peri_pms_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/rtcadc_reg.h b/components/soc/esp32p4/include/soc/lp_adc_reg.h similarity index 100% rename from components/soc/esp32p4/include/soc/rtcadc_reg.h rename to components/soc/esp32p4/include/soc/lp_adc_reg.h diff --git a/components/soc/esp32p4/include/soc/rtcadc_struct.h b/components/soc/esp32p4/include/soc/lp_adc_struct.h similarity index 96% rename from components/soc/esp32p4/include/soc/rtcadc_struct.h rename to components/soc/esp32p4/include/soc/lp_adc_struct.h index be919a948b8d..0886d6ba2a0f 100644 --- a/components/soc/esp32p4/include/soc/rtcadc_struct.h +++ b/components/soc/esp32p4/include/soc/lp_adc_struct.h @@ -259,11 +259,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_raw:1; /** cocpu_saradc1_error_int_raw : R/WTC/SS; bitpos: [2]; default: 0; - * An errro occurs from ADC1, int raw. + * An error occurs from ADC1, int raw. */ uint32_t cocpu_saradc1_error_int_raw:1; /** cocpu_saradc2_error_int_raw : R/WTC/SS; bitpos: [3]; default: 0; - * An errro occurs from ADC2, int raw. + * An error occurs from ADC2, int raw. */ uint32_t cocpu_saradc2_error_int_raw:1; /** cocpu_saradc1_wake_int_raw : R/WTC/SS; bitpos: [4]; default: 0; @@ -293,11 +293,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_ena:1; /** cocpu_saradc1_error_int_ena : R/WTC; bitpos: [2]; default: 0; - * An errro occurs from ADC1, int enable. + * An error occurs from ADC1, int enable. */ uint32_t cocpu_saradc1_error_int_ena:1; /** cocpu_saradc2_error_int_ena : R/WTC; bitpos: [3]; default: 0; - * An errro occurs from ADC2, int enable. + * An error occurs from ADC2, int enable. */ uint32_t cocpu_saradc2_error_int_ena:1; /** cocpu_saradc1_wake_int_ena : R/WTC; bitpos: [4]; default: 0; @@ -327,11 +327,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_st:1; /** cocpu_saradc1_error_int_st : RO; bitpos: [2]; default: 0; - * An errro occurs from ADC1, int status. + * An error occurs from ADC1, int status. */ uint32_t cocpu_saradc1_error_int_st:1; /** cocpu_saradc2_error_int_st : RO; bitpos: [3]; default: 0; - * An errro occurs from ADC2, int status. + * An error occurs from ADC2, int status. */ uint32_t cocpu_saradc2_error_int_st:1; /** cocpu_saradc1_wake_int_st : RO; bitpos: [4]; default: 0; @@ -361,11 +361,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_clr:1; /** cocpu_saradc1_error_int_clr : WT; bitpos: [2]; default: 0; - * An errro occurs from ADC1, int clear. + * An error occurs from ADC1, int clear. */ uint32_t cocpu_saradc1_error_int_clr:1; /** cocpu_saradc2_error_int_clr : WT; bitpos: [3]; default: 0; - * An errro occurs from ADC2, int clear. + * An error occurs from ADC2, int clear. */ uint32_t cocpu_saradc2_error_int_clr:1; /** cocpu_saradc1_wake_int_clr : WT; bitpos: [4]; default: 0; @@ -395,11 +395,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_ena_w1ts:1; /** cocpu_saradc1_error_int_ena_w1ts : WT; bitpos: [2]; default: 0; - * An errro occurs from ADC1, write 1 to assert int enable. + * An error occurs from ADC1, write 1 to assert int enable. */ uint32_t cocpu_saradc1_error_int_ena_w1ts:1; /** cocpu_saradc2_error_int_ena_w1ts : WT; bitpos: [3]; default: 0; - * An errro occurs from ADC2, write 1 to assert int enable. + * An error occurs from ADC2, write 1 to assert int enable. */ uint32_t cocpu_saradc2_error_int_ena_w1ts:1; /** cocpu_saradc1_wake_int_ena_w1ts : WT; bitpos: [4]; default: 0; @@ -429,11 +429,11 @@ typedef union { */ uint32_t cocpu_saradc2_int_ena_w1tc:1; /** cocpu_saradc1_error_int_ena_w1tc : WT; bitpos: [2]; default: 0; - * An errro occurs from ADC1, write 1 to deassert int enable. + * An error occurs from ADC1, write 1 to deassert int enable. */ uint32_t cocpu_saradc1_error_int_ena_w1tc:1; /** cocpu_saradc2_error_int_ena_w1tc : WT; bitpos: [3]; default: 0; - * An errro occurs from ADC2, write 1 to deassert int enable. + * An error occurs from ADC2, write 1 to deassert int enable. */ uint32_t cocpu_saradc2_error_int_ena_w1tc:1; /** cocpu_saradc1_wake_int_ena_w1tc : WT; bitpos: [4]; default: 0; @@ -592,6 +592,7 @@ typedef struct { volatile rtcadc_sar2_hw_wakeup_reg_t sar2_hw_wakeup; } rtcadc_dev_t; +extern rtcadc_dev_t LP_ADC; #ifndef __cplusplus _Static_assert(sizeof(rtcadc_dev_t) == 0x74, "Invalid size of rtcadc_dev_t structure"); diff --git a/components/soc/esp32p4/include/soc/lp_analog_peri_reg.h b/components/soc/esp32p4/include/soc/lp_analog_peri_reg.h index 9b55adfd1466..b9064e20c2b8 100644 --- a/components/soc/esp32p4/include/soc/lp_analog_peri_reg.h +++ b/components/soc/esp32p4/include/soc/lp_analog_peri_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -233,6 +233,8 @@ extern "C" { #define LP_ANALOG_PERI_ANA_FIB_ENA_V 0xFFFFFFFFU #define LP_ANALOG_PERI_ANA_FIB_ENA_S 0 +#define LP_ANALOG_PERI_LP_ANA_FIB_BOD_RST BIT(1) + /** LP_ANALOG_PERI_INT_RAW_REG register * need_des */ @@ -617,13 +619,13 @@ extern "C" { * need_des */ #define LP_ANALOG_PERI_TOUCH_FILTER1_REG (DR_REG_LP_ANALOG_PERI_BASE + 0x110) -/** LP_ANALOG_PERI_TOUCH_NEG_NOISE_DISUPDATE_BASELINE_EN : R/W; bitpos: [0]; default: 0; +/** LP_ANALOG_PERI_TOUCH_NN_DISUPDATE_BENCHMARK_EN : R/W; bitpos: [0]; default: 0; * Reserved */ -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_DISUPDATE_BASELINE_EN (BIT(0)) -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_DISUPDATE_BASELINE_EN_M (LP_ANALOG_PERI_TOUCH_NEG_NOISE_DISUPDATE_BASELINE_EN_V << LP_ANALOG_PERI_TOUCH_NEG_NOISE_DISUPDATE_BASELINE_EN_S) -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_DISUPDATE_BASELINE_EN_V 0x00000001U -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_DISUPDATE_BASELINE_EN_S 0 +#define LP_ANALOG_PERI_TOUCH_NN_DISUPDATE_BENCHMARK_EN (BIT(0)) +#define LP_ANALOG_PERI_TOUCH_NN_DISUPDATE_BENCHMARK_EN_M (LP_ANALOG_PERI_TOUCH_NN_DISUPDATE_BENCHMARK_EN_V << LP_ANALOG_PERI_TOUCH_NN_DISUPDATE_BENCHMARK_EN_S) +#define LP_ANALOG_PERI_TOUCH_NN_DISUPDATE_BENCHMARK_EN_V 0x00000001U +#define LP_ANALOG_PERI_TOUCH_NN_DISUPDATE_BENCHMARK_EN_S 0 /** LP_ANALOG_PERI_TOUCH_HYSTERESIS : R/W; bitpos: [2:1]; default: 0; * need_des */ @@ -631,13 +633,13 @@ extern "C" { #define LP_ANALOG_PERI_TOUCH_HYSTERESIS_M (LP_ANALOG_PERI_TOUCH_HYSTERESIS_V << LP_ANALOG_PERI_TOUCH_HYSTERESIS_S) #define LP_ANALOG_PERI_TOUCH_HYSTERESIS_V 0x00000003U #define LP_ANALOG_PERI_TOUCH_HYSTERESIS_S 1 -/** LP_ANALOG_PERI_TOUCH_NEG_NOISE_THRES : R/W; bitpos: [4:3]; default: 0; +/** LP_ANALOG_PERI_TOUCH_NN_THRES : R/W; bitpos: [4:3]; default: 0; * need_des */ -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_THRES 0x00000003U -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_THRES_M (LP_ANALOG_PERI_TOUCH_NEG_NOISE_THRES_V << LP_ANALOG_PERI_TOUCH_NEG_NOISE_THRES_S) -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_THRES_V 0x00000003U -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_THRES_S 3 +#define LP_ANALOG_PERI_TOUCH_NN_THRES 0x00000003U +#define LP_ANALOG_PERI_TOUCH_NN_THRES_M (LP_ANALOG_PERI_TOUCH_NN_THRES_V << LP_ANALOG_PERI_TOUCH_NN_THRES_S) +#define LP_ANALOG_PERI_TOUCH_NN_THRES_V 0x00000003U +#define LP_ANALOG_PERI_TOUCH_NN_THRES_S 3 /** LP_ANALOG_PERI_TOUCH_NOISE_THRES : R/W; bitpos: [6:5]; default: 0; * need_des */ @@ -673,13 +675,13 @@ extern "C" { #define LP_ANALOG_PERI_TOUCH_FILTER_EN_M (LP_ANALOG_PERI_TOUCH_FILTER_EN_V << LP_ANALOG_PERI_TOUCH_FILTER_EN_S) #define LP_ANALOG_PERI_TOUCH_FILTER_EN_V 0x00000001U #define LP_ANALOG_PERI_TOUCH_FILTER_EN_S 16 -/** LP_ANALOG_PERI_TOUCH_NEG_NOISE_LIMIT : R/W; bitpos: [20:17]; default: 5; +/** LP_ANALOG_PERI_TOUCH_NN_LIMIT : R/W; bitpos: [20:17]; default: 5; * need_des */ -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_LIMIT 0x0000000FU -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_LIMIT_M (LP_ANALOG_PERI_TOUCH_NEG_NOISE_LIMIT_V << LP_ANALOG_PERI_TOUCH_NEG_NOISE_LIMIT_S) -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_LIMIT_V 0x0000000FU -#define LP_ANALOG_PERI_TOUCH_NEG_NOISE_LIMIT_S 17 +#define LP_ANALOG_PERI_TOUCH_NN_LIMIT 0x0000000FU +#define LP_ANALOG_PERI_TOUCH_NN_LIMIT_M (LP_ANALOG_PERI_TOUCH_NN_LIMIT_V << LP_ANALOG_PERI_TOUCH_NN_LIMIT_S) +#define LP_ANALOG_PERI_TOUCH_NN_LIMIT_V 0x0000000FU +#define LP_ANALOG_PERI_TOUCH_NN_LIMIT_S 17 /** LP_ANALOG_PERI_TOUCH_APPROACH_LIMIT : R/W; bitpos: [28:21]; default: 80; * need_des */ @@ -713,32 +715,32 @@ extern "C" { #define LP_ANALOG_PERI_TOUCH_BYPASS_NOISE_THRES_M (LP_ANALOG_PERI_TOUCH_BYPASS_NOISE_THRES_V << LP_ANALOG_PERI_TOUCH_BYPASS_NOISE_THRES_S) #define LP_ANALOG_PERI_TOUCH_BYPASS_NOISE_THRES_V 0x00000001U #define LP_ANALOG_PERI_TOUCH_BYPASS_NOISE_THRES_S 30 -/** LP_ANALOG_PERI_TOUCH_BYPASS_NEG_NOISE_THRES : R/W; bitpos: [31]; default: 0; +/** LP_ANALOG_PERI_TOUCH_BYPASS_NN_THRES : R/W; bitpos: [31]; default: 0; * need_des */ -#define LP_ANALOG_PERI_TOUCH_BYPASS_NEG_NOISE_THRES (BIT(31)) -#define LP_ANALOG_PERI_TOUCH_BYPASS_NEG_NOISE_THRES_M (LP_ANALOG_PERI_TOUCH_BYPASS_NEG_NOISE_THRES_V << LP_ANALOG_PERI_TOUCH_BYPASS_NEG_NOISE_THRES_S) -#define LP_ANALOG_PERI_TOUCH_BYPASS_NEG_NOISE_THRES_V 0x00000001U -#define LP_ANALOG_PERI_TOUCH_BYPASS_NEG_NOISE_THRES_S 31 +#define LP_ANALOG_PERI_TOUCH_BYPASS_NN_THRES (BIT(31)) +#define LP_ANALOG_PERI_TOUCH_BYPASS_NN_THRES_M (LP_ANALOG_PERI_TOUCH_BYPASS_NN_THRES_V << LP_ANALOG_PERI_TOUCH_BYPASS_NN_THRES_S) +#define LP_ANALOG_PERI_TOUCH_BYPASS_NN_THRES_V 0x00000001U +#define LP_ANALOG_PERI_TOUCH_BYPASS_NN_THRES_S 31 /** LP_ANALOG_PERI_TOUCH_FILTER3_REG register * need_des */ #define LP_ANALOG_PERI_TOUCH_FILTER3_REG (DR_REG_LP_ANALOG_PERI_BASE + 0x118) -/** LP_ANALOG_PERI_TOUCH_BASELINE_SW : R/W; bitpos: [15:0]; default: 0; +/** LP_ANALOG_PERI_TOUCH_BENCHMARK_SW : R/W; bitpos: [15:0]; default: 0; * need_des */ -#define LP_ANALOG_PERI_TOUCH_BASELINE_SW 0x0000FFFFU -#define LP_ANALOG_PERI_TOUCH_BASELINE_SW_M (LP_ANALOG_PERI_TOUCH_BASELINE_SW_V << LP_ANALOG_PERI_TOUCH_BASELINE_SW_S) -#define LP_ANALOG_PERI_TOUCH_BASELINE_SW_V 0x0000FFFFU -#define LP_ANALOG_PERI_TOUCH_BASELINE_SW_S 0 -/** LP_ANALOG_PERI_TOUCH_UPDATE_BASELINE_SW : WT; bitpos: [16]; default: 0; +#define LP_ANALOG_PERI_TOUCH_BENCHMARK_SW 0x0000FFFFU +#define LP_ANALOG_PERI_TOUCH_BENCHMARK_SW_M (LP_ANALOG_PERI_TOUCH_BENCHMARK_SW_V << LP_ANALOG_PERI_TOUCH_BENCHMARK_SW_S) +#define LP_ANALOG_PERI_TOUCH_BENCHMARK_SW_V 0x0000FFFFU +#define LP_ANALOG_PERI_TOUCH_BENCHMARK_SW_S 0 +/** LP_ANALOG_PERI_TOUCH_UPDATE_BENCHMARK_SW : WT; bitpos: [16]; default: 0; * need_des */ -#define LP_ANALOG_PERI_TOUCH_UPDATE_BASELINE_SW (BIT(16)) -#define LP_ANALOG_PERI_TOUCH_UPDATE_BASELINE_SW_M (LP_ANALOG_PERI_TOUCH_UPDATE_BASELINE_SW_V << LP_ANALOG_PERI_TOUCH_UPDATE_BASELINE_SW_S) -#define LP_ANALOG_PERI_TOUCH_UPDATE_BASELINE_SW_V 0x00000001U -#define LP_ANALOG_PERI_TOUCH_UPDATE_BASELINE_SW_S 16 +#define LP_ANALOG_PERI_TOUCH_UPDATE_BENCHMARK_SW (BIT(16)) +#define LP_ANALOG_PERI_TOUCH_UPDATE_BENCHMARK_SW_M (LP_ANALOG_PERI_TOUCH_UPDATE_BENCHMARK_SW_V << LP_ANALOG_PERI_TOUCH_UPDATE_BENCHMARK_SW_S) +#define LP_ANALOG_PERI_TOUCH_UPDATE_BENCHMARK_SW_V 0x00000001U +#define LP_ANALOG_PERI_TOUCH_UPDATE_BENCHMARK_SW_S 16 /** LP_ANALOG_PERI_TOUCH_SLP0_REG register * need_des diff --git a/components/soc/esp32p4/include/soc/lp_analog_peri_struct.h b/components/soc/esp32p4/include/soc/lp_analog_peri_struct.h index 9e3b1839929b..54b0eb9f81be 100644 --- a/components/soc/esp32p4/include/soc/lp_analog_peri_struct.h +++ b/components/soc/esp32p4/include/soc/lp_analog_peri_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -510,18 +510,18 @@ typedef union { */ typedef union { struct { - /** touch_neg_noise_disupdate_baseline_en : R/W; bitpos: [0]; default: 0; + /** touch_nn_disupdate_benchmark_en : R/W; bitpos: [0]; default: 0; * Reserved */ - uint32_t touch_neg_noise_disupdate_baseline_en:1; + uint32_t touch_nn_disupdate_benchmark_en:1; /** touch_hysteresis : R/W; bitpos: [2:1]; default: 0; * need_des */ uint32_t touch_hysteresis:2; - /** touch_neg_noise_thres : R/W; bitpos: [4:3]; default: 0; + /** touch_nn_thres : R/W; bitpos: [4:3]; default: 0; * need_des */ - uint32_t touch_neg_noise_thres:2; + uint32_t touch_nn_thres:2; /** touch_noise_thres : R/W; bitpos: [6:5]; default: 0; * need_des */ @@ -542,10 +542,10 @@ typedef union { * need_des */ uint32_t touch_filter_en:1; - /** touch_neg_noise_limit : R/W; bitpos: [20:17]; default: 5; + /** touch_nn_limit : R/W; bitpos: [20:17]; default: 5; * need_des */ - uint32_t touch_neg_noise_limit:4; + uint32_t touch_nn_limit:4; /** touch_approach_limit : R/W; bitpos: [28:21]; default: 80; * need_des */ @@ -572,10 +572,10 @@ typedef union { * need_des */ uint32_t touch_bypass_noise_thres:1; - /** touch_bypass_neg_noise_thres : R/W; bitpos: [31]; default: 0; + /** touch_bypass_nn_thres : R/W; bitpos: [31]; default: 0; * need_des */ - uint32_t touch_bypass_neg_noise_thres:1; + uint32_t touch_bypass_nn_thres:1; }; uint32_t val; } lp_analog_peri_touch_filter2_reg_t; @@ -585,14 +585,14 @@ typedef union { */ typedef union { struct { - /** touch_baseline_sw : R/W; bitpos: [15:0]; default: 0; + /** touch_benchmark_sw : R/W; bitpos: [15:0]; default: 0; * need_des */ - uint32_t touch_baseline_sw:16; - /** touch_update_baseline_sw : WT; bitpos: [16]; default: 0; + uint32_t touch_benchmark_sw:16; + /** touch_update_benchmark_sw : WT; bitpos: [16]; default: 0; * need_des */ - uint32_t touch_update_baseline_sw:1; + uint32_t touch_update_benchmark_sw:1; uint32_t reserved_17:15; }; uint32_t val; @@ -704,10 +704,14 @@ typedef union { * High speed touch driver */ uint32_t touch_freq_drv_hs:5; - /** touch_freq_dbias : R/W; bitpos: [22:18]; default: 0; + /** touch_bypass_shield : R/W; bitpos: [18]; default: 0; + * bypass the shield channel output (only available since ECO1) + */ + uint32_t touch_bypass_shield:1; + /** touch_freq_dbias : R/W; bitpos: [22:19]; default: 0; * Internal LDO voltage */ - uint32_t touch_freq_dbias:5; + uint32_t touch_freq_dbias:4; uint32_t reserved_23:9; }; uint32_t val; @@ -746,7 +750,7 @@ typedef union { /** touch_data_sel : R/W; bitpos: [9:8]; default: 0; * The type of the output data for debugging * 0/1: raw data - * 2: baseline + * 2: benchmark * 3: smooth data */ uint32_t touch_data_sel:2; @@ -840,7 +844,7 @@ typedef union { typedef struct { - volatile lp_analog_peri_touch_pad_thn_reg_t thn[3]; + volatile lp_analog_peri_touch_pad_thn_reg_t thresh[3]; } lp_analog_peri_touch_padx_thn_reg_t; typedef struct { diff --git a/components/soc/esp32p4/include/soc/lp_peri_pms_reg.h b/components/soc/esp32p4/include/soc/lp_peri_pms_reg.h index 37c84db8f902..7074bc5236ff 100644 --- a/components/soc/esp32p4/include/soc/lp_peri_pms_reg.h +++ b/components/soc/esp32p4/include/soc/lp_peri_pms_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,290 +11,366 @@ extern "C" { #endif -/** TEE_PMS_DATE_REG register - * NA +/** PMS_LP_PERI_PMS_DATE_REG register + * Version control register */ -#define TEE_PMS_DATE_REG (DR_REG_TEE_BASE + 0x0) -/** TEE_TEE_DATE : R/W; bitpos: [31:0]; default: 2294537; - * NA +#define PMS_LP_PERI_PMS_DATE_REG (DR_REG_LP_PERI_PMS_BASE + 0x0) +/** PMS_LP_PERI_PMS_DATE : R/W; bitpos: [31:0]; default: 2294537; + * Version control register */ -#define TEE_TEE_DATE 0xFFFFFFFFU -#define TEE_TEE_DATE_M (TEE_TEE_DATE_V << TEE_TEE_DATE_S) -#define TEE_TEE_DATE_V 0xFFFFFFFFU -#define TEE_TEE_DATE_S 0 +#define PMS_LP_PERI_PMS_DATE 0xFFFFFFFFU +#define PMS_LP_PERI_PMS_DATE_M (PMS_LP_PERI_PMS_DATE_V << PMS_LP_PERI_PMS_DATE_S) +#define PMS_LP_PERI_PMS_DATE_V 0xFFFFFFFFU +#define PMS_LP_PERI_PMS_DATE_S 0 -/** TEE_PMS_CLK_EN_REG register - * NA - */ -#define TEE_PMS_CLK_EN_REG (DR_REG_TEE_BASE + 0x4) -/** TEE_REG_CLK_EN : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_CLK_EN (BIT(0)) -#define TEE_REG_CLK_EN_M (TEE_REG_CLK_EN_V << TEE_REG_CLK_EN_S) -#define TEE_REG_CLK_EN_V 0x00000001U -#define TEE_REG_CLK_EN_S 0 +/** PMS_LP_PERI_PMS_CLK_EN_REG register + * Clock gating register + */ +#define PMS_LP_PERI_PMS_CLK_EN_REG (DR_REG_LP_PERI_PMS_BASE + 0x4) +/** PMS_LP_PERI_PMS_CLK_EN : R/W; bitpos: [0]; default: 1; + * Configures whether to keep the clock always on. + * 0: Enable automatic clock gating + * 1: Keep the clock always on + */ +#define PMS_LP_PERI_PMS_CLK_EN (BIT(0)) +#define PMS_LP_PERI_PMS_CLK_EN_M (PMS_LP_PERI_PMS_CLK_EN_V << PMS_LP_PERI_PMS_CLK_EN_S) +#define PMS_LP_PERI_PMS_CLK_EN_V 0x00000001U +#define PMS_LP_PERI_PMS_CLK_EN_S 0 -/** TEE_LP_MM_PMS_REG0_REG register - * NA - */ -#define TEE_LP_MM_PMS_REG0_REG (DR_REG_TEE_BASE + 0x8) -/** TEE_REG_LP_MM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_SYSREG_ALLOW (BIT(0)) -#define TEE_REG_LP_MM_LP_SYSREG_ALLOW_M (TEE_REG_LP_MM_LP_SYSREG_ALLOW_V << TEE_REG_LP_MM_LP_SYSREG_ALLOW_S) -#define TEE_REG_LP_MM_LP_SYSREG_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_SYSREG_ALLOW_S 0 -/** TEE_REG_LP_MM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_AONCLKRST_ALLOW (BIT(1)) -#define TEE_REG_LP_MM_LP_AONCLKRST_ALLOW_M (TEE_REG_LP_MM_LP_AONCLKRST_ALLOW_V << TEE_REG_LP_MM_LP_AONCLKRST_ALLOW_S) -#define TEE_REG_LP_MM_LP_AONCLKRST_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_AONCLKRST_ALLOW_S 1 -/** TEE_REG_LP_MM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_TIMER_ALLOW (BIT(2)) -#define TEE_REG_LP_MM_LP_TIMER_ALLOW_M (TEE_REG_LP_MM_LP_TIMER_ALLOW_V << TEE_REG_LP_MM_LP_TIMER_ALLOW_S) -#define TEE_REG_LP_MM_LP_TIMER_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_TIMER_ALLOW_S 2 -/** TEE_REG_LP_MM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_ANAPERI_ALLOW (BIT(3)) -#define TEE_REG_LP_MM_LP_ANAPERI_ALLOW_M (TEE_REG_LP_MM_LP_ANAPERI_ALLOW_V << TEE_REG_LP_MM_LP_ANAPERI_ALLOW_S) -#define TEE_REG_LP_MM_LP_ANAPERI_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_ANAPERI_ALLOW_S 3 -/** TEE_REG_LP_MM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_PMU_ALLOW (BIT(4)) -#define TEE_REG_LP_MM_LP_PMU_ALLOW_M (TEE_REG_LP_MM_LP_PMU_ALLOW_V << TEE_REG_LP_MM_LP_PMU_ALLOW_S) -#define TEE_REG_LP_MM_LP_PMU_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_PMU_ALLOW_S 4 -/** TEE_REG_LP_MM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_WDT_ALLOW (BIT(5)) -#define TEE_REG_LP_MM_LP_WDT_ALLOW_M (TEE_REG_LP_MM_LP_WDT_ALLOW_V << TEE_REG_LP_MM_LP_WDT_ALLOW_S) -#define TEE_REG_LP_MM_LP_WDT_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_WDT_ALLOW_S 5 -/** TEE_REG_LP_MM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_MAILBOX_ALLOW (BIT(6)) -#define TEE_REG_LP_MM_LP_MAILBOX_ALLOW_M (TEE_REG_LP_MM_LP_MAILBOX_ALLOW_V << TEE_REG_LP_MM_LP_MAILBOX_ALLOW_S) -#define TEE_REG_LP_MM_LP_MAILBOX_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_MAILBOX_ALLOW_S 6 -/** TEE_REG_LP_MM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_RTC_ALLOW (BIT(7)) -#define TEE_REG_LP_MM_LP_RTC_ALLOW_M (TEE_REG_LP_MM_LP_RTC_ALLOW_V << TEE_REG_LP_MM_LP_RTC_ALLOW_S) -#define TEE_REG_LP_MM_LP_RTC_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_RTC_ALLOW_S 7 -/** TEE_REG_LP_MM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_PERICLKRST_ALLOW (BIT(8)) -#define TEE_REG_LP_MM_LP_PERICLKRST_ALLOW_M (TEE_REG_LP_MM_LP_PERICLKRST_ALLOW_V << TEE_REG_LP_MM_LP_PERICLKRST_ALLOW_S) -#define TEE_REG_LP_MM_LP_PERICLKRST_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_PERICLKRST_ALLOW_S 8 -/** TEE_REG_LP_MM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_UART_ALLOW (BIT(9)) -#define TEE_REG_LP_MM_LP_UART_ALLOW_M (TEE_REG_LP_MM_LP_UART_ALLOW_V << TEE_REG_LP_MM_LP_UART_ALLOW_S) -#define TEE_REG_LP_MM_LP_UART_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_UART_ALLOW_S 9 -/** TEE_REG_LP_MM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_I2C_ALLOW (BIT(10)) -#define TEE_REG_LP_MM_LP_I2C_ALLOW_M (TEE_REG_LP_MM_LP_I2C_ALLOW_V << TEE_REG_LP_MM_LP_I2C_ALLOW_S) -#define TEE_REG_LP_MM_LP_I2C_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_I2C_ALLOW_S 10 -/** TEE_REG_LP_MM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_SPI_ALLOW (BIT(11)) -#define TEE_REG_LP_MM_LP_SPI_ALLOW_M (TEE_REG_LP_MM_LP_SPI_ALLOW_V << TEE_REG_LP_MM_LP_SPI_ALLOW_S) -#define TEE_REG_LP_MM_LP_SPI_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_SPI_ALLOW_S 11 -/** TEE_REG_LP_MM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_I2CMST_ALLOW (BIT(12)) -#define TEE_REG_LP_MM_LP_I2CMST_ALLOW_M (TEE_REG_LP_MM_LP_I2CMST_ALLOW_V << TEE_REG_LP_MM_LP_I2CMST_ALLOW_S) -#define TEE_REG_LP_MM_LP_I2CMST_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_I2CMST_ALLOW_S 12 -/** TEE_REG_LP_MM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_I2S_ALLOW (BIT(13)) -#define TEE_REG_LP_MM_LP_I2S_ALLOW_M (TEE_REG_LP_MM_LP_I2S_ALLOW_V << TEE_REG_LP_MM_LP_I2S_ALLOW_S) -#define TEE_REG_LP_MM_LP_I2S_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_I2S_ALLOW_S 13 -/** TEE_REG_LP_MM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_ADC_ALLOW (BIT(14)) -#define TEE_REG_LP_MM_LP_ADC_ALLOW_M (TEE_REG_LP_MM_LP_ADC_ALLOW_V << TEE_REG_LP_MM_LP_ADC_ALLOW_S) -#define TEE_REG_LP_MM_LP_ADC_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_ADC_ALLOW_S 14 -/** TEE_REG_LP_MM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_TOUCH_ALLOW (BIT(15)) -#define TEE_REG_LP_MM_LP_TOUCH_ALLOW_M (TEE_REG_LP_MM_LP_TOUCH_ALLOW_V << TEE_REG_LP_MM_LP_TOUCH_ALLOW_S) -#define TEE_REG_LP_MM_LP_TOUCH_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_TOUCH_ALLOW_S 15 -/** TEE_REG_LP_MM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_IOMUX_ALLOW (BIT(16)) -#define TEE_REG_LP_MM_LP_IOMUX_ALLOW_M (TEE_REG_LP_MM_LP_IOMUX_ALLOW_V << TEE_REG_LP_MM_LP_IOMUX_ALLOW_S) -#define TEE_REG_LP_MM_LP_IOMUX_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_IOMUX_ALLOW_S 16 -/** TEE_REG_LP_MM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_INTR_ALLOW (BIT(17)) -#define TEE_REG_LP_MM_LP_INTR_ALLOW_M (TEE_REG_LP_MM_LP_INTR_ALLOW_V << TEE_REG_LP_MM_LP_INTR_ALLOW_S) -#define TEE_REG_LP_MM_LP_INTR_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_INTR_ALLOW_S 17 -/** TEE_REG_LP_MM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_EFUSE_ALLOW (BIT(18)) -#define TEE_REG_LP_MM_LP_EFUSE_ALLOW_M (TEE_REG_LP_MM_LP_EFUSE_ALLOW_V << TEE_REG_LP_MM_LP_EFUSE_ALLOW_S) -#define TEE_REG_LP_MM_LP_EFUSE_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_EFUSE_ALLOW_S 18 -/** TEE_REG_LP_MM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_PMS_ALLOW (BIT(19)) -#define TEE_REG_LP_MM_LP_PMS_ALLOW_M (TEE_REG_LP_MM_LP_PMS_ALLOW_V << TEE_REG_LP_MM_LP_PMS_ALLOW_S) -#define TEE_REG_LP_MM_LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_PMS_ALLOW_S 19 -/** TEE_REG_LP_MM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_HP2LP_PMS_ALLOW (BIT(20)) -#define TEE_REG_LP_MM_HP2LP_PMS_ALLOW_M (TEE_REG_LP_MM_HP2LP_PMS_ALLOW_V << TEE_REG_LP_MM_HP2LP_PMS_ALLOW_S) -#define TEE_REG_LP_MM_HP2LP_PMS_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_HP2LP_PMS_ALLOW_S 20 -/** TEE_REG_LP_MM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_TSENS_ALLOW (BIT(21)) -#define TEE_REG_LP_MM_LP_TSENS_ALLOW_M (TEE_REG_LP_MM_LP_TSENS_ALLOW_V << TEE_REG_LP_MM_LP_TSENS_ALLOW_S) -#define TEE_REG_LP_MM_LP_TSENS_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_TSENS_ALLOW_S 21 -/** TEE_REG_LP_MM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_HUK_ALLOW (BIT(22)) -#define TEE_REG_LP_MM_LP_HUK_ALLOW_M (TEE_REG_LP_MM_LP_HUK_ALLOW_V << TEE_REG_LP_MM_LP_HUK_ALLOW_S) -#define TEE_REG_LP_MM_LP_HUK_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_HUK_ALLOW_S 22 -/** TEE_REG_LP_MM_LP_TCM_RAM_ALLOW : R/W; bitpos: [23]; default: 1; - * NA - */ -#define TEE_REG_LP_MM_LP_TCM_RAM_ALLOW (BIT(23)) -#define TEE_REG_LP_MM_LP_TCM_RAM_ALLOW_M (TEE_REG_LP_MM_LP_TCM_RAM_ALLOW_V << TEE_REG_LP_MM_LP_TCM_RAM_ALLOW_S) -#define TEE_REG_LP_MM_LP_TCM_RAM_ALLOW_V 0x00000001U -#define TEE_REG_LP_MM_LP_TCM_RAM_ALLOW_S 23 +/** PMS_LP_MM_LP_PERI_PMS_REG0_REG register + * Permission control register0 for LP CPU in machine mode + */ +#define PMS_LP_MM_LP_PERI_PMS_REG0_REG (DR_REG_LP_PERI_PMS_BASE + 0x8) +/** PMS_LP_MM_LP_SYSREG_ALLOW : R/W; bitpos: [0]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP system + * registers. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_SYSREG_ALLOW (BIT(0)) +#define PMS_LP_MM_LP_SYSREG_ALLOW_M (PMS_LP_MM_LP_SYSREG_ALLOW_V << PMS_LP_MM_LP_SYSREG_ALLOW_S) +#define PMS_LP_MM_LP_SYSREG_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_SYSREG_ALLOW_S 0 +/** PMS_LP_MM_LP_AONCLKRST_ALLOW : R/W; bitpos: [1]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP_AONCLKRST (LP + * always-on clock and reset). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_AONCLKRST_ALLOW (BIT(1)) +#define PMS_LP_MM_LP_AONCLKRST_ALLOW_M (PMS_LP_MM_LP_AONCLKRST_ALLOW_V << PMS_LP_MM_LP_AONCLKRST_ALLOW_S) +#define PMS_LP_MM_LP_AONCLKRST_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_AONCLKRST_ALLOW_S 1 +/** PMS_LP_MM_LP_TIMER_ALLOW : R/W; bitpos: [2]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP timer. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_TIMER_ALLOW (BIT(2)) +#define PMS_LP_MM_LP_TIMER_ALLOW_M (PMS_LP_MM_LP_TIMER_ALLOW_V << PMS_LP_MM_LP_TIMER_ALLOW_S) +#define PMS_LP_MM_LP_TIMER_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_TIMER_ALLOW_S 2 +/** PMS_LP_MM_LP_ANAPERI_ALLOW : R/W; bitpos: [3]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP ANAPERI + * (analog peripherals). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_ANAPERI_ALLOW (BIT(3)) +#define PMS_LP_MM_LP_ANAPERI_ALLOW_M (PMS_LP_MM_LP_ANAPERI_ALLOW_V << PMS_LP_MM_LP_ANAPERI_ALLOW_S) +#define PMS_LP_MM_LP_ANAPERI_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_ANAPERI_ALLOW_S 3 +/** PMS_LP_MM_LP_PMU_ALLOW : R/W; bitpos: [4]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP PMU (Power + * Management Unit). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_PMU_ALLOW (BIT(4)) +#define PMS_LP_MM_LP_PMU_ALLOW_M (PMS_LP_MM_LP_PMU_ALLOW_V << PMS_LP_MM_LP_PMU_ALLOW_S) +#define PMS_LP_MM_LP_PMU_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_PMU_ALLOW_S 4 +/** PMS_LP_MM_LP_WDT_ALLOW : R/W; bitpos: [5]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP WDT (watchdog + * timer). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_WDT_ALLOW (BIT(5)) +#define PMS_LP_MM_LP_WDT_ALLOW_M (PMS_LP_MM_LP_WDT_ALLOW_V << PMS_LP_MM_LP_WDT_ALLOW_S) +#define PMS_LP_MM_LP_WDT_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_WDT_ALLOW_S 5 +/** PMS_LP_MM_LP_MAILBOX_ALLOW : R/W; bitpos: [6]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP Mailbox + * Controller. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_MAILBOX_ALLOW (BIT(6)) +#define PMS_LP_MM_LP_MAILBOX_ALLOW_M (PMS_LP_MM_LP_MAILBOX_ALLOW_V << PMS_LP_MM_LP_MAILBOX_ALLOW_S) +#define PMS_LP_MM_LP_MAILBOX_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_MAILBOX_ALLOW_S 6 +/** PMS_LP_MM_LP_RTC_ALLOW : R/W; bitpos: [7]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP RTC. + * 0: Not allowed + * 1: Allow + */ +#define PMS_LP_MM_LP_RTC_ALLOW (BIT(7)) +#define PMS_LP_MM_LP_RTC_ALLOW_M (PMS_LP_MM_LP_RTC_ALLOW_V << PMS_LP_MM_LP_RTC_ALLOW_S) +#define PMS_LP_MM_LP_RTC_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_RTC_ALLOW_S 7 +/** PMS_LP_MM_LP_PERICLKRST_ALLOW : R/W; bitpos: [8]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP PREICLKRST + * (peripheral clock and reset). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_PERICLKRST_ALLOW (BIT(8)) +#define PMS_LP_MM_LP_PERICLKRST_ALLOW_M (PMS_LP_MM_LP_PERICLKRST_ALLOW_V << PMS_LP_MM_LP_PERICLKRST_ALLOW_S) +#define PMS_LP_MM_LP_PERICLKRST_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_PERICLKRST_ALLOW_S 8 +/** PMS_LP_MM_LP_UART_ALLOW : R/W; bitpos: [9]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP UART. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_UART_ALLOW (BIT(9)) +#define PMS_LP_MM_LP_UART_ALLOW_M (PMS_LP_MM_LP_UART_ALLOW_V << PMS_LP_MM_LP_UART_ALLOW_S) +#define PMS_LP_MM_LP_UART_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_UART_ALLOW_S 9 +/** PMS_LP_MM_LP_I2C_ALLOW : R/W; bitpos: [10]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_I2C_ALLOW (BIT(10)) +#define PMS_LP_MM_LP_I2C_ALLOW_M (PMS_LP_MM_LP_I2C_ALLOW_V << PMS_LP_MM_LP_I2C_ALLOW_S) +#define PMS_LP_MM_LP_I2C_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_I2C_ALLOW_S 10 +/** PMS_LP_MM_LP_SPI_ALLOW : R/W; bitpos: [11]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP SPI. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_SPI_ALLOW (BIT(11)) +#define PMS_LP_MM_LP_SPI_ALLOW_M (PMS_LP_MM_LP_SPI_ALLOW_V << PMS_LP_MM_LP_SPI_ALLOW_S) +#define PMS_LP_MM_LP_SPI_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_SPI_ALLOW_S 11 +/** PMS_LP_MM_LP_I2CMST_ALLOW : R/W; bitpos: [12]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP I2C master. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_I2CMST_ALLOW (BIT(12)) +#define PMS_LP_MM_LP_I2CMST_ALLOW_M (PMS_LP_MM_LP_I2CMST_ALLOW_V << PMS_LP_MM_LP_I2CMST_ALLOW_S) +#define PMS_LP_MM_LP_I2CMST_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_I2CMST_ALLOW_S 12 +/** PMS_LP_MM_LP_I2S_ALLOW : R/W; bitpos: [13]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_I2S_ALLOW (BIT(13)) +#define PMS_LP_MM_LP_I2S_ALLOW_M (PMS_LP_MM_LP_I2S_ALLOW_V << PMS_LP_MM_LP_I2S_ALLOW_S) +#define PMS_LP_MM_LP_I2S_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_I2S_ALLOW_S 13 +/** PMS_LP_MM_LP_ADC_ALLOW : R/W; bitpos: [14]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP ADC. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_ADC_ALLOW (BIT(14)) +#define PMS_LP_MM_LP_ADC_ALLOW_M (PMS_LP_MM_LP_ADC_ALLOW_V << PMS_LP_MM_LP_ADC_ALLOW_S) +#define PMS_LP_MM_LP_ADC_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_ADC_ALLOW_S 14 +/** PMS_LP_MM_LP_TOUCH_ALLOW : R/W; bitpos: [15]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP touch sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_TOUCH_ALLOW (BIT(15)) +#define PMS_LP_MM_LP_TOUCH_ALLOW_M (PMS_LP_MM_LP_TOUCH_ALLOW_V << PMS_LP_MM_LP_TOUCH_ALLOW_S) +#define PMS_LP_MM_LP_TOUCH_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_TOUCH_ALLOW_S 15 +/** PMS_LP_MM_LP_IOMUX_ALLOW : R/W; bitpos: [16]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP IO MUX. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_IOMUX_ALLOW (BIT(16)) +#define PMS_LP_MM_LP_IOMUX_ALLOW_M (PMS_LP_MM_LP_IOMUX_ALLOW_V << PMS_LP_MM_LP_IOMUX_ALLOW_S) +#define PMS_LP_MM_LP_IOMUX_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_IOMUX_ALLOW_S 16 +/** PMS_LP_MM_LP_INTR_ALLOW : R/W; bitpos: [17]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP INTR + * (interrupt). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_INTR_ALLOW (BIT(17)) +#define PMS_LP_MM_LP_INTR_ALLOW_M (PMS_LP_MM_LP_INTR_ALLOW_V << PMS_LP_MM_LP_INTR_ALLOW_S) +#define PMS_LP_MM_LP_INTR_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_INTR_ALLOW_S 17 +/** PMS_LP_MM_LP_EFUSE_ALLOW : R/W; bitpos: [18]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP eFuse. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_EFUSE_ALLOW (BIT(18)) +#define PMS_LP_MM_LP_EFUSE_ALLOW_M (PMS_LP_MM_LP_EFUSE_ALLOW_V << PMS_LP_MM_LP_EFUSE_ALLOW_S) +#define PMS_LP_MM_LP_EFUSE_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_EFUSE_ALLOW_S 18 +/** PMS_LP_MM_LP_PMS_ALLOW : R/W; bitpos: [19]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_PMS_ALLOW (BIT(19)) +#define PMS_LP_MM_LP_PMS_ALLOW_M (PMS_LP_MM_LP_PMS_ALLOW_V << PMS_LP_MM_LP_PMS_ALLOW_S) +#define PMS_LP_MM_LP_PMS_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_PMS_ALLOW_S 19 +/** PMS_LP_MM_HP2LP_PMS_ALLOW : R/W; bitpos: [20]; default: 1; + * Configures whether LP CPU in machine mode has permission to access + * HP2LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_HP2LP_PMS_ALLOW (BIT(20)) +#define PMS_LP_MM_HP2LP_PMS_ALLOW_M (PMS_LP_MM_HP2LP_PMS_ALLOW_V << PMS_LP_MM_HP2LP_PMS_ALLOW_S) +#define PMS_LP_MM_HP2LP_PMS_ALLOW_V 0x00000001U +#define PMS_LP_MM_HP2LP_PMS_ALLOW_S 20 +/** PMS_LP_MM_LP_TSENS_ALLOW : R/W; bitpos: [21]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP temperature + * sensor. + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_TSENS_ALLOW (BIT(21)) +#define PMS_LP_MM_LP_TSENS_ALLOW_M (PMS_LP_MM_LP_TSENS_ALLOW_V << PMS_LP_MM_LP_TSENS_ALLOW_S) +#define PMS_LP_MM_LP_TSENS_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_TSENS_ALLOW_S 21 +/** PMS_LP_MM_LP_HUK_ALLOW : R/W; bitpos: [22]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP HUK (Hardware + * Unique Key). + * 0: Not allowed + * 1: Allowed + */ +#define PMS_LP_MM_LP_HUK_ALLOW (BIT(22)) +#define PMS_LP_MM_LP_HUK_ALLOW_M (PMS_LP_MM_LP_HUK_ALLOW_V << PMS_LP_MM_LP_HUK_ALLOW_S) +#define PMS_LP_MM_LP_HUK_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_HUK_ALLOW_S 22 +/** PMS_LP_MM_LP_SRAM_ALLOW : R/W; bitpos: [23]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP SRAM. + * 0: Not allowed + * 1: Allow + */ +#define PMS_LP_MM_LP_SRAM_ALLOW (BIT(23)) +#define PMS_LP_MM_LP_SRAM_ALLOW_M (PMS_LP_MM_LP_SRAM_ALLOW_V << PMS_LP_MM_LP_SRAM_ALLOW_S) +#define PMS_LP_MM_LP_SRAM_ALLOW_V 0x00000001U +#define PMS_LP_MM_LP_SRAM_ALLOW_S 23 -/** TEE_PERI_REGION0_LOW_REG register - * NA +/** PMS_PERI_REGION0_LOW_REG register + * Region0 start address configuration register */ -#define TEE_PERI_REGION0_LOW_REG (DR_REG_TEE_BASE + 0xc) -/** TEE_REG_PERI_REGION0_LOW : R/W; bitpos: [31:2]; default: 0; - * NA +#define PMS_PERI_REGION0_LOW_REG (DR_REG_LP_PERI_PMS_BASE + 0xc) +/** PMS_PERI_REGION0_LOW : R/W; bitpos: [31:2]; default: 0; + * Configures the high 30 bits of the start address of peripheral register's region0. */ -#define TEE_REG_PERI_REGION0_LOW 0x3FFFFFFFU -#define TEE_REG_PERI_REGION0_LOW_M (TEE_REG_PERI_REGION0_LOW_V << TEE_REG_PERI_REGION0_LOW_S) -#define TEE_REG_PERI_REGION0_LOW_V 0x3FFFFFFFU -#define TEE_REG_PERI_REGION0_LOW_S 2 +#define PMS_PERI_REGION0_LOW 0x3FFFFFFFU +#define PMS_PERI_REGION0_LOW_M (PMS_PERI_REGION0_LOW_V << PMS_PERI_REGION0_LOW_S) +#define PMS_PERI_REGION0_LOW_V 0x3FFFFFFFU +#define PMS_PERI_REGION0_LOW_S 2 -/** TEE_PERI_REGION0_HIGH_REG register - * NA +/** PMS_PERI_REGION0_HIGH_REG register + * Region0 end address configuration register */ -#define TEE_PERI_REGION0_HIGH_REG (DR_REG_TEE_BASE + 0x10) -/** TEE_REG_PERI_REGION0_HIGH : R/W; bitpos: [31:2]; default: 1073741823; - * NA +#define PMS_PERI_REGION0_HIGH_REG (DR_REG_LP_PERI_PMS_BASE + 0x10) +/** PMS_PERI_REGION0_HIGH : R/W; bitpos: [31:2]; default: 1073741823; + * Configures the high 30 bits of the end address of peripheral register's region0. */ -#define TEE_REG_PERI_REGION0_HIGH 0x3FFFFFFFU -#define TEE_REG_PERI_REGION0_HIGH_M (TEE_REG_PERI_REGION0_HIGH_V << TEE_REG_PERI_REGION0_HIGH_S) -#define TEE_REG_PERI_REGION0_HIGH_V 0x3FFFFFFFU -#define TEE_REG_PERI_REGION0_HIGH_S 2 +#define PMS_PERI_REGION0_HIGH 0x3FFFFFFFU +#define PMS_PERI_REGION0_HIGH_M (PMS_PERI_REGION0_HIGH_V << PMS_PERI_REGION0_HIGH_S) +#define PMS_PERI_REGION0_HIGH_V 0x3FFFFFFFU +#define PMS_PERI_REGION0_HIGH_S 2 -/** TEE_PERI_REGION1_LOW_REG register - * NA +/** PMS_PERI_REGION1_LOW_REG register + * Region1 start address configuration register */ -#define TEE_PERI_REGION1_LOW_REG (DR_REG_TEE_BASE + 0x14) -/** TEE_REG_PERI_REGION1_LOW : R/W; bitpos: [31:2]; default: 0; - * NA +#define PMS_PERI_REGION1_LOW_REG (DR_REG_LP_PERI_PMS_BASE + 0x14) +/** PMS_PERI_REGION1_LOW : R/W; bitpos: [31:2]; default: 0; + * Configures the high 30 bits of the start address of peripheral register's region1. */ -#define TEE_REG_PERI_REGION1_LOW 0x3FFFFFFFU -#define TEE_REG_PERI_REGION1_LOW_M (TEE_REG_PERI_REGION1_LOW_V << TEE_REG_PERI_REGION1_LOW_S) -#define TEE_REG_PERI_REGION1_LOW_V 0x3FFFFFFFU -#define TEE_REG_PERI_REGION1_LOW_S 2 +#define PMS_PERI_REGION1_LOW 0x3FFFFFFFU +#define PMS_PERI_REGION1_LOW_M (PMS_PERI_REGION1_LOW_V << PMS_PERI_REGION1_LOW_S) +#define PMS_PERI_REGION1_LOW_V 0x3FFFFFFFU +#define PMS_PERI_REGION1_LOW_S 2 -/** TEE_PERI_REGION1_HIGH_REG register - * NA +/** PMS_PERI_REGION1_HIGH_REG register + * Region1 end address configuration register */ -#define TEE_PERI_REGION1_HIGH_REG (DR_REG_TEE_BASE + 0x18) -/** TEE_REG_PERI_REGION1_HIGH : R/W; bitpos: [31:2]; default: 1073741823; - * NA +#define PMS_PERI_REGION1_HIGH_REG (DR_REG_LP_PERI_PMS_BASE + 0x18) +/** PMS_PERI_REGION1_HIGH : R/W; bitpos: [31:2]; default: 1073741823; + * Configures the high 30 bits of the end address of peripheral register's region1. */ -#define TEE_REG_PERI_REGION1_HIGH 0x3FFFFFFFU -#define TEE_REG_PERI_REGION1_HIGH_M (TEE_REG_PERI_REGION1_HIGH_V << TEE_REG_PERI_REGION1_HIGH_S) -#define TEE_REG_PERI_REGION1_HIGH_V 0x3FFFFFFFU -#define TEE_REG_PERI_REGION1_HIGH_S 2 +#define PMS_PERI_REGION1_HIGH 0x3FFFFFFFU +#define PMS_PERI_REGION1_HIGH_M (PMS_PERI_REGION1_HIGH_V << PMS_PERI_REGION1_HIGH_S) +#define PMS_PERI_REGION1_HIGH_V 0x3FFFFFFFU +#define PMS_PERI_REGION1_HIGH_S 2 -/** TEE_PERI_REGION_PMS_REG register - * NA - */ -#define TEE_PERI_REGION_PMS_REG (DR_REG_TEE_BASE + 0x1c) -/** TEE_REG_LP_CORE_REGION_PMS : R/W; bitpos: [1:0]; default: 3; - * NA - */ -#define TEE_REG_LP_CORE_REGION_PMS 0x00000003U -#define TEE_REG_LP_CORE_REGION_PMS_M (TEE_REG_LP_CORE_REGION_PMS_V << TEE_REG_LP_CORE_REGION_PMS_S) -#define TEE_REG_LP_CORE_REGION_PMS_V 0x00000003U -#define TEE_REG_LP_CORE_REGION_PMS_S 0 -/** TEE_REG_HP_CORE0_UM_REGION_PMS : R/W; bitpos: [3:2]; default: 3; - * NA - */ -#define TEE_REG_HP_CORE0_UM_REGION_PMS 0x00000003U -#define TEE_REG_HP_CORE0_UM_REGION_PMS_M (TEE_REG_HP_CORE0_UM_REGION_PMS_V << TEE_REG_HP_CORE0_UM_REGION_PMS_S) -#define TEE_REG_HP_CORE0_UM_REGION_PMS_V 0x00000003U -#define TEE_REG_HP_CORE0_UM_REGION_PMS_S 2 -/** TEE_REG_HP_CORE0_MM_REGION_PMS : R/W; bitpos: [5:4]; default: 3; - * NA - */ -#define TEE_REG_HP_CORE0_MM_REGION_PMS 0x00000003U -#define TEE_REG_HP_CORE0_MM_REGION_PMS_M (TEE_REG_HP_CORE0_MM_REGION_PMS_V << TEE_REG_HP_CORE0_MM_REGION_PMS_S) -#define TEE_REG_HP_CORE0_MM_REGION_PMS_V 0x00000003U -#define TEE_REG_HP_CORE0_MM_REGION_PMS_S 4 -/** TEE_REG_HP_CORE1_UM_REGION_PMS : R/W; bitpos: [7:6]; default: 3; - * NA - */ -#define TEE_REG_HP_CORE1_UM_REGION_PMS 0x00000003U -#define TEE_REG_HP_CORE1_UM_REGION_PMS_M (TEE_REG_HP_CORE1_UM_REGION_PMS_V << TEE_REG_HP_CORE1_UM_REGION_PMS_S) -#define TEE_REG_HP_CORE1_UM_REGION_PMS_V 0x00000003U -#define TEE_REG_HP_CORE1_UM_REGION_PMS_S 6 -/** TEE_REG_HP_CORE1_MM_REGION_PMS : R/W; bitpos: [9:8]; default: 3; - * NA - */ -#define TEE_REG_HP_CORE1_MM_REGION_PMS 0x00000003U -#define TEE_REG_HP_CORE1_MM_REGION_PMS_M (TEE_REG_HP_CORE1_MM_REGION_PMS_V << TEE_REG_HP_CORE1_MM_REGION_PMS_S) -#define TEE_REG_HP_CORE1_MM_REGION_PMS_V 0x00000003U -#define TEE_REG_HP_CORE1_MM_REGION_PMS_S 8 +/** PMS_PERI_REGION_PMS_REG register + * Permission register of region + */ +#define PMS_PERI_REGION_PMS_REG (DR_REG_LP_PERI_PMS_BASE + 0x1c) +/** PMS_LP_CORE_REGION_PMS : R/W; bitpos: [1:0]; default: 3; + * Configures whether LP core in machine mode has permission to access address region0 + * and address region1. Bit0 corresponds to region0 and bit1 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ +#define PMS_LP_CORE_REGION_PMS 0x00000003U +#define PMS_LP_CORE_REGION_PMS_M (PMS_LP_CORE_REGION_PMS_V << PMS_LP_CORE_REGION_PMS_S) +#define PMS_LP_CORE_REGION_PMS_V 0x00000003U +#define PMS_LP_CORE_REGION_PMS_S 0 +/** PMS_HP_CORE0_UM_REGION_PMS : R/W; bitpos: [3:2]; default: 3; + * Configures whether HP CPU0 in user mode has permission to access address region0 + * and address region1. Bit2 corresponds to region0 and bit3 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ +#define PMS_HP_CORE0_UM_REGION_PMS 0x00000003U +#define PMS_HP_CORE0_UM_REGION_PMS_M (PMS_HP_CORE0_UM_REGION_PMS_V << PMS_HP_CORE0_UM_REGION_PMS_S) +#define PMS_HP_CORE0_UM_REGION_PMS_V 0x00000003U +#define PMS_HP_CORE0_UM_REGION_PMS_S 2 +/** PMS_HP_CORE0_MM_REGION_PMS : R/W; bitpos: [5:4]; default: 3; + * Configures whether HP CPU0 in machine mode has permission to access address region0 + * and address region1. Bit4 corresponds to region0 and bit5 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ +#define PMS_HP_CORE0_MM_REGION_PMS 0x00000003U +#define PMS_HP_CORE0_MM_REGION_PMS_M (PMS_HP_CORE0_MM_REGION_PMS_V << PMS_HP_CORE0_MM_REGION_PMS_S) +#define PMS_HP_CORE0_MM_REGION_PMS_V 0x00000003U +#define PMS_HP_CORE0_MM_REGION_PMS_S 4 +/** PMS_HP_CORE1_UM_REGION_PMS : R/W; bitpos: [7:6]; default: 3; + * Configures whether HP CPU1 in user mode has permission to access address region0 + * and address region1. Bit6 corresponds to region0 and bit7 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ +#define PMS_HP_CORE1_UM_REGION_PMS 0x00000003U +#define PMS_HP_CORE1_UM_REGION_PMS_M (PMS_HP_CORE1_UM_REGION_PMS_V << PMS_HP_CORE1_UM_REGION_PMS_S) +#define PMS_HP_CORE1_UM_REGION_PMS_V 0x00000003U +#define PMS_HP_CORE1_UM_REGION_PMS_S 6 +/** PMS_HP_CORE1_MM_REGION_PMS : R/W; bitpos: [9:8]; default: 3; + * Configures whether HP CPU1 in machine mode has permission to access address region0 + * and address region1. Bit8 corresponds to region0 and bit9 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ +#define PMS_HP_CORE1_MM_REGION_PMS 0x00000003U +#define PMS_HP_CORE1_MM_REGION_PMS_M (PMS_HP_CORE1_MM_REGION_PMS_V << PMS_HP_CORE1_MM_REGION_PMS_S) +#define PMS_HP_CORE1_MM_REGION_PMS_V 0x00000003U +#define PMS_HP_CORE1_MM_REGION_PMS_S 8 #ifdef __cplusplus } diff --git a/components/soc/esp32p4/include/soc/lp_peri_pms_struct.h b/components/soc/esp32p4/include/soc/lp_peri_pms_struct.h index 1e2c83e59e1f..90ab5323b536 100644 --- a/components/soc/esp32p4/include/soc/lp_peri_pms_struct.h +++ b/components/soc/esp32p4/include/soc/lp_peri_pms_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,255 +10,298 @@ extern "C" { #endif -/** Group: TEE PMS DATE REG */ -/** Type of pms_date register - * NA +/** Group: Version Control Registers */ +/** Type of lp_peri_pms_date register + * Version control register */ typedef union { struct { - /** tee_date : R/W; bitpos: [31:0]; default: 2294537; - * NA + /** lp_peri_pms_date : R/W; bitpos: [31:0]; default: 2294537; + * Version control register */ - uint32_t tee_date:32; + uint32_t lp_peri_pms_date:32; }; uint32_t val; -} tee_pms_date_reg_t; +} pms_lp_peri_pms_date_reg_t; -/** Group: TEE PMS CLK EN REG */ -/** Type of pms_clk_en register - * NA +/** Group: Clock Gating Registers */ +/** Type of lp_peri_pms_clk_en register + * Clock gating register */ typedef union { struct { - /** reg_clk_en : R/W; bitpos: [0]; default: 1; - * NA + /** lp_peri_pms_clk_en : R/W; bitpos: [0]; default: 1; + * Configures whether to keep the clock always on. + * 0: Enable automatic clock gating + * 1: Keep the clock always on */ - uint32_t reg_clk_en:1; + uint32_t lp_peri_pms_clk_en:1; uint32_t reserved_1:31; }; uint32_t val; -} tee_pms_clk_en_reg_t; +} pms_lp_peri_pms_clk_en_reg_t; -/** Group: TEE LP MM PMS REG0 REG */ -/** Type of lp_mm_pms_reg0 register - * NA +/** Group: LP CPU Permission Control Registers */ +/** Type of lp_mm_lp_peri_pms_reg0 register + * Permission control register0 for LP CPU in machine mode */ typedef union { struct { - /** reg_lp_mm_lp_sysreg_allow : R/W; bitpos: [0]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_sysreg_allow:1; - /** reg_lp_mm_lp_aonclkrst_allow : R/W; bitpos: [1]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_aonclkrst_allow:1; - /** reg_lp_mm_lp_timer_allow : R/W; bitpos: [2]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_timer_allow:1; - /** reg_lp_mm_lp_anaperi_allow : R/W; bitpos: [3]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_anaperi_allow:1; - /** reg_lp_mm_lp_pmu_allow : R/W; bitpos: [4]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_pmu_allow:1; - /** reg_lp_mm_lp_wdt_allow : R/W; bitpos: [5]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_wdt_allow:1; - /** reg_lp_mm_lp_mailbox_allow : R/W; bitpos: [6]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_mailbox_allow:1; - /** reg_lp_mm_lp_rtc_allow : R/W; bitpos: [7]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_rtc_allow:1; - /** reg_lp_mm_lp_periclkrst_allow : R/W; bitpos: [8]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_periclkrst_allow:1; - /** reg_lp_mm_lp_uart_allow : R/W; bitpos: [9]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_uart_allow:1; - /** reg_lp_mm_lp_i2c_allow : R/W; bitpos: [10]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_i2c_allow:1; - /** reg_lp_mm_lp_spi_allow : R/W; bitpos: [11]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_spi_allow:1; - /** reg_lp_mm_lp_i2cmst_allow : R/W; bitpos: [12]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_i2cmst_allow:1; - /** reg_lp_mm_lp_i2s_allow : R/W; bitpos: [13]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_i2s_allow:1; - /** reg_lp_mm_lp_adc_allow : R/W; bitpos: [14]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_adc_allow:1; - /** reg_lp_mm_lp_touch_allow : R/W; bitpos: [15]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_touch_allow:1; - /** reg_lp_mm_lp_iomux_allow : R/W; bitpos: [16]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_iomux_allow:1; - /** reg_lp_mm_lp_intr_allow : R/W; bitpos: [17]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_intr_allow:1; - /** reg_lp_mm_lp_efuse_allow : R/W; bitpos: [18]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_efuse_allow:1; - /** reg_lp_mm_lp_pms_allow : R/W; bitpos: [19]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_pms_allow:1; - /** reg_lp_mm_hp2lp_pms_allow : R/W; bitpos: [20]; default: 1; - * NA - */ - uint32_t reg_lp_mm_hp2lp_pms_allow:1; - /** reg_lp_mm_lp_tsens_allow : R/W; bitpos: [21]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_tsens_allow:1; - /** reg_lp_mm_lp_huk_allow : R/W; bitpos: [22]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_huk_allow:1; - /** reg_lp_mm_lp_tcm_ram_allow : R/W; bitpos: [23]; default: 1; - * NA - */ - uint32_t reg_lp_mm_lp_tcm_ram_allow:1; + /** lp_mm_lp_sysreg_allow : R/W; bitpos: [0]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP system + * registers. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_sysreg_allow:1; + /** lp_mm_lp_aonclkrst_allow : R/W; bitpos: [1]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP_AONCLKRST (LP + * always-on clock and reset). + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_aonclkrst_allow:1; + /** lp_mm_lp_timer_allow : R/W; bitpos: [2]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP timer. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_timer_allow:1; + /** lp_mm_lp_anaperi_allow : R/W; bitpos: [3]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP ANAPERI + * (analog peripherals). + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_anaperi_allow:1; + /** lp_mm_lp_pmu_allow : R/W; bitpos: [4]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP PMU (Power + * Management Unit). + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_pmu_allow:1; + /** lp_mm_lp_wdt_allow : R/W; bitpos: [5]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP WDT (watchdog + * timer). + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_wdt_allow:1; + /** lp_mm_lp_mailbox_allow : R/W; bitpos: [6]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP Mailbox + * Controller. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_mailbox_allow:1; + /** lp_mm_lp_rtc_allow : R/W; bitpos: [7]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP RTC. + * 0: Not allowed + * 1: Allow + */ + uint32_t lp_mm_lp_rtc_allow:1; + /** lp_mm_lp_periclkrst_allow : R/W; bitpos: [8]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP PREICLKRST + * (peripheral clock and reset). + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_periclkrst_allow:1; + /** lp_mm_lp_uart_allow : R/W; bitpos: [9]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP UART. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_uart_allow:1; + /** lp_mm_lp_i2c_allow : R/W; bitpos: [10]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_i2c_allow:1; + /** lp_mm_lp_spi_allow : R/W; bitpos: [11]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP SPI. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_spi_allow:1; + /** lp_mm_lp_i2cmst_allow : R/W; bitpos: [12]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP I2C master. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_i2cmst_allow:1; + /** lp_mm_lp_i2s_allow : R/W; bitpos: [13]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP I2S. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_i2s_allow:1; + /** lp_mm_lp_adc_allow : R/W; bitpos: [14]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP ADC. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_adc_allow:1; + /** lp_mm_lp_touch_allow : R/W; bitpos: [15]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP touch sensor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_touch_allow:1; + /** lp_mm_lp_iomux_allow : R/W; bitpos: [16]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP IO MUX. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_iomux_allow:1; + /** lp_mm_lp_intr_allow : R/W; bitpos: [17]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP INTR + * (interrupt). + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_intr_allow:1; + /** lp_mm_lp_efuse_allow : R/W; bitpos: [18]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP eFuse. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_efuse_allow:1; + /** lp_mm_lp_pms_allow : R/W; bitpos: [19]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_pms_allow:1; + /** lp_mm_hp2lp_pms_allow : R/W; bitpos: [20]; default: 1; + * Configures whether LP CPU in machine mode has permission to access + * HP2LP_PERI_PMS_REG. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_hp2lp_pms_allow:1; + /** lp_mm_lp_tsens_allow : R/W; bitpos: [21]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP temperature + * sensor. + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_tsens_allow:1; + /** lp_mm_lp_huk_allow : R/W; bitpos: [22]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP HUK (Hardware + * Unique Key). + * 0: Not allowed + * 1: Allowed + */ + uint32_t lp_mm_lp_huk_allow:1; + /** lp_mm_lp_sram_allow : R/W; bitpos: [23]; default: 1; + * Configures whether LP CPU in machine mode has permission to access LP SRAM. + * 0: Not allowed + * 1: Allow + */ + uint32_t lp_mm_lp_sram_allow:1; uint32_t reserved_24:8; }; uint32_t val; -} tee_lp_mm_pms_reg0_reg_t; +} pms_lp_mm_lp_peri_pms_reg0_reg_t; -/** Group: TEE PERI REGION0 LOW REG */ -/** Type of peri_region0_low register - * NA +/** Group: Configurable Address Range Configuration Registers */ +/** Type of peri_regionn_low register + * Regionn start address configuration register */ typedef union { struct { uint32_t reserved_0:2; - /** reg_peri_region0_low : R/W; bitpos: [31:2]; default: 0; - * NA + /** peri_regionn_low : R/W; bitpos: [31:2]; default: 0; + * Configures the high 30 bits of the start address of peripheral register's regionn. */ - uint32_t reg_peri_region0_low:30; + uint32_t peri_regionn_low:30; }; uint32_t val; -} tee_peri_region0_low_reg_t; +} pms_peri_regionn_low_reg_t; - -/** Group: TEE PERI REGION0 HIGH REG */ -/** Type of peri_region0_high register - * NA - */ -typedef union { - struct { - uint32_t reserved_0:2; - /** reg_peri_region0_high : R/W; bitpos: [31:2]; default: 1073741823; - * NA - */ - uint32_t reg_peri_region0_high:30; - }; - uint32_t val; -} tee_peri_region0_high_reg_t; - - -/** Group: TEE PERI REGION1 LOW REG */ -/** Type of peri_region1_low register - * NA - */ -typedef union { - struct { - uint32_t reserved_0:2; - /** reg_peri_region1_low : R/W; bitpos: [31:2]; default: 0; - * NA - */ - uint32_t reg_peri_region1_low:30; - }; - uint32_t val; -} tee_peri_region1_low_reg_t; - - -/** Group: TEE PERI REGION1 HIGH REG */ -/** Type of peri_region1_high register - * NA +/** Type of peri_regionn_high register + * Regionn end address configuration register */ typedef union { struct { uint32_t reserved_0:2; - /** reg_peri_region1_high : R/W; bitpos: [31:2]; default: 1073741823; - * NA + /** peri_regionn_high : R/W; bitpos: [31:2]; default: 1073741823; + * Configures the high 30 bits of the end address of peripheral register's regionn. */ - uint32_t reg_peri_region1_high:30; + uint32_t peri_regionn_high:30; }; uint32_t val; -} tee_peri_region1_high_reg_t; +} pms_peri_regionn_high_reg_t; -/** Group: TEE PERI REGION PMS REG */ +/** Group: PMS Peripheral Region Permission Control Registers */ /** Type of peri_region_pms register - * NA + * Permission register of region */ typedef union { struct { - /** reg_lp_core_region_pms : R/W; bitpos: [1:0]; default: 3; - * NA - */ - uint32_t reg_lp_core_region_pms:2; - /** reg_hp_core0_um_region_pms : R/W; bitpos: [3:2]; default: 3; - * NA - */ - uint32_t reg_hp_core0_um_region_pms:2; - /** reg_hp_core0_mm_region_pms : R/W; bitpos: [5:4]; default: 3; - * NA - */ - uint32_t reg_hp_core0_mm_region_pms:2; - /** reg_hp_core1_um_region_pms : R/W; bitpos: [7:6]; default: 3; - * NA - */ - uint32_t reg_hp_core1_um_region_pms:2; - /** reg_hp_core1_mm_region_pms : R/W; bitpos: [9:8]; default: 3; - * NA - */ - uint32_t reg_hp_core1_mm_region_pms:2; + /** lp_core_region_pms : R/W; bitpos: [1:0]; default: 3; + * Configures whether LP core in machine mode has permission to access address region0 + * and address region1. Bit0 corresponds to region0 and bit1 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ + uint32_t lp_core_region_pms:2; + /** hp_core0_um_region_pms : R/W; bitpos: [3:2]; default: 3; + * Configures whether HP CPU0 in user mode has permission to access address region0 + * and address region1. Bit2 corresponds to region0 and bit3 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ + uint32_t hp_core0_um_region_pms:2; + /** hp_core0_mm_region_pms : R/W; bitpos: [5:4]; default: 3; + * Configures whether HP CPU0 in machine mode has permission to access address region0 + * and address region1. Bit4 corresponds to region0 and bit5 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ + uint32_t hp_core0_mm_region_pms:2; + /** hp_core1_um_region_pms : R/W; bitpos: [7:6]; default: 3; + * Configures whether HP CPU1 in user mode has permission to access address region0 + * and address region1. Bit6 corresponds to region0 and bit7 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ + uint32_t hp_core1_um_region_pms:2; + /** hp_core1_mm_region_pms : R/W; bitpos: [9:8]; default: 3; + * Configures whether HP CPU1 in machine mode has permission to access address region0 + * and address region1. Bit8 corresponds to region0 and bit9 corresponds to region1. + * 0: Not allowed + * 1: Allow + */ + uint32_t hp_core1_mm_region_pms:2; uint32_t reserved_10:22; }; uint32_t val; -} tee_peri_region_pms_reg_t; +} pms_peri_region_pms_reg_t; typedef struct { - volatile tee_pms_date_reg_t pms_date; - volatile tee_pms_clk_en_reg_t pms_clk_en; - volatile tee_lp_mm_pms_reg0_reg_t lp_mm_pms_reg0; - volatile tee_peri_region0_low_reg_t peri_region0_low; - volatile tee_peri_region0_high_reg_t peri_region0_high; - volatile tee_peri_region1_low_reg_t peri_region1_low; - volatile tee_peri_region1_high_reg_t peri_region1_high; - volatile tee_peri_region_pms_reg_t peri_region_pms; -} tee_dev_t; + volatile pms_lp_peri_pms_date_reg_t lp_peri_pms_date; + volatile pms_lp_peri_pms_clk_en_reg_t lp_peri_pms_clk_en; + volatile pms_lp_mm_lp_peri_pms_reg0_reg_t lp_mm_lp_peri_pms_reg0; + volatile pms_peri_regionn_low_reg_t peri_region0_low; + volatile pms_peri_regionn_high_reg_t peri_region0_high; + volatile pms_peri_regionn_low_reg_t peri_region1_low; + volatile pms_peri_regionn_high_reg_t peri_region1_high; + volatile pms_peri_region_pms_reg_t peri_region_pms; +} lp_peri_pms_dev_t; +extern lp_peri_pms_dev_t LP_PERI_PMS; #ifndef __cplusplus -_Static_assert(sizeof(tee_dev_t) == 0x20, "Invalid size of tee_dev_t structure"); +_Static_assert(sizeof(lp_peri_pms_dev_t) == 0x20, "Invalid size of lp_peri_pms_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/lp_spi_struct.h b/components/soc/esp32p4/include/soc/lp_spi_struct.h index b30c8192e110..8d052bf29713 100644 --- a/components/soc/esp32p4/include/soc/lp_spi_struct.h +++ b/components/soc/esp32p4/include/soc/lp_spi_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -116,7 +116,7 @@ typedef union { uint32_t reg_clkdiv_pre:4; uint32_t reserved_22:9; /** reg_clk_equ_sysclk : R/W; bitpos: [31]; default: 1; - * In the master mode 1: spi_clk is eqaul to system 0: spi_clk is divided from system + * In the master mode 1: spi_clk is equal to system 0: spi_clk is divided from system * clock. Can be configured in CONF state. */ uint32_t reg_clk_equ_sysclk:1; @@ -813,244 +813,19 @@ typedef union { } lp_spi_sleep_conf1_reg_t; -/** Group: LP SPI W0 REG */ -/** Type of spi_w0 register - * SPI CPU-controlled buffer0 +/** Group: LP SPI Wn REG */ +/** Type of spi_wn register + * SPI CPU-controlled buffer */ typedef union { struct { - /** reg_buf0 : R/W/SS; bitpos: [31:0]; default: 0; + /** reg_buf : R/W/SS; bitpos: [31:0]; default: 0; * data buffer */ - uint32_t reg_buf0:32; + uint32_t reg_buf:32; }; uint32_t val; -} lp_spi_w0_reg_t; - - -/** Group: LP SPI W1 REG */ -/** Type of spi_w1 register - * SPI CPU-controlled buffer1 - */ -typedef union { - struct { - /** reg_buf1 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf1:32; - }; - uint32_t val; -} lp_spi_w1_reg_t; - - -/** Group: LP SPI W2 REG */ -/** Type of spi_w2 register - * SPI CPU-controlled buffer2 - */ -typedef union { - struct { - /** reg_buf2 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf2:32; - }; - uint32_t val; -} lp_spi_w2_reg_t; - - -/** Group: LP SPI W3 REG */ -/** Type of spi_w3 register - * SPI CPU-controlled buffer3 - */ -typedef union { - struct { - /** reg_buf3 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf3:32; - }; - uint32_t val; -} lp_spi_w3_reg_t; - - -/** Group: LP SPI W4 REG */ -/** Type of spi_w4 register - * SPI CPU-controlled buffer4 - */ -typedef union { - struct { - /** reg_buf4 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf4:32; - }; - uint32_t val; -} lp_spi_w4_reg_t; - - -/** Group: LP SPI W5 REG */ -/** Type of spi_w5 register - * SPI CPU-controlled buffer5 - */ -typedef union { - struct { - /** reg_buf5 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf5:32; - }; - uint32_t val; -} lp_spi_w5_reg_t; - - -/** Group: LP SPI W6 REG */ -/** Type of spi_w6 register - * SPI CPU-controlled buffer6 - */ -typedef union { - struct { - /** reg_buf6 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf6:32; - }; - uint32_t val; -} lp_spi_w6_reg_t; - - -/** Group: LP SPI W7 REG */ -/** Type of spi_w7 register - * SPI CPU-controlled buffer7 - */ -typedef union { - struct { - /** reg_buf7 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf7:32; - }; - uint32_t val; -} lp_spi_w7_reg_t; - - -/** Group: LP SPI W8 REG */ -/** Type of spi_w8 register - * SPI CPU-controlled buffer8 - */ -typedef union { - struct { - /** reg_buf8 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf8:32; - }; - uint32_t val; -} lp_spi_w8_reg_t; - - -/** Group: LP SPI W9 REG */ -/** Type of spi_w9 register - * SPI CPU-controlled buffer9 - */ -typedef union { - struct { - /** reg_buf9 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf9:32; - }; - uint32_t val; -} lp_spi_w9_reg_t; - - -/** Group: LP SPI W10 REG */ -/** Type of spi_w10 register - * SPI CPU-controlled buffer10 - */ -typedef union { - struct { - /** reg_buf10 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf10:32; - }; - uint32_t val; -} lp_spi_w10_reg_t; - - -/** Group: LP SPI W11 REG */ -/** Type of spi_w11 register - * SPI CPU-controlled buffer11 - */ -typedef union { - struct { - /** reg_buf11 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf11:32; - }; - uint32_t val; -} lp_spi_w11_reg_t; - - -/** Group: LP SPI W12 REG */ -/** Type of spi_w12 register - * SPI CPU-controlled buffer12 - */ -typedef union { - struct { - /** reg_buf12 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf12:32; - }; - uint32_t val; -} lp_spi_w12_reg_t; - - -/** Group: LP SPI W13 REG */ -/** Type of spi_w13 register - * SPI CPU-controlled buffer13 - */ -typedef union { - struct { - /** reg_buf13 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf13:32; - }; - uint32_t val; -} lp_spi_w13_reg_t; - - -/** Group: LP SPI W14 REG */ -/** Type of spi_w14 register - * SPI CPU-controlled buffer14 - */ -typedef union { - struct { - /** reg_buf14 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf14:32; - }; - uint32_t val; -} lp_spi_w14_reg_t; - - -/** Group: LP SPI W15 REG */ -/** Type of spi_w15 register - * SPI CPU-controlled buffer15 - */ -typedef union { - struct { - /** reg_buf15 : R/W/SS; bitpos: [31:0]; default: 0; - * data buffer - */ - uint32_t reg_buf15:32; - }; - uint32_t val; -} lp_spi_w15_reg_t; +} lp_spi_wn_reg_t; /** Group: LP SPI SLAVE REG */ @@ -1062,7 +837,7 @@ typedef union { /** reg_clk_mode : R/W; bitpos: [1:0]; default: 0; * SPI clock mode bits. 0: SPI clock is off when CS inactive 1: SPI clock is delayed * one cycle after CS inactive 2: SPI clock is delayed two cycles after CS inactive 3: - * SPI clock is alwasy on. Can be configured in CONF state. + * SPI clock is always on. Can be configured in CONF state. */ uint32_t reg_clk_mode:2; /** reg_clk_mode_13 : R/W; bitpos: [2]; default: 0; @@ -1238,22 +1013,7 @@ typedef struct { volatile lp_spi_sleep_conf1_reg_t spi_sleep_conf1; volatile lp_spi_dma_int_set_reg_t spi_dma_int_set; uint32_t reserved_050[18]; - volatile lp_spi_w0_reg_t spi_w0; - volatile lp_spi_w1_reg_t spi_w1; - volatile lp_spi_w2_reg_t spi_w2; - volatile lp_spi_w3_reg_t spi_w3; - volatile lp_spi_w4_reg_t spi_w4; - volatile lp_spi_w5_reg_t spi_w5; - volatile lp_spi_w6_reg_t spi_w6; - volatile lp_spi_w7_reg_t spi_w7; - volatile lp_spi_w8_reg_t spi_w8; - volatile lp_spi_w9_reg_t spi_w9; - volatile lp_spi_w10_reg_t spi_w10; - volatile lp_spi_w11_reg_t spi_w11; - volatile lp_spi_w12_reg_t spi_w12; - volatile lp_spi_w13_reg_t spi_w13; - volatile lp_spi_w14_reg_t spi_w14; - volatile lp_spi_w15_reg_t spi_w15; + volatile lp_spi_wn_reg_t data_buf[16]; uint32_t reserved_0d8[2]; volatile lp_spi_slave_reg_t spi_slave; volatile lp_spi_slave1_reg_t spi_slave1; @@ -1263,11 +1023,12 @@ typedef struct { volatile lp_rnd_eco_cs_reg_t rnd_eco_cs; volatile lp_rnd_eco_low_reg_t rnd_eco_low; volatile lp_rnd_eco_high_reg_t rnd_eco_high; -} lp_dev_t; +} lp_spi_dev_t; +extern lp_spi_dev_t LP_SPI; #ifndef __cplusplus -_Static_assert(sizeof(lp_dev_t) == 0x100, "Invalid size of lp_dev_t structure"); +_Static_assert(sizeof(lp_spi_dev_t) == 0x100, "Invalid size of lp_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/reg_base.h b/components/soc/esp32p4/include/soc/reg_base.h index ca035cf30eb6..9a4b6fc06546 100644 --- a/components/soc/esp32p4/include/soc/reg_base.h +++ b/components/soc/esp32p4/include/soc/reg_base.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -43,7 +43,7 @@ #define DR_REG_REGDMA_BASE (DR_REG_HPPERIPH0_BASE + 0x82000) #define DR_REG_SDMMC_BASE (DR_REG_HPPERIPH0_BASE + 0x83000) #define DR_REG_H264_CORE_BASE (DR_REG_HPPERIPH0_BASE + 0x84000) -#define DR_REG_AHB_PDMA_BASE (DR_REG_HPPERIPH0_BASE + 0x85000) +#define DR_REG_AHB_DMA_BASE (DR_REG_HPPERIPH0_BASE + 0x85000) #define DR_REG_JPEG_BASE (DR_REG_HPPERIPH0_BASE + 0x86000) #define DR_REG_PPA_BASE (DR_REG_HPPERIPH0_BASE + 0x87000) #define DR_REG_DMA2D_BASE (DR_REG_HPPERIPH0_BASE + 0x88000) @@ -59,11 +59,14 @@ #define DR_REG_DDRPHY_BASE (DR_REG_HPPERIPH0_BASE + 0x9D000) #define DR_REG_PVT_BASE (DR_REG_HPPERIPH0_BASE + 0x9E000) #define DR_REG_CSI_HOST_BASE (DR_REG_HPPERIPH0_BASE + 0x9F000) +#define DR_REG_CSI_BRG_BASE (DR_REG_HPPERIPH0_BASE + 0x9F800) #define DR_REG_DSI_HOST_BASE (DR_REG_HPPERIPH0_BASE + 0xA0000) +#define DR_REG_DSI_BRG_BASE (DR_REG_HPPERIPH0_BASE + 0xA0800) #define DR_REG_ISP_BASE (DR_REG_HPPERIPH0_BASE + 0xA1000) #define DR_REG_RMT_BASE (DR_REG_HPPERIPH0_BASE + 0xA2000) #define DR_REG_BITSCRAM_BASE (DR_REG_HPPERIPH0_BASE + 0xA3000) #define DR_REG_AXI_ICM_BASE (DR_REG_HPPERIPH0_BASE + 0xA4000) +#define DR_REG_AXI_ICM_QOS_BASE (DR_REG_AXI_ICM_BASE + 0x400) #define DR_REG_HP_PERI_PMS_BASE (DR_REG_HPPERIPH0_BASE + 0xA5000) #define DR_REG_LP2HP_PERI_PMS_BASE (DR_REG_HPPERIPH0_BASE + 0xA5800) #define DR_REG_DMA_PMS_BASE (DR_REG_HPPERIPH0_BASE + 0xA6000) @@ -194,13 +197,6 @@ #define DR_REG_LPPERI_BASE DR_REG_LP_PERI_CLKRST_BASE #define DR_REG_CPU_BUS_MONITOR_BASE DR_REG_CPU_BUS_MON_BASE -//TODO: IDF-7542 -// #define DR_REG_TEE_BASE 0x60098000 -// #define DR_REG_HP_APM_BASE 0x60099000 -// #define DR_REG_LP_APM0_BASE 0x60099800 -// #define DR_REG_LP_TEE_BASE 0x600B3400 -// #define DR_REG_LP_APM_BASE 0x600B3800 - #define DR_REG_PAU_BASE DR_REG_REGDMA_BASE //TODO: IDF-7688 diff --git a/components/soc/esp32p4/include/soc/regi2c_brownout.h b/components/soc/esp32p4/include/soc/regi2c_brownout.h index 24377f93566c..0504a137056f 100644 --- a/components/soc/esp32p4/include/soc/regi2c_brownout.h +++ b/components/soc/esp32p4/include/soc/regi2c_brownout.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,3 +13,10 @@ * This file lists register fields of the brownout detector, located on an internal configuration * bus. These definitions are used via macros defined in regi2c_ctrl.h. */ + +#define I2C_BOD 0x61 +#define I2C_BOD_HOSTID 0 + +#define I2C_BOD_THRESHOLD 0x5 +#define I2C_BOD_THRESHOLD_MSB 2 +#define I2C_BOD_THRESHOLD_LSB 0 diff --git a/components/soc/esp32p4/include/soc/regi2c_saradc.h b/components/soc/esp32p4/include/soc/regi2c_saradc.h index b784a26a3eab..88fa3640bcdc 100644 --- a/components/soc/esp32p4/include/soc/regi2c_saradc.h +++ b/components/soc/esp32p4/include/soc/regi2c_saradc.h @@ -37,3 +37,44 @@ #define I2C_SAR_ADC_DTEST_VDD_GRP1 9 #define I2C_SAR_ADC_DTEST_VDD_GRP1_MSB 3 #define I2C_SAR_ADC_DTEST_VDD_GRP1_LSB 0 + +#define ADC_SAR1_SAMPLE_CYCLE_ADDR 0x2 +#define ADC_SAR1_SAMPLE_CYCLE_ADDR_MSB 0x2 +#define ADC_SAR1_SAMPLE_CYCLE_ADDR_LSB 0x0 + +#define ADC_SAR1_DREF_ADDR 0x2 +#define ADC_SAR1_DREF_ADDR_MSB 0x6 +#define ADC_SAR1_DREF_ADDR_LSB 0x4 + +#define ADC_SAR2_INITIAL_CODE_LOW_ADDR 0x3 +#define ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB 0x7 +#define ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB 0x0 + +#define ADC_SAR2_INITIAL_CODE_HIGH_ADDR 0x4 +#define ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB 0x3 +#define ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB 0x0 + + +#define ADC_SAR2_SAMPLE_CYCLE_ADDR 0x5 +#define ADC_SAR2_SAMPLE_CYCLE_ADDR_MSB 0x2 +#define ADC_SAR2_SAMPLE_CYCLE_ADDR_LSB 0x0 + +#define ADC_SAR2_DREF_ADDR 0x5 +#define ADC_SAR2_DREF_ADDR_MSB 0x6 +#define ADC_SAR2_DREF_ADDR_LSB 0x4 + +#define ADC_SAR1_ENCAL_REF_ADDR 0x7 +#define ADC_SAR1_ENCAL_REF_ADDR_MSB 4 +#define ADC_SAR1_ENCAL_REF_ADDR_LSB 4 + +#define ADC_SAR1_ENCAL_GND_ADDR 0x7 +#define ADC_SAR1_ENCAL_GND_ADDR_MSB 5 +#define ADC_SAR1_ENCAL_GND_ADDR_LSB 5 + +#define ADC_SAR2_ENCAL_REF_ADDR 0x7 +#define ADC_SAR2_ENCAL_REF_ADDR_MSB 6 +#define ADC_SAR2_ENCAL_REF_ADDR_LSB 6 + +#define ADC_SAR2_ENCAL_GND_ADDR 0x7 +#define ADC_SAR2_ENCAL_GND_ADDR_MSB 7 +#define ADC_SAR2_ENCAL_GND_ADDR_LSB 7 diff --git a/components/soc/esp32p4/include/soc/retention_periph_defs.h b/components/soc/esp32p4/include/soc/retention_periph_defs.h index fde9c3e68767..1460d3d5bf7a 100644 --- a/components/soc/esp32p4/include/soc/retention_periph_defs.h +++ b/components/soc/esp32p4/include/soc/retention_periph_defs.h @@ -17,10 +17,20 @@ typedef enum periph_retention_module { SLEEP_RETENTION_MODULE_MIN = 0, /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, - /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, - * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_SYS_PERIPH = 16, + * TEE, APM, UART, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_SYS_PERIPH = 2, + /* Timer Group by target*/ + SLEEP_RETENTION_MODULE_TG0_WDT = 3, + SLEEP_RETENTION_MODULE_TG1_WDT = 4, + SLEEP_RETENTION_MODULE_TG0_TIMER = 5, + SLEEP_RETENTION_MODULE_TG1_TIMER = 6, + /* MISC Peripherals */ + SLEEP_RETENTION_MODULE_UART0 = 7, + SLEEP_RETENTION_MODULE_UART1 = 8, + SLEEP_RETENTION_MODULE_UART2 = 9, + SLEEP_RETENTION_MODULE_UART3 = 10, + SLEEP_RETENTION_MODULE_UART4 = 11, SLEEP_RETENTION_MODULE_MAX = 31 } periph_retention_module_t; @@ -28,14 +38,37 @@ typedef enum periph_retention_module { typedef enum periph_retention_module_bitmap { /* clock module, which includes system and modem */ SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM), - /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), + /* Timer Group by target*/ + SLEEP_RETENTION_MODULE_BM_TG0_WDT = BIT(SLEEP_RETENTION_MODULE_TG0_WDT), + SLEEP_RETENTION_MODULE_BM_TG1_WDT = BIT(SLEEP_RETENTION_MODULE_TG1_WDT), + SLEEP_RETENTION_MODULE_BM_TG0_TIMER = BIT(SLEEP_RETENTION_MODULE_TG0_TIMER), + SLEEP_RETENTION_MODULE_BM_TG1_TIMER = BIT(SLEEP_RETENTION_MODULE_TG1_TIMER), + /* MISC Peripherals */ + SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0), + SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1), + SLEEP_RETENTION_MODULE_BM_UART2 = BIT(SLEEP_RETENTION_MODULE_UART2), + SLEEP_RETENTION_MODULE_BM_UART3 = BIT(SLEEP_RETENTION_MODULE_UART3), + SLEEP_RETENTION_MODULE_BM_UART4 = BIT(SLEEP_RETENTION_MODULE_UART4), SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1 } periph_retention_module_bitmap_t; +#define TOP_DOMAIN_PERIPHERALS_BM (SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM \ + | SLEEP_RETENTION_MODULE_BM_SYS_PERIPH \ + | SLEEP_RETENTION_MODULE_BM_TG0_WDT \ + | SLEEP_RETENTION_MODULE_BM_TG1_WDT \ + | SLEEP_RETENTION_MODULE_BM_TG0_TIMER \ + | SLEEP_RETENTION_MODULE_BM_TG1_TIMER \ + | SLEEP_RETENTION_MODULE_BM_UART0 \ + | SLEEP_RETENTION_MODULE_BM_UART1 \ + | SLEEP_RETENTION_MODULE_BM_UART2 \ + | SLEEP_RETENTION_MODULE_BM_UART3 \ + | SLEEP_RETENTION_MODULE_BM_UART4 \ + ) + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index ffe827f7393a..71d88b890a22 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -17,7 +17,7 @@ #pragma once /*-------------------------- COMMON CAPS ---------------------------------------*/ -// #define SOC_ADC_SUPPORTED 1 //TODO: IDF-6496 +#define SOC_ADC_SUPPORTED 1 #define SOC_ANA_CMPR_SUPPORTED 1 #define SOC_DEDICATED_GPIO_SUPPORTED 1 #define SOC_UART_SUPPORTED 1 @@ -29,18 +29,18 @@ #define SOC_GPTIMER_SUPPORTED 1 #define SOC_PCNT_SUPPORTED 1 // #define SOC_LCDCAM_SUPPORTED 1 // TODO: IDF-7465 +#define SOC_LCDCAM_CAM_SUPPORTED 1 #define SOC_MIPI_CSI_SUPPORTED 1 #define SOC_MIPI_DSI_SUPPORTED 1 #define SOC_MCPWM_SUPPORTED 1 #define SOC_TWAI_SUPPORTED 1 #define SOC_ETM_SUPPORTED 1 -// #define SOC_PARLIO_SUPPORTED 1 //TODO: IDF-7471 +#define SOC_PARLIO_SUPPORTED 1 #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_EMAC_SUPPORTED 1 #define SOC_USB_OTG_SUPPORTED 1 #define SOC_WIRELESS_HOST_SUPPORTED 1 -// disable usb serial jtag for esp32p4, current image does not support -// #define SOC_USB_SERIAL_JTAG_SUPPORTED 1 //TODO: IDF-7496 +#define SOC_USB_SERIAL_JTAG_SUPPORTED 1 #define SOC_TEMP_SENSOR_SUPPORTED 1 #define SOC_SUPPORTS_SECURE_DL_MODE 1 #define SOC_ULP_SUPPORTED 1 @@ -64,12 +64,12 @@ #define SOC_DIG_SIGN_SUPPORTED 1 #define SOC_ECC_SUPPORTED 1 #define SOC_ECC_EXTENDED_MODES_SUPPORTED 1 -#define SOC_ECDSA_SUPPORTED 1 -#define SOC_KEY_MANAGER_SUPPORTED 1 +#define SOC_ECDSA_SUPPORTED 0 +#define SOC_KEY_MANAGER_SUPPORTED 0 #define SOC_FLASH_ENC_SUPPORTED 1 #define SOC_SECURE_BOOT_SUPPORTED 1 -// #define SOC_BOD_SUPPORTED 1 //TODO: IDF-7519 -// #define SOC_APM_SUPPORTED 1 //TODO: IDF-7542 +#define SOC_BOD_SUPPORTED 1 +#define SOC_APM_SUPPORTED 1 #define SOC_PMU_SUPPORTED 1 #define SOC_DCDC_SUPPORTED 1 #define SOC_PAU_SUPPORTED 1 //TODO: IDF-7531 @@ -78,6 +78,7 @@ #define SOC_LP_GPIO_MATRIX_SUPPORTED 1 #define SOC_LP_PERIPHERALS_SUPPORTED 1 #define SOC_LP_I2C_SUPPORTED 1 +#define SOC_LP_SPI_SUPPORTED 1 #define SOC_SPIRAM_SUPPORTED 1 #define SOC_PSRAM_DMA_CAPABLE 1 // #define SOC_ULP_SUPPORTED 1 //TODO: IDF-7534 @@ -86,12 +87,13 @@ #define SOC_ASSIST_DEBUG_SUPPORTED 1 #define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 -// #define SOC_TOUCH_SENSOR_SUPPORTED 1 //TODO: IDF-7477 +#define SOC_TOUCH_SENSOR_SUPPORTED 1 #define SOC_RNG_SUPPORTED 1 #define SOC_GP_LDO_SUPPORTED 1 // General purpose LDO -// #define SOC_PPA_SUPPORTED 1 //TODO: IDF-6878 +#define SOC_PPA_SUPPORTED 1 #define SOC_LIGHT_SLEEP_SUPPORTED 1 #define SOC_DEEP_SLEEP_SUPPORTED 1 +#define SOC_PM_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 @@ -108,19 +110,20 @@ /*-------------------------- ADC CAPS -------------------------------*/ /*!< SAR ADC Module*/ -// #define SOC_ADC_DIG_CTRL_SUPPORTED 1 //TODO: IDF-6496, TODO: IDF-6497 +#define SOC_ADC_RTC_CTRL_SUPPORTED 1 +#define SOC_ADC_DIG_CTRL_SUPPORTED 1 // #define SOC_ADC_DIG_IIR_FILTER_SUPPORTED 1 // #define SOC_ADC_MONITOR_SUPPORTED 1 #define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) 1 //Digital controller supported ADC unit -// #define SOC_ADC_DMA_SUPPORTED 1 -#define SOC_ADC_PERIPH_NUM (1U) -#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) (7) -#define SOC_ADC_MAX_CHANNEL_NUM (7) +#define SOC_ADC_DMA_SUPPORTED 1 +#define SOC_ADC_PERIPH_NUM (2) +#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 6: 8) +#define SOC_ADC_MAX_CHANNEL_NUM (8) #define SOC_ADC_ATTEN_NUM (4) /*!< Digital */ -#define SOC_ADC_DIGI_CONTROLLER_NUM (1U) -#define SOC_ADC_PATT_LEN_MAX (8) /*!< Two pattern tables, each contains 4 items. Each item takes 1 byte */ +#define SOC_ADC_DIGI_CONTROLLER_NUM (2) +#define SOC_ADC_PATT_LEN_MAX (16) /*!< Four pattern tables, each contains 4 items. Each item takes 1 byte */ #define SOC_ADC_DIGI_MAX_BITWIDTH (12) #define SOC_ADC_DIGI_MIN_BITWIDTH (12) #define SOC_ADC_DIGI_IIR_FILTER_NUM (2) @@ -138,6 +141,9 @@ /*!< Calibration */ #define SOC_ADC_CALIBRATION_V1_SUPPORTED (0) /*!< support HW offset calibration version 1*/ +/*!< ADC power control is shared by PWDET, TempSensor */ +#define SOC_ADC_SHARED_POWER 1 + // ESP32P4-TODO: Copy from esp32c6, need check /*-------------------------- APB BACKUP DMA CAPS -------------------------------*/ #define SOC_APB_BACKUP_DMA (0) @@ -158,9 +164,15 @@ #define SOC_INT_CLIC_SUPPORTED 1 #define SOC_INT_HW_NESTED_SUPPORTED 1 // Support for hardware interrupts nesting #define SOC_BRANCH_PREDICTOR_SUPPORTED 1 +#define SOC_CPU_COPROC_NUM 3 #define SOC_CPU_HAS_FPU 1 #define SOC_CPU_HAS_FPU_EXT_ILL_BUG 1 // EXT_ILL CSR doesn't support FLW/FSW -#define SOC_CPU_COPROC_NUM 2 +#define SOC_CPU_HAS_HWLOOP 1 +/* PIE coprocessor assembly is only supported with GCC compiler */ +#ifndef __clang__ +#define SOC_CPU_HAS_PIE 1 +#endif + #define SOC_HP_CPU_HAS_MULTIPLE_CORES 1 // Convenience boolean macro used to determine if a target has multiple cores. #define SOC_CPU_BREAKPOINTS_NUM 3 @@ -182,6 +194,9 @@ See TRM DS chapter for more details */ #define SOC_DS_KEY_CHECK_MAX_WAIT_US (1100) +/*-------------------------- DMA Common CAPS ----------------------------------------*/ +#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */ + /*-------------------------- GDMA CAPS -------------------------------------*/ #define SOC_AHB_GDMA_VERSION 2 #define SOC_GDMA_SUPPORT_CRC 1 @@ -190,6 +205,7 @@ #define SOC_AXI_GDMA_SUPPORT_PSRAM 1 #define SOC_GDMA_SUPPORT_ETM 1 // #define SOC_GDMA_SUPPORT_SLEEP_RETENTION 1 +#define SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT (16) /*-------------------------- 2D-DMA CAPS -------------------------------------*/ #define SOC_DMA2D_GROUPS (1U) // Number of 2D-DMA groups @@ -211,14 +227,13 @@ // GPIO peripheral has the ETM extension #define SOC_GPIO_SUPPORT_ETM 1 -#define SOC_GPIO_ETM_EVENTS_PER_GROUP 8 -#define SOC_GPIO_ETM_TASKS_PER_GROUP 8 // Target has the full LP IO subsystem // On ESP32-P4, Digital IOs have their own registers to control pullup/down capability, independent of LP registers. #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) // GPIO0~15 on ESP32P4 can support chip deep sleep wakeup #define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) +#define SOC_LP_IO_HAS_INDEPENDENT_WAKEUP_SOURCE (1) #define SOC_GPIO_VALID_GPIO_MASK (0x007FFFFFFFFFFFFF) #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK SOC_GPIO_VALID_GPIO_MASK @@ -227,6 +242,7 @@ #define SOC_GPIO_OUT_RANGE_MAX 54 #define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK (0ULL | 0xFFFF) +#define SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT (16) // digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_16~GPIO_NUM_54) #define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x007FFFFFFFFF0000ULL @@ -304,10 +320,19 @@ #define SOC_I2S_TDM_FULL_DATA_WIDTH (1) /*!< No limitation to data bit width when using multiple slots */ /*-------------------------- ISP CAPS ----------------------------------------*/ +#define SOC_ISP_BF_SUPPORTED 1 +#define SOC_ISP_CCM_SUPPORTED 1 +#define SOC_ISP_DVP_SUPPORTED 1 + #define SOC_ISP_NUMS 1U +#define SOC_ISP_DVP_CTLR_NUMS 1U #define SOC_ISP_AF_CTLR_NUMS 1U #define SOC_ISP_AF_WINDOW_NUMS 3 #define SOC_ISP_SHARE_CSI_BRG 1 +#define SOC_ISP_BF_TEMPLATE_X_NUMS 3 +#define SOC_ISP_BF_TEMPLATE_Y_NUMS 3 +#define SOC_ISP_CCM_DIMENSION 3 +#define SOC_ISP_DVP_DATA_WIDTH_MAX 16 /*-------------------------- LEDC CAPS ---------------------------------------*/ #define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1) @@ -324,6 +349,7 @@ #define SOC_MMU_PERIPH_NUM (2U) #define SOC_MMU_LINEAR_ADDRESS_REGION_NUM (2U) #define SOC_MMU_DI_VADDR_SHARED (1) /*!< D/I vaddr are shared */ +#define SOC_MMU_PER_EXT_MEM_TARGET (1) /*!< MMU is per physical external memory target (flash, psram) */ /*-------------------------- MPU CAPS ----------------------------------------*/ #define SOC_MPU_CONFIGURABLE_REGIONS_SUPPORTED 0 @@ -393,6 +419,7 @@ #define SOC_PARLIO_RX_UNITS_PER_GROUP 1U /*!< number of RX units in each group */ #define SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH 16 /*!< Number of data lines of the TX unit */ #define SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH 16 /*!< Number of data lines of the RX unit */ +#define SOC_PARLIO_RX_CLK_SUPPORT_OUTPUT 1 /*!< Support output RX clock to a GPIO */ #define SOC_PARLIO_TX_SIZE_BY_DMA 1 /*!< Transaction length is controlled by DMA instead of indicated by register */ /*--------------------------- MPI CAPS ---------------------------------------*/ @@ -476,6 +503,10 @@ #define SOC_MEMSPI_IS_INDEPENDENT 1 #define SOC_SPI_MAX_PRE_DIVIDER 16 +/*-------------------------- LP SPI CAPS ----------------------------------------*/ +#define SOC_LP_SPI_PERIPH_NUM 1 +#define SOC_LP_SPI_MAXIMUM_BUFFER_SIZE 64 + /*-------------------------- SPI MEM CAPS ---------------------------------------*/ #define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1) //#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1) //TODO: IDF-7518 @@ -483,7 +514,7 @@ #define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) -#define SOC_SPI_MEM_SUPPORT_WRAP (1) +// #define SOC_SPI_MEM_SUPPORT_WRAP (1) //TODO: IDFCI-2073 #define SOC_SPI_MEM_SUPPORT_TIMING_TUNING (1) #define SOC_MEMSPI_TIMING_TUNING_BY_DQS (1) @@ -491,6 +522,9 @@ #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED 1 +/*-------------------------- SPIRAM CAPS ----------------------------------------*/ +#define SOC_SPIRAM_XIP_SUPPORTED 1 + /*-------------------------- SYSTIMER CAPS ----------------------------------*/ #define SOC_SYSTIMER_COUNTER_NUM 2 // Number of counter units #define SOC_SYSTIMER_ALARM_NUM 3 // Number of alarm units @@ -514,16 +548,23 @@ #define SOC_TIMER_GROUP_SUPPORT_RC_FAST 1 #define SOC_TIMER_GROUP_TOTAL_TIMERS 4 #define SOC_TIMER_SUPPORT_ETM 1 +#define SOC_TIMER_SUPPORT_SLEEP_RETENTION 1 /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ #define SOC_MWDT_SUPPORT_XTAL (1) /*-------------------------- TOUCH SENSOR CAPS -------------------------------*/ -#define SOC_TOUCH_SENSOR_VERSION (3) // Hardware version of touch sensor -#define SOC_TOUCH_SENSOR_NUM (14) // Touch available channel number. Actually there are 15 Touch channels, but channel 14 is not pinned out, limit to 14 channels -#define SOC_TOUCH_PROXIMITY_CHANNEL_NUM (3) // Sopport touch proximity channel number. -#define SOC_TOUCH_PROXIMITY_MEAS_DONE_SUPPORTED (1) // Sopport touch proximity channel measure done interrupt type. -#define SOC_TOUCH_SAMPLER_NUM (3) // The sampler number in total, each sampler can be used to sample on one frequency +#define SOC_TOUCH_SENSOR_VERSION (3) /*!< Hardware version of touch sensor */ +#define SOC_TOUCH_SENSOR_NUM (14) /*!< Touch available channel number. Actually there are 15 Touch channels, but channel 14 is not pinned out, limit to 14 channels */ + +/* Touch Sensor Features */ +#define SOC_TOUCH_SUPPORT_SLEEP_WAKEUP (1) /*!< Touch sensor supports sleep awake */ +#define SOC_TOUCH_SUPPORT_WATERPROOF (1) /*!< Touch sensor supports waterproof */ +#define SOC_TOUCH_SUPPORT_PROX_SENSING (1) /*!< Touch sensor supports proximity sensing */ +#define SOC_TOUCH_PROXIMITY_CHANNEL_NUM (3) /*!< Support touch proximity channel number. */ +#define SOC_TOUCH_PROXIMITY_MEAS_DONE_SUPPORTED (1) /*!< Support touch proximity channel measure done interrupt type. */ +#define SOC_TOUCH_SUPPORT_FREQ_HOP (1) /*!< Touch sensor supports frequency hopping */ +#define SOC_TOUCH_SAMPLE_CFG_NUM (3) /*!< The sample configurations number in total, each sampler can be used to sample on one frequency */ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 3 @@ -539,7 +580,11 @@ #define SOC_EFUSE_SOFT_DIS_JTAG 1 /* Capability to disable the MSPI access in download mode */ #define SOC_EFUSE_DIS_DOWNLOAD_MSPI 1 +#define SOC_EFUSE_ECDSA_KEY 1 +/*-------------------------- Key Manager CAPS----------------------------*/ +#define SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY 1 /*!< Key manager responsible to deploy ECDSA key */ +#define SOC_KEY_MANAGER_FE_KEY_DEPLOY 1 /*!< Key manager responsible to deploy Flash Encryption key */ /*-------------------------- Secure Boot CAPS----------------------------*/ #define SOC_SECURE_BOOT_V2_RSA 1 #define SOC_SECURE_BOOT_V2_ECC 1 @@ -553,7 +598,6 @@ #define SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS 1 #define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 #define SOC_FLASH_ENCRYPTION_XTS_AES_256 1 - /*-------------------------- MEMPROT CAPS ------------------------------------*/ /*-------------------------- UART CAPS ---------------------------------------*/ @@ -569,6 +613,7 @@ #define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ #define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */ +#define SOC_UART_SUPPORT_SLEEP_RETENTION (1) /*!< Support back up registers before sleep */ // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) @@ -590,12 +635,14 @@ #define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*!= bus_name##_ADDRESS_LOW && (vaddr) < bus_name##_ADDRESS_HIGH) diff --git a/components/soc/esp32s3/include/soc/sens_reg.h b/components/soc/esp32s3/include/soc/sens_reg.h index 666f3a9c1282..ca14d862dc92 100644 --- a/components/soc/esp32s3/include/soc/sens_reg.h +++ b/components/soc/esp32s3/include/soc/sens_reg.h @@ -1,16 +1,8 @@ -// Copyright 2017-2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _SOC_SENS_REG_H_ #define _SOC_SENS_REG_H_ @@ -602,7 +594,7 @@ extern "C" { #define SENS_TOUCH_DENOISE_END_V 0x1 #define SENS_TOUCH_DENOISE_END_S 18 /* SENS_TOUCH_DATA_SEL : R/W ;bitpos:[17:16] ;default: 2'd0 ; */ -/*description: 3: smooth data 2: baseline 1,0: raw_data.*/ +/*description: 3: smooth data 2: benchmark 1,0: raw_data.*/ #define SENS_TOUCH_DATA_SEL 0x00000003 #define SENS_TOUCH_DATA_SEL_M ((SENS_TOUCH_DATA_SEL_V)<<(SENS_TOUCH_DATA_SEL_S)) #define SENS_TOUCH_DATA_SEL_V 0x3 @@ -1378,8 +1370,8 @@ extern "C" { #define SENS_SAR_HALL_CTRL_REG (DR_REG_SENS_BASE + 0xFC) /* SENS_HALL_PHASE_FORCE : R/W ;bitpos:[31] ;default: 1'b1 ; */ -/*description: 1: HALL PHASE is controlled by SW 0: HALL PHASE is controlled by FSM in ULP-cop -rocessor.*/ +/*description: 1: HALL PHASE is controlled by SW 0: HALL PHASE is controlled by FSM in +ULP-coprocessor.*/ #define SENS_HALL_PHASE_FORCE (BIT(31)) #define SENS_HALL_PHASE_FORCE_M (BIT(31)) #define SENS_HALL_PHASE_FORCE_V 0x1 diff --git a/components/soc/esp32s3/include/soc/sens_struct.h b/components/soc/esp32s3/include/soc/sens_struct.h index c2a104d4ccf7..3fb730f3c953 100644 --- a/components/soc/esp32s3/include/soc/sens_struct.h +++ b/components/soc/esp32s3/include/soc/sens_struct.h @@ -217,7 +217,7 @@ typedef volatile struct sens_dev_s { struct { uint32_t touch_outen : 15; /*touch controller output enable*/ uint32_t touch_status_clr : 1; /*clear all touch active status*/ - uint32_t touch_data_sel : 2; /*3: smooth data 2: baseline 1,0: raw_data*/ + uint32_t touch_data_sel : 2; /*3: smooth data 2: benchmark 1,0: raw_data*/ uint32_t touch_denoise_end : 1; /*touch_denoise_done*/ uint32_t touch_unit_end : 1; /*touch_unit_done*/ uint32_t touch_approach_pad2 : 4; /*indicate which pad is approach pad2*/ diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 536560d2d126..90545f5d852f 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -79,6 +79,7 @@ #define SOC_LIGHT_SLEEP_SUPPORTED 1 #define SOC_DEEP_SLEEP_SUPPORTED 1 #define SOC_LP_PERIPH_SHARE_INTERRUPT 1 // LP peripherals sharing the same interrupt source +#define SOC_PM_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 @@ -369,12 +370,15 @@ #define SOC_TIMER_GROUP_TOTAL_TIMERS (4) /*-------------------------- TOUCH SENSOR CAPS -------------------------------*/ -#define SOC_TOUCH_SENSOR_VERSION (2) // Hardware version of touch sensor -#define SOC_TOUCH_SENSOR_NUM (15) /*! 15 Touch channels */ -#define SOC_TOUCH_PROXIMITY_CHANNEL_NUM (3) /* Sopport touch proximity channel number. */ -#define SOC_TOUCH_PROXIMITY_MEAS_DONE_SUPPORTED (1) /*Sopport touch proximity channel measure done interrupt type. */ - -#define SOC_TOUCH_SAMPLER_NUM (1U) /*!< The sampler number in total, each sampler can be used to sample on one frequency */ +#define SOC_TOUCH_SENSOR_VERSION (2) /*!< Hardware version of touch sensor */ +#define SOC_TOUCH_SENSOR_NUM (15) /*!< 15 Touch channels */ +#define SOC_TOUCH_SUPPORT_SLEEP_WAKEUP (1) /*!< Touch sensor supports sleep awake */ +#define SOC_TOUCH_SUPPORT_WATERPROOF (1) /*!< Touch sensor supports waterproof */ +#define SOC_TOUCH_SUPPORT_PROX_SENSING (1) /*!< Touch sensor supports proximity sensing */ +#define SOC_TOUCH_PROXIMITY_CHANNEL_NUM (3) /*!< Support touch proximity sensing channel number. */ +#define SOC_TOUCH_PROXIMITY_MEAS_DONE_SUPPORTED (1) /*!< Support touch proximity sensing measure done interrupt type. */ + +#define SOC_TOUCH_SAMPLE_CFG_NUM (1U) /*!< The sample configuration number in total, each sampler can be used to sample on one frequency */ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1UL diff --git a/components/soc/esp32s3/touch_sensor_periph.c b/components/soc/esp32s3/touch_sensor_periph.c index 0bf0a0b3b9e6..b948cbf82bb3 100644 --- a/components/soc/esp32s3/touch_sensor_periph.c +++ b/components/soc/esp32s3/touch_sensor_periph.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/touch_sensor_periph.h" +#include "soc/touch_sensor_channel.h" /* Store IO number corresponding to the Touch Sensor channel number. */ /* Note: T0 is an internal channel that does not have a corresponding external GPIO. */ diff --git a/components/soc/esp32s3/uart_periph.c b/components/soc/esp32s3/uart_periph.c index 450787854f6b..c9f0a2f4b4eb 100644 --- a/components/soc/esp32s3/uart_periph.c +++ b/components/soc/esp32s3/uart_periph.c @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "soc/uart_periph.h" @@ -49,7 +41,6 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { } }, .irq = ETS_UART0_INTR_SOURCE, - .module = PERIPH_UART0_MODULE, }, { @@ -83,7 +74,6 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { }, }, .irq = ETS_UART1_INTR_SOURCE, - .module = PERIPH_UART1_MODULE, }, { @@ -117,6 +107,5 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { } }, .irq = ETS_UART2_INTR_SOURCE, - .module = PERIPH_UART2_MODULE, } }; diff --git a/components/soc/include/soc/cam_periph.h b/components/soc/include/soc/cam_periph.h new file mode 100644 index 000000000000..e71f973656ea --- /dev/null +++ b/components/soc/include/soc/cam_periph.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc_caps.h" +#include "soc/periph_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_LCDCAM_CAM_SUPPORTED +typedef struct { + struct { + const periph_module_t module; + const int irq_id; + const int data_sigs[SOC_LCDCAM_CAM_DATA_WIDTH_MAX]; + const int hsync_sig; + const int vsync_sig; + const int pclk_sig; + const int de_sig; + const int clk_sig; + } buses[SOC_LCDCAM_CAM_PERIPH_NUM]; +} cam_signal_conn_t; + +extern const cam_signal_conn_t cam_periph_signals; +#endif // SOC_LCDCAM_CAM_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/include/soc/emac_periph.h b/components/soc/include/soc/emac_periph.h index 6f7323f46fed..bccc1ccb1f9e 100644 --- a/components/soc/include/soc/emac_periph.h +++ b/components/soc/include/soc/emac_periph.h @@ -1,15 +1,89 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once +#include +#include "soc/soc_caps.h" +#include "soc/gpio_sig_map.h" +#include "soc/gpio_num.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_EMAC_SUPPORTED +/** + * This structure lists pin numbers + */ +typedef struct { + uint32_t mdc_idx; + uint32_t mdo_idx; + uint32_t mdi_idx; + uint32_t mii_tx_clk_i_idx; + uint32_t mii_tx_en_o_idx; + uint32_t mii_txd0_o_idx; + uint32_t mii_txd1_o_idx; + uint32_t mii_txd2_o_idx; + uint32_t mii_txd3_o_idx; + uint32_t mii_rx_clk_i_idx; + uint32_t mii_rx_dv_i_idx; + uint32_t mii_rxd0_i_idx; + uint32_t mii_rxd1_i_idx; + uint32_t mii_rxd2_i_idx; + uint32_t mii_rxd3_i_idx; + uint32_t mii_col_i_idx; + uint32_t mii_crs_i_idx; + uint32_t mii_rx_er_i_idx; + uint32_t mii_tx_er_o_idx; +} emac_io_info_t; + +typedef struct { + gpio_num_t gpio_num; + uint32_t func; +} emac_iomux_info_t; + +typedef struct { + const emac_iomux_info_t *clki; + const emac_iomux_info_t *clko; + const emac_iomux_info_t *tx_en; + const emac_iomux_info_t *txd0; + const emac_iomux_info_t *txd1; + const emac_iomux_info_t *crs_dv; + const emac_iomux_info_t *rxd0; + const emac_iomux_info_t *rxd1; + const emac_iomux_info_t *tx_er; + const emac_iomux_info_t *rx_er; +} emac_rmii_iomux_info_t; + +typedef struct { + const emac_iomux_info_t *clk_tx; + const emac_iomux_info_t *tx_en; + const emac_iomux_info_t *txd0; + const emac_iomux_info_t *txd1; + const emac_iomux_info_t *txd2; + const emac_iomux_info_t *txd3; + const emac_iomux_info_t *clk_rx; + const emac_iomux_info_t *rx_dv; + const emac_iomux_info_t *rxd0; + const emac_iomux_info_t *rxd1; + const emac_iomux_info_t *rxd2; + const emac_iomux_info_t *rxd3; + const emac_iomux_info_t *tx_er; + const emac_iomux_info_t *rx_er; + const emac_iomux_info_t *col_in; + const emac_iomux_info_t *crs_in; +} emac_mii_iomux_info_t; + +extern const emac_io_info_t emac_io_idx; +extern const emac_rmii_iomux_info_t emac_rmii_iomux_pins; +extern const emac_mii_iomux_info_t emac_mii_iomux_pins; + +#endif // SOC_EMAC_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/include/soc/gdma_periph.h b/components/soc/include/soc/gdma_periph.h index 2d4459808001..233c366ebb5f 100644 --- a/components/soc/include/soc/gdma_periph.h +++ b/components/soc/include/soc/gdma_periph.h @@ -8,10 +8,7 @@ #include "soc/soc_caps.h" #include "soc/periph_defs.h" - -#if SOC_PM_SUPPORT_TOP_PD #include "soc/regdma.h" -#endif #ifdef __cplusplus extern "C" { @@ -36,7 +33,7 @@ typedef struct { uint32_t link_num; } gdma_chx_reg_ctx_link_t; -extern const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_PAIRS_PER_GROUP_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX]; +extern const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_NUM_GROUPS_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX]; #endif #endif diff --git a/components/soc/include/soc/i2c_periph.h b/components/soc/include/soc/i2c_periph.h index 47471d9e22bb..c72e7720f16e 100644 --- a/components/soc/include/soc/i2c_periph.h +++ b/components/soc/include/soc/i2c_periph.h @@ -10,9 +10,7 @@ #include "soc/soc_caps.h" #if SOC_I2C_SUPPORTED // TODO: [ESP32C5] IDF-8694 #include "soc/periph_defs.h" -#if SOC_PM_SUPPORT_TOP_PD #include "soc/regdma.h" -#endif #endif // SOC_I2C_SUPPORTED #ifdef __cplusplus @@ -32,7 +30,7 @@ typedef struct { extern const i2c_signal_conn_t i2c_periph_signal[SOC_I2C_NUM]; -#if SOC_PM_SUPPORT_TOP_PD +#if SOC_I2C_SUPPORT_SLEEP_RETENTION typedef struct { const regdma_entries_config_t *link_list; uint32_t link_num; diff --git a/components/soc/include/soc/isp_periph.h b/components/soc/include/soc/isp_periph.h index 54185323d6ee..288ed884c68a 100644 --- a/components/soc/include/soc/isp_periph.h +++ b/components/soc/include/soc/isp_periph.h @@ -9,6 +9,7 @@ #include #include "soc/soc_caps.h" #include "soc/periph_defs.h" +#include "soc/gpio_sig_map.h" #ifdef __cplusplus extern "C" { @@ -19,6 +20,13 @@ typedef struct { struct { const uint32_t irq; } instances[SOC_ISP_NUMS]; + struct { + const uint32_t dvp_pclk_sig; + const uint32_t dvp_hsync_sig; + const uint32_t dvp_vsync_sig; + const uint32_t dvp_de_sig; + const uint32_t dvp_data_sig[SOC_ISP_DVP_DATA_WIDTH_MAX]; + } dvp_ctlr[SOC_ISP_DVP_CTLR_NUMS]; } isp_info_t; extern const isp_info_t isp_hw_info; diff --git a/components/soc/include/soc/regdma.h b/components/soc/include/soc/regdma.h index 1662f733afac..59897b1ebf37 100644 --- a/components/soc/include/soc/regdma.h +++ b/components/soc/include/soc/regdma.h @@ -37,15 +37,19 @@ extern "C" { #define REGDMA_TEEAPM_LINK(_pri) ((0x0f << 8) | _pri) #define REGDMA_UART_LINK(_pri) ((0x10 << 8) | _pri) -#define REGDMA_TIMG_LINK(_pri) ((0x11 << 8) | _pri) -#define REGDMA_IOMUX_LINK(_pri) ((0x12 << 8) | _pri) -#define REGDMA_SPIMEM_LINK(_pri) ((0x13 << 8) | _pri) -#define REGDMA_SYSTIMER_LINK(_pri) ((0x14 << 8) | _pri) -#define REGDMA_BLE_MAC_LINK(_pri) ((0x15 << 8) | _pri) -#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x16 << 8) | _pri) -#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x17 << 8) | _pri) -#define REGDMA_GDMA_LINK(_pri) ((0x18 << 8) | _pri) -#define REGDMA_I2C_LINK(_pri) ((0x19 << 8) | _pri) +#define REGDMA_IOMUX_LINK(_pri) ((0x11 << 8) | _pri) +#define REGDMA_SPIMEM_LINK(_pri) ((0x12 << 8) | _pri) +#define REGDMA_SYSTIMER_LINK(_pri) ((0x13 << 8) | _pri) +#define REGDMA_BLE_MAC_LINK(_pri) ((0x14 << 8) | _pri) +#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x15 << 8) | _pri) +#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x16 << 8) | _pri) +#define REGDMA_GDMA_LINK(_pri) ((0x17 << 8) | _pri) +#define REGDMA_I2C_LINK(_pri) ((0x18 << 8) | _pri) +#define REGDMA_RMT_LINK(_pri) ((0x19 << 8) | _pri) +#define REGDMA_TG0_WDT_LINK(_pri) ((0x1A << 8) | _pri) +#define REGDMA_TG1_WDT_LINK(_pri) ((0x1B << 8) | _pri) +#define REGDMA_TG0_TIMER_LINK(_pri) ((0x1C << 8) | _pri) +#define REGDMA_TG1_TIMER_LINK(_pri) ((0x1D << 8) | _pri) #define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri) #define REGDMA_LINK_PRI_SYS_CLK REGDMA_LINK_PRI_0 @@ -56,8 +60,13 @@ extern "C" { #define REGDMA_LINK_PRI_BT_MAC_BB REGDMA_LINK_PRI_5 #define REGDMA_LINK_PRI_SYS_PERIPH_HIGH REGDMA_LINK_PRI_5 // INT_MTX & HP_SYSTEM & Console UART #define REGDMA_LINK_PRI_SYS_PERIPH_LOW REGDMA_LINK_PRI_6 // TG0 & IO MUX & SPI MEM & Systimer -#define REGDMA_LINK_PRI_IEEE802154 REGDMA_LINK_PRI_7 -#define REGDMA_LINK_PRI_GDMA REGDMA_LINK_PRI_7 +#define REGDMA_LINK_PRI_GENERAL_PERIPH REGDMA_LINK_PRI_7 // Low retenion priority for general peripherals +#define REGDMA_LINK_PRI_IEEE802154 REGDMA_LINK_PRI_GENERAL_PERIPH +#define REGDMA_LINK_PRI_GDMA REGDMA_LINK_PRI_GENERAL_PERIPH +#define REGDMA_LINK_PRI_RMT REGDMA_LINK_PRI_GENERAL_PERIPH +#define REGDMA_LINK_PRI_GPTIMER REGDMA_LINK_PRI_GENERAL_PERIPH +#define REGDMA_LINK_PRI_I2C REGDMA_LINK_PRI_GENERAL_PERIPH +#define REGDMA_LINK_PRI_UART REGDMA_LINK_PRI_GENERAL_PERIPH typedef enum { REGDMA_LINK_PRI_0 = 0, diff --git a/components/soc/include/soc/rtc_io_periph.h b/components/soc/include/soc/rtc_io_periph.h index 3eadcfda1a0d..b8c23f0e06dd 100644 --- a/components/soc/include/soc/rtc_io_periph.h +++ b/components/soc/include/soc/rtc_io_periph.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,10 +13,7 @@ #if SOC_RTCIO_PIN_COUNT > 0 #include "soc/rtc_io_channel.h" #endif - -#if SOC_ADC_RTC_CTRL_SUPPORTED -#include "soc/sens_struct.h" -#endif +#include "soc/io_mux_reg.h" #ifdef __cplusplus extern "C" diff --git a/components/soc/include/soc/timer_periph.h b/components/soc/include/soc/timer_periph.h index 883e69f787c4..1d7cd219b3c3 100644 --- a/components/soc/include/soc/timer_periph.h +++ b/components/soc/include/soc/timer_periph.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ #include "soc/timer_group_struct.h" #include "soc/soc_caps.h" #include "soc/periph_defs.h" +#include "soc/regdma.h" #ifdef __cplusplus extern "C" { @@ -28,6 +29,16 @@ typedef struct { extern const timer_group_signal_conn_t timer_group_periph_signals; +#if SOC_TIMER_SUPPORT_SLEEP_RETENTION && SOC_PAU_SUPPORTED +typedef struct { + const regdma_entries_config_t *link_list; + uint32_t link_num; +} tg_reg_ctx_link_t; + +extern const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS]; +extern const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS]; +#endif + #ifdef __cplusplus } #endif diff --git a/components/soc/include/soc/touch_sensor_periph.h b/components/soc/include/soc/touch_sensor_periph.h index fa9229f93094..dfa433339d33 100644 --- a/components/soc/include/soc/touch_sensor_periph.h +++ b/components/soc/include/soc/touch_sensor_periph.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,14 +7,6 @@ #pragma once #include "soc/soc_caps.h" -#if SOC_TOUCH_SENSOR_SUPPORTED -#include "soc/touch_sensor_channel.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/rtc_cntl_struct.h" -#include "soc/sens_reg.h" -#include "soc/sens_struct.h" -#include "soc/rtc_io_struct.h" -#endif // SOC_TOUCH_SENSOR_SUPPORTED #ifdef __cplusplus extern "C" { diff --git a/components/soc/include/soc/uart_periph.h b/components/soc/include/soc/uart_periph.h index 45781b208aae..2c0681e8dad6 100644 --- a/components/soc/include/soc/uart_periph.h +++ b/components/soc/include/soc/uart_periph.h @@ -1,17 +1,18 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include "soc/soc_caps.h" -#include "soc/periph_defs.h" +#include "soc/interrupts.h" #include "soc/gpio_sig_map.h" #include "soc/io_mux_reg.h" #include "soc/uart_pins.h" #include "soc/uart_struct.h" #include "soc/uart_reg.h" +#include "soc/regdma.h" #ifdef __cplusplus extern "C" { @@ -45,13 +46,19 @@ typedef struct { typedef struct { const uart_periph_sig_t pins[SOC_UART_PINS_COUNT]; const uint8_t irq; - union { - const periph_module_t module; - }; } uart_signal_conn_t; extern const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM]; +#if SOC_UART_SUPPORT_SLEEP_RETENTION +typedef struct { + const regdma_entries_config_t *regdma_entry_array; + uint32_t array_size; +} uart_reg_retention_info_t; + +extern const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM]; +#endif + #ifdef __cplusplus } #endif diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 8ba9a8d9f19e..fdff3c944cea 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -122,7 +122,7 @@ esp_flash_t *esp_flash_default_chip = NULL; #endif //!CONFIG_SPI_FLASH_AUTO_SUSPEND #endif // Other target -static IRAM_ATTR NOINLINE_ATTR void cs_initialize(esp_flash_t *chip, const esp_flash_spi_device_config_t *config, bool use_iomux, int cs_id) +static IRAM_ATTR NOINLINE_ATTR void cs_initialize(esp_flash_t *chip, const esp_flash_spi_device_config_t *config, bool cs_use_iomux, int cs_id) { //Not using spicommon_cs_initialize since we don't want to put the whole //spi_periph_signal into the DRAM. Copy these data from flash before the @@ -139,9 +139,9 @@ static IRAM_ATTR NOINLINE_ATTR void cs_initialize(esp_flash_t *chip, const esp_f //To avoid the panic caused by flash data line conflicts during cs line //initialization, disable the cache temporarily chip->os_func->start(chip->os_func_data); - PIN_INPUT_ENABLE(iomux_reg); - if (use_iomux) { - gpio_hal_iomux_func_sel(iomux_reg, spics_func); + gpio_hal_input_enable(&gpio_hal, cs_io_num); + if (cs_use_iomux) { + gpio_hal_func_sel(&gpio_hal, cs_io_num, spics_func); } else { gpio_hal_output_enable(&gpio_hal, cs_io_num); gpio_hal_od_disable(&gpio_hal, cs_io_num); @@ -175,6 +175,16 @@ static bool bus_using_iomux(spi_host_device_t host) return true; } +static bool cs_using_iomux(const esp_flash_spi_device_config_t *config) +{ + bool use_iomux = true; + CHECK_IOMUX_PIN(config->host_id, spics); + if (config->cs_io_num != spi_periph_signal[config->host_id].spics0_iomux_pin) { + use_iomux = false; + } + return use_iomux; +} + static esp_err_t acquire_spi_device(const esp_flash_spi_device_config_t *config, int* out_dev_id, spi_bus_lock_dev_handle_t* out_dev_handle) { esp_err_t ret = ESP_OK; @@ -274,7 +284,7 @@ esp_err_t spi_bus_add_flash_device(esp_flash_t **out_chip, const esp_flash_spi_d } // The cs_id inside `config` is deprecated, use the `dev_id` provided by the bus lock instead. - cs_initialize(chip, config, use_iomux, dev_id); + cs_initialize(chip, config, cs_using_iomux(config), dev_id); *out_chip = chip; return ret; fail: @@ -317,14 +327,14 @@ static void s_esp_flash_choose_correct_mode(memspi_host_config_t *cfg) static const char *mode = FLASH_MODE_STRING; if (bootloader_flash_is_octal_mode_enabled()) { #if !CONFIG_ESPTOOLPY_FLASHMODE_OPI - ESP_EARLY_LOGW(TAG, "Octal flash chip is using but %s mode is selected, will automatically swich to Octal mode", mode); + ESP_EARLY_LOGW(TAG, "Octal flash chip is using but %s mode is selected, will automatically switch to Octal mode", mode); cfg->octal_mode_en = 1; cfg->default_io_mode = SPI_FLASH_OPI_STR; default_chip.read_mode = SPI_FLASH_OPI_STR; #endif } else { #if CONFIG_ESPTOOLPY_FLASHMODE_OPI - ESP_EARLY_LOGW(TAG, "Quad flash chip is using but %s flash mode is selected, will automatically swich to DIO mode", mode); + ESP_EARLY_LOGW(TAG, "Quad flash chip is using but %s flash mode is selected, will automatically switch to DIO mode", mode); cfg->octal_mode_en = 0; cfg->default_io_mode = SPI_FLASH_DIO; default_chip.read_mode = SPI_FLASH_DIO; @@ -357,7 +367,7 @@ esp_err_t esp_flash_init_default_chip(void) #endif - // For chips need time tuning, get value directely from system here. + // For chips need time tuning, get value directly from system here. #if SOC_SPI_MEM_SUPPORT_TIMING_TUNING if (spi_flash_timing_is_tuned()) { cfg.using_timing_tuning = 1; diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index da4e991566a7..d7482f92b4ab 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -281,12 +281,22 @@ size_t spi_flash_cache2phys(const void *cached) uint32_t paddr = 0; mmu_target_t target = 0; +#if CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM //TODO: IDF-9049 + paddr = mmu_xip_psram_flash_vaddr_to_paddr(cached); + //SPI_FLASH_CACHE2PHYS_FAIL is UINT32_MAX + if (paddr != SPI_FLASH_CACHE2PHYS_FAIL) { + return paddr; + } +#endif + ret = esp_mmu_vaddr_to_paddr((void *)cached, &paddr, &target); if (ret != ESP_OK) { return SPI_FLASH_CACHE2PHYS_FAIL; } int offset = 0; + +#if !SOC_MMU_PER_EXT_MEM_TARGET //TODO: IDF-9049 #if CONFIG_SPIRAM_RODATA if ((uint32_t)cached >= (uint32_t)&_rodata_reserved_start && (uint32_t)cached <= (uint32_t)&_rodata_reserved_end) { offset = rodata_flash2spiram_offset(); @@ -297,6 +307,7 @@ size_t spi_flash_cache2phys(const void *cached) offset = instruction_flash2spiram_offset(); } #endif +#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET return paddr + offset * CONFIG_MMU_PAGE_SIZE; } @@ -309,6 +320,7 @@ const void * spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memo mmu_target_t target = MMU_TARGET_FLASH0; __attribute__((unused)) uint32_t phys_page = phys_offs / CONFIG_MMU_PAGE_SIZE; +#if !SOC_MMU_PER_EXT_MEM_TARGET #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS if (phys_page >= instruction_flash_start_page_get() && phys_page <= instruction_flash_end_page_get()) { target = MMU_TARGET_PSRAM0; @@ -322,6 +334,7 @@ const void * spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memo phys_offs -= rodata_flash2spiram_offset() * CONFIG_MMU_PAGE_SIZE; } #endif +#endif //#if !SOC_MMU_PER_EXT_MEM_TARGET mmu_vaddr_t type = (memory == SPI_FLASH_MMAP_DATA) ? MMU_VADDR_DATA : MMU_VADDR_INSTRUCTION; ret = esp_mmu_paddr_to_vaddr(phys_offs, target, type, &ptr); diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 0dd92a78101f..d88259ec7d2c 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -150,7 +150,10 @@ void IRAM_ATTR esp_mspi_pin_init(void) } //Set F4R4 board pin drive strength. TODO: IDF-3663 #endif - /* Reserve the GPIO pins */ +} + +void esp_mspi_pin_reserve(void) +{ uint64_t reserve_pin_mask = 0; for (esp_mspi_io_t i = 0; i < ESP_MSPI_IO_MAX; i++) { reserve_pin_mask |= BIT64(esp_mspi_get_io(i)); diff --git a/components/spi_flash/include/esp_private/spi_flash_os.h b/components/spi_flash/include/esp_private/spi_flash_os.h index 3d8512c9e92c..e68b0c8fb33b 100644 --- a/components/spi_flash/include/esp_private/spi_flash_os.h +++ b/components/spi_flash/include/esp_private/spi_flash_os.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -55,6 +55,11 @@ esp_err_t spi_flash_init_chip_state(void); */ void esp_mspi_pin_init(void); +/** + * @brief Reserve MSPI IOs + */ +void esp_mspi_pin_reserve(void); + /** * @brief Get the number of the GPIO corresponding to the given MSPI io * diff --git a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h index 766ea621d08c..ecbb64df5071 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h +++ b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h @@ -68,7 +68,7 @@ #define HSPI_PIN_NUM_WP FSPI_PIN_NUM_WP #define HSPI_PIN_NUM_CS FSPI_PIN_NUM_CS -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 #define SPI1_CS_IO 26 //the pin which is usually used by the PSRAM cs #define SPI1_HD_IO 27 //the pin which is usually used by the PSRAM hd #define SPI1_WP_IO 28 //the pin which is usually used by the PSRAM wp @@ -88,14 +88,14 @@ #define HSPI_PIN_NUM_WP FSPI_PIN_NUM_WP #define HSPI_PIN_NUM_CS FSPI_PIN_NUM_CS -#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 +#elif CONFIG_IDF_TARGET_ESP32H2 -#define FSPI_PIN_NUM_MOSI 7 -#define FSPI_PIN_NUM_MISO 2 -#define FSPI_PIN_NUM_CLK 6 -#define FSPI_PIN_NUM_HD 4 -#define FSPI_PIN_NUM_WP 5 -#define FSPI_PIN_NUM_CS 17 +#define FSPI_PIN_NUM_MOSI 5 +#define FSPI_PIN_NUM_MISO 0 +#define FSPI_PIN_NUM_CLK 4 +#define FSPI_PIN_NUM_HD 3 +#define FSPI_PIN_NUM_WP 2 +#define FSPI_PIN_NUM_CS 1 // Just use the same pins for HSPI #define HSPI_PIN_NUM_MOSI FSPI_PIN_NUM_MOSI diff --git a/components/spi_flash/test_apps/flash_mmap/main/test_flash_mmap.c b/components/spi_flash/test_apps/flash_mmap/main/test_flash_mmap.c index 548de17285a5..3f36d6bf34a6 100644 --- a/components/spi_flash/test_apps/flash_mmap/main/test_flash_mmap.c +++ b/components/spi_flash/test_apps/flash_mmap/main/test_flash_mmap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -23,7 +23,7 @@ static uint32_t buffer[1024]; -/* read-only region used for mmap tests, intialised in setup_mmap_tests() */ +/* read-only region used for mmap tests, initialised in setup_mmap_tests() */ static uint32_t start; static uint32_t end; @@ -101,6 +101,33 @@ static void setup_mmap_tests(void) } } +TEST_CASE("Can get correct data in existing mapped region", "[spi_flash][mmap]") +{ + setup_mmap_tests(); + + printf("Mapping %"PRIx32" (+%"PRIx32")\n", start, end - start); + const void *ptr1; + TEST_ESP_OK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); + printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle1, ptr1); + + /* Remap in the previously mapped region itself */ + uint32_t new_start = start + CONFIG_MMU_PAGE_SIZE; + printf("Mapping %"PRIx32" (+%"PRIx32")\n", new_start, end - new_start); + const void *ptr2; + TEST_ESP_OK( spi_flash_mmap(new_start, end - new_start, SPI_FLASH_MMAP_DATA, &ptr2, &handle2) ); + printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle2, ptr2); + + const void *src1 = (void *) ((uint32_t) ptr1 + CONFIG_MMU_PAGE_SIZE); + const void *src2 = ptr2; + /* Memory contents should be identical - as the region is same */ + TEST_ASSERT_EQUAL(0, memcmp(src1, src2, end - new_start)); + + spi_flash_munmap(handle1); + handle1 = 0; + spi_flash_munmap(handle2); + handle2 = 0; + TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA)); +} TEST_CASE("Can mmap into data address space", "[spi_flash][mmap]") { @@ -359,7 +386,14 @@ TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]") /* esp_partition_find is in IROM */ uint32_t phys = spi_flash_cache2phys(esp_partition_find); TEST_ASSERT_NOT_EQUAL(SPI_FLASH_CACHE2PHYS_FAIL, phys); +#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM + /** + * On CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM=y condition + * spi_flash_phys2cache will return exactly the flash paddr corresponding vaddr. + * Whereas `constant_data` is now actually on PSRAM + */ TEST_ASSERT_EQUAL_PTR(esp_partition_find, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_INST)); +#endif #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_DATA)); #endif //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 @@ -371,8 +405,14 @@ TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]") /* 'constant_data' should be in DROM */ phys = spi_flash_cache2phys(&constant_data); TEST_ASSERT_NOT_EQUAL(SPI_FLASH_CACHE2PHYS_FAIL, phys); - TEST_ASSERT_EQUAL_PTR(&constant_data, - spi_flash_phys2cache(phys, SPI_FLASH_MMAP_DATA)); +#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM + /** + * On CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM=y condition, + * spi_flash_phys2cache will return exactly the flash paddr corresponding vaddr. + * Whereas `constant_data` is now actually on PSRAM + */ + TEST_ASSERT_EQUAL_PTR(&constant_data, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_DATA)); +#endif #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(phys, SPI_FLASH_MMAP_INST)); #endif //#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 @@ -404,7 +444,18 @@ TEST_CASE("mmap consistent with phys2cache/cache2phys", "[spi_flash][mmap]") spi_flash_munmap(handle1); handle1 = 0; + esp_rom_printf("ptr; 0x%x\n", ptr); + +#if !CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM + /** + * On CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM=y condition, this is reasonable as there are two MMUs. + * Unmapping flash one, if it's XIP_PSRAM, we can still find it via `spi_flash_cache2phys` + * + * TODO, design a new API dedicated for `esp_ota_get_running_partition` usage, then here we can + * update this `spi_flash_cache2phys` back to its normal behaviour + */ TEST_ASSERT_EQUAL_HEX(SPI_FLASH_CACHE2PHYS_FAIL, spi_flash_cache2phys(ptr)); +#endif } TEST_CASE("munmap followed by mmap flushes cache", "[spi_flash][mmap]") diff --git a/components/tcp_transport/transport_ws.c b/components/tcp_transport/transport_ws.c index 75cea861041b..529494ca09da 100644 --- a/components/tcp_transport/transport_ws.c +++ b/components/tcp_transport/transport_ws.c @@ -131,7 +131,7 @@ static int esp_transport_read_internal(transport_ws_t *ws, char *buffer, int len return to_read; } -static char *trimwhitespace(const char *str) +static char *trimwhitespace(char *str) { char *end; @@ -141,19 +141,19 @@ static char *trimwhitespace(const char *str) } if (*str == 0) { - return (char *)str; + return str; } // Trim trailing space - end = (char *)(str + strlen(str) - 1); + end = str + strlen(str) - 1; while (end > str && isspace((unsigned char)*end)) { end--; } // Write new null terminator - *(end + 1) = 0; + *(end + 1) = '\0'; - return (char *)str; + return str; } static int get_http_status_code(const char *buffer) @@ -162,11 +162,11 @@ static int get_http_status_code(const char *buffer) const char *found = strcasestr(buffer, http); char status_code[4]; if (found) { - found += sizeof(http)/sizeof(http[0]) - 1; + found += sizeof(http) - 1; found = strchr(found, ' '); if (found) { found++; - strncpy(status_code, found, 4); + strncpy(status_code, found, 3); status_code[3] = '\0'; int code = atoi(status_code); ESP_LOGD(TAG, "HTTP status code is %d", code); @@ -176,14 +176,14 @@ static int get_http_status_code(const char *buffer) return -1; } -static char *get_http_header(const char *buffer, const char *key) +static char *get_http_header(char *buffer, const char *key) { char *found = strcasestr(buffer, key); if (found) { found += strlen(key); char *found_end = strstr(found, "\r\n"); if (found_end) { - found_end[0] = 0;//terminal string + *found_end = '\0'; // terminal string return trimwhitespace(found); } @@ -307,20 +307,6 @@ static int ws_connect(esp_transport_handle_t t, const char *host, int port, int return -1; } - if (delim_ptr != NULL) { - size_t delim_pos = delim_ptr - ws->buffer + sizeof(delimiter) - 1; - size_t remaining_len = ws->buffer_len - delim_pos; - if (remaining_len > 0) { - memmove(ws->buffer, ws->buffer + delim_pos, remaining_len); - ws->buffer_len = remaining_len; - } else { -#ifdef CONFIG_WS_DYNAMIC_BUFFER - free(ws->buffer); - ws->buffer = NULL; -#endif - ws->buffer_len = 0; - } - } // See esp_crypto_sha1() arg size unsigned char expected_server_sha1[20]; // Size of base64 coded string see above @@ -340,6 +326,22 @@ static int ws_connect(esp_transport_handle_t t, const char *host, int port, int ESP_LOGE(TAG, "Invalid websocket key"); return -1; } + + if (delim_ptr != NULL) { + size_t delim_pos = delim_ptr - ws->buffer + sizeof(delimiter) - 1; + size_t remaining_len = ws->buffer_len - delim_pos; + if (remaining_len > 0) { + memmove(ws->buffer, ws->buffer + delim_pos, remaining_len); + ws->buffer_len = remaining_len; + } else { +#ifdef CONFIG_WS_DYNAMIC_BUFFER + free(ws->buffer); + ws->buffer = NULL; +#endif + ws->buffer_len = 0; + } + } + return 0; } diff --git a/components/ulp/CMakeLists.txt b/components/ulp/CMakeLists.txt index ec5571d9c657..24ea46461d82 100644 --- a/components/ulp/CMakeLists.txt +++ b/components/ulp/CMakeLists.txt @@ -65,6 +65,14 @@ if(CONFIG_ULP_COPROC_TYPE_LP_CORE) if(CONFIG_SOC_LP_TIMER_SUPPORTED) list(APPEND srcs "lp_core/shared/ulp_lp_core_lp_timer_shared.c") endif() + + if(CONFIG_SOC_LP_SPI_SUPPORTED) + list(APPEND srcs "lp_core/lp_core_spi.c") + endif() + + if(CONFIG_SOC_LP_CORE_SUPPORT_ETM) + list(APPEND srcs "lp_core/lp_core_etm.c") + endif() endif() idf_component_register(SRCS ${srcs} diff --git a/components/ulp/Kconfig b/components/ulp/Kconfig index 1c7f7c29130e..52862fb61358 100644 --- a/components/ulp/Kconfig +++ b/components/ulp/Kconfig @@ -75,7 +75,7 @@ menu "Ultra Low Power (ULP) Co-processor" config ULP_SHARED_MEM depends on ULP_COPROC_TYPE_LP_CORE hex - default 0x8 + default 0x10 help Size of the shared memory defined in ulp_lp_core_memory_shared.c. Size should be kept in-sync with the size of the struct defined there. @@ -92,4 +92,39 @@ menu "Ultra Low Power (ULP) Co-processor" Note: For LP ROM prints to work properly, make sure that the LP core boots from the LP ROM. + menu "ULP Debugging Options" + config ULP_PANIC_OUTPUT_ENABLE + depends on ULP_COPROC_TYPE_LP_CORE && SOC_ULP_LP_UART_SUPPORTED + bool + prompt "Enable panic handler which outputs over LP UART" + default "y" if IDF_TARGET_ESP32P4 + help + Set this option to enable panic handler functionality. If this option is + enabled then the LP Core will output a panic dump over LP UART, + similar to what the main core does. Output depends on LP UART already being + initialized and configured. + Disabling this option will reduce the LP core binary size by not + linking in panic handler functionality. + + config ULP_HP_UART_CONSOLE_PRINT + depends on ULP_COPROC_TYPE_LP_CORE + bool + prompt "Route lp_core_printf to the console HP-UART" + help + Set this option to route lp_core_printf to the console HP-UART. + This allows you to easily view print outputs from the LP core, without + having to connect to the LP-UART. This option comes with the following + limitations: + + 1. There is no mutual exclusion between the HP-Core and the LP-Core accessing + the HP-UART, which means that if both cores are logging heavily the output + strings might get mangled together. + 2. The HP-UART can only work while the HP-Core is running, which means that + if the HP-Core is in deep sleep, the LP-Core will not be able to print to the + console HP-UART. + + Due to these limitations it is only recommended to use this option for easy debugging. + For more serious use-cases you should use the LP-UART. + endmenu + endmenu # Ultra Low Power (ULP) Co-processor diff --git a/components/ulp/cmake/CMakeLists.txt b/components/ulp/cmake/CMakeLists.txt index dceac3f78d10..9796f1c26b29 100644 --- a/components/ulp/cmake/CMakeLists.txt +++ b/components/ulp/cmake/CMakeLists.txt @@ -5,8 +5,8 @@ project(${ULP_APP_NAME} ASM C) add_executable(${ULP_APP_NAME}) set(CMAKE_EXECUTABLE_SUFFIX ".elf") -option(ULP_COCPU_IS_RISCV "Use RISC-V based ULP" OFF) -option(ULP_COCPU_IS_LP_CORE "Use RISC-V based LP Core" OFF) +# Import all sdkconfig variables into the cmake build +include(${SDKCONFIG_CMAKE}) function(create_arg_file arguments output_file) # Escape all spaces @@ -20,7 +20,7 @@ endfunction() message(STATUS "Building ULP app ${ULP_APP_NAME}") # Check the supported assembler version -if(NOT (ULP_COCPU_IS_RISCV OR ULP_COCPU_IS_LP_CORE)) +if(CONFIG_ULP_COPROC_TYPE_FSM) check_expected_tool_version("esp32ulp-elf" ${CMAKE_ASM_COMPILER}) endif() @@ -28,6 +28,8 @@ endif() set(ULP_MAP_GEN ${PYTHON} ${IDF_PATH}/components/ulp/esp32ulp_mapgen.py) get_filename_component(sdkconfig_dir ${SDKCONFIG_HEADER} DIRECTORY) + + foreach(include ${COMPONENT_INCLUDES}) list(APPEND component_includes -I${include}) endforeach() @@ -41,9 +43,9 @@ list(APPEND ULP_PREPROCESSOR_ARGS -I${IDF_PATH}/components/esp_system/ld) target_include_directories(${ULP_APP_NAME} PRIVATE ${COMPONENT_INCLUDES}) # Pre-process the linker script -if(ULP_COCPU_IS_RISCV) +if(CONFIG_ULP_COPROC_TYPE_RISCV) set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/ulp_riscv.ld) -elseif(ULP_COCPU_IS_LP_CORE) +elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE) set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/lp_core_riscv.ld) else() set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/ulp_fsm.ld) @@ -69,8 +71,7 @@ target_link_options(${ULP_APP_NAME} PRIVATE SHELL:-T ${CMAKE_CURRENT_BINARY_DIR} # To avoid warning "Manually-specified variables were not used by the project" set(bypassWarning "${IDF_TARGET}") -set(bypassWarning "${CONFIG_ESP_ROM_HAS_LP_ROM}") -if(ULP_COCPU_IS_RISCV) +if(CONFIG_ULP_COPROC_TYPE_RISCV) #risc-v ulp uses extra files for building: list(APPEND ULP_S_SOURCES "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_vectors.S" @@ -98,10 +99,11 @@ if(ULP_COCPU_IS_RISCV) target_compile_definitions(${ULP_APP_NAME} PRIVATE IS_ULP_COCPU) target_compile_definitions(${ULP_APP_NAME} PRIVATE ULP_RISCV_REGISTER_OPS) -elseif(ULP_COCPU_IS_LP_CORE) +elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE) list(APPEND ULP_S_SOURCES "${IDF_PATH}/components/ulp/lp_core/lp_core/start.S" "${IDF_PATH}/components/ulp/lp_core/lp_core/vector.S" + "${IDF_PATH}/components/ulp/lp_core/lp_core/port/${IDF_TARGET}/vector_table.S" "${IDF_PATH}/components/ulp/lp_core/shared/ulp_lp_core_memory_shared.c" "${IDF_PATH}/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c" "${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_startup.c" @@ -111,7 +113,10 @@ elseif(ULP_COCPU_IS_LP_CORE) "${IDF_PATH}/components/hal/uart_hal.c" "${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_uart.c" "${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_print.c" - "${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_i2c.c") + "${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_panic.c" + "${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_interrupt.c" + "${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_i2c.c" + "${IDF_PATH}/components/ulp/lp_core/lp_core/lp_core_spi.c") target_link_options(${ULP_APP_NAME} PRIVATE "-nostartfiles") target_link_options(${ULP_APP_NAME} PRIVATE "-Wl,--no-warn-rwx-segments") @@ -134,6 +139,8 @@ elseif(ULP_COCPU_IS_LP_CORE) PRIVATE SHELL:-T ${IDF_PATH}/components/esp_rom/${IDF_TARGET}/ld/${IDF_TARGET}lp.rom.newlib.ld) target_link_options(${ULP_APP_NAME} PRIVATE SHELL:-T ${IDF_PATH}/components/esp_rom/${IDF_TARGET}/ld/${IDF_TARGET}lp.rom.version.ld) + target_link_options(${ULP_APP_NAME} + PRIVATE SHELL:-T ${IDF_PATH}/components/esp_rom/${IDF_TARGET}/ld/${IDF_TARGET}lp.rom.api.ld) endif() target_sources(${ULP_APP_NAME} PRIVATE ${ULP_S_SOURCES}) @@ -168,7 +175,7 @@ else() endif() -if(ULP_COCPU_IS_LP_CORE) +if(CONFIG_ULP_COPROC_TYPE_LP_CORE) set(ULP_BASE_ADDR "0x0") else() set(ULP_BASE_ADDR "0x50000000") diff --git a/components/ulp/cmake/toolchain-lp-core-riscv.cmake b/components/ulp/cmake/toolchain-lp-core-riscv.cmake index 9b9ce09e8baf..eb3a0623bea5 100644 --- a/components/ulp/cmake/toolchain-lp-core-riscv.cmake +++ b/components/ulp/cmake/toolchain-lp-core-riscv.cmake @@ -5,11 +5,11 @@ set(CMAKE_C_COMPILER "riscv32-esp-elf-gcc") set(CMAKE_CXX_COMPILER "riscv32-esp-elf-g++") set(CMAKE_ASM_COMPILER "riscv32-esp-elf-gcc") -set(CMAKE_C_FLAGS "-Os -march=rv32imac_zicsr_zifencei -mdiv -fdata-sections -ffunction-sections" +set(CMAKE_C_FLAGS "-Os -ggdb -march=rv32imac_zicsr_zifencei -mdiv -fdata-sections -ffunction-sections" CACHE STRING "C Compiler Base Flags") -set(CMAKE_CXX_FLAGS "-Os -march=rv32imac_zicsr_zifencei -mdiv -fdata-sections -ffunction-sections" +set(CMAKE_CXX_FLAGS "-Os -ggdb -march=rv32imac_zicsr_zifencei -mdiv -fdata-sections -ffunction-sections" CACHE STRING "C++ Compiler Base Flags") -set(CMAKE_ASM_FLAGS "-march=rv32imac_zicsr_zifencei -x assembler-with-cpp" +set(CMAKE_ASM_FLAGS "-Os -ggdb -march=rv32imac_zicsr_zifencei -x assembler-with-cpp" CACHE STRING "Assembler Base Flags") set(CMAKE_EXE_LINKER_FLAGS "-march=rv32imac_zicsr_zifencei --specs=nano.specs --specs=nosys.specs" CACHE STRING "Linker Base Flags") diff --git a/components/ulp/ld/lp_core_riscv.ld b/components/ulp/ld/lp_core_riscv.ld index 4ecab5b34a18..0f2da81c3ec4 100644 --- a/components/ulp/ld/lp_core_riscv.ld +++ b/components/ulp/ld/lp_core_riscv.ld @@ -14,13 +14,20 @@ #define ULP_MEM_START_ADDRESS (SOC_RTC_DRAM_LOW) #endif +#define ALIGN_DOWN(SIZE, AL) (SIZE & ~(AL - 1)) +/* Ensure the end where the shared memory starts is aligned to 8 bytes + if updating this also update the same in ulp_lp_core_memory_shared.c + */ +#define ALIGNED_COPROC_MEM ALIGN_DOWN(CONFIG_ULP_COPROC_RESERVE_MEM, 0x8) + ENTRY(reset_vector) MEMORY { /*first 128byte for exception/interrupt vectors*/ vector_table(RX) : ORIGIN = ULP_MEM_START_ADDRESS , LENGTH = 0x80 - ram(RWX) : ORIGIN = ULP_MEM_START_ADDRESS + 0x80, LENGTH = CONFIG_ULP_COPROC_RESERVE_MEM - 0x80 - CONFIG_ULP_SHARED_MEM + ram(RWX) : ORIGIN = ULP_MEM_START_ADDRESS + 0x80, LENGTH = ALIGNED_COPROC_MEM - 0x80 - CONFIG_ULP_SHARED_MEM + shared_mem_ram(RW) : ORIGIN = ULP_MEM_START_ADDRESS + ALIGNED_COPROC_MEM - CONFIG_ULP_SHARED_MEM, LENGTH = CONFIG_ULP_SHARED_MEM } SECTIONS @@ -65,4 +72,10 @@ SECTIONS } >ram __stack_top = ORIGIN(ram) + LENGTH(ram); + + . = ORIGIN(shared_mem_ram); + .shared_mem (ALIGN(4)) : + { + KEEP(*(.shared_mem)) + } > shared_mem_ram } diff --git a/components/ulp/lp_core/include/lp_core_etm.h b/components/ulp/lp_core/include/lp_core_etm.h new file mode 100644 index 000000000000..5550906adbf9 --- /dev/null +++ b/components/ulp/lp_core/include/lp_core_etm.h @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_err.h" +#include "esp_etm.h" +#include "hal/lp_core_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LP-Core ETM event configuration + */ +typedef struct { + lp_core_etm_event_type_t event_type; /*!< LP-Core ETM event type */ +} lp_core_etm_event_config_t; + +/** + * @brief LP-Core ETM task configuration + */ +typedef struct { + lp_core_etm_task_type_t task_type; /*!< LP-Core ETM task type */ +} lp_core_etm_task_config_t; + +/** + * @brief Create a ETM event for LP-Core + * + * @note The created ETM event object can be deleted later by calling `esp_etm_del_event` + * + * @param[in] config LP-Core ETM event configuration + * @param[out] out_event Returned ETM event handle + * @return + * - ESP_OK: Get ETM event successfully + * - ESP_ERR_INVALID_ARG: Get ETM event failed because of invalid argument + * - ESP_FAIL: Get ETM event failed because of other error + */ +esp_err_t lp_core_new_etm_event(const lp_core_etm_event_config_t *config, esp_etm_event_handle_t *out_event); + +/** + * @brief Create a ETM task for LP-Core + * + * @note The created ETM task object can be deleted later by calling `esp_etm_del_task` + * + * @param[in] config LP-Core ETM task configuration + * @param[out] out_task Returned ETM task handle + * @return + * - ESP_OK: Get ETM task successfully + * - ESP_ERR_INVALID_ARG: Get ETM task failed because of invalid argument + * - ESP_FAIL: Get ETM task failed because of other error + */ +esp_err_t lp_core_new_etm_task(const lp_core_etm_task_config_t *config, esp_etm_task_handle_t *out_task); + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/lp_core/include/lp_core_spi.h b/components/ulp/lp_core/include/lp_core_spi.h new file mode 100644 index 000000000000..f2f0ea9f0368 --- /dev/null +++ b/components/ulp/lp_core/include/lp_core_spi.h @@ -0,0 +1,109 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LP SPI peripheral + * Since we have just one LP SPI peripheral, we can define it as a uint32_t type for now, instead of an enum. + */ +typedef uint32_t lp_spi_host_t; + +/** + * @brief LP SPI device configuration flags + */ +#define LP_SPI_DEVICE_TXBIT_LSBFIRST (1<<0) /*!< Transmit command/address/data LSB first instead of the default MSB first */ +#define LP_SPI_DEVICE_RXBIT_LSBFIRST (1<<1) /*!< Receive data LSB first instead of the default MSB first */ +#define LP_SPI_DEVICE_BIT_LSBFIRST (LP_SPI_DEVICE_TXBIT_LSBFIRST|LP_SPI_DEVICE_RXBIT_LSBFIRST) /*!< Transmit and receive LSB first */ +#define LP_SPI_DEVICE_3WIRE (1<<2) /*!< Use MOSI (=spid) for both sending and receiving data */ +#define LP_SPI_DEVICE_CS_ACTIVE_HIGH (1<<3) /*!< Make CS line active-high during a transanction instead of the default active-low state. Only available in SPI master mode. */ +#define LP_SPI_DEVICE_HALF_DUPLEX (1<<4) /*!< Transmit data before receiving it, instead of simultaneously. Only available in SPI master mode. */ + +/** + * @brief LP SPI bus configuration parameters + */ +typedef struct { + int mosi_io_num; /*!< GPIO pin for Master out, Slave In signal, a.k.a, SPI_D. */ + int miso_io_num; /*!< GPIO pin for Master in, Slave Out signal, a.k.a, SPI_Q. */ + int sclk_io_num; /*!< GPIO pin for LP SPI Clock signal. */ +} lp_spi_bus_config_t; + +/** + * @brief LP SPI device configuration parameters + */ +typedef struct { + int cs_io_num; /*!< GPIO pin for the device Chip Select (CS) signal. */ + int clock_speed_hz; /*!< SPI clock speed in Hz. */ + int spi_mode; /*!< SPI mode, representing a pair of Clock Polarity (CPOL) and Clock Phase (CPHA) configuration: + - SPI Mode 0: (0, 0) + - SPI Mode 1: (0, 1) + - SPI Mode 2: (1, 0) + - SPI Mode 3: (1, 1) + */ + int duty_cycle; /*!< Duty cycle of positive SPI clock, in 1/256th increments (128 = 50% duty cycle). Setting this to 0 (=not setting it) is equivalent to setting this to 128. */ + int flags; /*!< Bitwise OR of LP_SPI_DEVICE_* flags */ + int cs_ena_pretrans; /*!< Amount of SPI bit-cycles the CS should be active for, before the transmission (0-16). This only works on half-duplex transactions. */ + int cs_ena_posttrans; /*!< Amount of SPI bit-cycles the CS should stay active for, after the transmission (0-16). This only works on half-duplex transactions. */ +} lp_spi_device_config_t; + +/** + * @brief LP SPI slave configuration parameters + */ +typedef struct { + int cs_io_num; /*!< GPIO pin for the device Chip Select (CS) signal. */ + int spi_mode; /*!< SPI mode, representing a pair of Clock Polarity (CPOL) and Clock Phase (CPHA) configuration: + - SPI Mode 0: (0, 0) + - SPI Mode 1: (0, 1) + - SPI Mode 2: (1, 0) + - SPI Mode 3: (1, 1) + */ + int flags; /*!< Bitwise OR of LP_SPI_DEVICE_* flags */ +} lp_spi_slave_config_t; + +/** + * @brief Initialize the LP SPI bus for use by the LP core + * + * @param host_id LP SPI host number + * @param bus_config LP SPI bus configuration parameters + * + * @return esp_err_t ESP_OK when successful + * ESP_ERR_INVALID_ARG if the configuration is invalid + */ +esp_err_t lp_core_lp_spi_bus_initialize(lp_spi_host_t host_id, const lp_spi_bus_config_t *bus_config); + +/** + * @brief Initialize the LP SPI controller in master mode and add an SPI device to the LP SPI bus. + * + * @param host_id LP SPI host number + * @param dev_config LP SPI device configuration parameters + * + * @return esp_err_t ESP_OK when successful + * ESP_ERR_INVALID_ARG if the configuration is invalid + * ESP_FAIL if the device could not be added + */ +esp_err_t lp_core_lp_spi_bus_add_device(lp_spi_host_t host_id, const lp_spi_device_config_t *dev_config); + +/** + * @brief Initialize the LP SPI controller in slave mode + * + * @param host_id LP SPI host number + * @param slave_config LP SPI slave configuration parameters + * + * @return esp_err_t ESP_OK when successful + * ESP_FAIL if the SPI controller could not be initialized in slave mode + */ +esp_err_t lp_core_lp_spi_slave_initialize(lp_spi_host_t host_id, const lp_spi_slave_config_t *slave_config); + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/lp_core/include/ulp_lp_core.h b/components/ulp/lp_core/include/ulp_lp_core.h index 9a17cd5c800f..d737d638aca8 100644 --- a/components/ulp/lp_core/include/ulp_lp_core.h +++ b/components/ulp/lp_core/include/ulp_lp_core.h @@ -31,9 +31,9 @@ typedef struct { uint32_t wakeup_source; /*!< Wakeup source flags */ uint32_t lp_timer_sleep_duration_us; /*!< Sleep duration when ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER is specified. Measurement unit: us */ #if ESP_ROM_HAS_LP_ROM - bool skip_lp_rom_boot; /* !< Skips the LP rom code and boots directly into the app code placed in LP RAM, - this gives faster boot time for time sensitive use-cases at the cost of skipping - setup e.g. of UART */ + bool skip_lp_rom_boot; /*!< Skips the LP rom code and boots directly into the app code placed in LP RAM, + this gives faster boot time for time sensitive use-cases at the cost of skipping + setup e.g. of UART */ #endif //ESP_ROM_HAS_LP_ROM } ulp_lp_core_cfg_t; @@ -63,6 +63,14 @@ esp_err_t ulp_lp_core_load_binary(const uint8_t* program_binary, size_t program_ */ void ulp_lp_core_stop(void); +/** + * @brief Trigger a SW interrupt to the LP CPU from the PMU + * + * @note This is the same SW trigger that is used to wake up the LP CPU + * + */ +void ulp_lp_core_sw_intr_trigger(void); + #ifdef __cplusplus } #endif diff --git a/components/ulp/lp_core/lp_core.c b/components/ulp/lp_core/lp_core.c index 71aefe242957..6498c11e8080 100644 --- a/components/ulp/lp_core/lp_core.c +++ b/components/ulp/lp_core/lp_core.c @@ -36,6 +36,8 @@ const static char* TAG = "ulp-lp-core"; #define WAKEUP_SOURCE_MAX_NUMBER 5 +#define RESET_HANDLER_ADDR (intptr_t)(&_rtc_ulp_memory_start + 0x80 / 4) // Placed after the 0x80 byte long vector table + /* Maps the flags defined in ulp_lp_core.h e.g. ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU to their actual HW values */ static uint32_t wakeup_src_sw_to_hw_flag_lookup[WAKEUP_SOURCE_MAX_NUMBER] = { LP_CORE_LL_WAKEUP_SOURCE_HP_CPU, @@ -68,7 +70,7 @@ esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg) /* If we have a LP ROM we boot from it, before jumping to the app code */ intptr_t boot_addr; if (cfg->skip_lp_rom_boot) { - boot_addr = (intptr_t)(&_rtc_ulp_memory_start); + boot_addr = RESET_HANDLER_ADDR; } else { boot_addr = SOC_LP_ROM_LOW; /* Disable UART init in ROM, it defaults to XTAL clk src @@ -80,7 +82,8 @@ esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg) } lp_core_ll_set_boot_address(boot_addr); - lp_core_ll_set_app_boot_address((intptr_t)(&_rtc_ulp_memory_start)); + lp_core_ll_set_app_boot_address(RESET_HANDLER_ADDR); + #endif //ESP_ROM_HAS_LP_ROM LP_CORE_RCC_ATOMIC() { @@ -117,13 +120,14 @@ esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg) ESP_LOGI(TAG, "LP timer specified as wakeup source, but no sleep duration set. ULP will only wake-up once unless it calls ulp_lp_core_lp_timer_set_wakeup_time()"); } shared_mem->sleep_duration_us = cfg->lp_timer_sleep_duration_us; + shared_mem->sleep_duration_ticks = ulp_lp_core_lp_timer_calculate_sleep_ticks(cfg->lp_timer_sleep_duration_us); /* Set first wakeup alarm */ ulp_lp_core_lp_timer_set_wakeup_time(cfg->lp_timer_sleep_duration_us); } #endif - if (cfg->wakeup_source & (ULP_LP_CORE_WAKEUP_SOURCE_LP_UART | ULP_LP_CORE_WAKEUP_SOURCE_LP_IO | ULP_LP_CORE_WAKEUP_SOURCE_ETM)) { + if (cfg->wakeup_source & (ULP_LP_CORE_WAKEUP_SOURCE_LP_UART | ULP_LP_CORE_WAKEUP_SOURCE_LP_IO)) { ESP_LOGE(TAG, "Wake-up source not yet supported"); return ESP_ERR_INVALID_ARG; } @@ -161,3 +165,8 @@ void ulp_lp_core_stop(void) lp_core_ll_set_wakeup_source(0); lp_core_ll_request_sleep(); } + +void ulp_lp_core_sw_intr_trigger(void) +{ + lp_core_ll_hp_wake_lp(); +} diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h index 42745dc18639..9719a2957632 100644 --- a/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,7 @@ extern "C" { #endif +#include "soc/soc_caps.h" #include "hal/gpio_types.h" #include "hal/rtc_io_ll.h" @@ -25,15 +26,39 @@ typedef enum { LP_IO_NUM_5 = 5, /*!< GPIO5, input and output */ LP_IO_NUM_6 = 6, /*!< GPIO6, input and output */ LP_IO_NUM_7 = 7, /*!< GPIO7, input and output */ +#if SOC_RTCIO_PIN_COUNT > 8 + LP_IO_NUM_8 = 8, /*!< GPIO8, input and output */ + LP_IO_NUM_9 = 9, /*!< GPIO9, input and output */ + LP_IO_NUM_10 = 10, /*!< GPIO10, input and output */ + LP_IO_NUM_11 = 11, /*!< GPIO11, input and output */ + LP_IO_NUM_12 = 12, /*!< GPIO12, input and output */ + LP_IO_NUM_13 = 13, /*!< GPIO13, input and output */ + LP_IO_NUM_14 = 14, /*!< GPIO14, input and output */ + LP_IO_NUM_15 = 15, /*!< GPIO15, input and output */ +#endif } lp_io_num_t; +typedef enum { + LP_IO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */ + LP_IO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */ + LP_IO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */ + LP_IO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */ + LP_IO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */ + LP_IO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */ +} lp_io_intr_type_t; + /** * @brief Initialize a rtcio pin + * @note If IO is used in LP application, `rtc_gpio_init` must be called at least once + * for the using IO before loading LP core firmware in HP Code. * * @param lp_io_num The rtc io pin to initialize */ static inline void ulp_lp_core_gpio_init(lp_io_num_t lp_io_num) { +#if SOC_LP_IO_CLOCK_IS_INDEPENDENT + _rtcio_ll_enable_io_clock(true); +#endif rtcio_ll_function_select(lp_io_num, RTCIO_LL_FUNC_RTC); } @@ -153,6 +178,26 @@ static inline void ulp_lp_core_gpio_pulldown_disable(lp_io_num_t lp_io_num) rtcio_ll_pulldown_disable(lp_io_num); } +/** + * @brief Enable interrupt for lp io pin + * + * @param lp_io_num The lp io pin to enable interrupt for + * @param intr_type The interrupt type to enable + */ +static inline void ulp_lp_core_gpio_intr_enable(lp_io_num_t lp_io_num, lp_io_intr_type_t intr_type) +{ + rtcio_ll_intr_enable(lp_io_num, intr_type); +} + +/** + * @brief Clear interrupt status for all lp io + * + */ +static inline void ulp_lp_core_gpio_clear_intr_status(void) +{ + rtcio_ll_clear_interrupt_status(); +} + #ifdef __cplusplus } #endif diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h new file mode 100644 index 000000000000..f75771197435 --- /dev/null +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_IDF_TARGET_ESP32C6 +#define LP_CORE_ISR_ATTR // On C6 registers are saved by us before calling the ISR +#else +#define LP_CORE_ISR_ATTR __attribute__((interrupt)) +#endif + +/** + * Available interrupt handlers for the low power core are as follows: + * + * ulp_lp_core_lp_io_intr_handler(void); + * ulp_lp_core_lp_i2c_intr_handler(void); + * ulp_lp_core_lp_uart_intr_handler(void); + * ulp_lp_core_lp_timer_intr_handler(void); + * ulp_lp_core_lp_pmu_intr_handler(void); + * ulp_lp_core_lp_spi_intr_handler(void); + * ulp_lp_core_trng_intr_handler(void); + * ulp_lp_core_lp_adc_intr_handler(void); + * ulp_lp_core_lp_touch_intr_handler(void); + * ulp_lp_core_tsens_intr_handler(void); + * ulp_lp_core_efuse_intr_handler(void); + * ulp_lp_core_lp_sysreg_intr_handler(void); + * ulp_lp_core_lp_ana_peri_intr_handler(void); + * ulp_lp_core_mailbox_intr_handler(void); + * ulp_lp_core_lp_wdt_intr_handler(void); + * ulp_lp_core_lp_rtc_intr_handler(void); + * ulp_lp_core_sw_intr_handler(void); + * + * Not all handlers are available on all chips. Please refer to the Technical Reference Manual for your chip for more information. +*/ + +/** + * @brief Enables interrupts globally for the low power core + * + */ +void ulp_lp_core_intr_enable(void); + +/** + * @brief Disables interrupts globally for the low power core + * + */ +void ulp_lp_core_intr_disable(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h index 56401145d738..27a080581df4 100644 --- a/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h @@ -3,6 +3,8 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#pragma once + #include "sdkconfig.h" /** @@ -17,7 +19,7 @@ */ #if CONFIG_ULP_ROM_PRINT_ENABLE extern int ets_printf(const char* format, ...); -int (*lp_core_printf)(const char* format, ...) = ets_printf; +#define lp_core_printf ets_printf #else //TODO: Change return type from void to int in IDF 6.0 void lp_core_printf(const char* format, ...); @@ -33,5 +35,12 @@ void lp_core_printf(const char* format, ...); * powered down during sleep. */ extern void ets_install_uart_printf(void); -void (*lp_core_install_uart_printf)(void) = ets_install_uart_printf; +#define lp_core_install_uart_print ets_install_uart_printf #endif /* CONFIG_ULP_ROM_PRINT_ENABLE */ + +/** + * @brief Print a single character from the LP core + * + * @param c character to be printed + */ +void lp_core_print_char(char c); diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h new file mode 100644 index 000000000000..95b97e132007 --- /dev/null +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h @@ -0,0 +1,65 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "esp_err.h" + +/** + * The LP SPI bus identifier to initiate a transaction on. + */ +typedef uint32_t lp_spi_bus_t; + +/** + * This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes. + */ +typedef struct { + uint32_t tx_length; /*!< Total data length to transmit in bytes */ + uint32_t rx_length; /*!< Total data length to receive in bytes */ + const void *tx_buffer; /*!< Pointer to the transmit buffer. Must be set for master mode transactions. Can be NULL for slave mode transactions. */ + void *rx_buffer; /*!< Pointer to the receive buffer. Must be set for slave mode transactions. Can be NULL for master mode transactions. */ + lp_spi_bus_t bus; /*!< The LP SPI bus to transmit the data on */ + // The following are only used in master mode transactions + int command; /*!< Command data, of which the length is set in the ``command_bits`` field of this structure. */ + uint32_t address; /*!< Address data, of which the length is set in the ``address_bits`` field of this structure. */ + uint8_t command_bits; /*!< Default amount of bits in command phase */ + uint8_t address_bits; /*!< Default amount of bits in address phase */ + uint8_t dummy_bits; /*!< Amount of dummy bits to insert between address and data phase. */ +} lp_spi_transaction_t; + +/** + * @brief Initiate an LP SPI transaction in master mode to transmit device to an SPI device and optionally receive data + * from the device. + * + * @param trans_desc LP SPI transaction configuration descriptor + * @param ticks_to_wait Operation timeout in CPU cycles. Set to -1 to wait forever. + * + * @return esp_err_t ESP_OK when successful + * ESP_ERR_INVALID_ARG if the configuration is invalid + * ESP_ERR_TIMEOUT when the operation times out + */ +esp_err_t lp_core_lp_spi_master_transfer(lp_spi_transaction_t *trans_desc, int32_t ticks_to_wait); + +/** + * @brief Initiate an LP SPI transaction in slave mode to receive data from an SPI master and optionally transmit data + * back to the master. + * + * @param trans_desc LP SPI transaction configuration descriptor + * @param ticks_to_wait Operation timeout in CPU cycles. Set to -1 to wait forever. + * + * @return esp_err_t ESP_OK when successful + * ESP_ERR_INVALID_ARG if the configuration is invalid + * ESP_ERR_TIMEOUT when the operation times out + */ +esp_err_t lp_core_lp_spi_slave_transfer(lp_spi_transaction_t *trans_desc, int32_t ticks_to_wait); + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h index bee3d6c574fc..cfb8f697f287 100644 --- a/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ extern "C" { #include #include +#include /** * @brief Traverse all possible wake-up sources and update the wake-up cause so that @@ -72,6 +73,30 @@ __attribute__((__noreturn__)) void ulp_lp_core_halt(void); */ __attribute__((__noreturn__)) void ulp_lp_core_stop_lp_core(void); +/** + * @brief Enable the SW triggered interrupt from the PMU + * + * @note This is the same SW trigger interrupt that is used to wake up the LP CPU + * + * @param enable true to enable, false to disable + * + */ +void ulp_lp_core_sw_intr_enable(bool enable); + +/** + * @brief Clear the interrupt status for the SW triggered interrupt from the PMU + * + */ +void ulp_lp_core_sw_intr_clear(void); + +/** + * @brief Puts the CPU into a wait state until an interrupt is triggered + * + * @note The CPU will draw less power when in this state compared to actively running + * + */ +void ulp_lp_core_wait_for_intr(void); + #ifdef __cplusplus } #endif diff --git a/components/ulp/lp_core/lp_core/lp_core_interrupt.c b/components/ulp/lp_core/lp_core/lp_core_interrupt.c new file mode 100644 index 000000000000..a24b7953e13e --- /dev/null +++ b/components/ulp/lp_core/lp_core/lp_core_interrupt.c @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "sdkconfig.h" +#include "hal/lp_core_ll.h" +#include "riscv/rv_utils.h" +#include "riscv/rvruntime-frames.h" + +#if CONFIG_IDF_TARGET_ESP32C6 +/* Enable interrupt 30, which all external interrupts are routed to*/ +#define MIE_ALL_INTS_MASK (1 << 30) +#else +/* Enable all external interrupts routed to CPU, expect HP_INTR, + as this would trigger an LP core interrupt for every single interrupt + that triggers on HP Core. + */ +#define MIE_ALL_INTS_MASK 0x3FFF0888 +#endif + +void ulp_lp_core_intr_enable(void) +{ + /* Enable interrupt globally */ + RV_SET_CSR(mstatus, MSTATUS_MIE); + RV_SET_CSR(mie, MIE_ALL_INTS_MASK); + +} + +void ulp_lp_core_intr_disable(void) +{ + RV_CLEAR_CSR(mie, MIE_ALL_INTS_MASK); + /* Disable interrupts globally */ + RV_CLEAR_CSR(mstatus, MSTATUS_MIE); +} + +void __attribute__((weak)) ulp_lp_core_panic_handler(RvExcFrame *frame, int exccause) +{ + abort(); +} + +static void ulp_lp_core_default_intr_handler(void) +{ + abort(); +} + +/* Default ISR handlers, intended to be overwritten by users */ +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_io_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_i2c_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_uart_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_timer_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_pmu_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_spi_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_trng_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_adc_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_touch_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_tsens_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_efuse_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_sysreg_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_ana_peri_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_mailbox_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_wdt_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_lp_rtc_intr_handler(void); +void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_core_sw_intr_handler(void); + +#if CONFIG_IDF_TARGET_ESP32C6 + +static void* s_intr_handlers[] = { + ulp_lp_core_lp_io_intr_handler, + ulp_lp_core_lp_i2c_intr_handler, + ulp_lp_core_lp_uart_intr_handler, + ulp_lp_core_lp_timer_intr_handler, + 0, // Reserved / Unused + ulp_lp_core_lp_pmu_intr_handler, +}; + +void __attribute__((weak)) ulp_lp_core_intr_handler(void) +{ + uint8_t intr_source = lp_core_ll_get_triggered_interrupt_srcs(); + for (int i = 0; i < sizeof(s_intr_handlers) / 4; i++) { + if (intr_source & (1 << i)) { + void (*handler)(void) = s_intr_handlers[i]; + if (handler) { + handler(); + } + } + } +} + +#endif diff --git a/components/ulp/lp_core/lp_core/lp_core_panic.c b/components/ulp/lp_core/lp_core/lp_core_panic.c new file mode 100644 index 000000000000..70fac05483f9 --- /dev/null +++ b/components/ulp/lp_core/lp_core/lp_core_panic.c @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" + +#include +#include +#include "ulp_lp_core_print.h" +#include "riscv/rvruntime-frames.h" + +#if CONFIG_ULP_PANIC_OUTPUT_ENABLE + +static void dump_stack(RvExcFrame *frame, int exccause) +{ + uint32_t i = 0; + uint32_t sp = frame->sp; + lp_core_printf("\n\nStack memory:\n"); + const int per_line = 8; + for (i = 0; i < 1024; i += per_line * sizeof(uint32_t)) { + uint32_t *spp = (uint32_t *)(sp + i); + lp_core_printf("%08x: ", sp + i); + for (int y = 0; y < per_line; y++) { + lp_core_printf("0x%08x%c", spp[y], y == per_line - 1 ? '\n' : ' '); + } + } + lp_core_printf("\n"); +} + +static const char *desc[] = { + "MEPC ", "RA ", "SP ", "GP ", "TP ", "T0 ", "T1 ", "T2 ", + "S0/FP ", "S1 ", "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", + "A6 ", "A7 ", "S2 ", "S3 ", "S4 ", "S5 ", "S6 ", "S7 ", + "S8 ", "S9 ", "S10 ", "S11 ", "T3 ", "T4 ", "T5 ", "T6 ", + "MSTATUS ", "MTVEC ", "MCAUSE ", "MTVAL ", "MHARTID " +}; + +static const char *reason[] = { + NULL, + NULL, + "Illegal instruction", + "Breakpoint", + "Load address misaligned", + "Load access fault", + "Store address misaligned", + "Store access fault", +}; + +void ulp_lp_core_panic_handler(RvExcFrame *frame, int exccause) +{ +#define DIM(arr) (sizeof(arr)/sizeof(*arr)) + + const char *exccause_str = "Unhandled interrupt/Unknown cause"; + + if (exccause < DIM(reason) && reason[exccause] != NULL) { + exccause_str = reason[exccause]; + } + + lp_core_printf("Guru Meditation Error: LP Core panic'ed (%s)\n", exccause_str); + lp_core_printf("Core 0 register dump:\n"); + + uint32_t* frame_ints = (uint32_t*) frame; + for (int x = 0; x < DIM(desc); x++) { + if (desc[x][0] != 0) { + const int not_last = (x + 1) % 4; + lp_core_printf("%-8s: 0x%08x %c", desc[x], frame_ints[x], not_last ? ' ' : '\n'); + } + } + + dump_stack(frame, exccause); + + /* idf-monitor uses this string to mark the end of a panic dump */ + lp_core_printf("ELF file SHA256: No SHA256 Embedded\n"); + + while (1) { + } +} + +#endif //#if CONFIG_ULP_PANIC_OUTPUT_ENABLE diff --git a/components/ulp/lp_core/lp_core/lp_core_print.c b/components/ulp/lp_core/lp_core/lp_core_print.c index 785d59e6c476..0a704c28a328 100644 --- a/components/ulp/lp_core/lp_core/lp_core_print.c +++ b/components/ulp/lp_core/lp_core/lp_core_print.c @@ -4,26 +4,49 @@ * SPDX-License-Identifier: Apache-2.0 */ #include +#include "sdkconfig.h" #include "ulp_lp_core_uart.h" - -#if !CONFIG_ULP_ROM_PRINT_ENABLE +#include "hal/uart_hal.h" +#include "esp_rom_uart.h" #define LP_UART_PORT_NUM LP_UART_NUM_0 #define BINARY_SUPPORT 1 #define is_digit(c) ((c >= '0') && (c <= '9')) +#if CONFIG_ULP_HP_UART_CONSOLE_PRINT +void __attribute__((alias("hp_uart_send_char"))) lp_core_print_char(char c); + +static void hp_uart_send_char(char t) +{ + uart_dev_t *uart = (uart_dev_t *)UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM); + + while (uart_ll_get_txfifo_len(uart) < 2) { + ; + } + uart_ll_write_txfifo(uart, &t, 1); +} +#elif !CONFIG_ULP_ROM_PRINT_ENABLE +void __attribute__((alias("lp_uart_send_char"))) lp_core_print_char(char c); static void lp_uart_send_char(char c) { int tx_len = 0; int loop_cnt = 0; - /* Write one byte to LP UART. Break after few iterations if we are stuck for any reason. */ while (tx_len != 1 && loop_cnt < 1000) { tx_len = lp_core_uart_tx_chars(LP_UART_PORT_NUM, (const void *)&c, 1); loop_cnt++; } } +#else +void __attribute__((alias("lp_rom_send_char"))) lp_core_print_char(char c); +static void lp_rom_send_char(char c) +{ + esp_rom_output_putc(c); +} +#endif // CONFIG_ULP_HP_UART_CONSOLE_PRINT + +#if !CONFIG_ULP_ROM_PRINT_ENABLE // Ported over ROM function _cvt() static int lp_core_cvt(unsigned long long val, char *buf, long radix, char *digits) @@ -267,7 +290,7 @@ int lp_core_printf(const char* format, ...) va_start(ap, format); /* Pass the input string and the argument list to ets_vprintf() */ - int ret = lp_core_ets_vprintf(lp_uart_send_char, format, ap); + int ret = lp_core_ets_vprintf(lp_core_print_char, format, ap); va_end(ap); diff --git a/components/ulp/lp_core/lp_core/lp_core_spi.c b/components/ulp/lp_core/lp_core/lp_core_spi.c new file mode 100644 index 000000000000..9ff1f8a2734b --- /dev/null +++ b/components/ulp/lp_core/lp_core/lp_core_spi.c @@ -0,0 +1,262 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc_caps.h" + +#if SOC_LP_SPI_SUPPORTED + +#include +#include +#include "esp_err.h" +#include "ulp_lp_core_spi.h" +#include "soc/lp_spi_struct.h" + +/* Use the register structure to access LP_SPI module registers */ +lp_spi_dev_t *lp_spi_dev = &LP_SPI; + +static inline esp_err_t lp_core_spi_wait_for_interrupt(int32_t ticks_to_wait) +{ + uint32_t to = 0; + while (!lp_spi_dev->spi_dma_int_raw.reg_trans_done_int_raw) { + if (ticks_to_wait > -1) { + /* If the ticks_to_wait value is not -1, keep track of ticks and + * break from the loop once the timeout is reached. + */ + to++; + if (to >= ticks_to_wait) { + /* Clear interrupt bits */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + return ESP_ERR_TIMEOUT; + } + } + } + + return ESP_OK; +} + +////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////// Public APIs /////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// + +esp_err_t lp_core_lp_spi_master_transfer(lp_spi_transaction_t *trans_desc, int32_t ticks_to_wait) +{ + esp_err_t ret = ESP_OK; + + /* Argument sanity check + * Note: The Tx buffer is mandatory for this API. + */ + if (trans_desc == NULL || trans_desc->tx_buffer == NULL || trans_desc->tx_length == 0) { + return ESP_ERR_INVALID_ARG; + } + + /* Reset the Tx and Rx FIFOs */ + lp_spi_dev->spi_dma_conf.reg_rx_afifo_rst = 1; + lp_spi_dev->spi_dma_conf.reg_rx_afifo_rst = 0; + lp_spi_dev->spi_dma_conf.reg_buf_afifo_rst = 1; + lp_spi_dev->spi_dma_conf.reg_buf_afifo_rst = 0; + + /* Clear any previous interrupts. + * Note: LP SPI does not have any DMA access but the interrupt bit lives in the DMA interrupt register. + */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + + /* Make sure that we do not have any ongoing transactions */ + if (lp_spi_dev->spi_cmd.reg_usr) { + return ESP_ERR_INVALID_STATE; + } + + /* Configure dummy bits */ + lp_spi_dev->spi_user.reg_usr_dummy = trans_desc->dummy_bits ? 1 : 0; + if (trans_desc->dummy_bits) { + lp_spi_dev->spi_user1.reg_usr_dummy_cyclelen = trans_desc->dummy_bits - 1; + } + + /* Configure the command and command bit length */ + lp_spi_dev->spi_user.reg_usr_command = trans_desc->command_bits ? 1 : 0; + if (trans_desc->command_bits) { + lp_spi_dev->spi_user2.reg_usr_command_bitlen = trans_desc->command_bits - 1; + lp_spi_dev->spi_user2.reg_usr_command_value = lp_spi_dev->spi_ctrl.reg_wr_bit_order ? trans_desc->command : __builtin_bswap32(trans_desc->command << (32 - trans_desc->command_bits)); + } + + /* Configure the address and address bit length */ + lp_spi_dev->spi_user.reg_usr_addr = trans_desc->address_bits ? 1 : 0; + if (trans_desc->address_bits) { + lp_spi_dev->spi_user1.reg_usr_addr_bitlen = trans_desc->address_bits - 1; + lp_spi_dev->spi_addr.reg_usr_addr_value = lp_spi_dev->spi_ctrl.reg_wr_bit_order ? __builtin_bswap32(trans_desc->address) : trans_desc->address << (32 - trans_desc->address_bits); + } + + /* Set data lines */ + lp_spi_dev->spi_user.reg_usr_mosi = 1; + lp_spi_dev->spi_user.reg_usr_miso = trans_desc->rx_buffer ? 1 : 0; + + /* Configure the transaction bit length */ + int tx_bitlen = trans_desc->tx_length * 8; + lp_spi_dev->spi_ms_dlen.reg_ms_data_bitlen = tx_bitlen - 1; + + /* Prepare the data to be transmitted */ + uint32_t tx_idx = 0; + uint32_t rx_idx = 0; + + /* The TRM suggests that the data is sent from and received in the LP_SPI_W0_REG ~ LP_SPI_W15_REG registers. + * The following rules apply: + * 1. The first 64 bytes are sent from/received in LP_SPI_W0_REG ~ LP_SPI_W15_REG + * 2. Bytes 64 - 255 are repeatedly sent from or received in LP_SPI_W15_REG[31:24] + * 3. Subsequent blocks of 256 bytes of data continue to follow the above rules + * + * This driver, however, avoids using the LP_SPI_W15_REG altogether. In other words, + * this driver sends or receives data in chunks of 60 bytes (LP_SPI_W0_REG ~ LP_SPI_W14_REG) + * and does not handle the repeated use of the high-byte of LP_SPI_W15_REG. This design approach + * has been chosen to simplify the data handling logic. + */ + uint8_t max_data_reg_num = (SOC_LP_SPI_MAXIMUM_BUFFER_SIZE / 4) - 1; // 15 + uint8_t max_data_chunk_size = max_data_reg_num * 4; // 60 + while (tx_idx < trans_desc->tx_length) { + /* Store 4 bytes of data in the data buffer registers serially. */ + lp_spi_dev->data_buf[(tx_idx / 4) & max_data_reg_num].reg_buf = *(uint32_t *)(trans_desc->tx_buffer + tx_idx); + tx_idx += 4; + + /* Begin transmission of the data if we have pushed all the data or if we have reached the maximum data chunk size */ + if ((tx_idx >= trans_desc->tx_length) || (tx_idx % max_data_chunk_size) == 0) { + /* Apply the configuration */ + lp_spi_dev->spi_cmd.reg_update = 1; + while (lp_spi_dev->spi_cmd.reg_update) { + ; + } + + /* Start the transaction */ + lp_spi_dev->spi_cmd.reg_usr = 1; + + /* Wait for the transaction to complete */ + ret = lp_core_spi_wait_for_interrupt(ticks_to_wait); + if (ret != ESP_OK) { + return ret; + } + + /* Clear the transaction done interrupt */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + + /* Fetch the received data if an Rx buffer is provided */ + if (trans_desc->rx_buffer != NULL) { + while (rx_idx < tx_idx) { + *(uint32_t *)(trans_desc->rx_buffer + rx_idx) = lp_spi_dev->data_buf[(rx_idx / 4) & max_data_reg_num].reg_buf; + rx_idx += 4; + // This loop would exit even if we haven't received all the data. + } + } + } + } + + return ret; +} + +esp_err_t lp_core_lp_spi_slave_transfer(lp_spi_transaction_t *trans_desc, int32_t ticks_to_wait) +{ + esp_err_t ret = ESP_OK; + + /* Argument sanity check + * Note: The Rx buffer is mandatory for this API. + */ + if (trans_desc == NULL || trans_desc->rx_buffer == NULL || trans_desc->rx_length == 0) { + return ESP_ERR_INVALID_ARG; + } + + /* Reset the Tx and Rx FIFOs */ + lp_spi_dev->spi_dma_conf.reg_rx_afifo_rst = 1; + lp_spi_dev->spi_dma_conf.reg_rx_afifo_rst = 0; + lp_spi_dev->spi_dma_conf.reg_buf_afifo_rst = 1; + lp_spi_dev->spi_dma_conf.reg_buf_afifo_rst = 0; + + /* Clear any previous interrupts. + * Note: LP SPI does not have any DMA access but the interrupt bit lives in the DMA interrupt register. + */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + + /* Set data lines */ + lp_spi_dev->spi_user.reg_usr_mosi = 1; + lp_spi_dev->spi_user.reg_usr_miso = 1; + + /* Configure the transaction bit length */ + int rx_bitlen = trans_desc->rx_length * 8; + lp_spi_dev->spi_ms_dlen.reg_ms_data_bitlen = rx_bitlen - 1; + + /* Prepare the data to be received */ + uint32_t rx_idx = 0; + uint32_t rcvd_bitlen = 0; + uint32_t rcvd_length_in_bytes = 0; + + /* The LP SPI slave receives data in the LP_SPI_W0_REG ~ LP_SPI_W15_REG registers. + * The following rules apply: + * 1. The first 64 bytes are received in LP_SPI_W0_REG ~ LP_SPI_W15_REG + * 2. The next 64 bytes are overwritten in LP_SPI_W0_REG ~ LP_SPI_W15_REG + * + * Since the peripheral has no protection against overwriting the data, we restrict the + * driver to receive up to 64 bytes of data at a time. + */ + uint32_t length_in_bytes = trans_desc->rx_length; + if (trans_desc->rx_length > SOC_LP_SPI_MAXIMUM_BUFFER_SIZE) { + /* Truncate the length to the maximum buffer size */ + length_in_bytes = SOC_LP_SPI_MAXIMUM_BUFFER_SIZE; + } + + while (rx_idx < length_in_bytes) { + /* Wait for the transmission to complete */ + ret = lp_core_spi_wait_for_interrupt(ticks_to_wait); + if (ret != ESP_OK) { + return ret; + } + + /* Fetch the received bit length */ + rcvd_bitlen = lp_spi_dev->spi_slave1.reg_slv_data_bitlen > (trans_desc->rx_length * 8) ? (trans_desc->rx_length * 8) : lp_spi_dev->spi_slave1.reg_slv_data_bitlen; + rcvd_length_in_bytes = (rcvd_bitlen + 7) / 8; + + /* Read the received data */ + while (rx_idx < rcvd_length_in_bytes) { + *(uint32_t *)(trans_desc->rx_buffer + rx_idx) = lp_spi_dev->data_buf[(rx_idx / 4)].reg_buf; + rx_idx += 4; + } + + /* Clear the transaction done interrupt */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + } + + /* Prepare data for transmission if a Tx buffer is provided */ + if (trans_desc->tx_buffer != NULL) { + uint32_t tx_idx = 0; + uint32_t length_in_bytes = trans_desc->tx_length; + if (length_in_bytes > SOC_LP_SPI_MAXIMUM_BUFFER_SIZE) { + /* Truncate the length to the maximum buffer size */ + length_in_bytes = SOC_LP_SPI_MAXIMUM_BUFFER_SIZE; + } + + while (tx_idx < length_in_bytes) { + /* Store 4 bytes of data in the data buffer registers serially. */ + lp_spi_dev->data_buf[(tx_idx / 4)].reg_buf = *(uint32_t *)(trans_desc->tx_buffer + tx_idx); + tx_idx += 4; + } + + /* Apply the configuration */ + lp_spi_dev->spi_cmd.reg_update = 1; + while (lp_spi_dev->spi_cmd.reg_update) { + ; + } + + /* Start the transaction */ + lp_spi_dev->spi_cmd.reg_usr = 1; + + /* Wait for the transaction to complete */ + ret = lp_core_spi_wait_for_interrupt(ticks_to_wait); + if (ret != ESP_OK) { + return ret; + } + + /* Clear the transaction done interrupt */ + lp_spi_dev->spi_dma_int_clr.reg_trans_done_int_clr = 1; + } + + return ret; +} + +#endif /* SOC_LP_SPI_SUPPORTED */ diff --git a/components/ulp/lp_core/lp_core/lp_core_startup.c b/components/ulp/lp_core/lp_core/lp_core_startup.c index 4d87b07fd1aa..eb318b10801b 100644 --- a/components/ulp/lp_core/lp_core/lp_core_startup.c +++ b/components/ulp/lp_core/lp_core/lp_core_startup.c @@ -1,18 +1,27 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" #include "soc/soc_caps.h" +#include "esp_rom_caps.h" +#include "rom/ets_sys.h" #include "ulp_lp_core_utils.h" #include "ulp_lp_core_lp_timer_shared.h" #include "ulp_lp_core_memory_shared.h" +#include "ulp_lp_core_print.h" extern void main(); /* Initialize lp core related system functions before calling user's main*/ void lp_core_startup() { + +#if CONFIG_ULP_HP_UART_CONSOLE_PRINT && ESP_ROM_HAS_LP_ROM + ets_install_putc1(lp_core_print_char); +#endif + ulp_lp_core_update_wakeup_cause(); main(); @@ -20,10 +29,10 @@ void lp_core_startup() ulp_lp_core_memory_shared_cfg_t* shared_mem = ulp_lp_core_memory_shared_cfg_get(); #if SOC_LP_TIMER_SUPPORTED - uint64_t sleep_duration = shared_mem->sleep_duration_us; + uint64_t sleep_duration_ticks = shared_mem->sleep_duration_ticks; - if (sleep_duration) { - ulp_lp_core_lp_timer_set_wakeup_time(sleep_duration); + if (sleep_duration_ticks) { + ulp_lp_core_lp_timer_set_wakeup_ticks(sleep_duration_ticks); } #endif //SOC_LP_TIMER_SUPPORTED diff --git a/components/ulp/lp_core/lp_core/lp_core_utils.c b/components/ulp/lp_core/lp_core/lp_core_utils.c index 6c48a4ea28ee..0eecf4006dd4 100644 --- a/components/ulp/lp_core/lp_core/lp_core_utils.c +++ b/components/ulp/lp_core/lp_core/lp_core_utils.c @@ -15,6 +15,10 @@ #include "hal/uart_ll.h" #include "hal/rtc_io_ll.h" +#if !CONFIG_IDF_TARGET_ESP32P4 +#include "hal/lp_aon_ll.h" +#endif + #if SOC_ETM_SUPPORTED #include "hal/etm_ll.h" #endif @@ -52,7 +56,11 @@ void ulp_lp_core_update_wakeup_cause(void) if ((lp_core_ll_get_wakeup_source() & LP_CORE_LL_WAKEUP_SOURCE_ETM) \ && etm_ll_is_lpcore_wakeup_triggered()) { lp_wakeup_cause |= LP_CORE_LL_WAKEUP_SOURCE_ETM; - etm_ll_clear_lpcore_wakeup_status(); +#if CONFIG_IDF_TARGET_ESP32P4 + lp_core_ll_clear_etm_wakeup_status(); +#else + lp_aon_ll_clear_lpcore_etm_wakeup_flag(); +#endif } #endif /* SOC_ETM_SUPPORTED */ @@ -135,3 +143,18 @@ void __attribute__((noreturn)) abort(void) while (1); } + +void ulp_lp_core_sw_intr_enable(bool enable) +{ + pmu_ll_lp_enable_sw_intr(&PMU, enable); +} + +void ulp_lp_core_sw_intr_clear(void) +{ + pmu_ll_lp_clear_sw_intr_status(&PMU); +} + +void ulp_lp_core_wait_for_intr(void) +{ + asm volatile("wfi"); +} diff --git a/components/ulp/lp_core/lp_core/port/esp32c6/vector_table.S b/components/ulp/lp_core/lp_core/port/esp32c6/vector_table.S new file mode 100644 index 000000000000..a1309e3cf817 --- /dev/null +++ b/components/ulp/lp_core/lp_core/port/esp32c6/vector_table.S @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + .section .init.vector,"ax" + + .global _vector_table + .type _vector_table, @function +_vector_table: + .option push + .option norvc + + .rept 30 + j _panic_handler + .endr + j _interrupt_handler // All interrupts are routed to mtvec + 4*30, i.e. the 31st entry + j _panic_handler + + .option pop + .size _vector_table, .-_vector_table diff --git a/components/ulp/lp_core/lp_core/port/esp32p4/vector_table.S b/components/ulp/lp_core/lp_core/port/esp32p4/vector_table.S new file mode 100644 index 000000000000..c5e7ca9fee9e --- /dev/null +++ b/components/ulp/lp_core/lp_core/port/esp32p4/vector_table.S @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + .section .init.vector,"ax" + + .global _vector_table + .type _vector_table, @function +_vector_table: + .option push + .option norvc + + j _panic_handler + j _panic_handler + j _panic_handler + j ulp_lp_core_sw_intr_handler + j _panic_handler + j _panic_handler + j _panic_handler + j ulp_lp_core_lp_uart_intr_handler + j _panic_handler + j _panic_handler + j _panic_handler + j ulp_lp_core_lp_spi_intr_handler + j _panic_handler + j _panic_handler + j _panic_handler + j _panic_handler + j ulp_lp_core_trng_intr_handler + j ulp_lp_core_lp_i2c_intr_handler + j ulp_lp_core_lp_io_intr_handler + j ulp_lp_core_lp_adc_intr_handler + j ulp_lp_core_lp_touch_intr_handler + j ulp_lp_core_tsens_intr_handler + j ulp_lp_core_efuse_intr_handler + j ulp_lp_core_lp_sysreg_intr_handler + j ulp_lp_core_lp_ana_peri_intr_handler + j ulp_lp_core_lp_pmu_intr_handler + j ulp_lp_core_mailbox_intr_handler + j ulp_lp_core_lp_timer_intr_handler + j ulp_lp_core_lp_wdt_intr_handler + j ulp_lp_core_lp_rtc_intr_handler + j _panic_handler + j _panic_handler + + .option pop + .size _vector_table, .-_vector_table diff --git a/components/ulp/lp_core/lp_core/start.S b/components/ulp/lp_core/lp_core/start.S index f13a8819bdd2..b4665c9a3cbd 100644 --- a/components/ulp/lp_core/lp_core/start.S +++ b/components/ulp/lp_core/lp_core/start.S @@ -9,6 +9,11 @@ /* The reset vector, jumps to startup code */ reset_vector: + + /* _vector_table: Only 256-byte aligned addresses are allowed */ + la t0, _vector_table + csrw mtvec, t0 + j __start __start: diff --git a/components/ulp/lp_core/lp_core/vector.S b/components/ulp/lp_core/lp_core/vector.S index 76c41a81b127..b62cbc9ec377 100644 --- a/components/ulp/lp_core/lp_core/vector.S +++ b/components/ulp/lp_core/lp_core/vector.S @@ -1,24 +1,146 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ - .section .init.vector,"ax" - /* This is the vector table. It is currently empty, but will be populated - * with exception and interrupt handlers when this is supported - */ +#include "riscv/rvruntime-frames.h" +#include "soc/soc_caps.h" - .align 0x4, 0xff - .global _vector_table - .type _vector_table, @function -_vector_table: - .option push - .option norvc + .equ SAVE_REGS, 32 + .equ CONTEXT_SIZE, (SAVE_REGS * 4) +/* Macro which first allocates space on the stack to save general + * purpose registers, and then save them. GP register is excluded. + * The default size allocated on the stack is CONTEXT_SIZE, but it + * can be overridden. */ +.macro save_general_regs cxt_size=CONTEXT_SIZE + addi sp, sp, -\cxt_size + sw ra, RV_STK_RA(sp) + sw tp, RV_STK_TP(sp) + sw t0, RV_STK_T0(sp) + sw t1, RV_STK_T1(sp) + sw t2, RV_STK_T2(sp) + sw s0, RV_STK_S0(sp) + sw s1, RV_STK_S1(sp) + sw a0, RV_STK_A0(sp) + sw a1, RV_STK_A1(sp) + sw a2, RV_STK_A2(sp) + sw a3, RV_STK_A3(sp) + sw a4, RV_STK_A4(sp) + sw a5, RV_STK_A5(sp) + sw a6, RV_STK_A6(sp) + sw a7, RV_STK_A7(sp) + sw s2, RV_STK_S2(sp) + sw s3, RV_STK_S3(sp) + sw s4, RV_STK_S4(sp) + sw s5, RV_STK_S5(sp) + sw s6, RV_STK_S6(sp) + sw s7, RV_STK_S7(sp) + sw s8, RV_STK_S8(sp) + sw s9, RV_STK_S9(sp) + sw s10, RV_STK_S10(sp) + sw s11, RV_STK_S11(sp) + sw t3, RV_STK_T3(sp) + sw t4, RV_STK_T4(sp) + sw t5, RV_STK_T5(sp) + sw t6, RV_STK_T6(sp) +.endm - .rept 32 - nop - .endr +.macro save_mepc + csrr t0, mepc + sw t0, RV_STK_MEPC(sp) +.endm - .option pop - .size _vector_table, .-_vector_table +/* Restore the general purpose registers (excluding gp) from the context on + * the stack. The context is then deallocated. The default size is CONTEXT_SIZE + * but it can be overridden. */ +.macro restore_general_regs cxt_size=CONTEXT_SIZE + lw ra, RV_STK_RA(sp) + lw tp, RV_STK_TP(sp) + lw t0, RV_STK_T0(sp) + lw t1, RV_STK_T1(sp) + lw t2, RV_STK_T2(sp) + lw s0, RV_STK_S0(sp) + lw s1, RV_STK_S1(sp) + lw a0, RV_STK_A0(sp) + lw a1, RV_STK_A1(sp) + lw a2, RV_STK_A2(sp) + lw a3, RV_STK_A3(sp) + lw a4, RV_STK_A4(sp) + lw a5, RV_STK_A5(sp) + lw a6, RV_STK_A6(sp) + lw a7, RV_STK_A7(sp) + lw s2, RV_STK_S2(sp) + lw s3, RV_STK_S3(sp) + lw s4, RV_STK_S4(sp) + lw s5, RV_STK_S5(sp) + lw s6, RV_STK_S6(sp) + lw s7, RV_STK_S7(sp) + lw s8, RV_STK_S8(sp) + lw s9, RV_STK_S9(sp) + lw s10, RV_STK_S10(sp) + lw s11, RV_STK_S11(sp) + lw t3, RV_STK_T3(sp) + lw t4, RV_STK_T4(sp) + lw t5, RV_STK_T5(sp) + lw t6, RV_STK_T6(sp) + addi sp,sp, \cxt_size +.endm + +.macro restore_mepc + lw t0, RV_STK_MEPC(sp) + csrw mepc, t0 +.endm + + +/* _panic_handler: handle all exception */ + .section .text.handlers,"ax" + .global _panic_handler + .type _panic_handler, @function +_panic_handler: + save_general_regs RV_STK_FRMSZ + save_mepc + + addi t0, sp, RV_STK_FRMSZ /* restore sp with the value when trap happened */ + + /* Save CSRs */ + sw t0, RV_STK_SP(sp) + csrr t0, mstatus + sw t0, RV_STK_MSTATUS(sp) + csrr t0, mcause + sw t0, RV_STK_MCAUSE(sp) + csrr t0, mtvec + sw t0, RV_STK_MTVEC(sp) + csrr t0, mhartid + sw t0, RV_STK_MHARTID(sp) + csrr t0, mtval + sw t0, RV_STK_MTVAL(sp) + + csrr a1, mcause /* exception cause */ + + mv a0, sp /* RvExcFrame *regs */ + call ulp_lp_core_panic_handler +_end: + j _end /* loop forever */ + + +#if SOC_LP_CORE_SINGLE_INTERRUPT_VECTOR + +/* interrupt_handler: handle all interrupt */ + .section .text.handlers,"ax" + .global _interrupt_handler + .type _interrupt_handler, @function +_interrupt_handler: + /* save registers & mepc to stack */ + save_general_regs + save_mepc + + call ulp_lp_core_intr_handler + + /* restore registers & mepc from stack */ + restore_mepc + restore_general_regs + /* exit, this will also re-enable the interrupts */ + mret + +#endif // SOC_LP_CORE_SINGLE_INTERRUPT_VECTOR diff --git a/components/ulp/lp_core/lp_core_etm.c b/components/ulp/lp_core/lp_core_etm.c new file mode 100644 index 000000000000..16be0fc5da24 --- /dev/null +++ b/components/ulp/lp_core/lp_core_etm.c @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" +#include "lp_core_etm.h" +#include "esp_private/etm_interface.h" +#include "esp_err.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "soc/soc_etm_source.h" + +#define LP_CORE_ETM_EVENT_TABLE(event) \ + (uint32_t [LP_CORE_EVENT_MAX]){ \ + [LP_CORE_EVENT_ERR_INTR] = ULP_EVT_ERR_INTR, \ + [LP_CORE_EVENT_START_INTR] = ULP_EVT_START_INTR, \ + }[event] + +#define LP_CORE_ETM_TASK_TABLE(task) \ + (uint32_t [LP_CORE_TASK_MAX]){ \ + [LP_CORE_TASK_WAKEUP_CPU] = ULP_TASK_WAKEUP_CPU, \ + }[task] + +const static char* TAG = "lp-core-etm"; + +static esp_err_t lp_core_del_etm_event(esp_etm_event_t *event) +{ + free(event); + return ESP_OK; +} + +static esp_err_t lp_core_del_etm_task(esp_etm_task_t *task) +{ + free(task); + return ESP_OK; +} + +esp_err_t lp_core_new_etm_task(const lp_core_etm_task_config_t *config, esp_etm_task_handle_t *out_task) +{ + esp_etm_task_t *task = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(config && out_task, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(config->task_type < LP_CORE_TASK_MAX, ESP_ERR_INVALID_ARG, err, TAG, "invalid task type"); + task = heap_caps_calloc(1, sizeof(esp_etm_task_t), MALLOC_CAP_DEFAULT); + ESP_GOTO_ON_FALSE(task, ESP_ERR_NO_MEM, err, TAG, "no memory for ETM task"); + + uint32_t task_id = LP_CORE_ETM_TASK_TABLE(config->task_type); + ESP_GOTO_ON_FALSE(task_id != 0, ESP_ERR_NOT_SUPPORTED, err, TAG, "not supported task type"); + + // fill the ETM task object + task->task_id = task_id; + task->trig_periph = ETM_TRIG_PERIPH_LP_CORE; + task->del = lp_core_del_etm_task; + ESP_LOGD(TAG, "new task @%p, task_id=%"PRIu32, task, task_id); + *out_task = task; + return ESP_OK; + +err: + if (task) { + lp_core_del_etm_task(task); + } + return ret; +} + +esp_err_t lp_core_new_etm_event(const lp_core_etm_event_config_t *config, esp_etm_event_handle_t *out_event) +{ + esp_etm_event_t *event = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(config && out_event, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(config->event_type < LP_CORE_EVENT_MAX, ESP_ERR_INVALID_ARG, err, TAG, "invalid event type"); + event = heap_caps_calloc(1, sizeof(esp_etm_event_t), MALLOC_CAP_DEFAULT); + ESP_GOTO_ON_FALSE(event, ESP_ERR_NO_MEM, err, TAG, "no memory for ETM event"); + + uint32_t event_id = LP_CORE_ETM_EVENT_TABLE(config->event_type); + ESP_GOTO_ON_FALSE(event_id != 0, ESP_ERR_NOT_SUPPORTED, err, TAG, "not supported event type"); + + // fill the ETM event object + event->event_id = event_id; + event->trig_periph = ETM_TRIG_PERIPH_LP_CORE; + event->del = lp_core_del_etm_event; + *out_event = event; + return ESP_OK; + +err: + if (event) { + lp_core_del_etm_event(event); + } + return ret; +} diff --git a/components/ulp/lp_core/lp_core_i2c.c b/components/ulp/lp_core/lp_core_i2c.c index 0d41f7fba1d6..0b5db5add8b1 100644 --- a/components/ulp/lp_core/lp_core_i2c.c +++ b/components/ulp/lp_core/lp_core_i2c.c @@ -53,9 +53,10 @@ static esp_err_t lp_i2c_gpio_is_cfg_valid(gpio_num_t sda_io_num, gpio_num_t scl_ static esp_err_t lp_i2c_configure_io(gpio_num_t io_num, bool pullup_en) { + /* Set the IO pin to high to avoid them from toggling from Low to High state during initialization. This can register a spurious I2C start condition. */ + ESP_RETURN_ON_ERROR(rtc_gpio_set_level(io_num, 1), LPI2C_TAG, "LP GPIO failed to set level to high for %d", io_num); /* Initialize IO Pin */ ESP_RETURN_ON_ERROR(rtc_gpio_init(io_num), LPI2C_TAG, "LP GPIO Init failed for GPIO %d", io_num); - /* Set direction to input+output open-drain mode */ ESP_RETURN_ON_ERROR(rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_INPUT_OUTPUT_OD), LPI2C_TAG, "LP GPIO Set direction failed for %d", io_num); /* Disable pulldown on the io pin */ @@ -82,12 +83,16 @@ static esp_err_t lp_i2c_set_pin(const lp_core_i2c_cfg_t *cfg) /* Verify that the LP I2C GPIOs are valid */ ESP_RETURN_ON_ERROR(lp_i2c_gpio_is_cfg_valid(sda_io_num, scl_io_num), LPI2C_TAG, "LP I2C GPIO config invalid"); - /* Initialize SDA Pin */ - ESP_RETURN_ON_ERROR(lp_i2c_configure_io(sda_io_num, sda_pullup_en), LPI2C_TAG, "LP I2C SDA pin config failed"); + // NOTE: We always initialize the SCL pin first, then the SDA pin. + // This order of initialization is important to avoid any spurious + // I2C start conditions on the bus. /* Initialize SCL Pin */ ESP_RETURN_ON_ERROR(lp_i2c_configure_io(scl_io_num, scl_pullup_en), LPI2C_TAG, "LP I2C SCL pin config failed"); + /* Initialize SDA Pin */ + ESP_RETURN_ON_ERROR(lp_i2c_configure_io(sda_io_num, sda_pullup_en), LPI2C_TAG, "LP I2C SDA pin config failed"); + #if !SOC_LP_GPIO_MATRIX_SUPPORTED /* Select LP I2C function for the SDA Pin */ lp_io_dev->gpio[sda_io_num].mcu_sel = 1; @@ -123,7 +128,7 @@ static esp_err_t lp_i2c_config_clk(const lp_core_i2c_cfg_t *cfg) } } - /* Fetch the clock source fequency */ + /* Fetch the clock source frequency */ ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(source_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &source_freq), LPI2C_TAG, "Invalid LP I2C source clock selected"); /* Verify that the I2C_SCLK operates at a frequency 20 times larger than the requested SCL bus frequency */ @@ -162,6 +167,9 @@ esp_err_t lp_core_i2c_master_init(i2c_port_t lp_i2c_num, const lp_core_i2c_cfg_t i2c_hal_init(&i2c_hal, lp_i2c_num); } + /* Clear any pending interrupts */ + i2c_ll_clear_intr_mask(i2c_hal.dev, UINT32_MAX); + /* Initialize LP I2C Master mode */ i2c_hal_master_init(&i2c_hal); diff --git a/components/ulp/lp_core/lp_core_spi.c b/components/ulp/lp_core/lp_core_spi.c new file mode 100644 index 000000000000..0def39cc0153 --- /dev/null +++ b/components/ulp/lp_core/lp_core_spi.c @@ -0,0 +1,306 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" +#include "lp_core_spi.h" +#include "driver/rtc_io.h" +#include "driver/lp_io.h" +#include "hal/rtc_io_types.h" +#include "include/lp_core_spi.h" +#include "soc/lp_spi_struct.h" +#include "soc/lp_gpio_sig_map.h" +#include "soc/lpperi_struct.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk_tree_common.h" +#include "hal/spi_ll.h" + +static const char *LP_SPI_TAG = "lp_spi"; + +/* Use the LP SPI register structure to access peripheral registers */ +lp_spi_dev_t *lp_spi_dev = &LP_SPI; + +static esp_err_t lp_spi_config_io(gpio_num_t pin, rtc_gpio_mode_t direction, uint32_t out_pad_idx, uint32_t in_pad_idx) +{ + esp_err_t ret = ESP_OK; + + /* If pin is -1, then it is not connected to any LP_IO */ + if (pin == -1) { + return ESP_OK; + } + + /* Initialize LP_IO */ + ESP_RETURN_ON_ERROR(rtc_gpio_init(pin), LP_SPI_TAG, "LP IO Init failed for GPIO %d", pin); + + /* Set LP_IO direction */ + ESP_RETURN_ON_ERROR(rtc_gpio_set_direction(pin, direction), LP_SPI_TAG, "LP IO Set direction failed for %d", pin); + + /* Connect the LP SPI signals to the LP_IO Matrix */ + ESP_RETURN_ON_ERROR(lp_gpio_connect_out_signal(pin, out_pad_idx, 0, 0), LP_SPI_TAG, "LP IO Matrix connect out signal failed for %d", pin); + ESP_RETURN_ON_ERROR(lp_gpio_connect_in_signal(pin, in_pad_idx, 0), LP_SPI_TAG, "LP IO Matrix connect in signal failed for %d", pin); + + return ret; +} + +static esp_err_t lp_spi_bus_init_io(const lp_spi_bus_config_t *bus_config) +{ + esp_err_t ret = ESP_OK; + + /* Argument sanity check */ +#if SOC_LP_GPIO_MATRIX_SUPPORTED + /* LP SPI signals can be routed to any LP_IO */ + ESP_RETURN_ON_FALSE((rtc_gpio_is_valid_gpio(bus_config->mosi_io_num)), ESP_FAIL, LP_SPI_TAG, "mosi_io_num error"); + ESP_RETURN_ON_FALSE((bus_config->miso_io_num == -1) || (rtc_gpio_is_valid_gpio(bus_config->miso_io_num)), ESP_FAIL, LP_SPI_TAG, "miso_io_num error"); + ESP_RETURN_ON_FALSE((rtc_gpio_is_valid_gpio(bus_config->sclk_io_num)), ESP_FAIL, LP_SPI_TAG, "sclk_io_num error"); + + /* Configure miso pin*/ + ret = lp_spi_config_io(bus_config->miso_io_num, RTC_GPIO_MODE_INPUT_OUTPUT, LP_SPI_Q_PAD_OUT_IDX, LP_SPI_Q_PAD_IN_IDX); + /* Configure mosi pin */ + ret = lp_spi_config_io(bus_config->mosi_io_num, RTC_GPIO_MODE_INPUT_OUTPUT, LP_SPI_D_PAD_OUT_IDX, LP_SPI_D_PAD_IN_IDX); + /* Configure sclk pin */ + ret = lp_spi_config_io(bus_config->sclk_io_num, RTC_GPIO_MODE_INPUT_OUTPUT, LP_SPI_CK_PAD_OUT_IDX, LP_SPI_CK_PAD_IN_IDX); +#else +#error "LP SPI bus initialization is not supported without LP GPIO Matrix." +#endif /* SOC_LP_GPIO_MATRIX_SUPPORTED */ + + return ret; +} + +static esp_err_t lp_spi_cs_pin_init(int cs_io_num) +{ + esp_err_t ret = ESP_OK; + +#if SOC_LP_GPIO_MATRIX_SUPPORTED + /* CS signal can be routed to any LP_IO */ + ESP_RETURN_ON_FALSE((rtc_gpio_is_valid_gpio(cs_io_num)), ESP_FAIL, LP_SPI_TAG, "cs_io_num error"); + + /* Configure CS pin */ + ret = lp_spi_config_io(cs_io_num, RTC_GPIO_MODE_INPUT_OUTPUT, LP_SPI_CS_PAD_OUT_IDX, LP_SPI_CS_PAD_IN_IDX); +#else +#error "LP SPI device Chip Select (CS) initialization is not supported without LP GPIO Matrix." +#endif /* SOC_LP_GPIO_MATRIX_SUPPORTED */ + + return ret; +} + +static void lp_spi_enable_clock_gate(void) +{ + lpperi_dev_t *lp_peri_dev = &LPPERI; + PERIPH_RCC_ATOMIC() { + (void)__DECLARE_RCC_ATOMIC_ENV; // Avoid warnings for unused variable __DECLARE_RCC_ATOMIC_ENV + lp_peri_dev->clk_en.ck_en_lp_spi = 1; + } +} + +static esp_err_t lp_spi_clock_init(const lp_spi_device_config_t *dev_config) +{ + esp_err_t ret = ESP_OK; + + /* Max requested clock frequency cannot be more than the LP_FAST_CLK frequency */ + uint32_t max_clock_source_hz = esp_clk_tree_lp_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX); + ESP_RETURN_ON_FALSE(dev_config->clock_speed_hz <= max_clock_source_hz, ESP_ERR_INVALID_ARG, LP_SPI_TAG, "Invalid clock speed for SPI device. Max allowed = %ld Hz", max_clock_source_hz); + + /* Set the duty cycle. If not specified, use 50% */ + int duty_cycle = dev_config->duty_cycle ? dev_config->duty_cycle : 128; + + /* Calculate the clock pre-div values. We use the HP SPI LL function here for the calculation. */ + spi_ll_clock_val_t spi_clock; + spi_ll_master_cal_clock(max_clock_source_hz, dev_config->clock_speed_hz, duty_cycle, &spi_clock); + lp_spi_dev->spi_clock.val = spi_clock; + + return ret; +} + +static void lp_spi_master_init(void) +{ + /* Initialize the LP SPI in master mode. + * (We do not have a HAL/LL layer for LP SPI, yet, so let's use the LP SPI registers directly). + */ + + /* Clear Slave mode to enable Master mode */ + lp_spi_dev->spi_slave.reg_slave_mode = 0; + lp_spi_dev->spi_slave.reg_clk_mode = 0; + + /* Reset CS timing */ + lp_spi_dev->spi_user1.reg_cs_setup_time = 0; + lp_spi_dev->spi_user1.reg_cs_hold_time = 0; + + /* Use all 64 bytes of the Tx/Rx buffers in CPU controlled transfer */ + lp_spi_dev->spi_user.reg_usr_mosi_highpart = 0; + lp_spi_dev->spi_user.reg_usr_miso_highpart = 0; +} + +static void lp_spi_slave_init(void) +{ + /* Set Slave mode */ + lp_spi_dev->spi_slave.reg_slave_mode = 1; + + /* Reset the SPI peripheral */ + lp_spi_dev->spi_slave.reg_soft_reset = 1; + lp_spi_dev->spi_slave.reg_soft_reset = 0; + + /* Configure slave */ + lp_spi_dev->spi_clock.val = 0; + lp_spi_dev->spi_user.val = 0; + lp_spi_dev->spi_ctrl.val = 0; + lp_spi_dev->spi_user.reg_doutdin = 1; //we only support full duplex + lp_spi_dev->spi_user.reg_sio = 0; + + /* Use all 64 bytes of the Tx/Rx buffers in CPU controlled transfer */ + lp_spi_dev->spi_user.reg_usr_miso_highpart = 0; + lp_spi_dev->spi_user.reg_usr_mosi_highpart = 0; +} + +static void lp_spi_master_setup_device(const lp_spi_device_config_t *dev_config) +{ + /* Configure transmission bit order */ + lp_spi_dev->spi_ctrl.reg_rd_bit_order = dev_config->flags & LP_SPI_DEVICE_RXBIT_LSBFIRST ? 1 : 0; + lp_spi_dev->spi_ctrl.reg_wr_bit_order = dev_config->flags & LP_SPI_DEVICE_TXBIT_LSBFIRST ? 1 : 0; + + /* Configure SPI mode in master mode */ + if (dev_config->spi_mode == 0) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 0; + lp_spi_dev->spi_user.reg_ck_out_edge = 0; + } else if (dev_config->spi_mode == 1) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 0; + lp_spi_dev->spi_user.reg_ck_out_edge = 1; + } else if (dev_config->spi_mode == 2) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 1; + lp_spi_dev->spi_user.reg_ck_out_edge = 1; + } else if (dev_config->spi_mode == 3) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 1; + lp_spi_dev->spi_user.reg_ck_out_edge = 0; + } + + /* Configure the polarity of the CS line */ + lp_spi_dev->spi_misc.reg_master_cs_pol = dev_config->flags & LP_SPI_DEVICE_CS_ACTIVE_HIGH ? 1 : 0; + + /* Configure half-duplex (0) or full-duplex (1) mode for LP SPI master */ + lp_spi_dev->spi_user.reg_doutdin = dev_config->flags & LP_SPI_DEVICE_HALF_DUPLEX ? 0 : 1; + + /* Configure 3-Wire half-duplex mode */ + lp_spi_dev->spi_user.reg_sio = dev_config->flags & LP_SPI_DEVICE_3WIRE ? 1 : 0; + + /* Configure CS setup and hold times */ + lp_spi_dev->spi_user1.reg_cs_setup_time = dev_config->cs_ena_pretrans == 0 ? 0 : dev_config->cs_ena_pretrans - 1; + lp_spi_dev->spi_user.reg_cs_setup = dev_config->cs_ena_pretrans ? 1 : 0; + lp_spi_dev->spi_user1.reg_cs_hold_time = dev_config->cs_ena_posttrans; + lp_spi_dev->spi_user.reg_cs_hold = dev_config->cs_ena_posttrans ? 1 : 0; + + /* Select the CS pin */ + lp_spi_dev->spi_misc.reg_cs0_dis = 0; +} + +static void lp_spi_slave_setup_device(const lp_spi_slave_config_t *slave_config) +{ + /* Configure transmission bit order */ + lp_spi_dev->spi_ctrl.reg_rd_bit_order = slave_config->flags & LP_SPI_DEVICE_RXBIT_LSBFIRST ? 1 : 0; + lp_spi_dev->spi_ctrl.reg_wr_bit_order = slave_config->flags & LP_SPI_DEVICE_TXBIT_LSBFIRST ? 1 : 0; + + /* Configure SPI mode in slave mode */ + if (slave_config->spi_mode == 0) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 0; + lp_spi_dev->spi_user.reg_rsck_i_edge = 0; + lp_spi_dev->spi_user.reg_tsck_i_edge = 0; + lp_spi_dev->spi_slave.reg_clk_mode_13 = 0; + } else if (slave_config->spi_mode == 1) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 0; + lp_spi_dev->spi_user.reg_rsck_i_edge = 1; + lp_spi_dev->spi_user.reg_tsck_i_edge = 1; + lp_spi_dev->spi_slave.reg_clk_mode_13 = 1; + } else if (slave_config->spi_mode == 2) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 1; + lp_spi_dev->spi_user.reg_rsck_i_edge = 1; + lp_spi_dev->spi_user.reg_tsck_i_edge = 1; + lp_spi_dev->spi_slave.reg_clk_mode_13 = 0; + } else if (slave_config->spi_mode == 3) { + lp_spi_dev->spi_misc.reg_ck_idle_edge = 1; + lp_spi_dev->spi_user.reg_rsck_i_edge = 0; + lp_spi_dev->spi_user.reg_tsck_i_edge = 0; + lp_spi_dev->spi_slave.reg_clk_mode_13 = 1; + } + + if (slave_config->flags & LP_SPI_DEVICE_CS_ACTIVE_HIGH) { + ESP_LOGW(LP_SPI_TAG, "Active high CS line is not supported in slave mode. Using active low CS line."); + } + lp_spi_dev->spi_misc.reg_slave_cs_pol = 0; + + if (slave_config->flags & LP_SPI_DEVICE_HALF_DUPLEX) { + ESP_LOGW(LP_SPI_TAG, "Half-duplex mode is not supported in slave mode. Using full-duplex mode."); + } + lp_spi_dev->spi_user.reg_doutdin = 1; + + /* Configure 3-Wire half-duplex mode */ + lp_spi_dev->spi_user.reg_sio = slave_config->flags & LP_SPI_DEVICE_3WIRE ? 1 : 0; + + /* Select the CS pin */ + lp_spi_dev->spi_misc.reg_cs0_dis = 0; +} + +////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////// Public APIs /////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// + +esp_err_t lp_core_lp_spi_bus_initialize(lp_spi_host_t host_id, const lp_spi_bus_config_t *bus_config) +{ + (void)host_id; + + /* Sanity check arguments */ + if (bus_config == NULL) { + return ESP_ERR_INVALID_ARG; + } + + /* Connect the LP SPI peripheral to a "bus", i.e. a set of + * GPIO pins defined in the bus_config structure. + */ + esp_err_t ret = lp_spi_bus_init_io(bus_config); + + return ret; +} + +esp_err_t lp_core_lp_spi_bus_add_device(lp_spi_host_t host_id, const lp_spi_device_config_t *dev_config) +{ + (void)host_id; + + esp_err_t ret = ESP_OK; + + /* Configure the CS pin */ + ESP_RETURN_ON_ERROR(lp_spi_cs_pin_init(dev_config->cs_io_num), LP_SPI_TAG, "CS pin initialization failed"); + + /* Enable the LP SPI clock gate */ + lp_spi_enable_clock_gate(); + + /* Lazy initialize the LP SPI in master mode */ + lp_spi_master_init(); + + /* Configure clock */ + ESP_RETURN_ON_ERROR(lp_spi_clock_init(dev_config), LP_SPI_TAG, "Clock initialization failed"); + + /* Setup the SPI device */ + lp_spi_master_setup_device(dev_config); + + return ret; +} + +esp_err_t lp_core_lp_spi_slave_initialize(lp_spi_host_t host_id, const lp_spi_slave_config_t *slave_config) +{ + (void)host_id; + + esp_err_t ret = ESP_OK; + + /* Configure the CS pin */ + ESP_RETURN_ON_ERROR(lp_spi_cs_pin_init(slave_config->cs_io_num), LP_SPI_TAG, "CS pin initialization failed"); + + /* Enable the LP SPI clock gate */ + lp_spi_enable_clock_gate(); + + /* Initialize the LP SPI in slave mode */ + lp_spi_slave_init(); + + /* Setup the SPI device */ + lp_spi_slave_setup_device(slave_config); + + return ret; +} diff --git a/components/ulp/lp_core/shared/include/ulp_lp_core_lp_timer_shared.h b/components/ulp/lp_core/shared/include/ulp_lp_core_lp_timer_shared.h index dda58dc843c5..6743ebd6031d 100644 --- a/components/ulp/lp_core/shared/include/ulp_lp_core_lp_timer_shared.h +++ b/components/ulp/lp_core/shared/include/ulp_lp_core_lp_timer_shared.h @@ -31,6 +31,27 @@ uint64_t ulp_lp_core_lp_timer_get_cycle_count(void); */ void ulp_lp_core_lp_timer_set_wakeup_time(uint64_t sleep_duration_us); +/** + * @brief Set the next wakeup alarm in LP timer ticks + * + * @note This only sets the alarm for a single wakeup. For periodic wakeups you will + * have to call this function again after each wakeup to configure the next time. + * + * @note If ulp_lp_core_cfg_t.lp_timer_sleep_duration_us is set the ulp will automatically set + * the next wakeup time after returning from main and override this value. + * + * @param sleep_duration_ticks + */ +void ulp_lp_core_lp_timer_set_wakeup_ticks(uint64_t sleep_duration_ticks); + +/** + * @brief Converts from sleep duration in microseconds to LP timer ticks + * + * @param sleep_duration_us Sleep duration in microseconds + * @return uint64_t Number of LP timer ticks to sleep for + */ +uint64_t ulp_lp_core_lp_timer_calculate_sleep_ticks(uint64_t sleep_duration_us); + /** * @brief Disables the lp timer alarm and clears any pending alarm interrupts * diff --git a/components/ulp/lp_core/shared/include/ulp_lp_core_memory_shared.h b/components/ulp/lp_core/shared/include/ulp_lp_core_memory_shared.h index c76f4d8e2b4e..890b1ddca922 100644 --- a/components/ulp/lp_core/shared/include/ulp_lp_core_memory_shared.h +++ b/components/ulp/lp_core/shared/include/ulp_lp_core_memory_shared.h @@ -12,7 +12,8 @@ extern "C" { #endif typedef struct { - uint64_t sleep_duration_us; /* Configured sleep duration for periodic wakeup, if set the ulp will automatically schedule the next wakeup */ + uint64_t sleep_duration_us; /* Configured sleep duration for periodic wakeup, if set the ulp will automatically schedule the next wakeup */ + uint64_t sleep_duration_ticks; /* Configured sleep duration, in LP-timer clock ticks, if set it allows us to skip doing integer division when configuring the timer */ } ulp_lp_core_memory_shared_cfg_t; /** diff --git a/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c b/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c index d3947b338b08..b39e5ba0f2cb 100644 --- a/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c +++ b/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c @@ -42,7 +42,15 @@ uint64_t ulp_lp_core_lp_timer_get_cycle_count(void) void ulp_lp_core_lp_timer_set_wakeup_time(uint64_t sleep_duration_us) { uint64_t cycle_cnt = ulp_lp_core_lp_timer_get_cycle_count(); - uint64_t alarm_target = cycle_cnt + sleep_duration_us * (1 << RTC_CLK_CAL_FRACT) / clk_ll_rtc_slow_load_cal(); + uint64_t alarm_target = cycle_cnt + ulp_lp_core_lp_timer_calculate_sleep_ticks(sleep_duration_us); + + lp_timer_hal_set_alarm_target(alarm_target); +} + +void ulp_lp_core_lp_timer_set_wakeup_ticks(uint64_t sleep_duration_ticks) +{ + uint64_t cycle_cnt = ulp_lp_core_lp_timer_get_cycle_count(); + uint64_t alarm_target = cycle_cnt + sleep_duration_ticks; lp_timer_hal_set_alarm_target(alarm_target); } @@ -53,4 +61,9 @@ void ulp_lp_core_lp_timer_disable(void) lp_timer_ll_clear_lp_alarm_intr_status(lp_timer_context.dev); } +uint64_t ulp_lp_core_lp_timer_calculate_sleep_ticks(uint64_t sleep_duration_us) +{ + return (sleep_duration_us * (1 << RTC_CLK_CAL_FRACT) / clk_ll_rtc_slow_load_cal()); +} + #endif //SOC_LP_TIMER_SUPPORTED diff --git a/components/ulp/lp_core/shared/ulp_lp_core_memory_shared.c b/components/ulp/lp_core/shared/ulp_lp_core_memory_shared.c index e36c4b56dd12..c3779b502080 100644 --- a/components/ulp/lp_core/shared/ulp_lp_core_memory_shared.c +++ b/components/ulp/lp_core/shared/ulp_lp_core_memory_shared.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,21 +7,37 @@ #include "sdkconfig.h" #include "soc/soc.h" +#include "esp_rom_caps.h" #include "esp_assert.h" +#define ALIGN_DOWN(SIZE, AL) (SIZE & ~(AL - 1)) + /* The last CONFIG_ULP_SHARED_MEM bytes of the reserved memory are reserved for a shared cfg struct The main cpu app and the ulp binary can share variables automatically through the linkerscript generated from esp32ulp_mapgen.py, but this is not available when compiling the ULP library. For those special cases, e.g. config settings. We can use this shared area. */ -#define LP_CORE_SHARED_MEM_ADDR (SOC_RTC_DRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM - CONFIG_ULP_SHARED_MEM) - -static ulp_lp_core_memory_shared_cfg_t *const s_shared_mem = (ulp_lp_core_memory_shared_cfg_t *)LP_CORE_SHARED_MEM_ADDR; +#if IS_ULP_COCPU +static ulp_lp_core_memory_shared_cfg_t __attribute__((section(".shared_mem"))) s_shared_mem = {}; ESP_STATIC_ASSERT(CONFIG_ULP_SHARED_MEM == sizeof(ulp_lp_core_memory_shared_cfg_t)); +#endif ulp_lp_core_memory_shared_cfg_t* ulp_lp_core_memory_shared_cfg_get(void) { - return s_shared_mem; +#if IS_ULP_COCPU + return &s_shared_mem; +#else +#if ESP_ROM_HAS_LP_ROM + extern uint32_t _rtc_ulp_memory_start; + uint32_t ulp_base_addr = (uint32_t)&_rtc_ulp_memory_start; +#else + uint32_t ulp_base_addr = SOC_RTC_DRAM_LOW; +#endif + /* Ensure the end where the shared memory starts is aligned to 8 bytes + if updating this also update the same in ulp_lp_core_riscv.ld + */ + return (ulp_lp_core_memory_shared_cfg_t *)(ulp_base_addr + ALIGN_DOWN(CONFIG_ULP_COPROC_RESERVE_MEM, 0x8) - CONFIG_ULP_SHARED_MEM); +#endif } diff --git a/components/ulp/project_include.cmake b/components/ulp/project_include.cmake index b3e35dca962f..2e6f5e962090 100644 --- a/components/ulp/project_include.cmake +++ b/components/ulp/project_include.cmake @@ -30,6 +30,7 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs) string(REPLACE ";" "|" ulp_s_sources "${ulp_s_sources}") idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER) + idf_build_get_property(sdkconfig_cmake SDKCONFIG_CMAKE) idf_build_get_property(idf_path IDF_PATH) idf_build_get_property(idf_target IDF_TARGET) idf_build_get_property(python PYTHON) @@ -41,17 +42,11 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs) elseif(IDF_TARGET STREQUAL "esp32s2" OR IDF_TARGET STREQUAL "esp32s3") if(CONFIG_ULP_COPROC_TYPE_RISCV STREQUAL "y") set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-ulp-riscv.cmake) - set(ULP_IS_RISCV ON) else() set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-${idf_target}-ulp.cmake) - set(ULP_IS_RISCV OFF) endif() elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE) set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-lp-core-riscv.cmake) - set(ULP_IS_LP_CORE_RISCV ON) - if(CONFIG_ESP_ROM_HAS_LP_ROM) - set(CONFIG_ESP_ROM_HAS_LP_ROM ON) - endif() endif() externalproject_add(${app_name} @@ -67,10 +62,8 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs) -DIDF_TARGET=${idf_target} -DIDF_PATH=${idf_path} -DSDKCONFIG_HEADER=${SDKCONFIG_HEADER} + -DSDKCONFIG_CMAKE=${SDKCONFIG_CMAKE} -DPYTHON=${python} - -DULP_COCPU_IS_RISCV=${ULP_IS_RISCV} - -DULP_COCPU_IS_LP_CORE=${ULP_IS_LP_CORE_RISCV} - -DCONFIG_ESP_ROM_HAS_LP_ROM=${CONFIG_ESP_ROM_HAS_LP_ROM} ${extra_cmake_args} BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/${app_name} --target build BUILD_BYPRODUCTS ${ulp_artifacts} ${ulp_artifacts_extras} ${ulp_ps_sources} diff --git a/components/ulp/test_apps/lp_core/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_basic_tests/CMakeLists.txt similarity index 94% rename from components/ulp/test_apps/lp_core/CMakeLists.txt rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/CMakeLists.txt index 5a16c97e491c..2881fcd2f424 100644 --- a/components/ulp/test_apps/lp_core/CMakeLists.txt +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/CMakeLists.txt @@ -11,4 +11,4 @@ set(EXTRA_COMPONENT_DIRS set(COMPONENTS main) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(lp_core_test) +project(lp_core_basic_tests) diff --git a/components/ulp/test_apps/lp_core/README.md b/components/ulp/test_apps/lp_core/lp_core_basic_tests/README.md similarity index 100% rename from components/ulp/test_apps/lp_core/README.md rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/README.md diff --git a/components/ulp/test_apps/lp_core/main/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt similarity index 64% rename from components/ulp/test_apps/lp_core/main/CMakeLists.txt rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt index d539efc8fbff..5072dec7e3e6 100644 --- a/components/ulp/test_apps/lp_core/main/CMakeLists.txt +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt @@ -4,6 +4,14 @@ if(CONFIG_SOC_LP_I2C_SUPPORTED) list(APPEND app_sources "test_lp_core_i2c.c") endif() +if(CONFIG_SOC_LP_SPI_SUPPORTED) + list(APPEND app_sources "test_lp_core_spi.c") +endif() + +if(CONFIG_SOC_LP_CORE_SUPPORT_ETM AND CONFIG_SOC_ETM_SUPPORTED) + list(APPEND app_sources "test_lp_core_etm.c") +endif() + set(lp_core_sources "lp_core/test_main.c") set(lp_core_sources_counter "lp_core/test_main_counter.c") @@ -17,6 +25,11 @@ if(CONFIG_SOC_LP_I2C_SUPPORTED) set(lp_core_sources_i2c "lp_core/test_main_i2c.c") endif() +if(CONFIG_SOC_LP_SPI_SUPPORTED) + set(lp_core_sources_spi_master "lp_core/test_main_spi_master.c") + set(lp_core_sources_spi_slave "lp_core/test_main_spi_slave.c") +endif() + idf_component_register(SRCS ${app_sources} INCLUDE_DIRS "lp_core" REQUIRES ulp unity esp_timer test_utils @@ -26,6 +39,7 @@ set(lp_core_exp_dep_srcs ${app_sources}) ulp_embed_binary(lp_core_test_app "${lp_core_sources}" "${lp_core_exp_dep_srcs}") ulp_embed_binary(lp_core_test_app_counter "${lp_core_sources_counter}" "${lp_core_exp_dep_srcs}") +ulp_embed_binary(lp_core_test_app_isr "lp_core/test_main_isr.c" "${lp_core_exp_dep_srcs}") if(CONFIG_SOC_LP_TIMER_SUPPORTED) ulp_embed_binary(lp_core_test_app_set_timer_wakeup "${lp_core_sources_set_timer_wakeup}" "${lp_core_exp_dep_srcs}") @@ -36,3 +50,8 @@ ulp_embed_binary(lp_core_test_app_gpio "${lp_core_sources_gpio}" "${lp_core_exp_ if(CONFIG_SOC_LP_I2C_SUPPORTED) ulp_embed_binary(lp_core_test_app_i2c "${lp_core_sources_i2c}" "${lp_core_exp_dep_srcs}") endif() + +if(CONFIG_SOC_LP_SPI_SUPPORTED) + ulp_embed_binary(lp_core_test_app_spi_master "${lp_core_sources_spi_master}" "${lp_core_exp_dep_srcs}") + ulp_embed_binary(lp_core_test_app_spi_slave "${lp_core_sources_spi_slave}" "${lp_core_exp_dep_srcs}") +endif() diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main.c similarity index 96% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main.c index beff51564c41..b9adad2670f9 100644 --- a/components/ulp/test_apps/lp_core/main/lp_core/test_main.c +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main.c @@ -71,11 +71,9 @@ void handle_commands(lp_core_test_commands_t cmd) break; case LP_CORE_NO_COMMAND: - main_cpu_reply = LP_CORE_COMMAND_NOK; break; default: - main_cpu_reply = LP_CORE_COMMAND_NOK; break; } } diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_counter.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_counter.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_counter.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_counter.c diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_gpio.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_gpio.c similarity index 90% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_gpio.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_gpio.c index 4d5b09f7b661..53e71fc19c9d 100644 --- a/components/ulp/test_apps/lp_core/main/lp_core/test_main_gpio.c +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_gpio.c @@ -20,12 +20,15 @@ int main(void) ulp_lp_core_gpio_output_enable(LP_IO_NUM_0); ulp_lp_core_gpio_set_level(LP_IO_NUM_0, 0); + ulp_lp_core_delay_us(100); gpio_test_succeeded = (ulp_lp_core_gpio_get_level(LP_IO_NUM_0) == 0); ulp_lp_core_gpio_set_level(LP_IO_NUM_0, 1); + ulp_lp_core_delay_us(100); gpio_test_succeeded &= (ulp_lp_core_gpio_get_level(LP_IO_NUM_0) == 1); ulp_lp_core_gpio_set_level(LP_IO_NUM_0, 0); + ulp_lp_core_delay_us(100); gpio_test_succeeded &= (ulp_lp_core_gpio_get_level(LP_IO_NUM_0) == 0); gpio_test_finished = 1; diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_i2c.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_i2c.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_i2c.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_i2c.c diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_isr.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_isr.c new file mode 100644 index 000000000000..c3cc33c91060 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_isr.c @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "ulp_lp_core_utils.h" +#include "ulp_lp_core_interrupts.h" +#include "ulp_lp_core_gpio.h" +#include "hal/pmu_ll.h" + +volatile uint32_t io_isr_counter = 0; +volatile uint32_t pmu_isr_counter = 0; +volatile bool isr_test_started; + +void LP_CORE_ISR_ATTR ulp_lp_core_lp_io_intr_handler(void) +{ + ulp_lp_core_gpio_clear_intr_status(); + io_isr_counter++; +} + +void LP_CORE_ISR_ATTR ulp_lp_core_lp_pmu_intr_handler(void) +{ + ulp_lp_core_sw_intr_clear(); + pmu_isr_counter++; +} + +int main(void) +{ + ulp_lp_core_sw_intr_enable(true); + + ulp_lp_core_intr_enable(); + + isr_test_started = true; + + while (1) { + // Busy wait for the interrupts to occur + } + + return 0; +} diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_main_set_timer_wakeup.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_set_timer_wakeup.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/lp_core/test_main_set_timer_wakeup.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_set_timer_wakeup.c diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_master.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_master.c new file mode 100644 index 000000000000..f7872dbcfc5b --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_master.c @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "ulp_lp_core_spi.h" +#include "test_shared.h" + +volatile lp_core_test_commands_t spi_test_cmd = LP_CORE_NO_COMMAND; + +volatile uint8_t spi_master_tx_buf[100] = {0}; +volatile uint8_t spi_master_rx_buf[100] = {0}; +volatile uint32_t spi_tx_len = 0; + +int main(void) +{ + /* Wait for the HP core to start the test */ + while (spi_test_cmd == LP_CORE_NO_COMMAND) { + + } + + /* Setup SPI transaction */ + lp_spi_transaction_t trans_desc = { + .tx_length = spi_tx_len, + .rx_length = spi_tx_len, + .tx_buffer = (uint8_t *)spi_master_tx_buf, + .rx_buffer = (uint8_t *)spi_master_rx_buf, + }; + + /* Transmit data */ + lp_core_lp_spi_master_transfer(&trans_desc, -1); + + /* Synchronize with the HP core running the test */ + spi_test_cmd = LP_CORE_NO_COMMAND; + + return 0; +} diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_slave.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_slave.c new file mode 100644 index 000000000000..81b208295e5e --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_spi_slave.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "ulp_lp_core_spi.h" +#include "test_shared.h" + +volatile lp_core_test_command_reply_t spi_test_cmd_reply = LP_CORE_COMMAND_NOK; + +volatile uint8_t spi_slave_tx_buf[100] = {0}; +volatile uint8_t spi_slave_rx_buf[100] = {0}; +volatile uint32_t spi_rx_len = 0; + +int main(void) +{ + /* Setup SPI transaction */ + lp_spi_transaction_t trans_desc = { + .rx_length = spi_rx_len, + .rx_buffer = (uint8_t *)spi_slave_rx_buf, + .tx_buffer = NULL, + }; + + /* Receive data */ + lp_core_lp_spi_slave_transfer(&trans_desc, -1); + + /* Synchronize with the HP core running the test */ + spi_test_cmd_reply = LP_CORE_COMMAND_OK; + + return 0; +} diff --git a/components/ulp/test_apps/lp_core/main/lp_core/test_shared.h b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_shared.h similarity index 95% rename from components/ulp/test_apps/lp_core/main/lp_core/test_shared.h rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_shared.h index 7497ff4e6cbc..b044c34b483c 100644 --- a/components/ulp/test_apps/lp_core/main/lp_core/test_shared.h +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_shared.h @@ -17,6 +17,7 @@ typedef enum { LP_CORE_DELAY_TEST, LP_CORE_DEEP_SLEEP_WAKEUP_SHORT_DELAY_TEST, LP_CORE_DEEP_SLEEP_WAKEUP_LONG_DELAY_TEST, + LP_CORE_LP_SPI_WRITE_READ_TEST, LP_CORE_NO_COMMAND, } lp_core_test_commands_t; diff --git a/components/ulp/test_apps/lp_core/main/test_app_main.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_app_main.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/test_app_main.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_app_main.c diff --git a/components/ulp/test_apps/lp_core/main/test_lp_core.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core.c similarity index 86% rename from components/ulp/test_apps/lp_core/main/test_lp_core.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core.c index e27febe2e60a..a659b9337912 100644 --- a/components/ulp/test_apps/lp_core/main/test_lp_core.c +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core.c @@ -8,9 +8,11 @@ #include #include #include "soc/soc_caps.h" +#include "soc/gpio_num.h" #include "esp_rom_caps.h" #include "lp_core_test_app.h" #include "lp_core_test_app_counter.h" +#include "lp_core_test_app_isr.h" #if SOC_LP_TIMER_SUPPORTED #include "lp_core_test_app_set_timer_wakeup.h" @@ -23,9 +25,14 @@ #include "unity.h" #include "esp_sleep.h" #include "esp_timer.h" +#include "driver/rtc_io.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "hal/lp_core_ll.h" +#include "hal/rtc_io_ll.h" +#include "driver/rtc_io.h" + extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_test_app_bin_start"); extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_test_app_bin_end"); @@ -38,6 +45,9 @@ extern const uint8_t lp_core_main_set_timer_wakeup_bin_end[] asm("_binary_lp_c extern const uint8_t lp_core_main_gpio_bin_start[] asm("_binary_lp_core_test_app_gpio_bin_start"); extern const uint8_t lp_core_main_gpio_bin_end[] asm("_binary_lp_core_test_app_gpio_bin_end"); +extern const uint8_t lp_core_main_isr_bin_start[] asm("_binary_lp_core_test_app_isr_bin_start"); +extern const uint8_t lp_core_main_isr_bin_end[] asm("_binary_lp_core_test_app_isr_bin_end"); + static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_t* firmware_start, const uint8_t* firmware_end) { TEST_ASSERT(ulp_lp_core_load_binary(firmware_start, @@ -47,6 +57,12 @@ static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_ } +static void clear_test_cmds(void) +{ + ulp_main_cpu_command = LP_CORE_NO_COMMAND; + ulp_command_resp = LP_CORE_NO_COMMAND; +} + TEST_CASE("LP core and main CPU are able to exchange data", "[lp_core]") { const uint32_t test_data = 0x12345678; @@ -76,9 +92,7 @@ TEST_CASE("LP core and main CPU are able to exchange data", "[lp_core]") printf("data out: 0x%" PRIx32 ", expected: 0x%" PRIx32 " \n", ulp_test_data_out, test_data); TEST_ASSERT(test_data == ulp_test_data_out); - /* Clear test data */ - ulp_main_cpu_command = LP_CORE_NO_COMMAND; - ulp_command_resp = LP_CORE_NO_COMMAND; + clear_test_cmds(); } TEST_CASE("Test LP core delay", "[lp_core]") @@ -113,9 +127,7 @@ TEST_CASE("Test LP core delay", "[lp_core]") printf("Waited for %" PRIi64 "us, expected: %" PRIi32 "us\n", diff, delay_period_us); TEST_ASSERT_INT_WITHIN(delta_us, delay_period_us, diff); - /* Clear test data */ - ulp_main_cpu_command = LP_CORE_NO_COMMAND; - ulp_command_resp = LP_CORE_NO_COMMAND; + clear_test_cmds(); } #define LP_TIMER_TEST_DURATION_S (5) @@ -210,6 +222,8 @@ static void check_reset_reason_and_sleep_duration(void) printf("CPU slept for %"PRIi64" ms, expected it to sleep approx %"PRIi64" ms\n", sleep_duration, expected_sleep_duration_ms); /* Rough estimate, as CPU spends quite some time waking up, but will test if lp core is waking up way too often etc */ TEST_ASSERT_INT_WITHIN_MESSAGE(1000, expected_sleep_duration_ms, sleep_duration, "LP Core did not wake up the expected number of times"); + + clear_test_cmds(); } TEST_CASE_MULTIPLE_STAGES("LP Timer can wakeup lp core periodically during deep sleep", "[ulp]", @@ -316,6 +330,7 @@ TEST_CASE("LP core gpio tests", "[ulp]") .lp_timer_sleep_duration_us = LP_TIMER_TEST_SLEEP_DURATION_US, }; + rtc_gpio_init(GPIO_NUM_0); load_and_start_lp_core_firmware(&cfg, lp_core_main_gpio_bin_start, lp_core_main_gpio_bin_end); while (!ulp_gpio_test_finished) { @@ -325,3 +340,49 @@ TEST_CASE("LP core gpio tests", "[ulp]") } #endif //SOC_LP_TIMER_SUPPORTED + +#define ISR_TEST_ITERATIONS 100 +#define IO_TEST_PIN 0 +#include "lp_core_uart.h" + +TEST_CASE("LP core ISR tests", "[ulp]") +{ + lp_core_uart_cfg_t ucfg = LP_CORE_UART_DEFAULT_CONFIG(); + + ESP_ERROR_CHECK(lp_core_uart_init(&ucfg)); + + /* Load ULP firmware and start the coprocessor */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + + load_and_start_lp_core_firmware(&cfg, lp_core_main_isr_bin_start, lp_core_main_isr_bin_end); + + while (!ulp_isr_test_started) { + } + + for (int i = 0; i < ISR_TEST_ITERATIONS; i++) { + lp_core_ll_hp_wake_lp(); + vTaskDelay(pdMS_TO_TICKS(10)); + } + + printf("ULP PMU ISR triggered %"PRIu32" times\n", ulp_pmu_isr_counter); + TEST_ASSERT_EQUAL(ISR_TEST_ITERATIONS, ulp_pmu_isr_counter); + + /* Test LP IO interrupt */ + rtc_gpio_init(IO_TEST_PIN); + rtc_gpio_set_direction(IO_TEST_PIN, RTC_GPIO_MODE_INPUT_ONLY); + TEST_ASSERT_EQUAL(0, ulp_io_isr_counter); + + for (int i = 0; i < ISR_TEST_ITERATIONS; i++) { +#if CONFIG_IDF_TARGET_ESP32C6 + LP_IO.status_w1ts.val = 0x00000001; // Set GPIO 0 intr status to high +#else + LP_GPIO.status_w1ts.val = 0x00000001; // Set GPIO 0 intr status to high +#endif + vTaskDelay(pdMS_TO_TICKS(10)); + } + + printf("ULP LP IO ISR triggered %"PRIu32" times\n", ulp_io_isr_counter); + TEST_ASSERT_EQUAL(ISR_TEST_ITERATIONS, ulp_io_isr_counter); +} diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_etm.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_etm.c new file mode 100644 index 000000000000..4e640ac0f5e5 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_etm.c @@ -0,0 +1,130 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "lp_core_test_app_counter.h" +#include "ulp_lp_core.h" +#include "test_shared.h" +#include "unity.h" +#include "test_utils.h" +#include "esp_log.h" +#include "driver/gptimer.h" +#include "lp_core_etm.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +extern const uint8_t lp_core_main_counter_bin_start[] asm("_binary_lp_core_test_app_counter_bin_start"); +extern const uint8_t lp_core_main_counter_bin_end[] asm("_binary_lp_core_test_app_counter_bin_end"); + +static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_t* firmware_start, const uint8_t* firmware_end) +{ + TEST_ASSERT(ulp_lp_core_load_binary(firmware_start, + (firmware_end - firmware_start)) == ESP_OK); + + TEST_ASSERT(ulp_lp_core_run(cfg) == ESP_OK); + +} + +#define STOP_TEST_ITERATIONS 50 +#define TIMER_PERIOD_MS 10 + +static int timer_cb_count; + +static bool on_gptimer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) +{ + timer_cb_count++; + if (timer_cb_count >= STOP_TEST_ITERATIONS) { + gptimer_stop(timer); + } + return false; +} + +/** + * @brief Test connects ULP wakeup source to a GP timer alarm ETM event. + * At every wakeup the ULP program increments a counter and in the + * end we check that the ULP woke-up the expected number of times. + */ +TEST_CASE("LP core can be woken up by ETM event", "[ulp]") +{ + // GPTimer alarm ---> ETM channel A ---> ULP wake-up + printf("allocate etm channel\r\n"); + esp_etm_channel_config_t etm_config = {}; + esp_etm_channel_handle_t etm_channel_a; + TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_a)); + + esp_etm_task_handle_t lp_core_task = NULL; + + lp_core_etm_task_config_t lp_core_task_config = { + .task_type = LP_CORE_TASK_WAKEUP_CPU, + }; + TEST_ESP_OK(lp_core_new_etm_task(&lp_core_task_config, &lp_core_task)); + + printf("create a gptimer\r\n"); + gptimer_handle_t gptimer = NULL; + gptimer_config_t timer_config = { + .clk_src = GPTIMER_CLK_SRC_DEFAULT, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 1 * 1000 * 1000, // 1MHz, 1 tick = 1us + }; + TEST_ESP_OK(gptimer_new_timer(&timer_config, &gptimer)); + + printf("get gptimer etm event handle\r\n"); + esp_etm_event_handle_t gptimer_event = NULL; + gptimer_etm_event_config_t gptimer_etm_event_conf = { + .event_type = GPTIMER_ETM_EVENT_ALARM_MATCH, + }; + TEST_ESP_OK(gptimer_new_etm_event(gptimer, &gptimer_etm_event_conf, &gptimer_event)); + + printf("connect event and task to the channel\r\n"); + TEST_ESP_OK(esp_etm_channel_connect(etm_channel_a, gptimer_event, lp_core_task)); + + printf("enable etm channel\r\n"); + TEST_ESP_OK(esp_etm_channel_enable(etm_channel_a)); + + printf("set timer alarm action\r\n"); + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, + .alarm_count = TIMER_PERIOD_MS * 1000, // 10ms per alarm event + .flags.auto_reload_on_alarm = true, + }; + TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config)); + + printf("register alarm callback\r\n"); + gptimer_event_callbacks_t cbs = { + .on_alarm = on_gptimer_alarm_cb, + }; + TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, NULL)); + + /* Load ULP firmware and start the coprocessor */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_ETM, +#if ESP_ROM_HAS_LP_ROM + .skip_lp_rom_boot = true, +#endif //ESP_ROM_HAS_LP_ROM + }; + + load_and_start_lp_core_firmware(&cfg, lp_core_main_counter_bin_start, lp_core_main_counter_bin_end); + + printf("enable and start timer\r\n"); + TEST_ESP_OK(gptimer_enable(gptimer)); + TEST_ESP_OK(gptimer_start(gptimer)); + + // Wait for more than the expected time for the test to complete + // To ensure that the ULP ran exactly as many times as we expected + vTaskDelay((TIMER_PERIOD_MS * STOP_TEST_ITERATIONS * 2) / portTICK_PERIOD_MS); + + TEST_ASSERT_EQUAL(STOP_TEST_ITERATIONS, timer_cb_count); + TEST_ASSERT_EQUAL(STOP_TEST_ITERATIONS, ulp_counter); + + TEST_ESP_OK(gptimer_disable(gptimer)); + TEST_ESP_OK(gptimer_del_timer(gptimer)); + + TEST_ESP_OK(esp_etm_del_task(lp_core_task)); + TEST_ESP_OK(esp_etm_del_event(gptimer_event)); + TEST_ESP_OK(esp_etm_channel_disable(etm_channel_a)); + TEST_ESP_OK(esp_etm_del_channel(etm_channel_a)); +} diff --git a/components/ulp/test_apps/lp_core/main/test_lp_core_i2c.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_i2c.c similarity index 100% rename from components/ulp/test_apps/lp_core/main/test_lp_core_i2c.c rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_i2c.c diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_spi.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_spi.c new file mode 100644 index 000000000000..b23e99bd0997 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core_spi.c @@ -0,0 +1,254 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "lp_core_test_app_spi_master.h" +#include "lp_core_test_app_spi_slave.h" +#include "ulp_lp_core.h" +#include "lp_core_spi.h" +#include "unity.h" +#include "test_utils.h" +#include "esp_log.h" +#include "test_shared.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +extern const uint8_t lp_core_main_spi_master_bin_start[] asm("_binary_lp_core_test_app_spi_master_bin_start"); +extern const uint8_t lp_core_main_spi_master_bin_end[] asm("_binary_lp_core_test_app_spi_master_bin_end"); +extern const uint8_t lp_core_main_spi_slave_bin_start[] asm("_binary_lp_core_test_app_spi_slave_bin_start"); +extern const uint8_t lp_core_main_spi_slave_bin_end[] asm("_binary_lp_core_test_app_spi_slave_bin_end"); + +static const char* TAG = "lp_core_spi_test"; + +#define TEST_GPIO_PIN_MISO 6 +#define TEST_GPIO_PIN_MOSI 7 +#define TEST_GPIO_PIN_CLK 8 +#define TEST_GPIO_PIN_CS 4 + +#define TEST_DATA_LEN_BYTES 42 +uint8_t expected_data[100] = {0}; + +static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_t* firmware_start, const uint8_t* firmware_end) +{ + TEST_ASSERT(ulp_lp_core_load_binary(firmware_start, (firmware_end - firmware_start)) == ESP_OK); + TEST_ASSERT(ulp_lp_core_run(cfg) == ESP_OK); +} + +static void setup_test_data(void) +{ + uint8_t *tx_data = (uint8_t *)&ulp_spi_master_tx_buf; + ulp_spi_tx_len = TEST_DATA_LEN_BYTES; + + /* Setup test data */ + for (int i = 0; i < ulp_spi_tx_len; i++) { + tx_data[i] = (i + 1) % 256; + expected_data[i] = tx_data[i]; + } +} + +static void setup_expected_data(void) +{ + ulp_spi_rx_len = TEST_DATA_LEN_BYTES; + + /* Setup expected data */ + for (int i = 0; i < TEST_DATA_LEN_BYTES; i++) { + expected_data[i] = (i + 1) % 256; + } +} + +/* Base LP SPI bus settings */ +lp_spi_host_t host_id = 0; +lp_spi_bus_config_t bus_config = { + .miso_io_num = TEST_GPIO_PIN_MISO, + .mosi_io_num = TEST_GPIO_PIN_MOSI, + .sclk_io_num = TEST_GPIO_PIN_CLK, +}; + +/* Base LP SPI device settings */ +lp_spi_device_config_t device = { + .cs_io_num = TEST_GPIO_PIN_CS, + .spi_mode = 0, + .clock_speed_hz = 10 * 1000, // 10 MHz + .duty_cycle = 128, // 50% duty cycle +}; + +/* Base LP SPI slave device settings */ +lp_spi_slave_config_t slv_device = { + .cs_io_num = TEST_GPIO_PIN_CS, + .spi_mode = 0, +}; + +static void lp_spi_master_init(int spi_flags, bool setup_master_loop_back) +{ + /* Initialize LP SPI bus */ + /* Setup loop back for tests which do not use an LP SPI slave for looping back the data. */ + bus_config.miso_io_num = setup_master_loop_back ? TEST_GPIO_PIN_MOSI : TEST_GPIO_PIN_MISO; + TEST_ASSERT(lp_core_lp_spi_bus_initialize(host_id, &bus_config) == ESP_OK); + + /* Add LP SPI device */ + device.flags = spi_flags; + TEST_ASSERT(lp_core_lp_spi_bus_add_device(host_id, &device) == ESP_OK); +} + +static void lp_spi_slave_init(int spi_flags) +{ + /* Initialize LP SPI bus */ + TEST_ASSERT(lp_core_lp_spi_bus_initialize(host_id, &bus_config) == ESP_OK); + + /* Add LP SPI slave device */ + if (spi_flags != 0) { + slv_device.flags = spi_flags; + } + TEST_ASSERT(lp_core_lp_spi_slave_initialize(host_id, &slv_device) == ESP_OK); +} + +static void lp_spi_master_execute_test(bool wait_for_slave_ready) +{ + /* Load and run the LP core firmware */ + ulp_lp_core_cfg_t lp_cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + load_and_start_lp_core_firmware(&lp_cfg, lp_core_main_spi_master_bin_start, lp_core_main_spi_master_bin_end); + + if (wait_for_slave_ready) { + /* Wait for the HP SPI device to be initialized */ + unity_wait_for_signal("LP SPI slave ready"); + } + + /* Setup test data */ + setup_test_data(); + + /* Start the test */ + ulp_spi_test_cmd = LP_CORE_LP_SPI_WRITE_READ_TEST; + + while (ulp_spi_test_cmd != LP_CORE_NO_COMMAND) { + /* Wait for the test to complete */ + vTaskDelay(1); + } + + /* Verify the received data if we expect the data to be looped back from the LP SPI slave */ + uint8_t *rx_data = (uint8_t *)&ulp_spi_master_rx_buf; + for (int i = 0; i < TEST_DATA_LEN_BYTES; i++) { + ESP_LOGI(TAG, "LP SPI master received data: 0x%02x", rx_data[i]); + } + + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, rx_data, ulp_spi_tx_len); +} + +static void lp_spi_slave_execute_test(void) +{ + /* Load and run the LP core firmware */ + ulp_lp_core_cfg_t lp_cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + load_and_start_lp_core_firmware(&lp_cfg, lp_core_main_spi_slave_bin_start, lp_core_main_spi_slave_bin_end); + + /* Setup expected test data */ + setup_expected_data(); + + /* Send signal to LP SPI master */ + unity_send_signal("LP SPI slave ready"); + + /* Wait for the test to complete */ + while (ulp_spi_test_cmd_reply != LP_CORE_COMMAND_OK) { + vTaskDelay(1); + } + + /* Verify the received data */ + uint8_t *rx_data = (uint8_t *)&ulp_spi_slave_rx_buf; + for (int i = 0; i < TEST_DATA_LEN_BYTES; i++) { + ESP_LOGI(TAG, "LP SPI slave received data: 0x%02x", rx_data[i]); + } + + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, rx_data, TEST_DATA_LEN_BYTES); +} + +void test_lp_spi_master(void) +{ + /* Initialize LP SPI in master mode */ + lp_spi_master_init(0, false); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(true); +} + +void test_lp_spi_slave(void) +{ + /* Initialize LP SPI in slave mode */ + lp_spi_slave_init(0); + + /* Start the LP SPI slave test */ + lp_spi_slave_execute_test(); +} +void test_lp_spi_master_3wire(void) +{ + /* Initialize LP SPI in master mode */ + int spi_flags = LP_SPI_DEVICE_3WIRE; + lp_spi_master_init(spi_flags, false); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(true); +} + +void test_lp_spi_slave_3wire(void) +{ + /* Initialize LP SPI in slave mode */ + int spi_flags = LP_SPI_DEVICE_3WIRE; + lp_spi_slave_init(spi_flags); + + /* Start the LP SPI slave test */ + lp_spi_slave_execute_test(); +} + +void test_lp_spi_master_lsbfirst(void) +{ + /* Initialize LP SPI in master mode */ + int spi_flags = LP_SPI_DEVICE_BIT_LSBFIRST; + lp_spi_master_init(spi_flags, false); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(true); +} + +void test_lp_spi_slave_lsbfirst(void) +{ + /* Initialize LP SPI in slave mode */ + int spi_flags = LP_SPI_DEVICE_BIT_LSBFIRST; + lp_spi_slave_init(spi_flags); + + /* Start the LP SPI slave test */ + lp_spi_slave_execute_test(); +} + +/* Test LP-SPI master loopback */ +TEST_CASE("LP-Core LP-SPI master loopback test", "[lp_core]") +{ + /* Initialize LP SPI in master mode */ + lp_spi_master_init(0, true); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(false); +} + +/* Test LP-SPI master loopback with active low CS line */ +TEST_CASE("LP-Core LP-SPI master loopback test with active high CS line", "[lp_core]") +{ + /* Initialize LP SPI in master mode */ + int spi_flags = LP_SPI_DEVICE_CS_ACTIVE_HIGH; + lp_spi_master_init(spi_flags, true); + + /* Start the LP SPI master test */ + lp_spi_master_execute_test(false); +} + +/* Test LP-SPI master and LP-SPI slave communication */ +TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-SPI master and LP-SPI slave read write test", "[lp_core_spi][test_env=generic_multi_device][timeout=150]", test_lp_spi_master, test_lp_spi_slave); + +/* Test LP-SPI master in 3-Wire SPI mode */ +TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-SPI master and LP-SPI slave in 3-Wire SPI mode", "[lp_core_spi][test_env=generic_multi_device][timeout=150]", test_lp_spi_master_3wire, test_lp_spi_slave_3wire); + +/* Test LP-SPI master and LP-SPI slave in LSB first mode */ +TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-SPI master and LP-SPI in LSB first SPI mode", "[lp_core_spi][test_env=generic_multi_device][timeout=150]", test_lp_spi_master_lsbfirst, test_lp_spi_slave_lsbfirst); diff --git a/components/ulp/test_apps/lp_core/pytest_lp_core.py b/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py similarity index 91% rename from components/ulp/test_apps/lp_core/pytest_lp_core.py rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py index 24fdcd3bdfef..dc2233f81349 100644 --- a/components/ulp/test_apps/lp_core/pytest_lp_core.py +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut diff --git a/components/ulp/test_apps/lp_core/sdkconfig.ci.default b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.default similarity index 100% rename from components/ulp/test_apps/lp_core/sdkconfig.ci.default rename to components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.default diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.defaults b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.defaults new file mode 100644 index 000000000000..c7626f473328 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.defaults @@ -0,0 +1,6 @@ +CONFIG_ESP_TASK_WDT_INIT=n + +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y +CONFIG_ULP_COPROC_RESERVE_MEM=12000 +CONFIG_ULP_PANIC_OUTPUT_ENABLE=y diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_hp_uart/CMakeLists.txt new file mode 100644 index 000000000000..2c8bfb986121 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/CMakeLists.txt @@ -0,0 +1,14 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +list(PREPEND SDKCONFIG_DEFAULTS "$ENV{IDF_PATH}/tools/test_apps/configs/sdkconfig.debug_helpers" "sdkconfig.defaults") + +set(EXTRA_COMPONENT_DIRS + "$ENV{IDF_PATH}/tools/unit-test-app/components" +) + +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(lp_core_hp_uart_test) diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/README.md b/components/ulp/test_apps/lp_core/lp_core_hp_uart/README.md new file mode 100644 index 000000000000..b38644435588 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/README.md @@ -0,0 +1,3 @@ +| Supported Targets | ESP32-C6 | ESP32-P4 | +| ----------------- | -------- | -------- | + diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/CMakeLists.txt new file mode 100644 index 000000000000..d70b7ede3a1b --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/CMakeLists.txt @@ -0,0 +1,13 @@ +set(app_sources "test_app_main.c" "test_lp_core.c") +set(lp_core_sources "lp_core/test_hello_main.c") +set(lp_core_sources_shared_mem "lp_core/test_shared_mem_main.c") + +idf_component_register(SRCS ${app_sources} + INCLUDE_DIRS "lp_core" + REQUIRES ulp unity esp_timer test_utils + WHOLE_ARCHIVE) + +set(lp_core_exp_dep_srcs ${app_sources}) + +ulp_embed_binary(lp_core_test_app "${lp_core_sources}" "${lp_core_exp_dep_srcs}") +ulp_embed_binary(lp_core_test_app_shared_mem "${lp_core_sources_shared_mem}" "${lp_core_exp_dep_srcs}") diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_hello_main.c b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_hello_main.c new file mode 100644 index 000000000000..3c844cec7dfd --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_hello_main.c @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "ulp_lp_core_print.h" + +int main(void) +{ + lp_core_printf("Hello, World!\n"); + + return 0; +} diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_shared.h b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_shared.h new file mode 100644 index 000000000000..17571e195c2f --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_shared.h @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#pragma once + +#define SHARED_MEM_INIT_VALUE 0xEE +#define SHARED_MEM_END_VALUE 0xAA diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_shared_mem_main.c b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_shared_mem_main.c new file mode 100644 index 000000000000..c37c83962c38 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/lp_core/test_shared_mem_main.c @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "ulp_lp_core_print.h" +#include "ulp_lp_core_memory_shared.h" +#include "test_shared.h" + +int main(void) +{ + ulp_lp_core_memory_shared_cfg_t *shared_cfg = ulp_lp_core_memory_shared_cfg_get(); + lp_core_printf("ULP shared memory address: %p\n", shared_cfg); + + volatile uint8_t* shared_mem = (uint8_t*)shared_cfg; + for (int i = 0; i < sizeof(ulp_lp_core_memory_shared_cfg_t); i++) { + if (shared_mem[i] != SHARED_MEM_INIT_VALUE) { + lp_core_printf("Test failed: expected %X, got %X at %d\n", SHARED_MEM_INIT_VALUE, shared_mem[i], i); + return 0; + } + } + + for (int i = 0; i < sizeof(ulp_lp_core_memory_shared_cfg_t); i++) { + shared_mem[i] = SHARED_MEM_END_VALUE; + } + + lp_core_printf("ULP shared memory test passed\n"); + + return 0; +} diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_app_main.c b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_app_main.c new file mode 100644 index 000000000000..d8a9a98ccc0e --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_app_main.c @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in the sleep code, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-500) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_lp_core.c b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_lp_core.c new file mode 100644 index 000000000000..04644bc78df9 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/main/test_lp_core.c @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "sdkconfig.h" +#include "unity.h" +#include "soc/soc_caps.h" +#include "esp_rom_caps.h" +#include "lp_core_test_app.h" +#include "ulp_lp_core.h" +#include "ulp_lp_core_memory_shared.h" +#include "test_shared.h" + +extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_test_app_bin_start"); +extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_test_app_bin_end"); + +extern const uint8_t lp_core_shared_mem_bin_start[] asm("_binary_lp_core_test_app_shared_mem_bin_start"); +extern const uint8_t lp_core_shared_mem_bin_end[] asm("_binary_lp_core_test_app_shared_mem_bin_end"); + +static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_t* firmware_start, const uint8_t* firmware_end) +{ + TEST_ASSERT(ulp_lp_core_load_binary(firmware_start, + (firmware_end - firmware_start)) == ESP_OK); + + TEST_ASSERT(ulp_lp_core_run(cfg) == ESP_OK); + +} + +TEST_CASE("lp-print can output to hp-uart", "[lp_core]") +{ + /* Load ULP firmware and start the coprocessor */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + + load_and_start_lp_core_firmware(&cfg, lp_core_main_bin_start, lp_core_main_bin_end); + + // Actual test output on UART is checked by pytest, not unity test-case + // We simply wait to allow the lp-core to run once + vTaskDelay(1000 / portTICK_PERIOD_MS); +} + +TEST_CASE("LP-Core Shared-mem", "[lp_core]") +{ + /* Load ULP firmware and start the coprocessor */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + + TEST_ASSERT(ulp_lp_core_load_binary(lp_core_shared_mem_bin_start, (lp_core_shared_mem_bin_end - lp_core_shared_mem_bin_start)) == ESP_OK); + + printf("HP shared memory address: %p\n", ulp_lp_core_memory_shared_cfg_get()); + + volatile uint8_t* shared_mem = (uint8_t*)ulp_lp_core_memory_shared_cfg_get(); + for (int i = 0; i < sizeof(ulp_lp_core_memory_shared_cfg_t); i++) { + shared_mem[i] = SHARED_MEM_INIT_VALUE; + } + + TEST_ASSERT(ulp_lp_core_run(&cfg) == ESP_OK); + // Actual test output on UART is checked by pytest, not unity test-case + // We simply wait to allow the lp-core to run once + vTaskDelay(1000 / portTICK_PERIOD_MS); + + // Check that ULP set the shared memory to 0xAA, and it did not get overwritten by anything + for (int i = 0; i < sizeof(ulp_lp_core_memory_shared_cfg_t); i++) { + TEST_ASSERT_EQUAL(SHARED_MEM_END_VALUE, shared_mem[i]); + } + + printf("HP shared memory test passed\n"); +} diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py b/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py new file mode 100644 index 000000000000..28fbb57f694f --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32c6 +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_lp_core_hp_uart_print(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('"lp-print can output to hp-uart"') + dut.expect_exact('Hello, World!') + + +@pytest.mark.esp32c6 +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_lp_core_shared_mem(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('"LP-Core Shared-mem"') + + result = dut.expect(r'HP shared memory address: (0x[0-9a-fA-F]+)') + hp_addr = result[1] + + result = dut.expect(r'ULP shared memory address: (0x[0-9a-fA-F]+)') + ulp_addr = result[1] + + assert ulp_addr == hp_addr + + dut.expect_exact('ULP shared memory test passed') + dut.expect_exact('HP shared memory test passed') diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.ci.default b/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.ci.default new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.defaults b/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.defaults new file mode 100644 index 000000000000..e3c08c60fa94 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/sdkconfig.defaults @@ -0,0 +1,7 @@ +CONFIG_ESP_TASK_WDT_INIT=n + +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y +CONFIG_ULP_COPROC_RESERVE_MEM=12000 +CONFIG_ULP_PANIC_OUTPUT_ENABLE=y +CONFIG_ULP_HP_UART_CONSOLE_PRINT=y diff --git a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_gpio.h b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_gpio.h index 11e486c2f6d2..504b2e0c9138 100644 --- a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_gpio.h +++ b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_gpio.h @@ -109,7 +109,7 @@ static inline uint8_t ulp_riscv_gpio_get_level(gpio_num_t gpio_num) static inline void ulp_riscv_gpio_set_output_mode(gpio_num_t gpio_num, rtc_io_out_mode_t mode) { - REG_SET_FIELD(RTC_IO_TOUCH_PAD0_REG + gpio_num * 4, RTC_IO_TOUCH_PAD0_DRV, mode); + REG_SET_FIELD(RTC_GPIO_PIN0_REG + gpio_num * 4, RTC_GPIO_PIN0_PAD_DRIVER, mode); } static inline void ulp_riscv_gpio_pullup(gpio_num_t gpio_num) diff --git a/components/ulp/ulp_riscv/ulp_riscv_i2c.c b/components/ulp/ulp_riscv/ulp_riscv_i2c.c index a56be4c1bd26..138d479642a9 100644 --- a/components/ulp/ulp_riscv/ulp_riscv_i2c.c +++ b/components/ulp/ulp_riscv/ulp_riscv_i2c.c @@ -47,6 +47,9 @@ rtc_io_dev_t *rtc_io_dev = &RTCIO; /* Read/Write timeout (number of iterations)*/ #define ULP_RISCV_I2C_RW_TIMEOUT CONFIG_ULP_RISCV_I2C_RW_TIMEOUT +/* RTC I2C lock */ +static portMUX_TYPE rtc_i2c_lock = portMUX_INITIALIZER_UNLOCKED; + static esp_err_t i2c_gpio_is_cfg_valid(gpio_num_t sda_io_num, gpio_num_t scl_io_num) { /* Verify that the SDA and SCL GPIOs are valid RTC I2C io pins */ @@ -69,6 +72,8 @@ static esp_err_t i2c_gpio_is_cfg_valid(gpio_num_t sda_io_num, gpio_num_t scl_io_ static esp_err_t i2c_configure_io(gpio_num_t io_num, bool pullup_en) { + /* Set the IO pin to high to avoid them from toggling from Low to High state during initialization. This can register a spurious I2C start condition. */ + ESP_RETURN_ON_ERROR(rtc_gpio_set_level(io_num, 1), RTCI2C_TAG, "RTC GPIO failed to set level to high for %d", io_num); /* Initialize IO Pin */ ESP_RETURN_ON_ERROR(rtc_gpio_init(io_num), RTCI2C_TAG, "RTC GPIO Init failed for GPIO %d", io_num); /* Set direction to input+output */ @@ -95,12 +100,16 @@ static esp_err_t i2c_set_pin(const ulp_riscv_i2c_cfg_t *cfg) /* Verify that the I2C GPIOs are valid */ ESP_RETURN_ON_ERROR(i2c_gpio_is_cfg_valid(sda_io_num, scl_io_num), RTCI2C_TAG, "RTC I2C GPIO config invalid"); - /* Initialize SDA Pin */ - ESP_RETURN_ON_ERROR(i2c_configure_io(sda_io_num, sda_pullup_en), RTCI2C_TAG, "RTC I2C SDA pin config failed"); + // NOTE: We always initialize the SCL pin first, then the SDA pin. + // This order of initialization is important to avoid any spurious + // I2C start conditions on the bus. /* Initialize SCL Pin */ ESP_RETURN_ON_ERROR(i2c_configure_io(scl_io_num, scl_pullup_en), RTCI2C_TAG, "RTC I2C SCL pin config failed"); + /* Initialize SDA Pin */ + ESP_RETURN_ON_ERROR(i2c_configure_io(sda_io_num, sda_pullup_en), RTCI2C_TAG, "RTC I2C SDA pin config failed"); + /* Route SDA IO signal to the RTC subsystem */ rtc_io_dev->touch_pad[sda_io_num].mux_sel = 1; @@ -348,6 +357,8 @@ void ulp_riscv_i2c_master_read_from_device(uint8_t *data_rd, size_t size) SET_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START_FORCE); SET_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START); + portENTER_CRITICAL(&rtc_i2c_lock); + for (i = 0; i < size; i++) { /* Poll for RTC I2C Rx Data interrupt bit to be set */ ret = ulp_riscv_i2c_wait_for_interrupt(ULP_RISCV_I2C_RW_TIMEOUT); @@ -368,15 +379,17 @@ void ulp_riscv_i2c_master_read_from_device(uint8_t *data_rd, size_t size) /* Clear the Rx data interrupt bit */ SET_PERI_REG_MASK(RTC_I2C_INT_CLR_REG, RTC_I2C_RX_DATA_INT_CLR); } else { - ESP_LOGE(RTCI2C_TAG, "Read Failed!"); + ESP_EARLY_LOGE(RTCI2C_TAG, "ulp_riscv_i2c: Read Failed!"); uint32_t status = READ_PERI_REG(RTC_I2C_INT_RAW_REG); - ESP_LOGE(RTCI2C_TAG, "RTC I2C Interrupt Raw Reg 0x%"PRIx32"", status); - ESP_LOGE(RTCI2C_TAG, "RTC I2C Status Reg 0x%"PRIx32"", READ_PERI_REG(RTC_I2C_STATUS_REG)); + ESP_EARLY_LOGE(RTCI2C_TAG, "ulp_riscv_i2c: RTC I2C Interrupt Raw Reg 0x%"PRIx32"", status); + ESP_EARLY_LOGE(RTCI2C_TAG, "ulp_riscv_i2c: RTC I2C Status Reg 0x%"PRIx32"", READ_PERI_REG(RTC_I2C_STATUS_REG)); SET_PERI_REG_MASK(RTC_I2C_INT_CLR_REG, status); break; } } + portEXIT_CRITICAL(&rtc_i2c_lock); + /* Clear the RTC I2C transmission bits */ CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START_FORCE); CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START); @@ -422,6 +435,8 @@ void ulp_riscv_i2c_master_write_to_device(uint8_t *data_wr, size_t size) /* Configure the RTC I2C controller in write mode */ SET_PERI_REG_BITS(SENS_SAR_I2C_CTRL_REG, 0x1, 1, 27); + portENTER_CRITICAL(&rtc_i2c_lock); + for (i = 0; i < size; i++) { /* Write the data to be transmitted */ CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, I2C_CTRL_MASTER_TX_DATA_MASK); @@ -440,15 +455,17 @@ void ulp_riscv_i2c_master_write_to_device(uint8_t *data_wr, size_t size) /* Clear the Tx data interrupt bit */ SET_PERI_REG_MASK(RTC_I2C_INT_CLR_REG, RTC_I2C_TX_DATA_INT_CLR); } else { - ESP_LOGE(RTCI2C_TAG, "Write Failed!"); + ESP_EARLY_LOGE(RTCI2C_TAG, "ulp_riscv_i2c: Write Failed!"); uint32_t status = READ_PERI_REG(RTC_I2C_INT_RAW_REG); - ESP_LOGE(RTCI2C_TAG, "RTC I2C Interrupt Raw Reg 0x%"PRIx32"", status); - ESP_LOGE(RTCI2C_TAG, "RTC I2C Status Reg 0x%"PRIx32"", READ_PERI_REG(RTC_I2C_STATUS_REG)); + ESP_EARLY_LOGE(RTCI2C_TAG, "ulp_riscv_i2c: RTC I2C Interrupt Raw Reg 0x%"PRIx32"", status); + ESP_EARLY_LOGE(RTCI2C_TAG, "ulp_riscv_i2c: RTC I2C Status Reg 0x%"PRIx32"", READ_PERI_REG(RTC_I2C_STATUS_REG)); SET_PERI_REG_MASK(RTC_I2C_INT_CLR_REG, status); break; } } + portEXIT_CRITICAL(&rtc_i2c_lock); + /* Clear the RTC I2C transmission bits */ CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START_FORCE); CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START); @@ -460,6 +477,12 @@ esp_err_t ulp_riscv_i2c_master_init(const ulp_riscv_i2c_cfg_t *cfg) WRITE_PERI_REG(RTC_I2C_CTRL_REG, 0); WRITE_PERI_REG(SENS_SAR_I2C_CTRL_REG, 0); + /* Verify that the input cfg param is valid */ + ESP_RETURN_ON_FALSE(cfg, ESP_ERR_INVALID_ARG, RTCI2C_TAG, "RTC I2C configuration is NULL"); + + /* Configure RTC I2C GPIOs */ + ESP_RETURN_ON_ERROR(i2c_set_pin(cfg), RTCI2C_TAG, "Failed to configure RTC I2C GPIOs"); + /* Reset RTC I2C */ #if CONFIG_IDF_TARGET_ESP32S2 i2c_dev->ctrl.i2c_reset = 1; @@ -473,12 +496,6 @@ esp_err_t ulp_riscv_i2c_master_init(const ulp_riscv_i2c_cfg_t *cfg) CLEAR_PERI_REG_MASK(SENS_SAR_PERI_RESET_CONF_REG, SENS_RTC_I2C_RESET); #endif // CONFIG_IDF_TARGET_ESP32S2 - /* Verify that the input cfg param is valid */ - ESP_RETURN_ON_FALSE(cfg, ESP_ERR_INVALID_ARG, RTCI2C_TAG, "RTC I2C configuration is NULL"); - - /* Configure RTC I2C GPIOs */ - ESP_RETURN_ON_ERROR(i2c_set_pin(cfg), RTCI2C_TAG, "Failed to configure RTC I2C GPIOs"); - /* Enable internal open-drain mode for SDA and SCL lines */ #if CONFIG_IDF_TARGET_ESP32S2 i2c_dev->ctrl.sda_force_out = 0; @@ -505,9 +522,12 @@ esp_err_t ulp_riscv_i2c_master_init(const ulp_riscv_i2c_cfg_t *cfg) i2c_dev->i2c_ctrl.i2c_i2c_ctrl_clk_gate_en = 1; #endif // CONFIG_IDF_TARGET_ESP32S2 - /* Configure RTC I2C timing paramters */ + /* Configure RTC I2C timing parameters */ ESP_RETURN_ON_ERROR(i2c_set_timing(cfg), RTCI2C_TAG, "Failed to configure RTC I2C timing"); + /* Clear any pending interrupts */ + WRITE_PERI_REG(RTC_I2C_INT_CLR_REG, UINT32_MAX); + /* Enable RTC I2C interrupts */ SET_PERI_REG_MASK(RTC_I2C_INT_ENA_REG, RTC_I2C_RX_DATA_INT_ENA | RTC_I2C_TX_DATA_INT_ENA | diff --git a/components/usb/hcd_dwc.c b/components/usb/hcd_dwc.c index f9834b7ad8e1..f8ab81965dbb 100644 --- a/components/usb/hcd_dwc.c +++ b/components/usb/hcd_dwc.c @@ -60,10 +60,11 @@ #define XFER_LIST_LEN_CTRL 3 // One descriptor for each stage #define XFER_LIST_LEN_BULK 2 // One descriptor for transfer, one to support an extra zero length packet -// Same length as the frame list makes it easier to schedule. Must be power of 2 +// Periodic transfer descriptor lists: Same length as the frame list makes it easier to schedule. Must be power of 2 // FS: Must be 2-64. HS: Must be 8-256. See USB-OTG databook Table 5-47 #define XFER_LIST_LEN_INTR FRAME_LIST_LEN -#define XFER_LIST_LEN_ISOC FRAME_LIST_LEN +#define XFER_LIST_LEN_ISOC 64 // Implement longer ISOC transfer list to give us enough space for additional timing margin +#define XFER_LIST_ISOC_MARGIN 2 // The 1st ISOC transfer is scheduled 2 (micro)frames later so we have enough timing margin // ------------------------ Flags -------------------------- @@ -214,9 +215,7 @@ struct pipe_obj { uint32_t waiting_halt: 1; uint32_t pipe_cmd_processing: 1; uint32_t has_urb: 1; // Indicates there is at least one URB either pending, in-flight, or done - uint32_t persist: 1; // indicates that this pipe should persist through a run-time port reset - uint32_t reset_lock: 1; // Indicates that this pipe is undergoing a run-time reset - uint32_t reserved27: 27; + uint32_t reserved29: 29; }; uint32_t val; } cs_flags; @@ -560,28 +559,6 @@ static esp_err_t _pipe_cmd_clear(pipe_t *pipe); // ------------------------ Port --------------------------- -/** - * @brief Prepare persistent pipes for reset - * - * This function checks if all pipes are reset persistent and proceeds to free their underlying HAL channels for the - * persistent pipes. This should be called before a run time reset - * - * @param port Port object - * @return true All pipes are persistent and their channels are freed - * @return false Not all pipes are persistent - */ -static bool _port_persist_all_pipes(port_t *port); - -/** - * @brief Recovers all persistent pipes after a reset - * - * This function will recover all persistent pipes after a reset and reallocate their underlying HAl channels. This - * function should be called after a reset. - * - * @param port Port object - */ -static void _port_recover_all_pipes(port_t *port); - /** * @brief Checks if all pipes are in the halted state * @@ -1162,44 +1139,6 @@ esp_err_t hcd_uninstall(void) // ----------------------- Helpers ------------------------- -static bool _port_persist_all_pipes(port_t *port) -{ - if (port->num_pipes_queued > 0) { - // All pipes must be idle before we run-time reset - return false; - } - bool all_persist = true; - pipe_t *pipe; - // Check that each pipe is persistent - TAILQ_FOREACH(pipe, &port->pipes_idle_tailq, tailq_entry) { - if (!pipe->cs_flags.persist) { - all_persist = false; - break; - } - } - if (!all_persist) { - // At least one pipe is not persistent. All pipes must be freed or made persistent before we can reset - return false; - } - TAILQ_FOREACH(pipe, &port->pipes_idle_tailq, tailq_entry) { - pipe->cs_flags.reset_lock = 1; - usb_dwc_hal_chan_free(port->hal, pipe->chan_obj); - } - return true; -} - -static void _port_recover_all_pipes(port_t *port) -{ - pipe_t *pipe; - TAILQ_FOREACH(pipe, &port->pipes_idle_tailq, tailq_entry) { - pipe->cs_flags.persist = 0; - pipe->cs_flags.reset_lock = 0; - usb_dwc_hal_chan_alloc(port->hal, pipe->chan_obj, (void *)pipe); - usb_dwc_hal_chan_set_ep_char(port->hal, pipe->chan_obj, &pipe->ep_char); - } - CACHE_SYNC_FRAME_LIST(port->frame_list); -} - static bool _port_check_all_pipes_halted(port_t *port) { bool all_halted = true; @@ -1276,20 +1215,26 @@ static esp_err_t _port_cmd_power_off(port_t *port) static esp_err_t _port_cmd_reset(port_t *port) { esp_err_t ret; - // Port can only a reset when it is in the enabled or disabled states (in case of new connection) + + // Port can only a reset when it is in the enabled or disabled (in the case of a new connection)states. if (port->state != HCD_PORT_STATE_ENABLED && port->state != HCD_PORT_STATE_DISABLED) { ret = ESP_ERR_INVALID_STATE; goto exit; } - bool is_runtime_reset = (port->state == HCD_PORT_STATE_ENABLED) ? true : false; - if (is_runtime_reset && !_port_persist_all_pipes(port)) { - // If this is a run time reset, check all pipes that are still allocated can persist the reset + // Port can only be reset if all pipes are idle + if (port->num_pipes_queued > 0) { ret = ESP_ERR_INVALID_STATE; goto exit; } - // All pipes (if any_) are guaranteed to be persistent at this point. Proceed to resetting the bus + /* + Proceed to resetting the bus + - Update the port's state variable + - Hold the bus in the reset state for RESET_HOLD_MS. + - Return the bus to the idle state for RESET_RECOVERY_MS + */ port->state = HCD_PORT_STATE_RESETTING; - // Put and hold the bus in the reset state. If the port was previously enabled, a disabled event will occur after this + + // Place the bus into the reset state. If the port was previously enabled, a disabled event will occur after this usb_dwc_hal_port_toggle_reset(port->hal, true); HCD_EXIT_CRITICAL(); vTaskDelay(pdMS_TO_TICKS(RESET_HOLD_MS)); @@ -1299,7 +1244,8 @@ static esp_err_t _port_cmd_reset(port_t *port) ret = ESP_ERR_INVALID_RESPONSE; goto bailout; } - // Return the bus to the idle state and hold it for the required reset recovery time. Port enabled event should occur + + // Return the bus to the idle state. Port enabled event should occur usb_dwc_hal_port_toggle_reset(port->hal, false); HCD_EXIT_CRITICAL(); vTaskDelay(pdMS_TO_TICKS(RESET_RECOVERY_MS)); @@ -1309,16 +1255,20 @@ static esp_err_t _port_cmd_reset(port_t *port) ret = ESP_ERR_INVALID_RESPONSE; goto bailout; } - // Set FIFO sizes based on the selected biasing - usb_dwc_hal_set_fifo_bias(port->hal, port->fifo_bias); - // We start periodic scheduling only after a RESET command since SOFs only start after a reset - usb_dwc_hal_port_set_frame_list(port->hal, port->frame_list, FRAME_LIST_LEN); - usb_dwc_hal_port_periodic_enable(port->hal); + + // Reinitialize port registers. + usb_dwc_hal_set_fifo_bias(port->hal, port->fifo_bias); // Set FIFO biases + usb_dwc_hal_port_set_frame_list(port->hal, port->frame_list, FRAME_LIST_LEN); // Set periodic frame list + usb_dwc_hal_port_periodic_enable(port->hal); // Enable periodic scheduling + ret = ESP_OK; bailout: - if (is_runtime_reset) { - _port_recover_all_pipes(port); + // Reinitialize channel registers + pipe_t *pipe; + TAILQ_FOREACH(pipe, &port->pipes_idle_tailq, tailq_entry) { + usb_dwc_hal_chan_set_ep_char(port->hal, pipe->chan_obj, &pipe->ep_char); } + CACHE_SYNC_FRAME_LIST(port->frame_list); exit: return ret; } @@ -1987,8 +1937,7 @@ esp_err_t hcd_pipe_free(hcd_pipe_handle_t pipe_hdl) HCD_ENTER_CRITICAL(); // Check that all URBs have been removed and pipe has no pending events HCD_CHECK_FROM_CRIT(!pipe->multi_buffer_control.buffer_is_executing - && !pipe->cs_flags.has_urb - && !pipe->cs_flags.reset_lock, + && !pipe->cs_flags.has_urb, ESP_ERR_INVALID_STATE); // Remove pipe from the list of idle pipes (it must be in the idle list because it should have no queued URBs) TAILQ_REMOVE(&pipe->port->pipes_idle_tailq, pipe, tailq_entry); @@ -2011,8 +1960,7 @@ esp_err_t hcd_pipe_update_mps(hcd_pipe_handle_t pipe_hdl, int mps) HCD_ENTER_CRITICAL(); // Check if pipe is in the correct state to be updated HCD_CHECK_FROM_CRIT(!pipe->cs_flags.pipe_cmd_processing && - !pipe->cs_flags.has_urb && - !pipe->cs_flags.reset_lock, + !pipe->cs_flags.has_urb, ESP_ERR_INVALID_STATE); pipe->ep_char.mps = mps; // Update the underlying channel's registers @@ -2027,8 +1975,7 @@ esp_err_t hcd_pipe_update_dev_addr(hcd_pipe_handle_t pipe_hdl, uint8_t dev_addr) HCD_ENTER_CRITICAL(); // Check if pipe is in the correct state to be updated HCD_CHECK_FROM_CRIT(!pipe->cs_flags.pipe_cmd_processing && - !pipe->cs_flags.has_urb && - !pipe->cs_flags.reset_lock, + !pipe->cs_flags.has_urb, ESP_ERR_INVALID_STATE); pipe->ep_char.dev_addr = dev_addr; // Update the underlying channel's registers @@ -2037,35 +1984,6 @@ esp_err_t hcd_pipe_update_dev_addr(hcd_pipe_handle_t pipe_hdl, uint8_t dev_addr) return ESP_OK; } -esp_err_t hcd_pipe_update_callback(hcd_pipe_handle_t pipe_hdl, hcd_pipe_callback_t callback, void *user_arg) -{ - pipe_t *pipe = (pipe_t *)pipe_hdl; - HCD_ENTER_CRITICAL(); - // Check if pipe is in the correct state to be updated - HCD_CHECK_FROM_CRIT(!pipe->cs_flags.pipe_cmd_processing && - !pipe->cs_flags.has_urb && - !pipe->cs_flags.reset_lock, - ESP_ERR_INVALID_STATE); - pipe->callback = callback; - pipe->callback_arg = user_arg; - HCD_EXIT_CRITICAL(); - return ESP_OK; -} - -esp_err_t hcd_pipe_set_persist_reset(hcd_pipe_handle_t pipe_hdl) -{ - pipe_t *pipe = (pipe_t *)pipe_hdl; - HCD_ENTER_CRITICAL(); - // Check if pipe is in the correct state to be updated - HCD_CHECK_FROM_CRIT(!pipe->cs_flags.pipe_cmd_processing && - !pipe->cs_flags.has_urb && - !pipe->cs_flags.reset_lock, - ESP_ERR_INVALID_STATE); - pipe->cs_flags.persist = 1; - HCD_EXIT_CRITICAL(); - return ESP_OK; -} - void *hcd_pipe_get_context(hcd_pipe_handle_t pipe_hdl) { pipe_t *pipe = (pipe_t *)pipe_hdl; @@ -2102,27 +2020,22 @@ esp_err_t hcd_pipe_command(hcd_pipe_handle_t pipe_hdl, hcd_pipe_cmd_t command) esp_err_t ret = ESP_OK; HCD_ENTER_CRITICAL(); - // Cannot execute pipe commands the pipe is already executing a command, or if the pipe or its port are no longer valid - if (pipe->cs_flags.reset_lock) { - ret = ESP_ERR_INVALID_STATE; - } else { - pipe->cs_flags.pipe_cmd_processing = 1; - switch (command) { - case HCD_PIPE_CMD_HALT: { - ret = _pipe_cmd_halt(pipe); - break; - } - case HCD_PIPE_CMD_FLUSH: { - ret = _pipe_cmd_flush(pipe); - break; - } - case HCD_PIPE_CMD_CLEAR: { - ret = _pipe_cmd_clear(pipe); - break; - } - } - pipe->cs_flags.pipe_cmd_processing = 0; + pipe->cs_flags.pipe_cmd_processing = 1; + switch (command) { + case HCD_PIPE_CMD_HALT: { + ret = _pipe_cmd_halt(pipe); + break; + } + case HCD_PIPE_CMD_FLUSH: { + ret = _pipe_cmd_flush(pipe); + break; + } + case HCD_PIPE_CMD_CLEAR: { + ret = _pipe_cmd_clear(pipe); + break; + } } + pipe->cs_flags.pipe_cmd_processing = 0; HCD_EXIT_CRITICAL(); return ret; } @@ -2236,7 +2149,7 @@ static inline void IRAM_ATTR _buffer_fill_isoc(dma_buffer_block_t *buffer, usb_t assert(interval > 0); assert(__builtin_popcount(interval) == 1); // Isochronous interval must be power of 2 according to USB2.0 specification int total_num_desc = transfer->num_isoc_packets * interval; - assert(total_num_desc <= XFER_LIST_LEN_ISOC); + assert(total_num_desc <= XFER_LIST_LEN_ISOC - XFER_LIST_ISOC_MARGIN); // Some space in the qTD list is reserved for timing margin int desc_idx = start_idx; int bytes_filled = 0; // Zeroize the whole QTD, so we can focus only on the active descriptors @@ -2292,19 +2205,8 @@ static void IRAM_ATTR _buffer_fill(pipe_t *pipe) if (pipe->multi_buffer_control.buffer_num_to_exec == 0) { // There are no more previously filled buffers to execute. We need to calculate a new start index based on HFNUM and the pipe's schedule uint16_t cur_frame_num = usb_dwc_hal_port_get_cur_frame_num(pipe->port->hal); - start_idx = cur_frame_num + 1; // This is the next frame that the periodic scheduler will fetch - uint16_t rem_time = usb_dwc_ll_hfnum_get_frame_time_rem(pipe->port->hal->dev); - - // If there is not enough time remaining in this frame, consider the next frame as start index - // The remaining time is in USB PHY clocks. The threshold value is time between buffer fill and execute (6-11us) = 180 + 5 x num_packets - if (rem_time < 195 + 5 * transfer->num_isoc_packets) { - if (rem_time > 165 + 5 * transfer->num_isoc_packets) { - // If the remaining time is +-15 PHY clocks around the threshold value we cannot be certain whether we will schedule it in time for this frame - // Busy wait 10us to be sure that we are at the beginning of next frame/microframe - esp_rom_delay_us(10); - } - start_idx++; - } + start_idx = cur_frame_num + 1; // This is the next frame that the periodic scheduler will fetch + start_idx += XFER_LIST_ISOC_MARGIN; // Start scheduling with a little delay. This will get us enough timing margin so no transfer is skipped // Only every (interval + offset) transfer belongs to this channel // Following calculation effectively rounds up to nearest (interval + offset) @@ -2522,18 +2424,31 @@ static inline void _buffer_parse_isoc(dma_buffer_block_t *buffer, bool is_in) int desc_status; usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, desc_idx, &rem_len, &desc_status); usb_dwc_hal_xfer_desc_clear(buffer->xfer_desc_list, desc_idx); - assert(rem_len == 0 || is_in); - assert(desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS || desc_status == USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED); + switch (desc_status) { + case USB_DWC_HAL_XFER_DESC_STS_SUCCESS: + transfer->isoc_packet_desc[pkt_idx].status = USB_TRANSFER_STATUS_COMPLETED; + break; + case USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED: + transfer->isoc_packet_desc[pkt_idx].status = USB_TRANSFER_STATUS_SKIPPED; + break; + case USB_DWC_HAL_XFER_DESC_STS_PKTERR: + transfer->isoc_packet_desc[pkt_idx].status = USB_TRANSFER_STATUS_ERROR; + break; + case USB_DWC_HAL_XFER_DESC_STS_BUFFER_ERR: + transfer->isoc_packet_desc[pkt_idx].status = USB_TRANSFER_STATUS_ERROR; + break; + default: + assert(false); + break; + } + assert(rem_len <= transfer->isoc_packet_desc[pkt_idx].num_bytes); // Check for DMA errata // Update ISO packet actual length and status transfer->isoc_packet_desc[pkt_idx].actual_num_bytes = transfer->isoc_packet_desc[pkt_idx].num_bytes - rem_len; total_actual_num_bytes += transfer->isoc_packet_desc[pkt_idx].actual_num_bytes; - transfer->isoc_packet_desc[pkt_idx].status = (desc_status == USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED) ? USB_TRANSFER_STATUS_SKIPPED : USB_TRANSFER_STATUS_COMPLETED; // A descriptor is also allocated for unscheduled frames. We need to skip over them desc_idx += buffer->flags.isoc.interval; - if (desc_idx >= XFER_LIST_LEN_INTR) { - desc_idx -= XFER_LIST_LEN_INTR; - } + desc_idx %= XFER_LIST_LEN_ISOC; } // Write back the actual_num_bytes and statue of entire transfer assert(total_actual_num_bytes <= transfer->num_bytes); @@ -2658,8 +2573,7 @@ esp_err_t hcd_urb_enqueue(hcd_pipe_handle_t pipe_hdl, urb_t *urb) // Check that pipe and port are in the correct state to receive URBs HCD_CHECK_FROM_CRIT(pipe->port->state == HCD_PORT_STATE_ENABLED // The pipe's port must be in the correct state && pipe->state == HCD_PIPE_STATE_ACTIVE // The pipe must be in the correct state - && !pipe->cs_flags.pipe_cmd_processing // Pipe cannot currently be processing a pipe command - && !pipe->cs_flags.reset_lock, // Pipe cannot be persisting through a port reset + && !pipe->cs_flags.pipe_cmd_processing, // Pipe cannot currently be processing a pipe command ESP_ERR_INVALID_STATE); // Use the URB's reserved_ptr to store the pipe's urb->hcd_ptr = (void *)pipe; diff --git a/components/usb/hub.c b/components/usb/hub.c index 52aa84e00a9a..2735ef5a469e 100644 --- a/components/usb/hub.c +++ b/components/usb/hub.c @@ -40,6 +40,7 @@ implement the bare minimum to control the root HCD port. #define ENUM_CTRL_TRANSFER_MAX_DATA_LEN CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE #define ENUM_DEV_ADDR 1 // Device address used in enumeration +#define ENUM_DEV_UID 1 // Unique ID for device connected to root port #define ENUM_CONFIG_INDEX_DEFAULT 0 // Index used to get the first configuration descriptor of the device #define ENUM_SHORT_DESC_REQ_LEN 8 // Number of bytes to request when getting a short descriptor (just enough to get bMaxPacketSize0 or wTotalLength) #define ENUM_WORST_CASE_MPS_LS 8 // The worst case MPS of EP0 for a LS device @@ -50,9 +51,12 @@ implement the bare minimum to control the root HCD port. // Hub driver action flags. LISTED IN THE ORDER THEY SHOULD BE HANDLED IN within hub_process(). Some actions are mutually exclusive #define HUB_DRIVER_FLAG_ACTION_ROOT_EVENT 0x01 -#define HUB_DRIVER_FLAG_ACTION_PORT 0x02 +#define HUB_DRIVER_FLAG_ACTION_PORT_REQ 0x02 #define HUB_DRIVER_FLAG_ACTION_ENUM_EVENT 0x04 +#define PORT_REQ_DISABLE 0x01 +#define PORT_REQ_RECOVER 0x02 + /** * @brief Root port states * @@ -60,9 +64,8 @@ implement the bare minimum to control the root HCD port. typedef enum { ROOT_PORT_STATE_NOT_POWERED, /**< Root port initialized and/or not powered */ ROOT_PORT_STATE_POWERED, /**< Root port is powered, device is not connected */ - ROOT_PORT_STATE_ENUM, /**< A device has been connected to the root port and is undergoing enumeration */ - ROOT_PORT_STATE_ENUM_FAILED, /**< Enumeration of a connected device has failed. Waiting for that device to be disconnected */ - ROOT_PORT_ACTIVE, /**< The connected device was enumerated and port is active */ + ROOT_PORT_STATE_DISABLED, /**< A device is connected but is disabled (i.e., not reset, no SOFs are sent) */ + ROOT_PORT_STATE_ENABLED, /**< A device is connected, port has been reset, SOFs are sent */ ROOT_PORT_STATE_RECOVERY, /**< Root port encountered an error and needs to be recovered */ } root_port_state_t; @@ -156,7 +159,6 @@ typedef struct { urb_t *urb; /**< URB used for enumeration control transfers. Max data length of ENUM_CTRL_TRANSFER_MAX_DATA_LEN */ // Initialized at start of a particular enumeration usb_device_handle_t dev_hdl; /**< Handle of device being enumerated */ - hcd_pipe_handle_t pipe; /**< Default pipe handle of the device being enumerated */ // Updated during enumeration enum_stage_t stage; /**< Current enumeration stage */ int expect_num_bytes; /**< Expected number of bytes for IN transfers stages. Set to 0 for OUT transfer */ @@ -185,10 +187,11 @@ typedef struct { uint32_t val; } flags; root_port_state_t root_port_state; + unsigned int port_reqs; } dynamic; // Single thread members don't require a critical section so long as they are never accessed from multiple threads struct { - usb_device_handle_t root_dev_hdl; // Indicates if an enumerated device is connected to the root port + unsigned int root_dev_uid; // UID of the device connected to root port. 0 if no device connected enum_ctrl_t enum_ctrl; } single_thread; // Constant members do no change after installation thus do not require a critical section @@ -241,40 +244,26 @@ const char *HUB_DRIVER_TAG = "HUB"; static bool root_port_callback(hcd_port_handle_t port_hdl, hcd_port_event_t port_event, void *user_arg, bool in_isr); /** - * @brief HCD pipe callback for the default pipe of the device under enumeration - * - * - This callback is called from the context of the HCD, so any event handling should be deferred to hub_process() - * - This callback needs to call proc_req_cb to ensure that hub_process() gets a chance to run + * @brief Control transfer callback used for enumeration * - * @param pipe_hdl HCD pipe handle - * @param pipe_event Pipe event - * @param user_arg Callback argument - * @param in_isr Whether callback is in an ISR context - * @return Whether a yield is required + * @param transfer Transfer object */ -static bool enum_dflt_pipe_callback(hcd_pipe_handle_t pipe_hdl, hcd_pipe_event_t pipe_event, void *user_arg, bool in_isr); +static void enum_transfer_callback(usb_transfer_t *transfer); // ------------------------------------------------- Enum Functions ---------------------------------------------------- static bool enum_stage_start(enum_ctrl_t *enum_ctrl) { - // Get the speed of the device, and set the enum MPS to the worst case size for now - usb_speed_t speed; - if (hcd_port_get_speed(p_hub_driver_obj->constant.root_port_hdl, &speed) != ESP_OK) { - return false; - } - enum_ctrl->bMaxPacketSize0 = (speed == USB_SPEED_LOW) ? ENUM_WORST_CASE_MPS_LS : ENUM_WORST_CASE_MPS_FS; - // Try to add the device to USBH - usb_device_handle_t enum_dev_hdl; - hcd_pipe_handle_t enum_dflt_pipe_hdl; - // We use NULL as the parent device to indicate the Root Hub port 1. We currently only support a single device - if (usbh_hub_add_dev(p_hub_driver_obj->constant.root_port_hdl, speed, &enum_dev_hdl, &enum_dflt_pipe_hdl) != ESP_OK) { - return false; - } - // Set our own default pipe callback - ESP_ERROR_CHECK(hcd_pipe_update_callback(enum_dflt_pipe_hdl, enum_dflt_pipe_callback, NULL)); - enum_ctrl->dev_hdl = enum_dev_hdl; - enum_ctrl->pipe = enum_dflt_pipe_hdl; + // Open the newly added device (at address 0) + ESP_ERROR_CHECK(usbh_devs_open(0, &p_hub_driver_obj->single_thread.enum_ctrl.dev_hdl)); + + // Get the speed of the device to set the initial MPS of EP0 + usb_device_info_t dev_info; + ESP_ERROR_CHECK(usbh_dev_get_info(p_hub_driver_obj->single_thread.enum_ctrl.dev_hdl, &dev_info)); + enum_ctrl->bMaxPacketSize0 = (dev_info.speed == USB_SPEED_LOW) ? ENUM_WORST_CASE_MPS_LS : ENUM_WORST_CASE_MPS_FS; + + // Lock the device for enumeration. This allows us call usbh_dev_set_...() functions during enumeration + ESP_ERROR_CHECK(usbh_dev_enum_lock(p_hub_driver_obj->single_thread.enum_ctrl.dev_hdl)); // Flag to gracefully exit the enumeration process if requested by the user in the enumeration filter cb #ifdef ENABLE_ENUM_FILTER_CALLBACK @@ -285,7 +274,6 @@ static bool enum_stage_start(enum_ctrl_t *enum_ctrl) static bool enum_stage_second_reset(enum_ctrl_t *enum_ctrl) { - ESP_ERROR_CHECK(hcd_pipe_set_persist_reset(enum_ctrl->pipe)); // Persist the default pipe through the reset if (hcd_port_command(p_hub_driver_obj->constant.root_port_hdl, HCD_PORT_CMD_RESET) != ESP_OK) { ESP_LOGE(HUB_DRIVER_TAG, "Failed to issue second reset"); return false; @@ -442,7 +430,7 @@ static bool enum_stage_transfer(enum_ctrl_t *enum_ctrl) abort(); break; } - if (hcd_urb_enqueue(enum_ctrl->pipe, enum_ctrl->urb) != ESP_OK) { + if (usbh_dev_submit_ctrl_urb(enum_ctrl->dev_hdl, enum_ctrl->urb) != ESP_OK) { ESP_LOGE(HUB_DRIVER_TAG, "Failed to submit: %s", enum_stage_strings[enum_ctrl->stage]); return false; } @@ -467,18 +455,10 @@ static bool enum_stage_wait(enum_ctrl_t *enum_ctrl) static bool enum_stage_transfer_check(enum_ctrl_t *enum_ctrl) { - // Dequeue the URB - urb_t *dequeued_enum_urb = hcd_urb_dequeue(enum_ctrl->pipe); - assert(dequeued_enum_urb == enum_ctrl->urb); - // Check transfer status - usb_transfer_t *transfer = &dequeued_enum_urb->transfer; + usb_transfer_t *transfer = &enum_ctrl->urb->transfer; if (transfer->status != USB_TRANSFER_STATUS_COMPLETED) { ESP_LOGE(HUB_DRIVER_TAG, "Bad transfer status %d: %s", transfer->status, enum_stage_strings[enum_ctrl->stage]); - if (transfer->status == USB_TRANSFER_STATUS_STALL) { - // EP stalled, clearing the pipe to execute further stages - ESP_ERROR_CHECK(hcd_pipe_command(enum_ctrl->pipe, HCD_PIPE_CMD_CLEAR)); - } return false; } // Check IN transfer returned the expected correct number of bytes @@ -505,8 +485,8 @@ static bool enum_stage_transfer_check(enum_ctrl_t *enum_ctrl) ret = false; break; } - // Update and save the MPS of the default pipe - if (hcd_pipe_update_mps(enum_ctrl->pipe, device_desc->bMaxPacketSize0) != ESP_OK) { + // Update and save the MPS of the EP0 + if (usbh_dev_set_ep0_mps(enum_ctrl->dev_hdl, device_desc->bMaxPacketSize0) != ESP_OK) { ESP_LOGE(HUB_DRIVER_TAG, "Failed to update MPS"); ret = false; break; @@ -517,16 +497,15 @@ static bool enum_stage_transfer_check(enum_ctrl_t *enum_ctrl) break; } case ENUM_STAGE_CHECK_ADDR: { - // Update the pipe and device's address, and fill the address into the device object - ESP_ERROR_CHECK(hcd_pipe_update_dev_addr(enum_ctrl->pipe, ENUM_DEV_ADDR)); - ESP_ERROR_CHECK(usbh_hub_enum_fill_dev_addr(enum_ctrl->dev_hdl, ENUM_DEV_ADDR)); + // Update the device's address + ESP_ERROR_CHECK(usbh_dev_set_addr(enum_ctrl->dev_hdl, ENUM_DEV_ADDR)); ret = true; break; } case ENUM_STAGE_CHECK_FULL_DEV_DESC: { - // Fill device descriptor into the device object + // Set the device's descriptor const usb_device_desc_t *device_desc = (const usb_device_desc_t *)(transfer->data_buffer + sizeof(usb_setup_packet_t)); - ESP_ERROR_CHECK(usbh_hub_enum_fill_dev_desc(enum_ctrl->dev_hdl, device_desc)); + ESP_ERROR_CHECK(usbh_dev_set_desc(enum_ctrl->dev_hdl, device_desc)); enum_ctrl->iManufacturer = device_desc->iManufacturer; enum_ctrl->iProduct = device_desc->iProduct; enum_ctrl->iSerialNumber = device_desc->iSerialNumber; @@ -555,10 +534,10 @@ static bool enum_stage_transfer_check(enum_ctrl_t *enum_ctrl) break; } case ENUM_STAGE_CHECK_FULL_CONFIG_DESC: { - // Fill configuration descriptor into the device object + // Set the device's configuration descriptor const usb_config_desc_t *config_desc = (usb_config_desc_t *)(transfer->data_buffer + sizeof(usb_setup_packet_t)); enum_ctrl->bConfigurationValue = config_desc->bConfigurationValue; - ESP_ERROR_CHECK(usbh_hub_enum_fill_config_desc(enum_ctrl->dev_hdl, config_desc)); + ESP_ERROR_CHECK(usbh_dev_set_config_desc(enum_ctrl->dev_hdl, config_desc)); ret = true; break; } @@ -635,7 +614,7 @@ static bool enum_stage_transfer_check(enum_ctrl_t *enum_ctrl) } else { // ENUM_STAGE_CHECK_FULL_PROD_STR_DESC select = 2; } - ESP_ERROR_CHECK(usbh_hub_enum_fill_str_desc(enum_ctrl->dev_hdl, str_desc, select)); + ESP_ERROR_CHECK(usbh_dev_set_str_desc(enum_ctrl->dev_hdl, str_desc, select)); ret = true; break; } @@ -650,42 +629,27 @@ static bool enum_stage_transfer_check(enum_ctrl_t *enum_ctrl) static void enum_stage_cleanup(enum_ctrl_t *enum_ctrl) { - // We currently only support a single device connected to the root port. Move the device handle from enum to root - HUB_DRIVER_ENTER_CRITICAL(); - p_hub_driver_obj->dynamic.root_port_state = ROOT_PORT_ACTIVE; - HUB_DRIVER_EXIT_CRITICAL(); - p_hub_driver_obj->single_thread.root_dev_hdl = enum_ctrl->dev_hdl; - usb_device_handle_t dev_hdl = enum_ctrl->dev_hdl; + // Unlock the device as we are done with the enumeration + ESP_ERROR_CHECK(usbh_dev_enum_unlock(enum_ctrl->dev_hdl)); + // Propagate a new device event + ESP_ERROR_CHECK(usbh_devs_new_dev_event(enum_ctrl->dev_hdl)); + // We are done with using the device. Close it. + ESP_ERROR_CHECK(usbh_devs_close(enum_ctrl->dev_hdl)); // Clear values in enum_ctrl enum_ctrl->dev_hdl = NULL; - enum_ctrl->pipe = NULL; - // Update device object after enumeration is done - ESP_ERROR_CHECK(usbh_hub_enum_done(dev_hdl)); } static void enum_stage_cleanup_failed(enum_ctrl_t *enum_ctrl) { - // Enumeration failed. Clear the enum device handle and pipe if (enum_ctrl->dev_hdl) { - // If enumeration failed due to a port event, we need to Halt, flush, and dequeue enum default pipe in case there - // was an in-flight URB. - ESP_ERROR_CHECK(hcd_pipe_command(enum_ctrl->pipe, HCD_PIPE_CMD_HALT)); - ESP_ERROR_CHECK(hcd_pipe_command(enum_ctrl->pipe, HCD_PIPE_CMD_FLUSH)); - hcd_urb_dequeue(enum_ctrl->pipe); // This could return NULL if there - ESP_ERROR_CHECK(usbh_hub_enum_failed(enum_ctrl->dev_hdl)); // Free the underlying device object first before recovering the port + // Close the device and unlock it as we done with enumeration + ESP_ERROR_CHECK(usbh_dev_enum_unlock(enum_ctrl->dev_hdl)); + ESP_ERROR_CHECK(usbh_devs_close(enum_ctrl->dev_hdl)); + // We allow this to fail in case the device object was already freed + usbh_devs_remove(ENUM_DEV_UID); } // Clear values in enum_ctrl enum_ctrl->dev_hdl = NULL; - enum_ctrl->pipe = NULL; - HUB_DRIVER_ENTER_CRITICAL(); - // Enum could have failed due to a port error. If so, we need to trigger a port recovery - if (p_hub_driver_obj->dynamic.root_port_state == ROOT_PORT_STATE_RECOVERY) { - p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_PORT; - } else { - // Otherwise, we move to the enum failed state and wait for the device to disconnect - p_hub_driver_obj->dynamic.root_port_state = ROOT_PORT_STATE_ENUM_FAILED; - } - HUB_DRIVER_EXIT_CRITICAL(); } static enum_stage_t get_next_stage(enum_stage_t old_stage, enum_ctrl_t *enum_ctrl) @@ -799,13 +763,13 @@ static bool root_port_callback(hcd_port_handle_t port_hdl, hcd_port_event_t port return p_hub_driver_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_HUB, in_isr, p_hub_driver_obj->constant.proc_req_cb_arg); } -static bool enum_dflt_pipe_callback(hcd_pipe_handle_t pipe_hdl, hcd_pipe_event_t pipe_event, void *user_arg, bool in_isr) +static void enum_transfer_callback(usb_transfer_t *transfer) { - // Note: This callback may have triggered when a failed enumeration is already cleaned up (e.g., due to a failed port reset) + // We simply trigger a processing request to handle the completed enumeration control transfer HUB_DRIVER_ENTER_CRITICAL_SAFE(); p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_ENUM_EVENT; HUB_DRIVER_EXIT_CRITICAL_SAFE(); - return p_hub_driver_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_HUB, in_isr, p_hub_driver_obj->constant.proc_req_cb_arg); + p_hub_driver_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_HUB, false, p_hub_driver_obj->constant.proc_req_cb_arg); } // ---------------------- Handlers ------------------------- @@ -818,17 +782,32 @@ static void root_port_handle_events(hcd_port_handle_t root_port_hdl) // Nothing to do break; case HCD_PORT_EVENT_CONNECTION: { - if (hcd_port_command(root_port_hdl, HCD_PORT_CMD_RESET) == ESP_OK) { - ESP_LOGD(HUB_DRIVER_TAG, "Root port reset"); - // Start enumeration - HUB_DRIVER_ENTER_CRITICAL(); - p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_ENUM_EVENT; - p_hub_driver_obj->dynamic.root_port_state = ROOT_PORT_STATE_ENUM; - HUB_DRIVER_EXIT_CRITICAL(); - p_hub_driver_obj->single_thread.enum_ctrl.stage = ENUM_STAGE_START; - } else { + if (hcd_port_command(root_port_hdl, HCD_PORT_CMD_RESET) != ESP_OK) { ESP_LOGE(HUB_DRIVER_TAG, "Root port reset failed"); + goto reset_err; + } + ESP_LOGD(HUB_DRIVER_TAG, "Root port reset"); + usb_speed_t speed; + if (hcd_port_get_speed(p_hub_driver_obj->constant.root_port_hdl, &speed) != ESP_OK) { + goto new_dev_err; } + // Allocate a new device. We use a fixed ENUM_DEV_UID for now since we only support a single device + if (usbh_devs_add(ENUM_DEV_UID, speed, p_hub_driver_obj->constant.root_port_hdl) != ESP_OK) { + ESP_LOGE(HUB_DRIVER_TAG, "Failed to add device"); + goto new_dev_err; + } + p_hub_driver_obj->single_thread.root_dev_uid = ENUM_DEV_UID; + // Start enumeration + HUB_DRIVER_ENTER_CRITICAL(); + p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_ENUM_EVENT; + p_hub_driver_obj->dynamic.root_port_state = ROOT_PORT_STATE_ENABLED; + HUB_DRIVER_EXIT_CRITICAL(); + p_hub_driver_obj->single_thread.enum_ctrl.stage = ENUM_STAGE_START; + break; +new_dev_err: + // We allow this to fail in case a disconnect/port error happens while disabling. + hcd_port_command(p_hub_driver_obj->constant.root_port_hdl, HCD_PORT_CMD_DISABLE); +reset_err: break; } case HCD_PORT_EVENT_DISCONNECTION: @@ -838,17 +817,13 @@ static void root_port_handle_events(hcd_port_handle_t root_port_hdl) HUB_DRIVER_ENTER_CRITICAL(); switch (p_hub_driver_obj->dynamic.root_port_state) { case ROOT_PORT_STATE_POWERED: // This occurred before enumeration - case ROOT_PORT_STATE_ENUM_FAILED: // This occurred after a failed enumeration. - // Therefore, there's no device and we can go straight to port recovery - p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_PORT; - break; - case ROOT_PORT_STATE_ENUM: - // This occurred during enumeration. Therefore, we need to cleanup the failed enumeration - p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_ENUM_EVENT; - p_hub_driver_obj->single_thread.enum_ctrl.stage = ENUM_STAGE_CLEANUP_FAILED; + case ROOT_PORT_STATE_DISABLED: // This occurred after the device has already been disabled + // Therefore, there's no device object to clean up, and we can go straight to port recovery + p_hub_driver_obj->dynamic.port_reqs |= PORT_REQ_RECOVER; + p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_PORT_REQ; break; - case ROOT_PORT_ACTIVE: - // There was an enumerated device. We need to indicate to USBH that the device is gone + case ROOT_PORT_STATE_ENABLED: + // There is an enabled (active) device. We need to indicate to USBH that the device is gone pass_event_to_usbh = true; break; default: @@ -858,7 +833,10 @@ static void root_port_handle_events(hcd_port_handle_t root_port_hdl) p_hub_driver_obj->dynamic.root_port_state = ROOT_PORT_STATE_RECOVERY; HUB_DRIVER_EXIT_CRITICAL(); if (pass_event_to_usbh) { - ESP_ERROR_CHECK(usbh_hub_dev_gone(p_hub_driver_obj->single_thread.root_dev_hdl)); + // The port must have a device object + assert(p_hub_driver_obj->single_thread.root_dev_uid != 0); + // We allow this to fail in case the device object was already freed + usbh_devs_remove(p_hub_driver_obj->single_thread.root_dev_uid); } break; } @@ -868,6 +846,30 @@ static void root_port_handle_events(hcd_port_handle_t root_port_hdl) } } +static void root_port_req(hcd_port_handle_t root_port_hdl) +{ + unsigned int port_reqs; + + HUB_DRIVER_ENTER_CRITICAL(); + port_reqs = p_hub_driver_obj->dynamic.port_reqs; + p_hub_driver_obj->dynamic.port_reqs = 0; + HUB_DRIVER_EXIT_CRITICAL(); + + if (port_reqs & PORT_REQ_DISABLE) { + ESP_LOGD(HUB_DRIVER_TAG, "Disabling root port"); + // We allow this to fail in case a disconnect/port error happens while disabling. + hcd_port_command(p_hub_driver_obj->constant.root_port_hdl, HCD_PORT_CMD_DISABLE); + } + if (port_reqs & PORT_REQ_RECOVER) { + ESP_LOGD(HUB_DRIVER_TAG, "Recovering root port"); + ESP_ERROR_CHECK(hcd_port_recover(p_hub_driver_obj->constant.root_port_hdl)); + ESP_ERROR_CHECK(hcd_port_command(p_hub_driver_obj->constant.root_port_hdl, HCD_PORT_CMD_POWER_ON)); + HUB_DRIVER_ENTER_CRITICAL(); + p_hub_driver_obj->dynamic.root_port_state = ROOT_PORT_STATE_POWERED; + HUB_DRIVER_EXIT_CRITICAL(); + } +} + static void enum_handle_events(void) { bool stage_pass; @@ -926,7 +928,6 @@ static void enum_handle_events(void) stage_pass = true; break; default: - // Note: Don't abort here. The enum_dflt_pipe_callback() can trigger a HUB_DRIVER_FLAG_ACTION_ENUM_EVENT after a cleanup. stage_pass = true; break; } @@ -948,18 +949,22 @@ static void enum_handle_events(void) // ---------------------------------------------- Hub Driver Functions ------------------------------------------------- -esp_err_t hub_install(hub_config_t *hub_config) +esp_err_t hub_install(hub_config_t *hub_config, void **client_ret) { HUB_DRIVER_ENTER_CRITICAL(); HUB_DRIVER_CHECK_FROM_CRIT(p_hub_driver_obj == NULL, ESP_ERR_INVALID_STATE); HUB_DRIVER_EXIT_CRITICAL(); + esp_err_t ret; + // Allocate Hub driver object hub_driver_t *hub_driver_obj = heap_caps_calloc(1, sizeof(hub_driver_t), MALLOC_CAP_DEFAULT); urb_t *enum_urb = urb_alloc(sizeof(usb_setup_packet_t) + ENUM_CTRL_TRANSFER_MAX_DATA_LEN, 0); if (hub_driver_obj == NULL || enum_urb == NULL) { return ESP_ERR_NO_MEM; } - esp_err_t ret; + enum_urb->usb_host_client = (void *)hub_driver_obj; + enum_urb->transfer.callback = enum_transfer_callback; + // Install HCD port hcd_port_config_t port_config = { .fifo_bias = HUB_ROOT_HCD_PORT_FIFO_BIAS, @@ -972,6 +977,7 @@ esp_err_t hub_install(hub_config_t *hub_config) if (ret != ESP_OK) { goto err; } + // Initialize Hub driver object hub_driver_obj->single_thread.enum_ctrl.stage = ENUM_STAGE_NONE; hub_driver_obj->single_thread.enum_ctrl.urb = enum_urb; @@ -991,6 +997,9 @@ esp_err_t hub_install(hub_config_t *hub_config) } p_hub_driver_obj = hub_driver_obj; HUB_DRIVER_EXIT_CRITICAL(); + + // Write-back client_ret pointer + *client_ret = (void *)hub_driver_obj; ret = ESP_OK; return ret; @@ -1052,17 +1061,31 @@ esp_err_t hub_root_stop(void) return ret; } -esp_err_t hub_dev_is_free(uint8_t dev_addr) +esp_err_t hub_port_recycle(unsigned int dev_uid) { - assert(dev_addr == ENUM_DEV_ADDR); - assert(p_hub_driver_obj->single_thread.root_dev_hdl); - p_hub_driver_obj->single_thread.root_dev_hdl = NULL; - // Device is free, we can now request its port be recycled - HUB_DRIVER_ENTER_CRITICAL(); - p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_PORT; - HUB_DRIVER_EXIT_CRITICAL(); + if (dev_uid == p_hub_driver_obj->single_thread.root_dev_uid) { + // Device is free, we can now request its port be recycled + hcd_port_state_t port_state = hcd_port_get_state(p_hub_driver_obj->constant.root_port_hdl); + p_hub_driver_obj->single_thread.root_dev_uid = 0; + HUB_DRIVER_ENTER_CRITICAL(); + // How the port is recycled will depend on the port's state + switch (port_state) { + case HCD_PORT_STATE_ENABLED: + p_hub_driver_obj->dynamic.port_reqs |= PORT_REQ_DISABLE; + break; + case HCD_PORT_STATE_RECOVERY: + p_hub_driver_obj->dynamic.port_reqs |= PORT_REQ_RECOVER; + break; + default: + abort(); // Should never occur + break; + } + p_hub_driver_obj->dynamic.flags.actions |= HUB_DRIVER_FLAG_ACTION_PORT_REQ; + HUB_DRIVER_EXIT_CRITICAL(); + + p_hub_driver_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_HUB, false, p_hub_driver_obj->constant.proc_req_cb_arg); + } - p_hub_driver_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_HUB, false, p_hub_driver_obj->constant.proc_req_cb_arg); return ESP_OK; } @@ -1077,29 +1100,8 @@ esp_err_t hub_process(void) if (action_flags & HUB_DRIVER_FLAG_ACTION_ROOT_EVENT) { root_port_handle_events(p_hub_driver_obj->constant.root_port_hdl); } - if (action_flags & HUB_DRIVER_FLAG_ACTION_PORT) { - // Check current state of port - hcd_port_state_t port_state = hcd_port_get_state(p_hub_driver_obj->constant.root_port_hdl); - switch (port_state) { - case HCD_PORT_STATE_ENABLED: - // Port is still enabled with a connect device. Disable it. - ESP_LOGD(HUB_DRIVER_TAG, "Disabling root port"); - // We allow this to fail in case a disconnect/port error happens while disabling. - hcd_port_command(p_hub_driver_obj->constant.root_port_hdl, HCD_PORT_CMD_DISABLE); - break; - case HCD_PORT_STATE_RECOVERY: - // Port is in recovery after a disconnect/error. Recover it. - ESP_LOGD(HUB_DRIVER_TAG, "Recovering root port"); - ESP_ERROR_CHECK(hcd_port_recover(p_hub_driver_obj->constant.root_port_hdl)); - ESP_ERROR_CHECK(hcd_port_command(p_hub_driver_obj->constant.root_port_hdl, HCD_PORT_CMD_POWER_ON)); - HUB_DRIVER_ENTER_CRITICAL(); - p_hub_driver_obj->dynamic.root_port_state = ROOT_PORT_STATE_POWERED; - HUB_DRIVER_EXIT_CRITICAL(); - break; - default: - abort(); // Should never occur - break; - } + if (action_flags & HUB_DRIVER_FLAG_ACTION_PORT_REQ) { + root_port_req(p_hub_driver_obj->constant.root_port_hdl); } if (action_flags & HUB_DRIVER_FLAG_ACTION_ENUM_EVENT) { enum_handle_events(); diff --git a/components/usb/include/usb/usb_host.h b/components/usb/include/usb/usb_host.h index ba44c584d17b..b9a1c4dabb1f 100644 --- a/components/usb/include/usb/usb_host.h +++ b/components/usb/include/usb/usb_host.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -346,6 +346,35 @@ esp_err_t usb_host_get_device_descriptor(usb_device_handle_t dev_hdl, const usb_ */ esp_err_t usb_host_get_active_config_descriptor(usb_device_handle_t dev_hdl, const usb_config_desc_t **config_desc); +/** + * @brief Get get device's configuration descriptor + * + * - The USB Host library only caches a device's active configuration descriptor. + * - This function reads any configuration descriptor of a particular device (specified by bConfigurationValue). + * - This function will read the specified configuration descriptor via control transfers, and allocate memory to store that descriptor. + * - Users can call usb_host_free_config_desc() to free the descriptor's memory afterwards. + * + * @note This function can block + * @note A client must call usb_host_device_open() on the device first + * @param[in] client_hdl Client handle - usb_host_client_handle_events() should be called repeatedly in a separate task to handle client events + * @param[in] dev_hdl Device handle + * @param[out] config_desc_ret Returned configuration descriptor + * @param[in] bConfigurationValue Index of device's configuration descriptor to be read + * @note bConfigurationValue starts from index 1 + * @return esp_err_t + */ +esp_err_t usb_host_get_config_desc(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl, uint8_t bConfigurationValue, const usb_config_desc_t **config_desc_ret); + +/** + * @brief Free a configuration descriptor + * + * This function frees a configuration descriptor that was returned by usb_host_get_config_desc() + * + * @param[out] config_desc Configuration descriptor + * @return esp_err_t + */ +esp_err_t usb_host_free_config_desc(const usb_config_desc_t *config_desc); + // ----------------------------------------------- Interface Functions ------------------------------------------------- /** diff --git a/components/usb/private_include/hcd.h b/components/usb/private_include/hcd.h index f0c4a364b987..1fd361730712 100644 --- a/components/usb/private_include/hcd.h +++ b/components/usb/private_include/hcd.h @@ -418,36 +418,6 @@ esp_err_t hcd_pipe_update_mps(hcd_pipe_handle_t pipe_hdl, int mps); */ esp_err_t hcd_pipe_update_dev_addr(hcd_pipe_handle_t pipe_hdl, uint8_t dev_addr); -/** - * @brief Update a pipe's callback - * - * This function is intended to be called on default pipes at the end of enumeration to switch to a callback that - * handles the completion of regular control transfer. - * - Pipe is not current processing a command - * - Pipe does not have any enqueued URBs - * - Port cannot be resetting - * - * @param pipe_hdl Pipe handle - * @param callback Callback - * @param user_arg Callback argument - * @return esp_err_t - */ -esp_err_t hcd_pipe_update_callback(hcd_pipe_handle_t pipe_hdl, hcd_pipe_callback_t callback, void *user_arg); - -/** - * @brief Make a pipe persist through a run time reset - * - * Normally when a HCD_PORT_CMD_RESET is called, all pipes should already have been freed. However There may be cases - * (such as during enumeration) when a pipe must persist through a reset. This function will mark a pipe as - * persistent allowing it to survive a reset. When HCD_PORT_CMD_RESET is called, the pipe can continue to be used after - * the reset. - * - * @param pipe_hdl Pipe handle - * @retval ESP_OK: Pipe successfully marked as persistent - * @retval ESP_ERR_INVALID_STATE: Pipe is not in a condition to be made persistent - */ -esp_err_t hcd_pipe_set_persist_reset(hcd_pipe_handle_t pipe_hdl); - /** * @brief Get the context variable of a pipe from its handle * diff --git a/components/usb/private_include/hub.h b/components/usb/private_include/hub.h index a096de8fd960..cf85ad861d23 100644 --- a/components/usb/private_include/hub.h +++ b/components/usb/private_include/hub.h @@ -42,9 +42,10 @@ typedef struct { * - Initializes the HCD root port * * @param[in] hub_config Hub driver configuration + * @param[out] client_ret Unique pointer to identify the Hub as a USB Host client * @return esp_err_t */ -esp_err_t hub_install(hub_config_t *hub_config); +esp_err_t hub_install(hub_config_t *hub_config, void **client_ret); /** * @brief Uninstall Hub driver @@ -78,15 +79,16 @@ esp_err_t hub_root_start(void); esp_err_t hub_root_stop(void); /** - * @brief Indicate to the Hub driver that a device has been freed + * @brief Indicate to the Hub driver that a device's port can be recycled * - * Hub driver can now recover the port that the device was connected to + * The device connected to the port has been freed. The Hub driver can now + * recycled the port. * - * @param dev_addr Device address + * @param dev_uid Device's unique ID * @return * - ESP_OK: Success */ -esp_err_t hub_dev_is_free(uint8_t dev_addr); +esp_err_t hub_port_recycle(unsigned int dev_uid); /** * @brief Hub driver's processing function diff --git a/components/usb/private_include/usbh.h b/components/usb/private_include/usbh.h index 75be2b1f6685..a1b5b2a8452a 100644 --- a/components/usb/private_include/usbh.h +++ b/components/usb/private_include/usbh.h @@ -58,7 +58,7 @@ typedef struct { usb_device_handle_t dev_hdl; } dev_gone_data; struct { - uint8_t dev_addr; + unsigned int dev_uid; } dev_free_data; }; } usbh_event_data_t; @@ -130,7 +130,7 @@ typedef struct { void *event_cb_arg; /**< USBH event callback argument */ } usbh_config_t; -// ------------------------------------------------- USBH Functions ---------------------------------------------------- +// -------------------------------------------- USBH Processing Functions ---------------------------------------------- /** * @brief Installs the USBH driver @@ -169,6 +169,8 @@ esp_err_t usbh_uninstall(void); */ esp_err_t usbh_process(void); +// ---------------------------------------------- Device Pool Functions ------------------------------------------------ + /** * @brief Get the current number of devices * @@ -176,17 +178,13 @@ esp_err_t usbh_process(void); * @param[out] num_devs_ret Current number of devices * @return esp_err_t */ -esp_err_t usbh_num_devs(int *num_devs_ret); - -// ------------------------------------------------ Device Functions --------------------------------------------------- - -// --------------------- Device Pool ----------------------- +esp_err_t usbh_devs_num(int *num_devs_ret); /** * @brief Fill list with address of currently connected devices * * - This function fills the provided list with the address of current connected devices - * - Device address can then be used in usbh_dev_open() + * - Device address can then be used in usbh_devs_open() * - If there are more devices than the list_len, this function will only fill * up to list_len number of devices. * @@ -195,7 +193,44 @@ esp_err_t usbh_num_devs(int *num_devs_ret); * @param[out] num_dev_ret Number of devices filled into list * @return esp_err_t */ -esp_err_t usbh_dev_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num_dev_ret); +esp_err_t usbh_devs_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num_dev_ret); + +/** + * @brief Create a device and add it to the device pool + * + * The created device will not be enumerated where the device's address is 0, + * device and config descriptor are NULL. The device will still have a default + * pipe, thus allowing control transfers to be submitted. + * + * - Call usbh_devs_open() before communicating with the device + * - Call usbh_dev_enum_lock() before enumerating the device via the various + * usbh_dev_set_...() functions. + * + * @param[in] uid Unique ID assigned to the device + * @param[in] dev_speed Device's speed + * @param[in] port_hdl Handle of the port that the device is connected to + * @return esp_err_t + */ +esp_err_t usbh_devs_add(unsigned int uid, usb_speed_t dev_speed, hcd_port_handle_t port_hdl); + +/** + * @brief Indicates to the USBH that a device is gone + * + * @param[in] uid Unique ID assigned to the device on creation (see 'usbh_devs_add()') + * @return esp_err_t + */ +esp_err_t usbh_devs_remove(unsigned int uid); + +/** + * @brief Mark that all devices should be freed at the next possible opportunity + * + * A device marked as free will not be freed until the last client using the device has called usbh_devs_close() + * + * @return + * - ESP_OK: There were no devices to free to begin with. Current state is all free + * - ESP_ERR_NOT_FINISHED: One or more devices still need to be freed (but have been marked "to be freed") + */ +esp_err_t usbh_devs_mark_all_free(void); /** * @brief Open a device by address @@ -206,30 +241,31 @@ esp_err_t usbh_dev_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num * @param[out] dev_hdl Device handle * @return esp_err_t */ -esp_err_t usbh_dev_open(uint8_t dev_addr, usb_device_handle_t *dev_hdl); +esp_err_t usbh_devs_open(uint8_t dev_addr, usb_device_handle_t *dev_hdl); /** * @brief CLose a device * - * Device can be opened by calling usbh_dev_open() + * Device can be opened by calling usbh_devs_open() * * @param[in] dev_hdl Device handle * @return esp_err_t */ -esp_err_t usbh_dev_close(usb_device_handle_t dev_hdl); +esp_err_t usbh_devs_close(usb_device_handle_t dev_hdl); /** - * @brief Mark that all devices should be freed at the next possible opportunity + * @brief Trigger a USBH_EVENT_NEW_DEV event for the device * - * A device marked as free will not be freed until the last client using the device has called usbh_dev_close() + * This is typically called after a device has been fully enumerated. * - * @return - * - ESP_OK: There were no devices to free to begin with. Current state is all free - * - ESP_ERR_NOT_FINISHED: One or more devices still need to be freed (but have been marked "to be freed") + * @param[in] dev_hdl Device handle + * @return esp_err_t */ -esp_err_t usbh_dev_mark_all_free(void); +esp_err_t usbh_devs_new_dev_event(usb_device_handle_t dev_hdl); -// ------------------- Single Device ---------------------- +// ------------------------------------------------ Device Functions --------------------------------------------------- + +// ----------------------- Getters ------------------------- /** * @brief Get a device's address @@ -245,7 +281,8 @@ esp_err_t usbh_dev_get_addr(usb_device_handle_t dev_hdl, uint8_t *dev_addr); /** * @brief Get a device's information * - * @note This function can block + * @note It is possible that the device has not been enumerated yet, thus some + * fields may be NULL. * @param[in] dev_hdl Device handle * @param[out] dev_info Device information * @return esp_err_t @@ -257,6 +294,8 @@ esp_err_t usbh_dev_get_info(usb_device_handle_t dev_hdl, usb_device_info_t *dev_ * * - The device descriptor is cached when the device is created by the Hub driver * + * @note It is possible that the device has not been enumerated yet, thus the + * device descriptor could be NULL. * @param[in] dev_hdl Device handle * @param[out] dev_desc_ret Device descriptor * @return esp_err_t @@ -268,21 +307,108 @@ esp_err_t usbh_dev_get_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t * * Simply returns a reference to the internally cached configuration descriptor * - * @note This function can block + * @note It is possible that the device has not been enumerated yet, thus the + * configuration descriptor could be NULL. * @param[in] dev_hdl Device handle * @param config_desc_ret * @return esp_err_t */ esp_err_t usbh_dev_get_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t **config_desc_ret); +// ----------------------- Setters ------------------------- + /** - * @brief Submit a control transfer (URB) to a device + * @brief Lock a device for enumeration + * + * - A device's enumeration lock must be set before any of its enumeration fields + * (e.g., address, device/config descriptors) can be set/updated. + * - The caller must be the sole opener of the device (see 'usbh_devs_open()') + * when locking the device for enumeration. * * @param[in] dev_hdl Device handle - * @param[in] urb URB * @return esp_err_t */ -esp_err_t usbh_dev_submit_ctrl_urb(usb_device_handle_t dev_hdl, urb_t *urb); +esp_err_t usbh_dev_enum_lock(usb_device_handle_t dev_hdl); + +/** + * @brief Release a device's enumeration lock + * + * @param[in] dev_hdl Device handle + * @return esp_err_t + */ +esp_err_t usbh_dev_enum_unlock(usb_device_handle_t dev_hdl); + +/** + * @brief Set the maximum packet size of EP0 for a device + * + * Typically called during enumeration after obtaining the first 8 bytes of the + * device's descriptor. + * + * @note The device's enumeration lock must be set before calling this function + * (see 'usbh_dev_enum_lock()') + * @param[in] dev_hdl Device handle + * @param[in] wMaxPacketSize Maximum packet size + * @return esp_err_t + */ +esp_err_t usbh_dev_set_ep0_mps(usb_device_handle_t dev_hdl, uint16_t wMaxPacketSize); + +/** + * @brief Set a device's address + * + * Typically called during enumeration after a SET_ADDRESSS request has be + * sent to the device. + * + * @note The device's enumeration lock must be set before calling this function + * (see 'usbh_dev_enum_lock()') + * @param[in] dev_hdl Device handle + * @param[in] dev_addr + * @return esp_err_t + */ +esp_err_t usbh_dev_set_addr(usb_device_handle_t dev_hdl, uint8_t dev_addr); + +/** + * @brief Set a device's descriptor + * + * Typically called during enumeration after obtaining the device's descriptor + * via a GET_DESCRIPTOR request. + * + * @note The device's enumeration lock must be set before calling this function + * (see 'usbh_dev_enum_lock()') + * @param[in] dev_hdl Device handle + * @param[in] device_desc Device descriptor to copy + * @return esp_err_t + */ +esp_err_t usbh_dev_set_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t *device_desc); + +/** + * @brief Set a device's configuration descriptor + * + * Typically called during enumeration after obtaining the device's configuration + * descriptor via a GET_DESCRIPTOR request. + * + * @note The device's enumeration lock must be set before calling this function + * (see 'usbh_dev_enum_lock()') + * @param[in] dev_hdl Device handle + * @param[in] config_desc_full Configuration descriptor to copy + * @return esp_err_t + */ +esp_err_t usbh_dev_set_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t *config_desc_full); + +/** + * @brief Set a device's string descriptor + * + * Typically called during enumeration after obtaining one of the device's string + * descriptor via a GET_DESCRIPTOR request. + * + * @note The device's enumeration lock must be set before calling this function + * (see 'usbh_dev_enum_lock()') + * @param[in] dev_hdl Device handle + * @param[in] str_desc String descriptor to copy + * @param[in] select Select string descriptor. 0/1/2 for Manufacturer/Product/Serial + * Number string descriptors respectively + * @return esp_err_t + */ +esp_err_t usbh_dev_set_str_desc(usb_device_handle_t dev_hdl, const usb_str_desc_t *str_desc, int select); // ----------------------------------------------- Endpoint Functions ------------------------------------------------- @@ -291,7 +417,7 @@ esp_err_t usbh_dev_submit_ctrl_urb(usb_device_handle_t dev_hdl, urb_t *urb); * * This function allows clients to allocate a non-default endpoint (i.e., not EP0) on a connected device * - * - A client must have opened the device using usbh_dev_open() before attempting to allocate an endpoint on the device + * - A client must have opened the device using usbh_devs_open() before attempting to allocate an endpoint on the device * - A client should call this function to allocate all endpoints in an interface that the client has claimed. * - A client must allocate an endpoint using this function before attempting to communicate with it * - Once the client allocates an endpoint, the client is now owns/manages the endpoint. No other client should use or @@ -334,29 +460,6 @@ esp_err_t usbh_ep_free(usbh_ep_handle_t ep_hdl); */ esp_err_t usbh_ep_get_handle(usb_device_handle_t dev_hdl, uint8_t bEndpointAddress, usbh_ep_handle_t *ep_hdl_ret); -/** - * @brief Enqueue a URB to an endpoint - * - * The URB will remain enqueued until it completes (successfully or errors out). Use usbh_ep_dequeue_urb() to dequeue - * a completed URB. - * - * @param[in] ep_hdl Endpoint handle - * @param[in] urb URB to enqueue - * @return esp_err_t - */ -esp_err_t usbh_ep_enqueue_urb(usbh_ep_handle_t ep_hdl, urb_t *urb); - -/** - * @brief Dequeue a URB from an endpoint - * - * Dequeue a completed URB from an endpoint. The USBH_EP_EVENT_URB_DONE indicates that URBs can be dequeued - * - * @param[in] ep_hdl Endpoint handle - * @param[out] urb_ret Dequeued URB, or NULL if no more URBs to dequeue - * @return esp_err_t - */ -esp_err_t usbh_ep_dequeue_urb(usbh_ep_handle_t ep_hdl, urb_t **urb_ret); - /** * @brief Execute a command on a particular endpoint * @@ -379,109 +482,39 @@ esp_err_t usbh_ep_command(usbh_ep_handle_t ep_hdl, usbh_ep_cmd_t command); */ void *usbh_ep_get_context(usbh_ep_handle_t ep_hdl); -// -------------------------------------------------- Hub Functions ---------------------------------------------------- - -// ------------------- Device Related ---------------------- - -/** - * @brief Indicates to USBH the start of enumeration for a device - * - * - The Hub driver calls this function before it starts enumerating a new device. - * - The USBH will allocate a new device that will be initialized by the Hub driver using the remaining hub enumeration - * functions. - * - The new device's default pipe handle is returned to all the Hub driver to be used during enumeration. - * - * @note Hub Driver only - * @param[in] port_hdl Handle of the port that the device is connected to - * @param[in] dev_speed Device's speed - * @param[out] new_dev_hdl Device's handle - * @param[out] default_pipe_hdl Device's default pipe handle - * @return esp_err_t - */ -esp_err_t usbh_hub_add_dev(hcd_port_handle_t port_hdl, usb_speed_t dev_speed, usb_device_handle_t *new_dev_hdl, hcd_pipe_handle_t *default_pipe_hdl); - -/** - * @brief Indicates to the USBH that a device is gone - * - * @param dev_hdl Device handle - * @return esp_err_t - */ -esp_err_t usbh_hub_dev_gone(usb_device_handle_t dev_hdl); - -// ----------------- Enumeration Related ------------------- - -/** - * @brief Assign the enumerating device's address - * - * @note Hub Driver only - * @note Must call in sequence - * @param[in] dev_hdl Device handle - * @param dev_addr - * @return esp_err_t - */ -esp_err_t usbh_hub_enum_fill_dev_addr(usb_device_handle_t dev_hdl, uint8_t dev_addr); - -/** - * @brief Fill the enumerating device's descriptor - * - * @note Hub Driver only - * @note Must call in sequence - * @param[in] dev_hdl Device handle - * @param device_desc - * @return esp_err_t - */ -esp_err_t usbh_hub_enum_fill_dev_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t *device_desc); +// ----------------------------------------------- Transfer Functions -------------------------------------------------- /** - * @brief Fill the enumerating device's active configuration descriptor + * @brief Submit a control transfer (URB) to a device * - * @note Hub Driver only - * @note Must call in sequence - * @note This function can block * @param[in] dev_hdl Device handle - * @param config_desc_full - * @return esp_err_t - */ -esp_err_t usbh_hub_enum_fill_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t *config_desc_full); - -/** - * @brief Fill one of the string descriptors of the enumerating device - * - * @note Hub Driver only - * @note Must call in sequence - * @param dev_hdl Device handle - * @param str_desc Pointer to string descriptor - * @param select Select which string descriptor. 0/1/2 for Manufacturer/Product/Serial Number string descriptors respectively + * @param[in] urb URB * @return esp_err_t */ -esp_err_t usbh_hub_enum_fill_str_desc(usb_device_handle_t dev_hdl, const usb_str_desc_t *str_desc, int select); +esp_err_t usbh_dev_submit_ctrl_urb(usb_device_handle_t dev_hdl, urb_t *urb); /** - * @brief Indicate the device enumeration is completed + * @brief Enqueue a URB to an endpoint * - * This will allow the device to be opened by clients, and also trigger a USBH_EVENT_NEW_DEV event. + * The URB will remain enqueued until it completes (successfully or errors out). Use usbh_ep_dequeue_urb() to dequeue + * a completed URB. * - * @note Hub Driver only - * @note Must call in sequence - * @note This function can block - * @param[in] dev_hdl Device handle + * @param[in] ep_hdl Endpoint handle + * @param[in] urb URB to enqueue * @return esp_err_t */ -esp_err_t usbh_hub_enum_done(usb_device_handle_t dev_hdl); +esp_err_t usbh_ep_enqueue_urb(usbh_ep_handle_t ep_hdl, urb_t *urb); /** - * @brief Indicate that device enumeration has failed + * @brief Dequeue a URB from an endpoint * - * This will cause the enumerating device's resources to be cleaned up - * The Hub Driver must guarantee that the enumerating device's default pipe is already halted, flushed, and dequeued. + * Dequeue a completed URB from an endpoint. The USBH_EP_EVENT_URB_DONE indicates that URBs can be dequeued * - * @note Hub Driver only - * @note Must call in sequence - * @note This function can block - * @param[in] dev_hdl Device handle + * @param[in] ep_hdl Endpoint handle + * @param[out] urb_ret Dequeued URB, or NULL if no more URBs to dequeue * @return esp_err_t */ -esp_err_t usbh_hub_enum_failed(usb_device_handle_t dev_hdl); +esp_err_t usbh_ep_dequeue_urb(usbh_ep_handle_t ep_hdl, urb_t **urb_ret); #ifdef __cplusplus } diff --git a/components/usb/test_apps/common/CMakeLists.txt b/components/usb/test_apps/common/CMakeLists.txt index f03c668f9efa..047989446dad 100644 --- a/components/usb/test_apps/common/CMakeLists.txt +++ b/components/usb/test_apps/common/CMakeLists.txt @@ -1,3 +1,7 @@ -idf_component_register(SRCS "test_usb_common.c" "test_usb_mock_msc.c" "test_usb_mock_hid.c" +idf_component_register(SRCS "dev_hid.c" + "dev_isoc.c" + "dev_msc.c" + "mock_msc.c" + "test_usb_common.c" INCLUDE_DIRS "." REQUIRES usb unity) diff --git a/components/usb/test_apps/common/dev_hid.c b/components/usb/test_apps/common/dev_hid.c new file mode 100644 index 000000000000..91d52a67b7cf --- /dev/null +++ b/components/usb/test_apps/common/dev_hid.c @@ -0,0 +1,232 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" +#include "dev_hid.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device acting as an HID mouse be connected. That test device's information and descriptors are defined in this file. + +If you are connecting a different HID mouse, please update the descriptor and +getter functions accordingly. + +------------------------------ Device Descriptor ------------------------------- +bLength : 0x12 (18 bytes) +bDescriptorType : 0x01 (Device Descriptor) +bcdUSB : 0x0210 (2.00) +bDeviceClass : 0x00 +bDeviceSubClass : 0x00 +bDeviceProtocol : 0x00 +bMaxPacketSize0 : 0x08 (8 bytes) +idVendor : 0x413C (Dell Computer Corp) +idProduct : 0x301A (Dell MS116 Optical Mouse) +bcdDevice : 0x0100 (1.00) +iManufacturer : 1 +iProduct : 2 +iSerial : 0 +bNumConfigurations : 1 + +--------------------------- Configuration Descriptor --------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x02 (Configuration Descriptor) +wTotalLength : 0x0022 (34 bytes) +bNumInterfaces : 0x01 (1 Interface) +bConfigurationValue : 0x01 (Configuration 1) +iConfiguration : 0x00 (No String Descriptor) +bmAttributes : 0xA0 + D7: Reserved, set 1 : 0x01 + D6: Self Powered : 0x00 (no) + D5: Remote Wakeup : 0x01 (yes) + D4..0: Reserved, set 0 : 0x00 +MaxPower : 0x32 (100 mA) + +Data (HexDump) : 09 02 3B 00 02 01 00 A0 32 09 04 00 00 01 03 01 + 02 00 09 21 00 02 00 01 22 4D 00 07 05 81 03 08 + 00 0A 09 04 01 00 01 03 01 01 00 09 21 00 02 00 + 01 22 31 00 07 05 82 03 08 00 0A + +----------------------------- Interface Descriptor ----------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x04 (Interface Descriptor) +bInterfaceNumber : 0x00 +bAlternateSetting : 0x00 +bNumEndpoints : 0x01 (1 Endpoint) +bInterfaceClass : 0x03 (HID - Human Interface Device) +bInterfaceSubClass : 0x01 (Boot Interface) +bInterfaceProtocol : 0x02 (Mouse) +iInterface : 0x00 (No String Descriptor) + +-------------------------------- HID Descriptor -------------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x21 (HID Descriptor) +bcdHID : 0x0200 (HID Version 2.00) +bCountryCode : 0x00 (00 = not localized) +bNumDescriptors : 0x01 +Descriptor 1: +bDescriptorType : 0x22 (Class=Report) +wDescriptorLength : 0x004D (77 bytes) + +------------------------------ Endpoint Descriptor ----------------------------- +bLength : 0x07 (7 bytes) +bDescriptorType : 0x05 (Endpoint Descriptor) +bEndpointAddress : 0x81 (Direction=IN EndpointID=1) +bmAttributes : 0x03 (TransferType=Interrupt) +wMaxPacketSize : 0x0008 +bInterval : 0x0A (10 ms) + +---------------------------- String Descriptor Manu ---------------------------- +bLength : 0x0E (14 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : "PixArt" + +---------------------------- String Descriptor Prod ---------------------------- +bLength : 0x3A (58 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : "Dell MS116 USB Optical Mouse" +*/ + +// ------------------------------- Descriptors --------------------------------- + +static const usb_device_desc_t dev_desc = { + .bLength = USB_DEVICE_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_DEVICE, + .bcdUSB = 0x0210, // 2.10 + .bDeviceClass = USB_CLASS_PER_INTERFACE, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x413C, // Dell Computer Corp + .idProduct = 0x301A, // Dell MS116 Optical Mouse + .bcdDevice = 0x0100, // 1.00 + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 0, + .bNumConfigurations = 1, +}; + +static const usb_config_desc_t config_desc = { + .bLength = USB_CONFIG_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_CONFIGURATION, + .wTotalLength = 0x0022, // 34 bytes + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0xA0, + .bMaxPower = 0x32, // 100 mA +}; + +static const usb_intf_desc_t intf_desc = { + .bLength = USB_INTF_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 0x01, // Boot Interface + .bInterfaceProtocol = 0x02, // Mouse + .iInterface = 0, // (No String Descriptor) +}; + +const usb_ep_desc_t in_ep_desc = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x81, // EP 1 IN + .bmAttributes = USB_BM_ATTRIBUTES_XFER_INT, + .wMaxPacketSize = 0x0008, + .bInterval = 0x0A, // 10 ms +}; + +/* +String descriptors are dynamically initialized due to issues with static +initialization of variable length array members. See IDF-9886. +*/ + +static const usb_str_desc_t str_desc_manu_base = { + .bLength = sizeof(usb_str_desc_t) + (6 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_manu_data[] = { + 0x0050, // 'P' + 0x0069, // 'i' + 0x0078, // 'x' + 0x0041, // 'A' + 0x0072, // 'r' + 0x0074, // 't' +}; +static uint8_t *str_desc_manu[sizeof(str_desc_manu_base) + sizeof(str_desc_manu_data)]; + +static const usb_str_desc_t str_desc_prod_base = { + .bLength = sizeof(usb_str_desc_t) + (28 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_prod_data[] = { + /* + The following string encoded in UTF-16LE + + "Dell MS116 USB Optical Mouse" + */ + 0x0044, 0x0065, 0x006c, 0x006c, 0x0020, 0x004d, 0x0053, 0x0031, 0x0031, + 0x0036, 0x0020, 0x0055, 0x0053, 0x0042, 0x0020, 0x004f, 0x0070, 0x0074, + 0x0069, 0x0063, 0x0061, 0x006c, 0x0020, 0x004d, 0x006f, 0x0075, 0x0073, + 0x0065, +}; +static uint8_t *str_desc_prod[sizeof(str_desc_prod_base) + sizeof(str_desc_prod_data)]; + +// -------------------------------- Functions ---------------------------------- + +void dev_hid_init(void) +{ + // Dynamically initialize string descriptors due to compiler limitations (see IDF-9886) + uint8_t *ptr; + + // Initialize manufacturer string descriptor + ptr = (uint8_t *)str_desc_manu; + memcpy(ptr, &str_desc_manu_base, sizeof(str_desc_manu_base)); + ptr += sizeof(str_desc_manu_base); + memcpy(ptr, &str_desc_manu_data, sizeof(str_desc_manu_data)); + + // Initialize product string descriptor + ptr = (uint8_t *)str_desc_prod; + memcpy(ptr, &str_desc_prod_base, sizeof(str_desc_prod_base)); + ptr += sizeof(str_desc_prod_base); + memcpy(ptr, &str_desc_prod_data, sizeof(str_desc_prod_data)); + + // No serial string descriptor +} + +const usb_device_desc_t *dev_hid_get_dev_desc(usb_speed_t speed) +{ + return &dev_desc; +} + +const usb_config_desc_t *dev_hid_get_config_desc(usb_speed_t speed) +{ + return &config_desc; +} + +const usb_intf_desc_t *dev_hid_get_intf_desc(usb_speed_t speed) +{ + return &intf_desc; +} + +const usb_ep_desc_t *dev_hid_get_in_ep_desc(usb_speed_t speed) +{ + return &in_ep_desc; +} + +const usb_str_desc_t *dev_hid_get_str_desc_manu(void) +{ + return (const usb_str_desc_t *)str_desc_manu; +} + +const usb_str_desc_t *dev_hid_get_str_desc_prod(void) +{ + return (const usb_str_desc_t *)str_desc_prod; +} diff --git a/components/usb/test_apps/common/dev_hid.h b/components/usb/test_apps/common/dev_hid.h new file mode 100644 index 000000000000..a0eb581e3d24 --- /dev/null +++ b/components/usb/test_apps/common/dev_hid.h @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device acting as an HID mouse be connected. That test device's information and descriptors are defined in this file. + +If you are connecting a different device, please update the descriptors in +dev_hid.c accordingly. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the test device + * + * @note Call this before running tests. This is necessary due to IDF-9886 + */ +void dev_hid_init(void); + +/** + * @brief Get the test device's descriptor + * + * @param[in] speed Test device's current speed + * @return Device descriptor + */ +const usb_device_desc_t *dev_hid_get_dev_desc(usb_speed_t speed); + +/** + * @brief Get the test device's configuration descriptor + * + * @param[in] speed Test device's current speed + * @return Configuration descriptor + */ +const usb_config_desc_t *dev_hid_get_config_desc(usb_speed_t speed); + +/** + * @brief Get the test device's HID interface descriptor + * + * @param[in] speed Test device's current speed + * @return HID interface descriptor + */ +const usb_intf_desc_t *dev_hid_get_intf_desc(usb_speed_t speed); + +/** + * @brief Get the test device's HID interrupt IN endpoint descriptor + * + * @param[in] speed Test device's current speed + * @return Interrupt IN endpoint descriptor + */ +const usb_ep_desc_t *dev_hid_get_in_ep_desc(usb_speed_t speed); + +/** + * @brief Get the test device's manufacturer string descriptor + * + * @return Manufacturer string descriptor + */ +const usb_str_desc_t *dev_hid_get_str_desc_manu(void); + +/** + * @brief Get the test device's product string descriptor + * + * @return Product string descriptor + */ +const usb_str_desc_t *dev_hid_get_str_desc_prod(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb/test_apps/common/dev_isoc.c b/components/usb/test_apps/common/dev_isoc.c new file mode 100644 index 000000000000..6cf1eb52f6d5 --- /dev/null +++ b/components/usb/test_apps/common/dev_isoc.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" +#include "dev_isoc.h" + +// ------------------------------- Descriptors --------------------------------- + +static const usb_ep_desc_t isoc_out_ep_desc = { + .bLength = sizeof(usb_ep_desc_t), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x02, // EP 2 OUT + .bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC, + .wMaxPacketSize = 512, + .bInterval = 1, // Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms +}; + +// -------------------------------- Functions ---------------------------------- + +const usb_ep_desc_t *dev_isoc_get_out_ep_desc(usb_speed_t speed) +{ + return &isoc_out_ep_desc; +} diff --git a/components/usb/test_apps/common/dev_isoc.h b/components/usb/test_apps/common/dev_isoc.h new file mode 100644 index 000000000000..9096179ac373 --- /dev/null +++ b/components/usb/test_apps/common/dev_isoc.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device containing an ISOC endpoint be connected. This header contains +functions to get information and descriptors about that test device. + +If you are connecting a different device, please update the descriptors in +dev_isoc.c accordingly. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get the test device's ISOC OUT endpoint descriptor + * + * @param[in] speed Test device's current speed + * @return ISOC OUT endpoint descriptor + */ +const usb_ep_desc_t *dev_isoc_get_out_ep_desc(usb_speed_t speed); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb/test_apps/common/dev_msc.c b/components/usb/test_apps/common/dev_msc.c new file mode 100644 index 000000000000..6d5d93d2246e --- /dev/null +++ b/components/usb/test_apps/common/dev_msc.c @@ -0,0 +1,354 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "usb/usb_types_ch9.h" +#include "dev_msc.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device acting as a MSC SCSI flash drive be connected. That test device's +information and descriptors are defined in this file. + +If you are connecting a different MSC SCSI flash drive, please update +the descriptor and getter functions accordingly. + +------------------------------ Device Descriptor ------------------------------- +bLength : 0x12 (18 bytes) +bDescriptorType : 0x01 (Device Descriptor) +bcdUSB : 0x0210 (2.10) +bDeviceClass : 0x00 +bDeviceSubClass : 0x00 +bDeviceProtocol : 0x00 +bMaxPacketSize0 : 0x40 (64 bytes) +idVendor : 0x0781 (SanDisk Corp) +idProduct : 0x5595 +bcdDevice : 0x0100 (1.00) +iManufacturer : 1 +iProduct : 2 +iSerial : 3 +bNumConfigurations : 1 + +--------------------------- Configuration Descriptor --------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x02 (Configuration Descriptor) +wTotalLength : 0x0020 (32 bytes) +bNumInterfaces : 0x01 (1 Interface) +bConfigurationValue : 0x01 (Configuration 1) +iConfiguration : 0x00 (No String Descriptor) +bmAttributes : 0x80 + D7: Reserved, set 1 : 0x01 + D6: Self Powered : 0x00 (no) + D5: Remote Wakeup : 0x00 (no) + D4..0: Reserved, set 0 : 0x00 +MaxPower : 0x70 (224 mA) + +Data (HexDump) : 09 02 20 00 01 01 00 80 70 09 04 00 00 02 08 06 + 50 00 07 05 81 02 00 02 00 07 05 02 02 00 02 00 + +----------------------------- Interface Descriptor ----------------------------- +bLength : 0x09 (9 bytes) +bDescriptorType : 0x04 (Interface Descriptor) +bInterfaceNumber : 0x00 +bAlternateSetting : 0x00 +bNumEndpoints : 0x02 (2 Endpoints) +bInterfaceClass : 0x08 (Mass Storage) +bInterfaceSubClass : 0x06 (SCSI transparent command set) +bInterfaceProtocol : 0x50 (Bulk-Only Transport) +iInterface : 0x00 (No String Descriptor) + +------------------------------ Endpoint Descriptor ----------------------------- +bLength : 0x07 (7 bytes) +bDescriptorType : 0x05 (Endpoint Descriptor) +bEndpointAddress : 0x81 (Direction=IN EndpointID=1) +bmAttributes : 0x02 (TransferType=Bulk) +wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytes for HS) +bInterval : 0x00 (never NAKs) + +------------------------------ Endpoint Descriptor ----------------------------- +bLength : 0x07 (7 bytes) +bDescriptorType : 0x05 (Endpoint Descriptor) +bEndpointAddress : 0x02 (Direction=OUT EndpointID=2) +bmAttributes : 0x02 (TransferType=Bulk) +wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytes for HS) +bInterval : 0x00 (never NAKs) + +---------------------------- String Descriptor Manu ---------------------------- +bLength : 0x0A (10 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : " USB" + +---------------------------- String Descriptor Prod ---------------------------- +bLength : 0x22 (34 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : " SanDisk 3.2Gen1" + +----------------------------- String Descriptor Ser ---------------------------- +bLength : 0xF2 (242 bytes) +bDescriptorType : 0x03 (String Descriptor) +wData : "0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000000000000000096abe1a3ff83610095558107aea948b4" +*/ + +// --------------------------- Device Information ------------------------------ + +static const dev_msc_info_t dev_info = { + .bInterfaceNumber = 0x00, + .bAlternateSetting = 0x00, + .in_ep_addr = 0x81, + .out_up_addr = 0x02, + .scsi_sector_size = 512, +}; + +// ------------------------------- Descriptors --------------------------------- + +static const usb_device_desc_t dev_desc = { + .bLength = USB_DEVICE_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_DEVICE, + .bcdUSB = 0x0210, // 2.10 + .bDeviceClass = USB_CLASS_PER_INTERFACE, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x0781, // SanDisk Corp + .idProduct = 0x5595, + .bcdDevice = 0x0100, // 1.00 + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +static const usb_config_desc_t config_desc = { + .bLength = USB_CONFIG_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_CONFIGURATION, + .wTotalLength = 0x0020, // 32 bytes + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x70, // 224 mA +}; + +static const usb_intf_desc_t intf_desc = { + .bLength = USB_INTF_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_MASS_STORAGE, + .bInterfaceSubClass = 0x06, //SCSI + .bInterfaceProtocol = 0x50, //Bulk only + .iInterface = 0, +}; + +static const usb_ep_desc_t in_ep_desc_fs = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x81, // EP 1 IN + .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, + .wMaxPacketSize = 64, + .bInterval = 0, +}; + +static const usb_ep_desc_t in_ep_desc_hs = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x81, // EP 1 IN + .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, + .wMaxPacketSize = 512, + .bInterval = 0, +}; + +static const usb_ep_desc_t out_ep_desc_fs = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x02, // EP 2 OUT + .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, + .wMaxPacketSize = 64, + .bInterval = 0, +}; + +static const usb_ep_desc_t out_ep_desc_hs = { + .bLength = USB_EP_DESC_SIZE, + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, + .bEndpointAddress = 0x02, // EP 2 OUT + .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, + .wMaxPacketSize = 512, + .bInterval = 0, +}; + +/* +String descriptors are dynamically initialized due to issues with static +initialization of variable length array members. See IDF-9886. +*/ + +static const usb_str_desc_t str_desc_manu_base = { + .bLength = sizeof(usb_str_desc_t) + (4 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_manu_data[] = { + 0x0020, // ' ' + 0x0055, // 'U' + 0x0053, // 'S' + 0x0042, // 'B' +}; +static uint8_t *str_desc_manu[sizeof(str_desc_manu_base) + sizeof(str_desc_manu_data)]; + +static const usb_str_desc_t str_desc_prod_base = { + .bLength = sizeof(usb_str_desc_t) + (16 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_prod_data[] = { + 0x0020, // ' ' + 0x0053, // 'S' + 0x0061, // 'a' + 0x006e, // 'n' + 0x0044, // 'D' + 0x0069, // 'i' + 0x0073, // 's' + 0x006b, // 'k' + 0x0020, // ' ' + 0x0033, // '3' + 0x002e, // '.' + 0x0032, // '2' + 0x0047, // 'G' + 0x0065, // 'e' + 0x006e, // 'n' + 0x0031, // '1' +}; +static uint8_t *str_desc_prod[sizeof(str_desc_prod_base) + sizeof(str_desc_prod_data)]; + +static const usb_str_desc_t str_desc_ser_base = { + .bLength = sizeof(usb_str_desc_t) + (120 * sizeof(uint16_t)), + .bDescriptorType = USB_B_DESCRIPTOR_TYPE_STRING, +}; +static const uint16_t str_desc_ser_data[] = { + /* + The following string encoded in UTF-16LE + + "0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000 + 000000000000096abe1a3ff83610095558107aea948b4" + */ + 0x0030, 0x0031, 0x0030, 0x0031, 0x0063, 0x0064, 0x0064, 0x0031, 0x0065, + 0x0038, 0x0035, 0x0036, 0x0062, 0x0034, 0x0032, 0x0037, 0x0062, 0x0062, + 0x0062, 0x0037, 0x0039, 0x0036, 0x0066, 0x0038, 0x0037, 0x0030, 0x0035, + 0x0036, 0x0031, 0x0061, 0x0034, 0x0062, 0x0032, 0x0062, 0x0038, 0x0031, + 0x0037, 0x0061, 0x0066, 0x0039, 0x0064, 0x0061, 0x0039, 0x0038, 0x0037, + 0x0032, 0x0063, 0x0038, 0x0064, 0x0037, 0x0035, 0x0032, 0x0031, 0x0037, + 0x0063, 0x0063, 0x0063, 0x0064, 0x0064, 0x0035, 0x0064, 0x0035, 0x0065, + 0x0063, 0x0063, 0x0062, 0x0033, 0x0061, 0x0030, 0x0030, 0x0030, 0x0030, + 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, + 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0039, 0x0036, + 0x0061, 0x0062, 0x0065, 0x0031, 0x0061, 0x0033, 0x0066, 0x0066, 0x0038, + 0x0033, 0x0036, 0x0031, 0x0030, 0x0030, 0x0039, 0x0035, 0x0035, 0x0035, + 0x0038, 0x0031, 0x0030, 0x0037, 0x0061, 0x0065, 0x0061, 0x0039, 0x0034, + 0x0038, 0x0062, 0x0034, +}; +static uint8_t *str_desc_ser[sizeof(str_desc_ser_base) + sizeof(str_desc_ser_data)]; + +// -------------------------------- Functions ---------------------------------- + +void dev_msc_init(void) +{ + // Dynamically initialize string descriptors due to compiler limitations (see IDF-9886) + uint8_t *ptr; + + // Initialize manufacturer string descriptor + ptr = (uint8_t *)str_desc_manu; + memcpy(ptr, &str_desc_manu_base, sizeof(str_desc_manu_base)); + ptr += sizeof(str_desc_manu_base); + memcpy(ptr, &str_desc_manu_data, sizeof(str_desc_manu_data)); + + // Initialize product string descriptor + ptr = (uint8_t *)str_desc_prod; + memcpy(ptr, &str_desc_prod_base, sizeof(str_desc_prod_base)); + ptr += sizeof(str_desc_prod_base); + memcpy(ptr, &str_desc_prod_data, sizeof(str_desc_prod_data)); + + // Initialize serial string descriptor + ptr = (uint8_t *)str_desc_ser; + memcpy(ptr, &str_desc_ser_base, sizeof(str_desc_ser_base)); + ptr += sizeof(str_desc_ser_base); + memcpy(ptr, &str_desc_ser_data, sizeof(str_desc_ser_data)); +} + +const dev_msc_info_t *dev_msc_get_info(void) +{ + return &dev_info; +} + +const usb_device_desc_t *dev_msc_get_dev_desc(usb_speed_t speed) +{ + return &dev_desc; +} + +const usb_config_desc_t *dev_msc_get_config_desc(usb_speed_t speed) +{ + return &config_desc; +} + +const usb_intf_desc_t *dev_msc_get_intf_desc(usb_speed_t speed) +{ + return &intf_desc; +} + +const usb_ep_desc_t *dev_msc_get_in_ep_desc(usb_speed_t speed) +{ + const usb_ep_desc_t *ret; + + // EP descriptor differs by speed due to MPS + switch (speed) { + case USB_SPEED_FULL: + ret = &in_ep_desc_fs; + break; + case USB_SPEED_HIGH: + ret = &in_ep_desc_hs; + break; + default: + ret = NULL; + abort(); // Should never occur + break; + } + + return ret; +} + +const usb_ep_desc_t *dev_msc_get_out_ep_desc(usb_speed_t speed) +{ + const usb_ep_desc_t *ret; + + // EP descriptor differs by speed due to MPS + switch (speed) { + case USB_SPEED_FULL: + ret = &out_ep_desc_fs; + break; + case USB_SPEED_HIGH: + ret = &out_ep_desc_hs; + break; + default: + ret = NULL; + abort(); // Should never occur + break; + } + + return ret; +} + +const usb_str_desc_t *dev_msc_get_str_desc_manu(void) +{ + return (const usb_str_desc_t *)str_desc_manu; +} + +const usb_str_desc_t *dev_msc_get_str_desc_prod(void) +{ + return (const usb_str_desc_t *)str_desc_prod; +} + +const usb_str_desc_t *dev_msc_get_str_desc_ser(void) +{ + return (const usb_str_desc_t *)str_desc_ser; +} diff --git a/components/usb/test_apps/common/dev_msc.h b/components/usb/test_apps/common/dev_msc.h new file mode 100644 index 000000000000..ac21ca952e29 --- /dev/null +++ b/components/usb/test_apps/common/dev_msc.h @@ -0,0 +1,118 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "usb/usb_types_ch9.h" +#include "usb/usb_types_stack.h" + +/* +Some tests where the ESP (acting as host) will require that a particular test +device acting as a MSC SCSI flash drive be connected. This header contains +functions to get information and descriptors about that test device. + +If you are connecting a different MSC SCSI flash drive, please update +the descriptors in dev_msc.c accordingly. +*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief MSC SCSI test device information + * + * Structure containing basic information about the the MSC SCSI interface on + * the test device. + */ +typedef struct { + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t in_ep_addr; + uint8_t out_up_addr; + unsigned int scsi_sector_size; +} dev_msc_info_t; + +/** + * @brief Initialize the test device + * + * @note Call this before running tests. This is necessary due to IDF-9886 + */ +void dev_msc_init(void); + +/** + * @brief Get information about the test device's MSC SCSI interface + * + * @return Information object + */ +const dev_msc_info_t *dev_msc_get_info(void); + +/** + * @brief Get the test device's descriptor + * + * @param[in] speed Test device's current speed + * @return Device descriptor + */ +const usb_device_desc_t *dev_msc_get_dev_desc(usb_speed_t speed); + +/** + * @brief Get the test device's configuration descriptor + * + * @param[in] speed Test device's current speed + * @return Configuration descriptor + */ +const usb_config_desc_t *dev_msc_get_config_desc(usb_speed_t speed); + +/** + * @brief Get the test device's MSC interface descriptor + * + * @param[in] speed Test device's current speed + * @return MSC interface descriptor + */ +const usb_intf_desc_t *dev_msc_get_intf_desc(usb_speed_t speed); + +/** + * @brief Get the test device's MSC IN endpoint descriptor + * + * @param[in] speed Test device's current speed + * @return MSC IN endpoint descriptor + */ +const usb_ep_desc_t *dev_msc_get_in_ep_desc(usb_speed_t speed); + +/** + * @brief Get the test device's MSC OUT endpoint descriptor + * + * @param[in] speed Test device's current speed + * @return MSC OUT endpoint descriptor + */ +const usb_ep_desc_t *dev_msc_get_out_ep_desc(usb_speed_t speed); + +/** + * @brief Get the test device's manufacturer string descriptor + * + * @return Manufacturer string descriptor + */ +const usb_str_desc_t *dev_msc_get_str_desc_manu(void); + +/** + * @brief Get the test device's product string descriptor + * + * @return Product string descriptor + */ +const usb_str_desc_t *dev_msc_get_str_desc_prod(void); + +/** + * @brief Get the test device's serial number string descriptor + * + * @return Serial number string descriptor + */ +const usb_str_desc_t *dev_msc_get_str_desc_ser(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb/test_apps/common/mock_msc.c b/components/usb/test_apps/common/mock_msc.c new file mode 100644 index 000000000000..30538f0f7f63 --- /dev/null +++ b/components/usb/test_apps/common/mock_msc.c @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "usb/usb_types_ch9.h" +#include "mock_msc.h" + +// ---------------------------------------------------- MSC SCSI ------------------------------------------------------- + +const char *MSC_CLIENT_TAG = "MSC Client"; + +void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, + bool is_read, + unsigned int offset, + unsigned int num_sectors, + unsigned int sector_size, + uint32_t tag) +{ + cbw->dCBWSignature = 0x43425355; // Fixed value + cbw->dCBWTag = tag; // Random value that is echoed back + cbw->dCBWDataTransferLength = num_sectors * sector_size; + cbw->bmCBWFlags = (is_read) ? (1 << 7) : 0; // If this is a read, set the direction flag + cbw->bCBWLUN = 0; + cbw->bCBWCBLength = 10; // The length of the SCSI command + // Initialize SCSI CMD as READ10 or WRITE 10 + cbw->CBWCB.opcode = (is_read) ? 0x28 : 0x2A; // SCSI CMD READ10 or WRITE10 + cbw->CBWCB.flags = 0; + cbw->CBWCB.lba_3 = (offset >> 24); + cbw->CBWCB.lba_2 = (offset >> 16); + cbw->CBWCB.lba_1 = (offset >> 8); + cbw->CBWCB.lba_0 = (offset >> 0); + cbw->CBWCB.group = 0; + cbw->CBWCB.len_1 = (num_sectors >> 8); + cbw->CBWCB.len_0 = (num_sectors >> 0); + cbw->CBWCB.control = 0; +} + +bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect) +{ + bool no_issues = true; + if (csw->dCSWSignature != 0x53425355) { + no_issues = false; + printf("Warning: csw signature corrupt (0x%"PRIX32")\n", csw->dCSWSignature); + } + if (csw->dCSWTag != tag_expect) { + no_issues = false; + printf("Warning: csw tag unexpected! Expected %"PRIu32" got %"PRIu32"\n", tag_expect, csw->dCSWTag); + } + if (csw->dCSWDataResidue) { + no_issues = false; + printf("Warning: csw indicates data residue of %"PRIu32" bytes!\n", csw->dCSWDataResidue); + } + if (csw->bCSWStatus) { + no_issues = false; + printf("Warning: csw indicates non-good status %d!\n", csw->bCSWStatus); + } + return no_issues; +} diff --git a/components/usb/test_apps/common/mock_msc.h b/components/usb/test_apps/common/mock_msc.h new file mode 100644 index 000000000000..17e347d49abb --- /dev/null +++ b/components/usb/test_apps/common/mock_msc.h @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_assert.h" +#include "usb/usb_types_ch9.h" + +/* +This header contains bare-bone mock implementations of the MSC SCSI class +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern const char *MSC_CLIENT_TAG; + +#define MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt_ptr, intf_num) ({ \ + (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \ + (setup_pkt_ptr)->bRequest = 0xFF; \ + (setup_pkt_ptr)->wValue = 0; \ + (setup_pkt_ptr)->wIndex = (intf_num); \ + (setup_pkt_ptr)->wLength = 0; \ +}) + +typedef struct __attribute__((packed)) +{ + uint8_t opcode; //0x28 = read(10), 0x2A=write(10) + uint8_t flags; + uint8_t lba_3; + uint8_t lba_2; + uint8_t lba_1; + uint8_t lba_0; + uint8_t group; + uint8_t len_1; + uint8_t len_0; + uint8_t control; +} mock_scsi_cmd10_t; + +typedef struct __attribute__((packed)) +{ + uint32_t dCBWSignature; + uint32_t dCBWTag; + uint32_t dCBWDataTransferLength; + uint8_t bmCBWFlags; + uint8_t bCBWLUN; + uint8_t bCBWCBLength; + mock_scsi_cmd10_t CBWCB; + uint8_t padding[6]; +} mock_msc_bulk_cbw_t; + +// USB Bulk Transfer Command Status Wrapper data +typedef struct __attribute__((packed)) +{ + uint32_t dCSWSignature; + uint32_t dCSWTag; + uint32_t dCSWDataResidue; + uint8_t bCSWStatus; +} mock_msc_bulk_csw_t; + +/** + * @brief Initialize a MSC Command Block Wrapper (CBW) as an SCSI command + * + * @param[in] cbw CBW structure + * @param[in] is_read Is a read command + * @param[in] offset Block offset + * @param[in] num_sectors Number of sectors to read + * @param[in] sector_size Size of each sector in bytes + * @param[in] tag Tag (this is simply echoed back + */ +void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, + bool is_read, + unsigned int offset, + unsigned int num_sectors, + unsigned int sector_size, + uint32_t tag); + +/** + * @brief Check that returned Command Status Wrapper (CSW) is valid + * + * @param[in] csw CSW structure + * @param[in] tag_expect Expected tag + * @return True if CSW is valid, false otherwise + */ +bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect); + +/** + * @brief Construct configuration and string descriptors + */ +void mock_msc_scsi_init_reference_descriptors(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb/test_apps/common/test_usb_common.c b/components/usb/test_apps/common/test_usb_common.c index 2fa98b3dabba..09345017625f 100644 --- a/components/usb/test_apps/common/test_usb_common.c +++ b/components/usb/test_apps/common/test_usb_common.c @@ -17,12 +17,12 @@ static usb_phy_handle_t phy_hdl = NULL; void test_usb_init_phy(void) { - //Initialize the internal USB PHY to connect to the USB OTG peripheral + // Initialize the internal USB PHY to connect to the USB OTG peripheral usb_phy_config_t phy_config = { .controller = USB_PHY_CTRL_OTG, .target = USB_PHY_TARGET_INT, .otg_mode = USB_OTG_MODE_HOST, - .otg_speed = USB_PHY_SPEED_UNDEFINED, //In Host mode, the speed is determined by the connected device + .otg_speed = USB_PHY_SPEED_UNDEFINED, // In Host mode, the speed is determined by the connected device .ext_io_conf = NULL, .otg_io_conf = NULL, }; @@ -31,7 +31,7 @@ void test_usb_init_phy(void) void test_usb_deinit_phy(void) { - //Deinitialize the internal USB PHY + // Deinitialize the internal USB PHY TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_del_phy(phy_hdl), "Failed to delete PHY"); phy_hdl = NULL; } @@ -39,7 +39,7 @@ void test_usb_deinit_phy(void) void test_usb_set_phy_state(bool connected, TickType_t delay_ticks) { if (delay_ticks > 0) { - //Delay of 0 ticks causes a yield. So skip if delay_ticks is 0. + // Delay of 0 ticks causes a yield. So skip if delay_ticks is 0. vTaskDelay(delay_ticks); } ESP_ERROR_CHECK(usb_phy_action(phy_hdl, (connected) ? USB_PHY_ACTION_HOST_ALLOW_CONN : USB_PHY_ACTION_HOST_FORCE_DISCONN)); diff --git a/components/usb/test_apps/common/test_usb_mock_hid.c b/components/usb/test_apps/common/test_usb_mock_hid.c deleted file mode 100644 index ea7dc32af9b6..000000000000 --- a/components/usb/test_apps/common/test_usb_mock_hid.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include "usb/usb_types_ch9.h" -#include "test_usb_mock_hid.h" - -// ---------------------------------------------------- HID Mouse ------------------------------------------------------ - -const usb_ep_desc_t mock_hid_mouse_in_ep_desc = { - .bLength = sizeof(usb_ep_desc_t), - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = MOCK_HID_MOUSE_INTR_IN_EP_ADDR, //EP 1 IN - .bmAttributes = USB_BM_ATTRIBUTES_XFER_INT, - .wMaxPacketSize = MOCK_HID_MOUSE_INTR_IN_MPS, - .bInterval = 10, //Interval of 10ms -}; - -void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter) -{ - static int x_pos = 0; - static int y_pos = 0; - //Update X position - if (report->x_movement & 0x80) { //Positive movement - x_pos += report->x_movement & 0x7F; - } else { //Negative movement - x_pos -= report->x_movement & 0x7F; - } - //Update Y position - if (report->y_movement & 0x80) { //Positive movement - y_pos += report->y_movement & 0x7F; - } else { //Negative movement - y_pos -= report->y_movement & 0x7F; - } - printf("\rX:%d\tY:%d\tIter: %d\n", x_pos, y_pos, iter); -} diff --git a/components/usb/test_apps/common/test_usb_mock_hid.h b/components/usb/test_apps/common/test_usb_mock_hid.h deleted file mode 100644 index a9a145fbdfc2..000000000000 --- a/components/usb/test_apps/common/test_usb_mock_hid.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* -This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB -Host stack. -*/ - -#pragma once - -#include -#include -#include "esp_assert.h" -#include "usb/usb_types_ch9.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// ---------------------------------------------------- HID Mouse ------------------------------------------------------ - -/* -Note: The mock HID mouse tests require that USB low speed mouse be connected. The mouse should... - -- Be implement the HID with standard report format used by mice -- It's configuration 1 should have the following endpoint - - ------------------ Configuration Descriptor ------------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x02 (Configuration Descriptor) -wTotalLength : 0x003B (59 bytes) -bNumInterfaces : 0x02 (2 Interfaces) -bConfigurationValue : 0x01 (Configuration 1) -iConfiguration : 0x00 (No String Descriptor) -bmAttributes : 0xA0 - D7: Reserved, set 1 : 0x01 - D6: Self Powered : 0x00 (no) - D5: Remote Wakeup : 0x01 (yes) - D4..0: Reserved, set 0 : 0x00 -MaxPower : 0x32 (100 mA) -Data (HexDump) : 09 02 3B 00 02 01 00 A0 32 09 04 00 00 01 03 01 - 02 00 09 21 00 02 00 01 22 4D 00 07 05 81 03 08 - 00 0A 09 04 01 00 01 03 01 01 00 09 21 00 02 00 - 01 22 31 00 07 05 82 03 08 00 0A - - ---------------- Interface Descriptor ----------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x04 (Interface Descriptor) -bInterfaceNumber : 0x00 -bAlternateSetting : 0x00 -bNumEndpoints : 0x01 (1 Endpoint) -bInterfaceClass : 0x03 (HID - Human Interface Device) -bInterfaceSubClass : 0x01 (Boot Interface) -bInterfaceProtocol : 0x02 (Mouse) -iInterface : 0x00 (No String Descriptor) -Data (HexDump) : 09 04 00 00 01 03 01 02 00 - - ------------------- HID Descriptor -------------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x21 (HID Descriptor) -bcdHID : 0x0200 (HID Version 2.00) -bCountryCode : 0x00 (00 = not localized) -bNumDescriptors : 0x01 -Data (HexDump) : 09 21 00 02 00 01 22 4D 00 -Descriptor 1: -bDescriptorType : 0x22 (Class=Report) -wDescriptorLength : 0x004D (77 bytes) -Error reading descriptor : ERROR_INVALID_PARAMETER (due to a obscure limitation of the Win32 USB API, see UsbTreeView.txt) - - ----------------- Endpoint Descriptor ----------------- -bLength : 0x07 (7 bytes) -bDescriptorType : 0x05 (Endpoint Descriptor) -bEndpointAddress : 0x81 (Direction=IN EndpointID=1) -bmAttributes : 0x03 (TransferType=Interrupt) -wMaxPacketSize : 0x0008 -bInterval : 0x0A (10 ms) -Data (HexDump) : 07 05 81 03 08 00 0A - -If you're using another mice with different endpoints, modify the endpoint descriptor below -*/ - -extern const usb_ep_desc_t mock_hid_mouse_in_ep_desc; - -#define MOCK_HID_MOUSE_DEV_ID_VENDOR 0x03F0 -#define MOCK_HID_MOUSE_DEV_ID_PRODUCT 0x1198 -#define MOCK_HID_MOUSE_DEV_DFLT_EP_MPS 8 -#define MOCK_HID_MOUSE_INTF_NUMBER 0 -#define MOCK_HID_MOUSE_INTF_ALT_SETTING 0 -#define MOCK_HID_MOUSE_INTR_IN_EP_ADDR 0x81 -#define MOCK_HID_MOUSE_INTR_IN_MPS 8 - -typedef union { - struct { - uint32_t left_button: 1; - uint32_t right_button: 1; - uint32_t middle_button: 1; - uint32_t reserved5: 5; - uint8_t x_movement; - uint8_t y_movement; - } __attribute__((packed)); - uint8_t val[3]; -} mock_hid_mouse_report_t; -ESP_STATIC_ASSERT(sizeof(mock_hid_mouse_report_t) == 3, "Size of HID mouse report incorrect"); - -void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter); - -#ifdef __cplusplus -} -#endif diff --git a/components/usb/test_apps/common/test_usb_mock_msc.c b/components/usb/test_apps/common/test_usb_mock_msc.c deleted file mode 100644 index 6f7526023664..000000000000 --- a/components/usb/test_apps/common/test_usb_mock_msc.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include "usb/usb_types_ch9.h" -#include "test_usb_mock_msc.h" - -// ---------------------------------------------------- MSC SCSI ------------------------------------------------------- - -const char *MSC_CLIENT_TAG = "MSC Client"; - -const usb_device_desc_t mock_msc_scsi_dev_desc = { - .bLength = USB_DEVICE_DESC_SIZE, - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_DEVICE, - .bcdUSB = MOCK_MSC_SCSI_USB_VERSION, - .bDeviceClass = USB_CLASS_PER_INTERFACE, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = MOCK_MSC_SCSI_DEV_DFLT_EP_MPS, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, - .bcdDevice = MOCK_MSC_SCSI_DEV_VERSION, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigurations = 1, -}; - -#define MOCK_MSC_SCSI_WTOTALLENGTH (USB_CONFIG_DESC_SIZE + USB_INTF_DESC_SIZE + 2*USB_EP_DESC_SIZE) -static const usb_config_desc_t mock_msc_config_desc = { - .bLength = USB_CONFIG_DESC_SIZE, - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_CONFIGURATION, - .wTotalLength = MOCK_MSC_SCSI_WTOTALLENGTH, - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = 0, - .bmAttributes = 0x80, - .bMaxPower = 0x70, //224mA -}; - -static const usb_intf_desc_t mock_msc_intf_desc = { - .bLength = USB_INTF_DESC_SIZE, - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_INTERFACE, - .bInterfaceNumber = MOCK_MSC_SCSI_INTF_NUMBER, - .bAlternateSetting = MOCK_MSC_SCSI_INTF_ALT_SETTING, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = 0x06, //SCSI - .bInterfaceProtocol = 0x50, //Bulk only - .iInterface = 0, -}; - -uint8_t mock_msc_scsi_config_desc[255]; -uint16_t mock_msc_scsi_str_desc_manu[128]; -uint16_t mock_msc_scsi_str_desc_prod[128]; -uint16_t mock_msc_scsi_str_desc_ser_num[128]; -usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc; -usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc; - -const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc_fs = { - .bLength = sizeof(usb_ep_desc_t), - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR, //EP 1 OUT - .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, - .wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS_FS, //MPS of 64 bytes - .bInterval = 0, -}; - -const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc_hs = { - .bLength = sizeof(usb_ep_desc_t), - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR, //EP 1 OUT - .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, - .wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS_HS, //MPS of 512 bytes - .bInterval = 0, -}; - -const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc_fs = { - .bLength = sizeof(usb_ep_desc_t), - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR, - .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, - .wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS_FS, //MPS of 64 bytes - .bInterval = 0, -}; - -const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc_hs = { - .bLength = sizeof(usb_ep_desc_t), - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR, - .bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK, - .wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS_HS, //MPS of 512 bytes - .bInterval = 0, -}; - -void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag) -{ - cbw->dCBWSignature = 0x43425355; //Fixed value - cbw->dCBWTag = tag; //Random value that is echoed back - cbw->dCBWDataTransferLength = num_sectors * MOCK_MSC_SCSI_SECTOR_SIZE; - cbw->bmCBWFlags = (is_read) ? (1 << 7) : 0; //If this is a read, set the direction flag - cbw->bCBWLUN = MOCK_MSC_SCSI_LUN; - cbw->bCBWCBLength = 10; //The length of the SCSI command - //Initialize SCSI CMD as READ10 or WRITE 10 - cbw->CBWCB.opcode = (is_read) ? 0x28 : 0x2A; //SCSI CMD READ10 or WRITE10 - cbw->CBWCB.flags = 0; - cbw->CBWCB.lba_3 = (offset >> 24); - cbw->CBWCB.lba_2 = (offset >> 16); - cbw->CBWCB.lba_1 = (offset >> 8); - cbw->CBWCB.lba_0 = (offset >> 0); - cbw->CBWCB.group = 0; - cbw->CBWCB.len_1 = (num_sectors >> 8); - cbw->CBWCB.len_0 = (num_sectors >> 0); - cbw->CBWCB.control = 0; -} - -bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect) -{ - bool no_issues = true; - if (csw->dCSWSignature != 0x53425355) { - no_issues = false; - printf("Warning: csw signature corrupt (0x%"PRIX32")\n", csw->dCSWSignature); - } - if (csw->dCSWTag != tag_expect) { - no_issues = false; - printf("Warning: csw tag unexpected! Expected %"PRIu32" got %"PRIu32"\n", tag_expect, csw->dCSWTag); - } - if (csw->dCSWDataResidue) { - no_issues = false; - printf("Warning: csw indicates data residue of %"PRIu32" bytes!\n", csw->dCSWDataResidue); - } - if (csw->bCSWStatus) { - no_issues = false; - printf("Warning: csw indicates non-good status %d!\n", csw->bCSWStatus); - } - return no_issues; -} - -void mock_msc_scsi_init_reference_descriptors(void) -{ - // Configuration descriptor - uint8_t *dest_ptr = mock_msc_scsi_config_desc; - memcpy(dest_ptr, (void*)&mock_msc_config_desc, sizeof(mock_msc_config_desc)); - dest_ptr += USB_CONFIG_DESC_SIZE; - memcpy(dest_ptr, (void*)&mock_msc_intf_desc, sizeof(mock_msc_intf_desc)); - dest_ptr += USB_INTF_DESC_SIZE; - // Set endpoint descriptors with zeroes, FS or HS device has not been connected - memset(dest_ptr, 0, sizeof(usb_ep_desc_t)); - dest_ptr += USB_EP_DESC_SIZE; - memset(dest_ptr, 0, sizeof(usb_ep_desc_t)); - - // String descriptors - const char *str = MOCK_MSC_SCSI_STRING_1; - uint8_t chr_count = strlen(str); - mock_msc_scsi_str_desc_manu[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type - for (uint8_t i = 0; i < chr_count; i++) { - mock_msc_scsi_str_desc_manu[1 + i] = str[i]; - } - - str = MOCK_MSC_SCSI_STRING_2; - chr_count = strlen(str); - mock_msc_scsi_str_desc_prod[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type - for (uint8_t i = 0; i < chr_count; i++) { - mock_msc_scsi_str_desc_prod[1 + i] = str[i]; - } - - str = MOCK_MSC_SCSI_STRING_3; - chr_count = strlen(str); - mock_msc_scsi_str_desc_ser_num[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type - for (uint8_t i = 0; i < chr_count; i++) { - mock_msc_scsi_str_desc_ser_num[1 + i] = str[i]; - } -} diff --git a/components/usb/test_apps/common/test_usb_mock_msc.h b/components/usb/test_apps/common/test_usb_mock_msc.h deleted file mode 100644 index 466decf2be23..000000000000 --- a/components/usb/test_apps/common/test_usb_mock_msc.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* -This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB -Host stack. -*/ - -#pragma once - -#include -#include -#include "esp_assert.h" -#include "usb/usb_types_ch9.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// ---------------------------------------------------- MSC SCSI ------------------------------------------------------- - -extern const char *MSC_CLIENT_TAG; - -/* -Note: The mock MSC SCSI tests requires that USB flash drive be connected. The flash drive should... - -- Be implement the Mass Storage class supporting BULK only transfers using SCSI commands -- It's configuration 1 should have the following endpoints - - ------------------ Configuration Descriptor ------------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x02 (Configuration Descriptor) -wTotalLength : 0x0020 (32 bytes) -bNumInterfaces : 0x01 (1 Interface) -bConfigurationValue : 0x01 (Configuration 1) -iConfiguration : 0x00 (No String Descriptor) -bmAttributes : 0x80 - D7: Reserved, set 1 : 0x01 - D6: Self Powered : 0x00 (no) - D5: Remote Wakeup : 0x00 (no) - D4..0: Reserved, set 0 : 0x00 -MaxPower : 0x70 (224 mA) -Data (HexDump) : 09 02 20 00 01 01 00 80 70 09 04 00 00 02 08 06 - 50 00 07 05 81 02 00 02 00 07 05 02 02 00 02 00 - - ---------------- Interface Descriptor ----------------- -bLength : 0x09 (9 bytes) -bDescriptorType : 0x04 (Interface Descriptor) -bInterfaceNumber : 0x00 -bAlternateSetting : 0x00 -bNumEndpoints : 0x02 (2 Endpoints) -bInterfaceClass : 0x08 (Mass Storage) -bInterfaceSubClass : 0x06 (SCSI transparent command set) -bInterfaceProtocol : 0x50 (Bulk-Only Transport) -iInterface : 0x00 (No String Descriptor) -Data (HexDump) : 09 04 00 00 02 08 06 50 00 - - ----------------- Endpoint Descriptor ----------------- -bLength : 0x07 (7 bytes) -bDescriptorType : 0x05 (Endpoint Descriptor) -bEndpointAddress : 0x81 (Direction=IN EndpointID=1) -bmAttributes : 0x02 (TransferType=Bulk) -wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytes for HS) -bInterval : 0x00 (never NAKs) -Data (HexDump) : 07 05 81 02 40 00 00 - - ----------------- Endpoint Descriptor ----------------- -bLength : 0x07 (7 bytes) -bDescriptorType : 0x05 (Endpoint Descriptor) -bEndpointAddress : 0x02 (Direction=OUT EndpointID=2) -bmAttributes : 0x02 (TransferType=Bulk) -wMaxPacketSize : 0x0040 (max 64 bytes for FS, 512 bytest for HS) -bInterval : 0x00 (never NAKs) -Data (HexDump) : 07 05 02 02 40 00 00 - -If you're using a flash driver with different endpoints, modify the endpoint descriptors below. -*/ - -//Constant descriptors -extern const usb_device_desc_t mock_msc_scsi_dev_desc; -extern uint8_t mock_msc_scsi_config_desc[255]; -extern uint16_t mock_msc_scsi_str_desc_manu[128]; -extern uint16_t mock_msc_scsi_str_desc_prod[128]; -extern uint16_t mock_msc_scsi_str_desc_ser_num[128]; -extern usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc; -extern usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc; -extern const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc_fs; -extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc_fs; -extern const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc_hs; -extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc_hs; - -#define MOCK_MSC_SCSI_DEV_ID_VENDOR 0x0781 // Western Digital, Sandisk -#define MOCK_MSC_SCSI_DEV_ID_PRODUCT 0x5595 -#define MOCK_MSC_SCSI_DEV_VERSION 0x0100 //1.00 -#define MOCK_MSC_SCSI_USB_VERSION 0x0210 //2.10 -#define MOCK_MSC_SCSI_DEV_DFLT_EP_MPS 64 -#define MOCK_MSC_SCSI_SECTOR_SIZE 512 -#define MOCK_MSC_SCSI_LUN 0 -#define MOCK_MSC_SCSI_INTF_NUMBER 0 -#define MOCK_MSC_SCSI_INTF_ALT_SETTING 0 -#define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x02 -#define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x81 -#define MOCK_MSC_SCSI_BULK_EP_MPS_FS 64 // FS wMaxPacketSize -#define MOCK_MSC_SCSI_BULK_EP_MPS_HS 512 // HS wMaxPacketSize -#define MOCK_MSC_SCSI_STRING_1 (" USB") -#define MOCK_MSC_SCSI_STRING_2 (" SanDisk 3.2Gen1") -#define MOCK_MSC_SCSI_STRING_3 ("0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000000000000000096abe1a3ff83610095558107aea948b4") // This string is NOT checked by the enum test - -#define MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt_ptr, intf_num) ({ \ - (setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \ - (setup_pkt_ptr)->bRequest = 0xFF; \ - (setup_pkt_ptr)->wValue = 0; \ - (setup_pkt_ptr)->wIndex = (intf_num); \ - (setup_pkt_ptr)->wLength = 0; \ -}) - -typedef struct __attribute__((packed)) -{ - uint8_t opcode; //0x28 = read(10), 0x2A=write(10) - uint8_t flags; - uint8_t lba_3; - uint8_t lba_2; - uint8_t lba_1; - uint8_t lba_0; - uint8_t group; - uint8_t len_1; - uint8_t len_0; - uint8_t control; -} mock_scsi_cmd10_t; - -typedef struct __attribute__((packed)) -{ - uint32_t dCBWSignature; - uint32_t dCBWTag; - uint32_t dCBWDataTransferLength; - uint8_t bmCBWFlags; - uint8_t bCBWLUN; - uint8_t bCBWCBLength; - mock_scsi_cmd10_t CBWCB; - uint8_t padding[6]; -} mock_msc_bulk_cbw_t; - -// USB Bulk Transfer Command Status Wrapper data -typedef struct __attribute__((packed)) -{ - uint32_t dCSWSignature; - uint32_t dCSWTag; - uint32_t dCSWDataResidue; - uint8_t bCSWStatus; -} mock_msc_bulk_csw_t; - -/** - * @brief Initialize a MSC Command Block Wrapper (CBW) as an SCSI command - * - * @param cbw CBW structure - * @param is_read Is a read command - * @param offset Block offset - * @param num_sectors Number of sectors to read - * @param tag Tag (this is simply echoed back - */ -void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag); - -/** - * @brief Check that returned Command Status Wrapper (CSW) is valid - * - * @param csw CSW structure - * @param tag_expect Expected tag - * @return true CSW is valid - * @return false CSW is not valid - */ -bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect); - -/** - * @brief Construct configuration and string descriptors - */ -void mock_msc_scsi_init_reference_descriptors(void); - -// ---------------------------------------------------- Mock ISOC ------------------------------------------------------ - -/* -Note: ISOC test rely on communicating with a non existent endpoint using ISOC OUT transfers. Since no ACK is given for -ISOC, transferring to a non-existent endpoint should work. The non-existent endpoint descriptor is described below: -*/ - -#define MOCK_ISOC_EP_NUM 2 -#define MOCK_ISOC_EP_MPS 512 - -static const usb_ep_desc_t mock_isoc_out_ep_desc = { - .bLength = sizeof(usb_ep_desc_t), - .bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT, - .bEndpointAddress = MOCK_ISOC_EP_NUM, - .bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC, - .wMaxPacketSize = MOCK_ISOC_EP_MPS, //MPS of 512 bytes - .bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms -}; - -#ifdef __cplusplus -} -#endif diff --git a/components/usb/test_apps/hcd/main/test_app_main.c b/components/usb/test_apps/hcd/main/test_app_main.c index 224b068adae8..9137bfe46983 100644 --- a/components/usb/test_apps/hcd/main/test_app_main.c +++ b/components/usb/test_apps/hcd/main/test_app_main.c @@ -7,20 +7,23 @@ #include "unity.h" #include "unity_test_runner.h" #include "unity_test_utils_memory.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "dev_msc.h" +#include "dev_hid.h" #include "test_hcd_common.h" void setUp(void) { unity_utils_record_free_mem(); + dev_msc_init(); + dev_hid_init(); port_hdl = test_hcd_setup(); } void tearDown(void) { - //Short delay to allow task to be cleaned up + // Short delay to allow task to be cleaned up vTaskDelay(10); test_hcd_teardown(port_hdl); port_hdl = NULL; diff --git a/components/usb/test_apps/hcd/main/test_hcd_bulk.c b/components/usb/test_apps/hcd/main/test_hcd_bulk.c index 5ad852f590d0..8d7202001222 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_bulk.c +++ b/components/usb/test_apps/hcd/main/test_hcd_bulk.c @@ -9,24 +9,25 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "unity.h" -#include "test_usb_mock_msc.h" +#include "mock_msc.h" +#include "dev_msc.h" #include "test_hcd_common.h" // --------------------------------------------------- Test Cases ------------------------------------------------------ -static void mock_msc_reset_req(hcd_pipe_handle_t default_pipe) +static void mock_msc_reset_req(hcd_pipe_handle_t default_pipe, uint8_t bInterfaceNumber) { - //Create URB + // Create URB urb_t *urb = test_hcd_alloc_urb(0, sizeof(usb_setup_packet_t)); usb_setup_packet_t *setup_pkt = (usb_setup_packet_t *)urb->transfer.data_buffer; - MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt, MOCK_MSC_SCSI_INTF_NUMBER); + MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt, bInterfaceNumber); urb->transfer.num_bytes = sizeof(usb_setup_packet_t); - //Enqueue, wait, dequeue, and check URB + // Enqueue, wait, dequeue, and check URB TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb)); test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE); TEST_ASSERT_EQUAL_PTR(urb, hcd_urb_dequeue(default_pipe)); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); - //Free URB + // Free URB test_hcd_free_urb(urb); } @@ -54,47 +55,54 @@ Test HCD bulk pipe URBs TEST_CASE("Test HCD bulk pipe URBs", "[bulk][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Enumerate and reset MSC SCSI device - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Enumerate and reset MSC SCSI device + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); // Create a default pipe (using a NULL EP descriptor) uint8_t dev_addr = test_hcd_enum_device(default_pipe); - mock_msc_reset_req(default_pipe); - test_hcd_set_mock_msc_ep_descriptor(port_speed); + const dev_msc_info_t *dev_info = dev_msc_get_info(); + mock_msc_reset_req(default_pipe, dev_info->bInterfaceNumber); - //Create BULK IN and BULK OUT pipes for SCSI - hcd_pipe_handle_t bulk_out_pipe = test_hcd_pipe_alloc(port_hdl, &mock_msc_scsi_bulk_out_ep_desc, dev_addr, port_speed); - hcd_pipe_handle_t bulk_in_pipe = test_hcd_pipe_alloc(port_hdl, &mock_msc_scsi_bulk_in_ep_desc, dev_addr, port_speed); - //Create URBs for CBW, Data, and CSW transport. IN Buffer sizes are rounded up to nearest MPS + // Create BULK IN and BULK OUT pipes for SCSI + const usb_ep_desc_t *out_ep_desc = dev_msc_get_out_ep_desc(port_speed); + const usb_ep_desc_t *in_ep_desc = dev_msc_get_in_ep_desc(port_speed); + const uint16_t mps = USB_EP_DESC_GET_MPS(in_ep_desc) ; + hcd_pipe_handle_t bulk_out_pipe = test_hcd_pipe_alloc(port_hdl, out_ep_desc, dev_addr, port_speed); + hcd_pipe_handle_t bulk_in_pipe = test_hcd_pipe_alloc(port_hdl, in_ep_desc, dev_addr, port_speed); + // Create URBs for CBW, Data, and CSW transport. IN Buffer sizes are rounded up to nearest MPS urb_t *urb_cbw = test_hcd_alloc_urb(0, sizeof(mock_msc_bulk_cbw_t)); - urb_t *urb_data = test_hcd_alloc_urb(0, TEST_NUM_SECTORS_PER_XFER * MOCK_MSC_SCSI_SECTOR_SIZE); - const uint16_t mps = USB_EP_DESC_GET_MPS(&mock_msc_scsi_bulk_in_ep_desc) ; + urb_t *urb_data = test_hcd_alloc_urb(0, TEST_NUM_SECTORS_PER_XFER * dev_info->scsi_sector_size); urb_t *urb_csw = test_hcd_alloc_urb(0, sizeof(mock_msc_bulk_csw_t) + (mps - (sizeof(mock_msc_bulk_csw_t) % mps))); urb_cbw->transfer.num_bytes = sizeof(mock_msc_bulk_cbw_t); - urb_data->transfer.num_bytes = TEST_NUM_SECTORS_PER_XFER * MOCK_MSC_SCSI_SECTOR_SIZE; + urb_data->transfer.num_bytes = TEST_NUM_SECTORS_PER_XFER * dev_info->scsi_sector_size; urb_csw->transfer.num_bytes = sizeof(mock_msc_bulk_csw_t) + (mps - (sizeof(mock_msc_bulk_csw_t) % mps)); for (int block_num = 0; block_num < TEST_NUM_SECTORS_TOTAL; block_num += TEST_NUM_SECTORS_PER_XFER) { - //Initialize CBW URB, then send it on the BULK OUT pipe - mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)urb_cbw->transfer.data_buffer, true, block_num, TEST_NUM_SECTORS_PER_XFER, 0xAAAAAAAA); + // Initialize CBW URB, then send it on the BULK OUT pipe + mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)urb_cbw->transfer.data_buffer, + true, + block_num, + TEST_NUM_SECTORS_PER_XFER, + dev_info->scsi_sector_size, + 0xAAAAAAAA); TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(bulk_out_pipe, urb_cbw)); test_hcd_expect_pipe_event(bulk_out_pipe, HCD_PIPE_EVENT_URB_DONE); TEST_ASSERT_EQUAL_PTR(urb_cbw, hcd_urb_dequeue(bulk_out_pipe)); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb_cbw->transfer.status, "Transfer NOT completed"); - //Read data through BULK IN pipe + // Read data through BULK IN pipe TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(bulk_in_pipe, urb_data)); test_hcd_expect_pipe_event(bulk_in_pipe, HCD_PIPE_EVENT_URB_DONE); TEST_ASSERT_EQUAL_PTR(urb_data, hcd_urb_dequeue(bulk_in_pipe)); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb_data->transfer.status, "Transfer NOT completed"); - //Read the CSW through BULK IN pipe + // Read the CSW through BULK IN pipe TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(bulk_in_pipe, urb_csw)); test_hcd_expect_pipe_event(bulk_in_pipe, HCD_PIPE_EVENT_URB_DONE); TEST_ASSERT_EQUAL_PTR(urb_csw, hcd_urb_dequeue(bulk_in_pipe)); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb_data->transfer.status, "Transfer NOT completed"); TEST_ASSERT_EQUAL(sizeof(mock_msc_bulk_csw_t), urb_csw->transfer.actual_num_bytes); TEST_ASSERT_TRUE(mock_msc_scsi_check_csw((mock_msc_bulk_csw_t *)urb_csw->transfer.data_buffer, 0xAAAAAAAA)); - //Print the read data + // Print the read data printf("Block %d to %d:\n", block_num, block_num + TEST_NUM_SECTORS_PER_XFER); for (int i = 0; i < urb_data->transfer.actual_num_bytes; i++) { printf("0x%02x,", ((char *)urb_data->transfer.data_buffer)[i]); @@ -108,6 +116,6 @@ TEST_CASE("Test HCD bulk pipe URBs", "[bulk][full_speed]") test_hcd_pipe_free(bulk_out_pipe); test_hcd_pipe_free(bulk_in_pipe); test_hcd_pipe_free(default_pipe); - //Cleanup + // Cleanup test_hcd_wait_for_disconn(port_hdl, false); } diff --git a/components/usb/test_apps/hcd/main/test_hcd_common.c b/components/usb/test_apps/hcd/main/test_hcd_common.c index b2147b5ad163..293f6ca21fbf 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_common.c +++ b/components/usb/test_apps/hcd/main/test_hcd_common.c @@ -19,14 +19,14 @@ #include "usb/usb_types_ch9.h" #include "test_hcd_common.h" #include "test_usb_common.h" -#include "test_usb_mock_msc.h" +#include "mock_msc.h" #include "unity.h" #include "esp_dma_utils.h" #define PORT_NUM 1 #define EVENT_QUEUE_LEN 5 -#define ENUM_ADDR 1 //Device address to use for tests that enumerate the device -#define ENUM_CONFIG 1 //Device configuration number to use for tests that enumerate the device +#define ENUM_ADDR 1 // Device address to use for tests that enumerate the device +#define ENUM_CONFIG 1 // Device configuration number to use for tests that enumerate the device typedef struct { hcd_port_handle_t port_hdl; @@ -54,10 +54,10 @@ hcd_port_handle_t port_hdl = NULL; */ static bool port_callback(hcd_port_handle_t port_hdl, hcd_port_event_t port_event, void *user_arg, bool in_isr) { - //We store the port's queue handle in the port's context variable + // We store the port's queue handle in the port's context variable void *port_ctx = hcd_port_get_context(port_hdl); QueueHandle_t port_evt_queue = (QueueHandle_t)port_ctx; - TEST_ASSERT_TRUE(in_isr); //Current HCD implementation should never call a port callback in a task context + TEST_ASSERT_TRUE(in_isr); // Current HCD implementation should never call a port callback in a task context port_event_msg_t msg = { .port_hdl = port_hdl, .port_event = port_event, @@ -98,14 +98,14 @@ static bool pipe_callback(hcd_pipe_handle_t pipe_hdl, hcd_pipe_event_t pipe_even void test_hcd_expect_port_event(hcd_port_handle_t port_hdl, hcd_port_event_t expected_event) { - //Get the port event queue from the port's context variable + // Get the port event queue from the port's context variable QueueHandle_t port_evt_queue = (QueueHandle_t)hcd_port_get_context(port_hdl); TEST_ASSERT_NOT_NULL(port_evt_queue); - //Wait for port callback to send an event message + // Wait for port callback to send an event message port_event_msg_t msg; BaseType_t ret = xQueueReceive(port_evt_queue, &msg, pdMS_TO_TICKS(5000)); TEST_ASSERT_EQUAL_MESSAGE(pdPASS, ret, "Port event not generated on time"); - //Check the contents of that event message + // Check the contents of that event message TEST_ASSERT_EQUAL(port_hdl, msg.port_hdl); TEST_ASSERT_EQUAL_MESSAGE(expected_event, msg.port_event, "Unexpected event"); printf("\t-> Port event\n"); @@ -113,21 +113,21 @@ void test_hcd_expect_port_event(hcd_port_handle_t port_hdl, hcd_port_event_t exp void test_hcd_expect_pipe_event(hcd_pipe_handle_t pipe_hdl, hcd_pipe_event_t expected_event) { - //Get the pipe's event queue from the pipe's context variable + // Get the pipe's event queue from the pipe's context variable QueueHandle_t pipe_evt_queue = (QueueHandle_t)hcd_pipe_get_context(pipe_hdl); TEST_ASSERT_NOT_NULL(pipe_evt_queue); - //Wait for pipe callback to send an event message + // Wait for pipe callback to send an event message pipe_event_msg_t msg; BaseType_t ret = xQueueReceive(pipe_evt_queue, &msg, pdMS_TO_TICKS(5000)); TEST_ASSERT_EQUAL_MESSAGE(pdPASS, ret, "Pipe event not generated on time"); - //Check the contents of that event message + // Check the contents of that event message TEST_ASSERT_EQUAL(pipe_hdl, msg.pipe_hdl); TEST_ASSERT_EQUAL_MESSAGE(expected_event, msg.pipe_event, "Unexpected event"); } int test_hcd_get_num_port_events(hcd_port_handle_t port_hdl) { - //Get the port event queue from the port's context variable + // Get the port event queue from the port's context variable QueueHandle_t port_evt_queue = (QueueHandle_t)hcd_port_get_context(port_hdl); TEST_ASSERT_NOT_NULL(port_evt_queue); return EVENT_QUEUE_LEN - uxQueueSpacesAvailable(port_evt_queue); @@ -135,7 +135,7 @@ int test_hcd_get_num_port_events(hcd_port_handle_t port_hdl) int test_hcd_get_num_pipe_events(hcd_pipe_handle_t pipe_hdl) { - //Get the pipe's event queue from the pipe's context variable + // Get the pipe's event queue from the pipe's context variable QueueHandle_t pipe_evt_queue = (QueueHandle_t)hcd_pipe_get_context(pipe_hdl); TEST_ASSERT_NOT_NULL(pipe_evt_queue); return EVENT_QUEUE_LEN - uxQueueSpacesAvailable(pipe_evt_queue); @@ -145,16 +145,16 @@ int test_hcd_get_num_pipe_events(hcd_pipe_handle_t pipe_hdl) hcd_port_handle_t test_hcd_setup(void) { - test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing - //Create a queue for port callback to queue up port events + test_usb_init_phy(); // Initialize the internal USB PHY and USB Controller for testing + // Create a queue for port callback to queue up port events QueueHandle_t port_evt_queue = xQueueCreate(EVENT_QUEUE_LEN, sizeof(port_event_msg_t)); TEST_ASSERT_NOT_NULL(port_evt_queue); - //Install HCD + // Install HCD hcd_config_t hcd_config = { .intr_flags = ESP_INTR_FLAG_LEVEL1, }; TEST_ASSERT_EQUAL(ESP_OK, hcd_install(&hcd_config)); - //Initialize a port + // Initialize a port hcd_port_config_t port_config = { .fifo_bias = HCD_PORT_FIFO_BIAS_BALANCED, .callback = port_callback, @@ -165,7 +165,7 @@ hcd_port_handle_t test_hcd_setup(void) TEST_ASSERT_EQUAL(ESP_OK, hcd_port_init(PORT_NUM, &port_config, &port_hdl)); TEST_ASSERT_NOT_NULL(port_hdl); TEST_ASSERT_EQUAL(HCD_PORT_STATE_NOT_POWERED, hcd_port_get_state(port_hdl)); - test_usb_set_phy_state(false, 0); //Force disconnected state on PHY + test_usb_set_phy_state(false, 0); // Force disconnected state on PHY return port_hdl; } @@ -174,33 +174,33 @@ void test_hcd_teardown(hcd_port_handle_t port_hdl) if (!port_hdl) { return; // In case of setup stage failure, don't run tear-down stage } - //Get the queue handle from the port's context variable + // Get the queue handle from the port's context variable QueueHandle_t port_evt_queue = (QueueHandle_t)hcd_port_get_context(port_hdl); TEST_ASSERT_NOT_NULL(port_evt_queue); - //Deinitialize a port + // Deinitialize a port TEST_ASSERT_EQUAL(ESP_OK, hcd_port_deinit(port_hdl)); - //Uninstall the HCD + // Uninstall the HCD TEST_ASSERT_EQUAL(ESP_OK, hcd_uninstall()); vQueueDelete(port_evt_queue); - test_usb_deinit_phy(); //Deinitialize the internal USB PHY after testing + test_usb_deinit_phy(); // Deinitialize the internal USB PHY after testing } usb_speed_t test_hcd_wait_for_conn(hcd_port_handle_t port_hdl) { - //Power ON the port + // Power ON the port TEST_ASSERT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_POWER_ON)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_DISCONNECTED, hcd_port_get_state(port_hdl)); - //Wait for connection event + // Wait for connection event printf("Waiting for connection\n"); - test_usb_set_phy_state(true, pdMS_TO_TICKS(100)); //Allow for connected state on PHY + test_usb_set_phy_state(true, pdMS_TO_TICKS(100)); // Allow for connected state on PHY test_hcd_expect_port_event(port_hdl, HCD_PORT_EVENT_CONNECTION); TEST_ASSERT_EQUAL(HCD_PORT_EVENT_CONNECTION, hcd_port_handle_event(port_hdl)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_DISABLED, hcd_port_get_state(port_hdl)); - //Reset newly connected device + // Reset newly connected device printf("Resetting\n"); TEST_ASSERT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_RESET)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_ENABLED, hcd_port_get_state(port_hdl)); - //Get speed of connected + // Get speed of connected usb_speed_t port_speed; TEST_ASSERT_EQUAL(ESP_OK, hcd_port_get_speed(port_hdl, &port_speed)); TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(USB_SPEED_HIGH, port_speed, "Invalid port speed"); @@ -213,18 +213,18 @@ usb_speed_t test_hcd_wait_for_conn(hcd_port_handle_t port_hdl) void test_hcd_wait_for_disconn(hcd_port_handle_t port_hdl, bool already_disabled) { if (!already_disabled) { - //Disable the device + // Disable the device printf("Disabling\n"); TEST_ASSERT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_DISABLE)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_DISABLED, hcd_port_get_state(port_hdl)); } - //Wait for a safe disconnect + // Wait for a safe disconnect printf("Waiting for disconnection\n"); - test_usb_set_phy_state(false, pdMS_TO_TICKS(100)); //Force disconnected state on PHY + test_usb_set_phy_state(false, pdMS_TO_TICKS(100)); // Force disconnected state on PHY test_hcd_expect_port_event(port_hdl, HCD_PORT_EVENT_DISCONNECTION); TEST_ASSERT_EQUAL(HCD_PORT_EVENT_DISCONNECTION, hcd_port_handle_event(port_hdl)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_RECOVERY, hcd_port_get_state(port_hdl)); - //Power down the port + // Power down the port TEST_ASSERT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_POWER_OFF)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_NOT_POWERED, hcd_port_get_state(port_hdl)); } @@ -233,7 +233,7 @@ void test_hcd_wait_for_disconn(hcd_port_handle_t port_hdl, bool already_disabled hcd_pipe_handle_t test_hcd_pipe_alloc(hcd_port_handle_t port_hdl, const usb_ep_desc_t *ep_desc, uint8_t dev_addr, usb_speed_t dev_speed) { - //Create a queue for pipe callback to queue up pipe events + // Create a queue for pipe callback to queue up pipe events QueueHandle_t pipe_evt_queue = xQueueCreate(EVENT_QUEUE_LEN, sizeof(pipe_event_msg_t)); TEST_ASSERT_NOT_NULL(pipe_evt_queue); hcd_pipe_config_t pipe_config = { @@ -252,17 +252,17 @@ hcd_pipe_handle_t test_hcd_pipe_alloc(hcd_port_handle_t port_hdl, const usb_ep_d void test_hcd_pipe_free(hcd_pipe_handle_t pipe_hdl) { - //Get the pipe's event queue from its context variable + // Get the pipe's event queue from its context variable QueueHandle_t pipe_evt_queue = (QueueHandle_t)hcd_pipe_get_context(pipe_hdl); TEST_ASSERT_NOT_NULL(pipe_evt_queue); - //Free the pipe and queue + // Free the pipe and queue TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_free(pipe_hdl)); vQueueDelete(pipe_evt_queue); } urb_t *test_hcd_alloc_urb(int num_isoc_packets, size_t data_buffer_size) { - //Allocate a URB and data buffer + // Allocate a URB and data buffer urb_t *urb = heap_caps_calloc(1, sizeof(urb_t) + (sizeof(usb_isoc_packet_desc_t) * num_isoc_packets), MALLOC_CAP_DEFAULT); void *data_buffer; size_t real_size; @@ -273,7 +273,7 @@ urb_t *test_hcd_alloc_urb(int num_isoc_packets, size_t data_buffer_size) TEST_ASSERT_NOT_NULL_MESSAGE(urb, "Failed to allocate URB"); TEST_ASSERT_NOT_NULL_MESSAGE(data_buffer, "Failed to allocate transfer buffer"); - //Initialize URB and underlying transfer structure. Need to cast to dummy due to const fields + // Initialize URB and underlying transfer structure. Need to cast to dummy due to const fields usb_transfer_dummy_t *transfer_dummy = (usb_transfer_dummy_t *)&urb->transfer; transfer_dummy->data_buffer = data_buffer; transfer_dummy->data_buffer_size = real_size; @@ -283,19 +283,19 @@ urb_t *test_hcd_alloc_urb(int num_isoc_packets, size_t data_buffer_size) void test_hcd_free_urb(urb_t *urb) { - //Free data buffer of the transfer + // Free data buffer of the transfer heap_caps_free(urb->transfer.data_buffer); - //Free the URB + // Free the URB heap_caps_free(urb); } uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe) { - //We need to create a URB for the enumeration control transfers + // We need to create a URB for the enumeration control transfers urb_t *urb = test_hcd_alloc_urb(0, sizeof(usb_setup_packet_t) + 256); usb_setup_packet_t *setup_pkt = (usb_setup_packet_t *)urb->transfer.data_buffer; - //Get the device descriptor (note that device might only return 8 bytes) + // Get the device descriptor (note that device might only return 8 bytes) USB_SETUP_PACKET_INIT_GET_DEVICE_DESC(setup_pkt); urb->transfer.num_bytes = sizeof(usb_setup_packet_t) + sizeof(usb_device_desc_t); TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb)); @@ -303,22 +303,22 @@ uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe) TEST_ASSERT_EQUAL(urb, hcd_urb_dequeue(default_pipe)); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); - //Update the MPS of the default pipe + // Update the MPS of the default pipe usb_device_desc_t *device_desc = (usb_device_desc_t *)(urb->transfer.data_buffer + sizeof(usb_setup_packet_t)); TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_update_mps(default_pipe, device_desc->bMaxPacketSize0)); - //Send a set address request - USB_SETUP_PACKET_INIT_SET_ADDR(setup_pkt, ENUM_ADDR); //We only support one device for now so use address 1 + // Send a set address request + USB_SETUP_PACKET_INIT_SET_ADDR(setup_pkt, ENUM_ADDR); // We only support one device for now so use address 1 urb->transfer.num_bytes = sizeof(usb_setup_packet_t); TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb)); test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE); TEST_ASSERT_EQUAL(urb, hcd_urb_dequeue(default_pipe)); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); - //Update address of default pipe + // Update address of default pipe TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_update_dev_addr(default_pipe, ENUM_ADDR)); - //Send a set configuration request + // Send a set configuration request USB_SETUP_PACKET_INIT_SET_CONFIG(setup_pkt, ENUM_CONFIG); urb->transfer.num_bytes = sizeof(usb_setup_packet_t); TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb)); @@ -326,18 +326,7 @@ uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe) TEST_ASSERT_EQUAL(urb, hcd_urb_dequeue(default_pipe)); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); - //Free URB + // Free URB test_hcd_free_urb(urb); return ENUM_ADDR; } - -void test_hcd_set_mock_msc_ep_descriptor(usb_speed_t port_speed) -{ - if (port_speed == USB_SPEED_HIGH) { - mock_msc_scsi_bulk_out_ep_desc = mock_msc_scsi_bulk_out_ep_desc_hs; // HS wMaxPacketSize = 512 - mock_msc_scsi_bulk_in_ep_desc = mock_msc_scsi_bulk_in_ep_desc_hs; - } else { - mock_msc_scsi_bulk_out_ep_desc = mock_msc_scsi_bulk_out_ep_desc_fs; // FS wMaxPacketSize = 64 - mock_msc_scsi_bulk_in_ep_desc = mock_msc_scsi_bulk_in_ep_desc_fs; - } -} diff --git a/components/usb/test_apps/hcd/main/test_hcd_ctrl.c b/components/usb/test_apps/hcd/main/test_hcd_ctrl.c index 789d8b3c662d..75190e41c863 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_ctrl.c +++ b/components/usb/test_apps/hcd/main/test_hcd_ctrl.c @@ -13,7 +13,7 @@ #define TEST_DEV_ADDR 0 #define NUM_URBS 3 #define TRANSFER_MAX_BYTES 256 -#define URB_DATA_BUFF_SIZE (sizeof(usb_setup_packet_t) + TRANSFER_MAX_BYTES) //256 is worst case size for configuration descriptors +#define URB_DATA_BUFF_SIZE (sizeof(usb_setup_packet_t) + TRANSFER_MAX_BYTES) // 256 is worst case size for configuration descriptors /* Test HCD control pipe URBs (normal completion and early abort) @@ -35,36 +35,36 @@ Test HCD control pipe URBs (normal completion and early abort) */ TEST_CASE("Test HCD control pipe URBs", "[ctrl][low_speed][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Allocate some URBs and initialize their data buffers with control transfers - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Allocate some URBs and initialize their data buffers with control transfers + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); // Create a default pipe (using a NULL EP descriptor) urb_t *urb_list[NUM_URBS]; for (int i = 0; i < NUM_URBS; i++) { urb_list[i] = test_hcd_alloc_urb(0, URB_DATA_BUFF_SIZE); - //Initialize with a "Get Config Descriptor request" + // Initialize with a "Get Config Descriptor request" urb_list[i]->transfer.num_bytes = sizeof(usb_setup_packet_t) + TRANSFER_MAX_BYTES; USB_SETUP_PACKET_INIT_GET_CONFIG_DESC((usb_setup_packet_t *)urb_list[i]->transfer.data_buffer, 0, TRANSFER_MAX_BYTES); urb_list[i]->transfer.context = URB_CONTEXT_VAL; } - //Enqueue URBs but immediately suspend the port + // Enqueue URBs but immediately suspend the port printf("Enqueuing URBs\n"); for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb_list[i])); } - //Wait for each done event of each URB + // Wait for each done event of each URB for (int i = 0; i < NUM_URBS; i++) { test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE); } - //Dequeue URBs, check, and print + // Dequeue URBs, check, and print for (int i = 0; i < NUM_URBS; i++) { urb_t *urb = hcd_urb_dequeue(default_pipe); TEST_ASSERT_EQUAL(urb_list[i], urb); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); - //We must have transmitted at least the setup packet, but device may return less than bytes requested + // We must have transmitted at least the setup packet, but device may return less than bytes requested TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes); TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes); usb_config_desc_t *config_desc = (usb_config_desc_t *)(urb->transfer.data_buffer + sizeof(usb_setup_packet_t)); @@ -72,38 +72,38 @@ TEST_CASE("Test HCD control pipe URBs", "[ctrl][low_speed][full_speed]") printf("Config Desc wTotalLength %d\n", config_desc->wTotalLength); } - //Enqueue URBs again but abort them short after + // Enqueue URBs again but abort them short after for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb_list[i])); } for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_abort(urb_list[i])); } - vTaskDelay(pdMS_TO_TICKS(100)); //Give some time for any inflight transfers to complete + vTaskDelay(pdMS_TO_TICKS(100)); // Give some time for any inflight transfers to complete - //Wait for the URBs to complete and dequeue them, then check results - //Dequeue URBs + // Wait for the URBs to complete and dequeue them, then check results + // Dequeue URBs for (int i = 0; i < NUM_URBS; i++) { urb_t *urb = hcd_urb_dequeue(default_pipe); - //No need to check for URB pointer address as they may be out of order + // No need to check for URB pointer address as they may be out of order TEST_ASSERT(urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED || urb->transfer.status == USB_TRANSFER_STATUS_CANCELED); if (urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED) { - //We must have transmitted at least the setup packet, but device may return less than bytes requested + // We must have transmitted at least the setup packet, but device may return less than bytes requested TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes); TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes); } else { - //A failed transfer should 0 actual number of bytes transmitted + // A failed transfer should 0 actual number of bytes transmitted TEST_ASSERT_EQUAL(0, urb->transfer.actual_num_bytes); } TEST_ASSERT_EQUAL(urb->transfer.context, URB_CONTEXT_VAL); } - //Free URB list and pipe + // Free URB list and pipe for (int i = 0; i < NUM_URBS; i++) { test_hcd_free_urb(urb_list[i]); } test_hcd_pipe_free(default_pipe); - //Cleanup + // Cleanup test_hcd_wait_for_disconn(port_hdl, false); } @@ -130,27 +130,27 @@ Test HCD control pipe STALL condition, abort, and clear */ TEST_CASE("Test HCD control pipe STALL", "[ctrl][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Allocate some URBs and initialize their data buffers with control transfers - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Allocate some URBs and initialize their data buffers with control transfers + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); // Create a default pipe (using a NULL EP descriptor) urb_t *urb_list[NUM_URBS]; for (int i = 0; i < NUM_URBS; i++) { urb_list[i] = test_hcd_alloc_urb(0, URB_DATA_BUFF_SIZE); - //Initialize with a "Get Config Descriptor request" + // Initialize with a "Get Config Descriptor request" urb_list[i]->transfer.num_bytes = sizeof(usb_setup_packet_t) + TRANSFER_MAX_BYTES; USB_SETUP_PACKET_INIT_GET_CONFIG_DESC((usb_setup_packet_t *)urb_list[i]->transfer.data_buffer, 0, TRANSFER_MAX_BYTES); urb_list[i]->transfer.context = URB_CONTEXT_VAL; } - //Corrupt the first URB so that it triggers a STALL + // Corrupt the first URB so that it triggers a STALL ((usb_setup_packet_t *)urb_list[0]->transfer.data_buffer)->bRequest = 0xAA; - //Enqueue URBs. A STALL should occur + // Enqueue URBs. A STALL should occur int num_enqueued = 0; for (int i = 0; i < NUM_URBS; i++) { if (hcd_urb_enqueue(default_pipe, urb_list[i]) != ESP_OK) { - //STALL may occur before we are done enqueing + // STALL may occur before we are done enqueuing break; } num_enqueued++; @@ -160,7 +160,7 @@ TEST_CASE("Test HCD control pipe STALL", "[ctrl][full_speed]") test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_ERROR_STALL); TEST_ASSERT_EQUAL(HCD_PIPE_STATE_HALTED, hcd_pipe_get_state(default_pipe)); - //Call the pipe abort command to retire all URBs then dequeue them all + // Call the pipe abort command to retire all URBs then dequeue them all TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_FLUSH)); test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE); for (int i = 0; i < num_enqueued; i++) { @@ -168,36 +168,36 @@ TEST_CASE("Test HCD control pipe STALL", "[ctrl][full_speed]") TEST_ASSERT_EQUAL(urb_list[i], urb); TEST_ASSERT(urb->transfer.status == USB_TRANSFER_STATUS_STALL || urb->transfer.status == USB_TRANSFER_STATUS_CANCELED); if (urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED) { - //We must have transmitted at least the setup packet, but device may return less than bytes requested + // We must have transmitted at least the setup packet, but device may return less than bytes requested TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes); TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes); } else { - //A failed transfer should 0 actual number of bytes transmitted + // A failed transfer should 0 actual number of bytes transmitted TEST_ASSERT_EQUAL(0, urb->transfer.actual_num_bytes); } TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); } - //Call the clear command to un-stall the pipe + // Call the clear command to un-stall the pipe TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_CLEAR)); TEST_ASSERT_EQUAL(HCD_PIPE_STATE_ACTIVE, hcd_pipe_get_state(default_pipe)); printf("Retrying\n"); - //Correct first URB then requeue + // Correct first URB then requeue USB_SETUP_PACKET_INIT_GET_CONFIG_DESC((usb_setup_packet_t *)urb_list[0]->transfer.data_buffer, 0, TRANSFER_MAX_BYTES); for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb_list[i])); } - //Wait for each URB to be done, deequeue, and check results + // Wait for each URB to be done, deequeue, and check results for (int i = 0; i < NUM_URBS; i++) { test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE); - //expect_pipe_event(pipe_evt_queue, default_pipe, HCD_PIPE_EVENT_URB_DONE); + // expect_pipe_event(pipe_evt_queue, default_pipe, HCD_PIPE_EVENT_URB_DONE); urb_t *urb = hcd_urb_dequeue(default_pipe); TEST_ASSERT_EQUAL(urb_list[i], urb); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); - //We must have transmitted at least the setup packet, but device may return less than bytes requested + // We must have transmitted at least the setup packet, but device may return less than bytes requested TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes); TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes); usb_config_desc_t *config_desc = (usb_config_desc_t *)(urb->transfer.data_buffer + sizeof(usb_setup_packet_t)); @@ -205,12 +205,12 @@ TEST_CASE("Test HCD control pipe STALL", "[ctrl][full_speed]") printf("Config Desc wTotalLength %d\n", config_desc->wTotalLength); } - //Free URB list and pipe + // Free URB list and pipe for (int i = 0; i < NUM_URBS; i++) { test_hcd_free_urb(urb_list[i]); } test_hcd_pipe_free(default_pipe); - //Cleanup + // Cleanup test_hcd_wait_for_disconn(port_hdl, false); } @@ -234,21 +234,21 @@ Test control pipe run-time halt and clear */ TEST_CASE("Test HCD control pipe runtime halt and clear", "[ctrl][low_speed][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Allocate some URBs and initialize their data buffers with control transfers - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Allocate some URBs and initialize their data buffers with control transfers + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); // Create a default pipe (using a NULL EP descriptor) urb_t *urb_list[NUM_URBS]; for (int i = 0; i < NUM_URBS; i++) { urb_list[i] = test_hcd_alloc_urb(0, URB_DATA_BUFF_SIZE); - //Initialize with a "Get Config Descriptor request" + // Initialize with a "Get Config Descriptor request" urb_list[i]->transfer.num_bytes = sizeof(usb_setup_packet_t) + TRANSFER_MAX_BYTES; USB_SETUP_PACKET_INIT_GET_CONFIG_DESC((usb_setup_packet_t *)urb_list[i]->transfer.data_buffer, 0, TRANSFER_MAX_BYTES); urb_list[i]->transfer.context = URB_CONTEXT_VAL; } - //Enqueue URBs but immediately halt the pipe + // Enqueue URBs but immediately halt the pipe printf("Enqueuing URBs\n"); for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb_list[i])); @@ -258,36 +258,36 @@ TEST_CASE("Test HCD control pipe runtime halt and clear", "[ctrl][low_speed][ful TEST_ASSERT_EQUAL(HCD_PIPE_STATE_HALTED, hcd_pipe_get_state(default_pipe)); printf("Pipe halted\n"); - //Un-halt the pipe + // Un-halt the pipe TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_CLEAR)); TEST_ASSERT_EQUAL(HCD_PIPE_STATE_ACTIVE, hcd_pipe_get_state(default_pipe)); printf("Pipe cleared\n"); - vTaskDelay(pdMS_TO_TICKS(100)); //Give some time pending for transfers to restart and complete + vTaskDelay(pdMS_TO_TICKS(100)); // Give some time pending for transfers to restart and complete - //Wait for each URB to be done, dequeue, and check results + // Wait for each URB to be done, dequeue, and check results for (int i = 0; i < NUM_URBS; i++) { urb_t *urb = hcd_urb_dequeue(default_pipe); TEST_ASSERT_EQUAL_PTR(urb_list[i], urb); TEST_ASSERT(urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED || urb->transfer.status == USB_TRANSFER_STATUS_CANCELED); if (urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED) { - //We must have transmitted at least the setup packet, but device may return less than bytes requested + // We must have transmitted at least the setup packet, but device may return less than bytes requested TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes); TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes); usb_config_desc_t *config_desc = (usb_config_desc_t *)(urb->transfer.data_buffer + sizeof(usb_setup_packet_t)); TEST_ASSERT_EQUAL(USB_B_DESCRIPTOR_TYPE_CONFIGURATION, config_desc->bDescriptorType); printf("Config Desc wTotalLength %d\n", config_desc->wTotalLength); } else { - //A failed transfer should 0 actual number of bytes transmitted + // A failed transfer should 0 actual number of bytes transmitted TEST_ASSERT_EQUAL(0, urb->transfer.actual_num_bytes); } TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); } - //Free URB list and pipe + // Free URB list and pipe for (int i = 0; i < NUM_URBS; i++) { test_hcd_free_urb(urb_list[i]); } test_hcd_pipe_free(default_pipe); - //Cleanup + // Cleanup test_hcd_wait_for_disconn(port_hdl, false); } diff --git a/components/usb/test_apps/hcd/main/test_hcd_intr.c b/components/usb/test_apps/hcd/main/test_hcd_intr.c index cf300d269351..4416967c1bd1 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_intr.c +++ b/components/usb/test_apps/hcd/main/test_hcd_intr.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,8 +8,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "unity.h" -#include "test_usb_mock_msc.h" -#include "test_usb_mock_hid.h" +#include "dev_hid.h" #include "test_hcd_common.h" // --------------------------------------------------- Test Cases ------------------------------------------------------ @@ -36,52 +35,54 @@ Note: Some mice will NAK until it is moved, so try moving the mouse around if th #define TEST_HID_DEV_SPEED USB_SPEED_LOW #define NUM_URBS 3 -#define URB_DATA_BUFF_SIZE MOCK_HID_MOUSE_INTR_IN_MPS #define NUM_URB_ITERS (NUM_URBS * 100) TEST_CASE("Test HCD interrupt pipe URBs", "[intr][low_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection TEST_ASSERT_EQUAL_MESSAGE(TEST_HID_DEV_SPEED, port_speed, "Connected device is not Low Speed!"); - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); //Create a default pipe (using a NULL EP descriptor) + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); // Create a default pipe (using a NULL EP descriptor) uint8_t dev_addr = test_hcd_enum_device(default_pipe); - //Allocate interrupt pipe and URBS - hcd_pipe_handle_t intr_pipe = test_hcd_pipe_alloc(port_hdl, &mock_hid_mouse_in_ep_desc, dev_addr, port_speed); + // Allocate interrupt pipe and URBS + const usb_ep_desc_t *in_ep_desc = dev_hid_get_in_ep_desc(port_speed); + const int data_buff_size = USB_EP_DESC_GET_MPS(in_ep_desc); + hcd_pipe_handle_t intr_pipe = test_hcd_pipe_alloc(port_hdl, in_ep_desc, dev_addr, port_speed); urb_t *urb_list[NUM_URBS]; for (int i = 0; i < NUM_URBS; i++) { - urb_list[i] = test_hcd_alloc_urb(0, URB_DATA_BUFF_SIZE); - urb_list[i]->transfer.num_bytes = URB_DATA_BUFF_SIZE; + urb_list[i] = test_hcd_alloc_urb(0, data_buff_size); + urb_list[i]->transfer.num_bytes = data_buff_size; urb_list[i]->transfer.context = URB_CONTEXT_VAL; } - //Enqueue URBs + // Enqueue URBs for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(intr_pipe, urb_list[i])); } int iter_count = NUM_URB_ITERS; for (iter_count = NUM_URB_ITERS; iter_count > 0; iter_count--) { - //Wait for an URB to be done + // Wait for an URB to be done test_hcd_expect_pipe_event(intr_pipe, HCD_PIPE_EVENT_URB_DONE); - //Dequeue the URB and check results + // Dequeue the URB and check results urb_t *urb = hcd_urb_dequeue(intr_pipe); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); - mock_hid_process_report((mock_hid_mouse_report_t *)urb->transfer.data_buffer, iter_count); - //Requeue URB + // Byte 1 and 2 contains x and y movement respectively + printf("X mov %d, Y mov %d\n", urb->transfer.data_buffer[1], urb->transfer.data_buffer[2]); + // Requeue URB if (iter_count > NUM_URBS) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(intr_pipe, urb)); } } - //Free URB list and pipe + // Free URB list and pipe for (int i = 0; i < NUM_URBS; i++) { test_hcd_free_urb(urb_list[i]); } test_hcd_pipe_free(intr_pipe); test_hcd_pipe_free(default_pipe); - //Clearnup + // Clearnup test_hcd_wait_for_disconn(port_hdl, false); } diff --git a/components/usb/test_apps/hcd/main/test_hcd_isoc.c b/components/usb/test_apps/hcd/main/test_hcd_isoc.c index aff0440b499b..20c4c63ab582 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_isoc.c +++ b/components/usb/test_apps/hcd/main/test_hcd_isoc.c @@ -10,14 +10,13 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "unity.h" -#include "test_usb_mock_msc.h" +#include "dev_isoc.h" +#include "usb/usb_types_ch9.h" #include "test_usb_common.h" #include "test_hcd_common.h" #define NUM_URBS 3 #define NUM_PACKETS_PER_URB 3 -#define ISOC_PACKET_SIZE MOCK_ISOC_EP_MPS -#define URB_DATA_BUFF_SIZE (NUM_PACKETS_PER_URB * ISOC_PACKET_SIZE) #define POST_ENQUEUE_DELAY_US 20 #define ENQUEUE_DELAY (OTG_HSPHY_INTERFACE ? 100 : 500) // With this delay we want to enqueue the URBs at different times @@ -43,57 +42,59 @@ Test HCD ISOC pipe URBs TEST_CASE("Test HCD isochronous pipe URBs", "[isoc][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - //The MPS of the ISOC OUT pipe is quite large, so we need to bias the FIFO sizing + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + // The MPS of the ISOC OUT pipe is quite large, so we need to bias the FIFO sizing TEST_ASSERT_EQUAL(ESP_OK, hcd_port_set_fifo_bias(port_hdl, HCD_PORT_FIFO_BIAS_PTX)); - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Enumerate and reset device - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Enumerate and reset device + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); // Create a default pipe (using a NULL EP descriptor) uint8_t dev_addr = test_hcd_enum_device(default_pipe); - //Create ISOC OUT pipe to non-existent device - hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, &mock_isoc_out_ep_desc, dev_addr + 1, port_speed); - //Create URBs + // Create ISOC OUT pipe to non-existent device + const usb_ep_desc_t *out_ep_desc = dev_isoc_get_out_ep_desc(port_speed); + const int isoc_packet_size = USB_EP_DESC_GET_MPS(out_ep_desc); + hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, out_ep_desc, dev_addr + 1, port_speed); + // Create URBs urb_t *urb_list[NUM_URBS]; - //Initialize URBs + // Initialize URBs for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { - urb_list[urb_idx] = test_hcd_alloc_urb(NUM_PACKETS_PER_URB, URB_DATA_BUFF_SIZE); - urb_list[urb_idx]->transfer.num_bytes = URB_DATA_BUFF_SIZE; + urb_list[urb_idx] = test_hcd_alloc_urb(NUM_PACKETS_PER_URB, NUM_PACKETS_PER_URB * isoc_packet_size); + urb_list[urb_idx]->transfer.num_bytes = NUM_PACKETS_PER_URB * isoc_packet_size; urb_list[urb_idx]->transfer.context = URB_CONTEXT_VAL; for (int pkt_idx = 0; pkt_idx < NUM_PACKETS_PER_URB; pkt_idx++) { - urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = ISOC_PACKET_SIZE; - //Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) - memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * ISOC_PACKET_SIZE], (urb_idx * NUM_URBS) + pkt_idx, ISOC_PACKET_SIZE); + urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = isoc_packet_size; + // Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) + memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * isoc_packet_size], (urb_idx * NUM_URBS) + pkt_idx, isoc_packet_size); } } - //Enqueue URBs + // Enqueue URBs for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(isoc_out_pipe, urb_list[i])); } - //Wait for each done event from each URB + // Wait for each done event from each URB for (int i = 0; i < NUM_URBS; i++) { test_hcd_expect_pipe_event(isoc_out_pipe, HCD_PIPE_EVENT_URB_DONE); } - //Dequeue URBs + // Dequeue URBs for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { urb_t *urb = hcd_urb_dequeue(isoc_out_pipe); TEST_ASSERT_EQUAL(urb_list[urb_idx], urb); TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); - //Overall URB status and overall number of bytes - TEST_ASSERT_EQUAL(URB_DATA_BUFF_SIZE, urb->transfer.actual_num_bytes); + // Overall URB status and overall number of bytes + TEST_ASSERT_EQUAL(NUM_PACKETS_PER_URB * isoc_packet_size, urb->transfer.actual_num_bytes); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); for (int pkt_idx = 0; pkt_idx < NUM_PACKETS_PER_URB; pkt_idx++) { TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.isoc_packet_desc[pkt_idx].status, "Transfer NOT completed"); } } - //Free URB list and pipe + // Free URB list and pipe for (int i = 0; i < NUM_URBS; i++) { test_hcd_free_urb(urb_list[i]); } test_hcd_pipe_free(isoc_out_pipe); test_hcd_pipe_free(default_pipe); - //Cleanup + // Cleanup test_hcd_wait_for_disconn(port_hdl, false); } @@ -116,23 +117,25 @@ Test HCD ISOC pipe URBs with all channels and intervals combinations */ TEST_CASE("Test HCD isochronous pipe URBs all", "[isoc][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - //The MPS of the ISOC OUT pipe is quite large, so we need to bias the FIFO sizing + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + // The MPS of the ISOC OUT pipe is quite large, so we need to bias the FIFO sizing TEST_ASSERT_EQUAL(ESP_OK, hcd_port_set_fifo_bias(port_hdl, HCD_PORT_FIFO_BIAS_PTX)); - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Enumerate and reset device - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Enumerate and reset device + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); // Create a default pipe (using a NULL EP descriptor) uint8_t dev_addr = test_hcd_enum_device(default_pipe); urb_t *urb_list[NUM_URBS]; hcd_pipe_handle_t unused_pipes[OTG_NUM_HOST_CHAN]; + const usb_ep_desc_t *out_ep_desc = dev_isoc_get_out_ep_desc(port_speed); + const int isoc_packet_size = USB_EP_DESC_GET_MPS(out_ep_desc); // For all channels for (int channel = 0; channel < OTG_NUM_HOST_CHAN - 1; channel++) { // Allocate unused pipes, so the active isoc_out_pipe uses different channel index for (int ch = 0; ch < channel; ch++) { - unused_pipes[ch] = test_hcd_pipe_alloc(port_hdl, &mock_isoc_out_ep_desc, dev_addr + 1, port_speed); + unused_pipes[ch] = test_hcd_pipe_alloc(port_hdl, out_ep_desc, dev_addr + 1, port_speed); } // For all intervals @@ -141,48 +144,49 @@ TEST_CASE("Test HCD isochronous pipe URBs all", "[isoc][full_speed]") vTaskDelay(5); unsigned num_packets_per_urb = 32; // This is maximum number of packets if interval = 1. This is limited by FRAME_LIST_LEN num_packets_per_urb >>= (interval - 1); - //Create ISOC OUT pipe - usb_ep_desc_t isoc_out_ep = mock_isoc_out_ep_desc; // Implicit copy + // Create ISOC OUT pipe + usb_ep_desc_t isoc_out_ep; + memcpy(&isoc_out_ep, out_ep_desc, sizeof(usb_ep_desc_t)); isoc_out_ep.bInterval = interval; isoc_out_ep.bEndpointAddress = interval; // So you can see the bInterval value in trace hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, &isoc_out_ep, channel + 1, port_speed); // Channel number represented in dev_num, so you can see it in trace - //Initialize URBs + // Initialize URBs for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { - urb_list[urb_idx] = test_hcd_alloc_urb(num_packets_per_urb, num_packets_per_urb * ISOC_PACKET_SIZE); - urb_list[urb_idx]->transfer.num_bytes = num_packets_per_urb * ISOC_PACKET_SIZE; + urb_list[urb_idx] = test_hcd_alloc_urb(num_packets_per_urb, num_packets_per_urb * isoc_packet_size); + urb_list[urb_idx]->transfer.num_bytes = num_packets_per_urb * isoc_packet_size; urb_list[urb_idx]->transfer.context = URB_CONTEXT_VAL; for (int pkt_idx = 0; pkt_idx < num_packets_per_urb; pkt_idx++) { - urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = ISOC_PACKET_SIZE; - //Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) - memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * ISOC_PACKET_SIZE], (urb_idx * num_packets_per_urb) + pkt_idx, ISOC_PACKET_SIZE); + urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = isoc_packet_size; + // Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) + memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * isoc_packet_size], (urb_idx * num_packets_per_urb) + pkt_idx, isoc_packet_size); } } // Add a delay so we start scheduling the transactions at different time in USB frame esp_rom_delay_us(ENQUEUE_DELAY * interval + ENQUEUE_DELAY * channel); - //Enqueue URBs + // Enqueue URBs for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(isoc_out_pipe, urb_list[i])); } - //Wait for each done event from each URB + // Wait for each done event from each URB for (int i = 0; i < NUM_URBS; i++) { test_hcd_expect_pipe_event(isoc_out_pipe, HCD_PIPE_EVENT_URB_DONE); } - //Dequeue URBs + // Dequeue URBs for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { urb_t *urb = hcd_urb_dequeue(isoc_out_pipe); TEST_ASSERT_EQUAL(urb_list[urb_idx], urb); TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); - //Overall URB status and overall number of bytes - TEST_ASSERT_EQUAL(num_packets_per_urb * ISOC_PACKET_SIZE, urb->transfer.actual_num_bytes); + // Overall URB status and overall number of bytes + TEST_ASSERT_EQUAL(num_packets_per_urb * isoc_packet_size, urb->transfer.actual_num_bytes); TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); for (int pkt_idx = 0; pkt_idx < num_packets_per_urb; pkt_idx++) { TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.isoc_packet_desc[pkt_idx].status, "Transfer NOT completed"); } } - //Free URB list and pipe + // Free URB list and pipe for (int i = 0; i < NUM_URBS; i++) { test_hcd_free_urb(urb_list[i]); } @@ -195,7 +199,7 @@ TEST_CASE("Test HCD isochronous pipe URBs all", "[isoc][full_speed]") } } test_hcd_pipe_free(default_pipe); - //Cleanup + // Cleanup test_hcd_wait_for_disconn(port_hdl, false); } @@ -225,65 +229,67 @@ Purpose: Test that when sudden disconnection happens on an HCD port, the ISOC pi */ TEST_CASE("Test HCD isochronous pipe sudden disconnect", "[isoc][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - //The MPS of the ISOC OUT pipe is quite large, so we need to bias the FIFO sizing + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + // The MPS of the ISOC OUT pipe is quite large, so we need to bias the FIFO sizing TEST_ASSERT_EQUAL(ESP_OK, hcd_port_set_fifo_bias(port_hdl, HCD_PORT_FIFO_BIAS_PTX)); - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Enumerate and reset device - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Enumerate and reset device + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); // Create a default pipe (using a NULL EP descriptor) uint8_t dev_addr = test_hcd_enum_device(default_pipe); - //Create ISOC OUT pipe to non-existent device - hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, &mock_isoc_out_ep_desc, dev_addr + 1, port_speed); - //Create URBs + // Create ISOC OUT pipe to non-existent device + const usb_ep_desc_t *out_ep_desc = dev_isoc_get_out_ep_desc(port_speed); + const int isoc_packet_size = USB_EP_DESC_GET_MPS(out_ep_desc); + hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, out_ep_desc, dev_addr + 1, port_speed); + // Create URBs urb_t *urb_list[NUM_URBS]; - //Initialize URBs + // Initialize URBs for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { - urb_list[urb_idx] = test_hcd_alloc_urb(NUM_PACKETS_PER_URB, URB_DATA_BUFF_SIZE); - urb_list[urb_idx]->transfer.num_bytes = URB_DATA_BUFF_SIZE; + urb_list[urb_idx] = test_hcd_alloc_urb(NUM_PACKETS_PER_URB, NUM_PACKETS_PER_URB * isoc_packet_size); + urb_list[urb_idx]->transfer.num_bytes = NUM_PACKETS_PER_URB * isoc_packet_size; urb_list[urb_idx]->transfer.context = URB_CONTEXT_VAL; for (int pkt_idx = 0; pkt_idx < NUM_PACKETS_PER_URB; pkt_idx++) { - urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = ISOC_PACKET_SIZE; - //Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) - memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * ISOC_PACKET_SIZE], (urb_idx * NUM_URBS) + pkt_idx, ISOC_PACKET_SIZE); + urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = isoc_packet_size; + // Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) + memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * isoc_packet_size], (urb_idx * NUM_URBS) + pkt_idx, isoc_packet_size); } } - //Enqueue URBs + // Enqueue URBs for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(isoc_out_pipe, urb_list[i])); } - //Add a short delay to let the transfers run for a bit + // Add a short delay to let the transfers run for a bit esp_rom_delay_us(POST_ENQUEUE_DELAY_US); test_usb_set_phy_state(false, 0); - //Disconnect event should have occurred. Handle the port event + // Disconnect event should have occurred. Handle the port event test_hcd_expect_port_event(port_hdl, HCD_PORT_EVENT_DISCONNECTION); TEST_ASSERT_EQUAL(HCD_PORT_EVENT_DISCONNECTION, hcd_port_handle_event(port_hdl)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_RECOVERY, hcd_port_get_state(port_hdl)); printf("Sudden disconnect\n"); - //Both pipes should still be active + // Both pipes should still be active TEST_ASSERT_EQUAL(HCD_PIPE_STATE_ACTIVE, hcd_pipe_get_state(default_pipe)); TEST_ASSERT_EQUAL(HCD_PIPE_STATE_ACTIVE, hcd_pipe_get_state(isoc_out_pipe)); - //Halt both pipes + // Halt both pipes TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_HALT)); TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(isoc_out_pipe, HCD_PIPE_CMD_HALT)); TEST_ASSERT_EQUAL(HCD_PIPE_STATE_HALTED, hcd_pipe_get_state(default_pipe)); TEST_ASSERT_EQUAL(HCD_PIPE_STATE_HALTED, hcd_pipe_get_state(isoc_out_pipe)); - //Flush both pipes. ISOC pipe should return completed URBs + // Flush both pipes. ISOC pipe should return completed URBs TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_FLUSH)); TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(isoc_out_pipe, HCD_PIPE_CMD_FLUSH)); - //Dequeue ISOC URBs + // Dequeue ISOC URBs for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { urb_t *urb = hcd_urb_dequeue(isoc_out_pipe); TEST_ASSERT_EQUAL(urb_list[urb_idx], urb); TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); - //The URB has either completed entirely or is marked as no_device + // The URB has either completed entirely or is marked as no_device TEST_ASSERT(urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED || urb->transfer.status == USB_TRANSFER_STATUS_NO_DEVICE); } - //Free URB list and pipe + // Free URB list and pipe for (int i = 0; i < NUM_URBS; i++) { test_hcd_free_urb(urb_list[i]); } diff --git a/components/usb/test_apps/hcd/main/test_hcd_port.c b/components/usb/test_apps/hcd/main/test_hcd_port.c index 3b44623cba75..7ddb4a2cb2b6 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_port.c +++ b/components/usb/test_apps/hcd/main/test_hcd_port.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,9 +15,32 @@ #define TEST_DEV_ADDR 0 #define NUM_URBS 3 #define TRANSFER_MAX_BYTES 256 -#define URB_DATA_BUFF_SIZE (sizeof(usb_setup_packet_t) + TRANSFER_MAX_BYTES) //256 is worst case size for configuration descriptors +#define URB_DATA_BUFF_SIZE (sizeof(usb_setup_packet_t) + TRANSFER_MAX_BYTES) // 256 is worst case size for configuration descriptors #define POST_ENQUEUE_DELAY_US 10 +/* +Test a port for a disconnect event, when port is in ENABLED state + +Purpose: This test is essential on HS HCD ports, when device is detaching during the action. + When the HS port is ENABLED, the port operates in HS mode and device disconnection is detected by HS logic. + When the HS port is DISABLED (without issuing a reset), the port operates in FS mode and device disconnection differs for HS mode disconnection logic. + +Procedure: + - Setup the HCD and a port + - Trigger the port connection event + - Trigger the port disconnection event + - Teardown port and HCD +*/ +TEST_CASE("Test HCD port disconnect event, port enabled", "[port][low_speed][full_speed]") +{ + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + printf("Connected %s speed device \n", (char*[]) { + "Low", "Full", "High" + }[port_speed]); + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) + test_hcd_wait_for_disconn(port_hdl, true); +} + /* Test a port sudden disconnect and port recovery @@ -43,35 +66,35 @@ Purpose: Test that when sudden disconnection happens on an HCD port, the port wi TEST_CASE("Test HCD port sudden disconnect", "[port][low_speed][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Allocate some URBs and initialize their data buffers with control transfers - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Allocate some URBs and initialize their data buffers with control transfers + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); // Create a default pipe (using a NULL EP descriptor) urb_t *urb_list[NUM_URBS]; for (int i = 0; i < NUM_URBS; i++) { urb_list[i] = test_hcd_alloc_urb(0, URB_DATA_BUFF_SIZE); - //Initialize with a "Get Config Descriptor request" + // Initialize with a "Get Config Descriptor request" urb_list[i]->transfer.num_bytes = sizeof(usb_setup_packet_t) + TRANSFER_MAX_BYTES; USB_SETUP_PACKET_INIT_GET_CONFIG_DESC((usb_setup_packet_t *)urb_list[i]->transfer.data_buffer, 0, TRANSFER_MAX_BYTES); urb_list[i]->transfer.context = (void *)0xDEADBEEF; } - //Enqueue URBs but immediately trigger a disconnect + // Enqueue URBs but immediately trigger a disconnect printf("Enqueuing URBs\n"); for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb_list[i])); } - //Add a short delay to let the transfers run for a bit + // Add a short delay to let the transfers run for a bit esp_rom_delay_us(POST_ENQUEUE_DELAY_US); test_usb_set_phy_state(false, 0); - //Disconnect event should have occurred. Handle the port event + // Disconnect event should have occurred. Handle the port event test_hcd_expect_port_event(port_hdl, HCD_PORT_EVENT_DISCONNECTION); TEST_ASSERT_EQUAL(HCD_PORT_EVENT_DISCONNECTION, hcd_port_handle_event(port_hdl)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_RECOVERY, hcd_port_get_state(port_hdl)); printf("Sudden disconnect\n"); - //We should be able to halt then flush the pipe + // We should be able to halt then flush the pipe TEST_ASSERT_EQUAL(HCD_PIPE_STATE_ACTIVE, hcd_pipe_get_state(default_pipe)); TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_HALT)); printf("Pipe halted\n"); @@ -80,32 +103,32 @@ TEST_CASE("Test HCD port sudden disconnect", "[port][low_speed][full_speed]") test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE); printf("Pipe flushed\n"); - //Dequeue URBs + // Dequeue URBs for (int i = 0; i < NUM_URBS; i++) { urb_t *urb = hcd_urb_dequeue(default_pipe); TEST_ASSERT_EQUAL(urb_list[i], urb); TEST_ASSERT(urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED || urb->transfer.status == USB_TRANSFER_STATUS_NO_DEVICE); if (urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED) { - //We must have transmitted at least the setup packet, but device may return less than bytes requested + // We must have transmitted at least the setup packet, but device may return less than bytes requested TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes); TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes); } else { - //A failed transfer should 0 actual number of bytes transmitted + // A failed transfer should 0 actual number of bytes transmitted TEST_ASSERT_EQUAL(0, urb->transfer.actual_num_bytes); } TEST_ASSERT_EQUAL(0xDEADBEEF, urb->transfer.context); } - //Free URB list and pipe + // Free URB list and pipe for (int i = 0; i < NUM_URBS; i++) { test_hcd_free_urb(urb_list[i]); } test_hcd_pipe_free(default_pipe); - //Recover the port should return to the to NOT POWERED state + // Recover the port should return to the to NOT POWERED state TEST_ASSERT_EQUAL(ESP_OK, hcd_port_recover(port_hdl)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_NOT_POWERED, hcd_port_get_state(port_hdl)); - //Recovered port should be able to connect and disconnect again + // Recovered port should be able to connect and disconnect again test_hcd_wait_for_conn(port_hdl); test_hcd_wait_for_disconn(port_hdl, false); } @@ -132,38 +155,38 @@ Test port suspend and resume with active pipes */ TEST_CASE("Test HCD port suspend and resume", "[port][low_speed][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Allocate some URBs and initialize their data buffers with control transfers - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Allocate some URBs and initialize their data buffers with control transfers + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); // Create a default pipe (using a NULL EP descriptor) - //Test that suspending the port now fails as there is an active pipe + // Test that suspending the port now fails as there is an active pipe TEST_ASSERT_NOT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_SUSPEND)); - //Halt the default pipe before suspending + // Halt the default pipe before suspending TEST_ASSERT_EQUAL(HCD_PIPE_STATE_ACTIVE, hcd_pipe_get_state(default_pipe)); TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_HALT)); TEST_ASSERT_EQUAL(HCD_PIPE_STATE_HALTED, hcd_pipe_get_state(default_pipe)); - //Suspend the port + // Suspend the port TEST_ASSERT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_SUSPEND)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_SUSPENDED, hcd_port_get_state(port_hdl)); printf("Suspended\n"); - vTaskDelay(pdMS_TO_TICKS(100)); //Give some time for bus to remain suspended + vTaskDelay(pdMS_TO_TICKS(100)); // Give some time for bus to remain suspended - //Resume the port + // Resume the port TEST_ASSERT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_RESUME)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_ENABLED, hcd_port_get_state(port_hdl)); printf("Resumed\n"); - //Clear the default pipe's halt + // Clear the default pipe's halt TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_CLEAR)); TEST_ASSERT_EQUAL(HCD_PIPE_STATE_ACTIVE, hcd_pipe_get_state(default_pipe)); - vTaskDelay(pdMS_TO_TICKS(100)); //Give some time for resumed URBs to complete + vTaskDelay(pdMS_TO_TICKS(100)); // Give some time for resumed URBs to complete test_hcd_pipe_free(default_pipe); - //Cleanup + // Cleanup test_hcd_wait_for_disconn(port_hdl, false); } @@ -186,65 +209,65 @@ Test HCD port disable and disconnection */ TEST_CASE("Test HCD port disable", "[port][low_speed][full_speed]") { - usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); // Trigger a connection + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Allocate some URBs and initialize their data buffers with control transfers - hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); //Create a default pipe (using a NULL EP descriptor) + // Allocate some URBs and initialize their data buffers with control transfers + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, TEST_DEV_ADDR, port_speed); // Create a default pipe (using a NULL EP descriptor) urb_t *urb_list[NUM_URBS]; for (int i = 0; i < NUM_URBS; i++) { urb_list[i] = test_hcd_alloc_urb(0, URB_DATA_BUFF_SIZE); - //Initialize with a "Get Config Descriptor request" + // Initialize with a "Get Config Descriptor request" urb_list[i]->transfer.num_bytes = sizeof(usb_setup_packet_t) + TRANSFER_MAX_BYTES; USB_SETUP_PACKET_INIT_GET_CONFIG_DESC((usb_setup_packet_t *)urb_list[i]->transfer.data_buffer, 0, TRANSFER_MAX_BYTES); urb_list[i]->transfer.context = (void *)0xDEADBEEF; } - //Enqueue URBs but immediately disable the port + // Enqueue URBs but immediately disable the port printf("Enqueuing URBs\n"); for (int i = 0; i < NUM_URBS; i++) { TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb_list[i])); - //Add a short delay to let the transfers run for a bit + // Add a short delay to let the transfers run for a bit esp_rom_delay_us(POST_ENQUEUE_DELAY_US); } - //Halt the default pipe before suspending + // Halt the default pipe before suspending TEST_ASSERT_EQUAL(HCD_PIPE_STATE_ACTIVE, hcd_pipe_get_state(default_pipe)); TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_HALT)); TEST_ASSERT_EQUAL(HCD_PIPE_STATE_HALTED, hcd_pipe_get_state(default_pipe)); - //Check that port can be disabled + // Check that port can be disabled TEST_ASSERT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_DISABLE)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_DISABLED, hcd_port_get_state(port_hdl)); printf("Disabled\n"); - //Flush pipe + // Flush pipe TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_FLUSH)); - //Dequeue URBs + // Dequeue URBs for (int i = 0; i < NUM_URBS; i++) { urb_t *urb = hcd_urb_dequeue(default_pipe); TEST_ASSERT_EQUAL(urb_list[i], urb); - TEST_ASSERT(urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED || //The transfer completed before the pipe halted - urb->transfer.status == USB_TRANSFER_STATUS_CANCELED || //The transfer was stopped mid-way by the halt - urb->transfer.status == USB_TRANSFER_STATUS_NO_DEVICE); //The transfer was never started + TEST_ASSERT(urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED || // The transfer completed before the pipe halted + urb->transfer.status == USB_TRANSFER_STATUS_CANCELED || // The transfer was stopped mid-way by the halt + urb->transfer.status == USB_TRANSFER_STATUS_NO_DEVICE); // The transfer was never started if (urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED) { - //We must have transmitted at least the setup packet, but device may return less than bytes requested + // We must have transmitted at least the setup packet, but device may return less than bytes requested TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes); TEST_ASSERT_LESS_OR_EQUAL(urb->transfer.num_bytes, urb->transfer.actual_num_bytes); } else { - //A failed transfer should 0 actual number of bytes transmitted + // A failed transfer should 0 actual number of bytes transmitted TEST_ASSERT_EQUAL(0, urb->transfer.actual_num_bytes); } TEST_ASSERT_EQUAL(0xDEADBEEF, urb->transfer.context); } - //Free URB list and pipe + // Free URB list and pipe for (int i = 0; i < NUM_URBS; i++) { test_hcd_free_urb(urb_list[i]); } test_hcd_pipe_free(default_pipe); - //Trigger a disconnection and cleanup + // Trigger a disconnection and cleanup test_hcd_wait_for_disconn(port_hdl, true); } @@ -266,40 +289,40 @@ static void concurrent_task(void *arg) { SemaphoreHandle_t sync_sem = (SemaphoreHandle_t) arg; xSemaphoreTake(sync_sem, portMAX_DELAY); - vTaskDelay(pdMS_TO_TICKS(10)); //Give a short delay let reset command start in main thread - //Force a disconnection + vTaskDelay(pdMS_TO_TICKS(10)); // Give a short delay let reset command start in main thread + // Force a disconnection test_usb_set_phy_state(false, 0); - vTaskDelay(portMAX_DELAY); //Block forever and wait to be deleted + vTaskDelay(portMAX_DELAY); // Block forever and wait to be deleted } TEST_CASE("Test HCD port command bailout", "[port][low_speed][full_speed]") { - test_hcd_wait_for_conn(port_hdl); //Trigger a connection - vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + test_hcd_wait_for_conn(port_hdl); // Trigger a connection + vTaskDelay(pdMS_TO_TICKS(100)); // Short delay send of SOF (for FS) or EOPs (for LS) - //Create task to run port commands concurrently + // Create task to run port commands concurrently SemaphoreHandle_t sync_sem = xSemaphoreCreateBinary(); TaskHandle_t task_handle; TEST_ASSERT_NOT_NULL(sync_sem); TEST_ASSERT_EQUAL(pdTRUE, xTaskCreatePinnedToCore(concurrent_task, "tsk", 4096, (void *) sync_sem, uxTaskPriorityGet(NULL) + 1, &task_handle, 0)); - //Suspend the device + // Suspend the device printf("Suspending\n"); TEST_ASSERT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_SUSPEND)); - vTaskDelay(pdMS_TO_TICKS(20)); //Short delay for device to enter suspend state + vTaskDelay(pdMS_TO_TICKS(20)); // Short delay for device to enter suspend state - //Attempt to resume the port. But the concurrent task should override this with a disconnection event + // Attempt to resume the port. But the concurrent task should override this with a disconnection event printf("Attempting to resume\n"); - xSemaphoreGive(sync_sem); //Trigger concurrent task + xSemaphoreGive(sync_sem); // Trigger concurrent task TEST_ASSERT_EQUAL(ESP_ERR_INVALID_RESPONSE, hcd_port_command(port_hdl, HCD_PORT_CMD_RESUME)); - //Check that concurrent task triggered a sudden disconnection + // Check that concurrent task triggered a sudden disconnection test_hcd_expect_port_event(port_hdl, HCD_PORT_EVENT_DISCONNECTION); TEST_ASSERT_EQUAL(HCD_PORT_EVENT_DISCONNECTION, hcd_port_handle_event(port_hdl)); TEST_ASSERT_EQUAL(HCD_PORT_STATE_RECOVERY, hcd_port_get_state(port_hdl)); - //Cleanup task and semaphore - vTaskDelay(pdMS_TO_TICKS(10)); //Short delay for concurrent task finish running + // Cleanup task and semaphore + vTaskDelay(pdMS_TO_TICKS(10)); // Short delay for concurrent task finish running vTaskDelete(task_handle); vSemaphoreDelete(sync_sem); } diff --git a/components/usb/test_apps/hcd/main/test_usb_helpers.c b/components/usb/test_apps/hcd/main/test_usb_helpers.c index fafe81c03294..742ae56125a4 100644 --- a/components/usb/test_apps/hcd/main/test_usb_helpers.c +++ b/components/usb/test_apps/hcd/main/test_usb_helpers.c @@ -333,7 +333,7 @@ static uint8_t config_desc_bytes [] = { }; _Static_assert(sizeof(config_desc_bytes) == 0x0185, "Configuration Descriptor size does not match"); -#define TEST_NUM_INTF_DESC 3 //Total number of interface descriptors (including alternate) +#define TEST_NUM_INTF_DESC 3 // Total number of interface descriptors (including alternate) // --------------------- Sub-Test 1 ------------------------ @@ -348,7 +348,7 @@ static void test_walk_desc(const usb_config_desc_t *config_desc) cur_desc = usb_parse_next_descriptor_of_type(cur_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset); TEST_ASSERT_NOT_NULL(cur_desc); } - //Attempting to look for another interface descriptor should result in NULL + // Attempting to look for another interface descriptor should result in NULL cur_desc = usb_parse_next_descriptor_of_type(cur_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset); TEST_ASSERT_NULL(cur_desc); } @@ -358,11 +358,11 @@ Test if the count of number of alternate descriptors is correct */ static void test_alt_intf_desc_count(const usb_config_desc_t *config_desc) { - //bInterface 0 has no alternate interfaces + // bInterface 0 has no alternate interfaces TEST_ASSERT_EQUAL(0, usb_parse_interface_number_of_alternate(config_desc, 0)); - //bInterface 1 has 1 alternate interface + // bInterface 1 has 1 alternate interface TEST_ASSERT_EQUAL(1, usb_parse_interface_number_of_alternate(config_desc, 1)); - //Non existent bInterface 2 should return -1 + // Non existent bInterface 2 should return -1 TEST_ASSERT_EQUAL(-1, usb_parse_interface_number_of_alternate(config_desc, 2)); } @@ -370,10 +370,10 @@ static void test_parse_intf_and_ep(const usb_config_desc_t *config_desc) { int offset_intf = 0; - //Get bInterfaceNumber 0 (index 0) + // Get bInterfaceNumber 0 (index 0) const usb_intf_desc_t *intf_desc = usb_parse_interface_descriptor(config_desc, 0, 0, &offset_intf); TEST_ASSERT_NOT_NULL(intf_desc); - //Should only have one endpoint + // Should only have one endpoint int offset_ep = offset_intf; const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep); TEST_ASSERT_NOT_NULL(ep_desc); @@ -382,20 +382,20 @@ static void test_parse_intf_and_ep(const usb_config_desc_t *config_desc) ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 1, config_desc->wTotalLength, &offset_ep); TEST_ASSERT_NULL(ep_desc); - //Get bInterfaceNumber 1 alternate setting 0 + // Get bInterfaceNumber 1 alternate setting 0 offset_intf = 0; intf_desc = usb_parse_interface_descriptor(config_desc, 1, 0, &offset_intf); TEST_ASSERT_NOT_NULL(intf_desc); - //Should have no endpoints + // Should have no endpoints offset_ep = offset_intf; ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep); TEST_ASSERT_NULL(ep_desc); - //Get bInterfaceNumber 1 alternate setting 1 + // Get bInterfaceNumber 1 alternate setting 1 offset_intf = 0; intf_desc = usb_parse_interface_descriptor(config_desc, 1, 1, &offset_intf); TEST_ASSERT_NOT_NULL(intf_desc); - //Should only have one endpoint + // Should only have one endpoint offset_ep = offset_intf; ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep); TEST_ASSERT_NOT_NULL(ep_desc); @@ -408,21 +408,21 @@ static void test_parse_intf_and_ep(const usb_config_desc_t *config_desc) static void test_parse_ep_by_address(const usb_config_desc_t *config_desc) { int offset_ep = 0; - //Get bInterface 0 bAlternateSetting 0 EP 0x83 + // Get bInterface 0 bAlternateSetting 0 EP 0x83 const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 0, 0, 0x83, &offset_ep); TEST_ASSERT_NOT_NULL(ep_desc); TEST_ASSERT_EQUAL(0x83, ep_desc->bEndpointAddress); - //Getting same EP address under different interface should return NULL + // Getting same EP address under different interface should return NULL offset_ep = 0; ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 0, 0x83, &offset_ep); TEST_ASSERT_NULL(ep_desc); - //Get bInterface 1 bAlternateSetting 1 EP 0x81 + // Get bInterface 1 bAlternateSetting 1 EP 0x81 offset_ep = 0; ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 1, 0x81, &offset_ep); TEST_ASSERT_NOT_NULL(ep_desc); TEST_ASSERT_EQUAL(0x81, ep_desc->bEndpointAddress); - //Getting same EP address under different interface should return NULL + // Getting same EP address under different interface should return NULL offset_ep = 0; ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 0, 0x81, &offset_ep); TEST_ASSERT_NULL(ep_desc); diff --git a/components/usb/test_apps/usb_host/README.md b/components/usb/test_apps/usb_host/README.md index afe40d8da3b6..c76482cea32c 100644 --- a/components/usb/test_apps/usb_host/README.md +++ b/components/usb/test_apps/usb_host/README.md @@ -7,5 +7,5 @@ There are two sets of tests in this application: 1. Low-speed: Expects low-speed USB mouse with interrupt endpoint to be connected 2. Full-speed: Expects full-speed USB flash disk with 2 bulk endpoints to be connected -For running these tests locally, you will have to update device definitions (VID, PID, ...) in [test_usb_mock_msc.h](../common/test_usb_mock_msc.h) and [test_usb_mock_hid.h](../common/test_usb_mock_hid.h). +For running these tests locally, you will have to update device definitions (VID, PID, ...) in [mock_msc.h](../common/mock_msc.h) and [mock_hid.h](../common/mock_hid.h). diff --git a/components/usb/test_apps/usb_host/main/Kconfig.projbuild b/components/usb/test_apps/usb_host/main/Kconfig.projbuild new file mode 100644 index 000000000000..8706cdd15da6 --- /dev/null +++ b/components/usb/test_apps/usb_host/main/Kconfig.projbuild @@ -0,0 +1,24 @@ +menu "USB Host Library Test" + + config USB_HOST_TEST_CHECK_MANU_STR + bool "Check manufacturer string descriptor" + default y + help + USB Host tests that check string descriptors will check the manufacturer string + descriptor of the connected device. + + config USB_HOST_TEST_CHECK_PROD_STR + bool "Check product string descriptor" + default n + help + USB Host tests that check string descriptors will check the product string descriptor + of the connected device. + + config USB_HOST_TEST_CHECK_SERIAL_STR + bool "Check serial string descriptor" + default n + help + USB Host tests that check string descriptors will check the serial string descriptor + of the connected device. + +endmenu diff --git a/components/usb/test_apps/usb_host/main/ctrl_client.h b/components/usb/test_apps/usb_host/main/ctrl_client.h index 4cfeccc53d79..b780571f6b98 100644 --- a/components/usb/test_apps/usb_host/main/ctrl_client.h +++ b/components/usb/test_apps/usb_host/main/ctrl_client.h @@ -8,8 +8,6 @@ typedef struct { int num_ctrl_xfer_to_send; - uint16_t idVendor; - uint16_t idProduct; } ctrl_client_test_param_t; void ctrl_client_async_seq_task(void *arg); diff --git a/components/usb/test_apps/usb_host/main/ctrl_client_async_seq.c b/components/usb/test_apps/usb_host/main/ctrl_client_async_seq.c index b163dc20fbcb..657cf8759506 100644 --- a/components/usb/test_apps/usb_host/main/ctrl_client_async_seq.c +++ b/components/usb/test_apps/usb_host/main/ctrl_client_async_seq.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ #include "esp_err.h" #include "esp_log.h" #include "test_usb_common.h" +#include "dev_msc.h" #include "ctrl_client.h" #include "usb/usb_host.h" #include "unity.h" @@ -47,21 +48,26 @@ typedef enum { } test_stage_t; typedef struct { + // Test parameters ctrl_client_test_param_t test_param; + // MSC device info + uint8_t dev_addr; + usb_speed_t dev_speed; + // Client variables + usb_host_client_handle_t client_hdl; + usb_device_handle_t dev_hdl; + // Test state test_stage_t cur_stage; test_stage_t next_stage; uint8_t num_xfer_done; uint8_t num_xfer_sent; - uint8_t dev_addr_to_open; - usb_host_client_handle_t client_hdl; - usb_device_handle_t dev_hdl; const usb_config_desc_t *config_desc_cached; } ctrl_client_obj_t; static void ctrl_transfer_cb(usb_transfer_t *transfer) { ctrl_client_obj_t *ctrl_obj = (ctrl_client_obj_t *)transfer->context; - //Check the completed control transfer + // Check the completed control transfer TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed"); TEST_ASSERT_EQUAL(ctrl_obj->config_desc_cached->wTotalLength, transfer->actual_num_bytes - sizeof(usb_setup_packet_t)); ctrl_obj->num_xfer_done++; @@ -79,10 +85,10 @@ static void ctrl_client_event_cb(const usb_host_client_event_msg_t *event_msg, v case USB_HOST_CLIENT_EVENT_NEW_DEV: TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, ctrl_obj->cur_stage); ctrl_obj->next_stage = TEST_STAGE_DEV_OPEN; - ctrl_obj->dev_addr_to_open = event_msg->new_dev.address; + ctrl_obj->dev_addr = event_msg->new_dev.address; break; default: - abort(); //Should never occur in this test + abort(); // Should never occur in this test break; } } @@ -94,7 +100,7 @@ void ctrl_client_async_seq_task(void *arg) ctrl_obj.cur_stage = TEST_STAGE_WAIT_CONN; ctrl_obj.next_stage = TEST_STAGE_WAIT_CONN; - //Register client + // Register client usb_host_client_config_t client_config = { .is_synchronous = false, .max_num_event_msg = CTRL_CLIENT_MAX_EVENT_MSGS, @@ -105,7 +111,7 @@ void ctrl_client_async_seq_task(void *arg) }; TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &ctrl_obj.client_hdl)); - //Allocate transfers + // Allocate transfers usb_transfer_t *ctrl_xfer[NUM_TRANSFER_OBJ] = {NULL}; for (int i = 0; i < NUM_TRANSFER_OBJ; i++) { TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(sizeof(usb_setup_packet_t) + MAX_TRANSFER_BYTES, 0, &ctrl_xfer[i])); @@ -113,7 +119,7 @@ void ctrl_client_async_seq_task(void *arg) ctrl_xfer[i]->context = (void *)&ctrl_obj; } - //Wait to be started by main thread + // Wait to be started by main thread ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ESP_LOGD(CTRL_CLIENT_TAG, "Starting"); @@ -132,18 +138,23 @@ void ctrl_client_async_seq_task(void *arg) switch (ctrl_obj.next_stage) { case TEST_STAGE_DEV_OPEN: { ESP_LOGD(CTRL_CLIENT_TAG, "Open"); - //Open the device - TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_host_device_open(ctrl_obj.client_hdl, ctrl_obj.dev_addr_to_open, &ctrl_obj.dev_hdl), "Failed to open the device"); - //Target our transfers to the device + // Open the device + TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_host_device_open(ctrl_obj.client_hdl, ctrl_obj.dev_addr, &ctrl_obj.dev_hdl), "Failed to open the device"); + // Get device info to get device speed + usb_device_info_t dev_info; + TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(ctrl_obj.dev_hdl, &dev_info)); + ctrl_obj.dev_speed = dev_info.speed; + // Target our transfers to the device for (int i = 0; i < NUM_TRANSFER_OBJ; i++) { ctrl_xfer[i]->device_handle = ctrl_obj.dev_hdl; } - //Check the VID/PID of the opened device + // Check that the device descriptor matches our expected MSC device const usb_device_desc_t *device_desc; + const usb_device_desc_t *device_desc_ref = dev_msc_get_dev_desc(ctrl_obj.dev_speed); TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(ctrl_obj.dev_hdl, &device_desc)); - TEST_ASSERT_EQUAL(ctrl_obj.test_param.idVendor, device_desc->idVendor); - TEST_ASSERT_EQUAL(ctrl_obj.test_param.idProduct, device_desc->idProduct); - //Cache the active configuration descriptor for later comparison + TEST_ASSERT_EQUAL(device_desc_ref->bLength, device_desc->bLength); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, sizeof(usb_device_desc_t), "Device descriptors do not match."); + // Cache the active configuration descriptor for later comparison TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_active_config_descriptor(ctrl_obj.dev_hdl, &ctrl_obj.config_desc_cached)); ctrl_obj.next_stage = TEST_STAGE_CTRL_XFER; skip_event_handling = true; @@ -151,7 +162,7 @@ void ctrl_client_async_seq_task(void *arg) } case TEST_STAGE_CTRL_XFER: { ESP_LOGD(CTRL_CLIENT_TAG, "Transfer"); - //Send a control transfer to get the device's configuration descriptor + // Send a control transfer to get the device's configuration descriptor usb_transfer_t *transfer = ctrl_xfer[ctrl_obj.num_xfer_sent % NUM_TRANSFER_OBJ]; USB_SETUP_PACKET_INIT_GET_CONFIG_DESC((usb_setup_packet_t *)transfer->data_buffer, 0, MAX_TRANSFER_BYTES); transfer->num_bytes = sizeof(usb_setup_packet_t) + MAX_TRANSFER_BYTES; @@ -163,12 +174,12 @@ void ctrl_client_async_seq_task(void *arg) break; } case TEST_STAGE_CTRL_XFER_WAIT: { - //Nothing to do but wait + // Nothing to do but wait break; } case TEST_STAGE_DEV_CLOSE: { ESP_LOGD(CTRL_CLIENT_TAG, "Close"); - vTaskDelay(10); // Give USB Host Lib some time to process all trnsfers + vTaskDelay(10); // Give USB Host Lib some time to process all transfers TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(ctrl_obj.client_hdl, ctrl_obj.dev_hdl)); exit_loop = true; break; @@ -178,7 +189,7 @@ void ctrl_client_async_seq_task(void *arg) break; } } - //Free transfers and deregister client + // Free transfers and deregister client for (int i = 0; i < NUM_TRANSFER_OBJ; i++) { TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_free(ctrl_xfer[i])); } diff --git a/components/usb/test_apps/usb_host/main/msc_client.h b/components/usb/test_apps/usb_host/main/msc_client.h index c3bf2063f27f..6a816547bdd9 100644 --- a/components/usb/test_apps/usb_host/main/msc_client.h +++ b/components/usb/test_apps/usb_host/main/msc_client.h @@ -12,8 +12,6 @@ typedef struct { int num_sectors_to_read; int num_sectors_per_xfer; uint32_t msc_scsi_xfer_tag; - uint16_t idVendor; - uint16_t idProduct; } msc_client_test_param_t; void msc_client_async_seq_task(void *arg); diff --git a/components/usb/test_apps/usb_host/main/msc_client_async_dconn.c b/components/usb/test_apps/usb_host/main/msc_client_async_dconn.c index af6bc5435beb..5f1df1cf1512 100644 --- a/components/usb/test_apps/usb_host/main/msc_client_async_dconn.c +++ b/components/usb/test_apps/usb_host/main/msc_client_async_dconn.c @@ -12,9 +12,11 @@ #include "freertos/task.h" #include "esp_err.h" #include "esp_log.h" -#include "test_usb_mock_msc.h" +#include "mock_msc.h" +#include "dev_msc.h" #include "test_usb_common.h" #include "msc_client.h" +#include "usb/usb_types_ch9.h" #include "usb/usb_host.h" #include "unity.h" @@ -47,21 +49,26 @@ typedef enum { } test_stage_t; typedef struct { + // Test parameters msc_client_test_param_t test_param; - test_stage_t cur_stage; - test_stage_t next_stage; - uint8_t dev_addr_to_open; + // MSC device info + const dev_msc_info_t *dev_info; + usb_speed_t dev_speed; + uint8_t dev_addr; + // Client variables usb_host_client_handle_t client_hdl; usb_device_handle_t dev_hdl; + // Test state + test_stage_t cur_stage; + test_stage_t next_stage; int num_data_transfers; int event_count; - usb_speed_t dev_speed; } msc_client_obj_t; static void msc_reset_cbw_transfer_cb(usb_transfer_t *transfer) { msc_client_obj_t *msc_obj = (msc_client_obj_t *)transfer->context; - //We expect the reset and CBW transfers to complete with no issues + // We expect the reset and CBW transfers to complete with no issues TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed"); TEST_ASSERT_EQUAL(transfer->num_bytes, transfer->actual_num_bytes); switch (msc_obj->cur_stage) { @@ -79,7 +86,7 @@ static void msc_reset_cbw_transfer_cb(usb_transfer_t *transfer) static void msc_data_transfer_cb(usb_transfer_t *transfer) { - //The data stage should have either completed, or failed due to the disconnection. + // The data stage should have either completed, or failed due to the disconnection. TEST_ASSERT(transfer->status == USB_TRANSFER_STATUS_COMPLETED || transfer->status == USB_TRANSFER_STATUS_NO_DEVICE); if (transfer->status == USB_TRANSFER_STATUS_COMPLETED) { TEST_ASSERT_EQUAL(transfer->num_bytes, transfer->actual_num_bytes); @@ -88,7 +95,7 @@ static void msc_data_transfer_cb(usb_transfer_t *transfer) } msc_client_obj_t *msc_obj = (msc_client_obj_t *)transfer->context; msc_obj->event_count++; - //If all transfers dequeued and device gone event occurred. Go to next stage + // If all transfers dequeued and device gone event occurred. Go to next stage if (msc_obj->event_count >= msc_obj->num_data_transfers + 1) { msc_obj->next_stage = TEST_STAGE_DEV_CLOSE; } @@ -101,17 +108,17 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo case USB_HOST_CLIENT_EVENT_NEW_DEV: TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, msc_obj->cur_stage); msc_obj->next_stage = TEST_STAGE_DEV_OPEN; - msc_obj->dev_addr_to_open = event_msg->new_dev.address; + msc_obj->dev_addr = event_msg->new_dev.address; break; case USB_HOST_CLIENT_EVENT_DEV_GONE: msc_obj->event_count++; - //If all transfers dequeued and device gone event occurred. Go to next stage + // If all transfers dequeued and device gone event occurred. Go to next stage if (msc_obj->event_count >= msc_obj->num_data_transfers + 1) { msc_obj->next_stage = TEST_STAGE_DEV_CLOSE; } break; default: - abort(); //Should never occur in this test + abort(); // Should never occur in this test break; } } @@ -119,16 +126,20 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo void msc_client_async_dconn_task(void *arg) { msc_client_obj_t msc_obj; + // Initialize test params memcpy(&msc_obj.test_param, arg, sizeof(msc_client_test_param_t)); - msc_obj.cur_stage = TEST_STAGE_WAIT_CONN; - msc_obj.next_stage = TEST_STAGE_WAIT_CONN; - msc_obj.dev_addr_to_open = 0; + // Initialize MSC device info + msc_obj.dev_info = dev_msc_get_info(); + // Initialize client variables msc_obj.client_hdl = NULL; msc_obj.dev_hdl = NULL; - msc_obj.num_data_transfers = msc_obj.test_param.num_sectors_per_xfer / MOCK_MSC_SCSI_SECTOR_SIZE; + // Initialize test state + msc_obj.cur_stage = TEST_STAGE_WAIT_CONN; + msc_obj.next_stage = TEST_STAGE_WAIT_CONN; + msc_obj.num_data_transfers = msc_obj.test_param.num_sectors_per_xfer / msc_obj.dev_info->scsi_sector_size; msc_obj.event_count = 0; - //Register client + // Register client usb_host_client_config_t client_config = { .is_synchronous = false, .max_num_event_msg = MSC_ASYNC_CLIENT_MAX_EVENT_MSGS, @@ -139,11 +150,11 @@ void msc_client_async_dconn_task(void *arg) }; TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &msc_obj.client_hdl)); - //Allocate transfers - usb_transfer_t *xfer_out; //Must be large enough to contain CBW and MSC reset control transfer - usb_transfer_t *xfer_in[msc_obj.num_data_transfers]; //We manually split the data stage into multiple transfers + // Allocate transfers + usb_transfer_t *xfer_out; // Must be large enough to contain CBW and MSC reset control transfer + usb_transfer_t *xfer_in[msc_obj.num_data_transfers]; // We manually split the data stage into multiple transfers size_t xfer_out_size = MAX(sizeof(mock_msc_bulk_cbw_t), sizeof(usb_setup_packet_t)); - size_t xfer_in_size = MOCK_MSC_SCSI_SECTOR_SIZE; + size_t xfer_in_size = msc_obj.dev_info->scsi_sector_size; TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(xfer_out_size, 0, &xfer_out)); xfer_out->context = (void *)&msc_obj; for (int i = 0; i < msc_obj.num_data_transfers; i++) { @@ -151,7 +162,7 @@ void msc_client_async_dconn_task(void *arg) xfer_in[i]->context = (void *)&msc_obj; } - //Wait to be started by main thread + // Wait to be started by main thread ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ESP_LOGD(MSC_CLIENT_TAG, "Starting"); @@ -170,82 +181,90 @@ void msc_client_async_dconn_task(void *arg) switch (msc_obj.cur_stage) { case TEST_STAGE_WAIT_CONN: { - //Nothing to do while waiting for connection + // Nothing to do while waiting for connection break; } case TEST_STAGE_DEV_OPEN: { ESP_LOGD(MSC_CLIENT_TAG, "Open"); - //Open the device - TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr_to_open, &msc_obj.dev_hdl)); - //Target our transfers to the device + // Open the device + TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr, &msc_obj.dev_hdl)); + // Target our transfers to the device xfer_out->device_handle = msc_obj.dev_hdl; xfer_out->callback = msc_reset_cbw_transfer_cb; for (int i = 0; i < msc_obj.num_data_transfers; i++) { xfer_in[i]->device_handle = msc_obj.dev_hdl; xfer_in[i]->callback = msc_data_transfer_cb; } - //Check the VID/PID of the opened device - const usb_device_desc_t *device_desc; - TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc)); - TEST_ASSERT_EQUAL(msc_obj.test_param.idVendor, device_desc->idVendor); - TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct); - //Get device info to get device speed + // Get device info to get device speed usb_device_info_t dev_info; TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(msc_obj.dev_hdl, &dev_info)); msc_obj.dev_speed = dev_info.speed; - //Claim the MSC interface - TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING)); + // Check the device descriptor of the opened device + const usb_device_desc_t *device_desc; + const usb_device_desc_t *device_desc_ref = dev_msc_get_dev_desc(msc_obj.dev_speed); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc)); + TEST_ASSERT_EQUAL(device_desc_ref->bLength, device_desc->bLength); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, device_desc_ref->bLength, "Device descriptors do not match."); + // Claim the MSC interface + TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(msc_obj.client_hdl, + msc_obj.dev_hdl, + msc_obj.dev_info->bInterfaceNumber, + msc_obj.dev_info->bAlternateSetting)); msc_obj.next_stage = TEST_STAGE_MSC_RESET; - skip_event_handling = true; //Need to execute TEST_STAGE_MSC_RESET + skip_event_handling = true; // Need to execute TEST_STAGE_MSC_RESET break; } case TEST_STAGE_MSC_RESET: { ESP_LOGD(MSC_CLIENT_TAG, "MSC Reset"); - //Send an MSC SCSI interface reset - MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, MOCK_MSC_SCSI_INTF_NUMBER); + // Send an MSC SCSI interface reset + MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, msc_obj.dev_info->bInterfaceNumber); xfer_out->num_bytes = sizeof(usb_setup_packet_t); xfer_out->bEndpointAddress = 0; TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit_control(msc_obj.client_hdl, xfer_out)); - //Next stage set from transfer callback + // Next stage set from transfer callback break; } case TEST_STAGE_MSC_CBW: { ESP_LOGD(MSC_CLIENT_TAG, "CBW"); - mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)xfer_out->data_buffer, true, 0, msc_obj.test_param.num_sectors_per_xfer, msc_obj.test_param.msc_scsi_xfer_tag); + mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)xfer_out->data_buffer, + true, + 0, + msc_obj.test_param.num_sectors_per_xfer, + msc_obj.dev_info->scsi_sector_size, + msc_obj.test_param.msc_scsi_xfer_tag); xfer_out->num_bytes = sizeof(mock_msc_bulk_cbw_t); - xfer_out->bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR; + xfer_out->bEndpointAddress = msc_obj.dev_info->out_up_addr; TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_out)); - //Next stage set from transfer callback + // Next stage set from transfer callback break; } case TEST_STAGE_MSC_DATA_DCONN: { ESP_LOGD(MSC_CLIENT_TAG, "Data and disconnect"); - //Setup the Data IN transfers - const int bulk_ep_mps = (msc_obj.dev_speed == USB_SPEED_HIGH) - ? MOCK_MSC_SCSI_BULK_EP_MPS_HS - : MOCK_MSC_SCSI_BULK_EP_MPS_FS; + // Setup the Data IN transfers + const usb_ep_desc_t *in_ep_desc = dev_msc_get_in_ep_desc(msc_obj.dev_speed); + const int bulk_ep_mps = USB_EP_DESC_GET_MPS(in_ep_desc); for (int i = 0; i < msc_obj.num_data_transfers; i++) { - xfer_in[i]->num_bytes = usb_round_up_to_mps(MOCK_MSC_SCSI_SECTOR_SIZE, bulk_ep_mps); - xfer_in[i]->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR; + xfer_in[i]->num_bytes = usb_round_up_to_mps(msc_obj.dev_info->scsi_sector_size, bulk_ep_mps); + xfer_in[i]->bEndpointAddress = msc_obj.dev_info->in_ep_addr; } - //Submit those transfers + // Submit those transfers for (int i = 0; i < msc_obj.num_data_transfers; i++) { TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in[i])); } - //Trigger a disconnect + // Trigger a disconnect test_usb_set_phy_state(false, 0); - //Next stage set from transfer callback + // Next stage set from transfer callback break; } case TEST_STAGE_DEV_CLOSE: { ESP_LOGD(MSC_CLIENT_TAG, "Close"); - TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER)); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, msc_obj.dev_info->bInterfaceNumber)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl)); dconn_iter++; if (dconn_iter < TEST_DCONN_ITERATIONS) { - //Start the next test iteration by going back to TEST_STAGE_WAIT_CONN and reenabling connections + // Start the next test iteration by going back to TEST_STAGE_WAIT_CONN and reenabling connections msc_obj.next_stage = TEST_STAGE_WAIT_CONN; - skip_event_handling = true; //Need to execute TEST_STAGE_WAIT_CONN + skip_event_handling = true; // Need to execute TEST_STAGE_WAIT_CONN test_usb_set_phy_state(true, 0); } else { exit_loop = true; @@ -257,12 +276,12 @@ void msc_client_async_dconn_task(void *arg) break; } } - //Free transfers + // Free transfers TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_free(xfer_out)); for (int i = 0; i < msc_obj.num_data_transfers; i++) { TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_free(xfer_in[i])); } - //Deregister the client + // Deregister the client TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_deregister(msc_obj.client_hdl)); ESP_LOGD(MSC_CLIENT_TAG, "Done"); vTaskDelete(NULL); diff --git a/components/usb/test_apps/usb_host/main/msc_client_async_enum.c b/components/usb/test_apps/usb_host/main/msc_client_async_enum.c index 38da2aee239a..68c783864761 100644 --- a/components/usb/test_apps/usb_host/main/msc_client_async_enum.c +++ b/components/usb/test_apps/usb_host/main/msc_client_async_enum.c @@ -12,7 +12,8 @@ #include "freertos/task.h" #include "esp_err.h" #include "esp_log.h" -#include "test_usb_mock_msc.h" +#include "dev_msc.h" +#include "mock_msc.h" #include "test_usb_common.h" #include "msc_client.h" #include "usb/usb_host.h" @@ -61,30 +62,12 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo msc_obj->dev_addr_to_open = event_msg->new_dev.address; break; default: - abort(); //Should never occur in this test + abort(); // Should never occur in this test break; } } -static void mock_msc_scsi_init_reference_ep_descriptors(const msc_client_obj_t *msc_obj) -{ - uint8_t *dest_ptr = mock_msc_scsi_config_desc; - dest_ptr += USB_CONFIG_DESC_SIZE; - dest_ptr += USB_INTF_DESC_SIZE; - - const usb_ep_desc_t en_desc_in = (msc_obj->dev_speed == USB_SPEED_HIGH) - ? mock_msc_scsi_bulk_in_ep_desc_hs - : mock_msc_scsi_bulk_in_ep_desc_fs; - const usb_ep_desc_t en_desc_out = (msc_obj->dev_speed == USB_SPEED_HIGH) - ? mock_msc_scsi_bulk_out_ep_desc_hs - : mock_msc_scsi_bulk_out_ep_desc_fs; - - memcpy(dest_ptr, (void*)&en_desc_in, sizeof(en_desc_in)); - dest_ptr += USB_EP_DESC_SIZE; - memcpy(dest_ptr, (void*)&en_desc_out, sizeof(en_desc_out)); -} - void msc_client_async_enum_task(void *arg) { msc_client_obj_t msc_obj; @@ -94,7 +77,7 @@ void msc_client_async_enum_task(void *arg) msc_obj.dev_addr_to_open = 0; msc_obj.dev_hdl = NULL; - //Register client + // Register client usb_host_client_config_t client_config = { .is_synchronous = false, .max_num_event_msg = MSC_ASYNC_CLIENT_MAX_EVENT_MSGS, @@ -105,7 +88,7 @@ void msc_client_async_enum_task(void *arg) }; TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &msc_obj.client_hdl)); - //Wait to be started by main thread + // Wait to be started by main thread ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ESP_LOGD(MSC_CLIENT_TAG, "Starting"); @@ -124,61 +107,67 @@ void msc_client_async_enum_task(void *arg) switch (msc_obj.cur_stage) { case TEST_STAGE_WAIT_CONN: { - //Wait for connection, nothing to do + // Wait for connection, nothing to do break; } case TEST_STAGE_DEV_OPEN: { ESP_LOGD(MSC_CLIENT_TAG, "Open"); - //Open the device + // Open the device TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr_to_open, &msc_obj.dev_hdl)); msc_obj.next_stage = TEST_STAGE_CHECK_DEV_DESC; - //Get device info to get device speed + // Get device info to get device speed usb_device_info_t dev_info; TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(msc_obj.dev_hdl, &dev_info)); msc_obj.dev_speed = dev_info.speed; - mock_msc_scsi_init_reference_ep_descriptors(&msc_obj); - skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_DEV_DESC + skip_event_handling = true; // Need to execute TEST_STAGE_CHECK_DEV_DESC break; } case TEST_STAGE_CHECK_DEV_DESC: { - //Check the device descriptor + // Check the device descriptor const usb_device_desc_t *device_desc; - const usb_device_desc_t *device_desc_ref = &mock_msc_scsi_dev_desc; + const usb_device_desc_t *device_desc_ref = dev_msc_get_dev_desc(msc_obj.dev_speed); TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc)); TEST_ASSERT_EQUAL(device_desc_ref->bLength, device_desc->bLength); - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, device_desc_ref->bLength, "Device descriptors do not match."); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, sizeof(usb_device_desc_t), "Device descriptors do not match."); msc_obj.next_stage = TEST_STAGE_CHECK_CONFIG_DESC; - skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_CONFIG_DESC + skip_event_handling = true; // Need to execute TEST_STAGE_CHECK_CONFIG_DESC break; } case TEST_STAGE_CHECK_CONFIG_DESC: { - //Check the configuration descriptor + // Check the configuration descriptor const usb_config_desc_t *config_desc; - const usb_config_desc_t *config_desc_ref = (const usb_config_desc_t *)mock_msc_scsi_config_desc; + const usb_config_desc_t *config_desc_ref = dev_msc_get_config_desc(msc_obj.dev_speed); TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_active_config_descriptor(msc_obj.dev_hdl, &config_desc)); - TEST_ASSERT_EQUAL_MESSAGE(config_desc_ref->wTotalLength, config_desc->wTotalLength, "Incorrent length of CFG descriptor"); - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(config_desc_ref, config_desc, config_desc_ref->wTotalLength, "Configuration descriptors do not match"); + TEST_ASSERT_EQUAL_MESSAGE(config_desc_ref->wTotalLength, config_desc->wTotalLength, "Incorrect length of CFG descriptor"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(config_desc_ref, config_desc, sizeof(usb_config_desc_t), "Configuration descriptors do not match"); msc_obj.next_stage = TEST_STAGE_CHECK_STR_DESC; - skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_STR_DESC + skip_event_handling = true; // Need to execute TEST_STAGE_CHECK_STR_DESC break; } case TEST_STAGE_CHECK_STR_DESC: { + // Get dev info and compare usb_device_info_t dev_info; TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(msc_obj.dev_hdl, &dev_info)); - //Check manufacturer string descriptors - const usb_str_desc_t *manu_str_desc_ref = (const usb_str_desc_t *)mock_msc_scsi_str_desc_manu; - const usb_str_desc_t *product_str_desc_ref = (const usb_str_desc_t *)mock_msc_scsi_str_desc_prod; - const usb_str_desc_t *ser_num_str_desc_ref = (const usb_str_desc_t *)mock_msc_scsi_str_desc_ser_num; +#if CONFIG_USB_HOST_TEST_CHECK_MANU_STR + // Check manufacturer string descriptors + const usb_str_desc_t *manu_str_desc_ref = dev_msc_get_str_desc_manu(); TEST_ASSERT_EQUAL(manu_str_desc_ref->bLength, dev_info.str_desc_manufacturer->bLength); - TEST_ASSERT_EQUAL(product_str_desc_ref->bLength, dev_info.str_desc_product->bLength); - TEST_ASSERT_EQUAL(ser_num_str_desc_ref->bLength, dev_info.str_desc_serial_num->bLength); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(manu_str_desc_ref, dev_info.str_desc_manufacturer, manu_str_desc_ref->bLength, "Manufacturer string descriptors do not match."); +#endif // CONFIG_USB_HOST_TEST_CHECK_MANU_STR +#if CONFIG_USB_HOST_TEST_CHECK_PROD_STR + const usb_str_desc_t *product_str_desc_ref = dev_msc_get_str_desc_prod(); + TEST_ASSERT_EQUAL(product_str_desc_ref->bLength, dev_info.str_desc_product->bLength); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(product_str_desc_ref, dev_info.str_desc_product, manu_str_desc_ref->bLength, "Product string descriptors do not match."); - //TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ser_num_str_desc_ref, dev_info.str_desc_serial_num , manu_str_desc_ref->bLength, "Serial number string descriptors do not match."); - //Get dev info and compare +#endif // CONFIG_USB_HOST_TEST_CHECK_PROD_STR +#if CONFIG_USB_HOST_TEST_CHECK_SERIAL_STR + const usb_str_desc_t *ser_num_str_desc_ref = dev_msc_get_str_desc_ser(); + TEST_ASSERT_EQUAL(ser_num_str_desc_ref->bLength, dev_info.str_desc_serial_num->bLength); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ser_num_str_desc_ref, dev_info.str_desc_serial_num, manu_str_desc_ref->bLength, "Serial number string descriptors do not match."); +#endif // CONFIG_USB_HOST_TEST_CHECK_SERIAL_STR + (void) dev_info; // Unused if all string descriptor checks are disabled msc_obj.next_stage = TEST_STAGE_DEV_CLOSE; - skip_event_handling = true; //Need to execute TEST_STAGE_DEV_CLOSE + skip_event_handling = true; // Need to execute TEST_STAGE_DEV_CLOSE break; } @@ -187,11 +176,11 @@ void msc_client_async_enum_task(void *arg) TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl)); enum_iter++; if (enum_iter < TEST_ENUM_ITERATIONS) { - //Start the next test iteration by disconnecting the device, then going back to TEST_STAGE_WAIT_CONN stage + // Start the next test iteration by disconnecting the device, then going back to TEST_STAGE_WAIT_CONN stage test_usb_set_phy_state(false, 0); test_usb_set_phy_state(true, 0); msc_obj.next_stage = TEST_STAGE_WAIT_CONN; - skip_event_handling = true; //Need to execute TEST_STAGE_WAIT_CONN + skip_event_handling = true; // Need to execute TEST_STAGE_WAIT_CONN } else { exit_loop = true; } @@ -202,7 +191,7 @@ void msc_client_async_enum_task(void *arg) break; } } - //Free transfers and deregister the client + // Free transfers and deregister the client TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_deregister(msc_obj.client_hdl)); ESP_LOGD(MSC_CLIENT_TAG, "Done"); vTaskDelete(NULL); diff --git a/components/usb/test_apps/usb_host/main/msc_client_async_seq.c b/components/usb/test_apps/usb_host/main/msc_client_async_seq.c index 69187ea583fa..192012fb3421 100644 --- a/components/usb/test_apps/usb_host/main/msc_client_async_seq.c +++ b/components/usb/test_apps/usb_host/main/msc_client_async_seq.c @@ -13,7 +13,8 @@ #include "esp_err.h" #include "esp_log.h" #include "test_usb_common.h" -#include "test_usb_mock_msc.h" +#include "mock_msc.h" +#include "dev_msc.h" #include "msc_client.h" #include "usb/usb_host.h" #include "unity.h" @@ -46,14 +47,19 @@ typedef enum { } test_stage_t; typedef struct { + // Test parameters msc_client_test_param_t test_param; - test_stage_t cur_stage; - test_stage_t next_stage; - uint8_t dev_addr_to_open; + // MSC device info + const dev_msc_info_t *dev_info; + usb_speed_t dev_speed; + uint8_t dev_addr; + // Client variables usb_host_client_handle_t client_hdl; usb_device_handle_t dev_hdl; + // Test state + test_stage_t cur_stage; + test_stage_t next_stage; int num_sectors_read; - usb_speed_t dev_speed; } msc_client_obj_t; static void msc_transfer_cb(usb_transfer_t *transfer) @@ -61,28 +67,28 @@ static void msc_transfer_cb(usb_transfer_t *transfer) msc_client_obj_t *msc_obj = (msc_client_obj_t *)transfer->context; switch (msc_obj->cur_stage) { case TEST_STAGE_MSC_RESET: { - //Check MSC SCSI interface reset + // Check MSC SCSI interface reset TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed"); TEST_ASSERT_EQUAL(transfer->num_bytes, transfer->actual_num_bytes); msc_obj->next_stage = TEST_STAGE_MSC_CBW; break; } case TEST_STAGE_MSC_CBW: { - //Check MSC SCSI CBW transfer + // Check MSC SCSI CBW transfer TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed"); TEST_ASSERT_EQUAL(sizeof(mock_msc_bulk_cbw_t), transfer->actual_num_bytes); msc_obj->next_stage = TEST_STAGE_MSC_DATA; break; } case TEST_STAGE_MSC_DATA: { - //Check MSC SCSI data IN transfer + // Check MSC SCSI data IN transfer TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed"); - TEST_ASSERT_EQUAL(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj->test_param.num_sectors_per_xfer, transfer->actual_num_bytes); + TEST_ASSERT_EQUAL(msc_obj->dev_info->scsi_sector_size * msc_obj->test_param.num_sectors_per_xfer, transfer->actual_num_bytes); msc_obj->next_stage = TEST_STAGE_MSC_CSW; break; } case TEST_STAGE_MSC_CSW: { - //Check MSC SCSI CSW transfer + // Check MSC SCSI CSW transfer TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed"); TEST_ASSERT_TRUE(mock_msc_scsi_check_csw((mock_msc_bulk_csw_t *)transfer->data_buffer, msc_obj->test_param.msc_scsi_xfer_tag)); msc_obj->num_sectors_read += msc_obj->test_param.num_sectors_per_xfer; @@ -107,10 +113,10 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo case USB_HOST_CLIENT_EVENT_NEW_DEV: TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, msc_obj->cur_stage); msc_obj->next_stage = TEST_STAGE_DEV_OPEN; - msc_obj->dev_addr_to_open = event_msg->new_dev.address; + msc_obj->dev_addr = event_msg->new_dev.address; break; default: - abort(); //Should never occur in this test + abort(); // Should never occur in this test break; } @@ -119,15 +125,20 @@ static void msc_client_event_cb(const usb_host_client_event_msg_t *event_msg, vo void msc_client_async_seq_task(void *arg) { msc_client_obj_t msc_obj; + // Initialize test params memcpy(&msc_obj.test_param, arg, sizeof(msc_client_test_param_t)); - msc_obj.cur_stage = TEST_STAGE_WAIT_CONN; - msc_obj.next_stage = TEST_STAGE_WAIT_CONN; + // Initialize MSC device info + msc_obj.dev_info = dev_msc_get_info(); + // Initialize client variables msc_obj.client_hdl = NULL; - msc_obj.dev_addr_to_open = 0; msc_obj.dev_hdl = NULL; + // Initialize test state + msc_obj.cur_stage = TEST_STAGE_WAIT_CONN; + msc_obj.next_stage = TEST_STAGE_WAIT_CONN; + msc_obj.dev_addr = 0; msc_obj.num_sectors_read = 0; - //Register client + // Register client usb_host_client_config_t client_config = { .is_synchronous = false, .max_num_event_msg = MSC_ASYNC_CLIENT_MAX_EVENT_MSGS, @@ -138,19 +149,12 @@ void msc_client_async_seq_task(void *arg) }; TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &msc_obj.client_hdl)); - //Allocate transfers - usb_transfer_t *xfer_out = NULL; //Must be large enough to contain CBW and MSC reset control transfer - usb_transfer_t *xfer_in = NULL; //Must be large enough to contain CSW and Data - size_t out_worst_case_size = MAX(sizeof(mock_msc_bulk_cbw_t), sizeof(usb_setup_packet_t)); - size_t in_worst_case_size = usb_round_up_to_mps(MAX(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj.test_param.num_sectors_per_xfer, sizeof(mock_msc_bulk_csw_t)), MOCK_MSC_SCSI_BULK_EP_MPS_HS); - TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(out_worst_case_size, 0, &xfer_out)); - TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(in_worst_case_size, 0, &xfer_in)); - xfer_out->callback = msc_transfer_cb; - xfer_in->callback = msc_transfer_cb; - xfer_out->context = (void *)&msc_obj; - xfer_in->context = (void *)&msc_obj; + // IN MPS and transfers to be set/allocated later (after device connects and MPS is determined) + int in_ep_mps = 0; + usb_transfer_t *xfer_in = NULL; + usb_transfer_t *xfer_out = NULL; - //Wait to be started by main thread + // Wait to be started by main thread ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ESP_LOGD(MSC_CLIENT_TAG, "Starting"); @@ -169,78 +173,100 @@ void msc_client_async_seq_task(void *arg) switch (msc_obj.cur_stage) { case TEST_STAGE_DEV_OPEN: { ESP_LOGD(MSC_CLIENT_TAG, "Open"); - //Open the device - TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr_to_open, &msc_obj.dev_hdl)); - //Target our transfers to the device - xfer_out->device_handle = msc_obj.dev_hdl; - xfer_in->device_handle = msc_obj.dev_hdl; - //Check the VID/PID of the opened device - const usb_device_desc_t *device_desc; - TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc)); - TEST_ASSERT_EQUAL(msc_obj.test_param.idVendor, device_desc->idVendor); - TEST_ASSERT_EQUAL(msc_obj.test_param.idProduct, device_desc->idProduct); - //Get device info to get device speed + // Open the device + TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(msc_obj.client_hdl, msc_obj.dev_addr, &msc_obj.dev_hdl)); + // Get device info to get device speed usb_device_info_t dev_info; TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(msc_obj.dev_hdl, &dev_info)); msc_obj.dev_speed = dev_info.speed; - //Claim the MSC interface - TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING)); + // Check that the device descriptor matches our expected MSC device + const usb_device_desc_t *device_desc; + const usb_device_desc_t *device_desc_ref = dev_msc_get_dev_desc(msc_obj.dev_speed); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc)); + TEST_ASSERT_EQUAL(device_desc_ref->bLength, device_desc->bLength); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, sizeof(usb_device_desc_t), "Device descriptors do not match."); + // Claim the MSC interface + TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(msc_obj.client_hdl, + msc_obj.dev_hdl, + msc_obj.dev_info->bInterfaceNumber, + msc_obj.dev_info->bAlternateSetting)); + /* + Allocate transfers + + IN transfer must be large enough to contain CSW and Data + OUT transfer must be large enough to contain CBW and MSC reset control transfer + */ + const usb_ep_desc_t *in_ep_desc = dev_msc_get_in_ep_desc(msc_obj.dev_speed); + in_ep_mps = USB_EP_DESC_GET_MPS(in_ep_desc); + const size_t in_worst_case_size = usb_round_up_to_mps(MAX(msc_obj.dev_info->scsi_sector_size * msc_obj.test_param.num_sectors_per_xfer, + sizeof(mock_msc_bulk_csw_t)), + in_ep_mps); + const size_t out_worst_case_size = MAX(sizeof(mock_msc_bulk_cbw_t), sizeof(usb_setup_packet_t)); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(out_worst_case_size, 0, &xfer_out)); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_alloc(in_worst_case_size, 0, &xfer_in)); + xfer_out->callback = msc_transfer_cb; + xfer_in->callback = msc_transfer_cb; + xfer_out->context = (void *)&msc_obj; + xfer_in->context = (void *)&msc_obj; + // Target our transfers to the device + xfer_out->device_handle = msc_obj.dev_hdl; + xfer_in->device_handle = msc_obj.dev_hdl; + // Set next stage msc_obj.next_stage = TEST_STAGE_MSC_RESET; - skip_event_handling = true; //Need to execute TEST_STAGE_MSC_RESET + skip_event_handling = true; // Need to execute TEST_STAGE_MSC_RESET break; } case TEST_STAGE_MSC_RESET: { ESP_LOGD(MSC_CLIENT_TAG, "MSC Reset"); - //Send an MSC SCSI interface reset - MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, MOCK_MSC_SCSI_INTF_NUMBER); + // Send an MSC SCSI interface reset + MOCK_MSC_SCSI_REQ_INIT_RESET((usb_setup_packet_t *)xfer_out->data_buffer, msc_obj.dev_info->bInterfaceNumber); xfer_out->num_bytes = sizeof(usb_setup_packet_t); xfer_out->bEndpointAddress = 0; TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit_control(msc_obj.client_hdl, xfer_out)); - //Test that an inflight control transfer cannot be resubmitted + // Test that an inflight control transfer cannot be resubmitted TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit_control(msc_obj.client_hdl, xfer_out)); - //Next stage set from transfer callback + // Next stage set from transfer callback break; } case TEST_STAGE_MSC_CBW: { ESP_LOGD(MSC_CLIENT_TAG, "CBW"); - mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)xfer_out->data_buffer, true, msc_obj.next_stage, msc_obj.test_param.num_sectors_per_xfer, msc_obj.test_param.msc_scsi_xfer_tag); + mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)xfer_out->data_buffer, + true, + msc_obj.next_stage, + msc_obj.test_param.num_sectors_per_xfer, + msc_obj.dev_info->scsi_sector_size, + msc_obj.test_param.msc_scsi_xfer_tag); xfer_out->num_bytes = sizeof(mock_msc_bulk_cbw_t); - xfer_out->bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR; + xfer_out->bEndpointAddress = msc_obj.dev_info->out_up_addr; TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_out)); - //Test that an inflight transfer cannot be resubmitted + // Test that an inflight transfer cannot be resubmitted TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit(xfer_out)); - //Next stage set from transfer callback + // Next stage set from transfer callback break; } case TEST_STAGE_MSC_DATA: { ESP_LOGD(MSC_CLIENT_TAG, "Data"); - const int bulk_ep_mps = (msc_obj.dev_speed == USB_SPEED_HIGH) - ? MOCK_MSC_SCSI_BULK_EP_MPS_HS - : MOCK_MSC_SCSI_BULK_EP_MPS_FS; - xfer_in->num_bytes = usb_round_up_to_mps(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj.test_param.num_sectors_per_xfer, bulk_ep_mps); - xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR; + xfer_in->num_bytes = usb_round_up_to_mps(msc_obj.dev_info->scsi_sector_size * msc_obj.test_param.num_sectors_per_xfer, in_ep_mps); + xfer_in->bEndpointAddress = msc_obj.dev_info->in_ep_addr; TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in)); - //Test that an inflight transfer cannot be resubmitted + // Test that an inflight transfer cannot be resubmitted TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit(xfer_in)); - //Next stage set from transfer callback + // Next stage set from transfer callback break; } case TEST_STAGE_MSC_CSW: { ESP_LOGD(MSC_CLIENT_TAG, "CSW"); - const int bulk_ep_mps = (msc_obj.dev_speed == USB_SPEED_HIGH) - ? MOCK_MSC_SCSI_BULK_EP_MPS_HS - : MOCK_MSC_SCSI_BULK_EP_MPS_FS; - xfer_in->num_bytes = usb_round_up_to_mps(sizeof(mock_msc_bulk_csw_t), bulk_ep_mps); - xfer_in->bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR; + xfer_in->num_bytes = usb_round_up_to_mps(sizeof(mock_msc_bulk_csw_t), in_ep_mps); + xfer_in->bEndpointAddress = msc_obj.dev_info->in_ep_addr; TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_submit(xfer_in)); - //Test that an inflight transfer cannot be resubmitted + // Test that an inflight transfer cannot be resubmitted TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_transfer_submit(xfer_in)); - //Next stage set from transfer callback + // Next stage set from transfer callback break; } case TEST_STAGE_DEV_CLOSE: { ESP_LOGD(MSC_CLIENT_TAG, "Close"); - TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER)); + TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(msc_obj.client_hdl, msc_obj.dev_hdl, msc_obj.dev_info->bInterfaceNumber)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(msc_obj.client_hdl, msc_obj.dev_hdl)); exit_loop = true; break; @@ -250,7 +276,7 @@ void msc_client_async_seq_task(void *arg) break; } } - //Free transfers and deregister the client + // Free transfers and deregister the client TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_free(xfer_out)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_transfer_free(xfer_in)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_deregister(msc_obj.client_hdl)); diff --git a/components/usb/test_apps/usb_host/main/multiconf_client.h b/components/usb/test_apps/usb_host/main/multiconf_client.h new file mode 100644 index 000000000000..b5af74db74ff --- /dev/null +++ b/components/usb/test_apps/usb_host/main/multiconf_client.h @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +typedef struct { + SemaphoreHandle_t dev_open_smp; + uint8_t bConfigurationValue; +} multiconf_client_test_param_t; + +/** + * @brief Multiconfiguration client task + */ +void multiconf_client_async_task(void *arg); + +/** + * @brief Get configuration descriptor + */ +void multiconf_client_get_conf_desc(void); diff --git a/components/usb/test_apps/usb_host/main/multiconf_client_async.c b/components/usb/test_apps/usb_host/main/multiconf_client_async.c new file mode 100644 index 000000000000..811a1dbdc14c --- /dev/null +++ b/components/usb/test_apps/usb_host/main/multiconf_client_async.c @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "esp_err.h" +#include "esp_log.h" +#include "test_usb_common.h" +#include "multiconf_client.h" +#include "mock_msc.h" +#include "dev_msc.h" +#include "usb/usb_host.h" +#include "unity.h" + +/* +Implementation of a multi-configuration client used for USB Host Tests. + +- The multi-configuration client will: + - Register itself as a client + - Receive USB_HOST_CLIENT_EVENT_NEW_DEV event message, and open the device + - Get active configuration descriptor + - Start handling client events + - Wait for a request from main task to read a configuration descriptor + - Compare the obtained configuration descriptor with the active configuration descriptor + - Free the memory used for storing the configuration descriptor + - Close the device + - Deregister control client +*/ + +const char *MULTICONF_CLIENT_TAG = "Multi config Client"; + +#define CLIENT_NUM_EVENT_MSG 5 + +typedef enum { + TEST_STAGE_WAIT_CONN, + TEST_STAGE_DEV_OPEN, + TEST_STAGE_WAIT, + TEST_STAGE_CHECK_CONFIG_DESC, + TEST_STAGE_DEV_CLOSE, +} test_stage_t; + +typedef struct { + // Test parameters + multiconf_client_test_param_t test_param; + // device info + uint8_t dev_addr; + usb_speed_t dev_speed; + // Client variables + usb_host_client_handle_t client_hdl; + usb_device_handle_t dev_hdl; + // Test state + test_stage_t cur_stage; + test_stage_t next_stage; + const usb_config_desc_t *config_desc_cached; +} multiconf_client_obj_t; + +static multiconf_client_obj_t *s_multiconf_obj; + +static void multiconf_client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg) +{ + multiconf_client_obj_t *multiconf_obj = (multiconf_client_obj_t *)arg; + switch (event_msg->event) { + case USB_HOST_CLIENT_EVENT_NEW_DEV: + TEST_ASSERT_EQUAL(TEST_STAGE_WAIT_CONN, multiconf_obj->cur_stage); + multiconf_obj->next_stage = TEST_STAGE_DEV_OPEN; + multiconf_obj->dev_addr = event_msg->new_dev.address; + break; + default: + abort(); // Should never occur in this test + break; + } +} + +void multiconf_client_async_task(void *arg) +{ + multiconf_client_obj_t multiconf_obj; + // Initialize test params + memcpy(&multiconf_obj.test_param, arg, sizeof(multiconf_client_test_param_t)); + // Initialize client variables + multiconf_obj.client_hdl = NULL; + multiconf_obj.dev_hdl = NULL; + // Initialize test stage + multiconf_obj.cur_stage = TEST_STAGE_WAIT_CONN; + multiconf_obj.next_stage = TEST_STAGE_WAIT_CONN; + multiconf_obj.dev_addr = 0; + + // Register client + usb_host_client_config_t client_config = { + .is_synchronous = false, + .max_num_event_msg = CLIENT_NUM_EVENT_MSG, + .async = { + .client_event_callback = multiconf_client_event_cb, + .callback_arg = (void *) &multiconf_obj, + }, + }; + TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &multiconf_obj.client_hdl)); + s_multiconf_obj = &multiconf_obj; + + // Wait to be started by main thread + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + ESP_LOGD(MULTICONF_CLIENT_TAG, "Starting"); + + bool exit_loop = false; + bool skip_event_handling = false; + while (!exit_loop) { + if (!skip_event_handling) { + TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_handle_events(multiconf_obj.client_hdl, portMAX_DELAY)); + } + skip_event_handling = false; + if (multiconf_obj.cur_stage == multiconf_obj.next_stage) { + continue; + } + multiconf_obj.cur_stage = multiconf_obj.next_stage; + + switch (multiconf_obj.next_stage) { + case TEST_STAGE_DEV_OPEN: { + ESP_LOGD(MULTICONF_CLIENT_TAG, "Open"); + // Open the device + TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_host_device_open(multiconf_obj.client_hdl, multiconf_obj.dev_addr, &multiconf_obj.dev_hdl), "Failed to open the device"); + + // Get device info to get it's speed + usb_device_info_t dev_info; + TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_info(multiconf_obj.dev_hdl, &dev_info)); + multiconf_obj.dev_speed = dev_info.speed; + + multiconf_obj.next_stage = TEST_STAGE_WAIT; + skip_event_handling = true; + break; + } + case TEST_STAGE_WAIT: { + // Give semaphore signalizing that the device has been opened + xSemaphoreGive(multiconf_obj.test_param.dev_open_smp); + break; + } + case TEST_STAGE_CHECK_CONFIG_DESC: { + ESP_LOGD(MULTICONF_CLIENT_TAG, "Check config descriptors"); + // Get mocked config descriptor + const usb_config_desc_t *config_desc_ref = dev_msc_get_config_desc(multiconf_obj.dev_speed); + TEST_ASSERT_EQUAL_MESSAGE(multiconf_obj.config_desc_cached->wTotalLength, config_desc_ref->wTotalLength, "Incorrect length of CFG descriptor"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(config_desc_ref, multiconf_obj.config_desc_cached, sizeof(usb_config_desc_t), "Configuration descriptors do not match"); + + // Free the memory used to store the config descriptor + TEST_ASSERT_EQUAL(ESP_OK, usb_host_free_config_desc(multiconf_obj.config_desc_cached)); + multiconf_obj.next_stage = TEST_STAGE_DEV_CLOSE; + skip_event_handling = true; + break; + } + case TEST_STAGE_DEV_CLOSE: { + ESP_LOGD(MULTICONF_CLIENT_TAG, "Close"); + vTaskDelay(10); // Give USB Host Lib some time to process all transfers + TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(multiconf_obj.client_hdl, multiconf_obj.dev_hdl)); + exit_loop = true; + break; + } + default: + abort(); + break; + } + } + TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_deregister(multiconf_obj.client_hdl)); + ESP_LOGD(MULTICONF_CLIENT_TAG, "Done"); + vTaskDelete(NULL); +} + +void multiconf_client_get_conf_desc(void) +{ + // Get configuration descriptor, ctrl transfer is sent to the device to get the config descriptor + TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_config_desc(s_multiconf_obj->client_hdl, s_multiconf_obj->dev_hdl, s_multiconf_obj->test_param.bConfigurationValue, &s_multiconf_obj->config_desc_cached)); + + // Go to next stage + s_multiconf_obj->next_stage = TEST_STAGE_CHECK_CONFIG_DESC; + ESP_ERROR_CHECK(usb_host_client_unblock(s_multiconf_obj->client_hdl)); +} diff --git a/components/usb/test_apps/usb_host/main/test_app_main.c b/components/usb/test_apps/usb_host/main/test_app_main.c index 6a2363359549..de47f0b0f3f8 100644 --- a/components/usb/test_apps/usb_host/main/test_app_main.c +++ b/components/usb/test_apps/usb_host/main/test_app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -7,21 +7,20 @@ #include "unity.h" #include "unity_test_runner.h" #include "unity_test_utils_memory.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "test_usb_common.h" -#include "test_usb_mock_msc.h" +#include "dev_msc.h" #include "usb/usb_host.h" void setUp(void) { - mock_msc_scsi_init_reference_descriptors(); unity_utils_record_free_mem(); - test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing - //Install USB Host + dev_msc_init(); + test_usb_init_phy(); // Initialize the internal USB PHY and USB Controller for testing + // Install USB Host usb_host_config_t host_config = { - .skip_phy_setup = true, //test_usb_init_phy() will already have setup the internal USB PHY for us + .skip_phy_setup = true, // test_usb_init_phy() will already have setup the internal USB PHY for us .intr_flags = ESP_INTR_FLAG_LEVEL1, }; ESP_ERROR_CHECK(usb_host_install(&host_config)); @@ -30,11 +29,13 @@ void setUp(void) void tearDown(void) { - //Short delay to allow task to be cleaned up + // Short delay to allow task to be cleaned up vTaskDelay(10); - //Clean up USB Host + // Clean up USB Host ESP_ERROR_CHECK(usb_host_uninstall()); - test_usb_deinit_phy(); //Deinitialize the internal USB PHY after testing + // Short delay to allow task to be cleaned up after client uninstall + vTaskDelay(10); + test_usb_deinit_phy(); // Deinitialize the internal USB PHY after testing unity_utils_evaluate_leaks(); } diff --git a/components/usb/test_apps/usb_host/main/test_usb_host_async.c b/components/usb/test_apps/usb_host/main/test_usb_host_async.c index 98b978acf9dd..0dac7076f5b3 100644 --- a/components/usb/test_apps/usb_host/main/test_usb_host_async.c +++ b/components/usb/test_apps/usb_host/main/test_usb_host_async.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,9 +11,10 @@ #include "esp_err.h" #include "esp_intr_alloc.h" #include "test_usb_common.h" -#include "test_usb_mock_msc.h" +#include "dev_msc.h" #include "msc_client.h" #include "ctrl_client.h" +#include "multiconf_client.h" #include "usb/usb_host.h" #include "unity.h" @@ -21,6 +22,7 @@ #define TEST_MSC_NUM_SECTORS_PER_XFER 2 #define TEST_MSC_SCSI_TAG 0xDEADBEEF #define TEST_CTRL_NUM_TRANSFERS 30 +#define B_CONFIGURATION_VALUE 1 // --------------------------------------------------- Test Cases ------------------------------------------------------ @@ -46,22 +48,20 @@ Requires: This test requires an MSC SCSI device to be attached (see the MSC mock TEST_CASE("Test USB Host async client (single client)", "[usb_host][full_speed][high_speed]") { - //Create task to run client that communicates with MSC SCSI interface + // Create task to run client that communicates with MSC SCSI interface msc_client_test_param_t params = { .num_sectors_to_read = TEST_MSC_NUM_SECTORS_TOTAL, .num_sectors_per_xfer = TEST_MSC_NUM_SECTORS_PER_XFER, .msc_scsi_xfer_tag = TEST_MSC_SCSI_TAG, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, }; TaskHandle_t task_hdl; xTaskCreatePinnedToCore(msc_client_async_seq_task, "async", 4096, (void *)¶ms, 2, &task_hdl, 0); TEST_ASSERT_NOT_NULL_MESSAGE(task_hdl, "Failed to create async task"); - //Start the task + // Start the task xTaskNotifyGive(task_hdl); while (1) { - //Start handling system events + // Start handling system events uint32_t event_flags; usb_host_lib_handle_events(portMAX_DELAY, &event_flags); if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { @@ -96,34 +96,30 @@ Requires: This test requires an MSC SCSI device to be attached (see the MSC mock */ TEST_CASE("Test USB Host async client (multi client)", "[usb_host][full_speed][high_speed]") { - //Create task to run the MSC client + // Create task to run the MSC client msc_client_test_param_t msc_params = { .num_sectors_to_read = TEST_MSC_NUM_SECTORS_TOTAL, .num_sectors_per_xfer = TEST_MSC_NUM_SECTORS_PER_XFER, .msc_scsi_xfer_tag = TEST_MSC_SCSI_TAG, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, }; TaskHandle_t msc_task_hdl; xTaskCreatePinnedToCore(msc_client_async_seq_task, "msc", 4096, (void *)&msc_params, 2, &msc_task_hdl, 0); TEST_ASSERT_NOT_NULL_MESSAGE(msc_task_hdl, "Failed to create MSC task"); - //Create task a control transfer client + // Create task a control transfer client ctrl_client_test_param_t ctrl_params = { .num_ctrl_xfer_to_send = TEST_CTRL_NUM_TRANSFERS, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, }; TaskHandle_t ctrl_task_hdl; xTaskCreatePinnedToCore(ctrl_client_async_seq_task, "ctrl", 4096, (void *)&ctrl_params, 2, &ctrl_task_hdl, 0); TEST_ASSERT_NOT_NULL_MESSAGE(ctrl_task_hdl, "Failed to create CTRL task"); - //Start both tasks + // Start both tasks xTaskNotifyGive(msc_task_hdl); xTaskNotifyGive(ctrl_task_hdl); while (1) { - //Start handling system events + // Start handling system events uint32_t event_flags; usb_host_lib_handle_events(portMAX_DELAY, &event_flags); if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { @@ -188,7 +184,7 @@ static void test_async_client_cb(const usb_host_client_event_msg_t *event_msg, v TEST_CASE("Test USB Host async API", "[usb_host][full_speed][low_speed]") { - //Register two clients + // Register two clients client_test_stage_t client0_stage = CLIENT_TEST_STAGE_NONE; client_test_stage_t client1_stage = CLIENT_TEST_STAGE_NONE; @@ -206,7 +202,7 @@ TEST_CASE("Test USB Host async API", "[usb_host][full_speed][low_speed]") client_config.async.callback_arg = (void *)&client1_stage; TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_register(&client_config, &client1_hdl)); - //Wait until the device connects and the clients receive the event + // Wait until the device connects and the clients receive the event while (!(client0_stage == CLIENT_TEST_STAGE_CONN && client1_stage == CLIENT_TEST_STAGE_CONN)) { usb_host_lib_handle_events(0, NULL); usb_host_client_handle_events(client0_hdl, 0); @@ -214,35 +210,49 @@ TEST_CASE("Test USB Host async API", "[usb_host][full_speed][low_speed]") vTaskDelay(pdMS_TO_TICKS(10)); } - //Check that both clients can open the device + // Check that both clients can open the device TEST_ASSERT_NOT_EQUAL(0, dev_addr); usb_device_handle_t client0_dev_hdl; usb_device_handle_t client1_dev_hdl; printf("Opening device\n"); TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(client0_hdl, dev_addr, &client0_dev_hdl)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(client1_hdl, dev_addr, &client1_dev_hdl)); - TEST_ASSERT_EQUAL_PTR(client0_dev_hdl, client1_dev_hdl); //Check that its the same device - //Check that a client cannot open a non-existent device + TEST_ASSERT_EQUAL_PTR(client0_dev_hdl, client1_dev_hdl); // Check that its the same device + // Check that a client cannot open a non-existent device TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_device_open(client0_hdl, 0, &client0_dev_hdl)); - //Check that the device cannot be opened again by the same client + // Check that the device cannot be opened again by the same client + const dev_msc_info_t *dev_info = dev_msc_get_info(); usb_device_handle_t dummy_dev_hdl; TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_device_open(client0_hdl, dev_addr, &dummy_dev_hdl)); TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_device_open(client1_hdl, dev_addr, &dummy_dev_hdl)); printf("Claiming interface\n"); - //Check that both clients cannot claim the same interface - TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING)); - TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client1_hdl, client1_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING)); - //Check that client0 cannot claim the same interface multiple times - TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING)); + // Check that both clients cannot claim the same interface + TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, + client0_dev_hdl, + dev_info->bInterfaceNumber, + dev_info->bAlternateSetting)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client1_hdl, + client1_dev_hdl, + dev_info->bInterfaceNumber, + dev_info->bAlternateSetting)); + // Check that client0 cannot claim the same interface multiple times + TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, + client0_dev_hdl, + dev_info->bInterfaceNumber, + dev_info->bAlternateSetting)); printf("Releasing interface\n"); - //Check that client0 can release the interface - TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER)); - //Check that client0 cannot release interface it has not claimed - TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_release(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER)); - - //Wait until the device disconnects and the clients receive the event + // Check that client0 can release the interface + TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(client0_hdl, + client0_dev_hdl, + dev_info->bInterfaceNumber)); + // Check that client0 cannot release interface it has not claimed + TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_release(client0_hdl, + client0_dev_hdl, + dev_info->bInterfaceNumber)); + + // Wait until the device disconnects and the clients receive the event test_usb_set_phy_state(false, 0); while (!(client0_stage == CLIENT_TEST_STAGE_DCONN && client1_stage == CLIENT_TEST_STAGE_DCONN)) { usb_host_lib_handle_events(0, NULL); @@ -254,7 +264,7 @@ TEST_CASE("Test USB Host async API", "[usb_host][full_speed][low_speed]") TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(client0_hdl, client0_dev_hdl)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(client1_hdl, client1_dev_hdl)); - //Deregister the clients + // Deregister the clients TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_deregister(client0_hdl)); TEST_ASSERT_EQUAL(ESP_OK, usb_host_client_deregister(client1_hdl)); @@ -267,3 +277,66 @@ TEST_CASE("Test USB Host async API", "[usb_host][full_speed][low_speed]") vTaskDelay(10); } } + +/* +Test USB Host Asynchronous API single client + +Purpose: + - Test that client can read configuration descriptor by request + +Procedure: + - Install USB Host Library + - Create a task to run a multiconfig client + - Create a task to handle system events + - Start the MSC client task. It will open the device and start handling client events + - Wait for the main task requests client to read configuration descriptor + - Compare the requested configuration descriptor with the active configuration descriptor + - Wait for the host library event handler to report a USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS event + - Free all devices + - Uninstall USB Host Library +*/ +static void host_lib_task(void *arg) +{ + while (1) { + // Start handling system events + uint32_t event_flags; + usb_host_lib_handle_events(portMAX_DELAY, &event_flags); + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + printf("No more clients\n"); + TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_device_free_all()); + } + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + break; + } + } + + printf("Deleting host_lib_task\n"); + vTaskDelete(NULL); +} + +TEST_CASE("Test USB Host multiconfig client (single client)", "[usb_host][full_speed][high_speed]") +{ + SemaphoreHandle_t dev_open_smp = xSemaphoreCreateBinary(); + TaskHandle_t client_task; + + multiconf_client_test_param_t multiconf_params = { + .dev_open_smp = dev_open_smp, + .bConfigurationValue = B_CONFIGURATION_VALUE, + }; + + xTaskCreatePinnedToCore(multiconf_client_async_task, "async client", 4096, (void*)&multiconf_params, 2, &client_task, 0); + TEST_ASSERT_NOT_NULL_MESSAGE(client_task, "Failed to create async client task"); + // Start the task + xTaskNotifyGive(client_task); + + TaskHandle_t host_lib_task_hdl; + xTaskCreatePinnedToCore(host_lib_task, "host lib", 4096, NULL, 2, &host_lib_task_hdl, 0); + TEST_ASSERT_NOT_NULL_MESSAGE(host_lib_task_hdl, "Failed to create host lib task"); + + // Wait for the device to be open + xSemaphoreTake(dev_open_smp, portMAX_DELAY); + multiconf_client_get_conf_desc(); + + // Cleanup + vSemaphoreDelete(dev_open_smp); +} diff --git a/components/usb/test_apps/usb_host/main/test_usb_host_plugging.c b/components/usb/test_apps/usb_host/main/test_usb_host_plugging.c index 5851988f4215..263898c0de95 100644 --- a/components/usb/test_apps/usb_host/main/test_usb_host_plugging.c +++ b/components/usb/test_apps/usb_host/main/test_usb_host_plugging.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,7 +10,8 @@ #include "esp_err.h" #include "esp_intr_alloc.h" #include "test_usb_common.h" -#include "test_usb_mock_msc.h" +#include "mock_msc.h" +#include "dev_msc.h" #include "msc_client.h" #include "ctrl_client.h" #include "usb/usb_host.h" @@ -38,24 +39,24 @@ TEST_CASE("Test USB Host sudden disconnection (no client)", "[usb_host][full_spe bool connected = false; int dconn_iter = 0; while (1) { - //Start handling system events + // Start handling system events uint32_t event_flags; usb_host_lib_handle_events(portMAX_DELAY, &event_flags); if (!connected) { usb_host_lib_info_t lib_info; TEST_ASSERT_EQUAL(ESP_OK, usb_host_lib_info(&lib_info)); if (lib_info.num_devices == 1) { - //We've just connected. Trigger a disconnect + // We've just connected. Trigger a disconnect connected = true; printf("Forcing Sudden Disconnect\n"); test_usb_set_phy_state(false, 0); } } if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { - //The device has disconnected and it's disconnection has been handled + // The device has disconnected and it's disconnection has been handled printf("Dconn iter %d done\n", dconn_iter); if (++dconn_iter < TEST_DCONN_NO_CLIENT_ITERATIONS) { - //Start next iteration + // Start next iteration connected = false; test_usb_set_phy_state(true, 0); } else { @@ -83,23 +84,22 @@ Test USB Host Library Sudden Disconnection Handling (with client) TEST_CASE("Test USB Host sudden disconnection (single client)", "[usb_host][full_speed]") { - //Create task to run client that communicates with MSC SCSI interface + // Create task to run client that communicates with MSC SCSI interface + const dev_msc_info_t *dev_info = dev_msc_get_info(); msc_client_test_param_t params = { - .num_sectors_to_read = 1, //Unused by disconnect MSC client - .num_sectors_per_xfer = TEST_FORCE_DCONN_NUM_TRANSFERS * MOCK_MSC_SCSI_SECTOR_SIZE, + .num_sectors_to_read = 1, // Unused by disconnect MSC client + .num_sectors_per_xfer = TEST_FORCE_DCONN_NUM_TRANSFERS * dev_info->scsi_sector_size, .msc_scsi_xfer_tag = TEST_MSC_SCSI_TAG, - .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR, - .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT, }; TaskHandle_t task_hdl; xTaskCreatePinnedToCore(msc_client_async_dconn_task, "async", 4096, (void *)¶ms, 2, &task_hdl, 0); - //Start the task + // Start the task xTaskNotifyGive(task_hdl); bool all_clients_gone = false; bool all_dev_free = false; while (!all_clients_gone || !all_dev_free) { - //Start handling system events + // Start handling system events uint32_t event_flags; usb_host_lib_handle_events(portMAX_DELAY, &event_flags); if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { @@ -133,16 +133,16 @@ Test USB Host Library Enumeration TEST_CASE("Test USB Host enumeration", "[usb_host][full_speed]") { - //Create task to run client that checks the enumeration of the device + // Create task to run client that checks the enumeration of the device TaskHandle_t task_hdl; xTaskCreatePinnedToCore(msc_client_async_enum_task, "async", 6144, NULL, 2, &task_hdl, 0); - //Start the task + // Start the task xTaskNotifyGive(task_hdl); bool all_clients_gone = false; bool all_dev_free = false; while (!all_clients_gone || !all_dev_free) { - //Start handling system events + // Start handling system events uint32_t event_flags; usb_host_lib_handle_events(portMAX_DELAY, &event_flags); if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { diff --git a/components/usb/usb_host.c b/components/usb/usb_host.c index 11fd7810aa8d..7094839db63f 100644 --- a/components/usb/usb_host.c +++ b/components/usb/usb_host.c @@ -10,6 +10,7 @@ Warning: The USB Host Library API is still a beta version and may be subject to #include #include +#include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -52,6 +53,9 @@ static portMUX_TYPE host_lock = portMUX_INITIALIZER_UNLOCKED; #define ENABLE_ENUM_FILTER_CALLBACK #endif // CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK +#define SHORT_DESC_REQ_LEN 8 +#define CTRL_TRANSFER_MAX_DATA_LEN CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE + typedef struct ep_wrapper_s ep_wrapper_t; typedef struct interface_s interface_t; typedef struct client_s client_t; @@ -148,6 +152,7 @@ typedef struct { SemaphoreHandle_t event_sem; SemaphoreHandle_t mux_lock; usb_phy_handle_t phy_handle; // Will be NULL if host library is installed with skip_phy_setup + void *hub_client; // Pointer to Hub driver (acting as a client). Used to reroute completed USBH control transfers } constant; } host_lib_t; @@ -171,8 +176,15 @@ static inline void _clear_client_opened_device(client_t *client_obj, uint8_t dev static inline bool _check_client_opened_device(client_t *client_obj, uint8_t dev_addr) { - assert(dev_addr != 0); - return (client_obj->dynamic.opened_dev_addr_map & (1 << (dev_addr - 1))); + bool ret; + + if (dev_addr != 0) { + ret = client_obj->dynamic.opened_dev_addr_map & (1 << (dev_addr - 1)); + } else { + ret = false; + } + + return ret; } static bool _unblock_client(client_t *client_obj, bool in_isr) @@ -268,14 +280,18 @@ static void usbh_event_callback(usbh_event_data_t *event_data, void *arg) case USBH_EVENT_CTRL_XFER: { assert(event_data->ctrl_xfer_data.urb != NULL); assert(event_data->ctrl_xfer_data.urb->usb_host_client != NULL); - // Redistribute done control transfer to the clients that submitted them - client_t *client_obj = (client_t *)event_data->ctrl_xfer_data.urb->usb_host_client; - - HOST_ENTER_CRITICAL(); - TAILQ_INSERT_TAIL(&client_obj->dynamic.done_ctrl_xfer_tailq, event_data->ctrl_xfer_data.urb, tailq_entry); - client_obj->dynamic.num_done_ctrl_xfer++; - _unblock_client(client_obj, false); - HOST_EXIT_CRITICAL(); + // Redistribute completed control transfers to the clients that submitted them + if (event_data->ctrl_xfer_data.urb->usb_host_client == p_host_lib_obj->constant.hub_client) { + // Redistribute to Hub driver. Simply call the transfer callback + event_data->ctrl_xfer_data.urb->transfer.callback(&event_data->ctrl_xfer_data.urb->transfer); + } else { + client_t *client_obj = (client_t *)event_data->ctrl_xfer_data.urb->usb_host_client; + HOST_ENTER_CRITICAL(); + TAILQ_INSERT_TAIL(&client_obj->dynamic.done_ctrl_xfer_tailq, event_data->ctrl_xfer_data.urb, tailq_entry); + client_obj->dynamic.num_done_ctrl_xfer++; + _unblock_client(client_obj, false); + HOST_EXIT_CRITICAL(); + } break; } case USBH_EVENT_NEW_DEV: { @@ -297,8 +313,8 @@ static void usbh_event_callback(usbh_event_data_t *event_data, void *arg) break; } case USBH_EVENT_DEV_FREE: { - // Let the Hub driver know that the device is free - ESP_ERROR_CHECK(hub_dev_is_free(event_data->dev_free_data.dev_addr)); + // Let the Hub driver know that the device is free and its port can be recycled + ESP_ERROR_CHECK(hub_port_recycle(event_data->dev_free_data.dev_uid)); break; } case USBH_EVENT_ALL_FREE: { @@ -337,6 +353,12 @@ static bool endpoint_callback(usbh_ep_handle_t ep_hdl, usbh_ep_event_t ep_event, return yield; } +static void get_config_desc_transfer_cb(usb_transfer_t *transfer) +{ + SemaphoreHandle_t transfer_done = (SemaphoreHandle_t)transfer->context; + xSemaphoreGive(transfer_done); +} + // ------------------------------------------------ Library Functions -------------------------------------------------- // ----------------------- Public -------------------------- @@ -420,7 +442,7 @@ esp_err_t usb_host_install(const usb_host_config_t *config) .enum_filter_cb = config->enum_filter_cb, #endif // ENABLE_ENUM_FILTER_CALLBACK }; - ret = hub_install(&hub_config); + ret = hub_install(&hub_config, &host_lib_obj->constant.hub_client); if (ret != ESP_OK) { goto hub_err; } @@ -574,7 +596,7 @@ esp_err_t usb_host_lib_info(usb_host_lib_info_t *info_ret) HOST_CHECK_FROM_CRIT(p_host_lib_obj != NULL, ESP_ERR_INVALID_STATE); num_clients_temp = p_host_lib_obj->dynamic.flags.num_clients; HOST_EXIT_CRITICAL(); - usbh_num_devs(&num_devs_temp); + usbh_devs_num(&num_devs_temp); // Write back return values info_ret->num_devices = num_devs_temp; @@ -820,7 +842,7 @@ esp_err_t usb_host_device_open(usb_host_client_handle_t client_hdl, uint8_t dev_ esp_err_t ret; usb_device_handle_t dev_hdl; - ret = usbh_dev_open(dev_addr, &dev_hdl); + ret = usbh_devs_open(dev_addr, &dev_hdl); if (ret != ESP_OK) { goto exit; } @@ -841,7 +863,7 @@ esp_err_t usb_host_device_open(usb_host_client_handle_t client_hdl, uint8_t dev_ return ret; already_opened: - ESP_ERROR_CHECK(usbh_dev_close(dev_hdl)); + ESP_ERROR_CHECK(usbh_devs_close(dev_hdl)); exit: return ret; } @@ -883,7 +905,7 @@ esp_err_t usb_host_device_close(usb_host_client_handle_t client_hdl, usb_device_ _clear_client_opened_device(client_obj, dev_addr); HOST_EXIT_CRITICAL(); - ESP_ERROR_CHECK(usbh_dev_close(dev_hdl)); + ESP_ERROR_CHECK(usbh_devs_close(dev_hdl)); ret = ESP_OK; exit: xSemaphoreGive(p_host_lib_obj->constant.mux_lock); @@ -896,7 +918,7 @@ esp_err_t usb_host_device_free_all(void) HOST_CHECK_FROM_CRIT(p_host_lib_obj->dynamic.flags.num_clients == 0, ESP_ERR_INVALID_STATE); // All clients must have been deregistered HOST_EXIT_CRITICAL(); esp_err_t ret; - ret = usbh_dev_mark_all_free(); + ret = usbh_devs_mark_all_free(); // If ESP_ERR_NOT_FINISHED is returned, caller must wait for USB_HOST_LIB_EVENT_FLAGS_ALL_FREE to confirm all devices are free return ret; } @@ -904,7 +926,7 @@ esp_err_t usb_host_device_free_all(void) esp_err_t usb_host_device_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num_dev_ret) { HOST_CHECK(dev_addr_list != NULL && num_dev_ret != NULL, ESP_ERR_INVALID_ARG); - return usbh_dev_addr_list_fill(list_len, dev_addr_list, num_dev_ret); + return usbh_devs_addr_list_fill(list_len, dev_addr_list, num_dev_ret); } // ------------------------------------------------- Device Requests --------------------------------------------------- @@ -933,6 +955,135 @@ esp_err_t usb_host_get_active_config_descriptor(usb_device_handle_t dev_hdl, con return usbh_dev_get_config_desc(dev_hdl, config_desc); } +// ----------------- Descriptors Transfer Requests -------------------- + +static usb_transfer_status_t wait_for_transmission_done(usb_transfer_t *transfer) +{ + SemaphoreHandle_t transfer_done = (SemaphoreHandle_t)transfer->context; + xSemaphoreTake(transfer_done, portMAX_DELAY); + usb_transfer_status_t status = transfer->status; + + // EP0 halt->flush->clear is managed by USBH and lower layers + return status; +} + +static esp_err_t get_config_desc_transfer(usb_host_client_handle_t client_hdl, usb_transfer_t *ctrl_transfer, const int bConfigurationValue, const int num_bytes) +{ + const usb_device_desc_t *dev_desc; + ESP_ERROR_CHECK(usbh_dev_get_desc(ctrl_transfer->device_handle, &dev_desc)); + + usb_setup_packet_t *setup_pkt = (usb_setup_packet_t *)ctrl_transfer->data_buffer; + USB_SETUP_PACKET_INIT_GET_CONFIG_DESC(setup_pkt, bConfigurationValue - 1, num_bytes); + ctrl_transfer->num_bytes = sizeof(usb_setup_packet_t) + usb_round_up_to_mps(num_bytes, dev_desc->bMaxPacketSize0); + + // IN data stage should return exactly num_bytes (SHORT_DESC_REQ_LEN or wTotalLength) bytes + const int expect_num_bytes = sizeof(usb_setup_packet_t) + num_bytes; + + // Submit control transfer + esp_err_t ret = usb_host_transfer_submit_control(client_hdl, ctrl_transfer); + if (ret != ESP_OK) { + ESP_LOGE(USB_HOST_TAG, "Submit ctrl transfer failed"); + return ret; + } + + // Wait for transfer to finish + const usb_transfer_status_t status_short_desc = wait_for_transmission_done(ctrl_transfer); + if (status_short_desc != USB_TRANSFER_STATUS_COMPLETED) { + ESP_LOGE(USB_HOST_TAG, "Get config descriptor transfer status: %d", status_short_desc); + ret = ESP_ERR_INVALID_STATE; + return ret; + } + + // Check IN transfer returned the expected correct number of bytes + if ((expect_num_bytes != 0) && (ctrl_transfer->actual_num_bytes != expect_num_bytes)) { + if (ctrl_transfer->actual_num_bytes > expect_num_bytes) { + // The device returned more bytes than requested. + // This violates the USB specs chapter 9.3.5, but we can continue + ESP_LOGW(USB_HOST_TAG, "Incorrect number of bytes returned %d", ctrl_transfer->actual_num_bytes); + return ESP_OK; + } else { + // The device returned less bytes than requested. We cannot continue. + ESP_LOGE(USB_HOST_TAG, "Incorrect number of bytes returned %d", ctrl_transfer->actual_num_bytes); + return ESP_ERR_INVALID_RESPONSE; + } + } + return ESP_OK; +} + +esp_err_t usb_host_get_config_desc(usb_host_client_handle_t client_hdl, usb_device_handle_t dev_hdl, uint8_t bConfigurationValue, const usb_config_desc_t **config_desc_ret) +{ + esp_err_t ret = ESP_OK; + HOST_CHECK(client_hdl != NULL && dev_hdl != NULL && config_desc_ret != NULL, ESP_ERR_INVALID_ARG); + + // Get number of configurations + const usb_device_desc_t *dev_desc; + ESP_ERROR_CHECK(usbh_dev_get_desc(dev_hdl, &dev_desc)); + + HOST_CHECK(bConfigurationValue != 0, ESP_ERR_INVALID_ARG); + HOST_CHECK(bConfigurationValue <= dev_desc->bNumConfigurations, ESP_ERR_NOT_SUPPORTED); + + // Initialize transfer + usb_transfer_t *ctrl_transfer; + if (usb_host_transfer_alloc(sizeof(usb_setup_packet_t) + CTRL_TRANSFER_MAX_DATA_LEN, 0, &ctrl_transfer)) { + return ESP_ERR_NO_MEM; + } + + SemaphoreHandle_t transfer_done = xSemaphoreCreateBinary(); + if (transfer_done == NULL) { + ret = ESP_ERR_NO_MEM; + goto exit; + } + + ctrl_transfer->device_handle = dev_hdl; + ctrl_transfer->bEndpointAddress = 0; + ctrl_transfer->callback = get_config_desc_transfer_cb; + ctrl_transfer->context = (void *)transfer_done; + + // Initiate control transfer for short config descriptor + ret = get_config_desc_transfer(client_hdl, ctrl_transfer, bConfigurationValue, SHORT_DESC_REQ_LEN); + if (ret != ESP_OK) { + goto exit; + } + + // Get length of full config descriptor + const usb_config_desc_t *config_desc_short = (usb_config_desc_t *)(ctrl_transfer->data_buffer + sizeof(usb_setup_packet_t)); + + // Initiate control transfer for full config descriptor + ret = get_config_desc_transfer(client_hdl, ctrl_transfer, bConfigurationValue, config_desc_short->wTotalLength); + if (ret != ESP_OK) { + goto exit; + } + + // Allocate memory to store the configuration descriptor + const usb_config_desc_t *config_desc_full = (usb_config_desc_t *)(ctrl_transfer->data_buffer + sizeof(usb_setup_packet_t)); + usb_config_desc_t *config_desc = heap_caps_malloc(config_desc_full->wTotalLength, MALLOC_CAP_DEFAULT); + if (config_desc == NULL) { + ret = ESP_ERR_NO_MEM; + goto exit; + } + + // Copy the configuration descriptor + memcpy(config_desc, config_desc_full, config_desc_full->wTotalLength); + *config_desc_ret = config_desc; + ret = ESP_OK; + +exit: + if (ctrl_transfer) { + usb_host_transfer_free(ctrl_transfer); + } + if (transfer_done != NULL) { + vSemaphoreDelete(transfer_done); + } + return ret; +} + +esp_err_t usb_host_free_config_desc(const usb_config_desc_t *config_desc) +{ + HOST_CHECK(config_desc != NULL, ESP_ERR_INVALID_ARG); + heap_caps_free((usb_config_desc_t*)config_desc); + return ESP_OK; +} + // ----------------------------------------------- Interface Functions ------------------------------------------------- // ----------------------- Private ------------------------- diff --git a/components/usb/usb_phy_p4.c b/components/usb/usb_phy_p4.c index cff6420e0826..a541fafe4c45 100644 --- a/components/usb/usb_phy_p4.c +++ b/components/usb/usb_phy_p4.c @@ -6,11 +6,27 @@ // This is only a dummy USB PHY file for successful linking of ESP32-P4 target // The internal HS PHY is enabled by default, therefore it needs no configuration + +// TODO: Refactor during the IDF-9198 +#include "sdkconfig.h" +#include "soc/usb_dwc_cfg.h" +#include "hal/usb_wrap_hal.h" // TODO: Remove this file when proper support of P4 PHYs is implemented IDF-7323 #include "esp_private/usb_phy.h" esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_ret) { +#if (OTG_HSPHY_INTERFACE != 0) +#if CONFIG_IDF_TARGET_ESP32P4 + /* + Additional setting to solve missing DCONN event on ESP32P4 (IDF-9953). + + Note: On ESP32P4, the HP_SYSTEM_OTG_SUSPENDM is not connected to 1 by hardware. + For correct detection of the device detaching, internal signal should be set to 1 by the software. + */ + usb_wrap_ll_enable_precise_detection(); +#endif // CONFIG_IDF_TARGET_ESP32P4 +#endif // (OTG_HSPHY_INTERFACE != 0) return ESP_OK; } diff --git a/components/usb/usbh.c b/components/usb/usbh.c index a50f4fc94443..b402e72a9962 100644 --- a/components/usb/usbh.c +++ b/components/usb/usbh.c @@ -57,14 +57,15 @@ struct device_s { uint32_t in_pending_list: 1; uint32_t is_gone: 1; // Device is gone (disconnected or port error) uint32_t waiting_free: 1; // Device object is awaiting to be freed - uint32_t reserved29: 29; + uint32_t enum_lock: 1; // Device is locked for enumeration. Enum information (e.g., address, device/config desc etc) may change + uint32_t reserved28: 28; }; uint32_t val; } flags; uint32_t action_flags; int num_ctrl_xfers_inflight; usb_device_state_t state; - uint32_t ref_count; + uint32_t open_count; } dynamic; // Mux protected members must be protected by the USBH mux_lock when accessed struct { @@ -74,17 +75,22 @@ struct device_s { */ endpoint_t *endpoints[NUM_NON_DEFAULT_EP]; } mux_protected; - // Constant members do not change after device allocation and enumeration thus do not require a critical section + // Constant members do not require a critical section struct { + // Assigned on device allocation and remain constant for the device's lifetime hcd_pipe_handle_t default_pipe; hcd_port_handle_t port_hdl; - uint8_t address; usb_speed_t speed; - const usb_device_desc_t *desc; - const usb_config_desc_t *config_desc; - const usb_str_desc_t *str_desc_manu; - const usb_str_desc_t *str_desc_product; - const usb_str_desc_t *str_desc_ser_num; + unsigned int uid; + /* + These fields are can only be changed when enum_lock is set, thus can be treated as constant + */ + uint8_t address; + usb_device_desc_t *desc; + usb_config_desc_t *config_desc; + usb_str_desc_t *str_desc_manu; + usb_str_desc_t *str_desc_product; + usb_str_desc_t *str_desc_ser_num; } constant; }; @@ -143,6 +149,50 @@ static bool _dev_set_actions(device_t *dev_obj, uint32_t action_flags); // ----------------------------------------------------- Helpers ------------------------------------------------------- +static device_t *_find_dev_from_uid(unsigned int uid) +{ + /* + THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION + */ + device_t *dev_iter; + + // Search the device lists for a device with the specified address + TAILQ_FOREACH(dev_iter, &p_usbh_obj->dynamic.devs_idle_tailq, dynamic.tailq_entry) { + if (dev_iter->constant.uid == uid) { + return dev_iter; + } + } + TAILQ_FOREACH(dev_iter, &p_usbh_obj->dynamic.devs_pending_tailq, dynamic.tailq_entry) { + if (dev_iter->constant.uid == uid) { + return dev_iter; + } + } + + return NULL; +} + +static device_t *_find_dev_from_addr(uint8_t dev_addr) +{ + /* + THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION + */ + device_t *dev_iter; + + // Search the device lists for a device with the specified address + TAILQ_FOREACH(dev_iter, &p_usbh_obj->dynamic.devs_idle_tailq, dynamic.tailq_entry) { + if (dev_iter->constant.address == dev_addr) { + return dev_iter; + } + } + TAILQ_FOREACH(dev_iter, &p_usbh_obj->dynamic.devs_pending_tailq, dynamic.tailq_entry) { + if (dev_iter->constant.address == dev_addr) { + return dev_iter; + } + } + + return NULL; +} + static inline bool check_ep_addr(uint8_t bEndpointAddress) { /* @@ -204,13 +254,21 @@ static bool urb_check_args(urb_t *urb) return true; } -static bool transfer_check_usb_compliance(usb_transfer_t *transfer, usb_transfer_type_t type, int mps, bool is_in) +static bool transfer_check_usb_compliance(usb_transfer_t *transfer, usb_transfer_type_t type, unsigned int mps, bool is_in) { if (type == USB_TRANSFER_TYPE_CTRL) { // Check that num_bytes and wLength are set correctly usb_setup_packet_t *setup_pkt = (usb_setup_packet_t *)transfer->data_buffer; - if (transfer->num_bytes != sizeof(usb_setup_packet_t) + setup_pkt->wLength) { - ESP_LOGE(USBH_TAG, "usb_transfer_t num_bytes and usb_setup_packet_t wLength mismatch"); + bool mismatch = false; + if (is_in) { + // For IN transfers, 'num_bytes >= sizeof(usb_setup_packet_t) + setup_pkt->wLength' due to MPS rounding + mismatch = (transfer->num_bytes < sizeof(usb_setup_packet_t) + setup_pkt->wLength); + } else { + // For OUT transfers, num_bytes must match 'sizeof(usb_setup_packet_t) + setup_pkt->wLength' + mismatch = (transfer->num_bytes != sizeof(usb_setup_packet_t) + setup_pkt->wLength); + } + if (mismatch) { + ESP_LOGE(USBH_TAG, "usb_transfer_t num_bytes %d and usb_setup_packet_t wLength %d mismatch", transfer->num_bytes, setup_pkt->wLength); return false; } } else if (type == USB_TRANSFER_TYPE_ISOCHRONOUS) { @@ -300,19 +358,21 @@ static void endpoint_free(endpoint_t *ep_obj) heap_caps_free(ep_obj); } -static esp_err_t device_alloc(hcd_port_handle_t port_hdl, usb_speed_t speed, device_t **dev_obj_ret) +static esp_err_t device_alloc(unsigned int uid, + usb_speed_t speed, + hcd_port_handle_t port_hdl, + device_t **dev_obj_ret) { - esp_err_t ret; device_t *dev_obj = heap_caps_calloc(1, sizeof(device_t), MALLOC_CAP_DEFAULT); - usb_device_desc_t *dev_desc = heap_caps_calloc(1, sizeof(usb_device_desc_t), MALLOC_CAP_DEFAULT); - if (dev_obj == NULL || dev_desc == NULL) { - ret = ESP_ERR_NO_MEM; - goto err; + if (dev_obj == NULL) { + return ESP_ERR_NO_MEM; } - // Allocate a pipe for EP0. We set the pipe callback to NULL for now + + esp_err_t ret; + // Allocate a pipe for EP0 hcd_pipe_config_t pipe_config = { - .callback = NULL, - .callback_arg = NULL, + .callback = ep0_pipe_callback, + .callback_arg = (void *)dev_obj, .context = (void *)dev_obj, .ep_desc = NULL, // No endpoint descriptor means we're allocating a pipe for EP0 .dev_speed = speed, @@ -327,15 +387,17 @@ static esp_err_t device_alloc(hcd_port_handle_t port_hdl, usb_speed_t speed, dev dev_obj->dynamic.state = USB_DEVICE_STATE_DEFAULT; dev_obj->constant.default_pipe = default_pipe_hdl; dev_obj->constant.port_hdl = port_hdl; - // Note: dev_obj->constant.address is assigned later during enumeration dev_obj->constant.speed = speed; - dev_obj->constant.desc = dev_desc; + dev_obj->constant.uid = uid; + // Note: Enumeration related dev_obj->constant fields are initialized later using usbh_dev_set_...() functions + + // Write-back device object *dev_obj_ret = dev_obj; ret = ESP_OK; + return ret; err: - heap_caps_free(dev_desc); heap_caps_free(dev_obj); return ret; } @@ -345,21 +407,24 @@ static void device_free(device_t *dev_obj) if (dev_obj == NULL) { return; } - // Configuration might not have been allocated (in case of early enumeration failure) + // Device descriptor might not have been set yet + if (dev_obj->constant.desc) { + heap_caps_free(dev_obj->constant.desc); + } + // Configuration descriptor might not have been set yet if (dev_obj->constant.config_desc) { - heap_caps_free((usb_config_desc_t *)dev_obj->constant.config_desc); + heap_caps_free(dev_obj->constant.config_desc); } - // String descriptors might not have been allocated (in case of early enumeration failure) + // String descriptors might not have been set yet if (dev_obj->constant.str_desc_manu) { - heap_caps_free((usb_str_desc_t *)dev_obj->constant.str_desc_manu); + heap_caps_free(dev_obj->constant.str_desc_manu); } if (dev_obj->constant.str_desc_product) { - heap_caps_free((usb_str_desc_t *)dev_obj->constant.str_desc_product); + heap_caps_free(dev_obj->constant.str_desc_product); } if (dev_obj->constant.str_desc_ser_num) { - heap_caps_free((usb_str_desc_t *)dev_obj->constant.str_desc_ser_num); + heap_caps_free(dev_obj->constant.str_desc_ser_num); } - heap_caps_free((usb_device_desc_t *)dev_obj->constant.desc); ESP_ERROR_CHECK(hcd_pipe_free(dev_obj->constant.default_pipe)); heap_caps_free(dev_obj); } @@ -426,6 +491,9 @@ static bool epN_pipe_callback(hcd_pipe_handle_t pipe_hdl, hcd_pipe_event_t pipe_ static bool _dev_set_actions(device_t *dev_obj, uint32_t action_flags) { + /* + THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION + */ if (action_flags == 0) { return false; } @@ -512,7 +580,7 @@ static inline void handle_prop_gone_evt(device_t *dev_obj) static inline void handle_free(device_t *dev_obj) { // Cache a copy of the device's address as we are about to free the device object - const uint8_t dev_addr = dev_obj->constant.address; + const unsigned int dev_uid = dev_obj->constant.uid; bool all_free; ESP_LOGD(USBH_TAG, "Freeing device %d", dev_obj->constant.address); @@ -536,7 +604,7 @@ static inline void handle_free(device_t *dev_obj) usbh_event_data_t event_data = { .event = USBH_EVENT_DEV_FREE, .dev_free_data = { - .dev_addr = dev_addr, + .dev_uid = dev_uid, } }; p_usbh_obj->constant.event_cb(&event_data, p_usbh_obj->constant.event_cb_arg); @@ -561,7 +629,7 @@ static inline void handle_prop_new_dev(device_t *dev_obj) p_usbh_obj->constant.event_cb(&event_data, p_usbh_obj->constant.event_cb_arg); } -// ------------------------------------------------- USBH Functions ---------------------------------------------------- +// -------------------------------------------- USBH Processing Functions ---------------------------------------------- esp_err_t usbh_install(const usbh_config_t *usbh_config) { @@ -661,8 +729,6 @@ esp_err_t usbh_process(void) --------------------------------------------------------------------- */ USBH_EXIT_CRITICAL(); ESP_LOGD(USBH_TAG, "Processing actions 0x%"PRIx32"", action_flags); - // Sanity check. If the device is being freed, there must not be any other action flags set - assert(!(action_flags & DEV_ACTION_FREE) || action_flags == DEV_ACTION_FREE); if (action_flags & DEV_ACTION_EPn_HALT_FLUSH) { handle_epn_halt_flush(dev_obj); @@ -700,7 +766,9 @@ esp_err_t usbh_process(void) return ESP_OK; } -esp_err_t usbh_num_devs(int *num_devs_ret) +// ---------------------------------------------- Device Pool Functions ------------------------------------------------ + +esp_err_t usbh_devs_num(int *num_devs_ret) { USBH_CHECK(num_devs_ret != NULL, ESP_ERR_INVALID_ARG); xSemaphoreTake(p_usbh_obj->constant.mux_lock, portMAX_DELAY); @@ -709,31 +777,45 @@ esp_err_t usbh_num_devs(int *num_devs_ret) return ESP_OK; } -// ------------------------------------------------ Device Functions --------------------------------------------------- - -// --------------------- Device Pool ----------------------- - -esp_err_t usbh_dev_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num_dev_ret) +esp_err_t usbh_devs_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num_dev_ret) { USBH_CHECK(dev_addr_list != NULL && num_dev_ret != NULL, ESP_ERR_INVALID_ARG); - USBH_ENTER_CRITICAL(); int num_filled = 0; device_t *dev_obj; - // Fill list with devices from idle tailq + + USBH_ENTER_CRITICAL(); + /* + Fill list with devices from idle tailq and pending tailq. Only devices that + are fully enumerated are added to the list. Thus, the following devices are + not excluded: + - Devices with their enum_lock set + - Devices not in the configured state + - Devices with address 0 + */ TAILQ_FOREACH(dev_obj, &p_usbh_obj->dynamic.devs_idle_tailq, dynamic.tailq_entry) { if (num_filled < list_len) { - dev_addr_list[num_filled] = dev_obj->constant.address; - num_filled++; + if (!dev_obj->dynamic.flags.enum_lock && + dev_obj->dynamic.state == USB_DEVICE_STATE_CONFIGURED && + dev_obj->constant.address != 0) { + dev_addr_list[num_filled] = dev_obj->constant.address; + num_filled++; + } } else { + // Address list is already full break; } } // Fill list with devices from pending tailq TAILQ_FOREACH(dev_obj, &p_usbh_obj->dynamic.devs_pending_tailq, dynamic.tailq_entry) { if (num_filled < list_len) { - dev_addr_list[num_filled] = dev_obj->constant.address; - num_filled++; + if (!dev_obj->dynamic.flags.enum_lock && + dev_obj->dynamic.state == USB_DEVICE_STATE_CONFIGURED && + dev_obj->constant.address != 0) { + dev_addr_list[num_filled] = dev_obj->constant.address; + num_filled++; + } } else { + // Address list is already full break; } } @@ -743,72 +825,83 @@ esp_err_t usbh_dev_addr_list_fill(int list_len, uint8_t *dev_addr_list, int *num return ESP_OK; } -esp_err_t usbh_dev_open(uint8_t dev_addr, usb_device_handle_t *dev_hdl) +esp_err_t usbh_devs_add(unsigned int uid, usb_speed_t dev_speed, hcd_port_handle_t port_hdl) { - USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); + USBH_CHECK(port_hdl != NULL, ESP_ERR_INVALID_ARG); esp_err_t ret; + device_t *dev_obj; + // Allocate a device object (initialized to address 0) + ret = device_alloc(uid, dev_speed, port_hdl, &dev_obj); + if (ret != ESP_OK) { + return ret; + } + + // We need to take the mux_lock to access mux_protected members + xSemaphoreTake(p_usbh_obj->constant.mux_lock, portMAX_DELAY); USBH_ENTER_CRITICAL(); - // Go through the device lists to find the device with the specified address - device_t *found_dev_obj = NULL; - device_t *dev_obj; - TAILQ_FOREACH(dev_obj, &p_usbh_obj->dynamic.devs_idle_tailq, dynamic.tailq_entry) { - if (dev_obj->constant.address == dev_addr) { - found_dev_obj = dev_obj; - goto exit; - } + + // Check that there is not already a device with the same uid + if (_find_dev_from_uid(uid) != NULL) { + ret = ESP_ERR_INVALID_ARG; + goto exit; } - TAILQ_FOREACH(dev_obj, &p_usbh_obj->dynamic.devs_pending_tailq, dynamic.tailq_entry) { - if (dev_obj->constant.address == dev_addr) { - found_dev_obj = dev_obj; - goto exit; - } + // Check that there is not already a device currently with address 0 + if (_find_dev_from_addr(0) != NULL) { + ret = ESP_ERR_NOT_FINISHED; + goto exit; } + // Add the device to the idle device list + TAILQ_INSERT_TAIL(&p_usbh_obj->dynamic.devs_idle_tailq, dev_obj, dynamic.tailq_entry); + p_usbh_obj->mux_protected.num_device++; + ret = ESP_OK; + exit: - if (found_dev_obj != NULL) { - // The device is not in a state to be referenced - if (dev_obj->dynamic.flags.is_gone || dev_obj->dynamic.flags.waiting_free) { - ret = ESP_ERR_INVALID_STATE; - } else { - dev_obj->dynamic.ref_count++; - *dev_hdl = (usb_device_handle_t)found_dev_obj; - ret = ESP_OK; - } - } else { - ret = ESP_ERR_NOT_FOUND; - } USBH_EXIT_CRITICAL(); + xSemaphoreGive(p_usbh_obj->constant.mux_lock); return ret; } -esp_err_t usbh_dev_close(usb_device_handle_t dev_hdl) +esp_err_t usbh_devs_remove(unsigned int uid) { - USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); - device_t *dev_obj = (device_t *)dev_hdl; + esp_err_t ret; + device_t *dev_obj; + bool call_proc_req_cb = false; USBH_ENTER_CRITICAL(); - dev_obj->dynamic.ref_count--; - bool call_proc_req_cb = false; - if (dev_obj->dynamic.ref_count == 0) { - // Sanity check. - assert(dev_obj->dynamic.num_ctrl_xfers_inflight == 0); // There cannot be any control transfer in-flight - assert(!dev_obj->dynamic.flags.waiting_free); // This can only be set when ref count reaches 0 - if (dev_obj->dynamic.flags.is_gone || dev_obj->dynamic.flags.waiting_free) { - // Device is already gone or is awaiting to be freed. Trigger the USBH process to free the device - call_proc_req_cb = _dev_set_actions(dev_obj, DEV_ACTION_FREE); - } - // Else, there's nothing to do. Leave the device allocated + dev_obj = _find_dev_from_uid(uid); + if (dev_obj == NULL) { + ret = ESP_ERR_NOT_FOUND; + goto exit; + } + // Mark the device as gone + dev_obj->dynamic.flags.is_gone = 1; + // Check if the device can be freed immediately + if (dev_obj->dynamic.open_count == 0) { + // Device is not currently opened at all. Can free immediately. + call_proc_req_cb = _dev_set_actions(dev_obj, DEV_ACTION_FREE); + } else { + // Device is still opened. Flush endpoints and propagate device gone event + call_proc_req_cb = _dev_set_actions(dev_obj, + DEV_ACTION_EPn_HALT_FLUSH | + DEV_ACTION_EP0_FLUSH | + DEV_ACTION_EP0_DEQUEUE | + DEV_ACTION_PROP_GONE_EVT); } + ret = ESP_OK; +exit: USBH_EXIT_CRITICAL(); + // Call the processing request callback if (call_proc_req_cb) { p_usbh_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_USBH, false, p_usbh_obj->constant.proc_req_cb_arg); } - return ESP_OK; + + return ret; } -esp_err_t usbh_dev_mark_all_free(void) +esp_err_t usbh_devs_mark_all_free(void) { USBH_ENTER_CRITICAL(); /* @@ -830,11 +923,11 @@ esp_err_t usbh_dev_mark_all_free(void) while (dev_obj_cur != NULL) { // Keep a copy of the next item first in case we remove the current item dev_obj_next = TAILQ_NEXT(dev_obj_cur, dynamic.tailq_entry); - if (dev_obj_cur->dynamic.ref_count == 0) { - // Device is not referenced. Can free immediately. + if (dev_obj_cur->dynamic.open_count == 0) { + // Device is not opened. Can free immediately. call_proc_req_cb |= _dev_set_actions(dev_obj_cur, DEV_ACTION_FREE); } else { - // Device is still referenced. Just mark it as waiting to be freed + // Device is still opened. Just mark it as waiting to be freed dev_obj_cur->dynamic.flags.waiting_free = 1; } // At least one device needs to be freed. User needs to wait for USBH_EVENT_ALL_FREE event @@ -850,7 +943,85 @@ esp_err_t usbh_dev_mark_all_free(void) return (wait_for_free) ? ESP_ERR_NOT_FINISHED : ESP_OK; } -// ------------------- Single Device ---------------------- +esp_err_t usbh_devs_open(uint8_t dev_addr, usb_device_handle_t *dev_hdl) +{ + USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); + esp_err_t ret; + + USBH_ENTER_CRITICAL(); + // Go through the device lists to find the device with the specified address + device_t *dev_obj = _find_dev_from_addr(dev_addr); + if (dev_obj != NULL) { + // Check if the device is in a state to be opened + if (dev_obj->dynamic.flags.is_gone || // Device is already gone (disconnected) + dev_obj->dynamic.flags.waiting_free) { // Device is waiting to be freed + ret = ESP_ERR_INVALID_STATE; + } else if (dev_obj->dynamic.flags.enum_lock) { // Device's enum_lock is set + ret = ESP_ERR_NOT_ALLOWED; + } else { + dev_obj->dynamic.open_count++; + *dev_hdl = (usb_device_handle_t)dev_obj; + ret = ESP_OK; + } + } else { + ret = ESP_ERR_NOT_FOUND; + } + USBH_EXIT_CRITICAL(); + + return ret; +} + +esp_err_t usbh_devs_close(usb_device_handle_t dev_hdl) +{ + USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); + device_t *dev_obj = (device_t *)dev_hdl; + + USBH_ENTER_CRITICAL(); + // Device should never be closed while its enum_lock is + USBH_CHECK_FROM_CRIT(!dev_obj->dynamic.flags.enum_lock, ESP_ERR_NOT_ALLOWED); + dev_obj->dynamic.open_count--; + bool call_proc_req_cb = false; + if (dev_obj->dynamic.open_count == 0) { + // Sanity check. + assert(dev_obj->dynamic.num_ctrl_xfers_inflight == 0); // There cannot be any control transfer in-flight + assert(!dev_obj->dynamic.flags.waiting_free); // This can only be set when open_count reaches 0 + if (dev_obj->dynamic.flags.is_gone || dev_obj->dynamic.flags.waiting_free) { + // Device is already gone or is awaiting to be freed. Trigger the USBH process to free the device + call_proc_req_cb = _dev_set_actions(dev_obj, DEV_ACTION_FREE); + } + // Else, there's nothing to do. Leave the device allocated + } + USBH_EXIT_CRITICAL(); + + if (call_proc_req_cb) { + p_usbh_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_USBH, false, p_usbh_obj->constant.proc_req_cb_arg); + } + + return ESP_OK; +} + +esp_err_t usbh_devs_new_dev_event(usb_device_handle_t dev_hdl) +{ + device_t *dev_obj = (device_t *)dev_hdl; + bool call_proc_req_cb = false; + + USBH_ENTER_CRITICAL(); + // Device must be in the configured state + USBH_CHECK_FROM_CRIT(dev_obj->dynamic.state == USB_DEVICE_STATE_CONFIGURED, ESP_ERR_INVALID_STATE); + call_proc_req_cb = _dev_set_actions(dev_obj, DEV_ACTION_PROP_NEW_DEV); + USBH_EXIT_CRITICAL(); + + // Call the processing request callback + if (call_proc_req_cb) { + p_usbh_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_USBH, false, p_usbh_obj->constant.proc_req_cb_arg); + } + + return ESP_OK; +} + +// ------------------------------------------------ Device Functions --------------------------------------------------- + +// ----------------------- Getters ------------------------- esp_err_t usbh_dev_get_addr(usb_device_handle_t dev_hdl, uint8_t *dev_addr) { @@ -870,28 +1041,26 @@ esp_err_t usbh_dev_get_info(usb_device_handle_t dev_hdl, usb_device_info_t *dev_ USBH_CHECK(dev_hdl != NULL && dev_info != NULL, ESP_ERR_INVALID_ARG); device_t *dev_obj = (device_t *)dev_hdl; - esp_err_t ret; - // Device must be configured, or not attached (if it suddenly disconnected) - USBH_ENTER_CRITICAL(); - if (!(dev_obj->dynamic.state == USB_DEVICE_STATE_CONFIGURED || dev_obj->dynamic.state == USB_DEVICE_STATE_NOT_ATTACHED)) { - USBH_EXIT_CRITICAL(); - ret = ESP_ERR_INVALID_STATE; - goto exit; - } - // Critical section for the dynamic members dev_info->speed = dev_obj->constant.speed; dev_info->dev_addr = dev_obj->constant.address; - dev_info->bMaxPacketSize0 = dev_obj->constant.desc->bMaxPacketSize0; - USBH_EXIT_CRITICAL(); - assert(dev_obj->constant.config_desc); - dev_info->bConfigurationValue = dev_obj->constant.config_desc->bConfigurationValue; - // String descriptors are allowed to be NULL as not all devices support them + // Device descriptor might not have been set yet + if (dev_obj->constant.desc) { + dev_info->bMaxPacketSize0 = dev_obj->constant.desc->bMaxPacketSize0; + } else { + // Use the default pipe's MPS instead + dev_info->bMaxPacketSize0 = hcd_pipe_get_mps(dev_obj->constant.default_pipe); + } + // Configuration descriptor might not have been set yet + if (dev_obj->constant.config_desc) { + dev_info->bConfigurationValue = dev_obj->constant.config_desc->bConfigurationValue; + } else { + dev_info->bConfigurationValue = 0; + } dev_info->str_desc_manufacturer = dev_obj->constant.str_desc_manu; dev_info->str_desc_product = dev_obj->constant.str_desc_product; dev_info->str_desc_serial_num = dev_obj->constant.str_desc_ser_num; - ret = ESP_OK; -exit: - return ret; + + return ESP_OK; } esp_err_t usbh_dev_get_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t **dev_desc_ret) @@ -899,10 +1068,6 @@ esp_err_t usbh_dev_get_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t USBH_CHECK(dev_hdl != NULL && dev_desc_ret != NULL, ESP_ERR_INVALID_ARG); device_t *dev_obj = (device_t *)dev_hdl; - USBH_ENTER_CRITICAL(); - USBH_CHECK_FROM_CRIT(dev_obj->dynamic.state == USB_DEVICE_STATE_CONFIGURED, ESP_ERR_INVALID_STATE); - USBH_EXIT_CRITICAL(); - *dev_desc_ret = dev_obj->constant.desc; return ESP_OK; } @@ -912,56 +1077,260 @@ esp_err_t usbh_dev_get_config_desc(usb_device_handle_t dev_hdl, const usb_config USBH_CHECK(dev_hdl != NULL && config_desc_ret != NULL, ESP_ERR_INVALID_ARG); device_t *dev_obj = (device_t *)dev_hdl; + *config_desc_ret = dev_obj->constant.config_desc; + + return ESP_OK; +} + +// ----------------------- Setters ------------------------- + +esp_err_t usbh_dev_enum_lock(usb_device_handle_t dev_hdl) +{ + USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); esp_err_t ret; - // Device must be in the configured state - USBH_ENTER_CRITICAL(); - if (dev_obj->dynamic.state != USB_DEVICE_STATE_CONFIGURED) { - USBH_EXIT_CRITICAL(); + device_t *dev_obj = (device_t *)dev_hdl; + + // We need to take the mux_lock to access mux_protected members + xSemaphoreTake(p_usbh_obj->constant.mux_lock, portMAX_DELAY); + + /* + The device's enum_lock can only be set when the following conditions are met: + - No other endpoints except EP0 have been allocated + - We are the sole opener + - Device's enum_lock is not already set + */ + // Check that no other endpoints except EP0 have been allocated + bool ep_found = false; + for (int i = 0; i < NUM_NON_DEFAULT_EP; i++) { + if (dev_obj->mux_protected.endpoints[i] != NULL) { + ep_found = true; + break; + } + } + if (ep_found) { ret = ESP_ERR_INVALID_STATE; goto exit; } + // Check that we are the sole opener and enum_lock is not already set + USBH_ENTER_CRITICAL(); + if (!dev_obj->dynamic.flags.enum_lock && (dev_obj->dynamic.open_count == 1)) { + dev_obj->dynamic.flags.enum_lock = true; + ret = ESP_OK; + } else { + ret = ESP_ERR_INVALID_STATE; + } USBH_EXIT_CRITICAL(); - assert(dev_obj->constant.config_desc); - *config_desc_ret = dev_obj->constant.config_desc; - ret = ESP_OK; + exit: + xSemaphoreGive(p_usbh_obj->constant.mux_lock); + return ret; } -esp_err_t usbh_dev_submit_ctrl_urb(usb_device_handle_t dev_hdl, urb_t *urb) +esp_err_t usbh_dev_enum_unlock(usb_device_handle_t dev_hdl) { - USBH_CHECK(dev_hdl != NULL && urb != NULL, ESP_ERR_INVALID_ARG); + USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); + esp_err_t ret; device_t *dev_obj = (device_t *)dev_hdl; - USBH_CHECK(urb_check_args(urb), ESP_ERR_INVALID_ARG); - bool xfer_is_in = ((usb_setup_packet_t *)urb->transfer.data_buffer)->bmRequestType & USB_BM_REQUEST_TYPE_DIR_IN; - USBH_CHECK(transfer_check_usb_compliance(&(urb->transfer), USB_TRANSFER_TYPE_CTRL, dev_obj->constant.desc->bMaxPacketSize0, xfer_is_in), ESP_ERR_INVALID_ARG); USBH_ENTER_CRITICAL(); - USBH_CHECK_FROM_CRIT(dev_obj->dynamic.state == USB_DEVICE_STATE_CONFIGURED, ESP_ERR_INVALID_STATE); - // Increment the control transfer count first - dev_obj->dynamic.num_ctrl_xfers_inflight++; + // Device's enum_lock must have been previously set + if (dev_obj->dynamic.flags.enum_lock) { + assert(dev_obj->dynamic.open_count == 1); // We must still be the sole opener + dev_obj->dynamic.flags.enum_lock = false; + ret = ESP_OK; + } else { + ret = ESP_ERR_INVALID_STATE; + } USBH_EXIT_CRITICAL(); + return ret; +} + +esp_err_t usbh_dev_set_ep0_mps(usb_device_handle_t dev_hdl, uint16_t wMaxPacketSize) +{ + USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); esp_err_t ret; - if (hcd_pipe_get_state(dev_obj->constant.default_pipe) != HCD_PIPE_STATE_ACTIVE) { + device_t *dev_obj = (device_t *)dev_hdl; + + USBH_ENTER_CRITICAL(); + // Device's EP0 MPS can only be updated when in the default state + if (dev_obj->dynamic.state != USB_DEVICE_STATE_DEFAULT) { ret = ESP_ERR_INVALID_STATE; - goto hcd_err; + goto exit; } - ret = hcd_urb_enqueue(dev_obj->constant.default_pipe, urb); - if (ret != ESP_OK) { - goto hcd_err; + // Device's enum_lock must be set before enumeration related data fields can be set + if (dev_obj->dynamic.flags.enum_lock) { + ret = hcd_pipe_update_mps(dev_obj->constant.default_pipe, wMaxPacketSize); + } else { + ret = ESP_ERR_NOT_ALLOWED; + } +exit: + USBH_EXIT_CRITICAL(); + + return ret; +} + +esp_err_t usbh_dev_set_addr(usb_device_handle_t dev_hdl, uint8_t dev_addr) +{ + USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); + esp_err_t ret; + device_t *dev_obj = (device_t *)dev_hdl; + + USBH_ENTER_CRITICAL(); + // Device's address can only be set when in the default state + USBH_CHECK_FROM_CRIT(dev_obj->dynamic.state == USB_DEVICE_STATE_DEFAULT, ESP_ERR_INVALID_STATE); + // Device's enum_lock must be set before enumeration related data fields can be set + USBH_CHECK_FROM_CRIT(dev_obj->dynamic.flags.enum_lock, ESP_ERR_NOT_ALLOWED); + // Update the device and default pipe's target address + ret = hcd_pipe_update_dev_addr(dev_obj->constant.default_pipe, dev_addr); + if (ret == ESP_OK) { + dev_obj->constant.address = dev_addr; + dev_obj->dynamic.state = USB_DEVICE_STATE_ADDRESS; + } + USBH_EXIT_CRITICAL(); + + return ret; +} + +esp_err_t usbh_dev_set_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t *device_desc) +{ + USBH_CHECK(dev_hdl != NULL && device_desc != NULL, ESP_ERR_INVALID_ARG); + esp_err_t ret; + device_t *dev_obj = (device_t *)dev_hdl; + usb_device_desc_t *new_desc, *old_desc; + + // Allocate and copy new device descriptor + new_desc = heap_caps_malloc(sizeof(usb_device_desc_t), MALLOC_CAP_DEFAULT); + if (new_desc == NULL) { + return ESP_ERR_NO_MEM; } + memcpy(new_desc, device_desc, sizeof(usb_device_desc_t)); + + USBH_ENTER_CRITICAL(); + // Device's descriptor can only be set in the default or addressed state + if (!(dev_obj->dynamic.state == USB_DEVICE_STATE_DEFAULT || dev_obj->dynamic.state == USB_DEVICE_STATE_ADDRESS)) { + ret = ESP_ERR_INVALID_STATE; + goto err; + } + // Device's enum_lock must be set before we can set its device descriptor + if (!dev_obj->dynamic.flags.enum_lock) { + ret = ESP_ERR_NOT_ALLOWED; + goto err; + } + old_desc = dev_obj->constant.desc; // Save old descriptor for cleanup + dev_obj->constant.desc = new_desc; // Assign new descriptor + USBH_EXIT_CRITICAL(); + + // Clean up old descriptor or failed assignment + heap_caps_free(old_desc); ret = ESP_OK; + return ret; -hcd_err: +err: + USBH_EXIT_CRITICAL(); + heap_caps_free(new_desc); + return ret; +} + +esp_err_t usbh_dev_set_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t *config_desc_full) +{ + USBH_CHECK(dev_hdl != NULL && config_desc_full != NULL, ESP_ERR_INVALID_ARG); + esp_err_t ret; + device_t *dev_obj = (device_t *)dev_hdl; + usb_config_desc_t *new_desc, *old_desc; + + // Allocate and copy new config descriptor + new_desc = heap_caps_malloc(config_desc_full->wTotalLength, MALLOC_CAP_DEFAULT); + if (new_desc == NULL) { + return ESP_ERR_NO_MEM; + } + memcpy(new_desc, config_desc_full, config_desc_full->wTotalLength); + USBH_ENTER_CRITICAL(); - dev_obj->dynamic.num_ctrl_xfers_inflight--; + // Device's config descriptor can only be set when in the addressed state + if (dev_obj->dynamic.state != USB_DEVICE_STATE_ADDRESS) { + ret = ESP_ERR_INVALID_STATE; + goto err; + } + // Device's enum_lock must be set before we can set its config descriptor + if (!dev_obj->dynamic.flags.enum_lock) { + ret = ESP_ERR_NOT_ALLOWED; + goto err; + } + old_desc = dev_obj->constant.config_desc; // Save old descriptor for cleanup + dev_obj->constant.config_desc = new_desc; // Assign new descriptor + dev_obj->dynamic.state = USB_DEVICE_STATE_CONFIGURED; USBH_EXIT_CRITICAL(); + + // Clean up old descriptor or failed assignment + heap_caps_free(old_desc); + ret = ESP_OK; + + return ret; + +err: + USBH_EXIT_CRITICAL(); + heap_caps_free(new_desc); + return ret; +} + +esp_err_t usbh_dev_set_str_desc(usb_device_handle_t dev_hdl, const usb_str_desc_t *str_desc, int select) +{ + USBH_CHECK(dev_hdl != NULL && str_desc != NULL && (select >= 0 && select < 3), ESP_ERR_INVALID_ARG); + esp_err_t ret; + device_t *dev_obj = (device_t *)dev_hdl; + usb_str_desc_t *new_desc, *old_desc; + + // Allocate and copy new string descriptor + new_desc = heap_caps_malloc(str_desc->bLength, MALLOC_CAP_DEFAULT); + if (new_desc == NULL) { + return ESP_ERR_NO_MEM; + } + memcpy(new_desc, str_desc, str_desc->bLength); + + USBH_ENTER_CRITICAL(); + // Device's string descriptors can only be set when in the default state + if (dev_obj->dynamic.state != USB_DEVICE_STATE_CONFIGURED) { + ret = ESP_ERR_INVALID_STATE; + goto err; + } + // Device's enum_lock must be set before we can set its string descriptors + if (!dev_obj->dynamic.flags.enum_lock) { + ret = ESP_ERR_NOT_ALLOWED; + goto err; + } + // Assign to the selected descriptor + switch (select) { + case 0: + old_desc = dev_obj->constant.str_desc_manu; + dev_obj->constant.str_desc_manu = new_desc; + break; + case 1: + old_desc = dev_obj->constant.str_desc_product; + dev_obj->constant.str_desc_product = new_desc; + break; + default: // 2 + old_desc = dev_obj->constant.str_desc_ser_num; + dev_obj->constant.str_desc_ser_num = new_desc; + break; + } + USBH_EXIT_CRITICAL(); + + // Clean up old descriptor or failed assignment + heap_caps_free(old_desc); + ret = ESP_OK; + + return ret; + +err: + USBH_EXIT_CRITICAL(); + heap_caps_free(new_desc); return ret; } -// ----------------------------------------------- Interface Functions ------------------------------------------------- +// ----------------------------------------------- Endpoint Functions ------------------------------------------------- esp_err_t usbh_ep_alloc(usb_device_handle_t dev_hdl, usbh_ep_config_t *ep_config, usbh_ep_handle_t *ep_hdl_ret) { @@ -972,6 +1341,7 @@ esp_err_t usbh_ep_alloc(usb_device_handle_t dev_hdl, usbh_ep_config_t *ep_config esp_err_t ret; device_t *dev_obj = (device_t *)dev_hdl; endpoint_t *ep_obj; + USBH_CHECK(dev_obj->constant.config_desc, ESP_ERR_INVALID_STATE); // Configuration descriptor must be set // Find the endpoint descriptor from the device's current configuration descriptor const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_address(dev_obj->constant.config_desc, ep_config->bInterfaceNumber, ep_config->bAlternateSetting, ep_config->bEndpointAddress, NULL); @@ -1074,36 +1444,6 @@ esp_err_t usbh_ep_get_handle(usb_device_handle_t dev_hdl, uint8_t bEndpointAddre return ret; } -esp_err_t usbh_ep_enqueue_urb(usbh_ep_handle_t ep_hdl, urb_t *urb) -{ - USBH_CHECK(ep_hdl != NULL && urb != NULL, ESP_ERR_INVALID_ARG); - USBH_CHECK(urb_check_args(urb), ESP_ERR_INVALID_ARG); - - endpoint_t *ep_obj = (endpoint_t *)ep_hdl; - - USBH_CHECK(transfer_check_usb_compliance(&(urb->transfer), - USB_EP_DESC_GET_XFERTYPE(ep_obj->constant.ep_desc), - USB_EP_DESC_GET_MPS(ep_obj->constant.ep_desc), - USB_EP_DESC_GET_EP_DIR(ep_obj->constant.ep_desc)), - ESP_ERR_INVALID_ARG); - // Check that the EP's underlying pipe is in the active state before submitting the URB - if (hcd_pipe_get_state(ep_obj->constant.pipe_hdl) != HCD_PIPE_STATE_ACTIVE) { - return ESP_ERR_INVALID_STATE; - } - // Enqueue the URB to the EP's underlying pipe - return hcd_urb_enqueue(ep_obj->constant.pipe_hdl, urb); -} - -esp_err_t usbh_ep_dequeue_urb(usbh_ep_handle_t ep_hdl, urb_t **urb_ret) -{ - USBH_CHECK(ep_hdl != NULL && urb_ret != NULL, ESP_ERR_INVALID_ARG); - - endpoint_t *ep_obj = (endpoint_t *)ep_hdl; - // Enqueue the URB to the EP's underlying pipe - *urb_ret = hcd_urb_dequeue(ep_obj->constant.pipe_hdl); - return ESP_OK; -} - esp_err_t usbh_ep_command(usbh_ep_handle_t ep_hdl, usbh_ep_cmd_t command) { USBH_CHECK(ep_hdl != NULL, ESP_ERR_INVALID_ARG); @@ -1120,155 +1460,68 @@ void *usbh_ep_get_context(usbh_ep_handle_t ep_hdl) return hcd_pipe_get_context(ep_obj->constant.pipe_hdl); } -// -------------------------------------------------- Hub Functions ---------------------------------------------------- +// ----------------------------------------------- Transfer Functions -------------------------------------------------- -// ------------------- Device Related ---------------------- - -esp_err_t usbh_hub_add_dev(hcd_port_handle_t port_hdl, usb_speed_t dev_speed, usb_device_handle_t *new_dev_hdl, hcd_pipe_handle_t *default_pipe_hdl) -{ - // Note: Parent device handle can be NULL if it's connected to the root hub - USBH_CHECK(new_dev_hdl != NULL, ESP_ERR_INVALID_ARG); - esp_err_t ret; - device_t *dev_obj; - ret = device_alloc(port_hdl, dev_speed, &dev_obj); - if (ret != ESP_OK) { - return ret; - } - // Write-back device handle - *new_dev_hdl = (usb_device_handle_t)dev_obj; - *default_pipe_hdl = dev_obj->constant.default_pipe; - ret = ESP_OK; - return ret; -} - -esp_err_t usbh_hub_dev_gone(usb_device_handle_t dev_hdl) +esp_err_t usbh_dev_submit_ctrl_urb(usb_device_handle_t dev_hdl, urb_t *urb) { - USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); + USBH_CHECK(dev_hdl != NULL && urb != NULL, ESP_ERR_INVALID_ARG); device_t *dev_obj = (device_t *)dev_hdl; - bool call_proc_req_cb; + USBH_CHECK(urb_check_args(urb), ESP_ERR_INVALID_ARG); + bool xfer_is_in = ((usb_setup_packet_t *)urb->transfer.data_buffer)->bmRequestType & USB_BM_REQUEST_TYPE_DIR_IN; + // Device descriptor could still be NULL at this point, so we get the MPS from the pipe instead. + unsigned int mps = hcd_pipe_get_mps(dev_obj->constant.default_pipe); + USBH_CHECK(transfer_check_usb_compliance(&(urb->transfer), USB_TRANSFER_TYPE_CTRL, mps, xfer_is_in), ESP_ERR_INVALID_ARG); USBH_ENTER_CRITICAL(); - dev_obj->dynamic.flags.is_gone = 1; - // Check if the device can be freed immediately - if (dev_obj->dynamic.ref_count == 0) { - // Device is not currently referenced at all. Can free immediately. - call_proc_req_cb = _dev_set_actions(dev_obj, DEV_ACTION_FREE); - } else { - // Device is still being referenced. Flush endpoints and propagate device gone event - call_proc_req_cb = _dev_set_actions(dev_obj, - DEV_ACTION_EPn_HALT_FLUSH | - DEV_ACTION_EP0_FLUSH | - DEV_ACTION_EP0_DEQUEUE | - DEV_ACTION_PROP_GONE_EVT); - } + // Increment the control transfer count first + dev_obj->dynamic.num_ctrl_xfers_inflight++; USBH_EXIT_CRITICAL(); - if (call_proc_req_cb) { - p_usbh_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_USBH, false, p_usbh_obj->constant.proc_req_cb_arg); + esp_err_t ret; + if (hcd_pipe_get_state(dev_obj->constant.default_pipe) != HCD_PIPE_STATE_ACTIVE) { + ret = ESP_ERR_INVALID_STATE; + goto hcd_err; } - return ESP_OK; -} - -// ----------------- Enumeration Related ------------------- - -esp_err_t usbh_hub_enum_fill_dev_addr(usb_device_handle_t dev_hdl, uint8_t dev_addr) -{ - USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); - device_t *dev_obj = (device_t *)dev_hdl; + ret = hcd_urb_enqueue(dev_obj->constant.default_pipe, urb); + if (ret != ESP_OK) { + goto hcd_err; + } + ret = ESP_OK; + return ret; +hcd_err: USBH_ENTER_CRITICAL(); - dev_obj->dynamic.state = USB_DEVICE_STATE_ADDRESS; + dev_obj->dynamic.num_ctrl_xfers_inflight--; USBH_EXIT_CRITICAL(); - - // We can modify the info members outside the critical section - dev_obj->constant.address = dev_addr; - return ESP_OK; + return ret; } -esp_err_t usbh_hub_enum_fill_dev_desc(usb_device_handle_t dev_hdl, const usb_device_desc_t *device_desc) +esp_err_t usbh_ep_enqueue_urb(usbh_ep_handle_t ep_hdl, urb_t *urb) { - USBH_CHECK(dev_hdl != NULL && device_desc != NULL, ESP_ERR_INVALID_ARG); - device_t *dev_obj = (device_t *)dev_hdl; - // We can modify the info members outside the critical section - memcpy((usb_device_desc_t *)dev_obj->constant.desc, device_desc, sizeof(usb_device_desc_t)); - return ESP_OK; -} + USBH_CHECK(ep_hdl != NULL && urb != NULL, ESP_ERR_INVALID_ARG); + USBH_CHECK(urb_check_args(urb), ESP_ERR_INVALID_ARG); -esp_err_t usbh_hub_enum_fill_config_desc(usb_device_handle_t dev_hdl, const usb_config_desc_t *config_desc_full) -{ - USBH_CHECK(dev_hdl != NULL && config_desc_full != NULL, ESP_ERR_INVALID_ARG); - device_t *dev_obj = (device_t *)dev_hdl; - // Allocate memory to store the configuration descriptor - usb_config_desc_t *config_desc = heap_caps_malloc(config_desc_full->wTotalLength, MALLOC_CAP_DEFAULT); // Buffer to copy over full configuration descriptor (wTotalLength) - if (config_desc == NULL) { - return ESP_ERR_NO_MEM; - } - // Copy the configuration descriptor - memcpy(config_desc, config_desc_full, config_desc_full->wTotalLength); - // Assign the config desc to the device object - assert(dev_obj->constant.config_desc == NULL); - dev_obj->constant.config_desc = config_desc; - return ESP_OK; -} + endpoint_t *ep_obj = (endpoint_t *)ep_hdl; -esp_err_t usbh_hub_enum_fill_str_desc(usb_device_handle_t dev_hdl, const usb_str_desc_t *str_desc, int select) -{ - USBH_CHECK(dev_hdl != NULL && str_desc != NULL && (select >= 0 && select < 3), ESP_ERR_INVALID_ARG); - device_t *dev_obj = (device_t *)dev_hdl; - // Allocate memory to store the manufacturer string descriptor - usb_str_desc_t *str_desc_fill = heap_caps_malloc(str_desc->bLength, MALLOC_CAP_DEFAULT); - if (str_desc_fill == NULL) { - return ESP_ERR_NO_MEM; - } - // Copy the string descriptor - memcpy(str_desc_fill, str_desc, str_desc->bLength); - // Assign filled string descriptor to the device object - switch (select) { - case 0: - assert(dev_obj->constant.str_desc_manu == NULL); - dev_obj->constant.str_desc_manu = str_desc_fill; - break; - case 1: - assert(dev_obj->constant.str_desc_product == NULL); - dev_obj->constant.str_desc_product = str_desc_fill; - break; - default: // 2 - assert(dev_obj->constant.str_desc_ser_num == NULL); - dev_obj->constant.str_desc_ser_num = str_desc_fill; - break; + USBH_CHECK(transfer_check_usb_compliance(&(urb->transfer), + USB_EP_DESC_GET_XFERTYPE(ep_obj->constant.ep_desc), + USB_EP_DESC_GET_MPS(ep_obj->constant.ep_desc), + USB_EP_DESC_GET_EP_DIR(ep_obj->constant.ep_desc)), + ESP_ERR_INVALID_ARG); + // Check that the EP's underlying pipe is in the active state before submitting the URB + if (hcd_pipe_get_state(ep_obj->constant.pipe_hdl) != HCD_PIPE_STATE_ACTIVE) { + return ESP_ERR_INVALID_STATE; } - return ESP_OK; + // Enqueue the URB to the EP's underlying pipe + return hcd_urb_enqueue(ep_obj->constant.pipe_hdl, urb); } -esp_err_t usbh_hub_enum_done(usb_device_handle_t dev_hdl) +esp_err_t usbh_ep_dequeue_urb(usbh_ep_handle_t ep_hdl, urb_t **urb_ret) { - USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); - device_t *dev_obj = (device_t *)dev_hdl; - - // We need to take the mux_lock to access mux_protected members - xSemaphoreTake(p_usbh_obj->constant.mux_lock, portMAX_DELAY); - USBH_ENTER_CRITICAL(); - dev_obj->dynamic.state = USB_DEVICE_STATE_CONFIGURED; - // Add the device to list of devices, then trigger a device event - TAILQ_INSERT_TAIL(&p_usbh_obj->dynamic.devs_idle_tailq, dev_obj, dynamic.tailq_entry); // Add it to the idle device list first - bool call_proc_req_cb = _dev_set_actions(dev_obj, DEV_ACTION_PROP_NEW_DEV); - USBH_EXIT_CRITICAL(); - p_usbh_obj->mux_protected.num_device++; - xSemaphoreGive(p_usbh_obj->constant.mux_lock); - - // Update the EP0's underlying pipe's callback - ESP_ERROR_CHECK(hcd_pipe_update_callback(dev_obj->constant.default_pipe, ep0_pipe_callback, (void *)dev_obj)); - // Call the processing request callback - if (call_proc_req_cb) { - p_usbh_obj->constant.proc_req_cb(USB_PROC_REQ_SOURCE_USBH, false, p_usbh_obj->constant.proc_req_cb_arg); - } - return ESP_OK; -} + USBH_CHECK(ep_hdl != NULL && urb_ret != NULL, ESP_ERR_INVALID_ARG); -esp_err_t usbh_hub_enum_failed(usb_device_handle_t dev_hdl) -{ - USBH_CHECK(dev_hdl != NULL, ESP_ERR_INVALID_ARG); - device_t *dev_obj = (device_t *)dev_hdl; - device_free(dev_obj); + endpoint_t *ep_obj = (endpoint_t *)ep_hdl; + // Enqueue the URB to the EP's underlying pipe + *urb_ret = hcd_urb_dequeue(ep_obj->constant.pipe_hdl); return ESP_OK; } diff --git a/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h b/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h index fc19e16b171a..c30a3a86b8b7 100644 --- a/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h +++ b/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h @@ -1,16 +1,8 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -65,9 +57,9 @@ void wifi_prov_scheme_ble_event_cb_free_bt (void *user_data, wifi_prov_cb_event * the default UUID will be used. * * @note The data being pointed to by the argument must be valid - * atleast till provisioning is started. Upon start, the + * at least till provisioning is started. Upon start, the * manager will store an internal copy of this UUID, and - * this data can be freed or invalidated afterwords. + * this data can be freed or invalidated afterwards. * * @param[in] uuid128 A custom 128 bit UUID * @@ -100,6 +92,31 @@ esp_err_t wifi_prov_scheme_ble_set_service_uuid(uint8_t *uuid128); */ esp_err_t wifi_prov_scheme_ble_set_mfg_data(uint8_t *mfg_data, ssize_t mfg_data_len); +/** + * @brief Set Bluetooth Random address + * + * This must be called before starting provisioning, i.e. before + * making a call to wifi_prov_mgr_start_provisioning(). + * + * This API can be used in cases where a new identity address is to be used during + * provisioning. This will result in this device being treated as a new device by remote + * devices. + * + * @note This API will change the existing BD address for the device. The address once + * set will remain unchanged until BLE stack tear down happens when + * wifi_prov_mgr_deinit is invoked. + * + * This API is only to be called to set random address. Re-invoking this API + * after provisioning is started will have no effect. + * + * @param[in] rand_addr The static random address to be set of length 6 bytes. + * + * @return + * - ESP_OK : Success + * - ESP_ERR_INVALID_ARG : Null argument + */ +esp_err_t wifi_prov_scheme_ble_set_random_addr(const uint8_t *rand_addr); + #ifdef __cplusplus } #endif diff --git a/components/wifi_provisioning/src/scheme_ble.c b/components/wifi_provisioning/src/scheme_ble.c index 6b594f22c46a..f1240fbaea96 100644 --- a/components/wifi_provisioning/src/scheme_ble.c +++ b/components/wifi_provisioning/src/scheme_ble.c @@ -22,7 +22,7 @@ static const char *TAG = "wifi_prov_scheme_ble"; extern const wifi_prov_scheme_t wifi_prov_scheme_ble; static uint8_t *custom_service_uuid; - +static uint8_t *custom_ble_addr; static uint8_t *custom_manufacturer_data; static size_t custom_manufacturer_data_len; @@ -59,6 +59,22 @@ static esp_err_t prov_start(protocomm_t *pc, void *config) return ESP_OK; } +esp_err_t wifi_prov_scheme_ble_set_random_addr(const uint8_t *addr) +{ + if (!addr) { + return ESP_ERR_INVALID_ARG; + } + + custom_ble_addr = (uint8_t *) malloc(BLE_ADDR_LEN); + if (custom_ble_addr == NULL) { + ESP_LOGE(TAG, "Error allocating memory for random address"); + return ESP_ERR_NO_MEM; + } + + memcpy(custom_ble_addr, addr, BLE_ADDR_LEN); + return ESP_OK; +} + esp_err_t wifi_prov_scheme_ble_set_service_uuid(uint8_t *uuid128) { if (!uuid128) { @@ -159,6 +175,12 @@ static esp_err_t set_config_service(void *config, const char *service_name, cons ble_config->manufacturer_data_len = 0; } + if (custom_ble_addr){ + ble_config->ble_addr = custom_ble_addr; + } else { + ble_config->ble_addr = NULL; + } + return ESP_OK; } diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index 9279f340dc6c..639c7bbf39ed 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -87,7 +87,7 @@ static uint8_t esp_dpp_deinit_auth(void) static void esp_dpp_call_cb(esp_supp_dpp_event_t evt, void *data) { - if (evt == ESP_SUPP_DPP_FAIL && s_dpp_ctx.dpp_auth) { + if (s_dpp_ctx.dpp_auth) { esp_dpp_deinit_auth(); } s_dpp_ctx.dpp_event_cb(evt, data); @@ -178,7 +178,7 @@ static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_d own_bi, rx_param->channel, (const u8 *)&rx_param->action_frm->u.public_action.v, dpp_data, len); os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN); - + wpa_printf(MSG_DEBUG, "DPP: Sending authentication response."); esp_dpp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg), rx_param->channel, OFFCHAN_TX_WAIT_TIME); @@ -845,7 +845,7 @@ esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb) return ESP_FAIL; } if (s_dpp_ctx.dpp_global) { - wpa_printf(MSG_ERROR, "DPP: failed to init as init already done."); + wpa_printf(MSG_ERROR, "DPP: failed to init as init already done. Please deinit first and retry."); return ESP_FAIL; } diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostpad_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostpad_wps.c index 8ee667892298..044ca46223b5 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostpad_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostpad_wps.c @@ -220,7 +220,7 @@ int esp_wifi_ap_wps_enable(const esp_wps_config_t *config) return ret; } -static int wifi_ap_wps_disable_internal(void) +int wifi_ap_wps_disable_internal(void) { struct wps_sm *sm = gWpsSm; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h index 44f8ca2cc331..248c18a62ca4 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -142,7 +142,6 @@ struct wpa_funcs { void (*wpa_config_done)(void); uint8_t *(*owe_build_dhie)(uint16_t group); int (*owe_process_assoc_resp)(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_ie, size_t dh_len); - int (*wpa_sta_set_ap_rsnxe)(const u8 *rsnxe, size_t rsnxe_ie_len); }; struct wpa2_funcs { diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c index 360eee44e689..036506278026 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c @@ -564,6 +564,7 @@ int wpa3_hostap_auth_init(void *data) &g_wpa3_hostap_task_hdl) != pdPASS) { wpa_printf(MSG_ERROR, "wpa3_hostap_auth_init: failed to create task"); os_queue_delete(g_wpa3_hostap_evt_queue); + g_wpa3_hostap_evt_queue = NULL; return ESP_FAIL; } diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index 32f8efec0e1b..7972a6c93f5d 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -33,6 +33,7 @@ #include "esp_owe_i.h" #include "esp_wps.h" +#include "esp_wps_i.h" #include "eap_server/eap.h" #include "eapol_auth/eapol_auth_sm.h" #include "ap/ieee802_1x.h" @@ -294,7 +295,6 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code) case WIFI_REASON_ASSOC_FAIL: case WIFI_REASON_CONNECTION_FAIL: case WIFI_REASON_HANDSHAKE_TIMEOUT: - esp_wpa3_free_sae_data(); wpa_sta_clear_curr_pmksa(); wpa_sm_notify_disassoc(&gWpaSm); break; @@ -304,10 +304,16 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code) } break; } + + struct wps_sm_funcs *wps_sm_cb = wps_get_wps_sm_cb(); + if (wps_sm_cb && wps_sm_cb->wps_sm_notify_deauth) { + wps_sm_cb->wps_sm_notify_deauth(); + } #ifdef CONFIG_OWE_STA owe_deinit(); #endif /* CONFIG_OWE_STA */ + esp_wpa3_free_sae_data(); supplicant_sta_disconn_handler(reason_code); } @@ -469,7 +475,6 @@ int esp_supplicant_init(void) wpa_cb->wpa_config_bss = NULL;//wpa_config_bss; wpa_cb->wpa_michael_mic_failure = wpa_michael_mic_failure; wpa_cb->wpa_config_done = wpa_config_done; - wpa_cb->wpa_sta_set_ap_rsnxe = wpa_sm_set_ap_rsnxe; esp_wifi_register_wpa3_ap_cb(wpa_cb); esp_wifi_register_wpa3_cb(wpa_cb); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index 54a01e741b4a..b68c2403c1d3 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -45,6 +45,7 @@ struct wps_rx_param { }; static STAILQ_HEAD(, wps_rx_param) s_wps_rxq; +static struct wps_sm_funcs *s_wps_sm_cb = NULL; static void *s_wps_task_hdl = NULL; static void *s_wps_queue = NULL; static void *s_wps_data_lock = NULL; @@ -839,6 +840,13 @@ int wps_finish(void) return ret; } +static void wps_sm_notify_deauth(void) +{ + if (gWpsSm && gWpsSm->wps->state != WPS_FINISHED) { + wps_stop_process(WPS_FAIL_REASON_RECV_DEAUTH); + } +} + /* Add current ap to discard ap list */ void wps_add_discard_ap(u8 *bssid) { @@ -1385,6 +1393,11 @@ int wps_init_cfg_pin(struct wps_config *cfg) return 0; } +struct wps_sm_funcs* wps_get_wps_sm_cb(void) +{ + return s_wps_sm_cb; +} + static int wifi_station_wps_init(const esp_wps_config_t *config) { struct wps_funcs *wps_cb; @@ -1466,6 +1479,12 @@ static int wifi_station_wps_init(const esp_wps_config_t *config) wps_cb->wps_start_pending = wps_start_pending; esp_wifi_set_wps_cb_internal(wps_cb); + s_wps_sm_cb = os_malloc(sizeof(struct wps_sm_funcs)); + if (s_wps_sm_cb == NULL) { + goto _err; + } + s_wps_sm_cb->wps_sm_notify_deauth = wps_sm_notify_deauth; + return ESP_OK; _err: @@ -1539,6 +1558,10 @@ wifi_station_wps_deinit(void) wps_deinit(sm->wps); sm->wps = NULL; } + if (s_wps_sm_cb) { + os_free(s_wps_sm_cb); + s_wps_sm_cb = NULL; + } os_free(gWpsSm); gWpsSm = NULL; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h index a59dc897f95e..4ffbb8b4ddfa 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h @@ -118,6 +118,11 @@ int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len); int wps_dev_deinit(struct wps_device_data *dev); int wps_dev_init(void); int wps_set_factory_info(const esp_wps_config_t *config); +struct wps_sm_funcs { + void (*wps_sm_notify_deauth)(void); +}; + +struct wps_sm_funcs* wps_get_wps_sm_cb(void); static inline int wps_get_type(void) { diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 24def3358445..513ec9fa8220 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -2620,21 +2620,6 @@ bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, return true; } -#ifdef CONFIG_WPS_REGISTRAR -static void ap_free_sta_timeout(void *ctx, void *data) -{ - struct hostapd_data *hapd = (struct hostapd_data *) ctx; - u8 *addr = (u8 *) data; - struct sta_info *sta = ap_get_sta(hapd, addr); - - if (sta) { - ap_free_sta(hapd, sta); - } - - os_free(addr); -} -#endif - bool wpa_ap_remove(u8* bssid) { struct hostapd_data *hapd = hostapd_get_hapd_data(); @@ -2657,19 +2642,6 @@ bool wpa_ap_remove(u8* bssid) return true; } #endif /* CONFIG_SAE */ - -#ifdef CONFIG_WPS_REGISTRAR - wpa_printf(MSG_DEBUG, "wps_status=%d", wps_get_status()); - if (wps_get_status() == WPS_STATUS_PENDING) { - u8 *addr = os_malloc(ETH_ALEN); - - if (!addr) { - return false; - } - os_memcpy(addr, sta->addr, ETH_ALEN); - eloop_register_timeout(0, 10000, ap_free_sta_timeout, hapd, addr); - } else -#endif ap_free_sta(hapd, sta); return true; diff --git a/components/wpa_supplicant/src/crypto/crypto_ops.c b/components/wpa_supplicant/src/crypto/crypto_ops.c index 17c052c986b7..7b3f31a148be 100644 --- a/components/wpa_supplicant/src/crypto/crypto_ops.c +++ b/components/wpa_supplicant/src/crypto/crypto_ops.c @@ -43,7 +43,7 @@ static int esp_aes_gmac(const u8 *key, size_t key_len, const u8 *iv, size_t iv_l #if CONFIG_GMAC return aes_gmac(key, key_len, iv, iv_len, aad, aad_len, tag); #else - return 0; + return -1; #endif } diff --git a/components/wpa_supplicant/src/eap_server/eap_server_wsc.c b/components/wpa_supplicant/src/eap_server/eap_server_wsc.c index f3c4756257f2..653480efcc18 100644 --- a/components/wpa_supplicant/src/eap_server/eap_server_wsc.c +++ b/components/wpa_supplicant/src/eap_server/eap_server_wsc.c @@ -103,6 +103,13 @@ static void eap_wsc_reset(struct eap_sm *sm, void *priv) wpabuf_free(data->out_buf); //wps_deinit(data->wps); os_free(data); +#ifdef ESP_SUPPLICANT + /* TODO: When wps-registrar is shifted in a separate task other than wifi task, + * call esp_wifi_ap_wps_disable() here instead of wifi_ap_wps_disable_internal() + * */ + extern int wifi_ap_wps_disable_internal(void); + wifi_ap_wps_disable_internal(); +#endif } diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index df5448077d3e..aef17fc9c0db 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -2434,6 +2434,11 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, if (res < 0) return -1; sm->assoc_wpa_ie_len = res; + + const u8 *rsnxe; + rsnxe = esp_wifi_sta_get_rsnxe((u8*)bssid); + wpa_sm_set_ap_rsnxe(rsnxe, rsnxe ? (rsnxe[1] + 2) : 0); + res = wpa_gen_rsnxe(sm, assoc_rsnxe, assoc_rsnxe_len); if (res < 0) return -1; @@ -2863,7 +2868,8 @@ int owe_process_assoc_resp(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_i struct wpa_sm *sm; sm = get_wpa_sm(); - wpabuf_free(sm->owe_ie); //free the dh ie constructed in owe_build_assoc_req + /* Deallocate the dh ie buffer constructed in owe_build_assoc_req */ + wpabuf_free(sm->owe_ie); sm->owe_ie = NULL; struct wpa_ie_data *parsed_rsn_data; @@ -2877,121 +2883,129 @@ int owe_process_assoc_resp(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_i goto fail; } + if (!dh_ie && parsed_rsn_data->num_pmkid == 0) { + wpa_printf(MSG_ERROR, "OWE: Assoc response should either have pmkid or DH IE"); + goto fail; + } + + /* Check for PMK caching */ + if (sm->cur_pmksa && parsed_rsn_data && parsed_rsn_data->num_pmkid == 1 && parsed_rsn_data->pmkid) { + if (os_memcmp(parsed_rsn_data->pmkid, sm->cur_pmksa->pmkid, OWE_PMKID_LEN) == 0) { + wpa_printf(MSG_DEBUG, "OWE: Using PMK caching"); + wpa_sm_set_pmk_from_pmksa(sm); + goto done; + } else { + /* If PMKID mismatches, derive keys again */ + wpa_printf(MSG_DEBUG, "OWE : Invalid PMKID in response"); + } + } + + if (dh_ie == NULL) { + wpa_printf(MSG_ERROR, "OWE: No Diffie Hellman IE in association response"); + goto fail; + } if (dh_ie && MIN_DH_LEN(dh_len)) { wpa_printf(MSG_ERROR, "OWE: Invalid Diffie Hellman IE"); goto fail; } - if (!dh_ie && parsed_rsn_data->num_pmkid == 0) { - wpa_printf(MSG_ERROR, "OWE: Assoc response should either have pmkid or DH IE"); + + /* If STA or AP does not have PMKID, or PMKID mismatches, proceed with normal association */ + dh_len += 2; + + dh_ie += 3; + dh_len -=3; + group = WPA_GET_LE16(dh_ie); + + /* Only group 19 is supported */ + if ((group != sm->owe_group) || (group != OWE_DH_GRP19)) { + wpa_printf(MSG_ERROR, "OWE: Unexpected Diffie-Hellman group in response"); goto fail; } - if (!sm->cur_pmksa) { /* No PMK caching */ - if (dh_ie == NULL) { - goto fail; - } - dh_len += 2; + prime_len = OWE_PRIME_LEN; - dh_ie += 3; - dh_len -=3; - group = WPA_GET_LE16(dh_ie); + /* Set peer's public key point and calculate shared secret */ + sh_secret = crypto_ecdh_set_peerkey(sm->owe_ecdh, 0, dh_ie+2, dh_len-2); + sh_secret = wpabuf_zeropad(sh_secret, prime_len); + if (!sh_secret) { + wpa_printf(MSG_ERROR, "OWE: Invalid peer DH public key"); + goto fail; + } - /* Only group 19 is supported */ - if ((group != sm->owe_group) || (group != OWE_DH_GRP19)) { - wpa_printf(MSG_ERROR, "OWE: Unexpected Diffie-Hellman group in response"); - goto fail; - } + wpa_hexdump_buf_key(MSG_DEBUG, "OWE: DH shared secret", sh_secret); + pub = crypto_ecdh_get_pubkey(sm->owe_ecdh, 0); + if (!pub) { + wpa_printf(MSG_ERROR, "No own public key"); + goto fail; + } - prime_len = OWE_PRIME_LEN; + /* PMKID = Truncate-128(Hash(C | A)) */ + addr[0] = wpabuf_head(pub); + len[0] = wpabuf_len(pub); + addr[1] = dh_ie + 2; + len[1] = dh_len - 2; - /* Set peer's public key point and calculate shared secret */ - sh_secret = crypto_ecdh_set_peerkey(sm->owe_ecdh, 0, dh_ie+2, dh_len-2); - sh_secret = wpabuf_zeropad(sh_secret, prime_len); - if (!sh_secret) { - wpa_printf(MSG_ERROR, "OWE: Invalid peer DH public key"); - goto fail; - } + int res = sha256_vector(2, addr, len, pmkid); + if (res < 0 ) { + goto fail; + } - wpa_hexdump_buf_key(MSG_DEBUG, "OWE: DH shared secret", sh_secret); - pub = crypto_ecdh_get_pubkey(sm->owe_ecdh, 0); - if (!pub) { - wpa_printf(MSG_ERROR, "No own public key"); - wpabuf_free(sh_secret); - goto fail; - } + hash_len = SHA256_MAC_LEN; - /* PMKID = Truncate-128(Hash(C | A)) */ - addr[0] = wpabuf_head(pub); - len[0] = wpabuf_len(pub); - addr[1] = dh_ie + 2; - len[1] = dh_len - 2; + pub = wpabuf_zeropad(pub, prime_len); + if (!pub) { + goto fail; + } - int res = sha256_vector(2, addr, len, pmkid); - if (res < 0 ) { - goto fail; - } + /* prk = HKDF-extract(C | A | group, z) */ + hkey = wpabuf_alloc(wpabuf_len(pub) + dh_len - 2 + 2); + if (!hkey) { + goto fail; + } - hash_len = SHA256_MAC_LEN; + wpabuf_put_buf(hkey, pub); /* C */ + wpabuf_free(pub); - pub = wpabuf_zeropad(pub, prime_len); + wpabuf_put_data(hkey, dh_ie + 2, dh_len - 2); /* A */ + wpabuf_put_le16(hkey, sm->owe_group); /* group */ - /* prk = HKDF-extract(C | A | group, z) */ - hkey = wpabuf_alloc(wpabuf_len(pub) + dh_len - 2 + 2); + res = hmac_sha256(wpabuf_head(hkey), wpabuf_len(hkey), wpabuf_head(sh_secret), wpabuf_len(sh_secret), prk); + if (res < 0 ) { + goto fail; + } - wpabuf_put_buf(hkey, pub); /* C */ - wpabuf_free(pub); + hash_len = SHA256_MAC_LEN; - wpabuf_put_data(hkey, dh_ie + 2, dh_len - 2); /* A */ - wpabuf_put_le16(hkey, sm->owe_group); /* group */ + wpabuf_free(hkey); + wpabuf_clear_free(sh_secret); - res = hmac_sha256(wpabuf_head(hkey), wpabuf_len(hkey), wpabuf_head(sh_secret), wpabuf_len(sh_secret), prk); - if (res < 0 ) { - goto fail; - } + wpa_hexdump_key(MSG_DEBUG, "OWE: prk", prk, hash_len); - hash_len = SHA256_MAC_LEN; + /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */ + res = hmac_sha256_kdf(prk, hash_len, NULL, (const u8 *)info, + os_strlen(info), pmk, hash_len); + if (res < 0 ) { + goto fail; + } - wpabuf_free(hkey); - wpabuf_free(sh_secret); + forced_memzero(prk, SHA256_MAC_LEN); + wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, OWE_PMKID_LEN); - wpa_hexdump_key(MSG_DEBUG, "OWE: prk", prk, hash_len); + os_memcpy(sm->pmk,pmk,hash_len); + sm->pmk_len = hash_len; + wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sm->pmk, sm->pmk_len); - /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */ - res = hmac_sha256_kdf(prk, hash_len, NULL, (const u8 *)info, - os_strlen(info), pmk, hash_len); - if (res < 0 ) { - goto fail; - } + pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, pmkid, NULL, 0, + sm->bssid, sm->own_addr, sm->network_ctx, sm->key_mgmt); - forced_memzero(prk, SHA256_MAC_LEN); - wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, OWE_PMKID_LEN); - - os_memcpy(sm->pmk,pmk,hash_len); - sm->pmk_len = hash_len; - wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sm->pmk, sm->pmk_len); - - pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, pmkid, NULL, 0, - sm->bssid, sm->own_addr, sm->network_ctx, sm->key_mgmt); - goto done; - } else { /* PMK caching */ - if (parsed_rsn_data && sm->cur_pmksa) { - if (parsed_rsn_data->num_pmkid == 1 && parsed_rsn_data->pmkid) { - if (os_memcmp(parsed_rsn_data->pmkid, sm->cur_pmksa->pmkid, OWE_PMKID_LEN) == 0) { - wpa_printf(MSG_DEBUG, "OWE: Using PMK caching"); - wpa_sm_set_pmk_from_pmksa(sm); - goto done; - } else { - wpa_printf(MSG_DEBUG, "OWE : Invalid PMKID in response"); - goto fail; - } - } - } - } done: os_free(parsed_rsn_data); return 0; fail: os_free(parsed_rsn_data); + wpabuf_free(pub); + wpabuf_free(hkey); + wpabuf_clear_free(sh_secret); return -1; } #endif // CONFIG_OWE_STA diff --git a/components/wpa_supplicant/test_apps/main/test_crypto.c b/components/wpa_supplicant/test_apps/main/test_crypto.c index 42fefce80382..23f14b8da52d 100644 --- a/components/wpa_supplicant/test_apps/main/test_crypto.c +++ b/components/wpa_supplicant/test_apps/main/test_crypto.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,7 +37,6 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]") bn = crypto_bignum_init_set(buf, 32); TEST_ASSERT_NOT_NULL(bn); - TEST_ASSERT(crypto_bignum_to_bin(bn, buf2, 32, 0) == 32); TEST_ASSERT(!memcmp(buf, buf2, 32)); @@ -245,7 +244,6 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]") uint8_t buf1[32], buf2[32]; crypto_bignum *bn1, *bn2; - buf1[0] = 0xf; buf2[0] = 0x11; @@ -277,7 +275,6 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]") } } - /* * Conversion macros for embedded constants: * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2 @@ -322,30 +319,29 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]") * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint) * Allocate a new memory as well so that it can be freed. */ -static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len ) +static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len) { X->MBEDTLS_PRIVATE(s) = 1; - X->MBEDTLS_PRIVATE(n) = len / sizeof( mbedtls_mpi_uint ); + X->MBEDTLS_PRIVATE(n) = len / sizeof(mbedtls_mpi_uint); X->MBEDTLS_PRIVATE(p) = os_zalloc(len); memcpy(X->MBEDTLS_PRIVATE(p), (void *)p, len); } - TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") { - set_leak_threshold(600); + set_leak_threshold(620); static const mbedtls_mpi_uint secp256r1_gx[] = { - BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ), - BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ), - BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ), - BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ), + BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4), + BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77), + BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8), + BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B), }; static const mbedtls_mpi_uint secp256r1_gy[] = { - BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ), - BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ), - BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ), - BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ), + BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB), + BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B), + BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E), + BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F), }; { @@ -393,8 +389,8 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") TEST_ASSERT_NOT_NULL(q); TEST_ASSERT_NOT_NULL(r); - mbedtls_mpi_init( &num ); - mbedtls_mpi_lset( &num, 3 ); + mbedtls_mpi_init(&num); + mbedtls_mpi_lset(&num, 3); ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx)); ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy)); @@ -408,7 +404,7 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") TEST_ASSERT(crypto_ec_point_cmp(e, q, r) == 0); - mbedtls_mpi_free( &num ); + mbedtls_mpi_free(&num); crypto_ec_point_deinit(p, 1); crypto_ec_point_deinit(q, 1); crypto_ec_point_deinit(r, 1); @@ -432,8 +428,8 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") TEST_ASSERT_NOT_NULL(q); TEST_ASSERT_NOT_NULL(r); - mbedtls_mpi_init( &num ); - mbedtls_mpi_lset( &num, 100 ); + mbedtls_mpi_init(&num); + mbedtls_mpi_lset(&num, 100); ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx)); ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy)); @@ -448,7 +444,7 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") TEST_ASSERT(crypto_ec_point_is_at_infinity(e, r)); - mbedtls_mpi_free( &num ); + mbedtls_mpi_free(&num); crypto_ec_point_deinit(p, 1); crypto_ec_point_deinit(q, 1); crypto_ec_point_deinit(r, 1); @@ -468,8 +464,8 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") TEST_ASSERT_NOT_NULL(p); TEST_ASSERT_NOT_NULL(q); - mbedtls_mpi_init( &num ); - mbedtls_mpi_lset( &num, 50 ); + mbedtls_mpi_init(&num); + mbedtls_mpi_lset(&num, 50); ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx)); ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy)); @@ -483,8 +479,7 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") TEST_ASSERT(crypto_ec_point_mul(e, p, (crypto_bignum *) &num, q) == 0); TEST_ASSERT(crypto_ec_point_is_on_curve(e, q)); - - mbedtls_mpi_free( &num ); + mbedtls_mpi_free(&num); crypto_ec_point_deinit(p, 1); crypto_ec_point_deinit(q, 1); crypto_ec_deinit(e); @@ -506,8 +501,8 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") TEST_ASSERT_NOT_NULL(q); TEST_ASSERT_NOT_NULL(r); - mbedtls_mpi_init( &num ); - mbedtls_mpi_lset( &num, 50 ); + mbedtls_mpi_init(&num); + mbedtls_mpi_lset(&num, 50); ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx)); ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy)); @@ -532,7 +527,7 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") TEST_ASSERT(crypto_ec_point_add(e, q, r, r) == 0); TEST_ASSERT(crypto_ec_point_is_at_infinity(e, r)); - mbedtls_mpi_free( &num ); + mbedtls_mpi_free(&num); crypto_ec_point_deinit(p, 1); crypto_ec_point_deinit(q, 1); crypto_ec_point_deinit(r, 1); diff --git a/conftest.py b/conftest.py index 17c5f11549cc..1fac842312a4 100644 --- a/conftest.py +++ b/conftest.py @@ -25,7 +25,7 @@ import typing as t import zipfile from copy import deepcopy -from datetime import datetime +from urllib.parse import quote import common_test_methods # noqa: F401 import gitlab_api @@ -39,7 +39,8 @@ from idf_ci.app import import_apps_from_txt from idf_ci.uploader import AppDownloader, AppUploader from idf_ci_utils import IDF_PATH, idf_relpath -from idf_pytest.constants import DEFAULT_SDKCONFIG, ENV_MARKERS, SPECIAL_MARKERS, TARGET_MARKERS, PytestCase +from idf_pytest.constants import DEFAULT_SDKCONFIG, ENV_MARKERS, SPECIAL_MARKERS, TARGET_MARKERS, PytestCase, \ + DEFAULT_LOGDIR from idf_pytest.plugin import IDF_PYTEST_EMBEDDED_KEY, ITEM_PYTEST_CASE_KEY, IdfPytestEmbedded from idf_pytest.utils import format_case_id from pytest_embedded.plugin import multi_dut_argument, multi_dut_fixture @@ -55,15 +56,10 @@ def idf_path() -> str: return os.path.dirname(__file__) -@pytest.fixture(scope='session', autouse=True) -def session_tempdir() -> str: - _tmpdir = os.path.join( - os.path.dirname(__file__), - 'pytest_embedded_log', - datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), - ) - os.makedirs(_tmpdir, exist_ok=True) - return _tmpdir +@pytest.fixture(scope='session') +def session_root_logdir(idf_path: str) -> str: + """Session scoped log dir for pytest-embedded""" + return idf_path @pytest.fixture @@ -465,11 +461,12 @@ def pytest_runtest_makereport(item, call): # type: ignore job_id = os.getenv('CI_JOB_ID', 0) url = os.getenv('CI_PAGES_URL', '').replace('esp-idf', '-/esp-idf') - template = f'{url}/-/jobs/{job_id}/artifacts/pytest_embedded_log/{{}}' + template = f'{url}/-/jobs/{job_id}/artifacts/{DEFAULT_LOGDIR}/{{}}' logs_files = [] def get_path(x: str) -> str: - return x.split('pytest_embedded_log/', 1)[1] + return x.split(f'{DEFAULT_LOGDIR}/', 1)[1] + if isinstance(_dut, list): logs_files.extend([template.format(get_path(d.logfile)) for d in _dut]) dut_artifacts_url.append('{}:'.format(_dut[0].test_case_name)) @@ -478,7 +475,7 @@ def get_path(x: str) -> str: dut_artifacts_url.append('{}:'.format(_dut.test_case_name)) for file in logs_files: - dut_artifacts_url.append(' - {}'.format(file)) + dut_artifacts_url.append(' - {}'.format(quote(file, safe=':/'))) def pytest_terminal_summary(terminalreporter, exitstatus, config): # type: ignore diff --git a/docs/_static/diagrams/cap_touch_sens/touch_file_structure.svg b/docs/_static/diagrams/cap_touch_sens/touch_file_structure.svg new file mode 100644 index 000000000000..8d1abf0dd2f0 --- /dev/null +++ b/docs/_static/diagrams/cap_touch_sens/touch_file_structure.svg @@ -0,0 +1,4 @@ + + + +
touch_sens.h
touch_sens.h
touch_sens_types.h
touch_sens_types.h
touch_version_types.h
touch_version_types.h
touch_sensor_ll.h
touch_sensor_ll.h
touch_sensor_hal.h
touch_sensor_hal.h
touch_sensor_hal.c
touch_sensor_hal.c
touch_sensor_types.h
touch_sensor_types.h
touch_sens_common.c
touch_sens_common.c
touch_sens_private.h
touch_sens_private.h
touch_sens_v1.c
touch_sens_v1.c
Capacitive Touch Sensor Application
Capacitive Touch Sensor Application
components / esp_driver_touch_sens
components / esp_driver_touch_sens
components / hal
components / hal
public header
public header
private header
private header
source file
source file
includes
includes
Legend
Legend
touch_sens_v2.c
touch_sens_v2.c
touch_sens_v3.c
touch_sens_v3.c
touch_version_types.h
touch_version_types.h
touch_version_types.h
touch_version_types.h
Text is not SVG - cannot display
diff --git a/docs/_static/diagrams/cap_touch_sens/touch_state_machine.svg b/docs/_static/diagrams/cap_touch_sens/touch_state_machine.svg new file mode 100644 index 000000000000..2f4eecf8d931 --- /dev/null +++ b/docs/_static/diagrams/cap_touch_sens/touch_state_machine.svg @@ -0,0 +1,4 @@ + + + +
BEGIN
BEGIN
touch_sensor_new_controller
touch_sensor_new_controller
touch_sensor_new_channel
touch_sensor_new_channel
INIT
INIT
READY
READY
SCAN
SCAN
<other_configurations>
<other_configurations>
touch_sensor_enable
touch_sensor_enable
touch_sensor_disable
touch_sensor_disable
touch_sensor_start_continuous_scanning
touch_sensor_start_continuous_scanning
touch_sensor_stop_continuous_scanning
touch_sensor_stop_continuous_scanning
touch_sensor_trigger_oneshot_sacnning
touch_sensor_trigger_oneshot_sacnning
All channels scanned?
All channels scanned?
touch_sensor_del_channel
touch_sensor_del_channel
touch_sensor_del_controller
touch_sensor_del_controller
END
END
Y
Y
N
N
Text is not SVG - cannot display
diff --git a/docs/_static/diagrams/ppa/pic_blk_concept.png b/docs/_static/diagrams/ppa/pic_blk_concept.png new file mode 100644 index 000000000000..21eadd08264d Binary files /dev/null and b/docs/_static/diagrams/ppa/pic_blk_concept.png differ diff --git a/docs/_static/esp32-c3-devkitc-02-v1-annotated-photo.png b/docs/_static/esp32-c3-devkitc-02-v1-annotated-photo.png deleted file mode 100644 index 5b05cc38b4a8..000000000000 Binary files a/docs/_static/esp32-c3-devkitc-02-v1-annotated-photo.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitc-02-v1-block-diags.png b/docs/_static/esp32-c3-devkitc-02-v1-block-diags.png deleted file mode 100644 index d45410221b5f..000000000000 Binary files a/docs/_static/esp32-c3-devkitc-02-v1-block-diags.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitc-02-v1-isometric.png b/docs/_static/esp32-c3-devkitc-02-v1-isometric.png deleted file mode 100644 index 24636265821f..000000000000 Binary files a/docs/_static/esp32-c3-devkitc-02-v1-isometric.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitc-02-v1-pinout.png b/docs/_static/esp32-c3-devkitc-02-v1-pinout.png deleted file mode 100644 index ca1a40782f6d..000000000000 Binary files a/docs/_static/esp32-c3-devkitc-02-v1-pinout.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitm-1-v1-annotated-photo.png b/docs/_static/esp32-c3-devkitm-1-v1-annotated-photo.png deleted file mode 100644 index 1f8b081d5e00..000000000000 Binary files a/docs/_static/esp32-c3-devkitm-1-v1-annotated-photo.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitm-1-v1-block-diagram.png b/docs/_static/esp32-c3-devkitm-1-v1-block-diagram.png deleted file mode 100644 index 29c14e0a0b02..000000000000 Binary files a/docs/_static/esp32-c3-devkitm-1-v1-block-diagram.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitm-1-v1-isometric.png b/docs/_static/esp32-c3-devkitm-1-v1-isometric.png deleted file mode 100644 index 69667b511fd5..000000000000 Binary files a/docs/_static/esp32-c3-devkitm-1-v1-isometric.png and /dev/null differ diff --git a/docs/_static/esp32-c3-devkitm-1-v1-pinout.png b/docs/_static/esp32-c3-devkitm-1-v1-pinout.png deleted file mode 100644 index e2022e34dcae..000000000000 Binary files a/docs/_static/esp32-c3-devkitm-1-v1-pinout.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitc-1-v1-annotated-photo.png b/docs/_static/esp32-s2-devkitc-1-v1-annotated-photo.png deleted file mode 100644 index 1b33bf478796..000000000000 Binary files a/docs/_static/esp32-s2-devkitc-1-v1-annotated-photo.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitc-1-v1-block-diags.png b/docs/_static/esp32-s2-devkitc-1-v1-block-diags.png deleted file mode 100644 index a19c87eddcbe..000000000000 Binary files a/docs/_static/esp32-s2-devkitc-1-v1-block-diags.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitc-1-v1-isometric.png b/docs/_static/esp32-s2-devkitc-1-v1-isometric.png deleted file mode 100644 index 7c57f1cfd200..000000000000 Binary files a/docs/_static/esp32-s2-devkitc-1-v1-isometric.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitc-1-v1-pinout.png b/docs/_static/esp32-s2-devkitc-1-v1-pinout.png deleted file mode 100644 index 2bf7f57b8883..000000000000 Binary files a/docs/_static/esp32-s2-devkitc-1-v1-pinout.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitm-1-v1-annotated-photo.png b/docs/_static/esp32-s2-devkitm-1-v1-annotated-photo.png deleted file mode 100644 index 7da28ae22572..000000000000 Binary files a/docs/_static/esp32-s2-devkitm-1-v1-annotated-photo.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitm-1-v1-block-diagram.png b/docs/_static/esp32-s2-devkitm-1-v1-block-diagram.png deleted file mode 100644 index 5cdeade38270..000000000000 Binary files a/docs/_static/esp32-s2-devkitm-1-v1-block-diagram.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitm-1-v1-isometric.png b/docs/_static/esp32-s2-devkitm-1-v1-isometric.png deleted file mode 100644 index 4b53ee2ffec4..000000000000 Binary files a/docs/_static/esp32-s2-devkitm-1-v1-isometric.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitm-1-v1-pin-layout.png b/docs/_static/esp32-s2-devkitm-1-v1-pin-layout.png deleted file mode 100644 index 7b24a546d340..000000000000 Binary files a/docs/_static/esp32-s2-devkitm-1-v1-pin-layout.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitm-1u-v1-annotated-photo.png b/docs/_static/esp32-s2-devkitm-1u-v1-annotated-photo.png deleted file mode 100644 index 3cb77d6ae02d..000000000000 Binary files a/docs/_static/esp32-s2-devkitm-1u-v1-annotated-photo.png and /dev/null differ diff --git a/docs/_static/esp32-s2-devkitm-1u-v1-isometric.png b/docs/_static/esp32-s2-devkitm-1u-v1-isometric.png deleted file mode 100644 index 97d02020fe98..000000000000 Binary files a/docs/_static/esp32-s2-devkitm-1u-v1-isometric.png and /dev/null differ diff --git a/docs/_static/itwt_10s_current.png b/docs/_static/itwt_10s_current.png new file mode 100644 index 000000000000..bfd315c042e4 Binary files /dev/null and b/docs/_static/itwt_10s_current.png differ diff --git a/docs/_static/itwt_30s_current.png b/docs/_static/itwt_30s_current.png new file mode 100644 index 000000000000..7b8890149f40 Binary files /dev/null and b/docs/_static/itwt_30s_current.png differ diff --git a/docs/_static/itwt_setup.png b/docs/_static/itwt_setup.png new file mode 100644 index 000000000000..0aa68878e1b2 Binary files /dev/null and b/docs/_static/itwt_setup.png differ diff --git a/docs/_static/itwt_suspend.png b/docs/_static/itwt_suspend.png new file mode 100644 index 000000000000..c49403313e32 Binary files /dev/null and b/docs/_static/itwt_suspend.png differ diff --git a/docs/_static/itwt_teardown.png b/docs/_static/itwt_teardown.png new file mode 100644 index 000000000000..c3c6805e32ba Binary files /dev/null and b/docs/_static/itwt_teardown.png differ diff --git a/docs/component_info_ignore_file.txt b/docs/component_info_ignore_file.txt index 32bb50d4eb7f..fd09655d2170 100644 --- a/docs/component_info_ignore_file.txt +++ b/docs/component_info_ignore_file.txt @@ -6,6 +6,8 @@ components/ulp/lp_core/lp_core/include/ulp_lp_core_i2c.h components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h components/ulp/lp_core/lp_core/include/ulp_lp_core_uart.h components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h +components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h +components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h # ESSL headers do not belong to any IDF component, in a user project it will come from a managed component components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_spi.h diff --git a/docs/conf_common.py b/docs/conf_common.py index 812210c89c26..7c8d64663b01 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -108,8 +108,6 @@ TEMP_SENSOR_DOCS = ['api-reference/peripherals/temp_sensor.rst'] -TOUCH_SENSOR_DOCS = ['api-reference/peripherals/touch_pad.rst'] - SPIRAM_DOCS = ['api-guides/external-ram.rst'] USB_DOCS = ['api-reference/peripherals/usb_device.rst', @@ -117,7 +115,8 @@ 'api-reference/peripherals/usb_host/usb_host_notes_arch.rst', 'api-reference/peripherals/usb_host/usb_host_notes_design.rst', 'api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst', - 'api-reference/peripherals/usb_host/usb_host_notes_index.rst'] + 'api-reference/peripherals/usb_host/usb_host_notes_index.rst', + 'api-reference/peripherals/usb_host/usb_host_notes_usbh.rst'] I80_LCD_DOCS = ['api-reference/peripherals/lcd/i80_lcd.rst'] RGB_LCD_DOCS = ['api-reference/peripherals/lcd/rgb_lcd.rst'] @@ -175,6 +174,8 @@ JPEG_DOCS = ['api-reference/peripherals/jpeg.rst'] +PPA_DOCS = ['api-reference/peripherals/ppa.rst'] + QEMU_DOCS = ['api-guides/tools/qemu.rst'] ESP32_DOCS = ['api-reference/system/himem.rst', @@ -183,6 +184,7 @@ 'security/secure-boot-v1.rst', 'api-reference/peripherals/dac.rst', 'api-reference/peripherals/sd_pullup_requirements.rst', + 'api-reference/peripherals/touch_pad.rst', 'hw-reference/esp32/**', 'api-guides/RF_calibration.rst', 'api-guides/phy.rst'] + FTDI_JTAG_DOCS + QEMU_DOCS @@ -192,6 +194,7 @@ 'api-reference/peripherals/ds.rst', 'api-reference/peripherals/temp_sensor.rst', 'api-reference/system/async_memcpy.rst', + 'api-reference/peripherals/touch_pad.rst', 'api-reference/peripherals/touch_element.rst', 'api-guides/RF_calibration.rst', 'api-guides/phy.rst'] + FTDI_JTAG_DOCS + USB_OTG_DFU_DOCS + USB_OTG_CONSOLE_DOCS @@ -199,6 +202,7 @@ ESP32S3_DOCS = ['hw-reference/esp32s3/**', 'api-reference/system/ipc.rst', 'api-guides/flash_psram_config.rst', + 'api-reference/peripherals/touch_pad.rst', 'api-reference/peripherals/sd_pullup_requirements.rst', 'api-guides/RF_calibration.rst', 'api-guides/phy.rst'] + USB_OTG_DFU_DOCS + USB_OTG_CONSOLE_DOCS @@ -221,6 +225,7 @@ 'api-guides/phy.rst'] ESP32P4_DOCS = ['api-reference/system/ipc.rst', + 'api-reference/peripherals/cap_touch_sens.rst', 'api-reference/peripherals/sd_pullup_requirements.rst'] # format: {tag needed to include: documents to included}, tags are parsed from sdkconfig and peripheral_caps.h headers @@ -251,7 +256,6 @@ 'SOC_RMT_SUPPORTED':RMT_DOCS, 'SOC_DAC_SUPPORTED':DAC_DOCS, 'SOC_ETM_SUPPORTED':ETM_DOCS, - 'SOC_TOUCH_SENSOR_SUPPORTED':TOUCH_SENSOR_DOCS, 'SOC_ULP_FSM_SUPPORTED':ULP_FSM_DOCS, 'SOC_RISCV_COPROC_SUPPORTED':RISCV_COPROC_DOCS, 'SOC_LP_CORE_SUPPORTED':LP_CORE_DOCS, @@ -277,6 +281,7 @@ 'SOC_SPI_SUPPORT_SLAVE_HD_VER2':SPI_SLAVE_HD_DOCS, 'SOC_WIFI_NAN_SUPPORT':NAN_DOCS, 'SOC_JPEG_CODEC_SUPPORTED':JPEG_DOCS, + 'SOC_PPA_SUPPORTED':PPA_DOCS, 'SOC_GP_LDO_SUPPORTED':LDO_DOCS, 'esp32':ESP32_DOCS, 'esp32s2':ESP32S2_DOCS, diff --git a/docs/docs_not_updated/esp32c5.txt b/docs/docs_not_updated/esp32c5.txt index 326cbc716c58..4f10ca5edf2e 100644 --- a/docs/docs_not_updated/esp32c5.txt +++ b/docs/docs_not_updated/esp32c5.txt @@ -7,10 +7,6 @@ contribute/copyright-guide.rst contribute/install-pre-commit-hook.rst contribute/index.rst api-guides/core_dump_internals.rst -api-guides/performance/speed.rst -api-guides/performance/size.rst -api-guides/performance/ram-usage.rst -api-guides/performance/index.rst api-guides/jtag-debugging/debugging-examples.rst api-guides/jtag-debugging/configure-ft2232h-jtag.rst api-guides/jtag-debugging/tips-and-quirks.rst @@ -21,10 +17,7 @@ api-guides/jtag-debugging/configure-other-jtag.rst api-guides/jtag-debugging/building-openocd-windows.rst api-guides/jtag-debugging/index.rst api-guides/jtag-debugging/configure-builtin-jtag.rst -api-guides/partition-tables.rst api-guides/app_trace.rst -api-guides/thread-local-storage.rst -api-guides/error-handling.rst api-guides/tools/idf-tools.rst api-guides/tools/idf-clang-tidy.rst api-guides/tools/idf-component-manager.rst @@ -35,29 +28,19 @@ api-guides/tools/idf-monitor.rst api-guides/tools/idf-docker-image.rst api-guides/tools/index.rst api-guides/low-power-mode.rst -api-guides/startup.rst -api-guides/hlinterrupts.rst api-guides/RF_calibration.rst -api-guides/unit-tests.rst api-guides/deep-sleep-stub.rst api-guides/blufi.rst api-guides/lwip.rst api-guides/coexist.rst -api-guides/flash_psram_config.rst api-guides/usb-serial-jtag-console.rst -api-guides/linker-script-generation.rst api-guides/wifi.rst api-guides/usb-otg-console.rst api-guides/bluetooth.rst api-guides/wireshark-user-guide.rst -api-guides/bootloader.rst api-guides/esp-wifi-mesh.rst -api-guides/cplusplus.rst -api-guides/build-system.rst api-guides/core_dump.rst api-guides/inc/external-ram-esp32-notes.rst -api-guides/inc/linux-host-requirements.rst -api-guides/c.rst api-guides/dfu.rst api-guides/current-consumption-measurement-modules.rst api-guides/esp-ble-mesh/ble-mesh-index.rst @@ -66,15 +49,8 @@ api-guides/esp-ble-mesh/ble-mesh-terminology.rst api-guides/esp-ble-mesh/ble-mesh-architecture.rst api-guides/esp-ble-mesh/ble-mesh-faq.rst api-guides/external-ram.rst -api-guides/reproducible-builds.rst -api-guides/hardware-abstraction.rst api-guides/wifi-security.rst -api-guides/host-apps.rst -api-guides/index.rst api-guides/openthread.rst -api-guides/fatal-errors.rst -api-guides/memory-types.rst -api-guides/general-notes.rst third-party-tools/platformio.rst third-party-tools/clion.rst third-party-tools/visualgdb.rst @@ -83,7 +59,6 @@ libraries-and-frameworks/libs-frameworks.rst libraries-and-frameworks/index.rst libraries-and-frameworks/cloud-frameworks.rst versions.rst -api-reference/api-conventions.rst api-reference/template.rst api-reference/provisioning/protocomm.rst api-reference/provisioning/provisioning.rst @@ -111,9 +86,9 @@ api-reference/peripherals/usb_host/usb_host_notes_arch.rst api-reference/peripherals/usb_host/usb_host_notes_index.rst api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst api-reference/peripherals/usb_host/usb_host_notes_design.rst +api-reference/peripherals/usb_host/usb_host_notes_usbh.rst api-reference/peripherals/hmac.rst api-reference/peripherals/usb_device.rst -api-reference/peripherals/gpio.rst api-reference/peripherals/sdspi_host.rst api-reference/peripherals/spi_slave.rst api-reference/peripherals/etm.rst @@ -147,7 +122,6 @@ api-reference/peripherals/index.rst api-reference/peripherals/sdmmc_host.rst api-reference/peripherals/ecdsa.rst api-reference/peripherals/rmt.rst -api-reference/kconfig.rst api-reference/network/esp_openthread.rst api-reference/network/esp_eth.rst api-reference/network/esp_netif_driver.rst @@ -163,41 +137,17 @@ api-reference/system/sleep_modes.rst api-reference/system/mm_sync.rst api-reference/system/ota.rst api-reference/system/app_trace.rst -api-reference/system/perfmon.rst -api-reference/system/esp_function_with_shared_stack.rst api-reference/system/efuse.rst api-reference/system/chip_revision.rst api-reference/system/async_memcpy.rst api-reference/system/random.rst -api-reference/system/esp_timer.rst -api-reference/system/esp_event.rst -api-reference/system/freertos.rst -api-reference/system/system_time.rst -api-reference/system/log.rst -api-reference/system/soc_caps.rst -api-reference/system/internal-unstable.rst -api-reference/system/app_image_format.rst -api-reference/system/freertos_additions.rst -api-reference/system/himem.rst api-reference/system/power_management.rst -api-reference/system/mem_alloc.rst -api-reference/system/wdts.rst -api-reference/system/misc_system_api.rst -api-reference/system/bootloader_image_format.rst api-reference/system/inc/show-efuse-table_ESP32-C5.rst api-reference/system/inc/revisions_ESP32-C5.rst api-reference/system/inc/espefuse_summary_ESP32-C5.rst api-reference/system/inc/power_management_esp32c5.rst -api-reference/system/heap_debug.rst api-reference/system/mm.rst -api-reference/system/ipc.rst api-reference/system/esp_https_ota.rst -api-reference/system/esp_err.rst -api-reference/system/freertos_idf.rst -api-reference/system/console.rst -api-reference/system/intr_alloc.rst -api-reference/system/index.rst -api-reference/system/pthread.rst api-reference/bluetooth/esp_spp.rst api-reference/bluetooth/esp_l2cap_bt.rst api-reference/bluetooth/esp_hidd.rst @@ -224,7 +174,6 @@ api-reference/bluetooth/esp-ble-mesh.rst api-reference/bluetooth/index.rst api-reference/bluetooth/esp_gap_ble.rst api-reference/bluetooth/classic_bt.rst -api-reference/error-codes.rst api-reference/index.rst api-reference/protocols/icmp_echo.rst api-reference/protocols/esp_serial_slave_link.rst @@ -249,41 +198,6 @@ security/secure-boot-v1.rst security/index.rst about.rst resources.rst -migration-guides/release-5.x/5.2/ieee802154.rst -migration-guides/release-5.x/5.2/gcc.rst -migration-guides/release-5.x/5.2/protocols.rst -migration-guides/release-5.x/5.2/wifi.rst -migration-guides/release-5.x/5.2/storage.rst -migration-guides/release-5.x/5.2/index.rst -migration-guides/release-5.x/5.2/system.rst -migration-guides/release-5.x/5.2/peripherals.rst -migration-guides/release-5.x/5.3/security.rst -migration-guides/release-5.x/5.3/bluetooth-low-energy.rst -migration-guides/release-5.x/5.3/storage.rst -migration-guides/release-5.x/5.3/index.rst -migration-guides/release-5.x/5.3/system.rst -migration-guides/release-5.x/5.3/peripherals.rst -migration-guides/release-5.x/5.1/ieee802154.rst -migration-guides/release-5.x/5.1/gcc.rst -migration-guides/release-5.x/5.1/networking.rst -migration-guides/release-5.x/5.1/storage.rst -migration-guides/release-5.x/5.1/index.rst -migration-guides/release-5.x/5.1/system.rst -migration-guides/release-5.x/5.1/peripherals.rst -migration-guides/release-5.x/5.0/bluetooth-classic.rst -migration-guides/release-5.x/5.0/gcc.rst -migration-guides/release-5.x/5.0/bluetooth-low-energy.rst -migration-guides/release-5.x/5.0/removed-components.rst -migration-guides/release-5.x/5.0/protocols.rst -migration-guides/release-5.x/5.0/networking.rst -migration-guides/release-5.x/5.0/provisioning.rst -migration-guides/release-5.x/5.0/build-system.rst -migration-guides/release-5.x/5.0/storage.rst -migration-guides/release-5.x/5.0/index.rst -migration-guides/release-5.x/5.0/system.rst -migration-guides/release-5.x/5.0/tools.rst -migration-guides/release-5.x/5.0/peripherals.rst -migration-guides/index.rst get-started/establish-serial-connection.rst get-started/linux-macos-setup.rst get-started/linux-macos-start-project.rst diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index c7e0c82202ec..eeb73f960289 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -1,48 +1,13 @@ -api-guides/performance/speed.rst -api-guides/performance/size.rst -api-guides/performance/ram-usage.rst -api-guides/performance/index.rst api-guides/partition-tables.rst -api-guides/app_trace.rst -api-guides/thread-local-storage.rst -api-guides/error-handling.rst -api-guides/tools/idf-tools.rst -api-guides/tools/idf-clang-tidy.rst -api-guides/tools/idf-component-manager.rst -api-guides/tools/idf-py.rst -api-guides/tools/idf-windows-installer.rst -api-guides/tools/idf-monitor.rst -api-guides/tools/idf-tools-notes.inc -api-guides/tools/idf-docker-image.rst -api-guides/tools/index.rst api-guides/RF_calibration.rst api-guides/deep-sleep-stub.rst api-guides/coexist.rst -api-guides/flash_psram_config.rst -api-guides/usb-serial-jtag-console.rst api-guides/wifi.rst api-guides/usb-otg-console.rst -api-guides/wireshark-user-guide.rst api-guides/esp-wifi-mesh.rst -api-guides/SYSVIEW_FreeRTOS.txt api-guides/dfu.rst api-guides/current-consumption-measurement-modules.rst api-guides/wifi-security.rst -api-guides/host-apps.rst -api-guides/index.rst -api-guides/openthread.rst -api-reference/storage/vfs.rst -api-reference/storage/spiffs.rst -api-reference/storage/nvs_encryption.rst -api-reference/storage/wear-levelling.rst -api-reference/storage/fatfs.rst -api-reference/storage/nvs_partition_gen.rst -api-reference/storage/nvs_flash.rst -api-reference/storage/partition.rst -api-reference/storage/mass_mfg.rst -api-reference/storage/fatfsgen.rst -api-reference/storage/index.rst -api-reference/storage/nvs_partition_parse.rst api-reference/peripherals/adc_continuous.rst api-reference/peripherals/adc_oneshot.rst api-reference/peripherals/usb_host.rst @@ -50,25 +15,13 @@ api-reference/peripherals/usb_host/usb_host_notes_arch.rst api-reference/peripherals/usb_host/usb_host_notes_index.rst api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst api-reference/peripherals/usb_host/usb_host_notes_design.rst +api-reference/peripherals/usb_host/usb_host_notes_usbh.rst api-reference/peripherals/usb_device.rst api-reference/peripherals/touch_element.rst -api-reference/peripherals/ana_cmpr.rst -api-reference/peripherals/temp_sensor.rst -api-reference/peripherals/spi_flash/xip_from_psram.inc -api-reference/peripherals/spi_flash/spi_flash_concurrency.rst -api-reference/peripherals/spi_flash/spi_flash_override_driver.rst -api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst -api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst -api-reference/peripherals/spi_flash/index.rst -api-reference/peripherals/spi_flash/auto_suspend.inc -api-reference/peripherals/sdm.rst api-reference/peripherals/touch_pad.rst api-reference/peripherals/adc_calibration.rst api-reference/peripherals/parlio.rst -api-reference/peripherals/i2c.rst api-reference/peripherals/sd_pullup_requirements.rst -api-reference/peripherals/index.rst -api-reference/network/esp_openthread.rst api-reference/network/esp_dpp.rst api-reference/network/esp_now.rst api-reference/network/esp-wifi-mesh.rst @@ -77,22 +30,5 @@ api-reference/network/esp_nan.rst api-reference/network/esp_wifi.rst api-reference/network/index.rst api-reference/system/sleep_modes.rst -api-reference/system/app_trace.rst -api-reference/system/random.rst api-reference/system/power_management.rst -api-reference/system/misc_system_api.rst api-reference/system/inc/power_management_esp32p4.rst -api-reference/index.rst -api-reference/protocols/icmp_echo.rst -api-reference/protocols/esp_serial_slave_link.rst -api-reference/protocols/index.rst -get-started/establish-serial-connection.rst -get-started/linux-macos-setup.rst -get-started/linux-macos-start-project.rst -get-started/windows-setup.rst -get-started/start-project.rst -get-started/flashing-troubleshooting.rst -get-started/windows-start-project.rst -get-started/index.rst -get-started/windows-setup-update.rst -hw-reference/index.rst diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 735514400335..50539c457b6a 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -149,6 +149,8 @@ INPUT = \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_com.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_driver.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_mac.h \ + $(PROJECT_PATH)/components/esp_eth/include/esp_eth_mac_esp.h \ + $(PROJECT_PATH)/components/esp_eth/include/esp_eth_mac_spi.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_netif_glue.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_phy_802_3.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_phy.h \ @@ -159,7 +161,6 @@ INPUT = \ $(PROJECT_PATH)/components/esp_http_server/include/esp_http_server.h \ $(PROJECT_PATH)/components/esp_https_ota/include/esp_https_ota.h \ $(PROJECT_PATH)/components/esp_https_server/include/esp_https_server.h \ - $(PROJECT_PATH)/components/esp_hw_support/dma/include/esp_dma_utils.h \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_clk_tree.h \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_async_memcpy.h \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_chip_info.h \ @@ -174,6 +175,9 @@ INPUT = \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_random.h \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_sleep.h \ $(PROJECT_PATH)/components/esp_hw_support/ldo/include/esp_ldo_regulator.h \ + $(PROJECT_PATH)/components/esp_lcd/include/esp_lcd_io_i2c.h \ + $(PROJECT_PATH)/components/esp_lcd/include/esp_lcd_io_i80.h \ + $(PROJECT_PATH)/components/esp_lcd/include/esp_lcd_io_spi.h \ $(PROJECT_PATH)/components/esp_lcd/include/esp_lcd_panel_io.h \ $(PROJECT_PATH)/components/esp_lcd/include/esp_lcd_panel_ops.h \ $(PROJECT_PATH)/components/esp_lcd/include/esp_lcd_panel_vendor.h \ @@ -260,6 +264,7 @@ INPUT = \ $(PROJECT_PATH)/components/hal/include/hal/uart_types.h \ $(PROJECT_PATH)/components/hal/include/hal/efuse_hal.h \ $(PROJECT_PATH)/components/hal/include/hal/eth_types.h \ + $(PROJECT_PATH)/components/hal/include/hal/lp_core_types.h \ $(PROJECT_PATH)/components/heap/include/esp_heap_caps_init.h \ $(PROJECT_PATH)/components/heap/include/esp_heap_caps.h \ $(PROJECT_PATH)/components/heap/include/esp_heap_trace.h \ diff --git a/docs/doxygen/Doxyfile_esp32c5 b/docs/doxygen/Doxyfile_esp32c5 index 82c15ca68e1f..faf09ce4a4cb 100644 --- a/docs/doxygen/Doxyfile_esp32c5 +++ b/docs/doxygen/Doxyfile_esp32c5 @@ -1,4 +1,4 @@ -# TODO: IDF-9197 Use beta3 in doc temprory +# TODO: IDF-9197 Use beta3 in doc temporary INPUT += \ $(PROJECT_PATH)/components/soc/$(IDF_TARGET)/mp/include/soc/soc_caps.h \ $(PROJECT_PATH)/components/soc/$(IDF_TARGET)/mp/include/soc/clk_tree_defs.h \ @@ -6,6 +6,7 @@ INPUT += \ $(PROJECT_PATH)/components/soc/$(IDF_TARGET)/mp/include/soc/uart_channel.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_i2c.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_uart.h \ + $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_etm.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/ulp_lp_core.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_i2c.h \ diff --git a/docs/doxygen/Doxyfile_esp32c6 b/docs/doxygen/Doxyfile_esp32c6 index c99dfba77bc8..cc8eb9578a47 100644 --- a/docs/doxygen/Doxyfile_esp32c6 +++ b/docs/doxygen/Doxyfile_esp32c6 @@ -1,12 +1,14 @@ INPUT += \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_i2c.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_uart.h \ + $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_etm.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/ulp_lp_core.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_i2c.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_uart.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h \ + $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h \ $(PROJECT_PATH)/components/bt/include/esp32c6/include/esp_bt.h \ $(PROJECT_PATH)/components/esp_phy/include/esp_phy_init.h \ $(PROJECT_PATH)/components/esp_phy/include/esp_phy_cert_test.h \ diff --git a/docs/doxygen/Doxyfile_esp32p4 b/docs/doxygen/Doxyfile_esp32p4 index 7c914430b398..bef28c609972 100644 --- a/docs/doxygen/Doxyfile_esp32p4 +++ b/docs/doxygen/Doxyfile_esp32p4 @@ -1,12 +1,16 @@ INPUT += \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_i2c.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_uart.h \ + $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_spi.h \ + $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_etm.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/ulp_lp_core.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_i2c.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_uart.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h \ + $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h \ + $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h \ $(PROJECT_PATH)/components/ulp/ulp_common/include/ulp_common.h \ $(PROJECT_PATH)/components/usb/include/usb/usb_helpers.h \ $(PROJECT_PATH)/components/usb/include/usb/usb_host.h \ @@ -16,12 +20,19 @@ INPUT += \ $(PROJECT_PATH)/components/esp_driver_cam/include/esp_cam_ctlr_types.h \ $(PROJECT_PATH)/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h \ $(PROJECT_PATH)/components/hal/include/hal/jpeg_types.h \ + $(PROJECT_PATH)/components/hal/include/hal/ppa_types.h \ + $(PROJECT_PATH)/components/esp_driver_touch_sens/include/driver/touch_sens.h \ + $(PROJECT_PATH)/components/esp_driver_touch_sens/include/driver/touch_sens_types.h \ + $(PROJECT_PATH)/components/esp_driver_touch_sens/hw_ver3/include/driver/touch_version_types.h \ $(PROJECT_PATH)/components/esp_driver_jpeg/include/driver/jpeg_types.h \ $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp.h \ $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_types.h \ $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_af.h \ + $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_awb.h \ + $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_ccm.h \ $(PROJECT_PATH)/components/esp_driver_jpeg/include/driver/jpeg_decode.h \ $(PROJECT_PATH)/components/esp_driver_jpeg/include/driver/jpeg_encode.h \ + $(PROJECT_PATH)/components/esp_driver_ppa/include/driver/ppa.h \ $(PROJECT_PATH)/components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h \ $(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/adc_channel.h \ $(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/clk_tree_defs.h \ diff --git a/docs/en/api-guides/core_dump.rst b/docs/en/api-guides/core_dump.rst index c544ab982769..065101d6bf0e 100644 --- a/docs/en/api-guides/core_dump.rst +++ b/docs/en/api-guides/core_dump.rst @@ -56,9 +56,28 @@ Setting this option to 0 bytes will cause the core dump routines to run from the .. note:: - If a separate stack is used, the recommended stack size should be larger than 800 bytes to ensure that the core dump routines themselves do not cause a stack overflow. + If a separate stack is used, the recommended stack size should be larger than 1300 bytes to ensure that the core dump routines themselves do not cause a stack overflow. +.. only:: not esp32c5 + + Core Dump Memory Regions + ^^^^^^^^^^^^^^^^^^^^^^^^ + + By default, core dumps typically save CPU registers, tasks data and summary of the panic reason. When the :ref:`CONFIG_ESP_COREDUMP_CAPTURE_DRAM` option is selected, ``.bss`` and ``.data`` sections and ``heap`` data will also be part of the dump. + + For a better debugging experience, it is recommended to dump these sections. However, this will result in a larger coredump file. The required additional storage space may vary based on the amount of DRAM the application uses. + + .. only:: SOC_SPIRAM_SUPPORTED + + .. note:: + + Apart from the crashed task's TCB and stack, data located in the external RAM will not be stored in the core dump file, this include variables defined with ``EXT_RAM_BSS_ATTR`` or ``EXT_RAM_NOINIT_ATTR`` attributes, as well as any data stored in the ``extram_bss`` section. + + .. note:: + + This feature is only enabled when using the ELF file format. + Core Dump to Flash ------------------ diff --git a/docs/en/api-guides/error-handling.rst b/docs/en/api-guides/error-handling.rst index b27fc2ec58d3..9d22768f45cd 100644 --- a/docs/en/api-guides/error-handling.rst +++ b/docs/en/api-guides/error-handling.rst @@ -39,7 +39,7 @@ For the complete list of error codes, see :doc:`Error Code Reference <../api-ref Converting Error Codes to Error Messages ---------------------------------------- -For each error code defined in ESP-IDF components, :cpp:type:`esp_err_t` value can be converted to an error code name using :cpp:func:`esp_err_to_name` or :cpp:func:`esp_err_to_name_r` functions. For example, passing ``0x101`` to :cpp:func:`esp_err_to_name` will return "ESP_ERR_NO_MEM" string. Such strings can be used in log output to make it easier to understand which error has happened. +For each error code defined in ESP-IDF components, :cpp:type:`esp_err_t` value can be converted to an error code name using :cpp:func:`esp_err_to_name` or :cpp:func:`esp_err_to_name_r` functions. For example, passing ``0x101`` to :cpp:func:`esp_err_to_name` will return a ``ESP_ERR_NO_MEM`` string. Such strings can be used in log output to make it easier to understand which error has happened. Additionally, :cpp:func:`esp_err_to_name_r` function will attempt to interpret the error code as a `standard POSIX error code `_, if no matching ``ESP_ERR_`` value is found. This is done using ``strerror_r`` function. POSIX error codes (such as ``ENOENT``, ``ENOMEM``) are defined in ``errno.h`` and are typically obtained from ``errno`` variable. In ESP-IDF this variable is thread-local: multiple FreeRTOS tasks have their own copies of ``errno``. Functions which set ``errno`` only modify its value for the task they run in. @@ -53,7 +53,9 @@ This feature is enabled by default, but can be disabled to reduce application bi :c:macro:`ESP_ERROR_CHECK` macro serves similar purpose as ``assert``, except that it checks :cpp:type:`esp_err_t` value rather than a ``bool`` condition. If the argument of :c:macro:`ESP_ERROR_CHECK` is not equal :c:macro:`ESP_OK`, then an error message is printed on the console, and ``abort()`` is called. -Error message will typically look like this:: +Error message will typically look like this: + +.. code-block:: none ESP_ERROR_CHECK failed: esp_err_t 0x107 (ESP_ERR_TIMEOUT) at 0x400d1fdf @@ -63,7 +65,9 @@ Error message will typically look like this:: Backtrace: 0x40086e7c:0x3ffb4ff0 0x40087328:0x3ffb5010 0x400d1fdf:0x3ffb5030 0x400d0816:0x3ffb5050 -.. note:: If :doc:`ESP-IDF monitor ` is used, addresses in the backtrace will be converted to file names and line numbers. +.. note:: + + If :doc:`ESP-IDF monitor ` is used, addresses in the backtrace will be converted to file names and line numbers. - The first line mentions the error code as a hexadecimal value, and the identifier used for this error in source code. The latter depends on :ref:`CONFIG_ESP_ERR_TO_NAME_LOOKUP` option being set. Address in the program where error has occurred is printed as well. @@ -85,7 +89,7 @@ Error message will typically look like this:: ``ESP_RETURN_ON_ERROR`` Macro ----------------------------- -:c:macro:`ESP_RETURN_ON_ERROR` macro checks the error code, if the error code is not equal :c:macro:`ESP_OK`, it prints the message and returns. +:c:macro:`ESP_RETURN_ON_ERROR` macro checks the error code, if the error code is not equal :c:macro:`ESP_OK`, it prints the message and returns the error code. .. _esp-goto-on-error-macro: @@ -93,7 +97,7 @@ Error message will typically look like this:: ``ESP_GOTO_ON_ERROR`` Macro --------------------------- -:c:macro:`ESP_GOTO_ON_ERROR` macro checks the error code, if the error code is not equal :c:macro:`ESP_OK`, it prints the message, sets the local variable `ret` to the code, and then exits by jumping to `goto_tag`. +:c:macro:`ESP_GOTO_ON_ERROR` macro checks the error code, if the error code is not equal :c:macro:`ESP_OK`, it prints the message, sets the local variable ``ret`` to the code, and then exits by jumping to ``goto_tag``. .. _esp-return-on-false-macro: @@ -101,7 +105,7 @@ Error message will typically look like this:: ``ESP_RETURN_ON_FALSE`` Macro ----------------------------- -:c:macro:`ESP_RETURN_ON_FALSE` macro checks the condition, if the condition is not equal `true`, it prints the message and returns with the supplied `err_code`. +:c:macro:`ESP_RETURN_ON_FALSE` macro checks the condition, if the condition is not equal ``true``, it prints the message and returns with the supplied ``err_code``. .. _esp-goto-on-false-macro: @@ -109,15 +113,17 @@ Error message will typically look like this:: ``ESP_GOTO_ON_FALSE`` Macro --------------------------- -:c:macro:`ESP_GOTO_ON_FALSE` macro checks the condition, if the condition is not equal `true`, it prints the message, sets the local variable `ret` to the supplied `err_code`, and then exits by jumping to `goto_tag`. +:c:macro:`ESP_GOTO_ON_FALSE` macro checks the condition, if the condition is not equal ``true``, it prints the message, sets the local variable ``ret`` to the supplied ``err_code``, and then exits by jumping to ``goto_tag``. .. _check_macros_examples: -``CHECK MACROS Examples`` +``CHECK MACROS`` Examples ------------------------- -Some examples:: +Some examples + +.. code-block:: c static const char* TAG = "Test"; @@ -139,9 +145,9 @@ Some examples:: .. note:: - If the option :ref:`CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT` in Kconfig is enabled, the err message will be discarded, while the other action works as is. + If the option :ref:`CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT` in Kconfig is enabled, the error message will be discarded, while the other action works as is. - The ``ESP_RETURN_XX`` and ``ESP_GOTO_xx`` macros cannot be called from ISR. While there are ``xx_ISR`` versions for each of them, e.g., `ESP_RETURN_ON_ERROR_ISR`, these macros could be used in ISR. + The ``ESP_RETURN_XX`` and ``ESP_GOTO_xx`` macros cannot be called from ISR. While there are ``xx_ISR`` versions for each of them, e.g., ``ESP_RETURN_ON_ERROR_ISR``, these macros could be used in ISR. Error Handling Patterns @@ -149,11 +155,13 @@ Error Handling Patterns 1. Attempt to recover. Depending on the situation, we may try the following methods: - - retry the call after some time; - - attempt to de-initialize the driver and re-initialize it again; - - fix the error condition using an out-of-band mechanism (e.g reset an external peripheral which is not responding). + - retry the call after some time; + - attempt to de-initialize the driver and re-initialize it again; + - fix the error condition using an out-of-band mechanism (e.g reset an external peripheral which is not responding). - Example:: + Example: + + .. code-block:: c esp_err_t err; do { @@ -166,7 +174,9 @@ Error Handling Patterns 2. Propagate the error to the caller. In some middleware components this means that a function must exit with the same error code, making sure any resource allocations are rolled back. - Example:: + Example: + + .. code-block:: c sdmmc_card_t* card = calloc(1, sizeof(sdmmc_card_t)); if (card == NULL) { @@ -183,11 +193,13 @@ Error Handling Patterns 3. Convert into unrecoverable error, for example using ``ESP_ERROR_CHECK``. See `ESP_ERROR_CHECK macro`_ section for details. - Terminating the application in case of an error is usually undesirable behavior for middleware components, but is sometimes acceptable at application level. + Terminating the application in case of an error is usually undesirable behavior for middleware components, but is sometimes acceptable at application level. + + Many ESP-IDF examples use ``ESP_ERROR_CHECK`` to handle errors from various APIs. This is not the best practice for applications, and is done to make example code more concise. - Many ESP-IDF examples use ``ESP_ERROR_CHECK`` to handle errors from various APIs. This is not the best practice for applications, and is done to make example code more concise. + Example: - Example:: + .. code-block:: c ESP_ERROR_CHECK(spi_bus_initialize(host, bus_config, dma_chan)); diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index f566897aeefd..39f2b402b9bc 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/docs/en/api-guides/external-ram.rst @@ -26,7 +26,7 @@ Hardware .. only:: esp32 or esp32s2 or esp32s3 - Some PSRAM chips are 1.8 V devices and some are 3.3 V. The working voltage of the PSRAM chip must match the working voltage of the flash component. Consult the datasheet for your PSRAM chip and {IDF_TARGET_NAME} device to find out the working voltages. For a 1.8 V PSRAM chip, make sure to either set the MTDI pin to a high signal level on bootup, or program {IDF_TARGET_NAME} eFuses to always use the VDD_SIO level of 1.8 V. Not doing this can damage the PSRAM and/or flash chip. + Some PSRAM chips are 1.8 V devices and some are 3.3 V. The working voltage of the PSRAM chip must match the working voltage of the flash component. Consult the datasheet for your PSRAM chip and {IDF_TARGET_NAME} device to find out the working voltages. For a 1.8 V PSRAM chip, make sure to either set the MTDI pin to a high signal level on boot-up, or program {IDF_TARGET_NAME} eFuses to always use the VDD_SIO level of 1.8 V. Not doing this can damage the PSRAM and/or flash chip. .. only:: esp32p4 @@ -55,8 +55,7 @@ ESP-IDF fully supports the use of external RAM in applications. Once the externa * :ref:`external_ram_config_malloc` (default) * :ref:`external_ram_config_bss` :esp32: * :ref:`external_ram_config_noinit` - :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_instructions` - :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_rodata` + :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_xip` .. _external_ram_config_memory_map: @@ -137,35 +136,53 @@ Remaining external RAM can also be added to the capability heap allocator using .. only:: SOC_SPIRAM_XIP_SUPPORTED - .. _external_ram_config_instructions: + .. only:: esp32s2 or esp32s3 - Move Instructions in Flash to PSRAM - ----------------------------------- + Move Instructions in Flash to PSRAM + ----------------------------------- - The :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` option allows the flash ``.text`` sections (use for instructions) to be placed in PSRAM. + The :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` option allows the flash ``.text`` sections (for instructions) to be placed in PSRAM. - By enabling the :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` option + By enabling the :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` option, - - Instructions from the ``.text`` sections of flash are moved into PSRAM on system startup. + - Instructions from the ``.text`` sections of flash are moved into PSRAM on system startup. - - The corresponding virtual memory range of those instructions will also be re-mapped to PSRAM. + - The corresponding virtual memory range of those instructions will also be re-mapped to PSRAM. - If :ref:`CONFIG_SPIRAM_RODATA` is also enabled, the cache will not be disabled during an SPI1 flash operation. You do not need to make sure ISRs, ISR callbacks and involved data are placed in internal RAM, thus internal RAM usage can be optimized. + Move Read-Only Data in Flash to PSRAM + --------------------------------------- - .. _external_ram_config_rodata: + The :ref:`CONFIG_SPIRAM_RODATA` option allows the flash ``.rodata`` sections (for read only data) to be placed in PSRAM. - Move Read-Only Data in Flash to PSRAM - --------------------------------------- + By enabling the :ref:`CONFIG_SPIRAM_RODATA` option, - The :ref:`CONFIG_SPIRAM_RODATA` option allows the flash ``.rodata`` sections (use for read only data) to be placed in PSRAM. + - Instructions from the ``.rodata`` sections of flash are moved into PSRAM on system startup. - By enabling the :ref:`CONFIG_SPIRAM_RODATA` option + - The corresponding virtual memory range of those rodata will also be re-mapped to PSRAM. - - Instructions from the ``.rodata`` sections of flash are moved into PSRAM on system startup. + .. _external_ram_config_xip: - - The corresponding virtual memory range of those rodata will also be re-mapped to PSRAM. + Execute In Place (XiP) from PSRAM + ------------------------------------ - If :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` is also enabled, the cache will not be disabled during an SPI1 flash operation. You do not need to make sure ISRs, ISR callbacks and involved data are placed in internal RAM, thus internal RAM usage can be optimized. + The :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` is a helper option for you to select both the :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` and :ref:`CONFIG_SPIRAM_RODATA`. + + The benefits of XiP from PSRAM is: + + - PSRAM access speed is faster than Flash access. So the performance is better. + + - The cache will not be disabled during an SPI1 flash operation, thus optimizing the code execution performance during SPI1 flash operations. For ISRs, ISR callbacks and data which might be accessed during this period, you do not need to place them in internal RAM, thus internal RAM usage can be optimized. This feature is useful for high throughput peripheral involved applications to improve the performance during SPI1 flash operations. + + .. only:: esp32p4 + + .. _external_ram_config_xip: + + Execute In Place (XiP) from PSRAM + ------------------------------------ + + The :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` option enables the executable in place (XiP) from PSRAM feature. With this option sections that are normally placed in flash, ``.text`` (for instructions) and ``.rodata`` (for read only data), will be loaded in PSRAM. + + With this option enabled, the cache will not be disabled during an SPI1 flash operation, so code that requires executing during an SPI1 flash operation does not have to be placed in internal RAM. Because P4 flash and PSRAM are using two separate SPI buses, moving flash content to PSRAM will actually increase the load of the PSRAM MSPI bus, so the exact impact on performance will be dependent on your app usage of PSRAM. For example, as the PSRAM bus speed could be much faster than flash bus speed, if the instructions and data that are used to be in flash are not accessed very frequently, you might get better performance with this option enabled. We suggest doing performance profiling to determine if enabling this option. Restrictions ============ diff --git a/docs/en/api-guides/hlinterrupts.rst b/docs/en/api-guides/hlinterrupts.rst index 97d7fff255ab..c7ef140dc069 100644 --- a/docs/en/api-guides/hlinterrupts.rst +++ b/docs/en/api-guides/hlinterrupts.rst @@ -77,8 +77,8 @@ Using these symbols is done by creating an assembly file with suffix ``.S`` and .. code-block:: none .section .iram1,"ax" - .global xt_highint5 - .type xt_highint5,@function + .global xt_highint4 + .type xt_highint4,@function .align 4 xt_highint5: ... your code here diff --git a/docs/en/api-guides/performance/ram-usage.rst b/docs/en/api-guides/performance/ram-usage.rst index 6ef063cde755..68c7fefc4aeb 100644 --- a/docs/en/api-guides/performance/ram-usage.rst +++ b/docs/en/api-guides/performance/ram-usage.rst @@ -183,6 +183,7 @@ The following options will reduce IRAM usage of some ESP-IDF features: Any memory that ends up unused for static IRAM will be added to the heap. + .. only:: esp32c3 Flash Suspend Feature @@ -233,3 +234,19 @@ The following options will reduce IRAM usage of some ESP-IDF features: .. note:: Other configuration options exist that will increase IRAM usage by moving some functionality into IRAM, usually for performance, but the default option is not to do this. These are not listed here. The IRAM size impact of enabling these options is usually noted in the configuration item help text. + + +.. only:: esp32s2 or esp32s3 or esp32p4 + + Change cache size + ^^^^^^^^^^^^^^^^^ + + The {IDF_TARGET_NAME} RAM memory available size is dependent on the size of cache. Decreasing the cache size in the Kconfig options listed below will result in increasing the available RAM. + + .. list:: + + :esp32s2: - :ref:`CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE` + :esp32s2: - :ref:`CONFIG_ESP32S2_DATA_CACHE_SIZE` + :esp32s3: - :ref:`CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE` + :esp32s3: - :ref:`CONFIG_ESP32S3_DATA_CACHE_SIZE` + :esp32p4: - :ref:`CONFIG_CACHE_L2_CACHE_SIZE` diff --git a/docs/en/api-guides/performance/speed.rst b/docs/en/api-guides/performance/speed.rst index 017707144e6e..d8c9fefc3d87 100644 --- a/docs/en/api-guides/performance/speed.rst +++ b/docs/en/api-guides/performance/speed.rst @@ -4,7 +4,7 @@ Speed Optimization :link_to_translation:`zh_CN:[中文]` {IDF_TARGET_CONTROLLER_CORE_CONFIG:default="CONFIG_BT_CTRL_PINNED_TO_CORE", esp32="CONFIG_BTDM_CTRL_PINNED_TO_CORE_CHOICE", esp32s3="CONFIG_BT_CTRL_PINNED_TO_CORE_CHOICE"} -{IDF_TARGET_RF_TYPE:default="Wi-Fi/Bluetooth", esp32s2="Wi-Fi", esp32c6="Wi-Fi/Bluetooth/802.15.4", esp32h2="Bluetooth/802.15.4"} +{IDF_TARGET_RF_TYPE:default="Wi-Fi/Bluetooth", esp32s2="Wi-Fi", esp32c6="Wi-Fi/Bluetooth/802.15.4", esp32h2="Bluetooth/802.15.4, esp32c5="Wi-Fi/Bluetooth/802.15.4"} Overview -------- @@ -88,6 +88,36 @@ The following optimizations improve the execution of nearly all code, including :not SOC_CPU_HAS_FPU: - Avoid using floating point arithmetic ``float``. On {IDF_TARGET_NAME} these calculations are emulated in software and are very slow. If possible, use fixed point representations, a different method of integer representation, or convert part of the calculation to be integer only before switching to floating point. - Avoid using double precision floating point arithmetic ``double``. These calculations are emulated in software and are very slow. If possible then use an integer-based representation, or single-precision floating point. + +.. only:: esp32s2 or esp32s3 or esp32p4 + + Change cache size + ^^^^^^^^^^^^^^^^^ + + On {IDF_TARGET_NAME}, increasing the overall speed can be achieved to some degree by increasing the size of cache and thus potentially decreasing the frequency of "cache misses" through the Kconfig option(s) listed below. + + .. list:: + + :esp32s2: - :ref:`CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE`. + :esp32s2: - :ref:`CONFIG_ESP32S2_DATA_CACHE_SIZE`. + :esp32s3: - :ref:`CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE`. + :esp32s3: - :ref:`CONFIG_ESP32S3_DATA_CACHE_SIZE`. + :esp32p4: - :ref:`CONFIG_CACHE_L2_CACHE_SIZE`. + + + .. note:: + + Increasing the cache size will also result in reducing the amount of available RAM. + + +.. only:: SOC_CACHE_L2_CACHE_SIZE_CONFIGURABLE + + .. note:: + + On {IDF_TARGET_NAME}, the L2 cache size is configurable via the Kconfig option :ref:`CONFIG_CACHE_L2_CACHE_SIZE`. + Setting the L2 cache size to its smallest value will maximize the available RAM while also potentially augmenting the frequency of "cache misses". + Setting the L2 cache size to its largest value will potentially lower the frequency of "cache misses" at the cost of reducing the available RAM. + Reduce Logging Overhead ^^^^^^^^^^^^^^^^^^^^^^^ @@ -110,6 +140,7 @@ The following options also increase execution speed, but are not recommended as .. _speed-targeted-optimizations: + Targeted Optimizations ---------------------- @@ -134,6 +165,8 @@ In addition to the overall performance improvements shown above, the following o :SOC_RTC_FAST_MEM_SUPPORTED: - If using Deep-sleep mode, setting :ref:`CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` allows a faster wake from sleep. Note that if using Secure Boot, this represents a security compromise, as Secure Boot validation are not be performed on wake. - Setting :ref:`CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON` skips verifying the binary on every boot from the power-on reset. How much time this saves depends on the binary size and the flash settings. Note that this setting carries some risk if the flash becomes corrupt unexpectedly. Read the help text of the :ref:`config item ` for an explanation and recommendations if using this option. - It is possible to save a small amount of time during boot by disabling RTC slow clock calibration. To do so, set :ref:`CONFIG_RTC_CLK_CAL_CYCLES` to 0. Any part of the firmware that uses RTC slow clock as a timing source will be less accurate as a result. + :SOC_SPIRAM_SUPPORTED: - When external memory is used (:ref:`CONFIG_SPIRAM` enabled), enabling memory test on the external memory (:ref:`CONFIG_SPIRAM_MEMTEST`) can have a large impact on startup time (approximately 1 second per 4 MB of memory tested). Disabling the memory tests will reduce startup time at the expense of testing the external memory. + :SOC_SPIRAM_SUPPORTED: - When external memory is used (:ref:`CONFIG_SPIRAM` enabled), enabling comprehensive poisoning will increase the startup time (approximately 300 milliseconds per 4 MiB of memory set) since all the memory used as heap (including the external memory) will be set to a default value. The example project :example:`system/startup_time` is pre-configured to optimize startup time. The file :example_file:`system/startup_time/sdkconfig.defaults` contain all of these settings. You can append these to the end of your project's own ``sdkconfig`` file to merge the settings, but please read the documentation for each setting first. @@ -198,7 +231,7 @@ Common priorities are: - The Ethernet driver creates a task for the MAC to receive Ethernet frames. If using the default config ``ETH_MAC_DEFAULT_CONFIG`` then the priority is medium-high (15) and the task is not pinned to any core. These settings can be changed by passing a custom :cpp:class:`eth_mac_config_t` struct when initializing the Ethernet MAC. - If using the :doc:`/api-reference/protocols/mqtt` component, it creates a task with default priority 5 (:ref:`configurable `, depending on :ref:`CONFIG_MQTT_USE_CUSTOM_CONFIG`) and not pinned to any core (:ref:`configurable `). - - To see what is the task priority for ``mDNS`` service, please check `Performance Optimization `__. + - To see what is the task priority for ``mDNS`` service, please check `Performance Optimization `__. Choosing Task Priorities of the Application @@ -206,13 +239,25 @@ Choosing Task Priorities of the Application .. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES - In general, it is not recommended to set task priorities higher than the built-in {IDF_TARGET_RF_TYPE} operations as starving them of CPU may make the system unstable. For very short timing-critical operations that do not use the network, use an ISR or a very restricted task (with very short bursts of runtime only) at the highest priority (24). Choosing priority 19 allows lower-layer {IDF_TARGET_RF_TYPE} functionality to run without delays, but still preempts the lwIP TCP/IP stack and other less time-critical internal functionality - this is the best option for time-critical tasks that do not perform network operations. Any task that does TCP/IP network operations should run at a lower priority than the lwIP TCP/IP task (18) to avoid priority-inversion issues. + .. only:: SOC_WIFI_SUPPORTED or SOC_BT_SUPPORTED or SOC_IEEE802154_SUPPORTED -.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES + In general, it is not recommended to set task priorities higher than the built-in {IDF_TARGET_RF_TYPE} operations as starving them of CPU may make the system unstable. + + For very short timing-critical operations that do not use the network, use an ISR or a very restricted task (with very short bursts of runtime only) at the highest priority (24). + + .. only:: SOC_WIFI_SUPPORTED or SOC_BT_SUPPORTED or SOC_IEEE802154_SUPPORTED + + Choosing priority 19 allows lower-layer {IDF_TARGET_RF_TYPE} functionality to run without delays, but still preempts the lwIP TCP/IP stack and other less time-critical internal functionality - this is the best option for time-critical tasks that do not perform network operations. + + Any task that does TCP/IP network operations should run at a lower priority than the lwIP TCP/IP task (18) to avoid priority-inversion issues. + +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES With a few exceptions, most importantly the lwIP TCP/IP task, in the default configuration most built-in tasks are pinned to Core 0. This makes it quite easy for the application to place high priority tasks on Core 1. Using priority 19 or higher guarantees that an application task can run on Core 1 without being preempted by any built-in task. To further isolate the tasks running on each CPU, configure the :ref:`lwIP task ` to only run on Core 0 instead of either core, which may reduce total TCP/IP throughput depending on what other tasks are running. - In general, it is not recommended to set task priorities on Core 0 higher than the built-in {IDF_TARGET_RF_TYPE} operations as starving them of CPU may make the system unstable. Choosing priority 19 and Core 0 allows lower-layer {IDF_TARGET_RF_TYPE} functionality to run without delays, but still pre-empts the lwIP TCP/IP stack and other less time-critical internal functionality. This is an option for time-critical tasks that do not perform network operations. Any task that does TCP/IP network operations should run at lower priority than the lwIP TCP/IP task (18) to avoid priority-inversion issues. + .. only:: SOC_WIFI_SUPPORTED or SOC_BT_SUPPORTED or SOC_IEEE802154_SUPPORTED + + In general, it is not recommended to set task priorities on Core 0 higher than the built-in {IDF_TARGET_RF_TYPE} operations as starving them of CPU may make the system unstable. Choosing priority 19 and Core 0 allows lower-layer {IDF_TARGET_RF_TYPE} functionality to run without delays, but still pre-empts the lwIP TCP/IP stack and other less time-critical internal functionality. This is an option for time-critical tasks that do not perform network operations. Any task that does TCP/IP network operations should run at lower priority than the lwIP TCP/IP task (18) to avoid priority-inversion issues. .. note:: diff --git a/docs/en/api-guides/startup.rst b/docs/en/api-guides/startup.rst index e0276986eac4..a9196363aefc 100644 --- a/docs/en/api-guides/startup.rst +++ b/docs/en/api-guides/startup.rst @@ -50,11 +50,11 @@ Startup code called from the reset vector determines the boot mode by checking ` Second stage bootloader binary image is loaded from flash starting at address {IDF_TARGET_CONFIG_BOOTLOADER_OFFSET_IN_FLASH}. The 4 kB sector of flash before this address is unused. -.. only:: esp32p4 +.. only:: SOC_KEY_MANAGER_SUPPORTED Second stage bootloader binary image is loaded from flash starting at address {IDF_TARGET_CONFIG_BOOTLOADER_OFFSET_IN_FLASH}. The 8 kB sector of flash before this address is reserved for the key manager for use with flash encryption (AES-XTS). -.. only:: not (esp32 or esp32s2 or esp32p4) +.. only:: not (esp32 or esp32s2 or SOC_KEY_MANAGER_SUPPORTED) Second stage bootloader binary image is loaded from the start of flash at offset {IDF_TARGET_CONFIG_BOOTLOADER_OFFSET_IN_FLASH}. diff --git a/docs/en/api-guides/usb-serial-jtag-console.rst b/docs/en/api-guides/usb-serial-jtag-console.rst index 23d57436a3e9..4bde079df73c 100644 --- a/docs/en/api-guides/usb-serial-jtag-console.rst +++ b/docs/en/api-guides/usb-serial-jtag-console.rst @@ -19,8 +19,8 @@ Generally, ESP chips implement a serial port using UART and can be connected to Hardware Requirements ===================== -{IDF_TARGET_USB_DP_GPIO:default="Not Updated!",esp32c3="19",esp32s3="20", esp32c6="13", esp32h2="27"} -{IDF_TARGET_USB_DM_GPIO:default="Not Updated!",esp32c3="18",esp32s3="19", esp32c6="12", esp32h2="26"} +{IDF_TARGET_USB_DP_GPIO:default="Not Updated!",esp32c3="19",esp32s3="20", esp32c6="13", esp32h2="27", esp32p4="25/27"} +{IDF_TARGET_USB_DM_GPIO:default="Not Updated!",esp32c3="18",esp32s3="19", esp32c6="12", esp32h2="26", esp32p4="24/26"} Connect {IDF_TARGET_NAME} to the USB port as follows: diff --git a/docs/en/api-reference/network/esp_eth.rst b/docs/en/api-reference/network/esp_eth.rst index c049fcba49c5..39bf96cdb0d8 100644 --- a/docs/en/api-reference/network/esp_eth.rst +++ b/docs/en/api-reference/network/esp_eth.rst @@ -150,7 +150,7 @@ The Ethernet driver is composed of two parts: MAC and PHY. .. only:: esp32 .. note:: - The ``REF_CLK`` can be also configured via Project Configuration when :cpp:member:`eth_esp32_emac_config_t::clock_config::mode` of :cpp:member:`eth_esp32_emac_config_t::clock_config` is set to :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_DEFAULT`. Choose appropriately ``CONFIG_ETH_RMII_CLK_INPUT`` or ``CONFIG_ETH_RMII_CLK_OUTPUT`` option under :ref:`CONFIG_ETH_RMII_CLK_MODE` configuration based on your design as discussed above. + The ``REF_CLK`` can be also configured via Project Configuration when :cpp:class:`eth_esp32_emac_config_t` is initialized using :c:macro:`ETH_ESP32_EMAC_DEFAULT_CONFIG` macro. In the Project Configuration, choose appropriately ``CONFIG_ETH_RMII_CLK_INPUT`` or ``CONFIG_ETH_RMII_CLK_OUTPUT`` option under :ref:`CONFIG_ETH_RMII_CLK_MODE` configuration based on your design as discussed above. .. warning:: If the RMII clock mode is configured to :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_OUT` (or ``CONFIG_ETH_RMII_CLK_OUTPUT`` is selected), then ``GPIO0`` can be used to output the ``REF_CLK`` signal. See :cpp:enumerator:`emac_rmii_clock_gpio_t::EMAC_APPL_CLK_OUT_GPIO` or :ref:`CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0` for more information. @@ -188,12 +188,12 @@ The Ethernet driver is composed of two parts: MAC and PHY. **No matter which RMII clock mode you select, you really need to take care of the signal integrity of REF_CLK in your hardware design!** Keep the trace as short as possible. Keep it away from RF devices and inductor elements. - .. only:: not SOC_EMAC_USE_IO_MUX + .. only:: not SOC_EMAC_USE_MULTI_IO_MUX .. note:: Signals used in the data plane are fixed to specific GPIOs via IO_MUX, they can not be modified to other GPIOs. Signals used in the control plane can be routed to any free GPIOs via Matrix. Please refer to :doc:`ESP32-Ethernet-Kit <../../hw-reference/esp32/get-started-ethernet-kit>` for hardware design example. - .. only:: SOC_EMAC_USE_IO_MUX + .. only:: SOC_EMAC_USE_MULTI_IO_MUX .. note:: Signals used in the data plane can be configured to predefined set of GPIOs via IO_MUX for the RMII, see below table. The data plane GPIO configuration is performed by the driver based on content of :cpp:member:`eth_esp32_emac_config_t::emac_dataif_gpio`. Signals used in the control plane can be routed to any free GPIOs via GPIO Matrix. @@ -250,7 +250,7 @@ Basic common configuration for MAC layer is described in :cpp:class:`eth_mac_con * :cpp:member:`eth_esp32_emac_config_t::intr_priority`: sets the priority of the MAC interrupt. If it is set to ``0`` or a negative value, the driver will allocate an interrupt with a default priority. Otherwise, the driver will use the given priority. Note that *Low* and *Medium* interrupt priorities (1 to 3) can be set since these can be handled in C. - :SOC_EMAC_USE_IO_MUX: * :cpp:member:`eth_esp32_emac_config_t::emac_dataif_gpio`: configuration of EMAC MII/RMII data plane GPIO numbers. + :SOC_EMAC_USE_MULTI_IO_MUX: * :cpp:member:`eth_esp32_emac_config_t::emac_dataif_gpio`: configuration of EMAC MII/RMII data plane GPIO numbers. :not SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK: * :cpp:member:`eth_esp32_emac_config_t::clock_config_out_in`: configuration of EMAC input interface clock when ``REF_CLK`` signal is generated internally and is looped back to the EMAC externally. The mode must be always configured to :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_EXT_IN`. This option is valid only when configuration of :cpp:member:`eth_esp32_emac_config_t::clock_config` is set to :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_OUT`. @@ -549,12 +549,12 @@ Custom PHY Driver There are multiple PHY manufacturers with wide portfolios of chips available. The ESP-IDF already supports several PHY chips however one can easily get to a point where none of them satisfies the user's actual needs due to price, features, stock availability, etc. -Luckily, a management interface between EMAC and PHY is standardized by IEEE 802.3 in Section 22.2.4 Management Functions. It defines provisions of the so-called "MII Management Interface" to control the PHY and gather status from the PHY. A set of management registers is defined to control chip behavior, link properties, auto-negotiation configuration, etc. This basic management functionality is addressed by :component_file:`esp_eth/src/esp_eth_phy_802_3.c` in ESP-IDF and so it makes the creation of a new custom PHY chip driver quite a simple task. +Luckily, a management interface between EMAC and PHY is standardized by IEEE 802.3 in Section 22.2.4 Management Functions. It defines provisions of the so-called "MII Management Interface" to control the PHY and gather status from the PHY. A set of management registers is defined to control chip behavior, link properties, auto-negotiation configuration, etc. This basic management functionality is addressed by :component_file:`esp_eth/src/phy/esp_eth_phy_802_3.c` in ESP-IDF and so it makes the creation of a new custom PHY chip driver quite a simple task. .. note:: Always consult with PHY datasheet since some PHY chips may not comply with IEEE 802.3, Section 22.2.4. It does not mean you are not able to create a custom PHY driver, but it just requires more effort. You will have to define all PHY management functions. -The majority of PHY management functionality required by the ESP-IDF Ethernet driver is covered by the :component_file:`esp_eth/src/esp_eth_phy_802_3.c`. However, the following may require developing chip-specific management functions: +The majority of PHY management functionality required by the ESP-IDF Ethernet driver is covered by the :component_file:`esp_eth/src/phy/esp_eth_phy_802_3.c`. However, the following may require developing chip-specific management functions: * Link status which is almost always chip-specific * Chip initialization, even though not strictly required, should be customized to at least ensure that the expected chip is used @@ -562,11 +562,11 @@ The majority of PHY management functionality required by the ESP-IDF Ethernet dr **Steps to create a custom PHY driver:** -1. Define vendor-specific registry layout based on the PHY datasheet. See :component_file:`esp_eth/src/esp_eth_phy_ip101.c` as an example. +1. Define vendor-specific registry layout based on the PHY datasheet. See :component_file:`esp_eth/src/phy/esp_eth_phy_ip101.c` as an example. 2. Prepare derived PHY management object info structure which: * must contain at least parent IEEE 802.3 :cpp:class:`phy_802_3_t` object - * optionally contain additional variables needed to support non-IEEE 802.3 or customized functionality. See :component_file:`esp_eth/src/esp_eth_phy_ksz80xx.c` as an example. + * optionally contain additional variables needed to support non-IEEE 802.3 or customized functionality. See :component_file:`esp_eth/src/phy/esp_eth_phy_ksz80xx.c` as an example. 3. Define chip-specific management call-back functions. 4. Initialize parent IEEE 802.3 object and re-assign chip-specific management call-back functions. @@ -583,6 +583,8 @@ API Reference .. include-build-file:: inc/esp_eth_driver.inc .. include-build-file:: inc/esp_eth_com.inc .. include-build-file:: inc/esp_eth_mac.inc +.. include-build-file:: inc/esp_eth_mac_esp.inc +.. include-build-file:: inc/esp_eth_mac_spi.inc .. include-build-file:: inc/esp_eth_phy.inc .. include-build-file:: inc/esp_eth_phy_802_3.inc .. include-build-file:: inc/esp_eth_netif_glue.inc diff --git a/docs/en/api-reference/peripherals/camera_driver.rst b/docs/en/api-reference/peripherals/camera_driver.rst index 6707535827b5..bc9bec1c5740 100644 --- a/docs/en/api-reference/peripherals/camera_driver.rst +++ b/docs/en/api-reference/peripherals/camera_driver.rst @@ -48,8 +48,8 @@ Resource Allocation .h_res = MIPI_CSI_DISP_HSIZE, .v_res = MIPI_CSI_DISP_VSIZE_640P, .lane_bit_rate_mbps = MIPI_CSI_LANE_BITRATE_MBPS, - .input_data_color_type = MIPI_CSI_COLOR_RAW8, - .output_data_color_type = MIPI_CSI_COLOR_RGB565, + .input_data_color_type = CAM_CTLR_COLOR_RAW8, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .data_lane_num = 2, .byte_swap_en = false, .queue_items = 1, @@ -60,7 +60,7 @@ Resource Allocation Uninstall Camera Controller Driver ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If a previously installed Camera Controller Driver is no longer needed, it's recommended to recycle the resource by calling :cpp:func:`esp_cam_del_ctlr`, so that to release the underlying hardware. +If a previously installed Camera Controller Driver is no longer needed, it's recommended to recycle the resource by calling :cpp:func:`esp_cam_ctlr_del`, so that to release the underlying hardware. .. _cam-enable-disable: @@ -127,14 +127,14 @@ After the Camera Controller Driver starts receiving, it can generate a specific Thread Safety ^^^^^^^^^^^^^ -The factory function :cpp:func:`esp_cam_new_csi_ctlr` and :cpp:func:`esp_cam_del_ctlr` are guaranteed to be thread safe by the driver, which means, user can call them from different RTOS tasks without protection by extra locks. +The factory function :cpp:func:`esp_cam_new_csi_ctlr` and :cpp:func:`esp_cam_ctlr_del` are guaranteed to be thread safe by the driver, which means, user can call them from different RTOS tasks without protection by extra locks. .. _cam-kconfig-options: Kconfig Options ^^^^^^^^^^^^^^^ -- :ref:`CONFIG_MIPI_CSI_ISR_IRAM_SAFE` controls whether the default ISR handler should be masked when the cache is disabled +- :ref:`CONFIG_CAM_CTLR_MIPI_CSI_ISR_IRAM_SAFE` controls whether the default ISR handler should be masked when the cache is disabled .. _cam-iram-safe: @@ -144,7 +144,7 @@ IRAM Safe By default, the CSI interrupt will be deferred when the cache is disabled because of writing or erasing the flash. -There is a Kconfig option :ref:`CONFIG_MIPI_CSI_ISR_IRAM_SAFE` that: +There is a Kconfig option :ref:`CONFIG_CAM_CTLR_MIPI_CSI_ISR_IRAM_SAFE` that: - Enables the interrupt being serviced even when the cache is disabled - Places all functions that used by the ISR into IRAM diff --git a/docs/en/api-reference/peripherals/cap_touch_sens.rst b/docs/en/api-reference/peripherals/cap_touch_sens.rst new file mode 100644 index 000000000000..2583952c3ac7 --- /dev/null +++ b/docs/en/api-reference/peripherals/cap_touch_sens.rst @@ -0,0 +1,416 @@ +Capacitive Touch Sensor +========================= + +:link_to_translation:`zh_CN:[中文]` + +{IDF_TARGET_TOUCH_SENSOR_VERSION:default="NOT_UPDATED", esp32p4="v3"} + +Introduction +--------------- + +A touch sensor system is built on a substrate which carries electrodes and relevant connections under a protective flat surface. When the surface is touched, the capacitance variation is used to evaluate if the touch was valid. + +The sensing pads can be arranged in different combinations (e.g., matrix, slider), so that a larger area or more points can be detected. The touch pad sensing process is under the control of a hardware-implemented finite-state machine (FSM) which is initiated by software or a dedicated hardware timer. + +For design, operation, and control registers of a touch sensor, see **{IDF_TARGET_NAME} Technical Reference Manual** > **On-Chip Sensors and Analog Signal Processing** [`PDF <{IDF_TARGET_TRM_EN_URL}#sensor>`__]. + +In-depth design details of touch sensors and firmware development guidelines for {IDF_TARGET_NAME} are available in `Touch Sensor Application Note `_. + +Overview of Capacitive Touch Sensor Versions +----------------------------------------------- + ++------------------+--------------+------------------------------------------------------------------------+ +| Hardware Version | Chip | Main Features | ++==================+==============+========================================================================+ +| V1 | ESP32 | Version 1, the channel value decreases when it is touched | ++------------------+--------------+------------------------------------------------------------------------+ +| V2 | ESP32-S2 | Version 2, the channel value increases when it is touched | +| | | Supports waterproof, proximity sensing and sleep wake-up | +| +--------------+------------------------------------------------------------------------+ +| | ESP32-S3 | Version 2, support proximity measurement done interrupt | ++------------------+--------------+------------------------------------------------------------------------+ +| V3 | ESP32-P4 | Version 3, support frequency hopping | ++------------------+--------------+------------------------------------------------------------------------+ + +Overview of Touch Sensor Channels +------------------------------------ + +.. only:: esp32p4 + + ========= ===== ===== ===== ===== ===== ===== ===== ===== ====== ====== ====== ====== ====== ====== ========== + Channel CH0 CH1 CH2 CH3 CH4 CH5 CH6 CH7 CH8 CH9 CH10 CH11 CH12 CH13 CH14 + --------- ----- ----- ----- ----- ----- ----- ----- ----- ------ ------ ------ ------ ------ ------ ---------- + GPIO IO2 IO3 IO4 IO5 IO6 IO7 IO8 IO9 IO10 IO11 IO12 IO13 IO14 IO15 Internal + ========= ===== ===== ===== ===== ===== ===== ===== ===== ====== ====== ====== ====== ====== ====== ========== + +Terminology in the Driver +---------------------------- + +- **Touch Sensor Controller**: The controller of the touch sensor, responsible for configuring and managing the touch sensor. +- **Touch Sensor Channel**: A specific touch sensor sampling channel. A touch sensor module has multiple touch channels, which are usually connected to the touch pad for measuring the capacitance change. In the driver, sampling of **one** channel is called one ``measurement`` and the scanning of **all** registered channels is called one ``scan``. + +.. only:: SOC_TOUCH_SUPPORT_FREQ_HOP + + - **Touch Sensor Sampling Configuration**: Touch sensor sampling configuration refers to all the hardware configurations that related to the sampling. It can determine how the touch channels sample by setting the number of charging times, charging frequency, measurement interval, etc. {IDF_TARGET_NAME} supports multiple sets of sample configuration, which means it can support frequency hopping. + +.. only:: not SOC_TOUCH_SUPPORT_FREQ_HOP + + - **Touch Sensor Sampling Configuration**: Touch sensor sampling configuration refers to all the hardware configurations that related to the sampling. It can determine how the touch channels sample by setting the number of charging times, charging frequency, measurement interval, etc. {IDF_TARGET_NAME} only support one set of sample configuration, so it doesn't support frequency hopping. + +File Structure +----------------- + +.. figure:: ../../../_static/diagrams/cap_touch_sens/touch_file_structure.svg + :align: center + :alt: File Structure of Touch Sensor Driver + + File Structure of Touch Sensor Driver + +Finite-state Machine +--------------------- + +The following diagram shows the state machine of the touch sensor driver, which describes the driver state after calling a function, and the constraint of the state transition. + +.. figure:: ../../../_static/diagrams/cap_touch_sens/touch_state_machine.svg + :align: center + :alt: Finite-state Machine of Touch Sensor Driver + + Finite-state Machine of Touch Sensor Driver + +The diagram above is the finite-state machine of the touch sensor driver, which describes how the state transferred by invoking different APIs. ```` in the diagram stands for the other optional configurations, like reconfigurations to the touch sensor controller or channels, callback registration, filter, and so on. + +.. note:: + + :cpp:func:`touch_channel_read_data` can be called at any time after the channel is registered (i.e., since ``INIT`` state), but please take care of the validation of the data. + +Functionality Introduction +------------------------------ + +Categorized by functionality, the APIs of Capacitive Touch Sensor mainly include: + +.. list:: + + - `Touch Sensor Controller Management <#touch-ctrl>`__ + - `Touch Sensor Channel Management <#touch-chan>`__ + - `Filter Configuration <#touch-filter>`__ + - `Callback <#touch-callback>`__ + - `Enable and Disable <#touch-enable>`__ + - `Continuous Scan <#touch-conti-scan>`__ + - `Oneshot Scan <#touch-oneshot-scan>`__ + - `Benchmark Configuration <#touch-benchmark>`__ + - `Read Measurement Data <#touch-read>`__ + :SOC_TOUCH_SUPPORT_WATERPROOF: - `Waterproof Configuration <#touch-waterproof>`__ + :SOC_TOUCH_SUPPORT_PROX_SENSING: - `Proximity Sensing Configuration <#touch-prox-sensing>`__ + :SOC_TOUCH_SUPPORT_SLEEP_WAKEUP: - `Sleep Wake-up Configuration <#touch-sleep-wakeup>`__ + +.. _touch-ctrl: + +Touch Sensor Controller Management +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Touch Sensor is controlled by controller handle :cpp:type:`touch_sensor_handle_t`, it can be initialized and allocated by :cpp:func:`touch_sensor_new_controller`. + +.. code-block:: c + + // Some target has multiple sets of sample configuration can be set, here take one for example + #define SAMPLE_NUM 1 + touch_sensor_handle_t sens_handle = NULL; + // sample configuration + touch_sensor_sample_config_t sample_cfg[SAMPLE_NUM] = { + // Specify sample configuration or apply the default sample configuration via `TOUCH_SENSOR_Vn_DEFAULT_SAMPLE_CONFIG` + // ... + }; + // Use the default touch controller configuration + touch_sensor_config_t touch_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(SAMPLE_NUM, sample_cfg); + // Allocate a new touch sensor controller handle + ESP_ERROR_CHECK(touch_sensor_new_controller(&touch_cfg, &sens_handle)); + +To delete the controller handle and free the software and hardware resources, please call :cpp:func:`touch_sensor_del_controller`. But note that you need to delete the other resources that based on the controller first, like the registered touch channels, otherwise it can't be deleted directly. + +.. code-block:: c + + ESP_ERROR_CHECK(touch_sensor_del_controller(sens_handle)); + +You can also update the configurations via :cpp:func:`touch_sensor_reconfig_controller` before the controller is enabled. + +.. code-block:: c + + touch_sensor_config_t touch_cfg = { + // New controller configurations + // ... + }; + ESP_ERROR_CHECK(touch_sensor_reconfig_controller(sens_handle, &touch_cfg)); + +.. _touch-chan: + +Touch Sensor Channel Management +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are multiple touch channels in the touch sensor module, the touch sensor channel is controlled by the channel handle :cpp:type:`touch_channel_handle_t`. It can be initialized and allocated by :cpp:func:`touch_sensor_new_channel`. + +.. code-block:: c + + // ... + touch_channel_config_t chan_cfg = { + // Touch channel configurations + // ... + }; + touch_channel_handle_t chan_handle = NULL; + int chan_id = 0; + // Allocate a new touch sensor controller handle + ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, chan_id, &chan_cfg, &chan_handle)); + +To delete the touch channel handle and free the software and hardware resources, please call :cpp:func:`touch_sensor_del_channel`. + +.. code-block:: c + + ESP_ERROR_CHECK(touch_sensor_del_channel(chan_handle)); + +You can also update the configurations via :cpp:func:`touch_sensor_reconfig_channel` before the controller is enabled. + +.. code-block:: c + + touch_channel_config_t chan_cfg = { + // New touch channel configurations + // ... + }; + ESP_ERROR_CHECK(touch_sensor_reconfig_channel(chan_handle, &chan_cfg)); + +.. _touch-filter: + +Filter Configuration +^^^^^^^^^^^^^^^^^^^^^^ + +The filter can help to increase the stability in different use cases. The filter can be registered by calling :cpp:func:`touch_sensor_config_filter` and specify the configurations :cpp:type:`touch_sensor_filter_config_t`. These configurations mainly determine how to filter and update the benchmark and read data. Please note that all touch channels will share this filter. + +To deregister the filter, you can call :cpp:func:`touch_sensor_config_filter` again, and set the second parameter (i.e. :cpp:type:`touch_sensor_filter_config_t` pointer) to ``NULL``. + +.. code-block:: c + + // ... + touch_sensor_filter_config_t filter_config = { + // Filter configurations + // ... + }; + // Register the filter + ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, &filter_config)); + // ... + // Deregister the filter + ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, NULL)); + +.. _touch-callback: + +Callback +^^^^^^^^^^^^^ + +Calling :cpp:func:`touch_sensor_register_callbacks` to register the touch sensor event callbacks. Once the touch sensor events (like ``on_active``, ``on_inactive``) trigger, the corresponding callbacks will be invoked, so that to deal with the event in the upper application. + +For the general example, when the measured data of the current touch channel exceed the ``benchmark`` + ``active_threshold``, this channel is activated, and the driver will call ``on_active`` callback to inform the application layer. Similar, when the active channel measured a lower data than ``benchmark`` + ``active_threshold``, then this channel will be inactivated, and ``on_inactive`` will be called to inform this channel is released. + +.. note:: + + To ensure the stability of the triggering and releasing, ``active_hysteresis`` and ``debounce_cnt`` can be configured to avoid the frequent triggering that caused by jitter and noise. + +Please refer to :cpp:type:`touch_event_callbacks_t` for the details about the supported callbacks. + +.. code-block:: c + + touch_event_callbacks_t callbacks = { + .on_active = example_touch_on_active_cb, + // Other callbacks + // ... + }; + // Register callbacks + ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL)); + + // To deregister callbacks, set the corresponding callback to NULL + callbacks.on_active = NULL; + // Other callbacks to deregister + // ... + ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL)); + +.. _touch-enable: + +Enable and Disable +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After finished the configuration of the touch controller and touch channels, :cpp:func:`touch_sensor_enable` can be called to enable the touch sensor controller. It will enter ``READY`` status and power on the registered channels, then you can start scanning and sampling the touch data. Note that you can only do scanning and reading operation once the controller is enabled. If you want to update the controller or channel configurations, you need to call :cpp:func:`touch_sensor_disable` first. + +.. code-block:: c + + // Enable touch sensor + ESP_ERROR_CHECK(touch_sensor_enable(sens_handle)); + // ... + // Disable touch sensor + ESP_ERROR_CHECK(touch_sensor_disable(sens_handle)); + +.. _touch-conti-scan: + +Continuous Scan +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +With the touch controller enabled, :cpp:func:`touch_sensor_start_continuous_scanning` can be called to start the continuous scanning to all the registered touch channels. The read data of these touch channels will be updated automatically in each scan. Calling :cpp:func:`touch_sensor_stop_continuous_scanning` can stop the continuous scan. + +.. code-block:: c + + // Start continuous scan + ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle)); + // ... + // Stop continuous scan + ESP_ERROR_CHECK(touch_sensor_stop_continuous_scanning(sens_handle)); + +.. _touch-oneshot-scan: + +Oneshot Scan +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +With the touch controller enabled, :cpp:func:`touch_sensor_trigger_oneshot_scanning` can be called to trigger an one-time scan to all the registered touch channels. Note that oneshot scan is a blocking function, it will keep blocking and only return when the scan is finished. Moreover, you can't trigger an oneshot scan after the continuous scan has started. + +.. code-block:: c + + // Trigger an oneshot scan with timeout 1000ms + ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(sens_handle, 1000)); + +.. _touch-benchmark: + +Benchmark Configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Normally, you don't have to set the benchmark manually, but you can force reset the benchmark to the current smooth value by calling :cpp:func:`touch_channel_config_benchmark` when necessary + +.. code-block:: c + + touch_chan_benchmark_config_t benchmark_cfg = { + // Benchmark operations + // ... + }; + ESP_ERROR_CHECK(touch_channel_config_benchmark(chan_handle, &benchmark_cfg)); + +.. _touch-read: + +Read Measurement Data +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Call :cpp:func:`touch_channel_read_data` to read the data with different types. Like, benchmark, smooth data, etc. You can refer to :cpp:type:`touch_chan_data_type_t` for the supported data types. + +.. only:: SOC_TOUCH_SUPPORT_FREQ_HOP + + {IDF_TARGET_NAME} supports frequency hopping by configuring multiple set of sample configurations, :cpp:func:`touch_channel_read_data` can read out the data of each sample configuration in a single call, you can determine the sample configuration number by :cpp:member:`touch_sensor_config_t::sample_cfg_num`, and pass an array (which length is not smaller than the configuration number) to the third parameter ``*data``, so that all the measured data of this channel will be stored in the array. + +.. code-block:: c + + #define SAMPLE_NUM 1 // Take one sample configuration set for example + uint32_t smooth_data[SAMPLE_NUM] = {}; + // Read the smooth data + ESP_ERROR_CHECK(touch_channel_read_data(chan_handle, TOUCH_CHAN_DATA_TYPE_SMOOTH, smooth_data)); + +.. _touch-waterproof: + +.. only:: SOC_TOUCH_SUPPORT_WATERPROOF + + Waterproof Configuration + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} supports waterproof. Waterproof can be registered by calling :cpp:func:`touch_sensor_config_waterproof` and specify the configurations :cpp:type:`touch_waterproof_config_t`. There are two parts of the waterproof function: + + - Immersion (in-water) proof: :cpp:member:`touch_waterproof_config_t::guard_chan` can be specified for detecting immersion. It is usually designed as a ring on the PCB, which surrounds all the other touch pads. When this guard ring channel is triggered, that means the touch panel is immersed by water, all the touch channels will stop measuring to avoid falsely triggering. + - Moisture (water-drop) proof: :cpp:member:`touch_waterproof_config_t::shield_chan` can be specified for detecting moisture. It usually uses the grid layout on the PCB, which covers the whole touch panel. The shield channel will charge and discharge synchronously with the current touch channel, when there is a water droplet covers both shield channel and normal touch channel, :cpp:member:`touch_waterproof_config_t::shield_drv` can strengthen the electrical coupling caused by the water droplets, and then reconfigure the active threshold based on the disturbance to eliminate the influence that introduced by the water droplet. + + To deregister the waterproof function, you can call :cpp:func:`touch_sensor_config_waterproof` again, and set the second parameter (i.e. :cpp:type:`touch_waterproof_config_t` pointer) to ``NULL``. + + .. code-block:: c + + touch_waterproof_config_t waterproof_cfg = { + // Waterproof configurations + // ... + }; + // Register waterproof function + ESP_ERROR_CHECK(touch_sensor_config_waterproof(sens_handle, &waterproof_cfg)); + // ... + // Deregister waterproof function + ESP_ERROR_CHECK(touch_sensor_config_waterproof(sens_handle, NULL)); + +.. _touch-prox-sensing: + +.. only:: SOC_TOUCH_SUPPORT_PROX_SENSING + + Proximity Sensing Configuration + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} supports proximity sensing. Proximity sensing can be registered by calling :cpp:func:`touch_sensor_config_proximity_sensing` and specify the configurations :cpp:type:`touch_proximity_config_t`. + + Since the capacitance change caused by proximity sensing is far less than that caused by physical touch, large area of copper foil is often used on PCB to increase the sensing area. In addition, multiple rounds of scans are needed and the result of each scan will be accumulated in the driver to improve the measurement sensitivity. The scan times (rounds) can be determined by :cpp:member:`touch_proximity_config_t::scan_times` and the charging times of the proximity channel in one scan can be determined by :cpp:member:`touch_proximity_config_t::charge_times`. Generally, the larger the scan times and charging times is, the higher the sensitivity will be, however, the read data will be unstable if the sensitivity is too high. Proper parameters should be determined regarding the application. + + The accumulated proximity data can be read by :cpp:func:`touch_channel_read_data` with the data type :cpp:enumerator:`TOUCH_CHAN_DATA_TYPE_PROXIMITY` + + To deregister the proximity sensing, you can call :cpp:func:`touch_sensor_config_proximity_sensing` again, and set the second parameter (i.e. :cpp:type:`touch_proximity_config_t` pointer) to ``NULL``. + + .. code-block:: c + + touch_proximity_config_t prox_cfg = { + // Proximity sensing configuration + // ... + }; + // Register the proximity sensing + ESP_ERROR_CHECK(touch_sensor_config_proximity_sensing(sens_handle, &prox_cfg)); + // ... + // Deregister the proximity sensing + ESP_ERROR_CHECK(touch_sensor_config_proximity_sensing(sens_handle, NULL)); + +.. _touch-sleep-wakeup: + +.. only:: SOC_TOUCH_SUPPORT_SLEEP_WAKEUP + + Sleep Wake-up Configuration + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} supports waking-up the chip from light sleep or deep sleep with the touch sensor as a wake-up source. The wake-up functionality can be registered by calling :cpp:func:`touch_sensor_config_sleep_wakeup` and specifying the configurations :cpp:type:`touch_sleep_config_t`. + + After registering the touch sensor sleep wake-up, the chip will continue to sample the touch channels after sleep, which will increase the power consumption during the sleep. To reduce the sleep power consumption, you can reduce the number of charging and discharging times, increase the sampling interval, etc. + + Moreover, please note that the operations like sampling, wake-up are all done by hardware when the main core is sleeping. Since this driver runs on the main core, it cannot provide functions such as reading or configuring during the sleep. + + .. only:: SOC_RISCV_COPROC_SUPPORTED + + If you want to read or configure the touch sensor during the sleep, you can turn to the driver ``components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_touch_ulp_core.h`` which based on the :doc:`Ultra Low Power (ULP) Coprocessor <../system/ulp>`. + + - Light sleep wake-up: you need to set :cpp:member:`slp_wakeup_lvl` to :cpp:enumerator:`TOUCH_LIGHT_SLEEP_WAKEUP` to enable the light sleep wake-up by touch sensor. Note that any registered touch channel can wake-up the chip from light sleep. + - Deep sleep wake-up: beside setting :cpp:member:`slp_wakeup_lvl` to :cpp:enumerator:`TOUCH_DEEP_SLEEP_WAKEUP`, you need to specify :cpp:member:`deep_slp_chan` additionally. Only the specified channel can wake-up the chip from the deep sleep, in order to reduce the power consumption. And also, the driver supports to store another set of configurations for the deep sleep via :cpp:member:`deep_slp_sens_cfg`, this set of configurations only takes effect during the deep sleep, you can customize the configurations to save more power. The configurations will be reset to the previous set after waking-up from the deep sleep. Please be aware that, not only deep sleep wake-up, but also light sleep wake-up will be enabled when the :cpp:member:`slp_wakeup_lvl` is :cpp:enumerator:`TOUCH_DEEP_SLEEP_WAKEUP`. + + To deregister the sleep wake-up function, you can call :cpp:func:`touch_sensor_config_sleep_wakeup` again, and set the second parameter (i.e. :cpp:type:`touch_sleep_config_t` pointer) to ``NULL``. + + .. code-block:: c + + touch_sleep_config_t light_slp_cfg = { + .slp_wakeup_lvl = TOUCH_LIGHT_SLEEP_WAKEUP, + }; + // Register the light sleep wake-up + ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &light_slp_cfg)); + // ... + // Deregister the light sleep wake-up + ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, NULL)); + touch_sleep_config_t deep_slp_cfg = { + .slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP, + .deep_slp_chan = dslp_chan_handle, + // Other deep sleep configurations + // ... + }; + // Register the deep sleep wake-up + ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &deep_slp_cfg)); + +Application Examples +------------------------ + +.. only:: esp32p4 + + - Touch sensor basic example: :example:`peripherals/touch_sensor/touch_sensor_{IDF_TARGET_TOUCH_SENSOR_VERSION}`. + +API 参考 +------------- + +.. only:: esp32p4 + + .. include-build-file:: inc/touch_sens.inc + .. include-build-file:: inc/touch_sens_types.inc + .. include-build-file:: inc/touch_version_types.inc + diff --git a/docs/en/api-reference/peripherals/etm.rst b/docs/en/api-reference/peripherals/etm.rst index 8c9d901881d2..467ed590ad2f 100644 --- a/docs/en/api-reference/peripherals/etm.rst +++ b/docs/en/api-reference/peripherals/etm.rst @@ -56,7 +56,7 @@ GPIO Events GPIO **edge** event is the most common event type, it can be generated by any GPIO pin. You can call :cpp:func:`gpio_new_etm_event` to create a GPIO event handle, with the configurations provided in :cpp:type:`gpio_etm_event_config_t`: -- :cpp:member:`gpio_etm_event_config_t::edge` decides which edge to trigger the event, supported edge types are listed in the :cpp:type:`gpio_etm_event_edge_t`. +- :cpp:member:`gpio_etm_event_config_t::edge` or :cpp:member:`gpio_etm_event_config_t::edges` decides which edge(s) to trigger the event(s), supported edge types are listed in the :cpp:type:`gpio_etm_event_edge_t`. You need to build a connection between the GPIO ETM event handle and the GPIO number. So you should call :cpp:func:`gpio_etm_event_bind_gpio` afterwards. Please note, only the ETM event handle that created by :cpp:func:`gpio_new_etm_event` can set a GPIO number. Calling this function with other kinds of ETM events returns :c:macro:`ESP_ERR_INVALID_ARG` error. Needless to say, this function does not help with the GPIO initialization, you still need to call :cpp:func:`gpio_config` to set the property like direction, pull up/down mode separately. @@ -83,9 +83,9 @@ ETM Task abstracts the task action and is represented by :cpp:type:`esp_etm_task GPIO Tasks ~~~~~~~~~~ -GPIO task is the most common task type, one GPIO task can even manage multiple GPIOs. When the task gets activated by the ETM channel, all managed GPIOs can set/clear/toggle at the same time. You can call :cpp:func:`gpio_new_etm_task` to create a GPIO task handle, with the configurations provided in :cpp:type:`gpio_etm_task_config_t`: +GPIO task is the most common task type. One GPIO can take one or more GPIO ETM task actions, and one GPIO ETM task action can even manage multiple GPIOs. When the task gets activated by the ETM channel, all managed GPIOs can set/clear/toggle at the same time. You can call :cpp:func:`gpio_new_etm_task` to create a GPIO task handle, with the configurations provided in :cpp:type:`gpio_etm_task_config_t`: -- :cpp:member:`gpio_etm_task_config_t::action` decides what GPIO action would be taken by the ETM task. Supported actions are listed in the :cpp:type:`gpio_etm_task_action_t`. +- :cpp:member:`gpio_etm_task_config_t::action` or :cpp:member:`gpio_etm_task_config_t::actions` decides what GPIO action(s) would be taken by the ETM task. Supported actions are listed in the :cpp:type:`gpio_etm_task_action_t`. If one GPIO needs to take more than one actions, the action tasks have to be created in one :cpp:func:`gpio_new_etm_task` call with filling the actions into the array of :cpp:member:`gpio_etm_task_config_t::actions`. To build a connection between the GPIO ETM task and the GPIO number, you should call :cpp:func:`gpio_etm_task_add_gpio`. You can call this function by several times if you want the task handle to manage more GPIOs. Please note, only the ETM task handle that created by :cpp:func:`gpio_new_etm_task` can manage a GPIO. Calling this function with other kinds of ETM tasks returns :c:macro:`ESP_ERR_INVALID_ARG` error. Needless to say, this function does not help with the GPIO initialization, you still need to call :cpp:func:`gpio_config` to set the property like direction, pull up/down mode separately. diff --git a/docs/en/api-reference/peripherals/gpio.rst b/docs/en/api-reference/peripherals/gpio.rst index 617d43fd1a19..3efd331f076d 100644 --- a/docs/en/api-reference/peripherals/gpio.rst +++ b/docs/en/api-reference/peripherals/gpio.rst @@ -73,7 +73,9 @@ In addition, if you would like to dump the configurations of all IOs, you can us If an IO pin is routed to a peripheral signal through the GPIO matrix, the signal ID printed in the dump information is defined in the :component_file:`soc/{IDF_TARGET_PATH_NAME}/include/soc/gpio_sig_map.h` header file. The word ``**RESERVED**`` indicates the IO is occupied by either SPI flash or PSRAM. It is strongly not recommended to reconfigure them for other application purposes. -.. only:: esp32c3 or esp32c6 or esp32h2 or esp32p4 or esp32s2 or esp32s3 +Do not rely on the default configurations values in the Technical Reference Manual, because it may be changed in the bootloader or application startup code before app_main. + +.. only:: esp32c3 or esp32c6 or esp32h2 or esp32p4 or esp32s2 or esp32s3 or esp32c5 Configure USB PHY Pins to GPIO ------------------------------- diff --git a/docs/en/api-reference/peripherals/gpio/esp32c5.inc b/docs/en/api-reference/peripherals/gpio/esp32c5.inc index 9a16e59dae6a..e62afa2ffd34 100644 --- a/docs/en/api-reference/peripherals/gpio/esp32c5.inc +++ b/docs/en/api-reference/peripherals/gpio/esp32c5.inc @@ -9,9 +9,7 @@ .. gpio-summary -Current GPIOs are for {IDF_TARGET_NAME} beta3 version. {IDF_TARGET_NAME} MP version would have 2 more available IOs, and some pin functions are changed. The {IDF_TARGET_NAME} MP version will be updated later. - -The {IDF_TARGET_NAME} chip features 27 physical GPIO pins (GPIO0 ~ GPIO26). Each pin can be used as a general-purpose I/O, or to be connected to an internal peripheral signal. Through GPIO matrix and IO MUX, peripheral input signals can be from any IO pins, and peripheral output signals can be routed to any IO pins. Together these modules provide highly configurable I/O. For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *IO MUX and GPIO Matrix (GPIO, IO_MUX)* [`PDF <{IDF_TARGET_TRM_EN_URL}#iomuxgpio>`__]. +The {IDF_TARGET_NAME} chip features 29 physical GPIO pins (GPIO0 ~ GPIO28). Each pin can be used as a general-purpose I/O, or to be connected to an internal peripheral signal. Through GPIO matrix and IO MUX, peripheral input signals can be from any IO pins, and peripheral output signals can be routed to any IO pins. Together these modules provide highly configurable I/O. For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *IO MUX and GPIO Matrix (GPIO, IO_MUX)* [`PDF <{IDF_TARGET_TRM_EN_URL}#iomuxgpio>`__]. The table below provides more information on pin usage, and please note the comments in the table for GPIOs with restrictions. @@ -42,7 +40,7 @@ The table below provides more information on pin usage, and please note the comm * - GPIO3 - ADC1_CH2 - LP_GPIO3 - - Strapping pin + - * - GPIO4 - ADC1_CH3 @@ -57,7 +55,7 @@ The table below provides more information on pin usage, and please note the comm * - GPIO6 - ADC1_CH5 - LP_GPIO6 - - Strapping pin + - * - GPIO7 - @@ -92,12 +90,12 @@ The table below provides more information on pin usage, and please note the comm * - GPIO13 - - - - + - USB-JTAG * - GPIO14 - - - - + - USB-JTAG * - GPIO15 - @@ -107,12 +105,12 @@ The table below provides more information on pin usage, and please note the comm * - GPIO16 - - - - + - SPI0/1 * - GPIO17 - - - - + - SPI0/1 * - GPIO18 - @@ -142,27 +140,37 @@ The table below provides more information on pin usage, and please note the comm * - GPIO23 - - - - SPI0/1 + - * - GPIO24 - - - - SPI0/1 + - * - GPIO25 - - - - USB-JTAG + - * - GPIO26 - - - - USB-JTAG + - + + * - GPIO27 + - + - + - Strapping pin + + * - GPIO28 + - + - + - Strapping pin .. note:: - - Strapping pin: GPIO2, GPIO3, GPIO6, and GPIO7 are strapping pins. For more information, please refer to `datasheet <{IDF_TARGET_DATASHEET_EN_URL}>`__. - - SPI0/1: GPIO18 ~ GPIO24 are usually used for SPI flash and not recommended for other uses. - - USB-JTAG: GPIO25 and GPIO26 are used by USB-JTAG by default. If they are reconfigured to operate as normal GPIOs, USB-JTAG functionality will be disabled. + - Strapping pin: GPIO2, GPIO7, GPIO27, and GPIO28 are strapping pins. For more information, please refer to `datasheet <{IDF_TARGET_DATASHEET_EN_URL}>`__. + - SPI0/1: GPIO16 ~ GPIO22 are usually used for SPI flash and not recommended for other uses. + - USB-JTAG: GPIO13 and GPIO14 are used by USB-JTAG by default. If they are reconfigured to operate as normal GPIOs, USB-JTAG functionality will be disabled. --- diff --git a/docs/en/api-reference/peripherals/index.rst b/docs/en/api-reference/peripherals/index.rst index 5094e38dd73b..3a959b724906 100644 --- a/docs/en/api-reference/peripherals/index.rst +++ b/docs/en/api-reference/peripherals/index.rst @@ -30,6 +30,7 @@ Peripherals API :SOC_MCPWM_SUPPORTED: mcpwm :SOC_PARLIO_SUPPORTED: parlio :SOC_PCNT_SUPPORTED: pcnt + :SOC_PPA_SUPPORTED: ppa :SOC_RMT_SUPPORTED: rmt :SOC_SDMMC_HOST_SUPPORTED or SOC_SDIO_SLAVE_SUPPORTED: sd_pullup_requirements :SOC_SDMMC_HOST_SUPPORTED: sdmmc_host @@ -41,7 +42,8 @@ Peripherals API :SOC_GPSPI_SUPPORTED: spi_slave :SOC_SPI_SUPPORT_SLAVE_HD_VER2: spi_slave_hd :SOC_TEMP_SENSOR_SUPPORTED: temp_sensor - :SOC_TOUCH_SENSOR_SUPPORTED: touch_pad + :SOC_TOUCH_SENSOR_SUPPORTED and not esp32p4: touch_pad + :esp32p4: cap_touch_sens :esp32s2: touch_element :SOC_TWAI_SUPPORTED: twai uart diff --git a/docs/en/api-reference/peripherals/isp.rst b/docs/en/api-reference/peripherals/isp.rst index 4d05b9c74a49..ed4e7250859f 100644 --- a/docs/en/api-reference/peripherals/isp.rst +++ b/docs/en/api-reference/peripherals/isp.rst @@ -4,7 +4,7 @@ Image Signal Processor Introduction ------------ -{IDF_TARGET_NAME} includes an image signal processor (ISP), which is a feature pipeline that consists of many image processing algorithms. ISP receives image data from the DVP camera or MIPI-CSI camera, or system memory, and writes the processed image data to the system memory through DMA. ISP shall work with other modules to read and write data, it can not work alone. +{IDF_TARGET_NAME} includes an Image Signal Processor (ISP), which is a feature pipeline that consists of many image processing algorithms. ISP receives image data from the DVP camera or MIPI-CSI camera, or system memory, and writes the processed image data to the system memory through DMA. ISP shall work with other modules to read and write data, it can not work alone. Terminology ----------- @@ -15,7 +15,42 @@ Terminology - RAW: Unprocessed data directly output from an image sensor, typically divided into R, Gr, Gb, and B four channels classified into RAW8, RAW10, RAW12, etc., based on bit width - RGB: Colored image format composed of red, green, and blue colors classified into RGB888, RGB565, etc., based on the bit width of each color - YUV: Colored image format composed of luminance and chrominance classified into YUV444, YUV422, YUV420, etc., based on the data arrangement + - BF: Bayer Domain Filter - AF: Auto-focus + - AWB: Auto-white balance + - CCM: Color correction matrix + +ISP Pipeline +------------ + +.. blockdiag:: + :scale: 100% + :caption: ISP Pipeline + :align: center + + blockdiag isp_pipeline { + orientation = portrait; + node_height = 30; + node_width = 120; + span_width = 100; + default_fontsize = 16; + + isp_header [label = "ISP Header"]; + isp_tail [label = "ISP Tail"]; + isp_chs [label = "Contrast &\n Hue & Saturation", width = 150, height = 70]; + isp_yuv [label = "YUV Limit\nYUB2RGB", width = 120, height = 70]; + + isp_header -> BF -> Demosaic -> CCM -> RGB2YUV -> isp_chs -> isp_yuv -> isp_tail; + + BF -> HIST + Demosaic -> AWB + Demosaic -> AE + Demosaic -> HIST + CCM -> AWB + CCM -> AE + RGB2YUV -> HIST + RGB2YUV -> AF + } Functional Overview ------------------- @@ -24,7 +59,9 @@ The ISP driver offers following services: - `Resource Allocation <#isp-resource-allocation>`__ - covers how to allocate ISP resources with properly set of configurations. It also covers how to recycle the resources when they finished working. - `Enable and disable ISP processor <#isp-enable-disable>`__ - covers how to enable and disable an ISP processor. -- `Get AF oneshot result <#isp-af-get-oneshot-result>`__ - covers how to get AF oneshot result. +- `Get AF statistics in one shot or continuous way <#isp-af-statistics>`__ - covers how to get AF statistics one-shot or continuously. +- `Get AWB statistics in one shot or continuous way <#isp-awb-statistics>`__ - covers how to get AWB white patches statistics one-shot or continuously. +- `Configure CCM <#isp-ccm-config>`__ - covers how to config the Color Correction Matrix. - `Register callback <#isp-callback>`__ - covers how to hook user specific code to ISP driver event callback function. - `Thread Safety <#isp-thread-safety>`__ - lists which APIs are guaranteed to be thread safe by the driver. - `Kconfig Options <#isp-kconfig-options>`__ - lists the supported Kconfig options that can bring different effects to the driver. @@ -35,8 +72,8 @@ The ISP driver offers following services: Resource Allocation ^^^^^^^^^^^^^^^^^^^ -Install Image Signal Processor (ISP) Driver -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Install ISP Driver +~~~~~~~~~~~~~~~~~~ ISP driver requires the configuration that specified by :cpp:type:`esp_isp_processor_cfg_t`. @@ -58,8 +95,8 @@ If the configurations in :cpp:type:`esp_isp_processor_cfg_t` is specified, users You can use the created handle to do driver enable / disable the ISP driver and do other ISP module installation. -Install Image Signal Processor (ISP) Auto-Focus (AF) Driver -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Install ISP Auto-Focus (AF) Driver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ISP auto-focus (AF) driver requires the configuration that specified by :cpp:type:`esp_isp_af_config_t`. @@ -70,38 +107,71 @@ If the configurations in :cpp:type:`esp_isp_af_config_t` is specified, users can esp_isp_af_config_t af_config = { .edge_thresh = 128, }; - isp_af_ctrlr_t af_ctrlr = NULL; + isp_af_ctlr_t af_ctrlr = NULL; ESP_ERROR_CHECK(esp_isp_new_af_controller(isp_proc, &af_config, &af_ctrlr)); You can use the created handle to do driver enable / disable the ISP AF driver and ISP AF Env module installation. -Uninstall Image Signal Processor (ISP) Driver -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Install ISP Auto-White-Balance (AWB) Driver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +ISP auto-white-balance (AWB) driver requires the configuration specified by :cpp:type:`esp_isp_awb_config_t`. + +If an :cpp:type:`esp_isp_awb_config_t` configuration is specified, you can call :cpp:func:`esp_isp_new_awb_controller` to allocate and initialize an ISP AWB processor. This function will return an ISP AWB processor handle on success. You can take following code as reference. + +.. code:: c + + isp_awb_ctlr_t awb_ctlr = NULL; + uint32_t image_width = 800; + uint32_t image_height = 600; + /* The AWB configuration, please refer to the API comment for how to tune these parameters */ + esp_isp_awb_config_t awb_config = { + .sample_point = ISP_AWB_SAMPLE_POINT_AFTER_CCM, + .window = { + .top_left = {.x = image_width * 0.2, .y = image_height * 0.2}, + .btm_right = {.x = image_width * 0.8, .y = image_height * 0.8}, + }, + .white_patch = { + .luminance = {.min = 0, .max = 220 * 3}, + .red_green_ratio = {.min = 0.0f, .max = 3.999f}, + .blue_green_ratio = {.min = 0.0f, .max = 3.999f}, + }, + }; + ESP_ERROR_CHECK(esp_isp_new_awb_controller(isp_proc, &awb_config, &awb_ctlr)); + +The AWB handle created in this step is required by other AWB APIs and AWB scheme. + +Uninstall ISP Driver +~~~~~~~~~~~~~~~~~~~~ If a previously installed ISP processor is no longer needed, it's recommended to recycle the resource by calling :cpp:func:`esp_isp_del_processor`, so that to release the underlying hardware. -UnInstall Image Signal Processor (ISP) Auto-Focus (AF) Driver -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +UnInstall ISP AF Driver +~~~~~~~~~~~~~~~~~~~~~~~ If a previously installed ISP AF processor is no longer needed, it's recommended to recycle the resource by calling :cpp:func:`esp_isp_del_af_controller`, so that to release the underlying hardware. +UnInstall ISP AWB Driver +~~~~~~~~~~~~~~~~~~~~~~~~ + +If a previously installed ISP AWB processor is no longer needed, it's recommended to free the resource by calling :cpp:func:`esp_isp_del_awb_controller`, it will also release the underlying hardware. -.. _isp-enable-disable: -Enable and Disable Image Signal Processor (ISP) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _isp-enable-disable: -Image Signal Processor (ISP) ----------------------------- +Enable and Disable ISP +^^^^^^^^^^^^^^^^^^^^^^ +ISP +--------- Before doing ISP pipeline, you need to enable the ISP processor first, by calling :cpp:func:`esp_isp_enable`. This function: * Switches the driver state from **init** to **enable**. Calling :cpp:func:`esp_isp_disable` does the opposite, that is, put the driver back to the **init** state. -Image Signal Processor (ISP) Auto-Focus (AF) Processor ------------------------------------------------------- +ISP AF Processor +---------------- Before doing ISP AF, you need to enable the ISP AF processor first, by calling :cpp:func:`esp_isp_af_controller_enable`. This function: @@ -109,25 +179,44 @@ Before doing ISP AF, you need to enable the ISP AF processor first, by calling : Calling :cpp:func:`esp_isp_af_controller_disable` does the opposite, that is, put the driver back to the **init** state. -.. _isp-af-get-oneshot-result: +.. _isp-af-statistics: -Get Auto-Focus (AF) Oneshot Result -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AF One-shot and Continuous Statistics +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Calling :cpp:func:`esp_isp_af_controller_get_oneshot_result` to get oneshot AF result. You can take following code as reference. +Calling :cpp:func:`esp_isp_af_controller_get_oneshot_statistics` to get oneshot AF statistics result. You can take following code as reference. + +Aside from the above oneshot API, the ISP AF driver also provides a way to start AF statistics continuously. Calling :cpp:func:`esp_isp_af_controller_start_continuous_statistics` to start the continuous statistics and :cpp:func:`esp_isp_af_controller_stop_continuous_statistics` to stop it. + +Note that if you want to use the continuous statistics, you need to register the :cpp:member:`esp_isp_af_env_detector_evt_cbs_t::on_env_statistics_done` or :cpp:member:`esp_isp_af_env_detector_evt_cbs_t::on_env_change` callback to get the statistics result. See how to register in `Register Event Callbacks <#isp-callback>`__ .. code:: c esp_isp_af_config_t af_config = { .edge_thresh = 128, }; - isp_af_ctrlr_t af_ctrlr = NULL; + isp_af_ctlr_t af_ctrlr = NULL; ESP_ERROR_CHECK(esp_isp_new_af_controller(isp_proc, &af_config, &af_ctrlr)); + ESP_ERROR_CHECK(esp_isp_af_controller_enable(af_ctrlr)); isp_af_result_t result = {}; - ESP_ERROR_CHECK(esp_isp_af_controller_get_oneshot_result(ctx->af_ctlr, &result)); + /* Trigger the AF statistics and get its result for one time with timeout value 2000ms. */ + ESP_ERROR_CHECK(esp_isp_af_controller_get_oneshot_statistics(af_ctrlr, 2000, &result)); + + /* Start continuous AF statistics */ + ESP_ERROR_CHECK(esp_isp_af_controller_start_continuous_statistics(af_ctrlr)); + // You can do other stuffs here, the statistics result can be obtained in the callback + // ...... + // vTaskDelay(pdMS_TO_TICKS(1000)); + /* Stop continuous AF statistics */ + ESP_ERROR_CHECK(esp_isp_af_controller_stop_continuous_statistics(af_ctrlr)); -Set Auto-Focus (AF) Environment Detector -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /* Disable the af controller */ + ESP_ERROR_CHECK(esp_isp_af_controller_disable(af_ctrlr)); + /* Delete the af controller and free the resources */ + ESP_ERROR_CHECK(esp_isp_del_af_controller(af_ctrlr)); + +Set AF Environment Detector +^^^^^^^^^^^^^^^^^^^^^^^^^^^ Calling :cpp:func:`esp_isp_af_controller_set_env_detector` to set an ISP AF environment detector. You can take following code as reference. @@ -136,12 +225,12 @@ Calling :cpp:func:`esp_isp_af_controller_set_env_detector` to set an ISP AF envi esp_isp_af_env_config_t env_config = { .interval = 10, }; - isp_af_ctrlr_t af_ctrlr = NULL; + isp_af_ctlr_t af_ctrlr = NULL; ESP_ERROR_CHECK(esp_isp_new_af_controller(isp_proc, &af_config, &af_ctrlr)); ESP_ERROR_CHECK(esp_isp_af_controller_set_env_detector(af_ctrlr, &env_config)); -Set Auto-Focus (AF) Environment Detector Threshold -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Set AF Environment Detector Threshold +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Calling :cpp:func:`esp_isp_af_env_detector_set_threshold` to set the threshold of an ISP AF environment detector. @@ -151,20 +240,127 @@ Calling :cpp:func:`esp_isp_af_env_detector_set_threshold` to set the threshold o int luminance_thresh = 0; ESP_ERROR_CHECK(esp_isp_af_env_detector_set_threshold(env_detector, definition_thresh, luminance_thresh)); +ISP AWB Processor +----------------- + +Before doing ISP AWB, you need to enable the ISP AWB processor first, by calling :cpp:func:`esp_isp_awb_controller_enable`. This function: + +* Switches the driver state from **init** to **enable**. + +Calling :cpp:func:`esp_isp_awb_controller_disable` does the opposite, that is, put the driver back to the **init** state. + +.. _isp-awb-statistics: + +AWB One-shot and Continuous Statistics +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Calling :cpp:func:`esp_isp_awb_controller_get_oneshot_result` to get oneshot AWB statistics result of white patches. You can take following code as reference. + +Aside from the above oneshot API, the ISP AWB driver also provides a way to start AWB statistics continuously. Calling :cpp:func:`esp_isp_awb_controller_start_continuous_statistics` starts the continuous statistics and :cpp:func:`esp_isp_awb_controller_stop_continuous_statistics` stops it. + +Note that if you want to use the continuous statistics, you need to register the :cpp:member:`esp_isp_awb_cbs_t::on_statistics_done` callback to get the statistics result. See how to register it in `Register Event Callbacks <#isp-callback>`__ + +.. code:: c + + bool example_isp_awb_on_statistics_done_cb(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_evt_data_t *edata, void *user_data); + // ... + isp_awb_ctlr_t awb_ctlr = NULL; + uint32_t image_width = 800; + uint32_t image_height = 600; + /* The AWB configuration, please refer to the API comment for how to tune these parameters */ + esp_isp_awb_config_t awb_config = { + .sample_point = ISP_AWB_SAMPLE_POINT_AFTER_CCM, + .window = { + .top_left = {.x = image_width * 0.2, .y = image_height * 0.2}, + .btm_right = {.x = image_width * 0.8, .y = image_height * 0.8}, + }, + .white_patch = { + .luminance = {.min = 0, .max = 220 * 3}, + .red_green_ratio = {.min = 0.0f, .max = 3.999f}, + .blue_green_ratio = {.min = 0.0f, .max = 3.999f}, + }, + }; + isp_awb_stat_result_t stat_res = {}; + /* Create the awb controller */ + ESP_ERROR_CHECK(esp_isp_new_awb_controller(isp_proc, &awb_config, &awb_ctlr)); + /* Register AWB callback */ + esp_isp_awb_cbs_t awb_cb = { + .on_statistics_done = example_isp_awb_on_statistics_done_cb, + }; + ESP_ERROR_CHECK(esp_isp_awb_register_event_callbacks(awb_ctlr, &awb_cb, NULL)); + /* Enabled the awb controller */ + ESP_ERROR_CHECK(esp_isp_awb_controller_enable(awb_ctlr)); + + /* Get oneshot AWB statistics result */ + ESP_ERROR_CHECK(esp_isp_awb_controller_get_oneshot_statistics(awb_ctlr, -1, &stat_res)); + + /* Start continuous AWB statistics, note that continuous statistics requires `on_statistics_done` callback */ + ESP_ERROR_CHECK(esp_isp_awb_controller_start_continuous_statistics(awb_ctlr)); + // You can do other stuffs here, the statistics result can be obtained in the callback + // ...... + // vTaskDelay(pdMS_TO_TICKS(1000)); + /* Stop continuous AWB statistics */ + ESP_ERROR_CHECK(esp_isp_awb_controller_stop_continuous_statistics(awb_ctlr)); + + /* Disable the awb controller */ + ESP_ERROR_CHECK(esp_isp_awb_controller_disable(awb_ctlr)); + /* Delete the awb controller and free the resources */ + ESP_ERROR_CHECK(esp_isp_del_awb_controller(awb_ctlr)); + +.. _isp-ccm-config: + +Configure CCM +^^^^^^^^^^^^^ + +Color Correction Matrix can scale the color ratio of RGB888 pixels. It can be used for adjusting the image color via some algorithms, for example, used for white balance by inputting the AWB computed result, or used as a Filter with some filter algorithms. + +To adjust the color correction matrix, you can refer to the following code: + +.. code-block:: c + + // ... + // Configure CCM + esp_isp_ccm_config_t ccm_cfg = { + .matrix = { + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0 + }, + .saturation = false, + }; + ESP_ERROR_CHECK(esp_isp_ccm_configure(isp_proc, &ccm_cfg)); + // The configured CCM will be applied to the image once the CCM module is enabled + ESP_ERROR_CHECK(esp_isp_ccm_enable(isp_proc)); + // CCM can also be configured after it is enabled + ccm_cfg.matrix[0][0] = 2.0; + ESP_ERROR_CHECK(esp_isp_ccm_configure(isp_proc, &ccm_cfg)); + // Disable CCM if no longer needed + ESP_ERROR_CHECK(esp_isp_ccm_disable(isp_proc)); + .. _isp-callback: Register Event Callbacks ^^^^^^^^^^^^^^^^^^^^^^^^ -Register Image Signal Processor (ISP) Auto-Focus (AF) Environment Detector Event Callbacks -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Register ISP AF Environment Detector Event Callbacks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ After the ISP AF environment detector starts up, it can generate a specific event dynamically. If you have some functions that should be called when the event happens, please hook your function to the interrupt service routine by calling :cpp:func:`esp_isp_af_env_detector_register_event_callbacks`. All supported event callbacks are listed in :cpp:type:`esp_isp_af_env_detector_evt_cbs_t`: +- :cpp:member:`esp_isp_af_env_detector_evt_cbs_t::on_env_statistics_done` sets a callback function for environment statistics done. As this function is called within the ISR context, you must ensure that the function does not attempt to block (e.g., by making sure that only FreeRTOS APIs with ``ISR`` suffix are called from within the function). The function prototype is declared in :cpp:type:`esp_isp_af_env_detector_callback_t`. - :cpp:member:`esp_isp_af_env_detector_evt_cbs_t::on_env_change` sets a callback function for environment change. As this function is called within the ISR context, you must ensure that the function does not attempt to block (e.g., by making sure that only FreeRTOS APIs with ``ISR`` suffix are called from within the function). The function prototype is declared in :cpp:type:`esp_isp_af_env_detector_callback_t`. You can save your own context to :cpp:func:`esp_isp_af_env_detector_register_event_callbacks` as well, via the parameter ``user_data``. The user data will be directly passed to the callback function. +Register ISP AWB Statistics Done Event Callbacks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After the ISP AWB controller finished statistics of white patches, it can generate a specific event dynamically. If you want to be informed when the statistics done event takes place, please hook your function to the interrupt service routine by calling :cpp:func:`esp_isp_awb_register_event_callbacks`. All supported event callbacks are listed in :cpp:type:`esp_isp_awb_cbs_t`: + +- :cpp:member:`esp_isp_awb_cbs_t::on_statistics_done` sets a callback function when finished statistics of the white patches. As this function is called within the ISR context, you must ensure that the function does not attempt to block (e.g., by making sure that only FreeRTOS APIs with ``ISR`` suffix are called from within the function). The function prototype is declared in :cpp:type:`esp_isp_awb_callback_t`. + +You can save your own context via the parameter ``user_data`` of :cpp:func:`esp_isp_awb_register_event_callbacks`. The user data will be directly passed to the callback function. + .. _isp-thread-safety: Thread Safety diff --git a/docs/en/api-reference/peripherals/lcd/i2c_lcd.rst b/docs/en/api-reference/peripherals/lcd/i2c_lcd.rst index 6f41f57d6b38..24c51f775f6b 100644 --- a/docs/en/api-reference/peripherals/lcd/i2c_lcd.rst +++ b/docs/en/api-reference/peripherals/lcd/i2c_lcd.rst @@ -48,3 +48,8 @@ I2C Interfaced LCD .reset_gpio_num = EXAMPLE_PIN_NUM_RST, }; ESP_ERROR_CHECK(esp_lcd_new_panel_ssd1306(io_handle, &panel_config, &panel_handle)); + +API Reference +------------- + +.. include-build-file:: inc/esp_lcd_io_i2c.inc diff --git a/docs/en/api-reference/peripherals/lcd/i80_lcd.rst b/docs/en/api-reference/peripherals/lcd/i80_lcd.rst index 69df232a9355..01fb707ed6f1 100644 --- a/docs/en/api-reference/peripherals/lcd/i80_lcd.rst +++ b/docs/en/api-reference/peripherals/lcd/i80_lcd.rst @@ -29,8 +29,7 @@ I80 Interfaced LCD }, .bus_width = 8, .max_transfer_bytes = EXAMPLE_LCD_H_RES * 100 * sizeof(uint16_t), // transfer 100 lines of pixels (assume pixel is RGB565) at most in one transaction - .psram_trans_align = EXAMPLE_PSRAM_DATA_ALIGNMENT, - .sram_trans_align = 4, + .dma_burst_size = EXAMPLE_DMA_BURST_SIZE, }; ESP_ERROR_CHECK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); @@ -73,3 +72,8 @@ I80 Interfaced LCD .bits_per_pixel = 16, }; ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle)); + +API Reference +------------- + +.. include-build-file:: inc/esp_lcd_io_i80.inc diff --git a/docs/en/api-reference/peripherals/lcd/rgb_lcd.rst b/docs/en/api-reference/peripherals/lcd/rgb_lcd.rst index 882dfb7406a4..1ecb0a0646c8 100644 --- a/docs/en/api-reference/peripherals/lcd/rgb_lcd.rst +++ b/docs/en/api-reference/peripherals/lcd/rgb_lcd.rst @@ -7,7 +7,7 @@ RGB LCD panel is allocated in one step: :cpp:func:`esp_lcd_new_rgb_panel`, with - :cpp:member:`esp_lcd_rgb_panel_config_t::data_width` set number of data lines used by the RGB interface. Currently, the supported value can be 8 or 16. - :cpp:member:`esp_lcd_rgb_panel_config_t::bits_per_pixel` set the number of bits per pixel. This is different from :cpp:member:`esp_lcd_rgb_panel_config_t::data_width`. By default, if you set this field to 0, the driver will automatically adjust the bpp to the :cpp:member:`esp_lcd_rgb_panel_config_t::data_width`. But in some cases, these two value must be different. For example, a Serial RGB interface LCD only needs ``8`` data lines, but the color width can reach to ``RGB888``, i.e., the :cpp:member:`esp_lcd_rgb_panel_config_t::bits_per_pixel` should be set to ``24``. - :cpp:member:`esp_lcd_rgb_panel_config_t::hsync_gpio_num`, :cpp:member:`esp_lcd_rgb_panel_config_t::vsync_gpio_num`, :cpp:member:`esp_lcd_rgb_panel_config_t::de_gpio_num`, :cpp:member:`esp_lcd_rgb_panel_config_t::pclk_gpio_num`, :cpp:member:`esp_lcd_rgb_panel_config_t::disp_gpio_num` and :cpp:member:`esp_lcd_rgb_panel_config_t::data_gpio_nums` are the GPIO pins used by the RGB LCD controller. If some of them are not used, please set it to `-1`. - - :cpp:member:`esp_lcd_rgb_panel_config_t::sram_trans_align` and :cpp:member:`esp_lcd_rgb_panel_config_t::psram_trans_align` set the alignment of the allocated frame buffer. Internally, the DMA transfer ability will adjust against these alignment values. A higher alignment value can lead to a bigger DMA burst size. Please note, the alignment value must be a power of 2. + - :cpp:member:`esp_lcd_rgb_panel_config_t::dma_burst_size` set the DMA transfer burst size, the value must be a power of 2. - :cpp:member:`esp_lcd_rgb_panel_config_t::bounce_buffer_size_px` set the size of bounce buffer. This is only necessary for a so-called "bounce buffer" mode. Please refer to :ref:`bounce_buffer_with_single_psram_frame_buffer` for more information. - :cpp:member:`esp_lcd_rgb_panel_config_t::timings` sets the LCD panel specific timing parameters. All required parameters are listed in the :cpp:type:`esp_lcd_rgb_timing_t`, including the LCD resolution and blanking porches. Please fill them according to the datasheet of your LCD. - :cpp:member:`esp_lcd_rgb_panel_config_t::fb_in_psram` sets whether to allocate the frame buffer from PSRAM or not. Please refer to :ref:`single_frame_buffer_in_psram` for more information. diff --git a/docs/en/api-reference/peripherals/lcd/spi_lcd.rst b/docs/en/api-reference/peripherals/lcd/spi_lcd.rst index 6731c42b8c4a..5c44794c6193 100644 --- a/docs/en/api-reference/peripherals/lcd/spi_lcd.rst +++ b/docs/en/api-reference/peripherals/lcd/spi_lcd.rst @@ -56,3 +56,8 @@ SPI Interfaced LCD }; // Create LCD panel handle for ST7789, with the SPI IO device handle ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle)); + +API Reference +------------- + +.. include-build-file:: inc/esp_lcd_io_spi.inc diff --git a/docs/en/api-reference/peripherals/ppa.rst b/docs/en/api-reference/peripherals/ppa.rst new file mode 100644 index 000000000000..e108558839c4 --- /dev/null +++ b/docs/en/api-reference/peripherals/ppa.rst @@ -0,0 +1,149 @@ +Pixel-Processing Accelerator (PPA) +================================== + +Introduction +------------ + +{IDF_TARGET_NAME} includes a pixel-processing accelerator (PPA) module, to realize hardware-level acceleration of image algorithms, such as image rotation, scaling, mirroring, and blending. + +Terminology +----------- + +The terms used in relation to the PPA driver are given in the table and the diagram below. + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Term + - Definition + * - Picture (pic) + - A complete image stored in the system memory. + * - Block + - A portion cropped from a picture at a certain size, with the maximum size equivalent to the entire picture. + * - Pixel + - The unit to be used in the PPA context. + * - PPA Operation + - Types of image algorithm accelerations, includes scale-rotate-mirror (SRM), blend, and fill. + * - PPA Client + - Who wants to do the PPA operations. Typically, every PPA client is hold by a specific task. + * - PPA Transaction + - One request from a PPA client to do a PPA operation is one PPA transaction. + +.. figure:: ../../../_static/diagrams/ppa/pic_blk_concept.png + :align: center + :alt: PPA picture/block terminology + + PPA picture/block terminology + +Functional Overview +------------------- + +The following sections detail the design of the PPA driver: + +- :ref:`ppa-client-registration` - Covers how to register a PPA client to perform any PPA operations. +- :ref:`ppa-register-callback` - Covers how to hook user specific code to PPA driver event callback function. +- :ref:`ppa-perform-operation` - Covers how to perform a PPA operation. +- :ref:`ppa-thread-safety` - Covers the usage of the PPA operation APIs in thread safety aspect. +- :ref:`ppa-performance-overview` - Covers the performance of PPA operations. + +.. _ppa-client-registration: + +Register PPA Client +^^^^^^^^^^^^^^^^^^^ + +Requests to perform PPA operations are made by PPA clients. Therefore, PPA clients need to be registered first before doing any PPA operations. Call :cpp:func:`ppa_register_client` function to register a new client. :cpp:type:`ppa_client_config_t` structure is used to specific the properties of the client. + +- :cpp:member:`ppa_client_config_t::oper_type` - Each PPA operation type corresponds to one PPA client type, a registered PPA client can only request one specific type of PPA operations. +- :cpp:member:`ppa_client_config_t::max_pending_trans_num` - Decides the maximum number of pending PPA transactions the client can hold. + +It is recommended that every task to register its own PPA clients. For example, an application contains two tasks: Task A requires both the PPA SRM and the PPA fill functionalities, so one PPA SRM client and one PPA fill client should be registered in Task A; While Task B also requires the PPA SRM functionality, then another PPA SRM client should be registered in Task B. + +If the task no longer needs to do PPA operations, the corresponding PPA clients can be deregistered with :cpp:func:`ppa_unregister_client` function. + +.. _ppa-register-callback: + +Register PPA Event Callbacks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When an event occurs (e.g., a PPA transaction is completed), the CPU is notified of this event via an interrupt. If some specific functions need to be called when a particular event occurs, a callback can be registered for that event by calling :cpp:func:`ppa_client_register_event_callbacks`. This can be specifically useful when ``PPA_TRANS_MODE_NON_BLOCKING`` mode is selected to perform the PPA operations. It is worth noticing that the event callbacks are bound to PPA clients, but the user context is provided per transaction in the call to the PPA operation APIs. This allows the maximum flexibility in utilizing the event callbacks. + +The registered callback functions are called in the interrupt context, therefore, the callback functions should follow common ISR (Interrupt Service Routine) rules. + +.. _ppa-perform-operation: + +Perform PPA Operations +^^^^^^^^^^^^^^^^^^^^^^ + +Once the PPA client is registered, a PPA operation can be requested with the returned :cpp:type:`ppa_client_handle_t`. + +PPA operations includes: + +Scale, Rotate, Mirror (SRM) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Call :cpp:func:`ppa_do_scale_rotate_mirror` to apply one or more of the scaling, rotation, mirroring operations to the target block inside a picture. + +Some notes to avoid confusion in configuring :cpp:type:`ppa_srm_oper_config_t`: + +.. list:: + - :cpp:member:`ppa_in_pic_blk_config_t::buffer` and :cpp:member:`ppa_out_pic_blk_config_t::buffer` have to be the pointers to different picture buffers for a SRM operation. + - The precision of :cpp:member:`ppa_srm_oper_config_t::scale_x` and :cpp:member:`ppa_srm_oper_config_t::scale_y` will be truncated to a step size of 1/16. + - Output block's width/height is totally determined by the input block's width/height, scaling factor, and rotation angle, so output block's width/height does not need to be configured. However, please make sure the output block can fit at the offset location in the output picture. + - If the color mode of the input or output picture is ``PPA_SRM_COLOR_MODE_YUV420``, then its ``pic_w``, ``pic_h``, ``block_w``, ``block_h``, ``block_offset_x``, ``block_offset_y`` fields must be even. + +Blend +~~~~~ + +Call :cpp:func:`ppa_do_blend` to blend the two target blocks of two so-called foreground (FG) and background (BG) pictures. + +Blend follows the normal Alpha Blending formula: + +:math:`A_{out} = A_b + A_f - A_b \times A_f` + +:math:`C_{out} = (C_b \times A_b \times (1 - A_f) + C_f \times A_f) / (A_b + A_f - A_b \times A_f)` + +where :math:`A_b` is the Alpha channel of the background layer, :math:`A_f` is the Alpha channel of the foreground layer, :math:`C_b` corresponds to the R, G, B components of the background layer, and :math:`C_f` corresponds to the R, G, B components of the foreground layer. + +Note that this formula is not symmetric to FG and BG. When :math:`A_f = 1`, it calculates :math:`C_{out} = C_f`, :math:`A_{out} = 1`, which means if the color mode of the FG picture is ``PPA_BLEND_COLOR_MODE_RGB565`` or ``PPA_BLEND_COLOR_MODE_RGB888``, since a Alpha value of 255 will be filled by the PPA hardware (i.e. :math:`A_f = 1`), the blended result will be identical to the FG block. + +If :cpp:member:`ppa_blend_oper_config_t::bg_ck_en` or :cpp:member:`ppa_blend_oper_config_t::fg_ck_en` is set to ``true``, the pixels fall into the color-key (also known as Chroma-key) range does not follow Alpha Blending process. Please check **{IDF_TARGET_NAME} Technical Reference Manual** > **Pixel-Processing Accelerator (PPA)** > **Functional Description** > **Layer Blending (BLEND)** [`PDF <{IDF_TARGET_TRM_EN_URL}#ppa>`__] for the detailed rules. + +Similarly, some notes to avoid confusion in configuring :cpp:type:`ppa_blend_oper_config_t`: + +.. list:: + - :cpp:member:`ppa_out_pic_blk_config_t::buffer` can be the same pointer to one of the input's :cpp:member:`ppa_in_pic_blk_config_t::buffer` for a blend operation. + - The blocks' width/height of FG and BG should be identical, and are the width/height values for the output block. + - If the color mode of the input picture is ``PPA_BLEND_COLOR_MODE_A4``, then its ``block_w`` and ``block_offset_x`` fields must be even. + +Fill +~~~~ + +Call :cpp:func:`ppa_do_fill` to fill a target block inside a picture. + +:cpp:type:`ppa_trans_mode_t` is a field configurable to all the PPA operation APIs. It decides whether you want the call to the PPA operation API to block until the transaction finishes or to return immediately after the transaction is pushed to the internal queue. + +.. _ppa-thread-safety: + +Thread Safety +^^^^^^^^^^^^^ + +The PPA driver has guaranteed the thread safety of calling the PPA operation APIs in all following situations: + +.. list:: + - Among clients of different types in one task + - Among clients of same type in different tasks + - Among clients of different types in different tasks + +.. _ppa-performance-overview: + +Performance Overview +^^^^^^^^^^^^^^^^^^^^ + +The PPA operations are acted on the target block of an input picture. Therefore, the time it takes to complete a PPA transaction is proportional to the amount of the data in the block. The size of the entire picture has no influence on the performance. More importantly, the PPA performance highly relies on the PSRAM bandwidth if the pictures are located in the PSRAM section. When there are quite a few peripherals reading and writing to the PSRAM at the same time, the performance of PPA operation will be greatly reduced. + +API Reference +------------- + +.. include-build-file:: inc/ppa.inc +.. include-build-file:: inc/ppa_types.inc diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst index dcd5198928fc..6db75246cf7a 100644 --- a/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst @@ -19,7 +19,7 @@ The SPI0/1 bus is shared between the instruction & data cache (for firmware exec .. only:: SOC_SPIRAM_XIP_SUPPORTED - On {IDF_TARGET_NAME}, the config options :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` (disabled by default) and :ref:`CONFIG_SPIRAM_RODATA` (disabled by default) allow the cache to read/write PSRAM concurrently with SPI1 operations. See :ref:`xip_from_psram` for more details. + On {IDF_TARGET_NAME}, the config options :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` (disabled by default) allows the cache to read/write PSRAM concurrently with SPI1 operations. See :ref:`xip_from_psram` for more details. If these options are disabled, the caches must be disabled while reading/writing/erasing operations. There are some constraints using driver on the SPI1 bus, see :ref:`impact_disabled_cache`. These constraints will cause more IRAM/DRAM usages. @@ -40,7 +40,7 @@ Under this condition, all CPUs should always execute code and access data from i .. note:: - When :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` and :ref:`CONFIG_SPIRAM_RODATA` are both enabled, these APIs will not disable the caches. + When :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` is enabled, these APIs will not disable the caches. .. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES @@ -77,6 +77,13 @@ Non-IRAM-Safe Interrupt Handlers If the ``ESP_INTR_FLAG_IRAM`` flag is not set when registering, the interrupt handler will not get executed when the caches are disabled. Once the caches are restored, the non-IRAM-safe interrupts will be re-enabled. After this moment, the interrupt handler will run normally again. This means that as long as caches are disabled, users will not see the corresponding hardware event happening. +.. only:: SOC_DMA_CAN_ACCESS_FLASH + + When DMA Read Data from Flash + ----------------------------- + + When DMA is reading data from Flash, erase/write operations from SPI1 take higher priority in hardware, resulting in unpredictable data read by DMA if auto-suspend is not enabled. It is recommended to stop DMA access to Flash before erasing or writing to it. If DMA cannot be stopped (for example, the LCD needs to continuously refresh image data stored in Flash), it is advisable to copy such data to PSRAM or internal SRAM. + .. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND diff --git a/docs/en/api-reference/peripherals/spi_flash/xip_from_psram.inc b/docs/en/api-reference/peripherals/spi_flash/xip_from_psram.inc index d0af4a89be4e..e4e0a6acb380 100644 --- a/docs/en/api-reference/peripherals/spi_flash/xip_from_psram.inc +++ b/docs/en/api-reference/peripherals/spi_flash/xip_from_psram.inc @@ -3,10 +3,8 @@ XIP from PSRAM Feature ---------------------- -If :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` is enabled, the flash ``.text`` sections (used for instructions) will be placed in PSRAM. +If :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` is enabled, the flash ``.text`` sections (used for instructions) and the flash ``.rodata`` sections (used for read only data) will be placed in PSRAM. -If :ref:`CONFIG_SPIRAM_RODATA` is enabled, the flash ``.rodata`` sections (used for read only data) will be placed in PSRAM. - -The corresponding virtual memory range will be re-mapped to PSRAM. +The corresponding virtual memory range will be mapped to PSRAM. If both of the above options are enabled, the Cache won't be disabled during an SPI1 Flash operation. You don't need to make sure ISRs, ISR callbacks and involved data are placed in internal RAM. diff --git a/docs/en/api-reference/peripherals/touch_element.rst b/docs/en/api-reference/peripherals/touch_element.rst index 18bc2a377b25..8be2d2ecdccc 100644 --- a/docs/en/api-reference/peripherals/touch_element.rst +++ b/docs/en/api-reference/peripherals/touch_element.rst @@ -443,7 +443,7 @@ The Touch Element Wakeup example is available in `system/light_sleep` directory. // ESP_ERROR_CHECK(touch_element_enable_light_sleep(&sleep_config)); ESP_ERROR_CHECK(touch_element_enable_deep_sleep(button_handle[0], &sleep_config)); - // ESP_ERROR_CHECK(touch_element_sleep_enable_wakeup_calibration(button_handle[0], false)); // (optional) Disable wakeup calibration to prevent updating the baseline to a wrong value + // ESP_ERROR_CHECK(touch_element_sleep_enable_wakeup_calibration(button_handle[0], false)); // (optional) Disable wakeup calibration to prevent updating the benchmark to a wrong value touch_element_start(); diff --git a/docs/en/api-reference/peripherals/uart.rst b/docs/en/api-reference/peripherals/uart.rst index eba495f20eeb..b28bdf929ea5 100644 --- a/docs/en/api-reference/peripherals/uart.rst +++ b/docs/en/api-reference/peripherals/uart.rst @@ -68,6 +68,10 @@ Call the function :cpp:func:`uart_param_config` and pass to it a :cpp:type:`uart For more information on how to configure the hardware flow control options, please refer to :example:`peripherals/uart/uart_echo`. +.. only:: SOC_UART_SUPPORT_SLEEP_RETENTION + + Additionally, :cpp:member:`uart_config_t::backup_before_sleep` can be set to enable the backup of the UART configuration registers before entering sleep and restore these registers after exiting sleep. This allows the UART to continue working properly after waking up even when the UART module power domain is entirely off during sleep. This option implies an balance between power consumption and memory usage. If the power consumption is not a concern, you can disable this option to save memory. + Multiple Steps """""""""""""" diff --git a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_index.rst b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_index.rst index 0cff74a4668d..2d23befb42fc 100644 --- a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_index.rst +++ b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_index.rst @@ -21,12 +21,12 @@ This document is split into the following sections: usb_host_notes_design usb_host_notes_arch usb_host_notes_dwc_otg + usb_host_notes_usbh Todo: - USB Host Maintainers Notes (HAL & LL) - USB Host Maintainers Notes (HCD) -- USB Host Maintainers Notes (USBH) - USB Host Maintainers Notes (Hub) - USB Host Maintainers Notes (USB Host Library) diff --git a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_usbh.rst b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_usbh.rst new file mode 100644 index 000000000000..b1cd35fad902 --- /dev/null +++ b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_usbh.rst @@ -0,0 +1,115 @@ +USB Host Driver (USBH) +====================== + +Introduction +------------ + +The USB Host Driver (henceforth referred to as USBH) provides a USB Host software interface which abstracts USB devices. The USBH interface provides APIs to... + +- manage the device pool (i.e., adding and removing devices) +- address and configure a device (i.e., setting device and configuration descriptors) +- submit transfers to a particular endpoint of a device + +Requirements +------------ + +USB Specification Requirements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Chapter 10 of the USB 2.0 specification outlines some requirements of the USBH (referred to as USBD in the specification). The design of the USBH takes into consideration these requirements from the specification. + +- Default pipe of a device is owned by the USBH +- All other pipes are owned and managed by clients of the USBH +- USBH interface must provide the following services + + - Configuration and command mechanism + - Transfer services via both command and pipe mechanisms + - Event notification + - Status reporting and error recovery + +Host Stack Requirements +^^^^^^^^^^^^^^^^^^^^^^^ + +In addition to the USB 2.0 specification requirements, the USBH also takes into consideration the requirements set for the overall Host Stack (see :doc:`./usb_host_notes_design`): + +- USBH must not instantiate any tasks/threads +- USBH must be event driven, providing event callbacks and an event processing function + +Implementation & Usage +---------------------- + +Events & Processing +^^^^^^^^^^^^^^^^^^^ + +The USBH is completely event driven and all event handling is done via then ``usbh_process()`` function. The ``usbh_config_t.proc_req_cb`` callback provided on USBH installation will be called when processing is required. Typically, ``usbh_process()`` will be called from a dedicated thread/task. + +The USBH exposes the following event callbacks: + +- ``usbh_event_cb_t`` used to indicate various events regarding a particular device and control transfers to EP0. This callback is called from the context of ``usbh_process()`` +- ``usbh_ep_cb_t`` used to indicate events for all other endpoints. This callback is not called from the ``usbh_process()`` context (currently called from an HCD interrupt context). + +Device Pool +^^^^^^^^^^^ + +The USBH keeps track of all currently connected devices by internally maintaining a device pool (simply a linked list) where each device is represented by a device object. + +The USB 2.0 specification "assumes a specialized client of the USBD, called a hub driver, that acts as a clearinghouse for the addition and removal of devices from a particular hub". As a result, the USBH is completely reliant on an external client(s) (typically a Hub Driver) to inform the USBH of device addition and removal. The USBH provides the following APIs for device addition and removal: + +- ``usbh_devs_add()`` which will allocate a new device object and add it to the device pool. The newly added device will be unenumerated, meaning the device object will... + + - be assigned to address 0 + - have no device and configuration descriptor + +- ``usbh_devs_remove()`` which will indicate to the USBH that a device has been removed (such as due to a disconnection or a port error). + + - If the device is not currently opened (i.e., used by one or more clients), the USBH will free the underlying device object immediately. + - If the device is currently opened, a ``USBH_EVENT_DEV_GONE`` event will be propagated and the device will be flagged for removal. The last client to close the device will free the device object. + - When a device object is freed, a ``USBH_EVENT_DEV_FREE`` event will be propagated. This event is used to indicate that the device's upstream port can be recycled. + +Device Enumeration +^^^^^^^^^^^^^^^^^^ + +Newly added devices will need to be enumerated. The USBH provides various ``usbh_dev_set_...()`` functions to enumerate the device, such as assigning the device's address and setting device/configuration/string descriptors. Given that USBH devices can be shared by multiple clients, attempting to enumerate a device while another client has opened the device can cause issues. + +Thus, before calling any ``usbh_dev_set_...()`` enumeration function, a device must be locked for enumeration by calling ``usbh_dev_enum_lock()``. This prevents the device from being opened by any other client but the enumerating client. + +After enumeration is complete, the enumerating client can call ``usbh_devs_trigger_new_dev_event()`` to propagate a ``USBH_EVENT_NEW_DEV`` event. + +Device Usage +^^^^^^^^^^^^ + +Clients that want to use a device must open the device by calling ``usbh_devs_open()`` and providing the device's address. The device's address can either be obtained from a ``USBH_EVENT_NEW_DEV`` event or by calling ``usbh_devs_addr_list_fill()``. + +Opening a device will do the following: + +- Return a ``usb_device_handle_t`` device handle which can be used to refer to the device in various USBH functions +- Increment the device's internal ``open_count`` which indicates how many clients have opened the device. As long as ``open_count > 0``, the underlying device object will not be freed, thus guaranteeing that the device handle refers to a valid device object. + +Once a client no longer needs to use a device, the client should call ``usbh_devs_close()`` thus invalidating the device handle. + +.. note:: + + Most device related APIs accept ``usb_device_handle_t`` as an argument, which means that the calling client must have previously opened the device to obtain the device handle beforehand. This design choice is intentional in order to enforce an "open before use" pattern. + + However, a limited set of APIs (e.g., ``usbh_devs_remove()``) refer to devices using a Unique Identifier (``uid``) which is assigned on device addition (see ``usbh_devs_add()``). The use of ``uid`` in these functions allows their callers to refer to a device **without needing to open it** due to the lack of a ``usb_device_handle_t``. + + As a result, it is possible that a caller of a ``uid`` function may refer to a device that has already been freed. Thus, callers should account for a fact that these functions may return :c:macro:`ESP_ERR_NOT_FOUND`. + +Endpoints & Transfers +^^^^^^^^^^^^^^^^^^^^^ + +USBH supports transfer to default (i.e., EP0) and non-default endpoints. + +For non-default endpoints: + +- A client must first allocate the endpoint by calling ``usbh_ep_alloc()`` which assigns a ``usbh_ep_cb_t`` callback and returns a ``usbh_ep_handle_t`` endpoint handle so that the endpoint can be referred to. +- A client can then enqueue a ``urb_t`` transfer to the endpoint by calling ``usbh_ep_enqueue_urb()``. +- The ``usbh_ep_cb_t`` callback is called to indicate transfer completion +- The client must then dequeue the transfer using ``usbh_ep_dequeue_urb()`` + +Default endpoints are owned and managed by the USBH, thus API for control transfers are different: + +- EP0 is always allocated for each device, thus clients do no need to allocate EP0 or provide an endpoint callback. +- Clients call should call ``usbh_dev_submit_ctrl_urb()`` to submit a control transfer to a device's EP0. +- A ``USBH_EVENT_CTRL_XFER`` event will be propagated when the transfer is complete +- Control transfers do not need to be dequeued diff --git a/docs/en/api-reference/system/async_memcpy.rst b/docs/en/api-reference/system/async_memcpy.rst index d2ff7f2030ba..000e86d4a2cc 100644 --- a/docs/en/api-reference/system/async_memcpy.rst +++ b/docs/en/api-reference/system/async_memcpy.rst @@ -36,8 +36,7 @@ There are several ways to install the async memcpy driver, depending on the unde Driver configuration is described in :cpp:type:`async_memcpy_config_t`: * :cpp:member:`backlog`: This is used to configure the maximum number of memory copy transactions that can be queued up before the first one is completed. If this field is set to zero, then the default value 4 will be applied. -* :cpp:member:`sram_trans_align`: Declare SRAM alignment for both data address and copy size, set to zero if the data has no restriction in alignment. If set to a quadruple value (i.e., 4X), the driver will enable the burst mode internally, which is helpful for some performance related application. -* :cpp:member:`psram_trans_align`: Declare PSRAM alignment for both data address and copy size. User has to give it a valid value (only 16, 32, 64 are supported) if the destination of memcpy is located in PSRAM. The default alignment (i.e., 16) will be applied if it is set to zero. Internally, the driver configures the size of block used by DMA to access PSRAM, according to the alignment. +* :cpp:member:`dma_burst_size`: Set the burst size in a DMA burst transfer. * :cpp:member:`flags`: This is used to enable some special driver features. .. code-block:: c diff --git a/docs/en/api-reference/system/esp_timer.rst b/docs/en/api-reference/system/esp_timer.rst index 981780d5bae6..eb2d7456e315 100644 --- a/docs/en/api-reference/system/esp_timer.rst +++ b/docs/en/api-reference/system/esp_timer.rst @@ -5,7 +5,7 @@ ESP Timer (High Resolution Timer) {IDF_TARGET_HR_TIMER:default = "SYSTIMER", esp32 = "LAC timer"} -{IDF_TARGET_HR_TIMER_Resolution:default = "Not updated", esp32 = "64", esp32s2 = "64", esp32c3 = "52", esp32s3 = "52", esp32c2 = "52", esp32c6 = "52", esp32h2 = "52", esp32p4 = "52"} +{IDF_TARGET_HR_TIMER_Resolution:default = "Not updated", esp32 = "64", esp32s2 = "64", esp32c3 = "52", esp32s3 = "52", esp32c2 = "52", esp32c5 = "52", esp32c6 = "52", esp32h2 = "52", esp32p4 = "52"} .. only:: html diff --git a/docs/en/api-reference/system/freertos_additions.rst b/docs/en/api-reference/system/freertos_additions.rst index 832baf43b308..a4e8ea8f110f 100644 --- a/docs/en/api-reference/system/freertos_additions.rst +++ b/docs/en/api-reference/system/freertos_additions.rst @@ -97,9 +97,9 @@ The following example demonstrates the usage of :cpp:func:`xRingbufferSendAcquir //Retrieve space for DMA descriptor and corresponding data buffer //This has to be done with SendAcquire, or the address may be different when we copy - dma_item_t item; + dma_item_t *item; UBaseType_t res = xRingbufferSendAcquire(buf_handle, - &item, DMA_ITEM_SIZE(buffer_size), pdMS_TO_TICKS(1000)); + (void**) &item, DMA_ITEM_SIZE(buffer_size), pdMS_TO_TICKS(1000)); if (res != pdTRUE) { printf("Failed to acquire memory for item\n"); } @@ -108,7 +108,7 @@ The following example demonstrates the usage of :cpp:func:`xRingbufferSendAcquir .length = buffer_size, .eof = 0, .owner = 1, - .buf = &item->buf, + .buf = item->buf, }; //Actually send to the ring buffer for consumer to use res = xRingbufferSendComplete(buf_handle, &item); diff --git a/docs/en/api-reference/system/intr_alloc.rst b/docs/en/api-reference/system/intr_alloc.rst index 9d8743bfec74..19e56de49c03 100644 --- a/docs/en/api-reference/system/intr_alloc.rst +++ b/docs/en/api-reference/system/intr_alloc.rst @@ -26,6 +26,10 @@ Overview The {IDF_TARGET_NAME} has two cores, with 32 external asynchronous interrupts each. Each interrupt's priority is independently programmable. In addition, there are also 3 core local interrupt sources (CLINT) on each core. See **{IDF_TARGET_NAME} Technical Reference Manual** [`PDF <{IDF_TARGET_TRM_EN_URL}#riscvcpu>`__] for more details. +.. only:: esp32c5 + + The {IDF_TARGET_NAME} has one core, with 32 external asynchronous interrupts. Each interrupt's priority is independently programmable. In addition, there are also 3 core local interrupt sources (CLINT). For details, see **{IDF_TARGET_NAME} Technical Reference Manual** > **High-Performance CPU** [`PDF <{IDF_TARGET_TRM_EN_URL}#riscvcpu>`__]. + Because there are more interrupt sources than interrupts, sometimes it makes sense to share an interrupt in multiple drivers. The :cpp:func:`esp_intr_alloc` abstraction exists to hide all these implementation details. A driver can allocate an interrupt for a certain peripheral by calling :cpp:func:`esp_intr_alloc` (or :cpp:func:`esp_intr_alloc_intrstatus`). It can use the flags passed to this function to specify the type, priority, and trigger method of the interrupt to allocate. The interrupt allocation code will then find an applicable interrupt, use the interrupt matrix to hook it up to the peripheral, and install the given interrupt handler and ISR to it. diff --git a/docs/en/api-reference/system/mem_alloc.rst b/docs/en/api-reference/system/mem_alloc.rst index f4f47ce0c67c..5641ef8254be 100644 --- a/docs/en/api-reference/system/mem_alloc.rst +++ b/docs/en/api-reference/system/mem_alloc.rst @@ -107,7 +107,8 @@ Use the ``MALLOC_CAP_DMA`` flag to allocate memory which is suitable for use wit .. only SOC_SPIRAM_SUPPORTED and not esp32:: - The EDMA hardware feature allows DMA buffers to be placed in external PSRAM, but there may be additional alignment constraints. Consult the {IDF_TARGET_NAME} Technical Reference Manual for details. To allocate a DMA-capable external memory buffer, use the ``MALLOC_CAP_SPIRAM`` capabilities flag together with :cpp:func:`heap_caps_aligned_alloc` with the necessary alignment specified. + The EDMA hardware feature allows DMA buffers to be placed in external PSRAM, but there may be additional alignment constraints. Consult the {IDF_TARGET_NAME} Technical Reference Manual for details. To allocate a DMA-capable external memory buffer, use the ``MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA`` capabilities flags; the heap allocator will take care of alignment requirements imposed by the cache and DMA subsystems. If a peripheral has additional alignment requirements, you can use :cpp:func:`heap_caps_aligned_alloc` with the necessary alignment specified. + .. _32-bit accessible memory: diff --git a/docs/en/api-reference/system/mm_sync.rst b/docs/en/api-reference/system/mm_sync.rst index 55fb9932d1c8..fafb5a26d124 100644 --- a/docs/en/api-reference/system/mm_sync.rst +++ b/docs/en/api-reference/system/mm_sync.rst @@ -101,17 +101,6 @@ There is address and size alignment requirement (in bytes) for using :cpp:func:` By default, if you specify an unaligned address region, :cpp:func:`esp_cache_msync` will return an :c:macro:`ESP_ERR_INVALID_ARG` error, together with the required alignment. -Memory Allocation Helper ------------------------- - -cache memory synchronization is usually considered when DMA is involved. ESP-IDF provides an API to do memory allocation that can meet the alignment requirement from both the cache and the DMA. - -- :cpp:func:`esp_dma_capable_malloc`, this API allocates a chunk of memory that meets the alignment requirement from both the cache and the DMA. -- :cpp:func:`esp_dma_capable_calloc`, this API allocates a chunk of memory that meets the alignment requirement from both the cache and the DMA. The initialized value in the memory is set to zero. - -You can also use :c:macro:`ESP_DMA_MALLOC_FLAG_PSRAM` to allocate from the PSRAM. - - Warning for Address Alignment Requirement ----------------------------------------- @@ -138,9 +127,3 @@ API Reference - ESP Msync Driver -------------------------------- .. include-build-file:: inc/esp_cache.inc - - -API Reference - ESP DMA Utils ------------------------------ - -.. include-build-file:: inc/esp_dma_utils.inc diff --git a/docs/en/api-reference/system/random.rst b/docs/en/api-reference/system/random.rst index abca5925d066..4a71b1ef0b2b 100644 --- a/docs/en/api-reference/system/random.rst +++ b/docs/en/api-reference/system/random.rst @@ -5,15 +5,16 @@ Random Number Generation {IDF_TARGET_RF_NAME: default="Wi-Fi or Bluetooth", esp32s2="Wi-Fi", esp32h2="Bluetooth or 802.15.4 Thread/Zigbee", esp32c6="Wi-Fi or Bluetooth or 802.15.4 Thread/Zigbee"} {IDF_TARGET_RF_IS: default="are", esp32s2="is"} -{IDF_TARGET_BOOTLOADER_RANDOM_INCOMPATIBLE: default="", esp32="I2S, "} {IDF_TARGET_NAME} contains a hardware random number generator (RNG). You can use the APIs :cpp:func:`esp_random` and :cpp:func:`esp_fill_random` to obtained random values from it. The hardware RNG produces true random numbers so long as one or more of the following conditions are met: -- RF subsystem is enabled. i.e., {IDF_TARGET_RF_NAME} {IDF_TARGET_RF_IS} enabled. -- An internal entropy source has been enabled by calling :cpp:func:`bootloader_random_enable` and not yet disabled by calling :cpp:func:`bootloader_random_disable`. -- While the ESP-IDF :ref:`second-stage-bootloader` is running. This is because the default ESP-IDF bootloader implementation calls :cpp:func:`bootloader_random_enable` when the bootloader starts, and :cpp:func:`bootloader_random_disable` before executing the application. +.. list:: + + :SOC_WIFI_SUPPORTED or SOC_IEEE802154_SUPPORTED or SOC_BT_SUPPORTED: - RF subsystem is enabled. i.e., {IDF_TARGET_RF_NAME} {IDF_TARGET_RF_IS} enabled. + - The internal entropy source (SAR ADC) has been enabled by calling :cpp:func:`bootloader_random_enable` and not yet disabled by calling :cpp:func:`bootloader_random_disable`. + - While the ESP-IDF :ref:`second-stage-bootloader` is running. This is because the default ESP-IDF bootloader implementation calls :cpp:func:`bootloader_random_enable` when the bootloader starts, and :cpp:func:`bootloader_random_disable` before executing the application. When any of these conditions are true, samples of physical noise are continuously mixed into the internal hardware RNG state to provide entropy. Consult the **{IDF_TARGET_NAME} Technical Reference Manual** > **Random Number Generator (RNG)** [`PDF <{IDF_TARGET_TRM_EN_URL}#rng>`__] chapter for more details. @@ -22,9 +23,26 @@ If none of the above conditions are true, the output of the RNG should be consid Startup ------- -During startup, ESP-IDF bootloader temporarily enables a non-RF entropy source (internal reference voltage noise) that provides entropy for any first boot key generation. However, after the application starts executing, then normally only pseudo-random numbers are available until {IDF_TARGET_RF_NAME} {IDF_TARGET_RF_IS} initialized. +During startup, the ESP-IDF bootloader temporarily enables the non-RF internal entropy source (SAR ADC using internal reference voltage noise) that provides entropy for any first boot key generation. + +.. only:: not SOC_WIFI_SUPPORTED and not SOC_IEEE802154_SUPPORTED and not SOC_BT_SUPPORTED + + However, after the application starts executing, then normally only pseudo-random numbers are available until the internal entropy source has been enabled again. + +.. only:: SOC_WIFI_SUPPORTED or SOC_IEEE802154_SUPPORTED or SOC_BT_SUPPORTED + + However, after the application starts executing, then normally only pseudo-random numbers are available until {IDF_TARGET_RF_NAME} {IDF_TARGET_RF_IS} initialized or until the internal entropy source has been enabled again. + + +To re-enable the entropy source temporarily during application startup, or for an application that does not use {IDF_TARGET_RF_NAME}, call the function :cpp:func:`bootloader_random_enable` to re-enable the internal entropy source. The function :cpp:func:`bootloader_random_disable` must be called to disable the entropy source again before using any of the following features: + +.. list:: + + - ADC + + :esp32: - I2S -To re-enable the entropy source temporarily during application startup, or for an application that does not use {IDF_TARGET_RF_NAME}, call the function :cpp:func:`bootloader_random_enable` to re-enable the internal entropy source. The function :cpp:func:`bootloader_random_disable` must be called to disable the entropy source again before using ADC, {IDF_TARGET_BOOTLOADER_RANDOM_INCOMPATIBLE} {IDF_TARGET_RF_NAME}. + :SOC_WIFI_SUPPORTED or SOC_IEEE802154_SUPPORTED or SOC_BT_SUPPORTED: - {IDF_TARGET_RF_NAME} .. note:: diff --git a/docs/en/api-reference/system/sleep_modes.rst b/docs/en/api-reference/system/sleep_modes.rst index e3a4bc2b7934..faf68f80d74e 100644 --- a/docs/en/api-reference/system/sleep_modes.rst +++ b/docs/en/api-reference/system/sleep_modes.rst @@ -37,7 +37,7 @@ In Deep-sleep mode, the CPUs, most of the RAM, and all digital peripherals that Wi-Fi/Bluetooth and Sleep Modes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - In Deep-sleep and Light-sleep modes, the wireless peripherals are powered down. Before entering Deep-sleep or Light-sleep modes, the application must disable Wi-Fi and Bluetooth using the appropriate calls (i.e., :cpp:func:`esp_bluedroid_disable`, :cpp:func:`esp_bt_controller_disable`, :cpp:func:`esp_wifi_stop`). Wi-Fi and Bluetooth connections are not maintained in Deep-sleep or Light-sleep mode, even if these functions are not called. + In Deep-sleep and Light-sleep modes, the wireless peripherals are powered down. Before entering Deep-sleep or Light-sleep modes, the application must disable Wi-Fi and Bluetooth using the appropriate calls (i.e., :cpp:func:`nimble_port_stop`, :cpp:func:`nimble_port_deinit`, :cpp:func:`esp_bluedroid_disable`, :cpp:func:`esp_bluedroid_deinit`, :cpp:func:`esp_bt_controller_disable`, :cpp:func:`esp_bt_controller_deinit`, :cpp:func:`esp_wifi_stop`). Wi-Fi and Bluetooth connections are not maintained in Deep-sleep or Light-sleep mode, even if these functions are not called. If Wi-Fi/Bluetooth connections need to be maintained, enable Wi-Fi/Bluetooth Modem-sleep mode and automatic Light-sleep feature (see :doc:`Power Management APIs `). This allows the system to wake up from sleep automatically when required by the Wi-Fi/Bluetooth driver, thereby maintaining the connection. @@ -304,6 +304,20 @@ RTC peripherals or RTC memories do not need to be powered on during sleep in thi esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON); + .. only:: SOC_PM_SUPPORT_TOP_PD + + .. note:: + + .. only:: SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + In Light-sleep mode, if you set Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`, to continue using :cpp:func:`gpio_wakeup_enable` for GPIO wakeup, you need to first call :cpp:func:`rtc_gpio_init` and :cpp:func:`rtc_gpio_set_direction`, setting the RTCIO to input mode. + + Alternatively,you can use :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` directly in that condition for GPIO wakeup, because the digital IO power domain is being powered off, where the situation is the same as entering Deep-sleep. + + .. only:: not SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + In Light-sleep mode, if you set Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`, to continue using :cpp:func:`gpio_wakeup_enable` for GPIO wakeup, you need to first call :cpp:func:`rtc_gpio_init` and :cpp:func:`rtc_gpio_set_direction`, setting the RTCIO to input mode. + .. only:: not SOC_RTCIO_WAKE_SUPPORTED GPIO Wakeup @@ -313,11 +327,13 @@ RTC peripherals or RTC memories do not need to be powered on during sleep in thi Additionally, IOs that are powered by the VDD3P3_RTC power domain can be used to wake up the chip from Deep-sleep. The wakeup pin and wakeup trigger level can be configured by calling :cpp:func:`esp_deep_sleep_enable_gpio_wakeup`. The function will enable the Deep-sleep wakeup for the selected pin. - .. only:: esp32c6 or esp32h2 + .. only:: SOC_PM_SUPPORT_TOP_PD .. note:: - In Light-sleep mode, setting Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` will invalidate GPIO wakeup. + .. only:: SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + In Light-sleep mode, if you set Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`, you can use :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` directly for GPIO wakeup, because the digital IO power domain is being powered off, where the situation is the same as entering Deep-sleep. UART Wakeup (Light-sleep Only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/en/api-reference/system/system_time.rst b/docs/en/api-reference/system/system_time.rst index f959f1c42c5e..3713fc69b922 100644 --- a/docs/en/api-reference/system/system_time.rst +++ b/docs/en/api-reference/system/system_time.rst @@ -3,12 +3,11 @@ System Time :link_to_translation:`zh_CN:[中文]` -{IDF_TARGET_RTC_CLK_FRE:default="Not updated", esp32="150 kHz", esp32s2="90 kHz", esp32s3="136 kHz", esp32c3="136 kHz", esp32c2="136 kHz", esp32c6="150 kHz", esp32h2="150 kHz", esp32p4="150 kHz"} +{IDF_TARGET_RTC_CLK_FRE:default="Not updated", esp32="150 kHz", esp32s2="90 kHz", esp32s3="136 kHz", esp32c3="136 kHz", esp32c2="136 kHz", esp32c5="136 kHz", esp32c6="136 kHz", esp32h2="136 kHz", esp32p4="136 kHz"} {IDF_TARGET_INT_OSC_FRE:default="Not updated", esp32="8.5 MHz", esp32s2="8.5 MHz", esp32s3="17.5 MHz", esp32c3="17.5 MHz", esp32c2="17.5 MHz"} {IDF_TARGET_INT_OSC_FRE_DIVIDED:default="Not updated", esp32="about 33 kHz", esp32s2="about 33 kHz", esp32s3="about 68 kHz", esp32c3="about 68 kHz", esp32c2="about 68 kHz"} -{IDF_TARGET_EXT_CRYSTAL_PIN:default="Not updated", esp32="32K_XP and 32K_XN", esp32s2="XTAL_32K_P and XTAL_32K_N", esp32s3="XTAL_32K_P and XTAL_32K_N", esp32c3="XTAL_32K_P and XTAL_32K_N", esp32c6="XTAL_32K_P and XTAL_32K_N", esp32h2="XTAL_32K_P and XTAL_32K_N", esp32p4="XTAL_32K_P and XTAL_32K_N"} -{IDF_TARGET_EXT_OSC_PIN:default="Not updated", esp32="32K_XN", esp32s2="XTAL_32K_P", esp32s3="XTAL_32K_P", esp32c3="XTAL_32K_P", esp32c2="GPIO0", esp32c6="XTAL_32K_P", esp32h2="XTAL_32K_P", esp32p4="XTAL_32K_P"} -{IDF_TARGET_HARDWARE_DESIGN_URL:default="Not updated",esp32="`ESP32 Hardware Design Guidelines `_", esp32s2="`ESP32-S2 Hardware Design Guidelines `_", esp32s3="`ESP32-S3 Hardware Design Guidelines `_", esp32c3="`ESP32-C3 Hardware Design Guidelines `_", esp32c6="`ESP32-C6 Hardware Design Guidelines `_", esp32c2="`ESP8684 Hardware Design Guidelines `_", esp32h2="`ESP32-H2 Hardware Design Guidelines `_", esp32p4="`ESP32-P4 Hardware Design Guidelines `_"} +{IDF_TARGET_EXT_CRYSTAL_PIN:default="Not updated", esp32="32K_XP and 32K_XN", esp32s2="XTAL_32K_P and XTAL_32K_N", esp32s3="XTAL_32K_P and XTAL_32K_N", esp32c3="XTAL_32K_P and XTAL_32K_N", esp32c5="XTAL_32K_P and XTAL_32K_N", esp32c6="XTAL_32K_P and XTAL_32K_N", esp32h2="XTAL_32K_P and XTAL_32K_N", esp32p4="XTAL_32K_P and XTAL_32K_N"} +{IDF_TARGET_EXT_OSC_PIN:default="Not updated", esp32="32K_XN", esp32s2="XTAL_32K_P", esp32s3="XTAL_32K_P", esp32c3="XTAL_32K_P", esp32c2="GPIO0", esp32c5="XTAL_32K_P", esp32c6="XTAL_32K_P", esp32h2="XTAL_32K_P", esp32p4="XTAL_32K_P"} Overview @@ -51,7 +50,7 @@ The RTC timer has the following clock sources: The choice depends on your requirements for system time accuracy and power consumption in sleep modes. To modify the RTC clock source, set :ref:`CONFIG_RTC_CLK_SRC` in project configuration. -More details about the wiring requirements for the external crystal or external oscillator, please refer to {IDF_TARGET_HARDWARE_DESIGN_URL}. +More details about the wiring requirements for the external crystal or external oscillator, please refer to the `Hardware Design Guidelines `_. Get Current Time ---------------- diff --git a/docs/en/api-reference/system/ulp-lp-core.rst b/docs/en/api-reference/system/ulp-lp-core.rst index d53d6438d8ad..dd3cb7cd0c7c 100644 --- a/docs/en/api-reference/system/ulp-lp-core.rst +++ b/docs/en/api-reference/system/ulp-lp-core.rst @@ -7,7 +7,7 @@ The ULP LP-Core (Low-power core) coprocessor is a variant of the ULP present in The ULP LP-Core coprocessor has the following features: -* Utilizes a 32-bit processor based on the RISC-V ISA, encompassing the standard extensions integer (I), multiplication/division (M), atomic (A), and compressed (C). +* A RV32I (32-bit RISC-V ISA) processor, with the multiplication/division (M), atomic (A), and compressed (C) extensions. * Interrupt controller. * Includes a debug module that supports external debugging via JTAG. * Can access all of the High-power (HP) SRAM and peripherals when the entire system is active. @@ -22,6 +22,8 @@ The ULP LP-Core code is compiled together with your ESP-IDF project as a separat 2. After registering the component in the CMakeLists.txt file, call the ``ulp_embed_binary`` function. Here is an example: +.. code-block:: cmake + idf_component_register() set(ulp_app_name ulp_${COMPONENT_NAME}) @@ -32,7 +34,7 @@ The ULP LP-Core code is compiled together with your ESP-IDF project as a separat The first argument to ``ulp_embed_binary`` specifies the ULP binary name. The name specified here is also used by other generated artifacts such as the ELF file, map file, header file, and linker export file. The second argument specifies the ULP source files. Finally, the third argument specifies the list of component source files which include the header file to be generated. This list is needed to build the dependencies correctly and ensure that the generated header file is created before any of these files are compiled. See the section below for the concept of generated header files for ULP applications. -1. Enable both :ref:`CONFIG_ULP_COPROC_ENABLED` and :ref:`CONFIG_ULP_COPROC_TYPE` in menucofig, and set :ref:`CONFIG_ULP_COPROC_TYPE` to ``CONFIG_ULP_COPROC_TYPE_LP_CORE``. The :ref:`CONFIG_ULP_COPROC_RESERVE_MEM` option reserves RTC memory for the ULP, and must be set to a value big enough to store both the ULP LP-Core code and data. If the application components contain multiple ULP programs, then the size of the RTC memory must be sufficient to hold the largest one. +1. Enable both :ref:`CONFIG_ULP_COPROC_ENABLED` and :ref:`CONFIG_ULP_COPROC_TYPE` in menuconfig, and set :ref:`CONFIG_ULP_COPROC_TYPE` to ``CONFIG_ULP_COPROC_TYPE_LP_CORE``. The :ref:`CONFIG_ULP_COPROC_RESERVE_MEM` option reserves RTC memory for the ULP, and must be set to a value big enough to store both the ULP LP-Core code and data. If the application components contain multiple ULP programs, then the size of the RTC memory must be sufficient to hold the largest one. 2. Build the application as usual (e.g., ``idf.py app``). @@ -59,7 +61,7 @@ Accessing the ULP LP-Core Program Variables Global symbols defined in the ULP LP-Core program may be used inside the main program. -For example, the ULP LP-Core program may define a variable ``measurement_count`` which defines the number of GPIO measurements the program needs to make before waking up the chip from deep sleep. +For example, the ULP LP-Core program may define a variable ``measurement_count`` which defines the number of GPIO measurements the program needs to make before waking up the chip from Deep-sleep. .. code-block:: c @@ -83,7 +85,9 @@ The header file contains the declaration of the symbol: Note that all symbols (variables, arrays, functions) are declared as ``uint32_t``. For functions and arrays, take the address of the symbol and cast it to the appropriate type. -The generated linker script file defines the locations of symbols in LP_MEM:: +The generated linker script file defines the locations of symbols in LP_MEM: + +.. code-block:: none PROVIDE ( ulp_measurement_count = 0x50000060 ); @@ -97,6 +101,10 @@ To access the ULP LP-Core program variables from the main program, the generated ulp_measurement_count = 64; } +.. note:: + + Variables declared in the global scope of the LP-Core program reside in either the ``.bss`` or ``.data`` section of the binary. These sections are initialized when the LP-Core binary is loaded and executed. Accessing these variables from the main program on the HP-Core before the first LP-Core run may result in undefined behavior. + Starting the ULP LP-Core Program -------------------------------- @@ -129,7 +137,7 @@ Once the program is loaded into LP memory, the application can be configured and ULP LP-Core Program Flow ------------------------ -How the ULP LP-Core coprocessor is started depends on the wakeup source selected in :cpp:type:`ulp_lp_core_cfg_t`. The most common use-case is for the ULP to periodically wake-up, do some measurements before either waking up the main CPU or going back to sleep again. +How the ULP LP-Core coprocessor is started depends on the wake-up source selected in :cpp:type:`ulp_lp_core_cfg_t`. The most common use-case is for the ULP to periodically wake up, do some measurements before either waking up the main CPU or going back to sleep again. The ULP has the following wake-up sources: * :c:macro:`ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU` - LP Core can be woken up by the HP CPU. @@ -153,20 +161,21 @@ When the ULP is woken up, it will go through the following steps: ULP LP-Core Peripheral Support ------------------------------ -To enhance the capabilities of the ULP LP-Core coprocessor, it has access to peripherals which operate in the low-power domain. The ULP LP-Core coprocessor can interact with these peripherals when the main CPU is in sleep mode, and can wake up the main CPU once a wakeup condition is reached. The following peripherals are supported: +To enhance the capabilities of the ULP LP-Core coprocessor, it has access to peripherals that operate in the low-power domain. The ULP LP-Core coprocessor can interact with these peripherals when the main CPU is in sleep mode, and can wake up the main CPU once a wake-up condition is reached. The following peripherals are supported: .. list:: * LP IO * LP I2C * LP UART + :SOC_LP_SPI_SUPPORTED: * LP SPI .. only:: CONFIG_ESP_ROM_HAS_LP_ROM ULP LP-Core ROM --------------- - The ULP LP-Core ROM is a small pre-built piece of code located in LP-ROM, which is not modifiable by users. Similar to the bootloader ROM code ran by the main CPU, this code is executed when the ULP LP-Core coprocessor is started. The ROM code initializes the ULP LP-Core coprocessor and then jumps to the user program. The ROM code also prints boot messages if the LP UART has been initialized. + The ULP LP-Core ROM is a small pre-built piece of code located in LP-ROM, which can't be modified. Similar to the bootloader ROM code ran by the main CPU, this code is executed when the ULP LP-Core coprocessor is started. The ROM code initializes the ULP LP-Core coprocessor and then jumps to the user program. The ROM code also prints boot messages if the LP UART has been initialized. The ROM code is not executed if :cpp:member:`ulp_lp_core_cfg_t::skip_lp_rom_boot` is set to true. This is useful when you need the ULP to wake-up as quickly as possible and the extra overhead of initializing and printing is unwanted. @@ -178,13 +187,51 @@ To enhance the capabilities of the ULP LP-Core coprocessor, it has access to per Since these functions are already present in LP-ROM no matter what, using these in your program allows you to reduce the RAM footprint of your ULP application. +ULP LP-Core Interrupts +---------------------- + +The LP-Core coprocessor can be configured to handle interrupts from various sources. Examples of such interrupts could be LP IO low/high or LP timer interrupts. To register a handler for an interrupt, simply override any of the weak handlers provided by IDF. A complete list of handlers can be found in :component_file:`ulp_lp_core_interrupts.h `. For details on which interrupts are available on a specific target, please consult **{IDF_TARGET_NAME} Technical Reference Manual** [`PDF <{IDF_TARGET_TRM_EN_URL}#ulp>`__]. + +For example, to override the handler for the LP IO interrupt, you can define the following function in your ULP LP-Core code: + +.. code-block:: c + + void LP_CORE_ISR_ATTR ulp_lp_core_lp_io_intr_handler(void) + { + // Handle the interrupt and clear the interrupt source + } + +:c:macro:`LP_CORE_ISR_ATTR` is a macro that is used to define the interrupt handler function. This macro ensures that registers are saved and restored correctly when the interrupt handler is called. + +In addition to configuring the interrupt related registers for the interrupt source you want to handle, you also need to enable the interrupts globally in the LP-Core interrupt controller. This can be done using the :cpp:func:`ulp_lp_core_intr_enable` function. + +Debugging ULP LP-Core Applications +---------------------------------- + +When programming the LP-Core, it can sometimes be challenging to figure out why the program is not behaving as expected. Here are some strategies to help you debug your LP-Core program: + +* Use the LP-UART to print: the LP-Core has access to the LP-UART peripheral, which can be used for printing information independently of the main CPU sleep state. See :example:`system/ulp/lp_core/lp_uart/lp_uart_print` for an example of how to use this driver. + +* Routing :cpp:func:`lp_core_printf` to the HP-Core console UART with :ref:`CONFIG_ULP_HP_UART_CONSOLE_PRINT`. This allows you to easily print LP-Core information to the already connected HP-Core console UART. The drawback of this approach is that it requires the main CPU to be awake and since there is no synchronization between the LP and HP cores, the output may be interleaved. + +* Share program state through shared variables: as described in :ref:`ulp-lp-core-access-variables`, both the main CPU and the ULP core can easily access global variables in RTC memory. Writing state information to such a variable from the ULP and reading it from the main CPU can help you discern what is happening on the ULP core. The downside of this approach is that it requires the main CPU to be awake, which will not always be the case. Keeping the main CPU awake might even, in some cases, mask problems, as some issues may only occur when certain power domains are powered down. + +* Panic handler: the LP-Core has a panic handler that can dump the state of the LP-Core registers by the LP-UART when an exception is detected. To enable the panic handler, set the :ref:`CONFIG_ULP_PANIC_OUTPUT_ENABLE` option to ``y``. This option can be kept disabled to reduce LP-RAM usage by the LP-Core application. To recover a backtrace from the panic dump, it is possible to use esp-idf-monitor_., e.g.: + + .. code-block:: bash + + python -m esp_idf_monitor --toolchain-prefix riscv32-esp-elf- --target {IDF_TARGET_NAME} --decode-panic backtrace PATH_TO_ULP_ELF_FILE + + Application Examples -------------------- -* :example:`system/ulp/lp_core/gpio` polls GPIO while main CPU is in deep sleep. +* :example:`system/ulp/lp_core/gpio` polls GPIO while main CPU is in Deep-sleep. * :example:`system/ulp/lp_core/lp_i2c` reads external I2C ambient light sensor (BH1750) while the main CPU is in Deep-sleep and wakes up the main CPU once a threshold is met. * :example:`system/ulp/lp_core/lp_uart/lp_uart_echo` reads data written to a serial console and echoes it back. This example demonstrates the usage of the LP UART driver running on the LP core. * :example:`system/ulp/lp_core/lp_uart/lp_uart_print` shows how to print various statements from a program running on the LP core. +* :example:`system/ulp/lp_core/interrupt` shows how to register an interrupt handler on the LP core to receive an interrupt triggered by the main CPU. +* :example:`system/ulp/lp_core/gpio_intr_pulse_counter` shows how to use GPIO interrupts to count pulses while the main CPU is in Deep-sleep mode. API Reference ------------- @@ -196,6 +243,16 @@ Main CPU API Reference .. include-build-file:: inc/lp_core_i2c.inc .. include-build-file:: inc/lp_core_uart.inc +.. only:: SOC_LP_SPI_SUPPORTED + + .. include-build-file:: inc/lp_core_spi.inc + +.. only:: SOC_LP_CORE_SUPPORT_ETM + + .. include-build-file:: inc/lp_core_etm.inc + +.. include-build-file:: inc/lp_core_types.inc + LP Core API Reference ~~~~~~~~~~~~~~~~~~~~~~ @@ -204,3 +261,10 @@ LP Core API Reference .. include-build-file:: inc/ulp_lp_core_i2c.inc .. include-build-file:: inc/ulp_lp_core_uart.inc .. include-build-file:: inc/ulp_lp_core_print.inc +.. include-build-file:: inc/ulp_lp_core_interrupts.inc + +.. only:: SOC_LP_SPI_SUPPORTED + + .. include-build-file:: inc/ulp_lp_core_spi.inc + +.. _esp-idf-monitor: https://github.com/espressif/esp-idf-monitor diff --git a/docs/en/get-started/esp32p4_output_log.inc b/docs/en/get-started/esp32p4_output_log.inc index 69a66d4736d2..e8d0eb6553fc 100644 --- a/docs/en/get-started/esp32p4_output_log.inc +++ b/docs/en/get-started/esp32p4_output_log.inc @@ -1 +1,39 @@ -.. output_log \ No newline at end of file +.. output_log + + +.. code-block:: none + + ... + esptool.py v4.8.dev3 + Serial port /dev/cu.SLAB_USBtoUART + Connecting.... + Chip is ESP32-P4 (revision v0.0) + Features: High-Performance MCU + Crystal is 40MHz + MAC: 00:00:00:00:00:00 + Uploading stub... + Running stub... + Stub running... + Changing baud rate to 460800 + Changed. + Configuring flash size... + Flash will be erased from 0x00002000 to 0x00007fff... + Flash will be erased from 0x00010000 to 0x0003bfff... + Flash will be erased from 0x00008000 to 0x00008fff... + SHA digest in image updated + Compressed 20960 bytes to 12653... + Writing at 0x00002000... (100 %) + Wrote 20960 bytes (12653 compressed) at 0x00002000 in 0.6 seconds (effective 277.1 kbit/s)... + Hash of data verified. + Compressed 179584 bytes to 94528... + Writing at 0x00035efb... (100 %) + Wrote 179584 bytes (94528 compressed) at 0x00010000 in 2.6 seconds (effective 549.9 kbit/s)... + Hash of data verified. + Compressed 3072 bytes to 103... + Writing at 0x00008000... (100 %) + Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.1 seconds (effective 420.7 kbit/s)... + Hash of data verified. + + Leaving... + Hard resetting via RTS pin... + Done diff --git a/docs/en/get-started/establish-serial-connection.rst b/docs/en/get-started/establish-serial-connection.rst index 51d6ab56fe65..bce1fb158a24 100644 --- a/docs/en/get-started/establish-serial-connection.rst +++ b/docs/en/get-started/establish-serial-connection.rst @@ -141,21 +141,21 @@ Sometimes the USB-to-UART bridge is external. This is often used in small develo For the {IDF_TARGET_NAME}, the USB peripheral is available, allowing you to flash the binaries without the need for an external USB-to-UART bridge. - {IDF_TARGET_USB_PIN_DM:default="Not Updated!", esp32c3="GPIO18", esp32s3="GPIO19", esp32s2="GPIO19", esp32c6="GPIO12", esp32h2="GPIO26"} - {IDF_TARGET_USB_PIN_DP:default="Not Updated!", esp32c3="GPIO19", esp32s3="GPIO20", esp32s2="GPIO20", esp32c6="GPIO13", esp32h2="GPIO27"} + {IDF_TARGET_USB_PIN_DM:default="Not Updated!", esp32c3="GPIO18", esp32s3="GPIO19", esp32s2="GPIO19", esp32c6="GPIO12", esp32h2="GPIO26", esp32p4="GPIO24/26"} + {IDF_TARGET_USB_PIN_DP:default="Not Updated!", esp32c3="GPIO19", esp32s3="GPIO20", esp32s2="GPIO20", esp32c6="GPIO13", esp32h2="GPIO27", esp32p4="GPIO25/27"} The USB on the {IDF_TARGET_NAME} uses the **{IDF_TARGET_USB_PIN_DP}** for **D+** and **{IDF_TARGET_USB_PIN_DM}** for **D-**. - .. only:: SOC_USB_SERIAL_JTAG_SUPPORTED and not esp32s3 + .. only:: SOC_USB_SERIAL_JTAG_SUPPORTED and not esp32s3 and not esp32p4 - .. note:: The {IDF_TARGET_NAME} supports only *USB CDC and JTAG*. + .. only:: not SOC_USB_OTG_SUPPORTED - If you are flashing for the first time, you need to get the {IDF_TARGET_NAME} into the download mode manually. To do so, press and hold the ``BOOT`` button and then press the ``RESET`` button once. After that release the ``BOOT`` button. - - .. only:: esp32s3 + .. note:: The {IDF_TARGET_NAME} supports only *USB CDC and JTAG*. If you are flashing for the first time, you need to get the {IDF_TARGET_NAME} into the download mode manually. To do so, press and hold the ``BOOT`` button and then press the ``RESET`` button once. After that release the ``BOOT`` button. + For any usage for usb serial jtag, please refer to :doc:`USB_SERIAL_JTAG_CONSOLE <../api-guides/usb-serial-jtag-console>` for more information. + .. only:: esp32s2 After flashing the binaries, a manual reset is needed. @@ -348,6 +348,8 @@ To spare you the trouble of installing a serial terminal program, macOS offers t Example Output ^^^^^^^^^^^^^^ +{IDF_TARGET_STRAP_GPIO:default="[NEEDS TO BE UPDATED]", esp32="GPIO0", esp32s2="GPIO0", esp32s3="GPIO0", esp32c2="GPIO9", esp32c3="GPIO9", esp32c6="GPIO9", esp32h2="GPIO9", esp32p4="GPIO35"} + An example log is shown below. Reset the board if you do not see anything. .. highlight:: none @@ -376,7 +378,7 @@ If you can see readable log output, it means serial connection is working and yo .. note:: - For some serial port wiring configurations, the serial RTS & DTR pins need to be disabled in the terminal program before the {IDF_TARGET_NAME} booting and producing serial output. This depends on the hardware itself, most development boards (including all Espressif boards) *do not* have this issue. The issue is present if RTS & DTR are wired directly to the EN & GPIO0 pins. See the `esptool documentation`_ for more details. + For some serial port wiring configurations, the serial RTS & DTR pins need to be disabled in the terminal program before the {IDF_TARGET_NAME} booting and producing serial output. This depends on the hardware itself, most development boards (including all Espressif boards) *do not* have this issue. The issue is present if RTS & DTR are wired directly to the EN & {IDF_TARGET_STRAP_GPIO} pins. See the `esptool documentation`_ for more details. If you got here from :ref:`get-started-connect` when installing s/w for {IDF_TARGET_NAME} development, then you can continue with :ref:`get-started-configure`. diff --git a/docs/en/get-started/flashing-troubleshooting.rst b/docs/en/get-started/flashing-troubleshooting.rst index 7f0bdcc6462c..8664fe1ede6b 100644 --- a/docs/en/get-started/flashing-troubleshooting.rst +++ b/docs/en/get-started/flashing-troubleshooting.rst @@ -6,7 +6,7 @@ Flashing Troubleshooting Failed to Connect ----------------- -{IDF_TARGET_STRAP_GPIO:default="[NEEDS TO BE UPDATED]", esp32="GPIO0", esp32s2="GPIO0", esp32s3="GPIO0", esp32c2="GPIO9", esp32c3="GPIO9", esp32c6="GPIO9", esp32h2="GPIO9"} +{IDF_TARGET_STRAP_GPIO:default="[NEEDS TO BE UPDATED]", esp32="GPIO0", esp32s2="GPIO0", esp32s3="GPIO0", esp32c2="GPIO9", esp32c3="GPIO9", esp32c6="GPIO9", esp32h2="GPIO9", esp32p4="GPIO35"} If you run the given command and see errors such as "Failed to connect", there might be several reasons for this. One of the reasons might be issues encountered by ``esptool.py``, the utility that is called by the build system to reset the chip, interact with the ROM bootloader, and flash firmware. One simple solution to try is to manually reset as described below. If it does not help, you can find more details about possible issues in the `esptool troubleshooting `_ page. diff --git a/docs/en/get-started/index.rst b/docs/en/get-started/index.rst index e8869448e52c..8b3071c787a7 100644 --- a/docs/en/get-started/index.rst +++ b/docs/en/get-started/index.rst @@ -76,6 +76,14 @@ Introduction * Multiple peripherals * Built-in security hardware +.. only:: esp32p4 + + * High performance MCU with RISC-V dual-core processors + * Powerful image and voice processing capability + * Single-precision FPU and AI extensions + * Rich set of peripherals including MIPI, USB, SDIO, and Ethernet + * Built-in security hardware + Powered by 40 nm technology, {IDF_TARGET_NAME} provides a robust, highly integrated platform, which helps meet the continuous demands for efficient power usage, compact design, security, high performance, and reliability. Espressif provides basic hardware and software resources to help application developers realize their ideas using the {IDF_TARGET_NAME} series hardware. The software development framework by Espressif is intended for development of Internet-of-Things (IoT) applications with Wi-Fi, Bluetooth, power management and several other system features. @@ -114,8 +122,8 @@ If you have one of {IDF_TARGET_NAME} official development boards listed below, y :maxdepth: 1 ESP32-S2-Saola-1 <../hw-reference/esp32s2/user-guide-saola-1-v1.2> - ESP32-S2-DevKitM-1 <../hw-reference/esp32s2/user-guide-devkitm-1-v1> - ESP32-S2-DevKitC-1 <../hw-reference/esp32s2/user-guide-s2-devkitc-1> + ESP32-S2-DevKitM-1 + ESP32-S2-DevKitC-1 ESP32-S2-Kaluga-Kit <../hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit> .. only:: esp32c3 @@ -123,8 +131,8 @@ If you have one of {IDF_TARGET_NAME} official development boards listed below, y .. toctree:: :maxdepth: 1 - ESP32-C3-DevKitM-1 <../hw-reference/esp32c3/user-guide-devkitm-1> - ESP32-C3-DevKitC-02 <../hw-reference/esp32c3/user-guide-devkitc-02> + ESP32-C3-DevKitM-1 + ESP32-C3-DevKitC-02 .. only:: esp32s3 @@ -150,6 +158,10 @@ If you have one of {IDF_TARGET_NAME} official development boards listed below, y ESP32-C6-DevKitC-1 ESP32-C6-DevKitM-1 +.. only:: esp32p4 + + To be announced. + .. _get-started-get-prerequisites: Software diff --git a/docs/en/get-started/start-project.rst b/docs/en/get-started/start-project.rst index 1e837f8edd01..9826f7130c0f 100644 --- a/docs/en/get-started/start-project.rst +++ b/docs/en/get-started/start-project.rst @@ -1,6 +1,6 @@ -{IDF_TARGET_FEATURES:default="[NEEDS TO BE UPDATED]", esp32="WiFi/BT/BLE, silicon revision 1, 2 MB external flash", esp32s2="WiFi, silicon revision 0, 2 MB external flash", esp32s3="This is esp32s3 chip with 2 CPU core(s), WiFi/BLE, silicon revision 0, 2 MB external flash", esp32c2="WiFi/BLE, silicon revision 0, 2 MB embedded flash", esp32c3="WiFi/BLE, silicon revision 0, 2 MB external flash", esp32c6="WiFi/BLE, 802.15.4 (Zigbee/Thread), silicon revision v0.0, 2 MB external flash", esp32h2="BLE, 802.15.4 (Zigbee/Thread), silicon revision v0.1, 2 MB external flash"} +{IDF_TARGET_FEATURES:default="[NEEDS TO BE UPDATED]", esp32="WiFi/BT/BLE, silicon revision 1, 2 MB external flash", esp32s2="WiFi, silicon revision 0, 2 MB external flash", esp32s3="This is esp32s3 chip with 2 CPU core(s), WiFi/BLE, silicon revision 0, 2 MB external flash", esp32c2="WiFi/BLE, silicon revision 0, 2 MB embedded flash", esp32c3="WiFi/BLE, silicon revision 0, 2 MB external flash", esp32c6="WiFi/BLE, 802.15.4 (Zigbee/Thread), silicon revision v0.0, 2 MB external flash", esp32h2="BLE, 802.15.4 (Zigbee/Thread), silicon revision v0.1, 2 MB external flash", esp32p4="silicon revision v0.0, 2 MB external flash"} -{IDF_TARGET_HEAP_SIZE:default="[NEEDS TO BE UPDATED]", esp32="298968", esp32s2="253900", esp32s3="390684", esp32c2="203888", esp32c3="337332", esp32c6="473816", esp32h2="268256"} +{IDF_TARGET_HEAP_SIZE:default="[NEEDS TO BE UPDATED]", esp32="298968", esp32s2="253900", esp32s3="390684", esp32c2="203888", esp32c3="337332", esp32c6="473816", esp32h2="268256", esp32p4="618848"} Build the Project ================= @@ -72,7 +72,9 @@ Monitor the Output To check if "hello_world" is indeed running, type ``idf.py -p PORT monitor`` (Do not forget to replace PORT with your serial port name). -This command launches the :doc:`IDF Monitor <../api-guides/tools/idf-monitor>` application:: +This command launches the :doc:`IDF Monitor <../api-guides/tools/idf-monitor>` application. + +.. code-block:: bash $ idf.py -p monitor Running idf_monitor in directory [...]/esp/hello_world/build diff --git a/docs/en/get-started/windows-setup.rst b/docs/en/get-started/windows-setup.rst index b9a0ad6deead..9911b9b7c4a0 100644 --- a/docs/en/get-started/windows-setup.rst +++ b/docs/en/get-started/windows-setup.rst @@ -12,7 +12,9 @@ ESP-IDF requires some prerequisite tools to be installed so you can build firmwa For this Getting Started we are going to use the Command Prompt, but after ESP-IDF is installed you can use `Eclipse Plugin `_ or another graphical IDE with CMake support instead. .. note:: + Limitations: + - The installation path of ESP-IDF and ESP-IDF Tools must not be longer than 90 characters. Too long installation paths might result in a failed build. - The installation path of Python or ESP-IDF must not contain white spaces or parentheses. - The installation path of Python or ESP-IDF should not contain special characters (non-ASCII) unless the operating system is configured with "Unicode UTF-8" support. @@ -41,7 +43,7 @@ What Is the Usecase for Online and Offline Installer Online Installer is very small and allows the installation of all available releases of ESP-IDF. The installer downloads only necessary dependencies including `Git For Windows`_ during the installation process. The installer stores downloaded files in the cache directory ``%userprofile%\.espressif`` -Offline Installer does not require any network connection. The installer contains all required dependencies including `Git For Windows`_ . +Offline Installer does not require any network connection. The installer contains all required dependencies including `Git For Windows`_. Components of the Installation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/en/hw-reference/esp32c3/user-guide-devkitc-02.rst b/docs/en/hw-reference/esp32c3/user-guide-devkitc-02.rst deleted file mode 100644 index 61cd114383a5..000000000000 --- a/docs/en/hw-reference/esp32c3/user-guide-devkitc-02.rst +++ /dev/null @@ -1,239 +0,0 @@ -=================== -ESP32-C3-DevKitC-02 -=================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide will help you get started with ESP32-C3-DevKitC-02 and will also provide more in-depth information. - -ESP32-C3-DevKitC-02 is an entry-level development board based on `ESP32-C3-WROOM-02 `_, a general-purpose module with 4 MB SPI flash. This board integrates complete Wi-Fi and Bluetooth® Low Energy functions. - -Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can either connect peripherals with jumper wires or mount ESP32-C3-DevKitC-02 on a breadboard. - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-isometric.png - :align: center - :alt: ESP32-C3-DevKitC-02 - :figclass: align-center - - ESP32-C3-DevKitC-02 - -The document consists of the following major sections: - -- `Getting Started`_: Overview of ESP32-C3-DevKitC-02 and hardware/software setup instructions to get started. -- `Hardware Reference`_: More detailed information about the ESP32-C3-DevKitC-02's hardware. -- `Hardware Revision Details`_: Revision history, known issues, and links to user guides for previous versions (if any) of ESP32-C3-DevKitC-02. -- `Related Documents`_: Links to related documentation. - - -Getting Started -=============== - -This section provides a brief introduction of ESP32-C3-DevKitC-02, instructions on how to do the initial hardware setup and how to flash firmware onto it. - - -Description of Components -------------------------- - -.. _user-guide-c3-devkitc-02-v1-board-front: - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-annotated-photo.png - :align: center - :alt: ESP32-C3-DevKitC-02 - front - :figclass: align-center - - ESP32-C3-DevKitC-02 - front - -The key components of the board are described in a counter-clockwise direction. - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-C3-WROOM-02 - - ESP32-C3-WROOM-02 from Espressif is a powerful and general-purpose module that offers Wi-Fi and Bluetooth Low Energy coexistence. It has a PCB antenna and a 4 MB SPI flash. - * - 5 V to 3.3 V LDO - - Power regulator that converts a 5 V supply into a 3.3 V output. - * - 5 V Power On LED - - Turns on when the USB power is connected to the board. - * - Pin Headers - - All available GPIO pins (except for the SPI bus for flash) are broken out to the pin headers on the board. For details, please see :ref:`user-guide-c3-devkitc-02-v1-header-blocks`. - * - Boot Button - - Download button. Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. - * - Micro-USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32-C3 chip. - * - Reset Button - - Press this button to restart the system. - * - USB-to-UART Bridge - - Single USB-to-UART bridge chip provides transfer rates up to 3 Mbps. - * - RGB LED - - Addressable RGB LED, driven by GPIO8. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-C3-DevKitC-02, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- ESP32-C3-DevKitC-02 -- USB 2.0 cable (Standard-A to Micro-B) -- Computer running Windows, Linux, or macOS - -.. note:: - - Be sure to use an appropriate USB cable. Some cables are for charging only and do not provide the needed data lines nor work for programming the boards. - - -Software Setup -^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an application example into your ESP32-C3-DevKitC-02. - - -Contents and Packaging ----------------------- - -Retail Orders -^^^^^^^^^^^^^ - -If you order a few samples, each ESP32-C3-DevKitC-02 comes in an individual package in either antistatic bag or any packaging depending on your retailer. - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - - -Wholesale Orders -^^^^^^^^^^^^^^^^ - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Hardware Reference -================== - -Block Diagram -------------- - -The block diagram below shows the components of ESP32-C3-DevKitC-02 and their interconnections. - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-block-diags.png - :align: center - :scale: 70% - :alt: ESP32-C3-DevKitC-02 (click to enlarge) - :figclass: align-center - - ESP32-C3-DevKitC-02 (click to enlarge) - - -Power Supply Options -^^^^^^^^^^^^^^^^^^^^ - -There are three mutually exclusive ways to provide power to the board: - -- Micro-USB Port, default power supply -- 5V and GND pin headers -- 3V3 and GND pin headers - -It is recommended to use the first option: Micro-USB Port. - - -.. _user-guide-c3-devkitc-02-v1-header-blocks: - -Header Block ------------- - -The two tables below provide the **Name** and **Function** of the pin headers on both sides of the board (J1 and J3). The pin header names are shown in :ref:`user-guide-c3-devkitc-02-v1-board-front`. The numbering is the same as in the `ESP32-C3-DevKitC-02 Schematic`_ (PDF). - - -J1 -^^^ - -=== ==== ========== =================================== -No. Name Type [1]_ Function -=== ==== ========== =================================== -1 G G Ground -2 3V3 P 3.3 V power supply -3 3V3 P 3.3 V power supply -4 RST I CHIP_PU -5 G G Ground -6 4 I/O/T GPIO4, ADC1_CH4, FSPIHD, MTMS -7 5 I/O/T GPIO5, ADC2_CH0, FSPIWP, MTDI -8 6 I/O/T GPIO6, FSPICLK, MTCK -9 7 I/O/T GPIO7, FSPID, MTDO -10 G G Ground -11 8 I/O/T GPIO8 [2]_, RGB LED -12 9 I/O/T GPIO9 [2]_ -13 5V P 5 V power supply -14 5V P 5 V power supply -15 G G Ground -=== ==== ========== =================================== - - -J3 -^^^ - -=== ==== ========== ==================================== -No. Name Type [1]_ Function -=== ==== ========== ==================================== -1 G G Ground -2 0 I/O/T GPIO0, ADC1_CH0, XTAL_32K_P -3 1 I/O/T GPIO1, ADC1_CH1, XTAL_32K_N -4 2 I/O/T GPIO2 [2]_, ADC1_CH2, FSPIQ -5 3 I/O/T GPIO3, ADC1_CH3 -6 G G Ground -7 10 I/O/T GPIO10, FSPICS0 -8 G G Ground -9 RX I/O/T GPIO20, U0RXD -10 TX I/O/T GPIO21, U0TXD -11 G G Ground -12 18 I/O/T GPIO18 -13 19 I/O/T GPIO19 -14 G G Ground -15 G G Ground -=== ==== ========== ==================================== - -.. [1] P: Power supply; I: Input; O: Output; T: High impedance. -.. [2] GPIO2, GPIO8, and GPIO9 are strapping pins of the ESP32-C3 chip. These pins are used to control several chip functions depending on binary voltage values applied to the pins during chip power-up or system reset. For description and application of the strapping pins, please refer to Section Strapping Pins in `ESP32-C3 Datasheet`_. - - -Pin Layout -^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-pinout.png - :align: center - :scale: 50% - :alt: ESP32-C3-DevKitC-02 (click to enlarge) - :figclass: align-center - - ESP32-C3-DevKitC-02 Pin Layout (click to enlarge) - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -* `Build Secure and Cost-effective Connected Devices with ESP32-C3 `_ -* `ESP32-C3 Datasheet`_ (PDF) -* `ESP32-C3-WROOM-02 Datasheet`_ (PDF) -* `ESP32-C3-DevKitC-02 Schematic`_ (PDF) -* `ESP32-C3-DevKitC-02 PCB Layout `_ (PDF) -* `ESP32-C3-DevKitC-02 Dimensions `_ (PDF) -* `ESP32-C3-DevKitC-02 Dimensions source file `_ (DXF) - You can view it with `Autodesk Viewer `_ online - -For further design documentation for the board, please contact us at `sales@espressif.com `_. - - -.. _ESP32-C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _ESP32-C3-WROOM-02 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3-wroom-02_datasheet_en.pdf -.. _ESP32-C3-DevKitC-02 Schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-C3-DEVKITC-02_V1_1_20210126A.pdf diff --git a/docs/en/hw-reference/esp32c3/user-guide-devkitm-1.rst b/docs/en/hw-reference/esp32c3/user-guide-devkitm-1.rst deleted file mode 100644 index 2e9cb14e42c8..000000000000 --- a/docs/en/hw-reference/esp32c3/user-guide-devkitm-1.rst +++ /dev/null @@ -1,240 +0,0 @@ -================== -ESP32-C3-DevKitM-1 -================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide will help you get started with ESP32-C3-DevKitM-1 and will also provide more in-depth information. - -ESP32-C3-DevKitM-1 is an entry-level development board based on `ESP32-C3-MINI-1 `_, a module named for its small size. This board integrates complete Wi-Fi and Bluetooth® Low Energy functions. - -Most of the I/O pins on the ESP32-C3-MINI-1 module are broken out to the pin headers on both sides of this board for easy interfacing. Developers can either connect peripherals with jumper wires or mount ESP32-C3-DevKitM-1 on a breadboard. - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-isometric.png - :align: center - :alt: ESP32-C3-DevKitM-1 - :figclass: align-center - - ESP32-C3-DevKitM-1 - -The document consists of the following major sections: - -- `Getting Started`_: Overview of ESP32-C3-DevKitM-1 and hardware/software setup instructions to get started. -- `Hardware Reference`_: More detailed information about the ESP32-C3-DevKitM-1's hardware. -- `Hardware Revision Details`_: Revision history, known issues, and links to user guides for previous versions (if any) of ESP32-C3-DevKitM-1. -- `Related Documents`_: Links to related documentation. - - -Getting Started -=============== - -This section provides a brief introduction of ESP32-C3-DevKitM-1, instructions on how to do the initial hardware setup and how to flash firmware onto it. - - -Description of Components -------------------------- - -.. _user-guide-c3-devkitm-1-v1-board-front: - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-annotated-photo.png - :align: center - :alt: ESP32-C3-DevKitM-1 - front - :figclass: align-center - - ESP32-C3-DevKitM-1 - front - -The key components of the board are described in a counter-clockwise direction. - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-C3-MINI-1 - - ESP32-C3-MINI-1 is a general-purpose Wi-Fi and Bluetooth Low Energy combo module that comes with a PCB antenna. At the core of this module is `ESP32-C3FN4 `_, a chip that has an embedded flash of 4 MB. Since flash is packaged in the ESP32-C3FN4 chip, rather than integrated into the module, ESP32-C3-MINI-1 has a smaller package size. - * - 5 V to 3.3 V LDO - - Power regulator that converts a 5 V supply into a 3.3 V output. - * - 5 V Power On LED - - Turns on when the USB power is connected to the board. - * - Pin Headers - - All available GPIO pins (except for the SPI bus for flash) are broken out to the pin headers on the board. For details, please see :ref:`user-guide-c3-devkitm-1-v1-header-blocks`. - * - Boot Button - - Download button. Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. - * - Micro-USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32-C3FN4 chip. - * - Reset Button - - Press this button to restart the system. - * - USB-to-UART Bridge - - Single USB-UART bridge chip provides transfer rates up to 3 Mbps. - * - RGB LED - - Addressable RGB LED, driven by GPIO8. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-C3-DevKitM-1, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- ESP32-C3-DevKitM-1 -- USB 2.0 cable (Standard-A to Micro-B) -- Computer running Windows, Linux, or macOS - -.. note:: - - Be sure to use an appropriate USB cable. Some cables are for charging only and do not provide the needed data lines nor work for programming the boards. - - -Software Setup -^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an application example onto your ESP32-C3-DevKitM-1. - - -Contents and Packaging ----------------------- - -Retail Orders -^^^^^^^^^^^^^ - -If you order one or several samples, each ESP32-C3-DevKitM-1 comes in an individual package in either antistatic bag or any packaging depending on your retailer. - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - - -Wholesale Orders -^^^^^^^^^^^^^^^^ - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Hardware Reference -================== - -Block Diagram -------------- - -The block diagram below shows the components of ESP32-C3-DevKitM-1 and their interconnections. - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-block-diagram.png - :align: center - :scale: 70% - :alt: ESP32-C3-DevKitM-1 (click to enlarge) - :figclass: align-center - - ESP32-C3-DevKitM-1 (click to enlarge) - - -Power Supply Options -^^^^^^^^^^^^^^^^^^^^ - -There are three mutually exclusive ways to provide power to the board: - -- Micro-USB Port, default power supply -- 5V and GND pin headers -- 3V3 and GND pin headers - -It is recommended to use the first option: Micro-USB Port. - - -.. _user-guide-c3-devkitm-1-v1-header-blocks: - -Header Block ------------- - -The two tables below provide the **Name** and **Function** of the pin headers on both sides of the board (J1 and J3). The pin header names are shown in :ref:`user-guide-c3-devkitm-1-v1-board-front`. The numbering is the same as in the `ESP32-C3-DevKitM-1 Schematic`_ (PDF). - - -J1 -^^^ - -=== ==== ========== =================================== -No. Name Type [1]_ Function -=== ==== ========== =================================== -1 GND G Ground -2 3V3 P 3.3 V power supply -3 3V3 P 3.3 V power supply -4 IO2 I/O/T GPIO2 [2]_, ADC1_CH2, FSPIQ -5 IO3 I/O/T GPIO3, ADC1_CH3 -6 GND G Ground -7 RST I CHIP_PU -8 GND G Ground -9 IO0 I/O/T GPIO0, ADC1_CH0, XTAL_32K_P -10 IO1 I/O/T GPIO1, ADC1_CH1, XTAL_32K_N -11 IO10 I/O/T GPIO10, FSPICS0 -12 GND G Ground -13 5V P 5 V power supply -14 5V P 5 V power supply -15 GND G Ground -=== ==== ========== =================================== - - -J3 -^^^ - -=== ==== ========== ==================================== -No. Name Type [1]_ Function -=== ==== ========== ==================================== -1 GND G Ground -2 TX I/O/T GPIO21, U0TXD -3 RX I/O/T GPIO20, U0RXD -4 GND G Ground -5 IO9 I/O/T GPIO9 [2]_ -6 IO8 I/O/T GPIO8 [2]_, RGB LED -7 GND G Ground -8 IO7 I/O/T GPIO7, FSPID, MTDO -9 IO6 I/O/T GPIO6, FSPICLK, MTCK -10 IO5 I/O/T GPIO5, ADC2_CH0, FSPIWP, MTDI -11 IO4 I/O/T GPIO4, ADC1_CH4, FSPIHD, MTMS -12 GND G Ground -13 IO18 I/O/T GPIO18, USB_D- -14 IO19 I/O/T GPIO19, USB_D+ -15 GND G Ground -=== ==== ========== ==================================== - -.. [1] P: Power supply; I: Input; O: Output; T: High impedance. -.. [2] GPIO2, GPIO8, and GPIO9 are strapping pins of the ESP32-C3FN4 chip. These pins are used to control several chip functions depending on binary voltage values applied to the pins during chip power-up or system reset. For description and application of the strapping pins, please refer to Section Strapping Pins in `ESP32-C3 Datasheet`_. - - -Pin Layout -^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-pinout.png - :align: center - :scale: 45% - :alt: ESP32-C3-DevKitM-1 (click to enlarge) - - ESP32-C3-DevKitM-1 Pin Layout (click to enlarge) - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -* `Build Secure and Cost-effective Connected Devices with ESP32-C3 `_ -* `ESP32-C3 Datasheet`_ (PDF) -* `ESP32-C3-MINI-1 Datasheet`_ (PDF) -* `ESP32-C3-DevKitM-1 Schematic`_ (PDF) -* `ESP32-C3-DevKitM-1 PCB Layout`_ (PDF) -* `ESP32-C3-DevKitM-1 Dimensions`_ (PDF) -* `ESP32-C3-DevKitM-1 Dimensions source file`_ (DXF) - You can view it with `Autodesk Viewer `_ online - -For further design documentation for the board, please contact us at `sales@espressif.com `_. - -.. _ESP32-C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf -.. _ESP32-C3-MINI-1 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_en.pdf -.. _ESP32-C3-DevKitM-1 Schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-C3-DEVKITM-1_V1_20200915A.pdf -.. _ESP32-C3-DevKitM-1 PCB Layout: https://dl.espressif.com/dl/schematics/PCB_ESP32-C3-DEVKITM-1_V1_20200915AA.pdf -.. _ESP32-C3-DevKitM-1 Dimensions: https://dl.espressif.com/dl/schematics/DIMENSION_ESP32-C3-DEVKITM-1_V1_20200915AA.pdf -.. _ESP32-C3-DevKitM-1 Dimensions source file: https://dl.espressif.com/dl/schematics/DIMENSION_ESP32-C3-DEVKITM-1_V1_20200915AA.dxf diff --git a/docs/en/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst b/docs/en/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst deleted file mode 100644 index 5174afa98ee3..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst +++ /dev/null @@ -1,321 +0,0 @@ -================== -ESP32-S2-DevKitM-1 -================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide provides information on Espressif's small-sized development board ESP32-S2-DevKitM-1. - -ESP32-S2-DevKitM-1 is entry-level development board. Most of the I/O pins on the module are broken out to the pin headers on both sides for easy interfacing. Developers can either connect peripherals with jumper wires or mount ESP32-S2-DevKitM-1 on a breadboard. - -+----------------------+-----------------------+ -| |ESP32-S2-DevKitM-1| | |ESP32-S2-DevKitM-1U| | -+----------------------+-----------------------+ -| ESP32-S2-DevKitM-1 | ESP32-S2-DevKitM-1U | -+----------------------+-----------------------+ - -.. |ESP32-S2-DevKitM-1| image:: ../../../_static/esp32-s2-devkitm-1-v1-isometric.png - -.. |ESP32-S2-DevKitM-1U| image:: ../../../_static/esp32-s2-devkitm-1u-v1-isometric.png - -The document consists of the following major sections: - -- `Getting started`_: Provides an overview of the ESP32-S2-DevKitM-1 and hardware/software setup instructions to get started. -- `Hardware reference`_: Provides more detailed information about the ESP32-S2-DevKitM-1's hardware. -- `Hardware Revision Details`_: Revision history, known issues, and links to user guides for previous versions (if any) of ESP32-S2-DevKitM-1. -- `Related Documents`_: Gives links to related documentation. - - -Getting Started -=============== - -This section describes how to get started with ESP32-S2-DevKitM-1. It begins with a few introductory sections about the ESP32-S2-DevKitM-1, then Section `Start Application Development`_ provides instructions on how to get the ESP32-S2-DevKitM-1 ready and flash firmware into it. - - -Contents and Packaging ----------------------- - - -.. _user-guide-s2-devkitm-1-v1-ordering-info: - -Ordering Information -^^^^^^^^^^^^^^^^^^^^ - -The development board has a variety of variants to choose from, as shown in the table below. - -.. list-table:: - :header-rows: 1 - :widths: 41 24 9 8 18 - - * - Ordering Code - - On-board Module [#]_ - - Flash - - PSRAM - - Antenna - * - ESP32-S2-DevKitM-1-N4R2 - - ESP32-S2-MINI-2 - - (Recommended) - - 4 MB - - 2 MB - - PCB on-board antenna - * - ESP32-S2-DevKitM-1U-N4R2 - - ESP32-S2-MINI-2U - - (Recommended) - - 4 MB - - 2 MB - - External antenna connector - * - ESP32-S2-DevKitM-1 - - ESP32-S2-MINI-1 - - 4 MB - - --- - - PCB on-board antenna - * - ESP32-S2-DevKitM-1U - - ESP32-S2-MINI-1U - - 4 MB - - --- - - External antenna connector - * - ESP32-S2-DevKitM-1R - - ESP32-S2-MINI-1 - - 4 MB - - 2 MB - - PCB on-board antenna - * - ESP32-S2-DevKitM-1RU - - ESP32-S2-MINI-1U - - 4 MB - - 2 MB - - External antenna connector - - -.. [#] The ESP32-S2-MINI-2 and ESP32-S2-MINI-2U modules use chip revision v1.0, and the rest use chip revision v0.0. For more information about chip revisions, please refer to `ESP32-S2 Series SoC Errata`_. - - -Retail Orders -^^^^^^^^^^^^^ - -If you order a few samples, each ESP32-S2-DevKitM-1 comes in an individual package in either antistatic bag or any packaging depending on your retailer. - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - - -Wholesale Orders -^^^^^^^^^^^^^^^^ - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Description of Components -------------------------- - -.. _user-guide-devkitm-1-v1-board-front: - -.. figure:: ../../../_static/esp32-s2-devkitm-1-v1-annotated-photo.png - :align: center - :alt: ESP32-S2-DevKitM-1 - front - :figclass: align-center - - ESP32-S2-DevKitM-1 - front - -.. figure:: ../../../_static/esp32-s2-devkitm-1u-v1-annotated-photo.png - :align: center - :alt: ESP32-S2-DevKitM-1U - front - :figclass: align-center - - ESP32-S2-DevKitM-1U - front - -The key components of the board are described in a clockwise direction. - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - On-board module (ESP32-S2-MINI-1 or ESP32-S2-MINI-1U in figures above) - - ESP32-S2-MINI series modules with an on-board PCB antenna or a connector for an external antenna. This series of modules, known for its small size, have a flash and/or a PSRAM integrated in the chip package. For more information, please refer to :ref:`user-guide-s2-devkitm-1-v1-ordering-info`. - * - Pin Headers - - All available GPIO pins (except for the SPI bus for flash) are broken out to the pin headers on the board. Users can program ESP32-S2FH4 chip to enable multiple functions such as SPI, I2S, UART, I2C, touch sensors, PWM etc. For details, please see :ref:`user-guide-devkitm-1-v1-header-blocks`. - * - 3.3 V Power On LED - - Turns on when the USB power is connected to the board. - * - USB to UART Bridge - - Single USB-UART bridge chip provides transfer rates up to 3 Mbps. - * - Reset Button - - Reset button. - * - Micro-USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32-S2FH4 chip. - * - Boot Button - - Download button. Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. - * - RGB LED - - Addressable RGB LED, driven by GPIO18. - * - 5 V to 3.3 V LDO - - Power regulator that converts a 5 V supply into a 3.3 V output. - * - External Antenna Connector - - On **ESP32-S2-MINI-2U** and **ESP32-S2-MINI-1U** module only. For connector dimensions, please refer to Section External Antenna Connector Dimensions in module datasheet. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-S2-DevKitM-1, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- ESP32-S2-DevKitM-1 -- USB 2.0 cable (Standard-A to Micro-B) -- Computer running Windows, Linux, or macOS - -.. note:: - - Be sure to use an appropriate USB cable. Some cables are for charging only and do not provide the needed data lines nor work for programming the boards. - - -Software Setup -^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an application example into your ESP32-S2-DevKitM-1. - -.. note:: - - ESP32-S2 series of chips only is only supported in ESP-IDF master or version v4.2 and higher. - - -Hardware Reference -================== - -Block Diagram -------------- - -A block diagram below shows the components of ESP32-S2-DevKitM-1 and their interconnections. - -.. figure:: ../../../_static/esp32-s2-devkitm-1-v1-block-diagram.png - :align: center - :scale: 70% - :alt: ESP32-S2-DevKitM-1 (click to enlarge) - :figclass: align-center - - ESP32-S2-DevKitM-1 (click to enlarge) - - -Power Supply Options -^^^^^^^^^^^^^^^^^^^^ - -There are three mutually exclusive ways to provide power to the board: - -- Micro-USB Port, default power supply -- 5V and GND pin headers -- 3V3 and GND pin headers - -It is recommended to use the first option: micro USB Port. - - -.. _user-guide-devkitm-1-v1-header-blocks: - -Header Block ------------- - -The two tables below provide the **Name** and **Function** of the pin headers on both sides of the board (J1 and J3). The pin header names are shown in :ref:`user-guide-devkitm-1-v1-board-front`. The numbering is the same as in the `ESP32-S2-DevKitM-1 Schematics `_ (PDF). - - -J1 -^^^ - -=== ==== ========== ============================================================= -No. Name Type [#]_ Function -=== ==== ========== ============================================================= -1 3V3 P 3.3 V power supply -2 0 I/O/T RTC_GPIO0, GPIO0 -3 1 I/O/T RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 -4 2 I/O/T RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 -5 3 I/O/T RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2 -6 4 I/O/T RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 -7 5 I/O/T RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 -8 6 I/O/T RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 -9 7 I/O/T RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 -10 8 I/O/T RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7 -11 9 I/O/T RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, FSPIHD -12 10 I/O/T RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPICS0, FSPIIO4 -13 11 I/O/T RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPID, FSPIIO5 -14 12 I/O/T RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPICLK, FSPIIO6 -15 13 I/O/T RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIQ, FSPIIO7 -16 14 I/O/T RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIWP, FSPIDQS -17 15 I/O/T RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P -18 16 I/O/T RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N -19 17 I/O/T RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6, DAC_1 -20 5V P 5 V power supply -21 G G Ground -=== ==== ========== ============================================================= - - -J3 -^^^ - -=== ==== ===== ======================================================== -No. Name Type Function -=== ==== ===== ======================================================== -1 G G Ground -2 RST I CHIP_PU -3 46 I GPIO46 -4 45 I/O/T GPIO45 -5 RX I/O/T U0RXD, GPIO44, CLK_OUT2 -6 TX I/O/T U0TXD, GPIO43, CLK_OUT1 -7 42 I/O/T MTMS, GPIO42 -8 41 I/O/T MTDI, GPIO41, CLK_OUT1 -9 40 I/O/T MTDO, GPIO40, CLK_OUT2 -10 39 I/O/T MTCK, GPIO39, CLK_OUT3 -11 38 I/O/T GPIO38, FSPIWP -12 37 I/O/T SPIDQS, GPIO37, FSPIQ -13 36 I/O/T SPIIO7, GPIO36, FSPICLK -14 35 I/O/T SPIIO6, GPIO35, FSPID -15 34 I/O/T SPIIO5, GPIO34, FSPICS0 -16 33 I/O/T SPIIO4, GPIO33, FSPIHD -17 26 I/O/T SPICS1, GPIO26 -18 21 I/O/T RTC_GPIO21, GPIO21 -19 20 I/O/T RTC_GPIO20, GPIO20, U1CTS, ADC2_CH9, CLK_OUT1, USB_D+ -20 19 I/O/T RTC_GPIO19, GPIO19, U1RTS, ADC2_CH8, CLK_OUT2, USB_D- -21 18 I/O/T RTC_GPIO18, GPIO18, U1RXD, ADC2_CH7, DAC_2, CLK_OUT3, RGB LED -=== ==== ===== ======================================================== - -.. [#] P: Power supply; I: Input; O: Output; T: High impedance. - - -Pin Layout -^^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-s2-devkitm-1-v1-pin-layout.png - :align: center - :scale: 15% - :alt: ESP32-S2-DevKitM-1 (click to enlarge) - :figclass: align-center - - ESP32-S2-DevKitM-1 Pin Layout (click to enlarge) - - -Hardware Revision Details -========================= - -This is the first revision of this board released. - - -Related Documents -================= - -* `ESP32-S2 Series Chip Revision v1.0 Datasheet`_ (PDF) -* `ESP32-S2 Series Chip Revision v0.0 Datasheet `_ (PDF) -* `ESP32-S2 Series SoC Errata`_ (PDF) -* `ESP32-S2-MINI-2 & ESP32-S2-MINI-2U Module Datasheet `_ (PDF) -* `ESP32-S2-MINI-1 & ESP32-S2-MINI-1U Module Datasheet `_ (PDF) -* `ESP32-S2-DevKitM-1 Schematics `_ (PDF) -* `ESP32-S2-DevKitM-1 PCB Layout `_ (PDF) -* `ESP32-S2-DevKitM-1 Dimensions `_ (PDF) -* `ESP Product Selector `_ - -For other design documentation for the board, please contact us at `sales@espressif.com `_. - -.. _NRND: https://www.espressif.com/en/products/longevity-commitment?id=nrnd -.. _ESP32-S2 Series Chip Revision v1.0 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s2-v1.0_datasheet_en.pdf -.. _ESP32-S2 Series SoC Errata: https://espressif.com/sites/default/files/documentation/esp32-s2_errata_en.pdf diff --git a/docs/en/hw-reference/esp32s2/user-guide-s2-devkitc-1.rst b/docs/en/hw-reference/esp32s2/user-guide-s2-devkitc-1.rst deleted file mode 100644 index d14331f64b97..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-s2-devkitc-1.rst +++ /dev/null @@ -1,313 +0,0 @@ -================== -ESP32-S2-DevKitC-1 -================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide will help you get started with ESP32-S2-DevKitC-1 and will also provide more in-depth information. - -ESP32-S2-DevKitC-1 is an entry-level development board. This board integrates complete Wi-Fi functions. Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can either connect peripherals with jumper wires or mount ESP32-S2-DevKitC-1 on a breadboard. - -.. figure:: ../../../_static/esp32-s2-devkitc-1-v1-isometric.png - :align: center - :alt: ESP32-S2-DevKitC-1 with the ESP32-S2-SOLO Module - :figclass: align-center - - ESP32-S2-DevKitC-1 with the ESP32-S2-SOLO Module - -The document consists of the following major sections: - -- `Getting Started`_: Overview of ESP32-S2-DevKitC-1 and hardware/software setup instructions to get started. -- `Hardware Reference`_: More detailed information about the ESP32-S2-DevKitC-1's hardware. -- `Hardware Revision Details`_: Revision history, known issues, and links to user guides for previous versions (if any) of ESP32-S2-DevKitC-1. -- `Related Documents`_: Links to related documentation. - - -Getting Started -=============== - -This section provides a brief introduction of ESP32-S2-DevKitC-1, instructions on how to do the initial hardware setup and how to flash firmware onto it. - - -Description of Components -------------------------- - -.. _user-guide-s2-devkitc-1-v1-board-front: - -.. figure:: ../../../_static/esp32-s2-devkitc-1-v1-annotated-photo.png - :align: center - :alt: ESP32-S2-DevKitC-1 - front - :figclass: align-center - - ESP32-S2-DevKitC-1 - front - -The key components of the board are described in a clockwise direction. - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - On-board module (ESP32-S2-SOLO or ESP32-S2-SOLO-U in the above figure) - - ESP32-S2-SOLO series modules with an on-board PCB antenna or a connector for an external antenna. This series of modules have multiple options for flash and PSRAM size. For more information, please refer to :ref:`user-guide-s2-devkitc-1-v1-ordering-info`. - * - 3.3 V Power On LED - - Turns on when the USB power is connected to the board. - * - USB-to-UART Bridge - - Single USB-to-UART bridge chip provides transfer rates up to 3 Mbps. - * - Pin Headers - - All available GPIO pins (except for the SPI bus for flash) are broken out to the pin headers on the board. For details, please see :ref:`user-guide-s2-devkitc-1-v1-header-blocks`. - * - ESP32-S2 USB Port - - ESP32-S2 full-speed USB OTG interface, compliant with the USB 1.1 specifications. The interface is used for power supply to the board, for flashing applications to the chip, and for communication with the chip using USB 1.1 protocols. - * - Reset Button - - Press this button to restart the system. - * - Boot Button - - Download button. Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. - * - USB-to-UART Port - - A Micro-USB port used for power supply to the board, for flashing applications to the chip, as well as the communication with the chip via the on-board USB-to-UART bridge. - * - RGB LED - - Addressable RGB LED, driven by GPIO18. - * - 5 V to 3.3 V LDO - - Power regulator that converts a 5 V supply into a 3.3 V output. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-S2-DevKitC-1, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- ESP32-S2-DevKitC-1 -- USB 2.0 cable (Standard-A to Micro-B) -- Computer running Windows, Linux, or macOS - -.. note:: - - Be sure to use an appropriate USB cable. Some cables are for charging only and do not provide the needed data lines nor work for programming the boards. - - -Hardware Setup -^^^^^^^^^^^^^^ - -Connect the board with the computer using **USB-to-UART Port** or **ESP32-S2 USB Port**. In subsequent steps, **USB-to-UART Port** will be used by default. - - -Software Setup -^^^^^^^^^^^^^^ - -Please proceed to `ESP-IDF Get Started `_, where Section `Installation Step by Step `_ will quickly help you set up the development environment and then flash an application example into your ESP32-S2-DevKitC-1. - - -Contents and Packaging ----------------------- - -.. _user-guide-s2-devkitc-1-v1-ordering-info: - -Ordering Information -^^^^^^^^^^^^^^^^^^^^ - -The development board has a variety of variants to choose from, as shown in the table below. - -.. list-table:: - :header-rows: 1 - :widths: 41 24 9 8 18 - - * - Ordering Code - - On-board Module [#]_ - - Flash - - PSRAM - - Antenna - * - ESP32-S2-DevKitC-1-N8R2 - - ESP32-S2-SOLO-2 - - (Recommended) - - 8 MB - - 2 MB - - PCB on-board antenna - * - ESP32-S2-DevKitC-1U-N8R2 - - ESP32-S2-SOLO-2U - - (Recommended) - - 8 MB - - 2 MB - - External antenna connector - * - ESP32-S2-DevKitC-1 - - ESP32-S2-SOLO - - 4 MB - - --- - - PCB on-board antenna - * - ESP32-S2-DevKitC-1U - - ESP32-S2-SOLO-U - - 4 MB - - --- - - External antenna connector - * - ESP32-S2-DevKitC-1R - - ESP32-S2-SOLO - - 4 MB - - 2 MB - - PCB on-board antenna - * - ESP32-S2-DevKitC-1RU - - ESP32-S2-SOLO-U - - 4 MB - - 2 MB - - External antenna connector - -.. [#] The ESP32-S2-SOLO-2 and ESP32-S2-SOLO-2U modules use chip revision v1.0, and the rest use chip revision v0.0. For more information about chip revisions, please refer to `ESP32-S2 Series SoC Errata`_. - - -Retail Orders -^^^^^^^^^^^^^ - -If you order a few samples, each ESP32-S2-DevKitC-1 comes in an individual package in either antistatic bag or any packaging depending on your retailer. - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - - -Wholesale Orders -^^^^^^^^^^^^^^^^ - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Hardware Reference -================== - -Block Diagram -------------- - -The block diagram below shows the components of ESP32-S2-DevKitC-1 and their interconnections. - -.. figure:: ../../../_static/esp32-s2-devkitc-1-v1-block-diags.png - :align: center - :scale: 70% - :alt: ESP32-S2-DevKitC-1 (click to enlarge) - :figclass: align-center - - ESP32-S2-DevKitC-1 (click to enlarge) - - -Power Supply Options -^^^^^^^^^^^^^^^^^^^^ - -There are three mutually exclusive ways to provide power to the board: - -- USB-to-UART Port and ESP32-S2 USB Port (either one or both), default power supply (recommended) -- 5V and G (GND) pins -- 3V3 and G (GND) pins - - -.. _user-guide-s2-devkitc-1-v1-header-blocks: - -Header Block ------------- - -The two tables below provide the **Name** and **Function** of the pin headers on both sides of the board (J1 and J3). The pin header names are shown in :ref:`user-guide-s2-devkitc-1-v1-board-front`. The numbering is the same as in the `ESP32-S2-DevKitC-1 Schematic`_ (PDF). - - -J1 -^^^ - -=== ========= ========== ========================================================================== -No. Name Type [#]_ Function -=== ========= ========== ========================================================================== -1 3V3 P 3.3 V power supply -2 3V3 P 3.3 V power supply -3 RST I CHIP_PU -4 4 I/O/T RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 -5 5 I/O/T RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 -6 6 I/O/T RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 -7 7 I/O/T RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 -8 15 I/O/T RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P -9 16 I/O/T RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N -10 17 I/O/T RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6, DAC_1 -11 18 [#]_ I/O/T RTC_GPIO18, GPIO18, U1RXD, ADC2_CH7, DAC_2, CLK_OUT3, RGB LED -12 8 I/O/T RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7 -13 3 I/O/T RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2 -14 46 I GPIO46 -15 9 I/O/T RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, FSPIHD -16 10 I/O/T RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPICS0, FSPIIO4 -17 11 I/O/T RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPID, FSPIIO5 -18 12 I/O/T RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPICLK, FSPIIO6 -19 13 I/O/T RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIQ, FSPIIO7 -20 14 I/O/T RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIWP, FSPIDQS -21 5V P 5 V power supply -22 G G Ground -=== ========= ========== ========================================================================== - - -J3 -^^^ - -=== ==== ===== ============================================================ -No. Name Type Function -=== ==== ===== ============================================================ -1 G G Ground -2 TX I/O/T U0TXD, GPIO43, CLK_OUT1 -3 RX I/O/T U0RXD, GPIO44, CLK_OUT2 -4 1 I/O/T RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 -5 2 I/O/T RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 -6 42 I/O/T MTMS, GPIO42 -7 41 I/O/T MTDI, GPIO41, CLK_OUT1 -8 40 I/O/T MTDO, GPIO40, CLK_OUT2 -9 39 I/O/T MTCK, GPIO39, CLK_OUT3 -10 38 I/O/T GPIO38, FSPIWP -11 37 I/O/T SPIDQS, GPIO37, FSPIQ -12 36 I/O/T SPIIO7, GPIO36, FSPICLK -13 35 I/O/T SPIIO6, GPIO35, FSPID -14 0 I/O/T RTC_GPIO0, GPIO0 -15 45 I/O/T GPIO45 -16 34 I/O/T SPIIO5, GPIO34, FSPICS0 -17 33 I/O/T SPIIO4, GPIO33, FSPIHD -18 21 I/O/T RTC_GPIO21, GPIO21 -19 20 I/O/T RTC_GPIO20, GPIO20, U1CTS, ADC2_CH9, CLK_OUT1, USB_D+ -20 19 I/O/T RTC_GPIO19, GPIO19, U1RTS, ADC2_CH8, CLK_OUT2, USB_D- -21 G G Ground -22 G G Ground -=== ==== ===== ============================================================ - -.. [#] P: Power supply; I: Input; O: Output; T: High impedance. -.. [#] GPIO18 is not pulled up on boards with an ESP32-S2-SOLO-2 or ESP32-S2-SOLO-2U module. - - -Pin Layout -^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-s2-devkitc-1-v1-pinout.png - :align: center - :scale: 45% - :alt: ESP32-S2-DevKitC-1 (click to enlarge) - :figclass: align-center - - ESP32-S2-DevKitC-1 Pin Layout (click to enlarge) - - -Hardware Revision Details -========================= - -This is the first revision of this board released. - - -Related Documents -================= - -* `ESP32-S2 Series Chip Revision v1.0 Datasheet`_ (PDF) -* `ESP32-S2 Series Chip Revision v0.0 Datasheet `_ (PDF) -* `ESP32-S2 Series SoC Errata`_ (PDF) -* `ESP32-S2-SOLO-2 & ESP32-S2-SOLO-2U Module Datasheet `_ (PDF) -* `ESP32-S2-SOLO & ESP32-S2-SOLO-U Module Datasheet `_ (PDF) -* `ESP32-S2-DevKitC-1 Schematic`_ (PDF) -* `ESP32-S2-DevKitC-1 PCB Layout `_ (PDF) -* `ESP32-S2-DevKitC-1 Dimensions `_ (PDF) -* `ESP32-S2-DevKitC-1 Dimensions source file `_ (DXF) - You can view it with `Autodesk Viewer `_ online - -For further design documentation for the board, please contact us at `sales@espressif.com `_. - -.. _NRND: https://www.espressif.com/en/products/longevity-commitment?id=nrnd -.. _ESP32-S2 Series Chip Revision v1.0 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s2-v1.0_datasheet_en.pdf -.. _ESP32-S2 Series SoC Errata: https://espressif.com/sites/default/files/documentation/esp32-s2_errata_en.pdf -.. _ESP32-S2-DevKitC-1 Schematic: https://dl.espressif.com/dl/schematics/esp-idf/SCH_ESP32-S2-DEVKITC-1_V1_20220817.pdf diff --git a/docs/en/hw-reference/index.rst b/docs/en/hw-reference/index.rst index 29f262c063b4..3f8b92b1439a 100644 --- a/docs/en/hw-reference/index.rst +++ b/docs/en/hw-reference/index.rst @@ -15,6 +15,7 @@ Hardware Reference :esp32c3: Chip Datasheet (PDF) :esp32c6: Chip Datasheet (PDF) :esp32h2: Chip Datasheet (PDF) + :esp32p4: Chip Datasheet (PDF) :esp32: Hardware Design Guidelines (PDF) :esp32s2: Hardware Design Guidelines (PDF) :esp32s3: Hardware Design Guidelines (PDF) @@ -22,11 +23,14 @@ Hardware Reference :esp32c3: Hardware Design Guidelines (PDF) :esp32c6: Hardware Design Guidelines (PDF) :esp32h2: Hardware Design Guidelines (PDF) + :esp32p4: Hardware Design Guidelines (PDF) :esp32: Silicon Errata (PDF) :esp32s2: Silicon Errata (PDF) :esp32s3: Silicon Errata (PDF) :esp32c3: Silicon Errata (PDF) :esp32c2: Silicon Errata (PDF) + :esp32c6: Silicon Errata (PDF) + :esp32h2: Silicon Errata (PDF) Chip Variants Modules Development Boards diff --git a/docs/en/migration-guides/release-5.x/5.0/networking.rst b/docs/en/migration-guides/release-5.x/5.0/networking.rst index ba52226cac47..bf778800362e 100644 --- a/docs/en/migration-guides/release-5.x/5.0/networking.rst +++ b/docs/en/migration-guides/release-5.x/5.0/networking.rst @@ -140,6 +140,8 @@ All the ``tcpip_adapter`` functions have their ``esp-netif`` counter-part. Pleas * :component_file:`DNS ` * :component_file:`IP address ` +The TCP/IP Adapter API ``tcpip_adapter_get_sta_list()`` that was used to acquire a list of associated Wi-Fi stations to the Software Access Point (softAP) has been moved to the Wi-Fi component and renamed to :cpp:func:`esp_wifi_ap_get_sta_list_with_ip()`, which is a special case of the ESP-NETIF API :cpp:func:`esp_netif_dhcps_get_clients_by_mac()` that could be used more generally to provide a list of clients connected to a DHCP server no matter which network interface the server is running on. + Default Event Handlers ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/en/security/secure-boot-v2.rst b/docs/en/security/secure-boot-v2.rst index 039c70c0b3e9..f0a85e272265 100644 --- a/docs/en/security/secure-boot-v2.rst +++ b/docs/en/security/secure-boot-v2.rst @@ -11,11 +11,11 @@ Secure Boot V2 {IDF_TARGET_ECO_VERSION:default="", esp32="(ECO 3 onwards)", esp32c3="(ECO 3 onwards)"} -{IDF_TARGET_RSA_TIME:default="", esp32c6="~2.7 ms", esp32h2="~4.5 ms"} +{IDF_TARGET_RSA_TIME:default="", esp32c6="~2.7 ms", esp32h2="~4.5 ms", esp32p4="~2.4 ms"} -{IDF_TARGET_ECDSA_TIME:default="", esp32c6="~21.5 ms", esp32h2="~36 ms"} +{IDF_TARGET_ECDSA_TIME:default="", esp32c6="~21.5 ms", esp32h2="~36 ms", esp32p4="~10.3 ms"} -{IDF_TARGET_CPU_FREQ:default="", esp32c6="160 MHz", esp32h2="96 MHz"} +{IDF_TARGET_CPU_FREQ:default="", esp32c6="160 MHz", esp32h2="96 MHz", esp32p4="360 MHz"} {IDF_TARGET_SBV2_DEFAULT_SCHEME:default="RSA", esp32c2="ECDSA (V2)"} diff --git a/docs/zh_CN/api-guides/core_dump.rst b/docs/zh_CN/api-guides/core_dump.rst index 83e4e8af77b5..27505a327074 100644 --- a/docs/zh_CN/api-guides/core_dump.rst +++ b/docs/zh_CN/api-guides/core_dump.rst @@ -56,8 +56,26 @@ ELF 格式具备扩展特性,支持在发生崩溃时保存更多关于错误 .. note:: - 如果使用了独立的栈,建议栈大小应大于 800 字节,确保核心转储例程本身不会导致栈溢出。 + 如果使用了独立的栈,建议栈大小应大于 1300 字节,确保核心转储例程本身不会导致栈溢出。 +.. only:: not esp32c5 + + 核心转储内存区域 + ^^^^^^^^^^^^^^^^ + + 核心转储默认保存 CPU 寄存器、任务数据和崩溃原因。选择 :ref:`CONFIG_ESP_COREDUMP_CAPTURE_DRAM` 选项后,``.bss`` 段和 ``.data`` 段以及 ``heap`` 数据也将保存到转储中。 + + 推荐将上面提到的几个数据段都保存到核心转储中,以方便调试。但这会导致核心转储文件变大,具体所需的额外存储空间取决于应用程序使用的 DRAM 大小。 + + .. only:: SOC_SPIRAM_SUPPORTED + + .. note:: + + 除了崩溃任务的 TCB 和栈外,位于外部 RAM 中的数据不会保存到核心转储文件中,包括使用 ``EXT_RAM_BSS_ATTR`` 或 ``EXT_RAM_NOINIT_ATTR`` 属性定义的变量,以及存储在 ``extram_bss`` 段中的任何数据。 + + .. note:: + + 该功能仅在使用 ELF 文件格式时可用。 将核心转储保存到 flash ----------------------- diff --git a/docs/zh_CN/api-guides/external-ram.rst b/docs/zh_CN/api-guides/external-ram.rst index cfd851fdd40d..864623b31162 100644 --- a/docs/zh_CN/api-guides/external-ram.rst +++ b/docs/zh_CN/api-guides/external-ram.rst @@ -55,8 +55,7 @@ ESP-IDF 完全支持将片外 RAM 集成到你的应用程序中。在启动并 * :ref:`external_ram_config_malloc` (default) * :ref:`external_ram_config_bss` :esp32: * :ref:`external_ram_config_noinit` - :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_instructions` - :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_rodata` + :SOC_SPIRAM_XIP_SUPPORTED: * :ref:`external_ram_config_xip` .. _external_ram_config_memory_map: @@ -82,7 +81,7 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 在 :ref:`CONFIG_SPIRAM_USE` 中选择 ``Make RAM allocatable using heap_caps_malloc(..., MALLOC_CAP_SPIRAM)`` 选项。 -启用上述选项后,片外 RAM 被映射到数据虚拟地址空间,并将这个区域添加到携带 ``MALLOC_CAP_SPIRAM`` 标志的 :doc:`堆内存分配器 ` 。 +启用上述选项后,片外 RAM 被映射到数据虚拟地址空间,并将这个区域添加到携带 ``MALLOC_CAP_SPIRAM`` 标志的 :doc:`堆内存分配器 `。 程序如果想从片外存储器分配存储空间,则需要调用 ``heap_caps_malloc(size, MALLOC_CAP_SPIRAM)``,之后可以调用 ``free()`` 函数释放这部分存储空间。 @@ -114,7 +113,7 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` 启用该选项。 -启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储来自 lwip、net80211、libpp, wpa_supplicant 和 bluedroid ESP-IDF 库中零初始化的数据(BSS 段)。 +启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储来自 lwip、net80211、libpp、wpa_supplicant 和 bluedroid ESP-IDF 库中零初始化的数据(BSS 段)。 通过将宏 ``EXT_RAM_BSS_ATTR`` 应用于任何静态声明(未初始化为非零值),可以将附加数据从内部 BSS 段移到片外 RAM。 @@ -137,35 +136,54 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 .. only:: SOC_SPIRAM_XIP_SUPPORTED - .. _external_ram_config_instructions: + .. only:: esp32s2 or esp32s3 - 将 flash 中的指令移至 PSRAM - ----------------------------------- + 将 flash 中的指令移至 PSRAM + ----------------------------------- - 启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后,flash 中 ``.text`` 部分的数据(用于指令)将被放入 PSRAM。 + 启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后,flash 中 ``.text`` 部分的数据(用于指令)将被放入 PSRAM。 - 启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后: + 启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后: - - flash ``.text`` 部分中的指令将在系统启动时移至 PSRAM。 + - flash ``.text`` 部分中的指令将在系统启动时移至 PSRAM。 - - 上述指令对应的虚拟内存范围也将重新映射至 PSRAM。 + - 上述指令对应的虚拟内存范围也将重新映射至 PSRAM。 - 如果同时启用 :ref:`CONFIG_SPIRAM_RODATA`,SPI1 flash 操作期间不会禁用 cache。ISR、ISR 回调和相关数据无需放在内部 RAM 中,因此可以优化内部 RAM 的使用。 + 将 flash 中的只读数据移至 PSRAM + --------------------------------------- - .. _external_ram_config_rodata: + 启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后,flash 中 ``.rodata`` 部分的数据(用于只读数据)将被放入 PSRAM。 - 将 flash 中的只读数据移至 PSRAM - --------------------------------------- + 启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后: - 启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后,flash 中 ``.rodata`` 部分的数据(用于只读数据)将被放入 PSRAM。 + - flash ``.rodata`` 部分中的指令将在系统启动时移至 PSRAM。 - 启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后: + - 上述只读数据对应的虚拟内存范围也将重新映射至 PSRAM。 - - flash ``.rodata`` 部分中的指令将在系统启动时移至 PSRAM。 + .. _external_ram_config_xip: - - 上述只读数据对应的虚拟内存范围也将重新映射至 PSRAM。 + 在 PSRAM 中直接执行代码 + ------------------------------------ + + 启用 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` 选项后,可同时指定 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 和 :ref:`CONFIG_SPIRAM_RODATA` 选项。 + + 在 PSRAM 中直接执行代码的好处包括: + + - PSRAM 访问速度快于 flash,因此性能更好。 + + - 在进行 SPI1 flash 操作期间,cache 仍然保持启用状态,这样可以优化代码执行性能。由于无需把中断服务程序 (ISR)、ISR 回调和在此期间可能被访问的数据放置在片上 RAM 中,片上 RAM 可用于其他用途,从而提高了使用效率。这个特性适用于需要处理大量数据的高吞吐量外设应用,能显著提高 SPI1 flash 操作期间的性能。 + + .. only:: esp32p4 + + .. _external_ram_config_xip: + + 在 PSRAM 中直接执行代码 + ------------------------------------ + + 启用 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` 选项后能在 PSRAM 中直接执行代码。通常放置在 flash 中的段,如 ``.text`` 部分的数据(用于指令)和 ``.rodata`` 部分的数据(用于只读数据),将被加载到 PSRAM 中。 + + 启用此选项后,SPI1 flash 操作期间 cache 保持启用状态,因此需要执行的代码在此期间不必放置在内部 RAM 中。由于 ESP32-P4 flash 和 PSRAM 使用两个独立的 SPI 总线,将 flash 内容移动到 PSRAM 实际上增加了 PSRAM MSPI 总线的负载,因此整体性能将取决于应用程序对 PSRAM 的使用。例如,因为 PSRAM 的总线速度可能远大于 flash 总线速度,如果那些之前存放在 flash 中的指令和只读数据(现在存放于 PSRAM 中)不被经常访问,那么整体性能将有可能更好。因此,建议先进行性能分析以确定启用此选项是否会显著影响应用程序性能。 - 如果同时启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS`,SPI1 flash 操作期间不会禁用 cache。ISR、ISR 回调和相关数据无需放在内部 RAM 中,因此可以优化内部 RAM 的使用。 片外 RAM 使用限制 =================== @@ -192,7 +210,7 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 初始化失败 -===================== +==================== 默认情况下,片外 RAM 初始化失败将终止 ESP-IDF 启动。如果想禁用此功能,可启用 :ref:`CONFIG_SPIRAM_IGNORE_NOTFOUND` 配置选项。 @@ -206,7 +224,7 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 加密 ========== - 可以为存储在外部 RAM 中的数据启用自动加密功能。启用该功能后,通过缓存读写的任何数据将被外部存储器加密硬件自动加密/解密。 + 可以为存储在外部 RAM 中的数据启用自动加密功能。启用该功能后,通过缓存读写的任何数据将被外部存储器加密硬件自动加密、解密。 只要启用了 flash 加密功能,就会启用这个功能。关于如何启用 flash 加密以及其工作原理,请参考 :doc:`/security/flash-encryption`。 diff --git a/docs/zh_CN/api-guides/hlinterrupts.rst b/docs/zh_CN/api-guides/hlinterrupts.rst index 8d0c48140f6b..7f78e1a3d9cc 100644 --- a/docs/zh_CN/api-guides/hlinterrupts.rst +++ b/docs/zh_CN/api-guides/hlinterrupts.rst @@ -77,8 +77,8 @@ Xtensa 架构支持 32 个中断处理程序,这些中断分为从 1 到 7 的 .. code-block:: none .section .iram1,"ax" - .global xt_highint5 - .type xt_highint5,@function + .global xt_highint4 + .type xt_highint4,@function .align 4 xt_highint5: ... your code here diff --git a/docs/zh_CN/api-guides/low-power-mode.rst b/docs/zh_CN/api-guides/low-power-mode.rst index c18605473a70..a1fd881f0fe5 100644 --- a/docs/zh_CN/api-guides/low-power-mode.rst +++ b/docs/zh_CN/api-guides/low-power-mode.rst @@ -743,3 +743,293 @@ Deep-sleep 有如下可配置选项: .. only:: esp32c2 平均电流约 4.9 μA + +.. only:: esp32c6 + + 目标唤醒时间 (TWT) + ---------------------------------- + + 目标唤醒时间 (Target Wake Time, TWT) 是 Wi-Fi 6 中引入的一项特性,旨在降低设备功耗和提高网络效率。 + + 在以往的 Wi-Fi 节能机制中,设备可能需要在每个 DTIM 周期醒来与 AP 交换数据,而在 TWT 机制中支持 AP 和设备协商得到特定的唤醒时间,设备会在这些时间点醒来与 AP 进行数据交换,而其余时间则处于休眠状态。TWT 协商的唤醒和休眠时间取决于设备具体的应用需求。例如,有些传感器设备需要定时上传数据,在该场景下设备可以与 AP 建立 TWT 协商,相隔多个小时交换一次数据。实际应用中可根据具体需求定制唤醒时间,在不影响设备正常工作的情况下降低功耗。 + + AP 可以与多个设备建立 TWT 协商。利用 Wi-Fi 6 的多用户特性,AP 可以对上行和下行数据传输做出合理协调,从而减少信道竞争,提高传输效率。 + + TWT 类型 + ++++++++++ + + 根据协商类型和工作模式,可以把 TWT 分为: + + - **Individual TWT (iTWT)** + + iTWT 模式下,AP 与终端设备建立的是一对一的 TWT 协商。 + + - **Broadcast TWT (bTWT)** + + 在 bTWT 模式下,AP 通过 Beacon 帧广播 TWT 信息,以组的形式来管理多个终端设备的 TWT 过程。终端设备可以根据 Beacon 中的 TWT 信息选择执行加组操作。 + + .. note:: + 在建立 TWT 协商前,需要确认 AP 是否支持并开启了 TWT 功能。{IDF_TARGET_NAME} 当前只支持 iTWT 模式。 + + TWT 工作流程 + ++++++++++++ + TWT 工作流程一般分为 TWT 协商建立、TWT 协商暂停/恢复、TWT 协商终止。TWT 协商建立后,Station 就可以按照协商的参数进入休眠状态,直到约定好的下一个 TWT 时间点到来时苏醒。 + 对已经建立的 TWT,用户可以根据需求协商暂停/恢复 TWT 或者终止 TWT。 + + - TWT 协商建立 + + - Individual TWT 协商建立 + + 在 iTWT 协商建立过程中,通常由 Station 充当请求发起方发送 TWT 请求,而后 AP 作为接收方对该请求做出回应。AP 也可以主动向 Station 发起 TWT 协商建立过程。 + 在成功建立起 iTWT 协商后,Station 可以进入休眠状态,直到约定好的下一个 TWT 时间点到来时苏醒,该时间点通过和 AP 间的协商得到。Station 醒来后和 AP 进行数据交换,这段时间被称为 TWT 服务时间 (Service Period, SP)。 + TWT SP 的持续时间被称为 TWT Wake Duration,其最小值为 256 微秒。当一次 TWT SP 结束后,Station 进入休眠状态直到下次 TWT SP 醒来进行数据传输。本次 TWT SP 的起始到下次 TWT SP 的起始的时间间隔被称为 TWT Wake Interval。下图为基本的 iTWT 示例: + + .. figure:: ../../_static/itwt_setup.png + :align: center + + Individual TWT 协商建立过程示例 + + Station 在 iTWT 协商建立时可以发送不同类型的请求,AP 会根据请求类型及参数做出对应的回复。用户需要根据 AP 回复中的类型和具体参数决定后续的操作逻辑。Station 所发送的请求类型有 ``Request``、``Suggest`` 和 ``Demand``。 + AP 的回复类型可分为 ``Accept``、``Alternate`` 和 ``Dictate``。下表描述了发送不同请求时 AP 可能的回复以及不同情况下对应的含义: + + .. list-table:: + :header-rows: 1 + :widths: 20 10 40 + + * - 请求类型 + - AP 回复 + - 含义 + * - Request, Suggest or Demand + - No response + - 在该情况下 AP 不会与 Station 建立 iTWT 协商。 + * - Suggest or Request + - Accept + - AP 同意建立 iTWT 协商,其使用的参数以回复中 TWT 参数为准。回复中的 TWT 参数有可能与请求中不一致。 + * - Demand + - Accept + - AP 同意建立 iTWT 协商,且回复中的 TWT 参数与请求中的一致。 + * - Demand or Suggest + - Alternate + - AP 使用该回复类型代表给 Station提供一组备选 TWT 参数,此时不会建立 iTWT 协商。后续 Station 可以发送新的请求,但 AP 仍有可能使用该组参数。 + * - Demand or Suggest + - Dictate + - AP 使用该回复类型代表给 Station 提供一组备选 TWT 参数,此时不会建立 iTWT 协商,同时也表明 AP 不接受除该组参数以外的其他参数。后续 Station 可以发送新的请求,但只有参数与所提供的备选参数一致才会收到 Accept 回复。 + * - Request, Suggest or Demand + - Reject + - 在该情况下 AP 不会与 station 建立 iTWT 协商。后续 Station 可以更改 TWT 参数发送新的请求。 + + 在 TWT SP 中依照数据交互时的操作可以将 TWT 进一步地细分为多种类型,下表描述了这些类型间的差异: + + .. list-table:: + :header-rows: 1 + :widths: 10 20 + + * - Types + - 含义 + * - Trigger-enabled + - AP 会在 SP 中使用 Trigger 帧来协调 Station 的数据传输。 + * - Non trigger-enabled + - 在 SP 中不需要使用 Trigger 帧。 + * - Announced + - Station 会发送 QoS Null 帧告知 AP 其唤醒状态。 + * - Unannounced + - 不需要发送 QoS Null 帧。 + + - Broadcast TWT 协商建立 + + 与 iTWT 不同的是,在 bTWT 模式下 AP 将 TWT 信息放在 Beacon 帧中进行广播宣告。Station 接收到 Beacon 后,可以向 AP 发送请求申请选择加入某个 TWT。 + 当建立起 bTWT 协商后, Station 和 AP 会在协商好的 TWT SP 中进行数据传输。 + + 与 iTWT 类似,可以把 bTWT 进一步分成 Trigger-enabled 和 Non trigger-enabled 类型,以及 Announced 和 Unannounced 类型,具体的行为差异可以参考 iTWT 中的描述。 + + - TWT 协商暂停/恢复 + + 建立起 TWT 协商后, Station 可以通过向 AP 发送 TWT Information 帧暂停或者恢复指定的 TWT 协商。由 flow_id 来标识需要暂停或者恢复的 TWT 协商,具体可以参考 TWT 参数配置。 + + .. figure:: ../../_static/itwt_suspend.png + :align: center + + Individual TWT 协商暂停/恢复过程示例 + + - TWT 协商终止 + + 建立起 TWT 协商后, Station 可以通过向 AP 发送 TWT Teardown 帧终止指定的 TWT 协商。由 flow_id 来标识需要终止的 TWT 协商,具体可以参考 TWT 参数配置。 + + .. figure:: ../../_static/itwt_teardown.png + :align: center + + Individual TWT 协商终止过程示例 + + TWT 参数配置 + ++++++++++++ + + 在使用过程中,需要配置 TWT 和低功耗模式的相关参数,其中低功耗模式相关参数决定了设备在休眠状态下的行为模式。本小节将主要阐述如何配置 TWT,有关低功耗模式下的参数配置,请参考 `如何配置 Wi-Fi 场景下低功耗模式`_。 + + - Individual TWT 参数配置 + + 在建立 Station 和 AP 间的 iTWT 时,使用 :component_file:`esp_wifi/include/esp_wifi_he_types.h` 中定义的结构体 :cpp:type:`wifi_twt_setup_config_t` 来配置 TWT 的相关参数,其定义如下: + + .. code-block:: C + + typedef struct + { + wifi_twt_setup_cmds_t setup_cmd; + uint16_t trigger :1; + uint16_t flow_type :1; + uint16_t flow_id :3; + uint16_t wake_invl_expn :5; + uint16_t wake_duration_unit :1; + uint16_t reserved :5; + uint8_t min_wake_dura; + uint16_t wake_invl_mant; + uint16_t twt_id; + uint16_t timeout_time_ms; + } wifi_twt_setup_config_t; + + :cpp:type:`wifi_twt_setup_config_t` 中各个字段的含义如下: + + .. list-table:: + :header-rows: 1 + :widths: 15 45 + :align: center + + * - 字段 + - 描述 + * - setup_cmd + - 指示了 TWT 建立时请求和回复使用的命令类型,具体类型请参阅 :cpp:type:`wifi_twt_setup_cmds_t` 。 + * - trigger + - 值为 1 时配置 TWT 类型为 Trigger-enabled,值为 0 时配置为 Non trigger-enabled。 + * - flow_type + - 值为 1 时配置 TWT 类型为 Unannounced,值为 0 时配置为 Announced。 + * - flow_id + - 当建立起一个 iTWT 协商后,AP 会为其分配 flow_id。Station 在协商建立请求中可以指定 flow_id,但在 AP 的回复中该字段可能会被改变。 + * - wake_invl_expn + - TWT Wake Interval 指数部分。 + * - wake_duration_unit + - TWT Wake Duration 计数单元。为 0 代表 256 微秒,为 1 代表以 TU (1024 微秒) 为单位。 + * - reserved + - 保留字段。 + * - min_wake_dura + - 该字段代表 Station 期望处于唤醒状态的时间,以 ``wake_duration_unit`` 作为基本单位。 + * - wake_invl_mant + - TWT Wake Interval 尾数部分。 + * - twt_id + - TWT 配置标识。在发起多个 TWT 请求时,该字段用于在 handler 中区分不同的 TWT 参数配置。 + * - timeout_time_ms + - TWT 请求超时时间,单位为毫秒。 + + 需要指出的是,Station 在协商中所期望的 TWT Wake Interval 为 wake_invl_mant * 2\ :sup:`wake_invl_expn`\,单位是微秒。 + 而所期望的 TWT Wake Duration 为 min_wake_dura * wake_duration_unit。 + + .. note:: + 注意, TWT Wake Interval 和 TWT Wake Duration 的差值需要大于 10 毫秒。 + + 配置示例如下: + + .. code-block:: C + + wifi_twt_setup_config_t setup_config = { + .setup_cmd = TWT_REQUEST, + .flow_id = 0, + .twt_id = 0, + .flow_type = 0, + .min_wake_dura = 255, + .wake_duration_unit = 0, + .wake_invl_expn = 10, + .wake_invl_mant = 512, + .trigger = 1, + .timeout_time_ms = 5000, + }; + + 以上配置指定建立 TWT 请求时使用的类型为 Trigger-enabled,Announced,期望的 TWT Wake Interval 为 524288 微秒, TWT Wake Duration 为 65280 微秒。配置好 :cpp:type:`wifi_twt_setup_config_t` 后,调用 API :cpp:func:`esp_wifi_sta_itwt_setup` 向 AP 发起 iTWT 建立请求。 + + .. note:: + {IDF_TARGET_NAME} 支持用户调用 API :cpp:func:`esp_wifi_sta_itwt_set_target_wake_time_offset` 配置相对于目标唤醒时间的偏移时间。 + + TWT 事件 + ++++++++++ + + - WIFI_EVENT_ITWT_SETUP + + 发送请求后,用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_SETUP` 事件的对应处理程序中获取请求结果并自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_itwt_setup_t` 结构体中,其成员变量 status 指示了此次事件的状态。 + 当 status 为 :c:macro:`ITWT_SETUP_SUCCESS` 时代表请求成功收到了对应回复,为其他值代表请求失败。在得到请求成功的状态后,用户可以从该结构体中的 config 成员变量中得到 AP 回复中的具体参数,并根据具体参数决定后续的处理逻辑。 + 例如,Station 发送了类型为 Demand 的 TWT 请求,收到 AP 的回复类型为 Dictate,用户此时可以考察回复中的 TWT 参数是否可行,若可行便可以发送一个新的 TWT 请求与 AP 继续建立 TWT 协商,并且该请求中的 TWT 参数需要与 AP 回复中一致。 + + 在 Station 未主动发送请求时也有可能触发 :cpp:enumerator:`WIFI_EVENT_ITWT_SETUP` 事件,这种情况下对应的是 AP 主动向 Station 发起 iTWT 协商建立过程,此时 AP 向 Station 发送的帧中会带有 TWT 参数。同样地,用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_SETUP` 事件的对应处理程序中获取结果并自定义处理逻辑。 + 用户需要检查 config 成员变量中 AP 发送的 TWT 参数类型,一般有两种情况: + 1. AP 发送的 TWT 参数为 Accept 类型,此时 Station 会与 AP 建立起使用该 TWT 参数的 iTWT 协商。若用户不希望建立此 iTWT 协商,可以向 AP 发送 Teardown 帧。 + 2. AP 发送的 TWT 参数为 Alternate 或 Dictate 类型,此时 Station 不会与 AP 建立起 iTWT 协商,但可以在接下来使用该参数向 AP 发起 iTWT 协商建立请求。 + + - WIFI_EVENT_ITWT_SUSPEND + + 在调用 API :cpp:func:`esp_wifi_sta_itwt_suspend` 请求暂停已经建立的 iTWT 协商时, 用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_SUSPEND` 事件的对应处理程序中获取请求结果并自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_itwt_suspend_t` 结构体中,其成员变量 status 指示了此次事件的状态。 + 当 status 为 :c:macro:`ESP_OK` 时代表成功暂停了指定的 iTWT 协商,为其他值代表请求暂停失败。 + + .. note:: + 注意,调用 API :cpp:func:`esp_wifi_sta_itwt_suspend` 请求暂停 iTWT 时,用户需要指定对应 iTWT 的 flow_id 以及暂停时间。需要注意的是,当暂停时间大于 0 时,对应 iTWT 会在暂停指定时间后恢复,而当暂停时间为 0 时,对应的 iTWT 会暂停,直到被用户调用 API 手动恢复为止。 + + - WIFI_EVENT_ITWT_TEARDOWN + + 在调用 API :cpp:func:`esp_wifi_sta_itwt_teardown` 请求终止 iTWT 时,用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_TEARDOWN` 事件的对应处理程序中获取请求结果并自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_itwt_teardown_t` 结构体中,其成员变量 status 指示了此次事件的状态。 + 当 status 为 :cpp:enumerator:`ITWT_TEARDOWN_SUCCESS` 时代表成功终止了指定的 iTWT 协商,为其他值代表终止 iTWT 失败。调用 API 时用户需要指定需要终止的 iTWT 的 flow_id。 + + - WIFI_EVENT_TWT_WAKEUP + + 当 Station 在休眠中醒来时,Wi-Fi 驱动程序将会上报 :cpp:enumerator:`WIFI_EVENT_TWT_WAKEUP` 事件,用户可以在该事件的对应处理程序中自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_twt_wakeup_t` 结构体中,成员变量 twt_type 指示了此次事件 TWT 的类型,成员变量 flow_id 指示了此次醒来的具体的 TWT。 + + - WIFI_EVENT_ITWT_PROBE + + 调用 API :cpp:func:`esp_wifi_sta_itwt_send_probe_req` 在 iTWT 期间发送 probe request 时,用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_PROBE` 事件的对应处理程序中获取请求结果并自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_itwt_probe_t` 结构体中,其成员变量 status 指示了此次事件的状态。 + 当 status 为 :cpp:enumerator:`ITWT_PROBE_SUCCESS` 时代表成功发送 probe request 并且接收到 AP 回复的 probe response,为其他值代表发送或者接收 probe 失败。 + + + 有关 iTWT 使用的更多信息,可以参考示例 :example:`wifi/itwt` 。 + + TWT 功耗分析 + +++++++++++++ + + 为了展现 TWT 在节省设备功耗方面的优势,我们使用功率分析仪追踪了 {IDF_TARGET_NAME} 在不同模式下的电流情况。如下图所示,{IDF_TARGET_NAME} 首先处于 DTIM 模式,接着与 AP 建立起 iTWT 协商,TWT Wake Interval 为 10 s,在 TWT SP 结束后,{IDF_TARGET_NAME} 会进入 Light-sleep 状态直到下个 SP 到来时唤醒。 + 其中 :cpp:type:`wifi_twt_setup_config_t` 配置示例如下: + + .. code-block:: C + + wifi_twt_setup_config_t setup_config = { + .setup_cmd = TWT_REQUEST, + .flow_id = 0, + .twt_id = 0, + .flow_type = 0, + .min_wake_dura = 255, + .wake_duration_unit = 0, + .wake_invl_expn = 10, + .wake_invl_mant = 10000, + .trigger = 1, + .timeout_time_ms = 5000, + }; + + .. figure:: ../../_static/itwt_10s_current.png + :align: center + + DTIM 与 iTWT 模式下的电流图 + + 进一步,将 TWT 协商中的 TWT Wake Interval 参数更改为 30 s,下图展现了参数变化对于电流的影响。 + 其中 :cpp:type:`wifi_twt_setup_config_t` 配置示例如下: + + .. code-block:: C + + wifi_twt_setup_config_t setup_config = { + .setup_cmd = TWT_REQUEST, + .flow_id = 0, + .twt_id = 0, + .flow_type = 0, + .min_wake_dura = 255, + .wake_duration_unit = 0, + .wake_invl_expn = 10, + .wake_invl_mant = 30000, + .trigger = 1, + .timeout_time_ms = 5000, + }; + + .. figure:: ../../_static/itwt_30s_current.png + :align: center + + 更改参数后的 DTIM 与 iTWT 模式下的电流图 diff --git a/docs/zh_CN/api-guides/performance/ram-usage.rst b/docs/zh_CN/api-guides/performance/ram-usage.rst index 1c912bac76a2..f8ea43f8dcdc 100644 --- a/docs/zh_CN/api-guides/performance/ram-usage.rst +++ b/docs/zh_CN/api-guides/performance/ram-usage.rst @@ -183,6 +183,7 @@ IRAM 优化 任何最终未用于静态 IRAM 的内存都将添加到堆内存中。 + .. only:: esp32c3 flash 暂停特性 @@ -233,3 +234,19 @@ IRAM 优化 .. note:: 部分配置选项可以将一些功能移动到 IRAM 中,从而提高性能,但这类选项默认不进行配置,因此未在此列出。了解启用上述选项对 IRAM 大小造成的影响,请参阅配置项的帮助文本。 + + +.. only:: esp32s2 or esp32s3 or esp32p4 + + 改变 cache 大小 + ^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} RAM 内存可用大小取决于 cache 的大小。在下面列出的 Kconfig 选项中减少 cache 大小将会增加可用的 RAM。 + + .. list:: + + :esp32s2: - :ref:`CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE` + :esp32s2: - :ref:`CONFIG_ESP32S2_DATA_CACHE_SIZE` + :esp32s3: - :ref:`CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE` + :esp32s3: - :ref:`CONFIG_ESP32S3_DATA_CACHE_SIZE` + :esp32p4: - :ref:`CONFIG_CACHE_L2_CACHE_SIZE` diff --git a/docs/zh_CN/api-guides/performance/speed.rst b/docs/zh_CN/api-guides/performance/speed.rst index 678abf9e6d08..81c53f0ff56c 100644 --- a/docs/zh_CN/api-guides/performance/speed.rst +++ b/docs/zh_CN/api-guides/performance/speed.rst @@ -4,7 +4,7 @@ :link_to_translation:`en:[English]` {IDF_TARGET_CONTROLLER_CORE_CONFIG:default="CONFIG_BT_CTRL_PINNED_TO_CORE", esp32="CONFIG_BTDM_CTRL_PINNED_TO_CORE_CHOICE", esp32s3="CONFIG_BT_CTRL_PINNED_TO_CORE_CHOICE"} -{IDF_TARGET_RF_TYPE:default="Wi-Fi/蓝牙", esp32s2="Wi-Fi", esp32c6="Wi-Fi/蓝牙/802.15.4", esp32h2="蓝牙/802.15.4"} +{IDF_TARGET_RF_TYPE:default="Wi-Fi/蓝牙", esp32s2="Wi-Fi", esp32c6="Wi-Fi/蓝牙/802.15.4", esp32h2="蓝牙/802.15.4, esp32c5="Wi-Fi/蓝牙/802.15.4"} 概述 ----------- @@ -56,7 +56,7 @@ .. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES - CPU 周期是各核心独立计数的,因此本方法仅适用于测量中断处理程序或固定在单个核心上的任务。 + CPU 周期是各内核独立计数的,因此本方法仅适用于测量中断处理程序或固定在单个核上的任务。 - 在执行“微基准测试”时(即仅对运行时间不到 1-2 ms 的小代码段进行基准测试),二进制文件会影响 flash 缓存的性能,进而可能会导致计时测量出现较大差异。这是因为二进制布局可能会导致在特定的执行顺序中产生不同模式的缓存缺失。执行较大测试代码通常可以抵消这种影响。在基准测试时多次执行一个小函数可以减少 flash 缓存缺失的影响。另外,将该代码移到 IRAM 中(参见 :ref:`speed-targeted-optimizations` )也可以解决这个问题。 @@ -88,6 +88,36 @@ :not SOC_CPU_HAS_FPU: - 避免使用浮点运算 ``float``。{IDF_TARGET_NAME} 通过软件模拟进行浮点运算,因此速度非常慢。可以考虑使用不同的整数表示方法进行运算,如定点表示法,或者将部分计算用整数运算后再切换为浮点运算。 - 避免使用双精度浮点运算 ``double``。{IDF_TARGET_NAME} 通过软件模拟进行双精度浮点运算,因此速度非常慢。可以考虑使用基于整数的表示方法或单精度浮点数。 + +.. only:: esp32s2 or esp32s3 or esp32p4 + + 更改 cache 大小 + ^^^^^^^^^^^^^^^ + + 在 {IDF_TARGET_NAME} 上,通过下面列出的 Kconfig 选项增加 cache 的大小,“cache 缺失”的频率可能会降低,从而在一定程度上提高整体速度。 + + .. list:: + + :esp32s2: - :ref:`CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE`. + :esp32s2: - :ref:`CONFIG_ESP32S2_DATA_CACHE_SIZE`. + :esp32s3: - :ref:`CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE`. + :esp32s3: - :ref:`CONFIG_ESP32S3_DATA_CACHE_SIZE`. + :esp32p4: - :ref:`CONFIG_CACHE_L2_CACHE_SIZE`. + + + .. note:: + + 增加 cache 大小也将导致可用 RAM 的减少。 + + +.. only:: SOC_CACHE_L2_CACHE_SIZE_CONFIGURABLE + + .. note:: + + 在 {IDF_TARGET_NAME} 上,可以通过 Kconfig 选项 :ref:`CONFIG_CACHE_L2_CACHE_SIZE` 来配置 L2 cache 大小。 + 将 L2 cache 大小设为最小,则可用 RAM 大小达到最大,但也可能提高“cache 缺失”的频率。 + 将 L2 cache 大小设为最大,则“cache 缺失”的频率可能降低,但可用 RAM 大小也随之减少。 + 减少日志开销 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -110,6 +140,7 @@ .. _speed-targeted-optimizations: + 针对性优化 --------------------------- @@ -134,6 +165,8 @@ :SOC_RTC_FAST_MEM_SUPPORTED: - 如果使用 Deep-sleep 模式,启用 :ref:`CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` 可以加快从睡眠中唤醒的速度。请注意,启用该选项后在唤醒时将不会执行安全启动验证,需要考量安全风险。 - 设置 :ref:`CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON` 可以在每次上电复位启动时跳过二进制文件验证,节省的时间取决于二进制文件大小和 flash 设置。请注意,如果 flash 意外损坏,此设置将有一定风险。更多关于使用该选项的解释和建议,参见 :ref:`项目配置 ` 。 - 禁用 RTC 慢速时钟校准可以节省一小部分启动时间。设置 :ref:`CONFIG_RTC_CLK_CAL_CYCLES` 为 0 可以实现该操作。设置后,以 RTC 慢速时钟为时钟源的固件部分精确度将降低。 + :SOC_SPIRAM_SUPPORTED: - 使用外部内存(启用 :ref:`CONFIG_SPIRAM`)时,启用外部内存 (:ref:`CONFIG_SPIRAM_MEMTEST`) 测试可能会大大增加启动时间(每测试 4 MB 的内存大约增加 1 秒)。禁用内存测试将减少启动时间,但将无法对外部存储器进行测试。 + :SOC_SPIRAM_SUPPORTED: - 使用外部内存(启用 :ref:`CONFIG_SPIRAM`)时,所有用作堆的内存(包括外部内存)都将被设为默认值,所以启用全面的 poisoning 将增加启动时间(每设置 4 MiB 的内存大约增加 300 毫秒)。 示例项目 :example:`system/startup_time` 预配了优化启动时间的设置,文件 :example_file:`system/startup_time/sdkconfig.defaults` 包含了所有相关设置。可以将这些设置追加到项目中 ``sdkconfig`` 文件的末尾并合并,但请事先阅读每个设置的相关说明。 @@ -180,25 +213,25 @@ ESP-IDF 启动的系统任务预设了固定优先级。启动时,一些任务 .. list:: - - :ref:`app-main-task` 中执行 app_main 函数的主任务优先级最低 (1) 且默认固定在核心 0 上执行( :ref:`可配置 ` )。 - - 系统任务 :doc:`/api-reference/system/esp_timer` 用于管理定时器事件并执行回调函数,优先级较高 (22, ``ESP_TASK_TIMER_PRIO``) 且固定在核心 0 上执行。 - - FreeRTOS 初始化调度器时会创建定时器任务,用于处理 FreeRTOS 定时器的回调函数,优先级最低(1, :ref:`可配置 ` )且固定在核心 0 上执行。 - - 系统任务 :doc:`/api-reference/system/esp_event` 用于管理默认的系统事件循环并执行回调函数,优先级较高 (20, ``ESP_TASK_EVENT_PRIO``) 且固定在核心 0 上执行。此配置仅在应用程序调用 :cpp:func:`esp_event_loop_create_default` 时使用。可以调用 :cpp:func:`esp_event_loop_create` 添加自定义任务配置。 - - :doc:`/api-guides/lwip` TCP/IP 任务优先级较高 (18, ``ESP_TASK_TCPIP_PRIO``) 且并未固定在特定核心上执行( :ref:`可配置 ` )。 - :SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi` 任务优先级较高 (23) 且默认固定在核心 0 上执行( :ref:`可配置 ` )。 - :SOC_WIFI_SUPPORTED: - 使用 Wi-Fi Protected Setup (WPS)、WPA2 EAP-TLS、Device Provisioning Protocol (DPP) 或 BSS Transition Management (BTM) 等功能时,Wi-Fi wpa_supplicant 组件可能会创建优先级较低的专用任务 (2),这些任务并未固定在特定核心上执行。 - :SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/controller_vhci` 任务优先级较高 (23, ``ESP_TASK_BT_CONTROLLER_PRIO``) 且默认固定在核心 0 上执行( :ref:`可配置 <{IDF_TARGET_CONTROLLER_CORE_CONFIG}>` )。蓝牙控制器需要以低延迟响应请求,因此其任务应始终为最高优先级的任务之一并分配给单个 CPU 执行。 - :SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/nimble/index` 任务优先级较高 (21) 且默认固定在核心 0 上执行( :ref:`可配置 ` ). + - :ref:`app-main-task` 中执行 app_main 函数的主任务优先级最低 (1) 且默认固定在核 0 上执行( :ref:`可配置 ` )。 + - 系统任务 :doc:`/api-reference/system/esp_timer` 用于管理定时器事件并执行回调函数,优先级较高 (22, ``ESP_TASK_TIMER_PRIO``) 且固定在核 0 上执行。 + - FreeRTOS 初始化调度器时会创建定时器任务,用于处理 FreeRTOS 定时器的回调函数,优先级最低(1, :ref:`可配置 ` )且固定在核 0 上执行。 + - 系统任务 :doc:`/api-reference/system/esp_event` 用于管理默认的系统事件循环并执行回调函数,优先级较高 (20, ``ESP_TASK_EVENT_PRIO``) 且固定在核 0 上执行。此配置仅在应用程序调用 :cpp:func:`esp_event_loop_create_default` 时使用。可以调用 :cpp:func:`esp_event_loop_create` 添加自定义任务配置。 + - :doc:`/api-guides/lwip` TCP/IP 任务优先级较高 (18, ``ESP_TASK_TCPIP_PRIO``) 且并未固定在特定内核上执行( :ref:`可配置 ` )。 + :SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi` 任务优先级较高 (23) 且默认固定在核 0 上执行( :ref:`可配置 ` )。 + :SOC_WIFI_SUPPORTED: - 使用 Wi-Fi Protected Setup (WPS)、WPA2 EAP-TLS、Device Provisioning Protocol (DPP) 或 BSS Transition Management (BTM) 等功能时,Wi-Fi wpa_supplicant 组件可能会创建优先级较低的专用任务 (2),这些任务并未固定在特定内核上执行。 + :SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/controller_vhci` 任务优先级较高 (23, ``ESP_TASK_BT_CONTROLLER_PRIO``) 且默认固定在核 0 上执行( :ref:`可配置 <{IDF_TARGET_CONTROLLER_CORE_CONFIG}>` )。蓝牙控制器需要以低延迟响应请求,因此其任务应始终为最高优先级的任务之一并分配给单个 CPU 执行。 + :SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/nimble/index` 任务优先级较高 (21) 且默认固定在核 0 上执行( :ref:`可配置 ` ). :esp32: - 使用 :doc:`/api-reference/bluetooth/index` 时会创建多个任务: - 堆栈事件回调任务 ("BTC") 优先级较高 (19)。 - 堆栈 BTU 层任务优先级较高 (20)。 - Host HCI 主任务优先级较高 (22)。 - 所有 Bluedroid 任务默认固定在同一个核心上执行,即核心 0( :ref:`可配置 ` )。 + 所有 Bluedroid 任务默认固定在同一个核心上执行,即核 0( :ref:`可配置 ` )。 - - 以太网驱动程序会创建一个 MAC 任务,用于接收以太网帧。如果使用默认配置 ``ETH_MAC_DEFAULT_CONFIG`` ,则该任务为中高优先级 (15) 且并未固定在特定核心上执行。可以在以太网 MAC 初始化时输入自定义 :cpp:class:`eth_mac_config_t` 结构体来更改此设置。 - - 如果使用 :doc:`/api-reference/protocols/mqtt` 组件,它会创建优先级默认为 5 的任务( :ref:`可配置 ` ,也可通过 :ref:`CONFIG_MQTT_USE_CUSTOM_CONFIG` 调整)。该任务未固定在特定核心上执行( :ref:`可配置 ` )。 - - 关于 ``mDNS`` 服务的任务优先级,参见 `性能优化 `__ 。 + - 以太网驱动程序会创建一个 MAC 任务,用于接收以太网帧。如果使用默认配置 ``ETH_MAC_DEFAULT_CONFIG`` ,则该任务为中高优先级 (15) 且并未固定在特定内核上执行。可以在以太网 MAC 初始化时输入自定义 :cpp:class:`eth_mac_config_t` 结构体来更改此设置。 + - 如果使用 :doc:`/api-reference/protocols/mqtt` 组件,它会创建优先级默认为 5 的任务( :ref:`可配置 ` ,也可通过 :ref:`CONFIG_MQTT_USE_CUSTOM_CONFIG` 调整)。该任务未固定在特定内核上执行( :ref:`可配置 ` )。 + - 关于 ``mDNS`` 服务的任务优先级,参见 `性能优化 `__ 。 设定应用程序任务优先级 @@ -206,17 +239,29 @@ ESP-IDF 启动的系统任务预设了固定优先级。启动时,一些任务 .. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES - 由于 {IDF_TARGET_RF_TYPE} 操作饥饿可能导致系统不稳定,通常不建议让特定任务的优先级高于 {IDF_TARGET_RF_TYPE} 操作的内置优先级。对于非常短且无需网络的实时操作,可以使用中断服务程序或极受限的任务(仅运行极短时间)并设置为最高优先级 (24)。将特定任务优先级设为 19 不会妨碍较低层级的 {IDF_TARGET_RF_TYPE} 功能无延迟运行,但仍然会抢占 lwIP TCP/IP 堆栈以及其他非实时内部功能,这对于不执行网络操作的实时任务而言是最佳选项。lwIP TCP/IP 任务优先级 (18) 应高于所有执行 TCP/IP 网络操作的任务,以保证任务正常执行。 + .. only:: SOC_WIFI_SUPPORTED or SOC_BT_SUPPORTED or SOC_IEEE802154_SUPPORTED -.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES + 一般情况下,不建议将任务优先级设置得比内置的 {IDF_TARGET_RF_TYPE} 操作更高,因为这样可能会使 CPU 被长时间占用,导致系统不稳定。 + + 对于非常短、对时序要求严格且不涉及网络的操作,可以使用中断服务程序或是限制运行时间的最高优先级 (24) 任务。 + + .. only:: SOC_WIFI_SUPPORTED or SOC_BT_SUPPORTED or SOC_IEEE802154_SUPPORTED + + 将特定任务优先级设为 19,则较低层级的 {IDF_TARGET_RF_TYPE} 功能可以无延迟运行,且仍然会抢占 lwIP TCP/IP 堆栈以及其他非实时内部功能,这对于不执行网络操作的实时任务而言是最佳选项。 + + lwIP TCP/IP 任务优先级 (18) 应高于所有执行 TCP/IP 网络操作的任务,从而避免优先级反转的问题。 + +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES + + 默认配置下,除了个别例外,尤其是 lwIP TCP/IP 任务,大多数内置任务都固定在核 0 上执行。因此,应用程序可以方便地将高优先级任务放置在核 1 上执行。优先级大于等于 19 的应用程序任务在核 1 上运行时可以确保不会被任何内置任务抢占。为了进一步隔离各个 CPU 上运行的任务,配置 :ref:`lwIP 任务 ` ,可以使 lwIP 任务仅在核 0 上运行,而非其他内核,这可能会根据其他任务的运行情况减少总 TCP/IP 吞吐量。 - 默认配置下,除了个别例外,尤其是 lwIP TCP/IP 任务,大多数内置任务都固定在核心 0 上执行。因此,应用程序可以方便地将高优先级任务放置在核心 1 上执行。优先级大于等于 19 的应用程序任务在核心 1 上运行时可以确保不会被任何内置任务抢占。为了进一步隔离各个 CPU 上运行的任务,配置 :ref:`lwIP 任务 ` ,可以使 lwIP 任务仅在核心 0 上运行,而非上述任一核心,这可能会根据其他任务的运行情况减少总 TCP/IP 吞吐量。 + .. only:: SOC_WIFI_SUPPORTED or SOC_BT_SUPPORTED or SOC_IEEE802154_SUPPORTED - 由于 {IDF_TARGET_RF_TYPE} 操作饥饿可能导致系统不稳定,通常不建议让核心 0 上特定任务的优先级高于 {IDF_TARGET_RF_TYPE} 操作的内置优先级。将特定任务优先级设置为 19 并在核心 0 上运行,不会妨碍较低层级的 {IDF_TARGET_RF_TYPE} 功能无延迟运行,但仍然会抢占 lwIP TCP/IP 堆栈以及其他非实时内部功能,该选项适用于不执行网络操作的实时任务。lwIP TCP/IP 任务优先级 (18) 应高于所有执行 TCP/IP 网络操作的任务,以保证任务正常执行。 + 一般情况下,不建议将核 0 上的任务优先级设置得比内置的 {IDF_TARGET_RF_TYPE} 操作更高,因为这样可能会使 CPU 被长时间占用,导致系统不稳定。选择优先级为 19 并在核 0 上运行可以使底层 {IDF_TARGET_RF_TYPE} 功能运行无延迟,但仍会抢占 lwIP TCP/IP 栈和其他不太关键的内部功能。这对于无需执行网络操作且时序要求高的任务来说是一个选择。执行 TCP/IP 网络操作的任何任务都应该以低于 lwIP TCP/IP 任务 (18) 的优先级运行,以避免优先级反转问题。 .. note:: - 如果要让特定任务始终先于 ESP-IDF 内置任务运行,并不需要将其固定在核心 1 上。将该任务优先级设置为小于等于 17,则无需与核心绑定,那么核心 0 上没有执行较高优先级的内置任务时,该任务也可以选择在核心 0 上执行。使用未固定的任务可以提高整体 CPU 利用率,但这会增加任务调度的复杂性。 + 如果要让特定任务始终先于 ESP-IDF 内置任务运行,并不需要将其固定在核 1 上。将该任务优先级设置为小于等于 17,则无需与内核绑定,那么核 0 上没有执行较高优先级的内置任务时,该任务也可以选择在核 0 上执行。使用未固定的任务可以提高整体 CPU 利用率,但这会增加任务调度的复杂性。 .. note:: @@ -234,7 +279,7 @@ ESP-IDF 支持动态 :doc:`/api-reference/system/intr_alloc` 和中断抢占。 .. list:: - 调用 :cpp:func:`esp_intr_alloc` 时使用 ``ESP_INTR_FLAG_LEVEL2`` 或 ``ESP_INTR_FLAG_LEVEL3`` 等标志,可以为更重要的中断设定更高优先级。 - :SOC_HP_CPU_HAS_MULTIPLE_CORES: - 将中断分配到不运行内置 {IDF_TARGET_RF_TYPE} 任务的 CPU 上执行,即默认情况下,将中断分配到核心 1 上执行,参见 :ref:`built-in-task-priorities` 。调用 :cpp:func:`esp_intr_alloc` 函数即可将中断分配到函数所在 CPU。 + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - 将中断分配到不运行内置 {IDF_TARGET_RF_TYPE} 任务的 CPU 上执行,即默认情况下,将中断分配到核 1 上执行,参见 :ref:`built-in-task-priorities` 。调用 :cpp:func:`esp_intr_alloc` 函数即可将中断分配到函数所在 CPU。 - 如果确定整个中断处理程序可以在 IRAM 中运行(参见 :ref:`iram-safe-interrupt-handlers` ),那么在调用 :cpp:func:`esp_intr_alloc` 分配中断时,请设置 ``ESP_INTR_FLAG_IRAM`` 标志,这样可以防止在应用程序固件写入内置 SPI flash 时临时禁用中断。 - 即使是非 IRAM 安全的中断处理程序,如果需要频繁执行,可以考虑将处理程序的函数移到 IRAM 中,从而尽可能规避执行中断代码时发生 flash 缓存缺失的可能性(参见 :ref:`speed-targeted-optimizations` )。如果可以确保只有部分处理程序位于 IRAM 中,则无需添加 ``ESP_INTR_FLAG_IRAM`` 标志将程序标记为 IRAM 安全。 diff --git a/docs/zh_CN/api-guides/sleep-current/esp32c6_light_sleep.inc b/docs/zh_CN/api-guides/sleep-current/esp32c6_light_sleep.inc index e2dd10abd0d2..5e8500b65175 100644 --- a/docs/zh_CN/api-guides/sleep-current/esp32c6_light_sleep.inc +++ b/docs/zh_CN/api-guides/sleep-current/esp32c6_light_sleep.inc @@ -10,18 +10,18 @@ * - 160 MHz - 1 - - / - - / - - / + - 0.919 + - 103.149 + - 0.053 * - 160 MHz - 3 - - / - - / - - / + - 0.368 + - 102.428 + - 0.052 * - 160 MHz - 10 - - / - - / - - / + - 0.172 + - 102.087 + - 0.052 diff --git a/docs/zh_CN/api-guides/sleep-current/esp32c6_modem_sleep.inc b/docs/zh_CN/api-guides/sleep-current/esp32c6_modem_sleep.inc index f43652792b25..e1c06637ae49 100644 --- a/docs/zh_CN/api-guides/sleep-current/esp32c6_modem_sleep.inc +++ b/docs/zh_CN/api-guides/sleep-current/esp32c6_modem_sleep.inc @@ -12,41 +12,41 @@ * - 160 MHz - ON - 1 - - / - - / - - / + - 14.37 + - 84.40 + - 10.02 * - 160 MHz - OFF - 1 - - / - - / - - / + - 27.48 + - 87.55 + - 26.92 * - 160 MHz - ON - 3 - - / - - / - - / + - 13.9 + - 83.9 + - 10.13 * - 160 MHz - OFF - 3 - - / - - / - - / + - 27.08 + - 87.74 + - 26.91 * - 160 MHz - ON - 10 - - / - - / - - / + - 13.71 + - 82.77 + - 10.04 * - 160 MHz - OFF - 10 - - / - - / - - / + - 26.85 + - 88.07 + - 26.7 diff --git a/docs/zh_CN/api-guides/sleep-current/esp32c6_summary.inc b/docs/zh_CN/api-guides/sleep-current/esp32c6_summary.inc index 581f1b8a38ab..e865abc938d5 100644 --- a/docs/zh_CN/api-guides/sleep-current/esp32c6_summary.inc +++ b/docs/zh_CN/api-guides/sleep-current/esp32c6_summary.inc @@ -45,25 +45,25 @@ - 关 * - DTIM1 - - / - - / - - / + - 27.48 mA + - 14.37 mA + - 0.919 mA - / * - DTIM3 - - / - - / - - / + - 27.08 mA + - 13.9 mA + - 0.368 mA - / * - DTIM10 - - / - - / - - / + - 26.85 mA + - 13.71 mA + - 0.172 mA - / * - 平均电流 - / - / - / - - / + - 6.7 μA diff --git a/docs/zh_CN/api-guides/startup.rst b/docs/zh_CN/api-guides/startup.rst index db8a0125492f..db82ddc7d976 100644 --- a/docs/zh_CN/api-guides/startup.rst +++ b/docs/zh_CN/api-guides/startup.rst @@ -50,11 +50,11 @@ 二级引导程序二进制镜像会从 flash 的 {IDF_TARGET_CONFIG_BOOTLOADER_OFFSET_IN_FLASH} 偏移地址处加载。该地址前面的 flash 4 kB 扇区未使用。 -.. only:: esp32p4 +.. only:: SOC_KEY_MANAGER_SUPPORTED 二级引导程序二进制镜像会从 flash 的 {IDF_TARGET_CONFIG_BOOTLOADER_OFFSET_IN_FLASH} 偏移地址处加载。该地址前面的 flash 8 kB 扇区将为密钥管理器保留,用于与 flash 加密 (AES-XTS) 相关的操作。 - .. only:: not (esp32 or esp32s2 or esp32p4) + .. only:: not (esp32 or esp32s2 or SOC_KEY_MANAGER_SUPPORTED) 二级引导程序二进制镜像会从 flash 的 {IDF_TARGET_CONFIG_BOOTLOADER_OFFSET_IN_FLASH} 偏移地址处加载。 diff --git a/docs/zh_CN/api-reference/network/esp_eth.rst b/docs/zh_CN/api-reference/network/esp_eth.rst index 255c7ea1a45f..1ed9aca6a73a 100644 --- a/docs/zh_CN/api-reference/network/esp_eth.rst +++ b/docs/zh_CN/api-reference/network/esp_eth.rst @@ -1,6 +1,16 @@ 以太网 ========= +{IDF_TARGET_SOC_REF_CLK_IN_GPIO:default="", esp32="GPIO0", esp32p4="GPIO32, GPIO44 and GPIO50"} +{IDF_TARGET_SOC_REF_CLK_OUT_GPIO:default="", esp32="GPIO0, GPIO16 and GPIO17", esp32p4="GPIO23 and GPIO39"} +{IDF_TARGET_SOC_RMII_TX_EN:default="", esp32="GPIO21", esp32p4="GPIO33, GPIO40 and GPIO49"} +{IDF_TARGET_SOC_RMII_TXD0:default="", esp32="GPIO19", esp32p4="GPIO34 and GPIO41"} +{IDF_TARGET_SOC_RMII_TXD1:default="", esp32="GPIO22", esp32p4="GPIO35 and GPIO42"} +{IDF_TARGET_SOC_RMII_CRS_DV:default="", esp32="GPIO27", esp32p4="GPIO28, GPIO45 and GPIO51"} +{IDF_TARGET_SOC_RMII_RXD0:default="", esp32="GPIO25", esp32p4="GPIO29, GPIO46 and GPIO52"} +{IDF_TARGET_SOC_RMII_RXD1:default="", esp32="GPIO26", esp32p4="GPIO30, GPIO47 and GPIO53"} + + :link_to_translation:`en:[English]` .. -------------------------------- Overview ----------------------------------- @@ -8,7 +18,13 @@ 概述 -------- -ESP-IDF 提供一系列功能强大且兼具一致性的 API,为内部以太网 MAC (EMAC) 控制器和外部 SPI-Ethernet 模块提供支持。 +.. only:: SOC_EMAC_SUPPORTED + + ESP-IDF 提供一系列灵活度高且兼具一致性的 API,为内部以太网 MAC (EMAC) 控制器和外部 SPI-Ethernet 模块提供支持。 + +.. only:: not SOC_EMAC_SUPPORTED + + ESP-IDF 提供一系列灵活度高且兼具一致性的 API,为外部 SPI-Ethernet 模块提供支持。 本编程指南分为以下几个部分: @@ -24,7 +40,7 @@ ESP-IDF 提供一系列功能强大且兼具一致性的 API,为内部以太 以太网基本概念 ----------------------- -以太网是一种异步的带冲突检测的载波侦听多路访问 (CSMA/CD) 协议/接口。通常来说,以太网不太适用于低功率应用。然而,得益于其广泛的部署、高效的网络连接、高数据率以及范围不限的可扩展性,几乎所有的有线通信都可以通过以太网进行。 +以太网是一种异步的带冲突检测的载波侦听多路访问 (CSMA/CD) 协议/接口。通常来说,以太网不太适用于低功耗应用。然而,得益于其广泛的部署、高效的网络连接、高数据率以及范围不限的可扩展性,几乎所有的有线通信都可以通过以太网进行。 符合 IEEE 802.3 标准的正常以太网帧的长度在 64 至 1518 字节之间,由五个或六个不同的字段组成:目的地 MAC 地址 (DA)、源 MAC 地址 (SA)、类型/长度字段、数据有效载荷字段、可选的填充字段和帧校验序列字段 (CRC)。此外,在以太网上传输时,以太网数据包的开头需附加 7 字节的前导码和 1 字节的帧起始符 (SOF)。 @@ -100,9 +116,7 @@ ESP-IDF 提供一系列功能强大且兼具一致性的 API,为内部以太 以太网驱动器由两部分组成:MAC 和 PHY。 -.. TODO remove esp32p4 (IDF-9057) - -.. only:: SOC_EMAC_SUPPORTED and not esp32p4 +.. only:: SOC_EMAC_SUPPORTED MAC 和 PHY 之间的通信可以通过多种方式进行,如: **MII** (媒体独立接口)、 **RMII** (简化媒体独立接口)等。 @@ -115,36 +129,100 @@ ESP-IDF 提供一系列功能强大且兼具一致性的 API,为内部以太 MII 和 RMII 的一个明显区别在于其所需的信号数。MII 通常需要多达 18 个信号,RMII 接口则仅需要 9 个信号。 + .. only:: esp32 + + .. note:: + ESP-IDF 只支持 RMII 接口,所以请将 :cpp:member:`eth_esp32_emac_config_t::interface` 设置为 :cpp:enumerator:`eth_data_interface_t::EMAC_DATA_INTERFACE_RMII` 或在 Kconfig 选项 :ref:`CONFIG_ETH_PHY_INTERFACE` 中选择 ``CONFIG_ETH_PHY_INTERFACE_RMII``。 + + .. only:: not esp32 + + .. note:: + ESP-IDF 只支持 RMII 接口,所以请将 :cpp:member:`eth_esp32_emac_config_t::interface` 设置为 :cpp:enumerator:`eth_data_interface_t::EMAC_DATA_INTERFACE_RMII`。 + 在 RMII 模式下,接收器和发射器信号的参考时钟为 ``REF_CLK``。 **在访问 PHY 和 MAC 时,REF_CLK 必须保持稳定**。一般来说,根据设计中 PHY 设备的特征,可通过以下三种方式生成 ``REF_CLK``: - * 一些 PHY 芯片可以从其外部连接的 25 MHz 晶体振荡器中获取 ``REF_CLK`` (如图中的选项 **a** 所示)。对于此类芯片,请在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_INPUT``。 + * 一些 PHY 芯片可以从其外部连接的 25 MHz 晶体振荡器中衍生出 ``REF_CLK`` (如图中的选项 **a** 所示)。对于此类芯片,请将 :cpp:member:`eth_esp32_emac_config_t::clock_config` 中的 :cpp:member:`eth_mac_clock_config_t::clock_mode` 设置为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_EXT_IN`。 + + * 一些 PHY 芯片使用外接的 50 MHz 晶体振荡器或其他时钟源作为 MAC 端的 ``REF_CLK`` (如图中的选项 **b** 所示)。对于此类芯片,请同样将 :cpp:member:`eth_esp32_emac_config_t::clock_config` 中的 :cpp:member:`eth_mac_clock_config_t::clock_mode` 设置为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_EXT_IN`。 + + * 一些 EMAC 控制器可以使用其内部的高精度 PLL 生成 ``REF_CLK`` (如图中的选项 **c** 所示)。此种情况下,请将 :cpp:member:`eth_esp32_emac_config_t::clock_config` 中的 :cpp:member:`eth_mac_clock_config_t::clock_mode` 设置为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_OUT`。 + + .. only:: esp32 + + .. note:: + 使用 :c:macro:`ETH_ESP32_EMAC_DEFAULT_CONFIG` 宏初始化 :cpp:class:`eth_esp32_emac_config_t` 时,也可以通过项目配置来配置 ``REF_CLK``。在项目配置中,根据上述个人设计,在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 配置下选择适当的选项, ``CONFIG_ETH_RMII_CLK_INPUT`` 或是 ``CONFIG_ETH_RMII_CLK_OUTPUT``。 + + .. warning:: + 如果配置 RMII 时钟模式为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_OUT` (或是选择 ``CONFIG_ETH_RMII_CLK_OUTPUT``,那么就可以使用 ``GPIO0`` 输出 ``REF_CLK`` 信号。更多细节,请参见 :cpp:enumerator:`emac_rmii_clock_gpio_t::EMAC_APPL_CLK_OUT_GPIO` 或是 :ref:`CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0`。 + + 值得一提的是,如果设计中并未使用 PSRAM,则 GPIO16 和 GPIO17 也可以用来输出参考时钟。更多细节,请参见 :cpp:enumerator:`emac_rmii_clock_gpio_t::EMAC_CLK_OUT_GPIO` 和 :cpp:enumerator:`emac_rmii_clock_gpio_t::EMAC_CLK_OUT_180_GPIO`,或是 :ref:`CONFIG_ETH_RMII_CLK_OUT_GPIO`。 + + 如果配置 RMII 时钟模式为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_EXT_IN` (或是选择 ``CONFIG_ETH_RMII_CLK_INPUT``,那么只能选择 ``GPIO0`` 输入 ``REF_CLK`` 信号。请注意, ``GPIO0`` 同时也是 ESP32 上一个重要的 strapping GPIO 管脚。如果上电时 GPIO0 为低电平,则 ESP32 将进入下载模式,需进行手动复位重启系统。解决这个问题的方法是,在硬件中默认禁用 ``REF_CLK``,从而避免 strapping 管脚在启动阶段受到其他信号的干扰。随后,再在以太网驱动安装阶段重新启用 ``REF_CLK``。 - * 一些 PHY 芯片使用可以作为 MAC 端 ``REF_CLK`` 的外接 50 MHz 晶体振荡器或其他时钟源(如图中的选项 **b** 所示)。对于此类芯片,请同样在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_INPUT``。 + 可以通过以下方法禁用 ``REF_CLK`` 信号: - * 一些 EMAC 控制器可以使用其内部的高精度 PLL 生成 ``REF_CLK`` (如图中的选项 **c** 所示)。此种情况下,请在 :ref:`CONFIG_ETH_RMII_CLK_MODE` 中选择 ``CONFIG_ETH_RMII_CLK_OUTPUT``。 + * 禁用或关闭晶体振荡器的电源(对应图中的选项 **b**)。 - .. note:: - 如上所述,``REF_CLK`` 默认通过项目配置进行配置。然而,通过设置 :cpp:member:`eth_esp32_emac_config_t::interface` 和 :cpp:member:`eth_esp32_emac_config_t::clock_config`,也可以实现在用户应用代码中覆盖该时钟。更多细节,请参见 :cpp:enum:`emac_rmii_clock_mode_t` 和 :cpp:enum:`emac_rmii_clock_gpio_t`。 + * 强制复位 PHY 设备(对应图中的选项 **a**)。**此种方法并不适用于所有 PHY 设备** (即便处于复位状态,某些 PHY 设备仍会向 GPIO0 输出信号)。 - .. warning:: - 如果配置 RMII 时钟模式为 ``CONFIG_ETH_RMII_CLK_OUTPUT``,那么就可以使用 ``GPIO0`` 输出 ``REF_CLK`` 信号。更多细节,请参见 :ref:`CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0`。 + .. only:: not esp32 - 值得一提的是,如果设计中并未使用 PSRAM,则 GPIO16 和 GPIO17 也可以用来输出参考时钟。更多细节,请参见 :ref:`CONFIG_ETH_RMII_CLK_OUT_GPIO`。 + .. note:: + 如果 RMII 时钟模式配置为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_OUT`,则可以通过 IO_MUX 将 {IDF_TARGET_SOC_REF_CLK_OUT_GPIO} 选择为 ``REF_CLK`` 信号的输出管脚。 - 如果配置 RMII 时钟模式为 ``CONFIG_ETH_RMII_CLK_INPUT``,那么有且只有 ``GPIO0`` 可以用来输入 ``REF_CLK`` 信号。请注意, ``GPIO0`` 同时也是 ESP32 上一个重要的 strapping GPIO 管脚。如果 GPIO0 在上电时采样为低电平,ESP32 将进入下载模式,需进行手动复位重启系统。解决这个问题的方法是,在硬件中默认禁用 ``REF_CLK``,从而避免 strapping 管脚在启动阶段受到其他信号的干扰。随后,再在以太网驱动安装阶段重新启用 ``REF_CLK``。 + 如果 RMII 时钟模式配置为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_EXT_IN`,则可以通过 IO_MUX 将 {IDF_TARGET_SOC_REF_CLK_IN_GPIO} 选择为 ``REF_CLK`` 信号的输入管脚。 - 可以通过以下方法禁用 ``REF_CLK`` 信号: + .. only:: not SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK - * 禁用或关闭晶体振荡器的电源(对应图中的选项 **b**)。 + .. warning:: + 如果 RMII 时钟模式配置为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_OUT`,则必须从外部将 ``REF_CLK`` 输出信号回环到 EMAC。请将 :cpp:member:`eth_esp32_emac_config_t::clock_config_out_in` 中的 :cpp:member:`eth_mac_clock_config_t::clock_mode` 配置为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_EXT_IN`,并选择与 ``REF_CLK`` 输入 GPIO ({IDF_TARGET_SOC_REF_CLK_IN_GPIO}) 相关联的 GPIO 编号。 - * 强制复位 PHY 设备(对应图中的选项 **a**)。 **此种方法并不适用于所有 PHY 设备**,即便处于复位状态,某些 PHY 设备仍会向 GPIO0 输出信号。 + .. only:: esp32p4 - **无论选择哪种 RMII 时钟模式,都请确保硬件设计中 REF_CLK 的信号完整性!** 信号线越短越好,并请保持信号线与 RF 设备和电感器元件的距离。 + .. figure:: ../../../_static/rmii_ref_clk_esp32p4.png + :scale: 95 % + :alt: RMII REF_CKL Output Loopback + :figclass: align-center - .. note:: - ESP-IDF 只支持 RMII 接口(即在 Kconfig 选项 :ref:`CONFIG_ETH_PHY_INTERFACE` 中始终选择 ``CONFIG_ETH_PHY_INTERFACE_RMII``)。 + RMII REF_CKL 输出回环 - 在数据平面使用的信号通过 MUX 连接至特定的 GPIO,这些信号无法配置至其他 GPIO。在控制平面使用的信号则可以通过 Matrix 矩阵路由到任何空闲 GPIO。相关的硬件设计示例,请参考 :doc:`ESP32-Ethernet-Kit <../../hw-reference/esp32/get-started-ethernet-kit>`。 + **无论选择哪种 RMII 时钟模式,都请确保硬件设计中 REF_CLK 的信号完整性!** 信号线越短越好,并远离 RF 设备和电感。 + + .. only:: not SOC_EMAC_USE_MULTI_IO_MUX + + .. note:: + 数据平面中使用的信号通过 IO_MUX 连接至特定的 GPIO,这些信号无法配置到其他 GPIO 上。控制平面中使用的信号可以通过矩阵路由到任何空闲的 GPIO 上。相关硬件设计示例,请参阅 :doc:`ESP32-Ethernet-Kit <../../hw-reference/esp32/get-started-ethernet-kit>`。 + + .. only:: SOC_EMAC_USE_MULTI_IO_MUX + + .. note:: + 数据平面中使用的信号可以通过 IO_MUX 配置为 RMII 预定义的 GPIO,请参阅下表。数据平面 GPIO 配置由驱动程序根据 :cpp:member:`eth_esp32_emac_config_t::emac_dataif_gpio` 的内容执行。控制平面中使用的信号可以通过 GPIO 矩阵路由到任何空闲的 GPIO。 + + .. list-table:: {IDF_TARGET_NAME} RMII 数据平面 GPIO + :header-rows: 1 + :widths: 50 50 + :align: center + + * - 管脚名 + - GPIO 编号 + + * - TX_EN + - {IDF_TARGET_SOC_RMII_TX_EN} + + * - TXD0 + - {IDF_TARGET_SOC_RMII_TXD0} + + * - TXD1 + - {IDF_TARGET_SOC_RMII_TXD1} + + * - CRS_DV + - {IDF_TARGET_SOC_RMII_CRS_DV} + + * - RXD0 + - {IDF_TARGET_SOC_RMII_RXD0} + + * - RXD1 + - {IDF_TARGET_SOC_RMII_RXD1} 根据以太网板设计,需要分别为 MAC 和 PHY 配置必要的参数,通过两者完成驱动程序的安装。 @@ -156,13 +234,25 @@ MAC 的相关配置可以在 :cpp:class:`eth_mac_config_t` 中找到,具体包 * :cpp:member:`eth_mac_config_t::rx_task_stack_size` 和 :cpp:member:`eth_mac_config_t::rx_task_prio`:MAC 驱动会创建一个专门的任务来处理传入的数据包,这两个参数用于设置该任务的堆栈大小和优先级。 - * :cpp:member:`eth_mac_config_t::flags`:指定 MAC 驱动应支持的额外功能,尤其适用于某些特殊情况。这个字段的值支持与以 ``ETH_MAC_FLAG_`` 为前缀的宏进行 OR 运算。例如,如果 MAC 驱动应在禁用缓存后开始工作,那么则需要用 :c:macro:`ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE` 配置这个字段。 + * :cpp:member:`eth_mac_config_t::flags`:指定 MAC 驱动应支持的额外功能,尤其适用于某些特殊情况。这个字段的值支持与以 ``ETH_MAC_FLAG_`` 为前缀的宏进行 OR 运算。例如,如果要求 MAC 驱动程序在 cache 禁用时仍能正常工作,那么则需要用 :c:macro:`ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE` 配置这个字段。 + +.. only:: SOC_EMAC_SUPPORTED + + :cpp:class:`eth_esp32_emac_config_t` 描述了 **内部 MAC 模块** 的特定配置,其中包括: + + .. list:: + + * :cpp:member:`eth_esp32_emac_config_t::smi_mdc_gpio_num` 和 :cpp:member:`eth_esp32_emac_config_t::smi_mdio_gpio_num`:连接 SMI 信号的 GPIO 编号。 + + * :cpp:member:`eth_esp32_emac_config_t::interface`:配置到 PHY (MII/RMII) 的 MAC 数据接口。 + + * :cpp:member:`eth_esp32_emac_config_t::clock_config`:配置 EMAC 接口时钟(RMII 模式下的 ``REF_CLK`` 模式以及 GPIO 编号)。 - :SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::smi_mdc_gpio_num` 和 :cpp:member:`eth_esp32_emac_config_t::smi_mdio_gpio_num`:连接 SMI 信号的 GPIO 编号。 + * :cpp:member:`eth_esp32_emac_config_t::intr_priority`: 设置 MAC 中断的优先级。如果设置为 ``0`` 或负值,则驱动程序将分配一个具有默认优先级的中断。否则,驱动程序将使用给定的优先级。请注意,可以设置 *低*、 *中* 中断优先级(1 到 3),因为这可以在 C 中处理。 - :SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::interface`:配置到 PHY (MII/RMII) 的 MAC 数据接口。 + :SOC_EMAC_USE_MULTI_IO_MUX: * :cpp:member:`eth_esp32_emac_config_t::emac_dataif_gpio`:EMAC MII/RMII 数据平面 GPIO 编号配置。 - :SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::clock_config`:配置 EMAC 接口时钟(RMII 模式下的 ``REF_CLK`` 模式以及 GPIO 编号)。 + :not SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK: * :cpp:member:`eth_esp32_emac_config_t::clock_config_out_in`:当 ``REF_CLK`` 信号在内部生成并从外部回环到 EMAC 时,配置 EMAC 输入接口时钟。必须始终将 EMAC 的模式配置为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_EXT_IN`。此选项仅在 :cpp:member:`eth_esp32_emac_config_t::clock_config` 的配置设置为 :cpp:enumerator:`emac_rmii_clock_mode_t::EMAC_CLK_OUT` 时有效。 PHY 的相关配置可以在 :cpp:class:`eth_phy_config_t` 中找到,具体包括: @@ -172,7 +262,7 @@ PHY 的相关配置可以在 :cpp:class:`eth_phy_config_t` 中找到,具体包 * :cpp:member:`eth_phy_config_t::reset_timeout_ms`:复位超时值,单位为毫秒。通常,PHY 复位应在 100 ms 内完成。 - * :cpp:member:`eth_phy_config_t::autonego_timeout_ms`:自动协商超时值,单位为毫秒。以太网驱动程序会自动与对等的以太网节点进行协商,以确定双工和速度模式。此值通常取决于电路板上 PHY 设备的性能。 + * :cpp:member:`eth_phy_config_t::autonego_timeout_ms`:自动协商超时值,单位为毫秒。以太网驱动程序会与链路另一端的设备进行自协商,以确定连接的最佳双工模式和速率。此值通常取决于电路板上 PHY 设备的性能。 * :cpp:member:`eth_phy_config_t::reset_gpio_num`:如果开发板同时将 PHY 复位管脚连接至了任意 GPIO 管脚,请使用该字段进行配置。否则,配置为 ``-1``。 @@ -434,7 +524,7 @@ ESP-IDF 在宏 :c:macro:`ETH_DEFAULT_CONFIG` 中为安装驱动程序提供了 bool flow_ctrl_enable = true; esp_eth_ioctl(eth_handle, ETH_CMD_S_FLOW_CTRL, &flow_ctrl_enable); -需注意,暂停帧是在自动协商期间由 PHY 向对等端公布的。只有当链路的两边都支持暂停帧时,以太网驱动程序才会发送暂停帧。 +需注意,暂停帧是在自动协商期间由 PHY 向对等端公布的。只有当链路两端都支持暂停帧时,以太网驱动程序才会发送暂停帧。 .. -------------------------------- Examples ----------------------------------- @@ -457,14 +547,14 @@ ESP-IDF 在宏 :c:macro:`ETH_DEFAULT_CONFIG` 中为安装驱动程序提供了 自定义 PHY 驱动程序 ^^^^^^^^^^^^^^^^^^^^^^^^^ -目前市面上已有多家 PHY 制造商提供了大量的芯片组合。ESP-IDF 现已支持数种 PHY 芯片,但是由于价格、功能、库存等原因,有时用户还是无法找到一款能满足其实际需求的芯片。 +市面上有多家 PHY 芯片制造商提供各种类型的芯片。ESP-IDF 现已支持数种 PHY 芯片,但是由于价格、功能、库存等原因,有时用户还是无法找到一款能满足其实际需求的芯片。 -好在 IEEE 802.3 在其 22.2.4 管理功能部分对 EMAC 和 PHY 之间的管理接口进行了标准化。该部分定义了所谓的 ”MII 管理接口”规范,用于控制 PHY 和收集 PHY 的状态,还定义了一组管理寄存器来控制芯片行为、链接属性、自动协商配置等。在 ESP-IDF 中,这项基本的管理功能是由 :component_file:`esp_eth/src/esp_eth_phy_802_3.c` 实现的,这也大大降低了创建新的自定义 PHY 芯片驱动的难度。 +好在 IEEE 802.3 在其 22.2.4 管理功能部分对 EMAC 和 PHY 之间的管理接口进行了标准化。该部分定义了所谓的 ”MII 管理接口”规范,用于控制 PHY 和收集 PHY 的状态,还定义了一组管理寄存器来控制芯片行为、链接属性、自动协商配置等。在 ESP-IDF 中,这项基本的管理功能是由 :component_file:`esp_eth/src/phy/esp_eth_phy_802_3.c` 实现的,这也大大降低了创建新的自定义 PHY 芯片驱动的难度。 .. note:: 由于一些 PHY 芯片可能不符合 IEEE 802.3 第 22.2.4 节的规定,所以请首先查看 PHY 数据手册。不过,就算芯片不符合规定,依旧可以创建自定义 PHY 驱动程序,只是由于需要自行定义所有的 PHY 管理功能,这个过程将变得较为复杂。 -ESP-IDF 以太网驱动程序所需的大部分 PHY 管理功能都已涵盖在 :component_file:`esp_eth/src/esp_eth_phy_802_3.c` 中。不过对于以下几项,可能仍需针对不同芯片开发具体的管理功能: +ESP-IDF 以太网驱动程序所需的大部分 PHY 管理功能都已涵盖在 :component_file:`esp_eth/src/phy/esp_eth_phy_802_3.c` 中。不过对于以下几项,可能仍需针对不同芯片开发具体的管理功能: * 链接状态。此项总是由使用的具体芯片决定 * 芯片初始化。即使不存在严格的限制,也应进行自定义,以确保使用的是符合预期的芯片 @@ -472,11 +562,11 @@ ESP-IDF 以太网驱动程序所需的大部分 PHY 管理功能都已涵盖在 **创建自定义 PHY 驱动程序的步骤:** -1. 请根据 PHY 数据手册,定义针对供应商的特定注册表布局。示例请参见 :component_file:`esp_eth/src/esp_eth_phy_ip101.c`。 +1. 请根据 PHY 数据手册,定义针对供应商的特定注册表布局。示例请参见 :component_file:`esp_eth/src/phy/esp_eth_phy_ip101.c`。 2. 准备衍生的 PHY 管理对象信息结构,该结构: * 必须至少包含 IEEE 802.3 :cpp:class:`phy_802_3_t` 父对象 - * 可选包含支持非 IEEE 802.3 或自定义功能所需的额外变量。示例请参见 :component_file:`esp_eth/src/esp_eth_phy_ksz80xx.c`。 + * 可选择包含额外的变量,以支持非 IEEE 802.3 或定制功能。示例请参见 :component_file:`esp_eth/src/phy/esp_eth_phy_ksz80xx.c`。 3. 定义针对芯片的特定管理回调功能。 4. 初始化 IEEE 802.3 父对象并重新分配针对芯片的特定管理回调功能。 @@ -488,10 +578,13 @@ ESP-IDF 以太网驱动程序所需的大部分 PHY 管理功能都已涵盖在 API 参考 ------------- +.. include-build-file:: inc/eth_types.inc .. include-build-file:: inc/esp_eth.inc .. include-build-file:: inc/esp_eth_driver.inc .. include-build-file:: inc/esp_eth_com.inc .. include-build-file:: inc/esp_eth_mac.inc +.. include-build-file:: inc/esp_eth_mac_esp.inc +.. include-build-file:: inc/esp_eth_mac_spi.inc .. include-build-file:: inc/esp_eth_phy.inc .. include-build-file:: inc/esp_eth_phy_802_3.inc .. include-build-file:: inc/esp_eth_netif_glue.inc diff --git a/docs/zh_CN/api-reference/peripherals/cap_touch_sens.rst b/docs/zh_CN/api-reference/peripherals/cap_touch_sens.rst new file mode 100644 index 000000000000..de4928883deb --- /dev/null +++ b/docs/zh_CN/api-reference/peripherals/cap_touch_sens.rst @@ -0,0 +1,415 @@ +电容式触摸传感器 +=================== + +:link_to_translation:`en:[English]` + +{IDF_TARGET_TOUCH_SENSOR_VERSION:default="NOT_UPDATED", esp32p4="v3"} + +概述 +------------ + +触摸传感器系统由保护覆盖层、触摸电极、绝缘基板和走线组成,保护覆盖层位于最上层,绝缘基板上设有电极及走线。触摸覆盖层将引起电容变化,根据电容变化,可以判断此次触摸是否为有效触摸行为。 + +触摸传感器可以以矩阵或滑条等方式组合使用,从而覆盖更大触感区域及更多触感点。触摸传感由软件或专用硬件计时器发起,由有限状态机 (FSM) 硬件控制。 + +如需了解触摸传感器设计、操作及其控制寄存器等相关信息,请参考《`{IDF_TARGET_NAME} 技术参考手册 <{IDF_TARGET_TRM_CN_URL}>`_》(PDF) 中“片上传感器与模拟信号处理”章节。 + +请参考 `触摸传感器应用方案简介 `_,查看触摸传感器设计详情和固件开发指南。 + +电容式触摸传感器版本概览 +------------------------- + ++-----------+--------------+------------------------------------------------------------------------+ +| 硬件版本 | 芯片 | 主要特征 | ++===========+==============+========================================================================+ +| V1 | ESP32 | 第一代触摸传感器,触摸时读数变小 | ++-----------+--------------+------------------------------------------------------------------------+ +| V2 | ESP32-S2 | 第二代触摸传感器,触摸时读数变大 | +| | | 新增防水防潮、接近感应、睡眠唤醒功能 | +| +--------------+------------------------------------------------------------------------+ +| | ESP32-S3 | 第二代触摸传感器,新增接近感应测量完成中断 | ++-----------+--------------+------------------------------------------------------------------------+ +| V3 | ESP32-P4 | 第三代触摸传感器,新增跳频扫描 | ++-----------+--------------+------------------------------------------------------------------------+ + +触摸通道概览 +---------------------- + +.. only:: esp32p4 + + ====== ===== ===== ===== ===== ===== ===== ===== ===== ====== ====== ====== ====== ====== ====== ========== + 通道 CH0 CH1 CH2 CH3 CH4 CH5 CH6 CH7 CH8 CH9 CH10 CH11 CH12 CH13 CH14 + ------ ----- ----- ----- ----- ----- ----- ----- ----- ------ ------ ------ ------ ------ ------ ---------- + GPIO IO2 IO3 IO4 IO5 IO6 IO7 IO8 IO9 IO10 IO11 IO12 IO13 IO14 IO15 未引出 + ====== ===== ===== ===== ===== ===== ===== ===== ===== ====== ====== ====== ====== ====== ====== ========== + +驱动中的术语介绍 +------------------------- + +- **触摸传感器控制器**:触摸传感器驱动的控制器,负责触摸传感器的配置和管理。 +- **触摸传感器通道**:具体的一路触摸传感器采样通道。一个触摸传感器模块具有多个通道,一般连接到触摸板上,用于测量该触摸板电容的变化。驱动中把对 **一个** 通道的采样称为 ``测量``,而对 **所有** 注册通道的 ``测量`` 称为一次 ``扫描``。 + +.. only:: IDF_TARGET_TOUCH_SAMPLE_CFG_DESC + + - **触摸传感器采样配置**:触摸传感器采样配置是驱动中对采样有关的硬件配置的统称。采样配置负责触摸传感器通道的采样,其配置决定了触摸通道的充放电次数、充放电频率、测量间隔等。{IDF_TARGET_NAME} 支持多套采样配置,支持跳频采样。 + +.. only:: not IDF_TARGET_TOUCH_SAMPLE_CFG_DESC + + - **触摸传感器采样配置**:触摸传感器采样配置是驱动中对采样有关的硬件配置的统称。采样配置负责触摸传感器通道的采样,其配置决定了触摸通道的充放电次数、充放电频率、测量间隔等。{IDF_TARGET_NAME} 仅支持一套采样配置,不支持跳频采样。 + +文件结构 +-------------------- + +.. figure:: ../../../_static/diagrams/cap_touch_sens/touch_file_structure.svg + :align: center + :alt: 触摸传感器驱动文件结构图 + + 触摸传感器驱动文件结构图 + +驱动状态机 +--------------------- + +下图为触摸传感器驱动的状态机,描述了调用不同函数后驱动的运行状态,以及状态变迁的约束。 + +.. figure:: ../../../_static/diagrams/cap_touch_sens/touch_state_machine.svg + :align: center + :alt: 触摸传感器驱动状态机示意图 + + 触摸传感器驱动状态机示意图 + +上图为触摸传感器驱动的状态机,描述了调用不同函数后状态的变换关系。其中 ```` 部分为可选的配置项,包括对触摸驱动控制器和触摸通道的重新配置、回调函数注册等。 + +.. note:: + + :cpp:func:`touch_channel_read_data` 可在获取触摸通道句柄后(即 ``INIT`` 后)任意状态调用,但请注意读数值的有效性。 + +功能介绍 +------------------ + +{IDF_TARGET_NAME} 的电容式触摸传感器驱动提供的 API 按功能主要可分为: + +.. list:: + + - `触摸传感器控制器管理 <#touch-ctrl>`__ + - `触摸传感器通道管理 <#touch-chan>`__ + - `滤波器配置 <#touch-filter>`__ + - `回调函数 <#touch-callback>`__ + - `启用和禁用 <#touch-enable>`__ + - `连续扫描 <#touch-conti-scan>`__ + - `单次扫描 <#touch-oneshot-scan>`__ + - `基线值配置 <#touch-benchmark>`__ + - `测量值读数 <#touch-read>`__ + :SOC_TOUCH_SUPPORT_WATERPROOF: - `防水防潮配置 <#touch-waterproof>`__ + :SOC_TOUCH_SUPPORT_PROX_SENSING: - `接近感应配置 <#touch-prox-sensing>`__ + :SOC_TOUCH_SUPPORT_SLEEP_WAKEUP: - `睡眠唤醒配置 <#touch-sleep-wakeup>`__ + +.. _touch-ctrl: + +触摸传感器控制器管理 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +触摸传感器驱动通过触摸传感器控制器句柄 :cpp:type:`touch_sensor_handle_t` 控制。调用 :cpp:func:`touch_sensor_new_controller` 函数即可初始化触摸传感器控制器并得到控制器句柄。 + +.. code-block:: c + + // 有些芯片支持多套采样配置,这里以一套为例 + #define SAMPLE_NUM 1 + touch_sensor_handle_t sens_handle = NULL; + // 采样配置 + touch_sensor_sample_config_t sample_cfg[SAMPLE_NUM] = { + // 指定采样配置或通过 `TOUCH_SENSOR_Vn_DEFAULT_SAMPLE_CONFIG` 使用默认采样配置 + // ... + }; + // 默认控制器配置 + touch_sensor_config_t touch_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(SAMPLE_NUM, sample_cfg); + // 申请一个新的触摸传感器控制器句柄 + ESP_ERROR_CHECK(touch_sensor_new_controller(&touch_cfg, &sens_handle)); + +删除触摸传感器驱动控制器时需调用 :cpp:func:`touch_sensor_del_controller` 函数,从而释放该控制器所占用的软硬件资源。注意,需要将基于该控制器申请的其他资源销毁或释放后才能删除该控制器。如该控制器下仍有触摸通道未被删除,则无法直接删除。 + +.. code-block:: c + + ESP_ERROR_CHECK(touch_sensor_del_controller(sens_handle)); + +在触摸传感器驱动控制器初始化后,且未启用触摸传感器时,可调用 :cpp:func:`touch_sensor_reconfig_controller` 函数对该控制器进行重新配置。 + +.. code-block:: c + + touch_sensor_config_t touch_cfg = { + // 控制器的新配置 + // ... + }; + ESP_ERROR_CHECK(touch_sensor_reconfig_controller(sens_handle, &touch_cfg)); + +.. _touch-chan: + +触摸传感器通道管理 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +一个触摸传感器具有多个测量通道,每个触摸传感器通道由句柄 :cpp:type:`touch_channel_handle_t` 控制。调用 :cpp:func:`touch_sensor_new_channel` 函数即可初始化触摸传感器通道并得到通道句柄。 + +.. code-block:: c + + // ... + touch_channel_config_t chan_cfg = { + // 触摸通道配置 + // ... + }; + touch_channel_handle_t chan_handle = NULL; + int chan_id = 0; + // 申请一个新的触摸通道句柄 + ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, chan_id, &chan_cfg, &chan_handle)); + +删除触摸传感器通道时需调用 :cpp:func:`touch_sensor_del_channel` 函数,从而释放该通道所占用的软硬件资源。 + +.. code-block:: c + + ESP_ERROR_CHECK(touch_sensor_del_channel(chan_handle)); + +在触摸传感器驱动通道初始化后,且未启用触摸传感器时,可调用 :cpp:func:`touch_sensor_reconfig_channel` 函数对该通道进行重新配置。 + +.. code-block:: c + + touch_channel_config_t chan_cfg = { + // 触摸通道新配置 + // ... + }; + ESP_ERROR_CHECK(touch_sensor_reconfig_channel(chan_handle, &chan_cfg)); + +.. _touch-filter: + +滤波器配置 +^^^^^^^^^^^^^^ + +触摸传感器可以通过配置滤波器来提升不同场景下的数据稳定性。调用 :cpp:func:`touch_sensor_config_filter` 并指定 :cpp:type:`touch_sensor_filter_config_t` 来配置基线值和读数值的滤波策略和更新方式,配置后对所有启用的触摸通道都生效。 + +若需要注销滤波器,可再次调用 :cpp:func:`touch_sensor_config_filter` 并将第二个参数(即 :cpp:type:`touch_sensor_filter_config_t` 的配置结构体指针)设为 ``NULL`` 来注销滤波器功能。 + +.. code-block:: c + + // ... + touch_sensor_filter_config_t filter_config = { + // 滤波器配置 + // ... + }; + // 注册滤波器 + ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, &filter_config)); + // ... + // 注销滤波器 + ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, NULL)); + +.. _touch-callback: + +回调函数 +^^^^^^^^^^^^^ + +通过调用 :cpp:func:`touch_sensor_register_callbacks` 注册各类触摸传感器事件回调函数,当触摸传感器通道触发如触摸 ``on_active``、释放 ``on_inactive`` 等事件时,就会调用对应的回调函数通知上层应用,以便对触摸事件进行处理。 + +例如,测量值超出当前的测量通道的 ``基线值`` + ``触发阈值``,则该通道将被触发,并调用 ``on_active`` 事件的回调函数,通知应用层该触摸通道被 ``触发``。同理,若处于 ``触发`` 状态的通道测量值小于 ``基线值`` + ``触发阈值``,则该通道将回到未触发状态,并调用 ``on_inactive`` 事件的回调函数,通知应用层该触摸通道被 ``释放``。 + +.. note:: + + 为保证触发和释放事件的稳定性,触摸传感器可配置 ``触发阈值`` 的迟滞比较裕量和 ``去抖动计数`` 来避免短时间内由噪声和读数抖动引起的反复触发和释放 + +具体可注册的回调时间请参考 :cpp:type:`touch_event_callbacks_t`。 + +.. code-block:: c + + touch_event_callbacks_t callbacks = { + .on_active = example_touch_on_active_cb, + // 其他回调函数 + // ... + }; + // 注册回调函数 + ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL)); + + // 通过把相应回调设为 NULL 以注销回调函数 + callbacks.on_active = NULL; + // 其他需要注销的回调函数 + // ... + ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL)); + +.. _touch-enable: + +启用和禁用 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +配置完成触摸传感器控制器以及通道后,可调用 :cpp:func:`touch_sensor_enable` 函数启用该控制器,启用后控制器处于 ``就绪`` 状态,会对注册的通道上电,可以开始扫描并采集触摸数据。注意,控制器启用后无法更新配置,只能进行扫描采样和读数操作。若要更新配置,需先调用 :cpp:func:`touch_sensor_disable` 函数禁用控制器,方可重新配置控制器、通道等。 + +.. code-block:: c + + // 启用触摸传感器 + ESP_ERROR_CHECK(touch_sensor_enable(sens_handle)); + // ... + // 禁用触摸传感器 + ESP_ERROR_CHECK(touch_sensor_disable(sens_handle)); + +.. _touch-conti-scan: + +连续扫描 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +在控制器启用后,调用 :cpp:func:`touch_sensor_start_continuous_scanning` 函数可开始对所有已注册的触摸通道进行连续扫描,每次扫描都会更新对应通道的测量值。调用 :cpp:func:`touch_sensor_stop_continuous_scanning` 函数后则停止扫描。 + +.. code-block:: c + + // 开始连续扫描 + ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle)); + // ... + // 停止连续扫描 + ESP_ERROR_CHECK(touch_sensor_stop_continuous_scanning(sens_handle)); + +.. _touch-oneshot-scan: + +单次扫描 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +在控制器启用后,调用 :cpp:func:`touch_sensor_trigger_oneshot_scanning` 函数可触发一次对所有已注册的触摸通道的扫描。注意,单次扫描为阻塞函数,调用后会保持阻塞直到扫描结束后返回。此外在开始连续扫描后,无法再触发单次扫描。 + +.. code-block:: c + + // 触发单次扫描,并设置超时时间为 1000ms + ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(sens_handle, 1000)); + +.. _touch-benchmark: + +基线值配置 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +一般情况下,不需要额外设置触摸传感器的基线值,若有必要强制复位基线值到当前平滑值,可调用 :cpp:func:`touch_channel_config_benchmark`。 + +.. code-block:: c + + touch_chan_benchmark_config_t benchmark_cfg = { + // 基线操作 + // ... + }; + ESP_ERROR_CHECK(touch_channel_config_benchmark(chan_handle, &benchmark_cfg)); + +.. _touch-read: + +测量值读数 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +调用 :cpp:func:`touch_channel_read_data` 可读取每个通道不同种类的数据,例如基线值、经过滤波后的平滑值等。支持的数据类型请参考 :cpp:type:`touch_chan_data_type_t`。 + +.. only:: SOC_TOUCH_SUPPORT_FREQ_HOP + + {IDF_TARGET_NAME} 支持通过配置多套采样配置来实现跳频采样,:cpp:func:`touch_channel_read_data` 可一次性读出一个通道所有采样配置的测量值。根据配置的 :cpp:member:`touch_sensor_config_t::sample_cfg_num` 采样配置数量,第三个参数 (``*data``) 数据指针传入数组长度大于等于采样配置数量的数组指针即可,该函数会将所指定通道的所有采样配置的测量值存入该数组中。 + +.. code-block:: c + + #define SAMPLE_NUM 1 // 以一套采样配置为例 + uint32_t smooth_data[SAMPLE_NUM] = {}; + // 读取滤波后的平滑数据 + ESP_ERROR_CHECK(touch_channel_read_data(chan_handle, TOUCH_CHAN_DATA_TYPE_SMOOTH, smooth_data)); + +.. _touch-waterproof: + +.. only:: SOC_TOUCH_SUPPORT_WATERPROOF + + 防水防潮配置 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} 支持防水防潮功能。可通过调用 :cpp:func:`touch_sensor_config_waterproof` 并配置 :cpp:type:`touch_waterproof_config_t` 来注册防水防潮功能。防水防潮功能主要包含两部分: + + - 遇水(浸没)保护功能: :cpp:member:`touch_waterproof_config_t::guard_chan` 用于指定用于遇水保护功能的触摸通道,该通道在 PCB 上一般设计成环形,其他普通触摸通道布局在该环形保护圈内,当电路板大面积浸水时,该环形保护通道会被触发,并停止其他触摸通道的扫描,由此防止其他普通通道的误触发; + - 防潮(水滴)屏蔽功能: :cpp:member:`touch_waterproof_config_t::shield_chan` 用于指定防潮屏蔽功能的触摸通道,该通道在 PCB 上一般设计成网格状铺铜。防潮屏蔽通道将与当前测量通道进行同步充放电,当有小水珠覆盖时,通过配置适当的 :cpp:member:`touch_waterproof_config_t::shield_drv` 来提高因水滴造成的电耦合强度,从而识别水滴造成的误触。在实际应用中识别到水滴造成的误触后可适当增加触摸通道触发的阈值来实现通道在水滴覆盖下的正常触发,从而实现防潮功能。 + + 若需要注销防水防潮功能,可再次调用 :cpp:func:`touch_sensor_config_waterproof` 并将第二个参数(即 :cpp:type:`touch_waterproof_config_t` 的配置结构体指针)设为 ``NULL`` 来注销防水防潮功能。 + + .. code-block:: c + + touch_waterproof_config_t waterproof_cfg = { + // 防水防潮配置 + // ... + }; + // 注册防水防潮功能 + ESP_ERROR_CHECK(touch_sensor_config_waterproof(sens_handle, &waterproof_cfg)); + // ... + // 注销防水防潮功能 + ESP_ERROR_CHECK(touch_sensor_config_waterproof(sens_handle, NULL)); + +.. _touch-prox-sensing: + +.. only:: SOC_TOUCH_SUPPORT_PROX_SENSING + + 接近感应配置 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} 支持接近感应功能。可通过调用 :cpp:func:`touch_sensor_config_proximity_sensing` 并配置 :cpp:type:`touch_proximity_config_t` 来注册接近感应功能。 + + 由于接近感应引起的电容变化远小于物理触摸,PCB 上常用较大面积的铺铜来增大触摸通道的感应面积,另外需要在硬件上对接近感应通道进行多轮扫描并在驱动中进行累加来提高测量灵敏度。接近感应的灵敏度由测量轮数 :cpp:member:`touch_proximity_config_t::scan_times` 以及单次测量的充放电次数 :cpp:member:`touch_proximity_config_t::charge_times` 决定。测量轮数以及充放电次数越高,灵敏度越高,但是过高的灵敏度容易导致误触发,请选择适当的灵敏度来保证触发的稳定性。 + + 接近感应通道多次测量的累加值也可通过 :cpp:func:`touch_channel_read_data` 获取,数据类型 :cpp:type:`touch_chan_data_type_t` 为 :cpp:enumerator:`TOUCH_CHAN_DATA_TYPE_PROXIMITY`。 + + 若需要注销接近感应功能,可再次调用 :cpp:func:`touch_sensor_config_proximity_sensing` 并将第二个参数(即 :cpp:type:`touch_proximity_config_t` 的配置结构体指针)设为 ``NULL`` 来注销接近感应功能。 + + .. code-block:: c + + touch_proximity_config_t prox_cfg = { + // 接近感应配置 + // ... + }; + // 注册接近感应功能 + ESP_ERROR_CHECK(touch_sensor_config_proximity_sensing(sens_handle, &prox_cfg)); + // ... + // 注销接近感应功能 + ESP_ERROR_CHECK(touch_sensor_config_proximity_sensing(sens_handle, NULL)); + +.. _touch-sleep-wakeup: + +.. only:: SOC_TOUCH_SUPPORT_SLEEP_WAKEUP + + 睡眠唤醒配置 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} 支持触摸传感器将芯片从浅睡眠或深睡眠状态中唤醒。可通过调用 :cpp:func:`touch_sensor_config_sleep_wakeup` 并配置 :cpp:type:`touch_sleep_config_t` 来注册接近感应功能。 + + 注册触摸传感器的睡眠唤醒功能后,处于睡眠状态下的芯片仍将继续保持对触摸传感器的采样,这将会导致芯片睡眠后的功耗增加,可通过减少充放电次数、增加采样间隔等方式来降低功耗。 + + 另外,请注意在主核睡眠期间的采样、唤醒等操作均由硬件完成,本驱动由于运行在主核上,无法提供读数、配置等功能。 + + .. only:: SOC_RISCV_COPROC_SUPPORTED + + 若需要在睡眠过程中进行读数、配置等操作,可通过运行在 :doc:`超低功耗协处理器 ULP <../system/ulp>` 上的触摸传感器驱动 ``components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_touch_ulp_core.h`` 实现。 + + - 浅睡眠状态唤醒:通过指定 :cpp:member:`slp_wakeup_lvl` 为 :cpp:enumerator:`TOUCH_LIGHT_SLEEP_WAKEUP` 即可启用触摸传感器浅睡眠唤醒功能。注意任何已注册的触摸传感器通道都会在浅睡眠状态下保持采样并支持唤醒浅睡眠。 + - 深睡眠状态唤醒:启用触摸传感器深睡眠唤醒功能除了指定 :cpp:member:`slp_wakeup_lvl` 为 :cpp:enumerator:`TOUCH_DEEP_SLEEP_WAKEUP` 外,还需要指定深睡眠唤醒通道 :cpp:member:`deep_slp_chan`,注意只有该指定的通道才会在深睡眠状态下保持采样以及唤醒,以此降低在深睡眠状态下的功耗。此外,若需要在深度睡眠下使用另一套低功耗的配置来进一步降低功耗,可以通过 :cpp:member:`deep_slp_sens_cfg` 额外指定一套低功耗配置,在进入深睡眠前,驱动会应用这套配置,从深睡眠状态唤醒后,则会重新配置到之前的配置。请注意当 :cpp:member:`slp_wakeup_lvl` 配置为 :cpp:enumerator:`TOUCH_DEEP_SLEEP_WAKEUP` 后,触摸传感器不仅能唤醒深睡眠状态,还能唤醒浅睡眠状态。 + + 若需要注销睡眠唤醒功能,可再次调用 :cpp:func:`touch_sensor_config_sleep_wakeup` 并将第二个参数(即 :cpp:type:`touch_sleep_config_t` 的配置结构体指针)设为 ``NULL`` 来注销睡眠唤醒功能。 + + .. code-block:: c + + touch_sleep_config_t light_slp_cfg = { + .slp_wakeup_lvl = TOUCH_LIGHT_SLEEP_WAKEUP, + }; + // 注册浅睡眠唤醒功能 + ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &light_slp_cfg)); + // ... + // 注销睡眠唤醒功能 + ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, NULL)); + touch_sleep_config_t deep_slp_cfg = { + .slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP, + .deep_slp_chan = dslp_chan_handle, + // 其他深睡眠唤醒配置 + // ... + }; + // 注册深睡眠唤醒功能 + ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &deep_slp_cfg)); + +应用示例 +-------------------- + +.. only:: esp32p4 + + - 触摸传感器基础例程: :example:`peripherals/touch_sensor/touch_sensor_{IDF_TARGET_TOUCH_SENSOR_VERSION}`. + +API 参考 +------------- + +.. only:: esp32p4 + + .. include-build-file:: inc/touch_sens.inc + .. include-build-file:: inc/touch_sens_types.inc + .. include-build-file:: inc/touch_version_types.inc diff --git a/docs/zh_CN/api-reference/peripherals/etm.rst b/docs/zh_CN/api-reference/peripherals/etm.rst index 8d56935aec34..4a490af6b50f 100644 --- a/docs/zh_CN/api-reference/peripherals/etm.rst +++ b/docs/zh_CN/api-reference/peripherals/etm.rst @@ -56,7 +56,7 @@ GPIO 事件 GPIO **边沿** 事件是最常见的事件类型,任何 GPIO 管脚均可触发这类事件。要创建 GPIO 事件句柄,请调用 :cpp:func:`gpio_new_etm_event`,并使用 :cpp:type:`gpio_etm_event_config_t` 提供的配置信息: -- :cpp:member:`gpio_etm_event_config_t::edge` 决定触发事件的边沿类型,支持的边沿类型已在 :cpp:type:`gpio_etm_event_edge_t` 中列出。 +- :cpp:member:`gpio_etm_event_config_t::edge` 或 :cpp:member:`gpio_etm_event_config_t::edges` 决定触发事件的边沿类型,支持的边沿类型已在 :cpp:type:`gpio_etm_event_edge_t` 中列出。 接下来,请调用 :cpp:func:`gpio_etm_event_bind_gpio` 函数,连接 GPIO ETM 事件句柄与 GPIO 管脚。注意,要设置 GPIO 管脚,只能使用由 :cpp:func:`gpio_new_etm_event` 函数创建的 ETM 事件句柄。对于其他类型的 ETM 事件,调用此函数,将返回 :c:macro:`ESP_ERR_INVALID_ARG` 错误。该函数也无法完成 GPIO 的初始化,在使用 GPIO ETM 事件之前,仍需调用 :cpp:func:`gpio_config` 函数,设置 GPIO 管脚的属性,如方向、高/低电平模式等。 @@ -82,9 +82,9 @@ ETM 任务对其操作进行了抽象,在软件中表示为 :cpp:type:`esp_etm GPIO 任务 ~~~~~~~~~~ -GPIO 任务是最常见的任务类型,一个 GPIO 任务可以同时管理多个 GPIO 管脚。当 ETM 通道激活任务时,任务可以同时设置管理的所有 GPIO 引脚,使其设置/清除/切换状态。要创建 GPIO 任务句柄,请调用 :cpp:func:`gpio_new_etm_task`,并使用 :cpp:type:`gpio_etm_task_config_t` 提供的配置信息: +GPIO 任务是最常见的任务类型。一个 GPIO 可以采取一个或多个 GPIO 操作,而一个 GPIO 任务也可以同时管理多个 GPIO 管脚。当 ETM 通道激活任务时,任务可以同时设置管理的所有 GPIO 引脚,使其设置/清除/切换状态。要创建 GPIO 任务句柄,请调用 :cpp:func:`gpio_new_etm_task`,并使用 :cpp:type:`gpio_etm_task_config_t` 提供的配置信息: -- :cpp:member:`gpio_etm_task_config_t::action` 决定 ETM 任务将采取的 GPIO 操作,支持的操作类型在 :cpp:type:`gpio_etm_task_action_t` 中列出。 +- :cpp:member:`gpio_etm_task_config_t::action` 或 :cpp:member:`gpio_etm_task_config_t::actions` 决定 ETM 任务将采取的 GPIO 操作,支持的操作类型在 :cpp:type:`gpio_etm_task_action_t` 中列出。如果一个 GPIO 需要采取多个 GPIO 操作,这些操作任务的创建必须通过配置 :cpp:member:`gpio_etm_task_config_t::actions` 的数组并在一次 :cpp:func:`gpio_new_etm_task` 调用中一并完成。 接下来,需要连接 GPIO ETM 任务句柄与 GPIO 管脚。为此,请调用 :cpp:func:`gpio_etm_task_add_gpio` 函数。如果需要任务句柄管理更多的 GPIO 管脚,可以重复调用以上函数,注意,要设置 GPIO 管脚,只能使用由 :cpp:func:`gpio_new_etm_task` 函数创建的 ETM 任务句柄。对于其他类型的 ETM 任务,调用此函数,将返回 :c:macro:`ESP_ERR_INVALID_ARG` 错误。该函数也无法完成 GPIO 的初始化,在使用 GPIO ETM 任务之前,仍需调用 :cpp:func:`gpio_config` 函数,设置 GPIO 管脚的属性,如方向、高/低电平模式等。 diff --git a/docs/zh_CN/api-reference/peripherals/gpio.rst b/docs/zh_CN/api-reference/peripherals/gpio.rst index e071fc93195d..99d6fcac03ef 100644 --- a/docs/zh_CN/api-reference/peripherals/gpio.rst +++ b/docs/zh_CN/api-reference/peripherals/gpio.rst @@ -73,7 +73,9 @@ GPIO 驱动提供了一个函数 :cpp:func:`gpio_dump_io_configuration` 用来 如果 IO 管脚通过 GPIO 交换矩阵连接到内部外设信号,输出信息打印中的外设信号 ID 定义可以在 :component_file:`soc/{IDF_TARGET_PATH_NAME}/include/soc/gpio_sig_map.h` 头文件中查看。``**RESERVED**`` 字样则表示此 IO 用于连接 SPI flash 或 PSRAM,强烈建议不要重新配置这些管脚用于其他功能。 -.. only:: esp32c3 or esp32c6 or esp32h2 or esp32p4 or esp32s2 or esp32s3 +请不要依赖技术参考手册中记录的 GPIO 默认配置状态,因为特殊用途的 GPIO 可能会在 app_main 之前被引导程序或应用程序启动阶段的代码更改。 + +.. only:: esp32c3 or esp32c6 or esp32h2 or esp32p4 or esp32s2 or esp32s3 or esp32c5 配置 USB PHY 管脚 为普通 GPIO 管脚 --------------------------------------- diff --git a/docs/zh_CN/api-reference/peripherals/gpio/esp32c5.inc b/docs/zh_CN/api-reference/peripherals/gpio/esp32c5.inc index 78f87a207f43..a3b314371886 100644 --- a/docs/zh_CN/api-reference/peripherals/gpio/esp32c5.inc +++ b/docs/zh_CN/api-reference/peripherals/gpio/esp32c5.inc @@ -9,9 +9,7 @@ .. gpio-summary -当前的 GPIO 适用于 {IDF_TARGET_NAME} beta3 版本。{IDF_TARGET_NAME} MP 版本将会增加 2 个可用的 IO,并且一些引脚功能将会改变。{IDF_TARGET_NAME} MP 版本将会在以后更新。 - -{IDF_TARGET_NAME} 芯片具有 27 个物理 GPIO 管脚(GPIO0 ~ GPIO26)。每个管脚都可用作一个通用 IO,或连接一个内部的外设信号。通过 GPIO 交换矩阵和 IO MUX,可配置外设模块的输入信号来源于任何的 IO 管脚,并且外设模块的输出信号也可连接到任意 IO 管脚。这些模块共同组成了芯片的 IO 控制。更多详细信息,请参阅 *{IDF_TARGET_NAME} 技术参考手册* > *IO MUX 和 GPIO 矩阵(GPIO、IO_MUX)* [`PDF <{IDF_TARGET_TRM_CN_URL}#iomuxgpio>`__]。 +{IDF_TARGET_NAME} 芯片具有 29 个物理 GPIO 管脚(GPIO0 ~ GPIO28)。每个管脚都可用作一个通用 IO,或连接一个内部的外设信号。通过 GPIO 交换矩阵和 IO MUX,可配置外设模块的输入信号来源于任何的 IO 管脚,并且外设模块的输出信号也可连接到任意 IO 管脚。这些模块共同组成了芯片的 IO 控制。更多详细信息,请参阅 *{IDF_TARGET_NAME} 技术参考手册* > *IO MUX 和 GPIO 矩阵(GPIO、IO_MUX)* [`PDF <{IDF_TARGET_TRM_CN_URL}#iomuxgpio>`__]。 下表提供了各管脚的详细信息,部分 GPIO 具有特殊的使用限制,具体可参考表中的注释列。 @@ -42,7 +40,7 @@ * - GPIO3 - ADC1_CH2 - LP_GPIO3 - - Strapping 管脚 + - * - GPIO4 - ADC1_CH3 @@ -57,7 +55,7 @@ * - GPIO6 - ADC1_CH5 - LP_GPIO6 - - Strapping 管脚 + - * - GPIO7 - @@ -92,12 +90,12 @@ * - GPIO13 - - - - + - USB-JTAG * - GPIO14 - - - - + - USB-JTAG * - GPIO15 - @@ -107,12 +105,12 @@ * - GPIO16 - - - - + - SPI0/1 * - GPIO17 - - - - + - SPI0/1 * - GPIO18 - @@ -142,27 +140,37 @@ * - GPIO23 - - - - SPI0/1 + - * - GPIO24 - - - - SPI0/1 + - * - GPIO25 - - - - USB-JTAG + - * - GPIO26 - - - - USB-JTAG + - + + * - GPIO27 + - + - + - Strapping 管脚 + + * - GPIO28 + - + - + - Strapping 管脚 .. note:: - - Strapping 管脚:GPIO2、GPIO3、GPIO6 和 GPIO7 是 Strapping 管脚。更多信息请参考 `ESP32-C5 技术规格书 <{IDF_TARGET_DATASHEET_CN_URL}>`_。 - - SPI0/1:GPIO18 ~ GPIO24 通常用于 SPI flash,不推荐用于其他用途。 - - USB-JTAG:GPIO25 和 GPIO26 默认用于 USB-JTAG。如果将它们配置为普通 GPIO,驱动程序将禁用 USB-JTAG 功能。 + - Strapping 管脚:GPIO2、GPIO7、GPIO27 和 GPIO28 是 Strapping 管脚。更多信息请参考 `ESP32-C5 技术规格书 <{IDF_TARGET_DATASHEET_CN_URL}>`_。 + - SPI0/1:GPIO16 ~ GPIO22 通常用于 SPI flash,不推荐用于其他用途。 + - USB-JTAG:GPIO13 和 GPIO14 默认用于 USB-JTAG。如果将它们配置为普通 GPIO,驱动程序将禁用 USB-JTAG 功能。 --- diff --git a/docs/zh_CN/api-reference/peripherals/index.rst b/docs/zh_CN/api-reference/peripherals/index.rst index 36c28c313100..ea2198b57a30 100644 --- a/docs/zh_CN/api-reference/peripherals/index.rst +++ b/docs/zh_CN/api-reference/peripherals/index.rst @@ -29,6 +29,7 @@ :SOC_MCPWM_SUPPORTED: mcpwm :SOC_PARLIO_SUPPORTED: parlio :SOC_PCNT_SUPPORTED: pcnt + :SOC_PPA_SUPPORTED: ppa :SOC_RMT_SUPPORTED: rmt :SOC_SDMMC_HOST_SUPPORTED or SOC_SDIO_SLAVE_SUPPORTED: sd_pullup_requirements :SOC_SDMMC_HOST_SUPPORTED: sdmmc_host @@ -41,7 +42,8 @@ :SOC_SPI_SUPPORT_SLAVE_HD_VER2: spi_slave_hd :SOC_JPEG_CODEC_SUPPORTED: jpeg :SOC_TEMP_SENSOR_SUPPORTED: temp_sensor - :SOC_TOUCH_SENSOR_SUPPORTED: touch_pad + :SOC_TOUCH_SENSOR_SUPPORTED and not esp32p4: touch_pad + :esp32p4: cap_touch_sens :esp32s2: touch_element :SOC_TWAI_SUPPORTED: twai uart diff --git a/docs/zh_CN/api-reference/peripherals/ppa.rst b/docs/zh_CN/api-reference/peripherals/ppa.rst new file mode 100644 index 000000000000..80c3ffb369d7 --- /dev/null +++ b/docs/zh_CN/api-reference/peripherals/ppa.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-reference/peripherals/ppa.rst diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst index a222654aa8f9..eb3b3dab14a2 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst @@ -19,7 +19,7 @@ SPI1 flash 并发约束 .. only:: SOC_SPIRAM_XIP_SUPPORTED - 在 {IDF_TARGET_NAME} 上,启用配置选项 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` (默认禁用)和 :ref:`CONFIG_SPIRAM_RODATA` (默认禁用)后将允许 flash/PSRAM 的 cache 访问和 SPI1 的操作并发执行。请参阅 :ref:`xip_from_psram`,查看详细信息。 + 在 {IDF_TARGET_NAME} 上,启用配置选项 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` (默认禁用)后将允许 flash/PSRAM 的 cache 访问和 SPI1 的操作并发执行。请参阅 :ref:`xip_from_psram`,查看详细信息。 禁用该选项时,在读取/写入/擦除 flash 期间,必须禁用 cache。使用驱动访问 SPI1 的相关约束参见 :ref:`impact_disabled_cache`。这些约束会带来更多的 IRAM/DRAM 消耗。 @@ -40,7 +40,7 @@ SPI1 flash 并发约束 .. note:: - 同时启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 和 :ref:`CONFIG_SPIRAM_RODATA` 选项后,不会禁用 cache。 + 启用 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` 选项后,不会禁用 cache。 .. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES @@ -77,6 +77,13 @@ IRAM 安全中断处理程序 如果在注册时没有设置 ``ESP_INTR_FLAG_IRAM`` 标志,当禁用 cache 时,将不会执行中断处理程序。一旦 cache 恢复,非 IRAM 安全的中断将重新启用,中断处理程序随即再次正常运行。这意味着,只要禁用了 cache,就不会发生相应的硬件事件。 +.. only:: SOC_DMA_CAN_ACCESS_FLASH + + 当 DMA 也可以访问 Flash 中的数据时 + ---------------------------------- + + 当 DMA 正在从 Flash 中读取数据时,来自 SPI1 的擦/写操作优先级会更高,如果 Flash 的 auto-suspend 功能没有开启,将会导致 DMA 读到错误的数据。建议在擦写 Flash 之前先停止 DMA 对 Flash 的访问。如果 DMA 不可以停止,比如 LCD 需要持续刷新保存在 Flash 中的图像数据,建议将此类数据拷贝到 PSRAM 或者内部的 SRAM 中。 + .. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/xip_from_psram.inc b/docs/zh_CN/api-reference/peripherals/spi_flash/xip_from_psram.inc index 0ab88d805b2c..ec11ccda61b9 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/xip_from_psram.inc +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/xip_from_psram.inc @@ -3,10 +3,8 @@ 在 PSRAM 中执行代码 ---------------------- -启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 选项后,flash 中 ``.text`` 部分的数据(用于指令)将被放入 PSRAM。 +启用 :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM` 选项后,flash 中 ``.text`` 部分的数据(用于指令)和 flash 中 ``.rodata`` 部分的数据(用于只读数据)将被放入 PSRAM。 -启用 :ref:`CONFIG_SPIRAM_RODATA` 选项后,flash 中 ``.rodata`` 部分的数据(用于只读数据)将被放入 PSRAM。 - -相应的虚拟内存地址将被重新映射到 PSRAM。 +相应的虚拟内存地址将被映射到 PSRAM。 如果同时启用以上两个选项,则在 SPI1 flash 操作期间 cache 不会被禁用,无需确保 ISR、ISR 回调及相关数据放置在内部 RAM 中。 diff --git a/docs/zh_CN/api-reference/peripherals/uart.rst b/docs/zh_CN/api-reference/peripherals/uart.rst index d93f7e239585..e2cf8b6ca895 100644 --- a/docs/zh_CN/api-reference/peripherals/uart.rst +++ b/docs/zh_CN/api-reference/peripherals/uart.rst @@ -68,6 +68,10 @@ UART 通信参数可以在一个步骤中完成全部配置,也可以在多个 了解配置硬件流控模式的更多信息,请参考 :example:`peripherals/uart/uart_echo`。 +.. only:: SOC_UART_SUPPORT_SLEEP_RETENTION + + 此外,置位 :cpp:member:`uart_config_t::backup_before_sleep` 会使能在进入睡眠模式前备份 UART 配置寄存器并在退出睡眠后恢复这些寄存器。这个功能使 UART 能够在系统唤醒后继续正常工作,即使其电源域在睡眠过程中被完全关闭。此选项需要用户在功耗和内存使用之间取得平衡。如果功耗不是一个问题,可以禁用这个选项来节省内存。 + 分步依次配置每个参数 """"""""""""""""""""""""""""""" diff --git a/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_arch.rst b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_arch.rst index bebedf8f3587..3670348e5a2f 100644 --- a/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_arch.rst +++ b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_arch.rst @@ -1,2 +1 @@ -.. include:: ../../../../en/api-reference/peripherals/usb_host/usb_host_notes_arch - .rst +.. include:: ../../../../en/api-reference/peripherals/usb_host/usb_host_notes_arch.rst diff --git a/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_index.rst b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_index.rst index 020a913ef7cc..1ab83954de25 100644 --- a/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_index.rst +++ b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_index.rst @@ -21,14 +21,14 @@ USB 主机维护者注意事项(简介) usb_host_notes_design usb_host_notes_arch usb_host_notes_dwc_otg + usb_host_notes_usbh 待写章节: - USB 主机维护者注意事项(HAL 和 LL) -- USB 主机维护者注意事项 (HCD) -- USB 主机维护者注意事项 (USBH) -- USB 主机维护者注意事项 (Hub) -- USB 主机维护者注意事项 (USB Host Library) +- USB 主机维护者注意事项(HCD) +- USB 主机维护者注意事项(Hub) +- USB 主机维护者注意事项(USB Host Library) .. -------------------------------------------------- Introduction ----------------------------------------------------- diff --git a/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_usbh.rst b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_usbh.rst new file mode 100644 index 000000000000..262547c0f017 --- /dev/null +++ b/docs/zh_CN/api-reference/peripherals/usb_host/usb_host_notes_usbh.rst @@ -0,0 +1 @@ +.. include:: ../../../../en/api-reference/peripherals/usb_host/usb_host_notes_usbh.rst diff --git a/docs/zh_CN/api-reference/system/async_memcpy.rst b/docs/zh_CN/api-reference/system/async_memcpy.rst index fdd40d6befb9..af3d772b85bb 100644 --- a/docs/zh_CN/api-reference/system/async_memcpy.rst +++ b/docs/zh_CN/api-reference/system/async_memcpy.rst @@ -36,8 +36,7 @@ DMA 允许多个内存复制请求在首个请求完成之前排队,即允许 在 :cpp:type:`async_memcpy_config_t` 中设置驱动配置: * :cpp:member:`backlog`:此项用于配置首个请求完成前可以排队的最大内存复制事务数量。如果将此字段设置为零,会应用默认值 4。 -* :cpp:member:`sram_trans_align`:声明 SRAM 中数据地址和复制大小的对齐方式,如果数据没有对齐限制,则设置为零。如果设置为四的倍数值(即 4X),驱动程序将内部启用突发模式,这有利于某些和性能相关的应用程序。 -* :cpp:member:`psram_trans_align`:声明 PSRAM 中数据地址和复制大小的对齐方式。如果 memcpy 的目标地址位于 PSRAM 中,用户必须给出一个有效值(只支持 16、32、64)。如果设置为零,会默认采用 16 位对齐。在内部,驱动程序会根据对齐方式来配置 DMA 访问 PSRAM 时所用的块大小。 +* :cpp:member:`dma_burst_size`:设置单次 DMA 传输中突发数据量的大小。 * :cpp:member:`flags`:此项可以启用一些特殊的驱动功能。 .. code-block:: c diff --git a/docs/zh_CN/api-reference/system/esp_timer.rst b/docs/zh_CN/api-reference/system/esp_timer.rst index 279c2e990797..8c8579909891 100644 --- a/docs/zh_CN/api-reference/system/esp_timer.rst +++ b/docs/zh_CN/api-reference/system/esp_timer.rst @@ -5,7 +5,7 @@ ESP 定时器 {IDF_TARGET_HR_TIMER:default = "SYSTIMER", esp32 = "LAC 定时器"} -{IDF_TARGET_HR_TIMER_Resolution:default = "Not updated", esp32 = "64", esp32s2 = "64", esp32c3 = "52", esp32s3 = "52", esp32c2 = "52", esp32c6 = "52", esp32h2 = "52"} +{IDF_TARGET_HR_TIMER_Resolution:default = "Not updated", esp32 = "64", esp32s2 = "64", esp32c3 = "52", esp32s3 = "52", esp32c2 = "52", esp32c5 = "52", esp32c6 = "52", esp32h2 = "52"} diff --git a/docs/zh_CN/api-reference/system/freertos_additions.rst b/docs/zh_CN/api-reference/system/freertos_additions.rst index 0f8db58e71b9..eb2f0f41b46e 100644 --- a/docs/zh_CN/api-reference/system/freertos_additions.rst +++ b/docs/zh_CN/api-reference/system/freertos_additions.rst @@ -97,9 +97,9 @@ ESP-IDF 环形 buffer 是一个典型的 FIFO buffer,支持任意大小的数 //为 DMA 描述符和相应的数据 buffer 检索空间 //此步骤必须通过 SendAcquire 完成,否则,复制时地址可能会不同 - dma_item_t item; + dma_item_t *item; UBaseType_t res = xRingbufferSendAcquire(buf_handle, - &item, DMA_ITEM_SIZE(buffer_size), pdMS_TO_TICKS(1000)); + (void**) &item, DMA_ITEM_SIZE(buffer_size), pdMS_TO_TICKS(1000)); if (res != pdTRUE) { printf("Failed to acquire memory for item\n"); } @@ -108,7 +108,7 @@ ESP-IDF 环形 buffer 是一个典型的 FIFO buffer,支持任意大小的数 .length = buffer_size, .eof = 0, .owner = 1, - .buf = &item->buf, + .buf = item->buf, }; //实际发送到环形 buffer 以供使用 res = xRingbufferSendComplete(buf_handle, &item); diff --git a/docs/zh_CN/api-reference/system/intr_alloc.rst b/docs/zh_CN/api-reference/system/intr_alloc.rst index eb4fa1dd1236..ec60d86e417c 100644 --- a/docs/zh_CN/api-reference/system/intr_alloc.rst +++ b/docs/zh_CN/api-reference/system/intr_alloc.rst @@ -26,6 +26,10 @@ {IDF_TARGET_NAME} 有两个核,每个核有 32 个外部异步中断。每个中断的优先级别都可独立地通过编程设置。此外,每个核还有 3 个核心本地中断源 (CLINT)。详细信息请参见 **{IDF_TARGET_NAME} 技术参考手册** [`PDF <{IDF_TARGET_TRM_CN_URL}#riscvcpu>`__]。 +.. only:: esp32c5 + + {IDF_TARGET_NAME} 有一个核,32 个外部异步中断。每个中断的优先级别都可独立地通过编程设置。此外,还有 3 个核心本地中断源 (CLINT)。详细信息请参见 **{IDF_TARGET_NAME} 技术参考手册** > **高性能处理器** [`PDF <{IDF_TARGET_TRM_CN_URL}#riscvcpu>`__]。 + 由于中断源数量多于中断,有时多个驱动程序可以共用一个中断。:cpp:func:`esp_intr_alloc` 抽象隐藏了这些实现细节。 驱动程序可以通过调用 :cpp:func:`esp_intr_alloc`,或 :cpp:func:`esp_intr_alloc_intrstatus` 为某个外设分配中断。通过向此函数传递 flag,可以指定中断类型、优先级和触发方式。然后,中断分配代码会找到适用的中断,使用中断矩阵将其连接到外设,并为其安装给定的中断处理程序和 ISR。 diff --git a/docs/zh_CN/api-reference/system/mem_alloc.rst b/docs/zh_CN/api-reference/system/mem_alloc.rst index 768165115d35..12fef6b8f119 100644 --- a/docs/zh_CN/api-reference/system/mem_alloc.rst +++ b/docs/zh_CN/api-reference/system/mem_alloc.rst @@ -50,7 +50,7 @@ ESP-IDF 应用程序使用常见的计算机架构模式:由程序控制流动 DRAM ^^^^ -启动时,DRAM 堆包含应用程序未静态分配的所有数据内存,减少静态分配的缓冲区将增加可用的空闲堆空间。 +启动时,DRAM 堆包含应用程序未静态分配的所有数据内存,减少静态分配的 buffer 将增加可用的空闲堆空间。 调用命令 :ref:`idf.py size ` 可查找静态分配内存大小。 @@ -107,7 +107,8 @@ DMA 存储器 .. only SOC_SPIRAM_SUPPORTED and not esp32:: - EDMA 硬件功能允许将 DMA 缓冲区放置在外部 PSRAM,但可能存在其他对齐限制,详情请参阅 {IDF_TARGET_NAME} 技术参考手册。要分配一个可用 DMA 的外部内存缓冲区,请使用 ``MALLOC_CAP_SPIRAM`` 属性标志 和 :cpp:func:`heap_caps_aligned_alloc`,并指定必要的对齐方式。 + EDMA 硬件功能可以将 DMA buffer 放置在外部 PSRAM,但可能存在一定的对齐限制,详情请参阅 {IDF_TARGET_NAME} 技术参考手册。若要分配一个可用 DMA 的外部 buffer,请使用 ``MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA`` 属性标志,堆分配器将处理 cache 及 DMA 子系统的对齐要求。如果某个外设有额外的对齐要求,可以调用 :cpp:func:heap_caps_aligned_alloc 并指定必要的对齐方式。 + .. _32-bit accessible memory: @@ -138,7 +139,7 @@ DMA 存储器 堆函数是线程安全的,因此可不受限制,在不同任务中同时调用多个堆函数。 -从中断处理程序 (ISR) 上下文中调用 ``malloc``、 ``free`` 和相关函数虽然在技术层面可行(请参阅 :ref:`calling-heap-related-functions-from-isr`),但不建议使用此种方法,因为调用堆函数可能会延迟其他中断。建议重构应用程序,将 ISR 使用的任何缓冲区预先分配到 ISR 之外。之后可能会删除从 ISR 调用堆函数的功能。 +从中断处理程序 (ISR) 上下文中调用 ``malloc``、 ``free`` 和相关函数虽然在技术层面可行(请参阅 :ref:`calling-heap-related-functions-from-isr`),但不建议使用此种方法,因为调用堆函数可能会延迟其他中断。建议重构应用程序,将 ISR 使用的任何 buffer 预先分配到 ISR 之外。之后可能会删除从 ISR 调用堆函数的功能。 .. _calling-heap-related-functions-from-isr: diff --git a/docs/zh_CN/api-reference/system/sleep_modes.rst b/docs/zh_CN/api-reference/system/sleep_modes.rst index ae61e1b18607..76567ecffea3 100644 --- a/docs/zh_CN/api-reference/system/sleep_modes.rst +++ b/docs/zh_CN/api-reference/system/sleep_modes.rst @@ -37,7 +37,7 @@ 睡眠模式下的 Wi-Fi 和 Bluetooth 功能 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 在 Light-sleep 和 Deep-sleep 模式下,无线外设会被断电。因此,在进入这两种睡眠模式前,应用程序必须调用恰当的函数(:cpp:func:`esp_bluedroid_disable`、:cpp:func:`esp_bt_controller_disable` 或 :cpp:func:`esp_wifi_stop`)来禁用 Wi-Fi 和 Bluetooth。在 Light-sleep 或 Deep-sleep 模式下,即使不调用这些函数也无法连接 Wi-Fi 和 Bluetooth。 + 在 Light-sleep 和 Deep-sleep 模式下,无线外设会被断电。因此,在进入这两种睡眠模式前,应用程序必须调用恰当的函数(:cpp:func:`nimble_port_stop`、:cpp:func:`nimble_port_deinit`、:cpp:func:`esp_bluedroid_disable`、:cpp:func:`esp_bluedroid_deinit`、:cpp:func:`esp_bt_controller_disable`、:cpp:func:`esp_bt_controller_deinit` 或 :cpp:func:`esp_wifi_stop`)来禁用 Wi-Fi 和 Bluetooth。在 Light-sleep 或 Deep-sleep 模式下,即使不调用这些函数也无法连接 Wi-Fi 和 Bluetooth。 如需保持 Wi-Fi 和 Bluetooth 连接,请启用 Wi-Fi 和 Bluetooth Modem-sleep 模式和自动 Light-sleep 模式(请参阅 :doc:`电源管理 API `)。在这两种模式下,Wi-Fi 和 Bluetooth 驱动程序发出请求时,系统将自动从睡眠中被唤醒,从而保持连接。 @@ -304,6 +304,20 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒 esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON); + .. only:: SOC_PM_SUPPORT_TOP_PD + + .. note:: + + .. only:: SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + 在 Light-sleep 模式下,如果设置 Kconfig 选项 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`,为了继续使用 :cpp:func:`gpio_wakeup_enable` 用于 GPIO 唤醒, 需要先调用 :cpp:func:`rtc_gpio_init` 和 :cpp:func:`rtc_gpio_set_direction`,用于设置 RTC IO 为输入模式。 + + 或者, 可以使用直接调用 :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` 用于 GPIO 唤醒,因为此时 digital IO 的电源域已经被关闭,这个情况类似于进入 Deep-sleep。 + + .. only:: not SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + 在 Light-sleep 模式下,如果设置 Kconfig 选项 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`,为了继续使用 :cpp:func:`gpio_wakeup_enable` 用于 GPIO 唤醒, 需要先调用 :cpp:func:`rtc_gpio_init` 和 :cpp:func:`rtc_gpio_set_direction`,用于设置 RTC IO 为输入模式。 + .. only:: not SOC_RTCIO_WAKE_SUPPORTED GPIO 唤醒 @@ -313,11 +327,13 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒 此外,可将由 VDD3P3_RTC 电源域供电的 IO 用于芯片的 Deep-sleep 唤醒。调用 :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` 函数可以配置相应的唤醒管脚和唤醒触发电平,该函数用于启用相应管脚的 Deep-sleep 唤醒功能。 - .. only:: esp32c6 or esp32h2 + .. only:: SOC_PM_SUPPORT_TOP_PD .. note:: - 在 Light-sleep 模式下,设置 Kconfig 选项 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` 将使 GPIO 唤醒失效。 + .. only:: SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + + 在 Light-sleep 模式下,如果设置 Kconfig 选项 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`,可以使用直接调用 :cpp:func:`esp_deep_sleep_enable_gpio_wakeup` 用于 GPIO 唤醒,因为此时 digital IO 的电源域已经被关闭,这个情况类似于进入 Deep-sleep。 UART 唤醒(仅适用于 Light-sleep 模式) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/zh_CN/api-reference/system/system_time.rst b/docs/zh_CN/api-reference/system/system_time.rst index f14dc1886150..4f405f19b616 100644 --- a/docs/zh_CN/api-reference/system/system_time.rst +++ b/docs/zh_CN/api-reference/system/system_time.rst @@ -3,12 +3,11 @@ :link_to_translation:`en:[English]` -{IDF_TARGET_RTC_CLK_FRE:default="未更新", esp32="150 kHz", esp32s2="90 kHz", esp32s3="136 kHz", esp32c3="136 kHz", esp32c2="136 kHz", esp32c6="150 kHz", esp32h2="150 kHz", esp32p4="150 kHz"} +{IDF_TARGET_RTC_CLK_FRE:default="未更新", esp32="150 kHz", esp32s2="90 kHz", esp32s3="136 kHz", esp32c3="136 kHz", esp32c2="136 kHz", esp32c5="136 kHz", esp32c6="136 kHz", esp32h2="136 kHz", esp32p4="136 kHz"} {IDF_TARGET_INT_OSC_FRE:default="未更新", esp32="8.5 MHz", esp32s2="8.5 MHz", esp32s3="17.5 MHz", esp32c3="17.5 MHz", esp32c2="17.5 MHz"} {IDF_TARGET_INT_OSC_FRE_DIVIDED:default="未更新", esp32="约 33 kHz", esp32s2="约 33 kHz", esp32s3="约 68 kHz", esp32c3="约 68 kHz", esp32c2="约 68 kHz"} -{IDF_TARGET_EXT_CRYSTAL_PIN:default="未更新", esp32="32K_XP 和 32K_XN", esp32s2="XTAL_32K_P 和 XTAL_32K_N", esp32s3="XTAL_32K_P 和 XTAL_32K_N", esp32c3="XTAL_32K_P 和 XTAL_32K_N", esp32c6="XTAL_32K_P 和 XTAL_32K_N", esp32h2="XTAL_32K_P 和 XTAL_32K_N", esp32p4="XTAL_32K_P 和 XTAL_32K_N"} -{IDF_TARGET_EXT_OSC_PIN:default="未更新", esp32="32K_XN", esp32s2="XTAL_32K_P", esp32s3="XTAL_32K_P", esp32c3="XTAL_32K_P", esp32c2="GPIO0", esp32c6="XTAL_32K_P", esp32h2="XTAL_32K_P", esp32p4="XTAL_32K_P"} -{IDF_TARGET_HARDWARE_DESIGN_URL:default="未更新", esp32="`ESP32 硬件设计指南 `_", esp32s2="`ESP32-S2 硬件设计指南 `_", esp32s3="`ESP32-S3 硬件设计指南 `_", esp32c3="`ESP32-C3 硬件设计指南 `_", esp32c2="`ESP8684 硬件设计指南 `_", esp32c6="`ESP32-C6 硬件设计指南 `_", esp32h2="`ESP32-H2 硬件设计指南 `_", esp32p4="`ESP32-P4 硬件设计指南 `_"} +{IDF_TARGET_EXT_CRYSTAL_PIN:default="未更新", esp32="32K_XP 和 32K_XN", esp32s2="XTAL_32K_P 和 XTAL_32K_N", esp32s3="XTAL_32K_P 和 XTAL_32K_N", esp32c3="XTAL_32K_P 和 XTAL_32K_N", esp32c5="XTAL_32K_P 和 XTAL_32K_N", esp32c6="XTAL_32K_P 和 XTAL_32K_N", esp32h2="XTAL_32K_P 和 XTAL_32K_N", esp32p4="XTAL_32K_P 和 XTAL_32K_N"} +{IDF_TARGET_EXT_OSC_PIN:default="未更新", esp32="32K_XN", esp32s2="XTAL_32K_P", esp32s3="XTAL_32K_P", esp32c3="XTAL_32K_P", esp32c2="GPIO0", esp32c5="XTAL_32K_P", esp32c6="XTAL_32K_P", esp32h2="XTAL_32K_P", esp32p4="XTAL_32K_P"} 概述 @@ -51,7 +50,7 @@ RTC 定时器有以下时钟源: 时钟源的选择取决于系统时间精度要求和睡眠模式下的功耗要求。要修改 RTC 时钟源,请在项目配置中设置 :ref:`CONFIG_RTC_CLK_SRC`。 -想要了解外置晶振或外置振荡器的更多布线要求,请参考 {IDF_TARGET_HARDWARE_DESIGN_URL}。 +想要了解外置晶振或外置振荡器的更多布线要求,请参考 `硬件设计指南 `_。 获取当前时间 -------------- diff --git a/docs/zh_CN/api-reference/system/ulp-lp-core.rst b/docs/zh_CN/api-reference/system/ulp-lp-core.rst index f44bd3efa600..02b5aae14c37 100644 --- a/docs/zh_CN/api-reference/system/ulp-lp-core.rst +++ b/docs/zh_CN/api-reference/system/ulp-lp-core.rst @@ -160,6 +160,7 @@ ULP LP-Core 支持的外设 * LP IO * LP I2C * LP UART + :SOC_LP_SPI_SUPPORTED: * LP SPI .. only:: CONFIG_ESP_ROM_HAS_LP_ROM @@ -196,6 +197,16 @@ API 参考 .. include-build-file:: inc/lp_core_i2c.inc .. include-build-file:: inc/lp_core_uart.inc +.. only:: SOC_LP_SPI_SUPPORTED + + .. include-build-file:: inc/lp_core_spi.inc + +.. only:: SOC_LP_CORE_SUPPORT_ETM + + .. include-build-file:: inc/lp_core_etm.inc + +.. include-build-file:: inc/lp_core_types.inc + LP 内核 API 参考 ~~~~~~~~~~~~~~~~~~~~~~ @@ -204,3 +215,10 @@ LP 内核 API 参考 .. include-build-file:: inc/ulp_lp_core_i2c.inc .. include-build-file:: inc/ulp_lp_core_uart.inc .. include-build-file:: inc/ulp_lp_core_print.inc +.. include-build-file:: inc/ulp_lp_core_interrupts.inc + +.. only:: SOC_LP_SPI_SUPPORTED + + .. include-build-file:: inc/ulp_lp_core_spi.inc + +.. _esp-idf-monitor: https://github.com/espressif/esp-idf-monitor diff --git a/docs/zh_CN/get-started/esp32p4_output_log.inc b/docs/zh_CN/get-started/esp32p4_output_log.inc index 69a66d4736d2..e8d0eb6553fc 100644 --- a/docs/zh_CN/get-started/esp32p4_output_log.inc +++ b/docs/zh_CN/get-started/esp32p4_output_log.inc @@ -1 +1,39 @@ -.. output_log \ No newline at end of file +.. output_log + + +.. code-block:: none + + ... + esptool.py v4.8.dev3 + Serial port /dev/cu.SLAB_USBtoUART + Connecting.... + Chip is ESP32-P4 (revision v0.0) + Features: High-Performance MCU + Crystal is 40MHz + MAC: 00:00:00:00:00:00 + Uploading stub... + Running stub... + Stub running... + Changing baud rate to 460800 + Changed. + Configuring flash size... + Flash will be erased from 0x00002000 to 0x00007fff... + Flash will be erased from 0x00010000 to 0x0003bfff... + Flash will be erased from 0x00008000 to 0x00008fff... + SHA digest in image updated + Compressed 20960 bytes to 12653... + Writing at 0x00002000... (100 %) + Wrote 20960 bytes (12653 compressed) at 0x00002000 in 0.6 seconds (effective 277.1 kbit/s)... + Hash of data verified. + Compressed 179584 bytes to 94528... + Writing at 0x00035efb... (100 %) + Wrote 179584 bytes (94528 compressed) at 0x00010000 in 2.6 seconds (effective 549.9 kbit/s)... + Hash of data verified. + Compressed 3072 bytes to 103... + Writing at 0x00008000... (100 %) + Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.1 seconds (effective 420.7 kbit/s)... + Hash of data verified. + + Leaving... + Hard resetting via RTS pin... + Done diff --git a/docs/zh_CN/get-started/establish-serial-connection.rst b/docs/zh_CN/get-started/establish-serial-connection.rst index 0141ba239c93..f4cda3c71ad4 100644 --- a/docs/zh_CN/get-started/establish-serial-connection.rst +++ b/docs/zh_CN/get-started/establish-serial-connection.rst @@ -141,12 +141,12 @@ {IDF_TARGET_NAME} 支持 USB 外设,无需外部 USB 至 UART 桥,即可烧录二进制文件。 - {IDF_TARGET_USB_PIN_DM:default="尚未更新!", esp32c3="GPIO18", esp32s3="GPIO19", esp32s2="GPIO19", esp32c6="GPIO12", esp32h2="GPIO26"} - {IDF_TARGET_USB_PIN_DP:default="尚未更新!", esp32c3="GPIO19", esp32s3="GPIO20", esp32s2="GPIO20", esp32c6="GPIO13", esp32h2="GPIO27"} + {IDF_TARGET_USB_PIN_DM:default="尚未更新!", esp32c3="GPIO18", esp32s3="GPIO19", esp32s2="GPIO19", esp32c6="GPIO12", esp32h2="GPIO26", esp32p4="GPIO24/26"} + {IDF_TARGET_USB_PIN_DP:default="尚未更新!", esp32c3="GPIO19", esp32s3="GPIO20", esp32s2="GPIO20", esp32c6="GPIO13", esp32h2="GPIO27", esp32p4="GPIO24/26"} {IDF_TARGET_NAME} 上的 USB 使用 **{IDF_TARGET_USB_PIN_DP}** 作为 **D+**, **{IDF_TARGET_USB_PIN_DM}** 作为 **D-**。 - .. only:: SOC_USB_SERIAL_JTAG_SUPPORTED and not esp32s3 + .. only:: SOC_USB_SERIAL_JTAG_SUPPORTED and not esp32s3 and not esp32p4 .. note:: {IDF_TARGET_NAME} 仅支持 *USB CDC and JTAG*。 @@ -348,6 +348,9 @@ macOS 提供了 **屏幕** 命令,因此无需安装串口终端程序。 输出示例 ^^^^^^^^^^^ + +{IDF_TARGET_STRAP_GPIO:default="[NEEDS TO BE UPDATED]", esp32="GPIO0", esp32s2="GPIO0", esp32s3="GPIO0", esp32c2="GPIO9", esp32c3="GPIO9", esp32c6="GPIO9", esp32h2="GPIO9", esp32p4="GPIO35"} + 以下是一个日志示例。如果没看到任何输出,请尝试重置开发板。 .. highlight:: none @@ -376,7 +379,7 @@ macOS 提供了 **屏幕** 命令,因此无需安装串口终端程序。 .. 注解:: - 在某些串口接线方式下,在 {IDF_TARGET_NAME} 启动并开始打印串口日志前,需要在终端程序中禁用串口 RTS & DTR 管脚。该问题仅存在于将 RTS & DTR 管脚直接连接到 EN & GPIO0 管脚上的情况,绝大多数开发板(包括乐鑫所有的开发板)都没有这个问题。更多详细信息,请参考 `esptool 文档`_。 + 在某些串口接线方式下,在 {IDF_TARGET_NAME} 启动并开始打印串口日志前,需要在终端程序中禁用串口 RTS & DTR 管脚。该问题仅存在于将 RTS & DTR 管脚直接连接到 EN & {IDF_TARGET_STRAP_GPIO} 管脚上的情况,绝大多数开发板(包括乐鑫所有的开发板)都没有这个问题。更多详细信息,请参考 `esptool 文档`_。 如在安装 {IDF_TARGET_NAME} 硬件开发的软件环境时,从 :ref:`get-started-connect` 跳转到了这里,请从 :ref:`get-started-configure` 继续阅读。 diff --git a/docs/zh_CN/get-started/flashing-troubleshooting.rst b/docs/zh_CN/get-started/flashing-troubleshooting.rst index 992b2310bec4..278196ccf657 100644 --- a/docs/zh_CN/get-started/flashing-troubleshooting.rst +++ b/docs/zh_CN/get-started/flashing-troubleshooting.rst @@ -6,7 +6,7 @@ 连接失败 ----------------- -{IDF_TARGET_STRAP_GPIO:default="[NEEDS TO BE UPDATED]", esp32="GPIO0", esp32s2="GPIO0", esp32s3="GPIO0", esp32c2="GPIO9", esp32c3="GPIO9", esp32c6="GPIO9", esp32h2="GPIO9"} +{IDF_TARGET_STRAP_GPIO:default="[NEEDS TO BE UPDATED]", esp32="GPIO0", esp32s2="GPIO0", esp32s3="GPIO0", esp32c2="GPIO9", esp32c3="GPIO9", esp32c6="GPIO9", esp32h2="GPIO9", esp32p4="GPIO35"} 如果在运行给定命令时出现如“连接失败”这样的错误,造成该错误的原因之一可能是运行 ``esptool.py`` 时出现错误。 ``esptool.py`` 是构建系统调用的程序,用于重置芯片、与 ROM 引导加载器交互以及烧录固件的工具。可以按照以下步骤进行手动复位,轻松解决该问题。如果问题仍未解决,请参考 `esptool 故障排除 `_ 获取更多信息。 diff --git a/docs/zh_CN/get-started/index.rst b/docs/zh_CN/get-started/index.rst index 1d5a54b0d6d4..c5dff638e1de 100644 --- a/docs/zh_CN/get-started/index.rst +++ b/docs/zh_CN/get-started/index.rst @@ -76,6 +76,14 @@ * 多种外设 * 内置安全硬件 +.. only:: esp32p4 + + * 搭载 RISC-V 32 位双核处理器的高性能 MCU + * 强大的图像与语音处理能力 + * 支持单精度 FPU 和 AI 扩展 + * 外设丰富包括 MIPI、USB、SDIO、以太网等 + * 内置安全硬件 + {IDF_TARGET_NAME} 采用 40 nm 工艺制成,具有最佳的功耗性能、射频性能、稳定性、通用性和可靠性,适用于各种应用场景和不同功耗需求。 乐鑫为用户提供完整的软、硬件资源,进行 {IDF_TARGET_NAME} 硬件设备的开发。其中,乐鑫的软件开发环境 ESP-IDF 旨在协助用户快速开发物联网 (IoT) 应用,可满足用户对 Wi-Fi、蓝牙、低功耗等方面的要求。 @@ -114,8 +122,8 @@ :maxdepth: 1 ESP32-S2-Saola-1 <../hw-reference/esp32s2/user-guide-saola-1-v1.2> - ESP32-S2-DevKitM-1 <../hw-reference/esp32s2/user-guide-devkitm-1-v1> - ESP32-S2-DevKitC-1 <../hw-reference/esp32s2/user-guide-s2-devkitc-1> + ESP32-S2-DevKitM-1 + ESP32-S2-DevKitC-1 ESP32-S2-Kaluga-Kit <../hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit> .. only:: esp32c3 @@ -123,8 +131,8 @@ .. toctree:: :maxdepth: 1 - ESP32-C3-DevKitM-1 <../hw-reference/esp32c3/user-guide-devkitm-1> - ESP32-C3-DevKitC-02 <../hw-reference/esp32c3/user-guide-devkitc-02> + ESP32-C3-DevKitC-02 + ESP32-C3-DevKitM-1 .. only:: esp32s3 @@ -150,6 +158,10 @@ ESP32-C6-DevKitC-1 ESP32-C6-DevKitM-1 +.. only:: esp32p4 + + 即将发布 + .. _get-started-get-prerequisites: 软件: diff --git a/docs/zh_CN/get-started/start-project.rst b/docs/zh_CN/get-started/start-project.rst index 96346ea04866..982e78deca6b 100644 --- a/docs/zh_CN/get-started/start-project.rst +++ b/docs/zh_CN/get-started/start-project.rst @@ -1,6 +1,6 @@ -{IDF_TARGET_FEATURES:default="[NEEDS TO BE UPDATED]", esp32="WiFi/BT/BLE, silicon revision 1, 2 MB external flash", esp32s2="WiFi, silicon revision 0, 2 MB external flash", esp32s3="This is esp32s3 chip with 2 CPU core(s), WiFi/BLE, silicon revision 0, 2 MB external flash", esp32c2="WiFi/BLE, silicon revision 0, 2 MB embedded flash", esp32c3="WiFi/BLE, silicon revision 0, 2 MB external flash", esp32c6="WiFi/BLE, 802.15.4 (Zigbee/Thread), silicon revision v0.0, 2 MB external flash", esp32h2="BLE, 802.15.4 (Zigbee/Thread), silicon revision v0.1, 2 MB external flash"} +{IDF_TARGET_FEATURES:default="[NEEDS TO BE UPDATED]", esp32="WiFi/BT/BLE, silicon revision 1, 2 MB external flash", esp32s2="WiFi, silicon revision 0, 2 MB external flash", esp32s3="This is esp32s3 chip with 2 CPU core(s), WiFi/BLE, silicon revision 0, 2 MB external flash", esp32c2="WiFi/BLE, silicon revision 0, 2 MB embedded flash", esp32c3="WiFi/BLE, silicon revision 0, 2 MB external flash", esp32c6="WiFi/BLE, 802.15.4 (Zigbee/Thread), silicon revision v0.0, 2 MB external flash", esp32h2="BLE, 802.15.4 (Zigbee/Thread), silicon revision v0.1, 2 MB external flash", esp32p4="silicon revision v0.0, 2 MB external flash"} -{IDF_TARGET_HEAP_SIZE:default="[NEEDS TO BE UPDATED]", esp32="298968", esp32s2="253900", esp32s3="390684", esp32c2="203888", esp32c3="337332", esp32c6="473816", esp32h2="268256"} +{IDF_TARGET_HEAP_SIZE:default="[NEEDS TO BE UPDATED]", esp32="298968", esp32s2="253900", esp32s3="390684", esp32c2="203888", esp32c3="337332", esp32c6="473816", esp32h2="268256", esp32p4="618848"} 编译工程 ========================= @@ -72,7 +72,9 @@ 可以使用 ``idf.py -p PORT monitor`` 命令,监视 “hello_world” 工程的运行情况。注意,不要忘记将 PORT 替换为自己的串口名称。 -运行该命令后,:doc:`IDF 监视器 <../api-guides/tools/idf-monitor>` 应用程序将启动::: +运行该命令后,:doc:`IDF 监视器 <../api-guides/tools/idf-monitor>` 应用程序将启动。 + +.. code-block:: bash $ idf.py -p monitor Running idf_monitor in directory [...]/esp/hello_world/build diff --git a/docs/zh_CN/get-started/windows-setup.rst b/docs/zh_CN/get-started/windows-setup.rst index 2c109110c970..a447a7110dea 100644 --- a/docs/zh_CN/get-started/windows-setup.rst +++ b/docs/zh_CN/get-started/windows-setup.rst @@ -12,7 +12,9 @@ ESP-IDF 需要安装一些必备工具,才能围绕 {IDF_TARGET_NAME} 构建 本入门指南介绍了如何通过 **命令提示符** 进行有关操作。不过,安装 ESP-IDF 后,还可以使用 `Eclipse Plugin `_ 或其他支持 CMake 的图形化工具 IDE。 .. note:: + 限定条件: + - 请注意 ESP-IDF 和 ESP-IDF 工具的安装路径不能超过 90 个字符,安装路径过长可能会导致构建失败。 - Python 或 ESP-IDF 的安装路径中一定不能包含空格或括号。 - 除非操作系统配置为支持 Unicode UTF-8,否则 Python 或 ESP-IDF 的安装路径中也不能包括特殊字符(非 ASCII 码字符) diff --git a/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitc-02.rst b/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitc-02.rst deleted file mode 100644 index e23aa28b1c29..000000000000 --- a/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitc-02.rst +++ /dev/null @@ -1,239 +0,0 @@ -=================== -ESP32-C3-DevKitC-02 -=================== - -:link_to_translation:`en: [English]` - -本指南将帮助你快速上手 ESP32-C3-DevKitC-02,并提供该款开发板的详细信息。 - -ESP32-C3-DevKitC-02 是一款入门级开发板,使用配置 4 MB SPI flash 的通用型模组 `ESP32-C3-WROOM-02 `_。该款开发板具备完整的 Wi-Fi 和低功耗蓝牙功能。 - -板上模组大部分管脚均已引出至两侧排针,开发人员可根据实际需求,轻松通过跳线连接多种外围设备,同时也可将开发板插在面包板上使用。 - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-isometric.png - :align: center - :alt: ESP32-C3-DevKitC-02 - :figclass: align-center - - ESP32-C3-DevKitC-02 - -本指南包括如下内容: - -- `入门指南`_:简要介绍了 ESP32-C3-DevKitC-02 和硬件、软件设置指南。 -- `硬件参考`_:详细介绍了 ESP32-C3-DevKitC-02 的硬件。 -- `硬件版本`_:介绍硬件历史版本和已知问题,并提供链接至历史版本开发板的入门指南(如有)。 -- `相关文档`_:列出了相关文档的链接。 - - -入门指南 -======== - -本小节将简要介绍 ESP32-C3-DevKitC-02,说明如何在 ESP32-C3-DevKitC-02 上烧录固件及相关准备工作。 - - -组件介绍 --------- - -.. _user-guide-c3-devkitc-02-v1-board-front: - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-annotated-photo.png - :align: center - :alt: ESP32-C3-DevKitC-02 - 正面 - :figclass: align-center - - ESP32-C3-DevKitC-02 - 正面 - -以下按照逆时针的顺序依次介绍开发板上的主要组件。 - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 介绍 - * - ESP32-C3-WROOM-02 - - ESP32-C3-WROOM-02 是乐鑫推出的一款通用型 Wi-Fi 和低功耗蓝牙双模模组,功能强大。该模组采用 PCB 板载天线,配置了 4 MB SPI flash。 - * - 5 V to 3.3 V LDO(5 V 转 3.3 V LDO) - - 电源转换器,输入 5 V,输出 3.3 V。 - * - 5 V Power On LED(5 V 电源指示灯) - - 开发板连接 USB 电源后,该指示灯亮起。 - * - Pin Headers(排针) - - 所有可用 GPIO 管脚(除 Flash 的 SPI 总线)均已引出至开发板的排针。请查看 :ref:`user-guide-c3-devkitc-02-v1-header-blocks` 获取更多信息。 - * - Boot Button(Boot 键) - - 下载按键。按住 **Boot** 键的同时按一下 **Reset** 键进入“固件下载”模式,通过串口下载固件。 - * - Micro-USB Port(Micro-USB 接口) - - USB 接口。可用作开发板的供电电源或 PC 和 ESP32-C3 芯片的通信接口。 - * - Reset Button(Reset 键) - - 复位按键。 - * - USB-to-UART Bridge(USB 至 UART 桥接器) - - 单芯片 USB 至 UART 桥接器,可提供高达 3 Mbps 的传输速率。 - * - RGB LED - - 可寻址 RGB 发光二极管,由 GPIO8 驱动。 - - -开始开发应用 ------------- - -通电前,请确保 ESP32-C3-DevKitC-02 完好无损。 - - -必备硬件 -^^^^^^^^ - -- ESP32-C3-DevKitC-02 -- USB 2.0 数据线(标准 A 型转 Micro-B 型) -- 电脑(Windows、Linux 或 macOS) - -.. 注解:: - - 请确保使用适当的 USB 数据线。部分数据线仅可用于充电,无法用于数据传输和编程。 - - -软件设置 -^^^^^^^^ - -请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 小节查看如何快速设置开发环境,将应用程序烧录至 ESP32-C3-DevKitC-02。 - - -内含组件和包装 --------------- - -零售订单 -^^^^^^^^ - -如购买样品,每个 ESP32-C3-DevKitC-02 开发板将以防静电袋或零售商选择的其他方式包装。 - -零售订单请前往 https://www.espressif.com/zh-hans/company/contact/buy-a-sample。 - - -批量订单 -^^^^^^^^ - -如批量购买,ESP32-C3-DevKitC-02 开发板将以大纸板箱包装。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -硬件参考 -======== - -功能框图 --------- - -ESP32-C3-DevKitC-02 的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-block-diags.png - :align: center - :scale: 70% - :alt: ESP32-C3-DevKitC-02(点击放大) - :figclass: align-center - - ESP32-C3-DevKitC-02(点击放大) - - -电源选项 -^^^^^^^^ - -以下任一供电方式均可为 ESP32-C3-DevKitC-02 供电: - -- Micro-USB 接口供电(默认) -- 5V 和 GND 排针供电 -- 3V3 和 GND 排针供电 - -建议选择第一种供电方式:Micro-USB 接口供电。 - - -.. _user-guide-c3-devkitc-02-v1-header-blocks: - -排针 ----- - -下表列出了开发板两侧排针(J1 和 J3)的 **名称** 和 **功能**,排针的名称如图 :ref:`user-guide-c3-devkitc-02-v1-board-front` 所示,排针的序号与 `ESP32-C3-DevKitC-02 原理图`_ (PDF) 一致。 - - -J1 -^^^ - -==== ==== ========== ================================ -序号 名称 类型 [1]_ 功能 -==== ==== ========== ================================ -1 G G 接地 -2 3V3 P 3.3 V 电源 -3 3V3 P 3.3 V 电源 -4 RST I CHIP_PU -5 G G 接地 -6 4 I/O/T GPIO4, ADC1_CH4, FSPIHD, MTMS -7 5 I/O/T GPIO5, ADC2_CH0, FSPIWP, MTDI -8 6 I/O/T GPIO6, FSPICLK, MTCK -9 7 I/O/T GPIO7, FSPID, MTDO -10 G G 接地 -11 8 I/O/T GPIO8 [2]_, RGB LED -12 9 I/O/T GPIO9 [2]_ -13 5V P 5 V 电源 -14 5V P 5 V 电源 -15 G G 接地 -==== ==== ========== ================================ - - -J3 -^^^ - -==== ==== ========== ================================ -序号 名称 类型 [1]_ 功能 -==== ==== ========== ================================ -1 G G 接地 -2 0 I/O/T GPIO0, ADC1_CH0, XTAL_32K_P -3 1 I/O/T GPIO1, ADC1_CH1, XTAL_32K_N -4 2 I/O/T GPIO2 [2]_, ADC1_CH2, FSPIQ -5 3 I/O/T GPIO3, ADC1_CH3 -6 G G 接地 -7 10 I/O/T GPIO10, FSPICS0 -8 G G 接地 -9 RX I/O/T GPIO20, U0RXD -10 TX I/O/T GPIO21, U0TXD -11 G G 接地 -12 18 I/O/T GPIO18 -13 19 I/O/T GPIO19 -14 G G 接地 -15 G G 接地 -==== ==== ========== ================================ - - -.. [1] P:电源;I:输入;O:输出;T:可设置为高阻。 -.. [2] GPIO2、GPIO8、GPIO9 为 ESP32-C3 芯片的 Strapping 管脚。在芯片上电和系统复位过程中,Strapping 管脚根据管脚的二进制电压值控制芯片功能。Strapping 管脚的具体描述和应用,请参考 `ESP32-C3 技术规格书`_ 的 Strapping 管脚章节。 - - -管脚布局 -^^^^^^^^ - -.. figure:: ../../../_static/esp32-c3-devkitc-02-v1-pinout.png - :align: center - :scale: 50% - :alt: ESP32-C3-DevKitC-02 管脚布局(点击放大) - :figclass: align-center - - ESP32-C3-DevKitC-02 管脚布局(点击放大) - - -硬件版本 -========== - -该开发板为最新硬件,尚未有历史版本。 - - -相关文档 -======== - -* `使用 ESP32-C3 构建安全高性价比的互联设备 `_ -* `ESP32-C3 技术规格书`_ (PDF) -* `ESP32-C3-WROOM-02 规格书`_ (PDF) -* `ESP32-C3-DevKitC-02 原理图`_ (PDF) -* `ESP32-C3-DevKitC-02 PCB 布局图 `_ (PDF) -* `ESP32-C3-DevKitC-02 尺寸图 `_ (PDF) -* `ESP32-C3-DevKitC-02 尺寸图源文件 `_ (DXF) - 可使用 `Autodesk Viewer `_ 查看 - -有关本开发板的更多设计文档,请联系我们的商务部门 `sales@espressif.com `_。 - -.. _ESP32-C3 技术规格书: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_cn.pdf -.. _ESP32-C3-WROOM-02 规格书: https://www.espressif.com/sites/default/files/documentation/esp32-c3-wroom-02_datasheet_cn.pdf -.. _ESP32-C3-DevKitC-02 原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-C3-DEVKITC-02_V1_1_20210126A.pdf diff --git a/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitm-1.rst b/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitm-1.rst deleted file mode 100644 index bf521bbf019c..000000000000 --- a/docs/zh_CN/hw-reference/esp32c3/user-guide-devkitm-1.rst +++ /dev/null @@ -1,240 +0,0 @@ -================== -ESP32-C3-DevKitM-1 -================== - -:link_to_translation:`en: [English]` - -本指南将帮助你快速上手 ESP32-C3-DevKitM-1,并提供该款开发板的详细信息。 - -ESP32-C3-DevKitM-1 是一款入门级开发板,使用以尺寸小而得名的 `ESP32-C3-MINI-1 `_ 模组。该款开发板具备完整的 Wi-Fi 和低功耗蓝牙功能。 - -板上模组大部分管脚均已引出至两侧排针,开发人员可根据实际需求,轻松通过跳线连接多种外围设备,同时也可将开发板插在面包板上使用。 - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-isometric.png - :align: center - :alt: ESP32-C3-DevKitM-1 - :figclass: align-center - - ESP32-C3-DevKitM-1 - -本指南包括如下内容: - -- `入门指南`_:简要介绍了 ESP32-C3-DevKitM-1 和硬件、软件设置指南。 -- `硬件参考`_:详细介绍了 ESP32-C3-DevKitM-1 的硬件。 -- `硬件版本`_:介绍硬件历史版本和已知问题,并提供链接至历史版本开发板的入门指南(如有)。 -- `相关文档`_:列出了相关文档的链接。 - - -入门指南 -======== - -本小节将简要介绍 ESP32-C3-DevKitM-1,说明如何在 ESP32-C3-DevKitM-1 上烧录固件及相关准备工作。 - - -组件介绍 --------- - -.. _user-guide-c3-devkitm-1-v1-board-front: - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-annotated-photo.png - :align: center - :alt: ESP32-C3-DevKitM-1 - 正面 - :figclass: align-center - - ESP32-C3-DevKitM-1 - 正面 - -以下按照逆时针的顺序依次介绍开发板上的主要组件。 - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 介绍 - * - ESP32-C3-MINI-1 - - ESP32-C3-MINI-1 是一款通用型 Wi-Fi 和低功耗蓝牙双模模组,采用 PCB 板载天线。该款模组集成配置 4 MB 嵌入式 flash 的 `ESP32-C3FN4 `_ 芯片。由于 flash 直接封装在芯片中,ESP32-C3-MINI-1 模组具有更小的封装尺寸。 - * - 5 V to 3.3 V LDO(5 V 转 3.3 V LDO) - - 电源转换器,输入 5 V,输出 3.3 V。 - * - 5 V Power On LED(5 V 电源指示灯) - - 开发板连接 USB 电源后,该指示灯亮起。 - * - Pin Headers(排针) - - 所有可用 GPIO 管脚(除 flash 的 SPI 总线)均已引出至开发板的排针。请查看 :ref:`user-guide-c3-devkitm-1-v1-header-blocks` 获取更多信息。 - * - Boot Button(Boot 键) - - 下载按键。按住 **Boot** 键的同时按一下 **Reset** 键进入“固件下载”模式,通过串口下载固件。 - * - Micro-USB Port(Micro-USB 接口) - - USB 接口。可用作开发板的供电电源或 PC 和 ESP32-C3FN4 芯片的通信接口。 - * - Reset Button(Reset 键) - - 复位按键。 - * - USB-to-UART Bridge(USB 至 UART 桥接器) - - 单芯片 USB 至 UART 桥接器,可提供高达 3 Mbps 的传输速率。 - * - RGB LED - - 可寻址 RGB 发光二极管,由 GPIO8 驱动。 - - -开始开发应用 ------------- - -通电前,请确保 ESP32-C3-DevKitM-1 完好无损。 - - -必备硬件 -^^^^^^^^ - -- ESP32-C3-DevKitM-1 -- USB 2.0 数据线(标准 A 型转 Micro-B 型) -- 电脑(Windows、Linux 或 macOS) - -.. 注解:: - - 请确保使用适当的 USB 数据线。部分数据线仅可用于充电,无法用于数据传输和编程。 - - -软件设置 -^^^^^^^^ - -请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 小节查看如何快速设置开发环境,将应用程序烧录至 ESP32-C3-DevKitM-1。 - - -内含组件和包装 --------------- - -零售订单 -^^^^^^^^ - -如购买样品,每个 ESP32-C3-DevKitM-1 开发板将以防静电袋或零售商选择的其他方式包装。 - -零售订单请前往 https://www.espressif.com/zh-hans/company/contact/buy-a-sample。 - - -批量订单 -^^^^^^^^ - -如批量购买,ESP32-C3-DevKitM-1 开发板将以大纸板箱包装。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -硬件参考 -======== - -功能框图 --------- - -ESP32-C3-DevKitM-1 的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-block-diagram.png - :align: center - :scale: 70% - :alt: ESP32-C3-DevKitM-1 (点击放大) - :figclass: align-center - - ESP32-C3-DevKitM-1 (点击放大) - - -电源选项 -^^^^^^^^ - -以下任一供电方式均可为 ESP32-C3-DevKitM-1 供电: - -- Micro-USB 接口供电(默认) -- 5V 和 GND 排针供电 -- 3V3 和 GND 排针供电 - -建议选择第一种供电方式:Micro-USB 接口供电。 - - -.. _user-guide-c3-devkitm-1-v1-header-blocks: - -排针 ----- - -下表列出了开发板两侧排针(J1 和 J3)的 **名称** 和 **功能**,排针的名称如图 :ref:`user-guide-c3-devkitm-1-v1-board-front` 所示,排针的序号与 `ESP32-C3-DevKitM-1 原理图`_ (PDF) 一致。 - - -J1 -^^^ - -==== ==== ========== ================================ -序号 名称 类型 [1]_ 功能 -==== ==== ========== ================================ -1 GND G 接地 -2 3V3 P 3.3 V 电源 -3 3V3 P 3.3 V 电源 -4 IO2 I/O/T GPIO2 [2]_ , ADC1_CH2, FSPIQ -5 IO3 I/O/T GPIO3, ADC1_CH3 -6 GND G 接地 -7 RST I CHIP_PU -8 GND G 接地 -9 IO0 I/O/T GPIO0, ADC1_CH0, XTAL_32K_P -10 IO1 I/O/T GPIO1, ADC1_CH1, XTAL_32K_N -11 IO10 I/O/T GPIO10, FSPICS0 -12 GND G 接地 -13 5V P 5 V 电源 -14 5V P 5 V 电源 -15 GND G 接地 -==== ==== ========== ================================ - - -J3 -^^^ - -==== ==== ========== ================================ -序号 名称 类型 [1]_ 功能 -==== ==== ========== ================================ -1 GND G 接地 -2 TX I/O/T GPIO21, U0TXD -3 RX I/O/T GPIO20, U0RXD -4 GND G 接地 -5 IO9 I/O/T GPIO9 [2]_ -6 IO8 I/O/T GPIO8 [2]_, RGB LED -7 GND G 接地 -8 IO7 I/O/T GPIO7, FSPID, MTDO -9 IO6 I/O/T GPIO6, FSPICLK, MTCK -10 IO5 I/O/T GPIO5, ADC2_CH0, FSPIWP, MTDI -11 IO4 I/O/T GPIO4, ADC1_CH4, FSPIHD, MTMS -12 GND G 接地 -13 IO18 I/O/T GPIO18 -14 IO19 I/O/T GPIO19 -15 GND G 接地 -==== ==== ========== ================================ - -.. [1] P:电源;I:输入;O:输出;T:可设置为高阻。 -.. [2] GPIO2、GPIO8、GPIO9 为 ESP32-C3FN4 芯片的 Strapping 管脚。在芯片上电和系统复位过程中,Strapping 管脚根据管脚的二进制电压值控制芯片功能。Strapping 管脚的具体描述和应用,请参考 `ESP32-C3 技术规格书`_ 的 Strapping 管脚章节。 - - -管脚布局 -^^^^^^^^ - -.. figure:: ../../../_static/esp32-c3-devkitm-1-v1-pinout.png - :align: center - :scale: 45% - :alt: ESP32-C3-DevKitM-1 管脚布局(点击放大) - - ESP32-C3-DevKitM-1 管脚布局(点击放大) - - -硬件版本 -========== - -该开发板为最新硬件,尚未有历史版本。 - - -相关文档 -======== - -* `使用 ESP32-C3 构建安全高性价比的互联设备 `_ -* `ESP32-C3 技术规格书`_ (PDF) -* `ESP32-C3-MINI-1 规格书`_ (PDF) -* `ESP32-C3-DevKitM-1 原理图`_ (PDF) -* `ESP32-C3-DevKitM-1 PCB 布局图 `_ (PDF) -* `ESP32-C3-DevKitM-1 尺寸图 `_ (PDF) -* `ESP32-C3-DevKitM-1 尺寸图源文件 `_ (DXF) - 可使用 `Autodesk Viewer `_ 查看 - -有关本开发板的更多设计文档,请联系我们的商务部门 `sales@espressif.com `_。 - -.. _ESP32-C3 技术规格书: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_cn.pdf -.. _ESP32-C3-MINI-1 规格书: https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_cn.pdf -.. _ESP32-C3-DevKitM-1 原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-C3-DEVKITM-1_V1_20200915A.pdf -.. _ESP32-C3-DevKitM-1 PCB 布局图: https://dl.espressif.com/dl/schematics/PCB_ESP32-C3-DEVKITM-1_V1_20200915AA.pdf -.. _ESP32-C3-DevKitM-1 尺寸图: https://dl.espressif.com/dl/schematics/DIMENSION_ESP32-C3-DEVKITM-1_V1_20200915AA.pdf -.. _ESP32-C3-DevKitM-1 尺寸图源文件: https://dl.espressif.com/dl/schematics/DIMENSION_ESP32-C3-DEVKITM-1_V1_20200915AA.dxf diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst deleted file mode 100644 index 03e03e38de76..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-devkitm-1-v1.rst +++ /dev/null @@ -1,321 +0,0 @@ -================== -ESP32-S2-DevKitM-1 -================== - -:link_to_translation:`en: [English]` - -本指南介绍了乐鑫的小型开发板 ESP32-S2-DevKitM-1。 - -ESP32-S2-DevKitM-1 是乐鑫一款入门级开发板。板上模组大部分管脚均已引出至两侧排针,开发人员可根据实际需求,轻松通过跳线连接多种外围设备,同时也可将开发板插在面包板上使用。 - -+----------------------+-----------------------+ -| |ESP32-S2-DevKitM-1| | |ESP32-S2-DevKitM-1U| | -+----------------------+-----------------------+ -| ESP32-S2-DevKitM-1 | ESP32-S2-DevKitM-1U | -+----------------------+-----------------------+ - -.. |ESP32-S2-DevKitM-1| image:: ../../../_static/esp32-s2-devkitm-1-v1-isometric.png - -.. |ESP32-S2-DevKitM-1U| image:: ../../../_static/esp32-s2-devkitm-1u-v1-isometric.png - -本指南包括如下内容: - -- `入门指南`_: 简要介绍了 ESP32-S2-DevKitM-1 和硬件、软件设置指南。 -- `硬件参考`_: 详细介绍了 ESP32-S2-DevKitM-1 的硬件。 -- `硬件版本`_:介绍硬件历史版本和已知问题,并提供链接至历史版本开发板的入门指南(如有)。 -- `相关文档`_: 列出了相关文档的链接。 - - -入门指南 -======== - -本节介绍了如何快速上手 ESP32-S2-DevKitM-1。开头部分介绍了 ESP32-S2-DevKitM-1,`开始开发应用`_ 小节介绍了怎样在 ESP32-S2-DevKitM-1 上烧录固件及相关准备工作。 - - -内含组件和包装 --------------- - - -.. _user-guide-devkitm-1-v1-ordering-info: - -订购信息 -^^^^^^^^ - -该开发板有多种型号可供选择,详见下表。 - -.. list-table:: - :header-rows: 1 - :widths: 30 30 10 10 20 - - * - 订购代码 - - 搭载模组 [#]_ - - Flash - - PSRAM - - 天线 - * - ESP32-S2-DevKitM-1-N4R2 - - ESP32-S2-MINI-1-2 - - (推荐) - - 4 MB - - 2 MB - - PCB 板载天线 - * - ESP32-S2-DevKitM-1U-N4R2 - - ESP32-S2-MINI-1-2U - - (推荐) - - 4 MB - - 2 MB - - 外部天线连接器 - * - ESP32-S2-DevKitM-1 - - ESP32-S2-MINI-1 - - 4 MB - - --- - - PCB 板载天线 - * - ESP32-S2-DevKitM-1U - - ESP32-S2-MINI-1U - - 4 MB - - --- - - 外部天线连接器 - * - ESP32-S2-DevKitM-1R - - ESP32-S2-MINI-1 - - 4 MB - - 2 MB - - PCB 板载天线 - * - ESP32-S2-DevKitM-1RU - - ESP32-S2-MINI-1U - - 4 MB - - 2 MB - - 外部天线连接器 - - -.. [#] ESP32-S2-MINI-2 和 ESP32-S2-MINI-2U 模组使用 v1.0 版本芯片,其余模组使用 v0.0 版本芯片。更多关于芯片版本的信息,请参考 `《ESP32-S2 系列芯片勘误表》`_。 - - -零售订单 -^^^^^^^^ - -如购买样品,每个 ESP32-S2-DevKitM-1 开发板将以防静电袋或零售商选择的其他方式包装。 - -零售订单请前往 https://www.espressif.com/zh-hans/company/contact/buy-a-sample。 - - -批量订单 -^^^^^^^^ - -如批量购买,ESP32-S2-DevKitM-1 开发板将以大纸板箱包装。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -组件介绍 --------- - -.. _user-guide-devkitm-1-v1-board-front: - -.. figure:: ../../../_static/esp32-s2-devkitm-1-v1-annotated-photo.png - :align: center - :alt: ESP32-S2-DevKitM-1 - 正面 - :figclass: align-center - - ESP32-S2-DevKitM-1 - 正面 - -.. figure:: ../../../_static/esp32-s2-devkitm-1u-v1-annotated-photo.png - :align: center - :alt: ESP32-S2-DevKitM-1U - 正面 - :figclass: align-center - - ESP32-S2-DevKitM-1U - 正面 - -以下按照顺时针的顺序依次介绍开发板上的主要组件。 - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 介绍 - * - 板载模组(上图中为 ESP32-S2-MINI-1 或 ESP32-S2-MINI-1U) - - ESP32-S2-MINI 系列模组,可搭载 PCB 板载天线或外部天线连接器。该系列模组尺寸小,flash 和/或 PSRAM 集成在芯片封装内。更多信息,详见 :ref:`user-guide-devkitm-1-v1-ordering-info`。 - * - Pin Headers(排针) - - 所有可用 GPIO 管脚(除 flash 的 SPI 总线)均已引出至开发板的排针。用户可对 ESP32-S2FH4 芯片编程,使能 SPI、I2S、UART、I2C、触摸传感器、PWM 等多种功能。请查看 :ref:`user-guide-devkitm-1-v1-header-blocks` 获取更多信息。 - * - 3.3 V Power On LED(3.3 V 电源指示灯) - - 开发板连接 USB 电源后,该指示灯亮起。 - * - USB-to-UART Bridge(USB 转 UART 桥接器) - - 单芯片 USB 至 UART 桥接器,可提供高达 3 Mbps 的传输速率。 - * - Reset Button(Reset 键) - - 复位按键。 - * - Micro-USB(Micro-USB 接口) - - USB 接口。可用作开发板的供电电源或 PC 和 ESP32-S2FH4 芯片的通信接口。 - * - Boot Button(Boot 键) - - 下载按键。按住 **Boot** 键的同时按一下 **Reset** 键进入“固件下载”模式,通过串口下载固件。 - * - RGB LED - - 可寻址 RGB 发光二极管,由 GPIO18 驱动。 - * - 5 V to 3.3 V LDO(5 V 转 3.3 V LDO) - - 电源转换器,输入 5 V,输出 3.3 V。 - * - External Antenna Connector(外部天线连接器) - - 仅 **ESP32-S2-MINI-2U** 和 **ESP32-S2-MINI-1U** 模组带有外部天线连接器。连接器尺寸,请参考模组规格书的 外部天线连接器尺寸章节。 - - -开始开发应用 ------------- - -通电前,请确保 ESP32-S2-DevKitM-1 完好无损。 - - -必备硬件 -^^^^^^^^ - -- ESP32-S2-DevKitM-1 -- USB 2.0 数据线(标准 A 型转 Micro-B 型) -- 电脑(Windows、Linux 或 macOS) - -.. 注解:: - - 请确保使用适当的 USB 数据线。部分数据线仅可用于充电,无法用于数据传输和编程。 - - -软件设置 -^^^^^^^^ - -请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 一节查看如何快速设置开发环境,将应用程序烧录至 ESP32-S2-DevKitM-1。 - -.. 注解:: - - ESP32-S2 系列芯片仅支持 ESP-IDF master 分支或 v4.2 以上版本。 - - -硬件参考 -======== - -功能框图 --------- - -ESP32-S2-DevKitM-1 的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp32-s2-devkitm-1-v1-block-diagram.png - :align: center - :scale: 70% - :alt: ESP32-S2-DevKitM-1 (点击放大) - :figclass: align-center - - ESP32-S2-DevKitM-1 (点击放大) - - -电源选项 -^^^^^^^^ - -以下任一供电方式均可给 ESP32-S2-DevKitM-1 供电: - -- Micro-USB 接口供电(默认) -- 5V 和 GND 排针供电 -- 3V3 和 GND 排针供电 - -建议选择第一种供电方式:micro USB 接口供电。 - - -.. _user-guide-devkitm-1-v1-header-blocks: - -排针 ----- - -下表列出了开发板两侧排针(J1 和 J3)的 **名称** 和 **功能**,排针的名称如图 :ref:`user-guide-devkitm-1-v1-board-front` 所示,排针的序号与 `ESP32-S2-DevKitM-1 原理图 `_ (PDF) 一致。 - - -J1 -^^^ - -==== ==== ========= ========================================================================= -序号 名称 类型 [#]_ 功能 -==== ==== ========= ========================================================================= -1 3V3 P 3.3 V 电源 -2 0 I/O/T RTC_GPIO0, GPIO0 -3 1 I/O/T RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 -4 2 I/O/T RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 -5 3 I/O/T RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2 -6 4 I/O/T RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 -7 5 I/O/T RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 -8 6 I/O/T RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 -9 7 I/O/T RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 -10 8 I/O/T RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7 -11 9 I/O/T RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, FSPIHD -12 10 I/O/T RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPICS0, FSPIIO4 -13 11 I/O/T RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPID, FSPIIO5 -14 12 I/O/T RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPICLK, FSPIIO6 -15 13 I/O/T RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIQ, FSPIIO7 -16 14 I/O/T RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIWP, FSPIDQS -17 15 I/O/T RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P -18 16 I/O/T RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N -19 17 I/O/T RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6, DAC_1 -20 5V P 5 V 电源 -21 G G 接地 -==== ==== ========= ========================================================================= - - -J3 -^^^ - -==== ==== ===== ======================================================== -序号 名称 类型 功能 -==== ==== ===== ======================================================== -1 G G 接地 -2 RST I CHIP_PU -3 46 I GPIO46 -4 45 I/O/T GPIO45 -5 RX I/O/T U0RXD, GPIO44, CLK_OUT2 -6 TX I/O/T U0TXD, GPIO43, CLK_OUT1 -7 42 I/O/T MTMS, GPIO42 -8 41 I/O/T MTDI, GPIO41, CLK_OUT1 -9 40 I/O/T MTDO, GPIO40, CLK_OUT2 -10 39 I/O/T MTCK, GPIO39, CLK_OUT3 -11 38 I/O/T GPIO38, FSPIWP -12 37 I/O/T SPIDQS, GPIO37, FSPIQ -13 36 I/O/T SPIIO7, GPIO36, FSPICLK -14 35 I/O/T SPIIO6, GPIO35, FSPID -15 34 I/O/T SPIIO5, GPIO34, FSPICS0 -16 33 I/O/T SPIIO4, GPIO33, FSPIHD -17 26 I/O/T SPICS1, GPIO26 -18 21 I/O/T RTC_GPIO21, GPIO21 -19 20 I/O/T RTC_GPIO20, GPIO20, U1CTS, ADC2_CH9, CLK_OUT1, USB_D+ -20 19 I/O/T RTC_GPIO19, GPIO19, U1RTS, ADC2_CH8, CLK_OUT2, USB_D- -21 18 I/O/T RTC_GPIO18, GPIO18, U1RXD, ADC2_CH7, DAC_2, CLK_OUT3, RGB LED -==== ==== ===== ======================================================== - -.. [#] P:电源;I:输入;O:输出;T:可设置为高阻。 - - -管脚布局 -^^^^^^^^ - -.. figure:: ../../../_static/esp32-s2-devkitm-1-v1-pin-layout.png - :align: center - :scale: 15% - :alt: ESP32-S2-DevKitM-1 管脚布局(点击放大) - :figclass: align-center - - ESP32-S2-DevKitM-1 管脚布局(点击放大) - - -硬件版本 -========== - -无历史版本。 - - -相关文档 -======== - -* `ESP32-S2 系列芯片 v1.0 版本技术规格书`_ (PDF) -* `ESP32-S2 系列芯片 v0.0 版本技术规格书 `_ (PDF) -* `《ESP32-S2 系列芯片勘误表》`_ (PDF) -* `《ESP32-S2-MINI-2 & ESP32-S2-MINI-2U 技术规格书》 `_ (PDF) -* `《ESP32-S2-MINI-1 & ESP32-S2-MINI-1U 技术规格书》 `_ (PDF) -* `ESP32-S2-DevKitM-1 原理图 `_ (PDF) -* `ESP32-S2-DevKitM-1 PCB 布局 `_ (PDF) -* `ESP32-S2-DevKitM-1 尺寸图 `_ (PDF) -* `乐鑫产品选型工具 `__ - -有关本开发板的更多设计文档,请联系我们的商务部门 `sales@espressif.com `_。 - -.. _不推荐用于新设计: https://www.espressif.com/zh-hans/products/longevity-commitment -.. _ESP32-S2 系列芯片 v1.0 版本技术规格书: https://www.espressif.com/sites/default/files/documentation/esp32-s2-v1.0_datasheet_cn.pdf -.. _《ESP32-S2 系列芯片勘误表》: https://espressif.com/sites/default/files/documentation/esp32-s2_errata_cn.pdf diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-s2-devkitc-1.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-s2-devkitc-1.rst deleted file mode 100644 index 117a7a742525..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-s2-devkitc-1.rst +++ /dev/null @@ -1,313 +0,0 @@ -================== -ESP32-S2-DevKitC-1 -================== - -:link_to_translation:`en: [English]` - -本指南将帮助你快速上手 ESP32-S2-DevKitC-1,并提供该款开发板的详细信息。 - -ESP32-S2-DevKitC-1 是一款入门级开发板,具备完整的 Wi-Fi 功能。板上模组大部分管脚均已引出至两侧排针,开发人员可根据实际需求,轻松通过跳线连接多种外围设备,同时也可将开发板插在面包板上使用。 - -.. figure:: ../../../_static/esp32-s2-devkitc-1-v1-isometric.png - :align: center - :alt: ESP32-S2-DevKitC-1(板载 ESP32-S2-SOLO 模组) - :figclass: align-center - - ESP32-S2-DevKitC-1(板载 ESP32-S2-SOLO 模组) - -本指南包括如下内容: - -- `入门指南`_:简要介绍了 ESP32-S2-DevKitC-1 和硬件、软件设置指南。 -- `硬件参考`_:详细介绍了 ESP32-S2-DevKitC-1 的硬件。 -- `硬件版本`_:介绍硬件历史版本和已知问题,并提供链接至历史版本开发板的入门指南(如有)。 -- `相关文档`_:列出了相关文档的链接。 - - -入门指南 -======== - -本小节将简要介绍 ESP32-S2-DevKitC-1,说明如何在 ESP32-S2-DevKitC-1 上烧录固件及相关准备工作。 - - -组件介绍 --------- - -.. _user-guide-s2-devkitc-1-v1-board-front: - -.. figure:: ../../../_static/esp32-s2-devkitc-1-v1-annotated-photo.png - :align: center - :alt: ESP32-S2-DevKitC-1 - 正面 - :figclass: align-center - - ESP32-S2-DevKitC-1 - 正面 - -以下按照顺时针的顺序依次介绍开发板上的主要组件。 - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 介绍 - * - 板载模组(上图中为 ESP32-S2-SOLO 或 ESP32-S2-SOLO-U) - - ESP32-S2-SOLO 系列模组,可搭载 PCB 板载天线或外部天线连接器,支持多种 flash 和 PSRAM 大小。更多信息,详见 :ref:`user-guide-s2-devkitc-1-v1-ordering-info`。 - * - 3.3 V Power On LED(3.3 V 电源指示灯) - - 开发板连接 USB 电源后,该指示灯亮起。 - * - USB-to-UART Bridge(USB 转 UART 桥接器) - - 单芯片 USB 转 UART 桥接器,可提供高达 3 Mbps 的传输速率。 - * - Pin Headers(排针) - - 所有可用 GPIO 管脚(除 flash 的 SPI 总线)均已引出至开发板的排针。请查看 :ref:`user-guide-s2-devkitc-1-v1-header-blocks` 获取更多信息。 - * - ESP32-S2 USB Port(ESP32-S2 USB 接口) - - ESP32-S2 USB OTG 接口,支持全速 USB 1.1 标准。该接口可用作开发板的供电接口,可烧录固件至芯片,也可通过 USB 协议与芯片通信。 - * - Reset Button(Reset 键) - - 复位按键。 - * - Boot Button(Boot 键) - - 下载按键。按住 **Boot** 键的同时按一下 **Reset** 键进入“固件下载”模式,通过串口下载固件。 - * - USB-to-UART Port(USB 转 UART 接口) - - Micro-USB 接口,可用作开发板的供电接口,可烧录固件至芯片,也可作为通信接口,通过板载 USB 转 UART 桥接器与 ESP32-S2 芯片通信。 - * - RGB LED - - 可寻址 RGB 发光二极管,由 GPIO18 驱动。 - * - 5 V to 3.3 V LDO(5 V 转 3.3 V LDO) - - 电源转换器,输入 5 V,输出 3.3 V。 - - -开始开发应用 ------------- - -通电前,请确保 ESP32-S2-DevKitC-1 完好无损。 - - -必备硬件 -^^^^^^^^ - -- ESP32-S2-DevKitC-1 -- USB 2.0 数据线(标准 A 型转 Micro-B 型) -- 电脑(Windows、Linux 或 macOS) - -.. 注解:: - - 请确保使用适当的 USB 数据线。部分数据线仅可用于充电,无法用于数据传输和编程。 - - -硬件设置 -^^^^^^^^ - -通过 **USB 转 UART 接口** 或 **ESP32-S2 USB 接口** 连接开发板与电脑。在后续步骤中,默认使用 **USB 转 UART 接口**。 - - -软件设置 -^^^^^^^^ - -请前往 `ESP-IDF 快速入门 `_,在 `详细安装步骤 `_ 小节查看如何快速设置开发环境,将应用程序烧录至 ESP32-S2-DevKitC-1。 - - -内含组件和包装 --------------- - -.. _user-guide-s2-devkitc-1-v1-ordering-info: - -订购信息 -^^^^^^^^ - -该开发板有多种型号可供选择,详见下表。 - -.. list-table:: - :header-rows: 1 - :widths: 35 25 10 10 20 - - * - 订购代码 - - 搭载模组 [#]_ - - Flash - - PSRAM - - 天线 - * - ESP32-S2-DevKitC-1-N8R2 - - ESP32-S2-SOLO-2 - - (推荐) - - 8 MB - - 2 MB - - PCB 板载天线 - * - ESP32-S2-DevKitC-1U-N8R2 - - ESP32-S2-SOLO-2U - - (推荐) - - 8 MB - - 2 MB - - 外部天线连接器 - * - ESP32-S2-DevKitC-1 - - ESP32-S2-SOLO - - 4 MB - - --- - - PCB 板载天线 - * - ESP32-S2-DevKitC-1U - - ESP32-S2-SOLO-U - - 4 MB - - --- - - 外部天线连接器 - * - ESP32-S2-DevKitC-1R - - ESP32-S2-SOLO - - 4 MB - - 2 MB - - PCB 板载天线 - * - ESP32-S2-DevKitC-1RU - - ESP32-S2-SOLO-U - - 4 MB - - 2 MB - - 外部天线连接器 - -.. [#] ESP32-S2-SOLO-2 和 ESP32-S2-SOLO-2U 模组使用 v1.0 版本芯片,其余模组使用 v0.0 版本芯片。更多关于芯片版本的信息,请参考 `《ESP32-S2 系列芯片勘误表》`_。 - - -零售订单 -^^^^^^^^ - -如购买样品,每个 ESP32-S2-DevKitC-1 将以防静电袋或零售商选择的其他方式包装。 - -零售订单请前往 https://www.espressif.com/zh-hans/company/contact/buy-a-sample。 - - -批量订单 -^^^^^^^^ - -如批量购买,ESP32-S2-DevKitC-1 将以大纸板箱包装。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -硬件参考 -======== - -功能框图 --------- - -ESP32-S2-DevKitC-1 的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp32-s2-devkitc-1-v1-block-diags.png - :align: center - :scale: 70% - :alt: ESP32-S2-DevKitC-1(点击放大) - :figclass: align-center - - ESP32-S2-DevKitC-1(点击放大) - - -电源选项 -^^^^^^^^ - -以下任一供电方式均可给 ESP32-S2-DevKitC-1 供电: - -- USB 转 UART 接口供电或 ESP32-S2 USB 接口供电(选择其一或同时供电),默认供电方式(推荐) -- 5V 和 G (GND) 排针供电 -- 3V3 和 G (GND) 排针供电 - - -.. _user-guide-s2-devkitc-1-v1-header-blocks: - -排针 ----- - -下表列出了开发板两侧排针(J1 和 J3)的 **名称** 和 **功能**,排针的名称如图 :ref:`user-guide-s2-devkitc-1-v1-board-front` 所示,排针的序号与 `ESP32-S2-DevKitC-1 原理图`_ (PDF) 一致。 - - -J1 -^^^ - -==== ========= ========= ========================================================================= -序号 名称 类型 [#]_ 功能 -==== ========= ========= ========================================================================= -1 3V3 P 3.3 V 电源 -2 3V3 P 3.3 V 电源 -3 RST I CHIP_PU -4 4 I/O/T RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 -5 5 I/O/T RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 -6 6 I/O/T RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 -7 7 I/O/T RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 -8 15 I/O/T RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P -9 16 I/O/T RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N -10 17 I/O/T RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6, DAC_1 -11 18 [#]_ I/O/T RTC_GPIO18, GPIO18[#]_, U1RXD, ADC2_CH7, DAC_2, CLK_OUT3, RGB LED -12 8 I/O/T RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7 -13 3 I/O/T RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2 -14 46 I GPIO46 -15 9 I/O/T RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, FSPIHD -16 10 I/O/T RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPICS0, FSPIIO4 -17 11 I/O/T RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPID, FSPIIO5 -18 12 I/O/T RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPICLK, FSPIIO6 -19 13 I/O/T RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIQ, FSPIIO7 -20 14 I/O/T RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIWP, FSPIDQS -21 5V P 5 V 电源 -22 G G 接地 -==== ========= ========= ========================================================================= - - -J3 -^^^ - -==== ==== ===== ================================================================ -序号 名称 类型 功能 -==== ==== ===== ================================================================ -1 G G 接地 -2 TX I/O/T U0TXD, GPIO43, CLK_OUT1 -3 RX I/O/T U0RXD, GPIO44, CLK_OUT2 -4 1 I/O/T RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 -5 2 I/O/T RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 -6 42 I/O/T MTMS, GPIO42 -7 41 I/O/T MTDI, GPIO41, CLK_OUT1 -8 40 I/O/T MTDO, GPIO40, CLK_OUT2 -9 39 I/O/T MTCK, GPIO39, CLK_OUT3 -10 38 I/O/T GPIO38, FSPIWP -11 37 I/O/T SPIDQS, GPIO37, FSPIQ -12 36 I/O/T SPIIO7, GPIO36, FSPICLK -13 35 I/O/T SPIIO6, GPIO35, FSPID -14 0 I/O/T RTC_GPIO0, GPIO0 -15 45 I/O/T GPIO45 -16 34 I/O/T SPIIO5, GPIO34, FSPICS0 -17 33 I/O/T SPIIO4, GPIO33, FSPIHD -18 21 I/O/T RTC_GPIO21, GPIO21 -19 20 I/O/T RTC_GPIO20, GPIO20, U1CTS, ADC2_CH9, CLK_OUT1, USB_D+ -20 19 I/O/T RTC_GPIO19, GPIO19, U1RTS, ADC2_CH8, CLK_OUT2, USB_D- -21 G G 接地 -22 G G 接地 -==== ==== ===== ================================================================ - -.. [#] P:电源;I:输入;O:输出;T:可设置为高阻。 -.. [#] 搭载 ESP32-S2-SOLO-2 或 ESP32-S2-SOLO-2U 的开发板未上拉 GPIO18。 - - -管脚布局 -^^^^^^^^ - -.. figure:: ../../../_static/esp32-s2-devkitc-1-v1-pinout.png - :align: center - :scale: 45% - :alt: ESP32-S2-DevKitC-1 管脚布局(点击放大) - :figclass: align-center - - ESP32-S2-DevKitC-1 管脚布局(点击放大) - - -硬件版本 -========== - -无历史版本。 - - -相关文档 -======== - -* `ESP32-S2 系列芯片 v1.0 版本技术规格书`_ (PDF) -* `ESP32-S2 系列芯片 v0.0 版本技术规格书 `_ (PDF) -* `《ESP32-S2 系列芯片勘误表》`_ (PDF) -* `《ESP32-S2-SOLO-2 & ESP32-S2-SOLO-2U 模组技术规格书》 `_ (PDF) -* `《ESP32-S2-SOLO & ESP32-S2-SOLO-U 模组技术规格书》 `_ (PDF) -* `ESP32-S2-DevKitC-1 原理图`_ (PDF) -* `ESP32-S2-DevKitC-1 PCB 布局图 `_ (PDF) -* `ESP32-S2-DevKitC-1 尺寸图 `_ (PDF) -* `ESP32-S2-DevKitC-1 尺寸图源文件 `_ (DXF) - 可使用 `Autodesk Viewer `_ 查看 - -有关本开发板的更多设计文档,请联系我们的商务部门 `sales@espressif.com `_。 - -.. _不推荐用于新设计: https://www.espressif.com/zh-hans/products/longevity-commitment -.. _ESP32-S2 系列芯片 v1.0 版本技术规格书: https://www.espressif.com/sites/default/files/documentation/esp32-s2-v1.0_datasheet_cn.pdf -.. _《ESP32-S2 系列芯片勘误表》: https://espressif.com/sites/default/files/documentation/esp32-s2_errata_cn.pdf -.. _ESP32-S2-DevKitC-1 原理图: https://dl.espressif.com/dl/schematics/esp-idf/SCH_ESP32-S2-DEVKITC-1_V1_20220817.pdf diff --git a/docs/zh_CN/hw-reference/index.rst b/docs/zh_CN/hw-reference/index.rst index fa139e62a0e6..8ee7f2fa33f3 100644 --- a/docs/zh_CN/hw-reference/index.rst +++ b/docs/zh_CN/hw-reference/index.rst @@ -15,6 +15,7 @@ H/W 硬件参考 :esp32c3: 技术规格书 (PDF) :esp32c6: 技术规格书 (PDF) :esp32h2: 技术规格书 (PDF) + :esp32p4: 技术规格书 (PDF) :esp32: 硬件设计指南 (PDF) :esp32s2: 硬件设计指南 (PDF) :esp32s3: 硬件设计指南 (PDF) @@ -22,11 +23,14 @@ H/W 硬件参考 :esp32c3: 硬件设计指南 (PDF) :esp32c6: 硬件设计指南 (PDF) :esp32h2: 硬件设计指南 (PDF) + :esp32p4: 硬件设计指南 (PDF) :esp32: 勘误表及解决方法 (PDF) :esp32s2: 勘误表及解决方法 (PDF) :esp32s3: 勘误表及解决方法 (PDF) :esp32c3: 勘误表及解决方法 (PDF) :esp32c2: 勘误表及解决方法 (PDF) + :esp32c6: 勘误表及解决方法 (PDF) + :esp32h2: 勘误表及解决方法 (PDF) 芯片变型 模组 开发板 diff --git a/docs/zh_CN/migration-guides/release-5.x/5.0/networking.rst b/docs/zh_CN/migration-guides/release-5.x/5.0/networking.rst index 4293fd438c2c..cbf492f79825 100644 --- a/docs/zh_CN/migration-guides/release-5.x/5.0/networking.rst +++ b/docs/zh_CN/migration-guides/release-5.x/5.0/networking.rst @@ -140,6 +140,8 @@ TCP/IP 适配器是在 ESP-IDF v4.1 之前使用的网络接口抽象组件。 * :component_file:`DNS ` * :component_file:`IP address ` +TCP/IP 适配器 API ``tcpip_adapter_get_sta_list()`` 用于获取与软件接入点 (softAP) 相关联的 Wi-Fi 站点列表,现已移到 Wi-Fi 组件,并更名为 :cpp:func:`esp_wifi_ap_get_sta_list_with_ip()`,它是 ESP-NETIF API :cpp:func:`esp_netif_dhcps_get_clients_by_mac()` 一个特例。无论服务器在哪个网络接口上运行,该 API 都可更方便地提供连接到 DHCP 服务器的客户端列表。 + 默认事件处理程序 ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/bluetooth/.build-test-rules.yml b/examples/bluetooth/.build-test-rules.yml index ab792435afd1..16d87cc996bc 100644 --- a/examples/bluetooth/.build-test-rules.yml +++ b/examples/bluetooth/.build-test-rules.yml @@ -131,17 +131,12 @@ examples/bluetooth/hci/controller_hci_uart_esp32c3_and_esp32s3: # config BT_NIMBLE_ENABLED does not depends on any soc cap -examples/bluetooth/nimble: - <<: *bt_default_depends - disable: - - if: SOC_BLE_SUPPORTED != 1 - depends_filepatterns: - - examples/bluetooth/nimble/common/**/* - examples/bluetooth/nimble/ble_enc_adv_data: <<: *bt_default_depends - disable: - - if: SOC_ESP_NIMBLE_CONTROLLER != 1 + enable: + - if: SOC_BLE_SUPPORTED == 1 and IDF_TARGET != "esp32" + temporary: true + reason: BLE5.0 not supported on esp32 depends_filepatterns: - examples/bluetooth/nimble/common/**/* diff --git a/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c b/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c index a06f91479f08..f8a6253c3f30 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -410,6 +410,12 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par param->update_conn_params.latency, param->update_conn_params.timeout); break; + case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT: + ESP_LOGI(GATTC_TAG, "packet length updated: rx = %d, tx = %d, status = %d", + param->pkt_data_length_cmpl.params.rx_len, + param->pkt_data_length_cmpl.params.tx_len, + param->pkt_data_length_cmpl.status); + break; default: break; } diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c index ff240df6cbcc..fc808471e10e 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -235,6 +235,12 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param param->update_conn_params.latency, param->update_conn_params.timeout); break; + case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT: + ESP_LOGI(GATTS_TAG, "packet length updated: rx = %d, tx = %d, status = %d", + param->pkt_data_length_cmpl.params.rx_len, + param->pkt_data_length_cmpl.params.tx_len, + param->pkt_data_length_cmpl.status); + break; default: break; } diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/main/periodic_adv_demo.c b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/main/periodic_adv_demo.c index 240c7c2fcf49..af0bcd8f62a5 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/main/periodic_adv_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/main/periodic_adv_demo.c @@ -35,7 +35,7 @@ #include "freertos/semphr.h" -#define LOG_TAG "MULTI_ADV_DEMO" +#define LOG_TAG "PERIODIC_ADV_DEMO" #define FUNC_SEND_WAIT_SEM(func, sem) do {\ esp_err_t __err_rc = (func);\ @@ -99,39 +99,39 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param switch (event) { case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d", param->ext_adv_set_rand_addr.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d, instance %d", param->ext_adv_set_rand_addr.status, param->ext_adv_set_rand_addr.instance); break; case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->ext_adv_set_params.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d, instance %d", param->ext_adv_set_params.status, param->ext_adv_set_params.instance); break; case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d", param->ext_adv_data_set.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d, instance %d", param->ext_adv_data_set.status, param->ext_adv_data_set.instance); break; case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d", param->scan_rsp_set.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d, instance %d", param->scan_rsp_set.status, param->scan_rsp_set.instance); break; case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d", param->ext_adv_start.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d, instance numble %d", param->ext_adv_start.status, param->ext_adv_start.instance_num); break; case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d", param->ext_adv_stop.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d, instance numble %d", param->ext_adv_stop.status, param->ext_adv_stop.instance_num); break; case ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->peroid_adv_set_params.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, status %d, instance %d", param->peroid_adv_set_params.status, param->peroid_adv_set_params.instance); break; case ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, status %d", param->period_adv_data_set.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, status %d, instance %d", param->period_adv_data_set.status, param->period_adv_data_set.instance); break; case ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT, status %d", param->period_adv_start.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT, status %d, instance %d", param->period_adv_start.status, param->period_adv_start.instance); break; default: break; diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/tutorial/Periodic_adv_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/tutorial/Periodic_adv_Example_Walkthrough.md index 6cba53448221..4cab5258ac15 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_adv/tutorial/Periodic_adv_Example_Walkthrough.md +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_adv/tutorial/Periodic_adv_Example_Walkthrough.md @@ -257,46 +257,44 @@ Once the Extended advertising data have been set, the GAP event `ESP_GAP_BLE_EXT ```c -static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param){ - switch (event) { - case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT: - xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d", param->ext _adv_set_rand_addr.status); - break; - case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT: - xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->ext_adv_set_params.status); - break; - case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT: - xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d", param->ext_adv_data_set.status); - break; - case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT: - xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d", param->scan_rsp_set.status); - break; - case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT: - xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d", param->ext_adv_start.status); - break; - case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT: - xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d", param->ext_adv_stop.status); - break; - case ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT: - xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->p -eroid_adv_set_params.status); +static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + switch (event) { + case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d, instance %d", param->ext_adv_set_rand_addr.status, param->ext_adv_set_rand_addr.instance); + break; + case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d, instance %d", param->ext_adv_set_params.status, param->ext_adv_set_params.instance); + break; + case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d, instance %d", param->ext_adv_data_set.status, param->ext_adv_data_set.instance); + break; + case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d, instance %d", param->scan_rsp_set.status, param->scan_rsp_set.instance); + break; + case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d, instance numble %d", param->ext_adv_start.status, param->ext_adv_start.instance_num); + break; + case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d, instance numble %d", param->ext_adv_stop.status, param->ext_adv_stop.instance_num); + break; + case ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT: + xSemaphoreGive(test_sem); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, status %d, instance %d", param->peroid_adv_set_params.status, param->peroid_adv_set_params.instance); break; case ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, status %d", param->per -iod_adv_data_set.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, status %d, instance %d", param->period_adv_data_set.status, param->period_adv_data_set.instance); break; case ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT: xSemaphoreGive(test_sem); - ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT, status %d", param->period -_adv_start.status); + ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT, status %d, instance %d", param->period_adv_start.status, param->period_adv_start.instance); break; default: break; diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c index bda0bea28365..894f8862bb5a 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -47,6 +47,17 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); /******************************* * STATIC FUNCTION DEFINITIONS ******************************/ +static char *bda2str(uint8_t * bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param) { @@ -176,6 +187,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) void app_main(void) { + char bda_str[18] = {0}; /* initialize NVS — it is used to store PHY calibration data */ esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { @@ -230,6 +242,7 @@ void app_main(void) pin_code[3] = '4'; esp_bt_gap_set_pin(pin_type, 4, pin_code); + ESP_LOGI(BT_AV_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); bt_app_task_start_up(); /* bluetooth device name, connection mode and profile set up */ bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c index 16fceef28533..9bad03babffd 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c @@ -735,6 +735,7 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param) void app_main(void) { + char bda_str[18] = {0}; /* initialize NVS — it is used to store PHY calibration data */ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { @@ -788,6 +789,7 @@ void app_main(void) esp_bt_pin_code_t pin_code; esp_bt_gap_set_pin(pin_type, 0, pin_code); + ESP_LOGI(BT_AV_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); bt_app_task_start_up(); /* Bluetooth device name, connection mode and profile set up */ bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_STACK_UP_EVT, NULL, 0, NULL); diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/main.c index 5b4123c45e26..0c7669fadced 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/main/main.c @@ -272,6 +272,7 @@ static void bt_app_gap_start_up(void) void app_main(void) { + char bda_str[18] = {0}; /* Initialize NVS — it is used to store PHY calibration data and save key-value pairs in flash memory*/ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { @@ -304,5 +305,6 @@ void app_main(void) return; } + ESP_LOGI(GAP_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); bt_app_gap_start_up(); } diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/main.c index 349a81280115..0d4ca2cf2d1d 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -71,6 +71,18 @@ uint8_t hid_mouse_descriptor[] = { 0xc0 // END_COLLECTION }; +static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} + const int hid_mouse_descriptor_len = sizeof(hid_mouse_descriptor); /** @@ -158,16 +170,6 @@ void mouse_move_task(void *pvParameters) } } -static void print_bt_address(void) -{ - const char *TAG = "bt_address"; - const uint8_t *bd_addr; - - bd_addr = esp_bt_dev_get_address(); - ESP_LOGI(TAG, "my bluetooth address is %02X:%02X:%02X:%02X:%02X:%02X", - bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); -} - void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) { const char *TAG = "esp_bt_gap_cb"; @@ -390,6 +392,7 @@ void app_main(void) { const char *TAG = "app_main"; esp_err_t ret; + char bda_str[18] = {0}; ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { @@ -477,6 +480,6 @@ void app_main(void) esp_bt_pin_code_t pin_code; esp_bt_gap_set_pin(pin_type, 0, pin_code); - print_bt_address(); + ESP_LOGI(TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); ESP_LOGI(TAG, "exiting"); } diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/console_uart.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/console_uart.c index 7e10c2ea1060..4bd1b2a0e195 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/console_uart.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/console_uart.c @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ +#include "stdlib.h" #include "driver/uart.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -31,7 +32,7 @@ extern void spp_msg_args_parser(char *buf, int len); void spp_msg_handler(char *buf, int len) { - ESP_LOGE(TAG_CNSL, "Command [%s]", buf); + ESP_LOGI(TAG_CNSL, "Command [%s]", buf); spp_msg_args_parser(buf, len); } @@ -44,13 +45,18 @@ static void console_uart_task(void *pvParameters) spp_msg_parser_register_callback(parser, spp_msg_handler); spp_msg_show_usage(); #define TMP_BUF_LEN 128 - uint8_t tmp_buf[128] = {0}; + uint8_t *tmp_buf = NULL; + + if ((tmp_buf = (uint8_t *)calloc(TMP_BUF_LEN, sizeof(uint8_t))) == NULL) { + ESP_LOGE(TAG_CNSL,"temp buf malloc fail"); + return; + } for (;;) { //Waiting for UART event. if (xQueueReceive(uart_queue, (void * )&event, (TickType_t)portMAX_DELAY)) { switch (event.type) { - //Event of UART receving data + //Event of UART receiving data case UART_DATA: { len = uart_read_bytes(CONSOLE_UART_NUM, tmp_buf, TMP_BUF_LEN, 0); @@ -95,6 +101,8 @@ static void console_uart_task(void *pvParameters) } } } + + free(tmp_buf); vTaskDelete(NULL); } diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md index d00c97a9fd89..fc13dc110ad6 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md @@ -43,6 +43,19 @@ The default configuration is `PCM`, if you want to use `vHCI` you should configu `Component config --> Bluetooth --> Bluedroid Options --> Hands Free/Handset Profile --> audio(SCO) data path --> HCI`. +#### PCM Signal Configurations + +PCM Signal supports two configurations in menuconfig: PCM Role, PCM Polar. + +- PCM Role: PCM role can be configured as PCM master or PCM slave. The default configuration is `Master`, you can change the PCM role in `menuconfig` path: + `Component config --> Bluetooth --> Controller Options --> PCM Signal Config(Role and Polar) --> PCM Role` + +- PCM Polar: PCM polarity can be configured as Falling Edge or Rising Edge. The default configuration is `Falling Edge`, you can change the PCM polar in `menuconfig` path: + `Component config --> Bluetooth --> Controller Options --> PCM Signal Config(Role and Polar) --> PCM Polar` + +The default configuration of PCM frame synchronization signal is `Stereo mode(Dual channel)`. FSYNC and DOUT signals both change simultaneously on the edge of CLK. The FSYNC signal continues until the end of the current channel-data transmission. As is shown in the figure ![Stereo](image/Channel_Mode.png) +The latest version of esp-idf master branch can configure three different forms(Stereo mode, Mono mode 1, Mono mode 2). + ### Codec Choice ESP32 supports two types of codec for HFP audio data: `CVSD` and `mSBC`. @@ -75,7 +88,7 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l ## Example Output -When you flash and monitor this example, the commands help table prints the following log at the very begining: +When you flash and monitor this example, the commands help table prints the following log at the very beginning: ``` Type 'help' to get the list of commands. diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/image/Channel_Mode.png b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/image/Channel_Mode.png new file mode 100644 index 000000000000..80b31499e738 Binary files /dev/null and b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/image/Channel_Mode.png differ diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c index d5e6f3d30e76..c93aac3da220 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -32,6 +32,18 @@ enum { BT_APP_EVT_STACK_UP = 0, }; +static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} + /* handler for bluetooth stack enabled events */ static void bt_hf_hdl_stack_evt(uint16_t event, void *p_param) { @@ -73,6 +85,7 @@ static void bt_hf_hdl_stack_evt(uint16_t event, void *p_param) void app_main(void) { + char bda_str[18] = {0}; /* Initialize NVS — it is used to store PHY calibration data */ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { @@ -101,6 +114,7 @@ void app_main(void) return; } + ESP_LOGI(BT_HF_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); /* create application task */ bt_app_task_start_up(); diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md index 55660bf85d42..000851983956 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/README.md @@ -45,6 +45,19 @@ The default configuration is `PCM`, if you want to use `vHCI` you should configu `Component config --> Bluetooth --> Bluedroid Options --> Hands Free/Handset Profile --> audio(SCO) data path --> HCI`. +#### PCM Signal Configurations + +PCM Signal supports two configurations in menuconfig: PCM Role, PCM Polar. + +- PCM Role: PCM role can be configured as PCM master or PCM slave. The default configuration is `Master`, you can change the PCM role in `menuconfig` path: + `Component config --> Bluetooth --> Controller Options --> PCM Signal Config(Role and Polar) --> PCM Role` + +- PCM Polar: PCM polarity can be configured as Falling Edge or Rising Edge. The default configuration is `Falling Edge`, you can change the PCM polar in `menuconfig` path: + `Component config --> Bluetooth --> Controller Options --> PCM Signal Config(Role and Polar) --> PCM Polar` + +The default configuration of PCM frame synchronization signal is `Stereo mode(Dual channel)`. FSYNC and DOUT signals both change simultaneously on the edge of CLK. The FSYNC signal continues until the end of the current channel-data transmission. As is shown in the figure ![Stereo](../hfp_ag/image/Channel_Mode.png) +The latest version of esp-idf master branch can configure three different forms(Stereo mode, Mono mode 1, Mono mode 2). + ### Codec Choice ESP32 supports two types of codec for HFP audio data: `CVSD` and `mSBC`. @@ -53,7 +66,7 @@ ESP32 supports two types of codec for HFP audio data: `CVSD` and `mSBC`. `Component config --> Bluetooth --> Bluedroid Options --> Wide Band Speech`. -Switching on the `Wide Band Speech` means that the prefered codec is `mSBC`, but which one is actually being used also depends on the `Data Path` configuration. +Switching on the `Wide Band Speech` means that the preferred codec is `mSBC`, but which one is actually being used also depends on the `Data Path` configuration. - If you choose `PCM` for datapath, you can only use `CVSD` and hardware is responsible for the codec job. In the meanwhile, you cannot use `mSBC` by switching `Wide Band Speech` on, because the `mSBC` is implemented in the Bluedroid (Bluetooth Host Stack) by software. @@ -77,7 +90,7 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l ## Example Output -When you run this example, the explain prints the following at the very begining: +When you run this example, the explain prints the following at the very beginning: ``` Type 'help' to get the list of commands. @@ -167,7 +180,7 @@ I (133262) BT_HF: --audio state disconnected - Reject an incoming call - Disable the voice recognition -#### Choise of Codec +#### Choice of Codec ESP32 supports both CVSD and mSBC codec. HF Unit and AG device determine which codec to use by exchanging features during service level connection. The choice of codec also depends on the your configuration in `menuconfig`. @@ -268,7 +281,7 @@ I (293172) BT_HF: APP HFP event: AT_RESPONSE I (293172) BT_HF: --AT response event, code 0, cme 0 E (293702) BT_BTM: btm_sco_connected, handle 181 I (293702) BT_HF: APP HFP event: AUDIO_STATE_EVT -I (293702) BT_HF: --audio state connecte +I (293702) BT_HF: --audio state connected ``` #### Query Current Operator Name diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c index cfd1e4844f03..cdf47d7b2f9d 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -32,6 +32,18 @@ static uint8_t peer_bdname_len; static const char remote_device_name[] = "ESP_HFP_AG"; +static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} + static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len) { uint8_t *rmt_bdname = NULL; @@ -151,6 +163,7 @@ static void bt_hf_client_hdl_stack_evt(uint16_t event, void *p_param); void app_main(void) { + char bda_str[18] = {0}; /* Initialize NVS — it is used to store PHY calibration data */ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { @@ -186,6 +199,7 @@ void app_main(void) return; } + ESP_LOGI(BT_HF_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); /* create application task */ bt_app_task_start_up(); diff --git a/examples/bluetooth/blufi/main/blufi_example_main.c b/examples/bluetooth/blufi/main/blufi_example_main.c index 301a9ea72b09..3e0090783035 100644 --- a/examples/bluetooth/blufi/main/blufi_example_main.c +++ b/examples/bluetooth/blufi/main/blufi_example_main.c @@ -246,7 +246,7 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, } case WIFI_EVENT_AP_STADISCONNECTED: { wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; - BLUFI_INFO("station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid); + BLUFI_INFO("station "MACSTR" leave, AID=%d, reason=%d", MAC2STR(event->mac), event->aid, event->reason); break; } diff --git a/examples/bluetooth/esp_hid_host/main/esp_hid_host_main.c b/examples/bluetooth/esp_hid_host/main/esp_hid_host_main.c index 420ff9d72bf1..1643b8a33ea8 100644 --- a/examples/bluetooth/esp_hid_host/main/esp_hid_host_main.c +++ b/examples/bluetooth/esp_hid_host/main/esp_hid_host_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -51,6 +51,18 @@ static const char *TAG = "ESP_HIDH_DEMO"; +static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} + void hidh_callback(void *handler_args, esp_event_base_t base, int32_t id, void *event_data) { esp_hidh_event_t event = (esp_hidh_event_t)id; @@ -165,6 +177,7 @@ void ble_store_config_init(void); #endif void app_main(void) { + char bda_str[18] = {0}; esp_err_t ret; #if HID_HOST_MODE == HIDH_IDLE_MODE ESP_LOGE(TAG, "Please turn on BT HID host or BLE!"); @@ -188,6 +201,7 @@ void app_main(void) }; ESP_ERROR_CHECK( esp_hidh_init(&config) ); + ESP_LOGI(TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); #if CONFIG_BT_NIMBLE_ENABLED /* XXX Need to have template for store */ ble_store_config_init(); diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild index 8cad8f99527c..12750f2701df 100644 --- a/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild @@ -15,7 +15,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild index a52400353482..8e5ab9f250a4 100644 --- a/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_cent/README.md b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_cent/README.md index 294852040c32..09290a2409c9 100644 --- a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_cent/README.md +++ b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_cent/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C2 | ESP32-C6 | ESP32-H2 | -| ----------------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | # BLE Encrypted Advertising Data Central Example diff --git a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/README.md b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/README.md index 1402564ca28a..ad4acd83fd9b 100644 --- a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/README.md +++ b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C2 | ESP32-C6 | ESP32-H2 | -| ----------------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | # BLE Encrypted Advertising Data Peripheral Example diff --git a/examples/bluetooth/nimble/ble_htp/htp_cent/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_htp/htp_cent/main/Kconfig.projbuild index 8cad8f99527c..12750f2701df 100644 --- a/examples/bluetooth/nimble/ble_htp/htp_cent/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_htp/htp_cent/main/Kconfig.projbuild @@ -15,7 +15,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_htp/htp_prph/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_htp/htp_prph/main/Kconfig.projbuild index 92f93deb845b..3705112d5e20 100644 --- a/examples/bluetooth/nimble/ble_htp/htp_prph/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_htp/htp_prph/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_htp/htp_prph/sdkconfig.defaults b/examples/bluetooth/nimble/ble_htp/htp_prph/sdkconfig.defaults index c829fc5c002e..09631ee6856e 100644 --- a/examples/bluetooth/nimble/ble_htp/htp_prph/sdkconfig.defaults +++ b/examples/bluetooth/nimble/ble_htp/htp_prph/sdkconfig.defaults @@ -10,3 +10,4 @@ CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=n CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4000 diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/Kconfig.projbuild index 58d5dc4ef8ac..b259360eb0ea 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/Kconfig.projbuild @@ -8,7 +8,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/Kconfig.projbuild index ede9e666abd7..5d41352b16dd 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/Kconfig.projbuild @@ -50,7 +50,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/Kconfig.projbuild index 0662463dcb01..e57e163cccd4 100644 --- a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_periodic_adv/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_periodic_adv/main/Kconfig.projbuild index c7b32ae16d8a..fd4037d16a65 100644 --- a/examples/bluetooth/nimble/ble_periodic_adv/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_periodic_adv/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_periodic_sync/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_periodic_sync/main/Kconfig.projbuild index 0763e71d72c8..f5315592b1cb 100644 --- a/examples/bluetooth/nimble/ble_periodic_sync/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_periodic_sync/main/Kconfig.projbuild @@ -1,7 +1,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_cent/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_cent/main/Kconfig.projbuild index c084eb3e35b9..eefb5c981549 100644 --- a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_cent/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_cent/main/Kconfig.projbuild @@ -15,7 +15,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/Kconfig.projbuild index 92f93deb845b..3705112d5e20 100644 --- a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/blecent/main/Kconfig.projbuild b/examples/bluetooth/nimble/blecent/main/Kconfig.projbuild index 23e88bae48c5..13d5cd0ddf0e 100644 --- a/examples/bluetooth/nimble/blecent/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/blecent/main/Kconfig.projbuild @@ -8,7 +8,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/blehr/sdkconfig.defaults b/examples/bluetooth/nimble/blehr/sdkconfig.defaults index c829fc5c002e..09631ee6856e 100644 --- a/examples/bluetooth/nimble/blehr/sdkconfig.defaults +++ b/examples/bluetooth/nimble/blehr/sdkconfig.defaults @@ -10,3 +10,4 @@ CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=n CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4000 diff --git a/examples/bluetooth/nimble/bleprph/main/Kconfig.projbuild b/examples/bluetooth/nimble/bleprph/main/Kconfig.projbuild index e4520eefa294..2529f3bab9ac 100644 --- a/examples/bluetooth/nimble/bleprph/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/bleprph/main/Kconfig.projbuild @@ -50,7 +50,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/bleprph_host_only/main/Kconfig.projbuild b/examples/bluetooth/nimble/bleprph_host_only/main/Kconfig.projbuild index 197519e90386..1162b1216cc3 100644 --- a/examples/bluetooth/nimble/bleprph_host_only/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/bleprph_host_only/main/Kconfig.projbuild @@ -110,7 +110,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/bleprph_host_only/main/uart_driver.c b/examples/bluetooth/nimble/bleprph_host_only/main/uart_driver.c index 07e82387f519..cd3916724a6e 100644 --- a/examples/bluetooth/nimble/bleprph_host_only/main/uart_driver.c +++ b/examples/bluetooth/nimble/bleprph_host_only/main/uart_driver.c @@ -170,6 +170,13 @@ void hci_uart_send(uint8_t *buf, uint16_t len) } } + +void +ble_transport_ll_init(void) +{ + +} + int ble_transport_to_ll_acl_impl(struct os_mbuf *om) { diff --git a/examples/bluetooth/nimble/power_save/README.md b/examples/bluetooth/nimble/power_save/README.md index bfad7b536ddf..048de15e2576 100644 --- a/examples/bluetooth/nimble/power_save/README.md +++ b/examples/bluetooth/nimble/power_save/README.md @@ -140,4 +140,5 @@ X: This feature is currently not supported. - ESP32 does not support the use of main XTAL in light sleep mode, so an external 32kHz crystal is required. - ESP32C2 support XTAL frequency of 26MHz and 40MHz, the XTAL frequency is set to 26MHz in default. -- ESP32C2 support external 32kHz crystal by connecting the crystal to the chip through pin0 \ No newline at end of file +- ESP32C2 support external 32kHz crystal by connecting the crystal to the chip through pin0 +- ESP32C6 REQUIRES CONFIG_ESP_PHY_MAC_BB_PD to be set for light sleep to run properly \ No newline at end of file diff --git a/examples/bluetooth/nimble/power_save/main/Kconfig.projbuild b/examples/bluetooth/nimble/power_save/main/Kconfig.projbuild index 9fb8e7323181..ca160813febf 100644 --- a/examples/bluetooth/nimble/power_save/main/Kconfig.projbuild +++ b/examples/bluetooth/nimble/power_save/main/Kconfig.projbuild @@ -129,7 +129,7 @@ menu "Example Configuration" config EXAMPLE_EXTENDED_ADV bool - depends on SOC_BLE_50_SUPPORTED + depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT default y if SOC_ESP_NIMBLE_CONTROLLER select BT_NIMBLE_EXT_ADV prompt "Enable Extended Adv" diff --git a/examples/bluetooth/nimble/power_save/sdkconfig.defaults b/examples/bluetooth/nimble/power_save/sdkconfig.defaults index 8b57fab433bf..7f51e2e7a5ca 100644 --- a/examples/bluetooth/nimble/power_save/sdkconfig.defaults +++ b/examples/bluetooth/nimble/power_save/sdkconfig.defaults @@ -19,3 +19,4 @@ CONFIG_FREERTOS_USE_TICKLESS_IDLE=y CONFIG_FREERTOS_HZ=1000 # Minimum number of ticks to enter sleep mode for CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP=3 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4000 diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index a5b654d50ed2..1b450b923624 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -4,8 +4,8 @@ menu "Example Connection Configuration" config EXAMPLE_CONNECT_WIFI bool "connect using WiFi interface" - depends on !IDF_TARGET_LINUX && SOC_WIFI_SUPPORTED - default y + depends on !IDF_TARGET_LINUX && (SOC_WIFI_SUPPORTED || ESP_WIFI_REMOTE_ENABLED) + default y if SOC_WIFI_SUPPORTED help Protocol examples can use Wi-Fi and/or Ethernet to connect to the network. Choose this option to connect with WiFi @@ -119,7 +119,7 @@ menu "Example Connection Configuration" config EXAMPLE_CONNECT_ETHERNET bool "connect using Ethernet interface" depends on !IDF_TARGET_LINUX - default y if !SOC_WIFI_SUPPORTED + default y if !EXAMPLE_CONNECT_WIFI help Protocol examples can use Wi-Fi and/or Ethernet to connect to the network. Choose this option to connect with Ethernet @@ -218,7 +218,7 @@ menu "Example Connection Configuration" bool "KSZ80xx" help With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX - Ethernet Physical Layer Tranceivers (PHY). + Ethernet Physical Layer Transceivers (PHY). The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041, KSZ8051, KSZ8061, KSZ8081, KSZ8091 Goto https://www.microchip.com for more information about them. diff --git a/examples/common_components/protocol_examples_common/eth_connect.c b/examples/common_components/protocol_examples_common/eth_connect.c index 72cfa8987bda..8e89dbe28eb3 100644 --- a/examples/common_components/protocol_examples_common/eth_connect.c +++ b/examples/common_components/protocol_examples_common/eth_connect.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -13,6 +13,7 @@ #include "driver/spi_master.h" #endif // CONFIG_ETH_USE_SPI_ETHERNET #include "esp_log.h" +#include "esp_mac.h" #include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -99,8 +100,8 @@ static esp_netif_t *eth_start(void) phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; #if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); - esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; - esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; + esp32_emac_config.smi_gpio.mdc_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; + esp32_emac_config.smi_gpio.mdio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); #if CONFIG_EXAMPLE_ETH_PHY_IP101 s_phy = esp_eth_phy_new_ip101(&phy_config); @@ -153,11 +154,12 @@ static esp_netif_t *eth_start(void) ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle)); #if !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET /* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually. - 02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control. + We set the ESP_MAC_ETH mac address as the default, if you want to use ESP_MAC_EFUSE_CUSTOM mac address, please enable the + configuration: `ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC` */ - ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) { - 0x02, 0x00, 0x00, 0x12, 0x34, 0x56 - })); + uint8_t eth_mac[6] = {0}; + ESP_ERROR_CHECK(esp_read_mac(eth_mac, ESP_MAC_ETH)); + ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, eth_mac)); #endif // combine driver with netif s_eth_glue = esp_eth_new_netif_glue(s_eth_handle); diff --git a/examples/common_components/protocol_examples_common/include/protocol_examples_common.h b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h index fc2e54cd3529..b23f452acc77 100644 --- a/examples/common_components/protocol_examples_common/include/protocol_examples_common.h +++ b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h @@ -35,6 +35,38 @@ extern "C" { #define EXAMPLE_NETIF_DESC_PPP "example_netif_ppp" #endif +#if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST +#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN +#elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL +#define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN +#endif + +#if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL +#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL +#elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY +#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY +#endif + +#if CONFIG_EXAMPLE_WIFI_AUTH_OPEN +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN +#elif CONFIG_EXAMPLE_WIFI_AUTH_WEP +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK +#endif + /* Example default interface, prefer the ethernet one if running in example-test (CI) configuration */ #if CONFIG_EXAMPLE_CONNECT_ETHERNET #define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH) diff --git a/examples/common_components/protocol_examples_common/wifi_connect.c b/examples/common_components/protocol_examples_common/wifi_connect.c index e4e146868879..ed95bccb2feb 100644 --- a/examples/common_components/protocol_examples_common/wifi_connect.c +++ b/examples/common_components/protocol_examples_common/wifi_connect.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -26,38 +26,6 @@ static SemaphoreHandle_t s_semph_get_ip_addrs = NULL; static SemaphoreHandle_t s_semph_get_ip6_addrs = NULL; #endif -#if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST -#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN -#elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL -#define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN -#endif - -#if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL -#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL -#elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY -#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY -#endif - -#if CONFIG_EXAMPLE_WIFI_AUTH_OPEN -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN -#elif CONFIG_EXAMPLE_WIFI_AUTH_WEP -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK -#endif - static int s_retry_num = 0; static void example_handler_on_wifi_disconnect(void *arg, esp_event_base_t event_base, @@ -75,6 +43,7 @@ static void example_handler_on_wifi_disconnect(void *arg, esp_event_base_t event xSemaphoreGive(s_semph_get_ip6_addrs); } #endif + example_wifi_sta_do_disconnect(); return; } ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect..."); diff --git a/examples/ethernet/basic/components/ethernet_init/CMakeLists.txt b/examples/ethernet/basic/components/ethernet_init/CMakeLists.txt index 382893ed87ff..ef299cdfd4c3 100644 --- a/examples/ethernet/basic/components/ethernet_init/CMakeLists.txt +++ b/examples/ethernet/basic/components/ethernet_init/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "ethernet_init.c" - PRIV_REQUIRES driver esp_eth + PRIV_REQUIRES esp_driver_gpio esp_eth INCLUDE_DIRS ".") diff --git a/examples/ethernet/basic/components/ethernet_init/ethernet_init.c b/examples/ethernet/basic/components/ethernet_init/ethernet_init.c index 61adee9ee219..b34304e4a372 100644 --- a/examples/ethernet/basic/components/ethernet_init/ethernet_init.c +++ b/examples/ethernet/basic/components/ethernet_init/ethernet_init.c @@ -9,11 +9,9 @@ #include "esp_mac.h" #include "driver/gpio.h" #include "sdkconfig.h" -#if CONFIG_ETH_USE_SPI_ETHERNET +#if CONFIG_EXAMPLE_USE_SPI_ETHERNET #include "driver/spi_master.h" -#endif // CONFIG_ETH_USE_SPI_ETHERNET - -static const char *TAG = "example_eth_init"; +#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET #if CONFIG_EXAMPLE_SPI_ETHERNETS_NUM #define SPI_ETHERNETS_NUM CONFIG_EXAMPLE_SPI_ETHERNETS_NUM @@ -45,6 +43,12 @@ typedef struct { uint8_t *mac_addr; }spi_eth_module_config_t; +static const char *TAG = "example_eth_init"; +#if CONFIG_EXAMPLE_USE_SPI_ETHERNET +static bool gpio_isr_svc_init_by_eth = false; // indicates that we initialized the GPIO ISR service +#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET + + #if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET /** * @brief Internal ESP32 Ethernet initialization @@ -69,8 +73,8 @@ static esp_eth_handle_t eth_init_internal(esp_eth_mac_t **mac_out, esp_eth_phy_t // Init vendor specific MAC config to default eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); // Update vendor specific MAC config based on board configuration - esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; - esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; + esp32_emac_config.smi_gpio.mdc_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; + esp32_emac_config.smi_gpio.mdio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; #if CONFIG_EXAMPLE_USE_SPI_ETHERNET // The DMA is shared resource between EMAC and the SPI. Therefore, adjust // EMAC DMA burst length when SPI Ethernet is used along with EMAC. @@ -128,17 +132,19 @@ static esp_err_t spi_bus_init(void) { esp_err_t ret = ESP_OK; +#if (CONFIG_EXAMPLE_ETH_SPI_INT0_GPIO >= 0) || (CONFIG_EXAMPLE_ETH_SPI_INT1_GPIO > 0) // Install GPIO ISR handler to be able to service SPI Eth modules interrupts ret = gpio_install_isr_service(0); - if (ret != ESP_OK) { - if (ret == ESP_ERR_INVALID_STATE) { - ESP_LOGW(TAG, "GPIO ISR handler has been already installed"); - ret = ESP_OK; // ISR handler has been already installed so no issues - } else { - ESP_LOGE(TAG, "GPIO ISR handler install failed"); - goto err; - } + if (ret == ESP_OK) { + gpio_isr_svc_init_by_eth = true; + } else if (ret == ESP_ERR_INVALID_STATE) { + ESP_LOGW(TAG, "GPIO ISR handler has been already installed"); + ret = ESP_OK; // ISR handler has been already installed so no issues + } else { + ESP_LOGE(TAG, "GPIO ISR handler install failed"); + goto err; } +#endif // Init SPI bus spi_bus_config_t buscfg = { @@ -283,7 +289,7 @@ esp_err_t example_eth_init(esp_eth_handle_t *eth_handles_out[], uint8_t *eth_cnt ESP_GOTO_ON_FALSE(eth_handles[eth_cnt], ESP_FAIL, err, TAG, "SPI Ethernet init failed"); eth_cnt++; } -#endif // CONFIG_ETH_USE_SPI_ETHERNET +#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET #else ESP_LOGD(TAG, "no Ethernet device selected to init"); #endif // CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET || CONFIG_EXAMPLE_USE_SPI_ETHERNET @@ -297,3 +303,36 @@ esp_err_t example_eth_init(esp_eth_handle_t *eth_handles_out[], uint8_t *eth_cnt return ret; #endif } + +esp_err_t example_eth_deinit(esp_eth_handle_t *eth_handles, uint8_t eth_cnt) +{ + ESP_RETURN_ON_FALSE(eth_handles != NULL, ESP_ERR_INVALID_ARG, TAG, "array of Ethernet handles cannot be NULL"); + for (int i = 0; i < eth_cnt; i++) { + esp_eth_mac_t *mac = NULL; + esp_eth_phy_t *phy = NULL; + if (eth_handles[i] != NULL) { + esp_eth_get_mac_instance(eth_handles[i], &mac); + esp_eth_get_phy_instance(eth_handles[i], &phy); + ESP_RETURN_ON_ERROR(esp_eth_driver_uninstall(eth_handles[i]), TAG, "Ethernet %p uninstall failed", eth_handles[i]); + } + if (mac != NULL) { + mac->del(mac); + } + if (phy != NULL) { + phy->del(phy); + } + } +#if CONFIG_EXAMPLE_USE_SPI_ETHERNET + spi_bus_free(CONFIG_EXAMPLE_ETH_SPI_HOST); +#if (CONFIG_EXAMPLE_ETH_SPI_INT0_GPIO >= 0) || (CONFIG_EXAMPLE_ETH_SPI_INT1_GPIO > 0) + // We installed the GPIO ISR service so let's uninstall it too. + // BE CAREFUL HERE though since the service might be used by other functionality! + if (gpio_isr_svc_init_by_eth) { + ESP_LOGW(TAG, "uninstalling GPIO ISR service!"); + gpio_uninstall_isr_service(); + } +#endif +#endif //CONFIG_EXAMPLE_USE_SPI_ETHERNET + free(eth_handles); + return ESP_OK; +} diff --git a/examples/ethernet/basic/components/ethernet_init/ethernet_init.h b/examples/ethernet/basic/components/ethernet_init/ethernet_init.h index 8fa5df6106c7..6ebec50aee6c 100644 --- a/examples/ethernet/basic/components/ethernet_init/ethernet_init.h +++ b/examples/ethernet/basic/components/ethernet_init/ethernet_init.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -24,6 +24,18 @@ extern "C" { */ esp_err_t example_eth_init(esp_eth_handle_t *eth_handles_out[], uint8_t *eth_cnt_out); +/** + * @brief De-initialize array of Ethernet drivers + * @note All Ethernet drivers in the array must be stopped prior calling this function. + * + * @param[in] eth_handles array of Ethernet drivers to be de-initialized + * @param[in] eth_cnt number of Ethernets drivers to be de-initialized + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG when passed invalid pointers + */ +esp_err_t example_eth_deinit(esp_eth_handle_t *eth_handles, uint8_t eth_cnt); + #ifdef __cplusplus } #endif diff --git a/examples/ethernet/basic/main/Kconfig.projbuild b/examples/ethernet/basic/main/Kconfig.projbuild new file mode 100644 index 000000000000..27a8f9d74223 --- /dev/null +++ b/examples/ethernet/basic/main/Kconfig.projbuild @@ -0,0 +1,9 @@ +menu "Example Configuration" + config EXAMPLE_ETH_DEINIT_AFTER_S + int "Stop and deinit Ethernet after elapsing number of secs" + range -1 300 + default -1 + help + This option is for demonstration purposes only to demonstrate deinitialization of the Ethernet driver. + Set to -1 to not deinitialize. +endmenu diff --git a/examples/ethernet/basic/main/ethernet_example_main.c b/examples/ethernet/basic/main/ethernet_example_main.c index b3033e3329d0..71f99a168772 100644 --- a/examples/ethernet/basic/main/ethernet_example_main.c +++ b/examples/ethernet/basic/main/ethernet_example_main.c @@ -75,14 +75,18 @@ void app_main(void) // Create default event loop that running in background ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_t *eth_netifs[eth_port_cnt]; + esp_eth_netif_glue_handle_t eth_netif_glues[eth_port_cnt]; + // Create instance(s) of esp-netif for Ethernet(s) if (eth_port_cnt == 1) { // Use ESP_NETIF_DEFAULT_ETH when just one Ethernet interface is used and you don't need to modify // default esp-netif configuration parameters. esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); - esp_netif_t *eth_netif = esp_netif_new(&cfg); + eth_netifs[0] = esp_netif_new(&cfg); + eth_netif_glues[0] = esp_eth_new_netif_glue(eth_handles[0]); // Attach Ethernet driver to TCP/IP stack - ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[0]))); + ESP_ERROR_CHECK(esp_netif_attach(eth_netifs[0], eth_netif_glues[0])); } else { // Use ESP_NETIF_INHERENT_DEFAULT_ETH when multiple Ethernet interfaces are used and so you need to modify // esp-netif configuration parameters for each interface (name, priority, etc.). @@ -101,10 +105,10 @@ void app_main(void) esp_netif_config.if_key = if_key_str; esp_netif_config.if_desc = if_desc_str; esp_netif_config.route_prio -= i*5; - esp_netif_t *eth_netif = esp_netif_new(&cfg_spi); - + eth_netifs[i] = esp_netif_new(&cfg_spi); + eth_netif_glues[i] = esp_eth_new_netif_glue(eth_handles[0]); // Attach Ethernet driver to TCP/IP stack - ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[i]))); + ESP_ERROR_CHECK(esp_netif_attach(eth_netifs[i], eth_netif_glues[i])); } } @@ -116,4 +120,21 @@ void app_main(void) for (int i = 0; i < eth_port_cnt; i++) { ESP_ERROR_CHECK(esp_eth_start(eth_handles[i])); } + +#if CONFIG_EXAMPLE_ETH_DEINIT_AFTER_S >= 0 + // For demonstration purposes, wait and then deinit Ethernet network + vTaskDelay(pdMS_TO_TICKS(CONFIG_EXAMPLE_ETH_DEINIT_AFTER_S * 1000)); + ESP_LOGI(TAG, "stop and deinitialize Ethernet network..."); + // Stop Ethernet driver state machine and destroy netif + for (int i = 0; i < eth_port_cnt; i++) { + ESP_ERROR_CHECK(esp_eth_stop(eth_handles[i])); + ESP_ERROR_CHECK(esp_eth_del_netif_glue(eth_netif_glues[i])); + esp_netif_destroy(eth_netifs[i]); + } + esp_netif_deinit(); + ESP_ERROR_CHECK(example_eth_deinit(eth_handles, eth_port_cnt)); + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler)); + ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler)); + ESP_ERROR_CHECK(esp_event_loop_delete_default()); +#endif // EXAMPLE_ETH_DEINIT_AFTER_S > 0 } diff --git a/examples/get-started/blink/sdkconfig.defaults esp32h2 b/examples/get-started/blink/sdkconfig.defaults.esp32h2 similarity index 100% rename from examples/get-started/blink/sdkconfig.defaults esp32h2 rename to examples/get-started/blink/sdkconfig.defaults.esp32h2 diff --git a/examples/mesh/ip_internal_network/sdkconfig.defaults b/examples/mesh/ip_internal_network/sdkconfig.defaults index 95bb5df8328a..81c7be5f664e 100644 --- a/examples/mesh/ip_internal_network/sdkconfig.defaults +++ b/examples/mesh/ip_internal_network/sdkconfig.defaults @@ -9,3 +9,4 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y diff --git a/examples/openthread/ot_br/main/esp_ot_br.c b/examples/openthread/ot_br/main/esp_ot_br.c index d29718c4aeb9..bf887803a939 100644 --- a/examples/openthread/ot_br/main/esp_ot_br.c +++ b/examples/openthread/ot_br/main/esp_ot_br.c @@ -73,29 +73,15 @@ static void ot_task_worker(void *aContext) // Initialize the OpenThread stack ESP_ERROR_CHECK(esp_openthread_init(&config)); - - // Initialize border routing features - esp_openthread_lock_acquire(portMAX_DELAY); -#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE - ESP_ERROR_CHECK(esp_openthread_state_indicator_init(esp_openthread_get_instance())); -#endif ESP_ERROR_CHECK(esp_netif_attach(openthread_netif, esp_openthread_netif_glue_init(&config))); - + esp_openthread_lock_acquire(portMAX_DELAY); (void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL); esp_openthread_cli_init(); - -#if CONFIG_OPENTHREAD_BR_AUTO_START - ESP_ERROR_CHECK(esp_openthread_border_router_init()); - otOperationalDatasetTlvs dataset; - otError error = otDatasetGetActiveTlvs(esp_openthread_get_instance(), &dataset); - ESP_ERROR_CHECK(esp_openthread_auto_start((error == OT_ERROR_NONE) ? &dataset : NULL)); -#endif // CONFIG_OPENTHREAD_BR_AUTO_START - esp_cli_custom_command_init(); + esp_openthread_cli_create_task(); esp_openthread_lock_release(); // Run the main loop - esp_openthread_cli_create_task(); esp_openthread_launch_mainloop(); // Clean up @@ -105,36 +91,15 @@ static void ot_task_worker(void *aContext) vTaskDelete(NULL); } -void app_main(void) +void ot_br_init(void *ctx) { - // Used eventfds: - // * netif - // * task queue - // * border router - esp_vfs_eventfd_config_t eventfd_config = { -#if CONFIG_OPENTHREAD_RADIO_NATIVE || CONFIG_OPENTHREAD_RADIO_SPINEL_SPI - // * radio driver (A native radio device needs a eventfd for radio driver.) - // * SpiSpinelInterface (The Spi Spinel Interface needs a eventfd.) - // The above will not exist at the same time. - .max_fds = 4, -#else - .max_fds = 3, -#endif - }; - ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config)); - - ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - #if CONFIG_EXAMPLE_CONNECT_WIFI #if CONFIG_OPENTHREAD_BR_AUTO_START ESP_ERROR_CHECK(example_connect()); + ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MAX_MODEM)); #if CONFIG_ESP_COEX_SW_COEXIST_ENABLE && CONFIG_OPENTHREAD_RADIO_NATIVE - ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MIN_MODEM)); ESP_ERROR_CHECK(esp_coex_wifi_i154_enable()); #else - ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); #if CONFIG_EXTERNAL_COEX_ENABLE ot_br_external_coexist_init(); @@ -155,5 +120,44 @@ void app_main(void) ESP_ERROR_CHECK(mdns_init()); ESP_ERROR_CHECK(mdns_hostname_set("esp-ot-br")); - xTaskCreate(ot_task_worker, "ot_br_main", 20480, xTaskGetCurrentTaskHandle(), 5, NULL); + + // Initialize border routing features + esp_openthread_lock_acquire(portMAX_DELAY); +#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE + ESP_ERROR_CHECK(esp_openthread_state_indicator_init(esp_openthread_get_instance())); +#endif + +#if CONFIG_OPENTHREAD_BR_AUTO_START + ESP_ERROR_CHECK(esp_openthread_border_router_init()); + otOperationalDatasetTlvs dataset; + otError error = otDatasetGetActiveTlvs(esp_openthread_get_instance(), &dataset); + ESP_ERROR_CHECK(esp_openthread_auto_start((error == OT_ERROR_NONE) ? &dataset : NULL)); +#endif // CONFIG_OPENTHREAD_BR_AUTO_START + + esp_openthread_lock_release(); + vTaskDelete(NULL); +} + +void app_main(void) +{ + // Used eventfds: + // * netif + // * task queue + // * border router + esp_vfs_eventfd_config_t eventfd_config = { +#if CONFIG_OPENTHREAD_RADIO_NATIVE || CONFIG_OPENTHREAD_RADIO_SPINEL_SPI + // * radio driver (A native radio device needs a eventfd for radio driver.) + // * SpiSpinelInterface (The Spi Spinel Interface needs a eventfd.) + // The above will not exist at the same time. + .max_fds = 4, +#else + .max_fds = 3, +#endif + }; + ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config)); + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + xTaskCreate(ot_task_worker, "ot_br_main", 8192, xTaskGetCurrentTaskHandle(), 5, NULL); + xTaskCreate(ot_br_init, "ot_br_init", 6144, NULL, 4, NULL); } diff --git a/examples/openthread/ot_br/main/idf_component.yml b/examples/openthread/ot_br/main/idf_component.yml index 10a25935ff83..519cf7f89d2a 100644 --- a/examples/openthread/ot_br/main/idf_component.yml +++ b/examples/openthread/ot_br/main/idf_component.yml @@ -1,7 +1,7 @@ ## IDF Component Manager Manifest File dependencies: espressif/esp_ot_cli_extension: - version: "~1.0.0" + version: "~1.1.0" espressif/mdns: "^1.0.3" ## Required IDF version idf: @@ -10,5 +10,3 @@ dependencies: path: ${IDF_PATH}/examples/common_components/protocol_examples_common ot_led: path: ${IDF_PATH}/examples/openthread/ot_common_components/ot_led - espressif/iperf: - version: "~0.1.1" diff --git a/examples/openthread/ot_br/sdkconfig.defaults b/examples/openthread/ot_br/sdkconfig.defaults index 6620bfa46b18..619ab0f7e78d 100644 --- a/examples/openthread/ot_br/sdkconfig.defaults +++ b/examples/openthread/ot_br/sdkconfig.defaults @@ -31,7 +31,7 @@ CONFIG_OPENTHREAD_RADIO_SPINEL_UART=y # lwIP # CONFIG_LWIP_IPV6_FORWARD=y -CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 +CONFIG_LWIP_IPV6_NUM_ADDRESSES=12 CONFIG_LWIP_MULTICAST_PING=y CONFIG_LWIP_NETIF_STATUS_CALLBACK=y CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y diff --git a/examples/openthread/ot_cli/main/idf_component.yml b/examples/openthread/ot_cli/main/idf_component.yml index 6b1234251fb5..3f1f6778d275 100644 --- a/examples/openthread/ot_cli/main/idf_component.yml +++ b/examples/openthread/ot_cli/main/idf_component.yml @@ -1,10 +1,8 @@ ## IDF Component Manager Manifest File dependencies: espressif/esp_ot_cli_extension: - version: "~1.0.0" + version: "~1.1.0" idf: version: ">=4.1.0" ot_led: path: ${IDF_PATH}/examples/openthread/ot_common_components/ot_led - espressif/iperf: - version: "~0.1.1" diff --git a/examples/openthread/ot_rcp/sdkconfig.defaults b/examples/openthread/ot_rcp/sdkconfig.defaults index 002c6f9f3056..914395913458 100644 --- a/examples/openthread/ot_rcp/sdkconfig.defaults +++ b/examples/openthread/ot_rcp/sdkconfig.defaults @@ -8,6 +8,11 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_SW_COEXIST_ENABLE=n + # # OpenThread # diff --git a/examples/openthread/pytest_otbr.py b/examples/openthread/pytest_otbr.py index c307adc1c711..fbadbf684beb 100644 --- a/examples/openthread/pytest_otbr.py +++ b/examples/openthread/pytest_otbr.py @@ -18,7 +18,7 @@ # This file contains the test scripts for Thread: # Case 1: Thread network formation and attaching -# A Thread Border Router forms a Thread network, Thread devices attache to it, then test ping connection between them. +# A Thread Border Router forms a Thread network, Thread devices attach to it, then test ping connection between them. # Case 2: Bidirectional IPv6 connectivity # Test IPv6 ping connection between Thread device and Linux Host (via Thread Border Router). @@ -29,10 +29,10 @@ # Case 4: Multicast forwarding from Thread to Wi-Fi network # Linux Host joins the multicast group, test group communication from Thread to Wi-Fi network. -# Case 5: discover Serice published by Thread device +# Case 5: discover Service published by Thread device # Thread device publishes the service, Linux Host discovers the service on Wi-Fi network. -# Case 6: discover Serice published by W-Fi device +# Case 6: discover Service published by W-Fi device # Linux Host device publishes the service on Wi-Fi network, Thread device discovers the service. # Case 7: ICMP communication via NAT64 @@ -728,7 +728,7 @@ def test_br_meshcop(Init_interface:bool, Init_avahi:bool, dut: Tuple[IdfDut, Idf assert 'hostname = [esp-ot-br.local]' in str(output_str) assert ('address = [' + ipv4_address + ']') in str(output_str) assert 'dn=DefaultDomain' in str(output_str) - assert 'tv=1.3.0' in str(output_str) + assert 'tv=1.4.0' in str(output_str) assert ('nn=' + networkname) in str(output_str) assert 'mn=BorderRouter' in str(output_str) assert 'vn=OpenThread' in str(output_str) diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 174a6caafd42..e99615502ae9 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -10,11 +10,19 @@ examples/peripherals/adc/continuous_read: disable: - if: SOC_ADC_DMA_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: lack of runners, TODO IDF-9573 <<: *adc_dependencies examples/peripherals/adc/oneshot_read: disable: - if: SOC_ADC_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: lack of runner, TODO IDF-9573 <<: *adc_dependencies examples/peripherals/analog_comparator: @@ -24,6 +32,13 @@ examples/peripherals/analog_comparator: - esp_driver_gpio - esp_driver_ana_cmpr +examples/peripherals/camera/camera_dsi: + disable: + - if: SOC_MIPI_CSI_SUPPORTED != 1 or SOC_MIPI_DSI_SUPPORTED != 1 + depends_components: + - esp_lcd + - esp_driver_cam + examples/peripherals/dac: disable: - if: SOC_DAC_SUPPORTED != 1 @@ -39,10 +54,6 @@ examples/peripherals/dac/dac_cosine_wave: - esp_driver_dac examples/peripherals/gpio: - disable: - - if: IDF_TARGET == "esp32c5" - temporary: true - reason: GPIO is not supported on ESP32-C5 # TODO: [ESP32C5] IDF-8717 depends_components: - esp_driver_gpio @@ -118,11 +129,11 @@ examples/peripherals/i2s/i2s_recorder: examples/peripherals/isp/auto_focus: disable: - - if: INCLUDE_DEFAULT == 1 - temporary: true - reason: disable build temporarily # TODO: IDF-8895 + - if: SOC_MIPI_CSI_SUPPORTED != 1 or SOC_MIPI_DSI_SUPPORTED != 1 or SOC_ISP_SUPPORTED != 1 depends_components: - esp_driver_isp + - esp_driver_cam + - esp_lcd examples/peripherals/jpeg/jpeg_decode: disable: @@ -179,12 +190,18 @@ examples/peripherals/lcd/tjpgd: examples/peripherals/ledc: disable: - if: SOC_LEDC_SUPPORTED != 1 + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: build failed. track in IDFCI-2204 depends_components: - esp_driver_ledc examples/peripherals/ledc/ledc_gamma_curve_fade: disable: - if: SOC_LEDC_SUPPORTED != 1 or SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED != 1 + - if: IDF_TARGET == "esp32c5" + temporary: true + reason: build failed. track in IDFCI-22041 depends_components: - esp_driver_ledc @@ -254,9 +271,11 @@ examples/peripherals/parlio: examples/peripherals/parlio/parlio_rx: disable: - - if: SOC_PARLIO_SUPPORTED != 1 or IDF_TARGET == "esp32p4" + - if: SOC_PARLIO_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET == "esp32p4" temporary: true - reason: not support esp32p4 yet (IDF-7471) + reason: lack of runner depends_components: - esp_driver_parlio @@ -294,12 +313,14 @@ examples/peripherals/rmt/ir_nec_transceiver: examples/peripherals/rmt/musical_buzzer: disable: + - if: SOC_RMT_SUPPORTED != 1 - if: SOC_RMT_SUPPORT_TX_LOOP_COUNT != 1 depends_components: - esp_driver_rmt examples/peripherals/rmt/stepper_motor: disable: + - if: SOC_RMT_SUPPORTED != 1 - if: SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP != 1 depends_components: - esp_driver_rmt @@ -412,6 +433,16 @@ examples/peripherals/touch_sensor/touch_sensor_v2: disable: - if: SOC_TOUCH_SENSOR_VERSION != 2 +examples/peripherals/touch_sensor/touch_sensor_v3: + disable: + - if: SOC_TOUCH_SENSOR_VERSION != 3 + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: the runners do not support the pins for touch sensor + depends_components: + - esp_driver_touch_sens + examples/peripherals/twai/twai_alert_and_recovery: disable: - if: SOC_TWAI_SUPPORTED != 1 diff --git a/examples/peripherals/adc/continuous_read/README.md b/examples/peripherals/adc/continuous_read/README.md index 94ecfd9889b1..e02022f3c10e 100644 --- a/examples/peripherals/adc/continuous_read/README.md +++ b/examples/peripherals/adc/continuous_read/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # ADC DMA Example diff --git a/examples/peripherals/adc/oneshot_read/README.md b/examples/peripherals/adc/oneshot_read/README.md index cc872ff214a6..15404c47ee1d 100644 --- a/examples/peripherals/adc/oneshot_read/README.md +++ b/examples/peripherals/adc/oneshot_read/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # ADC Single Read Example diff --git a/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py b/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py index 9d5ad5058ac5..8bb86e3c00bc 100644 --- a/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py +++ b/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded.dut import Dut diff --git a/examples/peripherals/analog_comparator/main/ana_cmpr_example_etm.c b/examples/peripherals/analog_comparator/main/ana_cmpr_example_etm.c index 46c827610cbe..f5f8c42f07aa 100644 --- a/examples/peripherals/analog_comparator/main/ana_cmpr_example_etm.c +++ b/examples/peripherals/analog_comparator/main/ana_cmpr_example_etm.c @@ -26,17 +26,19 @@ static void example_etm_bind_ana_cmpr_event_with_gpio_task(ana_cmpr_handle_t cmp .event_type = ANA_CMPR_EVENT_POS_CROSS, }; ESP_ERROR_CHECK(ana_cmpr_new_etm_event(cmpr, &evt_cfg, &cmpr_pos_evt)); - evt_cfg.event_type = GPIO_ETM_EVENT_EDGE_NEG; + evt_cfg.event_type = ANA_CMPR_EVENT_NEG_CROSS; ESP_ERROR_CHECK(ana_cmpr_new_etm_event(cmpr, &evt_cfg, &cmpr_neg_evt)); /* Allocate the GPIO set & clear tasks */ - esp_etm_task_handle_t gpio_toggle_task = NULL; - gpio_etm_task_config_t task_cfg = { - .action = GPIO_ETM_TASK_ACTION_TOG, - }; - ESP_ERROR_CHECK(gpio_new_etm_task(&task_cfg, &gpio_toggle_task)); + esp_etm_task_handle_t gpio_set_task = NULL; + esp_etm_task_handle_t gpio_clr_task = NULL; + gpio_etm_task_config_t task_cfg = {}; + task_cfg.actions[0] = GPIO_ETM_TASK_ACTION_SET; + task_cfg.actions[1] = GPIO_ETM_TASK_ACTION_CLR; + ESP_ERROR_CHECK(gpio_new_etm_task(&task_cfg, &gpio_set_task, &gpio_clr_task)); /* Add task to the monitor GPIO */ - ESP_ERROR_CHECK(gpio_etm_task_add_gpio(gpio_toggle_task, EXAMPLE_MONITOR_GPIO_NUM)); + ESP_ERROR_CHECK(gpio_etm_task_add_gpio(gpio_set_task, EXAMPLE_MONITOR_GPIO_NUM)); + ESP_ERROR_CHECK(gpio_etm_task_add_gpio(gpio_clr_task, EXAMPLE_MONITOR_GPIO_NUM)); /* Allocate the Event Task Matrix channels */ esp_etm_channel_handle_t etm_pos_handle; @@ -45,8 +47,8 @@ static void example_etm_bind_ana_cmpr_event_with_gpio_task(ana_cmpr_handle_t cmp ESP_ERROR_CHECK(esp_etm_new_channel(&etm_cfg, &etm_pos_handle)); ESP_ERROR_CHECK(esp_etm_new_channel(&etm_cfg, &etm_neg_handle)); /* Bind the events and tasks */ - ESP_ERROR_CHECK(esp_etm_channel_connect(etm_pos_handle, cmpr_pos_evt, gpio_toggle_task)); - ESP_ERROR_CHECK(esp_etm_channel_connect(etm_neg_handle, cmpr_neg_evt, gpio_toggle_task)); + ESP_ERROR_CHECK(esp_etm_channel_connect(etm_pos_handle, cmpr_pos_evt, gpio_set_task)); + ESP_ERROR_CHECK(esp_etm_channel_connect(etm_neg_handle, cmpr_neg_evt, gpio_clr_task)); /* Enable the ETM channels */ ESP_ERROR_CHECK(esp_etm_channel_enable(etm_pos_handle)); ESP_ERROR_CHECK(esp_etm_channel_enable(etm_neg_handle)); diff --git a/examples/peripherals/camera/camera_dsi/CMakeLists.txt b/examples/peripherals/camera/camera_dsi/CMakeLists.txt new file mode 100644 index 000000000000..69a158b554a2 --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(camera_dsi) diff --git a/examples/peripherals/camera/camera_dsi/README.md b/examples/peripherals/camera/camera_dsi/README.md new file mode 100644 index 000000000000..c078a675f319 --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/README.md @@ -0,0 +1,139 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | + + +# Camera display via DSI example + +## Overview + +This example demonstrates how to use the esp_driver_cam component to capture camera sensor signals and display it via DSI interface. + +## Usage + +The subsections below give only absolutely necessary information. For full steps to configure ESP-IDF and use it to build and run projects, see [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started). + + +### Hardware Required + +This example requires: + +- OV5647 camera sensor +- ILI9881C LCD screen +- ESP32P4 devkit + + + GND GND + ┌────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ ┌───────────────┴─────────────┴──────────────────┐ │ + │ │ │ ┌──────────┴───────────┐ + │ │ │ DSI DATA 1P │ │ + │ │ ├───────────────────────────┤ │ + ┌───────────┴─────────┐ CSI DATA 1P │ │ │ │ + │ ├──────────────────────┤ │ DSI DATA 1N │ │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI DATA 1N │ ESP32-P4 │ │ │ + │ OV5647 ├──────────────────────┤ │ DSI CLK N │ ILI9881C │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI CLK N │ │ │ │ + │ ├──────────────────────┤ │ DSI CLK P │ │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI CLK P │ │ │ │ + │ ├──────────────────────┤ │ DSI DATA 0P │ │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI DATA 0P │ │ │ │ + │ ├──────────────────────┤ │ DSI DATA 0N │ │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI DATA 0N │ │ │ │ + │ ├──────────────────────┤ │ └──────────────────────┘ + │ │ │ │ + └───────┬──┬──────────┘ │ │ + │ │ I2C SCL │ │ + │ └─────────────────────────────────┤ │ + │ I2C SDA │ │ + └────────────────────────────────────┤ │ + └────────────────────────────────────────────────┘ + + +### Set Chip Target + +First of all, your target must be supported by both: + +- **By your ESP-IDF version**: For the full list of supported targets, run: + ``` + idf.py --list-targets + ``` +- **By this example**: For the full list of supported targets, refer to the supported targets table at the top of this README. + +After you make sure that your target is supported, go to your example project directory and [set the chip target](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/tools/idf-py.html#select-the-target-chip-set-target): + +``` +idf.py set-target +``` + +For example, to set esp32-P4 as the chip target, run: + +``` +idf.py set-target esp32p4 +``` + + +### Configure the Project + +For information about Kconfig options, see [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) > _Name of relevant section(s)_. + +To conveniently check or modify Kconfig options for this example in a project configuration menu, run: + +``` +idf.py menuconfig +``` + +``` +Set CONFIG_CAMERA_OV5647 to y +``` + + +### Build and Flash + +Execute the following command to build the project, flash it to your development board, and run the monitor tool to view the serial output: + +``` +idf.py build flash monitor +``` + +This command can be reduced to `idf.py flash monitor`. + +If the above command fails, check the log on the serial monitor which usually provides information on the possible cause of the issue. + +To exit the serial monitor, use `Ctrl` + `]`. + + +## Example Output + +If you see the following console output, your example should be running correctly: + +``` +I (1085) main_task: Calling app_main() +I (1095) ili9881c: ID1: 0x98, ID2: 0x81, ID3: 0x5c +I (1125) gpio: GPIO[31]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (1125) gpio: GPIO[34]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (1295) ov5647: Detected Camera sensor PID=0x5647 with index 0 +I (1305) cam_dsi: fmt[0].name:MIPI_2lane_24Minput_RAW8_800x1280_50fps +I (1305) cam_dsi: fmt[1].name:MIPI_2lane_24Minput_RAW8_800x640_50fps +I (1315) cam_dsi: fmt[2].name:MIPI_2lane_24Minput_RAW8_800x800_50fps +I (1355) cam_dsi: Format in use:MIPI_2lane_24Minput_RAW8_800x640_50fps +``` + + +## Reference + +- Link to the ESP-IDF feature's API reference, for example [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/camera_driver.html) +- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started) +- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options) diff --git a/examples/peripherals/camera/camera_dsi/components/dsi_init/CMakeLists.txt b/examples/peripherals/camera/camera_dsi/components/dsi_init/CMakeLists.txt new file mode 100644 index 000000000000..f8432fc1e70e --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/components/dsi_init/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "example_dsi_init.c" + INCLUDE_DIRS "include" + REQUIRES esp_lcd + ) diff --git a/examples/peripherals/camera/camera_dsi/components/dsi_init/Kconfig.projbuild b/examples/peripherals/camera/camera_dsi/components/dsi_init/Kconfig.projbuild new file mode 100644 index 000000000000..c67e3516ad9b --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/components/dsi_init/Kconfig.projbuild @@ -0,0 +1,25 @@ +menu "Example DSI Configuration" + choice EXAMPLE_MIPI_DSI_DISP_HRES + bool "Set MIPI CSI horizontal resolution" + default EXAMPLE_MIPI_DSI_DISP_HRES_800 + + config EXAMPLE_MIPI_DSI_DISP_HRES_800 + bool "800" + endchoice + + config EXAMPLE_MIPI_DSI_DISP_HRES + int + default 800 if EXAMPLE_MIPI_DSI_DISP_HRES_800 + + choice EXAMPLE_MIPI_DSI_DISP_VRES + bool "Set MIPI CSI vertical resolution" + default EXAMPLE_MIPI_DSI_DISP_VRES_1280 + + config EXAMPLE_MIPI_DSI_DISP_VRES_1280 + bool "1280" + endchoice + + config EXAMPLE_MIPI_DSI_DISP_VRES + int + default 1280 if EXAMPLE_MIPI_DSI_DISP_VRES_1280 +endmenu diff --git a/examples/peripherals/camera/camera_dsi/components/dsi_init/example_dsi_init.c b/examples/peripherals/camera/camera_dsi/components/dsi_init/example_dsi_init.c new file mode 100644 index 000000000000..157901431944 --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/components/dsi_init/example_dsi_init.c @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_log.h" +#include "esp_lcd_mipi_dsi.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_ili9881c.h" +#include "example_dsi_init.h" +#include "example_dsi_init_config.h" + +void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer) +{ + esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL; + esp_lcd_panel_io_handle_t mipi_dbi_io = NULL; + + //---------------DSI resource allocation------------------// + esp_lcd_dsi_bus_config_t bus_config = { + .bus_id = 0, + .num_data_lanes = 2, + .phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, + .lane_bit_rate_mbps = 1000, // 1000 Mbps + }; + ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus)); + + esp_lcd_dbi_io_config_t dbi_config = { + .virtual_channel = 0, + .lcd_cmd_bits = 8, + .lcd_param_bits = 8, + }; + ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &mipi_dbi_io)); + + esp_lcd_panel_dev_config_t lcd_dev_config = { + .bits_per_pixel = 16, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, + .reset_gpio_num = -1, + }; + ESP_ERROR_CHECK(esp_lcd_new_panel_ili9881c(mipi_dbi_io, &lcd_dev_config, ili9881c_ctrl_panel)); + + esp_lcd_dpi_panel_config_t dpi_config = { + .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, + .dpi_clock_freq_mhz = 80, + .virtual_channel = 0, + .pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565, + .video_timing = { + .h_size = CONFIG_EXAMPLE_MIPI_DSI_DISP_HRES, + .v_size = CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES, + .hsync_back_porch = EXAMPLE_MIPI_DSI_IMAGE_HBP, + .hsync_pulse_width = EXAMPLE_MIPI_DSI_IMAGE_HSYNC, + .hsync_front_porch = EXAMPLE_MIPI_DSI_IMAGE_HFP, + .vsync_back_porch = EXAMPLE_MIPI_DSI_IMAGE_VBP, + .vsync_pulse_width = EXAMPLE_MIPI_DSI_IMAGE_VSYNC, + .vsync_front_porch = EXAMPLE_MIPI_DSI_IMAGE_VFP, + }, + }; + ESP_ERROR_CHECK(esp_lcd_new_panel_dpi(mipi_dsi_bus, &dpi_config, mipi_dpi_panel)); + ESP_ERROR_CHECK(esp_lcd_dpi_panel_get_frame_buffer(*mipi_dpi_panel, 1, frame_buffer)); +} + +void example_dsi_ili9881c_panel_init(esp_lcd_panel_handle_t ili9881c_ctrl_panel) +{ + //---------------DSI Panel Init------------------// + ESP_ERROR_CHECK(esp_lcd_panel_reset(ili9881c_ctrl_panel)); + ESP_ERROR_CHECK(esp_lcd_panel_init(ili9881c_ctrl_panel)); + // turn on display + ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(ili9881c_ctrl_panel, true)); +} + +void example_dpi_panel_init(esp_lcd_panel_handle_t mipi_dpi_panel) +{ + //---------------DPI Panel Init------------------// + ESP_ERROR_CHECK(esp_lcd_panel_init(mipi_dpi_panel)); +} diff --git a/examples/peripherals/camera/camera_dsi/components/dsi_init/idf_component.yml b/examples/peripherals/camera/camera_dsi/components/dsi_init/idf_component.yml new file mode 100644 index 000000000000..3d1a63b55072 --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/components/dsi_init/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + esp_lcd_ili9881c: "~0.2.0" + idf: + version: ">=5.3.0" diff --git a/examples/peripherals/camera/camera_dsi/components/dsi_init/include/example_dsi_init.h b/examples/peripherals/camera/camera_dsi/components/dsi_init/include/example_dsi_init.h new file mode 100644 index 000000000000..df04c79eb15c --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/components/dsi_init/include/example_dsi_init.h @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_lcd_mipi_dsi.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_ili9881c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief DSI init function + * + * @param[out] ili9881c_ctrl_panel ILI9881C panel handle + * @param[out] mipi_dpi_panel MIPI DPI panel handle + * @param[out] frame_buffer frame buffer + */ +void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer); + +/** + * @brief DSI ILI9881C panel init function + * + * @param[in] ili9881c_ctrl_panel ILI9881C panel handle + */ +void example_dsi_ili9881c_panel_init(esp_lcd_panel_handle_t ili9881c_ctrl_panel); + +/** + * @brief DPI panel init function + * + * @param[in] mipi_dpi_panel MIPI DPI panel handle + */ +void example_dpi_panel_init(esp_lcd_panel_handle_t mipi_dpi_panel); + +#ifdef __cplusplus +} +#endif diff --git a/examples/peripherals/camera/camera_dsi/components/dsi_init/include/example_dsi_init_config.h b/examples/peripherals/camera/camera_dsi/components/dsi_init/include/example_dsi_init_config.h new file mode 100644 index 000000000000..c804154298ad --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/components/dsi_init/include/example_dsi_init_config.h @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXAMPLE_MIPI_DSI_IMAGE_HSYNC 40 +#define EXAMPLE_MIPI_DSI_IMAGE_HBP 140 +#define EXAMPLE_MIPI_DSI_IMAGE_HFP 40 +#define EXAMPLE_MIPI_DSI_IMAGE_VSYNC 4 +#define EXAMPLE_MIPI_DSI_IMAGE_VBP 16 +#define EXAMPLE_MIPI_DSI_IMAGE_VFP 16 + +#ifdef __cplusplus +} +#endif diff --git a/examples/peripherals/camera/camera_dsi/main/CMakeLists.txt b/examples/peripherals/camera/camera_dsi/main/CMakeLists.txt new file mode 100644 index 000000000000..e760975a4816 --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "camera_dsi_main.c" + INCLUDE_DIRS "." + REQUIRES esp_mm esp_driver_isp esp_driver_cam esp_driver_i2c dsi_init + ) diff --git a/examples/peripherals/camera/camera_dsi/main/Kconfig.projbuild b/examples/peripherals/camera/camera_dsi/main/Kconfig.projbuild new file mode 100644 index 000000000000..8117f6ef7ba4 --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/main/Kconfig.projbuild @@ -0,0 +1,41 @@ +menu "Example Configuration" + config EXAMPLE_USED_LDO_CHAN_ID + int "example used LDO channel ID" + default 3 + help + Example used LDO channel ID, you may check datasheet to know more details. + + config EXAMPLE_USED_LDO_VOLTAGE_MV + int "example used LDO voltage in mV" + default 2500 + range 0 3300 + help + Example used LDO voltage, in mV + + choice EXAMPLE_MIPI_CSI_DISP_HRES + bool "Set MIPI CSI horizontal resolution" + default EXAMPLE_MIPI_CSI_HRES_800 + + config EXAMPLE_MIPI_CSI_HRES_800 + bool "800" + endchoice + + config EXAMPLE_MIPI_CSI_DISP_HRES + int + default 800 if EXAMPLE_MIPI_CSI_HRES_800 + + choice EXAMPLE_MIPI_CSI_DISP_VRES + bool "Set MIPI CSI vertical resolution" + default EXAMPLE_MIPI_CSI_VRES_640 + + config EXAMPLE_MIPI_CSI_VRES_640 + bool "640" + config EXAMPLE_MIPI_CSI_VRES_1280 + bool "1280" + endchoice + + config EXAMPLE_MIPI_CSI_DISP_VRES + int + default 640 if EXAMPLE_MIPI_CSI_VRES_640 + default 1280 if EXAMPLE_MIPI_CSI_VRES_1280 +endmenu diff --git a/examples/peripherals/camera/camera_dsi/main/camera_dsi_main.c b/examples/peripherals/camera/camera_dsi/main/camera_dsi_main.c new file mode 100644 index 000000000000..a5c5c2dcb709 --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/main/camera_dsi_main.c @@ -0,0 +1,213 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_attr.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "esp_lcd_mipi_dsi.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_ili9881c.h" +#include "esp_ldo_regulator.h" +#include "esp_cache.h" +#include "driver/i2c_master.h" +#include "driver/isp.h" +#include "esp_cam_ctlr_csi.h" +#include "esp_cam_ctlr.h" +#include "esp_sccb_intf.h" +#include "esp_sccb_i2c.h" +#include "esp_cam_sensor.h" +#include "ov5647.h" +#include "example_dsi_init.h" +#include "example_dsi_init_config.h" +#include "example_config.h" + +static const char *TAG = "cam_dsi"; + +static bool s_camera_get_new_vb(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data); +static bool s_camera_get_finished_trans(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data); + +void app_main(void) +{ + esp_err_t ret = ESP_FAIL; + esp_lcd_panel_handle_t ili9881c_ctrl_panel = NULL; + esp_lcd_panel_handle_t mipi_dpi_panel = NULL; + void *frame_buffer = NULL; + size_t frame_buffer_size = 0; + + //mipi ldo + esp_ldo_channel_handle_t ldo_mipi_phy = NULL; + esp_ldo_channel_config_t ldo_mipi_phy_config = { + .chan_id = CONFIG_EXAMPLE_USED_LDO_CHAN_ID, + .voltage_mv = CONFIG_EXAMPLE_USED_LDO_VOLTAGE_MV, + }; + ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy)); + + /** + * @background + * Sensor use RAW8 + * ISP convert to RGB565 + */ + //---------------DSI Init------------------// + example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dpi_panel, &frame_buffer); + + //---------------Necessary variable config------------------// + frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8; + + ESP_LOGD(TAG, "CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES: %d, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES: %d, bits per pixel: %d", CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES, 8); + ESP_LOGD(TAG, "frame_buffer_size: %zu", frame_buffer_size); + ESP_LOGD(TAG, "frame_buffer: %p", frame_buffer); + + esp_cam_ctlr_trans_t new_trans = { + .buffer = frame_buffer, + .buflen = frame_buffer_size, + }; + + //---------------I2C Init------------------// + i2c_master_bus_config_t i2c_bus_conf = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .sda_io_num = EXAMPLE_MIPI_SCCB_SDA_IO, + .scl_io_num = EXAMPLE_MIPI_SCCB_SCL_IO, + .i2c_port = I2C_NUM_0, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle = NULL; + ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_conf, &bus_handle)); + + //---------------SCCB Init------------------// + esp_sccb_io_handle_t ov5647_io_handle = NULL; + sccb_i2c_config_t i2c_config = { + .scl_speed_hz = EXAMPLE_MIPI_SCCB_FREQ, + .device_address = EXAMPLE_OV5647_DEV_ADDR, + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + }; + ESP_ERROR_CHECK(sccb_new_i2c_io(bus_handle, &i2c_config, &ov5647_io_handle)); + + //---------------CSI Init------------------// + esp_cam_ctlr_csi_config_t csi_config = { + .ctlr_id = 0, + .h_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, + .v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES, + .lane_bit_rate_mbps = EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS, + .input_data_color_type = CAM_CTLR_COLOR_RAW8, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, + .data_lane_num = 2, + .byte_swap_en = false, + .queue_items = 1, + }; + esp_cam_ctlr_handle_t cam_handle = NULL; + ret = esp_cam_new_csi_ctlr(&csi_config, &cam_handle); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "csi init fail[%d]", ret); + return; + } + + esp_cam_ctlr_evt_cbs_t cbs = { + .on_get_new_trans = s_camera_get_new_vb, + .on_trans_finished = s_camera_get_finished_trans, + }; + if (esp_cam_ctlr_register_event_callbacks(cam_handle, &cbs, &new_trans) != ESP_OK) { + ESP_LOGE(TAG, "ops register fail"); + return; + } + + ESP_ERROR_CHECK(esp_cam_ctlr_enable(cam_handle)); + + //---------------ISP Init------------------// + isp_proc_handle_t isp_proc = NULL; + esp_isp_processor_cfg_t isp_config = { + .clk_hz = 80 * 1000 * 1000, + .input_data_source = ISP_INPUT_DATA_SOURCE_CSI, + .input_data_color_type = ISP_COLOR_RAW8, + .output_data_color_type = ISP_COLOR_RGB565, + .has_line_start_packet = false, + .has_line_end_packet = false, + .h_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, + .v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES, + }; + ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc)); + ESP_ERROR_CHECK(esp_isp_enable(isp_proc)); + + //---------------DSI Panel Init------------------// + example_dsi_ili9881c_panel_init(ili9881c_ctrl_panel); + + //init to all white + memset(frame_buffer, 0xFF, frame_buffer_size); + esp_cache_msync((void *)frame_buffer, frame_buffer_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + + if (esp_cam_ctlr_start(cam_handle) != ESP_OK) { + ESP_LOGE(TAG, "Driver start fail"); + return; + } + + esp_cam_sensor_config_t cam_config = { + .sccb_handle = ov5647_io_handle, + .reset_pin = -1, + .pwdn_pin = -1, + .xclk_pin = -1, + .sensor_port = ESP_CAM_SENSOR_MIPI_CSI, + }; + + esp_cam_sensor_device_t *cam = ov5647_detect(&cam_config); + if (!cam) { + ESP_LOGE(TAG, "failed to detect 5647"); + return; + } + + esp_cam_sensor_format_array_t cam_fmt_array = {0}; + esp_cam_sensor_query_format(cam, &cam_fmt_array); + const esp_cam_sensor_format_t *parray = cam_fmt_array.format_array; + for (int i = 0; i < cam_fmt_array.count; i++) { + ESP_LOGI(TAG, "fmt[%d].name:%s", i, parray[i].name); + } + + esp_cam_sensor_format_t *cam_cur_fmt = NULL; + for (int i = 0; i < cam_fmt_array.count; i++) { +#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640 + if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x640_50fps")) { + cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name); + } +#else + if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x1280_50fps")) { + cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name); + } +#endif + } + + ret = esp_cam_sensor_set_format(cam, (const esp_cam_sensor_format_t *) cam_cur_fmt); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Format set fail"); + } else { + ESP_LOGI(TAG, "Format in use:%s", cam_cur_fmt->name); + } + int enable_flag = 1; + // Set sensor output stream + ret = esp_cam_sensor_ioctl(cam, ESP_CAM_SENSOR_IOC_S_STREAM, &enable_flag); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Start stream fail"); + } + + example_dpi_panel_init(mipi_dpi_panel); + + while (1) { + ESP_ERROR_CHECK(esp_cam_ctlr_receive(cam_handle, &new_trans, ESP_CAM_CTLR_MAX_DELAY)); + } +} + +static bool s_camera_get_new_vb(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data) +{ + esp_cam_ctlr_trans_t new_trans = *(esp_cam_ctlr_trans_t *)user_data; + trans->buffer = new_trans.buffer; + trans->buflen = new_trans.buflen; + + return false; +} + +static bool s_camera_get_finished_trans(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data) +{ + return false; +} diff --git a/examples/peripherals/camera/camera_dsi/main/example_config.h b/examples/peripherals/camera/camera_dsi/main/example_config.h new file mode 100644 index 000000000000..c72a6b02ea09 --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/main/example_config.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXAMPLE_RGB565_BITS_PER_PIXEL 16 +#define EXAMPLE_MIPI_SCCB_FREQ (100000) +#define EXAMPLE_MIPI_SCCB_SCL_IO (8) +#define EXAMPLE_MIPI_SCCB_SDA_IO (7) +#define EXAMPLE_MIPI_IDI_CLOCK_RATE (50000000) +#define EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS 200 //line_rate = pclk * 4 + +#define EXAMPLE_OV5647_DEV_ADDR 0x36 +#ifdef __cplusplus +} +#endif diff --git a/examples/peripherals/camera/camera_dsi/main/idf_component.yml b/examples/peripherals/camera/camera_dsi/main/idf_component.yml new file mode 100644 index 000000000000..ebecc56255c2 --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/main/idf_component.yml @@ -0,0 +1,7 @@ +dependencies: + espressif/esp_cam_sensor: "^0.2.2" + espressif/esp_lcd_ili9881c: "~0.2.0" + idf: + version: ">=5.3.0" + dsi_init: + path: ${IDF_PATH}/examples/peripherals/camera/camera_dsi/components/dsi_init diff --git a/examples/peripherals/camera/camera_dsi/pytest_camera_dsi.py b/examples/peripherals/camera/camera_dsi/pytest_camera_dsi.py new file mode 100644 index 000000000000..9c234e62174c --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/pytest_camera_dsi.py @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_camera_dsi(dut: Dut) -> None: + dut.expect_exact('Calling app_main()') diff --git a/examples/peripherals/camera/camera_dsi/sdkconfig.defaults b/examples/peripherals/camera/camera_dsi/sdkconfig.defaults new file mode 100644 index 000000000000..7c4a6989325b --- /dev/null +++ b/examples/peripherals/camera/camera_dsi/sdkconfig.defaults @@ -0,0 +1,4 @@ +CONFIG_SPIRAM=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM_SPEED_200M=y +CONFIG_CAMERA_OV5647=y diff --git a/examples/peripherals/gpio/generic_gpio/README.md b/examples/peripherals/gpio/generic_gpio/README.md index 5b01af050832..e6ac34b725c7 100644 --- a/examples/peripherals/gpio/generic_gpio/README.md +++ b/examples/peripherals/gpio/generic_gpio/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Example: GPIO diff --git a/examples/peripherals/isp/auto_focus/CMakeLists.txt b/examples/peripherals/isp/auto_focus/CMakeLists.txt new file mode 100644 index 000000000000..dd9fec70ab31 --- /dev/null +++ b/examples/peripherals/isp/auto_focus/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(isp_af_dsi) diff --git a/examples/peripherals/isp/auto_focus/README.md b/examples/peripherals/isp/auto_focus/README.md new file mode 100644 index 000000000000..3e3ba628b48d --- /dev/null +++ b/examples/peripherals/isp/auto_focus/README.md @@ -0,0 +1,141 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | + + +# Camera display via DSI example + +## Overview + +This example demonstrates how to use the ISP (image signal processor) to work with esp_driver_cam component. This example will capture camera sensor signals via CSI interface and display it via DSI interface. This example also enables the ISP AF (auto-focus) feature and ISP BF (bayer denoise) feature. + +## Usage + +The subsections below give only absolutely necessary information. For full steps to configure ESP-IDF and use it to build and run projects, see [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started). + + +### Hardware Required + +This example requires: + +- OV5647 camera sensor with VCM (Voice Coil Motor). The VCM used in this example is DW9714. +- ILI9881C LCD screen +- ESP32P4 devkit + + + GND GND + ┌────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ ┌───────────────┴─────────────┴──────────────────┐ │ + │ │ │ ┌──────────┴───────────┐ + │ │ │ DSI DATA 1P │ │ + │ │ ├───────────────────────────┤ │ + ┌───────────┴─────────┐ CSI DATA 1P │ │ │ │ + │ ├──────────────────────┤ │ DSI DATA 1N │ │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI DATA 1N │ ESP32-P4 │ │ │ + │ OV5647 ├──────────────────────┤ │ DSI CLK N │ ILI9881C │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI CLK N │ │ │ │ + │ ├──────────────────────┤ │ DSI CLK P │ │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI CLK P │ │ │ │ + │ ├──────────────────────┤ │ DSI DATA 0P │ │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI DATA 0P │ │ │ │ + │ ├──────────────────────┤ │ DSI DATA 0N │ │ + │ │ │ ├───────────────────────────┤ │ + │ │ CSI DATA 0N │ │ │ │ + │ ├──────────────────────┤ │ └──────────────────────┘ + │ │ │ │ + └───────┬──┬──────────┘ │ │ + │ │ I2C SCL │ │ + │ └─────────────────────────────────┤ │ + │ I2C SDA │ │ + └────────────────────────────────────┤ │ + └────────────────────────────────────────────────┘ + + +### Set Chip Target + +First of all, your target must be supported by both: + +- **By your ESP-IDF version**: For the full list of supported targets, run: + ``` + idf.py --list-targets + ``` +- **By this example**: For the full list of supported targets, refer to the supported targets table at the top of this README. + +After you make sure that your target is supported, go to your example project directory and [set the chip target](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/tools/idf-py.html#select-the-target-chip-set-target): + +``` +idf.py set-target +``` + +For example, to set esp32-P4 as the chip target, run: + +``` +idf.py set-target esp32p4 +``` + + +### Configure the Project + +For information about Kconfig options, see [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) > _Name of relevant section(s)_. + +To conveniently check or modify Kconfig options for this example in a project configuration menu, run: + +``` +idf.py menuconfig +``` + +``` +Set CONFIG_CAMERA_OV5647 to y +``` + + +### Build and Flash + +Execute the following command to build the project, flash it to your development board, and run the monitor tool to view the serial output: + +``` +idf.py build flash monitor +``` + +This command can be reduced to `idf.py flash monitor`. + +If the above command fails, check the log on the serial monitor which usually provides information on the possible cause of the issue. + +To exit the serial monitor, use `Ctrl` + `]`. + + +## Example Output + +If you see the following console output, your example should be running correctly: + +``` +I (1085) main_task: Calling app_main() +I (1095) ili9881c: ID1: 0x98, ID2: 0x81, ID3: 0x5c +I (1125) gpio: GPIO[31]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (1125) gpio: GPIO[34]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 +I (1295) ov5647: Detected Camera sensor PID=0x5647 with index 0 +I (1305) cam_dsi: fmt[0].name:MIPI_2lane_24Minput_RAW8_800x1280_50fps +I (1305) cam_dsi: fmt[1].name:MIPI_2lane_24Minput_RAW8_800x640_50fps +I (1315) cam_dsi: fmt[2].name:MIPI_2lane_24Minput_RAW8_800x800_50fps +I (1355) cam_dsi: Format in use:MIPI_2lane_24Minput_RAW8_800x640_50fps +``` + +You will also see the screen auto-focus when the screen image changes. + +## Reference + +- Link to the ESP-IDF camera controller driver API reference, [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/camera_driver.html) +- Link to the ESP-IDF ISP driver API reference, [ESP-IDF: Image Signal Processor](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/isp.html) +- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started) +- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options) diff --git a/examples/peripherals/isp/auto_focus/components/isp_af_schemes/include/isp_af_scheme.h b/examples/peripherals/isp/auto_focus/components/isp_af_schemes/include/isp_af_scheme.h index 1926c484fd23..95164fce3a23 100644 --- a/examples/peripherals/isp/auto_focus/components/isp_af_schemes/include/isp_af_scheme.h +++ b/examples/peripherals/isp/auto_focus/components/isp_af_schemes/include/isp_af_scheme.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/examples/peripherals/isp/auto_focus/components/isp_af_schemes/include/isp_af_scheme_sa.h b/examples/peripherals/isp/auto_focus/components/isp_af_schemes/include/isp_af_scheme_sa.h index 44e6a57decba..b01ab5db6625 100644 --- a/examples/peripherals/isp/auto_focus/components/isp_af_schemes/include/isp_af_scheme_sa.h +++ b/examples/peripherals/isp/auto_focus/components/isp_af_schemes/include/isp_af_scheme_sa.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,8 +33,9 @@ typedef struct { * @brief Sensor driver API to set sensor focus value * * @param[in] focus_val Camera sensor focus value + * @param[in] arg User arg */ - esp_err_t (*af_sensor_set_focus)(int focus_val); + esp_err_t (*af_sensor_set_focus)(int focus_val, void *arg); } isp_af_sa_scheme_sensor_drv_t; @@ -51,7 +52,7 @@ typedef struct { * - ESP_ERR_INVALID_STATE Invalid state * - ESP_ERR_NO_MEM If out of memory */ -esp_err_t isp_af_create_sa_scheme(isp_af_ctrlr_t af_ctrlr, const isp_af_sa_scheme_config_t *config, isp_af_scheme_handle_t *ret_scheme); +esp_err_t isp_af_create_sa_scheme(isp_af_ctlr_t af_ctrlr, const isp_af_sa_scheme_config_t *config, isp_af_scheme_handle_t *ret_scheme); /** * @brief Delete an AF step approximation scheme @@ -72,13 +73,14 @@ esp_err_t isp_af_delete_sa_scheme(isp_af_scheme_handle_t scheme); * @param[in] scheme AF scheme handle * @param[in] sensor_drv Sensor driver, see `isp_af_sa_scheme_sensor_drv_t` * @param[in] info Sensor info + * @param[in] arg User arg * * @return * - ESP_OK On success * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid * - ESP_ERR_INVALID_STATE Invalid state */ -esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme, const isp_af_sa_scheme_sensor_drv_t *sensor_drv, const isp_af_sa_scheme_sensor_info_t *info); +esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme, const isp_af_sa_scheme_sensor_drv_t *sensor_drv, const isp_af_sa_scheme_sensor_info_t *info, void *arg); #ifdef __cplusplus } diff --git a/examples/peripherals/isp/auto_focus/components/isp_af_schemes/src/isp_af_scheme_sa.c b/examples/peripherals/isp/auto_focus/components/isp_af_schemes/src/isp_af_scheme_sa.c index 516782695dbc..9e8830b00d31 100644 --- a/examples/peripherals/isp/auto_focus/components/isp_af_schemes/src/isp_af_scheme_sa.c +++ b/examples/peripherals/isp/auto_focus/components/isp_af_schemes/src/isp_af_scheme_sa.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,7 +21,7 @@ static const char *TAG = "AF_SCHEME"; typedef struct { - isp_af_ctrlr_t af_ctlr; + isp_af_ctlr_t af_ctlr; int first_step_val; int first_approx_cycles; int second_step_val; @@ -29,13 +29,14 @@ typedef struct { isp_af_sa_scheme_sensor_info_t sensor_info; isp_af_sa_scheme_sensor_drv_t sensor_drv; + void *arg; } af_scheme_context_t; /* ------------------------ Interface Functions --------------------------- */ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_luminance_thresh); /* ------------------------- Public API ------------------------------------- */ -esp_err_t isp_af_create_sa_scheme(isp_af_ctrlr_t af_ctlr, const isp_af_sa_scheme_config_t *config, isp_af_scheme_handle_t *ret_scheme) +esp_err_t isp_af_create_sa_scheme(isp_af_ctlr_t af_ctlr, const isp_af_sa_scheme_config_t *config, isp_af_scheme_handle_t *ret_scheme) { esp_err_t ret = ESP_FAIL; ESP_RETURN_ON_FALSE(af_ctlr && config && ret_scheme, ESP_ERR_INVALID_ARG, TAG, "invalid arg: null pointer"); @@ -78,7 +79,7 @@ esp_err_t isp_af_delete_sa_scheme(isp_af_scheme_handle_t scheme) return ESP_OK; } -esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme, const isp_af_sa_scheme_sensor_drv_t *sensor_drv, const isp_af_sa_scheme_sensor_info_t *info) +esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme, const isp_af_sa_scheme_sensor_drv_t *sensor_drv, const isp_af_sa_scheme_sensor_info_t *info, void *arg) { ESP_RETURN_ON_FALSE(scheme, ESP_ERR_INVALID_ARG, TAG, "invalid arg: null pointer"); ESP_RETURN_ON_FALSE(scheme->ctx, ESP_ERR_INVALID_STATE, TAG, "no scheme created yet"); @@ -86,6 +87,7 @@ esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme, af_scheme_context_t *ctx = scheme->ctx; ctx->sensor_drv.af_sensor_set_focus = sensor_drv->af_sensor_set_focus; ctx->sensor_info.focus_val_max = info->focus_val_max; + ctx->arg = arg; return ESP_OK; } @@ -117,7 +119,7 @@ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_lu isp_af_result_t result = {}; - ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(0), TAG, "sensor set focus val fail"); + ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(0, ctx->arg), TAG, "sensor set focus val fail"); ESP_LOGV(TAG, "//----------- af start ----------//"); @@ -128,7 +130,7 @@ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_lu for (int x = 0; x <= ctx->first_approx_cycles; x++) { af_current = af_current_base + x * ctx->first_step_val; - ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current), TAG, "sensor set focus val fail"); + ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current, ctx->arg), TAG, "sensor set focus val fail"); ESP_RETURN_ON_ERROR(esp_isp_af_controller_get_oneshot_result(ctx->af_ctlr, &result), TAG, "get AF result fail"); af_sum = result.definition[0] + result.definition[1] + result.definition[2]; if (af_sum > af_sum_max) { @@ -136,7 +138,7 @@ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_lu af_current_best = af_current; } - ESP_LOGV(TAG, "af_sum: %"PRId32", af_current: %"PRId32".%"PRId32, af_sum, (int)af_current, (int)((int)(af_current * 1000) % 1000)); + ESP_LOGV(TAG, "af_sum: %d, af_current: %d.%d", af_sum, (int)af_current, (int)((int)(af_current * 1000) % 1000)); } // second search @@ -154,7 +156,7 @@ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_lu af_current = 0; } - ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current), TAG, "sensor set focus val fail"); + ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current, ctx->arg), TAG, "sensor set focus val fail"); ESP_RETURN_ON_ERROR(esp_isp_af_controller_get_oneshot_result(ctx->af_ctlr, &result), TAG, "get AF result fail"); af_sum = result.definition[0] + result.definition[1] + result.definition[2]; if (af_sum > af_sum_max) { @@ -167,7 +169,7 @@ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_lu // af done ESP_LOGV(TAG, "//----------- af done ----------//"); ESP_LOGV(TAG, "af_sum_max: %d, af_current_best: %d.%d", af_sum_max, (int)af_current_best, (int)((int)(af_current_best * 1000) % 1000)); - ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current_best), TAG, "sensor set focus val fail"); + ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current_best, ctx->arg), TAG, "sensor set focus val fail"); // update env threshold ESP_LOGV(TAG, "//------- update env threshold -------//"); diff --git a/examples/peripherals/isp/auto_focus/main/CMakeLists.txt b/examples/peripherals/isp/auto_focus/main/CMakeLists.txt new file mode 100644 index 000000000000..60d0b9d6057a --- /dev/null +++ b/examples/peripherals/isp/auto_focus/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "isp_af_dsi_main.c" + INCLUDE_DIRS "." + REQUIRES esp_mm esp_driver_isp esp_driver_cam esp_driver_i2c esp_lcd dsi_init + ) diff --git a/examples/peripherals/isp/auto_focus/main/Kconfig.projbuild b/examples/peripherals/isp/auto_focus/main/Kconfig.projbuild new file mode 100644 index 000000000000..8117f6ef7ba4 --- /dev/null +++ b/examples/peripherals/isp/auto_focus/main/Kconfig.projbuild @@ -0,0 +1,41 @@ +menu "Example Configuration" + config EXAMPLE_USED_LDO_CHAN_ID + int "example used LDO channel ID" + default 3 + help + Example used LDO channel ID, you may check datasheet to know more details. + + config EXAMPLE_USED_LDO_VOLTAGE_MV + int "example used LDO voltage in mV" + default 2500 + range 0 3300 + help + Example used LDO voltage, in mV + + choice EXAMPLE_MIPI_CSI_DISP_HRES + bool "Set MIPI CSI horizontal resolution" + default EXAMPLE_MIPI_CSI_HRES_800 + + config EXAMPLE_MIPI_CSI_HRES_800 + bool "800" + endchoice + + config EXAMPLE_MIPI_CSI_DISP_HRES + int + default 800 if EXAMPLE_MIPI_CSI_HRES_800 + + choice EXAMPLE_MIPI_CSI_DISP_VRES + bool "Set MIPI CSI vertical resolution" + default EXAMPLE_MIPI_CSI_VRES_640 + + config EXAMPLE_MIPI_CSI_VRES_640 + bool "640" + config EXAMPLE_MIPI_CSI_VRES_1280 + bool "1280" + endchoice + + config EXAMPLE_MIPI_CSI_DISP_VRES + int + default 640 if EXAMPLE_MIPI_CSI_VRES_640 + default 1280 if EXAMPLE_MIPI_CSI_VRES_1280 +endmenu diff --git a/examples/peripherals/isp/auto_focus/main/example_config.h b/examples/peripherals/isp/auto_focus/main/example_config.h new file mode 100644 index 000000000000..628a441f56fb --- /dev/null +++ b/examples/peripherals/isp/auto_focus/main/example_config.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXAMPLE_RGB565_BITS_PER_PIXEL 16 +#define EXAMPLE_MIPI_SCCB_FREQ (100000) +#define EXAMPLE_MIPI_SCCB_SCL_IO (8) +#define EXAMPLE_MIPI_SCCB_SDA_IO (7) +#define EXAMPLE_MIPI_IDI_CLOCK_RATE (50000000) +#define EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS 200 //line_rate = pclk * 4 + +#define EXAMPLE_OV5647_DEV_ADDR 0x36 +#define EXAMPLE_DW9714_DEV_ADDR 0xC +#ifdef __cplusplus +} +#endif diff --git a/examples/peripherals/isp/auto_focus/main/idf_component.yml b/examples/peripherals/isp/auto_focus/main/idf_component.yml new file mode 100644 index 000000000000..0e139a9d0815 --- /dev/null +++ b/examples/peripherals/isp/auto_focus/main/idf_component.yml @@ -0,0 +1,9 @@ +dependencies: + espressif/esp_cam_sensor: "^0.5.*" + espressif/esp_lcd_ili9881c: "~0.2.0" + idf: + version: ">=5.3.0" + isp_af_schemes: + path: ${IDF_PATH}/examples/peripherals/isp/auto_focus/components/isp_af_schemes + dsi_init: + path: ${IDF_PATH}/examples/peripherals/camera/camera_dsi/components/dsi_init diff --git a/examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c b/examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c new file mode 100644 index 000000000000..2e60bac2551f --- /dev/null +++ b/examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c @@ -0,0 +1,385 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "esp_log.h" +#include "esp_heap_caps.h" +#include "esp_lcd_mipi_dsi.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_ili9881c.h" +#include "esp_ldo_regulator.h" +#include "esp_cache.h" +#include "driver/i2c_master.h" +#include "driver/isp.h" +#include "driver/isp_bf.h" +#include "isp_af_scheme_sa.h" +#include "esp_cam_ctlr_csi.h" +#include "esp_cam_ctlr.h" +#include "esp_sccb_intf.h" +#include "esp_sccb_i2c.h" +#include "esp_cam_sensor.h" +#include "ov5647.h" +#include "example_dsi_init.h" +#include "example_dsi_init_config.h" +#include "example_config.h" + +static const char *TAG = "isp_dsi"; + +static bool s_camera_get_new_vb(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data); +static bool s_camera_get_finished_trans(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data); + +typedef union { + struct { + uint16_t s : 4; + uint16_t d : 10; + uint16_t flag : 1; + uint16_t pd : 1; + }; + struct { + uint16_t byte2 : 8; + uint16_t byte1 : 8; + }; + uint16_t val; +} dw9714_reg_t; + +static bool IRAM_ATTR s_env_change_cb(isp_af_ctlr_t af_ctrlr, const esp_isp_af_env_detector_evt_data_t *edata, void *user_data) +{ + BaseType_t mustYield = pdFALSE; + TaskHandle_t task_handle = (TaskHandle_t)user_data; + vTaskNotifyGiveFromISR(task_handle, &mustYield); + + return (mustYield == pdTRUE); +} + +static esp_err_t s_sensor_set_focus_val(int focus_val, void *arg) +{ + esp_sccb_io_handle_t dw9714_io_handle = arg; + + dw9714_reg_t reg = {0}; + reg.d = (uint16_t)((focus_val / 120.0) * 1023.0); + + uint8_t data[2] = {0}; + data[0] = reg.byte1; + data[1] = reg.byte2; + + uint16_t reg_addr = (data[0] << 8) + (data[1]); + uint8_t reg_val = 0; + + esp_err_t ret = esp_sccb_transmit_reg_a16v8(dw9714_io_handle, reg_addr, reg_val); + if (ret != ESP_OK) { + printf("dw9714 esp_sccb_transmit_reg_a16v8 failed\n"); + return ret; + } + + return ESP_OK; +} + +static void af_task(void *arg) +{ + TaskHandle_t task_handle = xTaskGetCurrentTaskHandle(); + + typedef struct af_task_param_t { + isp_proc_handle_t isp_proc; + esp_sccb_io_handle_t dw9714_io_handle; + } af_task_param_t; + + af_task_param_t af_task_param = *(af_task_param_t *)arg; + + /** + * AF window, windows for ISP hardware to record the + * - luminance + * - definition + * of the current windows + */ + esp_isp_af_config_t af_config = { + .window = { + [0] = { + .top_left = { + .x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) - 100, + .y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) - 100, + }, + .btm_right = { + .x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) + 99, + .y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) + 99, + }, + }, + [1] = { + .top_left = { + .x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) - 100, + .y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) - 100, + }, + .btm_right = { + .x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) + 99, + .y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) + 99, + }, + }, + [2] = { + .top_left = { + .x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) - 100, + .y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) - 100, + }, + .btm_right = { + .x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) + 99, + .y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) + 99, + }, + }, + }, + .edge_thresh = 128, + }; + + isp_af_ctlr_t af_ctrlr = NULL; + ESP_ERROR_CHECK(esp_isp_new_af_controller(af_task_param.isp_proc, &af_config, &af_ctrlr)); + + esp_isp_af_env_config_t env_config = { + .interval = 10, + }; + ESP_ERROR_CHECK(esp_isp_af_controller_set_env_detector(af_ctrlr, &env_config)); + + esp_isp_af_env_detector_evt_cbs_t cbs = { + .on_env_change = s_env_change_cb, + }; + ESP_ERROR_CHECK(esp_isp_af_env_detector_register_event_callbacks(af_ctrlr, &cbs, task_handle)); + + isp_af_sa_scheme_config_t af_scheme_config = { + .first_step_val = 12, + .first_approx_cycles = 10, + .second_step_val = 2, + .second_approx_cycles = 10, + }; + isp_af_scheme_handle_t af_scheme = NULL; + ESP_ERROR_CHECK(isp_af_create_sa_scheme(af_ctrlr, &af_scheme_config, &af_scheme)); + + isp_af_sa_scheme_sensor_drv_t sensor_driver = { + .af_sensor_set_focus = s_sensor_set_focus_val, + }; + isp_af_sa_scheme_sensor_info_t sensor_info = { + .focus_val_max = 120, + }; + ESP_ERROR_CHECK(isp_af_sa_scheme_register_sensor_driver(af_scheme, &sensor_driver, &sensor_info, af_task_param.dw9714_io_handle)); + + int definition_thresh = 0; + int luminance_thresh = 0; + ESP_ERROR_CHECK(esp_isp_af_controller_enable(af_ctrlr)); + + while (1) { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + ESP_ERROR_CHECK(isp_af_process(af_scheme, &definition_thresh, &luminance_thresh)); + ESP_ERROR_CHECK(esp_isp_af_controller_set_env_detector_threshold(af_ctrlr, definition_thresh, luminance_thresh)); + } +} + +void app_main(void) +{ + esp_err_t ret = ESP_FAIL; + esp_lcd_panel_handle_t ili9881c_ctrl_panel = NULL; + esp_lcd_panel_handle_t mipi_dpi_panel = NULL; + void *frame_buffer = NULL; + size_t frame_buffer_size = 0; + + //mipi ldo + esp_ldo_channel_handle_t ldo_mipi_phy = NULL; + esp_ldo_channel_config_t ldo_mipi_phy_config = { + .chan_id = CONFIG_EXAMPLE_USED_LDO_CHAN_ID, + .voltage_mv = CONFIG_EXAMPLE_USED_LDO_VOLTAGE_MV, + }; + ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy)); + + /** + * @background + * Sensor use RAW8 + * ISP convert to RGB565 + */ + //---------------DSI Init------------------// + example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dpi_panel, &frame_buffer); + + //---------------Necessary variable config------------------// + frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8; + + ESP_LOGD(TAG, "CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES: %d, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES: %d, bits per pixel: %d", CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES, 8); + ESP_LOGD(TAG, "frame_buffer_size: %zu", frame_buffer_size); + ESP_LOGD(TAG, "frame_buffer: %p", frame_buffer); + + esp_cam_ctlr_trans_t new_trans = { + .buffer = frame_buffer, + .buflen = frame_buffer_size, + }; + + //---------------I2C Init------------------// + i2c_master_bus_config_t i2c_bus_conf = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .sda_io_num = EXAMPLE_MIPI_SCCB_SDA_IO, + .scl_io_num = EXAMPLE_MIPI_SCCB_SCL_IO, + .i2c_port = I2C_NUM_0, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle = NULL; + ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_conf, &bus_handle)); + + //---------------SCCB Init------------------// + esp_sccb_io_handle_t ov5647_io_handle = NULL; + sccb_i2c_config_t i2c_config = { + .scl_speed_hz = EXAMPLE_MIPI_SCCB_FREQ, + .device_address = EXAMPLE_OV5647_DEV_ADDR, + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + }; + ESP_ERROR_CHECK(sccb_new_i2c_io(bus_handle, &i2c_config, &ov5647_io_handle)); + + esp_sccb_io_handle_t dw9714_io_handle = NULL; + i2c_config.device_address = EXAMPLE_DW9714_DEV_ADDR; + ESP_ERROR_CHECK(sccb_new_i2c_io(bus_handle, &i2c_config, &dw9714_io_handle)); + + //---------------CSI Init------------------// + esp_cam_ctlr_csi_config_t csi_config = { + .ctlr_id = 0, + .h_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, + .v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES, + .lane_bit_rate_mbps = EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS, + .input_data_color_type = CAM_CTLR_COLOR_RAW8, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, + .data_lane_num = 2, + .byte_swap_en = false, + .queue_items = 1, + }; + esp_cam_ctlr_handle_t handle = NULL; + ret = esp_cam_new_csi_ctlr(&csi_config, &handle); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "csi init fail[%d]", ret); + return; + } + + esp_cam_ctlr_evt_cbs_t cbs = { + .on_get_new_trans = s_camera_get_new_vb, + .on_trans_finished = s_camera_get_finished_trans, + }; + if (esp_cam_ctlr_register_event_callbacks(handle, &cbs, &new_trans) != ESP_OK) { + ESP_LOGE(TAG, "ops register fail"); + return; + } + + ESP_ERROR_CHECK(esp_cam_ctlr_enable(handle)); + //---------------ISP Init------------------// + isp_proc_handle_t isp_proc = NULL; + esp_isp_processor_cfg_t isp_config = { + .clk_hz = 80 * 1000 * 1000, + .input_data_source = ISP_INPUT_DATA_SOURCE_CSI, + .input_data_color_type = ISP_COLOR_RAW8, + .output_data_color_type = ISP_COLOR_RGB565, + .has_line_start_packet = false, + .has_line_end_packet = false, + .h_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, + .v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES, + }; + ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc)); + ESP_ERROR_CHECK(esp_isp_enable(isp_proc)); + + esp_isp_bf_config_t bf_config = { + .denoising_level = 5, + .padding_mode = ISP_BF_EDGE_PADDING_MODE_SRND_DATA, + .bf_template = { + {1, 2, 1}, + {2, 4, 2}, + {1, 2, 1}, + }, + .padding_line_tail_valid_start_pixel = 0, + .padding_line_tail_valid_end_pixel = 0, + }; + ESP_ERROR_CHECK(esp_isp_bf_configure(isp_proc, &bf_config)); + ESP_ERROR_CHECK(esp_isp_bf_enable(isp_proc)); + + typedef struct af_task_param_t { + isp_proc_handle_t isp_proc; + esp_sccb_io_handle_t dw9714_io_handle; + } af_task_param_t; + + af_task_param_t af_task_param = { + .isp_proc = isp_proc, + .dw9714_io_handle = dw9714_io_handle, + }; + xTaskCreatePinnedToCore(af_task, "af_task", 8192, &af_task_param, 5, NULL, 0); + + //---------------DSI Panel Init------------------// + example_dsi_ili9881c_panel_init(ili9881c_ctrl_panel); + + //init to all white + memset(frame_buffer, 0xFF, frame_buffer_size); + esp_cache_msync((void *)frame_buffer, frame_buffer_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + + if (esp_cam_ctlr_start(handle) != ESP_OK) { + ESP_LOGE(TAG, "Driver start fail"); + return; + } + + esp_cam_sensor_config_t cam_config = { + .sccb_handle = ov5647_io_handle, + .reset_pin = -1, + .pwdn_pin = -1, + .xclk_pin = -1, + .sensor_port = ESP_CAM_SENSOR_MIPI_CSI, + }; + + esp_cam_sensor_device_t *cam = ov5647_detect(&cam_config); + if (!cam) { + ESP_LOGE(TAG, "failed to detect 5647"); + return; + } + + esp_cam_sensor_format_array_t cam_fmt_array = {0}; + esp_cam_sensor_query_format(cam, &cam_fmt_array); + const esp_cam_sensor_format_t *parray = cam_fmt_array.format_array; + for (int i = 0; i < cam_fmt_array.count; i++) { + ESP_LOGI(TAG, "fmt[%d].name:%s", i, parray[i].name); + } + + esp_cam_sensor_format_t *cam_cur_fmt = NULL; + for (int i = 0; i < cam_fmt_array.count; i++) { +#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640 + if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x640_50fps")) { + cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name); + break; + } +#else + if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x1280_50fps")) { + cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name); + break; + } +#endif + } + + ret = esp_cam_sensor_set_format(cam, (const esp_cam_sensor_format_t *) cam_cur_fmt); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Format set fail"); + } else { + ESP_LOGI(TAG, "Format in use:%s", cam_cur_fmt->name); + } + int enable_flag = 1; + // Set sensor output stream + ret = esp_cam_sensor_ioctl(cam, ESP_CAM_SENSOR_IOC_S_STREAM, &enable_flag); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Start stream fail"); + } + + example_dpi_panel_init(mipi_dpi_panel); + + while (1) { + ESP_ERROR_CHECK(esp_cam_ctlr_receive(handle, &new_trans, ESP_CAM_CTLR_MAX_DELAY)); + } +} + +static bool s_camera_get_new_vb(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data) +{ + esp_cam_ctlr_trans_t new_trans = *(esp_cam_ctlr_trans_t *)user_data; + trans->buffer = new_trans.buffer; + trans->buflen = new_trans.buflen; + + return false; +} + +bool s_camera_get_finished_trans(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data) +{ + return false; +} diff --git a/examples/peripherals/isp/auto_focus/sdkconfig.defaults b/examples/peripherals/isp/auto_focus/sdkconfig.defaults new file mode 100644 index 000000000000..7c4a6989325b --- /dev/null +++ b/examples/peripherals/isp/auto_focus/sdkconfig.defaults @@ -0,0 +1,4 @@ +CONFIG_SPIRAM=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM_SPEED_200M=y +CONFIG_CAMERA_OV5647=y diff --git a/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c b/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c index 86e8ce2b415b..259dd4bcb5b2 100644 --- a/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c +++ b/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c @@ -9,6 +9,7 @@ #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_timer.h" +#include "esp_heap_caps.h" #include "esp_lcd_panel_io.h" #include "esp_lcd_panel_vendor.h" #include "esp_lcd_panel_ops.h" @@ -18,7 +19,6 @@ #include "driver/i2c.h" #include "esp_err.h" #include "esp_log.h" -#include "esp_dma_utils.h" #include "lvgl.h" #if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 #include "esp_lcd_touch_gt911.h" @@ -93,8 +93,7 @@ static const char *TAG = "example"; #define EXAMPLE_LVGL_TASK_STACK_SIZE (4 * 1024) #define EXAMPLE_LVGL_TASK_PRIORITY 2 -// Supported alignment: 16, 32, 64. A higher alignment can enables higher burst transfer size, thus a higher i80 bus throughput. -#define EXAMPLE_PSRAM_DATA_ALIGNMENT 64 +#define EXAMPLE_DMA_BURST_SIZE 64 // 16, 32, 64. Higher burst size can improve the performance when the DMA buffer comes from PSRAM static SemaphoreHandle_t lvgl_mux = NULL; @@ -248,8 +247,7 @@ void example_init_i80_bus(esp_lcd_panel_io_handle_t *io_handle, void *user_ctx) }, .bus_width = CONFIG_EXAMPLE_LCD_I80_BUS_WIDTH, .max_transfer_bytes = EXAMPLE_LCD_H_RES * 100 * sizeof(uint16_t), - .psram_trans_align = EXAMPLE_PSRAM_DATA_ALIGNMENT, - .sram_trans_align = 4, + .dma_burst_size = EXAMPLE_DMA_BURST_SIZE, }; ESP_ERROR_CHECK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); @@ -445,18 +443,12 @@ void app_main(void) lv_init(); // alloc draw buffers used by LVGL // it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized - lv_color_t *buf1 = NULL; - lv_color_t *buf2 = NULL; - esp_dma_mem_info_t dma_mem_info = { - .dma_alignment_bytes = 4, + uint32_t draw_buf_alloc_caps = 0; #if CONFIG_EXAMPLE_LCD_I80_COLOR_IN_PSRAM - .extra_heap_caps = MALLOC_CAP_SPIRAM, -#else - .extra_heap_caps = MALLOC_CAP_INTERNAL, -#endif // CONFIG_EXAMPLE_LCD_I80_COLOR_IN_PSRAM - }; - ESP_ERROR_CHECK(esp_dma_capable_malloc(EXAMPLE_LCD_H_RES * 100 * sizeof(lv_color_t), &dma_mem_info, (void *)&buf1, NULL)); - ESP_ERROR_CHECK(esp_dma_capable_malloc(EXAMPLE_LCD_H_RES * 100 * sizeof(lv_color_t), &dma_mem_info, (void *)&buf2, NULL)); + draw_buf_alloc_caps |= MALLOC_CAP_SPIRAM; +#endif + lv_color_t *buf1 = esp_lcd_i80_alloc_draw_buffer(io_handle, EXAMPLE_LCD_H_RES * 100 * sizeof(lv_color_t), draw_buf_alloc_caps); + lv_color_t *buf2 = esp_lcd_i80_alloc_draw_buffer(io_handle, EXAMPLE_LCD_H_RES * 100 * sizeof(lv_color_t), draw_buf_alloc_caps); assert(buf1); assert(buf2); ESP_LOGI(TAG, "buf1@%p, buf2@%p", buf1, buf2); diff --git a/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml b/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml index 4cf2c942b0ba..f4d4be77e464 100644 --- a/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml +++ b/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml @@ -1,3 +1,3 @@ dependencies: lvgl/lvgl: "^9.0.0" - esp_lcd_ili9881c: "*" + esp_lcd_ili9881c: "~0.2.0" diff --git a/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c b/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c index 8c8599a3d3cf..f388294a41c0 100644 --- a/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c +++ b/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c @@ -166,7 +166,7 @@ void app_main(void) esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_rgb_panel_config_t panel_config = { .data_width = 16, // RGB565 in parallel mode, thus 16bit in width - .psram_trans_align = 64, + .dma_burst_size = 64, .num_fbs = EXAMPLE_LCD_NUM_FB, #if CONFIG_EXAMPLE_USE_BOUNCE_BUFFER .bounce_buffer_size_px = 10 * EXAMPLE_LCD_H_RES, diff --git a/examples/peripherals/ledc/ledc_check/CMakeLists.txt b/examples/peripherals/ledc/ledc_check/CMakeLists.txt new file mode 100644 index 000000000000..6fd196565b1e --- /dev/null +++ b/examples/peripherals/ledc/ledc_check/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(ledc) diff --git a/examples/peripherals/ledc/ledc_check/main/CMakeLists.txt b/examples/peripherals/ledc/ledc_check/main/CMakeLists.txt new file mode 100644 index 000000000000..89e84133bb2f --- /dev/null +++ b/examples/peripherals/ledc/ledc_check/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "ledc_check.c" + INCLUDE_DIRS ".") diff --git a/examples/peripherals/ledc/ledc_check/main/ledc_check.c b/examples/peripherals/ledc/ledc_check/main/ledc_check.c new file mode 100755 index 000000000000..3243a0ebcdfd --- /dev/null +++ b/examples/peripherals/ledc/ledc_check/main/ledc_check.c @@ -0,0 +1,130 @@ +/* LEDC (LED Controller) basic example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include "driver/ledc.h" +#include "esp_err.h" + +#include "freertos/FreeRTOS.h" +#include "esp_clk_tree.h" + +#define CHECK_SET 0 // 1 +#if CHECK_SET != 0 +Add to the esp-idf/components/esp_driver_ledc/include/driver/ledc.h +uint32_t ledc_calculate_divisor(uint32_t src_clk_freq, int freq_hz, uint32_t precision); +#endif + +#define CHECK_ALL 0 // 1 +#define FDIV 1 // 2 // 5 +#define DELAY_ms 500 // 3000 + +#undef ESP_ERROR_CHECK +#define ESP_ERROR_CHECK(err) do {if (err != ESP_OK) {printf("freq=%lu, err=%d, LINE=%d\n", freq, err, __LINE__);} } while (0); + +#define LEDC_OUTPUT_IO (26) // Define the output GPIO +#define LEDC_TIMER LEDC_TIMER_0 +#define LEDC_MODE LEDC_HIGH_SPEED_MODE // LEDC_LOW_SPEED_MODE // +#define LEDC_CHANNEL LEDC_CHANNEL_0 + +#define LEDC_DUTY ((1UL << timer.duty_resolution) / 2) // 50% +/* Warning: + * For ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2, ESP32P4 targets, + * when LEDC_DUTY_RES selects the maximum duty resolution (i.e. value equal to SOC_LEDC_TIMER_BIT_WIDTH), + * 100% duty cycle is not reachable (duty cannot be set to (2 ** SOC_LEDC_TIMER_BIT_WIDTH)). + */ + +#define FREQ_PERCENT (10) +#define DUTY_PERCENT (10) + +ledc_timer_config_t timer; +ledc_channel_config_t channel; + +static void check(uint32_t freq) +{ + printf("freq=%lu \t", freq); + + // Set the LEDC peripheral configuration + uint32_t src_clk_freq; + ESP_ERROR_CHECK(esp_clk_tree_src_get_freq_hz(LEDC_USE_APB_CLK, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &src_clk_freq)); + // Prepare and then apply the LEDC PWM timer configuration + timer = (ledc_timer_config_t){ + .speed_mode = LEDC_MODE, + .timer_num = LEDC_TIMER, + .duty_resolution = ledc_find_suitable_duty_resolution(src_clk_freq, freq), + .freq_hz = freq, + .clk_cfg = LEDC_USE_APB_CLK + }; + ESP_ERROR_CHECK(ledc_timer_config(&timer)); + + // Prepare and then apply the LEDC PWM channel configuration + channel = (ledc_channel_config_t){ + .speed_mode = LEDC_MODE, + .channel = LEDC_CHANNEL, + .timer_sel = LEDC_TIMER, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = LEDC_OUTPUT_IO, + .duty = LEDC_DUTY, + .hpoint = 0 + }; + ESP_ERROR_CHECK(ledc_channel_config(&channel)); + + #if CHECK_SET + uint32_t divider = ledc_calculate_divisor(src_clk_freq, timer.freq_hz, 0x1 << timer.duty_resolution); + ESP_ERROR_CHECK(ledc_timer_set(timer.speed_mode, timer.timer_num, divider, timer.duty_resolution, timer.clk_cfg)); + + // Set duty + ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY)); + // Update duty to apply the new value + ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); + #endif + + vTaskDelay((2000 / freq) / portTICK_PERIOD_MS); + + uint32_t get_freq = ledc_get_freq(LEDC_MODE, LEDC_CHANNEL); + float freq_percent = 100.0 * fabs((float)timer.freq_hz - get_freq) / timer.freq_hz; + uint32_t get_duty = ledc_get_duty(LEDC_MODE, LEDC_CHANNEL); + float duty_percent = 100.0 * fabs((float)channel.duty - get_duty) / channel.duty; + + //if ((timer.freq_hz != get_freq) || (channel.duty != get_duty)) { + if ((freq_percent >= FREQ_PERCENT) || (duty_percent >= DUTY_PERCENT)) { + printf("%6.2f%% timer.freq_hz=%lu, get_freq=%lu, \t\t %6.2f%% channel.duty=%lu, get_duty=%lu \t\t timer.duty_resolution=%u\n", + freq_percent, timer.freq_hz, get_freq, + duty_percent, channel.duty, get_duty, + timer.duty_resolution); + } else { + printf("\n"); + } +} + +void app_main(void) { + uint32_t freq; + for(freq=1; freq<=40000000; freq+=1) { + #if CHECK_ALL != 1 + if (freq > 10000000) + freq += 10000000 / FDIV - 1; + else if (freq > 1000000) + freq += 1000000 / FDIV - 1; + else if (freq > 100000) + freq += 100000 / FDIV - 1; + else if (freq > 10000) + freq += 10000 / FDIV - 1; + else if (freq > 1000) + freq += 1000 / FDIV - 1; + else if (freq > 100) + freq += 100 / FDIV - 1; + else if (freq > 10) + freq += 10 / FDIV - 1; + #endif + + check(freq); + + vTaskDelay(DELAY_ms / portTICK_PERIOD_MS); + } + printf("END.\n"); +} diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/README.md b/examples/peripherals/parlio/parlio_rx/logic_analyzer/README.md index 6f91587df245..1881bdf2238c 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/README.md +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C6 | ESP32-H2 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C6 | ESP32-H2 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | # Logic Analyzer Example diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/esp_probe_private.h b/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/esp_probe_private.h index 77d6b4b517ee..94bd1e521ff0 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/esp_probe_private.h +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/esp_probe_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,8 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" +#include "soc/soc_caps.h" +#include "hal/dma_types.h" #include "esp_heap_caps.h" #include "esp_probe.h" @@ -19,12 +21,17 @@ extern "C" { #endif #define ESP_PROBE_DEFAULT_Q_DEPTH 8 -#define ESP_PROBE_DEFAULT_MAX_RECV_SIZE (ESP_PROBE_DEFAULT_Q_DEPTH * 4092) +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#define ESP_PROBE_DEFAULT_MAX_RECV_SIZE (ESP_PROBE_DEFAULT_Q_DEPTH * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_64B_ALIGNED) +#else +#define ESP_PROBE_DEFAULT_MAX_RECV_SIZE (ESP_PROBE_DEFAULT_Q_DEPTH * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) +#endif #if CONFIG_PARLIO_ISR_IRAM_SAFE #define ESP_PROBE_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #else #define ESP_PROBE_ALLOC_CAPS MALLOC_CAP_DEFAULT #endif +#define ESP_PROBE_DMA_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA) struct esp_probe_t { uint32_t sample_width; /*!< sample width, i.e., enabled probe channel nums */ diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/hw_impl/esp_probe_impl_parlio.c b/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/hw_impl/esp_probe_impl_parlio.c index 389687f609a2..41de582782c5 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/hw_impl/esp_probe_impl_parlio.c +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/hw_impl/esp_probe_impl_parlio.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,8 @@ #include #include "sdkconfig.h" #include "driver/parlio_rx.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" #include "esp_clk_tree.h" #include "esp_heap_caps.h" #include "esp_check.h" @@ -43,7 +45,11 @@ esp_err_t esp_probe_priv_init_hardware(esp_probe_handle_t handle, esp_probe_conf esp_err_t ret = ESP_OK; s_ephi = calloc(1, sizeof(esp_probe_impl_pralio_t)); ESP_RETURN_ON_FALSE(s_ephi, ESP_ERR_NO_MEM, TAG, "no memory for the esp probe hardware implementation"); - s_ephi->payload = heap_caps_calloc(1, ESP_PROBE_DEFAULT_MAX_RECV_SIZE, ESP_PROBE_ALLOC_CAPS); + + uint32_t alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + alignment = alignment < 4 ? 4 : alignment; + size_t payload_aligned_size = ESP_PROBE_DEFAULT_MAX_RECV_SIZE & ~(alignment - 1); + s_ephi->payload = heap_caps_aligned_calloc(alignment, 1, payload_aligned_size, ESP_PROBE_DMA_ALLOC_CAPS); ESP_GOTO_ON_FALSE(s_ephi->payload, ESP_ERR_NO_MEM, err, TAG, "no memory for payload"); // Get the channel number, the channel number can only be the power of 2 diff --git a/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/README.md b/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/README.md index d995f56c6d9c..db62a41730d7 100644 --- a/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/README.md +++ b/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C6 | ESP32-H2 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-C6 | ESP32-H2 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | # Parallel IO TX Example: Simple RGB LED Matrix diff --git a/examples/peripherals/timer_group/gptimer/README.md b/examples/peripherals/timer_group/gptimer/README.md index b5b3aff407e1..7ff20c6a7d93 100644 --- a/examples/peripherals/timer_group/gptimer/README.md +++ b/examples/peripherals/timer_group/gptimer/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Example: General Purpose Timer diff --git a/examples/peripherals/timer_group/legacy_driver/README.md b/examples/peripherals/timer_group/legacy_driver/README.md index 3a595073c073..fb7f50aab6f2 100644 --- a/examples/peripherals/timer_group/legacy_driver/README.md +++ b/examples/peripherals/timer_group/legacy_driver/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Example: General Purpose Timer diff --git a/examples/peripherals/touch_sensor/touch_periph_version.txt b/examples/peripherals/touch_sensor/README.md similarity index 80% rename from examples/peripherals/touch_sensor/touch_periph_version.txt rename to examples/peripherals/touch_sensor/README.md index 9285732ba03b..2ef4a1b703e5 100644 --- a/examples/peripherals/touch_sensor/touch_periph_version.txt +++ b/examples/peripherals/touch_sensor/README.md @@ -2,3 +2,4 @@ | ------- | ----------------- | | V1 | ESP32 | | V2 | ESP32S2, ESP32S3 | +| V3 | ESP32P4 | diff --git a/examples/peripherals/touch_sensor/touch_sensor_v3/CMakeLists.txt b/examples/peripherals/touch_sensor/touch_sensor_v3/CMakeLists.txt new file mode 100644 index 000000000000..dc484f27e810 --- /dev/null +++ b/examples/peripherals/touch_sensor/touch_sensor_v3/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(touch_sens_example) diff --git a/examples/peripherals/touch_sensor/touch_sensor_v3/README.md b/examples/peripherals/touch_sensor/touch_sensor_v3/README.md new file mode 100644 index 000000000000..650d3a24a66f --- /dev/null +++ b/examples/peripherals/touch_sensor/touch_sensor_v3/README.md @@ -0,0 +1,125 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | + +# Capacity Touch Sensor Example (for hardware version 3) + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example is going to demonstrate how to register the touch channels and read the data. + +## How to Use Example + +### Hardware Required + +* A development board with any supported Espressif SOC chip (see `Supported Targets` table above) +* A USB cable for power supply and programming +* (Optional) Touch board with touch buttons on it. + - If you don't have a touch board, you can connect the touch pins with male jump wires and touch it directly for testing. + +### Configure the Project + +You can determine the touch channel number by ``EXAMPLE_TOUCH_CHANNEL_NUM`` in the example. And adjust the active threshold by ``s_thresh2bm_ratio``. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT build flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +You can see the following output in the monitor if the example runs successfully: + +``` +W (461) touch: [sample_cfg_id 0] clock precision loss, expect 4000000 hz, got 4006725 hz +W (461) touch: [sample_cfg_id 1] clock precision loss, expect 8000000 hz, got 8013450 hz +W (461) touch: [sample_cfg_id 2] clock precision loss, expect 16000000 hz, got 16026900 hz +Initial benchmark and new threshold are: +[CH 0] 0: 4114, 411 1: 2057, 205 2: 1028, 102 +[CH 1] 0: 4643, 464 1: 2322, 232 2: 1160, 116 +[CH 2] 0: 4848, 484 1: 2424, 242 2: 1211, 121 +[CH 3] 0: 4340, 434 1: 2170, 217 2: 1085, 108 +================================= +benchmark [CH 0]: 4115 2056 1028 +chan_data [CH 0]: 4115 2056 1028 + +benchmark [CH 1]: 4644 2322 1160 +chan_data [CH 1]: 4644 2322 1160 + +benchmark [CH 2]: 4848 2423 1211 +chan_data [CH 2]: 4848 2423 1211 + +benchmark [CH 3]: 4337 2168 1084 +chan_data [CH 3]: 4337 2168 1084 + +================================= +benchmark [CH 0]: 4109 2054 1027 +chan_data [CH 0]: 4109 2054 1027 + +benchmark [CH 1]: 4638 2318 1158 +chan_data [CH 1]: 4638 2318 1158 + +benchmark [CH 2]: 4843 2421 1210 +chan_data [CH 2]: 4845 2421 1210 + +benchmark [CH 3]: 4334 2167 1084 +chan_data [CH 3]: 4334 2167 1083 +... +``` + +And if you touch and release a button, you will see the following output: + +``` +... +I (1321) touch_callback: [CH 1] active +================================= +benchmark [CH 0]: 4111 2055 1027 +chan_data [CH 0]: 4111 2055 1027 + +benchmark [CH 1]: 4676 2339 1168 +chan_data [CH 1]: 17701 8798 4399 + +benchmark [CH 2]: 4870 2434 1217 +chan_data [CH 2]: 4867 2433 1217 + +benchmark [CH 3]: 4333 2165 1082 +chan_data [CH 3]: 4333 2165 1082 + +================================= +benchmark [CH 0]: 4109 2053 1027 +chan_data [CH 0]: 4108 2053 1027 + +benchmark [CH 1]: 4676 2339 1168 +chan_data [CH 1]: 11256 8817 4363 + +benchmark [CH 2]: 4868 2434 1217 +chan_data [CH 2]: 4862 2429 1214 + +benchmark [CH 3]: 4332 2165 1082 +chan_data [CH 3]: 4330 2164 1081 + +I (1931) touch_callback: [CH 1] inactive +================================= +benchmark [CH 0]: 4106 2052 1026 +chan_data [CH 0]: 4106 2052 1026 + +benchmark [CH 1]: 4649 2323 1161 +chan_data [CH 1]: 4650 2323 1161 + +benchmark [CH 2]: 4847 2422 1211 +chan_data [CH 2]: 4846 2422 1211 + +benchmark [CH 3]: 4329 2163 1082 +chan_data [CH 3]: 4329 2164 1082 +... +``` + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/peripherals/touch_sensor/touch_sensor_v3/main/CMakeLists.txt b/examples/peripherals/touch_sensor/touch_sensor_v3/main/CMakeLists.txt new file mode 100644 index 000000000000..8c6b0002d3b2 --- /dev/null +++ b/examples/peripherals/touch_sensor/touch_sensor_v3/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "touch_sens_v3_example_main.c" + REQUIRES esp_driver_touch_sens + INCLUDE_DIRS ".") diff --git a/examples/peripherals/touch_sensor/touch_sensor_v3/main/touch_sens_v3_example_main.c b/examples/peripherals/touch_sensor/touch_sensor_v3/main/touch_sens_v3_example_main.c new file mode 100644 index 000000000000..77d37045f08c --- /dev/null +++ b/examples/peripherals/touch_sensor/touch_sensor_v3/main/touch_sens_v3_example_main.c @@ -0,0 +1,168 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/touch_sens.h" +#include "esp_check.h" + +// Touch version 3 supports multiple sample configurations +#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM 1 // Up to 'TOUCH_SAMPLE_CFG_NUM' +#define EXAMPLE_TOUCH_CHANNEL_NUM 4 +#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3 + +static touch_sensor_handle_t s_sens_handle = NULL; +static touch_channel_handle_t s_chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM] = {}; +// Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio)) +static float s_thresh2bm_ratio[EXAMPLE_TOUCH_CHANNEL_NUM] = { + [0 ... EXAMPLE_TOUCH_CHANNEL_NUM - 1] = 0.015f, // 1.5% +}; + +bool example_touch_on_active_callback(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx) +{ + ESP_EARLY_LOGI("touch_callback", "[CH %d] active", (int)event->chan_id); + return false; +} + +bool example_touch_on_inactive_callback(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx) +{ + ESP_EARLY_LOGI("touch_callback", "[CH %d] inactive", (int)event->chan_id); + return false; +} + +static void example_touch_do_initial_scanning(void) +{ + /* Enable the touch sensor to do the initial scanning, so that to initialize the channel data */ + ESP_ERROR_CHECK(touch_sensor_enable(s_sens_handle)); + + /* Scan the enabled touch channels for several times, to make sure the initial channel data is stable */ + for (int i = 0; i < EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES; i++) { + ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(s_sens_handle, 2000)); + } + + /* Disable the touch channel to rollback the state */ + ESP_ERROR_CHECK(touch_sensor_disable(s_sens_handle)); + + /* (Optional) Read the initial channel benchmark and reconfig the channel active threshold accordingly */ + printf("Initial benchmark and new threshold are:\n"); + for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) { + /* Read the initial benchmark of the touch channel */ + uint32_t benchmark[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {}; + ESP_ERROR_CHECK(touch_channel_read_data(s_chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark)); + /* Calculate the proper active thresholds regarding the initial benchmark */ + printf("[CH %d]", i); + touch_channel_config_t chan_cfg = {}; + for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) { + chan_cfg.active_thresh[j] = (uint32_t)(benchmark[j] * s_thresh2bm_ratio[i]); + printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.active_thresh[j]); + } + printf("\n"); + /* Update the channel configuration */ + ESP_ERROR_CHECK(touch_sensor_reconfig_channel(s_chan_handle[i], &chan_cfg)); + } +} + +void app_main(void) +{ + /* Use the default sample configurations */ + touch_sensor_sample_config_t sample_cfg[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = { + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(1, 1, 1), +#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 1 + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(2, 1, 1), +#endif +#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 2 + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(4, 1, 1), +#endif + }; + /* Allocate new touch controller handle */ + touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(EXAMPLE_TOUCH_SAMPLE_CFG_NUM, sample_cfg); + ESP_ERROR_CHECK(touch_sensor_new_controller(&sens_cfg, &s_sens_handle)); + + /* Configure the touch sensor filter */ + touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG(); + ESP_ERROR_CHECK(touch_sensor_config_filter(s_sens_handle, &filter_cfg)); + + /* Allocate new touch channel on the touch controller */ + touch_channel_config_t chan_cfg = { + /** Set the touch channel active threshold of each sample configuration. + * + * @How to Determine: + * As the actual threshold is affected by various factors in real application, + * we need to run the touch app first to get the `benchmark` and the `smooth_data` that being touched. + * + * @Formula: + * threshold = benchmark * coeff, (coeff for example, 0.1%~20%) + * Please adjust the coeff to guarantee the threshold < smooth_data - benchmark + * + * @Typical Practice: + * Normally, we can't determine a fixed threshold at the beginning, + * but we can give them estimated values first and update them after an initial scanning (like this example), + * Step1: set an estimated value for each sample configuration first. (i.e., here) + * Step2: then reconfig the threshold after the initial scanning.(see `example_touch_do_initial_scanning`) + * Step3: adjust the `s_thresh2bm_ratio` to a proper value to trigger the active callback + */ + .active_thresh = { + 1000, // estimated active threshold of sample configuration 0 +#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 1 + 2500, // estimated active threshold of sample configuration 1 +#endif +#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 2 + 5000, // estimated active threshold of sample configuration 2 +#endif + }, + }; + for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) { + ESP_ERROR_CHECK(touch_sensor_new_channel(s_sens_handle, i, &chan_cfg, &s_chan_handle[i])); + } + + /* Do the initial scanning to initialize the touch channel data + * Without this step, the channel data in the first read will be invalid + */ + example_touch_do_initial_scanning(); + + /* Register the touch sensor callbacks, here only take `active` and `deactivate` event for example */ + touch_event_callbacks_t callbacks = { + .on_active = example_touch_on_active_callback, + .on_inactive = example_touch_on_inactive_callback, + .on_measure_done = NULL, + .on_scan_done = NULL, + .on_timeout = NULL, + .on_proximity_meas_done = NULL, + }; + ESP_ERROR_CHECK(touch_sensor_register_callbacks(s_sens_handle, &callbacks, NULL)); + + /* Enable the touch sensor */ + ESP_ERROR_CHECK(touch_sensor_enable(s_sens_handle)); + + /* Start continuous scanning, you can also trigger oneshot scanning manually */ + ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(s_sens_handle)); + + uint32_t benchmark[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {}; + uint32_t chan_data[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {}; + while (1) { + printf("=================================\n"); + for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) { + /* Read and print the benchmark of each sample configuration */ + ESP_ERROR_CHECK(touch_channel_read_data(s_chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark)); + printf("benchmark [CH %d]:", i); + for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) { + printf(" %"PRIu32, benchmark[j]); + } + printf("\n"); + /* Read and print the channel data of each sample configuration */ + ESP_ERROR_CHECK(touch_channel_read_data(s_chan_handle[i], TOUCH_CHAN_DATA_TYPE_SMOOTH, chan_data)); + printf("chan_data [CH %d]:", i); + for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) { + printf(" %"PRIu32, chan_data[j]); + } + printf("\n\n"); + } + /* Read and display the data every 300 ms */ + vTaskDelay(pdMS_TO_TICKS(300)); + } +} diff --git a/examples/peripherals/touch_sensor/touch_sensor_v3/pytest_touch_sens_v3.py b/examples/peripherals/touch_sensor/touch_sensor_v3/pytest_touch_sens_v3.py new file mode 100644 index 000000000000..f03c56c2ffd0 --- /dev/null +++ b/examples/peripherals/touch_sensor/touch_sensor_v3/pytest_touch_sens_v3.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32p4 +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 runners do not support touch pins') +@pytest.mark.generic +def test_touch_sens_v3(dut: Dut) -> None: + dut.expect_exact('Initial benchmark and new threshold are:') + dut.expect(r'\[CH [0-9]+\] 0: [0-9]+, [0-9]+') + dut.expect(r'benchmark \[CH [0-9]+\]: [0-9]+') + dut.expect(r'chan_data \[CH [0-9]+\]: [0-9]+') diff --git a/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/README.md b/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/README.md index 1b053da468f6..ce33f425ea6d 100644 --- a/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/README.md +++ b/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | # USB SERIAL JTAG Echo Example diff --git a/examples/protocols/.build-test-rules.yml b/examples/protocols/.build-test-rules.yml index 76a30e263232..26f38fb99caa 100644 --- a/examples/protocols/.build-test-rules.yml +++ b/examples/protocols/.build-test-rules.yml @@ -184,7 +184,7 @@ examples/protocols/modbus: disable: - if: IDF_TARGET == "esp32c5" temporary: true - reason: not supported yet # TODO: [ESP32C5] IDF-8722, IDF-8697 + reason: not supported yet # TODO: [ESP32C5] IDF-8697 depends_filepatterns: - examples/common_components/protocol_examples_common/**/* - examples/protocols/modbus/mb_example_common/**/* diff --git a/examples/protocols/http_server/async_handlers/main/main.c b/examples/protocols/http_server/async_handlers/main/main.c index 96fb13e671f0..7a1091c10d57 100644 --- a/examples/protocols/http_server/async_handlers/main/main.c +++ b/examples/protocols/http_server/async_handlers/main/main.c @@ -36,7 +36,7 @@ static const char *TAG = "example"; -// Async reqeusts are queued here while they wait to +// Async requests are queued here while they wait to // be processed by the workers static QueueHandle_t async_req_queue; diff --git a/examples/protocols/http_server/captive_portal/main/main.c b/examples/protocols/http_server/captive_portal/main/main.c index 6111a5b37a8d..8dee238e86b6 100644 --- a/examples/protocols/http_server/captive_portal/main/main.c +++ b/examples/protocols/http_server/captive_portal/main/main.c @@ -39,8 +39,8 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, MAC2STR(event->mac), event->aid); } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data; - ESP_LOGI(TAG, "station " MACSTR " leave, AID=%d", - MAC2STR(event->mac), event->aid); + ESP_LOGI(TAG, "station " MACSTR " leave, AID=%d, reason=%d", + MAC2STR(event->mac), event->aid, event->reason); } } diff --git a/examples/protocols/http_server/simple/main/main.c b/examples/protocols/http_server/simple/main/main.c index d3dfffe497f7..e13810a4e122 100644 --- a/examples/protocols/http_server/simple/main/main.c +++ b/examples/protocols/http_server/simple/main/main.c @@ -397,9 +397,9 @@ static httpd_handle_t start_webserver(void) httpd_handle_t server = NULL; httpd_config_t config = HTTPD_DEFAULT_CONFIG(); #if CONFIG_IDF_TARGET_LINUX - // Setting port as 8001 when building for Linux. Port 80 can be used only by a priviliged user in linux. - // So when a unpriviliged user tries to run the application, it throws bind error and the server is not started. - // Port 8001 can be used by an unpriviliged user as well. So the application will not throw bind error and the + // Setting port as 8001 when building for Linux. Port 80 can be used only by a privileged user in linux. + // So when a unprivileged user tries to run the application, it throws bind error and the server is not started. + // Port 8001 can be used by an unprivileged user as well. So the application will not throw bind error and the // server will be started. config.server_port = 8001; #endif // !CONFIG_IDF_TARGET_LINUX diff --git a/examples/protocols/https_request/pytest_https_request.py b/examples/protocols/https_request/pytest_https_request.py index 0afcda609e52..340945937ec9 100644 --- a/examples/protocols/https_request/pytest_https_request.py +++ b/examples/protocols/https_request/pytest_https_request.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import http.server import logging @@ -50,8 +50,10 @@ def start_https_server(server_file: str, key_file: str, server_ip: str, server_p requestHandler = https_request_handler() httpd = http.server.HTTPServer((server_ip, server_port), requestHandler) - httpd.socket = ssl.wrap_socket(httpd.socket, keyfile=key_file, - certfile=server_file, server_side=True) + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.load_cert_chain(certfile=server_file, keyfile=key_file) + + httpd.socket = ssl_context.wrap_socket(httpd.socket, server_side=True) httpd.serve_forever() diff --git a/examples/protocols/mqtt/tcp/README.md b/examples/protocols/mqtt/tcp/README.md index 52888e39dff5..07e4333e5222 100644 --- a/examples/protocols/mqtt/tcp/README.md +++ b/examples/protocols/mqtt/tcp/README.md @@ -59,3 +59,174 @@ I (5194) MQTT_EXAMPLE: MQTT_EVENT_DATA TOPIC=/topic/qos0 DATA=data ``` + +## Using Wi-Fi connection with ESP32P4 + +It is possible to use Wi-Fi connection on targets that do not support native Wi-Fi peripheral. This example demonstrates using `esp_wifi_remote` on ESP32P4 in the test configuration defined as `sdkconfig.ci.p4_wifi`. This configuration requires another ESP target with native Wi-Fi support physically connected to the ESP32-P4. + +### Configure master-slave verification + +In order to secure the physical connection between the ESP32-P4 (master) and the slave device, it is necessary to set certificates and keys for each side. +To bootstrap this step, you can use one-time generated self-signed RSA keys and certificates running: +``` +./managed_components/espressif__esp_wifi_remote/examples/test_certs/generate_test_certs.sh espressif.local +``` + +### Configure the slave project + +It is recommended to create a new project from `esp_wifi_remote` component's example with +``` +idf.py create-project-from-example "espressif/esp_wifi_remote:server" +``` +but you can also build and flash the slave project directly from the `managed_components` directory using: +``` +idf.py -C managed_components/espressif__esp_wifi_remote/examples/server/ -B build_slave +``` + +Please follow these steps to setup the slave application: +* `idf.py set-target` -- choose the slave target (must support Wi-Fi) +* `idf.py menuconfig` -- configure the physical connection and verification details: + - `CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_CA` -- CA for verifying ESP32-P4 application + - `CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_CRT` -- slave's certificate + - `CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_KEY` -- slave's private key +* `idf.py build flash monitor` + +### Configure the master project (ESP32-P4) + +similarly to the slave project, we have to configure +* the physical connection +* the verification + - `CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_CA` -- CA for verifying the slave application + - `CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_CRT` -- our own certificate + - `CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_KEY` -- our own private key + +After project configuration, you build and flash the board with +``` +idf.py build flash monitor +``` + +### Example Output of the slave device + +``` +I (7982) main_task: Returned from app_main() +I (8242) rpc_server: Received header id 2 +I (8242) pp: pp rom version: 5b8dcfa +I (8242) net80211: net80211 rom version: 5b8dcfa +I (8252) wifi:wifi driver task: 4082be8c, prio:23, stack:6656, core=0 +I (8252) wifi:wifi firmware version: feaf82d +I (8252) wifi:wifi certification version: v7.0 +I (8252) wifi:config NVS flash: enabled +I (8262) wifi:config nano formatting: disabled +I (8262) wifi:mac_version:HAL_MAC_ESP32AX_761,ut_version:N, band:0x1 +I (8272) wifi:Init data frame dynamic rx buffer num: 32 +I (8272) wifi:Init static rx mgmt buffer num: 5 +I (8282) wifi:Init management short buffer num: 32 +I (8282) wifi:Init dynamic tx buffer num: 32 +I (8292) wifi:Init static tx FG buffer num: 2 +I (8292) wifi:Init static rx buffer size: 1700 (rxctrl:92, csi:512) +I (8302) wifi:Init static rx buffer num: 10 +I (8302) wifi:Init dynamic rx buffer num: 32 +I (8302) wifi_init: rx ba win: 6 +I (8312) wifi_init: accept mbox: 6 +I (8312) wifi_init: tcpip mbox: 32 +I (8322) wifi_init: udp mbox: 6 +I (8322) wifi_init: tcp mbox: 6 +I (8322) wifi_init: tcp tx win: 5760 +I (8332) wifi_init: tcp rx win: 5760 +I (8332) wifi_init: tcp mss: 1440 +I (8342) wifi_init: WiFi IRAM OP enabled +I (8342) wifi_init: WiFi RX IRAM OP enabled +I (8352) wifi_init: WiFi SLP IRAM OP enabled +I (8362) rpc_server: Received header id 11 +I (8362) rpc_server: Received header id 4 +I (8372) rpc_server: Received header id 6 +I (8372) phy_init: phy_version 270,339aa07,Apr 3 2024,16:36:11 +I (8492) wifi:enable tsf +I (8492) rpc_server: Received WIFI event 41 +I (8502) rpc_server: Received WIFI event 2 +I (8732) rpc_server: Received header id 10 +I (8742) rpc_server: Received header id 5 +I (8752) rpc_server: Received header id 8 +I (11452) wifi:new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1, snd_ch_cfg:0x0 +I (11452) wifi:(connect)dot11_authmode:0x3, pairwise_cipher:0x3, group_cipher:0x1 +I (11452) wifi:state: init -> auth (0xb0) +I (11462) rpc_server: Received WIFI event 41 +I (11462) wifi:state: auth -> assoc (0x0) +I (11472) wifi:(assoc)RESP, Extended Capabilities length:8, operating_mode_notification:0 +I (11472) wifi:(assoc)RESP, Extended Capabilities, MBSSID:0, TWT Responder:0, OBSS Narrow Bandwidth RU In OFDMA Tolerance:0 +I (11482) wifi:Extended Capabilities length:8, operating_mode_notification:1 +I (11492) wifi:state: assoc -> run (0x10) +I (11492) wifi:(trc)phytype:CBW20-SGI, snr:50, maxRate:144, highestRateIdx:0 +W (11502) wifi:(trc)band:2G, phymode:3, highestRateIdx:0, lowestRateIdx:11, dataSchedTableSize:14 +I (11512) wifi:(trc)band:2G, rate(S-MCS7, rateIdx:0), ampdu(rate:S-MCS7, schedIdx(0, stop:8)), snr:50, ampduState:wait operational +I (11522) wifi:ifidx:0, rssi:-45, nf:-95, phytype(0x3, CBW20-SGI), phymode(0x3, 11bgn), max_rate:144, he:0, vht:0, ht:1 +I (11532) wifi:(ht)max.RxAMPDULenExponent:3(65535 bytes), MMSS:6(8 us) +W (11542) wifi:idx:0, ifx:0, tid:0, TAHI:0x1002cb4, TALO:0x1b942980, (ssn:0, win:64, cur_ssn:0), CONF:0xc0000005 +I (11572) wifi:connected with Cermakowifi, aid = 2, channel 6, BW20, bssid = 80:29:94:1b:b4:2c +I (11572) wifi:cipher(pairwise:0x3, group:0x1), pmf:0, security:WPA2-PSK, phy:11bgn, rssi:-45 +I (11582) wifi:pm start, type: 1, twt_start:0 + +I (11582) wifi:pm start, type:1, aid:0x2, trans-BSSID:80:29:94:1b:b4:2c, BSSID[5]:0x2c, mbssid(max-indicator:0, index:0), he:0 +I (11592) wifi:dp: 1, bi: 102400, li: 3, scale listen interval from 307200 us to 307200 us +I (11602) wifi:set rx beacon pti, rx_bcn_pti: 10, bcn_timeout: 25000, mt_pti: 10, mt_time: 10000 +I (11612) wifi:[ADDBA]TX addba request, tid:0, dialogtoken:1, bufsize:64, A-MSDU:0(not supported), policy:1(IMR), ssn:0(0x0) +I (11622) wifi:[ADDBA]TX addba request, tid:7, dialogtoken:2, bufsize:64, A-MSDU:0(not supported), policy:1(IMR), ssn:0(0x20) +I (11632) wifi:[ADDBA]TX addba request, tid:5, dialogtoken:3, bufsize:64, A-MSDU:0(not supported), policy:1(IMR), ssn:0(0x0) +I (11642) wifi:[ADDBA]RX addba response, status:0, tid:7/tb:0(0x1), bufsize:64, batimeout:0, txa_wnd:64 +I (11652) wifi:[ADDBA]RX addba response, status:0, tid:5/tb:0(0x1), bufsize:64, batimeout:0, txa_wnd:64 +I (11662) wifi:[ADDBA]RX addba response, status:0, tid:0/tb:1(0x1), bufsize:64, batimeout:0, txa_wnd:64 +I (11672) wifi:AP's beacon interval = 102400 us, DTIM period = 1 +I (11682) rpc_server: Received WIFI event 4 +I (15682) esp_netif_handlers: sta ip: 192.168.0.33, mask: 255.255.255.0, gw: 192.168.0.1 +I (15682) rpc_server: Received IP event 0 +I (15682) rpc_server: Main DNS:185.162.24.55 +I (15682) rpc_server: IP address:192.168.0.33 +``` + +### Example Output of the master device (ESP32-P4) + +``` +I (445) example_connect: Start example_connect. +I (455) uart: queue free spaces: 16 +I (455) eppp_link: Waiting for IP address 0 +I (3195) esp-netif_lwip-ppp: Connected +I (3195) eppp_link: Got IPv4 event: Interface "pppos_client(EPPP0)" address: 192.168.11.2 +I (3195) esp-netif_lwip-ppp: Connected +I (3195) eppp_link: Connected! 0 +I (5475) example_connect: Waiting for IP(s) +I (8405) esp_wifi_remote: esp_wifi_internal_reg_rxcb: sta: 0x4001c68a +I (9445) example_connect: Got IPv6 event: Interface "pppos_client" address: fe80:0000:0000:0000:5632:04ff:fe08:5054, type: ESP_IP6_ADDR_IS_LINK_LOCAL +I (12415) rpc_client: Main DNS:185.162.24.55 +I (12415) esp_netif_handlers: pppos_client ip: 192.168.11.2, mask: 255.255.255.255, gw: 192.168.11.1 +I (12415) rpc_client: EPPP IP:192.168.11.1 +I (12415) example_connect: Got IPv4 event: Interface "pppos_client" address: 192.168.11.2 +I (12425) rpc_client: WIFI IP:192.168.0.33 +I (12435) example_common: Connected to pppos_client +I (12445) rpc_client: WIFI GW:192.168.0.1 +I (12455) example_common: - IPv6 address: fe80:0000:0000:0000:5632:04ff:fe08:5054, type: ESP_IP6_ADDR_IS_LINK_LOCAL +I (12455) rpc_client: WIFI mask:255.255.255.0 +I (12465) example_common: Connected to pppos_client +I (12475) example_common: - IPv4 address: 192.168.11.2, +I (12475) example_common: - IPv6 address: fe80:0000:0000:0000:5c3b:1291:05ca:6dc8, type: ESP_IP6_ADDR_IS_LINK_LOCAL +I (12495) mqtt_example: Other event id:7 +I (12495) main_task: Returned from app_main() +I (12905) mqtt_example: MQTT_EVENT_CONNECTED +I (12905) mqtt_example: sent publish successful, msg_id=36013 +I (12905) mqtt_example: sent subscribe successful, msg_id=44233 +I (12905) mqtt_example: sent subscribe successful, msg_id=36633 +I (12915) mqtt_example: sent unsubscribe successful, msg_id=15480 +I (13115) mqtt_example: MQTT_EVENT_PUBLISHED, msg_id=36013 +I (13415) mqtt_example: MQTT_EVENT_SUBSCRIBED, msg_id=44233 +I (13415) mqtt_example: sent publish successful, msg_id=0 +I (13415) mqtt_example: MQTT_EVENT_SUBSCRIBED, msg_id=36633 +I (13415) mqtt_example: sent publish successful, msg_id=0 +I (13425) mqtt_example: MQTT_EVENT_DATA +TOPIC=/topic/qos1 +DATA=data_3 +I (13435) mqtt_example: MQTT_EVENT_UNSUBSCRIBED, msg_id=15480 +I (13615) mqtt_example: MQTT_EVENT_DATA +TOPIC=/topic/qos0 +DATA=data +I (13925) mqtt_example: MQTT_EVENT_DATA +TOPIC=/topic/qos0 +``` diff --git a/examples/protocols/mqtt/tcp/main/idf_component.yml b/examples/protocols/mqtt/tcp/main/idf_component.yml index 718194867b74..1b1f6dbd59a1 100644 --- a/examples/protocols/mqtt/tcp/main/idf_component.yml +++ b/examples/protocols/mqtt/tcp/main/idf_component.yml @@ -1,3 +1,7 @@ dependencies: protocol_examples_common: path: ${IDF_PATH}/examples/common_components/protocol_examples_common + espressif/esp_wifi_remote: + version: ">=0.1.12" + rules: + - if: "target in [esp32p4, esp32h2]" diff --git a/examples/protocols/mqtt/tcp/sdkconfig.ci.p4_wifi b/examples/protocols/mqtt/tcp/sdkconfig.ci.p4_wifi new file mode 100644 index 000000000000..7a5574c7f3aa --- /dev/null +++ b/examples/protocols/mqtt/tcp/sdkconfig.ci.p4_wifi @@ -0,0 +1,4 @@ +CONFIG_IDF_TARGET="esp32p4" +CONFIG_EXAMPLE_CONNECT_WIFI=y +CONFIG_ESP_WIFI_REMOTE_EPPP_UART_TX_PIN=17 +CONFIG_ESP_WIFI_REMOTE_EPPP_UART_RX_PIN=16 diff --git a/examples/protocols/sockets/tcp_client_multi_net/main/tcp_client_multiple.c b/examples/protocols/sockets/tcp_client_multi_net/main/tcp_client_multiple.c index d537adf1bd33..2c9111460029 100644 --- a/examples/protocols/sockets/tcp_client_multi_net/main/tcp_client_multiple.c +++ b/examples/protocols/sockets/tcp_client_multi_net/main/tcp_client_multiple.c @@ -11,7 +11,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_netif.h" -#include "esp_eth.h" #include "esp_event.h" #include "esp_log.h" #include "sdkconfig.h" @@ -89,13 +88,13 @@ static void app_multiple_handle(esp_ip4_addr_t *ip4_addr, esp_netif_t *esp_netif ret = send(sock, payload, strlen(payload), 0); if (ret < 0) { - ESP_LOGE(TAG, "\"%s\" Error occured during sending: errno %d", netif_name, errno); + ESP_LOGE(TAG, "\"%s\" Error occurred during sending: errno %d", netif_name, errno); goto app_multiple_handle_fail; } ret = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0); if (ret < 0) { - ESP_LOGE(TAG, "\"%s\" Error occured during receiving: errno %d", netif_name, errno); + ESP_LOGE(TAG, "\"%s\" Error occurred during receiving: errno %d", netif_name, errno); } else if (ret > 0){ rx_buffer[ret] = 0; // Null-terminate whatever we received and treat like a string ESP_LOGI(TAG, "\"%s\" Received Data %d bytes", netif_name, ret); diff --git a/examples/provisioning/wifi_prov_mgr/main/app_main.c b/examples/provisioning/wifi_prov_mgr/main/app_main.c index 9c5f2a506485..233e450fea80 100644 --- a/examples/provisioning/wifi_prov_mgr/main/app_main.c +++ b/examples/provisioning/wifi_prov_mgr/main/app_main.c @@ -136,7 +136,7 @@ static void event_handler(void* arg, esp_event_base_t event_base, #ifdef CONFIG_EXAMPLE_RESET_PROV_MGR_ON_FAILURE retries++; if (retries >= CONFIG_EXAMPLE_PROV_MGR_MAX_RETRY_CNT) { - ESP_LOGI(TAG, "Failed to connect with provisioned AP, reseting provisioned credentials"); + ESP_LOGI(TAG, "Failed to connect with provisioned AP, resetting provisioned credentials"); wifi_prov_mgr_reset_sm_state_on_failure(); retries = 0; } diff --git a/examples/storage/.build-test-rules.yml b/examples/storage/.build-test-rules.yml index 028df4eb16ef..cc6f28981be3 100644 --- a/examples/storage/.build-test-rules.yml +++ b/examples/storage/.build-test-rules.yml @@ -46,10 +46,6 @@ examples/storage/nvs_rw_blob: depends_components: - nvs_flash - driver - disable: - - if: IDF_TARGET == "esp32c5" - temporary: true - reason: not supported yet # TODO: [ESP32C5] IDF-8717 disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: only one target per arch needed @@ -115,16 +111,13 @@ examples/storage/perf_benchmark: - esp_partition - esp_driver_sdmmc disable: - - if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["sdmmc_1line", "sdmmc_4line", "sdspi_1line"] - temporary: true - reason: SDMMC and SDSPI not supported on P4 yet # TODO: IDF-6502, IDF-7501 - if: IDF_TARGET == "esp32c5" temporary: true reason: not supported yet # TODO: [ESP32C5] IDF-8704 disable_test: - - if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["spiflash"] + - if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["sdmmc_1line", "sdmmc_4line", "sdspi_1line"] temporary: true - reason: SPIFLASH not supported on P4 yet, only build stage enabled # TODO: IDF-7499 + reason: lack of runners, build only # TODO: IDF-8970 examples/storage/sd_card/sdmmc: depends_components: diff --git a/examples/storage/littlefs/main/idf_component.yml b/examples/storage/littlefs/main/idf_component.yml index 427e1c36bdeb..0056553732a3 100644 --- a/examples/storage/littlefs/main/idf_component.yml +++ b/examples/storage/littlefs/main/idf_component.yml @@ -1,3 +1,3 @@ ## IDF Component Manager Manifest File dependencies: - joltwallet/littlefs: "~=1.14.2" + joltwallet/littlefs: "~=1.14.4" diff --git a/examples/storage/nvs_rw_blob/README.md b/examples/storage/nvs_rw_blob/README.md index 7563617da8c0..bdded9bfc5a4 100644 --- a/examples/storage/nvs_rw_blob/README.md +++ b/examples/storage/nvs_rw_blob/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Non-Volatile Storage (NVS) Read and Write Example diff --git a/examples/storage/perf_benchmark/README.md b/examples/storage/perf_benchmark/README.md index fefb02b31f21..d3f4f6b5d17b 100644 --- a/examples/storage/perf_benchmark/README.md +++ b/examples/storage/perf_benchmark/README.md @@ -54,14 +54,14 @@ This example doesn't utilize card detect (CD) and write protect (WP) signals fro The table below shows the default pin assignments. -SD card pin | SPI pin | ESP32 pin | ESP32-S2 | ESP32-S3 | ESP32-H2 | ESP32-C3 and other chips | Notes -------------|---------|---------------|----------|----------|----------|--------------------------|------------- - D0 | MISO | GPIO2 | GPIO37 | GPIO37 | GPIO0 | GPIO6 | 10k pullup - D1 | - | GPIO4 | - | GPIO38 | - | - | not used in 1-line SD mode; 10k pullup in 4-line mode - D2 | - | GPIO12 (MTDI) | - | GPIO33 | - | - | not used in 1-line SD mode; 10k pullup in 4-line mode - D3 | CS | GPIO13 (MTCK) | GPIO34 | GPIO34 | GPIO1 | GPIO1 | not used in 1-line SD mode, but card's D3 pin must have a 10k pullup - CLK | SCK | GPIO14 (MTMS) | GPIO36 | GPIO36 | GPIO4 | GPIO5 | 10k pullup - CMD | MOSI | GPIO15 (MTDO) | GPIO35 | GPIO35 | GPIO5 | GPIO4 | 10k pullup +SD card pin | SPI pin | ESP32 pin | ESP32-S2 | ESP32-S3 | ESP32-P4 SDMMC | ESP32-P4 SDSPI | ESP32-H2 | ESP32-C3 and other chips | Notes +------------|---------|---------------|----------|----------|----------------|----------------|----------|--------------------------|------------- + D0 | MISO | GPIO2 | GPIO37 | GPIO37 | GPIO43 | GPIO13 | GPIO0 | GPIO6 | 10k pullup + D1 | - | GPIO4 | - | GPIO38 | GPIO44 | - | - | - | not used in 1-line SD mode; 10k pullup in 4-line mode + D2 | - | GPIO12 (MTDI) | - | GPIO33 | GPIO39 | - | - | - | not used in 1-line SD mode; 10k pullup in 4-line mode + D3 | CS | GPIO13 (MTCK) | GPIO34 | GPIO34 | GPIO40 | GPIO10 | GPIO1 | GPIO1 | not used in 1-line SD mode, but card's D3 pin must have a 10k pullup + CLK | SCK | GPIO14 (MTMS) | GPIO36 | GPIO36 | GPIO41 | GPIO12 | GPIO4 | GPIO5 | 10k pullup + CMD | MOSI | GPIO15 (MTDO) | GPIO35 | GPIO35 | GPIO42 | GPIO11 | GPIO5 | GPIO4 | 10k pullup ### 4-line and 1-line SD modes @@ -97,6 +97,21 @@ This command will burn the `XPD_SDIO_TIEH`, `XPD_SDIO_FORCE`, and `XPD_SDIO_REG` See [the document about pullup requirements](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/sd_pullup_requirements.html) for more details about pullup support and compatibility of modules and development boards. +#### ESP32-P4 related notes + +This only applies when `Test SD card` setting in `Performance Benchmark Example Configuration` is enabled. + +On ESP32-P4, Slot 1 of the SDMMC peripheral is connected to GPIO pins using GPIO matrix. This allows arbitrary GPIOs to be used to connect an SD card. In this example, GPIOs can be configured in two ways: + +1. Using menuconfig: Run `idf.py menuconfig` in the project directory and open `Performance Benchmark Example Configuration` menu. +2. In the source code: See the initialization of `sdmmc_slot_config_t slot_config` structure in the example code. + +If pins selected correspond with default pins used for ESP32-P4 SDMMC (i.e. SD card slot is connected to them), possibly an additional setting up needs to be done. + +These pins are able to connect to an ultra high-speed SD card (UHS-I) which requires 1.8V switching (instead of the regular 3.3V). This means the user has to provide an external LDO power supply to use them, or to enable and configure an internal LDO via `idf.py menuconfig` -> `SD/MMC Example Configuration` -> `SD power supply comes from internal LDO IO`. + +When using different GPIO pins this is not required and `SD power supply comes from internal LDO IO` setting can be disabled. + ### Note about SPIFFS The test for SPIFFS is run only once, because SPIFFS has a problem with deleting files. diff --git a/examples/storage/perf_benchmark/main/Kconfig.projbuild b/examples/storage/perf_benchmark/main/Kconfig.projbuild index e12a3268ab7b..82debaba8f0d 100644 --- a/examples/storage/perf_benchmark/main/Kconfig.projbuild +++ b/examples/storage/perf_benchmark/main/Kconfig.projbuild @@ -179,28 +179,34 @@ menu "Performance Benchmark Example Configuration" config EXAMPLE_PIN_CMD int "CMD GPIO number" default 35 if IDF_TARGET_ESP32S3 + default 44 if IDF_TARGET_ESP32P4 config EXAMPLE_PIN_CLK int "CLK GPIO number" default 36 if IDF_TARGET_ESP32S3 + default 43 if IDF_TARGET_ESP32P4 config EXAMPLE_PIN_D0 int "D0 GPIO number" default 37 if IDF_TARGET_ESP32S3 + default 39 if IDF_TARGET_ESP32P4 if EXAMPLE_SDMMC_BUS_WIDTH_4 config EXAMPLE_PIN_D1 int "D1 GPIO number" default 38 if IDF_TARGET_ESP32S3 + default 40 if IDF_TARGET_ESP32P4 config EXAMPLE_PIN_D2 int "D2 GPIO number" default 33 if IDF_TARGET_ESP32S3 + default 41 if IDF_TARGET_ESP32P4 config EXAMPLE_PIN_D3 int "D3 GPIO number" default 34 if IDF_TARGET_ESP32S3 + default 42 if IDF_TARGET_ESP32P4 endif # EXAMPLE_SDMMC_BUS_WIDTH_4 @@ -243,6 +249,22 @@ menu "Performance Benchmark Example Configuration" endif # EXAMPLE_USE_SDSPI + config EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + depends on SOC_SDMMC_IO_POWER_EXTERNAL + bool "SD power supply comes from internal LDO IO (READ HELP!)" + default y + help + Only needed when the SD card is connected to specific IO pins which can be used for high-speed SDMMC. + Please read the schematic first and check if the SD VDD is connected to any internal LDO output. + Unselect this option if the SD card is powered by an external power supply. + + config EXAMPLE_SD_PWR_CTRL_LDO_IO_ID + depends on SOC_SDMMC_IO_POWER_EXTERNAL && EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + int "LDO ID" + default 4 if IDF_TARGET_ESP32P4 + help + Please read the schematic first and input your LDO ID. + endmenu # "SD card test config" endmenu # "Performance Monitor Example Configuration" diff --git a/examples/storage/perf_benchmark/main/perf_benchmark_example_sd_utils.c b/examples/storage/perf_benchmark/main/perf_benchmark_example_sd_utils.c index bfd647788691..9979d6d821d5 100644 --- a/examples/storage/perf_benchmark/main/perf_benchmark_example_sd_utils.c +++ b/examples/storage/perf_benchmark/main/perf_benchmark_example_sd_utils.c @@ -13,6 +13,10 @@ #if SOC_SDMMC_HOST_SUPPORTED #include "driver/sdmmc_host.h" #endif +#if SOC_SDMMC_IO_POWER_EXTERNAL +#include "sd_pwr_ctrl_by_on_chip_ldo.h" +#endif +#include "esp_err.h" #include "esp_log.h" #ifdef CONFIG_EXAMPLE_TEST_SD_CARD @@ -32,6 +36,22 @@ void init_sd_config(sdmmc_host_t *out_host, sdmmc_slot_config_t *out_slot_config void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_config, int freq_khz) { #endif // CONFIG_EXAMPLE_USE_SDSPI + // For SoCs where the SD power can be supplied both via an internal or external (e.g. on-board LDO) power supply. + // When using specific IO pins (which can be used for ultra high-speed SDMMC) to connect to the SD card + // and the internal LDO power supply, we need to initialize the power supply first. +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + sd_pwr_ctrl_ldo_config_t ldo_config = { + .ldo_chan_id = CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_IO_ID, + }; + sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; + + esp_err_t sd_pwr_ctrl_ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); + if (sd_pwr_ctrl_ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to create a new an on-chip LDO power control driver"); + ESP_ERROR_CHECK(sd_pwr_ctrl_ret); + } +#endif // CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + // By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT (20MHz) // For setting a specific frequency, use host.max_freq_khz // (range 400kHz - 40MHz for SDMMC, 400kHz - 20MHz for SDSPI) @@ -91,6 +111,11 @@ void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_conf slot_config.gpio_cs = CONFIG_EXAMPLE_PIN_CS; slot_config.host_id = host.slot; #endif // CONFIG_EXAMPLE_USE_SDSPI + +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + host.pwr_ctrl_handle = pwr_ctrl_handle; +#endif // CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + *out_host = host; *out_slot_config = slot_config; } @@ -137,6 +162,18 @@ void deinit_sd_card(sdmmc_card_t **card) { #else // CONFIG_EXAMPLE_USE_SDMMC sdspi_host_deinit(); #endif // CONFIG_EXAMPLE_USE_SDSPI + + // Deinitialize the power control driver if it was used +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + sd_pwr_ctrl_handle_t pwr_ctrl_handle = (*card)->host.pwr_ctrl_handle; + esp_err_t ret = sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to delete the on-chip LDO power control driver"); + ESP_ERROR_CHECK(ret); + } + pwr_ctrl_handle = NULL; +#endif + free(*card); *card = NULL; } diff --git a/examples/storage/sd_card/sdmmc/README.md b/examples/storage/sd_card/sdmmc/README.md index 3e5006020b0d..8f665f208e0e 100644 --- a/examples/storage/sd_card/sdmmc/README.md +++ b/examples/storage/sd_card/sdmmc/README.md @@ -70,7 +70,7 @@ GPIO34 | D3 | not used in 1-line SD mode, but card's D3 pin must On ESP32-P4, Slot 1 of the SDMMC peripheral is connected to GPIO pins using GPIO matrix. This allows arbitrary GPIOs to be used to connect an SD card. In this example, GPIOs can be configured in two ways: -1. Using menuconfig: Run `idf.py menuconfig` in the project directory and open "SD/MMC Example Configuration" menu. +1. Using menuconfig: Run `idf.py menuconfig` in the project directory and open `SD/MMC Example Configuration` menu. 2. In the source code: See the initialization of `sdmmc_slot_config_t slot_config` structure in the example code. The table below lists the default pin assignments. @@ -84,6 +84,10 @@ GPIO40 | D1 | not used in 1-line SD mode; 10k pullup in 4-line m GPIO41 | D2 | not used in 1-line SD mode; 10k pullup in 4-line mode GPIO42 | D3 | not used in 1-line SD mode, but card's D3 pin must have a 10k pullup +Default dedicated pins on ESP32-P4 are able to connect to an ultra high-speed SD card (UHS-I) which requires 1.8V switching (instead of the regular 3.3V). This means the user has to provide an external LDO power supply to use them, or to enable and configure an internal LDO via `idf.py menuconfig` -> `SD/MMC Example Configuration` -> `SD power supply comes from internal LDO IO`. + +When using different GPIO pins this is not required and `SD power supply comes from internal LDO IO` setting can be disabled. + ### 4-line and 1-line SD modes By default, this example uses 4 line SD mode, utilizing 6 pins: CLK, CMD, D0 - D3. It is possible to use 1-line mode (CLK, CMD, D0) by changing "SD/MMC bus width" in the example configuration menu (see `CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_1`). diff --git a/examples/storage/sd_card/sdmmc/main/Kconfig.projbuild b/examples/storage/sd_card/sdmmc/main/Kconfig.projbuild index 3e74dfacf75c..70449a8e3956 100644 --- a/examples/storage/sd_card/sdmmc/main/Kconfig.projbuild +++ b/examples/storage/sd_card/sdmmc/main/Kconfig.projbuild @@ -152,18 +152,19 @@ menu "SD/MMC Example Configuration" endif # EXAMPLE_SDMMC_BUS_WIDTH_4 - config EXAMPLE_SDMMC_IO_POWER_INTERNAL_LDO + config EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO depends on SOC_SDMMC_IO_POWER_EXTERNAL - bool "SDMMC IO power supply comes from internal LDO (READ HELP!)" + bool "SD power supply comes from internal LDO IO (READ HELP!)" default y help - Please read the schematic first and check if the SDMMC VDD is connected to any internal LDO output. - If the SDMMC is powered by an external supplier, unselect me + Only needed when the SD card is connected to specific IO pins which can be used for high-speed SDMMC. + Please read the schematic first and check if the SD VDD is connected to any internal LDO output. + Unselect this option if the SD card is powered by an external power supply. - config EXAMPLE_SDMMC_IO_LDO_ID - depends on SOC_SDMMC_IO_POWER_EXTERNAL + config EXAMPLE_SD_PWR_CTRL_LDO_IO_ID + depends on SOC_SDMMC_IO_POWER_EXTERNAL && EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO int "LDO ID" - default 4 + default 4 if IDF_TARGET_ESP32P4 help - Please read the schematic first and input your LDO ID + Please read the schematic first and input your LDO ID. endmenu diff --git a/examples/storage/sd_card/sdmmc/main/sd_card_example_main.c b/examples/storage/sd_card/sdmmc/main/sd_card_example_main.c index e752d3a3cbbb..6821d05fb24a 100644 --- a/examples/storage/sd_card/sdmmc/main/sd_card_example_main.c +++ b/examples/storage/sd_card/sdmmc/main/sd_card_example_main.c @@ -15,7 +15,9 @@ #include "sdmmc_cmd.h" #include "driver/sdmmc_host.h" #include "sd_test_io.h" +#if SOC_SDMMC_IO_POWER_EXTERNAL #include "sd_pwr_ctrl_by_on_chip_ldo.h" +#endif #define EXAMPLE_MAX_CHAR_SIZE 64 @@ -127,18 +129,18 @@ void app_main(void) // Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000; sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - /** - * On these chips, the SDMMC IO power is supplied externally - */ -#if CONFIG_EXAMPLE_SDMMC_IO_POWER_INTERNAL_LDO + // For SoCs where the SD power can be supplied both via an internal or external (e.g. on-board LDO) power supply. + // When using specific IO pins (which can be used for ultra high-speed SDMMC) to connect to the SD card + // and the internal LDO power supply, we need to initialize the power supply first. +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO sd_pwr_ctrl_ldo_config_t ldo_config = { - .ldo_chan_id = 4, // `LDO_VO4` is used as the SDMMC IO power + .ldo_chan_id = CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_IO_ID, }; sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to new an on-chip ldo power control driver"); + ESP_LOGE(TAG, "Failed to create a new on-chip LDO power control driver"); return; } host.pwr_ctrl_handle = pwr_ctrl_handle; @@ -237,7 +239,7 @@ void app_main(void) ESP_LOGI(TAG, "file still exists"); return; } else { - ESP_LOGI(TAG, "file doesnt exist, format done"); + ESP_LOGI(TAG, "file doesn't exist, formatting done"); } #endif // CONFIG_EXAMPLE_FORMAT_SD_CARD @@ -257,14 +259,14 @@ void app_main(void) // All done, unmount partition and disable SDMMC peripheral esp_vfs_fat_sdcard_unmount(mount_point, card); + ESP_LOGI(TAG, "Card unmounted"); -#if SOC_SDMMC_IO_POWER_EXTERNAL + // Deinitialize the power control driver if it was used +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO ret = sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle); if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to delete on-chip ldo power control driver"); + ESP_LOGE(TAG, "Failed to delete the on-chip LDO power control driver"); return; } #endif - - ESP_LOGI(TAG, "Card unmounted"); } diff --git a/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py b/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py index 0a1685e87322..d6bbb9bb55e1 100644 --- a/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py +++ b/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py @@ -1,7 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 - - import logging import re @@ -32,7 +30,7 @@ def test_examples_sd_card_sdmmc(dut: Dut) -> None: 'Reading file /sdcard/foo.txt', "Read from file: 'Hello {}!'".format(name)) sd_card_format = re.compile(str.encode('Formatting card, allocation unit size=\\S+')) - message_list2 = ('file doesnt exist, format done', + message_list2 = ("file doesn't exist, formatting done", 'Opening file /sdcard/nihao.txt', 'File written', 'Reading file /sdcard/nihao.txt', diff --git a/examples/storage/sd_card/sdspi/README.md b/examples/storage/sd_card/sdspi/README.md index 4e52527838ed..1432abf55794 100644 --- a/examples/storage/sd_card/sdspi/README.md +++ b/examples/storage/sd_card/sdspi/README.md @@ -41,12 +41,12 @@ This example doesn't utilize card detect (CD) and write protect (WP) signals fro The table below shows the default pin assignments. -SD card pin | SPI pin | ESP32 pin | ESP32-S2, ESP32-S3 | ESP32-H2 | ESP32-C3 and other chips | Notes -------------|---------|---------------|--------------------|----------|---------------------------|------------- - D0 | MISO | GPIO2 | GPIO37 | GPIO0 | GPIO6 | - D3 | CS | GPIO13 (MTCK) | GPIO34 | GPIO1 | GPIO1 | - CLK | SCK | GPIO14 (MTMS) | GPIO36 | GPIO4 | GPIO5 | - CMD | MOSI | GPIO15 (MTDO) | GPIO35 | GPIO5 | GPIO4 | 10k pullup +SD card pin | SPI pin | ESP32 pin | ESP32-S2, ESP32-S3 | ESP32-P4 | ESP32-H2 | ESP32-C3 and other chips | Notes +------------|---------|---------------|--------------------|----------|----------|--------------------------|------------ + D0 | MISO | GPIO2 | GPIO37 | GPIO13 | GPIO0 | GPIO6 | + D3 | CS | GPIO13 (MTCK) | GPIO34 | GPIO10 | GPIO1 | GPIO1 | + CLK | SCK | GPIO14 (MTMS) | GPIO36 | GPIO12 | GPIO4 | GPIO5 | + CMD | MOSI | GPIO15 (MTDO) | GPIO35 | GPIO11 | GPIO5 | GPIO4 | 10k pullup #### ESP32 related notes @@ -63,6 +63,28 @@ With the default pin assignments, this example is compatible ESP32-S2-USB-OTG an For other development boards, adjust the pin assignments as explained above. +#### ESP32-P4 related notes + +On ESP32-P4, Slot 1 of the SDMMC peripheral is connected to GPIO pins using GPIO matrix. This allows arbitrary GPIOs to be used to connect an SD card. In this example, GPIOs can be configured in two ways: + +1. Using menuconfig: Run `idf.py menuconfig` in the project directory and open `SD SPI Example Configuration` menu. +2. In the source code: See the initialization of `sdmmc_slot_config_t slot_config` structure in the example code. + +Default pins for SDSPI are listed in the table above [Pin assignments](#1-pin-assignments) and using them doesn't require any additional settings. + +However on some development boards the SD card slot can be wired to default dedicated pins for SDMMC, which are listed in the table below. + +SD card pin | ESP32-P4 pin +------------|-------------- +D0 (MISO) | GPIO39 +D3 (CS) | GPIO42 +CLK (SCK) | GPIO43 +CMD (MOSI) | GPIO44 + +These pins are able to connect to an ultra high-speed SD card (UHS-I) which requires 1.8V switching (instead of the regular 3.3V). This means the user has to provide an external LDO power supply to use them, or to enable and configure an internal LDO via `idf.py menuconfig` -> `SD/MMC Example Configuration` -> `SD power supply comes from internal LDO IO`. + +When using different GPIO pins this is not required and `SD power supply comes from internal LDO IO` setting can be disabled. + #### Notes for ESP32-C3 and other chips Espressif doesn't offer development boards with an SD card slot for these chips. Please check the pin assignments and adjust them for your board if necessary. The process to change pin assignments is described above. diff --git a/examples/storage/sd_card/sdspi/main/Kconfig.projbuild b/examples/storage/sd_card/sdspi/main/Kconfig.projbuild index 64f1c561e0b8..77fd451ed70c 100644 --- a/examples/storage/sd_card/sdspi/main/Kconfig.projbuild +++ b/examples/storage/sd_card/sdspi/main/Kconfig.projbuild @@ -93,4 +93,19 @@ menu "SD SPI Example Configuration" default 6 if IDF_TARGET_ESP32S3 default 1 + config EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + depends on SOC_SDMMC_IO_POWER_EXTERNAL + bool "SD power supply comes from internal LDO IO (READ HELP!)" + default n + help + Only needed when the SD card is connected to specific IO pins which can be used for high-speed SDMMC. + Please read the schematic first and check if the SD VDD is connected to any internal LDO output. + Unselect this option if the SD card is powered by an external power supply. + + config EXAMPLE_SD_PWR_CTRL_LDO_IO_ID + depends on SOC_SDMMC_IO_POWER_EXTERNAL && EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + int "LDO ID" + default 4 if IDF_TARGET_ESP32P4 + help + Please read the schematic first and input your LDO ID. endmenu diff --git a/examples/storage/sd_card/sdspi/main/sd_card_example_main.c b/examples/storage/sd_card/sdspi/main/sd_card_example_main.c index d5edc7503ecc..7f3a339e4164 100644 --- a/examples/storage/sd_card/sdspi/main/sd_card_example_main.c +++ b/examples/storage/sd_card/sdspi/main/sd_card_example_main.c @@ -14,6 +14,9 @@ #include "esp_vfs_fat.h" #include "sdmmc_cmd.h" #include "sd_test_io.h" +#if SOC_SDMMC_IO_POWER_EXTERNAL +#include "sd_pwr_ctrl_by_on_chip_ldo.h" +#endif #define EXAMPLE_MAX_CHAR_SIZE 64 @@ -120,6 +123,23 @@ void app_main(void) // Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000; sdmmc_host_t host = SDSPI_HOST_DEFAULT(); + // For SoCs where the SD power can be supplied both via an internal or external (e.g. on-board LDO) power supply. + // When using specific IO pins (which can be used for ultra high-speed SDMMC) to connect to the SD card + // and the internal LDO power supply, we need to initialize the power supply first. +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + sd_pwr_ctrl_ldo_config_t ldo_config = { + .ldo_chan_id = CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_IO_ID, + }; + sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; + + ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to create a new on-chip LDO power control driver"); + return; + } + host.pwr_ctrl_handle = pwr_ctrl_handle; +#endif + spi_bus_config_t bus_cfg = { .mosi_io_num = PIN_NUM_MOSI, .miso_io_num = PIN_NUM_MISO, @@ -128,6 +148,7 @@ void app_main(void) .quadhd_io_num = -1, .max_transfer_sz = 4000, }; + ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize bus."); @@ -205,7 +226,7 @@ void app_main(void) ESP_LOGI(TAG, "file still exists"); return; } else { - ESP_LOGI(TAG, "file doesnt exist, format done"); + ESP_LOGI(TAG, "file doesn't exist, formatting done"); } #endif // CONFIG_EXAMPLE_FORMAT_SD_CARD @@ -229,4 +250,13 @@ void app_main(void) //deinitialize the bus after all devices are removed spi_bus_free(host.slot); + + // Deinitialize the power control driver if it was used +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + ret = sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to delete the on-chip LDO power control driver"); + return; + } +#endif } diff --git a/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py b/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py index 4f2b42bb58e4..ddec7002bf19 100644 --- a/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py +++ b/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py @@ -1,7 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 - - import logging import re @@ -33,7 +31,7 @@ def test_examples_sd_card_sdspi(dut: Dut) -> None: 'Reading file /sdcard/foo.txt', "Read from file: 'Hello {}!'".format(name)) sd_card_format = re.compile(str.encode('Formatting card, allocation unit size=\\S+')) - message_list2 = ('file doesnt exist, format done', + message_list2 = ("file doesn't exist, formatting done", 'Opening file /sdcard/nihao.txt', 'File written', 'Reading file /sdcard/nihao.txt', diff --git a/examples/system/.build-test-rules.yml b/examples/system/.build-test-rules.yml index 5bc2392b6209..5ab62dc82e90 100644 --- a/examples/system/.build-test-rules.yml +++ b/examples/system/.build-test-rules.yml @@ -79,10 +79,6 @@ examples/system/freertos: - freertos examples/system/gcov: - disable: - - if: IDF_TARGET == "esp32c5" - temporary: true - reason: not supported yet #TODO: IDF-8717 disable_test: - if: IDF_TARGET != "esp32" temporary: true @@ -264,6 +260,18 @@ examples/system/ulp/lp_core/gpio: depends_components: - ulp +examples/system/ulp/lp_core/gpio_intr_pulse_counter: + enable: + - if: SOC_LP_CORE_SUPPORTED == 1 + depends_components: + - ulp + +examples/system/ulp/lp_core/interrupt: + enable: + - if: SOC_LP_CORE_SUPPORTED == 1 + depends_components: + - ulp + examples/system/ulp/lp_core/lp_i2c: enable: - if: SOC_LP_I2C_SUPPORTED == 1 diff --git a/examples/system/deep_sleep/main/Kconfig.projbuild b/examples/system/deep_sleep/main/Kconfig.projbuild index 51dffc1f8cac..7c34046cda61 100644 --- a/examples/system/deep_sleep/main/Kconfig.projbuild +++ b/examples/system/deep_sleep/main/Kconfig.projbuild @@ -44,6 +44,7 @@ menu "Example Configuration" range 7 14 if IDF_TARGET_ESP32H2 range 0 21 if IDF_TARGET_ESP32S2 range 0 21 if IDF_TARGET_ESP32S3 + range 0 15 if IDF_TARGET_ESP32P4 choice EXAMPLE_EXT1_WAKEUP_PIN_1_SEL prompt "Enable wakeup from PIN_1" @@ -118,6 +119,7 @@ menu "Example Configuration" range 7 14 if IDF_TARGET_ESP32H2 range 0 21 if IDF_TARGET_ESP32S2 range 0 21 if IDF_TARGET_ESP32S3 + range 0 15 if IDF_TARGET_ESP32P4 choice EXAMPLE_EXT1_WAKEUP_PIN_2_SEL prompt "Enable wakeup from PIN_2" @@ -247,7 +249,7 @@ menu "Example Configuration" if we turn off the RTC_PERIPH domain or if certain chips lack the RTC_PERIPH domain, we will use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep. but if we turn on the RTC_PERIPH domain, we don not need to use HOLD feature and this will - increase some power comsumption. + increase some power consumption. EXT0 wakeup source resides in the same power domain as RTCIO (RTC Periph), so internal pull-up/downs are always available. There's no need to explicitly force it on for EXT0. @@ -259,7 +261,7 @@ menu "Example Configuration" depends on SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP help This option enables wake up from GPIO. Be aware that if you use low level to trigger wakeup, we strongly - recommand you to connect external pull-up resistance. + recommend you to connect external pull-up resistance. menu "GPIO wakeup configuration" visible if EXAMPLE_GPIO_WAKEUP @@ -268,6 +270,7 @@ menu "Example Configuration" int "Enable wakeup from GPIO" default 0 range 0 7 if IDF_TARGET_ESP32C6 + range 0 15 if IDF_TARGET_ESP32P4 range 0 5 if !IDF_TARGET_ESP32C6 config EXAMPLE_GPIO_WAKEUP_HIGH_LEVEL diff --git a/examples/system/deep_sleep/main/touch_wakeup.c b/examples/system/deep_sleep/main/touch_wakeup.c index c2dd41daf881..13d4ff64d4d5 100644 --- a/examples/system/deep_sleep/main/touch_wakeup.c +++ b/examples/system/deep_sleep/main/touch_wakeup.c @@ -50,7 +50,7 @@ void example_deep_sleep_register_touch_wakeup(void) // If use touch pad wake up, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'. touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // Set reference voltage for charging/discharging - // In this case, the high reference valtage will be 2.4V - 1V = 1.4V + // In this case, the high reference voltage will be 2.4V - 1V = 1.4V // The low reference voltage will be 0.5 // The larger the range, the larger the pulse count value. touch_pad_set_voltage(TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); @@ -104,6 +104,8 @@ void example_deep_sleep_register_touch_wakeup(void) #endif printf("Enabling touch pad wakeup\n"); ESP_ERROR_CHECK(esp_sleep_enable_touchpad_wakeup()); +#if SOC_PM_SUPPORT_RTC_PERIPH_PD ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); +#endif } #endif // CONFIG_EXAMPLE_TOUCH_WAKEUP diff --git a/examples/system/light_sleep/main/CMakeLists.txt b/examples/system/light_sleep/main/CMakeLists.txt index 25d2112b95f1..f36ab83fd89e 100644 --- a/examples/system/light_sleep/main/CMakeLists.txt +++ b/examples/system/light_sleep/main/CMakeLists.txt @@ -9,5 +9,9 @@ if(IDF_TARGET IN_LIST TOUCH_ELEMENT_COMPATIBLE_TARGETS) list(APPEND srcs "touch_wakeup.c") endif() +if(IDF_TARGET STREQUAL "esp32p4") + list(APPEND srcs "touch_sens_wakeup.c") +endif() + idf_component_register(SRCS ${srcs} INCLUDE_DIRS ".") diff --git a/examples/system/light_sleep/main/light_sleep_example.h b/examples/system/light_sleep/main/light_sleep_example.h index c3401c4aed8e..cb62682502cc 100644 --- a/examples/system/light_sleep/main/light_sleep_example.h +++ b/examples/system/light_sleep/main/light_sleep_example.h @@ -1,15 +1,20 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #pragma once +#include "sdkconfig.h" + #ifdef __cplusplus extern "C" { #endif +// TODO: [ESP32P4] add P4 when runner is ready +#define EXAMPLE_TOUCH_LSLEEP_WAKEUP_SUPPORT (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3) + void example_wait_gpio_inactive(void); esp_err_t example_register_gpio_wakeup(void); @@ -18,7 +23,7 @@ esp_err_t example_register_timer_wakeup(void); esp_err_t example_register_uart_wakeup(void); -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if EXAMPLE_TOUCH_LSLEEP_WAKEUP_SUPPORT void example_register_touch_wakeup(void); #endif diff --git a/examples/system/light_sleep/main/light_sleep_example_main.c b/examples/system/light_sleep/main/light_sleep_example_main.c index 8791d4de6eb1..989cfea24bd9 100644 --- a/examples/system/light_sleep/main/light_sleep_example_main.c +++ b/examples/system/light_sleep/main/light_sleep_example_main.c @@ -50,7 +50,7 @@ static void light_sleep_task(void *args) * Otherwise the chip may fall sleep again before running uart task */ vTaskDelay(1); break; -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if EXAMPLE_TOUCH_LSLEEP_WAKEUP_SUPPORT case ESP_SLEEP_WAKEUP_TOUCHPAD: wakeup_reason = "touch"; break; @@ -83,7 +83,7 @@ void app_main(void) example_register_timer_wakeup(); /* Enable wakeup from light sleep by uart */ example_register_uart_wakeup(); -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if EXAMPLE_TOUCH_LSLEEP_WAKEUP_SUPPORT /* Enable wakeup from light sleep by touch element */ example_register_touch_wakeup(); #endif diff --git a/examples/system/light_sleep/main/touch_sens_wakeup.c b/examples/system/light_sleep/main/touch_sens_wakeup.c new file mode 100644 index 000000000000..22354c05762c --- /dev/null +++ b/examples/system/light_sleep/main/touch_sens_wakeup.c @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include "freertos/FreeRTOS.h" +#include "esp_log.h" +#include "driver/touch_sens.h" + +static const char *TAG = "touch_wakeup"; + +#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM 1 +#define EXAMPLE_TOUCH_CHANNEL_NUM 5 +#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3 + +// Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio)) +static float s_thresh2bm_ratio[EXAMPLE_TOUCH_CHANNEL_NUM] = { + [0 ... EXAMPLE_TOUCH_CHANNEL_NUM - 1] = 0.02f, // 2% +}; + +static bool example_touch_on_active_cb(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx) +{ + ESP_EARLY_LOGW("isr", "ch %d active", (int)event->chan_id); + return false; +} + +static bool example_touch_on_inactive_cb(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx) +{ + ESP_EARLY_LOGW("isr", "ch %d inactive", (int)event->chan_id); + return false; +} + +static void example_touch_do_initial_scanning(touch_sensor_handle_t sens_handle, touch_channel_handle_t chan_handle[]) +{ + /* Enable the touch sensor to do the initial scanning, so that to initialize the channel data */ + ESP_ERROR_CHECK(touch_sensor_enable(sens_handle)); + + /* Scan the enabled touch channels for several times, to make sure the initial channel data is stable */ + for (int i = 0; i < EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES; i++) { + ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(sens_handle, 2000)); + } + + /* Disable the touch channel to rollback the state */ + ESP_ERROR_CHECK(touch_sensor_disable(sens_handle)); + + /* (Optional) Read the initial channel benchmark and reconfig the channel active threshold accordingly */ + printf("Initial benchmark and new threshold are:\n"); + for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) { + /* Read the initial benchmark of the touch channel */ + uint32_t benchmark[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {}; + ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark)); + /* Calculate the proper active thresholds regarding the initial benchmark */ + printf("[CH %d]", i); + touch_channel_config_t chan_cfg = {}; + for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) { + chan_cfg.active_thresh[j] = (uint32_t)(benchmark[j] * s_thresh2bm_ratio[j]); + printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.active_thresh[j]); + } + printf("\n"); + /* Update the channel configuration */ + ESP_ERROR_CHECK(touch_sensor_reconfig_channel(chan_handle[i], &chan_cfg)); + } +} + +esp_err_t example_register_touch_wakeup(void) +{ + touch_sensor_handle_t sens_handle = NULL; + touch_sensor_sample_config_t sample_cfg[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = { + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(1, 1, 1), + }; + touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(EXAMPLE_TOUCH_SAMPLE_CFG_NUM, sample_cfg); + ESP_ERROR_CHECK(touch_sensor_new_controller(&sens_cfg, &sens_handle)); + + touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG(); + ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, &filter_cfg)); + + touch_channel_handle_t chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM]; + touch_channel_config_t chan_cfg = { + .active_thresh = {5000}, // Initial threshold + + }; + for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) { + ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, i, &chan_cfg, &chan_handle[i])); + } + + /* (Optional) Do the initial scanning to initialize the touch channel data + * Without this step, the channel data in the first read will be invalid + */ + example_touch_do_initial_scanning(sens_handle, chan_handle); + + touch_event_callbacks_t callbacks = { + .on_active = example_touch_on_active_cb, + .on_inactive = example_touch_on_inactive_cb, + }; + ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL)); + + touch_sleep_config_t light_slp_cfg = { + .slp_wakeup_lvl = TOUCH_LIGHT_SLEEP_WAKEUP, + }; + ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &light_slp_cfg)); + + ESP_ERROR_CHECK(touch_sensor_enable(sens_handle)); + ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle)); + + ESP_LOGI(TAG, "touch wakeup source is ready"); + return ESP_OK; +} diff --git a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py index d25ca408e433..fbabc2c4e7e0 100644 --- a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py +++ b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py @@ -50,9 +50,10 @@ def start_https_server(ota_image_dir: str, server_ip: str, server_port: int) -> requestHandler = https_request_handler() httpd = http.server.HTTPServer((server_ip, server_port), requestHandler) - httpd.socket = ssl.wrap_socket(httpd.socket, - keyfile=key_file, - certfile=server_file, server_side=True) + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.load_cert_chain(certfile=server_file, keyfile=key_file) + + httpd.socket = ssl_context.wrap_socket(httpd.socket, server_side=True) httpd.serve_forever() @@ -88,9 +89,10 @@ def start_redirect_server(ota_image_dir: str, server_ip: str, server_port: int, httpd = http.server.HTTPServer((server_ip, server_port), redirectHandler) - httpd.socket = ssl.wrap_socket(httpd.socket, - keyfile=key_file, - certfile=server_file, server_side=True) + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.load_cert_chain(certfile=server_file, keyfile=key_file) + + httpd.socket = ssl_context.wrap_socket(httpd.socket, server_side=True) httpd.serve_forever() @@ -154,8 +156,8 @@ def test_examples_protocol_advanced_https_ota_example_truncated_bin(dut: Dut) -> truncated_bin_size = 64000 binary_file = os.path.join(dut.app.binary_path, bin_name) with open(binary_file, 'rb+') as f: - with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as fo: - fo.write(f.read(truncated_bin_size)) + with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as output_file: + output_file.write(f.read(truncated_bin_size)) binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) # Start server thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) @@ -187,7 +189,7 @@ def test_examples_protocol_advanced_https_ota_example_truncated_bin(dut: Dut) -> @pytest.mark.ethernet_ota def test_examples_protocol_advanced_https_ota_example_truncated_header(dut: Dut) -> None: """ - Working of OTA if headers of binary file are truncated is vaildated in this test case. + Working of OTA if headers of binary file are truncated is validated in this test case. Application should return with error message in this case. steps: | 1. join AP/Ethernet @@ -205,8 +207,8 @@ def test_examples_protocol_advanced_https_ota_example_truncated_header(dut: Dut) # check and log bin size binary_file = os.path.join(dut.app.binary_path, bin_name) with open(binary_file, 'rb+') as f: - with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as fo: - fo.write(f.read(truncated_bin_size)) + with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as output_file: + output_file.write(f.read(truncated_bin_size)) binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) # Start server thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) @@ -249,16 +251,16 @@ def test_examples_protocol_advanced_https_ota_example_random(dut: Dut) -> None: server_port = 8001 # Random binary file to be generated random_bin_name = 'random.bin' - # Size of random binary file. 32000 is choosen, to reduce the time required to run the test-case + # Size of random binary file. 32000 is chosen, to reduce the time required to run the test-case random_bin_size = 32000 # check and log bin size binary_file = os.path.join(dut.app.binary_path, random_bin_name) - with open(binary_file, 'wb+') as fo: + with open(binary_file, 'wb+') as output_file: # First byte of binary file is always set to zero. If first byte is generated randomly, # in some cases it may generate 0xE9 which will result in failure of testcase. - fo.write(struct.pack('B', 0)) + output_file.write(struct.pack('B', 0)) for i in range(random_bin_size - 1): - fo.write(struct.pack('B', random.randrange(0,255,1))) + output_file.write(struct.pack('B', random.randrange(0,255,1))) # Start server thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True @@ -302,7 +304,7 @@ def test_examples_protocol_advanced_https_ota_example_invalid_chip_id(dut: Dut) # Random binary file to be generated random_bin_name = 'random.bin' random_binary_file = os.path.join(dut.app.binary_path, random_bin_name) - # Size of random binary file. 2000 is choosen, to reduce the time required to run the test-case + # Size of random binary file. 2000 is chosen, to reduce the time required to run the test-case random_bin_size = 2000 binary_file = os.path.join(dut.app.binary_path, bin_name) @@ -310,8 +312,8 @@ def test_examples_protocol_advanced_https_ota_example_invalid_chip_id(dut: Dut) data = list(f.read(random_bin_size)) # Changing Chip id data[13] = 0xfe - with open(random_binary_file, 'wb+') as fo: - fo.write(bytearray(data)) + with open(random_binary_file, 'wb+') as output_file: + output_file.write(bytearray(data)) # Start server thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True @@ -452,11 +454,11 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(dut: Dut) -> binary_file = os.path.join(dut.app.binary_path, bin_name) file_size = os.path.getsize(binary_file) with open(binary_file, 'rb+') as f: - with open(os.path.join(dut.app.binary_path, anti_rollback_bin_name), 'wb+') as fo: - fo.write(f.read(file_size)) + with open(os.path.join(dut.app.binary_path, anti_rollback_bin_name), 'wb+') as output_file: + output_file.write(f.read(file_size)) # Change security_version to 0 for negative test case - fo.seek(36) - fo.write(b'\x00') + output_file.seek(36) + output_file.write(b'\x00') binary_file = os.path.join(dut.app.binary_path, anti_rollback_bin_name) # Start server thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) @@ -666,10 +668,10 @@ def test_examples_protocol_advanced_https_ota_example_openssl_aligned_bin(dut: D # Dummy data required to align binary size to 289 bytes boundary dummy_data_size = 289 - (bin_size % 289) with open(binary_file, 'rb+') as f: - with open(os.path.join(dut.app.binary_path, aligned_bin_name), 'wb+') as fo: - fo.write(f.read(bin_size)) + with open(os.path.join(dut.app.binary_path, aligned_bin_name), 'wb+') as output_file: + output_file.write(f.read(bin_size)) for _ in range(dummy_data_size): - fo.write(struct.pack('B', random.randrange(0,255,1))) + output_file.write(struct.pack('B', random.randrange(0,255,1))) # Start server chunked_server = start_chunked_server(dut.app.binary_path, 8070) try: diff --git a/examples/system/ota/native_ota_example/pytest_native_ota.py b/examples/system/ota/native_ota_example/pytest_native_ota.py index ba61b6c75c34..3c0fcfe6dbb0 100644 --- a/examples/system/ota/native_ota_example/pytest_native_ota.py +++ b/examples/system/ota/native_ota_example/pytest_native_ota.py @@ -110,9 +110,10 @@ def start_https_server(ota_image_dir: str, server_ip: str, server_port: int) -> requestHandler = https_request_handler() httpd = http.server.HTTPServer((server_ip, server_port), requestHandler) - httpd.socket = ssl.wrap_socket(httpd.socket, - keyfile=key_file, - certfile=server_file, server_side=True) + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.load_cert_chain(certfile=server_file, keyfile=key_file) + + httpd.socket = ssl_context.wrap_socket(httpd.socket, server_side=True) httpd.serve_forever() @@ -186,8 +187,8 @@ def test_examples_protocol_native_ota_example_truncated_bin(dut: Dut) -> None: with open(binary_file, 'rb+') as fr: bin_data = fr.read(truncated_bin_size) binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - with open(binary_file, 'wb+') as fo: - fo.write(bin_data) + with open(binary_file, 'wb+') as output_file: + output_file.write(bin_data) # Start server thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True @@ -215,7 +216,7 @@ def test_examples_protocol_native_ota_example_truncated_bin(dut: Dut) -> None: @pytest.mark.ethernet_ota def test_examples_protocol_native_ota_example_truncated_header(dut: Dut) -> None: """ - Working of OTA if headers of binary file are truncated is vaildated in this test case. + Working of OTA if headers of binary file are truncated is validated in this test case. Application should return with error message in this case. steps: | 1. join AP/Ethernet @@ -235,8 +236,8 @@ def test_examples_protocol_native_ota_example_truncated_header(dut: Dut) -> None with open(binary_file, 'rb+') as fr: bin_data = fr.read(truncated_bin_size) binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - with open(binary_file, 'wb+') as fo: - fo.write(bin_data) + with open(binary_file, 'wb+') as output_file: + output_file.write(bin_data) # Start server thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True @@ -275,17 +276,17 @@ def test_examples_protocol_native_ota_example_random(dut: Dut) -> None: server_port = 8002 # Random binary file to be generated random_bin_name = 'random.bin' - # Size of random binary file. 32000 is choosen, to reduce the time required to run the test-case + # Size of random binary file. 32000 is chosen, to reduce the time required to run the test-case random_bin_size = 32000 # check and log bin size binary_file = os.path.join(dut.app.binary_path, random_bin_name) - fo = open(binary_file, 'wb+') + output_file = open(binary_file, 'wb+') # First byte of binary file is always set to zero. If first byte is generated randomly, # in some cases it may generate 0xE9 which will result in failure of testcase. - with open(binary_file, 'wb+') as fo: - fo.write(struct.pack('B', 0)) + with open(binary_file, 'wb+') as output_file: + output_file.write(struct.pack('B', 0)) for _ in range(random_bin_size - 1): - fo.write(struct.pack('B', random.randrange(0,255,1))) + output_file.write(struct.pack('B', random.randrange(0,255,1))) # Start server thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True diff --git a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py index 85f27c314866..c23217357436 100644 --- a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py +++ b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import http.server import multiprocessing @@ -46,9 +46,10 @@ def start_https_server(ota_image_dir: str, server_ip: str, server_port: int) -> requestHandler = https_request_handler() httpd = http.server.HTTPServer((server_ip, server_port), requestHandler) - httpd.socket = ssl.wrap_socket(httpd.socket, - keyfile=key_file, - certfile=server_file, server_side=True) + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.load_cert_chain(certfile=server_file, keyfile=key_file) + + httpd.socket = ssl_context.wrap_socket(httpd.socket, server_side=True) httpd.serve_forever() diff --git a/examples/system/ota/simple_ota_example/pytest_simple_ota.py b/examples/system/ota/simple_ota_example/pytest_simple_ota.py index a6f4a326796a..0595a9c2f76d 100644 --- a/examples/system/ota/simple_ota_example/pytest_simple_ota.py +++ b/examples/system/ota/simple_ota_example/pytest_simple_ota.py @@ -87,9 +87,10 @@ def start_https_server(ota_image_dir: str, server_ip: str, server_port: int, ser httpd = http.server.HTTPServer((server_ip, server_port), http.server.SimpleHTTPRequestHandler) - httpd.socket = ssl.wrap_socket(httpd.socket, - keyfile=key_file, - certfile=server_file, server_side=True) + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.load_cert_chain(certfile=server_file, keyfile=key_file) + + httpd.socket = ssl_context.wrap_socket(httpd.socket, server_side=True) httpd.serve_forever() diff --git a/examples/system/sysview_tracing/README.md b/examples/system/sysview_tracing/README.md index 41936bec3bb3..1b65d621793a 100644 --- a/examples/system/sysview_tracing/README.md +++ b/examples/system/sysview_tracing/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Example: Application Level Tracing - SystemView Tracing (sysview_tracing) This test code shows how to perform system-wide behavioral analysis of the program using [SEGGER SystemView tool](https://www.segger.com/products/development-tools/systemview/). diff --git a/examples/system/sysview_tracing_heap_log/README.md b/examples/system/sysview_tracing_heap_log/README.md index 8ad1b3955df5..573ce63a6fd9 100644 --- a/examples/system/sysview_tracing_heap_log/README.md +++ b/examples/system/sysview_tracing_heap_log/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # SystemView Heap and Log Tracing Example diff --git a/examples/system/ulp/lp_core/gpio_intr_pulse_counter/CMakeLists.txt b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/CMakeLists.txt new file mode 100644 index 000000000000..0d18f968a18e --- /dev/null +++ b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(lp_core_pulse_counter) diff --git a/examples/system/ulp/lp_core/gpio_intr_pulse_counter/README.md b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/README.md new file mode 100644 index 000000000000..1164376c1534 --- /dev/null +++ b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/README.md @@ -0,0 +1,66 @@ +| Supported Targets | ESP32-C6 | ESP32-P4 | +| ----------------- | -------- | -------- | + +# LP Core Pulse Counting Example + +This example demonstrates how to program the ULP Core coprocessor to count pulses on an IO while the main CPUs are either running some other code or are in deep sleep. See the README.md file in the upper level 'examples' directory for more information about examples. + +At runtime, the main code running on the ESP (found in lp_core_pulse_counter_example_main.c) loads ULP program into the `RTC_SLOW_MEM` memory region using `ulp_lp_core_load_binary` function. Main code configures the ULP program by setting up values of some variables and then starts it using `ulp_lp_core_run`. Once the ULP program is started, it monitors the IO pin for pulses. + +When the ULP program finds an edge in the input signal, it performs debouncing and increments the variable maintaining the total edge count. Once the edge count reaches certain value, ULP triggers wake up from deep sleep. Note that the ULP program keeps running and monitoring the input signal even when the SoC is woken up. + +## How to use example + +### Hardware Required + +To run this example, you should have a development board based on any of the chips listed in the supported targets table at the top and a host machine with a serial input connection. + +#### Pin Assignment: + +**Note:** The following pin assignments are used by default. + + +| | Uart Tx | Pulse Count Input | +| ----------------------- | ------- | ----------------- | +| ESP32-C6 | GPIO5 | GPIO6 | +| ESP32-P4 | GPIO14 | GPIO6 | +| Host machine | Rx | N/A | + +### Build and Flash + +Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +Use another serial monitor program/instance such as idf.py monitor, minicom or miniterm to send and receive data from the LP core. +The default baudrate used for the example is 115200. Care must be taken that the configuration matches on both the device and the serial terminal. + +## Example Output + +The log output from the serial monitor connected to the main core should indicate that the LP core and the LP UART peripheral have been successfully initialized. The main CPU would then enter deep sleep mode. + +```bash +Using pin 6 as pulse counter input +ULP will wake up processor after every 10 pulses +Not a ULP wakeup, initializing it! +Entering in deep sleep +... +rst:0x5 (SLEEP_WAKEUP),boot:0xc (SPI_FAST_FLASH_BOOT) +... +ULP woke up the main CPU! +Pulse count: 11 +Entering in deep sleep +``` + +The log output from the serial monitor connected to the LP core should display output as below - + +```bash +LP Core pulse counter started +Pulse count: 10, wake-up main CPU +``` + +## Troubleshooting + +(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.) diff --git a/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/CMakeLists.txt b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/CMakeLists.txt new file mode 100644 index 000000000000..79a7104a1f25 --- /dev/null +++ b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/CMakeLists.txt @@ -0,0 +1,22 @@ +idf_component_register(SRCS "lp_core_pulse_counter_example_main.c" + INCLUDE_DIRS ".") +# +# ULP support additions to component CMakeLists.txt. +# +# 1. The ULP app name must be unique (if multiple components use ULP). +set(ulp_app_name ulp_${COMPONENT_NAME}) +# +# 2. Specify all C and Assembly source files. +# Files should be placed into a separate directory (in this case, ulp/), +# which should not be added to COMPONENT_SRCS. +set(ulp_sources "ulp/main.c") + +# +# 3. List all the component source files which include automatically +# generated ULP export file, ${ulp_app_name}.h: +set(ulp_exp_dep_srcs ${app_sources}) + +# +# 4. Call function to build ULP binary and embed in project using the argument +# values above. +ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}") diff --git a/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/Kconfig.projbuild b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/Kconfig.projbuild new file mode 100644 index 000000000000..88618cecb26a --- /dev/null +++ b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/Kconfig.projbuild @@ -0,0 +1,20 @@ +menu "Example Configuration" + config EXAMPLE_PULSE_COUNT_PIN + int "Input pin for the pulse counter" + default 6 + help + GPIO pin used as the input for the pulse counter + + config EXAMPLE_PULSE_COUNT_WAKEUP_LIMIT + int "Wake-up pulse count limit" + default 10 + help + Number of pulses counted after which the ULP will wake up the main CPU + + config EXAMPLE_PULSE_COUNT_SIMULATE + bool "Simulate pulses on input pin" + default n + help + The ULP will periodically toggle the input pin to simulate pulses + +endmenu diff --git a/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/lp_core_pulse_counter_example_main.c b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/lp_core_pulse_counter_example_main.c new file mode 100644 index 000000000000..65bef47be21f --- /dev/null +++ b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/lp_core_pulse_counter_example_main.c @@ -0,0 +1,85 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* LP core gpio example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#include +#include +#include "esp_sleep.h" +#include "driver/gpio.h" +#include "driver/rtc_io.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "ulp_lp_core.h" +#include "ulp_main.h" +#include "lp_core_uart.h" + +extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start"); +extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end"); + + +static void init_ulp_program(void); + +void app_main(void) +{ + /* If user is using USB-serial-jtag then idf monitor needs some time to + * re-connect to the USB port. We wait 1 sec here to allow for it to make the reconnection + * before we print anything. Otherwise the chip will go back to sleep again before the user + * has time to monitor any output. + */ + vTaskDelay(pdMS_TO_TICKS(1000)); + + /* Initialize selected GPIO as RTC IO, enable input/output, disable pullup and pulldown */ + printf("Using pin %d as pulse counter input\n", CONFIG_EXAMPLE_PULSE_COUNT_PIN); + rtc_gpio_init(CONFIG_EXAMPLE_PULSE_COUNT_PIN); + rtc_gpio_set_direction(CONFIG_EXAMPLE_PULSE_COUNT_PIN, RTC_GPIO_MODE_INPUT_OUTPUT); + rtc_gpio_pulldown_dis(CONFIG_EXAMPLE_PULSE_COUNT_PIN); + rtc_gpio_pullup_dis(CONFIG_EXAMPLE_PULSE_COUNT_PIN); + + printf("ULP will wake up processor after every %d pulses\n", CONFIG_EXAMPLE_PULSE_COUNT_WAKEUP_LIMIT); + + esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); + /* not a wakeup from ULP, load the firmware */ + if (cause != ESP_SLEEP_WAKEUP_ULP) { + printf("Not a ULP wakeup, initializing it! \n"); + init_ulp_program(); + } else { + printf("ULP woke up the main CPU!\n"); + printf("Pulse count: %"PRIu32"\n", ulp_pulse_count); + } + + /* Go back to sleep, only the ULP will run */ + printf("Entering in deep sleep\n\n"); + + /* Small delay to ensure the messages are printed */ + ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup()); + + esp_deep_sleep_start(); +} + +static void init_ulp_program(void) +{ + lp_core_uart_cfg_t uart_cfg = LP_CORE_UART_DEFAULT_CONFIG(); + + ESP_ERROR_CHECK(lp_core_uart_init(&uart_cfg)); + + esp_err_t err = ulp_lp_core_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start)); + ESP_ERROR_CHECK(err); + + /* Start the program */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + + err = ulp_lp_core_run(&cfg); + ESP_ERROR_CHECK(err); +} diff --git a/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/ulp/main.c b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/ulp/main.c new file mode 100644 index 000000000000..6a45c04cb9e2 --- /dev/null +++ b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/main/ulp/main.c @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include "sdkconfig.h" +#include "ulp_lp_core.h" +#include "ulp_lp_core_utils.h" +#include "ulp_lp_core_gpio.h" +#include "ulp_lp_core_interrupts.h" +#include "ulp_lp_core_print.h" +#include "riscv/csr.h" + +#define DEBOUNCE_INTERVAL_CYCLES 10 // 10 cycles is about 0.625 us at 16 MHz + +#define SIMULATED_PULSE_FREQUENCY_HZ 2 +#define SIMULATED_PULSE_DELAY_US (1000000 / SIMULATED_PULSE_FREQUENCY_HZ) / 2 + +uint32_t pulse_count; +static uint32_t last_trigger_time_cycles; + +void LP_CORE_ISR_ATTR ulp_lp_core_lp_io_intr_handler(void) +{ + ulp_lp_core_gpio_clear_intr_status(); + uint32_t trigger_time_cycles = RV_READ_CSR(mcycle); + /* Do some simple debouncing, do not count spurious pulses */ + if (trigger_time_cycles - last_trigger_time_cycles > DEBOUNCE_INTERVAL_CYCLES) { + pulse_count++; + last_trigger_time_cycles = trigger_time_cycles; + } + + if (pulse_count % CONFIG_EXAMPLE_PULSE_COUNT_WAKEUP_LIMIT == 0) { + lp_core_printf("Pulse count: %d, wake-up main CPU\n", pulse_count); + ulp_lp_core_wakeup_main_processor(); + } + +} + + + +int main (void) +{ + lp_core_printf("LP Core pulse counter started\n"); + ulp_lp_core_intr_enable(); + ulp_lp_core_gpio_intr_enable(CONFIG_EXAMPLE_PULSE_COUNT_PIN, LP_IO_INTR_POSEDGE); + + while(1) { + +#if CONFIG_EXAMPLE_PULSE_COUNT_SIMULATE + /* No external device connected to generate pulses, we simulate them ourselves instead */ + ulp_lp_core_delay_us(SIMULATED_PULSE_DELAY_US); + ulp_lp_core_gpio_set_level(CONFIG_EXAMPLE_PULSE_COUNT_PIN, 1); + ulp_lp_core_delay_us(SIMULATED_PULSE_DELAY_US); + ulp_lp_core_gpio_set_level(CONFIG_EXAMPLE_PULSE_COUNT_PIN, 0); +#else + /* Put CPU into a wait state to reduce power consumption while waiting for pulses */ + ulp_lp_core_wait_for_intr(); +#endif //CONFIG_EXAMPLE_PULSE_COUNT_SIMULATE + } + + return 0; +} diff --git a/examples/system/ulp/lp_core/gpio_intr_pulse_counter/pytest_lp_core_pcnt.py b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/pytest_lp_core_pcnt.py new file mode 100644 index 000000000000..a4d8c0c2e4cb --- /dev/null +++ b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/pytest_lp_core_pcnt.py @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import logging + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32c6 +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_lp_core_pcnt(dut: Dut) -> None: + + res = dut.expect(r'ULP will wake up processor after every (\d+) pulses') + wakeup_limit = res.group(1).decode('utf-8') + assert (int(wakeup_limit) > 0) + logging.info(f'Wake-up limit: {wakeup_limit} pulses') + + dut.expect_exact('Not a ULP wakeup, initializing it!') + dut.expect_exact('Entering in deep sleep') + + dut.expect_exact('ULP woke up the main CPU!') + + res = dut.expect(r'Pulse count: (\d+)') + pulse_count = res.group(1).decode('utf-8') + logging.info(f'Pulse count: {pulse_count}') + + # Check that pulse count is correct, we could have gotten pulses between triggering + # the wakeup signal and printing the count, but it should at be equal to or greater + assert (int(pulse_count) >= int(wakeup_limit)) diff --git a/examples/system/ulp/lp_core/gpio_intr_pulse_counter/sdkconfig.ci b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/sdkconfig.ci new file mode 100644 index 000000000000..81f55539b974 --- /dev/null +++ b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/sdkconfig.ci @@ -0,0 +1 @@ +CONFIG_EXAMPLE_PULSE_COUNT_SIMULATE=y diff --git a/examples/system/ulp/lp_core/gpio_intr_pulse_counter/sdkconfig.defaults b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/sdkconfig.defaults new file mode 100644 index 000000000000..456833bc8c36 --- /dev/null +++ b/examples/system/ulp/lp_core/gpio_intr_pulse_counter/sdkconfig.defaults @@ -0,0 +1,9 @@ +# Enable ULP +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y +CONFIG_ULP_COPROC_RESERVE_MEM=8128 +# Set log level to Warning to produce clean output +CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y +CONFIG_BOOTLOADER_LOG_LEVEL=2 +CONFIG_LOG_DEFAULT_LEVEL_WARN=y +CONFIG_LOG_DEFAULT_LEVEL=2 diff --git a/examples/system/ulp/lp_core/interrupt/CMakeLists.txt b/examples/system/ulp/lp_core/interrupt/CMakeLists.txt new file mode 100644 index 000000000000..de93ae527f45 --- /dev/null +++ b/examples/system/ulp/lp_core/interrupt/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(interrupts) diff --git a/examples/system/ulp/lp_core/interrupt/README.md b/examples/system/ulp/lp_core/interrupt/README.md new file mode 100644 index 000000000000..b508bd913da0 --- /dev/null +++ b/examples/system/ulp/lp_core/interrupt/README.md @@ -0,0 +1,19 @@ +| Supported Targets | ESP32-C6 | ESP32-P4 | +| ----------------- | -------- | -------- | + +# LP-Core example with interrupt triggered from HP-Core: + +This example demonstrates how to program the ULP coprocessor to receive an interrupt triggered by the HP-Core + +ULP program written in C can be found across `lp_core/main.c`. The build system compiles and links this program, converts it into binary format, and embeds it into the .rodata section of the ESP-IDF application. + +At runtime, the application running inside the main CPU loads ULP program into the `RTC_SLOW_MEM` memory region using `ulp_lp_core_load_binary` function. The main code then configures the ULP and starts the coprocessor by using `ulp_lp_core_run`. Once the ULP program is started, it runs continuously, waiting for interrupts. The main program will periodically trigger interrupts on the LP-Core. + +After triggering a certain amount of interrupts, the main core will read and print the number of interrupts received as reported by the LP-Core. + +## Example output + +``` +LP core loaded with firmware and running successfully +Triggered 10 interrupts on the LP-Core, LP-Core received 10 interrupts +``` \ No newline at end of file diff --git a/examples/system/ulp/lp_core/interrupt/main/CMakeLists.txt b/examples/system/ulp/lp_core/interrupt/main/CMakeLists.txt new file mode 100644 index 000000000000..6eb2981339ce --- /dev/null +++ b/examples/system/ulp/lp_core/interrupt/main/CMakeLists.txt @@ -0,0 +1,25 @@ +# Register the component +idf_component_register(SRCS "lp_interrupts_main.c" + INCLUDE_DIRS "" + REQUIRES ulp) + +# +# ULP support additions to component CMakeLists.txt. +# +# 1. The LP Core app name must be unique (if multiple components use LP Core). +set(ulp_app_name lp_core_${COMPONENT_NAME}) +# +# 2. Specify all C files. +# Files should be placed into a separate directory (in this case, lp_core/), +# which should not be added to COMPONENT_SRCS. +set(ulp_lp_core_sources "lp_core/main.c") + +# +# 3. List all the component source files which include automatically +# generated LP Core export file, ${ulp_app_name}.h: +set(ulp_exp_dep_srcs "lp_interrupts_main.c") + +# +# 4. Call function to build ULP binary and embed in project using the argument +# values above. +ulp_embed_binary(${ulp_app_name} "${ulp_lp_core_sources}" "${ulp_exp_dep_srcs}") diff --git a/examples/system/ulp/lp_core/interrupt/main/lp_core/main.c b/examples/system/ulp/lp_core/interrupt/main/lp_core/main.c new file mode 100644 index 000000000000..c97f8e4f9876 --- /dev/null +++ b/examples/system/ulp/lp_core/interrupt/main/lp_core/main.c @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "ulp_lp_core_utils.h" +#include "ulp_lp_core_interrupts.h" + +uint32_t lp_core_pmu_intr_count = 0; + +/* Add LP_CORE_ISR_ATTR to ensure registers are saved and restored */ +void LP_CORE_ISR_ATTR ulp_lp_core_lp_pmu_intr_handler(void) +{ + ulp_lp_core_sw_intr_clear(); + lp_core_pmu_intr_count++; +} + +int main (void) +{ + ulp_lp_core_intr_enable(); + ulp_lp_core_sw_intr_enable(true); + + while(1) { + /* Wait forever, handling interrupts */ + asm volatile("wfi"); + } + return 0; +} diff --git a/examples/system/ulp/lp_core/interrupt/main/lp_interrupts_main.c b/examples/system/ulp/lp_core/interrupt/main/lp_interrupts_main.c new file mode 100644 index 000000000000..274b1b00b24e --- /dev/null +++ b/examples/system/ulp/lp_core/interrupt/main/lp_interrupts_main.c @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_sleep.h" +#include "esp_err.h" +#include "lp_core_main.h" +#include "ulp_lp_core.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_main_bin_start"); +extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_main_bin_end"); + + +static void lp_core_init(void) +{ + /* Set LP core wakeup source as the HP CPU */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + + /* Load LP core firmware */ + ESP_ERROR_CHECK(ulp_lp_core_load_binary(lp_core_main_bin_start, (lp_core_main_bin_end - lp_core_main_bin_start))); + + /* Run LP core */ + ESP_ERROR_CHECK(ulp_lp_core_run(&cfg)); + + // Give the LP core time to start up + vTaskDelay(pdMS_TO_TICKS(100)); + + printf("LP core loaded with firmware and running successfully\n"); +} + +#define INTERRUPT_COUNT 10 + +void app_main(void) +{ + /* Load LP Core binary and start the coprocessor */ + lp_core_init(); + + for (int i = 0; i < INTERRUPT_COUNT; i++) { + /* In addition to waking the LP source up, the HP-LP communication bit can also be used to trigger a PMU interrupt on the LP Core */ + ulp_lp_core_sw_intr_trigger(); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + printf("Triggered %d interrupts on the LP-Core, LP-Core received %"PRIu32" interrupts\n", INTERRUPT_COUNT, ulp_lp_core_pmu_intr_count); + +} diff --git a/examples/system/ulp/lp_core/interrupt/pytest_lp_core_intr.py b/examples/system/ulp/lp_core/interrupt/pytest_lp_core_intr.py new file mode 100644 index 000000000000..a9f96aba6c22 --- /dev/null +++ b/examples/system/ulp/lp_core/interrupt/pytest_lp_core_intr.py @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32c6 +@pytest.mark.esp32p4 +@pytest.mark.generic +def test_lp_core_intr(dut: Dut) -> None: + dut.expect('Triggered 10 interrupts on the LP-Core, LP-Core received 10 interrupts') diff --git a/components/ulp/test_apps/lp_core/sdkconfig.defaults b/examples/system/ulp/lp_core/interrupt/sdkconfig.defaults similarity index 77% rename from components/ulp/test_apps/lp_core/sdkconfig.defaults rename to examples/system/ulp/lp_core/interrupt/sdkconfig.defaults index b1dc7fcf8c1c..2e829c6faa34 100644 --- a/components/ulp/test_apps/lp_core/sdkconfig.defaults +++ b/examples/system/ulp/lp_core/interrupt/sdkconfig.defaults @@ -1,5 +1,4 @@ -CONFIG_ESP_TASK_WDT_INIT=n - +# Enable ULP CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_LP_CORE=y CONFIG_ULP_COPROC_RESERVE_MEM=4096 diff --git a/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/sdkconfig.defaults b/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/sdkconfig.defaults index 53ae7d35bfa2..f018081b4da2 100644 --- a/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/sdkconfig.defaults +++ b/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/sdkconfig.defaults @@ -1,4 +1,4 @@ # Enable LP Core CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_LP_CORE=y -CONFIG_ULP_COPROC_RESERVE_MEM=4096 +CONFIG_ULP_COPROC_RESERVE_MEM=8192 diff --git a/examples/wifi/getting_started/softAP/main/softap_example_main.c b/examples/wifi/getting_started/softAP/main/softap_example_main.c index 4eba17b50b94..485d74e90b38 100644 --- a/examples/wifi/getting_started/softAP/main/softap_example_main.c +++ b/examples/wifi/getting_started/softAP/main/softap_example_main.c @@ -39,8 +39,8 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, MAC2STR(event->mac), event->aid); } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; - ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d", - MAC2STR(event->mac), event->aid); + ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d, reason=%d", + MAC2STR(event->mac), event->aid, event->reason); } } diff --git a/examples/wifi/iperf/README.md b/examples/wifi/iperf/README.md index b6ed09ea29c8..b42b7c44405e 100644 --- a/examples/wifi/iperf/README.md +++ b/examples/wifi/iperf/README.md @@ -4,61 +4,74 @@ # Iperf Example ## Note about iperf version -The iperf example doesn't support all features in standard iperf. It's compitable with iperf version 2.x. +The iperf example doesn't support all features in standard iperf. It's compatible with iperf version 2.x. -## Note about 80MHz flash frequency +- Refer to the components registry iperf-cmd page for more information: https://components.espressif.com/components/espressif/iperf-cmd + +## Note about 80MHz flash frequency (ESP32) The iperf can get better throughput if the SPI flash frequency is set to 80MHz, but the system may crash in 80MHz mode for ESP-WROVER-KIT. Removing R140~R145 from the board can fix this issue. Currently the default SPI frequency is set to 40MHz, if you want to change the SPI flash frequency to 80MHz, please make sure R140~R145 are removed from ESP-WROVER-KIT or use ESP32 DevKitC. ## Introduction This example implements the protocol used by the common performance measurement tool [iPerf](https://iperf.fr/). -Performance can be measured between two ESP32s running this example, or between a single ESP32 and a computer running the iPerf tool +Performance can be measured between two ESP targets running this example, or between a single ESP target and a computer running the iPerf tool Demo steps to test station TCP Tx performance: -1. Configure in `menuconfig` which serial output you are using. Execute `idf.py menuconfig` and go to `Component config/ESP System Settings/Channel for console output`, then select the appropiate interface. By default the UART0 interface is used, this means that for example in the ESP32-S3-DevKitC-1 or ESP32-C6-DevKitC-1 you should connect to the micro-usb connector labeled as UART and not to the one labeled as USB. To use the one labeled as USB you should change the aforementioned setting to `USB Serial/JTAG Controller`. -2. Build the iperf example with sdkconfig.defaults, which contains performance test specific configurations +- Configure in `menuconfig` which serial output you are using. Execute `idf.py menuconfig` and go to `Component config/ESP System Settings/Channel for console output`, then select the appropriate interface. By default the UART0 interface is used, this means that for example in the ESP32-S3-DevKitC-1 or ESP32-C6-DevKitC-1 you should connect to the micro-usb connector labeled as UART and not to the one labeled as USB. To use the one labeled as USB you should change the aforementioned setting to `USB Serial/JTAG Controller`. -3. Run the demo as station mode and join the target AP - sta ssid password +- Build and flash the iperf example with `sdkconfig.defaults`, which contains performance test specific configurations + - Use `help` for detailed command usage information. -4. Run iperf as server on AP side - iperf -s -i 3 +- Run the demo as station mode and join the target AP + - `sta_connect ` + - NOTE: the dut is started in station mode by default. If you want to use the dut as softap, please set wifi mode first: + - `wifi_mode ap` + - `ap_set ` -5. Run iperf as client on ESP32 side - iperf -c 192.168.10.42 -i 3 -t 60 +- Run iperf as server on AP side + - `iperf -s -i 3` -The console output, which is printed by station TCP RX throughput test, looks like: +- Run iperf as client on ESP side + - `iperf -c 192.168.10.42 -i 3 -t 60` ->iperf> sta aptest -> ->I (5325) iperf: sta connecting to 'aptest' -> ->iperf> I (6017) event: ip: 192.168.10.248, mask: 255.255.255.0, gw: 192.168.10.1 -> ->iperf> iperf -s -i 3 -t 1000 -> ->I (14958) iperf: mode=tcp-server sip=192.168.10.248:5001, dip=0.0.0.0:5001, interval=3, time=1000 -> ->Interval Bandwidth -> ->iperf> accept: 192.168.10.42,62958 -> ->0- 3 sec 8.43 Mbits/sec -> ->3- 6 sec 36.16 Mbits/sec -> ->6- 9 sec 36.22 Mbits/sec -> ->9- 12 sec 36.44 Mbits/sec -> ->12- 15 sec 36.25 Mbits/sec -> ->15- 18 sec 24.36 Mbits/sec -> ->18- 21 sec 27.79 Mbits/sec +The console output, which is printed by station TCP RX throughput test, looks like: + ``` + iperf> sta_connect testap-11 ******** + I (36836) WIFI: Connecting to testap-11... + I (36839) WIFI: DONE.WIFI_CONNECT_START,OK. + iperf> I (39248) WIFI: WIFI_EVENT_STA_DISCONNECTED! reason: 201 + I (39249) WIFI: trying to reconnect... + I (41811) wifi:new:<11,2>, old:<1,0>, ap:<255,255>, sta:<11,2>, prof:1, snd_ch_cfg:0x0 + I (41813) wifi:state: init -> auth (0xb0) + I (41816) wifi:state: auth -> assoc (0x0) + I (41840) wifi:state: assoc -> run (0x10) + I (41847) wifi:idx:0 (ifx:0, 30:5a:3a:74:90:f0), tid:0, ssn:0, winSize:64 + I (41914) wifi:connected with testap-11, aid = 1, channel 11, 40D, bssid = 30:5a:3a:74:90:f0 + I (41915) wifi:security: WPA2-PSK, phy: bgn, rssi: -34 + I (41926) wifi:pm start, type: 0 + + I (41927) wifi:dp: 1, bi: 102400, li: 3, scale listen interval from 307200 us to 307200 us + I (41929) WIFI: WIFI_EVENT_STA_CONNECTED! + I (41983) wifi:AP's beacon interval = 102400 us, DTIM period = 3 + I (42929) esp_netif_handlers: sta ip: 192.168.1.79, mask: 255.255.255.0, gw: 192.168.1.1 + I (42930) WIFI: IP_EVENT_STA_GOT_IP: Interface "sta" address: 192.168.1.79 + I (42942) WIFI: - IPv4 address: 192.168.1.79, + iperf> + iperf> iperf -s -i 2 + I (84810) IPERF: mode=tcp-server sip=0.0.0.0:5001, dip=0.0.0.0:5001, interval=2, time=30 + I (84812) iperf: Socket created + iperf> I (87967) iperf: accept: 192.168.1.2,43726 + + Interval Bandwidth + 0.0- 2.0 sec 24.36 Mbits/sec + 2.0- 4.0 sec 23.38 Mbits/sec + 4.0- 6.0 sec 24.02 Mbits/sec + 6.0- 8.0 sec 25.27 Mbits/sec + 8.0-10.0 sec 23.84 Mbits/sec + ``` Steps to test station/soft-AP TCP/UDP RX/TX throughput are similar as test steps in station TCP TX. diff --git a/examples/wifi/iperf/main/iperf_example_main.c b/examples/wifi/iperf/main/iperf_example_main.c index 83df4b0d232a..a856e20ebc0d 100644 --- a/examples/wifi/iperf/main/iperf_example_main.c +++ b/examples/wifi/iperf/main/iperf_example_main.c @@ -58,7 +58,7 @@ void iperf_hook_show_wifi_stats(iperf_traffic_type_t type, iperf_status_t status } #endif #if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS - if (type != IPERF_UDP_SERVER) { + if (type != IPERF_UDP_CLIENT) { wifi_cmd_get_rx_statistics(0, NULL); } #endif diff --git a/examples/wifi/itwt/main/itwt_main.c b/examples/wifi/itwt/main/itwt_main.c index 1e4e1af461a1..e2f4ecc77191 100644 --- a/examples/wifi/itwt/main/itwt_main.c +++ b/examples/wifi/itwt/main/itwt_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -119,7 +119,7 @@ static void got_ip_handler(void *arg, esp_event_base_t event_base, esp_wifi_sta_get_negotiated_phymode(&phymode); if (phymode == WIFI_PHY_MODE_HE20) { esp_err_t err = ESP_OK; - wifi_twt_setup_config_t setup_config = { + wifi_itwt_setup_config_t setup_config = { .setup_cmd = TWT_REQUEST, .flow_id = 0, .twt_id = CONFIG_EXAMPLE_ITWT_ID, @@ -183,7 +183,11 @@ static void itwt_teardown_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { wifi_event_sta_itwt_teardown_t *teardown = (wifi_event_sta_itwt_teardown_t *) event_data; - ESP_LOGI(TAG, "flow_id %d%s", teardown->flow_id, (teardown->flow_id == 8) ? "(all twt)" : ""); + if (teardown->status == ITWT_TEARDOWN_FAIL) { + ESP_LOGE(TAG, "flow_id %d%s, twt teardown frame tx failed", teardown->flow_id, (teardown->flow_id == 8) ? "(all twt)" : ""); + } else { + ESP_LOGI(TAG, "flow_id %d%s", teardown->flow_id, (teardown->flow_id == 8) ? "(all twt)" : ""); + } } static void itwt_suspend_handler(void *arg, esp_event_base_t event_base, diff --git a/examples/wifi/itwt/main/wifi_itwt_cmd.c b/examples/wifi/itwt/main/wifi_itwt_cmd.c index 157a88ef0675..5b2f677ddb5e 100644 --- a/examples/wifi/itwt/main/wifi_itwt_cmd.c +++ b/examples/wifi/itwt/main/wifi_itwt_cmd.c @@ -110,7 +110,7 @@ static int wifi_cmd_itwt(int argc, char **argv) return 1; } } - wifi_twt_setup_config_t setup_config = { + wifi_itwt_setup_config_t setup_config = { .setup_cmd = (itwt_args.setup->ival[0] <= TWT_DEMAND) ? itwt_args.setup->ival[0] : TWT_REQUEST, .flow_id = 0, .twt_id = itwt_args.twtid->count ? itwt_args.twtid->ival[0] : 0, diff --git a/examples/wifi/scan/main/scan.c b/examples/wifi/scan/main/scan.c index 19e2c41555cd..243b4a7a98f8 100644 --- a/examples/wifi/scan/main/scan.c +++ b/examples/wifi/scan/main/scan.c @@ -179,14 +179,15 @@ static void wifi_scan(void) } array_2_channel_bitmap(channel_list, CHANNEL_LIST_SIZE, scan_config); esp_wifi_scan_start(scan_config, true); + free(scan_config); #else esp_wifi_scan_start(NULL, true); #endif /*USE_CHANNEL_BTIMAP*/ ESP_LOGI(TAG, "Max AP number ap_info can hold = %u", number); - ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info)); ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count)); + ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info)); ESP_LOGI(TAG, "Total APs scanned = %u, actual AP number ap_info holds = %u", ap_count, number); for (int i = 0; i < number; i++) { ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid); diff --git a/examples/wifi/softap_sta/main/softap_sta.c b/examples/wifi/softap_sta/main/softap_sta.c index 863bb963a49d..e10b21ec8ada 100644 --- a/examples/wifi/softap_sta/main/softap_sta.c +++ b/examples/wifi/softap_sta/main/softap_sta.c @@ -90,8 +90,8 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, MAC2STR(event->mac), event->aid); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED) { wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *) event_data; - ESP_LOGI(TAG_AP, "Station "MACSTR" left, AID=%d", - MAC2STR(event->mac), event->aid); + ESP_LOGI(TAG_AP, "Station "MACSTR" left, AID=%d, reason:%d", + MAC2STR(event->mac), event->aid, event->reason); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { esp_wifi_connect(); ESP_LOGI(TAG_STA, "Station started"); @@ -145,7 +145,7 @@ esp_netif_t *wifi_init_sta(void) .password = EXAMPLE_ESP_WIFI_STA_PASSWD, .scan_method = WIFI_ALL_CHANNEL_SCAN, .failure_retry_cnt = EXAMPLE_ESP_MAXIMUM_RETRY, - /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8). + /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8). * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards. diff --git a/examples/wifi/wps_softap_registrar/main/wps.c b/examples/wifi/wps_softap_registrar/main/wps.c index b7f5ef8d0d24..31ea23085864 100644 --- a/examples/wifi/wps_softap_registrar/main/wps.c +++ b/examples/wifi/wps_softap_registrar/main/wps.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -62,8 +62,8 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, { ESP_LOGI(TAG, "WIFI_EVENT_AP_STADISCONNECTED"); wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; - ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d", - MAC2STR(event->mac), event->aid); + ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d, reason=%d", + MAC2STR(event->mac), event->aid, event->reason); } break; case WIFI_EVENT_AP_STACONNECTED: diff --git a/pytest.ini b/pytest.ini index 82e028d894da..069d1cf41580 100644 --- a/pytest.ini +++ b/pytest.ini @@ -13,7 +13,7 @@ addopts = --logfile-extension ".txt" --check-duplicates y --ignore-glob */managed_components/* - --ignore pytest_embedded_log + --ignore pytest-embedded # ignore DeprecationWarning filterwarnings = diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index d2e8394f3e1f..db42d9fe3cf0 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -398,7 +398,6 @@ components/bt/host/bluedroid/stack/smp/smp_main.c components/bt/host/bluedroid/stack/smp/smp_utils.c components/console/linenoise/linenoise.c components/console/linenoise/linenoise.h -components/esp_eth/src/ksz8851.h components/esp_event/host_test/esp_event_unit_test/main/esp_event_test.cpp components/esp_event/host_test/fixtures.hpp components/esp_hid/include/esp_hidd.h @@ -588,7 +587,6 @@ components/soc/esp32/include/soc/uhci_struct.h components/soc/esp32/include/soc/wdev_reg.h components/soc/esp32/ledc_periph.c components/soc/esp32/spi_periph.c -components/soc/esp32/uart_periph.c components/soc/esp32c3/i2c_periph.c components/soc/esp32c3/include/soc/apb_saradc_reg.h components/soc/esp32c3/include/soc/assist_debug_reg.h @@ -619,7 +617,6 @@ components/soc/esp32c3/include/soc/usb_serial_jtag_struct.h components/soc/esp32c3/include/soc/wdev_reg.h components/soc/esp32c3/interrupts.c components/soc/esp32c3/ledc_periph.c -components/soc/esp32c3/uart_periph.c components/soc/esp32s2/adc_periph.c components/soc/esp32s2/dedic_gpio_periph.c components/soc/esp32s2/i2c_periph.c @@ -657,7 +654,6 @@ components/soc/esp32s2/include/soc/usb_wrap_reg.h components/soc/esp32s2/include/soc/usb_wrap_struct.h components/soc/esp32s2/include/soc/wdev_reg.h components/soc/esp32s2/ledc_periph.c -components/soc/esp32s2/uart_periph.c components/soc/esp32s3/dedic_gpio_periph.c components/soc/esp32s3/i2c_periph.c components/soc/esp32s3/include/soc/apb_saradc_reg.h @@ -693,7 +689,6 @@ components/soc/esp32s3/include/soc/rtc_io_reg.h components/soc/esp32s3/include/soc/rtc_io_struct.h components/soc/esp32s3/include/soc/sdmmc_pins.h components/soc/esp32s3/include/soc/sdmmc_reg.h -components/soc/esp32s3/include/soc/sens_reg.h components/soc/esp32s3/include/soc/sensitive_reg.h components/soc/esp32s3/include/soc/sensitive_struct.h components/soc/esp32s3/include/soc/soc_ulp.h @@ -717,9 +712,7 @@ components/soc/esp32s3/include/soc/usb_wrap_reg.h components/soc/esp32s3/include/soc/usb_wrap_struct.h components/soc/esp32s3/include/soc/wdev_reg.h components/soc/esp32s3/ledc_periph.c -components/soc/esp32s3/uart_periph.c components/soc/include/soc/dedic_gpio_periph.h -components/soc/include/soc/emac_periph.h components/soc/include/soc/gpio_periph.h components/soc/include/soc/ledc_periph.h components/soc/lldesc.c @@ -733,7 +726,6 @@ components/spi_flash/spi_flash_chip_boya.c components/spi_flash/spi_flash_chip_issi.c components/tcp_transport/include/esp_transport_ws.h components/vfs/include/esp_vfs_common.h -components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h components/wifi_provisioning/include/wifi_provisioning/scheme_console.h components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h components/wifi_provisioning/include/wifi_provisioning/wifi_scan.h diff --git a/tools/ci/check_ldgen_mapping_exceptions.txt b/tools/ci/check_ldgen_mapping_exceptions.txt index c1920680641f..6d470c462d62 100644 --- a/tools/ci/check_ldgen_mapping_exceptions.txt +++ b/tools/ci/check_ldgen_mapping_exceptions.txt @@ -3,3 +3,5 @@ sha256_coredump gcc clang_rt_builtins freertos_common +esp_psram +esp_mm diff --git a/tools/ci/check_type_comments.py b/tools/ci/check_type_comments.py index d89bf562b246..38865b084261 100755 --- a/tools/ci/check_type_comments.py +++ b/tools/ci/check_type_comments.py @@ -2,7 +2,6 @@ # # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 - import argparse import subprocess from sys import exit @@ -30,7 +29,7 @@ def types_valid_ignored_rules(file_name): # type: (str) -> bool """ Run Mypy check with rules for ignore list on the given file, return TRUE if Mypy check passes """ - mypy_exit_code = subprocess.call('mypy {} --allow-untyped-defs'.format(file_name), shell=True) + mypy_exit_code = subprocess.call('mypy {} --python-version 3.8 --allow-untyped-defs'.format(file_name), shell=True) return not bool(mypy_exit_code) diff --git a/tools/ci/dynamic_pipelines/templates/.dynamic_jobs.yml b/tools/ci/dynamic_pipelines/templates/.dynamic_jobs.yml index 72f0b76c2098..431664867235 100644 --- a/tools/ci/dynamic_pipelines/templates/.dynamic_jobs.yml +++ b/tools/ci/dynamic_pipelines/templates/.dynamic_jobs.yml @@ -60,7 +60,7 @@ artifacts: paths: - XUNIT_RESULT*.xml - - pytest_embedded_log/ + - pytest-embedded/ # Child pipeline reports won't be collected in the main one # https://gitlab.com/groups/gitlab-org/-/epics/8205 # reports: diff --git a/tools/ci/idf_ci/uploader.py b/tools/ci/idf_ci/uploader.py index 47dfcd7a4339..e42837884d5d 100644 --- a/tools/ci/idf_ci/uploader.py +++ b/tools/ci/idf_ci/uploader.py @@ -60,7 +60,7 @@ class AppUploader(AppDownloader): DEFAULT_BUILD_LOG_FILENAME, ], ArtifactType.SIZE_REPORTS: [ - '**/build*/size.json', + 'size.json', ], } diff --git a/tools/ci/idf_ci_utils.py b/tools/ci/idf_ci_utils.py index c865690a1938..b355090ffc76 100644 --- a/tools/ci/idf_ci_utils.py +++ b/tools/ci/idf_ci_utils.py @@ -11,7 +11,7 @@ from functools import cached_property from pathlib import Path -IDF_PATH = os.path.abspath(os.getenv('IDF_PATH', os.path.join(os.path.dirname(__file__), '..', '..'))) +IDF_PATH: str = os.path.abspath(os.getenv('IDF_PATH', os.path.join(os.path.dirname(__file__), '..', '..'))) def get_submodule_dirs(full_path: bool = False) -> t.List[str]: diff --git a/tools/ci/idf_pytest/constants.py b/tools/ci/idf_pytest/constants.py index 4ff0687e54ba..89f3bbe1c1eb 100644 --- a/tools/ci/idf_pytest/constants.py +++ b/tools/ci/idf_pytest/constants.py @@ -19,6 +19,7 @@ SUPPORTED_TARGETS = ['esp32', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32h2', 'esp32p4'] PREVIEW_TARGETS: t.List[str] = [] # this PREVIEW_TARGETS excludes 'linux' target DEFAULT_SDKCONFIG = 'default' +DEFAULT_LOGDIR = 'pytest-embedded' TARGET_MARKERS = { 'esp32': 'support esp32 target', @@ -200,7 +201,7 @@ def targets(self) -> t.List[str]: for _t in [app.target for app in self.apps]: if _t in self.target_markers: skip = False - warnings.warn(f'`pytest.mark.[TARGET]` defined in parametrize for multi-dut test cases is deprecated. ' + warnings.warn(f'`pytest.mark.[TARGET]` defined in parametrize for multi-dut test cases is deprecated. ' # noqa: W604 f'Please use parametrize instead for test case {self.item.nodeid}') break @@ -233,7 +234,7 @@ def _get_temp_markers_disabled_targets(marker_name: str) -> t.Set[str]: # temp markers should always use keyword arguments `targets` and `reason` if not temp_marker.kwargs.get('targets') or not temp_marker.kwargs.get('reason'): raise ValueError( - f'`{marker_name}` should always use keyword arguments `targets` and `reason`. ' + f'`{marker_name}` should always use keyword arguments `targets` and `reason`. ' # noqa: W604 f'For example: ' f'`@pytest.mark.{marker_name}(targets=["esp32"], reason="IDF-xxxx, will fix it ASAP")`' ) @@ -292,7 +293,7 @@ def all_built_in_app_lists(self, app_lists: t.Optional[t.List[str]] = None) -> t bin_found[i] = 1 if sum(bin_found) == 0: - msg = f'Skip test case {self.name} because all following binaries are not listed in the app lists: ' + msg = f'Skip test case {self.name} because all following binaries are not listed in the app lists: ' # noqa: E713 for app in self.apps: msg += f'\n - {app.build_dir}' @@ -303,7 +304,7 @@ def all_built_in_app_lists(self, app_lists: t.Optional[t.List[str]] = None) -> t return None # some found, some not, looks suspicious - msg = f'Found some binaries of test case {self.name} are not listed in the app lists.' + msg = f'Found some binaries of test case {self.name} are not listed in the app lists.' # noqa: E713 for i, app in enumerate(self.apps): if bin_found[i] == 0: msg += f'\n - {app.build_dir}' diff --git a/tools/ci/idf_pytest/tests/conftest.py b/tools/ci/idf_pytest/tests/conftest.py index bd85b7f4dfc5..e0def5265b66 100644 --- a/tools/ci/idf_pytest/tests/conftest.py +++ b/tools/ci/idf_pytest/tests/conftest.py @@ -19,6 +19,7 @@ sys.path.append(tools_dir) from idf_ci_utils import IDF_PATH # noqa: E402 +from idf_pytest.constants import DEFAULT_LOGDIR # noqa: E402 def create_project(name: str, folder: Path) -> Path: @@ -57,9 +58,9 @@ def create_project(name: str, folder: Path) -> Path: @pytest.fixture def work_dirpath() -> t.Generator[Path, None, None]: - os.makedirs(os.path.join(IDF_PATH, 'pytest_embedded_log'), exist_ok=True) + os.makedirs(os.path.join(IDF_PATH, DEFAULT_LOGDIR), exist_ok=True) - p = Path(tempfile.mkdtemp(prefix=os.path.join(IDF_PATH, 'pytest_embedded_log') + os.sep)) + p = Path(tempfile.mkdtemp(prefix=os.path.join(IDF_PATH, DEFAULT_LOGDIR) + os.sep)) try: yield p diff --git a/tools/cmake/project.cmake b/tools/cmake/project.cmake index e92e5855d5a1..c253a7008d5a 100644 --- a/tools/cmake/project.cmake +++ b/tools/cmake/project.cmake @@ -67,7 +67,7 @@ idf_build_set_property(__COMPONENT_MANAGER_INTERFACE_VERSION 2) # Parse and store the VERSION argument provided to the project() command. # function(__parse_and_store_version_arg) - # The project_name is the fisrt argument that was passed to the project() command + # The project_name is the first argument that was passed to the project() command set(project_name ${ARGV0}) # Parse other arguments passed to the project() call @@ -663,7 +663,7 @@ macro(project project_name) # 3. git describe if the project is in a git repository # 4. Default to 1 if none of the above conditions are true # - # PS: PROJECT_VER will get overidden later if CONFIG_APP_PROJECT_VER_FROM_CONFIG is defined. + # PS: PROJECT_VER will get overridden later if CONFIG_APP_PROJECT_VER_FROM_CONFIG is defined. # See components/esp_app_format/CMakeLists.txt. if(NOT DEFINED PROJECT_VER) # Read the version information from the version.txt file if it is present @@ -825,6 +825,10 @@ macro(project project_name) # Do not print RWX segment warnings target_link_options(${project_elf} PRIVATE "-Wl,--no-warn-rwx-segments") endif() + if(CONFIG_ESP_ORPHAN_SECTION_WARNING) + # Print warnings if orphan sections are found + target_link_options(${project_elf} PRIVATE "-Wl,--orphan-handling=warn") + endif() unset(idf_target) endif() diff --git a/tools/cmake/version.cmake b/tools/cmake/version.cmake index 4db536bdaa55..e01881ca4db7 100644 --- a/tools/cmake/version.cmake +++ b/tools/cmake/version.cmake @@ -1,5 +1,5 @@ set(IDF_VERSION_MAJOR 5) set(IDF_VERSION_MINOR 3) -set(IDF_VERSION_PATCH 0) +set(IDF_VERSION_PATCH 1) set(ENV{IDF_VERSION} "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}") diff --git a/tools/esp_prov/transport/transport_console.py b/tools/esp_prov/transport/transport_console.py index 8fbcc2fe9c1d..246a15e7aaa9 100644 --- a/tools/esp_prov/transport/transport_console.py +++ b/tools/esp_prov/transport/transport_console.py @@ -1,8 +1,7 @@ -# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 # - -from utils import hex_str_to_bytes, str_to_bytes +from utils import str_to_bytes from .transport import Transport @@ -16,4 +15,4 @@ async def send_data(self, path, data, session_id=0): except Exception as err: print('error:', err) return None - return hex_str_to_bytes(resp) + return bytearray.fromhex(resp).decode('latin-1') diff --git a/tools/idf_py_actions/debug_ext.py b/tools/idf_py_actions/debug_ext.py index dd4cacc1b410..eb05437e9254 100644 --- a/tools/idf_py_actions/debug_ext.py +++ b/tools/idf_py_actions/debug_ext.py @@ -11,16 +11,27 @@ import time from textwrap import indent from threading import Thread -from typing import Any, Dict, List, Optional, Union +from typing import Any +from typing import Dict +from typing import List +from typing import Optional +from typing import Tuple +from typing import Union from click import INT from click.core import Context from esp_coredump import CoreDump -from idf_py_actions.constants import OPENOCD_TAGET_CONFIG, OPENOCD_TAGET_CONFIG_DEFAULT +from idf_py_actions.constants import OPENOCD_TAGET_CONFIG +from idf_py_actions.constants import OPENOCD_TAGET_CONFIG_DEFAULT from idf_py_actions.errors import FatalError -from idf_py_actions.serial_ext import BAUD_RATE, PORT -from idf_py_actions.tools import (PropertyDict, ensure_build_directory, generate_hints, get_default_serial_port, - get_sdkconfig_value, yellow_print) +from idf_py_actions.serial_ext import BAUD_RATE +from idf_py_actions.serial_ext import PORT +from idf_py_actions.tools import ensure_build_directory +from idf_py_actions.tools import generate_hints +from idf_py_actions.tools import get_default_serial_port +from idf_py_actions.tools import get_sdkconfig_value +from idf_py_actions.tools import PropertyDict +from idf_py_actions.tools import yellow_print PYTHON = sys.executable ESP_ROM_INFO_FILE = 'roms.json' @@ -51,6 +62,7 @@ ''' GDBINIT_CONNECT = ''' # Connect to the default openocd-esp port and break on app_main() +set remotetimeout 10 target remote :3333 monitor reset halt maintenance flush register-cache @@ -146,10 +158,10 @@ def _terminate_async_target(target: str) -> None: def _get_espcoredump_instance(ctx: Context, args: PropertyDict, - gdb_timeout_sec: int = None, - core: str = None, - chip_rev: str = None, - save_core: str = None) -> CoreDump: + gdb_timeout_sec: Optional[int] = None, + core: Optional[str] = None, + chip_rev: Optional[str] = None, + save_core: Optional[str] = None) -> CoreDump: ensure_build_directory(args, ctx.info_name) project_desc = get_project_desc(args, ctx) @@ -232,7 +244,7 @@ def generate_gdbinit_rom_add_symbols(target: str) -> str: with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), ESP_ROM_INFO_FILE), 'r') as f: roms = json.load(f) if target not in roms: - msg_body = f'Target "{target}" was not found in "{ESP_ROM_INFO_FILE}". Please check IDF integrity.' + msg_body = f'Target "{target}" was not found in "{ESP_ROM_INFO_FILE}". Please check IDF integrity.' # noqa: E713 if os.getenv('ESP_IDF_GDB_TESTING'): raise FatalError(msg_body) print(f'Warning: {msg_body}') @@ -395,6 +407,24 @@ def get_gdb_args(project_desc: Dict[str, Any]) -> List: args.append('-ix={}'.format(debug_prefix_gdbinit)) return args + def _get_gdbgui_version(ctx: Context) -> Tuple[int, ...]: + completed_process = subprocess.run(['gdbgui', '--version'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + captured_output = completed_process.stdout.decode('utf-8', 'ignore') + + if completed_process.returncode != 0: + if sys.version_info[:2] >= (3, 11) and sys.platform == 'win32': + raise SystemExit('Unfortunately, gdbgui is supported only with Python 3.10 or older. ' + 'See: https://github.com/espressif/esp-idf/issues/10116. ' + 'Please use "idf.py gdb" or debug in Eclipse/Vscode instead.') + raise FatalError('Error starting gdbgui. Please make sure gdbgui has been installed with ' + '"install.{sh,bat,ps1,fish} --enable-gdbgui" and can be started. ' + f'Error: {captured_output}', ctx) + + v = re.search(r'(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?', captured_output) + if not v: + raise SystemExit(f'Error: "gdbgui --version" returned "{captured_output}"') + return tuple(int(i) if i else 0 for i in (v[1], v[2], v[3], v[4])) + def gdbui(action: str, ctx: Context, args: PropertyDict, gdbgui_port: Optional[str], gdbinit: Optional[str], require_openocd: bool) -> None: """ @@ -405,11 +435,11 @@ def gdbui(action: str, ctx: Context, args: PropertyDict, gdbgui_port: Optional[s gdb = project_desc['monitor_toolprefix'] + 'gdb' generate_gdbinit_files(gdb, gdbinit, project_desc) + gdbgui_version = _get_gdbgui_version(ctx) gdb_args_list = get_gdb_args(project_desc) - if sys.version_info[:2] >= (3, 11): - # If we use Python 3.11+ then the only compatible gdbgui doesn't support the --gdb-args argument. This - # check is easier than checking gdbgui version or re-running the process in case of gdb-args-related - # failure. + if gdbgui_version >= (0, 14, 0, 0): + # See breaking changes https://github.com/cs01/gdbgui/blob/master/CHANGELOG.md#01400, especially the + # replacement of command line arguments. gdb_args = ' '.join(gdb_args_list) args = ['gdbgui', '-g', ' '.join((gdb, gdb_args))] else: @@ -435,12 +465,7 @@ def gdbui(action: str, ctx: Context, args: PropertyDict, gdbgui_port: Optional[s process = subprocess.Popen(args, stdout=gdbgui_out, stderr=subprocess.STDOUT, bufsize=1, env=env) except (OSError, subprocess.CalledProcessError) as e: print(e) - if sys.version_info[:2] >= (3, 11) and sys.platform == 'win32': - raise SystemExit('Unfortunately, gdbgui is supported only with Python 3.10 or older. ' - 'See: https://github.com/espressif/esp-idf/issues/10116. ' - 'Please use "idf.py gdb" or debug in Eclipse/Vscode instead.') - raise FatalError('Error starting gdbgui. Please make sure gdbgui has been installed with ' - '"install.{sh,bat,ps1,fish} --enable-gdbgui" and can be started.', ctx) + raise FatalError('Error starting gdbgui', ctx) processes['gdbgui'] = process processes['gdbgui_outfile'] = gdbgui_out @@ -518,9 +543,9 @@ def coredump_info(action: str, ctx: Context, args: PropertyDict, gdb_timeout_sec: int, - core: str = None, - chip_rev: str = None, - save_core: str = None) -> None: + core: Optional[str] = None, + chip_rev: Optional[str] = None, + save_core: Optional[str] = None) -> None: espcoredump = _get_espcoredump_instance(ctx=ctx, args=args, gdb_timeout_sec=gdb_timeout_sec, core=core, chip_rev=chip_rev, save_core=save_core) @@ -530,9 +555,9 @@ def coredump_info(action: str, def coredump_debug(action: str, ctx: Context, args: PropertyDict, - core: str = None, - chip_rev: str = None, - save_core: str = None) -> None: + core: Optional[str] = None, + chip_rev: Optional[str] = None, + save_core: Optional[str] = None) -> None: espcoredump = _get_espcoredump_instance(ctx=ctx, args=args, core=core, chip_rev=chip_rev, save_core=save_core) espcoredump.dbg_corefile() diff --git a/tools/idf_py_actions/hints.yml b/tools/idf_py_actions/hints.yml index c47560a2be07..f3bd56bf21d2 100644 --- a/tools/idf_py_actions/hints.yml +++ b/tools/idf_py_actions/hints.yml @@ -426,3 +426,7 @@ - re: "implicit declaration of function '(opendir|readdir|telldir|seekdir|rewinddir|closedir|readdir_r|scandir|alphasort)'" hint: "Please include (not )" + +- + re: "unplaced orphan section" + hint: "Avoid creating custom sections. Please refer to the 'Linker Script Generation' article in the IDF documentation to address this. Or set option CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE (not recommended)." diff --git a/tools/idf_py_actions/qemu_ext.py b/tools/idf_py_actions/qemu_ext.py index 27797e087a8d..6bd38426237c 100644 --- a/tools/idf_py_actions/qemu_ext.py +++ b/tools/idf_py_actions/qemu_ext.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import atexit import binascii @@ -10,7 +10,9 @@ import sys import time from dataclasses import dataclass -from typing import Any, Dict, List +from typing import Any +from typing import Dict +from typing import List from click.core import Context @@ -90,6 +92,39 @@ class QemuTarget: '00000000000000000000000000000000000000000000000000000000000000000000000000000000' '00000000000000000000000000000000000000000000000000000000000000000000000000000000' '000000000000000000000000000000000000000000000000')), + 'esp32s3': QemuTarget( + 'esp32s3', + 'qemu-system-xtensa', + 'qemu-xtensa', + '-M esp32s3', + # Chip revision 0.3 + binascii.unhexlify( + '00000000000000000000000000000000000000000000000000000000000000000000000000000c00' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '00000000000000000000000000000000000000000000000000000000000000000000000000000000' + '000000000000000000000000000000000000000000000000')), } diff --git a/tools/idf_py_actions/tools.py b/tools/idf_py_actions/tools.py index 209424356918..76322ae7c66c 100644 --- a/tools/idf_py_actions/tools.py +++ b/tools/idf_py_actions/tools.py @@ -80,6 +80,7 @@ def executable_exists(args: List) -> bool: def _idf_version_from_cmake() -> Optional[str]: + """Acquires version of ESP-IDF from version.cmake""" version_path = os.path.join(os.environ['IDF_PATH'], 'tools/cmake/version.cmake') regex = re.compile(r'^\s*set\s*\(\s*IDF_VERSION_([A-Z]{5})\s+(\d+)') ver = {} @@ -113,7 +114,7 @@ def idf_version() -> Optional[str]: '--work-tree=%s' % os.environ['IDF_PATH'], 'describe', '--tags', '--dirty', '--match', 'v*.*', ]).decode('utf-8', 'ignore').strip() - except (subprocess.CalledProcessError, UnicodeError): + except Exception: # if failed, then try to parse cmake.version file sys.stderr.write('WARNING: Git version unavailable, reading from source\n') version = _idf_version_from_cmake() @@ -148,7 +149,7 @@ def get_default_serial_port() -> Any: # function prints warning when autocompletion is not being performed # set argument stream to sys.stderr for errors and exceptions -def print_warning(message: str, stream: TextIO=None) -> None: +def print_warning(message: str, stream: Optional[TextIO]=None) -> None: if not SHELL_COMPLETE_RUN: print(message, file=stream or sys.stderr) @@ -277,8 +278,9 @@ def fit_text_in_terminal(out: str) -> str: class RunTool: - def __init__(self, tool_name: str, args: List, cwd: str, env: Dict=None, custom_error_handler: FunctionType=None, build_dir: str=None, - hints: bool=True, force_progression: bool=False, interactive: bool=False, convert_output: bool=False) -> None: + def __init__(self, tool_name: str, args: List, cwd: str, env: Optional[Dict]=None, custom_error_handler: Optional[FunctionType]=None, + build_dir: Optional[str]=None, hints: bool=True, force_progression: bool=False, interactive: bool=False, convert_output: bool=False + ) -> None: self.tool_name = tool_name self.args = args self.cwd = cwd @@ -471,7 +473,7 @@ def run_tool(*args: Any, **kwargs: Any) -> None: def run_target(target_name: str, args: 'PropertyDict', env: Optional[Dict]=None, - custom_error_handler: FunctionType=None, force_progression: bool=False, interactive: bool=False) -> None: + custom_error_handler: Optional[FunctionType]=None, force_progression: bool=False, interactive: bool=False) -> None: """Run target in build directory.""" if env is None: env = {} @@ -554,7 +556,7 @@ def _detect_cmake_generator(prog_name: str) -> Any: def ensure_build_directory(args: 'PropertyDict', prog_name: str, always_run_cmake: bool=False, - env: Dict=None) -> None: + env: Optional[Dict]=None) -> None: """Check the build directory exists and that cmake has been run there. If this isn't the case, create the build directory (if necessary) and @@ -671,7 +673,7 @@ def merge_action_lists(*action_lists: Dict) -> Dict: return merged_actions -def get_sdkconfig_filename(args: 'PropertyDict', cache_cmdl: Dict=None) -> str: +def get_sdkconfig_filename(args: 'PropertyDict', cache_cmdl: Optional[Dict]=None) -> str: """ Get project's sdkconfig file name. """ @@ -720,7 +722,7 @@ def is_target_supported(project_path: str, supported_targets: List) -> bool: def _check_idf_target(args: 'PropertyDict', prog_name: str, cache: Dict, - cache_cmdl: Dict, env: Dict=None) -> None: + cache_cmdl: Dict, env: Optional[Dict]=None) -> None: """ Cross-check the three settings (sdkconfig, CMakeCache, environment) and if there is mismatch, fail with instructions on how to fix this. diff --git a/tools/idf_size.py b/tools/idf_size.py index 342340002ca1..a3cb75c7dabd 100755 --- a/tools/idf_size.py +++ b/tools/idf_size.py @@ -1,22 +1,35 @@ #!/usr/bin/env python # -# SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD # # SPDX-License-Identifier: Apache-2.0 # - import argparse import os import subprocess import sys if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--format') + # Here the argparse is used only to "peek" into arguments if + # legacy version is requested or if old json format is specified. + # In these two cases the esp_idf_size legacy version is spawned. + parser = argparse.ArgumentParser(add_help=False) + # Make the --format arg optional, so this argparse instance does not + # fail with an error and the proper underlying help is displayed. + # Note that exit_on_error is supported from python3.9, so this is + # a workaround how to make sure that the args parsing doesn't fail here if idf_size.py + # is invoked e.g. without specifying the format, like "idf_size.py --format". + parser.add_argument('--format', nargs='?') parser.add_argument('-l', '--legacy', action='store_true', default=os.environ.get('ESP_IDF_SIZE_LEGACY', '0') == '1') + + # The sys.argv is parsed with "exit_on_error", but the argparse.ArgumentError + # exception should never occur, because unknown args should be put into + # the rest variable, since the parse_known_args() method is used. args, rest = parser.parse_known_args() if not args.legacy and args.format != 'json': + # By default start the refactored version, unless legacy version is explicitly requested with + # -l/--legacy option or if old json format is specified. try: import esp_idf_size.ng # noqa: F401 except ImportError: @@ -24,9 +37,11 @@ args.legacy = True else: os.environ['ESP_IDF_SIZE_NG'] = '1' - - if args.legacy and args.format in ['json2', 'raw', 'tree']: - sys.exit(f'Legacy esp-idf-size does not support {args.format} format') + if not rest or '-h' in rest or '--help' in rest: + print(('Note: legacy esp_idf_size version can be invoked by specifying the -l/--legacy ' + 'option or by setting the ESP_IDF_SIZE_LEGACY environment variable. Additionally, the ' + 'legacy version is automatically employed when the JSON format is specified for ' + 'compatibility with previous versions.')) if args.format is not None: rest = ['--format', args.format] + rest diff --git a/tools/idf_tools.py b/tools/idf_tools.py index 4c0cfe8b68eb..50afe3a7f372 100755 --- a/tools/idf_tools.py +++ b/tools/idf_tools.py @@ -2139,7 +2139,8 @@ def check_python_venv_compatibility(idf_python_env_path: str, idf_version: str) raise SystemExit(1) except OSError as e: # perhaps the environment was generated before the support for VENV_VER_FILE was added - warn(f'Error while accessing the ESP-IDF version file in the Python environment: {e}') + warn(f'The following issue occurred while accessing the ESP-IDF version file in the Python environment: {e}. ' + '(Diagnostic information. It can be ignored.)') def action_export(args: Any) -> None: @@ -2598,18 +2599,12 @@ def action_install_python_env(args): # type: ignore warn(f'Removing the existing Python environment in {idf_python_env_path}') shutil.rmtree(idf_python_env_path) - venv_can_upgrade = False - if os.path.exists(virtualenv_python): check_python_venv_compatibility(idf_python_env_path, idf_version) else: if subprocess.run([sys.executable, '-m', 'venv', '-h'], check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0: # venv available virtualenv_options = ['--clear'] # delete environment if already exists - if sys.version_info[:2] >= (3, 9): - # upgrade pip & setuptools - virtualenv_options += ['--upgrade-deps'] - venv_can_upgrade = True info(f'Creating a new Python environment in {idf_python_env_path}') @@ -2638,7 +2633,8 @@ def action_install_python_env(args): # type: ignore with open(os.path.join(idf_python_env_path, VENV_VER_FILE), 'w') as f: f.write(idf_version) except OSError as e: - warn(f'Error while generating the ESP-IDF version file in the Python environment: {e}') + warn(f'The following issue occurred while generating the ESP-IDF version file in the Python environment: {e}. ' + '(Diagnostic information. It can be ignored.)') else: # The embeddable Python for Windows doesn't have the built-in venv module @@ -2649,17 +2645,19 @@ def action_install_python_env(args): # type: ignore warn('Found PIP_USER="yes" in the environment. Disabling PIP_USER in this shell to install packages into a virtual environment.') env_copy['PIP_USER'] = 'no' - if not venv_can_upgrade: - info('Upgrading pip and setuptools...') - subprocess.check_call([virtualenv_python, '-m', 'pip', 'install', '--upgrade', 'pip', 'setuptools'], - stdout=sys.stdout, stderr=sys.stderr, env=env_copy) + constraint_file = get_constraints(idf_version) if use_constraints else None + + info('Upgrading pip and setuptools...') + run_args = [virtualenv_python, '-m', 'pip', 'install', '--upgrade', 'pip', 'setuptools'] + if constraint_file: + run_args += ['--constraint', constraint_file] + subprocess.check_call(run_args, stdout=sys.stdout, stderr=sys.stderr, env=env_copy) run_args = [virtualenv_python, '-m', 'pip', 'install', '--no-warn-script-location'] requirements_file_list = get_requirements(args.features) for requirement_file in requirements_file_list: run_args += ['-r', requirement_file] - if use_constraints: - constraint_file = get_constraints(idf_version) + if constraint_file: run_args += ['--upgrade', '--constraint', constraint_file] if args.extra_wheels_dir: run_args += ['--find-links', args.extra_wheels_dir] @@ -2673,7 +2671,7 @@ def action_install_python_env(args): # type: ignore run_args += ['--find-links', wheels_dir] info('Installing Python packages') - if use_constraints: + if constraint_file: info(f' Constraint file: {constraint_file}') info(' Requirement files:') info(os.linesep.join(f' - {path}' for path in requirements_file_list)) diff --git a/tools/test_apps/linux_compatible/mock_build_test/main/mock_build_test.c b/tools/test_apps/linux_compatible/mock_build_test/main/mock_build_test.c index 1a00f1cf6889..9f64ecbd62e5 100644 --- a/tools/test_apps/linux_compatible/mock_build_test/main/mock_build_test.c +++ b/tools/test_apps/linux_compatible/mock_build_test/main/mock_build_test.c @@ -116,7 +116,7 @@ void app_main(void) esp_wifi_ap_get_sta_list_with_ip(NULL, NULL); esp_wifi_sta_itwt_setup_IgnoreAndReturn(ESP_OK); - esp_wifi_sta_itwt_setup((wifi_twt_setup_config_t*) NULL); + esp_wifi_sta_itwt_setup((wifi_itwt_setup_config_t*) NULL); sc_send_ack_stop_Ignore(); sc_send_ack_stop(); diff --git a/tools/test_apps/peripherals/i2c_wifi/main/i2c_wifi_main.c b/tools/test_apps/peripherals/i2c_wifi/main/i2c_wifi_main.c index 4f0cdcd7dce6..fcf1770a243a 100644 --- a/tools/test_apps/peripherals/i2c_wifi/main/i2c_wifi_main.c +++ b/tools/test_apps/peripherals/i2c_wifi/main/i2c_wifi_main.c @@ -56,7 +56,7 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, ESP_LOGI(TAG, "station "MACSTR" join, AID=%d", MAC2STR(event->mac), event->aid); } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *) event_data; - ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid); + ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d, reason=%d", MAC2STR(event->mac), event->aid, event->reason); } } diff --git a/tools/test_apps/system/cxx_build_test/main/CMakeLists.txt b/tools/test_apps/system/cxx_build_test/main/CMakeLists.txt index 695b17a1b3ee..59cbf3f832ab 100644 --- a/tools/test_apps/system/cxx_build_test/main/CMakeLists.txt +++ b/tools/test_apps/system/cxx_build_test/main/CMakeLists.txt @@ -1,6 +1,12 @@ -idf_component_register(SRCS cxx_build_test_main.cpp - test_soc_reg_macros.cpp - test_cxx_standard.cpp +set(srcs cxx_build_test_main.cpp + test_soc_reg_macros.cpp + test_cxx_standard.cpp) + +if(CONFIG_SOC_I2C_SUPPORTED) + list(APPEND srcs test_i2c_lcd.cpp) +endif() + +idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "." - PRIV_REQUIRES driver + PRIV_REQUIRES driver esp_lcd REQUIRES soc) diff --git a/tools/test_apps/system/cxx_build_test/main/test_i2c_lcd.cpp b/tools/test_apps/system/cxx_build_test/main/test_i2c_lcd.cpp new file mode 100644 index 000000000000..cb058d62c06c --- /dev/null +++ b/tools/test_apps/system/cxx_build_test/main/test_i2c_lcd.cpp @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include "esp_lcd_panel_vendor.h" +#include "esp_lcd_panel_io.h" +#include "driver/i2c_master.h" + +const esp_lcd_panel_dev_config_t panel_config0 = { + .reset_gpio_num = 0, + .color_space = ESP_LCD_COLOR_SPACE_MONOCHROME, + .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, + .bits_per_pixel = 16, + .flags = { + .reset_active_high = false, + }, + .vendor_config = NULL, +}; + +const esp_lcd_panel_dev_config_t panel_config1 = { + .reset_gpio_num = 0, + .color_space = ESP_LCD_COLOR_SPACE_BGR, + .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, + .bits_per_pixel = 16, + .flags = { + .reset_active_high = false, + }, + .vendor_config = NULL, +}; + +const esp_lcd_panel_dev_config_t panel_config2 = { + .reset_gpio_num = 0, + .rgb_endian = LCD_RGB_ENDIAN_BGR, + .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, + .bits_per_pixel = 16, + .flags = { + .reset_active_high = false, + }, + .vendor_config = NULL, +}; + +void test_i2c_lcd_apis(void) +{ + i2c_master_bus_config_t i2c_bus_conf = { + .i2c_port = -1, + .sda_io_num = GPIO_NUM_0, + .scl_io_num = GPIO_NUM_2, + .clk_source = I2C_CLK_SRC_DEFAULT, + .glitch_ignore_cnt = 0, + .intr_priority = 1, + .trans_queue_depth = 4, + .flags = { + .enable_internal_pullup = true, + } + }; + + i2c_master_bus_handle_t bus_handle; + i2c_new_master_bus(&i2c_bus_conf, &bus_handle); + + esp_lcd_panel_io_handle_t io_handle = NULL; + esp_lcd_panel_io_i2c_config_t io_config = { + .dev_addr = 0x3c, + .on_color_trans_done = NULL, + .user_ctx = NULL, + .control_phase_bytes = 1, + .dc_bit_offset = 6, + .lcd_cmd_bits = 8, + .lcd_param_bits = 8, + .flags = { + .dc_low_on_data = false, + .disable_control_phase = false, + }, + .scl_speed_hz = 10 * 1000, + }; + + esp_lcd_new_panel_io_i2c(bus_handle, &io_config, &io_handle); +} diff --git a/tools/test_apps/system/esp_intr_dump/expected_output/esp32c3.txt b/tools/test_apps/system/esp_intr_dump/expected_output/esp32c3.txt index 6140d1557b6f..5d10779cd1c9 100644 --- a/tools/test_apps/system/esp_intr_dump/expected_output/esp32c3.txt +++ b/tools/test_apps/system/esp_intr_dump/expected_output/esp32c3.txt @@ -5,11 +5,11 @@ CPU 0 interrupt status: 2 1 Level Used: RTC_CORE 3 1 Level Used: FROM_CPU_INTR0 4 1 Level Used: SYSTIMER_TARGET0_EDGE - 5 * * Reserved + 5 1 Level Used: TG0_WDT_LEVEL 6 * * Reserved - 7 1 Level Used: TG0_WDT_LEVEL - 8 * * Reserved - 9 1 Level Used: UART0 + 7 1 Level Used: UART0 + 8 * * Free + 9 * * Free 10 * * Free 11 * * Free 12 * * Free @@ -32,5 +32,4 @@ CPU 0 interrupt status: 29 * * Free 30 * * Free 31 * * Free -Interrupts available for general use: 18 -Shared interrupts: 0 \ No newline at end of file +Interrupts available for general use: 20 \ No newline at end of file diff --git a/tools/test_apps/system/esp_intr_dump/expected_output/esp32c6.txt b/tools/test_apps/system/esp_intr_dump/expected_output/esp32c6.txt index b72d47963284..2bb11d11c410 100644 --- a/tools/test_apps/system/esp_intr_dump/expected_output/esp32c6.txt +++ b/tools/test_apps/system/esp_intr_dump/expected_output/esp32c6.txt @@ -2,7 +2,7 @@ CPU 0 interrupt status: Int Level Type Status 0 * * Reserved 1 * * Reserved - 2 1 Level Used: LP_RTC_TIMER + 2 1 Level Shared: LP_RTC_TIMER 3 * * Reserved 4 * * Reserved 5 1 Level Used: CPU_FROM_CPU_0 @@ -33,4 +33,4 @@ CPU 0 interrupt status: 30 * * Free 31 * * Free Interrupts available for general use: 18 -Shared interrupts: 0 +Shared interrupts: 1 diff --git a/tools/test_apps/system/esp_intr_dump/expected_output/esp32h2.txt b/tools/test_apps/system/esp_intr_dump/expected_output/esp32h2.txt index e46e94fcc559..3af2a0d3d951 100644 --- a/tools/test_apps/system/esp_intr_dump/expected_output/esp32h2.txt +++ b/tools/test_apps/system/esp_intr_dump/expected_output/esp32h2.txt @@ -2,7 +2,7 @@ CPU 0 interrupt status: Int Level Type Status 0 * * Reserved 1 * * Reserved - 2 1 Level Used: LP_RTC_TIMER + 2 1 Level Shared: LP_RTC_TIMER 3 * * Reserved 4 * * Reserved 5 1 Level Used: CPUFROM_CPU_0 @@ -33,4 +33,4 @@ CPU 0 interrupt status: 30 * * Free 31 * * Free Interrupts available for general use: 18 -Shared interrupts: 0 +Shared interrupts: 1 diff --git a/tools/test_apps/system/esp_intr_dump/expected_output/esp32p4.txt b/tools/test_apps/system/esp_intr_dump/expected_output/esp32p4.txt index 0e92e63a9ab5..653010b71ef0 100644 --- a/tools/test_apps/system/esp_intr_dump/expected_output/esp32p4.txt +++ b/tools/test_apps/system/esp_intr_dump/expected_output/esp32p4.txt @@ -1,10 +1,10 @@ CPU 0 interrupt status: Int Level Type Status - 0 1 Level Used: CPU_INT_FROM_CPU_0 - 1 1 Level Used: SYSTIMER_TARGET0 - 2 1 Level Used: TG0_WDT_LEVEL - 3 1 Level Used: UART0 - 4 * * Free + 0 1 Level Used: LP_ANAPERI + 1 1 Level Used: CPU_INT_FROM_CPU_0 + 2 1 Level Used: SYSTIMER_TARGET0 + 3 1 Level Used: TG0_WDT_LEVEL + 4 1 Level Used: UART0 5 * * Free 6 * * Reserved 7 * * Free @@ -66,4 +66,4 @@ CPU 1 interrupt status: 29 * * Free 30 * * Free 31 * * Free -Interrupts available for general use: 48 +Interrupts available for general use: 47 diff --git a/tools/test_apps/system/esp_intr_dump/pytest_esp_intr_dump.py b/tools/test_apps/system/esp_intr_dump/pytest_esp_intr_dump.py index b4cfd0acf441..9beab7898441 100644 --- a/tools/test_apps/system/esp_intr_dump/pytest_esp_intr_dump.py +++ b/tools/test_apps/system/esp_intr_dump/pytest_esp_intr_dump.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import os @@ -12,7 +12,7 @@ @pytest.mark.qemu @pytest.mark.host_test def test_esp_intr_dump_nonshared(dut: Dut) -> None: - dut.expect_exact(PROMPT, timeout=10) + dut.expect_exact(PROMPT, timeout=30) dut.write('intr_alloc GPIO LEVEL3\n') dut.expect_exact('Allocated GPIO LEVEL3') @@ -26,7 +26,7 @@ def test_esp_intr_dump_nonshared(dut: Dut) -> None: @pytest.mark.qemu @pytest.mark.host_test def test_esp_intr_dump_shared(dut: Dut) -> None: - dut.expect_exact(PROMPT, timeout=10) + dut.expect_exact(PROMPT, timeout=30) dut.write('intr_alloc GPIO SHARED\n') dut.expect_exact('Allocated GPIO SHARED') @@ -50,7 +50,7 @@ def test_esp_intr_dump_shared(dut: Dut) -> None: @pytest.mark.supported_targets @pytest.mark.generic def test_esp_intr_dump_expected_output(dut: Dut) -> None: - dut.expect_exact(PROMPT, timeout=10) + dut.expect_exact(PROMPT, timeout=30) dut.write('intr_dump\n') exp_out_file = os.path.join(os.path.dirname(__file__), 'expected_output', f'{dut.target}.txt') for line in open(exp_out_file, 'r').readlines(): diff --git a/tools/test_apps/system/gdbstub_runtime/main/test_app_main.c b/tools/test_apps/system/gdbstub_runtime/main/test_app_main.c index 69bae474a830..7f3980e3a9cd 100644 --- a/tools/test_apps/system/gdbstub_runtime/main/test_app_main.c +++ b/tools/test_apps/system/gdbstub_runtime/main/test_app_main.c @@ -21,7 +21,7 @@ void foo(void) void app_main(void) { - printf("tested app is runnig.\n"); + printf("tested app is running.\n"); vTaskDelay(5000 / portTICK_PERIOD_MS); diff --git a/tools/test_apps/system/gdbstub_runtime/pytest_runtime.py b/tools/test_apps/system/gdbstub_runtime/pytest_runtime.py index b97fdc3b71fc..040e7f2c8352 100644 --- a/tools/test_apps/system/gdbstub_runtime/pytest_runtime.py +++ b/tools/test_apps/system/gdbstub_runtime/pytest_runtime.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import os.path as path import sys @@ -23,9 +22,9 @@ def get_line_number(lookup: str, offset: int = 0) -> int: @pytest.mark.supported_targets @pytest.mark.generic def test_gdbstub_runtime(dut: PanicTestDut) -> None: - dut.expect_exact('tested app is runnig.') + dut.expect_exact('tested app is running.') dut.write(b'\x03') # send Ctrl-C - dut.start_gdb() + dut.start_gdb_for_gdbstub() # Test breakpoint cmd = '-break-insert --source test_app_main.c --function app_main --label label_1' @@ -162,9 +161,9 @@ def test_gdbstub_runtime(dut: PanicTestDut) -> None: @pytest.mark.generic @pytest.mark.temp_skip_ci(targets=['esp32', 'esp32s2', 'esp32s3'], reason='fix IDF-7927') def test_gdbstub_runtime_xtensa_stepping_bug(dut: PanicTestDut) -> None: - dut.expect_exact('tested app is runnig.') + dut.expect_exact('tested app is running.') dut.write(b'\x03') # send Ctrl-C - dut.start_gdb() + dut.start_gdb_for_gdbstub() # Test breakpoint cmd = '-break-insert --source test_app_main.c --function app_main --label label_1' diff --git a/tools/test_apps/system/panic/CMakeLists.txt b/tools/test_apps/system/panic/CMakeLists.txt index 5d922b1b13e5..e9db4327f57b 100644 --- a/tools/test_apps/system/panic/CMakeLists.txt +++ b/tools/test_apps/system/panic/CMakeLists.txt @@ -17,7 +17,7 @@ if(CONFIG_TEST_MEMPROT) endif() endif() -if(NOT CONFIG_TEST_MEMPROT) +if(NOT CONFIG_TEST_MEMPROT AND NOT CONFIG_ESP_COREDUMP_CAPTURE_DRAM) # Enable UBSAN checks # # shift-base sanitizer is disabled due to the following pattern found in register header files: diff --git a/tools/test_apps/system/panic/main/include/test_memprot.h b/tools/test_apps/system/panic/main/include/test_memprot.h index d21d795f6082..6b8cfde2df9c 100644 --- a/tools/test_apps/system/panic/main/include/test_memprot.h +++ b/tools/test_apps/system/panic/main/include/test_memprot.h @@ -48,6 +48,10 @@ void test_drom_reg_write_violation(void); void test_drom_reg_execute_violation(void); +void test_invalid_memory_region_write_violation(void); + +void test_invalid_memory_region_execute_violation(void); + #ifdef __cplusplus } #endif diff --git a/tools/test_apps/system/panic/main/include/test_panic.h b/tools/test_apps/system/panic/main/include/test_panic.h index 5e96b2000c25..64dd22a5bc77 100644 --- a/tools/test_apps/system/panic/main/include/test_panic.h +++ b/tools/test_apps/system/panic/main/include/test_panic.h @@ -59,8 +59,14 @@ void test_assert(void); void test_assert_cache_disabled(void); +void test_assert_cache_write_back_error_can_print_backtrace(void); + +void test_assert_cache_write_back_error_can_print_backtrace2(void); + void test_illegal_access(void); +void test_capture_dram(void); + #ifdef __cplusplus } #endif diff --git a/tools/test_apps/system/panic/main/test_app_main.c b/tools/test_apps/system/panic/main/test_app_main.c index 1a387f0018b8..f1da4f2fd502 100644 --- a/tools/test_apps/system/panic/main/test_app_main.c +++ b/tools/test_apps/system/panic/main/test_app_main.c @@ -98,6 +98,9 @@ void app_main(void) #if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY HANDLE_TEST(test_name, test_panic_extram_stack); #endif +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM + HANDLE_TEST(test_name, test_capture_dram); +#endif #if !CONFIG_FREERTOS_UNICORE HANDLE_TEST(test_name, test_task_wdt_cpu1); #endif @@ -111,6 +114,8 @@ void app_main(void) HANDLE_TEST(test_name, test_ub); HANDLE_TEST(test_name, test_assert); HANDLE_TEST(test_name, test_assert_cache_disabled); + HANDLE_TEST(test_name, test_assert_cache_write_back_error_can_print_backtrace); + HANDLE_TEST(test_name, test_assert_cache_write_back_error_can_print_backtrace2); #if CONFIG_IDF_TARGET_ESP32 HANDLE_TEST(test_name, test_illegal_access); #endif @@ -155,6 +160,10 @@ void app_main(void) HANDLE_TEST(test_name, test_drom_reg_execute_violation); #endif +#ifdef CONFIG_SOC_CPU_HAS_PMA + HANDLE_TEST(test_name, test_invalid_memory_region_write_violation); + HANDLE_TEST(test_name, test_invalid_memory_region_execute_violation); +#endif #endif die("Unknown test name"); diff --git a/tools/test_apps/system/panic/main/test_memprot.c b/tools/test_apps/system/panic/main/test_memprot.c index cfefa415e69a..73885f1e0cb5 100644 --- a/tools/test_apps/system/panic/main/test_memprot.c +++ b/tools/test_apps/system/panic/main/test_memprot.c @@ -246,3 +246,21 @@ void test_drom_reg_execute_violation(void) func_ptr(); } #endif + +#ifdef CONFIG_SOC_CPU_HAS_PMA +void test_invalid_memory_region_write_violation(void) +{ + uint32_t *test_addr = (uint32_t *)((uint32_t)(SOC_DRAM_HIGH + 0x40)); + printf("Write operation | Address: %p\n", test_addr); + *test_addr = RND_VAL; + printf("%ld\n", *test_addr); +} + +void test_invalid_memory_region_execute_violation(void) +{ + void (*func_ptr)(void); + func_ptr = (void(*)(void))(SOC_DRAM_HIGH + 0x40); + printf("Execute operation | Address: %p\n", func_ptr); + func_ptr(); +} +#endif diff --git a/tools/test_apps/system/panic/main/test_panic.c b/tools/test_apps/system/panic/main/test_panic.c index eab2c082ee88..982049c07bfa 100644 --- a/tools/test_apps/system/panic/main/test_panic.c +++ b/tools/test_apps/system/panic/main/test_panic.c @@ -7,10 +7,12 @@ #include #include #include +#include #include "esp_partition.h" #include "esp_flash.h" #include "esp_system.h" +#include "spi_flash_mmap.h" #include "esp_private/cache_utils.h" #include "esp_memory_utils.h" @@ -20,6 +22,7 @@ #include "freertos/task.h" #include "hal/mpu_hal.h" +#include "rom/cache.h" /* Test utility function */ @@ -177,6 +180,46 @@ void IRAM_ATTR test_assert_cache_disabled(void) assert(0); } +const char TEST_STR[] = "my_tag"; +void test_assert_cache_write_back_error_can_print_backtrace(void) +{ + printf("1) %p\n", TEST_STR); + *(uint32_t*)TEST_STR = 3; // We changed the rodata string. + // All chips except ESP32S3 stop execution here and raise a LoadStore error on the line above. +#if CONFIG_IDF_TARGET_ESP32S3 + // On the ESP32S3, the error occurs later when the cache writeback is triggered + // (in this test, a direct call to Cache_WriteBack_All). + Cache_WriteBack_All(); // Cache writeback triggers the invalid cache access interrupt. +#endif + // We are testing that the backtrace is printed instead of TG1WDT. + printf("2) %p\n", TEST_STR); // never get to this place. +} + +void test_assert_cache_write_back_error_can_print_backtrace2(void) +{ + printf("1) %p\n", TEST_STR); + *(uint32_t*)TEST_STR = 3; // We changed the rodata string. + // All chips except ESP32S3 stop execution here and raise a LoadStore error on the line above. + // On the ESP32S3, the error occurs later when the cache writeback is triggered + // (in this test, a large range of DRAM is mapped and read, causing an error). + uint8_t temp = 0; + size_t map_size = SPI_FLASH_SEC_SIZE * 512; + const void *map; + spi_flash_mmap_handle_t out_handle; + esp_err_t err = spi_flash_mmap(0, map_size, SPI_FLASH_MMAP_DATA, &map, &out_handle); + if (err != ESP_OK) { + printf("spi_flash_mmap failed %x\n", err); + return; + } + const uint8_t *rodata = map; + for (size_t i = 0; i < map_size; i++) { + temp = rodata[i]; + } + // Cache writeback triggers the invalid cache access interrupt. + // We are testing that the backtrace is printed instead of TG1WDT. + printf("2) %p 0x%" PRIx8 " \n", TEST_STR, temp); // never get to this place. +} + /** * This function overwrites the stack beginning from the valid area continuously towards and beyond * the end of the stack (stack base) of the current task. @@ -252,3 +295,30 @@ void test_illegal_access(void) printf("[2] val: %d at %p\n", val, (void *)addr); } #endif + +#if CONFIG_ESP_COREDUMP_CAPTURE_DRAM +int g_data_var = 42; +int g_bss_var; +char *g_heap_ptr; +COREDUMP_IRAM_DATA_ATTR uint32_t g_cd_iram = 0x4242; +COREDUMP_DRAM_ATTR uint32_t g_cd_dram = 0x4343; +#if SOC_RTC_MEM_SUPPORTED +COREDUMP_RTC_FAST_ATTR uint32_t g_rtc_fast_var; +COREDUMP_RTC_DATA_ATTR uint32_t g_rtc_data_var = 0x55A9; +#endif + +void test_capture_dram(void) +{ + g_data_var++; + g_bss_var = 55; + g_heap_ptr = strdup("Coredump Test"); + assert(g_heap_ptr); + g_cd_iram++; + g_cd_dram++; +#if SOC_RTC_MEM_SUPPORTED + g_rtc_fast_var = 0xAABBCCDD; + g_rtc_data_var++; +#endif + assert(0); +} +#endif diff --git a/tools/test_apps/system/panic/partitions_capture_dram.csv b/tools/test_apps/system/panic/partitions_capture_dram.csv new file mode 100644 index 000000000000..3d69de387572 --- /dev/null +++ b/tools/test_apps/system/panic/partitions_capture_dram.csv @@ -0,0 +1,6 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +nvs,data,nvs,0x9000,24K, +phy_init,data,phy,0xf000,4K, +factory,app,factory,0x10000,1M, +coredump,data,coredump,0x110000,128K, diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index 90154a40d2e7..b83105b76f6d 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -89,6 +89,8 @@ pytest.param('panic', marks=TARGETS_RISCV_DUAL_CORE), ] +CONFIG_CAPTURE_DRAM = [pytest.param('coredump_flash_capture_dram', marks=TARGETS_ALL)] + # Panic abort information will start with this string. PANIC_ABORT_PREFIX = 'Panic reason: ' @@ -101,7 +103,7 @@ def common_test(dut: PanicTestDut, config: str, expected_backtrace: Optional[Lis expected_coredump: Optional[List[Union[str, re.Pattern]]] = None) -> None: if 'gdbstub' in config: dut.expect_exact('Entering gdb stub now.') - dut.start_gdb() + dut.start_gdb_for_gdbstub() frames = dut.gdb_backtrace() if expected_backtrace is not None: dut.verify_gdb_backtrace(frames, expected_backtrace) @@ -267,14 +269,12 @@ def test_cache_error(dut: PanicTestDut, config: str, test_func_name: str) -> Non if dut.target in ['esp32c3', 'esp32c2']: dut.expect_gme('Cache error') dut.expect_exact('Cached memory region accessed while ibus or cache is disabled') - elif dut.target in ['esp32c6', 'esp32h2']: + elif dut.target in ['esp32c6', 'esp32h2', 'esp32p4']: dut.expect_gme('Cache error') dut.expect_exact('Cache access error') elif dut.target in ['esp32s2']: # Cache error interrupt is not enabled, IDF-1558 dut.expect_gme('IllegalInstruction') - elif dut.target in ['esp32p4']: # TODO IDF-7515 - dut.expect_gme('Instruction access fault') else: dut.expect_gme('Cache disabled but cached memory region accessed') dut.expect_reg_dump(0) @@ -533,6 +533,42 @@ def test_assert_cache_disabled( ) +def cache_error_log_check(dut: PanicTestDut) -> None: + if dut.is_xtensa: + if dut.target == 'esp32s3': + dut.expect_exact("Guru Meditation Error: Core / panic'ed (Cache disabled but cached memory region accessed)") + dut.expect_exact('Write back error occurred while dcache tries to write back to flash') + dut.expect_exact('The following backtrace may not indicate the code that caused Cache invalid access') + else: + dut.expect_exact("Guru Meditation Error: Core 0 panic'ed (LoadStoreError)") + else: + dut.expect_exact("Guru Meditation Error: Core 0 panic'ed (Store access fault)") + dut.expect_reg_dump(0) + if dut.target == 'esp32s3': + dut.expect_reg_dump(1) + dut.expect_cpu_reset() + + +@pytest.mark.generic +@pytest.mark.supported_targets +@pytest.mark.parametrize('config', ['panic'], indirect=True) +def test_assert_cache_write_back_error_can_print_backtrace( + dut: PanicTestDut, config: str, test_func_name: str +) -> None: + dut.run_test_func(test_func_name) + cache_error_log_check(dut) + + +@pytest.mark.generic +@pytest.mark.supported_targets +@pytest.mark.parametrize('config', ['panic'], indirect=True) +def test_assert_cache_write_back_error_can_print_backtrace2( + dut: PanicTestDut, config: str, test_func_name: str +) -> None: + dut.run_test_func(test_func_name) + cache_error_log_check(dut) + + @pytest.mark.esp32 @pytest.mark.generic @pytest.mark.parametrize('config', ['panic_delay'], indirect=True) @@ -588,6 +624,12 @@ def test_panic_delay(dut: PanicTestDut) -> None: pytest.param('memprot_esp32p4', marks=[pytest.mark.esp32p4]) ] +CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA = [ + pytest.param('memprot_esp32c6', marks=[pytest.mark.esp32c6]), + pytest.param('memprot_esp32h2', marks=[pytest.mark.esp32h2]), + pytest.param('memprot_esp32p4', marks=[pytest.mark.esp32p4]) +] + @pytest.mark.parametrize('config', CONFIGS_MEMPROT_DCACHE, indirect=True) @pytest.mark.generic @@ -851,6 +893,24 @@ def test_drom_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> N dut.expect_cpu_reset() +@pytest.mark.parametrize('config', CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA, indirect=True) +@pytest.mark.generic +def test_invalid_memory_region_write_violation(dut: PanicTestDut, test_func_name: str) -> None: + dut.run_test_func(test_func_name) + dut.expect_gme('Store access fault') + dut.expect_reg_dump(0) + dut.expect_cpu_reset() + + +@pytest.mark.parametrize('config', CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA, indirect=True) +@pytest.mark.generic +def test_invalid_memory_region_execute_violation(dut: PanicTestDut, test_func_name: str) -> None: + dut.run_test_func(test_func_name) + dut.expect_gme('Instruction access fault') + dut.expect_reg_dump(0) + dut.expect_cpu_reset() + + @pytest.mark.esp32 @pytest.mark.generic @pytest.mark.parametrize('config', ['gdbstub_coredump'], indirect=True) @@ -861,7 +921,7 @@ def test_gdbstub_coredump(dut: PanicTestDut) -> None: dut.process_coredump_uart() dut.expect_exact('Entering gdb stub now.') - dut.start_gdb() + dut.start_gdb_for_gdbstub() frames = dut.gdb_backtrace() dut.verify_gdb_backtrace(frames, get_default_backtrace(test_func_name)) dut.revert_log_level() @@ -913,3 +973,34 @@ def test_illegal_access(dut: PanicTestDut, config: str, test_func_name: str) -> dut.expect_backtrace() dut.expect_elf_sha256() dut.expect_none('Guru Meditation') + + +@pytest.mark.parametrize('config', CONFIG_CAPTURE_DRAM, indirect=True) +@pytest.mark.generic +def test_capture_dram(dut: PanicTestDut, config: str, test_func_name: str) -> None: + dut.run_test_func(test_func_name) + regex_pattern = rb'assert failed:[\s\w()]*?\s[.\w/]*\.(?:c|cpp|h|hpp):\d.*$' + dut.expect(re.compile(regex_pattern, re.MULTILINE)) + if dut.is_xtensa: + dut.expect_backtrace() + else: + dut.expect_stack_dump() + dut.expect_elf_sha256() + dut.expect_none(['Guru Meditation', 'Re-entered core dump']) + + dut.expect_exact('Save core dump to flash...') + dut.expect_exact('Core dump has been saved to flash.') + dut.expect('Rebooting...') + + core_elf_file = dut.process_coredump_flash() + dut.start_gdb_for_coredump(core_elf_file) + + assert dut.gdb_data_eval_expr('g_data_var') == '43' + assert dut.gdb_data_eval_expr('g_bss_var') == '55' + assert re.search(r'0x[0-9a-fA-F]+ "Coredump Test"', dut.gdb_data_eval_expr('g_heap_ptr')) + assert int(dut.gdb_data_eval_expr('g_cd_iram')) == 0x4243 + assert int(dut.gdb_data_eval_expr('g_cd_dram')) == 0x4344 + + if dut.target != 'esp32c2': + assert int(dut.gdb_data_eval_expr('g_rtc_data_var')) == 0x55AA + assert int(dut.gdb_data_eval_expr('g_rtc_fast_var')) == 0xAABBCCDD diff --git a/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_capture_dram b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_capture_dram new file mode 100644 index 000000000000..d8e5231dc195 --- /dev/null +++ b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_capture_dram @@ -0,0 +1,7 @@ +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y +CONFIG_ESP_COREDUMP_CAPTURE_DRAM=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_capture_dram.csv" +CONFIG_LOG_DEFAULT_LEVEL_INFO=y diff --git a/tools/test_apps/system/panic/test_panic_util/panic_dut.py b/tools/test_apps/system/panic/test_panic_util/panic_dut.py index d7eae8d30602..205035e5b032 100644 --- a/tools/test_apps/system/panic/test_panic_util/panic_dut.py +++ b/tools/test_apps/system/panic/test_panic_util/panic_dut.py @@ -120,15 +120,15 @@ def expect_coredump(self, output_file_name: str, patterns: List[Union[str, re.Pa for pattern in patterns: if isinstance(pattern, str): position = coredump.find(pattern) - assert position != -1, f"'{pattern}' not found in the coredump output" + assert position != -1, f"'{pattern}' not in the coredump output" elif isinstance(pattern, re.Pattern): match = pattern.findall(coredump) - assert match, f"'{pattern.pattern}' not found in the coredump output" + assert match, f"'{pattern.pattern}' not in the coredump output" else: raise ValueError(f'Unsupported input type: {type(pattern).__name__}') def _call_espcoredump( - self, extra_args: List[str], coredump_file_name: str, output_file_name: str + self, extra_args: List[str], output_file_name: str ) -> None: # no "with" here, since we need the file to be open for later inspection by the test case if not self.coredump_output: @@ -142,14 +142,13 @@ def _call_espcoredump( espcoredump_script, '-b115200', 'info_corefile', - '--core', - coredump_file_name, ] espcoredump_args += extra_args espcoredump_args.append(self.app.elf_file) logging.info('Running %s', ' '.join(espcoredump_args)) logging.info('espcoredump output is written to %s', self.coredump_output.name) + self.serial.close() subprocess.check_call(espcoredump_args, stdout=self.coredump_output) self.coredump_output.flush() self.coredump_output.seek(0) @@ -165,33 +164,31 @@ def process_coredump_uart(self, expected: Optional[List[Union[str, re.Pattern]]] output_file_name = os.path.join(self.logdir, 'coredump_uart_result.txt') self._call_espcoredump( - ['--core-format', 'b64'], coredump_file.name, output_file_name + ['--core-format', 'b64', '--core', coredump_file.name], output_file_name ) if expected: self.expect_coredump(output_file_name, expected) - def process_coredump_flash(self, expected: Optional[List[Union[str, re.Pattern]]] = None) -> None: - """Extract the core dump from flash, run espcoredump on it""" + def process_coredump_flash(self, expected: Optional[List[Union[str, re.Pattern]]] = None) -> Any: coredump_file_name = os.path.join(self.logdir, 'coredump_data.bin') logging.info('Writing flash binary core dump to %s', coredump_file_name) - self.serial.dump_flash(partition='coredump', output=coredump_file_name) - output_file_name = os.path.join(self.logdir, 'coredump_flash_result.txt') self._call_espcoredump( - ['--core-format', 'raw'], coredump_file_name, output_file_name + ['--core-format', 'raw', '--save-core', coredump_file_name], output_file_name ) if expected: self.expect_coredump(output_file_name, expected) + return coredump_file_name def gdb_write(self, command: str) -> Any: """ Wrapper to write to gdb with a longer timeout, as test runner host can be slow sometimes """ - assert self.gdbmi, 'This function should be called only after start_gdb' + assert self.gdbmi, 'This function should be called only after run_gdb' return self.gdbmi.write(command, timeout_sec=10) - def start_gdb(self) -> None: + def run_gdb(self) -> None: """ Runs GDB and connects it to the "serial" port of the DUT. After this, the DUT expect methods can no longer be used to capture output. @@ -262,6 +259,11 @@ def start_gdb(self) -> None: # Load the ELF file self.gdb_write('-file-exec-and-symbols {}'.format(self.app.elf_file)) + # Prepare gdb for the gdb stub + def start_gdb_for_gdbstub(self) -> None: + + self.run_gdb() + # Connect GDB to UART self.serial.close() logging.info('Connecting to GDB Stub...') @@ -290,7 +292,14 @@ def start_gdb(self) -> None: logging.info('Stopped in {func} at {addr} ({file}:{line})'.format(**frame)) # Drain remaining responses - self.gdbmi.get_gdb_response(raise_error_on_timeout=False) + if self.gdbmi: + self.gdbmi.get_gdb_response(raise_error_on_timeout=False) + + # Prepare gdb to debug coredump file + def start_gdb_for_coredump(self, elf_file: str) -> None: + + self.run_gdb() + self.gdb_write('core {}'.format(elf_file)) def gdb_backtrace(self) -> Any: """ @@ -302,6 +311,10 @@ def gdb_backtrace(self) -> Any: responses = self.gdb_write('-stack-list-frames') return self.find_gdb_response('done', 'result', responses)['payload']['stack'] + def gdb_data_eval_expr(self, expr: str) -> Any: + responses = self.gdb_write('-data-evaluate-expression "%s"' % expr) + return self.find_gdb_response('done', 'result', responses)['payload']['value'] + @staticmethod def verify_gdb_backtrace( gdb_backtrace: List[Any], expected_functions_list: List[Any] diff --git a/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults b/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults index ffa7983c0fd1..f218f6c43e2a 100644 --- a/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults +++ b/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults @@ -4,3 +4,6 @@ CONFIG_APP_BUILD_TYPE_RAM=y CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y CONFIG_APP_BUILD_TYPE_PURE_RAM_APP=n + +CONFIG_COMPILER_OPTIMIZATION_DEBUG=n +CONFIG_COMPILER_OPTIMIZATION_SIZE=y diff --git a/tools/test_idf_size/pytest.ini b/tools/test_idf_size/pytest.ini new file mode 100644 index 000000000000..d95e773e5cd3 --- /dev/null +++ b/tools/test_idf_size/pytest.ini @@ -0,0 +1,12 @@ +[pytest] +addopts = -s -p no:pytest_embedded + +# log related +log_cli = True +log_cli_level = INFO +log_cli_format = %(asctime)s %(levelname)s %(message)s +log_cli_date_format = %Y-%m-%d %H:%M:%S + +## log all to `system-out` when case fail +junit_logging = stdout +junit_log_passing_tests = False diff --git a/tools/test_idf_size/test_idf_size.py b/tools/test_idf_size/test_idf_size.py new file mode 100644 index 000000000000..2a3baabbe0a9 --- /dev/null +++ b/tools/test_idf_size/test_idf_size.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import logging +import os +import sys +from pathlib import Path +from subprocess import DEVNULL +from subprocess import run + + +def test_idf_size() -> None: + # Simple test to make sure that the idf_size.py wrapper is compatible + # with idf.py minimum required python version. + logging.info('idf_size.py python compatibility check') + idf_size_path = Path(os.environ['IDF_PATH']) / 'tools' / 'idf_size.py' + run([sys.executable, idf_size_path, '--help'], stdout=DEVNULL, stderr=DEVNULL, check=True) diff --git a/tools/test_idf_tools/test_idf_tools.py b/tools/test_idf_tools/test_idf_tools.py index 09f2d1955392..c83df0daa279 100755 --- a/tools/test_idf_tools/test_idf_tools.py +++ b/tools/test_idf_tools/test_idf_tools.py @@ -118,14 +118,17 @@ def setUpClass(cls): old_tools_dir = os.environ.get('IDF_TOOLS_PATH') or os.path.expanduser(idf_tools.IDF_TOOLS_PATH_DEFAULT) mirror_prefix_map = None - if os.path.exists(old_tools_dir): - mirror_prefix_map = 'https://dl.espressif.com/dl/toolchains/preview,file:' + os.path.join(old_tools_dir, - 'dist') - mirror_prefix_map += ';https://dl.espressif.com/dl,file:' + os.path.join(old_tools_dir, 'dist') - mirror_prefix_map += ';https://github.com/espressif/.*/releases/download/.*/,file:' + os.path.join( - old_tools_dir, 'dist', '') + if os.path.exists(old_tools_dir) and sys.platform != 'win32': + # These are are all mapping to filesystem. Windows cannot download from there not even if file:// is omitted + local = ''.join(['file://', os.path.join(old_tools_dir, 'dist', '')]) + + mirror_prefix_map = ';'.join([f'https://dl.espressif.com/dl,{local}', + f'https://github.com/.*/.*/releases/download/.*/,{local}']) + + # Windows will keep downloading the tools from default location or IDF_MIRROR_PREFIX_MAP if set globally + if mirror_prefix_map: - print('Using IDF_MIRROR_PREFIX_MAP={}'.format(mirror_prefix_map)) + print(f'Using IDF_MIRROR_PREFIX_MAP={mirror_prefix_map}') os.environ['IDF_MIRROR_PREFIX_MAP'] = mirror_prefix_map cls.temp_tools_dir = tempfile.mkdtemp(prefix='idf_tools_tmp') diff --git a/tools/tools.json b/tools/tools.json index 70515fe35d4e..09e6053d6fc3 100644 --- a/tools/tools.json +++ b/tools/tools.json @@ -180,51 +180,51 @@ "versions": [ { "linux-amd64": { - "sha256": "4e43e56cd533a39c6b0ccc8b30320b19ce66b0b17e646b53fa84c9bf956b2c83", - "size": 112254280, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/xtensa-esp-elf-13.2.0_20240305-x86_64-linux-gnu.tar.xz" + "sha256": "fcef03d87eac44c0dbee2bbee98443ed2fcf82720dcd8ebfe00640807b0f07c2", + "size": 112073272, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.xz" }, "linux-arm64": { - "sha256": "06bc30be9d824fa8da507dff228085563baa7f6251e42a14deae0ca0e93ec2eb", - "size": 103677608, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/xtensa-esp-elf-13.2.0_20240305-aarch64-linux-gnu.tar.xz" + "sha256": "cfe55b92b4baeaa4309a948ba65e2adfc2d17a542c64856e36650869b419574a", + "size": 102954792, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-aarch64-linux-gnu.tar.xz" }, "linux-armel": { - "sha256": "f0ecab5ae0a63abf4e43b1f3873d89181d1772748f028653f5e81264fb451e61", - "size": 106290920, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/xtensa-esp-elf-13.2.0_20240305-arm-linux-gnueabi.tar.xz" + "sha256": "c57a062969ec3d98b02a97cd9240eb31091957788509b60c356b0a6f23032669", + "size": 104791600, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-arm-linux-gnueabi.tar.xz" }, "linux-armhf": { - "sha256": "15ed342e9d5c647dce8c688a4796bf8b0b9e44283f9ebe99e11aba63cc3d85b2", - "size": 102905548, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/xtensa-esp-elf-13.2.0_20240305-arm-linux-gnueabihf.tar.xz" + "sha256": "1adc660f4d7bcf863f54051c5843719456fabc7203c1d4ccbb855924fda82987", + "size": 101896352, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-arm-linux-gnueabihf.tar.xz" }, "linux-i686": { - "sha256": "73fe99abc7d7a33eeb13473902e7025f0b41626891cb358a4dc9bf02b2b53931", - "size": 117286888, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/xtensa-esp-elf-13.2.0_20240305-i586-linux-gnu.tar.xz" + "sha256": "f9203673aa0c42b041847c86b07e6f5b4aa9c90e6ff03d3cd3146928784447ea", + "size": 112724172, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-i586-linux-gnu.tar.xz" }, "macos": { - "sha256": "5bf2b5ececdf92169e5a084d2485b8d0d60480ce130a3035dc407f01e4e7820d", - "size": 115090676, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/xtensa-esp-elf-13.2.0_20240305-x86_64-apple-darwin.tar.xz" + "sha256": "39ee7df749f4ceb93624d73627688d5b86269a7429022f986f2940499936aacd", + "size": 114904912, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-x86_64-apple-darwin.tar.xz" }, "macos-arm64": { - "sha256": "e2bf7886bb39ad6558e1f46160fae887705f903ea8b77cd28bbf77093d3ca286", - "size": 100350656, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/xtensa-esp-elf-13.2.0_20240305-aarch64-apple-darwin.tar.xz" + "sha256": "d967e49a64f823e18fbae273efb1b094ac55e2207aa21fd3947c9d59f999f47e", + "size": 100018744, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-aarch64-apple-darwin.tar.xz" }, - "name": "esp-13.2.0_20240305", + "name": "esp-13.2.0_20240530", "status": "recommended", "win32": { - "sha256": "79ea0dbd314012f199fc9a9bbbcc4c11473ea87f81be4c1b4c60328d3d73b9f8", - "size": 266666180, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/xtensa-esp-elf-13.2.0_20240305-i686-w64-mingw32.zip" + "sha256": "d6b227c50e3c8e21d62502b3140e5ab74a4cb502c2b4169c36238b9858a8fb88", + "size": 266042967, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-i686-w64-mingw32_hotfix.zip" }, "win64": { - "sha256": "a80879c35b7f82ce80332ef0b68b0c7d245bafd9c98a35c45965850f40faf5ba", - "size": 270417276, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/xtensa-esp-elf-13.2.0_20240305-x86_64-w64-mingw32.zip" + "sha256": "155ee97b531236e6a7c763395c68ca793e55e74d2cb4d38a23057a153e01e7d0", + "size": 269831985, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-x86_64-w64-mingw32_hotfix.zip" } } ] @@ -328,51 +328,51 @@ "versions": [ { "linux-amd64": { - "sha256": "2bd71171ddb801e59c85ecbea3b89d6f707627d6c11e501cae43ca7c0db73eda", - "size": 145977452, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/riscv32-esp-elf-13.2.0_20240305-x86_64-linux-gnu.tar.xz" + "sha256": "f69a491d2f42f63e119f9077da995f7743ea8e1bf6944166a42a312cf60728a8", + "size": 145544808, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.xz" }, "linux-arm64": { - "sha256": "806ccd08333a96ae73507625a1762f7ac7a8c82f193602cafb835c4d7f5678ab", - "size": 144233996, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/riscv32-esp-elf-13.2.0_20240305-aarch64-linux-gnu.tar.xz" + "sha256": "276351b883a53e81b695d858be74114a8b627bbe4fc9c69ef46a7127ab143680", + "size": 145564848, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-aarch64-linux-gnu.tar.xz" }, "linux-armel": { - "sha256": "312f404e86dde7d22f5c4b7216ea386dbf8d5f93dea50f689471cedc2e457f91", - "size": 136753128, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/riscv32-esp-elf-13.2.0_20240305-arm-linux-gnueabi.tar.xz" + "sha256": "14890f2a624e70f11da7268347adf25b6c396f42bcd4d8ac3c5bfa4050b7c934", + "size": 140376832, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-arm-linux-gnueabi.tar.xz" }, "linux-armhf": { - "sha256": "a546224d8dc33c6a00a35b5856261232ce9218953e2ee8bcacdcc899d0c19591", - "size": 145140184, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/riscv32-esp-elf-13.2.0_20240305-arm-linux-gnueabihf.tar.xz" + "sha256": "b61ca9ceff25986ec1d166a01319bff09639be1d4ee5bf117502ce564fdae7e9", + "size": 142416372, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-arm-linux-gnueabihf.tar.xz" }, "linux-i686": { - "sha256": "09d0ee10e1e617a93f6597c279bf9388b6384790a45b1d87451a40d1ff4e5f71", - "size": 156611372, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/riscv32-esp-elf-13.2.0_20240305-i586-linux-gnu.tar.xz" + "sha256": "12ef50f96deb9040ce360974a4237c64ae0706b0c429b90cecc8ab664cf6dbb4", + "size": 156221552, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-i586-linux-gnu.tar.xz" }, "macos": { - "sha256": "dfb4a2f46c66a9246a25e3c34b19a91c7a3f33a44721cd61ec01d442d5344193", - "size": 152864248, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/riscv32-esp-elf-13.2.0_20240305-x86_64-apple-darwin.tar.xz" + "sha256": "cfbf5deaba05bf217701c8ceab7396bb0c2ca95ab58e134d4b2e175b86c2fd6c", + "size": 152568972, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-x86_64-apple-darwin.tar.xz" }, "macos-arm64": { - "sha256": "1e48833974a8e9ad2a0ac287ad244b825392d623edaf269bd66f4d8a215a0ef8", - "size": 136622828, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/riscv32-esp-elf-13.2.0_20240305-aarch64-apple-darwin.tar.xz" + "sha256": "230628fcf464ca8856c82c55514e40a8919e97fbc5e66b7165ca42c9653d2302", + "size": 136326672, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-aarch64-apple-darwin.tar.xz" }, - "name": "esp-13.2.0_20240305", + "name": "esp-13.2.0_20240530", "status": "recommended", "win32": { - "sha256": "61492d38a0ceaae7b4784820810f9717454a0b4413a9f20ced595122eae3111f", - "size": 362677865, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/riscv32-esp-elf-13.2.0_20240305-i686-w64-mingw32.zip" + "sha256": "590bfb10576702639825581cc00c445da6e577012840a787137417e80d15f46d", + "size": 366573064, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-i686-w64-mingw32.zip" }, "win64": { - "sha256": "e1e63f1926b9c643bc1de72e30cc79fc2079ad169546669e55836efbcc559d11", - "size": 366029146, - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240305/riscv32-esp-elf-13.2.0_20240305-x86_64-w64-mingw32.zip" + "sha256": "413eb9f6adf8fdaf25544d014c850fc09eb38bb93a2fc5ebd107ab1b0de1bb3a", + "size": 369820297, + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-x86_64-w64-mingw32.zip" } } ] @@ -896,31 +896,31 @@ "versions": [ { "linux-amd64": { - "sha256": "e7c72ef5705ad1444d391711088c8717fc89f42e9bf6d1487f9c2a326b8cfa83", - "size": 14714724, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-x86_64-linux-gnu.tar.xz" + "sha256": "071d117c44a6e9a1bc8664ab63b592d3e17ceb779119dcb46c59571a4a7a88c9", + "size": 13611248, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-xtensa-softmmu-esp_develop_9.0.0_20240606-x86_64-linux-gnu.tar.xz" }, "linux-arm64": { - "sha256": "77c83f2772f7d9b0c770722c2cebf3625d21d8eddbccfea6816f3d8f4982ea86", - "size": 14239876, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-aarch64-linux-gnu.tar.xz" + "sha256": "43552f32b303a6820d0d9551903e54fc221aca98ccbd04e5cbccbca881548008", + "size": 15247720, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-xtensa-softmmu-esp_develop_9.0.0_20240606-aarch64-linux-gnu.tar.xz" }, "macos": { - "sha256": "897126a12aeac1cc7d8e9a50626cdf0bc4812fd4bceb77b07ff4a81b86deaaa4", - "size": 3379992, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-x86_64-apple-darwin.tar.xz" + "sha256": "0096734280ce04f558cd9bd72f35db39667f80d44309a35565f2f8c02d1f9cc3", + "size": 3707956, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-xtensa-softmmu-esp_develop_9.0.0_20240606-x86_64-apple-darwin.tar.xz" }, "macos-arm64": { - "sha256": "9134f6dc653c6dd556a6c9c2d80b9eca0c437a8f625e994f9285aadf7b2e7d6f", - "size": 3200756, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-aarch64-apple-darwin.tar.xz" + "sha256": "fb4ca6be7b1a4dbcf153879cf0582300f974371def0826c0c5b728f12812ad08", + "size": 3456764, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-xtensa-softmmu-esp_develop_9.0.0_20240606-aarch64-apple-darwin.tar.xz" }, - "name": "esp_develop_8.2.0_20240122", + "name": "esp_develop_9.0.0_20240606", "status": "recommended", "win64": { - "sha256": "fc49844b506697542558d3fcb2fe64171b3d28f47e59000ebe8e198d32091d45", - "size": 32225200, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-x86_64-w64-mingw32.tar.xz" + "sha256": "281659f7a1d49761ac6f54d0aeb14366cb93c002f21948b847a0e15c0b8f5425", + "size": 33957256, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-xtensa-softmmu-esp_develop_9.0.0_20240606-x86_64-w64-mingw32.tar.xz" } } ] @@ -949,31 +949,31 @@ "versions": [ { "linux-amd64": { - "sha256": "95ac86d7b53bf98b5ff19c33aa926189b849f5a0daf8f41e160bc86c5e31abd4", - "size": 16275380, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-riscv32-softmmu-esp_develop_8.2.0_20240122-x86_64-linux-gnu.tar.xz" + "sha256": "47120e826cfec7180db8cb611a7a4aed2e9b2191c2a739194f8ce085e63cdd8d", + "size": 14454468, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-riscv32-softmmu-esp_develop_9.0.0_20240606-x86_64-linux-gnu.tar.xz" }, "linux-arm64": { - "sha256": "4089f7958f753779e5b4c93fe2469d62850a1f209b0bda8b75d55fe4a61ca39b", - "size": 15796904, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-riscv32-softmmu-esp_develop_8.2.0_20240122-aarch64-linux-gnu.tar.xz" + "sha256": "3b6221a8b1881d2c9b9fa0b0bf8d7065c84153d2a54e429307bde9feae235c27", + "size": 16542756, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-riscv32-softmmu-esp_develop_9.0.0_20240606-aarch64-linux-gnu.tar.xz" }, "macos": { - "sha256": "e9cc3c1344f6bf1ffa3748a4c59d88f9005c2689cc0583458cea35409a73c923", - "size": 3502440, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-riscv32-softmmu-esp_develop_8.2.0_20240122-x86_64-apple-darwin.tar.xz" + "sha256": "3afa55d5abea52ccf18d0bc41fe819d568bd4ee1582989b1ee9b1ee4a609a31e", + "size": 3751096, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-riscv32-softmmu-esp_develop_9.0.0_20240606-x86_64-apple-darwin.tar.xz" }, "macos-arm64": { - "sha256": "b3f23e294cf325f92e5e8948583cc985d55d5d2ba3d79c04c9d09f080b62954d", - "size": 3219984, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-riscv32-softmmu-esp_develop_8.2.0_20240122-aarch64-apple-darwin.tar.xz" + "sha256": "69ba5154594fb2922d5490a49ea6b4925c024c6c37f875b42f9885f513e0bcdd", + "size": 3409264, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-riscv32-softmmu-esp_develop_9.0.0_20240606-aarch64-apple-darwin.tar.xz" }, - "name": "esp_develop_8.2.0_20240122", + "name": "esp_develop_9.0.0_20240606", "status": "recommended", "win64": { - "sha256": "36008768c7ce91927e73de5e4298625087c01208e6122d886e578d400fd93b5c", - "size": 35229220, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-riscv32-softmmu-esp_develop_8.2.0_20240122-x86_64-w64-mingw32.tar.xz" + "sha256": "f49bb5c8f4d6e2cfbf7eeec21eb8ef190a57307778705bc689536ac13bde511c", + "size": 36274632, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-9.0.0-20240606/qemu-riscv32-softmmu-esp_develop_9.0.0_20240606-x86_64-w64-mingw32.tar.xz" } } ]