diff --git a/.github/workflows/issue_comment.yml b/.github/workflows/issue_comment.yml index b542f792f90..f78a699082b 100644 --- a/.github/workflows/issue_comment.yml +++ b/.github/workflows/issue_comment.yml @@ -12,7 +12,7 @@ jobs: name: Sync Issue Comments to Jira runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Sync issue comments to JIRA uses: espressif/github-actions/sync_issues_to_jira@master env: diff --git a/.github/workflows/new_issues.yml b/.github/workflows/new_issues.yml index 4d355c07767..7a8879a42a1 100644 --- a/.github/workflows/new_issues.yml +++ b/.github/workflows/new_issues.yml @@ -12,7 +12,7 @@ jobs: name: Sync issues to Jira runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Sync GitHub issues to Jira project uses: espressif/github-actions/sync_issues_to_jira@master env: diff --git a/.github/workflows/new_prs.yml b/.github/workflows/new_prs.yml index 4c750bba152..3000aff80a7 100644 --- a/.github/workflows/new_prs.yml +++ b/.github/workflows/new_prs.yml @@ -15,7 +15,7 @@ jobs: name: Sync PRs to Jira runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Sync PRs to Jira project uses: espressif/github-actions/sync_issues_to_jira@master with: diff --git a/.github/workflows/pr_approved.yml b/.github/workflows/pr_approved.yml index 963d6cba87d..a641a7e5019 100644 --- a/.github/workflows/pr_approved.yml +++ b/.github/workflows/pr_approved.yml @@ -11,7 +11,7 @@ jobs: (github.event.label.name == 'PR-Sync-Rebase') || (github.event.label.name == 'PR-Sync-Update') steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Sync approved PRs to internal codebase uses: espressif/github-actions/github_pr_to_internal_pr@master env: diff --git a/.github/workflows/pre_commit_check.yml b/.github/workflows/pre_commit_check.yml index af77668695a..859f5678071 100644 --- a/.github/workflows/pre_commit_check.yml +++ b/.github/workflows/pre_commit_check.yml @@ -14,7 +14,7 @@ jobs: SKIP: "cleanup-ignore-lists" # Comma-separated string of ignored pre-commit check IDs steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Fetch head and base refs # This is necessary for pre-commit to check the changes in the PR branch run: | diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 4dc470e3219..17ea1094728 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -87,6 +87,7 @@ /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_eth/ @esp-idf-codeowners/network /components/esp_event/ @esp-idf-codeowners/system /components/esp_gdbstub/ @esp-idf-codeowners/debugging @@ -152,18 +153,18 @@ /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/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 +/docs/ @esp-idf-codeowners/docs +/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 diff --git a/.gitlab/ci/README.md b/.gitlab/ci/README.md index a3ff2bbb986..ab138c09433 100644 --- a/.gitlab/ci/README.md +++ b/.gitlab/ci/README.md @@ -59,7 +59,7 @@ - `example_test[_esp32/esp32s2/...]` - `fuzzer_test` - `host_test` -- `integration_test[_wifi/ble]` +- `integration_test` - `iperf_stress_test` - `macos` - `macos_test` diff --git a/.gitlab/ci/build.yml b/.gitlab/ci/build.yml index 2b087a69cd9..e6decbb11d7 100644 --- a/.gitlab/ci/build.yml +++ b/.gitlab/ci/build.yml @@ -516,8 +516,10 @@ build_clang_test_apps_esp32c6: script: - ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh - cd ${IDF_PATH}/tools/test_build_system + - retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases - pytest --parallel-count ${CI_NODE_TOTAL:-1} --parallel-index ${CI_NODE_INDEX:-1} --work-dir ${CI_PROJECT_DIR}/test_build_system --junitxml=${CI_PROJECT_DIR}/XUNIT_RESULT.xml + --ignore-result-files known_failure_cases/known_failure_cases.txt pytest_build_system: extends: .test_build_system_template diff --git a/.gitlab/ci/common.yml b/.gitlab/ci/common.yml index 61e71d493b7..3956df42edb 100644 --- a/.gitlab/ci/common.yml +++ b/.gitlab/ci/common.yml @@ -6,9 +6,9 @@ stages: - pre_check - build - assign_test - - build_doc - target_test - host_test + - build_doc - test_deploy - deploy - post_deploy @@ -45,10 +45,10 @@ variables: PYTHON_VER: 3.8.17 # Docker images - ESP_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-env-v5.2:2" - ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env-v5.2:2-1" - QEMU_IMAGE: "${CI_DOCKER_REGISTRY}/qemu-v5.2:2-20230522" - TARGET_TEST_ENV_IMAGE: "$CI_DOCKER_REGISTRY/target-test-env-v5.2:2" + ESP_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-env-v5.3:1" + ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env-v5.3:1-1" + QEMU_IMAGE: "${CI_DOCKER_REGISTRY}/qemu-v5.3:1-20230522" + TARGET_TEST_ENV_IMAGE: "$CI_DOCKER_REGISTRY/target-test-env-v5.3:1" SONARQUBE_SCANNER_IMAGE: "${CI_DOCKER_REGISTRY}/sonarqube-scanner:5" @@ -66,7 +66,7 @@ variables: CI_PYTHON_CONSTRAINT_BRANCH: "" # Update the filename for a specific ESP-IDF release. It is used only with CI_PYTHON_CONSTRAINT_BRANCH. - CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v5.2.txt" + CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v5.3.txt" # Set this variable to repository name of a Python tool you wish to install and test in the context of ESP-IDF CI. # Keep the variable empty when not used. @@ -92,6 +92,7 @@ variables: if echo "$CI_MERGE_REQUEST_LABELS" | egrep "(^|,)include_nightly_run(,|$)"; then export INCLUDE_NIGHTLY_RUN="1" + export NIGHTLY_RUN="1" fi # configure cmake related flags diff --git a/.gitlab/ci/dependencies/dependencies.yml b/.gitlab/ci/dependencies/dependencies.yml index 87d3f539020..5905f5be9fb 100644 --- a/.gitlab/ci/dependencies/dependencies.yml +++ b/.gitlab/ci/dependencies/dependencies.yml @@ -83,16 +83,6 @@ - "build:{0}" - build:target_test -build:integration_test: - labels: - - build - patterns: - - build_components - - build_system - included_in: - - build:target_test - - #################### # Target Test Jobs # #################### @@ -173,23 +163,6 @@ build:integration_test: - "build:example_test" - build:target_test -"test:integration_test_{0}": - matrix: - - - wifi - - ble - labels: - - integration_test_{0} - - integration_test - - target_test - patterns: - - integration_test-{0} - - target_test-{0} - # - maybe others - included_in: - - test:integration_test - - build:integration_test - - build:target_test - "test:host_test": labels: - host_test diff --git a/.gitlab/ci/docs.yml b/.gitlab/ci/docs.yml index 72409404f2f..95141ffdb94 100644 --- a/.gitlab/ci/docs.yml +++ b/.gitlab/ci/docs.yml @@ -37,16 +37,25 @@ .if-dev-push: &if-dev-push if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && $CI_COMMIT_TAG !~ /^qa-test/ && ($CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event")' +.if-schedule: &if-schedule + if: '$CI_PIPELINE_SOURCE == "schedule"' + .doc-rules:build:docs-full: rules: - <<: *if-qa-test-tag when: never - - <<: *if-protected + - <<: *if-schedule - <<: *if-label-build_docs - <<: *if-label-docs_full - <<: *if-dev-push changes: *patterns-docs-full +.doc-rules:build:docs-full-prod: + rules: + - <<: *if-qa-test-tag + when: never + - <<: *if-protected-no_label + .doc-rules:build:docs-partial: rules: - <<: *if-qa-test-tag @@ -83,10 +92,6 @@ check_docs_lang_sync: stage: build_doc tags: - build_docs - needs: - - job: fast_template_app - artifacts: false - optional: true script: - cd docs - build-docs -t $DOCTGT -bs $DOC_BUILDERS -l $DOCLANG build @@ -110,6 +115,24 @@ build_docs_html_full: extends: - .build_docs_template - .doc-rules:build:docs-full + needs: + - job: fast_template_app + artifacts: false + optional: true + artifacts: + when: always + paths: + - docs/_build/*/*/*.txt + - docs/_build/*/*/html/* + expire_in: 4 days + variables: + DOC_BUILDERS: "html" + +build_docs_html_full_prod: + extends: + - .build_docs_template + - .doc-rules:build:docs-full-prod + dependencies: [] # Stop build_docs jobs from downloading all previous job's artifacts artifacts: when: always paths: @@ -123,6 +146,10 @@ build_docs_html_partial: extends: - .build_docs_template - .doc-rules:build:docs-partial + needs: + - job: fast_template_app + artifacts: false + optional: true artifacts: when: always paths: @@ -142,6 +169,23 @@ build_docs_pdf: extends: - .build_docs_template - .doc-rules:build:docs-full + needs: + - job: fast_template_app + artifacts: false + optional: true + artifacts: + when: always + paths: + - docs/_build/*/*/latex/* + expire_in: 4 days + variables: + DOC_BUILDERS: "latex" + +build_docs_pdf_prod: + extends: + - .build_docs_template + - .doc-rules:build:docs-full-prod + dependencies: [] # Stop build_docs jobs from downloading all previous job's artifacts artifacts: when: always paths: @@ -194,13 +238,12 @@ deploy_docs_production: # The DOCS_PROD_* variables used by this job are "Protected" so these branches must all be marked "Protected" in Gitlab settings extends: - .deploy_docs_template - rules: - - <<: *if-protected-no_label + - .doc-rules:build:docs-full-prod stage: post_deploy dependencies: # set dependencies to null to avoid missing artifacts issue needs: # ensure runs after push_to_github succeeded - - build_docs_html_full - - build_docs_pdf + - build_docs_html_full_prod + - build_docs_pdf_prod - job: push_to_github artifacts: false variables: @@ -215,8 +258,7 @@ deploy_docs_production: check_doc_links: extends: - .build_docs_template - rules: - - <<: *if-protected-no_label + - .doc-rules:build:docs-full-prod stage: post_deploy needs: - job: deploy_docs_production diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 9f39debe8b4..9202f59ddc0 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -112,22 +112,6 @@ .patterns-component_ut-wifi: &patterns-component_ut-wifi - "components/esp_wifi/**/*" -.patterns-integration_test-ble: &patterns-integration_test-ble - - "tools/ci/python_packages/gitlab_api.py" - - "tools/ci/integration_test/**/*" - - "components/bt/controller/lib_esp32" - - "components/bt/controller/lib_esp32c3_family" - - "components/bt/controller/lib_esp32h2/esp32h2-bt-lib" - - "components/bt/host/nimble/nimble" - - "components/esp_phy/lib" - - "components/esp_coex/??[!s][!t]*/**/*" - - "components/esp_coex/???/**/*" - - "components/esp_coex/*" - -.patterns-integration_test-wifi: &patterns-integration_test-wifi - - "tools/ci/python_packages/gitlab_api.py" - - "tools/ci/integration_test/**/*" - .patterns-build_macos: &patterns-build_macos - "tools/ci/test_configure_ci_environment.sh" @@ -571,15 +555,6 @@ .if-label-host_test: &if-label-host_test if: '$BOT_LABEL_HOST_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*host_test(?:,[^,\n\r]+)*$/i' -.if-label-integration_test: &if-label-integration_test - if: '$BOT_LABEL_INTEGRATION_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*integration_test(?:,[^,\n\r]+)*$/i' - -.if-label-integration_test_ble: &if-label-integration_test_ble - if: '$BOT_LABEL_INTEGRATION_TEST_BLE || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*integration_test_ble(?:,[^,\n\r]+)*$/i' - -.if-label-integration_test_wifi: &if-label-integration_test_wifi - if: '$BOT_LABEL_INTEGRATION_TEST_WIFI || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*integration_test_wifi(?:,[^,\n\r]+)*$/i' - .if-label-macos: &if-label-macos if: '$BOT_LABEL_MACOS || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*macos(?:,[^,\n\r]+)*$/i' @@ -1584,9 +1559,6 @@ - <<: *if-label-example_test_esp32p4 - <<: *if-label-example_test_esp32s2 - <<: *if-label-example_test_esp32s3 - - <<: *if-label-integration_test - - <<: *if-label-integration_test_ble - - <<: *if-label-integration_test_wifi - <<: *if-label-target_test - <<: *if-dev-push changes: *patterns-build-example_test @@ -1634,10 +1606,6 @@ changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - - <<: *if-dev-push - changes: *patterns-integration_test-ble - - <<: *if-dev-push - changes: *patterns-integration_test-wifi - <<: *if-dev-push changes: *patterns-target_test-adc - <<: *if-dev-push diff --git a/.gitlab/ci/static-code-analysis.yml b/.gitlab/ci/static-code-analysis.yml index 7ad423e62c0..0ceb6d7ca46 100644 --- a/.gitlab/ci/static-code-analysis.yml +++ b/.gitlab/ci/static-code-analysis.yml @@ -30,7 +30,7 @@ check_pylint: if [ -n "$CI_MERGE_REQUEST_IID" ]; then export files=$(python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py files ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} | grep ".py$"); else - export files=$(find . -iname "*.py" -print); + export files=$(git ls-files "*.py" | xargs); fi - if [ -z "$files" ]; then echo "No python files found"; exit 0; fi - run_cmd pylint --exit-zero --load-plugins=pylint_gitlab --output-format=gitlab-codeclimate:pylint.json $files diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 803efd9dae0..b2fec6d5400 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -50,6 +50,7 @@ --parallel-index ${CI_NODE_INDEX:-1} ${PYTEST_EXTRA_FLAGS} --app-info-filepattern \"list_job_*.txt\" + - python tools/ci/artifacts_handler.py upload --type logs junit_reports .pytest_examples_dir_template: extends: .pytest_template @@ -1298,6 +1299,7 @@ pytest_examples_openthread_br: --parallel-index ${CI_NODE_INDEX:-1} ${PYTEST_EXTRA_FLAGS} --app-info-filepattern \"list_job_*.txt\" + - python tools/ci/artifacts_handler.py upload --type logs junit_reports pytest_examples_openthread_bbr: extends: @@ -1332,6 +1334,7 @@ pytest_examples_openthread_bbr: --parallel-index ${CI_NODE_INDEX:-1} ${PYTEST_EXTRA_FLAGS} --app-info-filepattern \"list_job_*.txt\" + - python tools/ci/artifacts_handler.py upload --type logs junit_reports pytest_examples_openthread_sleep: extends: @@ -1363,6 +1366,7 @@ pytest_examples_openthread_sleep: --parallel-index ${CI_NODE_INDEX:-1} ${PYTEST_EXTRA_FLAGS} --app-info-filepattern \"list_job_*.txt\" + - python tools/ci/artifacts_handler.py upload --type logs junit_reports pytest_examples_esp32h2_zigbee: extends: diff --git a/components/app_trace/CMakeLists.txt b/components/app_trace/CMakeLists.txt index 5e360703596..ff17766baea 100644 --- a/components/app_trace/CMakeLists.txt +++ b/components/app_trace/CMakeLists.txt @@ -63,8 +63,8 @@ endif() idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}" - # Requires "driver" for GPTimer in "SEGGER_SYSVIEW_Config_FreeRTOS.c" - PRIV_REQUIRES soc driver + PRIV_REQUIRES soc esp_driver_gptimer esp_driver_gpio + driver # TODO: replace with esp_driver_uart (IDF-8384) REQUIRES esp_timer LDFRAGMENTS linker.lf) diff --git a/components/app_trace/linker.lf b/components/app_trace/linker.lf index e9c57c84570..5054ea44194 100644 --- a/components/app_trace/linker.lf +++ b/components/app_trace/linker.lf @@ -15,7 +15,7 @@ entries: SEGGER_SYSVIEW_FreeRTOS (noflash) [mapping:app_trace_driver] -archive: libdriver.a +archive: libesp_driver_gptimer.a entries: if APPTRACE_SV_TS_SOURCE_GPTIMER = y: gptimer (noflash) diff --git a/components/app_trace/test_apps/main/CMakeLists.txt b/components/app_trace/test_apps/main/CMakeLists.txt index 7661fbba768..45781494003 100644 --- a/components/app_trace/test_apps/main/CMakeLists.txt +++ b/components/app_trace/test_apps/main/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "test_app_trace_main.c" "test_trace.c" INCLUDE_DIRS "." - PRIV_REQUIRES app_trace unity driver + PRIV_REQUIRES app_trace unity esp_driver_gptimer WHOLE_ARCHIVE) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 810bc7fb136..ccccee451b7 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -139,7 +139,7 @@ menu "Bootloader config" config BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH bool - default y if ESPTOOLPY_OCT_FLASH && SPI_FLASH_32BIT_ADDRESS + default y if ESPTOOLPY_OCT_FLASH && BOOTLOADER_FLASH_32BIT_ADDR default n endmenu diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_config.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_config.h index 6fbb6d4fc8e..2709a3da30e 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_config.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_config.h @@ -58,6 +58,7 @@ void bootloader_flash_clock_config(const esp_image_header_t* pfhdr); */ void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr); +#ifdef CONFIG_IDF_TARGET_ESP32 /** * @brief Configure SPI flash read dummy based on different mode and frequency. * @@ -66,6 +67,10 @@ void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr); * @return None */ void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr); +#else +// The meaning has changed on this chip. Deprecated, Call `bootloader_configure_spi_pins()` and `bootloader_flash_set_dummy_out()` directly. +void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr) __attribute__((deprecated)); +#endif #ifdef CONFIG_IDF_TARGET_ESP32 /** diff --git a/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h b/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h index 4bff3f9dea3..92c9d3988dc 100644 --- a/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h +++ b/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h @@ -18,6 +18,15 @@ extern "C" { */ esp_err_t bootloader_init_spi_flash(void); +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +/** + * @brief Config all flash related stuff according to the header. The consistency of all flash configs is ensured. + * + * @return None + */ +void bootloader_flash_hardware_init(void); +#endif + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c index 99f6421c853..3c23ec5abcb 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,7 @@ #include "soc/gpio_periph.h" #include "soc/efuse_reg.h" #include "soc/spi_reg.h" +#include "soc/dport_reg.h" #include "soc/soc_caps.h" #include "soc/soc_pins.h" #include "soc/chip_revision.h" @@ -269,13 +270,10 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - Cache_Read_Disable(0); // Set flash chip size esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode // TODO: set frequency - Cache_Flush(0); - Cache_Read_Enable(0); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -354,6 +352,7 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr) ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); } + static void IRAM_ATTR bootloader_init_flash_configure(void) { bootloader_flash_gpio_config(&bootloader_image_hdr); @@ -379,8 +378,102 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + Cache_Read_Disable(0); update_flash_config(&bootloader_image_hdr); + Cache_Flush(0); + Cache_Read_Enable(0); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; } + + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); + + // reset MMU + /* completely reset MMU in case serial bootloader was running */ + Cache_Read_Disable(0); +#if !CONFIG_FREERTOS_UNICORE + Cache_Read_Disable(1); +#endif + Cache_Flush(0); +#if !CONFIG_FREERTOS_UNICORE + Cache_Flush(1); +#endif + mmu_init(0); +#if !CONFIG_FREERTOS_UNICORE + /* The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are + necessary to work around a hardware bug. */ + DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR); + mmu_init(1); + DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR); +#endif + + /* normal ROM boot exits with DROM0 cache unmasked, + but serial bootloader exits with it masked. */ + DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0); +#if !CONFIG_FREERTOS_UNICORE + DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0); +#endif + + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_gpio_config(&hdr); + bootloader_flash_dummy_config(&hdr); + bootloader_flash_cs_timing_config(); + + /* Remaining parts in bootloader_init_spi_flash */ + bootloader_flash_unlock(); + + Cache_Read_Disable(0); + update_flash_config(&hdr); + Cache_Flush(0); + Cache_Read_Enable(0); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c index 85f7c16654a..cf5a56809f4 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c @@ -71,6 +71,7 @@ void IRAM_ATTR bootloader_flash_set_dummy_out(void) REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); } +//deprecated void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) { bootloader_configure_spi_pins(1); @@ -127,10 +128,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -220,7 +219,8 @@ static void bootloader_print_mmu_page_size(void) static void IRAM_ATTR bootloader_init_flash_configure(void) { - bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_configure_spi_pins(1); + bootloader_flash_set_dummy_out(); bootloader_flash_cs_timing_config(); } @@ -243,8 +243,76 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_print_mmu_page_size(); print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(0, false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_set_dummy_out(); + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + bootloader_print_mmu_page_size(); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c index fb1f2329d1a..7b0eecefc48 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c @@ -75,6 +75,7 @@ void IRAM_ATTR bootloader_flash_set_dummy_out(void) REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); } +//deprecated void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) { bootloader_configure_spi_pins(1); @@ -138,10 +139,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -222,7 +221,8 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr) static void IRAM_ATTR bootloader_init_flash_configure(void) { - bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_configure_spi_pins(1); + bootloader_flash_set_dummy_out(); bootloader_flash_cs_timing_config(); } @@ -251,8 +251,78 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_set_dummy_out(); + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c index 6a1e62459c7..2e9ed60a12f 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c @@ -103,10 +103,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -214,8 +212,78 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(0, false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + // TODO: set proper dummy output + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c index b4b1bb94c3b..e9888da6f91 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c @@ -110,10 +110,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -216,8 +214,79 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(0, false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_clock_init(); + // TODO: set proper dummy output + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP 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 14887abe949..89894d5edd0 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 @@ -97,10 +97,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -202,8 +200,77 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(0, false); + + //init cache hal + cache_hal_init(); + //reset mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c index a1855bb4c4a..40587e4960f 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c @@ -81,6 +81,7 @@ void IRAM_ATTR bootloader_flash_set_dummy_out(void) REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); } +//deprecated void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t* pfhdr) { bootloader_configure_spi_pins(1); @@ -152,12 +153,10 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode // TODO: set frequency - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -247,7 +246,8 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr) static void IRAM_ATTR bootloader_init_flash_configure(void) { - bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_configure_spi_pins(1); + bootloader_flash_set_dummy_out(); bootloader_flash_cs_timing_config(); } @@ -269,8 +269,78 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); + + // init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // Workaround: normal ROM bootloader exits with DROM0 cache unmasked, but 2nd bootloader exits with it masked. + REG_CLR_BIT(EXTMEM_PRO_ICACHE_CTRL1_REG, EXTMEM_PRO_ICACHE_MASK_DROM0); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_set_dummy_out(); + bootloader_flash_cs_timing_config(); + + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c index 7ab25e7fc85..c02aad5bbf7 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c @@ -87,6 +87,7 @@ void IRAM_ATTR bootloader_flash_set_dummy_out(void) REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); } +//deprecated void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) { bootloader_configure_spi_pins(1); @@ -159,12 +160,10 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode // TODO: set frequency - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -254,7 +253,8 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr) static void IRAM_ATTR bootloader_init_flash_configure(void) { - bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_configure_spi_pins(1); + bootloader_flash_set_dummy_out(); bootloader_flash_cs_timing_config(); } @@ -292,8 +292,87 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_set_dummy_out(); + bootloader_flash_cs_timing_config(); + +#if CONFIG_BOOTLOADER_FLASH_DC_AWARE + // Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot. + bootloader_spi_flash_reset(); +#endif + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH || CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH + bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); +#endif + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); + +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index 7df9824d678..086394a876b 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,9 @@ #include "esp32s2/rom/usb/cdc_acm.h" #include "esp32s2/rom/usb/usb_common.h" #endif +#if SOC_USB_SERIAL_JTAG_SUPPORTED +#include "hal/usb_phy_ll.h" +#endif #include "esp_rom_gpio.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" @@ -98,6 +101,9 @@ void bootloader_console_init(void) esp_rom_uart_usb_acm_init(s_usb_cdc_buf, sizeof(s_usb_cdc_buf)); esp_rom_uart_set_as_console(ESP_ROM_USB_OTG_NUM); esp_rom_install_channel_putc(1, bootloader_console_write_char_usb); +#if SOC_USB_SERIAL_JTAG_SUPPORTED + usb_phy_ll_int_otg_enable(&USB_WRAP); +#endif } #endif //CONFIG_ESP_CONSOLE_USB_CDC diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 1dd9b3958de..a68e57543bd 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -23,7 +23,9 @@ static const char *TAG = "boot"; +#if !CONFIG_APP_BUILD_TYPE_RAM esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr; +#endif void bootloader_clear_bss_section(void) { diff --git a/components/bootloader_support/src/esp32/bootloader_esp32.c b/components/bootloader_support/src/esp32/bootloader_esp32.c index ddea3ee159d..fd6441023b7 100644 --- a/components/bootloader_support/src/esp32/bootloader_esp32.c +++ b/components/bootloader_support/src/esp32/bootloader_esp32.c @@ -39,7 +39,7 @@ static const char *TAG = "boot.esp32"; -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM static void bootloader_reset_mmu(void) { /* completely reset MMU in case serial bootloader was running */ @@ -208,7 +208,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM // reset MMU bootloader_reset_mmu(); // update flash ID @@ -218,7 +218,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -227,12 +226,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // #if !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c b/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c index a19fa85443c..3d9e1af1f4e 100644 --- a/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c +++ b/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c @@ -120,14 +120,13 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu mmu_hal_init(); // update flash ID bootloader_flash_update_id(); -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -136,12 +135,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c b/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c index 0160b921f1e..199ff656241 100644 --- a/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c +++ b/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c @@ -159,7 +159,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu @@ -171,7 +171,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -180,12 +179,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif //#if !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif //#if !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c index 76fd0b90b30..d2696579926 100644 --- a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c +++ b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c @@ -143,7 +143,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu @@ -155,7 +155,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -164,12 +163,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c index e5b23acfe3b..5cf7869c17f 100644 --- a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c +++ b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c @@ -132,7 +132,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu @@ -144,7 +144,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -153,12 +152,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c b/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c index 085ab34559f..aa515759ec9 100644 --- a/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c +++ b/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c @@ -136,7 +136,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //reset mmu @@ -148,7 +148,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -157,12 +156,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c b/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c index cf2a27fe657..4624e29f27c 100644 --- a/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c +++ b/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c @@ -139,7 +139,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM // init cache hal cache_hal_init(); //init mmu @@ -153,7 +153,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -162,12 +161,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c b/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c index 06b4825a3a7..368aa648b4d 100644 --- a/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c +++ b/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c @@ -178,7 +178,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu @@ -190,7 +190,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -199,12 +198,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 67ca86cd157..08f5e167b9f 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -70,30 +70,35 @@ if(CONFIG_BT_ENABLED) set(srcs "") set(include_dirs "") set(ldfragments "linker.lf") + if(CONFIG_BT_CONTROLLER_ENABLED) + if(CONFIG_IDF_TARGET_ESP32) + list(APPEND srcs "controller/esp32/bt.c" + "controller/esp32/hli_api.c" + "controller/esp32/hli_vectors.S") - if(CONFIG_IDF_TARGET_ESP32) - list(APPEND srcs "controller/esp32/bt.c" - "controller/esp32/hli_api.c" - "controller/esp32/hli_vectors.S") + elseif(CONFIG_IDF_TARGET_ESP32C3) + list(APPEND srcs "controller/esp32c3/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32C3) - list(APPEND srcs "controller/esp32c3/bt.c") + elseif(CONFIG_IDF_TARGET_ESP32S3) + list(APPEND srcs "controller/esp32c3/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32S3) - list(APPEND srcs "controller/esp32c3/bt.c") + elseif(CONFIG_IDF_TARGET_ESP32C2) + list(APPEND srcs "controller/esp32c2/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32C2) - set(ldfragments "linker.lf.esp32c2") - list(APPEND srcs "controller/esp32c2/bt.c") + elseif(CONFIG_IDF_TARGET_ESP32C2) + set(ldfragments "linker.lf.esp32c2") + list(APPEND srcs "controller/esp32c2/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32C6) - list(APPEND srcs "controller/esp32c6/bt.c") + elseif(CONFIG_IDF_TARGET_ESP32C6) + list(APPEND srcs "controller/esp32c6/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32H2) - list(APPEND srcs "controller/esp32h2/bt.c") - endif() + elseif(CONFIG_IDF_TARGET_ESP32H2) + list(APPEND srcs "controller/esp32h2/bt.c") + endif() - list(APPEND include_dirs ${target_specific_include_dirs}) + list(APPEND include_dirs ${target_specific_include_dirs}) + + endif() # Common list(APPEND include_dirs common/osi/include) @@ -174,6 +179,7 @@ if(CONFIG_BT_ENABLED) list(APPEND srcs "host/bluedroid/api/esp_a2dp_api.c" "host/bluedroid/api/esp_avrc_api.c" + "host/bluedroid/api/esp_bluedroid_hci.c" "host/bluedroid/api/esp_bt_device.c" "host/bluedroid/api/esp_bt_main.c" "host/bluedroid/api/esp_gap_ble_api.c" @@ -608,6 +614,7 @@ if(CONFIG_BT_ENABLED) host/nimble/nimble/nimble/host/services/ipss/include host/nimble/nimble/nimble/host/services/lls/include host/nimble/nimble/nimble/host/services/prox/include + host/nimble/nimble/nimble/host/services/cts/include host/nimble/nimble/nimble/host/services/tps/include host/nimble/nimble/nimble/host/util/include host/nimble/nimble/nimble/host/store/ram/include @@ -628,6 +635,7 @@ if(CONFIG_BT_ENABLED) "host/nimble/nimble/nimble/host/services/dis/src/ble_svc_dis.c" "host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c" "host/nimble/nimble/nimble/host/services/prox/src/ble_svc_prox.c" + "host/nimble/nimble/nimble/host/services/cts/src/ble_svc_cts.c" "host/nimble/nimble/nimble/host/src/ble_hs_conn.c" "host/nimble/nimble/nimble/host/src/ble_store_util.c" "host/nimble/nimble/nimble/host/src/ble_sm.c" diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 152ce7b3866..1781dc6f99f 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -1,9 +1,8 @@ menu "Bluetooth" - visible if SOC_BT_SUPPORTED config BT_ENABLED bool "Bluetooth" - depends on SOC_BT_SUPPORTED && !APP_NO_BLOBS + depends on !APP_NO_BLOBS help Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices. @@ -22,10 +21,12 @@ menu "Bluetooth" config BT_NIMBLE_ENABLED bool "NimBLE - BLE only" + depends on BT_CONTROLLER_ENABLED help This option is recommended for BLE only usecases to save on memory config BT_CONTROLLER_ONLY + depends on SOC_BT_SUPPORTED bool "Disabled" help This option is recommended when you want to communicate directly with the @@ -42,6 +43,7 @@ menu "Bluetooth" This helps to choose Bluetooth controller stack config BT_CONTROLLER_ENABLED + depends on SOC_BT_SUPPORTED bool "Enabled" help This option is recommended for Bluetooth controller usecases diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index 9f6df2bdd4b..738f4f2cd93 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,6 +29,12 @@ #define UC_BT_STACK_NO_LOG FALSE #endif +#ifdef CONFIG_BT_CONTROLLER_ENABLED +#define UC_BT_CONTROLLER_INCLUDED TRUE +#else +#define UC_BT_CONTROLLER_INCLUDED FALSE +#endif + /********************************************************** * Thread/Task reference **********************************************************/ diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 9a37c1c7c1c..0e1622ab806 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -1003,7 +1003,7 @@ uint8_t esp_ble_get_chip_rev_version(void) 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]); + esp_rom_printf("%02x ", addr[i]); } if (end) { esp_rom_printf("\n"); diff --git a/components/bt/controller/esp32c6/Kconfig.in b/components/bt/controller/esp32c6/Kconfig.in index 1f56aab918b..41619efd334 100644 --- a/components/bt/controller/esp32c6/Kconfig.in +++ b/components/bt/controller/esp32c6/Kconfig.in @@ -212,6 +212,15 @@ menu "Memory Settings" help Dynamic memory size of block 2 + config BT_LE_MSYS_BUF_FROM_HEAP + bool "Get Msys Mbuf from heap" + default y + depends on BT_LE_MSYS_INIT_IN_CONTROLLER + help + This option sets the source of the shared msys mbuf memory between + the Host and the Controller. Allocate the memory from the heap if + this option is sets, from the mempool otherwise. + config BT_LE_ACL_BUF_COUNT int "ACL Buffer count" default 10 @@ -539,5 +548,5 @@ config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD again. config BT_LE_MSYS_INIT_IN_CONTROLLER - bool + bool "Msys Mbuf Init in Controller" default y diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index 4691ba4a6de..0643b525fec 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -1173,7 +1173,7 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po 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]); + esp_rom_printf("%02x ", addr[i]); } if (end) { esp_rom_printf("\n"); diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 068387749f2..b3361bbb694 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -1147,7 +1147,7 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po 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]); + esp_rom_printf("%02x ", addr[i]); } if (end) { esp_rom_printf("\n"); diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 943b0f24eb6..cddb921d204 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 943b0f24eb6ed390213599e4a9556c66844ef0db +Subproject commit cddb921d20418cef04de83ddfe3543463dfbc2bc diff --git a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib index 4fb60aa91de..ea33fbad1fa 160000 --- a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib +++ b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib @@ -1 +1 @@ -Subproject commit 4fb60aa91de64b0f1d0eb6292d38b6c22a3aa005 +Subproject commit ea33fbad1fa0879fe0e118359d20463b3e2f126b diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family index 7fb979154be..ec7ef197cb8 160000 --- a/components/bt/controller/lib_esp32c3_family +++ b/components/bt/controller/lib_esp32c3_family @@ -1 +1 @@ -Subproject commit 7fb979154bec81163d55aa4e3134425aea0d52ab +Subproject commit ec7ef197cb8018c468cd59dca893dbe018f47a2a diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index 25d9661bc3d..a763b33ce1f 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit 25d9661bc3d5cc7bade40c03f501b935d3ad7642 +Subproject commit a763b33ce1f6bdc257947845b0520c3b44de87eb diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index 8450d3f5080..c8018101d5a 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit 8450d3f50804bc2d685a6ef5c5a76e1f4f13d579 +Subproject commit c8018101d5a71162c220782e6c860e9ba33013c4 diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 079080bf3af..479d0d68975 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -49,7 +49,7 @@ config BT_BLUEDROID_ESP_COEX_VSC config BT_CLASSIC_ENABLED bool "Classic Bluetooth" - depends on BT_BLUEDROID_ENABLED && IDF_TARGET_ESP32 + depends on BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BT_CLASSIC_SUPPORTED) || BT_CONTROLLER_DISABLED) default n help For now this option needs "SMP_ENABLE" to be set to yes @@ -83,21 +83,23 @@ config BT_L2CAP_ENABLED This enables the Logical Link Control and Adaptation Layer Protocol. Only supported classic bluetooth. -config BT_HFP_ENABLE +menuconfig BT_HFP_ENABLE bool "Hands Free/Handset Profile" depends on BT_CLASSIC_ENABLED default n + help + Hands Free Unit and Audio Gateway can be included simultaneously + but they cannot run simultaneously due to internal limitations. -choice BT_HFP_ROLE - prompt "Hands-free Profile Role configuration" +config BT_HFP_CLIENT_ENABLE + bool "Hands Free Unit" depends on BT_HFP_ENABLE + default y - config BT_HFP_CLIENT_ENABLE - bool "Hands Free Unit" - - config BT_HFP_AG_ENABLE - bool "Audio Gateway" -endchoice +config BT_HFP_AG_ENABLE + bool "Audio Gateway" + depends on BT_HFP_ENABLE + default y choice BT_HFP_AUDIO_DATA_PATH prompt "audio(SCO) data path" @@ -121,26 +123,26 @@ config BT_HFP_WBS_ENABLE This enables Wide Band Speech. Should disable it when SCO data path is PCM. Otherwise there will be no data transmited via GPIOs. -config BT_HID_ENABLED + +menuconfig BT_HID_ENABLED bool "Classic BT HID" depends on BT_CLASSIC_ENABLED default n help This enables the BT HID Host -choice BT_HID_ROLE - prompt "Profile Role configuration" +config BT_HID_HOST_ENABLED + bool "Classic BT HID Host" depends on BT_HID_ENABLED - config BT_HID_HOST_ENABLED - bool "Classic BT HID Host" - help - This enables the BT HID Host + default n + help + This enables the BT HID Host - config BT_HID_DEVICE_ENABLED - bool "Classic BT HID Device" - help - This enables the BT HID Device -endchoice +config BT_HID_DEVICE_ENABLED + bool "Classic BT HID Device" + depends on BT_HID_ENABLED + help + This enables the BT HID Device config BT_BLE_ENABLED bool "Bluetooth Low Energy" @@ -250,6 +252,14 @@ config BT_GATTC_MAX_CACHE_CHAR help Maximum GATTC cache characteristic count +config BT_GATTC_NOTIF_REG_MAX + int "Max gattc notify(indication) register number" + depends on BT_GATTC_ENABLE + range 1 64 + default 5 + help + Maximum GATTC notify(indication) register number + config BT_GATTC_CACHE_NVS_FLASH bool "Save gattc cache data to nvs flash" depends on BT_GATTC_ENABLE @@ -1106,8 +1116,9 @@ config BT_MAX_DEVICE_NAME_LEN config BT_BLE_RPA_SUPPORTED bool "Update RPA to Controller" - depends on BT_BLUEDROID_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED - default n + depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) || BT_CONTROLLER_DISABLED)) + default n if (BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) + default y if BT_CONTROLLER_DISABLED help This enables controller RPA list function. For ESP32, ESP32 only support network privacy mode. If this option is enabled, ESP32 will only accept @@ -1131,28 +1142,28 @@ config BT_BLE_RPA_TIMEOUT config BT_BLE_50_FEATURES_SUPPORTED bool "Enable BLE 5.0 features" - depends on (BT_BLUEDROID_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER)) + depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_50_SUPPORTED) || BT_CONTROLLER_DISABLED)) default y help This enables BLE 5.0 features, this option only support esp32c3/esp32s3 chip config BT_BLE_42_FEATURES_SUPPORTED bool "Enable BLE 4.2 features" - depends on (BT_BLUEDROID_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER)) + depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_SUPPORTED) || BT_CONTROLLER_DISABLED)) default n help This enables BLE 4.2 features. config BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER bool "Enable BLE periodic advertising sync transfer feature" - depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER) + depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_ESP_NIMBLE_CONTROLLER) || BT_CONTROLLER_DISABLED)) default n help This enables BLE periodic advertising sync transfer feature config BT_BLE_FEAT_PERIODIC_ADV_ENH bool "Enable periodic adv enhancements(adi support)" - depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER) + depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_ESP_NIMBLE_CONTROLLER) || BT_CONTROLLER_DISABLED)) default n help Enable the periodic advertising enhancements diff --git a/components/bt/host/bluedroid/api/esp_bluedroid_hci.c b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c new file mode 100644 index 00000000000..892f6790d60 --- /dev/null +++ b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_log.h" +#include "esp_bluedroid_hci.h" +#include "common/bt_target.h" +#include "hci/hci_trans_int.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) +#include "esp_bt.h" +#endif + +#define LOG_TAG "HCI_API" + +static esp_bluedroid_hci_driver_operations_t s_hci_driver_ops = { 0 }; + +esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *p_ops) +{ + if (!p_ops) { + ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__); + return ESP_FAIL; + } + + s_hci_driver_ops.send = p_ops->send; + s_hci_driver_ops.check_send_available = p_ops->check_send_available; + s_hci_driver_ops.register_host_callback = p_ops->register_host_callback; + + return ESP_OK; +} + +esp_err_t esp_bluedroid_detach_hci_driver(void) +{ + s_hci_driver_ops.send = NULL; + s_hci_driver_ops.check_send_available = NULL; + s_hci_driver_ops.register_host_callback = NULL; + + return ESP_OK; +} + +/**************************************************************** + * INTERNAL USE * + ****************************************************************/ + +bool hci_host_check_send_available(void) +{ + bool can_send = false; +#if (BT_CONTROLLER_INCLUDED == TRUE) + can_send = esp_vhci_host_check_send_available(); +#else /* BT_CONTROLLER_INCLUDED == TRUE */ + if (s_hci_driver_ops.check_send_available) { + can_send = s_hci_driver_ops.check_send_available(); + } +#endif /* BT_CONTROLLER_INCLUDED == TRUE */ + return can_send; +} + +void hci_host_send_packet(uint8_t *data, uint16_t len) +{ +#if (BT_CONTROLLER_INCLUDED == TRUE) + esp_vhci_host_send_packet(data, len); +#else /* BT_CONTROLLER_INCLUDED == TRUE */ + if (s_hci_driver_ops.send) { + s_hci_driver_ops.send(data, len); + } +#endif /* BT_CONTROLLER_INCLUDED == TRUE */ +} + +esp_err_t hci_host_register_callback(const esp_bluedroid_hci_driver_callbacks_t *callback) +{ + esp_err_t ret = ESP_FAIL; + + if (!callback) { + ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__); + return ESP_FAIL; + } + +#if (BT_CONTROLLER_INCLUDED == TRUE) + ret = esp_vhci_host_register_callback((esp_vhci_host_callback_t *)callback); +#else /* BT_CONTROLLER_INCLUDED == TRUE */ + if (s_hci_driver_ops.register_host_callback) { + ret = s_hci_driver_ops.register_host_callback(callback); + } +#endif /* BT_CONTROLLER_INCLUDED == TRUE */ + + return ret; +} diff --git a/components/bt/host/bluedroid/api/esp_bt_main.c b/components/bt/host/bluedroid/api/esp_bt_main.c index d4b93fbb33c..497ba769b65 100644 --- a/components/bt/host/bluedroid/api/esp_bt_main.c +++ b/components/bt/host/bluedroid/api/esp_bt_main.c @@ -5,10 +5,13 @@ */ +#include "common/bt_target.h" #include "esp_bt_main.h" #include "btc/btc_task.h" #include "btc/btc_main.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include "osi/future.h" #include "osi/allocator.h" #include "config/stack_config.h" @@ -123,10 +126,12 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg) return ESP_ERR_INVALID_ARG; } +#if (BT_CONTROLLER_INCLUDED == TRUE) if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { LOG_ERROR("Controller not initialised\n"); return ESP_ERR_INVALID_STATE; } +#endif if (bd_already_init) { LOG_ERROR("Bluedroid already initialised\n"); 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 65d24518c20..9a99c9c5f83 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -122,6 +122,19 @@ esp_err_t esp_ble_gap_stop_advertising(void) return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } + +esp_err_t esp_ble_gap_clear_advertising(void) +{ + btc_msg_t msg; + + 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_ACT_CLEAR_ADV; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params) diff --git a/components/bt/host/bluedroid/api/esp_hf_ag_api.c b/components/bt/host/bluedroid/api/esp_hf_ag_api.c index 42878a4c7ab..3098cd47161 100644 --- a/components/bt/host/bluedroid/api/esp_hf_ag_api.c +++ b/components/bt/host/bluedroid/api/esp_hf_ag_api.c @@ -21,7 +21,9 @@ #include "common/bt_target.h" #include "common/bt_defs.h" #include "device/bdaddr.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include "esp_hf_ag_api.h" #include "esp_err.h" #include "esp_bt_main.h" diff --git a/components/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h b/components/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h new file mode 100644 index 00000000000..0004072c667 --- /dev/null +++ b/components/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_BLUEDROID_HCI_H__ +#define __ESP_BLUEDROID_HCI_H__ + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* HCI driver callbacks */ +typedef struct esp_bluedroid_hci_driver_callbacks { + /** + * @brief callback used to notify that the host can send packet to controller + */ + void (*notify_host_send_available)(void); + + /** + * @brief callback used to notify that the controller has a packet to send to the host + * + * @param[in] data pointer to data buffer + * @param[in] len length of data + * + * @return 0 received successfully, failed otherwise + */ + int (*notify_host_recv)(uint8_t *data, uint16_t len); +} esp_bluedroid_hci_driver_callbacks_t; + +/* HCI driver operations */ +typedef struct esp_bluedroid_hci_driver_operations { + /** + * @brief send data from host to controller + * + * @param[in] data pointer to data buffer + * @param[in] len length of data + */ + void (*send)(uint8_t *data, uint16_t len); + + /** + * @brief host checks whether it can send data to controller + * + * @return true if host can send data, false otherwise + */ + bool (*check_send_available)(void); + + /** + * @brief register host callback + * + * @param[in] callback HCI driver callbacks + */ + esp_err_t (* register_host_callback)(const esp_bluedroid_hci_driver_callbacks_t *callback); +} esp_bluedroid_hci_driver_operations_t; + +/** + * @brief get the operations of HCI transport layer. This API should only be used in + * Bluedroid Host-only mode before Bluedroid initialization. + * + * @param[in] ops struct containing operations of HCI transport layer + * + * @return ESP_OK if get successfully, ESP_FAIL otherwise + */ +esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *ops); + +/** + * @brief remove the operations of HCI transport layer. This API should only be used in + * Bluedroid Host-only mode before Bluedroid initialization. + * + * @param[in] ops struct containing operations of HCI transport layer + * + * @return ESP_OK if get successfully, ESP_FAIL otherwise + */ +esp_err_t esp_bluedroid_detach_hci_driver(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_BLUEDROID_HCI_H__ */ 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 4ee8154affd..94680548bb5 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 @@ -54,7 +54,7 @@ typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit #define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE 0 /*!< authentication disable*/ #define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE 1 /*!< authentication enable*/ -#define ESP_BLE_OOB_DISABLE 0 /*!< disbale the out of bond*/ +#define ESP_BLE_OOB_DISABLE 0 /*!< disable the out of bond*/ #define ESP_BLE_OOB_ENABLE 1 /*!< enable the out of bond*/ /// relate to BTM_IO_CAP_xxx in stack/btm_api.h @@ -222,6 +222,8 @@ typedef enum { ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, /*!< when periodic advertising sync transfer received, the event comes */ // DTM ESP_GAP_BLE_DTM_TEST_UPDATE_EVT, /*!< when direct test mode state changes, the event comes */ + // BLE_INCLUDED + ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT, /*!< When clear advertising complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1086,6 +1088,12 @@ typedef union { struct ble_adv_stop_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate adv stop operation success status */ } adv_stop_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT + */ + struct ble_adv_clear_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate adv clear operation success status */ + } adv_clear_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT */ #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) /** * @brief ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT @@ -2499,6 +2507,16 @@ esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params); */ esp_err_t esp_ble_dtm_stop(void); +/** +* @brief This function is used to clear legacy advertising +* +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_clear_advertising(void); + #ifdef __cplusplus } #endif 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 82fa8ff0fe6..0509da0a71b 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -46,6 +46,9 @@ #if (GAP_INCLUDED == TRUE) #include "stack/gap_api.h" #endif +#if (BT_CONTROLLER_INCLUDED == TRUE) +#include "esp_bt.h" +#endif static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir); static void bta_dm_inq_cmpl_cb (void *p_result); @@ -136,7 +139,6 @@ static void bta_dm_observe_discard_cb (uint32_t num_dis); static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle); extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8 *p_uuid128); static void bta_dm_disable_timer_cback(TIMER_LIST_ENT *p_tle); -extern int bredr_txpwr_get(int *min_power_level, int *max_power_level); const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] = { UUID_SERVCLASS_PNP_INFORMATION, /* Reserved */ @@ -4313,7 +4315,14 @@ static void bta_dm_set_eir (char *local_name) if (p_bta_dm_eir_cfg->bta_dm_eir_included_tx_power) { if (free_eir_length >= 3) { int min_power_level, max_power_level; - if (bredr_txpwr_get(&min_power_level, &max_power_level) == 0) { +#if (BT_CONTROLLER_INCLUDED == TRUE) + if (esp_bredr_tx_power_get((esp_power_level_t *)&min_power_level, (esp_power_level_t *)&max_power_level) == ESP_OK) { +#else + { + min_power_level = 0; + max_power_level = 0; + UNUSED(min_power_level); +#endif INT8 btm_tx_power[BTM_TX_POWER_LEVEL_MAX + 1] = BTM_TX_POWER; p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power = btm_tx_power[max_power_level]; UINT8_TO_STREAM(p, 2); /* Length field */ @@ -5702,6 +5711,15 @@ void bta_dm_ble_gap_dtm_stop(tBTA_DM_MSG *p_data) BTM_BleTestEnd(p_data->dtm_stop.p_dtm_cmpl_cback); } +void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data) +{ + if (BTM_BleClearAdv(p_data->ble_clear_adv.p_clear_adv_cback) == FALSE) { + if (p_data->ble_clear_adv.p_clear_adv_cback) { + (*p_data->ble_clear_adv.p_clear_adv_cback)(BTA_FAILURE); + } + } +} + #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 ede373efde8..95301cb4038 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1813,6 +1813,29 @@ extern void BTA_DmBleBroadcast (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p } } +/******************************************************************************* +** +** Function BTA_DmBleClearAdv +** +** Description This function is called to clear Advertising +** +** Parameters p_adv_data_cback : clear adv complete callback. +** +** Returns None +** +*******************************************************************************/ +void BTA_DmBleClearAdv (tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback) +{ + tBTA_DM_API_CLEAR_ADV *p_msg; + + if ((p_msg = (tBTA_DM_API_CLEAR_ADV *) + osi_malloc(sizeof(tBTA_DM_API_CLEAR_ADV))) != NULL) { + p_msg->hdr.event = BTA_DM_API_BLE_CLEAR_ADV_EVT; + p_msg->p_clear_adv_cback = p_clear_adv_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 caf5e6872e2..c6b62f3a6f7 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c @@ -356,7 +356,7 @@ void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, *p_resp_key = bte_appl_cfg.ble_resp_key; } - if (bte_appl_cfg.ble_max_key_size > 7 && bte_appl_cfg.ble_max_key_size <= 16) { + if (bte_appl_cfg.ble_max_key_size >= 7 && bte_appl_cfg.ble_max_key_size <= 16) { *p_max_key_size = bte_appl_cfg.ble_max_key_size; } #endif ///SMP_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 83e8b12ca82..bff90453290 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -224,6 +224,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_dtm_tx_start, /* BTA_DM_API_DTM_TX_START_EVT */ bta_dm_ble_gap_dtm_rx_start, /* BTA_DM_API_DTM_RX_START_EVT */ bta_dm_ble_gap_dtm_stop, /* BTA_DM_API_DTM_STOP_EVT */ + bta_dm_ble_gap_clear_adv, /* BTA_DM_API_BLE_CLEAR_ADV_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 6694c0dfc2b..10823c9c96a 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 @@ -217,6 +217,7 @@ enum { BTA_DM_API_DTM_TX_START_EVT, BTA_DM_API_DTM_RX_START_EVT, BTA_DM_API_DTM_STOP_EVT, + BTA_DM_API_BLE_CLEAR_ADV_EVT, #endif BTA_DM_MAX_EVT }; @@ -896,6 +897,11 @@ typedef struct { tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; } tBTA_DM_API_BLE_DTM_STOP; +typedef struct { + BT_HDR hdr; + tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback; +} tBTA_DM_API_CLEAR_ADV; + #endif /* BLE_INCLUDED */ /* data type for BTA_DM_API_REMOVE_ACL_EVT */ @@ -1293,6 +1299,7 @@ typedef union { tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start; 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; #endif tBTA_DM_API_REMOVE_ACL remove_acl; @@ -1732,6 +1739,7 @@ extern void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_dtm_tx_start(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_dtm_rx_start(tBTA_DM_MSG *p_data); 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); #if (BLE_50_FEATURE_SUPPORT == TRUE) extern void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c index 3e42603aeb4..6e2586d69c0 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c @@ -932,7 +932,7 @@ tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if, } if (i == BTA_GATTC_NOTIF_REG_MAX) { status = BTA_GATT_NO_RESOURCES; - APPL_TRACE_ERROR("Max Notification Reached, registration failed."); + APPL_TRACE_ERROR("Max Notification Reached, registration failed,see CONFIG_BT_GATTC_NOTIF_REG_MAX in menuconfig"); } } } else { diff --git a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h index 9797c4793cd..108358ca63b 100644 --- a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h +++ b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h @@ -319,10 +319,6 @@ typedef struct { bool update_incl_srvc; } tBTA_GATTC_SERV; -#ifndef BTA_GATTC_NOTIF_REG_MAX -#define BTA_GATTC_NOTIF_REG_MAX BTA_GATTC_CONN_MAX -#endif - typedef struct { BOOLEAN in_use; BD_ADDR remote_bda; 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 bddc51bc007..e59bee7c08e 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1243,6 +1243,8 @@ typedef void (tBTA_START_STOP_SCAN_CMPL_CBACK) (tBTA_STATUS status); typedef void (tBTA_START_STOP_ADV_CMPL_CBACK) (tBTA_STATUS status); +typedef void (tBTA_CLEAR_ADV_CMPL_CBACK) (tBTA_STATUS status); + typedef void (tBTA_BLE_TRACK_ADV_CMPL_CBACK)(int action, tBTA_STATUS status, tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, tBTA_DM_BLE_REF_VALUE ref_value); @@ -2654,6 +2656,19 @@ extern void BTA_DmBleSetAdvConfigRaw (UINT8 *p_raw_adv, UINT32 raw_adv_len, void BTA_DmBleSetLongAdv (UINT8 *adv_data, UINT32 adv_data_len, tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback); +/******************************************************************************* +** +** Function BTA_DmBleClearAdv +** +** Description This function is called to clear Advertising +** +** Parameters p_adv_data_cback : clear adv complete callback. +** +** Returns None +** +*******************************************************************************/ +void BTA_DmBleClearAdv (tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback); + /******************************************************************************* ** ** Function BTA_DmBleSetScanRsp diff --git a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c index d21eda34cf7..be2bd3ab913 100644 --- a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c @@ -380,7 +380,7 @@ static bt_status_t _btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_a BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr); - _btc_storage_remove_all_ble_keys(bdstr); + ret = _btc_storage_remove_all_ble_keys(bdstr); //here don't remove section, because config_save will check it _btc_storage_save(); 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 4364f380269..99ef66ef724 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 @@ -9,6 +9,7 @@ #include "osi/allocator.h" #include "stack/bt_types.h" #include "common/bt_defs.h" +#include "common/bt_target.h" #include "bta/bta_api.h" #include "bta/bta_dm_co.h" #include "btc/btc_task.h" @@ -23,7 +24,9 @@ #include "osi/mutex.h" #include "osi/thread.h" #include "osi/pkt_queue.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #if (BLE_INCLUDED == TRUE) #if (BLE_42_FEATURE_SUPPORT == TRUE) @@ -187,7 +190,11 @@ static void btc_to_bta_adv_data(esp_ble_adv_data_t *p_adv_data, tBTA_BLE_ADV_DAT if (p_adv_data->include_txpower) { mask |= BTM_BLE_AD_BIT_TX_PWR; +#if (BT_CONTROLLER_INCLUDED == TRUE) bta_adv_data->tx_power = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_ADV); +#else + bta_adv_data->tx_power = 0; +#endif } if (p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 && @@ -470,6 +477,25 @@ static void btc_stop_adv_callback(uint8_t status) } } +static void btc_clear_adv_callback(uint8_t 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_ADV_CLEAR_COMPLETE_EVT; + param.adv_clear_cmpl.status = btc_hci_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_update_duplicate_exceptional_list_callback(tBTA_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info) { esp_ble_gap_cb_param_t param; @@ -1257,13 +1283,17 @@ static void btc_ble_stop_scanning(tBTA_START_STOP_SCAN_CMPL_CBACK *stop_scan_cb) BTA_DmBleScan(false, duration, NULL, stop_scan_cb); } - static void btc_ble_stop_advertising(tBTA_START_STOP_ADV_CMPL_CBACK *stop_adv_cb) { bool stop_adv = false; BTA_DmBleBroadcast(stop_adv, stop_adv_cb); } + +static void btc_ble_clear_advertising(tBTA_CLEAR_ADV_CMPL_CBACK *clear_adv_cb) +{ + BTA_DmBleClearAdv(clear_adv_cb); +} #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) static void btc_ble_update_conn_params(BD_ADDR bd_addr, uint16_t min_int, uint16_t max_int, uint16_t latency, uint16_t timeout) @@ -1731,6 +1761,9 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) case BTC_GAP_BLE_ACT_STOP_ADV: btc_ble_stop_advertising(btc_stop_adv_callback); break; + case BTC_GAP_BLE_ACT_CLEAR_ADV: + btc_ble_clear_advertising(btc_clear_adv_callback); + break; #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) case BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM: btc_ble_update_conn_params(arg->conn_update_params.conn_params.bda, diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c index 8ababa1c6fc..d04ec79f5c1 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c @@ -29,7 +29,9 @@ #include "common/bt_trace.h" #include "common/bt_defs.h" #include "device/bdaddr.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include "esp_hf_ag_api.h" #include "osi/allocator.h" @@ -328,12 +330,14 @@ bt_status_t btc_hf_init(void) // custom initialization here hf_local_param[idx].btc_hf_cb.initialized = true; // set audio path +#if (BT_CONTROLLER_INCLUDED == TRUE) #if BTM_SCO_HCI_INCLUDED uint8_t data_path = ESP_SCO_DATA_PATH_HCI; #else uint8_t data_path = ESP_SCO_DATA_PATH_PCM; #endif esp_bredr_sco_datapath_set(data_path); +#endif return BT_STATUS_SUCCESS; } diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c b/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c index 3909a4c6f6b..67973bc267a 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c @@ -25,7 +25,9 @@ #include "btc/btc_util.h" #include "esp_hf_client_api.h" #include "bta/bta_hf_client_api.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include #if BT_HF_CLIENT_BQB_INCLUDED @@ -167,19 +169,20 @@ bt_status_t btc_hf_client_init(void) { BTC_TRACE_EVENT("%s", __FUNCTION__); - uint8_t data_path; btc_dm_enable_service(BTA_HFP_HS_SERVICE_ID); clear_state(); hf_client_local_param.btc_hf_client_cb.initialized = true; +#if (BT_CONTROLLER_INCLUDED == TRUE) #if BTM_SCO_HCI_INCLUDED - data_path = ESP_SCO_DATA_PATH_HCI; + uint8_t data_path = ESP_SCO_DATA_PATH_HCI; #else - data_path = ESP_SCO_DATA_PATH_PCM; + uint8_t data_path = ESP_SCO_DATA_PATH_PCM; #endif esp_bredr_sco_datapath_set(data_path); +#endif return BT_STATUS_SUCCESS; } 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 89d72d05d56..3fb5f4b34ea 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 @@ -99,6 +99,9 @@ typedef enum { BTC_GAP_BLE_DTM_RX_START, #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) BTC_GAP_BLE_DTM_STOP, +#if (BLE_42_FEATURE_SUPPORT == TRUE) + BTC_GAP_BLE_ACT_CLEAR_ADV, +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h index c290dd7c0a9..313930a4d02 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h @@ -63,7 +63,7 @@ typedef struct { /* btc_hidd_args_t */ typedef union { // BTC_HD_CONNECT_EVT - struct connect_arg { + struct hd_connect_arg { BD_ADDR bd_addr; } connect; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h index d42c6912437..f936d1816d1 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h @@ -184,13 +184,13 @@ typedef union } phone; // BTC_HF_REGISTER_DATA_CALLBACK_EVT - struct reg_data_callback { + struct ag_reg_data_callback { esp_hf_incoming_data_cb_t recv; esp_hf_outgoing_data_cb_t send; } reg_data_cb; // BTC_HF_REQUEST_PKT_STAT_EVT - struct req_pkt_stat_sync_handle { + struct ag_req_pkt_stat_sync_handle { UINT16 sync_conn_handle; } pkt_sync_hd; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h index 0af84506858..4f10371bd01 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h @@ -102,7 +102,7 @@ typedef union { } send_dtmf; // BTC_HF_CLIENT_REGISTER_DATA_CALLBACK_EVT - struct reg_data_callback { + struct hf_client_reg_data_callback { esp_hf_client_incoming_data_cb_t recv; esp_hf_client_outgoing_data_cb_t send; } reg_data_cb; @@ -120,7 +120,7 @@ typedef union { } send_iphoneaccev; // BTC_HF_CLIENT_REQUEST_PKT_STAT_EVT - struct req_pkt_stat_sync_handle { + struct hf_client_req_pkt_stat_sync_handle { UINT16 sync_conn_handle; } pkt_sync_hd; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h index 0e0cea8a06d..ae6faefc1ef 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h @@ -103,7 +103,7 @@ typedef struct { /* btc_spp_args_t */ typedef union { // BTC_HH_CONNECT_EVT - struct connect_arg { + struct hh_connect_arg { BD_ADDR bd_addr; } connect; 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 82b3bf5bd02..101ae800667 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 @@ -105,7 +105,7 @@ #ifdef CONFIG_BT_BLE_RPA_SUPPORTED #define UC_BT_BLE_RPA_SUPPORTED CONFIG_BT_BLE_RPA_SUPPORTED #else -#if SOC_BLE_DEVICE_PRIVACY_SUPPORTED +#if (CONFIG_BT_CONTROLLER_ENABLED && SOC_BLE_DEVICE_PRIVACY_SUPPORTED) #define UC_BT_BLE_RPA_SUPPORTED TRUE #else #define UC_BT_BLE_RPA_SUPPORTED FALSE @@ -163,6 +163,13 @@ #define UC_BT_GATTC_MAX_CACHE_CHAR 40 #endif +//GATTC NOTIF +#ifdef CONFIG_BT_GATTC_NOTIF_REG_MAX +#define UC_BT_GATTC_NOTIF_REG_MAX CONFIG_BT_GATTC_NOTIF_REG_MAX +#else +#define UC_BT_GATTC_NOTIF_REG_MAX 5 +#endif + #ifdef CONFIG_BT_GATTC_CACHE_NVS_FLASH #define UC_BT_GATTC_CACHE_NVS_FLASH_ENABLED CONFIG_BT_GATTC_CACHE_NVS_FLASH #else @@ -454,13 +461,15 @@ #ifdef CONFIG_BT_LOG_HID_TRACE_LEVEL #if UC_BT_HID_HOST_ENABLED #define UC_BT_LOG_HIDH_TRACE_LEVEL CONFIG_BT_LOG_HID_TRACE_LEVEL -#elif UC_BT_HID_DEVICE_ENABLED +#endif +#if UC_BT_HID_DEVICE_ENABLED #define UC_BT_LOG_HIDD_TRACE_LEVEL CONFIG_BT_LOG_HID_TRACE_LEVEL #endif #else #if UC_BT_HID_HOST_ENABLED #define UC_BT_LOG_HIDH_TRACE_LEVEL UC_TRACE_LEVEL_WARNING -#elif UC_BT_HID_DEVICE_ENABLED +#endif +#if UC_BT_HID_DEVICE_ENABLED #define UC_BT_LOG_HIDD_TRACE_LEVEL UC_TRACE_LEVEL_WARNING #endif #endif 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 4c3c5ef37cb..21a728e247f 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -51,6 +51,12 @@ #define ESP_COEX_VSC_INCLUDED FALSE #endif +#if (UC_BT_CONTROLLER_INCLUDED == TRUE) +#define BT_CONTROLLER_INCLUDED TRUE +#else +#define BT_CONTROLLER_INCLUDED FALSE +#endif + /****************************************************************************** ** ** Classic BT features @@ -96,49 +102,50 @@ #define VND_BT_JV_BTA_L2CAP TRUE #endif /* UC_BT_L2CAP_ENABLED */ -#if (UC_BT_HFP_AG_ENABLED == TRUE) -#define BTC_HF_INCLUDED TRUE -#define BTA_AG_INCLUDED TRUE -#define PLC_INCLUDED TRUE -#define BTA_JV_RFCOMM_INCLUDED TRUE +#if (UC_BT_HFP_AG_ENABLED == TRUE) || (UC_BT_HFP_CLIENT_ENABLED == TRUE) #ifndef RFCOMM_INCLUDED #define RFCOMM_INCLUDED TRUE #endif #ifndef BTM_SCO_INCLUDED #define BTM_SCO_INCLUDED TRUE #endif -#ifndef BTM_MAX_SCO_LINKS -#define BTM_MAX_SCO_LINKS (1) -#endif #ifndef SBC_DEC_INCLUDED #define SBC_DEC_INCLUDED TRUE #endif #ifndef SBC_ENC_INCLUDED #define SBC_ENC_INCLUDED TRUE #endif -#endif /* UC_BT_HFP_AG_ENABLED */ +#ifndef PLC_INCLUDED +#define PLC_INCLUDED TRUE +#endif +#if (UC_BT_HFP_AG_ENABLED == TRUE) +#ifndef BTM_MAX_SCO_LINKS_AG +#define BTM_MAX_SCO_LINKS_AG (1) +#endif +#define BTC_HF_INCLUDED TRUE +#define BTA_AG_INCLUDED TRUE +#else +#ifndef BTM_MAX_SCO_LINKS_AG +#define BTM_MAX_SCO_LINKS_AG (0) +#endif +#endif /* (UC_BT_HFP_AG_ENABLED == TRUE) */ #if (UC_BT_HFP_CLIENT_ENABLED == TRUE) +#ifndef BTM_MAX_SCO_LINKS_CLIENT +#define BTM_MAX_SCO_LINKS_CLIENT (1) +#endif #define BTC_HF_CLIENT_INCLUDED TRUE #define BTA_HF_INCLUDED TRUE -#define PLC_INCLUDED TRUE -#ifndef RFCOMM_INCLUDED -#define RFCOMM_INCLUDED TRUE -#endif -#ifndef BTM_SCO_INCLUDED -#define BTM_SCO_INCLUDED TRUE -#endif -#ifndef BTM_MAX_SCO_LINKS -#define BTM_MAX_SCO_LINKS (1) +#else +#ifndef BTM_MAX_SCO_LINKS_CLIENT +#define BTM_MAX_SCO_LINKS_CLIENT (0) #endif +#endif /* (UC_BT_HFP_CLIENT_ENABLED == TRUE) */ -#ifndef SBC_DEC_INCLUDED -#define SBC_DEC_INCLUDED TRUE -#endif -#ifndef SBC_ENC_INCLUDED -#define SBC_ENC_INCLUDED TRUE +#ifndef BTM_MAX_SCO_LINKS +#define BTM_MAX_SCO_LINKS (BTM_MAX_SCO_LINKS_AG + BTM_MAX_SCO_LINKS_CLIENT) #endif -#endif /* UC_BT_HFP_CLIENT_ENABLED */ +#endif /* (UC_BT_HFP_AG_ENABLED == TRUE) || (UC_BT_HFP_CLIENT_ENABLED == TRUE) */ #if UC_BT_HID_ENABLED #define BT_HID_INCLUDED TRUE @@ -248,6 +255,12 @@ #define GATTC_CONNECT_RETRY_EN FALSE #endif +#ifdef UC_BT_GATTC_NOTIF_REG_MAX +#define BTA_GATTC_NOTIF_REG_MAX UC_BT_GATTC_NOTIF_REG_MAX +#else +#define BTA_GATTC_NOTIF_REG_MAX 5 +#endif + #if (UC_BT_SMP_ENABLE) #define SMP_INCLUDED TRUE #if (BLE_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index 7a1377f6115..121a4d51016 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -22,16 +22,20 @@ #include "hci/hci_hal.h" #include "hci/hci_internals.h" #include "hci/hci_layer.h" +#include "hci/hci_trans_int.h" #include "osi/thread.h" #include "osi/pkt_queue.h" #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) #include "osi/mutex.h" #include "osi/alarm.h" #endif +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif +#include "esp_bluedroid_hci.h" #include "stack/hcimsgs.h" -#if SOC_ESP_NIMBLE_CONTROLLER +#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) #include "nimble/ble_hci_trans.h" #endif @@ -87,7 +91,7 @@ typedef struct { static hci_hal_env_t hci_hal_env; static const hci_hal_t interface; -static const esp_vhci_host_callback_t vhci_host_cb; +static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb; static void host_send_pkt_available_cb(void); static int host_recv_pkt_cb(uint8_t *data, uint16_t len); @@ -167,7 +171,7 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks, void *task_thre hci_hal_env_init(upper_callbacks, (osi_thread_t *)task_thread); //register vhci host cb - if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) { + if (hci_host_register_callback(&hci_host_cb) != ESP_OK) { return false; } @@ -207,7 +211,7 @@ static uint16_t transmit_data(serial_data_type_t type, BTTRC_DUMP_BUFFER("Transmit Pkt", data, length); // TX Data to target - esp_vhci_host_send_packet(data, length); + hci_host_send_packet(data, length); // Be nice and restore the old value of that byte *(data) = previous_byte; @@ -590,7 +594,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) return 0; } -#if SOC_ESP_NIMBLE_CONTROLLER +#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) int ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg) @@ -625,7 +629,7 @@ ble_hs_rx_data(struct os_mbuf *om, void *arg) } #endif -static const esp_vhci_host_callback_t vhci_host_cb = { +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/hci/hci_layer.c b/components/bt/host/bluedroid/hci/hci_layer.c index b5c1bab66a9..56ab8877dc5 100644 --- a/components/bt/host/bluedroid/hci/hci_layer.c +++ b/components/bt/host/bluedroid/hci/hci_layer.c @@ -17,7 +17,10 @@ ******************************************************************************/ #include #include "sdkconfig.h" +#include "common/bt_target.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include "common/bt_defs.h" #include "common/bt_trace.h" @@ -28,6 +31,7 @@ #include "hci/hci_internals.h" #include "hci/hci_hal.h" #include "hci/hci_layer.h" +#include "hci/hci_trans_int.h" #include "osi/allocator.h" #include "hci/packet_fragmenter.h" #include "osi/list.h" @@ -226,7 +230,7 @@ static void hci_downstream_data_handler(void *arg) * All packets will be directly copied to single queue in driver layer with * H4 type header added (1 byte). */ - while (esp_vhci_host_check_send_available()) { + while (hci_host_check_send_available()) { /*Now Target only allowed one packet per TX*/ BT_HDR *pkt = packet_fragmenter->fragment_current_packet(); if (pkt != NULL) { diff --git a/components/bt/host/bluedroid/hci/include/hci/hci_hal.h b/components/bt/host/bluedroid/hci/include/hci/hci_hal.h index 9ed0692ef0f..fe5796db323 100644 --- a/components/bt/host/bluedroid/hci/include/hci/hci_hal.h +++ b/components/bt/host/bluedroid/hci/include/hci/hci_hal.h @@ -21,9 +21,10 @@ #include #include +#include "common/bt_target.h" #include "osi/pkt_queue.h" #include "stack/bt_types.h" -#if SOC_ESP_NIMBLE_CONTROLLER +#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) #include "os/os_mbuf.h" #endif typedef enum { @@ -85,7 +86,7 @@ typedef struct hci_hal_t { // Gets the correct hal implementation, as compiled for. const hci_hal_t *hci_hal_h4_get_interface(void); -#if SOC_ESP_NIMBLE_CONTROLLER +#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) int ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg); int ble_hs_rx_data(struct os_mbuf *om, void *arg); diff --git a/components/bt/host/bluedroid/hci/include/hci/hci_trans_int.h b/components/bt/host/bluedroid/hci/include/hci/hci_trans_int.h new file mode 100644 index 00000000000..86d74bd4bf1 --- /dev/null +++ b/components/bt/host/bluedroid/hci/include/hci/hci_trans_int.h @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __HCI_TRANS_INT_H__ +#define __HCI_TRANS_INT_H__ + +#include +#include +#include "esp_err.h" +#include "esp_bluedroid_hci.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief host checks whether it can send data to controller + * + * @return true if host can send data, false otherwise + */ +bool hci_host_check_send_available(void); + +/** + * @brief host sends packet to controller + * + * @param[in] data pointer to data buffer + * @param[in] len length of data in byte + */ +void hci_host_send_packet(uint8_t *data, uint16_t len); + +/** + * @brief register the HCI function interface + * + * @param[in] callback HCI function interface + * + * @return ESP_OK register successfully, ESP_FAIL otherwise + */ +esp_err_t hci_host_register_callback(const esp_bluedroid_hci_driver_callbacks_t *callback); + +#ifdef __cplusplus +} +#endif + +#endif /* __HCI_TRANS_INT_H__ */ 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 2ce4488e38e..89c306930ba 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -4352,7 +4352,7 @@ void btm_ble_read_remote_features_complete(UINT8 *p) *******************************************************************************/ void btm_ble_write_adv_enable_complete(UINT8 *p) { - /* if write adv enable/disbale not succeed */ + /* if write adv enable/disable not succeed */ if (*p != HCI_SUCCESS) { BTM_TRACE_ERROR("%s failed", __func__); } @@ -4669,6 +4669,28 @@ BOOLEAN BTM_Ble_Authorization(BD_ADDR bd_addr, BOOLEAN authorize) return FALSE; } +/******************************************************************************* +** +** Function BTM_BleClearAdv +** +** Description This function is called to clear legacy advertising +** +** Parameter p_clear_adv_cback - Command complete callback +** +*******************************************************************************/ +BOOLEAN BTM_BleClearAdv(tBTM_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback) +{ + tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; + + if (btsnd_hcic_ble_clear_adv() == FALSE) { + BTM_TRACE_ERROR("%s: Unable to Clear Advertising", __FUNCTION__); + return FALSE; + } + + p_cb->inq_var.p_clear_adv_cb = p_clear_adv_cback; + 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_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index 0656f18f99a..bffb5bbee0e 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -731,6 +731,14 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len, } break; } + case HCI_VENDOR_BLE_CLEAR_ADV: { + uint8_t status; + STREAM_TO_UINT8(status, p); + if (ble_cb && ble_cb->inq_var.p_clear_adv_cb) { + ble_cb->inq_var.p_clear_adv_cb(status); + } + break; + } default: break; } 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 2f864b04ecd..1f55289c75d 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 @@ -159,6 +159,7 @@ typedef struct { tBTM_BLE_SFP sfp; /* scanning filter policy */ tBTM_START_ADV_CMPL_CBACK *p_adv_cb; tBTM_START_STOP_ADV_CMPL_CBACK *p_stop_adv_cb; + tBTM_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cb; tBLE_ADDR_TYPE adv_addr_type; UINT8 evt_type; UINT8 adv_mode; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_db.c b/components/bt/host/bluedroid/stack/gatt/gatt_db.c index cd2d2ddc498..4aebc30f40e 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_db.c @@ -1173,39 +1173,39 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, if ((op_code == GATT_SIGN_CMD_WRITE) && !(perm & GATT_WRITE_SIGNED_PERM)) { status = GATT_WRITE_NOT_PERMIT; - GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed"); + GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed,handle:0x%04x",handle); } if ((op_code == GATT_SIGN_CMD_WRITE) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED)) { status = GATT_INVALID_PDU; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encypted link"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encypted link,handle:0x%04x",handle); } else if (!(perm & GATT_WRITE_ALLOWED)) { status = GATT_WRITE_NOT_PERMIT; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT,handle:0x%04x",handle); } /* require authentication, but not been authenticated */ else if ((perm & GATT_WRITE_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED)) { status = GATT_INSUF_AUTHENTICATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION,handle:0x%04x",handle); } else if ((perm & GATT_WRITE_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) { status = GATT_INSUF_AUTHENTICATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required,handle:0x%04x",handle); } else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) { status = GATT_INSUF_ENCRYPTION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION,handle:0x%04x",handle); } else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) { status = GATT_INSUF_KEY_SIZE; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE,handle:0x%04x",handle); } /* LE Authorization check*/ else if ((perm & GATT_WRITE_AUTHORIZATION) && (!(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED) || !(sec_flag & GATT_SEC_FLAG_AUTHORIZATION))){ status = GATT_INSUF_AUTHORIZATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHORIZATION"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHORIZATION,handle:0x%04x",handle); } /* LE security mode 2 attribute */ else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (perm & GATT_WRITE_ALLOWED) == 0) { status = GATT_INSUF_AUTHENTICATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required,handle:0x%04x",handle); } else { /* writable: must be char value declaration or char descritpors */ if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) { switch (p_attr->uuid) { @@ -1246,10 +1246,10 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, { if (op_code == GATT_REQ_PREPARE_WRITE && offset != 0) { /* does not allow write blob */ status = GATT_NOT_LONG; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_NOT_LONG"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_NOT_LONG,handle:0x%04x",handle); } else if (len != max_size) { /* data does not match the required format */ status = GATT_INVALID_ATTR_LEN; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_PDU"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_PDU,handle:0x%04x",handle); } else { status = GATT_SUCCESS; } diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 1f12c344b30..0324002792c 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1084,6 +1084,27 @@ BOOLEAN btsnd_hcic_ble_set_channels (BLE_CHANNELS channels) return (TRUE); } +BOOLEAN btsnd_hcic_ble_clear_adv (void) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_CLEAR_ADV)) == NULL) { + return (FALSE); + } + + pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CLEAR_ADV; + p->offset = 0; + + UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_CLEAR_ADV); + UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_CLEAR_ADV); + + btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + #define HCIC_BLE_CMD_CREATED(p, pp, size) do{\ if ((p = HCI_GET_CMD_BUF(size)) == NULL) { \ return FALSE; \ 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 3df5120421a..f64500656be 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 @@ -1000,6 +1000,7 @@ typedef void (tBTM_START_ADV_CMPL_CBACK) (UINT8 status); 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); #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 @@ -2638,6 +2639,17 @@ BOOLEAN BTM_GetCurrentConnParams(BD_ADDR bda, uint16_t *interval, uint16_t *late ** *******************************************************************************/ BOOLEAN BTM_Ble_Authorization(BD_ADDR bd_addr, BOOLEAN authorize); + +/******************************************************************************* +** +** Function BTM_BleClearAdv +** +** Description This function is called to clear legacy advertising +** +** Parameter p_clear_adv_cback - Command complete callback +** +*******************************************************************************/ +BOOLEAN BTM_BleClearAdv(tBTM_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback); /* #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 22d5727133b..8c5ba3f2f04 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -419,6 +419,8 @@ #define HCI_SUBCODE_BLE_DUPLICATE_EXCEPTIONAL_LIST 0x08 #define HCI_SUBCODE_BLE_SET_ADV_FLOW_CONTROL 0x09 #define HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL 0x0A +#define HCI_SUBCODE_BLE_RD_STATIC_ADDR 0x0B +#define HCI_SUBCODE_BLE_CLEAR_ADV 0x0C #define HCI_SUBCODE_BLE_MAX 0x7F //ESP BT subcode define @@ -462,6 +464,8 @@ #define HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_DUPLICATE_EXCEPTIONAL_LIST) #define HCI_VENDOR_BLE_SET_ADV_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_SET_ADV_FLOW_CONTROL) #define HCI_VENDOR_BLE_ADV_REPORT_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL) +/* BLE clear legacy advertising */ +#define HCI_VENDOR_BLE_CLEAR_ADV HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_CLEAR_ADV) //ESP BT HCI CMD /* subcode for multi adv feature */ diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index d8ef269e208..bd328fab238 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -751,8 +751,9 @@ void btsnd_hcic_vendor_spec_cmd (BT_HDR *buffer, UINT16 opcode, #define HCIC_PARAM_SIZE_BLE_SET_ADDR_RESOLUTION_ENABLE 1 #define HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT 2 #define HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH 6 -#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_WRITE_EXTENDED_SCAN_PARAM 11 +#define HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL 2 +#define HCIC_PARAM_SIZE_BLE_CLEAR_ADV 0 #if (BLE_50_FEATURE_SUPPORT == TRUE) #define HCIC_PARAM_SIZE_BLE_READ_PHY 2 #define HCIC_PARAM_SIZE_BLE_SET_DEF_PHY 3 @@ -906,6 +907,8 @@ BOOLEAN btsnd_hcic_ble_set_addr_resolution_enable (UINT8 addr_resolution_enable) BOOLEAN btsnd_hcic_ble_set_rand_priv_addr_timeout (UINT16 rpa_timout); +BOOLEAN btsnd_hcic_ble_clear_adv(void); + #endif /* BLE_INCLUDED */ #if (BLE_50_FEATURE_SUPPORT == TRUE) typedef struct { diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index 9a87c6d6789..38f956e5430 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -276,6 +276,15 @@ menu "Memory Settings" help Dynamic memory size of block 2 + config BT_NIMBLE_MSYS_BUF_FROM_HEAP + bool "Get Msys Mbuf from heap" + default y + depends on BT_LE_MSYS_INIT_IN_CONTROLLER + help + This option sets the source of the shared msys mbuf memory between + the Host and the Controller. Allocate the memory from the heap if + this option is sets, from the mempool otherwise. + config BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT int "ACL Buffer count" depends on BT_NIMBLE_ENABLED diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index b85d99de41d..6a14d2a3ec4 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit b85d99de41d8c9085c6f3de50a29ebedd9681381 +Subproject commit 6a14d2a3ec43697fa332c5b26b955b8778b8c352 diff --git a/components/bt/porting/nimble/src/os_msys_init.c b/components/bt/porting/nimble/src/os_msys_init.c index 53619197d07..bf4f4145166 100644 --- a/components/bt/porting/nimble/src/os_msys_init.c +++ b/components/bt/porting/nimble/src/os_msys_init.c @@ -30,6 +30,11 @@ static STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = #define OS_MSYS_1_SANITY_MIN_COUNT MYNEWT_VAL(MSYS_1_SANITY_MIN_COUNT) #define OS_MSYS_2_SANITY_MIN_COUNT MYNEWT_VAL(MSYS_2_SANITY_MIN_COUNT) +#if CONFIG_BT_NIMBLE_MSYS_BUF_FROM_HEAP +#define OS_MSYS_BLOCK_FROM_HEAP (1) +#else +#define OS_MSYS_BLOCK_FROM_HEAP (0) +#endif // CONFIG_BT_NIMBLE_MSYS_BUF_FROM_HEAP #else #define OS_MSYS_1_BLOCK_COUNT CONFIG_BT_LE_MSYS_1_BLOCK_COUNT #define OS_MSYS_1_BLOCK_SIZE CONFIG_BT_LE_MSYS_1_BLOCK_SIZE @@ -38,6 +43,12 @@ static STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = #define OS_MSYS_1_SANITY_MIN_COUNT 0 #define OS_MSYS_2_SANITY_MIN_COUNT 0 + +#if CONFIG_BT_LE_MSYS_BUF_FROM_HEAP +#define OS_MSYS_BLOCK_FROM_HEAP (1) +#else +#define OS_MSYS_BLOCK_FROM_HEAP (0) +#endif // CONFIG_BT_LE_MSYS_BUF_FROM_HEAP #endif @@ -71,7 +82,7 @@ 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); +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); int os_msys_init(void) @@ -79,7 +90,8 @@ int os_msys_init(void) return esp_ble_msys_init(SYSINIT_MSYS_1_MEMBLOCK_SIZE, SYSINIT_MSYS_2_MEMBLOCK_SIZE, OS_MSYS_1_BLOCK_COUNT, - OS_MSYS_2_BLOCK_COUNT); + OS_MSYS_2_BLOCK_COUNT, + OS_MSYS_BLOCK_FROM_HEAP); } void os_msys_deinit(void) diff --git a/components/bt/test_apps/main/test_smp.c b/components/bt/test_apps/main/test_smp.c index 4eefbe12f4b..ea89ec261b4 100644 --- a/components/bt/test_apps/main/test_smp.c +++ b/components/bt/test_apps/main/test_smp.c @@ -15,7 +15,6 @@ #include "unity.h" #include "esp_random.h" -#include "esp_bt.h" #include "esp_bt_main.h" #include "esp_bt_device.h" #include "esp_gap_ble_api.h" diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 9d43f985511..65a4add014e 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -6,9 +6,6 @@ endif() # Always compiled source files set(srcs - "gpio/gpio.c" - "gpio/gpio_glitch_filter_ops.c" - "gpio/rtc_io.c" "spi/spi_bus_lock.c") # Always included headers @@ -16,14 +13,11 @@ set(includes "include" "deprecated" "analog_comparator/include" "dac/include" - "gpio/include" - "gptimer/include" "i2c/include" "i2s/include" "ledc/include" "mcpwm/include" "parlio/include" - "pcnt/include" "rmt/include" "sdio_slave/include" "sdmmc/include" @@ -36,8 +30,7 @@ set(includes "include" "usb_serial_jtag/include") # Always included linker fragments -set(ldfragments "linker.lf" - "gpio/linker.lf") +set(ldfragments "linker.lf") # ADC related source files (dprecated) if(CONFIG_SOC_ADC_SUPPORTED) @@ -72,34 +65,9 @@ if(CONFIG_SOC_PARLIO_SUPPORTED) list(APPEND srcs "parlio/parlio_common.c" "parlio/parlio_tx.c") endif() -# GPIO related source files -if(CONFIG_SOC_DEDICATED_GPIO_SUPPORTED) - list(APPEND srcs "gpio/dedic_gpio.c") -endif() - -if(CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER) - list(APPEND srcs "gpio/gpio_pin_glitch_filter.c") -endif() - -if(CONFIG_SOC_GPIO_FLEX_GLITCH_FILTER_NUM GREATER 0) - list(APPEND srcs "gpio/gpio_flex_glitch_filter.c") -endif() - -if(CONFIG_SOC_GPIO_SUPPORT_ETM) - list(APPEND srcs "gpio/gpio_etm.c") -endif() - -# GPTimer related source files +# GPTimer legacy driver if(CONFIG_SOC_GPTIMER_SUPPORTED) - list(APPEND srcs "gptimer/gptimer.c" - "gptimer/gptimer_priv.c" - "deprecated/timer_legacy.c") - - list(APPEND ldfragments "gptimer/linker.lf") -endif() - -if(CONFIG_SOC_TIMER_SUPPORT_ETM) - list(APPEND srcs "gptimer/gptimer_etm.c") + list(APPEND srcs "deprecated/timer_legacy.c") endif() # I2C related source files @@ -108,6 +76,9 @@ if(CONFIG_SOC_I2C_SUPPORTED) "i2c/i2c_master.c" "i2c/i2c_common.c" ) + if(CONFIG_SOC_I2C_SUPPORT_SLAVE) + list(APPEND srcs "i2c/i2c_slave.c") + endif() list(APPEND ldfragments "i2c/linker.lf") endif() @@ -150,10 +121,9 @@ if(CONFIG_SOC_MCPWM_SUPPORTED) list(APPEND ldfragments "mcpwm/linker.lf") endif() -# PCNT related source files +# PCNT legacy driver if(CONFIG_SOC_PCNT_SUPPORTED) - list(APPEND srcs "pcnt/pulse_cnt.c" - "deprecated/pcnt_legacy.c") + list(APPEND srcs "deprecated/pcnt_legacy.c") endif() # RMT related source files @@ -245,6 +215,9 @@ else() INCLUDE_DIRS ${includes} PRIV_REQUIRES efuse esp_timer esp_mm REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support + # for backward compatibility, the driver component needs to + # have a public dependency on other "esp_driver_foo" components + esp_driver_gpio esp_driver_pcnt esp_driver_gptimer LDFRAGMENTS ${ldfragments} ) endif() diff --git a/components/driver/Kconfig b/components/driver/Kconfig index 4936d2fc73d..9b0729bb8d0 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -156,24 +156,6 @@ menu "Driver Configurations" orsource "./uart/Kconfig.uart" - menu "GPIO Configuration" - config GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL - bool "Support light sleep GPIO pullup/pulldown configuration for ESP32" - depends on IDF_TARGET_ESP32 - help - This option is intended to fix the bug that ESP32 is not able to switch to configured - pullup/pulldown mode in sleep. - If this option is selected, chip will automatically emulate the behaviour of switching, - and about 450B of source codes would be placed into IRAM. - - config GPIO_CTRL_FUNC_IN_IRAM - bool "Place GPIO control functions into IRAM" - default n - help - Place GPIO control functions (like intr_disable/set_level) into IRAM, - so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. - endmenu # GPIO Configuration - menu "Sigma Delta Modulator Configuration" depends on SOC_SDM_SUPPORTED config SDM_CTRL_FUNC_IN_IRAM @@ -225,10 +207,6 @@ menu "Driver Configurations" Note that, this option only controls the Analog Comparator driver log, won't affect other drivers. endmenu # Analog Comparator Configuration - orsource "./gptimer/Kconfig.gptimer" - - orsource "./pcnt/Kconfig.pcnt" - orsource "./rmt/Kconfig.rmt" orsource "./mcpwm/Kconfig.mcpwm" diff --git a/components/driver/deprecated/adc_i2s_deprecated.c b/components/driver/deprecated/adc_i2s_deprecated.c index 2971e476097..e05eec2c458 100644 --- a/components/driver/deprecated/adc_i2s_deprecated.c +++ b/components/driver/deprecated/adc_i2s_deprecated.c @@ -56,7 +56,7 @@ esp_pm_lock_handle_t adc_digi_arbiter_lock = NULL; ESP32 Depricated ADC APIs and functions ---------------------------------------------------------------*/ #define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIGI_FORMAT_12BIT) -#define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_11) +#define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_12) #define DIG_ADC_BIT_WIDTH_DEFUALT (3) //3 for ADC_WIDTH_BIT_12 /** diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index b20df639e66..a88c42465d3 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -802,7 +802,7 @@ int adc1_get_raw(adc1_channel_t channel) esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) { ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_2), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 channel error"); - ESP_RETURN_ON_FALSE((atten <= ADC_ATTEN_DB_11), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 Atten Err"); + ESP_RETURN_ON_FALSE((atten <= ADC_ATTEN_DB_12), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 Atten Err"); esp_err_t ret = ESP_OK; s_atten2_single[channel] = atten; diff --git a/components/driver/i2c/i2c.c b/components/driver/i2c/i2c.c index 1d638babb79..e9397b17526 100644 --- a/components/driver/i2c/i2c.c +++ b/components/driver/i2c/i2c.c @@ -110,6 +110,18 @@ static const char *I2C_TAG = "i2c"; #endif #define I2C_MEM_ALLOC_CAPS_DEFAULT MALLOC_CAP_DEFAULT +#if SOC_PERIPH_CLK_CTRL_SHARED +#define I2C_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2C_CLOCK_SRC_ATOMIC() +#endif + +#if !SOC_RCC_IS_INDEPENDENT +#define I2C_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2C_RCC_ATOMIC() +#endif + /** * I2C bus are defined in the header files, let's check that the values are correct */ @@ -240,7 +252,9 @@ static void i2c_hw_disable(i2c_port_t i2c_num) { I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); if (i2c_context[i2c_num].hw_enabled != false) { - periph_module_disable(i2c_periph_signal[i2c_num].module); + I2C_RCC_ATOMIC() { + i2c_ll_enable_bus_clock(i2c_num, false); + } i2c_context[i2c_num].hw_enabled = false; } I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); @@ -250,7 +264,10 @@ static void i2c_hw_enable(i2c_port_t i2c_num) { I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); if (i2c_context[i2c_num].hw_enabled != true) { - periph_module_enable(i2c_periph_signal[i2c_num].module); + I2C_RCC_ATOMIC() { + i2c_ll_enable_bus_clock(i2c_num, true); + i2c_ll_reset_register(i2c_num); + } i2c_context[i2c_num].hw_enabled = true; } I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); @@ -375,7 +392,9 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_ return ESP_FAIL; } i2c_hw_enable(i2c_num); - i2c_hal_init(&i2c_context[i2c_num].hal, i2c_num); + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_init(&i2c_context[i2c_num].hal, i2c_num); + } //Disable I2C interrupt. i2c_ll_disable_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK); i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK); @@ -478,7 +497,9 @@ esp_err_t i2c_driver_delete(i2c_port_t i2c_num) } #endif - i2c_hal_deinit(&i2c_context[i2c_num].hal); + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_deinit(&i2c_context[i2c_num].hal); + } free(p_i2c_obj[i2c_num]); p_i2c_obj[i2c_num] = NULL; @@ -746,7 +767,9 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) return ret; } i2c_hw_enable(i2c_num); - i2c_hal_init(&i2c_context[i2c_num].hal, i2c_num); + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_init(&i2c_context[i2c_num].hal, i2c_num); + } I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_ll_disable_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK); i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK); @@ -754,7 +777,9 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) if (i2c_conf->mode == I2C_MODE_SLAVE) { //slave mode i2c_hal_slave_init(&(i2c_context[i2c_num].hal)); i2c_ll_slave_tx_auto_start_en(i2c_context[i2c_num].hal.dev, true); - i2c_ll_set_source_clk(i2c_context[i2c_num].hal.dev, src_clk); + I2C_CLOCK_SRC_ATOMIC() { + i2c_ll_set_source_clk(i2c_context[i2c_num].hal.dev, src_clk); + } i2c_ll_set_slave_addr(i2c_context[i2c_num].hal.dev, i2c_conf->slave.slave_addr, i2c_conf->slave.addr_10bit_en); i2c_ll_set_rxfifo_full_thr(i2c_context[i2c_num].hal.dev, I2C_FIFO_FULL_THRESH_VAL); i2c_ll_set_txfifo_empty_thr(i2c_context[i2c_num].hal.dev, I2C_FIFO_EMPTY_THRESH_VAL); @@ -768,7 +793,9 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) i2c_hal_master_init(&(i2c_context[i2c_num].hal)); //Default, we enable hardware filter i2c_ll_master_set_filter(i2c_context[i2c_num].hal.dev, I2C_FILTER_CYC_NUM_DEF); - i2c_hal_set_bus_timing(&(i2c_context[i2c_num].hal), i2c_conf->master.clk_speed, src_clk, s_get_src_clk_freq(src_clk)); + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_set_bus_timing(&(i2c_context[i2c_num].hal), i2c_conf->master.clk_speed, src_clk, s_get_src_clk_freq(src_clk)); + } } i2c_ll_update(i2c_context[i2c_num].hal.dev); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); diff --git a/components/driver/i2c/i2c_common.c b/components/driver/i2c/i2c_common.c index 5f90a695dfc..831bef2bdc6 100644 --- a/components/driver/i2c/i2c_common.c +++ b/components/driver/i2c/i2c_common.c @@ -37,7 +37,7 @@ typedef struct i2c_platform_t { static i2c_platform_t s_i2c_platform = {}; // singleton platform -esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_new_bus, i2c_bus_mode_t mode) +static esp_err_t s_i2c_bus_handle_aquire(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_new_bus, i2c_bus_mode_t mode) { #if CONFIG_I2C_ENABLE_DEBUG_LOG esp_log_level_set(TAG, ESP_LOG_DEBUG); @@ -56,9 +56,13 @@ esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_ bus->bus_mode = mode; // Enable the I2C module - periph_module_enable(i2c_periph_signal[port_num].module); - periph_module_reset(i2c_periph_signal[port_num].module); - i2c_hal_init(&bus->hal, port_num); + I2C_RCC_ATOMIC() { + i2c_ll_enable_bus_clock(bus->port_num, true); + i2c_ll_reset_register(bus->port_num); + } + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_init(&bus->hal, port_num); + } } } else { ESP_LOGE(TAG, "I2C bus id(%d) has already been acquired", port_num); @@ -76,15 +80,41 @@ esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_ return ret; } -bool i2c_bus_occupied(i2c_port_num_t port_num) +static bool i2c_bus_occupied(i2c_port_num_t port_num) +{ + return s_i2c_platform.buses[port_num] != NULL; +} + +esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_new_bus, i2c_bus_mode_t mode) { bool bus_occupied = false; + bool bus_found = false; + esp_err_t ret = ESP_OK; _lock_acquire(&s_i2c_platform.mutex); - if (s_i2c_platform.buses[port_num]) { - bus_occupied = true; + if (port_num == -1) { + for (int i = 0; i < SOC_I2C_NUM; i++) { + bus_occupied = i2c_bus_occupied(i); + if (bus_occupied == false) { + ret = s_i2c_bus_handle_aquire(i, i2c_new_bus, mode); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "acquire bus failed"); + _lock_release(&s_i2c_platform.mutex); + return ret; + } + bus_found = true; + port_num = i; + break; + } + } + ESP_RETURN_ON_FALSE((bus_found == true), ESP_ERR_NOT_FOUND, TAG, "acquire bus failed, no free bus"); + } else { + ret = s_i2c_bus_handle_aquire(port_num, i2c_new_bus, mode); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "acquire bus failed"); + } } _lock_release(&s_i2c_platform.mutex); - return bus_occupied; + return ret; } esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus) @@ -105,7 +135,9 @@ esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus) ESP_RETURN_ON_ERROR(esp_pm_lock_delete(i2c_bus->pm_lock), TAG, "delete pm_lock failed"); } // Disable I2C module - periph_module_disable(i2c_periph_signal[port_num].module); + I2C_RCC_ATOMIC() { + i2c_ll_enable_bus_clock(port_num, false); + } free(i2c_bus); } } @@ -205,12 +237,8 @@ esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle) .pull_up_en = handle->pull_up_enable ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, .pin_bit_mask = 1ULL << handle->sda_num, }; -#if CONFIG_IDF_TARGET_ESP32 - // on esp32, must enable internal pull-up - sda_conf.pull_up_en = GPIO_PULLUP_ENABLE; -#endif - ESP_RETURN_ON_ERROR(gpio_config(&sda_conf), TAG, "config GPIO failed"); ESP_RETURN_ON_ERROR(gpio_set_level(handle->sda_num, 1), TAG, "i2c sda pin set level failed"); + ESP_RETURN_ON_ERROR(gpio_config(&sda_conf), TAG, "config GPIO failed"); gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[handle->sda_num], PIN_FUNC_GPIO); esp_rom_gpio_connect_out_signal(handle->sda_num, i2c_periph_signal[port_id].sda_out_sig, 0, 0); esp_rom_gpio_connect_in_signal(handle->sda_num, i2c_periph_signal[port_id].sda_in_sig, 0); @@ -224,12 +252,8 @@ esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle) .pull_up_en = handle->pull_up_enable ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, .pin_bit_mask = 1ULL << handle->scl_num, }; -#if CONFIG_IDF_TARGET_ESP32 - // on esp32, must enable internal pull-up - scl_conf.pull_up_en = GPIO_PULLUP_ENABLE; -#endif - ESP_RETURN_ON_ERROR(gpio_config(&scl_conf), TAG, "config GPIO failed"); ESP_RETURN_ON_ERROR(gpio_set_level(handle->scl_num, 1), TAG, "i2c scl pin set level failed"); + ESP_RETURN_ON_ERROR(gpio_config(&scl_conf), TAG, "config GPIO failed"); gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[handle->scl_num], PIN_FUNC_GPIO); esp_rom_gpio_connect_out_signal(handle->scl_num, i2c_periph_signal[port_id].scl_out_sig, 0, 0); esp_rom_gpio_connect_in_signal(handle->scl_num, i2c_periph_signal[port_id].scl_in_sig, 0); diff --git a/components/driver/i2c/i2c_master.c b/components/driver/i2c/i2c_master.c index 929c7b45d95..0ea9be27b60 100644 --- a/components/driver/i2c/i2c_master.c +++ b/components/driver/i2c/i2c_master.c @@ -35,7 +35,6 @@ #include "freertos/idf_additions.h" static const char *TAG = "i2c.master"; -static _lock_t s_i2c_bus_acquire; #define DIM(array) (sizeof(array)/sizeof(*array)) #define I2C_ADDRESS_TRANS_WRITE(device_address) (((device_address) << 1) | 0) @@ -487,7 +486,10 @@ static esp_err_t s_i2c_transaction_start(i2c_master_dev_handle_t i2c_dev, int xf i2c_master->rx_cnt = 0; i2c_master->read_len_static = 0; - i2c_hal_set_bus_timing(hal, i2c_dev->scl_speed_hz, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz); + I2C_CLOCK_SRC_ATOMIC() { + i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src); + i2c_hal_set_bus_timing(hal, i2c_dev->scl_speed_hz, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz); + } i2c_ll_master_set_fractional_divider(hal->dev, 0, 0); i2c_ll_update(hal->dev); @@ -785,39 +787,13 @@ esp_err_t i2c_new_master_bus(const i2c_master_bus_config_t *bus_config, i2c_mast ESP_RETURN_ON_FALSE(bus_config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE((bus_config->i2c_port < SOC_I2C_NUM || bus_config->i2c_port == -1), ESP_ERR_INVALID_ARG, TAG, "invalid i2c port number"); ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(bus_config->sda_io_num) && GPIO_IS_VALID_GPIO(bus_config->scl_io_num), ESP_ERR_INVALID_ARG, TAG, "invalid SDA/SCL pin number"); - bool bus_occupied = false; - bool bus_found = false; i2c_master = heap_caps_calloc(1, sizeof(i2c_master_bus_t) + 20 * sizeof(i2c_transaction_t), I2C_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(i2c_master, ESP_ERR_NO_MEM, TAG, "no memory for i2c master bus"); - _lock_acquire(&s_i2c_bus_acquire); - if (i2c_port_num == -1) { - for (int i = 0; i < SOC_I2C_NUM; i++) { - bus_occupied = i2c_bus_occupied(i); - if (bus_occupied == false) { - ret = i2c_acquire_bus_handle(i, &i2c_master->base, I2C_BUS_MODE_MASTER); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "acquire bus failed"); - _lock_release(&s_i2c_bus_acquire); - goto err; - } - bus_found = true; - i2c_port_num = i; - break; - } - } - ESP_GOTO_ON_FALSE((bus_found == true), ESP_ERR_NOT_FOUND, err, TAG, "acquire bus failed, no free bus"); - } else { - ret = i2c_acquire_bus_handle(i2c_port_num, &i2c_master->base, I2C_BUS_MODE_MASTER); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "acquire bus failed"); - _lock_release(&s_i2c_bus_acquire); - goto err; - } - } - _lock_release(&s_i2c_bus_acquire); + ESP_GOTO_ON_ERROR(i2c_acquire_bus_handle(i2c_port_num, &i2c_master->base, I2C_BUS_MODE_MASTER), err, TAG, "I2C bus acquire failed"); + i2c_port_num = i2c_master->base->port_num; i2c_hal_context_t *hal = &i2c_master->base->hal; i2c_master->base->scl_num = bus_config->scl_io_num; @@ -1071,7 +1047,10 @@ esp_err_t i2c_master_probe(i2c_master_bus_handle_t i2c_master, uint16_t address, // I2C probe does not have i2c device module. So set the clock parameter independently // This will not influence device transaction. - i2c_hal_set_bus_timing(hal, 100000, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz); + I2C_CLOCK_SRC_ATOMIC() { + i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src); + i2c_hal_set_bus_timing(hal, 100000, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz); + } i2c_ll_master_set_fractional_divider(hal->dev, 0, 0); i2c_ll_update(hal->dev); diff --git a/components/driver/i2c/i2c_private.h b/components/driver/i2c/i2c_private.h index bdf8e09a58d..546aae170a7 100644 --- a/components/driver/i2c/i2c_private.h +++ b/components/driver/i2c/i2c_private.h @@ -16,12 +16,26 @@ #include "freertos/semphr.h" #include "freertos/task.h" #include "freertos/ringbuf.h" +#include "driver/i2c_slave.h" +#include "esp_private/periph_ctrl.h" #include "esp_pm.h" #ifdef __cplusplus extern "C" { #endif +#if SOC_PERIPH_CLK_CTRL_SHARED +#define I2C_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2C_CLOCK_SRC_ATOMIC() +#endif + +#if !SOC_RCC_IS_INDEPENDENT +#define I2C_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2C_RCC_ATOMIC() +#endif + #if CONFIG_I2C_ISR_IRAM_SAFE #define I2C_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #else @@ -52,6 +66,7 @@ typedef struct i2c_bus_t i2c_bus_t; typedef struct i2c_master_bus_t i2c_master_bus_t; typedef struct i2c_bus_t *i2c_bus_handle_t; typedef struct i2c_master_dev_t i2c_master_dev_t; +typedef struct i2c_slave_dev_t i2c_slave_dev_t; typedef enum { I2C_BUS_MODE_MASTER = 0, @@ -153,6 +168,34 @@ struct i2c_master_dev_t { void *user_ctx; // Callback user context }; +typedef struct { + bool trans_complete; // Event of transaction complete + bool slave_stretch; // Event of slave stretch happens + bool addr_unmatch; // Event of address unmatched +} i2c_slave_evt_t; + +typedef struct { + uint8_t *buffer; // Pointer to the buffer need to be received in ISR + uint32_t rcv_fifo_cnt; // receive fifo count. +} i2c_slave_receive_t; + +struct i2c_slave_dev_t { + i2c_bus_t *base; // bus base class + SemaphoreHandle_t slv_rx_mux; // Mutex for slave rx direction + SemaphoreHandle_t slv_tx_mux; // Mutex for slave tx direction + RingbufHandle_t rx_ring_buf; // Handle for rx ringbuffer + RingbufHandle_t tx_ring_buf; // Handle for tx ringbuffer + uint8_t data_buf[SOC_I2C_FIFO_LEN]; // Data buffer for slave + uint32_t trans_data_length; // Send data length + i2c_slave_event_callbacks_t callbacks; // I2C slave callbacks + void *user_ctx; // Callback user context + i2c_slave_fifo_mode_t fifo_mode; // Slave fifo mode. + QueueHandle_t slv_evt_queue; // Event Queue used in slave nonfifo mode. + i2c_slave_evt_t slave_evt; // Slave event structure. + i2c_slave_receive_t receive_desc; // Slave receive descriptor + uint32_t already_receive_len; // Data length already received in ISR. +}; + /** * @brief Acquire I2C bus handle * @@ -198,14 +241,6 @@ esp_err_t i2c_select_periph_clock(i2c_bus_handle_t handle, i2c_clock_source_t cl */ esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle); -/** - * @brief Check whether I2C bus is occupied - * - * @param port_num I2C port number. - * @return true: occupied, otherwise, false. - */ -bool i2c_bus_occupied(i2c_port_num_t port_num); - #ifdef __cplusplus } #endif diff --git a/components/driver/i2c/i2c_slave.c b/components/driver/i2c/i2c_slave.c new file mode 100644 index 00000000000..41e6d2fa381 --- /dev/null +++ b/components/driver/i2c/i2c_slave.c @@ -0,0 +1,426 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_types.h" +#include "esp_intr_alloc.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/task.h" +#include "freertos/ringbuf.h" +#include "freertos/queue.h" +#include "hal/i2c_hal.h" +#include "soc/i2c_periph.h" +#include "esp_rom_gpio.h" +#include "driver/gpio.h" +#include "hal/gpio_ll.h" +#include "clk_ctrl_os.h" +#include "esp_private/esp_clk.h" +#include "driver/i2c_slave.h" +#include "i2c_private.h" +#include "esp_memory_utils.h" +#include "freertos/idf_additions.h" + +#if CONFIG_I2C_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_log.h" +#include "esp_check.h" + +#define I2C_SLAVE_TIMEOUT_DEFAULT (32000) /* I2C slave timeout value, APB clock cycle number */ +#define I2C_FIFO_EMPTY_THRESH_VAL_DEFAULT (SOC_I2C_FIFO_LEN/2) +#define I2C_FIFO_FULL_THRESH_VAL_DEFAULT (SOC_I2C_FIFO_LEN/2) + +static const char *TAG = "i2c.slave"; + +static esp_err_t i2c_slave_bus_destroy(i2c_slave_dev_handle_t i2c_slave); + +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE +static IRAM_ATTR void s_i2c_handle_clock_stretch(i2c_slave_dev_handle_t i2c_slave) +{ + i2c_hal_context_t *hal = &i2c_slave->base->hal; + if (i2c_slave->callbacks.on_stretch_occur) { + i2c_slave_stretch_event_data_t evt = { 0 }; + i2c_hal_context_t *hal = &i2c_slave->base->hal; + i2c_ll_slave_get_stretch_cause(hal->dev, &evt.stretch_cause); + i2c_slave->callbacks.on_stretch_occur(i2c_slave, &evt, i2c_slave->user_ctx); + } + i2c_ll_slave_clear_stretch(hal->dev); +} +#endif + +static IRAM_ATTR void s_i2c_handle_rx_fifo_wm(i2c_slave_dev_handle_t i2c_slave, i2c_slave_receive_t *t) +{ + i2c_hal_context_t *hal = &i2c_slave->base->hal; + uint32_t rx_fifo_cnt; + i2c_ll_get_rxfifo_cnt(hal->dev, &rx_fifo_cnt); + i2c_ll_read_rxfifo(hal->dev, i2c_slave->data_buf, rx_fifo_cnt); + memcpy(t->buffer + i2c_slave->already_receive_len, i2c_slave->data_buf, rx_fifo_cnt); + i2c_slave->already_receive_len += rx_fifo_cnt; + t->rcv_fifo_cnt -= rx_fifo_cnt; +} + +static IRAM_ATTR void s_i2c_handle_complete(i2c_slave_dev_handle_t i2c_slave, i2c_slave_receive_t *t, BaseType_t *do_yield) +{ + i2c_hal_context_t *hal = &i2c_slave->base->hal; + uint32_t rx_fifo_cnt; + i2c_ll_get_rxfifo_cnt(hal->dev, &rx_fifo_cnt); + if (rx_fifo_cnt != 0) { + i2c_ll_read_rxfifo(hal->dev, i2c_slave->data_buf, t->rcv_fifo_cnt); + memcpy(t->buffer + i2c_slave->already_receive_len, i2c_slave->data_buf, t->rcv_fifo_cnt); + i2c_slave->already_receive_len += t->rcv_fifo_cnt; + t->rcv_fifo_cnt -= t->rcv_fifo_cnt; + } + if (i2c_slave->callbacks.on_recv_done) { + + i2c_slave_rx_done_event_data_t edata = { + .buffer = t->buffer, + }; + i2c_slave->callbacks.on_recv_done(i2c_slave, &edata, i2c_slave->user_ctx); + xSemaphoreGiveFromISR(i2c_slave->slv_rx_mux, do_yield); + i2c_ll_disable_intr_mask(hal->dev, I2C_LL_SLAVE_RX_EVENT_INTR); + } +} + +static IRAM_ATTR void s_i2c_handle_tx_fifo_wm(i2c_slave_dev_handle_t i2c_slave, BaseType_t *do_yield) +{ + i2c_hal_context_t *hal = &i2c_slave->base->hal; + uint32_t tx_fifo_rem; + i2c_ll_get_txfifo_len(hal->dev, &tx_fifo_rem); + size_t size = 0; + uint8_t *data = (uint8_t *) xRingbufferReceiveUpToFromISR(i2c_slave->tx_ring_buf, &size, tx_fifo_rem); + if (data) { + i2c_ll_write_txfifo(hal->dev, data, size); + vRingbufferReturnItemFromISR(i2c_slave->tx_ring_buf, data, do_yield); + } + if (size <= i2c_slave->trans_data_length) { + portENTER_CRITICAL_ISR(&i2c_slave->base->spinlock); + i2c_slave->trans_data_length -= size; + portEXIT_CRITICAL_ISR(&i2c_slave->base->spinlock); + if (i2c_slave->trans_data_length == 0) { + i2c_ll_slave_disable_tx_it(hal->dev); + } + } else { + ESP_DRAM_LOGE(TAG, "I2C TX BUFFER SIZE ERROR"); + } +} + +static IRAM_ATTR void s_slave_fifo_isr_handler(uint32_t int_mask, void *arg, BaseType_t *do_yield) +{ + i2c_slave_dev_handle_t i2c_slave = (i2c_slave_dev_handle_t) arg; +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + if (int_mask & I2C_INTR_STRETCH) { + s_i2c_handle_clock_stretch(i2c_slave); + } +#endif + i2c_slave_receive_t *t = &i2c_slave->receive_desc; + if (int_mask & I2C_INTR_SLV_RXFIFO_WM) { + s_i2c_handle_rx_fifo_wm(i2c_slave, t); + } + if (int_mask & I2C_INTR_SLV_COMPLETE) { + s_i2c_handle_complete(i2c_slave, t, do_yield); + } + if (int_mask & I2C_INTR_SLV_TXFIFO_WM) { + s_i2c_handle_tx_fifo_wm(i2c_slave, do_yield); + } +} + +static IRAM_ATTR void s_slave_nonfifo_isr_handler(uint32_t int_mask, void *arg, BaseType_t *do_yield) +{ + i2c_slave_dev_handle_t i2c_slave = (i2c_slave_dev_handle_t) arg; + i2c_hal_context_t *hal = &i2c_slave->base->hal; + if (int_mask & I2C_INTR_STRETCH) { + i2c_slave->slave_evt.slave_stretch = 1; + i2c_ll_slave_clear_stretch(hal->dev); + } + + if (int_mask & I2C_INTR_SLV_COMPLETE) { + i2c_slave->slave_evt.trans_complete = 1; + } + xQueueSendFromISR(i2c_slave->slv_evt_queue, &i2c_slave->slave_evt, do_yield); +} + +static IRAM_ATTR void s_slave_isr_handle_default(void *arg) +{ + i2c_slave_dev_handle_t i2c_slave = (i2c_slave_dev_handle_t) arg; + i2c_hal_context_t *hal = &i2c_slave->base->hal; + portBASE_TYPE HPTaskAwoken = pdFALSE; + uint32_t int_mask = 0; + + i2c_ll_get_intr_mask(hal->dev, &int_mask); + i2c_ll_clear_intr_mask(hal->dev, int_mask); + if (int_mask == 0) { + return; + } +#if SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + if (int_mask & I2C_INTR_UNMATCH) { + i2c_slave->slave_evt.addr_unmatch = 1; + ESP_DRAM_LOGE(TAG, "I2C address not match, trans failed"); + } +#endif + + if (i2c_slave->fifo_mode == I2C_SLAVE_NONFIFO) { + s_slave_nonfifo_isr_handler(int_mask, i2c_slave, &HPTaskAwoken); + } else { + s_slave_fifo_isr_handler(int_mask, i2c_slave, &HPTaskAwoken); + } + + //We only need to check here if there is a high-priority task needs to be switched. + if (HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR(); + } + +} + +esp_err_t i2c_new_slave_device(const i2c_slave_config_t *slave_config, i2c_slave_dev_handle_t *ret_handle) +{ +#if CONFIG_I2C_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif + esp_err_t ret = ESP_OK; + i2c_slave_dev_t *i2c_slave = NULL; + ESP_RETURN_ON_FALSE(slave_config && ret_handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(slave_config->sda_io_num) && GPIO_IS_VALID_GPIO(slave_config->scl_io_num), ESP_ERR_INVALID_ARG, TAG, "invalid SDA/SCL pin number"); + ESP_RETURN_ON_FALSE(slave_config->i2c_port < SOC_I2C_NUM || slave_config->i2c_port == -1, ESP_ERR_INVALID_ARG, TAG, "invalid i2c port number"); + ESP_RETURN_ON_FALSE((slave_config->send_buf_depth > 0), ESP_ERR_INVALID_ARG, TAG, "invalid SCL speed"); +#if SOC_I2C_SLAVE_SUPPORT_BROADCAST + ESP_GOTO_ON_FALSE(((slave_config->addr_bit_len != I2C_ADDR_BIT_LEN_10) || (!slave_config->flags.broadcast_en)), ESP_ERR_INVALID_STATE, err, TAG, "10bits address cannot used together with broadcast"); +#endif + + int i2c_port_num = slave_config->i2c_port; + i2c_slave = heap_caps_calloc(1, sizeof(i2c_slave_dev_t), I2C_MEM_ALLOC_CAPS); + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_NO_MEM, TAG, "no memory for i2c slave bus"); + + ESP_GOTO_ON_ERROR(i2c_acquire_bus_handle(i2c_port_num, &i2c_slave->base, I2C_BUS_MODE_SLAVE), err, TAG, "I2C bus acquire failed"); + + i2c_hal_context_t *hal = &i2c_slave->base->hal; + i2c_slave->base->scl_num = slave_config->scl_io_num; + i2c_slave->base->sda_num = slave_config->sda_io_num; +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + i2c_slave->fifo_mode = (slave_config->flags.access_ram_en == true) ? I2C_SLAVE_NONFIFO : I2C_SLAVE_FIFO; +#endif + +#if SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + if (slave_config->flags.slave_unmatch_en) { + i2c_ll_enable_intr_mask(hal->dev, I2C_SLAVE_ADDR_UNMATCH_INT_ENA_M); + } +#endif + + ESP_GOTO_ON_ERROR(i2c_common_set_pins(i2c_slave->base), err, TAG, "i2c slave set pins failed"); + + i2c_slave->tx_ring_buf = xRingbufferCreateWithCaps(slave_config->send_buf_depth, RINGBUF_TYPE_BYTEBUF, I2C_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(i2c_slave->tx_ring_buf != NULL, ESP_ERR_INVALID_STATE, err, TAG, "ringbuffer create failed"); + + i2c_slave->slv_rx_mux = xSemaphoreCreateBinaryWithCaps(I2C_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(i2c_slave->slv_rx_mux, ESP_ERR_NO_MEM, err, TAG, "No memory for binary semaphore"); + i2c_slave->slv_tx_mux = xSemaphoreCreateBinaryWithCaps(I2C_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(i2c_slave->slv_tx_mux, ESP_ERR_NO_MEM, err, TAG, "No memory for binary semaphore"); + i2c_slave->slv_evt_queue = xQueueCreateWithCaps(1, sizeof(i2c_slave_evt_t), I2C_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE((i2c_slave->slv_evt_queue != NULL), ESP_ERR_INVALID_STATE, err, TAG, "queue create failed"); + + int isr_flags = I2C_INTR_ALLOC_FLAG; + if (slave_config->intr_priority) { + isr_flags |= 1 << (slave_config->intr_priority); + } + ret = esp_intr_alloc_intrstatus(i2c_periph_signal[i2c_port_num].irq, I2C_INTR_ALLOC_FLAG, (uint32_t)i2c_ll_get_interrupt_status_reg(hal->dev), I2C_LL_SLAVE_EVENT_INTR, s_slave_isr_handle_default, i2c_slave, &i2c_slave->base->intr_handle); + ESP_GOTO_ON_ERROR(ret, err, TAG, "install i2c slave interrupt failed"); + + portENTER_CRITICAL(&i2c_slave->base->spinlock); + i2c_ll_clear_intr_mask(hal->dev, I2C_LL_SLAVE_EVENT_INTR); + i2c_hal_slave_init(hal); + +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + if (i2c_slave->fifo_mode == I2C_SLAVE_NONFIFO) { + i2c_ll_slave_set_fifo_mode(hal->dev, false); + i2c_ll_enable_mem_access_nonfifo(hal->dev, true); + } else { + i2c_ll_slave_set_fifo_mode(hal->dev, true); + i2c_ll_enable_mem_access_nonfifo(hal->dev, false); + } +#endif + + //Default, we enable hardware filter + I2C_CLOCK_SRC_ATOMIC() { + i2c_ll_set_source_clk(hal->dev, slave_config->clk_source); + } + bool addr_10bit_en = slave_config->addr_bit_len != I2C_ADDR_BIT_LEN_7; + i2c_ll_set_slave_addr(hal->dev, slave_config->slave_addr, addr_10bit_en); +#if SOC_I2C_SLAVE_SUPPORT_BROADCAST + i2c_ll_slave_broadcast_enable(hal->dev, slave_config->flags.broadcast_en); +#endif + i2c_ll_set_txfifo_empty_thr(hal->dev, I2C_FIFO_EMPTY_THRESH_VAL_DEFAULT); + i2c_ll_set_rxfifo_full_thr(hal->dev, I2C_FIFO_FULL_THRESH_VAL_DEFAULT); + // set timing for data + i2c_ll_set_sda_timing(hal->dev, 10, 10); + i2c_ll_set_tout(hal->dev, I2C_SLAVE_TIMEOUT_DEFAULT); + +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + i2c_ll_slave_enable_scl_stretch(hal->dev, slave_config->flags.stretch_en); +#endif + i2c_ll_slave_tx_auto_start_en(hal->dev, true); + + i2c_ll_update(hal->dev); + portEXIT_CRITICAL(&i2c_slave->base->spinlock); + + xSemaphoreGive(i2c_slave->slv_rx_mux); + xSemaphoreGive(i2c_slave->slv_tx_mux); + *ret_handle = i2c_slave; + return ESP_OK; + +err: + if (i2c_slave) { + i2c_slave_bus_destroy(i2c_slave); + } + return ret; +} + +static esp_err_t i2c_slave_bus_destroy(i2c_slave_dev_handle_t i2c_slave) +{ + if (i2c_slave) { + if (i2c_slave->slv_rx_mux) { + vSemaphoreDeleteWithCaps(i2c_slave->slv_rx_mux); + i2c_slave->slv_rx_mux = NULL; + } + if (i2c_slave->slv_tx_mux) { + vSemaphoreDeleteWithCaps(i2c_slave->slv_tx_mux); + i2c_slave->slv_tx_mux = NULL; + } + if (i2c_slave->tx_ring_buf) { + vRingbufferDeleteWithCaps(i2c_slave->tx_ring_buf); + i2c_slave->tx_ring_buf = NULL; + } + if (i2c_slave->slv_evt_queue) { + vQueueDeleteWithCaps(i2c_slave->slv_evt_queue); + } + i2c_release_bus_handle(i2c_slave->base); + } + + free(i2c_slave); + return ESP_OK; +} + +esp_err_t i2c_del_slave_device(i2c_slave_dev_handle_t i2c_slave) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + int port_id = i2c_slave->base->port_num; + ESP_LOGD(TAG, "del i2c bus(%d)", port_id); + ESP_RETURN_ON_ERROR(i2c_slave_bus_destroy(i2c_slave), TAG, "destroy i2c bus failed"); + return ESP_OK; +} + +esp_err_t i2c_slave_transmit(i2c_slave_dev_handle_t i2c_slave, const uint8_t *data, int size, int xfer_timeout_ms) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "invalid data buffer"); + ESP_RETURN_ON_FALSE((i2c_slave->fifo_mode == I2C_SLAVE_FIFO), ESP_ERR_NOT_SUPPORTED, TAG, "non-fifo mode is not suppored in this API, please set access_ram_en to false"); + esp_err_t ret = ESP_OK; + i2c_hal_context_t *hal = &i2c_slave->base->hal; + TickType_t wait_ticks = (xfer_timeout_ms == -1) ? portMAX_DELAY : pdMS_TO_TICKS(xfer_timeout_ms); + + ESP_RETURN_ON_FALSE(xSemaphoreTake(i2c_slave->slv_tx_mux, wait_ticks) == pdTRUE, ESP_ERR_TIMEOUT, TAG, "transmit timeout"); + ESP_GOTO_ON_FALSE(xRingbufferSend(i2c_slave->tx_ring_buf, data, size, wait_ticks) == pdTRUE, ESP_ERR_INVALID_STATE, err, TAG, "no space in ringbuffer"); + portENTER_CRITICAL(&i2c_slave->base->spinlock); + i2c_slave->trans_data_length += size; + i2c_ll_enable_intr_mask(hal->dev, I2C_LL_SLAVE_TX_EVENT_INTR); + portEXIT_CRITICAL(&i2c_slave->base->spinlock); +err: + xSemaphoreGive(i2c_slave->slv_tx_mux); + return ret; +} + +esp_err_t i2c_slave_receive(i2c_slave_dev_handle_t i2c_slave, uint8_t *data, size_t receive_size) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "invalid data buffer"); + ESP_RETURN_ON_FALSE((i2c_slave->fifo_mode == I2C_SLAVE_FIFO), ESP_ERR_NOT_SUPPORTED, TAG, "non-fifo mode is not suppored in this API, please set access_ram_en to false"); +#if CONFIG_I2C_ISR_IRAM_SAFE + ESP_RETURN_ON_FALSE(esp_ptr_internal(data), ESP_ERR_INVALID_ARG, TAG, "buffer must locate in internal RAM if IRAM_SAFE is enabled"); +#endif + i2c_hal_context_t *hal = &i2c_slave->base->hal; + + xSemaphoreTake(i2c_slave->slv_rx_mux, portMAX_DELAY); + i2c_slave_receive_t *t = &i2c_slave->receive_desc; + t->buffer = data; + t->rcv_fifo_cnt = receive_size; + i2c_slave->already_receive_len = 0; + // Clear all interrupt raw bits before enable, avoid previous bus data affects interrupt. + i2c_ll_clear_intr_mask(hal->dev, I2C_LL_SLAVE_RX_EVENT_INTR); + i2c_ll_enable_intr_mask(hal->dev, I2C_LL_SLAVE_RX_EVENT_INTR); + + return ESP_OK; +} + +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + +esp_err_t i2c_slave_read_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_offset, uint8_t *data, size_t receive_size) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "invalid data buffer"); + ESP_RETURN_ON_FALSE((ram_offset + receive_size <= SOC_I2C_FIFO_LEN), ESP_ERR_INVALID_SIZE, TAG, "don't read data cross fifo boundary, see `SOC_I2C_FIFO_LEN`"); + ESP_RETURN_ON_FALSE((i2c_slave->fifo_mode == I2C_SLAVE_NONFIFO), ESP_ERR_NOT_SUPPORTED, TAG, "fifo mode is not suppored in this API, please set access_ram_en to true"); + i2c_hal_context_t *hal = &i2c_slave->base->hal; + + uint32_t fifo_size = 0; + portENTER_CRITICAL(&i2c_slave->base->spinlock); + i2c_ll_get_rxfifo_cnt(hal->dev, &fifo_size); + if (receive_size > fifo_size) { + ESP_LOGE(TAG, "receive size is so large that fifo has not so much data to get"); + portEXIT_CRITICAL(&i2c_slave->base->spinlock); + return ESP_ERR_INVALID_SIZE; + } + i2c_ll_read_by_nonfifo(hal->dev, ram_offset, data, fifo_size); + portEXIT_CRITICAL(&i2c_slave->base->spinlock); + + return ESP_OK; +} + +esp_err_t i2c_slave_write_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_offset, const uint8_t *data, size_t size) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "invalid data buffer"); + ESP_RETURN_ON_FALSE((i2c_slave->fifo_mode == I2C_SLAVE_NONFIFO), ESP_ERR_NOT_SUPPORTED, TAG, "fifo mode is not suppored in this API, please set access_ram_en to true"); + + i2c_hal_context_t *hal = &i2c_slave->base->hal; + ESP_RETURN_ON_FALSE(xSemaphoreTake(i2c_slave->slv_tx_mux, portMAX_DELAY) == pdTRUE, ESP_ERR_TIMEOUT, TAG, "write to ram lock timeout"); + uint32_t fifo_size = 0; + i2c_ll_txfifo_rst(hal->dev); + i2c_ll_get_txfifo_len(hal->dev, &fifo_size); + if (ram_offset + fifo_size < size) { + ESP_EARLY_LOGE(TAG, "No extra fifo to fill your buffer, please split your buffer"); + return ESP_ERR_INVALID_SIZE; + } + i2c_ll_write_by_nonfifo(hal->dev, ram_offset, data, size); + xSemaphoreGive(i2c_slave->slv_tx_mux); + return ESP_OK; +} + +#endif + +esp_err_t i2c_slave_register_event_callbacks(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_event_callbacks_t *cbs, void *user_data) +{ + ESP_RETURN_ON_FALSE(i2c_slave != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c slave handle not initialized"); + ESP_RETURN_ON_FALSE(cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + +#if CONFIG_I2C_ISR_IRAM_SAFE +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + if (cbs->on_stretch_occur) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_stretch_occur), ESP_ERR_INVALID_ARG, TAG, "i2c stretch occur callback not in IRAM"); + } +#endif // SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + if (cbs->on_recv_done) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_recv_done), ESP_ERR_INVALID_ARG, TAG, "i2c receive done 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 // CONFIG_I2C_ISR_IRAM_SAFE + + memcpy(&(i2c_slave->callbacks), cbs, sizeof(i2c_slave_event_callbacks_t)); + i2c_slave->user_ctx = user_data; + return ESP_OK; +} diff --git a/components/driver/i2c/include/driver/i2c_master.h b/components/driver/i2c/include/driver/i2c_master.h index 48471ddd67c..94f3f788344 100644 --- a/components/driver/i2c/include/driver/i2c_master.h +++ b/components/driver/i2c/include/driver/i2c_master.h @@ -109,7 +109,7 @@ esp_err_t i2c_master_bus_rm_device(i2c_master_dev_handle_t handle); * @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever. * @return * - ESP_OK: I2C master transmit success - * - ESP_ERR_INVALID_ARG: I2c master transmit parameter invalid. + * - ESP_ERR_INVALID_ARG: I2C master transmit parameter invalid. * - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the bus is busy or hardware crash. */ esp_err_t i2c_master_transmit(i2c_master_dev_handle_t i2c_dev, const uint8_t *write_buffer, size_t write_size, int xfer_timeout_ms); @@ -130,7 +130,7 @@ esp_err_t i2c_master_transmit(i2c_master_dev_handle_t i2c_dev, const uint8_t *wr * @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever. * @return * - ESP_OK: I2C master transmit-receive success - * - ESP_ERR_INVALID_ARG: I2c master transmit parameter invalid. + * - ESP_ERR_INVALID_ARG: I2C master transmit parameter invalid. * - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the bus is busy or hardware crash. */ esp_err_t i2c_master_transmit_receive(i2c_master_dev_handle_t i2c_dev, const uint8_t *write_buffer, size_t write_size, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms); @@ -149,7 +149,7 @@ esp_err_t i2c_master_transmit_receive(i2c_master_dev_handle_t i2c_dev, const uin * @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever. * @return * - ESP_OK: I2C master receive success - * - ESP_ERR_INVALID_ARG: I2c master receive parameter invalid. + * - ESP_ERR_INVALID_ARG: I2C master receive parameter invalid. * - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the bus is busy or hardware crash. */ esp_err_t i2c_master_receive(i2c_master_dev_handle_t i2c_dev, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms); diff --git a/components/driver/i2c/include/driver/i2c_slave.h b/components/driver/i2c/include/driver/i2c_slave.h new file mode 100644 index 00000000000..70ba813ce69 --- /dev/null +++ b/components/driver/i2c/include/driver/i2c_slave.h @@ -0,0 +1,166 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "driver/i2c_types.h" +#include "hal/gpio_types.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief I2C slave specific configurations + */ +typedef struct { + i2c_port_num_t i2c_port; /*!< I2C port number, `-1` for auto selecting */ + gpio_num_t sda_io_num; /*!< SDA IO number used by I2C bus */ + gpio_num_t scl_io_num; /*!< SCL IO number used by I2C bus */ + i2c_clock_source_t clk_source; /*!< Clock source of I2C bus. */ + uint32_t send_buf_depth; /*!< Depth of internal transfer ringbuffer, increase this value can support more transfers pending in the background */ + uint16_t slave_addr; /*!< I2C slave address */ + i2c_addr_bit_len_t addr_bit_len; /*!< I2C slave address in bit length */ + int intr_priority; /*!< I2C interrupt priority, if set to 0, driver will select the default priority (1,2,3). */ + struct { +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + uint32_t stretch_en:1; /*!< Enable slave stretch */ +#endif +#if SOC_I2C_SLAVE_SUPPORT_BROADCAST + uint32_t broadcast_en:1; /*!< I2C slave enable broadcast */ +#endif +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + uint32_t access_ram_en:1; /*!< Can get access to I2C RAM directly */ +#endif +#if SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + uint32_t slave_unmatch_en:1; /*!< Can trigger unmatch interrupt when slave address does not match what master sends*/ +#endif + } flags; +} i2c_slave_config_t; + +/** + * @brief Group of I2C slave callbacks (e.g. get i2c slave stretch cause). But take care of potential concurrency issues. + * @note The callbacks are all running under ISR context + * @note When CONFIG_I2C_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. + */ +typedef struct { +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + i2c_slave_stretch_callback_t on_stretch_occur; /*!< I2C slave stretched callback */ +#endif + i2c_slave_received_callback_t on_recv_done; /*!< I2C slave receive done callback */ +} i2c_slave_event_callbacks_t; + +/** + * @brief Initialize an I2C slave device + * + * @param[in] slave_config I2C slave device configurations + * @param[out] ret_handle Return a generic I2C device handle + * @return + * - ESP_OK: I2C slave device initialized successfully + * - ESP_ERR_INVALID_ARG: I2C device initialization failed because of invalid argument. + * - ESP_ERR_NO_MEM: Create I2C device failed because of out of memory. + */ +esp_err_t i2c_new_slave_device(const i2c_slave_config_t *slave_config, i2c_slave_dev_handle_t *ret_handle); + +/** + * @brief Deinitialize the I2C slave device + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @return + * - ESP_OK: Delete I2C device successfully. + * - ESP_ERR_INVALID_ARG: I2C device initialization failed because of invalid argument. + */ +esp_err_t i2c_del_slave_device(i2c_slave_dev_handle_t i2c_slave); + +/** + * @brief Read bytes from I2C internal buffer. Start a job to receive I2C data. + * + * @note This function is non-blocking, it initiates a new receive job and then returns. + * User should check the received data from the `on_recv_done` callback that registered by `i2c_slave_register_event_callbacks()`. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[out] data Buffer to store data from I2C fifo. Should be valid until `on_recv_done` is triggered. + * @param[in] buffer_size Buffer size of data that provided by users. + * @return + * - ESP_OK: I2C slave receive success. + * - ESP_ERR_INVALID_ARG: I2C slave receive parameter invalid. + * - ESP_ERR_NOT_SUPPORTED: This function should be work in fifo mode, but I2C_SLAVE_NONFIFO mode is configured + */ +esp_err_t i2c_slave_receive(i2c_slave_dev_handle_t i2c_slave, uint8_t *data, size_t buffer_size); + +/** + * @brief Write bytes to internal ringbuffer of the I2C slave data. When the TX fifo empty, the ISR will + * fill the hardware FIFO with the internal ringbuffer's data. + * + * @note If you connect this slave device to some master device, the data transaction direction is from slave + * device to master device. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[in] data Buffer to write to slave fifo, can pickup by master. Can be freed after this function returns. Equal or larger than `size`. + * @param[in] size In bytes, of `data` buffer. + * @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever. + * @return + * - ESP_OK: I2C slave transmit success. + * - ESP_ERR_INVALID_ARG: I2C slave transmit parameter invalid. + * - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the device is busy or hardware crash. + * - ESP_ERR_NOT_SUPPORTED: This function should be work in fifo mode, but I2C_SLAVE_NONFIFO mode is configured + */ +esp_err_t i2c_slave_transmit(i2c_slave_dev_handle_t i2c_slave, const uint8_t *data, int size, int xfer_timeout_ms); + +/** + * @brief Set I2C slave event callbacks for I2C slave channel. + * + * @note User can deregister a previously registered callback by calling this function and setting the callback member in the `cbs` structure to NULL. + * @note When CONFIG_I2C_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. The `user_data` should also reside in SRAM. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[in] cbs Group of callback functions + * @param[in] user_data User data, which will be passed to callback functions directly + * @return + * - ESP_OK: Set I2C transaction callbacks successfully + * - ESP_ERR_INVALID_ARG: Set I2C transaction callbacks failed because of invalid argument + * - ESP_FAIL: Set I2C transaction callbacks failed because of other error + */ +esp_err_t i2c_slave_register_event_callbacks(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_event_callbacks_t *cbs, void *user_data); + +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS +/** + * @brief Read bytes from I2C internal ram. This can be only used when `access_ram_en` in configuration structure set to true. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[in] ram_address The offset of RAM (Cannot larger than I2C RAM memory) + * @param[out] data Buffer to store data read from I2C ram. + * @param[in] receive_size Received size from RAM. + * @return + * - ESP_OK: I2C slave transmit success. + * - ESP_ERR_INVALID_ARG: I2C slave transmit parameter invalid. + * - ESP_ERR_NOT_SUPPORTED: This function should be work in non-fifo mode, but I2C_SLAVE_FIFO mode is configured + */ +esp_err_t i2c_slave_read_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_address, uint8_t *data, size_t receive_size); + +/** + * @brief Write bytes to I2C internal ram. This can be only used when `access_ram_en` in configuration structure set to true. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[in] ram_address The offset of RAM (Cannot larger than I2C RAM memory) + * @param[in] data Buffer to fill. + * @param[in] size Received size from RAM. + * @return + * - ESP_OK: I2C slave transmit success. + * - ESP_ERR_INVALID_ARG: I2C slave transmit parameter invalid. + * - ESP_ERR_INVALID_SIZE: Write size is larger than + * - ESP_ERR_NOT_SUPPORTED: This function should be work in non-fifo mode, but I2C_SLAVE_FIFO mode is configured + */ +esp_err_t i2c_slave_write_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_address, const uint8_t *data, size_t size); + +#endif +#ifdef __cplusplus +} +#endif diff --git a/components/driver/i2c/include/driver/i2c_types.h b/components/driver/i2c/include/driver/i2c_types.h index dd1683852b0..6e11cf8c2e1 100644 --- a/components/driver/i2c/include/driver/i2c_types.h +++ b/components/driver/i2c/include/driver/i2c_types.h @@ -51,6 +51,11 @@ typedef struct i2c_master_bus_t *i2c_master_bus_handle_t; */ typedef struct i2c_master_dev_t *i2c_master_dev_handle_t; +/** + * @brief Type of I2C slave device handle + */ +typedef struct i2c_slave_dev_t *i2c_slave_dev_handle_t; + /** * @brief Data type used in I2C event callback */ @@ -69,6 +74,46 @@ typedef struct { */ typedef bool (*i2c_master_callback_t)(i2c_master_dev_handle_t i2c_dev, const i2c_master_event_data_t *evt_data, void *arg); +/** + * @brief Event structure used in I2C slave + */ +typedef struct { + uint8_t *buffer; +} i2c_slave_rx_done_event_data_t; + +/** + * @brief Callback signature for I2C slave. + * + * @param[in] i2c_slave Handle for I2C slave. + * @param[out] evt_data I2C capture event data, fed by driver + * @param[in] user_ctx User data, set in `i2c_slave_register_event_callbacks()` + * + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*i2c_slave_received_callback_t)(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg); + +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + +/** + * @brief Stretch cause event structure used in I2C slave + */ +typedef struct { + i2c_slave_stretch_cause_t stretch_cause; +} i2c_slave_stretch_event_data_t; + +/** + * @brief Callback signature for I2C slave stretch. + * + * @param[in] i2c_slave Handle for I2C slave. + * @param[out] evt_cause I2C capture event cause, fed by driver + * @param[in] user_ctx User data, set in `i2c_slave_register_event_callbacks()` + * + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*i2c_slave_stretch_callback_t)(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_stretch_event_data_t *evt_cause, void *arg); + +#endif + #ifdef __cplusplus } #endif diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c index 3ec43562134..856cf43a1fc 100644 --- a/components/driver/i2s/i2s_pdm.c +++ b/components/driver/i2s/i2s_pdm.c @@ -103,10 +103,14 @@ static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_ /* Share bck and ws signal in full-duplex mode */ i2s_ll_share_bck_ws(handle->controller->hal.dev, handle->controller->full_duplex); + /* Update the mode info: slot configuration */ + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; + memcpy(&(pdm_tx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_tx_slot_config_t)); + portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply PDM format */ bool is_slave = handle->role == I2S_ROLE_SLAVE; - i2s_hal_slot_config_t *slot_hal_cfg = (i2s_hal_slot_config_t *)slot_cfg; + i2s_hal_slot_config_t *slot_hal_cfg = (i2s_hal_slot_config_t *)(&(pdm_tx_cfg->slot_cfg)); #if SOC_I2S_HW_VERSION_2 /* Times 10 to transform the float type to integer because we should avoid float type in hal */ slot_hal_cfg->pdm_tx.hp_cut_off_freq_hzx10 = (uint32_t)(slot_cfg->hp_cut_off_freq_hz * 10); @@ -114,10 +118,6 @@ static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_ i2s_hal_pdm_set_tx_slot(&(handle->controller->hal), is_slave, slot_hal_cfg); portEXIT_CRITICAL(&g_i2s.spinlock); - /* Update the mode info: slot configuration */ - i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; - memcpy(&(pdm_tx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_tx_slot_config_t)); - return ESP_OK; } @@ -389,16 +389,21 @@ static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_ /* Share bck and ws signal in full-duplex mode */ i2s_ll_share_bck_ws(handle->controller->hal.dev, handle->controller->full_duplex); + /* Update the mode info: slot configuration */ + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; + memcpy(&(pdm_rx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_rx_slot_config_t)); + portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply PDM format */ bool is_slave = (handle->role == I2S_ROLE_SLAVE) | handle->controller->full_duplex; - i2s_hal_pdm_set_rx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); + i2s_hal_slot_config_t *slot_hal_cfg = (i2s_hal_slot_config_t *)(&(pdm_rx_cfg->slot_cfg)); +#if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER + /* Times 10 to transform the float type to integer because we should avoid float type in hal */ + slot_hal_cfg->pdm_rx.hp_cut_off_freq_hzx10 = (uint32_t)(slot_cfg->hp_cut_off_freq_hz * 10); +#endif + i2s_hal_pdm_set_rx_slot(&(handle->controller->hal), is_slave, slot_hal_cfg); portEXIT_CRITICAL(&g_i2s.spinlock); - /* Update the mode info: slot configuration */ - i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; - memcpy(&(pdm_rx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_rx_slot_config_t)); - return ESP_OK; } diff --git a/components/driver/include/esp_private/spi_common_internal.h b/components/driver/include/esp_private/spi_common_internal.h index 4789182b73a..92f4a0e8992 100644 --- a/components/driver/include/esp_private/spi_common_internal.h +++ b/components/driver/include/esp_private/spi_common_internal.h @@ -13,6 +13,7 @@ #include "freertos/FreeRTOS.h" #include "hal/spi_types.h" #include "hal/dma_types.h" +#include "soc/gdma_channel.h" #include "esp_pm.h" #if SOC_GDMA_SUPPORTED #include "esp_private/gdma.h" @@ -46,19 +47,14 @@ extern "C" #define BUS_LOCK_DEBUG_EXECUTE_CHECK(x) #endif -#if !defined(SOC_GDMA_TRIG_PERIPH_SPI2_BUS) +#if SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB #define DMA_DESC_MEM_ALIGN_SIZE 4 +#define SPI_GDMA_NEW_CHANNEL gdma_new_ahb_channel typedef dma_descriptor_align4_t spi_dma_desc_t; #else -#if defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) #define DMA_DESC_MEM_ALIGN_SIZE 8 #define SPI_GDMA_NEW_CHANNEL gdma_new_axi_channel typedef dma_descriptor_align8_t spi_dma_desc_t; -#elif defined(SOC_GDMA_BUS_AHB) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) -#define DMA_DESC_MEM_ALIGN_SIZE 4 -#define SPI_GDMA_NEW_CHANNEL gdma_new_ahb_channel -typedef dma_descriptor_align4_t spi_dma_desc_t; -#endif #endif struct spi_bus_lock_t; diff --git a/components/driver/linker.lf b/components/driver/linker.lf index ae09bf19a9c..6c90eff1f4c 100644 --- a/components/driver/linker.lf +++ b/components/driver/linker.lf @@ -1,11 +1,6 @@ [mapping:driver] archive: libdriver.a entries: - if PCNT_CTRL_FUNC_IN_IRAM = y: - pulse_cnt: pcnt_unit_start (noflash) - pulse_cnt: pcnt_unit_stop (noflash) - pulse_cnt: pcnt_unit_clear_count (noflash) - pulse_cnt: pcnt_unit_get_count (noflash) if SDM_CTRL_FUNC_IN_IRAM = y: sdm: sdm_channel_set_pulse_density (noflash) if ANA_CMPR_CTRL_FUNC_IN_IRAM = y: diff --git a/components/driver/rmt/include/driver/rmt_tx.h b/components/driver/rmt/include/driver/rmt_tx.h index 80b08a02541..3cf273cfc4c 100644 --- a/components/driver/rmt/include/driver/rmt_tx.h +++ b/components/driver/rmt/include/driver/rmt_tx.h @@ -16,7 +16,6 @@ extern "C" { #endif - /** * @brief Group of RMT TX callbacks * @note The callbacks are all running under ISR environment @@ -38,14 +37,14 @@ typedef struct { In the DMA mode, this field controls the DMA buffer size, it can be set to a large value; In the normal mode, this field controls the number of RMT memory block that will be used by the channel. */ size_t trans_queue_depth; /*!< Depth of internal transfer queue, increase this value can support more transfers pending in the background */ + int intr_priority; /*!< RMT interrupt priority, + if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */ struct { uint32_t invert_out: 1; /*!< Whether to invert the RMT channel signal before output to GPIO pad */ uint32_t with_dma: 1; /*!< If set, the driver will allocate an RMT channel with DMA capability */ uint32_t io_loop_back: 1; /*!< The signal output from the GPIO will be fed to the input path as well */ uint32_t io_od_mode: 1; /*!< Configure the GPIO as open-drain mode */ } flags; /*!< TX channel config flags */ - int intr_priority; /*!< RMT interrupt priority, - if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */ } rmt_tx_channel_config_t; /** @@ -54,8 +53,9 @@ typedef struct { typedef struct { int loop_count; /*!< Specify the times of transmission in a loop, -1 means transmitting in an infinite loop */ struct { - uint32_t eot_level : 1; /*!< Set the output level for the "End Of Transmission" */ - } flags; /*!< Transmit config flags */ + uint32_t eot_level : 1; /*!< Set the output level for the "End Of Transmission" */ + uint32_t queue_nonblocking : 1; /*!< If set, when the transaction queue is full, driver will not block the thread but return directly */ + } flags; /*!< Transmit specific config flags */ } rmt_transmit_config_t; /** @@ -84,8 +84,11 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_ /** * @brief Transmit data by RMT TX channel * - * @note This function will construct a transaction descriptor and push to a queue. The transaction will not start immediately until it's dispatched in the ISR. - * If there're too many transactions pending in the queue, this function will block until the queue has free space. + * @note This function constructs a transaction descriptor then pushes to a queue. + * The transaction will not start immediately if there's another one under processing. + * Based on the setting of `rmt_transmit_config_t::queue_nonblocking`, + * if there're too many transactions pending in the queue, this function can block until it has free slot, + * otherwise just return quickly. * @note The data to be transmitted will be encoded into RMT symbols by the specific `encoder`. * * @param[in] tx_channel RMT TX channel that created by `rmt_new_tx_channel()` diff --git a/components/driver/rmt/rmt_common.c b/components/driver/rmt/rmt_common.c index 2176f771ea5..b280fa93fa7 100644 --- a/components/driver/rmt/rmt_common.c +++ b/components/driver/rmt/rmt_common.c @@ -205,7 +205,6 @@ esp_err_t rmt_apply_carrier(rmt_channel_handle_t channel, const rmt_carrier_conf esp_err_t rmt_del_channel(rmt_channel_handle_t channel) { ESP_RETURN_ON_FALSE(channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); gpio_reset_pin(channel->gpio_num); return channel->del(channel); } @@ -213,14 +212,12 @@ esp_err_t rmt_del_channel(rmt_channel_handle_t channel) esp_err_t rmt_enable(rmt_channel_handle_t channel) { ESP_RETURN_ON_FALSE(channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); return channel->enable(channel); } esp_err_t rmt_disable(rmt_channel_handle_t channel) { ESP_RETURN_ON_FALSE(channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not in enable state"); return channel->disable(channel); } diff --git a/components/driver/rmt/rmt_private.h b/components/driver/rmt/rmt_private.h index 5e05b192f84..ac1e4bbd22c 100644 --- a/components/driver/rmt/rmt_private.h +++ b/components/driver/rmt/rmt_private.h @@ -6,6 +6,7 @@ #pragma once +#include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -80,8 +81,12 @@ typedef enum { } rmt_channel_direction_t; typedef enum { + RMT_FSM_INIT_WAIT, RMT_FSM_INIT, + RMT_FSM_ENABLE_WAIT, RMT_FSM_ENABLE, + RMT_FSM_RUN_WAIT, + RMT_FSM_RUN, } rmt_fsm_t; enum { @@ -119,7 +124,7 @@ struct rmt_channel_t { portMUX_TYPE spinlock; // prevent channel resource accessing by user and interrupt concurrently uint32_t resolution_hz; // channel clock resolution intr_handle_t intr; // allocated interrupt handle for each channel - rmt_fsm_t fsm; // channel life cycle specific FSM + _Atomic rmt_fsm_t fsm; // channel life cycle specific FSM rmt_channel_direction_t direction; // channel direction rmt_symbol_word_t *hw_mem_base; // base address of RMT channel hardware memory rmt_symbol_word_t *dma_mem_base; // base address of RMT channel DMA buffer diff --git a/components/driver/rmt/rmt_rx.c b/components/driver/rmt/rmt_rx.c index 8176dfcc00e..742b23d2d9e 100644 --- a/components/driver/rmt/rmt_rx.c +++ b/components/driver/rmt/rmt_rx.c @@ -285,10 +285,10 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_ gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[config->gpio_num], PIN_FUNC_GPIO); // initialize other members of rx channel + portMUX_INITIALIZE(&rx_channel->base.spinlock); + atomic_init(&rx_channel->base.fsm, RMT_FSM_INIT); rx_channel->base.direction = RMT_CHANNEL_DIRECTION_RX; - rx_channel->base.fsm = RMT_FSM_INIT; rx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + RMT_RX_CHANNEL_OFFSET_IN_GROUP].symbols[0]; - rx_channel->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; // polymorphic methods rx_channel->base.del = rmt_del_rx_channel; rx_channel->base.set_carrier_action = rmt_rx_demodulate_carrier; @@ -310,6 +310,8 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_ static esp_err_t rmt_del_rx_channel(rmt_channel_handle_t channel) { + ESP_RETURN_ON_FALSE(atomic_load(&channel->fsm) == RMT_FSM_INIT, + ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); rmt_rx_channel_t *rx_chan = __containerof(channel, rmt_rx_channel_t, base); rmt_group_t *group = channel->group; int group_id = group->group_id; @@ -344,7 +346,6 @@ esp_err_t rmt_receive(rmt_channel_handle_t channel, void *buffer, size_t buffer_ { ESP_RETURN_ON_FALSE(channel && buffer && buffer_size && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(channel->direction == RMT_CHANNEL_DIRECTION_RX, ESP_ERR_INVALID_ARG, TAG, "invalid channel direction"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not in enable state"); rmt_rx_channel_t *rx_chan = __containerof(channel, rmt_rx_channel_t, base); if (channel->dma_chan) { @@ -369,6 +370,11 @@ esp_err_t rmt_receive(rmt_channel_handle_t channel, void *buffer, size_t buffer_ ESP_RETURN_ON_FALSE(filter_reg_value <= RMT_LL_MAX_FILTER_VALUE, ESP_ERR_INVALID_ARG, TAG, "signal_range_min_ns too big"); ESP_RETURN_ON_FALSE(idle_reg_value <= RMT_LL_MAX_IDLE_VALUE, ESP_ERR_INVALID_ARG, TAG, "signal_range_max_ns too big"); + // check if we're in a proper state to start the receiver + rmt_fsm_t expected_fsm = RMT_FSM_ENABLE; + ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT), + ESP_ERR_INVALID_STATE, TAG, "channel not in enable state"); + // fill in the transaction descriptor rmt_rx_trans_desc_t *t = &rx_chan->trans_desc; t->buffer = buffer; @@ -396,6 +402,11 @@ esp_err_t rmt_receive(rmt_channel_handle_t channel, void *buffer, size_t buffer_ // turn on RMT RX machine rmt_ll_rx_enable(hal->regs, channel_id, true); portEXIT_CRITICAL(&channel->spinlock); + + // saying we're in running state, this state will last until the receiving is done + // i.e., we will switch back to the enable state in the receive done interrupt handler + atomic_store(&channel->fsm, RMT_FSM_RUN); + return ESP_OK; } @@ -440,13 +451,18 @@ static esp_err_t rmt_rx_demodulate_carrier(rmt_channel_handle_t channel, const r static esp_err_t rmt_rx_enable(rmt_channel_handle_t channel) { + // can only enable the channel when it's in "init" state + rmt_fsm_t expected_fsm = RMT_FSM_INIT; + ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_ENABLE_WAIT), + ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); + rmt_group_t *group = channel->group; rmt_hal_context_t *hal = &group->hal; int channel_id = channel->channel_id; // acquire power manager lock if (channel->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(channel->pm_lock), TAG, "acquire pm_lock failed"); + esp_pm_lock_acquire(channel->pm_lock); } if (channel->dma_chan) { #if SOC_RMT_SUPPORT_DMA @@ -462,12 +478,26 @@ static esp_err_t rmt_rx_enable(rmt_channel_handle_t channel) rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_RX_MASK(channel_id), true); portEXIT_CRITICAL(&group->spinlock); } - channel->fsm = RMT_FSM_ENABLE; + + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + return ESP_OK; } static esp_err_t rmt_rx_disable(rmt_channel_handle_t channel) { + // can disable the channel when it's in `enable` or `run` state + bool valid_state = false; + rmt_fsm_t expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_INIT_WAIT)) { + valid_state = true; + } + expected_fsm = RMT_FSM_RUN; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_INIT_WAIT)) { + valid_state = true; + } + ESP_RETURN_ON_FALSE(valid_state, ESP_ERR_INVALID_STATE, TAG, "channel not in enable or run state"); + rmt_group_t *group = channel->group; rmt_hal_context_t *hal = &group->hal; int channel_id = channel->channel_id; @@ -493,9 +523,11 @@ static esp_err_t rmt_rx_disable(rmt_channel_handle_t channel) // release power manager lock if (channel->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_release(channel->pm_lock), TAG, "release pm_lock failed"); + esp_pm_lock_release(channel->pm_lock); } - channel->fsm = RMT_FSM_INIT; + + // now we can switch the state to init + atomic_store(&channel->fsm, RMT_FSM_INIT); return ESP_OK; } @@ -563,6 +595,8 @@ static bool IRAM_ATTR rmt_isr_handle_rx_done(rmt_rx_channel_t *rx_chan) need_yield = true; } } + // switch back to the enable state, then user can call `rmt_receive` to start a new receive + atomic_store(&channel->fsm, RMT_FSM_ENABLE); return need_yield; } @@ -674,6 +708,8 @@ static bool IRAM_ATTR rmt_dma_rx_eof_cb(gdma_channel_handle_t dma_chan, gdma_eve need_yield = true; } } + // switch back to the enable state, then user can call `rmt_receive` to start a new receive + atomic_store(&channel->fsm, RMT_FSM_ENABLE); return need_yield; } #endif // SOC_RMT_SUPPORT_DMA diff --git a/components/driver/rmt/rmt_tx.c b/components/driver/rmt/rmt_tx.c index f44eb9a0842..95188e8daa2 100644 --- a/components/driver/rmt/rmt_tx.c +++ b/components/driver/rmt/rmt_tx.c @@ -40,6 +40,7 @@ static esp_err_t rmt_tx_modulate_carrier(rmt_channel_handle_t channel, const rmt static esp_err_t rmt_tx_enable(rmt_channel_handle_t channel); static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel); static void rmt_tx_default_isr(void *args); +static void rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_trans_desc_t *t); #if SOC_RMT_SUPPORT_DMA static bool rmt_dma_tx_eof_cb(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data); @@ -310,10 +311,10 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_ config->flags.invert_out, false); gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[config->gpio_num], PIN_FUNC_GPIO); + portMUX_INITIALIZE(&tx_channel->base.spinlock); + atomic_init(&tx_channel->base.fsm, RMT_FSM_INIT); tx_channel->base.direction = RMT_CHANNEL_DIRECTION_TX; - tx_channel->base.fsm = RMT_FSM_INIT; tx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + RMT_TX_CHANNEL_OFFSET_IN_GROUP].symbols[0]; - tx_channel->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; // polymorphic methods tx_channel->base.del = rmt_del_tx_channel; tx_channel->base.set_carrier_action = rmt_tx_modulate_carrier; @@ -335,6 +336,8 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_ static esp_err_t rmt_del_tx_channel(rmt_channel_handle_t channel) { + ESP_RETURN_ON_FALSE(atomic_load(&channel->fsm) == RMT_FSM_INIT, + ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); rmt_group_t *group = channel->group; int group_id = group->group_id; @@ -373,7 +376,7 @@ esp_err_t rmt_new_sync_manager(const rmt_sync_manager_config_t *config, rmt_sync channel = config->tx_channel_array[i]; ESP_GOTO_ON_FALSE(channel->direction == RMT_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, err, TAG, "sync manager supports TX channel only"); ESP_GOTO_ON_FALSE(channel->group == group, ESP_ERR_INVALID_ARG, err, TAG, "channels to be managed should locate in the same group"); - ESP_GOTO_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, err, TAG, "channel should be started before creating sync manager"); + ESP_GOTO_ON_FALSE(atomic_load(&channel->fsm) == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, err, TAG, "channel not in enable state"); channel_mask |= 1 << channel->channel_id; } synchro->channel_mask = channel_mask; @@ -480,7 +483,6 @@ esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, con { ESP_RETURN_ON_FALSE(channel && encoder && payload && payload_bytes && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(channel->direction == RMT_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, TAG, "invalid channel direction"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not in enable state"); #if !SOC_RMT_SUPPORT_TX_LOOP_COUNT ESP_RETURN_ON_FALSE(config->loop_count <= 0, ESP_ERR_NOT_SUPPORTED, TAG, "loop count is not supported"); #endif // !SOC_RMT_SUPPORT_TX_LOOP_COUNT @@ -488,22 +490,20 @@ esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, con // payload is retrieved by the encoder, we should make sure it's still accessible even when the cache is disabled ESP_RETURN_ON_FALSE(esp_ptr_internal(payload), ESP_ERR_INVALID_ARG, TAG, "payload not in internal RAM"); #endif - rmt_group_t *group = channel->group; - rmt_hal_context_t *hal = &group->hal; - int channel_id = channel->channel_id; + TickType_t queue_wait_ticks = portMAX_DELAY; + if (config->flags.queue_nonblocking) { + queue_wait_ticks = 0; + } rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); rmt_tx_trans_desc_t *t = NULL; - // acquire one transaction description from ready_queue or done_queue - if (tx_chan->num_trans_inflight < tx_chan->queue_size) { - ESP_RETURN_ON_FALSE(xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, portMAX_DELAY) == pdTRUE, - ESP_FAIL, TAG, "no transaction in the ready queue"); - } else { - ESP_RETURN_ON_FALSE(xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, portMAX_DELAY) == pdTRUE, - ESP_FAIL, TAG, "recycle transaction from done queue failed"); - tx_chan->num_trans_inflight--; + // acquire one transaction description from ready queue or complete queue + if (xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, 0) != pdTRUE) { + if (xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, queue_wait_ticks) == pdTRUE) { + tx_chan->num_trans_inflight--; + } } - // sanity check - assert(t); + ESP_RETURN_ON_FALSE(t, ESP_ERR_INVALID_STATE, TAG, "no free transaction descriptor, please consider increasing trans_queue_depth"); + // fill in the transaction descriptor memset(t, 0, sizeof(rmt_tx_trans_desc_t)); t->encoder = encoder; @@ -514,7 +514,7 @@ esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, con t->flags.eot_level = config->flags.eot_level; // send the transaction descriptor to queue - if (xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, portMAX_DELAY) == pdTRUE) { + if (xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, 0) == pdTRUE) { tx_chan->num_trans_inflight++; } else { // put the trans descriptor back to ready_queue @@ -522,13 +522,18 @@ esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, con ESP_ERR_INVALID_STATE, TAG, "ready queue full"); } - // we don't know which "transmission complete" event will be triggered, but must be one of them: trans_done, loop_done - // when we run at here, the interrupt status bit for tx_done or loop_end should already up (ensured by `rmt_tx_enable()`) - // that's why we can go into ISR as soon as we enable the interrupt bit - // in the ISR, we will fetch the transactions from trans_queue and start it - portENTER_CRITICAL(&group->spinlock); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id) | RMT_LL_EVENT_TX_LOOP_END(channel_id), true); - portEXIT_CRITICAL(&group->spinlock); + // check if we need to start one pending transaction + rmt_fsm_t expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT)) { + // check if we need to start one transaction + if (xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, 0) == pdTRUE) { + atomic_store(&channel->fsm, RMT_FSM_RUN); + rmt_tx_do_transaction(tx_chan, t); + } else { + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + } + } + return ESP_OK; } @@ -625,6 +630,9 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr rmt_hal_context_t *hal = &group->hal; int channel_id = channel->channel_id; + // update current transaction + tx_chan->cur_trans = t; + #if SOC_RMT_SUPPORT_DMA if (channel->dma_chan) { gdma_reset(channel->dma_chan); @@ -638,7 +646,7 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr #endif // SOC_RMT_SUPPORT_DMA // set transaction specific parameters - portENTER_CRITICAL_ISR(&channel->spinlock); + portENTER_CRITICAL_SAFE(&channel->spinlock); rmt_ll_tx_reset_pointer(hal->regs, channel_id); // reset pointer for new transaction rmt_ll_tx_enable_loop(hal->regs, channel_id, t->loop_count != 0); #if SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP @@ -654,10 +662,10 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr t->remain_loop_count -= this_loop_count; } #endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT - portEXIT_CRITICAL_ISR(&channel->spinlock); + portEXIT_CRITICAL_SAFE(&channel->spinlock); // enable/disable specific interrupts - portENTER_CRITICAL_ISR(&group->spinlock); + portENTER_CRITICAL_SAFE(&group->spinlock); #if SOC_RMT_SUPPORT_TX_LOOP_COUNT rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), t->loop_count > 0); #endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT @@ -671,7 +679,7 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr } // don't generate trans done event for loop transmission rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), t->loop_count == 0); - portEXIT_CRITICAL_ISR(&group->spinlock); + portEXIT_CRITICAL_SAFE(&group->spinlock); // at the beginning of a new transaction, encoding memory offset should start from zero. // It will increase in the encode function e.g. `rmt_encode_copy()` @@ -691,39 +699,29 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr } #endif // turn on the TX machine - portENTER_CRITICAL_ISR(&channel->spinlock); + portENTER_CRITICAL_SAFE(&channel->spinlock); rmt_ll_tx_fix_idle_level(hal->regs, channel_id, t->flags.eot_level, true); rmt_ll_tx_start(hal->regs, channel_id); - portEXIT_CRITICAL_ISR(&channel->spinlock); + portEXIT_CRITICAL_SAFE(&channel->spinlock); } static esp_err_t rmt_tx_enable(rmt_channel_handle_t channel) { + // can enable the channel when it's in "init" state + rmt_fsm_t expected_fsm = RMT_FSM_INIT; + ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_ENABLE_WAIT), + ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); - rmt_group_t *group = channel->group; - rmt_hal_context_t *hal = &group->hal; - int channel_id = channel->channel_id; + // acquire power manager lock if (channel->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(channel->pm_lock), TAG, "acquire pm_lock failed"); + esp_pm_lock_acquire(channel->pm_lock); } - portENTER_CRITICAL(&channel->spinlock); - rmt_ll_tx_reset_pointer(hal->regs, channel_id); - rmt_ll_tx_enable_loop(hal->regs, channel_id, false); -#if SOC_RMT_SUPPORT_TX_LOOP_COUNT - rmt_ll_tx_reset_loop_count(hal->regs, channel_id); - rmt_ll_tx_enable_loop_count(hal->regs, channel_id, false); -#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT - // trigger a quick trans done event by sending a EOF symbol, no signal should appear on the GPIO - tx_chan->cur_trans = NULL; - channel->hw_mem_base[0].val = 0; - rmt_ll_tx_start(hal->regs, channel_id); - portEXIT_CRITICAL(&channel->spinlock); - - // wait the RMT interrupt line goes active, we won't go into the ISR handler until we enable the `RMT_LL_EVENT_TX_DONE` interrupt - while (!(rmt_ll_tx_get_interrupt_status_raw(hal->regs, channel_id) & RMT_LL_EVENT_TX_DONE(channel_id))) {} #if SOC_RMT_SUPPORT_DMA + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + int channel_id = channel->channel_id; if (channel->dma_chan) { // enable the DMA access mode portENTER_CRITICAL(&channel->spinlock); @@ -734,12 +732,22 @@ static esp_err_t rmt_tx_enable(rmt_channel_handle_t channel) } #endif // SOC_RMT_SUPPORT_DMA - channel->fsm = RMT_FSM_ENABLE; + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + + // check if we need to start one pending transaction + rmt_tx_trans_desc_t *t = NULL; + expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT)) { + if (xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, 0) == pdTRUE) { + // sanity check + assert(t); + atomic_store(&channel->fsm, RMT_FSM_RUN); + rmt_tx_do_transaction(tx_chan, t); + } else { + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + } + } - // enable channel interrupt, dispatch transactions in ISR (in case there're transaction descriptors in the queue, then we should start them) - portENTER_CRITICAL(&group->spinlock); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), true); - portEXIT_CRITICAL(&group->spinlock); return ESP_OK; } @@ -750,24 +758,37 @@ static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel) rmt_hal_context_t *hal = &group->hal; int channel_id = channel->channel_id; - portENTER_CRITICAL(&channel->spinlock); - rmt_ll_tx_enable_loop(hal->regs, channel->channel_id, false); + // can disable the channel when it's in `enable` or `run` state + bool valid_state = false; + rmt_fsm_t expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_INIT_WAIT)) { + valid_state = true; + } + expected_fsm = RMT_FSM_RUN; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_INIT_WAIT)) { + valid_state = true; + // disable the hardware + portENTER_CRITICAL(&channel->spinlock); + rmt_ll_tx_enable_loop(hal->regs, channel->channel_id, false); #if SOC_RMT_SUPPORT_TX_ASYNC_STOP - rmt_ll_tx_stop(hal->regs, channel->channel_id); + rmt_ll_tx_stop(hal->regs, channel->channel_id); #endif - portEXIT_CRITICAL(&channel->spinlock); + portEXIT_CRITICAL(&channel->spinlock); - portENTER_CRITICAL(&group->spinlock); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id), false); + portENTER_CRITICAL(&group->spinlock); + rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id), false); #if !SOC_RMT_SUPPORT_TX_ASYNC_STOP - // we do a trick to stop the undergoing transmission - // stop interrupt, insert EOF marker to the RMT memory, polling the trans_done event - channel->hw_mem_base[0].val = 0; - while (!(rmt_ll_tx_get_interrupt_status_raw(hal->regs, channel_id) & RMT_LL_EVENT_TX_DONE(channel_id))) {} + // we do a trick to stop the undergoing transmission + // stop interrupt, insert EOF marker to the RMT memory, polling the trans_done event + channel->hw_mem_base[0].val = 0; + while (!(rmt_ll_tx_get_interrupt_status_raw(hal->regs, channel_id) & RMT_LL_EVENT_TX_DONE(channel_id))) {} #endif - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id)); - portEXIT_CRITICAL(&group->spinlock); + rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id)); + portEXIT_CRITICAL(&group->spinlock); + } + ESP_RETURN_ON_FALSE(valid_state, ESP_ERR_INVALID_STATE, TAG, "channel can't be disabled in state %d", expected_fsm); + // disable the DMA #if SOC_RMT_SUPPORT_DMA if (channel->dma_chan) { gdma_stop(channel->dma_chan); @@ -779,9 +800,10 @@ static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel) portEXIT_CRITICAL(&channel->spinlock); } #endif + // recycle the interrupted transaction if (tx_chan->cur_trans) { - xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &tx_chan->cur_trans, portMAX_DELAY); + xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &tx_chan->cur_trans, 0); // reset corresponding encoder rmt_encoder_reset(tx_chan->cur_trans->encoder); } @@ -792,7 +814,9 @@ static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel) ESP_RETURN_ON_ERROR(esp_pm_lock_release(channel->pm_lock), TAG, "release pm_lock failed"); } - channel->fsm = RMT_FSM_INIT; + // finally we switch to the INIT state + atomic_store(&channel->fsm, RMT_FSM_INIT); + return ESP_OK; } @@ -836,12 +860,7 @@ static esp_err_t rmt_tx_modulate_carrier(rmt_channel_handle_t channel, const rmt static bool IRAM_ATTR rmt_isr_handle_tx_threshold(rmt_tx_channel_t *tx_chan) { - rmt_channel_t *channel = &tx_chan->base; - rmt_group_t *group = channel->group; - rmt_hal_context_t *hal = &group->hal; - uint32_t channel_id = channel->channel_id; - - // continue pingpong transmission + // continue ping-pong transmission rmt_tx_trans_desc_t *t = tx_chan->cur_trans; size_t encoded_symbols = t->transmitted_symbol_num; // encoding finished, only need to send the EOF symbol @@ -854,73 +873,54 @@ static bool IRAM_ATTR rmt_isr_handle_tx_threshold(rmt_tx_channel_t *tx_chan) 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 - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_THRES(channel_id)); - return false; } static bool IRAM_ATTR rmt_isr_handle_tx_done(rmt_tx_channel_t *tx_chan) { rmt_channel_t *channel = &tx_chan->base; - rmt_group_t *group = channel->group; - rmt_hal_context_t *hal = &group->hal; - uint32_t channel_id = channel->channel_id; BaseType_t awoken = pdFALSE; rmt_tx_trans_desc_t *trans_desc = NULL; bool need_yield = false; - portENTER_CRITICAL_ISR(&group->spinlock); - // disable interrupt temporarily, re-enable it when there is transaction unhandled in the queue - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), false); - portEXIT_CRITICAL_ISR(&group->spinlock); - - trans_desc = tx_chan->cur_trans; - // process finished transaction - if (trans_desc) { - // don't care of the tx done event for any undergoing loop transaction - // mostly it's triggered when a loop transmission is undergoing and user calls `rmt_transmit()` where tx done interrupt is generated by accident - if (trans_desc->loop_count != 0) { - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id)); - return need_yield; - } - if (tx_chan->on_trans_done) { - rmt_tx_done_event_data_t edata = { - .num_symbols = trans_desc->transmitted_symbol_num, - }; - if (tx_chan->on_trans_done(channel, &edata, tx_chan->user_data)) { - need_yield = true; - } - } - // move transaction to done_queue + rmt_fsm_t expected_fsm = RMT_FSM_RUN; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_ENABLE_WAIT)) { + trans_desc = tx_chan->cur_trans; + // move current finished transaction to the complete queue xQueueSendFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &trans_desc, &awoken); if (awoken == pdTRUE) { need_yield = true; } + tx_chan->cur_trans = NULL; + atomic_store(&channel->fsm, RMT_FSM_ENABLE); } - // fetch new transaction description from trans_queue - if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { - // sanity check - assert(trans_desc); - // update current transaction - tx_chan->cur_trans = trans_desc; - portENTER_CRITICAL_ISR(&group->spinlock); - // only clear the trans done status when we're sure there still remains transaction to handle - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id)); - // enable interrupt again, because the new transaction can trigger another trans done event - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), trans_desc->loop_count == 0); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), trans_desc->loop_count > 0); - portEXIT_CRITICAL_ISR(&group->spinlock); - - // begin a new transaction - rmt_tx_do_transaction(tx_chan, trans_desc); - } else { // No transactions left in the queue - // don't clear interrupt status, so when next time user push new transaction to the queue and call esp_intr_enable, - // we can go to this ISR handler again - tx_chan->cur_trans = NULL; + // invoke callback + rmt_tx_done_callback_t done_cb = tx_chan->on_trans_done; + if (done_cb) { + rmt_tx_done_event_data_t edata = { + .num_symbols = trans_desc->transmitted_symbol_num, + }; + if (done_cb(channel, &edata, tx_chan->user_data)) { + need_yield = true; + } } - if (awoken == pdTRUE) { - need_yield = true; + + // let's try start the next pending transaction + expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT)) { + if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { + // sanity check + assert(trans_desc); + atomic_store(&channel->fsm, RMT_FSM_RUN); + // begin a new transaction + rmt_tx_do_transaction(tx_chan, trans_desc); + if (awoken == pdTRUE) { + need_yield = true; + } + } else { + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + } } return need_yield; @@ -941,16 +941,16 @@ static bool IRAM_ATTR rmt_isr_handle_tx_loop_end(rmt_tx_channel_t *tx_chan) if (trans_desc) { #if !SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP portENTER_CRITICAL_ISR(&channel->spinlock); - // This is a workaround for chips that don't support auto stop + // This is a workaround for chips that don't support loop auto stop // Although we stop the transaction immediately in ISR handler, it's still possible that some rmt symbols have sneaked out rmt_ll_tx_stop(hal->regs, channel_id); portEXIT_CRITICAL_ISR(&channel->spinlock); #endif // SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP + // continue unfinished loop transaction if (trans_desc->remain_loop_count) { uint32_t this_loop_count = MIN(trans_desc->remain_loop_count, RMT_LL_MAX_LOOP_COUNT_PER_BATCH); trans_desc->remain_loop_count -= this_loop_count; - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id)); portENTER_CRITICAL_ISR(&channel->spinlock); rmt_ll_tx_set_loop_count(hal->regs, channel_id, this_loop_count); rmt_ll_tx_reset_pointer(hal->regs, channel_id); @@ -958,51 +958,49 @@ static bool IRAM_ATTR rmt_isr_handle_tx_loop_end(rmt_tx_channel_t *tx_chan) rmt_ll_tx_start(hal->regs, channel_id); portEXIT_CRITICAL_ISR(&channel->spinlock); return need_yield; - } else { - if (tx_chan->on_trans_done) { - rmt_tx_done_event_data_t edata = { - .num_symbols = trans_desc->transmitted_symbol_num, - }; - if (tx_chan->on_trans_done(channel, &edata, tx_chan->user_data)) { - need_yield = true; - } - } - // move transaction to done_queue + } + + // loop transaction finished + rmt_fsm_t expected_fsm = RMT_FSM_RUN; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_ENABLE_WAIT)) { + // move current finished transaction to the complete queue xQueueSendFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &trans_desc, &awoken); if (awoken == pdTRUE) { need_yield = true; } + tx_chan->cur_trans = NULL; + atomic_store(&channel->fsm, RMT_FSM_ENABLE); } - } - // trans_done and loop_done should be considered as one "transmission complete" - // but sometimes the trans done event might also be triggered together with loop done event, by accident, so clear it first - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id)); - portENTER_CRITICAL_ISR(&group->spinlock); - // disable interrupt temporarily, re-enable it when there is transaction unhandled in the queue - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), false); - portEXIT_CRITICAL_ISR(&group->spinlock); - - // fetch new transaction description from trans_queue - if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { - // sanity check - assert(trans_desc); - tx_chan->cur_trans = trans_desc; - // clear the loop end status when we're sure there still remains transaction to handle - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id)); - portENTER_CRITICAL_ISR(&group->spinlock); - // enable interrupt again, because the new transaction can trigger new trans done event - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), trans_desc->loop_count == 0); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), trans_desc->loop_count > 0); - portEXIT_CRITICAL_ISR(&group->spinlock); + // invoke callback + rmt_tx_done_callback_t done_cb = tx_chan->on_trans_done; + if (done_cb) { + rmt_tx_done_event_data_t edata = { + .num_symbols = trans_desc->transmitted_symbol_num, + }; + if (done_cb(channel, &edata, tx_chan->user_data)) { + need_yield = true; + } + } - // begin a new transaction - rmt_tx_do_transaction(tx_chan, trans_desc); - } else { // No transactions left in the queue - // don't clear interrupt status, so when next time user push new transaction to the queue and call esp_intr_enable, - // we can go into ISR handler again - tx_chan->cur_trans = NULL; + // let's try start the next pending transaction + expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT)) { + if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { + // sanity check + assert(trans_desc); + atomic_store(&channel->fsm, RMT_FSM_RUN); + // begin a new transaction + rmt_tx_do_transaction(tx_chan, trans_desc); + if (awoken == pdTRUE) { + need_yield = true; + } + } else { + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + } + } } + if (awoken == pdTRUE) { need_yield = true; } @@ -1020,6 +1018,7 @@ static void IRAM_ATTR rmt_tx_default_isr(void *args) bool need_yield = false; uint32_t status = rmt_ll_tx_get_interrupt_status(hal->regs, channel_id); + rmt_ll_clear_interrupt_status(hal->regs, status); // Tx threshold interrupt if (status & RMT_LL_EVENT_TX_THRES(channel_id)) { diff --git a/components/driver/spi/gpspi/spi_master.c b/components/driver/spi/gpspi/spi_master.c index 9daa87bd265..a0692ddfb09 100644 --- a/components/driver/spi/gpspi/spi_master.c +++ b/components/driver/spi/gpspi/spi_master.c @@ -887,15 +887,15 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_host_t *host, spi_trans uint32_t tx_byte_len = (trans_desc->length + 7) / 8; uint32_t rx_byte_len = (trans_desc->rxlength + 7) / 8; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - bool tx_un_align = ((((uint32_t)send_ptr) | tx_byte_len) & (alignment - 1)); - bool rx_un_align = ((((uint32_t)rcv_ptr) | rx_byte_len) & (alignment - 1)); + bool tx_unaligned = ((((uint32_t)send_ptr) | tx_byte_len) & (alignment - 1)); + bool rx_unaligned = ((((uint32_t)rcv_ptr) | rx_byte_len) & (alignment - 1)); #else - bool tx_un_align = false; //tx don't need align on addr or length, for other chips - bool rx_un_align = (((uint32_t)rcv_ptr) & (alignment - 1)); + bool tx_unaligned = false; //tx don't need align on addr or length, for other chips + bool rx_unaligned = (((uint32_t)rcv_ptr) & (alignment - 1)); #endif if (send_ptr && bus_attr->dma_enabled) { - if ((!esp_ptr_dma_capable(send_ptr) || tx_un_align )) { + if ((!esp_ptr_dma_capable(send_ptr) || tx_unaligned )) { ESP_RETURN_ON_FALSE(!(trans_desc->flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but TX buffer addr&len not align to %d, or not dma_capable", alignment); //if txbuf in the desc not DMA-capable, or not bytes aligned to alignment, malloc a new one ESP_EARLY_LOGD(SPI_TAG, "Allocate TX buffer for DMA" ); @@ -914,7 +914,7 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_host_t *host, spi_trans #endif } - if (rcv_ptr && bus_attr->dma_enabled && (!esp_ptr_dma_capable(rcv_ptr) || rx_un_align )) { + if (rcv_ptr && bus_attr->dma_enabled && (!esp_ptr_dma_capable(rcv_ptr) || rx_unaligned )) { ESP_RETURN_ON_FALSE(!(trans_desc->flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but RX buffer addr&len not align to %d, or not dma_capable", alignment); //if rxbuf in the desc not DMA-capable, or not aligned to alignment, malloc a new one ESP_EARLY_LOGD(SPI_TAG, "Allocate RX buffer for DMA" ); diff --git a/components/driver/spi/gpspi/spi_slave.c b/components/driver/spi/gpspi/spi_slave.c index af9ca699d92..1ab5299cb54 100644 --- a/components/driver/spi/gpspi/spi_slave.c +++ b/components/driver/spi/gpspi/spi_slave.c @@ -12,6 +12,7 @@ #include "esp_log.h" #include "esp_err.h" #include "esp_pm.h" +#include "esp_cache.h" #include "esp_heap_caps.h" #include "esp_rom_sys.h" #include "soc/lldesc.h" @@ -29,7 +30,7 @@ #include "hal/spi_slave_hal.h" #include "esp_private/spi_slave_internal.h" #include "esp_private/spi_common_internal.h" - +#include "esp_private/esp_cache_private.h" static const char *SPI_TAG = "spi_slave"; @@ -48,13 +49,20 @@ static const char *SPI_TAG = "spi_slave"; #define SPI_SLAVE_ATTR #endif +/// struct to hold private transaction data (like tx and rx buffer for DMA). +typedef struct { + spi_slave_transaction_t *trans; //original trans + void *tx_buffer; //actually tx buffer (re-malloced if needed) + void *rx_buffer; //actually rx buffer (re-malloced if needed) +} spi_slave_trans_priv_t; + typedef struct { int id; spi_bus_config_t bus_config; spi_slave_interface_config_t cfg; intr_handle_t intr; spi_slave_hal_context_t hal; - spi_slave_transaction_t *cur_trans; + spi_slave_trans_priv_t cur_trans; uint32_t flags; uint32_t intr_flags; int max_transfer_sz; @@ -63,6 +71,7 @@ typedef struct { bool dma_enabled; bool cs_iomux; uint8_t cs_in_signal; + uint16_t internal_mem_align_size; uint32_t tx_dma_chan; uint32_t rx_dma_chan; #ifdef CONFIG_PM_ENABLE @@ -159,17 +168,37 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b memcpy(&spihost[host]->cfg, slave_config, sizeof(spi_slave_interface_config_t)); memcpy(&spihost[host]->bus_config, bus_config, sizeof(spi_bus_config_t)); spihost[host]->id = host; + spi_slave_hal_context_t *hal = &spihost[host]->hal; - bool use_dma = (dma_chan != SPI_DMA_DISABLED); - spihost[host]->dma_enabled = use_dma; - if (use_dma) { -#if CONFIG_IDF_TARGET_ESP32P4 - abort(); //will supported in IDF-7503 -#endif + spihost[host]->dma_enabled = (dma_chan != SPI_DMA_DISABLED); + if (spihost[host]->dma_enabled) { ret = spicommon_dma_chan_alloc(host, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); if (ret != ESP_OK) { goto cleanup; } + spihost[host]->tx_dma_chan = actual_tx_dma_chan; + spihost[host]->rx_dma_chan = actual_rx_dma_chan; + + //See how many dma descriptors we need and allocate them + int dma_desc_ct = (bus_config->max_transfer_sz + SPI_MAX_DMA_LEN - 1) / SPI_MAX_DMA_LEN; + if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given + spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, (size_t *)&spihost[host]->internal_mem_align_size); +#else + spihost[host]->internal_mem_align_size = 4; +#endif + + hal->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); + hal->dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); + if (!hal->dmadesc_tx || !hal->dmadesc_rx) { + ret = ESP_ERR_NO_MEM; + goto cleanup; + } + hal->dmadesc_n = dma_desc_ct; + } else { + //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. + spihost[host]->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; } err = spicommon_bus_initialize_io(host, bus_config, SPICOMMON_BUSFLAG_SLAVE|bus_config->flags, &spihost[host]->flags); @@ -185,20 +214,8 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b } // The slave DMA suffers from unexpected transactions. Forbid reading if DMA is enabled by disabling the CS line. - if (use_dma) freeze_cs(spihost[host]); + if (spihost[host]->dma_enabled) freeze_cs(spihost[host]); - int dma_desc_ct = 0; - spihost[host]->tx_dma_chan = actual_tx_dma_chan; - spihost[host]->rx_dma_chan = actual_rx_dma_chan; - if (use_dma) { - //See how many dma descriptors we need and allocate them - dma_desc_ct = (bus_config->max_transfer_sz + SPI_MAX_DMA_LEN - 1) / SPI_MAX_DMA_LEN; - if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given - spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN; - } else { - //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. - spihost[host]->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; - } #ifdef CONFIG_PM_ENABLE err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_slave", &spihost[host]->pm_lock); @@ -211,13 +228,13 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b #endif //CONFIG_PM_ENABLE //Create queues - spihost[host]->trans_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_transaction_t *)); + spihost[host]->trans_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_trans_priv_t)); if (!spihost[host]->trans_queue) { ret = ESP_ERR_NO_MEM; goto cleanup; } if(!(slave_config->flags & SPI_SLAVE_NO_RETURN_RESULT)) { - spihost[host]->ret_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_transaction_t *)); + spihost[host]->ret_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_trans_priv_t)); if (!spihost[host]->ret_queue) { ret = ESP_ERR_NO_MEM; goto cleanup; @@ -243,7 +260,6 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b goto cleanup; } - spi_slave_hal_context_t *hal = &spihost[host]->hal; //assign the SPI, RX DMA and TX DMA peripheral registers beginning address spi_slave_hal_config_t hal_config = { .host_id = host, @@ -252,32 +268,20 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b }; spi_slave_hal_init(hal, &hal_config); - if (dma_desc_ct) { - hal->dmadesc_tx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA); - hal->dmadesc_rx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA); - if (!hal->dmadesc_tx || !hal->dmadesc_rx) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - } - hal->dmadesc_n = dma_desc_ct; hal->rx_lsbfirst = (slave_config->flags & SPI_SLAVE_RXBIT_LSBFIRST) ? 1 : 0; hal->tx_lsbfirst = (slave_config->flags & SPI_SLAVE_TXBIT_LSBFIRST) ? 1 : 0; hal->mode = slave_config->mode; - hal->use_dma = use_dma; + hal->use_dma = spihost[host]->dma_enabled; hal->tx_dma_chan = actual_tx_dma_chan; hal->rx_dma_chan = actual_rx_dma_chan; spi_slave_hal_setup_device(hal); - return ESP_OK; cleanup: if (spihost[host]) { if (spihost[host]->trans_queue) vQueueDelete(spihost[host]->trans_queue); if (spihost[host]->ret_queue) vQueueDelete(spihost[host]->ret_queue); - free(spihost[host]->hal.dmadesc_tx); - free(spihost[host]->hal.dmadesc_rx); #ifdef CONFIG_PM_ENABLE if (spihost[host]->pm_lock) { esp_pm_lock_release(spihost[host]->pm_lock); @@ -288,6 +292,8 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b spi_slave_hal_deinit(&spihost[host]->hal); if (spihost[host]->dma_enabled) { spicommon_dma_chan_free(host); + free(spihost[host]->hal.dmadesc_tx); + free(spihost[host]->hal.dmadesc_rx); } free(spihost[host]); @@ -305,10 +311,10 @@ esp_err_t spi_slave_free(spi_host_device_t host) if (spihost[host]->ret_queue) vQueueDelete(spihost[host]->ret_queue); if (spihost[host]->dma_enabled) { spicommon_dma_chan_free(host); + free(spihost[host]->hal.dmadesc_tx); + free(spihost[host]->hal.dmadesc_rx); } spicommon_bus_free_io_cfg(&spihost[host]->bus_config); - free(spihost[host]->hal.dmadesc_tx); - free(spihost[host]->hal.dmadesc_rx); esp_intr_free(spihost[host]->intr); #ifdef CONFIG_PM_ENABLE esp_pm_lock_release(spihost[host]->pm_lock); @@ -320,6 +326,89 @@ esp_err_t spi_slave_free(spi_host_device_t host) return ESP_OK; } +static void SPI_SLAVE_ISR_ATTR spi_slave_uninstall_priv_trans(spi_host_device_t host, spi_slave_trans_priv_t *priv_trans) +{ +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + spi_slave_transaction_t *trans = (spi_slave_transaction_t *)priv_trans->trans; + + if (spihost[host]->dma_enabled) { + if (trans->tx_buffer && (trans->tx_buffer != priv_trans->tx_buffer)) { + free(priv_trans->tx_buffer); + } + if (trans->rx_buffer && (trans->rx_buffer != priv_trans->rx_buffer)) { + memcpy(trans->rx_buffer, priv_trans->rx_buffer, (trans->length + 7) / 8); + free(priv_trans->rx_buffer); + } + } +#endif //SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +} + +static esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_setup_priv_trans(spi_host_device_t host, spi_slave_trans_priv_t *priv_trans) +{ + spi_slave_transaction_t *trans = (spi_slave_transaction_t *)priv_trans->trans; + + priv_trans->tx_buffer = (void *)trans->tx_buffer; + priv_trans->rx_buffer = trans->rx_buffer; + +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + uint16_t alignment = spihost[host]->internal_mem_align_size; + uint32_t buffer_byte_len = (trans->length + 7) / 8; + + if (spihost[host]->dma_enabled && trans->tx_buffer) { + if ((!esp_ptr_dma_capable( trans->tx_buffer ) || ((((uint32_t)trans->tx_buffer) | buffer_byte_len) & (alignment - 1)))) { + ESP_RETURN_ON_FALSE_ISR(trans->flags & SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, ESP_ERR_INVALID_ARG, SPI_TAG, "TX buffer addr&len not align to %d, or not dma_capable", alignment); + //if txbuf in the desc not DMA-capable, or not align to "alignment", malloc a new one + ESP_EARLY_LOGD(SPI_TAG, "Allocate TX buffer for DMA" ); + buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1)); // up align to "alignment" + uint32_t *temp = heap_caps_aligned_alloc(alignment, buffer_byte_len, MALLOC_CAP_DMA); + if (temp == NULL) { + return ESP_ERR_NO_MEM; + } + + memcpy(temp, trans->tx_buffer, (trans->length + 7) / 8); + priv_trans->tx_buffer = temp; + } + esp_err_t ret = esp_cache_msync((void *)priv_trans->tx_buffer, buffer_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + ESP_RETURN_ON_FALSE_ISR(ESP_OK == ret, ESP_ERR_INVALID_STATE, SPI_TAG, "mem sync c2m(writeback) fail"); + } + if (spihost[host]->dma_enabled && trans->rx_buffer && (!esp_ptr_dma_capable(trans->rx_buffer) || ((((uint32_t)trans->rx_buffer) | (trans->length + 7) / 8) & (alignment - 1)))) { + ESP_RETURN_ON_FALSE_ISR(trans->flags & SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, ESP_ERR_INVALID_ARG, SPI_TAG, "RX buffer addr&len not align to %d, or not dma_capable", alignment); + //if rxbuf in the desc not DMA-capable, or not align to "alignment", malloc a new one + ESP_EARLY_LOGD(SPI_TAG, "Allocate RX buffer for DMA" ); + buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1)); // up align to "alignment" + priv_trans->rx_buffer = heap_caps_aligned_alloc(alignment, buffer_byte_len, MALLOC_CAP_DMA); + if (priv_trans->rx_buffer == NULL) { + free (priv_trans->tx_buffer); + return ESP_ERR_NO_MEM; + } + } +#endif //SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + return ESP_OK; +} + +esp_err_t SPI_SLAVE_ATTR spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait) +{ + BaseType_t r; + SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG); + SPI_CHECK(spihost[host], "host not slave", ESP_ERR_INVALID_ARG); + SPI_CHECK(spihost[host]->dma_enabled == 0 || trans_desc->tx_buffer==NULL || esp_ptr_dma_capable(trans_desc->tx_buffer), + "txdata not in DMA-capable memory", ESP_ERR_INVALID_ARG); + SPI_CHECK(spihost[host]->dma_enabled == 0 || trans_desc->rx_buffer==NULL || + (esp_ptr_dma_capable(trans_desc->rx_buffer) && esp_ptr_word_aligned(trans_desc->rx_buffer) && + (trans_desc->length%4==0)), + "rxdata not in DMA-capable memory or not WORD aligned", ESP_ERR_INVALID_ARG); + + SPI_CHECK(trans_desc->length <= spihost[host]->max_transfer_sz * 8, "data transfer > host maximum", ESP_ERR_INVALID_ARG); + + spi_slave_trans_priv_t priv_trans = {.trans = (spi_slave_transaction_t *)trans_desc}; + SPI_CHECK(ESP_OK == spi_slave_setup_priv_trans(host, &priv_trans), "slave setup priv_trans failed", ESP_ERR_NO_MEM); + + r = xQueueSend(spihost[host]->trans_queue, (void *)&priv_trans, ticks_to_wait); + if (!r) return ESP_ERR_TIMEOUT; + esp_intr_enable(spihost[host]->intr); + return ESP_OK; +} + /** * @note * This API is used to reset SPI Slave transaction queue. After calling this function: @@ -342,70 +431,72 @@ esp_err_t SPI_SLAVE_ATTR spi_slave_queue_reset(spi_host_device_t host) esp_intr_disable(spihost[host]->intr); spi_ll_set_int_stat(spihost[host]->hal.hw); - spihost[host]->cur_trans = NULL; - xQueueReset(spihost[host]->trans_queue); + spi_slave_trans_priv_t trans; + while( uxQueueMessagesWaiting(spihost[host]->trans_queue)) { + xQueueReceive(spihost[host]->trans_queue, &trans, 0); + spi_slave_uninstall_priv_trans(host, &trans); + } + spihost[host]->cur_trans.trans = NULL; return ESP_OK; } -esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_queue_reset_isr(spi_host_device_t host) +esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_queue_trans_isr(spi_host_device_t host, const spi_slave_transaction_t *trans_desc) { + BaseType_t r; + BaseType_t do_yield = pdFALSE; ESP_RETURN_ON_FALSE_ISR(is_valid_host(host), ESP_ERR_INVALID_ARG, SPI_TAG, "invalid host"); ESP_RETURN_ON_FALSE_ISR(spihost[host], ESP_ERR_INVALID_ARG, SPI_TAG, "host not slave"); + ESP_RETURN_ON_FALSE_ISR(trans_desc->length <= spihost[host]->max_transfer_sz * 8, ESP_ERR_INVALID_ARG, SPI_TAG, "data transfer > host maximum"); + if (spihost[host]->dma_enabled) { + uint16_t alignment = spihost[host]->internal_mem_align_size; + uint32_t buffer_byte_len = (trans_desc->length + 7) / 8; + + ESP_RETURN_ON_FALSE_ISR(\ + (trans_desc->tx_buffer && \ + esp_ptr_dma_capable(trans_desc->tx_buffer) && \ + ((((uint32_t)trans_desc->tx_buffer) | buffer_byte_len) & (alignment - 1)) == 0), \ + ESP_ERR_INVALID_ARG, SPI_TAG, "txdata addr & len not align to %d bytes or not dma_capable", alignment\ + ); + ESP_RETURN_ON_FALSE_ISR(\ + (trans_desc->rx_buffer && \ + esp_ptr_dma_capable(trans_desc->rx_buffer) && \ + ((((uint32_t)trans_desc->rx_buffer) | buffer_byte_len) & (alignment - 1)) == 0), \ + ESP_ERR_INVALID_ARG, SPI_TAG, "rxdata addr & len not align to %d bytes or not dma_capable", alignment\ + ); + } - spi_slave_transaction_t *trans = NULL; - BaseType_t do_yield = pdFALSE; - while( pdFALSE == xQueueIsQueueEmptyFromISR(spihost[host]->trans_queue)) { - xQueueReceiveFromISR(spihost[host]->trans_queue, &trans, &do_yield); + spi_slave_trans_priv_t priv_trans = { + .trans = (spi_slave_transaction_t *)trans_desc, + .tx_buffer = (void *)trans_desc->tx_buffer, + .rx_buffer = trans_desc->rx_buffer, + }; + r = xQueueSendFromISR(spihost[host]->trans_queue, (void *)&priv_trans, &do_yield); + if (!r) { + return ESP_ERR_NO_MEM; } if (do_yield) { portYIELD_FROM_ISR(); } - - spihost[host]->cur_trans = NULL; return ESP_OK; } -esp_err_t SPI_SLAVE_ATTR spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait) -{ - BaseType_t r; - SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG); - SPI_CHECK(spihost[host], "host not slave", ESP_ERR_INVALID_ARG); - SPI_CHECK(spihost[host]->dma_enabled == 0 || trans_desc->tx_buffer==NULL || esp_ptr_dma_capable(trans_desc->tx_buffer), - "txdata not in DMA-capable memory", ESP_ERR_INVALID_ARG); - SPI_CHECK(spihost[host]->dma_enabled == 0 || trans_desc->rx_buffer==NULL || - (esp_ptr_dma_capable(trans_desc->rx_buffer) && esp_ptr_word_aligned(trans_desc->rx_buffer) && - (trans_desc->length%4==0)), - "rxdata not in DMA-capable memory or not WORD aligned", ESP_ERR_INVALID_ARG); - - SPI_CHECK(trans_desc->length <= spihost[host]->max_transfer_sz * 8, "data transfer > host maximum", ESP_ERR_INVALID_ARG); - r = xQueueSend(spihost[host]->trans_queue, (void *)&trans_desc, ticks_to_wait); - if (!r) return ESP_ERR_TIMEOUT; - esp_intr_enable(spihost[host]->intr); - return ESP_OK; -} - -esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_queue_trans_isr(spi_host_device_t host, const spi_slave_transaction_t *trans_desc) +esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_queue_reset_isr(spi_host_device_t host) { - BaseType_t r; - BaseType_t do_yield = pdFALSE; ESP_RETURN_ON_FALSE_ISR(is_valid_host(host), ESP_ERR_INVALID_ARG, SPI_TAG, "invalid host"); ESP_RETURN_ON_FALSE_ISR(spihost[host], ESP_ERR_INVALID_ARG, SPI_TAG, "host not slave"); - ESP_RETURN_ON_FALSE_ISR(spihost[host]->dma_enabled == 0 || trans_desc->tx_buffer==NULL || esp_ptr_dma_capable(trans_desc->tx_buffer), - ESP_ERR_INVALID_ARG, SPI_TAG, "txdata not in DMA-capable memory"); - ESP_RETURN_ON_FALSE_ISR(spihost[host]->dma_enabled == 0 || trans_desc->rx_buffer==NULL || - (esp_ptr_dma_capable(trans_desc->rx_buffer) && esp_ptr_word_aligned(trans_desc->rx_buffer) && - (trans_desc->length%4==0)), - ESP_ERR_INVALID_ARG, SPI_TAG, "rxdata not in DMA-capable memory or not WORD aligned"); - ESP_RETURN_ON_FALSE_ISR(trans_desc->length <= spihost[host]->max_transfer_sz * 8, ESP_ERR_INVALID_ARG, SPI_TAG, "data transfer > host maximum"); - r = xQueueSendFromISR(spihost[host]->trans_queue, (void *)&trans_desc, &do_yield); - if (!r) { - return ESP_ERR_NO_MEM; + spi_slave_trans_priv_t trans; + BaseType_t do_yield = pdFALSE; + while( pdFALSE == xQueueIsQueueEmptyFromISR(spihost[host]->trans_queue)) { + xQueueReceiveFromISR(spihost[host]->trans_queue, &trans, &do_yield); + spi_slave_uninstall_priv_trans(host, &trans); } if (do_yield) { portYIELD_FROM_ISR(); } + + spihost[host]->cur_trans.trans = NULL; return ESP_OK; } @@ -417,8 +508,12 @@ esp_err_t SPI_SLAVE_ATTR spi_slave_get_trans_result(spi_host_device_t host, spi_ //if SPI_SLAVE_NO_RETURN_RESULT is set, ret_queue will always be empty SPI_CHECK(!(spihost[host]->cfg.flags & SPI_SLAVE_NO_RETURN_RESULT), "API not Supported!", ESP_ERR_NOT_SUPPORTED); - r = xQueueReceive(spihost[host]->ret_queue, (void *)trans_desc, ticks_to_wait); + spi_slave_trans_priv_t priv_trans; + r = xQueueReceive(spihost[host]->ret_queue, (void *)&priv_trans, ticks_to_wait); if (!r) return ESP_ERR_TIMEOUT; + + spi_slave_uninstall_priv_trans(host, &priv_trans); + *trans_desc = priv_trans.trans; return ESP_OK; } @@ -451,19 +546,18 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) { BaseType_t r; BaseType_t do_yield = pdFALSE; - spi_slave_transaction_t *trans = NULL; spi_slave_t *host = (spi_slave_t *)arg; spi_slave_hal_context_t *hal = &host->hal; assert(spi_slave_hal_usr_is_done(hal)); bool use_dma = host->dma_enabled; - if (host->cur_trans) { + if (host->cur_trans.trans) { // When DMA is enabled, the slave rx dma suffers from unexpected transactions. Forbid reading until transaction ready. if (use_dma) freeze_cs(host); spi_slave_hal_store_result(hal); - host->cur_trans->trans_len = spi_slave_hal_get_rcv_bitlen(hal); + host->cur_trans.trans->trans_len = spi_slave_hal_get_rcv_bitlen(hal); #if CONFIG_IDF_TARGET_ESP32 //This workaround is only for esp32 @@ -473,12 +567,22 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) } #endif //#if CONFIG_IDF_TARGET_ESP32 - if (host->cfg.post_trans_cb) host->cfg.post_trans_cb(host->cur_trans); +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible + if (use_dma && host->cur_trans.rx_buffer) { + uint16_t alignment = host->internal_mem_align_size; + uint32_t buffer_byte_len = (host->cur_trans.trans->length + 7) / 8; + buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1)); + // invalidate priv_trans.buffer_to_rcv anyway, only user provide aligned buffer can rcv correct data in post_cb + esp_err_t ret = esp_cache_msync((void *)host->cur_trans.rx_buffer, buffer_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(ret == ESP_OK); + } +#endif + if (host->cfg.post_trans_cb) host->cfg.post_trans_cb(host->cur_trans.trans); if(!(host->cfg.flags & SPI_SLAVE_NO_RETURN_RESULT)) { xQueueSendFromISR(host->ret_queue, &host->cur_trans, &do_yield); } - host->cur_trans = NULL; + host->cur_trans.trans = NULL; } #if CONFIG_IDF_TARGET_ESP32 @@ -497,21 +601,22 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) //Disable interrupt before checking to avoid concurrency issue. esp_intr_disable(host->intr); + spi_slave_trans_priv_t priv_trans; //Grab next transaction - r = xQueueReceiveFromISR(host->trans_queue, &trans, &do_yield); + r = xQueueReceiveFromISR(host->trans_queue, &priv_trans, &do_yield); if (r) { // sanity check - assert(trans); + assert(priv_trans.trans); //enable the interrupt again if there is packet to send esp_intr_enable(host->intr); //We have a transaction. Send it. - host->cur_trans = trans; + host->cur_trans = priv_trans; - hal->bitlen = trans->length; - hal->rx_buffer = trans->rx_buffer; - hal->tx_buffer = trans->tx_buffer; + hal->bitlen = priv_trans.trans->length; + hal->rx_buffer = priv_trans.rx_buffer; + hal->tx_buffer = priv_trans.tx_buffer; #if CONFIG_IDF_TARGET_ESP32 if (use_dma) { @@ -530,7 +635,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) //Kick off transfer spi_slave_hal_user_start(hal); - if (host->cfg.post_setup_cb) host->cfg.post_setup_cb(trans); + if (host->cfg.post_setup_cb) host->cfg.post_setup_cb(priv_trans.trans); } if (do_yield) portYIELD_FROM_ISR(); } diff --git a/components/driver/spi/include/driver/spi_slave.h b/components/driver/spi/include/driver/spi_slave.h index dbbfc1fb20f..cc07d094f71 100644 --- a/components/driver/spi/include/driver/spi_slave.h +++ b/components/driver/spi/include/driver/spi_slave.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -65,15 +65,19 @@ typedef struct { */ } spi_slave_interface_config_t; + +#define SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO (1<<0) ///< Automatically re-malloc dma buffer if user buffer doesn't meet hardware alignment or dma_capable, this process may loss some memory and performance + /** * This structure describes one SPI transaction */ struct spi_slave_transaction_t { + uint32_t flags; ///< Bitwise OR of SPI_SLAVE_TRANS_* flags size_t length; ///< Total data length, in bits size_t trans_len; ///< Transaction data length, in bits const void *tx_buffer; ///< Pointer to transmit buffer, or NULL for no MOSI phase void *rx_buffer; /**< Pointer to receive buffer, or NULL for no MISO phase. - * When the DMA is anabled, must start at WORD boundary (``rx_buffer%4==0``), + * When the DMA is enabled, must start at WORD boundary (``rx_buffer%4==0``), * and has length of a multiple of 4 bytes. */ void *user; ///< User-defined variable. Can be used to store eg transaction ID. @@ -138,6 +142,8 @@ esp_err_t spi_slave_free(spi_host_device_t host); * never time out. * @return * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NO_MEM if set flag `SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO` but there is no free memory + * - ESP_ERR_INVALID_STATE if sync data between Cache and memory failed * - ESP_OK on success */ esp_err_t spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait); diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 98a33dbdf74..bf271a81f77 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -16,16 +16,6 @@ components/driver/test_apps/dac_test_apps/legacy_dac_driver: disable: - if: SOC_DAC_SUPPORTED != 1 -components/driver/test_apps/gpio_extensions: - disable: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: not supported yet # TODO: IDF-7551 - -components/driver/test_apps/gptimer: - disable: - - if: SOC_GPTIMER_SUPPORTED != 1 - components/driver/test_apps/i2c_test_apps: disable: - if: SOC_I2C_SUPPORTED != 1 # TODO: IDF-8070 @@ -97,6 +87,14 @@ components/driver/test_apps/legacy_rtc_temp_driver: disable: - if: SOC_TEMP_SENSOR_SUPPORTED != 1 +components/driver/test_apps/legacy_sigma_delta_driver: + disable: + - if: SOC_SDM_SUPPORTED != 1 + depends_filepatterns: + - components/driver/deprecated/**/* + depends_components: + - esp_driver_gpio + components/driver/test_apps/legacy_timer_driver: disable: - if: SOC_GPTIMER_SUPPORTED != 1 @@ -113,19 +111,13 @@ components/driver/test_apps/parlio: temporary: true reason: lack of runner -components/driver/test_apps/pulse_cnt: - disable: - - if: SOC_PCNT_SUPPORTED != 1 - components/driver/test_apps/rmt: disable: - if: SOC_RMT_SUPPORTED != 1 components/driver/test_apps/rs485: disable: - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-6511 + - if: SOC_UART_SUPPORTED != 1 disable_test: - if: IDF_TARGET != "esp32" temporary: true @@ -139,6 +131,14 @@ components/driver/test_apps/sdio: temporary: true reason: lack of runners +components/driver/test_apps/sigma_delta: + disable: + - if: SOC_SDM_SUPPORTED != 1 + depends_filepatterns: + - components/driver/sigma_delta/**/* + depends_components: + - esp_driver_gpio + components/driver/test_apps/spi/master: disable: - if: SOC_GPSPI_SUPPORTED != 1 @@ -148,14 +148,11 @@ components/driver/test_apps/spi/param: - if: SOC_GPSPI_SUPPORTED != 1 - if: IDF_TARGET in ["esp32p4"] temporary: true - reason: target(s) is not supported yet # TODO: IDF-7503 + reason: target(s) is not supported yet # TODO: IDF-7505 components/driver/test_apps/spi/slave: disable: - if: SOC_GPSPI_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-7503 slave support components/driver/test_apps/spi/slave_hd: disable: @@ -181,17 +178,14 @@ components/driver/test_apps/twai: components/driver/test_apps/uart: disable: - if: SOC_UART_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-6511 components/driver/test_apps/usb_serial_jtag: disable: - if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1 depends_filepatterns: - - components/driver/gpio/**/* - components/driver/usb_serial_jtag/**/* depends_components: - hal - esp_hw_support # for clock - vfs + - esp_driver_gpio diff --git a/components/driver/test_apps/dac_test_apps/dac/main/CMakeLists.txt b/components/driver/test_apps/dac_test_apps/dac/main/CMakeLists.txt index 9ae8264930d..369886c7ddf 100644 --- a/components/driver/test_apps/dac_test_apps/dac/main/CMakeLists.txt +++ b/components/driver/test_apps/dac_test_apps/dac/main/CMakeLists.txt @@ -8,5 +8,5 @@ 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 driver esp_adc + PRIV_REQUIRES unity esp_driver_pcnt driver esp_adc WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/dac_test_apps/dac/main/test_dac.c b/components/driver/test_apps/dac_test_apps/dac/main/test_dac.c index b6e17c98541..4a0a99f83e9 100644 --- a/components/driver/test_apps/dac_test_apps/dac/main/test_dac.c +++ b/components/driver/test_apps/dac_test_apps/dac/main/test_dac.c @@ -33,7 +33,7 @@ #define ADC_TEST_WIDTH ADC_BITWIDTH_13 #endif -#define ADC_TEST_ATTEN ADC_ATTEN_DB_11 +#define ADC_TEST_ATTEN ADC_ATTEN_DB_12 TEST_CASE("DAC_API_basic_logic_test", "[dac]") { diff --git a/components/driver/test_apps/dac_test_apps/legacy_dac_driver/main/test_legacy_dac.c b/components/driver/test_apps/dac_test_apps/legacy_dac_driver/main/test_legacy_dac.c index 7a2a5da90bf..f612a37229d 100644 --- a/components/driver/test_apps/dac_test_apps/legacy_dac_driver/main/test_legacy_dac.c +++ b/components/driver/test_apps/dac_test_apps/legacy_dac_driver/main/test_legacy_dac.c @@ -28,7 +28,7 @@ static const char *TAG = "test_dac"; #elif defined CONFIG_IDF_TARGET_ESP32S2 #define ADC_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width #endif -#define ADC_TEST_ATTEN ADC_ATTEN_DB_11 +#define ADC_TEST_ATTEN ADC_ATTEN_DB_12 #if CONFIG_IDF_TARGET_ESP32 #define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_8 // GPIO25 @@ -174,8 +174,8 @@ TEST_CASE("esp32s2_adc2-dac_with_adc2_calibration", "[dac_legacy]") subtest_adc_dac(1250, &chars); printf("Test 11dB atten...\n"); - adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_11); - esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_13, 0, &chars); + adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_12); + esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_13, 0, &chars); printf("a %"PRIu32", b %"PRIu32"\n", chars.coeff_a, chars.coeff_b); subtest_adc_dac(1500, &chars); subtest_adc_dac(2500, &chars); diff --git a/components/driver/test_apps/gpio_extensions/README.md b/components/driver/test_apps/gpio_extensions/README.md deleted file mode 100644 index a8b7833fa30..00000000000 --- a/components/driver/test_apps/gpio_extensions/README.md +++ /dev/null @@ -1,2 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/i2c_test_apps/main/CMakeLists.txt b/components/driver/test_apps/i2c_test_apps/main/CMakeLists.txt index 61d8e9dae66..b09b511df0b 100644 --- a/components/driver/test_apps/i2c_test_apps/main/CMakeLists.txt +++ b/components/driver/test_apps/i2c_test_apps/main/CMakeLists.txt @@ -1,7 +1,26 @@ set(srcs "test_app_main.c" - "test_i2c.c" + "test_i2c_common.c" ) +if(CONFIG_SOC_I2C_SUPPORT_SLAVE) + list(APPEND srcs "test_i2c_multi.c") + if(CONFIG_I2C_ISR_IRAM_SAFE) + list(APPEND srcs "test_i2c_iram.c") + endif() +endif() + +if(CONFIG_SOC_I2C_SLAVE_SUPPORT_BROADCAST) + list(APPEND srcs "test_i2c_broadcast.c") +endif() + +if(CONFIG_SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS) + list(APPEND srcs "test_i2c_ram.c") +endif() + +if(CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR AND CONFIG_SOC_I2C_SUPPORT_SLAVE) + list(APPEND srcs "test_i2c_10bit.c") +endif() + idf_component_register(SRCS ${srcs} PRIV_REQUIRES unity driver test_utils WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/i2c_test_apps/main/test_board.h b/components/driver/test_apps/i2c_test_apps/main/test_board.h new file mode 100644 index 00000000000..e420180d5ac --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_board.h @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2023 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_ESP32 +#define I2C_SLAVE_SCL_IO 18 /*! +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" + +static QueueHandle_t s_receive_queue; + +static IRAM_ATTR bool example_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t receive_queue = (QueueHandle_t)user_data; + xQueueSendFromISR(receive_queue, edata, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static void i2c_master_write_test_10bit(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_10, + .device_address = 0x134, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test_10bit(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_10, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x134, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = example_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(1000)); + + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test 10 bit", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_10bit, i2c_slave_read_test_10bit); + + +static void master_read_slave_test_10bit(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_10, + .device_address = 0x134, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + printf("Slave please write data to buffer\n"); + + unity_send_signal("slave write"); + unity_wait_for_signal("master read"); + + TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1)); + vTaskDelay(100 / portTICK_PERIOD_MS); + for (int i = 0; i < DATA_LENGTH; i++) { + printf("%d\n", data_rd[i]); + TEST_ASSERT(data_rd[i]==i); + } + unity_send_signal("ready to delete 10bit"); + + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void slave_write_buffer_test_10bit(void) +{ + uint8_t data_wr[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_10, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x134, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("slave write"); + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, DATA_LENGTH, -1)); + disp_buf(data_wr, DATA_LENGTH); + unity_send_signal("master read"); + unity_wait_for_signal("ready to delete 10bit"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + + +TEST_CASE_MULTIPLE_DEVICES("I2C master read slave test 10 bit", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_test_10bit, slave_write_buffer_test_10bit); diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c_broadcast.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_broadcast.c new file mode 100644 index 00000000000..e6cf562289c --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_broadcast.c @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" + +static QueueHandle_t s_receive_queue; + +static IRAM_ATTR bool example_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t receive_queue = (QueueHandle_t)user_data; + xQueueSendFromISR(receive_queue, edata, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static void i2c_master_write_test_broadcast(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x00, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test_broadcast(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x53, + .flags.broadcast_en = true, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = example_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(1000)); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test broadcast", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_broadcast, i2c_slave_read_test_broadcast); diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_common.c similarity index 87% rename from components/driver/test_apps/i2c_test_apps/main/test_i2c.c rename to components/driver/test_apps/i2c_test_apps/main/test_i2c_common.c index 17152f67c54..ee307c32a3d 100644 --- a/components/driver/test_apps/i2c_test_apps/main/test_i2c.c +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_common.c @@ -22,23 +22,18 @@ #include "esp_rom_gpio.h" #include "esp_log.h" #include "test_utils.h" +#include "test_board.h" static const char TAG[] = "test-i2c"; -#define TEST_I2C_SCL_PIN 2 -#define TEST_I2C_SDA_PIN 4 -#define TEST_I2C_SCL_FREQ (100 * 1000) -#define TEST_I2C_PORT 0 -#define SLAVE_ADDR 0x58 - - TEST_CASE("I2C bus install-uninstall test", "[i2c]") { i2c_master_bus_config_t i2c_mst_config_1 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = TEST_I2C_PORT, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t i2c_mst_handle1; @@ -46,8 +41,9 @@ TEST_CASE("I2C bus install-uninstall test", "[i2c]") i2c_master_bus_config_t i2c_mst_config_2 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = 1, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t i2c_mst_handle2; #endif @@ -75,8 +71,9 @@ TEST_CASE("I2C driver memory leaking check", "[i2c]") i2c_master_bus_config_t i2c_mst_config_1 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = TEST_I2C_PORT, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t bus_handle; @@ -95,8 +92,9 @@ TEST_CASE("I2C device add & remove check", "[i2c]") i2c_master_bus_config_t i2c_mst_config_1 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = TEST_I2C_PORT, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t bus_handle; @@ -137,8 +135,8 @@ TEST_CASE("I2C master probe device test", "[i2c]") i2c_master_bus_config_t i2c_mst_config_1 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = TEST_I2C_PORT, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t bus_handle; diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c_iram.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_iram.c new file mode 100644 index 00000000000..d59967fb0e5 --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_iram.c @@ -0,0 +1,141 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" +#include "unity_test_utils_cache.h" + +static QueueHandle_t s_send_queue; +static QueueHandle_t s_receive_queue; + +static IRAM_ATTR bool test_master_tx_done_callback(i2c_master_dev_handle_t i2c_dev, const i2c_master_event_data_t *evt_data, void *arg) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t s_send_queue = (QueueHandle_t)arg; + xQueueSendFromISR(s_send_queue, evt_data, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static IRAM_ATTR bool test_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t receive_queue = (QueueHandle_t)user_data; + xQueueSendFromISR(receive_queue, edata, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static void IRAM_ATTR test_delay_post_cache_disable(void *args) +{ + esp_rom_delay_us(10000); +} + +static void i2c_master_write_test_iram_safe(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + .trans_queue_depth = 200, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + s_send_queue = xQueueCreate(1, sizeof(i2c_master_event_data_t)); + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + i2c_master_event_callbacks_t cbs = { + .on_trans_done = test_master_tx_done_callback, + }; + i2c_master_event_data_t evt_data; + i2c_master_register_event_callbacks(dev_handle, &cbs, s_send_queue); + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL); + xQueueReceive(s_send_queue, &evt_data, pdMS_TO_TICKS(10000)); + unity_wait_for_signal("ready to delete"); + vQueueDelete(s_send_queue); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test_iram_safe(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL); + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000)); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test iram safe", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_iram_safe, i2c_slave_read_test_iram_safe); diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c_multi.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_multi.c new file mode 100644 index 00000000000..eaf026f0c8d --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_multi.c @@ -0,0 +1,487 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" + +void disp_buf(uint8_t *buf, int len) +{ + int i; + for (i = 0; i < len; i++) { + printf("%02x ", buf[i]); + if (( i + 1 ) % 16 == 0) { + printf("\n"); + } + } + printf("\n"); +} + +#define DATA_LENGTH 100 + +static QueueHandle_t s_receive_queue; + +static IRAM_ATTR bool test_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t receive_queue = (QueueHandle_t)user_data; + xQueueSendFromISR(receive_queue, edata, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static void i2c_master_write_test(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000)); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test, i2c_slave_read_test); + + +static void master_read_slave_test(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + printf("Slave please write data to buffer\n"); + + unity_send_signal("slave write"); + unity_wait_for_signal("master read"); + + TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1)); + vTaskDelay(100 / portTICK_PERIOD_MS); + for (int i = 0; i < DATA_LENGTH; i++) { + printf("%d\n", data_rd[i]); + TEST_ASSERT(data_rd[i]==i); + } + unity_send_signal("ready to delete master read test"); + + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void slave_write_buffer_test(void) +{ + uint8_t data_wr[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("slave write"); + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, DATA_LENGTH, -1)); + disp_buf(data_wr, DATA_LENGTH); + unity_send_signal("master read"); + unity_wait_for_signal("ready to delete master read test"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + + +TEST_CASE_MULTIPLE_DEVICES("I2C master read slave test", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_test, slave_write_buffer_test); + +static void i2c_master_write_read_test(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + uint8_t data_wr[DATA_LENGTH] = {0}; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + printf("master read buffer\n"); + + unity_send_signal("slave write"); + unity_wait_for_signal("master read and write"); + + TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1)); + vTaskDelay(100 / portTICK_PERIOD_MS); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + vTaskDelay(100 / portTICK_PERIOD_MS); + unity_send_signal("slave read"); + unity_wait_for_signal("ready to read"); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_send_signal("sent done"); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_write_test(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + uint8_t data_wr[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + unity_send_signal("i2c slave init finish"); + unity_wait_for_signal("slave write"); + + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, DATA_LENGTH, -1)); + disp_buf(data_wr, DATA_LENGTH); + unity_send_signal("master read and write"); + unity_wait_for_signal("slave read"); + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + unity_send_signal("ready to read"); + unity_wait_for_signal("sent done"); + i2c_slave_rx_done_event_data_t rx_data; + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(1000)); + + printf("slave read data is:\n"); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + unity_send_signal("ready to delete"); + vQueueDelete(s_receive_queue); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C read and write test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_read_test, i2c_slave_read_write_test); + + +static void i2c_master_repeat_write(void) +{ + uint8_t data_wr[DATA_LENGTH] = {0}; + int times = 3; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + + i2c_master_bus_handle_t bus_handle; + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + for (int j = 0; j < times; j++) { + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = j + i; + } + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + disp_buf(data_wr, DATA_LENGTH); + } + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_repeat_read(void) +{ + uint32_t size = 0; + int times = 3; + uint8_t data_rd[DATA_LENGTH * 3] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + TEST_ESP_OK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + unity_send_signal("i2c slave init finish"); + + while (times > 0) { + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd + size, DATA_LENGTH)); + xQueueReceive(s_receive_queue, &rx_data, (TickType_t)portMAX_DELAY); + + size += DATA_LENGTH; + times--; + } + + disp_buf(data_rd, size); + for (int j = 0; j < times; j++) { + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i + DATA_LENGTH * j] == (i + j)); + } + } + unity_send_signal("ready to delete"); + vQueueDelete(s_receive_queue); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C repeat write test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_repeat_write, i2c_slave_repeat_read); + +#if SOC_I2C_NUM > 1 +// Now chips with mutiple I2C controllers are up to 2, can change this to interation when we have more I2C controllers. +static void i2c_master_write_test_more_port(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = 1, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test_more_port(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = 1, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000)); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test, more ports", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_more_port, i2c_slave_read_test_more_port); +#endif diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c_ram.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_ram.c new file mode 100644 index 00000000000..165d3afb3b0 --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_ram.c @@ -0,0 +1,215 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" + +static esp_err_t i2c_master_write_to_addr(i2c_master_dev_handle_t device_handle, uint8_t address, const uint8_t *data, uint32_t size, int xfer_timeout_ms) +{ + esp_err_t ret = ESP_OK; + uint8_t *buffer = (uint8_t*)calloc(1, size + 1); + buffer[0] = address; + memcpy(buffer + 1, data, size); + ret = i2c_master_transmit(device_handle, buffer, 1 + size, xfer_timeout_ms); + return ret; +} + +#define DATA_LENGTH_RAM 6 + +static void i2c_master_write_to_ram_test(void) +{ + uint8_t data_wr[DATA_LENGTH_RAM] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH_RAM; i++) { + data_wr[i] = i + 1; + } + disp_buf(data_wr, i); + // Write slave ram address is 0x5. + i2c_master_write_to_addr(dev_handle, 0x5, data_wr, DATA_LENGTH_RAM, -1); + + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_from_ram_test(void) +{ + uint8_t data_rd[DATA_LENGTH_RAM] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + .flags.access_ram_en = true, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + + TEST_ESP_OK(i2c_slave_read_ram(slave_handle, 0x5, data_rd, DATA_LENGTH_RAM)); + + disp_buf(data_rd, DATA_LENGTH_RAM); + for (int i = 0; i < DATA_LENGTH_RAM; i++) { + TEST_ASSERT(data_rd[i] == (i + 1)); + } + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test - slave directly read from ram", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_to_ram_test, i2c_slave_read_from_ram_test); + + +static void master_read_slave_from_ram_test(void) +{ + uint8_t data_rd[DATA_LENGTH_RAM] = {0}; + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + printf("Slave please write data to buffer\n"); + + unity_send_signal("slave write"); + unity_wait_for_signal("master read"); + + uint8_t *buffer = (uint8_t*)malloc(sizeof(uint8_t)); + buffer[0] = 0x2; // Means write offset 2 in I2C ram. + TEST_ESP_OK(i2c_master_transmit_receive(dev_handle, buffer, 1, data_rd, DATA_LENGTH_RAM, -1)); + vTaskDelay(100 / portTICK_PERIOD_MS); + for (int i = 0; i < DATA_LENGTH_RAM; i++) { + printf("%d\n", data_rd[i]); + TEST_ASSERT(data_rd[i]==i); + } + unity_send_signal("ready to delete ram test"); + + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void slave_write_buffer_to_ram_test(void) +{ + uint8_t data_wr[DATA_LENGTH_RAM] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + .flags.access_ram_en = true, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("slave write"); + for (int i = 0; i < DATA_LENGTH_RAM; i++) { + data_wr[i] = i; + } + + TEST_ESP_OK(i2c_slave_write_ram(slave_handle, 0x2, data_wr, DATA_LENGTH_RAM)); + disp_buf(data_wr, DATA_LENGTH_RAM); + unity_send_signal("master read"); + unity_wait_for_signal("ready to delete ram test"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + + +TEST_CASE_MULTIPLE_DEVICES("I2C master read slave ram test", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_from_ram_test, slave_write_buffer_to_ram_test); + +TEST_CASE("I2C slave init as ram but read by fifo", "[i2c]") +{ + uint8_t data_rd[10] = {0}; + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + .flags.access_ram_en = true, + }; + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, i2c_slave_receive(slave_handle, data_rd, 10)); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} diff --git a/components/driver/test_apps/i2c_test_apps/pytest_i2c.py b/components/driver/test_apps/i2c_test_apps/pytest_i2c.py index 21bd8b43484..afcf27563fd 100644 --- a/components/driver/test_apps/i2c_test_apps/pytest_i2c.py +++ b/components/driver/test_apps/i2c_test_apps/pytest_i2c.py @@ -17,3 +17,23 @@ ) def test_i2c(dut: Dut) -> None: dut.run_all_single_board_cases() + + +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic_multi_device +@pytest.mark.parametrize( + 'count, config', + [ + (2, 'defaults',), + ], + indirect=True +) +def test_i2c_multi_device(case_tester) -> None: # type: ignore + for case in case_tester.test_menu: + if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': + case_tester.run_multi_dev_case(case=case, reset=True) diff --git a/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt index 9e911f818e5..1e48b532a39 100644 --- a/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt +++ b/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt @@ -3,5 +3,5 @@ set(srcs "test_app_main.c" "test_i2s_iram.c") idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity driver spi_flash + PRIV_REQUIRES unity esp_driver_pcnt driver spi_flash WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt index 8a091fba5f5..4e1ae63f7d9 100644 --- a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt @@ -2,5 +2,5 @@ set(srcs "test_app_main.c" "test_legacy_i2s.c") idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity driver + PRIV_REQUIRES unity esp_driver_pcnt driver WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c index 1c30ab7cd79..38e30e89774 100644 --- a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c @@ -114,7 +114,7 @@ TEST_CASE("I2S_adc_test", "[i2s_legacy]") i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); // init ADC pad i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_4); - // enable adc sampling, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11 hard-coded in adc_i2s_mode_init + // enable adc sampling, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_12 hard-coded in adc_i2s_mode_init i2s_adc_enable(I2S_NUM_0); // init read buffer uint16_t *i2sReadBuffer = (uint16_t *)calloc(1024, sizeof(uint16_t)); diff --git a/components/driver/test_apps/ledc/main/CMakeLists.txt b/components/driver/test_apps/ledc/main/CMakeLists.txt index 146642e5d3e..5a5d4f716a4 100644 --- a/components/driver/test_apps/ledc/main/CMakeLists.txt +++ b/components/driver/test_apps/ledc/main/CMakeLists.txt @@ -4,5 +4,5 @@ set(srcs "test_app_main.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} - PRIV_REQUIRES unity driver esp_timer esp_psram + PRIV_REQUIRES unity esp_driver_pcnt driver esp_timer esp_psram WHOLE_ARCHIVE) 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 455ec7c5d04..a34adcffadb 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 @@ -60,11 +60,11 @@ #define ADC_TEST_HIGH_VAL 3350 #define ADC_TEST_HIGH_THRESH 200 -#elif CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6216 -#define ADC_TEST_LOW_VAL 2144 -#define ADC_TEST_LOW_THRESH 200 +#elif CONFIG_IDF_TARGET_ESP32H2 +#define ADC_TEST_LOW_VAL 0 +#define ADC_TEST_LOW_THRESH 17 -#define ADC_TEST_HIGH_VAL 4081 +#define ADC_TEST_HIGH_VAL 3390 #define ADC_TEST_HIGH_THRESH 200 #endif @@ -110,10 +110,10 @@ TEST_CASE("Legacy ADC oneshot high/low test", "[legacy_adc_oneshot]") int adc_raw = 0; //ADC1 config TEST_ESP_OK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT)); - TEST_ESP_OK(adc1_config_channel_atten(ADC1_TEST_CHAN0, ADC_ATTEN_DB_11)); + TEST_ESP_OK(adc1_config_channel_atten(ADC1_TEST_CHAN0, ADC_ATTEN_DB_12)); #if ADC_TEST_ADC2 //ADC2 config - TEST_ESP_OK(adc2_config_channel_atten(ADC2_TEST_CHAN0, ADC_ATTEN_DB_11)); + TEST_ESP_OK(adc2_config_channel_atten(ADC2_TEST_CHAN0, ADC_ATTEN_DB_12)); #endif test_adc_set_io_level(ADC_UNIT_1, (adc1_channel_t)ADC1_TEST_CHAN0, 0); diff --git a/components/driver/test_apps/legacy_i2c_driver/main/test_i2c.c b/components/driver/test_apps/legacy_i2c_driver/main/test_i2c.c index b8f4257a318..ea4b03da85a 100644 --- a/components/driver/test_apps/legacy_i2c_driver/main/test_i2c.c +++ b/components/driver/test_apps/legacy_i2c_driver/main/test_i2c.c @@ -508,6 +508,66 @@ static void i2c_slave_repeat_read(void) TEST_CASE_MULTIPLE_DEVICES("I2C repeat write test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_repeat_write, i2c_slave_repeat_read); +#if SOC_I2C_NUM > 1 + +static void i2c_master_write_test_more_ports(void) +{ + uint8_t *data_wr = (uint8_t *) malloc(DATA_LENGTH); + int i; + + i2c_config_t conf_master = i2c_master_init(); + TEST_ESP_OK(i2c_param_config(I2C_NUM_1, &conf_master)); + + TEST_ESP_OK(i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, + I2C_MASTER_RX_BUF_DISABLE, + I2C_MASTER_TX_BUF_DISABLE, 0)); + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH / 2; i++) { + data_wr[i] = i; + } + i2c_master_write_slave(I2C_NUM_1, data_wr, DATA_LENGTH / 2); + disp_buf(data_wr, i); + free(data_wr); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_driver_delete(I2C_NUM_1)); +} + +static void i2c_slave_read_test_more_ports(void) +{ + uint8_t *data_rd = (uint8_t *) malloc(DATA_LENGTH); + int size_rd = 0; + int len = 0; + + i2c_config_t conf_slave = i2c_slave_init(); + TEST_ESP_OK(i2c_param_config( I2C_NUM_1, &conf_slave)); + TEST_ESP_OK(i2c_driver_install(I2C_NUM_1, I2C_MODE_SLAVE, + I2C_SLAVE_RX_BUF_LEN, + I2C_SLAVE_TX_BUF_LEN, 0)); + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + while (1) { + len = i2c_slave_read_buffer( I2C_NUM_1, data_rd + size_rd, DATA_LENGTH, 10000 / portTICK_PERIOD_MS); + if (len == 0) { + break; + } + size_rd += len; + } + disp_buf(data_rd, size_rd); + for (int i = 0; i < size_rd; i++) { + TEST_ASSERT(data_rd[i] == i); + } + free(data_rd); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_driver_delete(I2C_NUM_1)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test, more ports", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_more_ports, i2c_slave_read_test_more_ports); + +#endif + static volatile bool exit_flag; static bool test_read_func; diff --git a/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt b/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt index 8e3ba4f8043..bcdc50e5e68 100644 --- a/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt +++ b/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt @@ -4,5 +4,5 @@ set(srcs "test_app_main.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} - PRIV_REQUIRES unity driver + PRIV_REQUIRES unity esp_driver_pcnt driver WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/legacy_sigma_delta_driver/CMakeLists.txt b/components/driver/test_apps/legacy_sigma_delta_driver/CMakeLists.txt new file mode 100644 index 00000000000..23e05b8a327 --- /dev/null +++ b/components/driver/test_apps/legacy_sigma_delta_driver/CMakeLists.txt @@ -0,0 +1,8 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +# "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(legacy_sigma_delta_driver_test) diff --git a/components/driver/test_apps/legacy_sigma_delta_driver/README.md b/components/driver/test_apps/legacy_sigma_delta_driver/README.md new file mode 100644 index 00000000000..19f1d19a549 --- /dev/null +++ b/components/driver/test_apps/legacy_sigma_delta_driver/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_sigma_delta_driver/main/CMakeLists.txt b/components/driver/test_apps/legacy_sigma_delta_driver/main/CMakeLists.txt new file mode 100644 index 00000000000..85392372b95 --- /dev/null +++ b/components/driver/test_apps/legacy_sigma_delta_driver/main/CMakeLists.txt @@ -0,0 +1,11 @@ +set(srcs "test_app_main.c") + +if(CONFIG_SOC_SDM_SUPPORTED) + list(APPEND srcs "test_sigma_delta_legacy.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 driver esp_driver_gpio + WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/gpio/main/test_app_main.c b/components/driver/test_apps/legacy_sigma_delta_driver/main/test_app_main.c similarity index 100% rename from components/driver/test_apps/gpio/main/test_app_main.c rename to components/driver/test_apps/legacy_sigma_delta_driver/main/test_app_main.c diff --git a/components/driver/test_apps/gpio/main/test_sigma_delta_legacy.c b/components/driver/test_apps/legacy_sigma_delta_driver/main/test_sigma_delta_legacy.c similarity index 100% rename from components/driver/test_apps/gpio/main/test_sigma_delta_legacy.c rename to components/driver/test_apps/legacy_sigma_delta_driver/main/test_sigma_delta_legacy.c diff --git a/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py b/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py new file mode 100644 index 00000000000..cba1b0ab001 --- /dev/null +++ b/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py @@ -0,0 +1,22 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded_idf import IdfDut + + +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True) +def test_legacy_sigma_delta(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='sigma_delta') diff --git a/components/driver/test_apps/gpio/sdkconfig.ci.release b/components/driver/test_apps/legacy_sigma_delta_driver/sdkconfig.ci.release similarity index 100% rename from components/driver/test_apps/gpio/sdkconfig.ci.release rename to components/driver/test_apps/legacy_sigma_delta_driver/sdkconfig.ci.release diff --git a/components/driver/test_apps/gpio/sdkconfig.defaults b/components/driver/test_apps/legacy_sigma_delta_driver/sdkconfig.defaults similarity index 100% rename from components/driver/test_apps/gpio/sdkconfig.defaults rename to components/driver/test_apps/legacy_sigma_delta_driver/sdkconfig.defaults diff --git a/components/driver/test_apps/rmt/main/test_rmt_tx.c b/components/driver/test_apps/rmt/main/test_rmt_tx.c index 92892c35ebc..8fbca6f6a2e 100644 --- a/components/driver/test_apps/rmt/main/test_rmt_tx.c +++ b/components/driver/test_apps/rmt/main/test_rmt_tx.c @@ -367,7 +367,7 @@ TEST_CASE("rmt infinite loop transaction", "[rmt]") .resolution_hz = 1000000, // 1MHz, 1 tick = 1us .mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL, .gpio_num = TEST_RMT_GPIO_NUM_B, - .trans_queue_depth = 3, + .trans_queue_depth = 5, .intr_priority = 1 }; printf("install tx channel\r\n"); @@ -384,6 +384,7 @@ TEST_CASE("rmt infinite loop transaction", "[rmt]") rmt_transmit_config_t transmit_config = { .loop_count = -1, // infinite loop transmission + .flags.queue_nonblocking = true, // return immediately if the queue is full }; printf("infinite loop transmission: keep spinning stepper motor\r\n"); diff --git a/components/driver/test_apps/rs485/README.md b/components/driver/test_apps/rs485/README.md index a8b7833fa30..bf47d80ec64 100644 --- a/components/driver/test_apps/rs485/README.md +++ b/components/driver/test_apps/rs485/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/gpio/CMakeLists.txt b/components/driver/test_apps/sigma_delta/CMakeLists.txt similarity index 88% rename from components/driver/test_apps/gpio/CMakeLists.txt rename to components/driver/test_apps/sigma_delta/CMakeLists.txt index 7ba8cc2d2ca..2150ef0e3a7 100644 --- a/components/driver/test_apps/gpio/CMakeLists.txt +++ b/components/driver/test_apps/sigma_delta/CMakeLists.txt @@ -5,13 +5,13 @@ cmake_minimum_required(VERSION 3.16) set(COMPONENTS main) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(gpio_test) +project(sigma_delta_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/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/ - --elf-file ${CMAKE_BINARY_DIR}/gpio_test.elf + --elf-file ${CMAKE_BINARY_DIR}/sigma_delta_test.elf find-refs --from-sections=.iram0.text --to-sections=.flash.text,.flash.rodata diff --git a/components/driver/test_apps/sigma_delta/README.md b/components/driver/test_apps/sigma_delta/README.md new file mode 100644 index 00000000000..19f1d19a549 --- /dev/null +++ b/components/driver/test_apps/sigma_delta/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/sigma_delta/main/CMakeLists.txt b/components/driver/test_apps/sigma_delta/main/CMakeLists.txt new file mode 100644 index 00000000000..29c6893034e --- /dev/null +++ b/components/driver/test_apps/sigma_delta/main/CMakeLists.txt @@ -0,0 +1,11 @@ +set(srcs "test_app_main.c") + +if(CONFIG_SOC_SDM_SUPPORTED) + list(APPEND srcs "test_sdm.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 driver + WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/gpio_extensions/main/test_app_main.c b/components/driver/test_apps/sigma_delta/main/test_app_main.c similarity index 100% rename from components/driver/test_apps/gpio_extensions/main/test_app_main.c rename to components/driver/test_apps/sigma_delta/main/test_app_main.c diff --git a/components/driver/test_apps/gpio_extensions/main/test_sdm.c b/components/driver/test_apps/sigma_delta/main/test_sdm.c similarity index 100% rename from components/driver/test_apps/gpio_extensions/main/test_sdm.c rename to components/driver/test_apps/sigma_delta/main/test_sdm.c diff --git a/components/driver/test_apps/sigma_delta/pytest_sigma_delta.py b/components/driver/test_apps/sigma_delta/pytest_sigma_delta.py new file mode 100644 index 00000000000..6f5763207d6 --- /dev/null +++ b/components/driver/test_apps/sigma_delta/pytest_sigma_delta.py @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded_idf import IdfDut + +CONFIGS = [ + 'iram_safe', + 'release', +] + + +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.esp32h2 +@pytest.mark.generic +@pytest.mark.parametrize('config', CONFIGS, indirect=True) +def test_sdm(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='sdm') diff --git a/components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe b/components/driver/test_apps/sigma_delta/sdkconfig.ci.iram_safe similarity index 100% rename from components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe rename to components/driver/test_apps/sigma_delta/sdkconfig.ci.iram_safe diff --git a/components/driver/test_apps/gpio_extensions/sdkconfig.ci.release b/components/driver/test_apps/sigma_delta/sdkconfig.ci.release similarity index 100% rename from components/driver/test_apps/gpio_extensions/sdkconfig.ci.release rename to components/driver/test_apps/sigma_delta/sdkconfig.ci.release diff --git a/components/driver/test_apps/gpio_extensions/sdkconfig.defaults b/components/driver/test_apps/sigma_delta/sdkconfig.defaults similarity index 100% rename from components/driver/test_apps/gpio_extensions/sdkconfig.defaults rename to components/driver/test_apps/sigma_delta/sdkconfig.defaults diff --git a/components/driver/test_apps/spi/master/main/test_spi_master.c b/components/driver/test_apps/spi/master/main/test_spi_master.c index 4904d3a824f..d017af51752 100644 --- a/components/driver/test_apps/spi/master/main/test_spi_master.c +++ b/components/driver/test_apps/spi/master/main/test_spi_master.c @@ -1047,7 +1047,7 @@ TEST_CASE("SPI master variable dummy test", "[spi]") TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi)); spi_slave_interface_config_t slave_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG(); - TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slave_cfg, 0)); + TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slave_cfg, SPI_DMA_DISABLED)); spitest_gpio_output_sel(bus_cfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out); spitest_gpio_output_sel(bus_cfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out); @@ -1069,7 +1069,6 @@ TEST_CASE("SPI master variable dummy test", "[spi]") master_free_device_bus(spi); } -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support /** * This test is to check when the first transaction of the HD master is to send data without receiving data via DMA, * then if the master could receive data correctly. @@ -1113,6 +1112,7 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]") spi_slave_transaction_t slave_trans = { .rx_buffer = slv_recv_buf, .length = buf_size * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY)); @@ -1137,6 +1137,7 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]") slave_trans = (spi_slave_transaction_t) {}; slave_trans.tx_buffer = slv_send_buf; slave_trans.length = buf_size * 8; + slave_trans.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY)); vTaskDelay(50); @@ -1158,10 +1159,8 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]") spi_slave_free(TEST_SLAVE_HOST); master_free_device_bus(spi); } -#endif #endif //#if (TEST_SPI_PERIPH_NUM >= 2) -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32) //TODO: IDF-3494 #define FD_TEST_BUF_SIZE 32 #define TEST_NUM 4 @@ -1337,7 +1336,6 @@ static void fd_slave(void) TEST_CASE_MULTIPLE_DEVICES("SPI Master: FD, DMA, Master Single Direction Test", "[spi_ms][test_env=generic_multi_device]", fd_master, fd_slave); #endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32) //TODO: IDF-3494 -#endif //p4 slave support //NOTE: Explained in IDF-1445 | MR !14996 @@ -1491,7 +1489,6 @@ TEST_CASE("spi_speed", "[spi]") #endif // CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE #endif // !(CONFIG_SPIRAM) || (CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL >= 16384) -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support //****************************************spi master add device test************************************// //add dummy devices first #if CONFIG_IDF_TARGET_ESP32 @@ -1576,7 +1573,7 @@ void test_add_device_slave(void) .spics_io_num = CS_REAL_DEV, .queue_size = 3, }; - TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO)); + TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_DISABLED)); spi_slave_transaction_t slave_trans = {}; slave_trans.length = sizeof(slave_sendbuf) * 8; @@ -1602,7 +1599,7 @@ void test_add_device_slave(void) } TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test multiple devices", "[spi_ms]", test_add_device_master, test_add_device_slave); -#endif //p4 slave support + #if (SOC_CPU_CORES_NUM > 1) && (!CONFIG_FREERTOS_UNICORE) @@ -1662,7 +1659,6 @@ TEST_CASE("test_master_isr_pin_to_core","[spi]") } #endif -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support #if CONFIG_SPI_MASTER_IN_IRAM #define TEST_MASTER_IRAM_TRANS_LEN 120 static IRAM_ATTR void test_master_iram_post_trans_cbk(spi_transaction_t *trans) @@ -1768,4 +1764,3 @@ static void test_iram_slave_normal(void) TEST_CASE_MULTIPLE_DEVICES("SPI_Master:IRAM_safe", "[spi_ms]", test_master_iram, test_iram_slave_normal); #endif -#endif //p4 slave support diff --git a/components/driver/test_apps/spi/slave/README.md b/components/driver/test_apps/spi/slave/README.md index 07b81b7c84c..5b39ff96532 100644 --- a/components/driver/test_apps/spi/slave/README.md +++ b/components/driver/test_apps/spi/slave/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file diff --git a/components/driver/test_apps/spi/slave/main/test_app_main.c b/components/driver/test_apps/spi/slave/main/test_app_main.c index e883caa740f..e66cde4a034 100644 --- a/components/driver/test_apps/spi/slave/main/test_app_main.c +++ b/components/driver/test_apps/spi/slave/main/test_app_main.c @@ -10,23 +10,15 @@ #define TEST_MEMORY_LEAK_THRESHOLD (200) -static size_t before_free_8bit; -static size_t before_free_32bit; - 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); + unity_utils_record_free_mem(); } void tearDown(void) { esp_reent_cleanup(); //clean up some of the newlib's lazy allocations - 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); - printf("\n"); - unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD); - unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD); + unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); } void app_main(void) diff --git a/components/driver/test_apps/spi/slave/main/test_spi_slave.c b/components/driver/test_apps/spi/slave/main/test_spi_slave.c index 69cd1d48aba..5650233f392 100644 --- a/components/driver/test_apps/spi/slave/main/test_spi_slave.c +++ b/components/driver/test_apps/spi/slave/main/test_spi_slave.c @@ -133,6 +133,7 @@ TEST_CASE("test fullduplex slave with only RX direction", "[spi]") slave_t.length = 8 * 32; slave_t.tx_buffer = NULL; slave_t.rx_buffer = slave_rxbuf; + slave_t.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; // Colorize RX buffer with known pattern memset( slave_rxbuf, 0x66, sizeof(slave_rxbuf)); @@ -179,6 +180,7 @@ TEST_CASE("test fullduplex slave with only TX direction", "[spi]") slave_t.length = 8 * 32; slave_t.tx_buffer = slave_txbuf; slave_t.rx_buffer = NULL; + slave_t.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; // Colorize RX buffer with known pattern memset( master_rxbuf, 0x66, sizeof(master_rxbuf)); @@ -226,6 +228,7 @@ TEST_CASE("test slave send unaligned", "[spi]") slave_t.length = 8 * 32; slave_t.tx_buffer = slave_txbuf + i; slave_t.rx_buffer = slave_rxbuf; + slave_t.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; // Colorize RX buffers with known pattern memset( master_rxbuf, 0x66, sizeof(master_rxbuf)); @@ -391,7 +394,7 @@ TEST_CASE_MULTIPLE_DEVICES("SPI_Slave_Unaligned_Test", "[spi_ms][timeout=120]", #if CONFIG_SPI_SLAVE_ISR_IN_IRAM #define TEST_IRAM_TRANS_NUM 8 -#define TEST_TRANS_LEN 120 +#define TEST_TRANS_LEN 64 #define TEST_BUFFER_SZ (TEST_IRAM_TRANS_NUM*TEST_TRANS_LEN) static void test_slave_iram_master_normal(void) @@ -484,8 +487,8 @@ static IRAM_ATTR void test_slave_isr_iram(void) slvcfg.post_trans_cb = test_slave_iram_post_trans_cbk; TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO)); - uint8_t *slave_iram_send = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - uint8_t *slave_iram_recv = heap_caps_calloc(1, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_iram_send = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_iram_recv = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); uint8_t *slave_iram_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); get_tx_buffer(1001, slave_iram_exp, slave_iram_send, TEST_BUFFER_SZ); spi_slave_transaction_t trans_cfg[TEST_IRAM_TRANS_NUM] = {0}; @@ -522,7 +525,6 @@ static IRAM_ATTR void test_slave_isr_iram(void) free(slave_iram_exp); spi_slave_free(TEST_SPI_HOST); } - TEST_CASE_MULTIPLE_DEVICES("SPI_Slave: Test_ISR_IRAM_disable_cache", "[spi_ms]", test_slave_iram_master_normal, test_slave_isr_iram); static uint32_t isr_trans_cnt, isr_trans_test_fail; @@ -565,8 +567,8 @@ static IRAM_ATTR void spi_slave_trans_in_isr(void) slvcfg.post_trans_cb = test_trans_in_isr_post_trans_cbk; TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO)); - uint8_t *slave_isr_send = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - uint8_t *slave_isr_recv = heap_caps_calloc(1, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_isr_send = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_isr_recv = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); uint8_t *slave_isr_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); get_tx_buffer(1001, slave_isr_exp, slave_isr_send, TEST_BUFFER_SZ); spi_slave_transaction_t trans_cfg = { @@ -596,7 +598,6 @@ static IRAM_ATTR void spi_slave_trans_in_isr(void) } TEST_CASE_MULTIPLE_DEVICES("SPI_Slave: Test_Queue_Trans_in_ISR", "[spi_ms]", test_slave_iram_master_normal, spi_slave_trans_in_isr); -uint32_t dummy_data[2] = {0x38383838, 0x5b5b5b5b}; spi_slave_transaction_t dummy_trans[2]; static uint32_t queue_reset_isr_trans_cnt, test_queue_reset_isr_fail; static IRAM_ATTR void test_queue_reset_in_isr_post_trans_cbk(spi_slave_transaction_t *curr_trans) @@ -615,8 +616,6 @@ static IRAM_ATTR void test_queue_reset_in_isr_post_trans_cbk(spi_slave_transacti if (queue_reset_isr_trans_cnt > 4) { // add some confusing transactions - dummy_data[0] ++; - dummy_data[1] --; spi_slave_queue_trans_isr(TEST_SPI_HOST, &dummy_trans[0]); ESP_LOG_BUFFER_HEX_ISR(DRAM_STR("Queue Hacked hahhhhh..."), dummy_trans[0].tx_buffer, dummy_trans[0].length / 8); spi_slave_queue_trans_isr(TEST_SPI_HOST, &dummy_trans[1]); @@ -651,10 +650,12 @@ static IRAM_ATTR void spi_queue_reset_in_isr(void) slvcfg.post_trans_cb = test_queue_reset_in_isr_post_trans_cbk; TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO)); - uint8_t *slave_isr_send = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - uint8_t *slave_isr_recv = heap_caps_calloc(1, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_isr_send = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_isr_recv = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *dummy_data = heap_caps_aligned_alloc(64, 64*2, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); uint8_t *slave_isr_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); get_tx_buffer(1001, slave_isr_exp, slave_isr_send, TEST_BUFFER_SZ); + get_tx_buffer(1001, dummy_data, dummy_data + 64, 64); spi_slave_transaction_t trans_cfg = { .tx_buffer = slave_isr_send, .rx_buffer = slave_isr_recv, @@ -664,10 +665,10 @@ static IRAM_ATTR void spi_queue_reset_in_isr(void) unity_wait_for_signal("Master ready"); for (uint8_t i = 0; i < 2; i++) { - dummy_trans[i].tx_buffer = &dummy_data[i]; - dummy_trans[i].rx_buffer = &dummy_data[i]; - dummy_trans[i].user = &dummy_data[i]; - dummy_trans[i].length = sizeof(uint32_t) * 8; + dummy_trans[i].tx_buffer = dummy_data + i * 64; + dummy_trans[i].rx_buffer = dummy_data + i * 64; + dummy_trans[i].user = dummy_data + i * 64; + dummy_trans[i].length = 64 * 8; } // start a trans by normal API first to trigger spi isr spi_slave_queue_trans(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY); @@ -687,7 +688,7 @@ static IRAM_ATTR void spi_queue_reset_in_isr(void) spi_slave_free(TEST_SPI_HOST); } TEST_CASE_MULTIPLE_DEVICES("SPI_Slave: Test_Queue_Reset_in_ISR", "[spi_ms]", test_slave_iram_master_normal, spi_queue_reset_in_isr); -#endif // CONFIG_SPI_SLAVE_ISR_IN_IRAM +#endif // CONFIG_SPI_SLAVE_ISR_IN_IRAM #if (SOC_CPU_CORES_NUM > 1) && (!CONFIG_FREERTOS_UNICORE) @@ -716,7 +717,7 @@ TEST_CASE("test_slave_isr_pin_to_core", "[spi]") slave_expect = 0; for (int i = 0; i < TEST_ISR_CNT; i++) { - TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO)); + TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_DISABLED)); TEST_ESP_OK(spi_slave_queue_trans(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY)); TEST_ESP_OK(spi_slave_free(TEST_SPI_HOST)); } @@ -729,7 +730,7 @@ TEST_CASE("test_slave_isr_pin_to_core", "[spi]") slave_expect = 0; for (int i = 0; i < TEST_ISR_CNT; i++) { - TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO)); + TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_DISABLED)); TEST_ESP_OK(spi_slave_queue_trans(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY)); vTaskDelay(1); // Waiting ISR on core 1 to be done. TEST_ESP_OK(spi_slave_free(TEST_SPI_HOST)); @@ -737,5 +738,4 @@ TEST_CASE("test_slave_isr_pin_to_core", "[spi]") printf("Test Slave ISR Assign CPU1: %d : %ld\n", TEST_ISR_CNT, slave_expect); TEST_ASSERT_EQUAL_UINT32(TEST_ISR_CNT, slave_expect); } - #endif diff --git a/components/driver/test_apps/spi/slave/main/test_spi_slave_queue.c b/components/driver/test_apps/spi/slave/main/test_spi_slave_queue.c index 74103554003..1550fca913e 100644 --- a/components/driver/test_apps/spi/slave/main/test_spi_slave_queue.c +++ b/components/driver/test_apps/spi/slave/main/test_spi_slave_queue.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,6 @@ #define TEST_BUF_SIZE 32 #define TEST_TIMES 4 - static void test_master(void) { spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); @@ -144,6 +143,7 @@ static void test_slave(void) trans[0].tx_buffer = slv_tx_buf[0]; trans[0].rx_buffer = slv_rx_buf[0]; trans[0].length = TEST_BUF_SIZE * 8; + trans[0].flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &trans[0], portMAX_DELAY)); unity_send_signal("Slave ready"); TEST_ESP_OK(spi_slave_get_trans_result(SPI2_HOST, &ret_trans, portMAX_DELAY)); @@ -159,24 +159,28 @@ static void test_slave(void) spi_slave_transaction_t dummy_trans0 = { .tx_buffer = &dummy_data0, .length = sizeof(uint32_t) * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &dummy_trans0, portMAX_DELAY)); uint32_t dummy_data1 = 0xBB; spi_slave_transaction_t dummy_trans1 = { .tx_buffer = &dummy_data1, .length = sizeof(uint32_t) * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &dummy_trans1, portMAX_DELAY)); uint32_t dummy_data2 = 0xCC; spi_slave_transaction_t dummy_trans2 = { .tx_buffer = &dummy_data2, .length = sizeof(uint32_t) * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &dummy_trans2, portMAX_DELAY)); uint32_t dummy_data3 = 0xDD; spi_slave_transaction_t dummy_trans3 = { .tx_buffer = &dummy_data3, .length = sizeof(uint32_t) * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &dummy_trans3, portMAX_DELAY)); @@ -185,16 +189,19 @@ static void test_slave(void) trans[1].tx_buffer = slv_tx_buf[1]; trans[1].rx_buffer = slv_rx_buf[1]; trans[1].length = TEST_BUF_SIZE * 8; + trans[1].flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &trans[1], portMAX_DELAY)); trans[2].tx_buffer = slv_tx_buf[2]; trans[2].rx_buffer = slv_rx_buf[2]; trans[2].length = TEST_BUF_SIZE * 8; + trans[2].flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &trans[2], portMAX_DELAY)); trans[3].tx_buffer = slv_tx_buf[3]; trans[3].rx_buffer = slv_rx_buf[3]; trans[3].length = TEST_BUF_SIZE * 8; + trans[3].flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &trans[3], portMAX_DELAY)); unity_send_signal("Slave ready"); diff --git a/components/driver/test_apps/twai/README.md b/components/driver/test_apps/twai/README.md index 2eccd3e551a..bf6a3f380d3 100644 --- a/components/driver/test_apps/twai/README.md +++ b/components/driver/test_apps/twai/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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # Enable Socket CAN Device with bitrate 250Kbps diff --git a/components/driver/test_apps/twai/main/test_app_main.c b/components/driver/test_apps/twai/main/test_app_main.c index 8d0972047f5..5743bdfde58 100644 --- a/components/driver/test_apps/twai/main/test_app_main.c +++ b/components/driver/test_apps/twai/main/test_app_main.c @@ -1,38 +1,25 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "unity.h" -#include "unity_test_runner.h" +#include "unity_test_utils.h" #include "esp_heap_caps.h" // Some resources are lazy allocated in the TWAI driver, the threshold is left for that case -#define TEST_MEMORY_LEAK_THRESHOLD (-200) - -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"); -} +#define TEST_MEMORY_LEAK_THRESHOLD (200) 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); + unity_utils_record_free_mem(); } 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"); + 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) @@ -42,10 +29,10 @@ void app_main(void) // | | \ \ /\ / / _ \ | | | |/ _ \/ __| __| // | | \ V V / ___ \ | | | | __/\__ \ |_ // |_| \_/\_/_/ \_\___| |_|\___||___/\__| - printf(" _______ ___ ___ _____ _\r\n"); - printf("|_ _\\ \\ / / \\ |_ _| |_ _|__ ___| |_\r\n"); - printf(" | | \\ \\ /\\ / / _ \\ | | | |/ _ \\/ __| __|\r\n"); - printf(" | | \\ V V / ___ \\ | | | | __/\\__ \\ |_\r\n"); - printf(" |_| \\_/\\_/_/ \\_\\___| |_|\\___||___/\\__|\r\n"); + printf(" _______ ___ ___ _____ _\n"); + printf("|_ _\\ \\ / / \\ |_ _| |_ _|__ ___| |_\n"); + printf(" | | \\ \\ /\\ / / _ \\ | | | |/ _ \\/ __| __|\n"); + printf(" | | \\ V V / ___ \\ | | | | __/\\__ \\ |_\n"); + printf(" |_| \\_/\\_/_/ \\_\\___| |_|\\___||___/\\__|\n"); unity_run_menu(); } diff --git a/components/driver/test_apps/twai/main/test_twai_interactive.c b/components/driver/test_apps/twai/main/test_twai_interactive.c index d72a0e0847b..88b74af55bb 100644 --- a/components/driver/test_apps/twai/main/test_twai_interactive.c +++ b/components/driver/test_apps/twai/main/test_twai_interactive.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: Apache-2.0 */ @@ -14,7 +14,7 @@ #include "unity_test_utils.h" #include "driver/twai.h" #include "soc/soc_caps.h" -#include "esp_attr.h" +#include "esp_log.h" #if CONFIG_TWAI_ISR_IN_IRAM static void IRAM_ATTR test_delay_post_cache_disable(void *args) @@ -37,7 +37,7 @@ TEST_CASE("twai_listen_only", "[twai]") TEST_ESP_OK(twai_start()); #if CONFIG_TWAI_ISR_IN_IRAM - printf("disable flash cache and check if we can still receive the frame\r\n"); + printf("disable flash cache and check if we can still receive the frame\n"); for (int i = 0; i < 100; i++) { unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL); } @@ -48,9 +48,8 @@ TEST_CASE("twai_listen_only", "[twai]") TEST_ESP_OK(twai_receive(&rx_msg, portMAX_DELAY)); TEST_ASSERT_EQUAL(0x123, rx_msg.identifier); - for (int i = 0; i < rx_msg.data_length_code; i++) { - TEST_ASSERT_EQUAL_HEX8(expected_data[i], rx_msg.data[i]); - } + ESP_LOG_BUFFER_HEX("rx", rx_msg.data, rx_msg.data_length_code); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, rx_msg.data, rx_msg.data_length_code); TEST_ESP_OK(twai_stop()); TEST_ESP_OK(twai_driver_uninstall()); @@ -58,11 +57,13 @@ TEST_CASE("twai_listen_only", "[twai]") TEST_CASE("twai_remote_request", "[twai]") { + twai_handle_t bus_handle; twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS(); twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(0, 2, TWAI_MODE_NORMAL); - TEST_ESP_OK(twai_driver_install(&g_config, &t_config, &f_config)); - TEST_ESP_OK(twai_start()); + g_config.controller_id = 2; + TEST_ESP_OK(twai_driver_install_v2(&g_config, &t_config, &f_config, &bus_handle)); + TEST_ESP_OK(twai_start_v2(bus_handle)); twai_message_t req_msg = { .identifier = 0x6688, @@ -70,16 +71,17 @@ TEST_CASE("twai_remote_request", "[twai]") .rtr = true, // remote request .extd = true,// extended ID }; - TEST_ESP_OK(twai_transmit(&req_msg, portMAX_DELAY)); + TEST_ESP_OK(twai_transmit_v2(bus_handle, &req_msg, portMAX_DELAY)); + ESP_LOGI("TWAI", "send remote frame"); uint8_t expected_data[8] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}; twai_message_t res_msg; - TEST_ESP_OK(twai_receive(&res_msg, portMAX_DELAY)); + TEST_ESP_OK(twai_receive_v2(bus_handle, &res_msg, portMAX_DELAY)); + ESP_LOGI("TWAI", "receive with id %lx\n", res_msg.identifier); TEST_ASSERT_EQUAL(0x6688, res_msg.identifier); - for (int i = 0; i < 8; i++) { - TEST_ASSERT_EQUAL_HEX8(expected_data[i], res_msg.data[i]); - } + ESP_LOG_BUFFER_HEX("rx", res_msg.data, res_msg.data_length_code); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, res_msg.data, res_msg.data_length_code); - TEST_ESP_OK(twai_stop()); - TEST_ESP_OK(twai_driver_uninstall()); + TEST_ESP_OK(twai_stop_v2(bus_handle)); + TEST_ESP_OK(twai_driver_uninstall_v2(bus_handle)); } diff --git a/components/driver/test_apps/twai/pytest_twai.py b/components/driver/test_apps/twai/pytest_twai.py index 454511f2a62..d3d8ddeca35 100644 --- a/components/driver/test_apps/twai/pytest_twai.py +++ b/components/driver/test_apps/twai/pytest_twai.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import logging @@ -15,6 +15,7 @@ @pytest.mark.esp32h2 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -41,6 +42,7 @@ def fixture_create_socket_can() -> Bus: @pytest.mark.esp32h2 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.skip(reason='Runner not set up yet') @pytest.mark.parametrize( 'config', @@ -73,6 +75,7 @@ def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None: @pytest.mark.esp32h2 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.skip(reason='Runner not set up yet') @pytest.mark.parametrize( 'config', @@ -101,5 +104,6 @@ def test_twai_remote_request(dut: Dut, socket_can: Bus) -> None: data=[0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80], ) socket_can.send(reply, timeout=0.2) + print('send', reply) dut.expect_unity_test_output() diff --git a/components/driver/test_apps/uart/README.md b/components/driver/test_apps/uart/README.md index a8b7833fa30..bf47d80ec64 100644 --- a/components/driver/test_apps/uart/README.md +++ b/components/driver/test_apps/uart/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/twai/twai.c b/components/driver/twai/twai.c index 976a4dc3366..eb0ebfcd3a1 100644 --- a/components/driver/twai/twai.c +++ b/components/driver/twai/twai.c @@ -58,6 +58,12 @@ #define TWAI_RCC_ATOMIC() #endif +#if SOC_PERIPH_CLK_CTRL_SHARED +#define TWAI_PERI_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define TWAI_PERI_ATOMIC() +#endif + /* ------------------ Typedefs, structures, and variables ------------------- */ //Control structure for TWAI driver @@ -453,6 +459,11 @@ esp_err_t twai_driver_install_v2(const twai_general_config_t *g_config, const tw twai_ll_enable_bus_clock(controller_id, true); twai_ll_reset_register(controller_id); } + TWAI_PERI_ATOMIC() { + //Enable functional clock + twai_ll_set_clock_source(p_twai_obj->controller_id, clk_src); + twai_ll_enable_clock(p_twai_obj->controller_id, true); + } //Initialize TWAI HAL layer twai_hal_config_t hal_config = { @@ -514,6 +525,9 @@ esp_err_t twai_driver_uninstall_v2(twai_handle_t handle) //Clear registers by reading twai_hal_deinit(&p_twai_obj->hal); + TWAI_PERI_ATOMIC() { + twai_ll_enable_clock(controller_id, false); + } TWAI_RCC_ATOMIC() { twai_ll_enable_bus_clock(controller_id, false); } diff --git a/components/efuse/esp32c2/esp_efuse_rtc_calib.c b/components/efuse/esp32c2/esp_efuse_rtc_calib.c index c63dae5d2e1..79d91b23192 100644 --- a/components/efuse/esp32c2/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32c2/esp_efuse_rtc_calib.c @@ -28,12 +28,12 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a { assert((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && (version <= ESP_EFUSE_ADC_CALIB_VER_MAX)); - assert(atten <= ADC_ATTEN_DB_11); + assert(atten <= ADC_ATTEN_DB_12); (void) adc_unit; if (atten == ADC_ATTEN_DB_2_5 || atten == ADC_ATTEN_DB_6) { /** - * - ESP32C2 only supports HW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_11 + * - ESP32C2 only supports HW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_12 * - For other attenuation, we just return default value, which is 0. */ return 0; @@ -56,7 +56,7 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a if (atten == ADC_ATTEN_DB_0) { init_code = adc_icode_diff_atten0 + 2160; } else { - //ADC_ATTEN_DB_11 + //ADC_ATTEN_DB_12 init_code = adc_icode_diff_atten3 + adc_icode_diff_atten0 + 2160; } @@ -76,7 +76,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in if (atten == ADC_ATTEN_DB_2_5 || atten == ADC_ATTEN_DB_6) { /** - * - ESP32C2 only supports SW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_11 + * - ESP32C2 only supports SW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_12 * - For other attenuation, we need to return an error, informing upper layer SW calibration driver * to deal with the error. */ @@ -101,7 +101,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in *out_digi = adc_vol_diff_atten0 + 1540; *out_vol_mv = 400; } else { - //ADC_ATTEN_DB_11 + //ADC_ATTEN_DB_12 *out_digi = adc_vol_diff_atten0 + 1540 - adc_vol_diff_atten3 - 123; *out_vol_mv = 1370; } diff --git a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h index e2cb7610fd1..9e65f777b5c 100644 --- a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h @@ -16,7 +16,7 @@ extern "C" { #define ESP_EFUSE_ADC_CALIB_VER2 2 #define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER1 #define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER2 -#define VER2IDX(ver) (ver - 1) // Version number to index number of the array +#define VER2IDX(ver) ((ver) - 1) // Version number to index number of the array /** * @brief Get the RTC calibration efuse version * diff --git a/components/efuse/esp32h2/esp_efuse_rtc_calib.c b/components/efuse/esp32h2/esp_efuse_rtc_calib.c index 5c41630475d..2ff20ea3a3c 100644 --- a/components/efuse/esp32h2/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32h2/esp_efuse_rtc_calib.c @@ -7,6 +7,120 @@ #include #include "esp_efuse.h" #include "esp_efuse_table.h" +#include "esp_efuse_rtc_calib.h" +#include "hal/efuse_hal.h" + +/** + * @brief Get the signed value by the raw data that read from eFuse + * @param data The raw data that read from eFuse + * @param sign_bit The index of the sign bit, start from 0 + */ +#define RTC_CALIB_GET_SIGNED_VAL(data, sign_bit) ((data & BIT##sign_bit) ? -(int)(data & ~BIT##sign_bit) : (int)data) + +int esp_efuse_rtc_calib_get_ver(void) +{ + uint32_t cali_version = 0; + uint32_t blk_ver = efuse_hal_blk_version(); + if (blk_ver >= 2) { + cali_version = ESP_EFUSE_ADC_CALIB_VER1; + } else { + ESP_LOGW("eFuse", "calibration efuse version does not match, set default version to 0"); + } + + return cali_version; +} + +uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten) +{ + /* Version validation should be guaranteed in the caller */ + assert(atten >=0 && atten < 4); + (void) adc_unit; + + const esp_efuse_desc_t** init_code_efuse; + if (atten == 0) { + init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN0; + } else if (atten == 1) { + init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN1; + } else if (atten == 2) { + init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN2; + } else { + init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN3; + } + + int init_code_size = esp_efuse_get_field_size(init_code_efuse); + assert(init_code_size == 10); + + uint32_t init_code = 0; + ESP_ERROR_CHECK(esp_efuse_read_field_blob(init_code_efuse, &init_code, init_code_size)); + return init_code + 1600; // version 1 logic +} + +int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten) +{ + /* Version validation should be guaranteed in the caller */ + assert(atten < 4); + assert(adc_channel < SOC_ADC_CHANNEL_NUM(adc_unit)); + + const esp_efuse_desc_t** chan_diff_efuse = NULL; + switch (adc_channel) { + case 0: + chan_diff_efuse = ESP_EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF; + break; + case 1: + chan_diff_efuse = ESP_EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF; + break; + case 2: + chan_diff_efuse = ESP_EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF; + break; + case 3: + chan_diff_efuse = ESP_EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF; + break; + default: + chan_diff_efuse = ESP_EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF; + break; + } + + int chan_diff_size = esp_efuse_get_field_size(chan_diff_efuse); + assert(chan_diff_size == 4); + uint32_t chan_diff = 0; + ESP_ERROR_CHECK(esp_efuse_read_field_blob(chan_diff_efuse, &chan_diff, chan_diff_size)); + + return RTC_CALIB_GET_SIGNED_VAL(chan_diff, 3) * (4 - atten); +} + +esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t* out_digi, uint32_t* out_vol_mv) +{ + (void) adc_unit; + const esp_efuse_desc_t** cal_vol_efuse[4] = { + ESP_EFUSE_ADC1_HI_DOUT_ATTEN0, + ESP_EFUSE_ADC1_HI_DOUT_ATTEN1, + ESP_EFUSE_ADC1_HI_DOUT_ATTEN2, + ESP_EFUSE_ADC1_HI_DOUT_ATTEN3, + }; + const uint32_t input_vout_mv[1][4] = { + {750, 1000, 1500, 2800}, // Calibration V1 coefficients + }; + + if ((version < ESP_EFUSE_ADC_CALIB_VER_MIN) || + (version > ESP_EFUSE_ADC_CALIB_VER_MAX)) { + return ESP_ERR_INVALID_ARG; + } + if (atten >= 4 || atten < 0) { + return ESP_ERR_INVALID_ARG; + } + + assert(cal_vol_efuse[atten][0]->bit_count == 10); + + uint32_t cal_vol = 0; + esp_err_t ret = esp_efuse_read_field_blob(cal_vol_efuse[atten], &cal_vol, cal_vol_efuse[atten][0]->bit_count); + if (ret != ESP_OK) { + return ret; + } + uint32_t chk_offset = (atten == 2) ? 2970 : 2900; + *out_digi = chk_offset + RTC_CALIB_GET_SIGNED_VAL(cal_vol, 9); + *out_vol_mv = input_vout_mv[VER2IDX(version)][atten]; + return ESP_OK; +} esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal) { diff --git a/components/efuse/esp32h2/esp_efuse_table.c b/components/efuse/esp32h2/esp_efuse_table.c index f5407c8e484..f59aa56de8d 100644 --- a/components/efuse/esp32h2/esp_efuse_table.c +++ b/components/efuse/esp32h2/esp_efuse_table.c @@ -9,7 +9,7 @@ #include #include "esp_efuse_table.h" -// md5_digest_table 6b9b5b452050328626d767c44e489b8d +// md5_digest_table e3fb625011fff48d5d8b7569075d0bb3 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. @@ -243,6 +243,62 @@ static const esp_efuse_desc_t WR_DIS_DISABLE_BLK_VERSION_MAJOR[] = { {EFUSE_BLK0, 21, 1}, // [] wr_dis of DISABLE_BLK_VERSION_MAJOR, }; +static const esp_efuse_desc_t WR_DIS_TEMP_CALIB[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of TEMP_CALIB, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_AVE_INITCODE_ATTEN0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_AVE_INITCODE_ATTEN0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_AVE_INITCODE_ATTEN1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_AVE_INITCODE_ATTEN1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_AVE_INITCODE_ATTEN2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_AVE_INITCODE_ATTEN2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_AVE_INITCODE_ATTEN3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_AVE_INITCODE_ATTEN3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_HI_DOUT_ATTEN0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_HI_DOUT_ATTEN0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_HI_DOUT_ATTEN1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_HI_DOUT_ATTEN1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_HI_DOUT_ATTEN2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_HI_DOUT_ATTEN2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_HI_DOUT_ATTEN3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_HI_DOUT_ATTEN3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF, +}; + static const esp_efuse_desc_t WR_DIS_BLOCK_USR_DATA[] = { {EFUSE_BLK0, 22, 1}, // [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA, }; @@ -553,6 +609,62 @@ static const esp_efuse_desc_t DISABLE_BLK_VERSION_MAJOR[] = { {EFUSE_BLK2, 135, 1}, // [] Disables check of blk version major, }; +static const esp_efuse_desc_t TEMP_CALIB[] = { + {EFUSE_BLK2, 136, 9}, // [] Temperature calibration data, +}; + +static const esp_efuse_desc_t ADC1_AVE_INITCODE_ATTEN0[] = { + {EFUSE_BLK2, 145, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_AVE_INITCODE_ATTEN1[] = { + {EFUSE_BLK2, 155, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_AVE_INITCODE_ATTEN2[] = { + {EFUSE_BLK2, 165, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_AVE_INITCODE_ATTEN3[] = { + {EFUSE_BLK2, 175, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_HI_DOUT_ATTEN0[] = { + {EFUSE_BLK2, 185, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_HI_DOUT_ATTEN1[] = { + {EFUSE_BLK2, 195, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_HI_DOUT_ATTEN2[] = { + {EFUSE_BLK2, 205, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_HI_DOUT_ATTEN3[] = { + {EFUSE_BLK2, 215, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH0_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 225, 4}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH1_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 229, 4}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH2_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 233, 4}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH3_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 237, 4}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH4_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 241, 4}, // [] ADC1 calibration data, +}; + static const esp_efuse_desc_t USER_DATA[] = { {EFUSE_BLK3, 0, 256}, // [BLOCK_USR_DATA] User data, }; @@ -878,6 +990,76 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_BLK_VERSION_MAJOR[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP_CALIB[] = { + &WR_DIS_TEMP_CALIB[0], // [] wr_dis of TEMP_CALIB + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN0[] = { + &WR_DIS_ADC1_AVE_INITCODE_ATTEN0[0], // [] wr_dis of ADC1_AVE_INITCODE_ATTEN0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN1[] = { + &WR_DIS_ADC1_AVE_INITCODE_ATTEN1[0], // [] wr_dis of ADC1_AVE_INITCODE_ATTEN1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN2[] = { + &WR_DIS_ADC1_AVE_INITCODE_ATTEN2[0], // [] wr_dis of ADC1_AVE_INITCODE_ATTEN2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN3[] = { + &WR_DIS_ADC1_AVE_INITCODE_ATTEN3[0], // [] wr_dis of ADC1_AVE_INITCODE_ATTEN3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN0[] = { + &WR_DIS_ADC1_HI_DOUT_ATTEN0[0], // [] wr_dis of ADC1_HI_DOUT_ATTEN0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN1[] = { + &WR_DIS_ADC1_HI_DOUT_ATTEN1[0], // [] wr_dis of ADC1_HI_DOUT_ATTEN1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN2[] = { + &WR_DIS_ADC1_HI_DOUT_ATTEN2[0], // [] wr_dis of ADC1_HI_DOUT_ATTEN2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN3[] = { + &WR_DIS_ADC1_HI_DOUT_ATTEN3[0], // [] wr_dis of ADC1_HI_DOUT_ATTEN3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[] = { &WR_DIS_BLOCK_USR_DATA[0], // [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA NULL @@ -1264,6 +1446,76 @@ const esp_efuse_desc_t* ESP_EFUSE_DISABLE_BLK_VERSION_MAJOR[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[] = { + &TEMP_CALIB[0], // [] Temperature calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN0[] = { + &ADC1_AVE_INITCODE_ATTEN0[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN1[] = { + &ADC1_AVE_INITCODE_ATTEN1[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN2[] = { + &ADC1_AVE_INITCODE_ATTEN2[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN3[] = { + &ADC1_AVE_INITCODE_ATTEN3[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN0[] = { + &ADC1_HI_DOUT_ATTEN0[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN1[] = { + &ADC1_HI_DOUT_ATTEN1[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN2[] = { + &ADC1_HI_DOUT_ATTEN2[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN3[] = { + &ADC1_HI_DOUT_ATTEN3[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH0_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH1_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH2_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH3_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH4_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[] = { &USER_DATA[0], // [BLOCK_USR_DATA] User data NULL diff --git a/components/efuse/esp32h2/esp_efuse_table.csv b/components/efuse/esp32h2/esp_efuse_table.csv index 67f3ed78729..3ddbe98d7f7 100644 --- a/components/efuse/esp32h2/esp_efuse_table.csv +++ b/components/efuse/esp32h2/esp_efuse_table.csv @@ -9,7 +9,7 @@ # this will generate new source files, next rebuild all the sources. # !!!!!!!!!!! # -# This file was generated by regtools.py based on the efuses.yaml file with the version: 4df10f83de85f2d830b7c466aabb28e7 +# This file was generated by regtools.py based on the efuses.yaml file with the version: b69ddcfb39a412df490e3facbbfb46b2 WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS @@ -68,6 +68,20 @@ WR_DIS.OPTIONAL_UNIQUE_ID, EFUSE_BLK0, 21, 1, [] wr_dis WR_DIS.BLK_VERSION_MINOR, EFUSE_BLK0, 21, 1, [] wr_dis of BLK_VERSION_MINOR WR_DIS.BLK_VERSION_MAJOR, EFUSE_BLK0, 21, 1, [] wr_dis of BLK_VERSION_MAJOR WR_DIS.DISABLE_BLK_VERSION_MAJOR, EFUSE_BLK0, 21, 1, [] wr_dis of DISABLE_BLK_VERSION_MAJOR +WR_DIS.TEMP_CALIB, EFUSE_BLK0, 21, 1, [] wr_dis of TEMP_CALIB +WR_DIS.ADC1_AVE_INITCODE_ATTEN0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_AVE_INITCODE_ATTEN0 +WR_DIS.ADC1_AVE_INITCODE_ATTEN1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_AVE_INITCODE_ATTEN1 +WR_DIS.ADC1_AVE_INITCODE_ATTEN2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_AVE_INITCODE_ATTEN2 +WR_DIS.ADC1_AVE_INITCODE_ATTEN3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_AVE_INITCODE_ATTEN3 +WR_DIS.ADC1_HI_DOUT_ATTEN0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_HI_DOUT_ATTEN0 +WR_DIS.ADC1_HI_DOUT_ATTEN1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_HI_DOUT_ATTEN1 +WR_DIS.ADC1_HI_DOUT_ATTEN2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_HI_DOUT_ATTEN2 +WR_DIS.ADC1_HI_DOUT_ATTEN3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_HI_DOUT_ATTEN3 +WR_DIS.ADC1_CH0_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF +WR_DIS.ADC1_CH1_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF +WR_DIS.ADC1_CH2_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF +WR_DIS.ADC1_CH3_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF +WR_DIS.ADC1_CH4_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF WR_DIS.BLOCK_USR_DATA, EFUSE_BLK0, 22, 1, [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA WR_DIS.CUSTOM_MAC, EFUSE_BLK0, 22, 1, [WR_DIS.MAC_CUSTOM WR_DIS.USER_DATA_MAC_CUSTOM] wr_dis of CUSTOM_MAC WR_DIS.BLOCK_KEY0, EFUSE_BLK0, 23, 1, [WR_DIS.KEY0] wr_dis of BLOCK_KEY0 @@ -150,6 +164,20 @@ OPTIONAL_UNIQUE_ID, EFUSE_BLK2, 0, 128, [] Option BLK_VERSION_MINOR, EFUSE_BLK2, 130, 3, [] BLK_VERSION_MINOR of BLOCK2. 1: RF Calibration data in BLOCK1 BLK_VERSION_MAJOR, EFUSE_BLK2, 133, 2, [] BLK_VERSION_MAJOR of BLOCK2 DISABLE_BLK_VERSION_MAJOR, EFUSE_BLK2, 135, 1, [] Disables check of blk version major +TEMP_CALIB, EFUSE_BLK2, 136, 9, [] Temperature calibration data +ADC1_AVE_INITCODE_ATTEN0, EFUSE_BLK2, 145, 10, [] ADC1 calibration data +ADC1_AVE_INITCODE_ATTEN1, EFUSE_BLK2, 155, 10, [] ADC1 calibration data +ADC1_AVE_INITCODE_ATTEN2, EFUSE_BLK2, 165, 10, [] ADC1 calibration data +ADC1_AVE_INITCODE_ATTEN3, EFUSE_BLK2, 175, 10, [] ADC1 calibration data +ADC1_HI_DOUT_ATTEN0, EFUSE_BLK2, 185, 10, [] ADC1 calibration data +ADC1_HI_DOUT_ATTEN1, EFUSE_BLK2, 195, 10, [] ADC1 calibration data +ADC1_HI_DOUT_ATTEN2, EFUSE_BLK2, 205, 10, [] ADC1 calibration data +ADC1_HI_DOUT_ATTEN3, EFUSE_BLK2, 215, 10, [] ADC1 calibration data +ADC1_CH0_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 225, 4, [] ADC1 calibration data +ADC1_CH1_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 229, 4, [] ADC1 calibration data +ADC1_CH2_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 233, 4, [] ADC1 calibration data +ADC1_CH3_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 237, 4, [] ADC1 calibration data +ADC1_CH4_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 241, 4, [] ADC1 calibration data USER_DATA, EFUSE_BLK3, 0, 256, [BLOCK_USR_DATA] User data USER_DATA.MAC_CUSTOM, EFUSE_BLK3, 200, 48, [MAC_CUSTOM CUSTOM_MAC] Custom MAC KEY0, EFUSE_BLK4, 0, 256, [BLOCK_KEY0] Key0 or user data diff --git a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h index 6929d1e7a9e..2101902a7be 100644 --- a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,9 +12,10 @@ extern "C" { #endif //This is the ADC calibration value version burnt in efuse -#define ESP_EFUSE_ADC_CALIB_VER 1 -#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER -#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER +#define ESP_EFUSE_ADC_CALIB_VER1 1 +#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER1 +#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER1 +#define VER2IDX(ver) ((ver) - 1) // Version number to index number of the array /** * @brief Get the RTC calibration efuse version @@ -33,10 +34,21 @@ int esp_efuse_rtc_calib_get_ver(void); */ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten); +/** + * @brief Get the channel specific calibration compensation + * + * @param version Version of the stored efuse + * @param adc_unit ADC unit. Not used, for compatibility. ESP32H2 only supports one ADC unit + * @param atten Attenuation of the init code + * @return The channel calibration compensation value + */ +int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten); + /** * @brief Get the calibration digits stored in the efuse, and the corresponding voltage. * * @param version Version of the stored efuse + * @param adc_unit ADC unit (not used on ESP32H2, for compatibility) * @param atten Attenuation to use * @param out_digi Output buffer of the digits * @param out_vol_mv Output of the voltage, in mV @@ -44,7 +56,7 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a * - ESP_ERR_INVALID_ARG: If efuse version or attenuation is invalid * - ESP_OK: if success */ -esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t* out_digi, uint32_t* out_vol_mv); +esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t* out_digi, uint32_t* out_vol_mv); /** * @brief Get the temperature sensor calibration number delta_T stored in the efuse. diff --git a/components/efuse/esp32h2/include/esp_efuse_table.h b/components/efuse/esp32h2/include/esp_efuse_table.h index b8ea18db0fa..fbe83816b0a 100644 --- a/components/efuse/esp32h2/include/esp_efuse_table.h +++ b/components/efuse/esp32h2/include/esp_efuse_table.h @@ -10,7 +10,7 @@ extern "C" { #include "esp_efuse.h" -// md5_digest_table 6b9b5b452050328626d767c44e489b8d +// md5_digest_table e3fb625011fff48d5d8b7569075d0bb3 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. @@ -83,6 +83,20 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OPTIONAL_UNIQUE_ID[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MINOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MAJOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_BLK_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP_CALIB[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[]; #define ESP_EFUSE_WR_DIS_USER_DATA ESP_EFUSE_WR_DIS_BLOCK_USR_DATA extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_CUSTOM_MAC[]; @@ -185,6 +199,20 @@ extern const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[]; extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MAJOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_BLK_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF[]; extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[]; #define ESP_EFUSE_BLOCK_USR_DATA ESP_EFUSE_USER_DATA extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[]; diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index ac28442ef3d..32e1e0db832 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -38,16 +38,9 @@ menu "ESP-TLS" help Enable session ticket support as specified in RFC5077. - config ESP_TLS_SERVER - bool "Enable ESP-TLS Server" - depends on (ESP_TLS_USING_MBEDTLS && MBEDTLS_TLS_SERVER) || ESP_TLS_USING_WOLFSSL - help - Enable support for creating server side SSL/TLS session, available for mbedTLS - as well as wolfSSL TLS library. - config ESP_TLS_SERVER_SESSION_TICKETS bool "Enable server session tickets" - depends on ESP_TLS_SERVER && ESP_TLS_USING_MBEDTLS && MBEDTLS_SERVER_SSL_SESSION_TICKETS + depends on ESP_TLS_USING_MBEDTLS && MBEDTLS_SERVER_SSL_SESSION_TICKETS help Enable session ticket support as specified in RFC5077 @@ -60,7 +53,7 @@ menu "ESP-TLS" config ESP_TLS_SERVER_CERT_SELECT_HOOK bool "Certificate selection hook" - depends on ESP_TLS_USING_MBEDTLS && ESP_TLS_SERVER + depends on ESP_TLS_USING_MBEDTLS help Ability to configure and use a certificate selection callback during server handshake, to select a certificate to present to the client based on the TLS extensions supplied in @@ -68,7 +61,7 @@ menu "ESP-TLS" config ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL bool "ESP-TLS Server: Set minimum Certificate Verification mode to Optional" - depends on ESP_TLS_SERVER && ESP_TLS_USING_MBEDTLS + depends on ESP_TLS_USING_MBEDTLS help When this option is enabled, the peer (here, the client) certificate is checked by the server, however the handshake continues even if verification failed. By default, the diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index b80edd16793..76265587e97 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -64,12 +64,10 @@ static const char *TAG = "esp-tls"; #define _esp_tls_get_client_session esp_mbedtls_get_client_session #define _esp_tls_free_client_session esp_mbedtls_free_client_session #define _esp_tls_get_ssl_context esp_mbedtls_get_ssl_context -#ifdef CONFIG_ESP_TLS_SERVER #define _esp_tls_server_session_create esp_mbedtls_server_session_create #define _esp_tls_server_session_delete esp_mbedtls_server_session_delete #define _esp_tls_server_session_ticket_ctx_init esp_mbedtls_server_session_ticket_ctx_init #define _esp_tls_server_session_ticket_ctx_free esp_mbedtls_server_session_ticket_ctx_free -#endif /* CONFIG_ESP_TLS_SERVER */ #define _esp_tls_get_bytes_avail esp_mbedtls_get_bytes_avail #define _esp_tls_init_global_ca_store esp_mbedtls_init_global_ca_store #define _esp_tls_set_global_ca_store esp_mbedtls_set_global_ca_store /*!< Callback function for setting global CA store data for TLS/SSL */ @@ -83,10 +81,8 @@ static const char *TAG = "esp-tls"; #define _esp_tls_write esp_wolfssl_write #define _esp_tls_conn_delete esp_wolfssl_conn_delete #define _esp_tls_net_init esp_wolfssl_net_init -#ifdef CONFIG_ESP_TLS_SERVER #define _esp_tls_server_session_create esp_wolfssl_server_session_create #define _esp_tls_server_session_delete esp_wolfssl_server_session_delete -#endif /* CONFIG_ESP_TLS_SERVER */ #define _esp_tls_get_bytes_avail esp_wolfssl_get_bytes_avail #define _esp_tls_init_global_ca_store esp_wolfssl_init_global_ca_store #define _esp_tls_set_global_ca_store esp_wolfssl_set_global_ca_store /*!< Callback function for setting global CA store data for TLS/SSL */ @@ -108,7 +104,7 @@ static const char *TAG = "esp-tls"; static esp_err_t create_ssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls) { - return _esp_create_ssl_handle(hostname, hostlen, cfg, tls); + return _esp_create_ssl_handle(hostname, hostlen, cfg, tls, NULL); } static esp_err_t esp_tls_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg) @@ -638,7 +634,6 @@ void esp_tls_free_client_session(esp_tls_client_session_t *client_session) #endif /* CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS */ -#ifdef CONFIG_ESP_TLS_SERVER esp_err_t esp_tls_cfg_server_session_tickets_init(esp_tls_cfg_server_t *cfg) { #if defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS) @@ -682,7 +677,6 @@ void esp_tls_server_session_delete(esp_tls_t *tls) { return _esp_tls_server_session_delete(tls); } -#endif /* CONFIG_ESP_TLS_SERVER */ ssize_t esp_tls_get_bytes_avail(esp_tls_t *tls) { diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index 95779250043..32eccacb5d8 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -81,6 +81,16 @@ typedef enum esp_tls_addr_family { ESP_TLS_AF_INET6, /**< IPv6 address family. */ } esp_tls_addr_family_t; +/* +* @brief ESP-TLS TLS Protocol version +*/ +typedef enum { + ESP_TLS_VER_ANY = 0, /* No preference */ + ESP_TLS_VER_TLS_1_2 = 0x1, /* (D)TLS 1.2 */ + ESP_TLS_VER_TLS_1_3 = 0x2, /* (D)TLS 1.3 */ + ESP_TLS_VER_TLS_MAX, /* to indicate max */ +} esp_tls_proto_ver_t; + /** * @brief ESP-TLS configuration parameters * @@ -200,9 +210,9 @@ typedef struct esp_tls_cfg { esp_tls_addr_family_t addr_family; /*!< The address family to use when connecting to a host. */ const int *ciphersuites_list; /*!< Pointer to a zero-terminated array of IANA identifiers of TLS ciphersuites. Please check the list validity by esp_tls_get_ciphersuites_list() API */ + esp_tls_proto_ver_t tls_version; /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */ } esp_tls_cfg_t; -#ifdef CONFIG_ESP_TLS_SERVER #if defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS) /** * @brief Data structures necessary to support TLS session tickets according to RFC5077 @@ -217,7 +227,7 @@ typedef struct esp_tls_server_session_ticket_ctx { } esp_tls_server_session_ticket_ctx_t; #endif - +#if defined(CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK) /** * @brief tls handshake callback * Can be used to configure per-handshake attributes for the TLS connection. @@ -228,7 +238,11 @@ typedef struct esp_tls_server_session_ticket_ctx { * or a specific MBEDTLS_ERR_XXX code, which will cause the handhsake to abort */ typedef mbedtls_ssl_hs_cb_t esp_tls_handshake_callback; +#endif +/** + * @brief ESP-TLS Server configuration parameters + */ typedef struct esp_tls_cfg_server { const char **alpn_protos; /*!< Application protocols required for HTTP2. If HTTP2/ALPN support is required, a list @@ -330,7 +344,6 @@ esp_err_t esp_tls_cfg_server_session_tickets_init(esp_tls_cfg_server_t *cfg); * @param cfg server configuration as esp_tls_cfg_server_t */ void esp_tls_cfg_server_session_tickets_free(esp_tls_cfg_server_t *cfg); -#endif /* ! CONFIG_ESP_TLS_SERVER */ typedef struct esp_tls esp_tls_t; @@ -670,7 +683,6 @@ mbedtls_x509_crt *esp_tls_get_global_ca_store(void); */ const int *esp_tls_get_ciphersuites_list(void); #endif /* CONFIG_ESP_TLS_USING_MBEDTLS */ -#ifdef CONFIG_ESP_TLS_SERVER /** * @brief Create TLS/SSL server session * @@ -696,7 +708,6 @@ int esp_tls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls * @param[in] tls pointer to esp_tls_t */ void esp_tls_server_session_delete(esp_tls_t *tls); -#endif /* ! CONFIG_ESP_TLS_SERVER */ /** * @brief Creates a plain TCP connection, returning a valid socket fd on success or an error handle diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index d0a25084609..5708dfcb952 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -70,7 +70,9 @@ typedef struct esp_tls_pki_t { #endif } esp_tls_pki_t; -esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls) +static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls); + +esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params) { assert(cfg != NULL); assert(tls != NULL); @@ -97,17 +99,35 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const ESP_LOGE(TAG, "Failed to set client configurations, returned [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); goto exit; } + const esp_tls_proto_ver_t tls_ver = ((esp_tls_cfg_t *)cfg)->tls_version; + if (tls_ver == ESP_TLS_VER_TLS_1_3) { +#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 + ESP_LOGD(TAG, "Setting TLS version to 0x%4x", MBEDTLS_SSL_VERSION_TLS1_3); + mbedtls_ssl_conf_min_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3); + mbedtls_ssl_conf_max_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3); +#else + ESP_LOGW(TAG, "TLS 1.3 is not enabled in config, continuing with default TLS protocol"); +#endif + } else if (tls_ver == ESP_TLS_VER_TLS_1_2) { + ESP_LOGD(TAG, "Setting TLS version to 0x%4x", MBEDTLS_SSL_VERSION_TLS1_2); + mbedtls_ssl_conf_min_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_2); + mbedtls_ssl_conf_max_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_2); + } else if (tls_ver != ESP_TLS_VER_ANY) { + ESP_LOGE(TAG, "Unsupported protocol version"); + esp_ret = ESP_ERR_INVALID_ARG; + goto exit; + } } else if (tls->role == ESP_TLS_SERVER) { -#ifdef CONFIG_ESP_TLS_SERVER - esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls); + if (server_params == NULL) { + /* Server params cannot be NULL when TLS role is server */ + return ESP_ERR_INVALID_ARG; + } + esp_tls_server_params_t *input_server_params = server_params; + esp_ret = input_server_params->set_server_cfg((esp_tls_cfg_server_t *) cfg, tls); if (esp_ret != 0) { ESP_LOGE(TAG, "Failed to set server configurations, returned [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); goto exit; } -#else - ESP_LOGE(TAG, "ESP_TLS_SERVER Not enabled in Kconfig"); - goto exit; -#endif } if ((ret = mbedtls_ctr_drbg_seed(&tls->ctr_drbg, @@ -125,11 +145,6 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const mbedtls_esp_enable_debug_log(&tls->conf, CONFIG_MBEDTLS_DEBUG_LEVEL); #endif -#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - mbedtls_ssl_conf_min_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3); - mbedtls_ssl_conf_max_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3); -#endif - if ((ret = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) { ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%04X", -ret); mbedtls_print_error_msg(ret); @@ -233,15 +248,17 @@ ssize_t esp_mbedtls_read(esp_tls_t *tls, char *data, size_t datalen) { ssize_t ret = mbedtls_ssl_read(&tls->ssl, (unsigned char *)data, datalen); -#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 && CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS +#if CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS // If a post-handshake message is received, connection state is changed to `MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET` // Call mbedtls_ssl_read() till state is `MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET` or return code is `MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET` // to process session tickets in TLS 1.3 connection - while (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET || tls->ssl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET) { - ESP_LOGD(TAG, "got session ticket in TLS 1.3 connection, retry read"); - ret = mbedtls_ssl_read(&tls->ssl, (unsigned char *)data, datalen); + if (mbedtls_ssl_get_version_number(&tls->ssl) == MBEDTLS_SSL_VERSION_TLS1_3) { + while (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET || tls->ssl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET) { + ESP_LOGD(TAG, "got session ticket in TLS 1.3 connection, retry read"); + ret = mbedtls_ssl_read(&tls->ssl, (unsigned char *)data, datalen); + } } -#endif // CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 && CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS +#endif // CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS if (ret < 0) { if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { @@ -338,10 +355,6 @@ void esp_mbedtls_cleanup(esp_tls_t *tls) mbedtls_x509_crt_free(tls->cacert_ptr); } tls->cacert_ptr = NULL; -#ifdef CONFIG_ESP_TLS_SERVER - mbedtls_x509_crt_free(&tls->servercert); - mbedtls_pk_free(&tls->serverkey); -#endif mbedtls_x509_crt_free(&tls->cacert); mbedtls_x509_crt_free(&tls->clientcert); mbedtls_pk_free(&tls->clientkey); @@ -463,7 +476,6 @@ static esp_err_t set_global_ca_store(esp_tls_t *tls) return ESP_OK; } -#ifdef CONFIG_ESP_TLS_SERVER #ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS int esp_mbedtls_server_session_ticket_write(void *p_ticket, const mbedtls_ssl_session *session, unsigned char *start, const unsigned char *end, size_t *tlen, uint32_t *lifetime) { @@ -532,7 +544,7 @@ void esp_mbedtls_server_session_ticket_ctx_free(esp_tls_server_session_ticket_ct } #endif -esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) +static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) { assert(cfg != NULL); assert(tls != NULL); @@ -664,7 +676,6 @@ esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) return ESP_OK; } -#endif /* ! CONFIG_ESP_TLS_SERVER */ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls) { @@ -888,7 +899,6 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t return ESP_OK; } -#ifdef CONFIG_ESP_TLS_SERVER /** * @brief Create TLS/SSL server session */ @@ -899,7 +909,9 @@ int esp_mbedtls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp } tls->role = ESP_TLS_SERVER; tls->sockfd = sockfd; - esp_err_t esp_ret = esp_create_mbedtls_handle(NULL, 0, cfg, tls); + esp_tls_server_params_t server_params = {}; + server_params.set_server_cfg = &set_server_config; + esp_err_t esp_ret = esp_create_mbedtls_handle(NULL, 0, cfg, tls, &server_params); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "create_ssl_handle failed, returned [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, esp_ret); @@ -931,7 +943,6 @@ void esp_mbedtls_server_session_delete(esp_tls_t *tls) free(tls); } }; -#endif /* ! CONFIG_ESP_TLS_SERVER */ esp_err_t esp_mbedtls_init_global_ca_store(void) { diff --git a/components/esp-tls/esp_tls_wolfssl.c b/components/esp-tls/esp_tls_wolfssl.c index 9c4f1771a94..733b097429d 100644 --- a/components/esp-tls/esp_tls_wolfssl.c +++ b/components/esp-tls/esp_tls_wolfssl.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -44,9 +44,7 @@ static uint8_t psk_key_array[PSK_MAX_KEY_LEN]; static uint8_t psk_key_max_len = 0; #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */ -#ifdef CONFIG_ESP_TLS_SERVER static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls); -#endif /* CONFIG_ESP_TLS_SERVER */ /* This function shall return the error message when appropriate log level has been set otherwise this function shall do nothing */ @@ -124,7 +122,7 @@ void *esp_wolfssl_get_ssl_context(esp_tls_t *tls) return (void*)tls->priv_ssl; } -esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls) +esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params) { #ifdef CONFIG_ESP_DEBUG_WOLFSSL wolfSSL_Debugging_ON(); @@ -152,16 +150,11 @@ esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const goto exit; } } else if (tls->role == ESP_TLS_SERVER) { -#ifdef CONFIG_ESP_TLS_SERVER esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "Failed to set server configurations, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); goto exit; } -#else - ESP_LOGE(TAG, "ESP_TLS_SERVER Not enabled in menuconfig"); - goto exit; -#endif } else { ESP_LOGE(TAG, "tls->role is not valid"); @@ -321,7 +314,6 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls return ESP_OK; } -#ifdef CONFIG_ESP_TLS_SERVER static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) { int ret = WOLFSSL_FAILURE; @@ -378,7 +370,6 @@ static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd); return ESP_OK; } -#endif int esp_wolfssl_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg) { @@ -486,7 +477,6 @@ void esp_wolfssl_cleanup(esp_tls_t *tls) wolfSSL_Cleanup(); } -#ifdef CONFIG_ESP_TLS_SERVER /** * @brief Create TLS/SSL server session */ @@ -497,7 +487,9 @@ int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp } tls->role = ESP_TLS_SERVER; tls->sockfd = sockfd; - esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls); + esp_tls_server_params_t server_params = {}; + server_params.set_server_cfg = &set_server_config; + esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls, &server_params); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "create_ssl_handle failed, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, esp_ret); @@ -531,7 +523,6 @@ void esp_wolfssl_server_session_delete(esp_tls_t *tls) free(tls); } } -#endif /* CONFIG_ESP_TLS_SERVER */ esp_err_t esp_wolfssl_init_global_ca_store(void) { diff --git a/components/esp-tls/private_include/esp_tls_mbedtls.h b/components/esp-tls/private_include/esp_tls_mbedtls.h index 5526bba98c2..6bb1071ab04 100644 --- a/components/esp-tls/private_include/esp_tls_mbedtls.h +++ b/components/esp-tls/private_include/esp_tls_mbedtls.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,7 +46,7 @@ ssize_t esp_mbedtls_get_bytes_avail(esp_tls_t *tls); /** * Internal Callback for creating ssl handle for mbedtls */ -esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls); +esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void* server_params); /** * mbedTLS function for Initializing socket wrappers @@ -61,13 +61,6 @@ static inline void esp_mbedtls_net_init(esp_tls_t *tls) */ void *esp_mbedtls_get_ssl_context(esp_tls_t *tls); -#ifdef CONFIG_ESP_TLS_SERVER -/** - * Internal Callback for set_server_config - * - * /note :- can only be used with mbedtls ssl library - */ -esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls); /** * Internal Callback for mbedtls_server_session_create @@ -98,7 +91,6 @@ esp_err_t esp_mbedtls_server_session_ticket_ctx_init(esp_tls_server_session_tick */ void esp_mbedtls_server_session_ticket_ctx_free(esp_tls_server_session_ticket_ctx_t *cfg); #endif -#endif /** * Internal Callback for set_client_config_function diff --git a/components/esp-tls/private_include/esp_tls_private.h b/components/esp-tls/private_include/esp_tls_private.h index dcbb42070ea..4341557aaf9 100644 --- a/components/esp-tls/private_include/esp_tls_private.h +++ b/components/esp-tls/private_include/esp_tls_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -53,21 +53,21 @@ struct esp_tls { mbedtls_x509_crt cacert; /*!< Container for the X.509 CA certificate */ mbedtls_x509_crt *cacert_ptr; /*!< Pointer to the cacert being used. */ - + union { mbedtls_x509_crt clientcert; /*!< Container for the X.509 client certificate */ + mbedtls_x509_crt servercert; /*!< Container for the X.509 server certificate */ + }; + union { mbedtls_pk_context clientkey; /*!< Container for the private key of the client certificate */ + mbedtls_pk_context serverkey; /*!< Container for the private key of the server + certificate */ + }; #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN bool use_ecdsa_peripheral; /*!< Use the ECDSA peripheral for the private key operations. */ uint8_t ecdsa_efuse_blk; /*!< The efuse block number where the ECDSA key is stored. */ #endif -#ifdef CONFIG_ESP_TLS_SERVER - mbedtls_x509_crt servercert; /*!< Container for the X.509 server certificate */ - - mbedtls_pk_context serverkey; /*!< Container for the private key of the server - certificate */ -#endif #elif CONFIG_ESP_TLS_USING_WOLFSSL void *priv_ctx; void *priv_ssl; @@ -95,3 +95,11 @@ struct esp_tls { esp_tls_error_handle_t error_handle; /*!< handle to error descriptor */ }; + +// Function pointer for the server configuration API +typedef esp_err_t (*set_server_config_func_ptr) (esp_tls_cfg_server_t *cfg, esp_tls_t *tls); + +// This struct contains any data that is only specific to the server session and not required by the client. +typedef struct esp_tls_server_params { + set_server_config_func_ptr set_server_cfg; +} esp_tls_server_params_t; diff --git a/components/esp-tls/private_include/esp_tls_wolfssl.h b/components/esp-tls/private_include/esp_tls_wolfssl.h index 32c9a42917c..121c13477f2 100644 --- a/components/esp-tls/private_include/esp_tls_wolfssl.h +++ b/components/esp-tls/private_include/esp_tls_wolfssl.h @@ -11,7 +11,7 @@ /** * Internal Callback for creating ssl handle for wolfssl */ -int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls); +int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params); /** * Internal Callback for wolfssl_handshake @@ -76,7 +76,6 @@ static inline void esp_wolfssl_net_init(esp_tls_t *tls) { } -#ifdef CONFIG_ESP_TLS_SERVER /** * Function to Create ESP-TLS Server session with wolfssl Stack @@ -87,5 +86,3 @@ int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp * Delete Server Session */ void esp_wolfssl_server_session_delete(esp_tls_t *tls); - -#endif diff --git a/components/esp-tls/test_apps/main/test_esp_tls.c b/components/esp-tls/test_apps/main/test_esp_tls.c index e245fc7e8bd..f91c279a118 100644 --- a/components/esp-tls/test_apps/main/test_esp_tls.c +++ b/components/esp-tls/test_apps/main/test_esp_tls.c @@ -76,7 +76,6 @@ TEST_CASE("esp-tls global_ca_store set free", "[esp-tls]") esp_tls_free_global_ca_store(); } -#ifdef CONFIG_ESP_TLS_SERVER TEST_CASE("esp_tls_server session create delete", "[esp-tls]") { struct esp_tls *tls = esp_tls_init(); @@ -95,4 +94,3 @@ TEST_CASE("esp_tls_server session create delete", "[esp-tls]") esp_tls_server_session_delete(tls); } -#endif diff --git a/components/esp-tls/test_apps/sdkconfig.defaults b/components/esp-tls/test_apps/sdkconfig.defaults index 60afb44a2ea..e8191f02df1 100644 --- a/components/esp-tls/test_apps/sdkconfig.defaults +++ b/components/esp-tls/test_apps/sdkconfig.defaults @@ -5,6 +5,4 @@ CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y CONFIG_COMPILER_STACK_CHECK=y - CONFIG_ESP_TASK_WDT_EN=n -CONFIG_ESP_TLS_SERVER=y diff --git a/components/esp_adc/CMakeLists.txt b/components/esp_adc/CMakeLists.txt index bef8434a40d..180ef6e8cf1 100644 --- a/components/esp_adc/CMakeLists.txt +++ b/components/esp_adc/CMakeLists.txt @@ -42,5 +42,5 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} - PRIV_REQUIRES driver efuse + PRIV_REQUIRES driver esp_driver_gpio efuse esp_pm esp_ringbuf LDFRAGMENTS linker.lf) diff --git a/components/esp_adc/Kconfig b/components/esp_adc/Kconfig index 16ca0970373..24faca9919a 100644 --- a/components/esp_adc/Kconfig +++ b/components/esp_adc/Kconfig @@ -76,4 +76,13 @@ menu "ADC and ADC Calibration" If you stick to this, you can enable this option to force use ADC2 under above conditions. For more details, you can search for errata on espressif website. + + config ADC_ENABLE_DEBUG_LOG + bool "Enable ADC debug log" + default n + help + Wether to enable the debug log message for ADC driver. + Note that this option only controls the ADC driver log, will not affect other drivers. + + note: This cannot be used in the ADC legacy driver. endmenu diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index a52799210d2..d954e880eaf 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -9,6 +9,11 @@ #include #include #include "sdkconfig.h" +#if CONFIG_ADC_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_intr_alloc.h" #include "esp_log.h" #include "esp_pm.h" @@ -102,6 +107,9 @@ static esp_err_t adc_digi_gpio_init(adc_unit_t adc_unit, uint16_t channel_mask) esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_config, adc_continuous_handle_t *ret_handle) { +#if CONFIG_ADC_ENABLE_DEBUG_LOG + esp_log_level_set(ADC_TAG, ESP_LOG_DEBUG); +#endif esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE((hdl_config->conv_frame_size % SOC_ADC_DIGI_DATA_BYTES_PER_CONV == 0), ESP_ERR_INVALID_ARG, ADC_TAG, "conv_frame_size should be in multiples of `SOC_ADC_DIGI_DATA_BYTES_PER_CONV`"); diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index dba3fd6b1ca..80f2711489f 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -7,6 +7,11 @@ #include #include #include "sdkconfig.h" +#if CONFIG_ADC_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 "stdatomic.h" #include "esp_log.h" #include "esp_check.h" @@ -69,6 +74,9 @@ esp_err_t adc_oneshot_channel_to_io(adc_unit_t unit_id, adc_channel_t channel, i esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, adc_oneshot_unit_handle_t *ret_unit) { +#if CONFIG_ADC_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif esp_err_t ret = ESP_OK; adc_oneshot_unit_ctx_t *unit = NULL; ESP_GOTO_ON_FALSE(init_config && ret_unit, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument: null pointer"); diff --git a/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c index 08603733d12..68c46e534b0 100644 --- a/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c +++ b/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c @@ -316,7 +316,7 @@ esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, chars->bit_width = bit_width; chars->vref = (EFUSE_VREF_ENABLED && efuse_vref_present) ? read_efuse_vref() : default_vref; //Initialize fields for lookup table if necessary - if (LUT_ENABLED && atten == ADC_ATTEN_DB_11) { + if (LUT_ENABLED && atten == ADC_ATTEN_DB_12) { chars->low_curve = (adc_num == ADC_UNIT_1) ? lut_adc1_low : lut_adc2_low; chars->high_curve = (adc_num == ADC_UNIT_1) ? lut_adc1_high : lut_adc2_high; } else { @@ -336,8 +336,8 @@ uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_char adc_reading = ADC_12_BIT_RES - 1; //Set to 12bit res max } - if (LUT_ENABLED && (chars->atten == ADC_ATTEN_DB_11) && (adc_reading >= LUT_LOW_THRESH)) { //Check if in non-linear region - //Use lookup table to get voltage in non linear portion of ADC_ATTEN_DB_11 + if (LUT_ENABLED && (chars->atten == ADC_ATTEN_DB_12) && (adc_reading >= LUT_LOW_THRESH)) { //Check if in non-linear region + //Use lookup table to get voltage in non linear portion of ADC_ATTEN_DB_12 uint32_t lut_voltage = calculate_voltage_lut(adc_reading, chars->vref, chars->low_curve, chars->high_curve); if (adc_reading <= LUT_HIGH_THRESH) { //If ADC is transitioning from linear region to non-linear region //Linearly interpolate between linear voltage and lut voltage diff --git a/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c index 6e92f8f37e8..c59f27ad90e 100644 --- a/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c +++ b/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c @@ -75,7 +75,7 @@ static bool prepare_calib_data_for(adc_unit_t adc_num, adc_atten_t atten, adc_ca case ADC_ATTEN_DB_6: parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 1000; break; - case ADC_ATTEN_DB_11: + case ADC_ATTEN_DB_12: parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 2000; break; default: diff --git a/components/esp_adc/esp32/adc_cali_line_fitting.c b/components/esp_adc/esp32/adc_cali_line_fitting.c index adf79c4c3fb..60710818584 100644 --- a/components/esp_adc/esp32/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32/adc_cali_line_fitting.c @@ -190,7 +190,7 @@ esp_err_t adc_cali_create_scheme_line_fitting(const adc_cali_line_fitting_config chars->atten = config->atten; chars->bitwidth = (config->bitwidth == ADC_BITWIDTH_DEFAULT) ? ADC_BITWIDTH_12 : config->bitwidth; //Initialize fields for lookup table if necessary - if (LUT_ENABLED && config->atten == ADC_ATTEN_DB_11) { + if (LUT_ENABLED && config->atten == ADC_ATTEN_DB_12) { chars->low_curve = (config->unit_id == ADC_UNIT_1) ? lut_adc1_low : lut_adc2_low; chars->high_curve = (config->unit_id == ADC_UNIT_1) ? lut_adc1_high : lut_adc2_high; } else { @@ -251,8 +251,8 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage) raw = ADC_12_BIT_RES - 1; //Set to 12bit res max } - if (LUT_ENABLED && (ctx->atten == ADC_ATTEN_DB_11) && (raw >= LUT_LOW_THRESH)) { //Check if in non-linear region - //Use lookup table to get voltage in non linear portion of ADC_ATTEN_DB_11 + if (LUT_ENABLED && (ctx->atten == ADC_ATTEN_DB_12) && (raw >= LUT_LOW_THRESH)) { //Check if in non-linear region + //Use lookup table to get voltage in non linear portion of ADC_ATTEN_DB_12 uint32_t lut_voltage = calculate_voltage_lut(raw, ctx->vref, ctx->low_curve, ctx->high_curve); if (raw <= LUT_HIGH_THRESH) { //If ADC is transitioning from linear region to non-linear region //Linearly interpolate between linear voltage and lut voltage diff --git a/components/esp_adc/esp32c2/adc_cali_line_fitting.c b/components/esp_adc/esp32c2/adc_cali_line_fitting.c index 3ccf36eba43..c5a7b263cd1 100644 --- a/components/esp_adc/esp32c2/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32c2/adc_cali_line_fitting.c @@ -118,7 +118,7 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage) static esp_err_t check_valid(const adc_cali_line_fitting_config_t *config) { ESP_RETURN_ON_FALSE(config->unit_id < SOC_ADC_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid ADC unit"); - ESP_RETURN_ON_FALSE((config->atten == ADC_ATTEN_DB_0 || config->atten == ADC_ATTEN_DB_11), ESP_ERR_NOT_SUPPORTED, TAG, "only ADC_ATTEN_DB_0 and ADC_ATTEN_DB_11 are supported"); + ESP_RETURN_ON_FALSE((config->atten == ADC_ATTEN_DB_0 || config->atten == ADC_ATTEN_DB_12), ESP_ERR_NOT_SUPPORTED, TAG, "only ADC_ATTEN_DB_0 and ADC_ATTEN_DB_12 are supported"); if (config->atten == ADC_ATTEN_DB_0) { ESP_LOGW(TAG, "Experimental: ADC Atten 0 calibration can now only used for inputs lower than 950mV. Calibration Scheme may get updated, DON'T USE FOR MASS PRODUCTION!"); } diff --git a/components/esp_adc/esp32h2/curve_fitting_coefficients.c b/components/esp_adc/esp32h2/curve_fitting_coefficients.c new file mode 100644 index 00000000000..8ba3f37afc3 --- /dev/null +++ b/components/esp_adc/esp32h2/curve_fitting_coefficients.c @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_efuse_rtc_calib.h" +#include "../curve_fitting_coefficients.h" + +#define COEFF_VERSION_NUM 1 // Currently H2 has one versions of curve calibration schemes +#define COEFF_GROUP_NUM 4 +#define TERM_MAX 3 + +/** + * @note Error Calculation + * Coefficients for calculating the reading voltage error. + * Four sets of coefficients for atten0 ~ atten3 respectively. + * + * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. + * + * @note {0,0} stands for unused item + * @note In case of the overflow, these coefficients are recorded as Absolute Value + * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + * @note For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + * @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. + */ +const static uint64_t adc1_error_coef_atten[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX][2] = { + /* Coefficients of calibration version 1 */ + { + {{5081991760658888, 1e16}, {7858995318513, 1e19}, {0, 1}}, //atten0 + {{8359230818901277, 1e16}, {9025419089179, 1e19}, {0, 1}}, //atten1 + {{1165668771581976, 1e15}, {8294679249061, 1e19}, {0, 1}}, //atten2 + {{3637329628677273, 1e16}, {19607259738935, 1e18}, {7871689227, 1e16}}, //atten3 + }, +}; + +/** + * Term sign + */ +const static int32_t adc1_error_sign[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX] = { + /* Coefficient sign of calibration version 1 */ + { + {-1, 1, 1}, //atten0 + {-1, 1, 1}, //atten1 + {-1, 1, 1}, //atten2 + {-1, -1, 1}, //atten3 + }, +}; + +void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *config, cali_chars_second_step_t *ctx) +{ + uint32_t adc_calib_ver = esp_efuse_rtc_calib_get_ver(); + assert((adc_calib_ver >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (adc_calib_ver <= ESP_EFUSE_ADC_CALIB_VER_MAX)); + + ctx->term_num = 3; + ctx->coeff = adc1_error_coef_atten[VER2IDX(adc_calib_ver)][config->atten]; + ctx->sign = adc1_error_sign[VER2IDX(adc_calib_ver)][config->atten]; +} diff --git a/components/esp_adc/esp32h2/include/adc_cali_schemes.h b/components/esp_adc/esp32h2/include/adc_cali_schemes.h index 16dc6be4f1f..96067994e06 100644 --- a/components/esp_adc/esp32h2/include/adc_cali_schemes.h +++ b/components/esp_adc/esp32h2/include/adc_cali_schemes.h @@ -12,4 +12,4 @@ * @brief Supported calibration schemes */ -//Now no scheme supported +#define ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED 1 diff --git a/components/esp_adc/esp32s2/adc_cali_line_fitting.c b/components/esp_adc/esp32s2/adc_cali_line_fitting.c index 87ec4e7e3ed..2e826e1f08a 100644 --- a/components/esp_adc/esp32s2/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32s2/adc_cali_line_fitting.c @@ -177,7 +177,7 @@ static bool prepare_calib_data_for(adc_unit_t unit_id, adc_atten_t atten, adc_ca case ADC_ATTEN_DB_6: parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 1000; break; - case ADC_ATTEN_DB_11: + case ADC_ATTEN_DB_12: parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 2000; break; default: diff --git a/components/esp_adc/test_apps/.build-test-rules.yml b/components/esp_adc/test_apps/.build-test-rules.yml index 4b1b071e72b..ab0728836d8 100644 --- a/components/esp_adc/test_apps/.build-test-rules.yml +++ b/components/esp_adc/test_apps/.build-test-rules.yml @@ -6,8 +6,8 @@ components/esp_adc/test_apps/adc: - if: CONFIG_NAME == "gdma_iram_safe" and IDF_TARGET in ["esp32", "esp32s2", "esp32c2"] depends_components: - esp_adc + - esp_driver_gpio - efuse depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* # ADC continuous driver relies on SPI on ESP32S2 - components/driver/i2s/**/* # ADC continuous driver relies on I2S on ESP32 diff --git a/components/esp_adc/test_apps/adc/main/CMakeLists.txt b/components/esp_adc/test_apps/adc/main/CMakeLists.txt index cde2d68cc25..8b8cc4b0856 100644 --- a/components/esp_adc/test_apps/adc/main/CMakeLists.txt +++ b/components/esp_adc/test_apps/adc/main/CMakeLists.txt @@ -9,5 +9,5 @@ set(srcs "test_app_main.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} - PRIV_REQUIRES driver esp_wifi nvs_flash esp_adc test_utils efuse + PRIV_REQUIRES esp_driver_gptimer esp_driver_gpio esp_wifi nvs_flash esp_adc test_utils efuse WHOLE_ARCHIVE) diff --git a/components/esp_adc/test_apps/adc/main/test_adc.c b/components/esp_adc/test_apps/adc/main/test_adc.c index 30230fa4c29..f568dde6c72 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc.c +++ b/components/esp_adc/test_apps/adc/main/test_adc.c @@ -15,6 +15,7 @@ #include "driver/gpio.h" #include "driver/rtc_io.h" #include "test_common_adc.h" +#include "esp_rom_sys.h" const __attribute__((unused)) static char *TAG = "TEST_ADC"; @@ -65,7 +66,7 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]") //-------------ADC1 TEST Channel 0 Config---------------// adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, ADC1_TEST_CHAN0, &config)); @@ -117,6 +118,44 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]") #endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2 } +TEST_CASE("ADC oneshot stress test that get zero even if convent done", "[adc_oneshot]") +{ + //There is a hardware limitation. After ADC get DONE signal, it still need a delay to synchronize ADC raw data or it may get zero even if getting DONE signal. + + int test_num = 100; + adc_channel_t channel = ADC1_TEST_CHAN1; + adc_atten_t atten = ADC_ATTEN_DB_12; + adc_unit_t unit_id = ADC_UNIT_1; + + adc_oneshot_unit_handle_t adc1_handle; + adc_oneshot_unit_init_cfg_t init_config1 = { + .unit_id = unit_id, + .ulp_mode = ADC_ULP_MODE_DISABLE, + }; + + adc_oneshot_chan_cfg_t config = { + .bitwidth = SOC_ADC_RTC_MAX_BITWIDTH, + .atten = atten, + }; + + int raw_data = 0; + srand(199); + + for (int i = 0; i < test_num; i++) { + test_adc_set_io_level(unit_id, ADC1_TEST_CHAN1, 1); + + TEST_ESP_OK(adc_oneshot_new_unit(&init_config1, &adc1_handle)); + TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, channel, &config)); + TEST_ESP_OK(adc_oneshot_read(adc1_handle, channel, &raw_data)); + + TEST_ASSERT_NOT_EQUAL(0, raw_data); + + TEST_ESP_OK(adc_oneshot_del_unit(adc1_handle)); + + esp_rom_delay_us(rand() % 512); + } +} + #if SOC_ADC_CALIBRATION_V1_SUPPORTED /*--------------------------------------------------------------- ADC Oneshot with Light Sleep @@ -283,7 +322,7 @@ TEST_CASE("ADC continuous monitor init_deinit", "[adc]") adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0}; for (int i = 0; i < 1; i++) { - adc_pattern[i].atten = ADC_ATTEN_DB_11; + adc_pattern[i].atten = ADC_ATTEN_DB_12; adc_pattern[i].channel = i; adc_pattern[i].unit = ADC_UNIT_1; adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; @@ -401,7 +440,7 @@ TEST_CASE("ADC continuous monitor functionary", "[adc][manual][ignore]") adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0}; for (int i = 0; i < 2; i++) { - adc_pattern[i].atten = ADC_ATTEN_DB_11; + adc_pattern[i].atten = ADC_ATTEN_DB_12; adc_pattern[i].channel = TEST_ADC_CHANNEL; adc_pattern[i].unit = ADC_UNIT_1; adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; diff --git a/components/esp_adc/test_apps/adc/main/test_adc_driver.c b/components/esp_adc/test_apps/adc/main/test_adc_driver.c index a38f4270fe8..913820bd771 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_driver.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_driver.c @@ -80,7 +80,7 @@ TEST_CASE("ADC oneshot fast work with ISR", "[adc_oneshot]") //-------------ADC1 TEST Channel 0 Config---------------// adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; TEST_ESP_OK(adc_oneshot_config_channel(isr_test_ctx.oneshot_handle, ADC1_TEST_CHAN0, &config)); @@ -171,7 +171,7 @@ TEST_CASE("ADC continuous big conv_frame_size test", "[adc_continuous]") .format = ADC_DRIVER_TEST_OUTPUT_TYPE, }; adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0}; - adc_pattern[0].atten = ADC_ATTEN_DB_11; + adc_pattern[0].atten = ADC_ATTEN_DB_12; adc_pattern[0].channel = ADC1_TEST_CHAN0; adc_pattern[0].unit = ADC_UNIT_1; adc_pattern[0].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; @@ -229,7 +229,7 @@ TEST_CASE("ADC continuous flush internal pool", "[adc_continuous][mannual][ignor .format = ADC_DRIVER_TEST_OUTPUT_TYPE, }; adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0}; - adc_pattern[0].atten = ADC_ATTEN_DB_11; + adc_pattern[0].atten = ADC_ATTEN_DB_12; adc_pattern[0].channel = ADC1_TEST_CHAN0; adc_pattern[0].unit = ADC_UNIT_1; adc_pattern[0].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; diff --git a/components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c b/components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c index a69d4fcf76b..59c86a60429 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c @@ -84,7 +84,7 @@ TEST_CASE("ADC oneshot fast work with ISR and Flash", "[adc_oneshot]") //-------------ADC1 TEST Channel 0 Config---------------// adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; TEST_ESP_OK(adc_oneshot_config_channel(oneshot_handle, ADC1_TEST_CHAN0, &config)); diff --git a/components/esp_adc/test_apps/adc/main/test_adc_performance.c b/components/esp_adc/test_apps/adc/main/test_adc_performance.c index e0da5d9aef5..82ef8dde078 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_performance.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_performance.c @@ -269,29 +269,29 @@ TEST_CASE("ADC1 continuous raw average and std_deviation", "[adc_continuous][man TEST_CASE("ADC1 continuous std deviation performance, no filter", "[adc_continuous][performance]") { - float std = test_adc_continuous_std(ADC_ATTEN_DB_11, false, 0, true); + float std = test_adc_continuous_std(ADC_ATTEN_DB_12, false, 0, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER, "%.2f", std); } #if SOC_ADC_DIG_IIR_FILTER_SUPPORTED TEST_CASE("ADC1 continuous std deviation performance, with filter", "[adc_continuous][performance]") { - float std = test_adc_continuous_std(ADC_ATTEN_DB_11, false, 0, true); + float std = test_adc_continuous_std(ADC_ATTEN_DB_12, false, 0, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_2, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_2, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_2, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_4, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_4, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_4, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_8, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_8, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_8, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_16, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_16, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_16, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_64, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_64, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_64, "%.2f", std); } #endif //#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED @@ -375,7 +375,7 @@ TEST_CASE("ADC1 oneshot raw average and std_deviation", "[adc_oneshot][manual]") TEST_CASE("ADC1 oneshot std_deviation performance", "[adc_oneshot][performance]") { - float std = test_adc_oneshot_std(ADC_ATTEN_DB_11, true); + float std = test_adc_oneshot_std(ADC_ATTEN_DB_12, true); TEST_PERFORMANCE_LESS_THAN(ADC_ONESHOT_STD_ATTEN3, "%.2f", std); } /*--------------------------------------------------------------- diff --git a/components/esp_adc/test_apps/adc/main/test_adc_wifi.c b/components/esp_adc/test_apps/adc/main/test_adc_wifi.c index a967fcf9f8b..b236f8ea2db 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_wifi.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_wifi.c @@ -170,7 +170,7 @@ __attribute__((unused)) static void adc_work_with_wifi(adc_unit_t unit_id, adc_c //-------------ADC TEST Channel Config---------------// adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; TEST_ESP_OK(adc_oneshot_config_channel(adc_handle, channel, &config)); 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 7212d849c96..7cf974c43f5 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 @@ -20,9 +20,9 @@ __attribute__((unused)) static const char *TAG = "TEST_ADC"; ADC Attenuation ---------------------------------------------------------------*/ #if CONFIG_IDF_TARGET_ESP32C2 -adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_11}; +adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_12}; #else -adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_2_5, ADC_ATTEN_DB_6, ADC_ATTEN_DB_11}; +adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_2_5, ADC_ATTEN_DB_6, ADC_ATTEN_DB_12}; #endif #if SOC_ADC_DIG_IIR_FILTER_SUPPORTED 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 742b536aa95..5228713af93 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-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -79,11 +79,11 @@ extern "C" { #define ADC_TEST_HIGH_VAL_DMA 4081 #define ADC_TEST_HIGH_THRESH 200 -#elif CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6216 -#define ADC_TEST_LOW_VAL 2144 -#define ADC_TEST_LOW_THRESH 200 +#elif CONFIG_IDF_TARGET_ESP32H2 +#define ADC_TEST_LOW_VAL 0 +#define ADC_TEST_LOW_THRESH 17 -#define ADC_TEST_HIGH_VAL 4081 +#define ADC_TEST_HIGH_VAL 3390 #define ADC_TEST_HIGH_VAL_DMA 4081 #define ADC_TEST_HIGH_THRESH 200 #endif diff --git a/components/esp_coex/lib b/components/esp_coex/lib index ad378ec993c..68cbbdb45cd 160000 --- a/components/esp_coex/lib +++ b/components/esp_coex/lib @@ -1 +1 @@ -Subproject commit ad378ec993cde453b0c93439aa4dbcd317970ccf +Subproject commit 68cbbdb45cdc8c88ffbfc2587a4e7af020695e56 diff --git a/components/esp_common/include/esp_idf_version.h b/components/esp_common/include/esp_idf_version.h index cc68d2d1329..4cb488257a4 100644 --- a/components/esp_common/include/esp_idf_version.h +++ b/components/esp_common/include/esp_idf_version.h @@ -13,7 +13,7 @@ extern "C" { /** Major version number (X.x.x) */ #define ESP_IDF_VERSION_MAJOR 5 /** Minor version number (x.X.x) */ -#define ESP_IDF_VERSION_MINOR 2 +#define ESP_IDF_VERSION_MINOR 3 /** Patch version number (x.x.X) */ #define ESP_IDF_VERSION_PATCH 0 diff --git a/components/esp_driver_gpio/CMakeLists.txt b/components/esp_driver_gpio/CMakeLists.txt new file mode 100644 index 00000000000..dce1295124c --- /dev/null +++ b/components/esp_driver_gpio/CMakeLists.txt @@ -0,0 +1,33 @@ +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 "src/gpio.c" + "src/gpio_glitch_filter_ops.c" + "src/rtc_io.c" + ) +set(public_include "include") + +if(CONFIG_SOC_DEDICATED_GPIO_SUPPORTED) + list(APPEND srcs "src/dedic_gpio.c") +endif() + +if(CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER) + list(APPEND srcs "src/gpio_pin_glitch_filter.c") +endif() + +if(CONFIG_SOC_GPIO_FLEX_GLITCH_FILTER_NUM GREATER 0) + list(APPEND srcs "src/gpio_flex_glitch_filter.c") +endif() + +if(CONFIG_SOC_GPIO_SUPPORT_ETM) + list(APPEND srcs "src/gpio_etm.c") +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${public_include} + PRIV_REQUIRES esp_pm + LDFRAGMENTS "linker.lf" + ) diff --git a/components/esp_driver_gpio/Kconfig b/components/esp_driver_gpio/Kconfig new file mode 100644 index 00000000000..36d2b13794a --- /dev/null +++ b/components/esp_driver_gpio/Kconfig @@ -0,0 +1,17 @@ +menu "ESP-Driver:GPIO Configurations" + config GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL + bool "Support light sleep GPIO pullup/pulldown configuration for ESP32" + depends on IDF_TARGET_ESP32 + help + This option is intended to fix the bug that ESP32 is not able to switch to configured + pullup/pulldown mode in sleep. + If this option is selected, chip will automatically emulate the behaviour of switching, + and about 450B of source codes would be placed into IRAM. + + config GPIO_CTRL_FUNC_IN_IRAM + bool "Place GPIO control functions into IRAM" + default n + help + Place GPIO control functions (like intr_disable/set_level) into IRAM, + so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. +endmenu diff --git a/components/driver/gpio/include/driver/dedic_gpio.h b/components/esp_driver_gpio/include/driver/dedic_gpio.h similarity index 100% rename from components/driver/gpio/include/driver/dedic_gpio.h rename to components/esp_driver_gpio/include/driver/dedic_gpio.h diff --git a/components/driver/gpio/include/driver/gpio.h b/components/esp_driver_gpio/include/driver/gpio.h similarity index 100% rename from components/driver/gpio/include/driver/gpio.h rename to components/esp_driver_gpio/include/driver/gpio.h diff --git a/components/driver/gpio/include/driver/gpio_etm.h b/components/esp_driver_gpio/include/driver/gpio_etm.h similarity index 100% rename from components/driver/gpio/include/driver/gpio_etm.h rename to components/esp_driver_gpio/include/driver/gpio_etm.h diff --git a/components/driver/gpio/include/driver/gpio_filter.h b/components/esp_driver_gpio/include/driver/gpio_filter.h similarity index 100% rename from components/driver/gpio/include/driver/gpio_filter.h rename to components/esp_driver_gpio/include/driver/gpio_filter.h diff --git a/components/driver/gpio/include/driver/lp_io.h b/components/esp_driver_gpio/include/driver/lp_io.h similarity index 100% rename from components/driver/gpio/include/driver/lp_io.h rename to components/esp_driver_gpio/include/driver/lp_io.h diff --git a/components/driver/gpio/include/driver/rtc_io.h b/components/esp_driver_gpio/include/driver/rtc_io.h similarity index 99% rename from components/driver/gpio/include/driver/rtc_io.h rename to components/esp_driver_gpio/include/driver/rtc_io.h index 4e9c2d0e3c2..27a161d6555 100644 --- a/components/driver/gpio/include/driver/rtc_io.h +++ b/components/esp_driver_gpio/include/driver/rtc_io.h @@ -13,7 +13,6 @@ #include "hal/rtc_io_types.h" #include "driver/gpio.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/components/driver/gpio/glitch_filter_priv.h b/components/esp_driver_gpio/include/esp_private/glitch_filter_priv.h similarity index 100% rename from components/driver/gpio/glitch_filter_priv.h rename to components/esp_driver_gpio/include/esp_private/glitch_filter_priv.h diff --git a/components/driver/include/esp_private/gpio.h b/components/esp_driver_gpio/include/esp_private/gpio.h similarity index 100% rename from components/driver/include/esp_private/gpio.h rename to components/esp_driver_gpio/include/esp_private/gpio.h diff --git a/components/driver/gpio/linker.lf b/components/esp_driver_gpio/linker.lf similarity index 80% rename from components/driver/gpio/linker.lf rename to components/esp_driver_gpio/linker.lf index 4ca65040df7..46d901a627c 100644 --- a/components/driver/gpio/linker.lf +++ b/components/esp_driver_gpio/linker.lf @@ -1,9 +1,10 @@ [mapping:gpio_driver] -archive: libdriver.a +archive: libesp_driver_gpio.a entries: if GPIO_CTRL_FUNC_IN_IRAM = y: gpio: gpio_set_level (noflash) gpio: gpio_intr_disable (noflash) + gpio: gpio_get_level (noflash) [mapping:gpio_hal] archive: libhal.a diff --git a/components/driver/gpio/dedic_gpio.c b/components/esp_driver_gpio/src/dedic_gpio.c similarity index 99% rename from components/driver/gpio/dedic_gpio.c rename to components/esp_driver_gpio/src/dedic_gpio.c index b6ddc8e6d1a..077efff88e1 100644 --- a/components/driver/gpio/dedic_gpio.c +++ b/components/esp_driver_gpio/src/dedic_gpio.c @@ -31,7 +31,6 @@ #include "hal/dedic_gpio_ll.h" #endif - static const char *TAG = "dedic_gpio"; typedef struct dedic_gpio_platform_t dedic_gpio_platform_t; @@ -313,7 +312,7 @@ esp_err_t dedic_gpio_del_bundle(dedic_gpio_bundle_handle_t bundle) s_platform[core_id]->out_occupied_mask &= ~(bundle->out_mask); s_platform[core_id]->in_occupied_mask &= ~(bundle->in_mask); if (s_platform[core_id]->in_occupied_mask == (UINT32_MAX & ~((1 << SOC_DEDIC_GPIO_IN_CHANNELS_NUM) - 1)) && - s_platform[core_id]->out_occupied_mask == (UINT32_MAX & ~((1 << SOC_DEDIC_GPIO_OUT_CHANNELS_NUM) - 1))) { + s_platform[core_id]->out_occupied_mask == (UINT32_MAX & ~((1 << SOC_DEDIC_GPIO_OUT_CHANNELS_NUM) - 1))) { recycle_all = true; } portEXIT_CRITICAL(&s_platform[core_id]->spinlock); @@ -349,7 +348,6 @@ esp_err_t dedic_gpio_get_in_mask(dedic_gpio_bundle_handle_t bundle, uint32_t *ma return ret; } - esp_err_t dedic_gpio_get_out_offset(dedic_gpio_bundle_handle_t bundle, uint32_t *offset) { esp_err_t ret = ESP_OK; diff --git a/components/driver/gpio/gpio.c b/components/esp_driver_gpio/src/gpio.c similarity index 94% rename from components/driver/gpio/gpio.c rename to components/esp_driver_gpio/src/gpio.c index e1d81a2b3e2..3e09f30a60e 100644 --- a/components/driver/gpio/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -10,8 +10,7 @@ #include "esp_heap_caps.h" #include "driver/gpio.h" #include "driver/rtc_io.h" -#include "soc/soc.h" -#include "soc/periph_defs.h" +#include "soc/interrupts.h" #if !CONFIG_FREERTOS_UNICORE #include "esp_ipc.h" #endif @@ -166,7 +165,7 @@ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) return ESP_OK; } -static esp_err_t gpio_intr_enable_on_core(gpio_num_t gpio_num, uint32_t core_id) +static inline esp_err_t gpio_intr_enable_on_core(gpio_num_t gpio_num, uint32_t core_id) { gpio_hal_intr_enable_on_core(gpio_context.gpio_hal, gpio_num, core_id); return ESP_OK; @@ -176,11 +175,11 @@ esp_err_t gpio_intr_enable(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&gpio_context.gpio_spinlock); - if(gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) { + if (gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) { gpio_context.isr_core_id = xPortGetCoreID(); } portEXIT_CRITICAL(&gpio_context.gpio_spinlock); - return gpio_intr_enable_on_core (gpio_num, gpio_context.isr_core_id); + return gpio_intr_enable_on_core(gpio_num, gpio_context.isr_core_id); } esp_err_t gpio_intr_disable(gpio_num_t gpio_num) @@ -274,30 +273,30 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) esp_err_t ret = ESP_OK; switch (pull) { - case GPIO_PULLUP_ONLY: - gpio_pulldown_dis(gpio_num); - gpio_pullup_en(gpio_num); - break; - - case GPIO_PULLDOWN_ONLY: - gpio_pulldown_en(gpio_num); - gpio_pullup_dis(gpio_num); - break; - - case GPIO_PULLUP_PULLDOWN: - gpio_pulldown_en(gpio_num); - gpio_pullup_en(gpio_num); - break; - - case GPIO_FLOATING: - gpio_pulldown_dis(gpio_num); - gpio_pullup_dis(gpio_num); - break; - - default: - ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull); - ret = ESP_ERR_INVALID_ARG; - break; + case GPIO_PULLUP_ONLY: + gpio_pulldown_dis(gpio_num); + gpio_pullup_en(gpio_num); + break; + + case GPIO_PULLDOWN_ONLY: + gpio_pulldown_en(gpio_num); + gpio_pullup_dis(gpio_num); + break; + + case GPIO_PULLUP_PULLDOWN: + gpio_pulldown_en(gpio_num); + gpio_pullup_en(gpio_num); + break; + + case GPIO_FLOATING: + gpio_pulldown_dis(gpio_num); + gpio_pullup_dis(gpio_num); + break; + + default: + ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull); + ret = ESP_ERR_INVALID_ARG; + break; } return ret; @@ -347,13 +346,13 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig) uint8_t pd_en = 0; if (pGPIOConfig->pin_bit_mask == 0 || - pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_GPIO_MASK) { + pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_GPIO_MASK) { ESP_LOGE(GPIO_TAG, "GPIO_PIN mask error "); return ESP_ERR_INVALID_ARG; } if (pGPIOConfig->mode & GPIO_MODE_DEF_OUTPUT && - pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_OUTPUT_GPIO_MASK) { + pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_OUTPUT_GPIO_MASK) { ESP_LOGE(GPIO_TAG, "GPIO can only be used as input mode"); return ESP_ERR_INVALID_ARG; } @@ -538,7 +537,7 @@ esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void gpio_context.gpio_isr_func[gpio_num].fn = isr_handler; gpio_context.gpio_isr_func[gpio_num].args = args; } - gpio_intr_enable_on_core (gpio_num, esp_intr_get_cpu(gpio_context.gpio_isr_handle)); + gpio_intr_enable_on_core(gpio_num, esp_intr_get_cpu(gpio_context.gpio_isr_handle)); portEXIT_CRITICAL(&gpio_context.gpio_spinlock); return ESP_OK; } @@ -577,7 +576,6 @@ void gpio_uninstall_isr_service(void) return; } - static void gpio_isr_register_on_core_static(void *param) { gpio_isr_alloc_t *p = (gpio_isr_alloc_t *)param; @@ -602,7 +600,7 @@ esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, p.arg = arg; p.handle = handle; portENTER_CRITICAL(&gpio_context.gpio_spinlock); - if(gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) { + if (gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) { gpio_context.isr_core_id = xPortGetCoreID(); } portEXIT_CRITICAL(&gpio_context.gpio_spinlock); @@ -739,7 +737,7 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num) #if SOC_RTCIO_HOLD_SUPPORTED ret = rtc_gpio_hold_dis(gpio_num); #endif - }else if (GPIO_HOLD_MASK[gpio_num]) { + } else if (GPIO_HOLD_MASK[gpio_num]) { portENTER_CRITICAL(&gpio_context.gpio_spinlock); gpio_hal_hold_dis(gpio_context.gpio_hal, gpio_num); portEXIT_CRITICAL(&gpio_context.gpio_spinlock); @@ -905,30 +903,30 @@ esp_err_t gpio_sleep_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) esp_err_t ret = ESP_OK; switch (pull) { - case GPIO_PULLUP_ONLY: - gpio_sleep_pulldown_dis(gpio_num); - gpio_sleep_pullup_en(gpio_num); - break; - - case GPIO_PULLDOWN_ONLY: - gpio_sleep_pulldown_en(gpio_num); - gpio_sleep_pullup_dis(gpio_num); - break; - - case GPIO_PULLUP_PULLDOWN: - gpio_sleep_pulldown_en(gpio_num); - gpio_sleep_pullup_en(gpio_num); - break; - - case GPIO_FLOATING: - gpio_sleep_pulldown_dis(gpio_num); - gpio_sleep_pullup_dis(gpio_num); - break; - - default: - ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull); - ret = ESP_ERR_INVALID_ARG; - break; + case GPIO_PULLUP_ONLY: + gpio_sleep_pulldown_dis(gpio_num); + gpio_sleep_pullup_en(gpio_num); + break; + + case GPIO_PULLDOWN_ONLY: + gpio_sleep_pulldown_en(gpio_num); + gpio_sleep_pullup_dis(gpio_num); + break; + + case GPIO_PULLUP_PULLDOWN: + gpio_sleep_pulldown_en(gpio_num); + gpio_sleep_pullup_en(gpio_num); + break; + + case GPIO_FLOATING: + gpio_sleep_pulldown_dis(gpio_num); + gpio_sleep_pullup_dis(gpio_num); + break; + + default: + ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull); + ret = ESP_ERR_INVALID_ARG; + break; } return ret; diff --git a/components/driver/gpio/gpio_etm.c b/components/esp_driver_gpio/src/gpio_etm.c similarity index 100% rename from components/driver/gpio/gpio_etm.c rename to components/esp_driver_gpio/src/gpio_etm.c diff --git a/components/driver/gpio/gpio_flex_glitch_filter.c b/components/esp_driver_gpio/src/gpio_flex_glitch_filter.c similarity index 99% rename from components/driver/gpio/gpio_flex_glitch_filter.c rename to components/esp_driver_gpio/src/gpio_flex_glitch_filter.c index 8a0138e46f2..1c16b100949 100644 --- a/components/driver/gpio/gpio_flex_glitch_filter.c +++ b/components/esp_driver_gpio/src/gpio_flex_glitch_filter.c @@ -7,7 +7,7 @@ #include #include "freertos/FreeRTOS.h" #include "esp_check.h" -#include "glitch_filter_priv.h" +#include "esp_private/glitch_filter_priv.h" #include "esp_private/io_mux.h" #include "soc/soc_caps.h" #include "hal/gpio_glitch_filter_ll.h" diff --git a/components/driver/gpio/gpio_glitch_filter_ops.c b/components/esp_driver_gpio/src/gpio_glitch_filter_ops.c similarity index 94% rename from components/driver/gpio/gpio_glitch_filter_ops.c rename to components/esp_driver_gpio/src/gpio_glitch_filter_ops.c index 841d0953260..001968575d4 100644 --- a/components/driver/gpio/gpio_glitch_filter_ops.c +++ b/components/esp_driver_gpio/src/gpio_glitch_filter_ops.c @@ -5,7 +5,7 @@ */ #include "esp_check.h" -#include "glitch_filter_priv.h" +#include "esp_private/glitch_filter_priv.h" static const char *TAG = "gpio-filter"; diff --git a/components/driver/gpio/gpio_pin_glitch_filter.c b/components/esp_driver_gpio/src/gpio_pin_glitch_filter.c similarity index 98% rename from components/driver/gpio/gpio_pin_glitch_filter.c rename to components/esp_driver_gpio/src/gpio_pin_glitch_filter.c index 877f345e4f9..3778becfe7d 100644 --- a/components/driver/gpio/gpio_pin_glitch_filter.c +++ b/components/esp_driver_gpio/src/gpio_pin_glitch_filter.c @@ -8,7 +8,7 @@ #include "freertos/FreeRTOS.h" #include "esp_check.h" #include "esp_pm.h" -#include "glitch_filter_priv.h" +#include "esp_private/glitch_filter_priv.h" #include "hal/gpio_ll.h" #include "esp_clk_tree.h" #include "esp_private/io_mux.h" diff --git a/components/driver/gpio/rtc_io.c b/components/esp_driver_gpio/src/rtc_io.c similarity index 100% rename from components/driver/gpio/rtc_io.c rename to components/esp_driver_gpio/src/rtc_io.c diff --git a/components/esp_driver_gpio/test_apps/.build-test-rules.yml b/components/esp_driver_gpio/test_apps/.build-test-rules.yml new file mode 100644 index 00000000000..13e104d9c9a --- /dev/null +++ b/components/esp_driver_gpio/test_apps/.build-test-rules.yml @@ -0,0 +1,10 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/esp_driver_gpio/test_apps: + depends_components: + - esp_driver_gpio + +components/esp_driver_gpio/test_apps/gpio_extensions: + enable: + - if: SOC_DEDICATED_GPIO_SUPPORTED == 1 + - if: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER == 1 or SOC_GPIO_FLEX_GLITCH_FILTER_NUM > 0 diff --git a/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt new file mode 100644 index 00000000000..886e85131ab --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt @@ -0,0 +1,21 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +# "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(gpio_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_driver_gpio/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --elf-file ${CMAKE_BINARY_DIR}/gpio_test.elf + find-refs + --from-sections=.iram0.text + --to-sections=.flash.text,.flash.rodata + --exit-code + DEPENDS ${elf} + ) +endif() diff --git a/components/driver/test_apps/gpio/README.md b/components/esp_driver_gpio/test_apps/gpio/README.md similarity index 100% rename from components/driver/test_apps/gpio/README.md rename to components/esp_driver_gpio/test_apps/gpio/README.md diff --git a/components/driver/test_apps/gpio/main/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio/main/CMakeLists.txt similarity index 69% rename from components/driver/test_apps/gpio/main/CMakeLists.txt rename to components/esp_driver_gpio/test_apps/gpio/main/CMakeLists.txt index de29a112f9b..54bda14eae0 100644 --- a/components/driver/test_apps/gpio/main/CMakeLists.txt +++ b/components/esp_driver_gpio/test_apps/gpio/main/CMakeLists.txt @@ -1,10 +1,6 @@ set(srcs "test_app_main.c" "test_gpio.c") -if(CONFIG_SOC_SDM_SUPPORTED) - list(APPEND srcs "test_sigma_delta_legacy.c") -endif() - if(CONFIG_SOC_RTCIO_PIN_COUNT GREATER 0) list(APPEND srcs "test_rtcio.c") endif() @@ -12,5 +8,5 @@ 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 driver spi_flash + PRIV_REQUIRES unity esp_driver_gpio spi_flash WHOLE_ARCHIVE) diff --git a/components/esp_driver_gpio/test_apps/gpio/main/test_app_main.c b/components/esp_driver_gpio/test_apps/gpio/main/test_app_main.c new file mode 100644 index 00000000000..bb65240ed5f --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio/main/test_app_main.c @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "unity_test_utils.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in gpio/rtcio driver, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (100) + +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) +{ + unity_run_menu(); +} diff --git a/components/driver/test_apps/gpio/main/test_gpio.c b/components/esp_driver_gpio/test_apps/gpio/main/test_gpio.c similarity index 100% rename from components/driver/test_apps/gpio/main/test_gpio.c rename to components/esp_driver_gpio/test_apps/gpio/main/test_gpio.c diff --git a/components/driver/test_apps/gpio/main/test_gpio.h b/components/esp_driver_gpio/test_apps/gpio/main/test_gpio.h similarity index 100% rename from components/driver/test_apps/gpio/main/test_gpio.h rename to components/esp_driver_gpio/test_apps/gpio/main/test_gpio.h diff --git a/components/driver/test_apps/gpio/main/test_rtcio.c b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c similarity index 80% rename from components/driver/test_apps/gpio/main/test_rtcio.c rename to components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c index 346d774b13c..fcc12b8a97e 100644 --- a/components/driver/test_apps/gpio/main/test_rtcio.c +++ b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c @@ -36,10 +36,10 @@ TEST_CASE("RTCIO_input/output_test", "[rtcio]") // init rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_init(i) ); - RTCIO_CHECK( rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT) ); - RTCIO_CHECK( rtc_gpio_pullup_dis(i) ); - RTCIO_CHECK( rtc_gpio_pulldown_dis(i) ); + RTCIO_CHECK(rtc_gpio_init(i)); + RTCIO_CHECK(rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT)); + RTCIO_CHECK(rtc_gpio_pullup_dis(i)); + RTCIO_CHECK(rtc_gpio_pulldown_dis(i)); ESP_LOGI(TAG, "gpio %d init", i); } } @@ -49,7 +49,7 @@ TEST_CASE("RTCIO_input/output_test", "[rtcio]") ESP_LOGI(TAG, "RTCIO output level %d", level); for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_set_level(i, level) ); + RTCIO_CHECK(rtc_gpio_set_level(i, level)); vTaskDelay(10 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(i) != level) { ESP_LOGE(TAG, "RTCIO input/output test err, gpio%d", i); @@ -63,7 +63,7 @@ TEST_CASE("RTCIO_input/output_test", "[rtcio]") // Deinit rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_deinit(i) ); + RTCIO_CHECK(rtc_gpio_deinit(i)); } } ESP_LOGI(TAG, "RTCIO input/output test over"); @@ -81,10 +81,10 @@ TEST_CASE("RTCIO_pullup/pulldown_test", "[rtcio]") for (int i = 0; i < TEST_GPIO_PIN_COUNT; i++) { int num = rtc_io_number_get(s_test_map[i]); if (rtc_gpio_is_valid_gpio(s_test_map[i]) && num > 0 && RTCIO_SUPPORT_PU_PD(num)) { - RTCIO_CHECK( rtc_gpio_init(s_test_map[i]) ); - RTCIO_CHECK( rtc_gpio_set_direction(s_test_map[i], RTC_GPIO_MODE_INPUT_ONLY) ); - RTCIO_CHECK( rtc_gpio_pullup_dis(s_test_map[i]) ); - RTCIO_CHECK( rtc_gpio_pulldown_dis(s_test_map[i]) ); + RTCIO_CHECK(rtc_gpio_init(s_test_map[i])); + RTCIO_CHECK(rtc_gpio_set_direction(s_test_map[i], RTC_GPIO_MODE_INPUT_ONLY)); + RTCIO_CHECK(rtc_gpio_pullup_dis(s_test_map[i])); + RTCIO_CHECK(rtc_gpio_pulldown_dis(s_test_map[i])); ESP_LOGI(TAG, "gpio %d init", s_test_map[i]); } } @@ -96,11 +96,11 @@ TEST_CASE("RTCIO_pullup/pulldown_test", "[rtcio]") int num = rtc_io_number_get(s_test_map[i]); if (rtc_gpio_is_valid_gpio(s_test_map[i]) && num > 0 && RTCIO_SUPPORT_PU_PD(num)) { if (level) { - RTCIO_CHECK( rtc_gpio_pulldown_dis(s_test_map[i]) ); - RTCIO_CHECK( rtc_gpio_pullup_en(s_test_map[i]) ); + RTCIO_CHECK(rtc_gpio_pulldown_dis(s_test_map[i])); + RTCIO_CHECK(rtc_gpio_pullup_en(s_test_map[i])); } else { - RTCIO_CHECK( rtc_gpio_pullup_dis(s_test_map[i]) ); - RTCIO_CHECK( rtc_gpio_pulldown_en(s_test_map[i]) ); + RTCIO_CHECK(rtc_gpio_pullup_dis(s_test_map[i])); + RTCIO_CHECK(rtc_gpio_pulldown_en(s_test_map[i])); } vTaskDelay(20 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(s_test_map[i]) != level) { @@ -116,7 +116,7 @@ TEST_CASE("RTCIO_pullup/pulldown_test", "[rtcio]") for (int i = 0; i < TEST_GPIO_PIN_COUNT; i++) { int num = rtc_io_number_get(s_test_map[i]); if (rtc_gpio_is_valid_gpio(s_test_map[i]) && num > 0 && RTCIO_SUPPORT_PU_PD(num)) { - RTCIO_CHECK( rtc_gpio_deinit(s_test_map[i]) ); + RTCIO_CHECK(rtc_gpio_deinit(s_test_map[i])); } } ESP_LOGI(TAG, "RTCIO pullup/pulldown test over"); @@ -132,10 +132,10 @@ TEST_CASE("RTCIO_output_OD_test", "[rtcio]") // init rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_init(i) ); - RTCIO_CHECK( rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD) ); - RTCIO_CHECK( rtc_gpio_pullup_en(i) ); - RTCIO_CHECK( rtc_gpio_pulldown_dis(i) ); + RTCIO_CHECK(rtc_gpio_init(i)); + RTCIO_CHECK(rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD)); + RTCIO_CHECK(rtc_gpio_pullup_en(i)); + RTCIO_CHECK(rtc_gpio_pulldown_dis(i)); ESP_LOGI(TAG, "gpio %d init", i); } } @@ -145,7 +145,7 @@ TEST_CASE("RTCIO_output_OD_test", "[rtcio]") ESP_LOGI(TAG, "RTCIO output level %d", level); for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_set_level(i, level) ); + RTCIO_CHECK(rtc_gpio_set_level(i, level)); vTaskDelay(10 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(i) != level) { ESP_LOGE(TAG, "RTCIO output OD test err, gpio%d", i); @@ -159,7 +159,7 @@ TEST_CASE("RTCIO_output_OD_test", "[rtcio]") // Deinit rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_deinit(i) ); + RTCIO_CHECK(rtc_gpio_deinit(i)); } } ESP_LOGI(TAG, "RTCIO output OD test over"); @@ -176,11 +176,11 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") // init rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_init(i) ); - RTCIO_CHECK( rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD) ); - RTCIO_CHECK( rtc_gpio_pullup_en(i) ); - RTCIO_CHECK( rtc_gpio_pulldown_dis(i) ); - RTCIO_CHECK( rtc_gpio_set_level(i, 1) ); + RTCIO_CHECK(rtc_gpio_init(i)); + RTCIO_CHECK(rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD)); + RTCIO_CHECK(rtc_gpio_pullup_en(i)); + RTCIO_CHECK(rtc_gpio_pulldown_dis(i)); + RTCIO_CHECK(rtc_gpio_set_level(i, 1)); ESP_LOGI(TAG, "gpio %d init, level 1", i); } } @@ -188,9 +188,9 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") // hold all output rtcio. for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_hold_en(i) ); + RTCIO_CHECK(rtc_gpio_hold_en(i)); vTaskDelay(10 / portTICK_PERIOD_MS); - RTCIO_CHECK( rtc_gpio_set_level(i, 0) ); + RTCIO_CHECK(rtc_gpio_set_level(i, 0)); ESP_LOGI(TAG, "RTCIO output pin hold, then set level 0"); vTaskDelay(10 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(i) == 0) { @@ -203,7 +203,7 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") // unhold all rtcio. for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_hold_dis(i) ); + RTCIO_CHECK(rtc_gpio_hold_dis(i)); } } @@ -213,7 +213,7 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") ESP_LOGI(TAG, "RTCIO output level %d", level); for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_set_level(i, level) ); + RTCIO_CHECK(rtc_gpio_set_level(i, level)); vTaskDelay(10 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(i) != level) { ESP_LOGE(TAG, "RTCIO output OD test err, gpio%d", i); @@ -227,7 +227,7 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") // Deinit rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_deinit(i) ); + RTCIO_CHECK(rtc_gpio_deinit(i)); } } ESP_LOGI(TAG, "RTCIO hold test over"); @@ -282,6 +282,6 @@ static void rtcio_deep_sleep_hold_test_second_stage(void) * please use logic analyzer or oscilloscope */ TEST_CASE_MULTIPLE_STAGES("RTCIO_deep_sleep_output_hold_test", "[rtcio]", - rtcio_deep_sleep_hold_test_first_stage, - rtcio_deep_sleep_hold_test_second_stage) + rtcio_deep_sleep_hold_test_first_stage, + rtcio_deep_sleep_hold_test_second_stage) #endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) diff --git a/components/driver/test_apps/gpio/main/test_rtcio.h b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h similarity index 100% rename from components/driver/test_apps/gpio/main/test_rtcio.h rename to components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h diff --git a/components/driver/test_apps/gpio/pytest_gpio.py b/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py similarity index 69% rename from components/driver/test_apps/gpio/pytest_gpio.py rename to components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py index f0682a007d2..09cba420440 100644 --- a/components/driver/test_apps/gpio/pytest_gpio.py +++ b/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py @@ -17,18 +17,6 @@ def test_gpio(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='gpio') -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS, indirect=True) -def test_legacy_sigma_delta(dut: IdfDut) -> None: - dut.run_all_single_board_cases(group='sigma_delta') - - @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32s3 diff --git a/components/driver/test_apps/gpio/sdkconfig.ci.iram_safe b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.iram_safe similarity index 100% rename from components/driver/test_apps/gpio/sdkconfig.ci.iram_safe rename to components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.iram_safe diff --git a/components/driver/test_apps/pulse_cnt/sdkconfig.ci.release b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.release similarity index 100% rename from components/driver/test_apps/pulse_cnt/sdkconfig.ci.release rename to components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.release diff --git a/components/driver/test_apps/pulse_cnt/sdkconfig.defaults b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.defaults similarity index 100% rename from components/driver/test_apps/pulse_cnt/sdkconfig.defaults rename to components/esp_driver_gpio/test_apps/gpio/sdkconfig.defaults diff --git a/components/driver/test_apps/gpio_extensions/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio_extensions/CMakeLists.txt similarity index 87% rename from components/driver/test_apps/gpio_extensions/CMakeLists.txt rename to components/esp_driver_gpio/test_apps/gpio_extensions/CMakeLists.txt index 42d10a85539..fb191523e9d 100644 --- a/components/driver/test_apps/gpio_extensions/CMakeLists.txt +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/CMakeLists.txt @@ -10,7 +10,7 @@ project(gpio_extension_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/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_gpio/,${CMAKE_BINARY_DIR}/esp-idf/hal/ --elf-file ${CMAKE_BINARY_DIR}/gpio_extension_test.elf find-refs --from-sections=.iram0.text diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/README.md b/components/esp_driver_gpio/test_apps/gpio_extensions/README.md new file mode 100644 index 00000000000..d2553ff6db3 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/gpio_extensions/main/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt similarity index 82% rename from components/driver/test_apps/gpio_extensions/main/CMakeLists.txt rename to components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt index 81700812a48..3b4bd6d6204 100644 --- a/components/driver/test_apps/gpio_extensions/main/CMakeLists.txt +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt @@ -8,10 +8,6 @@ if(CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER OR (CONFIG_SOC_GPIO_FLEX_GLITCH_FIL list(APPEND srcs "test_gpio_filter.c") endif() -if(CONFIG_SOC_SDM_SUPPORTED) - list(APPEND srcs "test_sdm.c") -endif() - if(CONFIG_SOC_GPIO_SUPPORT_PIN_HYS_FILTER) list(APPEND srcs "test_hysteresis.c") endif() @@ -19,5 +15,5 @@ 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 driver + PRIV_REQUIRES unity esp_driver_gpio WHOLE_ARCHIVE) diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_app_main.c b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_app_main.c new file mode 100644 index 00000000000..60becdb1e94 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_app_main.c @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_utils.h" +#include "esp_heap_caps.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(" ____ ____ ___ ___ _____ _ _____ _\r\n"); + printf(" / ___| _ \\_ _/ _ \\ | ____|_ _| |_ |_ _|__ ___| |_\r\n"); + printf("| | _| |_) | | | | | | _| \\ \\/ / __| | |/ _ \\/ __| __|\r\n"); + printf("| |_| | __/| | |_| | | |___ > <| |_ | | __/\\__ \\ |_\r\n"); + printf(" \\____|_| |___\\___/ |_____/_/\\_\\\\__| |_|\\___||___/\\__|\r\n"); + unity_run_menu(); +} diff --git a/components/driver/test_apps/gpio_extensions/main/test_dedicated_gpio.c b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_dedicated_gpio.c similarity index 100% rename from components/driver/test_apps/gpio_extensions/main/test_dedicated_gpio.c rename to components/esp_driver_gpio/test_apps/gpio_extensions/main/test_dedicated_gpio.c diff --git a/components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_gpio_filter.c similarity index 100% rename from components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c rename to components/esp_driver_gpio/test_apps/gpio_extensions/main/test_gpio_filter.c diff --git a/components/driver/test_apps/gpio_extensions/main/test_hysteresis.c b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c similarity index 93% rename from components/driver/test_apps/gpio_extensions/main/test_hysteresis.c rename to components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c index e3acf87b923..d75594d2a9f 100644 --- a/components/driver/test_apps/gpio_extensions/main/test_hysteresis.c +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c @@ -9,7 +9,6 @@ #include "unity.h" #include "driver/gpio.h" - /** * NOTE: To run this special feature test case, a slope analog signal is needed. * A simple RC circuit used here to formate pin switches to continuos slop signal. @@ -29,10 +28,9 @@ * which enabled the hysteresis feature directly to have a test. **/ - static void test_gpio_hysteresis_intr_handler(void *args) { - esp_rom_printf("%d\n", ++*((uint32_t *)args)); + esp_rom_printf("%d\n", ++ * ((uint32_t *)args)); } // This case is now tested only manually @@ -40,10 +38,10 @@ TEST_CASE("GPIO Input hysteresis filter", "[gpio_filter][timeout=50][ignore]") { const gpio_num_t TEST_HYS_IO = 26; const gpio_num_t TEST_WAVE_IO = 27; - uint32_t intr_cnt=0; + uint32_t intr_cnt = 0; gpio_config_t gpio_cfg = { - .pin_bit_mask = 1 << TEST_WAVE_IO, + .pin_bit_mask = (1 << TEST_WAVE_IO), .mode = GPIO_MODE_OUTPUT, .pull_down_en = GPIO_PULLDOWN_ENABLE, }; @@ -59,7 +57,7 @@ TEST_CASE("GPIO Input hysteresis filter", "[gpio_filter][timeout=50][ignore]") gpio_isr_handler_add(TEST_HYS_IO, test_gpio_hysteresis_intr_handler, &intr_cnt); // generate 5 rising and falling slopes to test gpio interrupt - for (uint8_t i=0; i<5; i++) { + for (uint8_t i = 0; i < 5; i++) { printf("----falling %dth\n", i); gpio_set_level(TEST_WAVE_IO, 0); vTaskDelay(1500); diff --git a/components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py b/components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py similarity index 72% rename from components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py rename to components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py index 7da5ce3c9d9..a51ae5e89d4 100644 --- a/components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py @@ -10,19 +10,6 @@ ] -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32h2 -@pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS, indirect=True) -def test_sdm(dut: IdfDut) -> None: - dut.run_all_single_board_cases(group='sdm') - - @pytest.mark.esp32c2 @pytest.mark.esp32c3 @pytest.mark.esp32c6 diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.iram_safe b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.iram_safe new file mode 100644 index 00000000000..9eb666b35b8 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.iram_safe @@ -0,0 +1,9 @@ +CONFIG_COMPILER_DUMP_RTL_FILES=y +CONFIG_COMPILER_OPTIMIZATION_NONE=y +# place non-ISR FreeRTOS functions in Flash +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=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 +# GPIO test uses IPC call, the default stack size of IPC task can satisfy the -O0 optimization +CONFIG_ESP_IPC_TASK_STACK_SIZE=2048 diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.release b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.release new file mode 100644 index 00000000000..91d93f163e6 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/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_gpio/test_apps/gpio_extensions/sdkconfig.defaults b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.defaults new file mode 100644 index 00000000000..fa8ac618b94 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT_EN=n diff --git a/components/esp_driver_gptimer/CMakeLists.txt b/components/esp_driver_gptimer/CMakeLists.txt new file mode 100644 index 00000000000..4ec99842f0f --- /dev/null +++ b/components/esp_driver_gptimer/CMakeLists.txt @@ -0,0 +1,16 @@ +set(srcs) +set(public_include "include") +if(CONFIG_SOC_GPTIMER_SUPPORTED) + list(APPEND srcs "src/gptimer.c" + "src/gptimer_priv.c") +endif() + +if(CONFIG_SOC_TIMER_SUPPORT_ETM) + list(APPEND srcs "src/gptimer_etm.c") +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${public_include} + PRIV_REQUIRES "esp_pm" + LDFRAGMENTS "linker.lf" + ) diff --git a/components/driver/gptimer/Kconfig.gptimer b/components/esp_driver_gptimer/Kconfig similarity index 96% rename from components/driver/gptimer/Kconfig.gptimer rename to components/esp_driver_gptimer/Kconfig index 5aeda6fd04f..8aa5f2d9ba5 100644 --- a/components/driver/gptimer/Kconfig.gptimer +++ b/components/esp_driver_gptimer/Kconfig @@ -1,4 +1,4 @@ -menu "GPTimer Configuration" +menu "ESP-Driver:GPTimer Configurations" depends on SOC_GPTIMER_SUPPORTED config GPTIMER_ISR_HANDLER_IN_IRAM bool "Place GPTimer ISR handler into IRAM" @@ -36,4 +36,4 @@ menu "GPTimer Configuration" help Wether to enable the debug log message for GPTimer driver. Note that, this option only controls the GPTimer driver log, won't affect other drivers. -endmenu # GPTimer Configuration +endmenu diff --git a/components/driver/gptimer/README.md b/components/esp_driver_gptimer/README.md similarity index 100% rename from components/driver/gptimer/README.md rename to components/esp_driver_gptimer/README.md diff --git a/components/driver/gptimer/include/driver/gptimer.h b/components/esp_driver_gptimer/include/driver/gptimer.h similarity index 100% rename from components/driver/gptimer/include/driver/gptimer.h rename to components/esp_driver_gptimer/include/driver/gptimer.h diff --git a/components/driver/gptimer/include/driver/gptimer_etm.h b/components/esp_driver_gptimer/include/driver/gptimer_etm.h similarity index 100% rename from components/driver/gptimer/include/driver/gptimer_etm.h rename to components/esp_driver_gptimer/include/driver/gptimer_etm.h diff --git a/components/driver/gptimer/include/driver/gptimer_types.h b/components/esp_driver_gptimer/include/driver/gptimer_types.h similarity index 88% rename from components/driver/gptimer/include/driver/gptimer_types.h rename to components/esp_driver_gptimer/include/driver/gptimer_types.h index 8fc188d8289..38abfd44181 100644 --- a/components/driver/gptimer/include/driver/gptimer_types.h +++ b/components/esp_driver_gptimer/include/driver/gptimer_types.h @@ -35,7 +35,7 @@ typedef struct { * @param[in] user_ctx User data, passed from `gptimer_register_event_callbacks` * @return Whether a high priority task has been waken up by this function */ -typedef bool (*gptimer_alarm_cb_t) (gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx); +typedef bool (*gptimer_alarm_cb_t)(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx); #ifdef __cplusplus } diff --git a/components/driver/include/esp_private/gptimer.h b/components/esp_driver_gptimer/include/esp_private/gptimer.h similarity index 100% rename from components/driver/include/esp_private/gptimer.h rename to components/esp_driver_gptimer/include/esp_private/gptimer.h diff --git a/components/driver/gptimer/linker.lf b/components/esp_driver_gptimer/linker.lf similarity index 95% rename from components/driver/gptimer/linker.lf rename to components/esp_driver_gptimer/linker.lf index 11d7eeb26c1..72f9e6eafd1 100644 --- a/components/driver/gptimer/linker.lf +++ b/components/esp_driver_gptimer/linker.lf @@ -1,5 +1,5 @@ [mapping:gptimer_driver] -archive: libdriver.a +archive: libesp_driver_gptimer.a entries: if GPTIMER_ISR_HANDLER_IN_IRAM = y: gptimer: gptimer_default_isr (noflash) diff --git a/components/driver/gptimer/gptimer.c b/components/esp_driver_gptimer/src/gptimer.c similarity index 98% rename from components/driver/gptimer/gptimer.c rename to components/esp_driver_gptimer/src/gptimer.c index 61978935b1e..447aebfbbfb 100644 --- a/components/driver/gptimer/gptimer.c +++ b/components/esp_driver_gptimer/src/gptimer.c @@ -254,8 +254,8 @@ esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer isr_flags |= 1 << (timer->intr_priority); } ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(timer_group_periph_signals.groups[group_id].timer_irq_id[timer_id], isr_flags, - (uint32_t)timer_ll_get_intr_status_reg(timer->hal.dev), TIMER_LL_EVENT_ALARM(timer_id), - gptimer_default_isr, timer, &timer->intr), TAG, "install interrupt service failed"); + (uint32_t)timer_ll_get_intr_status_reg(timer->hal.dev), TIMER_LL_EVENT_ALARM(timer_id), + gptimer_default_isr, timer, &timer->intr), TAG, "install interrupt service failed"); } // enable/disable GPTimer interrupt events diff --git a/components/driver/gptimer/gptimer_etm.c b/components/esp_driver_gptimer/src/gptimer_etm.c similarity index 100% rename from components/driver/gptimer/gptimer_etm.c rename to components/esp_driver_gptimer/src/gptimer_etm.c diff --git a/components/driver/gptimer/gptimer_priv.c b/components/esp_driver_gptimer/src/gptimer_priv.c similarity index 100% rename from components/driver/gptimer/gptimer_priv.c rename to components/esp_driver_gptimer/src/gptimer_priv.c diff --git a/components/driver/gptimer/gptimer_priv.h b/components/esp_driver_gptimer/src/gptimer_priv.h similarity index 100% rename from components/driver/gptimer/gptimer_priv.h rename to components/esp_driver_gptimer/src/gptimer_priv.h diff --git a/components/esp_driver_gptimer/test_apps/.build-test-rules.yml b/components/esp_driver_gptimer/test_apps/.build-test-rules.yml new file mode 100644 index 00000000000..a48c8d7cfcf --- /dev/null +++ b/components/esp_driver_gptimer/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_gptimer/test_apps/gptimer: + disable: + - if: SOC_GPTIMER_SUPPORTED != 1 + depends_components: + - esp_driver_gptimer diff --git a/components/driver/test_apps/gptimer/CMakeLists.txt b/components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt similarity index 87% rename from components/driver/test_apps/gptimer/CMakeLists.txt rename to components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt index 50a85ed1dd5..ba96212bd03 100644 --- a/components/driver/test_apps/gptimer/CMakeLists.txt +++ b/components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt @@ -10,7 +10,7 @@ project(gptimer_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/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_gptimer/,${CMAKE_BINARY_DIR}/esp-idf/hal/ --elf-file ${CMAKE_BINARY_DIR}/gptimer_test.elf find-refs --from-sections=.iram0.text diff --git a/components/driver/test_apps/gptimer/README.md b/components/esp_driver_gptimer/test_apps/gptimer/README.md similarity index 100% rename from components/driver/test_apps/gptimer/README.md rename to components/esp_driver_gptimer/test_apps/gptimer/README.md diff --git a/components/driver/test_apps/gptimer/main/CMakeLists.txt b/components/esp_driver_gptimer/test_apps/gptimer/main/CMakeLists.txt similarity index 100% rename from components/driver/test_apps/gptimer/main/CMakeLists.txt rename to components/esp_driver_gptimer/test_apps/gptimer/main/CMakeLists.txt diff --git a/components/driver/test_apps/gptimer/main/test_app_main.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_app_main.c similarity index 100% rename from components/driver/test_apps/gptimer/main/test_app_main.c rename to components/esp_driver_gptimer/test_apps/gptimer/main/test_app_main.c diff --git a/components/driver/test_apps/gptimer/main/test_gptimer.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c similarity index 100% rename from components/driver/test_apps/gptimer/main/test_gptimer.c rename to components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c diff --git a/components/driver/test_apps/gptimer/main/test_gptimer_iram.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_iram.c similarity index 100% rename from components/driver/test_apps/gptimer/main/test_gptimer_iram.c rename to components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_iram.c diff --git a/components/driver/test_apps/gptimer/pytest_gptimer.py b/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py similarity index 100% rename from components/driver/test_apps/gptimer/pytest_gptimer.py rename to components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py diff --git a/components/driver/test_apps/gptimer/sdkconfig.ci.esp32c2_xtal26m b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.esp32c2_xtal26m similarity index 100% rename from components/driver/test_apps/gptimer/sdkconfig.ci.esp32c2_xtal26m rename to components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.esp32c2_xtal26m diff --git a/components/driver/test_apps/gptimer/sdkconfig.ci.iram_safe b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.iram_safe similarity index 100% rename from components/driver/test_apps/gptimer/sdkconfig.ci.iram_safe rename to components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.iram_safe diff --git a/components/driver/test_apps/gptimer/sdkconfig.ci.release b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release similarity index 100% rename from components/driver/test_apps/gptimer/sdkconfig.ci.release rename to components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release diff --git a/components/driver/test_apps/gptimer/sdkconfig.defaults b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.defaults similarity index 100% rename from components/driver/test_apps/gptimer/sdkconfig.defaults rename to components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.defaults diff --git a/components/esp_driver_pcnt/CMakeLists.txt b/components/esp_driver_pcnt/CMakeLists.txt new file mode 100644 index 00000000000..6cf979b0cc6 --- /dev/null +++ b/components/esp_driver_pcnt/CMakeLists.txt @@ -0,0 +1,11 @@ +set(srcs) +set(public_include "include") +if(CONFIG_SOC_PCNT_SUPPORTED) + list(APPEND srcs "src/pulse_cnt.c") +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${public_include} + PRIV_REQUIRES "esp_pm" "esp_driver_gpio" + LDFRAGMENTS "linker.lf" + ) diff --git a/components/driver/pcnt/Kconfig.pcnt b/components/esp_driver_pcnt/Kconfig similarity index 95% rename from components/driver/pcnt/Kconfig.pcnt rename to components/esp_driver_pcnt/Kconfig index 4a01e451411..e7f2d526e56 100644 --- a/components/driver/pcnt/Kconfig.pcnt +++ b/components/esp_driver_pcnt/Kconfig @@ -1,4 +1,4 @@ -menu "PCNT Configuration" +menu "ESP-Driver:PCNT Configurations" depends on SOC_PCNT_SUPPORTED config PCNT_CTRL_FUNC_IN_IRAM bool "Place PCNT control functions into IRAM" @@ -29,4 +29,4 @@ menu "PCNT Configuration" help Wether to enable the debug log message for PCNT driver. Note that, this option only controls the PCNT driver log, won't affect other drivers. -endmenu # PCNT Configuration +endmenu diff --git a/components/driver/pcnt/include/driver/pulse_cnt.h b/components/esp_driver_pcnt/include/driver/pulse_cnt.h similarity index 100% rename from components/driver/pcnt/include/driver/pulse_cnt.h rename to components/esp_driver_pcnt/include/driver/pulse_cnt.h diff --git a/components/esp_driver_pcnt/linker.lf b/components/esp_driver_pcnt/linker.lf new file mode 100644 index 00000000000..13556e6a9c1 --- /dev/null +++ b/components/esp_driver_pcnt/linker.lf @@ -0,0 +1,8 @@ +[mapping:pcnt_driver] +archive: libesp_driver_pcnt.a +entries: + if PCNT_CTRL_FUNC_IN_IRAM = y: + pulse_cnt: pcnt_unit_start (noflash) + pulse_cnt: pcnt_unit_stop (noflash) + pulse_cnt: pcnt_unit_clear_count (noflash) + pulse_cnt: pcnt_unit_get_count (noflash) diff --git a/components/driver/pcnt/pulse_cnt.c b/components/esp_driver_pcnt/src/pulse_cnt.c similarity index 98% rename from components/driver/pcnt/pulse_cnt.c rename to components/esp_driver_pcnt/src/pulse_cnt.c index fc2c0a709e8..ce9619de23a 100644 --- a/components/driver/pcnt/pulse_cnt.c +++ b/components/esp_driver_pcnt/src/pulse_cnt.c @@ -192,7 +192,7 @@ esp_err_t pcnt_new_unit(const pcnt_unit_config_t *config, pcnt_unit_handle_t *re "invalid limit range:[%d,%d]", config->low_limit, config->high_limit); if (config->intr_priority) { ESP_GOTO_ON_FALSE(1 << (config->intr_priority) & PCNT_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, err, - TAG, "invalid interrupt priority:%d", config->intr_priority); + TAG, "invalid interrupt priority:%d", config->intr_priority); } unit = heap_caps_calloc(1, sizeof(pcnt_unit_t), PCNT_MEM_ALLOC_CAPS); @@ -225,8 +225,8 @@ esp_err_t pcnt_new_unit(const pcnt_unit_config_t *config, pcnt_unit_handle_t *re isr_flags |= PCNT_ALLOW_INTR_PRIORITY_MASK; } ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(pcnt_periph_signals.groups[group_id].irq, isr_flags, - (uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id), - pcnt_default_isr, unit, &unit->intr), err, + (uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id), + pcnt_default_isr, unit, &unit->intr), err, TAG, "install interrupt service failed"); } @@ -488,8 +488,8 @@ esp_err_t pcnt_unit_register_event_callbacks(pcnt_unit_handle_t unit, const pcnt isr_flags |= PCNT_ALLOW_INTR_PRIORITY_MASK; } ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(pcnt_periph_signals.groups[group_id].irq, isr_flags, - (uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id), - pcnt_default_isr, unit, &unit->intr), + (uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id), + pcnt_default_isr, unit, &unit->intr), TAG, "install interrupt service failed"); } // enable/disable PCNT interrupt events diff --git a/components/esp_driver_pcnt/test_apps/.build-test-rules.yml b/components/esp_driver_pcnt/test_apps/.build-test-rules.yml new file mode 100644 index 00000000000..d94a1f9237b --- /dev/null +++ b/components/esp_driver_pcnt/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_pcnt/test_apps/pulse_cnt: + disable: + - if: SOC_PCNT_SUPPORTED != 1 + depends_components: + - esp_driver_pcnt diff --git a/components/driver/test_apps/pulse_cnt/CMakeLists.txt b/components/esp_driver_pcnt/test_apps/pulse_cnt/CMakeLists.txt similarity index 87% rename from components/driver/test_apps/pulse_cnt/CMakeLists.txt rename to components/esp_driver_pcnt/test_apps/pulse_cnt/CMakeLists.txt index 46dee2c382e..aac95204843 100644 --- a/components/driver/test_apps/pulse_cnt/CMakeLists.txt +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/CMakeLists.txt @@ -10,7 +10,7 @@ project(pcnt_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/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_pcnt/,${CMAKE_BINARY_DIR}/esp-idf/hal/ --elf-file ${CMAKE_BINARY_DIR}/pcnt_test.elf find-refs --from-sections=.iram0.text diff --git a/components/driver/test_apps/pulse_cnt/README.md b/components/esp_driver_pcnt/test_apps/pulse_cnt/README.md similarity index 100% rename from components/driver/test_apps/pulse_cnt/README.md rename to components/esp_driver_pcnt/test_apps/pulse_cnt/README.md diff --git a/components/driver/test_apps/pulse_cnt/main/CMakeLists.txt b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/CMakeLists.txt similarity index 71% rename from components/driver/test_apps/pulse_cnt/main/CMakeLists.txt rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/CMakeLists.txt index a7ee53f40d7..82fd9210955 100644 --- a/components/driver/test_apps/pulse_cnt/main/CMakeLists.txt +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/CMakeLists.txt @@ -9,5 +9,6 @@ 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 driver spi_flash + PRIV_REQUIRES unity esp_driver_pcnt spi_flash + driver # will be replaced by esp_driver_gpio WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/pulse_cnt/main/test_app_main.c b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_app_main.c similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_app_main.c rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_app_main.c diff --git a/components/driver/test_apps/pulse_cnt/main/test_pulse_cnt.c b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt.c similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_pulse_cnt.c rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt.c diff --git a/components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_board.h b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_board.h similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_board.h rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_board.h diff --git a/components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_iram.c b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_iram.c similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_iram.c rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_iram.c diff --git a/components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_simulator.c b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_simulator.c similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_simulator.c rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_simulator.c diff --git a/components/driver/test_apps/pulse_cnt/pytest_pulse_cnt.py b/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py similarity index 100% rename from components/driver/test_apps/pulse_cnt/pytest_pulse_cnt.py rename to components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py diff --git a/components/driver/test_apps/pulse_cnt/sdkconfig.ci.iram_safe b/components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.ci.iram_safe similarity index 100% rename from components/driver/test_apps/pulse_cnt/sdkconfig.ci.iram_safe rename to components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.ci.iram_safe diff --git a/components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.ci.release b/components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.ci.release new file mode 100644 index 00000000000..91d93f163e6 --- /dev/null +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/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_pcnt/test_apps/pulse_cnt/sdkconfig.defaults b/components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.defaults new file mode 100644 index 00000000000..fa8ac618b94 --- /dev/null +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT_EN=n diff --git a/components/esp_eth/CMakeLists.txt b/components/esp_eth/CMakeLists.txt index 55f0fc09373..439180e557f 100644 --- a/components/esp_eth/CMakeLists.txt +++ b/components/esp_eth/CMakeLists.txt @@ -67,7 +67,7 @@ endif() if(CONFIG_ETH_ENABLED) if(CONFIG_ETH_USE_SPI_ETHERNET) - idf_component_optional_requires(PUBLIC driver) + idf_component_optional_requires(PUBLIC driver esp_driver_gpio) endif() idf_component_optional_requires(PRIVATE esp_netif esp_pm) endif() diff --git a/components/esp_eth/src/esp_eth_mac_esp.c b/components/esp_eth/src/esp_eth_mac_esp.c index d59e1e33b4a..25472c1e8cb 100644 --- a/components/esp_eth/src/esp_eth_mac_esp.c +++ b/components/esp_eth/src/esp_eth_mac_esp.c @@ -18,6 +18,7 @@ #include "esp_cpu.h" #include "esp_heap_caps.h" #include "esp_intr_alloc.h" +#include "esp_clock_output.h" #include "esp_private/esp_clk.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -51,6 +52,7 @@ typedef struct { int smi_mdc_gpio_num; int smi_mdio_gpio_num; eth_mac_clock_config_t clock_config; + 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 uint8_t addr[6]; uint8_t *rx_buf[CONFIG_ETH_DMA_RX_BUFFER_NUM]; uint8_t *tx_buf[CONFIG_ETH_DMA_TX_BUFFER_NUM]; @@ -472,6 +474,9 @@ static void esp_emac_free_driver_obj(emac_esp32_t *emac, void *descriptors) for (int i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) { free(emac->rx_buf[i]); } + if (emac->rmii_clk_hdl) { + esp_clock_output_stop(emac->rmii_clk_hdl); + } #ifdef CONFIG_PM_ENABLE if (emac->pm_lock) { esp_pm_lock_delete(emac->pm_lock); @@ -519,7 +524,7 @@ static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_ core_num = esp_cpu_get_core_id(); } BaseType_t xReturned = xTaskCreatePinnedToCore(emac_esp32_rx_task, "emac_rx", config->rx_task_stack_size, emac, - config->rx_task_prio, &emac->rx_task_hdl, core_num); + 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"); *out_descriptors = descriptors; @@ -578,15 +583,18 @@ static esp_err_t esp_emac_config_data_interface(const eth_esp32_emac_config_t *e emac->clock_config.rmii.clock_gpio == EMAC_CLK_OUT_180_GPIO, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC clock output GPIO"); emac_hal_iomux_rmii_clk_ouput(emac->clock_config.rmii.clock_gpio); - if (emac->clock_config.rmii.clock_gpio == EMAC_APPL_CLK_OUT_GPIO) { - REG_SET_FIELD(PIN_CTRL, CLK_OUT1, 6); - } /* Enable RMII clock */ emac_hal_clock_enable_rmii_output(&emac->hal); - // Power up APLL clock + // the RMII reference comes from the APLL periph_rtc_apll_acquire(); ESP_GOTO_ON_ERROR(emac_config_apll_clock(), err, TAG, "Configure APLL for RMII failed"); emac->use_apll = true; + + // 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"); + } } else { ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC clock mode"); } diff --git a/components/esp_eth/test_apps/pytest_esp_eth.py b/components/esp_eth/test_apps/pytest_esp_eth.py index e6b83c4980e..921636f4419 100644 --- a/components/esp_eth/test_apps/pytest_esp_eth.py +++ b/components/esp_eth/test_apps/pytest_esp_eth.py @@ -214,6 +214,7 @@ def test_esp_eth_ip101(dut: IdfDut) -> None: # ----------- LAN8720 ----------- @pytest.mark.esp32 @pytest.mark.eth_lan8720 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_lan8720', ], indirect=True) @@ -226,6 +227,7 @@ def test_esp_eth_lan8720(dut: IdfDut) -> None: # ----------- RTL8201 ----------- @pytest.mark.esp32 @pytest.mark.eth_rtl8201 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_rtl8201', ], indirect=True) @@ -238,6 +240,7 @@ def test_esp_eth_rtl8201(dut: IdfDut) -> None: # ----------- KSZ8041 ----------- @pytest.mark.esp32 @pytest.mark.eth_ksz8041 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_ksz8041', ], indirect=True) @@ -250,6 +253,7 @@ def test_esp_eth_ksz8041(dut: IdfDut) -> None: # ----------- DP83848 ----------- @pytest.mark.esp32 @pytest.mark.eth_dp83848 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_dp83848', ], indirect=True) @@ -262,6 +266,7 @@ def test_esp_eth_dp83848(dut: IdfDut) -> None: # ----------- W5500 ----------- @pytest.mark.esp32 @pytest.mark.eth_w5500 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_w5500', ], indirect=True) @@ -274,6 +279,7 @@ def test_esp_eth_w5500(dut: IdfDut) -> None: # ----------- KSZ8851SNL ----------- @pytest.mark.esp32 @pytest.mark.eth_ksz8851snl +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_ksz8851snl', ], indirect=True) @@ -286,6 +292,7 @@ def test_esp_eth_ksz8851snl(dut: IdfDut) -> None: # ----------- DM9051 ----------- @pytest.mark.esp32 @pytest.mark.eth_dm9051 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_dm9051', ], indirect=True) diff --git a/components/esp_event/test_apps/main/test_event_common.cpp b/components/esp_event/test_apps/main/test_event_common.cpp index 9b327cd5997..0daa3844eff 100644 --- a/components/esp_event/test_apps/main/test_event_common.cpp +++ b/components/esp_event/test_apps/main/test_event_common.cpp @@ -1225,6 +1225,15 @@ static void test_handler_give_sem(void* handler_arg, esp_event_base_t base, int3 TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreGive(sem)); } +const TickType_t ONE_TICK = 1; + +static void wait_taken(SemaphoreHandle_t sem, TickType_t delay_ticks_if_not_taken) { + while (xSemaphoreTake(sem, ONE_TICK) == pdTRUE) { + xSemaphoreGive(sem); + vTaskDelay(delay_ticks_if_not_taken); + } +} + TEST_CASE("can post while handler is executing - dedicated task", "[event][linux]") { EV_LoopFix loop_fix(1, "loop_task"); @@ -1248,6 +1257,9 @@ TEST_CASE("can post while handler is executing - dedicated task", "[event][linux // Trigger waiting by sending first event TEST_ESP_OK(esp_event_post_to(loop_fix.loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY)); + // Wait until semaphore is actually taken, which means handler is running and blocked + wait_taken(ev1_sem, 2); + // Check that event can be posted while handler is running (waiting on the semaphore) TEST_ESP_OK(esp_event_post_to(loop_fix.loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY)); @@ -1317,10 +1329,7 @@ TEST_CASE("can not post while handler is executing - no dedicated task", "[event TEST_ESP_OK(esp_event_post_to(loop_fix.loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY)); // Wait until semaphore is actually taken, which means handler is running and blocked - while (xSemaphoreTake(sem, 1) == pdTRUE) { - xSemaphoreGive(sem); - vTaskDelay(2); - } + wait_taken(sem, 2); // For loop without tasks, posting is more restrictive. Posting should wait until execution of handler finishes TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, esp_event_post_to(loop_fix.loop, diff --git a/components/esp_hid/src/ble_hidd.c b/components/esp_hid/src/ble_hidd.c index 249ac913e01..a70e47a3178 100644 --- a/components/esp_hid/src/ble_hidd.c +++ b/components/esp_hid/src/ble_hidd.c @@ -12,7 +12,6 @@ #include "esp_hidd_private.h" #include "esp_log.h" -#include "esp_bt.h" #include "esp_bt_main.h" #include "esp_bt_defs.h" #include "esp_gatts_api.h" @@ -282,7 +281,7 @@ static esp_err_t create_hid_db(esp_ble_hidd_dev_t *dev, int device_index) add_db_record(_last_db, HIDD_LE_IDX_HID_INFO_VAL, (uint8_t *)&s_hid_info_char_uuid, ESP_GATT_PERM_READ, 4, 4, (uint8_t *)hidInfo); add_db_record(_last_db, HIDD_LE_IDX_HID_CTNL_PT_CHAR, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_write_nr); - add_db_record(_last_db, HIDD_LE_IDX_HID_CTNL_PT_VAL, (uint8_t *)&s_hid_control_point_uuid, ESP_GATT_PERM_READ, 1, 0, NULL); + add_db_record(_last_db, HIDD_LE_IDX_HID_CTNL_PT_VAL, (uint8_t *)&s_hid_control_point_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 1, 0, NULL); add_db_record(_last_db, HIDD_LE_IDX_PROTO_MODE_CHAR, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_write_nr); add_db_record(_last_db, HIDD_LE_IDX_PROTO_MODE_VAL, (uint8_t *)&s_hid_proto_mode_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 1, 1, (uint8_t *)&dev->protocol); @@ -301,7 +300,7 @@ static esp_err_t create_hid_db(esp_ble_hidd_dev_t *dev, int device_index) add_db_record(_last_db, index++, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_notify); report->index = index; add_db_record(_last_db, index++, (uint8_t *)&s_hid_report_uuid, ESP_GATT_PERM_READ, report->value_len, 0, NULL); - add_db_record(_last_db, index++, (uint8_t *)&s_character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 2, 0, NULL); + add_db_record(_last_db, index++, (uint8_t *)&s_character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE_ENCRYPTED, 2, 0, NULL); } else if (report->report_type == ESP_HID_REPORT_TYPE_OUTPUT) { //Output Report add_db_record(_last_db, index++, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_write_write_nr); @@ -463,7 +462,7 @@ static void hid_event_handler(esp_ble_hidd_dev_t *dev, int device_index, esp_gat link_report_handles(&dev->devices[device_index], param->add_attr_tab.handles); esp_ble_gatts_start_service(dev->devices[device_index].hid_svc.handle); if ((device_index + 1) < dev->devices_len) { - create_hid_db(dev, device_index + 1);//add next device + create_hid_db(dev, device_index + 1);//add next device if support } break; } diff --git a/components/esp_hid/src/ble_hidh.c b/components/esp_hid/src/ble_hidh.c index 99b7f44b3b3..8df54c2fc99 100644 --- a/components/esp_hid/src/ble_hidh.c +++ b/components/esp_hid/src/ble_hidh.c @@ -11,7 +11,6 @@ #include "esp_err.h" #include "esp_log.h" -#include "esp_bt.h" #include "esp_bt_defs.h" #include "esp_bt_main.h" #include "esp_gattc_api.h" diff --git a/components/esp_hid/src/bt_hidd.c b/components/esp_hid/src/bt_hidd.c index ab3d3460533..08e7209a361 100644 --- a/components/esp_hid/src/bt_hidd.c +++ b/components/esp_hid/src/bt_hidd.c @@ -6,7 +6,6 @@ #include "bt_hidd.h" #if CONFIG_BT_HID_DEVICE_ENABLED -#include "esp_bt.h" #include "esp_bt_defs.h" #include "esp_bt_main.h" #include "esp_hidd.h" diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 460470a1f8c..8f91ef3b05e 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/esp_http_client.c @@ -9,6 +9,7 @@ #include #include "esp_log.h" +#include "esp_assert.h" #include "esp_check.h" #include "http_parser.h" #include "http_header.h" @@ -20,6 +21,7 @@ #include "esp_http_client.h" #include "errno.h" #include "esp_random.h" +#include "esp_tls.h" #ifdef CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS #include "esp_transport_ssl.h" @@ -29,6 +31,9 @@ ESP_EVENT_DEFINE_BASE(ESP_HTTP_CLIENT_EVENT); static const char *TAG = "HTTP_CLIENT"; +ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_ANY == (int)ESP_TLS_VER_ANY, "Enum mismatch in esp_http_client and esp-tls"); +ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_MAX <= (int)ESP_TLS_VER_TLS_MAX, "HTTP client supported TLS is not supported in esp-tls"); + /** * HTTP Buffer */ @@ -723,6 +728,7 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co esp_transport_ssl_set_client_cert_data_der(ssl, config->client_cert_pem, config->client_cert_len); } } + esp_transport_ssl_set_tls_version(ssl, config->tls_version); #if CONFIG_ESP_TLS_USE_SECURE_ELEMENT if (config->use_secure_element) { diff --git a/components/esp_http_client/include/esp_http_client.h b/components/esp_http_client/include/esp_http_client.h index 6135976d568..06bee3dda82 100644 --- a/components/esp_http_client/include/esp_http_client.h +++ b/components/esp_http_client/include/esp_http_client.h @@ -78,6 +78,16 @@ typedef enum { HTTP_TRANSPORT_OVER_SSL, /*!< Transport over ssl */ } esp_http_client_transport_t; +/* +* @brief TLS Protocol version +*/ +typedef enum { + ESP_HTTP_CLIENT_TLS_VER_ANY = 0, /* No preference */ + ESP_HTTP_CLIENT_TLS_VER_TLS_1_2 = 0x1, /* (D)TLS 1.2 */ + ESP_HTTP_CLIENT_TLS_VER_TLS_1_3 = 0x2, /* (D)TLS 1.3 */ + ESP_HTTP_CLIENT_TLS_VER_MAX, /* to indicate max */ +} esp_http_client_proto_ver_t; + typedef esp_err_t (*http_event_handle_cb)(esp_http_client_event_t *evt); /** @@ -133,6 +143,7 @@ typedef struct { size_t client_key_len; /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */ const char *client_key_password; /*!< Client key decryption password string */ size_t client_key_password_len; /*!< String length of the password pointed to by client_key_password */ + esp_http_client_proto_ver_t tls_version; /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */ #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN bool use_ecdsa_peripheral; /*!< Use ECDSA peripheral to use private key. */ uint8_t ecdsa_key_efuse_blk; /*!< The efuse block where ECDSA key is stored. */ diff --git a/components/esp_https_server/CMakeLists.txt b/components/esp_https_server/CMakeLists.txt index 95c24291153..916597b723c 100644 --- a/components/esp_https_server/CMakeLists.txt +++ b/components/esp_https_server/CMakeLists.txt @@ -1,7 +1,5 @@ -if(CONFIG_ESP_HTTPS_SERVER_ENABLE OR CONFIG_IDF_DOC_BUILD) - set(src "src/https_server.c") - set(inc "include") -endif() +set(src "src/https_server.c") +set(inc "include") idf_component_register(SRCS ${src} INCLUDE_DIRS ${inc} diff --git a/components/esp_https_server/Kconfig b/components/esp_https_server/Kconfig index 4fae425f0f7..f4cd30282c3 100644 --- a/components/esp_https_server/Kconfig +++ b/components/esp_https_server/Kconfig @@ -3,7 +3,6 @@ menu "ESP HTTPS server" config ESP_HTTPS_SERVER_ENABLE bool "Enable ESP_HTTPS_SERVER component" depends on (ESP_TLS_USING_MBEDTLS && MBEDTLS_TLS_SERVER) - select ESP_TLS_SERVER help Enable ESP HTTPS server component diff --git a/components/esp_https_server/include/esp_https_server.h b/components/esp_https_server/include/esp_https_server.h index 1fd31b45439..0a598f602ec 100644 --- a/components/esp_https_server/include/esp_https_server.h +++ b/components/esp_https_server/include/esp_https_server.h @@ -104,70 +104,30 @@ struct httpd_ssl_config { esp_https_server_user_cb *user_cb; void *ssl_userdata; /*!< user data to add to the ssl context */ +#if CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK esp_tls_handshake_callback cert_select_cb; /*!< Certificate selection callback to use */ +#endif const char** alpn_protos; /*!< Application protocols the server supports in order of prefernece. Used for negotiating during the TLS handshake, first one the client supports is selected. The data structure must live as long as the https server itself! */ }; typedef struct httpd_ssl_config httpd_ssl_config_t; +/* Macro kept for compatibility reasons */ +#define HTTPD_SSL_CONFIG_DEFAULT httpd_ssl_config_default /** - * Default config struct init - * - * (http_server default config had to be copied for customization) + * Returns the httpd config struct with default initialisation * + * @return + * httpd_ssl_config_t HTTPD ssl config struct + * with default initialisation * Notes: * - port is set when starting the server, according to 'transport_mode' * - one socket uses ~ 40kB RAM with SSL, we reduce the default socket count to 4 * - SSL sockets are usually long-lived, closing LRU prevents pool exhaustion DOS * - Stack size may need adjustments depending on the user application */ -#define HTTPD_SSL_CONFIG_DEFAULT() { \ - .httpd = { \ - .task_priority = tskIDLE_PRIORITY+5, \ - .stack_size = 10240, \ - .core_id = tskNO_AFFINITY, \ - .server_port = 0, \ - .ctrl_port = ESP_HTTPD_DEF_CTRL_PORT+1, \ - .max_open_sockets = 4, \ - .max_uri_handlers = 8, \ - .max_resp_headers = 8, \ - .backlog_conn = 5, \ - .lru_purge_enable = true, \ - .recv_wait_timeout = 5, \ - .send_wait_timeout = 5, \ - .global_user_ctx = NULL, \ - .global_user_ctx_free_fn = NULL, \ - .global_transport_ctx = NULL, \ - .global_transport_ctx_free_fn = NULL, \ - .enable_so_linger = false, \ - .linger_timeout = 0, \ - .keep_alive_enable = false, \ - .keep_alive_idle = 0, \ - .keep_alive_interval = 0, \ - .keep_alive_count = 0, \ - .open_fn = NULL, \ - .close_fn = NULL, \ - .uri_match_fn = NULL \ - }, \ - .servercert = NULL, \ - .servercert_len = 0, \ - .cacert_pem = NULL, \ - .cacert_len = 0, \ - .prvtkey_pem = NULL, \ - .prvtkey_len = 0, \ - .use_ecdsa_peripheral = false, \ - .ecdsa_key_efuse_blk = 0, \ - .transport_mode = HTTPD_SSL_TRANSPORT_SECURE, \ - .port_secure = 443, \ - .port_insecure = 80, \ - .session_tickets = false, \ - .use_secure_element = false, \ - .user_cb = NULL, \ - .ssl_userdata = NULL, \ - .cert_select_cb = NULL, \ - .alpn_protos = NULL, \ -} +httpd_ssl_config_t httpd_ssl_config_default(void); /** * Create a SSL capable HTTP server (secure mode may be disabled in config) diff --git a/components/esp_https_server/src/https_server.c b/components/esp_https_server/src/https_server.c index c224b7c0e1c..42a29c3b746 100644 --- a/components/esp_https_server/src/https_server.c +++ b/components/esp_https_server/src/https_server.c @@ -48,6 +48,60 @@ static void httpd_ssl_close(void *ctx) ESP_LOGD(TAG, "Secure socket closed"); } +httpd_ssl_config_t httpd_ssl_config_default(void) +{ + httpd_ssl_config_t config = { + .httpd = { + .task_priority = tskIDLE_PRIORITY + 5, + .stack_size = 10240, + .core_id = tskNO_AFFINITY, + .server_port = 0, + .ctrl_port = ESP_HTTPD_DEF_CTRL_PORT + 1, + .max_open_sockets = 4, + .max_uri_handlers = 8, + .max_resp_headers = 8, + .backlog_conn = 5, + .lru_purge_enable = true, + .recv_wait_timeout = 5, + .send_wait_timeout = 5, + .global_user_ctx = NULL, + .global_user_ctx_free_fn = NULL, + .global_transport_ctx = NULL, + .global_transport_ctx_free_fn = NULL, + .enable_so_linger = false, + .linger_timeout = 0, + .keep_alive_enable = false, + .keep_alive_idle = 0, + .keep_alive_interval = 0, + .keep_alive_count = 0, + .open_fn = NULL, + .close_fn = NULL, + .uri_match_fn = NULL, + }, + .servercert = NULL, + .servercert_len = 0, + .cacert_pem = NULL, + .cacert_len = 0, + .prvtkey_pem = NULL, + .prvtkey_len = 0, + .use_ecdsa_peripheral = false, + .ecdsa_key_efuse_blk = 0, + .transport_mode = HTTPD_SSL_TRANSPORT_SECURE, + .port_secure = 443, + .port_insecure = 80, + .session_tickets = false, + .use_secure_element = false, + .user_cb = NULL, + .ssl_userdata = NULL, +#if CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK + .cert_select_cb = NULL, +#endif + .alpn_protos = NULL, + }; + + return config; +} + /** * SSL socket pending-check function * diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index ad5e37ad648..f996e17e520 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -50,8 +50,11 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "sleep_retention.c" "sleep_system_peripheral.c" "sleep_clock.c") endif() - # [refactor-todo]: requires "driver" for GPIO and RTC (by sleep_gpio and sleep_modes) - list(APPEND priv_requires driver esp_timer) + # [refactor-todo] + list(APPEND priv_requires driver # for UART (by sleep_modes) + esp_driver_gpio # for GPIO and RTC (by sleep_gpio and sleep_modes) + esp_timer + esp_pm) list(APPEND priv_requires esp_mm) diff --git a/components/esp_hw_support/include/esp_private/clkout_channel.h b/components/esp_hw_support/clkout_channel.h similarity index 99% rename from components/esp_hw_support/include/esp_private/clkout_channel.h rename to components/esp_hw_support/clkout_channel.h index 2daa0d447f2..57169f0cc20 100644 --- a/components/esp_hw_support/include/esp_private/clkout_channel.h +++ b/components/esp_hw_support/clkout_channel.h @@ -5,7 +5,9 @@ */ #pragma once + #include "sdkconfig.h" +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_hw_support/esp_clock_output.c b/components/esp_hw_support/esp_clock_output.c index 0ccf0123230..1f2248aa40a 100644 --- a/components/esp_hw_support/esp_clock_output.c +++ b/components/esp_hw_support/esp_clock_output.c @@ -6,13 +6,12 @@ #include #include "sdkconfig.h" - +#include "freertos/FreeRTOS.h" #include "driver/gpio.h" #include "esp_clock_output.h" #include "esp_check.h" #include "esp_rom_gpio.h" -#include "esp_private/clkout_channel.h" -#include "esp_private/startup_internal.h" +#include "clkout_channel.h" #include "hal/gpio_hal.h" #include "soc/soc_caps.h" #include "soc/io_mux_reg.h" @@ -59,13 +58,13 @@ static clkout_channel_handle_t* clkout_channel_alloc(soc_clkout_sig_id_t clk_sig s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].is_mapped = true; allocated_channel = &s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)]; } else if ((s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_io_bmap & BIT(gpio_num)) && - (s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_clock == clk_sig)) { + (s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_clock == clk_sig)) { allocated_channel = &s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)]; } allocated_channel->channel_id = (clock_out_channel_t)IONUM_TO_CLKOUT_CHANNEL(gpio_num); portEXIT_CRITICAL(&s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].clkout_channel_lock); #elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX - for(uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) { + for (uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) { portENTER_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock); if (!s_clkout_handle[channel].is_mapped) { s_clkout_handle[channel].is_mapped = true; diff --git a/components/esp_hw_support/include/esp_clock_output.h b/components/esp_hw_support/include/esp_clock_output.h index 33c87f9cec5..2acbb1377d8 100644 --- a/components/esp_hw_support/include/esp_clock_output.h +++ b/components/esp_hw_support/include/esp_clock_output.h @@ -6,15 +6,11 @@ #pragma once -#include #include -#include "sdkconfig.h" +#include "esp_err.h" #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" - -#include "esp_err.h" #include "driver/gpio.h" -#include "freertos/FreeRTOS.h" #ifdef __cplusplus extern "C" { @@ -46,7 +42,7 @@ esp_err_t esp_clock_output_start(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_nu * - ESP_ERR_INVALID_STATE The clock in handle is already in the disabled state */ esp_err_t esp_clock_output_stop(esp_clock_output_mapping_handle_t clkout_mapping_hdl); -#endif +#endif // SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX || SOC_GPIO_CLOCKOUT_BY_IO_MUX #ifdef __cplusplus } diff --git a/components/esp_hw_support/port/esp32c3/adc2_init_cal.c b/components/esp_hw_support/port/esp32c3/adc2_init_cal.c index edb92a8eb27..096d3e85ab8 100644 --- a/components/esp_hw_support/port/esp32c3/adc2_init_cal.c +++ b/components/esp_hw_support/port/esp32c3/adc2_init_cal.c @@ -22,9 +22,9 @@ extern portMUX_TYPE rtc_spinlock; static __attribute__((constructor)) void adc2_init_code_calibration(void) { adc_hal_calibration_init(ADC_UNIT_2); - adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); portENTER_CRITICAL(&rtc_spinlock); - adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); portEXIT_CRITICAL(&rtc_spinlock); } diff --git a/components/esp_hw_support/port/esp32c6/pmu_param.c b/components/esp_hw_support/port/esp32c6/pmu_param.c index ccfc32b6ef6..af0e1c38b4e 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_param.c +++ b/components/esp_hw_support/port/esp32c6/pmu_param.c @@ -361,14 +361,20 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm /** LP system default parameter */ +#if CONFIG_ESP_SYSTEM_RTC_EXT_XTAL +# define PMU_SLOW_CLK_USE_EXT_XTAL (1) +#else +# define PMU_SLOW_CLK_USE_EXT_XTAL (0) +#endif + #define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \ .dig_power = { \ .mem_dslp = 0, \ .peri_pd_en = 0, \ }, \ .clk_power = { \ - .xpd_xtal32k = 1, \ - .xpd_rc32k = 1, \ + .xpd_xtal32k = PMU_SLOW_CLK_USE_EXT_XTAL, \ + .xpd_rc32k = 0, \ .xpd_fosc = 1, \ .pd_osc = 0 \ } \ 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 f340c5ca05d..0938e058b88 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 @@ -285,8 +285,8 @@ typedef struct { .mem_dslp = 0 \ }, \ .clk_power = { \ - .xpd_xtal32k = 1, \ - .xpd_rc32k = 1, \ + .xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \ + .xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \ .xpd_fosc = 1 \ } \ }, \ diff --git a/components/esp_hw_support/port/esp32h2/pmu_param.c b/components/esp_hw_support/port/esp32h2/pmu_param.c index 83bf887aa31..b0662d50f71 100644 --- a/components/esp_hw_support/port/esp32h2/pmu_param.c +++ b/components/esp_hw_support/port/esp32h2/pmu_param.c @@ -359,13 +359,19 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm /** LP system default parameter */ +#if CONFIG_ESP_SYSTEM_RTC_EXT_XTAL +# define PMU_SLOW_CLK_USE_EXT_XTAL (1) +#else +# define PMU_SLOW_CLK_USE_EXT_XTAL (0) +#endif + #define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \ .dig_power = { \ .mem_dslp = 0, \ .peri_pd_en = 0, \ }, \ .clk_power = { \ - .xpd_xtal32k = 0, \ + .xpd_xtal32k = PMU_SLOW_CLK_USE_EXT_XTAL, \ .xpd_rc32k = 0, \ .xpd_fosc = 1, \ .pd_osc = 0 \ diff --git a/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h b/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h index b6f183522e1..824ccb9db71 100644 --- a/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h @@ -280,8 +280,8 @@ typedef struct { .mem_dslp = 0 \ }, \ .clk_power = { \ - .xpd_xtal32k = 1, \ - .xpd_rc32k = 1, \ + .xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \ + .xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \ .xpd_fosc = 1 \ } \ }, \ diff --git a/components/esp_hw_support/port/esp32s2/adc2_init_cal.c b/components/esp_hw_support/port/esp32s2/adc2_init_cal.c index edb92a8eb27..096d3e85ab8 100644 --- a/components/esp_hw_support/port/esp32s2/adc2_init_cal.c +++ b/components/esp_hw_support/port/esp32s2/adc2_init_cal.c @@ -22,9 +22,9 @@ extern portMUX_TYPE rtc_spinlock; static __attribute__((constructor)) void adc2_init_code_calibration(void) { adc_hal_calibration_init(ADC_UNIT_2); - adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); portENTER_CRITICAL(&rtc_spinlock); - adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); portEXIT_CRITICAL(&rtc_spinlock); } 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 dcb1f22d885..badd45f01ac 100644 --- a/components/esp_hw_support/test_apps/.build-test-rules.yml +++ b/components/esp_hw_support/test_apps/.build-test-rules.yml @@ -13,6 +13,11 @@ components/esp_hw_support/test_apps/esp_hw_support_unity_tests: components/esp_hw_support/test_apps/etm: disable: - if: SOC_ETM_SUPPORTED != 1 + depends_components: + - esp_driver_gptimer + - esp_driver_gpio + - esp_timer + - driver # TODO: replace with esp_driver_mcpwm, esp_driver_ana_cmpr components/esp_hw_support/test_apps/host_test_linux: enable: 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 e7a895debdc..7b84296f731 100644 --- a/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt +++ b/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt @@ -29,5 +29,6 @@ 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_timer driver + PRIV_REQUIRES unity esp_timer esp_driver_gptimer esp_driver_gpio + driver # TODO: replace with esp_driver_mcpwm (IDF-8379), esp_driver_ana_cmpr WHOLE_ARCHIVE) diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_80ddr_80ddr_ecc b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_80ddr_80ddr_ecc index f9dd19e0c88..7ab1d4bcfe0 100644 --- a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_80ddr_80ddr_ecc +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_80ddr_80ddr_ecc @@ -10,4 +10,4 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_SPIRAM=y CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SPEED_80M=y -CONFIG_SPIRAM_ECC_ENABLE = y +CONFIG_SPIRAM_ECC_ENABLE=y diff --git a/components/esp_hw_support/test_apps/mspi_psram_with_dfs/sdkconfig.ci.f8r8_80ddr_80ddr_ecc b/components/esp_hw_support/test_apps/mspi_psram_with_dfs/sdkconfig.ci.f8r8_80ddr_80ddr_ecc index 200726d60d8..d9441e88687 100644 --- a/components/esp_hw_support/test_apps/mspi_psram_with_dfs/sdkconfig.ci.f8r8_80ddr_80ddr_ecc +++ b/components/esp_hw_support/test_apps/mspi_psram_with_dfs/sdkconfig.ci.f8r8_80ddr_80ddr_ecc @@ -7,4 +7,4 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_SPIRAM=y CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SPEED_80M=y -CONFIG_SPIRAM_ECC_ENABLE = y +CONFIG_SPIRAM_ECC_ENABLE=y diff --git a/components/esp_lcd/CMakeLists.txt b/components/esp_lcd/CMakeLists.txt index 9e1c10b1374..aa0595a54db 100644 --- a/components/esp_lcd/CMakeLists.txt +++ b/components/esp_lcd/CMakeLists.txt @@ -27,5 +27,5 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} PRIV_REQUIRES ${priv_requires} - REQUIRES driver + REQUIRES driver esp_driver_gpio LDFRAGMENTS linker.lf) diff --git a/components/esp_netif/include/esp_netif_ip_addr.h b/components/esp_netif/include/esp_netif_ip_addr.h index 354da5814ba..b8608c9c755 100644 --- a/components/esp_netif/include/esp_netif_ip_addr.h +++ b/components/esp_netif/include/esp_netif_ip_addr.h @@ -79,8 +79,8 @@ extern "C" { #define ESP_IP4TOADDR(a,b,c,d) esp_netif_htonl(ESP_IP4TOUINT32(a, b, c, d)) -#define ESP_IP4ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V4, .u_addr = { .ip4 = { .addr = ESP_IP4TOADDR(a, b, c, d) }}}; -#define ESP_IP6ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V6, .u_addr = { .ip6 = { .addr = { a, b, c, d }, .zone = 0 }}}; +#define ESP_IP4ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V4, .u_addr = { .ip4 = { .addr = ESP_IP4TOADDR(a, b, c, d) }}} +#define ESP_IP6ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V6, .u_addr = { .ip6 = { .addr = { a, b, c, d }, .zone = 0 }}} #ifndef IP4ADDR_STRLEN_MAX #define IP4ADDR_STRLEN_MAX 16 diff --git a/components/esp_partition/CMakeLists.txt b/components/esp_partition/CMakeLists.txt index 6610d7a4d1e..1f0ecb38fbb 100644 --- a/components/esp_partition/CMakeLists.txt +++ b/components/esp_partition/CMakeLists.txt @@ -41,5 +41,3 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU") set_property(SOURCE ${cache_srcs} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-inline-small-functions -fno-inline-functions-called-once") endif() - -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/esp_partition/partition_linux.c b/components/esp_partition/partition_linux.c index cf3e86491e7..9303498282e 100644 --- a/components/esp_partition/partition_linux.c +++ b/components/esp_partition/partition_linux.c @@ -7,6 +7,7 @@ #include #include #include +#include #if __has_include() // for strlcpy #include @@ -106,8 +107,8 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) if (strlen(s_esp_partition_file_mmap_ctrl_input.flash_file_name) > 0) { // Open existing file. If size or partition table file were specified, raise errors if (s_esp_partition_file_mmap_ctrl_input.flash_file_size > 0) { - ESP_LOGE(TAG, "Flash emulation file size: %u was specified while together with the file name: %s (illegal). Use file size = 0", - s_esp_partition_file_mmap_ctrl_input.flash_file_size, + ESP_LOGE(TAG, "Flash emulation file size: %" PRIu32" was specified while together with the file name: %s (illegal). Use file size = 0", + (uint32_t) s_esp_partition_file_mmap_ctrl_input.flash_file_size, s_esp_partition_file_mmap_ctrl_input.flash_file_name); return ESP_ERR_INVALID_ARG; } @@ -133,9 +134,9 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) // conflicting input if (has_partfile != has_len) { - ESP_LOGE(TAG, "Invalid combination of Partition file name: %s flash file size: %u was specified. Use either both parameters or none.", + ESP_LOGE(TAG, "Invalid combination of Partition file name: %s flash file size: %" PRIu32 " was specified. Use either both parameters or none.", s_esp_partition_file_mmap_ctrl_input.partition_file_name, - s_esp_partition_file_mmap_ctrl_input.flash_file_size); + (uint32_t) s_esp_partition_file_mmap_ctrl_input.flash_file_size); return ESP_ERR_INVALID_ARG; } @@ -211,7 +212,7 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) break; } - ESP_LOGV(TAG, "SPIFLASH memory emulation file created: %s (size: %d B)", s_esp_partition_file_mmap_ctrl_act.flash_file_name, s_esp_partition_file_mmap_ctrl_act.flash_file_size); + ESP_LOGV(TAG, "SPIFLASH memory emulation file created: %s (size: %" PRIu32 " B)", s_esp_partition_file_mmap_ctrl_act.flash_file_name, (uint32_t) s_esp_partition_file_mmap_ctrl_act.flash_file_size); // create memory-mapping for the flash holder file if ((s_spiflash_mem_file_buf = mmap(NULL, s_esp_partition_file_mmap_ctrl_act.flash_file_size, PROT_READ | PROT_WRITE, MAP_SHARED, s_spiflash_mem_file_fd, 0)) == MAP_FAILED) { @@ -242,10 +243,10 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) // check whether partition table fits into the memory mapped file if (partition_table_file_size + ESP_PARTITION_TABLE_OFFSET > s_esp_partition_file_mmap_ctrl_act.flash_file_size) { - ESP_LOGE(TAG, "Flash file: %s (size: %d B) cannot hold partition table requiring %d B", + ESP_LOGE(TAG, "Flash file: %s (size: %" PRIu32 " B) cannot hold partition table requiring %d B", s_esp_partition_file_mmap_ctrl_act.flash_file_name, - s_esp_partition_file_mmap_ctrl_act.flash_file_size, - partition_table_file_size + ESP_PARTITION_TABLE_OFFSET); + (uint32_t) s_esp_partition_file_mmap_ctrl_act.flash_file_size, + (int) (partition_table_file_size + ESP_PARTITION_TABLE_OFFSET)); ret = ESP_ERR_INVALID_SIZE; break; } @@ -294,9 +295,9 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) ESP_LOGV(TAG, " label: %s", p_part_item->label); ESP_LOGV(TAG, " type: %s", esp_partition_type_to_str(p_part_item->type)); ESP_LOGV(TAG, " subtype: %s", esp_partition_subtype_to_str(p_part_item->type, p_part_item->subtype)); - ESP_LOGV(TAG, " offset: 0x%08X", p_part_item->pos.offset); - ESP_LOGV(TAG, " size: %d", p_part_item->pos.size); - ESP_LOGV(TAG, " flags: %d", p_part_item->flags); + ESP_LOGV(TAG, " offset: 0x%08" PRIX32, (uint32_t) p_part_item->pos.offset); + ESP_LOGV(TAG, " size: %" PRIu32, (uint32_t) p_part_item->pos.size); + ESP_LOGV(TAG, " flags: %" PRIu32, (uint32_t) p_part_item->flags); part_ptr += sizeof(esp_partition_info_t); } @@ -383,7 +384,7 @@ esp_err_t esp_partition_write(const esp_partition_t *partition, size_t dst_offse } void *dst_addr = s_spiflash_mem_file_buf + partition->address + dst_offset; - ESP_LOGV(TAG, "esp_partition_write(): partition=%s dst_offset=%zu src=%p size=%zu (real dst address: %p)", partition->label, dst_offset, src, size, dst_addr); + ESP_LOGV(TAG, "esp_partition_write(): partition=%s dst_offset=%" PRIu32 " src=%p size=%" PRIu32 " (real dst address: %p)", partition->label, (uint32_t) dst_offset, src, (uint32_t) size, dst_addr); // local size, can be modified by the write hook in case of simulated power-off size_t new_size = size; @@ -428,7 +429,7 @@ esp_err_t esp_partition_read(const esp_partition_t *partition, size_t src_offset } void *src_addr = s_spiflash_mem_file_buf + partition->address + src_offset; - ESP_LOGV(TAG, "esp_partition_read(): partition=%s src_offset=%zu dst=%p size=%zu (real src address: %p)", partition->label, src_offset, dst, size, src_addr); + ESP_LOGV(TAG, "esp_partition_read(): partition=%s src_offset=%" PRIu32 " dst=%p size=%" PRIu32 " (real src address: %p)", partition->label, (uint32_t) src_offset, dst, (uint32_t) size, src_addr); memcpy(dst, src_addr, size); @@ -464,7 +465,7 @@ esp_err_t esp_partition_erase_range(const esp_partition_t *partition, size_t off } void *target_addr = s_spiflash_mem_file_buf + partition->address + offset; - ESP_LOGV(TAG, "esp_partition_erase_range(): partition=%s offset=%zu size=%zu (real target address: %p)", partition->label, offset, size, target_addr); + ESP_LOGV(TAG, "esp_partition_erase_range(): partition=%s offset=%" PRIu32 " size=%" PRIu32 " (real target address: %p)", partition->label, (uint32_t) offset, (uint32_t) size, target_addr); // local size to be potentially updated by the hook in case of power-off event size_t new_size = size; @@ -496,7 +497,7 @@ esp_err_t esp_partition_mmap(const esp_partition_t *partition, size_t offset, si esp_partition_mmap_memory_t memory, const void **out_ptr, esp_partition_mmap_handle_t *out_handle) { - ESP_LOGV(TAG, "esp_partition_mmap(): partition=%s offset=%zu size=%zu", partition->label, offset, size); + ESP_LOGV(TAG, "esp_partition_mmap(): partition=%s offset=%" PRIu32 " size=%" PRIu32 "", partition->label, (uint32_t) offset, (uint32_t) size); assert(partition != NULL); if (offset > partition->size) { diff --git a/components/esp_partition/test/CMakeLists.txt b/components/esp_partition/test/CMakeLists.txt index 56c4de4a73e..6451ab5bd65 100644 --- a/components/esp_partition/test/CMakeLists.txt +++ b/components/esp_partition/test/CMakeLists.txt @@ -1,4 +1,3 @@ idf_component_register(SRC_DIRS "." PRIV_INCLUDE_DIRS "." PRIV_REQUIRES test_utils esp_partition esp_system app_update bootloader_support spi_flash) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/esp_phy/lib b/components/esp_phy/lib index ecd88d5ce35..a8e8b9532e2 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit ecd88d5ce3578e45402b80b78c26969ef8732839 +Subproject commit a8e8b9532e2874ac167d4ade7808fda70fe05820 diff --git a/components/esp_phy/linker.lf b/components/esp_phy/linker.lf index a5a355da2e3..40d3b99c9d0 100644 --- a/components/esp_phy/linker.lf +++ b/components/esp_phy/linker.lf @@ -1,7 +1,10 @@ if IDF_TARGET_ESP32 = y: [scheme:phy_iram] entries: + if ESP_WIFI_SLP_IRAM_OPT = y: phy_iram -> iram0_text + else: + phy_iram -> flash_text [sections:phy_iram] entries: @@ -11,7 +14,7 @@ if IDF_TARGET_ESP32 = y: archive: libphy.a entries: * (noflash_data) - if ESP_WIFI_SLP_IRAM_OPT = y && IDF_TARGET_ESP32 = y: + if IDF_TARGET_ESP32 = y: * (phy_iram) [mapping:rtc] diff --git a/components/esp_phy/src/phy_common.c b/components/esp_phy/src/phy_common.c index d28745b8e8b..ad4a3b388e3 100644 --- a/components/esp_phy/src/phy_common.c +++ b/components/esp_phy/src/phy_common.c @@ -13,7 +13,7 @@ static volatile uint16_t s_phy_modem_flag = 0; extern void phy_param_track_tot(bool en_wifi, bool en_ble_154); static esp_timer_handle_t phy_track_pll_timer; -#if CONFIG_WIFI_ENABLED +#if CONFIG_ESP_WIFI_ENABLED static volatile int64_t s_wifi_prev_timestamp; #endif #if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED @@ -21,7 +21,7 @@ static volatile int64_t s_bt_154_prev_timestamp; #endif #define PHY_TRACK_PLL_PERIOD_IN_US 1000000 -#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED || CONFIG_WIFI_ENABLED +#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED || CONFIG_ESP_WIFI_ENABLED bool phy_enabled_modem_contains(esp_phy_modem_t modem) { return (s_phy_modem_flag & modem) != 0; @@ -32,7 +32,7 @@ static void phy_track_pll(void) { bool wifi_track_pll = false; bool ble_154_track_pll = false; -#if CONFIG_WIFI_ENABLED +#if CONFIG_ESP_WIFI_ENABLED if (phy_enabled_modem_contains(PHY_MODEM_WIFI)) { wifi_track_pll = true; s_wifi_prev_timestamp = esp_timer_get_time(); @@ -64,7 +64,7 @@ void phy_track_pll_init(void) // Using a variable to record the previously tracked time when PLL was last called. // If the duration is larger than PHY_TRACK_PLL_PERIOD_IN_US, then track PLL. bool need_track_pll = false; -#if CONFIG_WIFI_ENABLED +#if CONFIG_ESP_WIFI_ENABLED need_track_pll = need_track_pll || ((esp_timer_get_time() - s_wifi_prev_timestamp) > PHY_TRACK_PLL_PERIOD_IN_US); #endif #if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED diff --git a/components/esp_phy/test/test_phy_rtc.c b/components/esp_phy/test/test_phy_rtc.c index 7cfe722722c..1d653ce15cc 100644 --- a/components/esp_phy/test/test_phy_rtc.c +++ b/components/esp_phy/test/test_phy_rtc.c @@ -46,7 +46,7 @@ static void test_phy_rtc_init(void) ret = nvs_flash_init(); } TEST_ESP_OK(ret); -#if CONFIG_WIFI_ENABLED +#if CONFIG_ESP_WIFI_ENABLED esp_phy_enable(PHY_MODEM_WIFI); #endif #if CONFIG_BT_ENABLED diff --git a/components/esp_pm/CMakeLists.txt b/components/esp_pm/CMakeLists.txt index 72c97423711..a4b414e99b2 100644 --- a/components/esp_pm/CMakeLists.txt +++ b/components/esp_pm/CMakeLists.txt @@ -6,5 +6,5 @@ endif() idf_component_register(SRCS "pm_locks.c" "pm_trace.c" "pm_impl.c" INCLUDE_DIRS include - PRIV_REQUIRES esp_system driver esp_timer + PRIV_REQUIRES esp_system driver esp_driver_gpio esp_timer LDFRAGMENTS linker.lf) diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index ea712c420c6..b1809a422a8 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -77,7 +77,7 @@ entries: esp_time_impl:esp_set_time_from_rtc (noflash) [mapping:driver_pm] -archive: libdriver.a +archive: libesp_driver_gpio.a entries: if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y: gpio:gpio_sleep_pupd_config_unapply (noflash) diff --git a/components/esp_ringbuf/CMakeLists.txt b/components/esp_ringbuf/CMakeLists.txt index 04ed12a0fb9..09bfac678b7 100644 --- a/components/esp_ringbuf/CMakeLists.txt +++ b/components/esp_ringbuf/CMakeLists.txt @@ -1,9 +1,5 @@ idf_build_get_property(target IDF_TARGET) -if(${target} STREQUAL "linux") - return() # This component is not supported by the POSIX/Linux simulator -endif() - idf_component_register(SRCS "ringbuf.c" INCLUDE_DIRS "include" LDFRAGMENTS linker.lf) diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 02ec89d331f..0701edc6c82 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -30,7 +30,7 @@ else() endif() endif() - if(CONFIG_HEAP_TLSF_USE_ROM_IMPL AND CONFIG_ESP_ROM_TLSF_CHECK_PATCH) + if(CONFIG_HEAP_TLSF_USE_ROM_IMPL AND (CONFIG_ESP_ROM_TLSF_CHECK_PATCH OR CONFIG_HEAP_TLSF_CHECK_PATCH)) # This file shall be included in the build if TLSF in ROM is activated list(APPEND sources "patches/esp_rom_tlsf.c") endif() @@ -301,7 +301,7 @@ else() # Regular app build # to force the linker to integrate the whole `esp_rom_tlsf.c` object file inside the # final binary. This is necessary because tlsf_set_rom_patches is a constructor, thus, # there as no explicit reference/call to it in IDF. - if(CONFIG_ESP_ROM_TLSF_CHECK_PATCH) + if((CONFIG_ESP_ROM_TLSF_CHECK_PATCH OR CONFIG_HEAP_TLSF_CHECK_PATCH)) target_link_libraries(${COMPONENT_LIB} PRIVATE "-u tlsf_set_rom_patches") endif() diff --git a/components/esp_rom/esp32c2/Kconfig.soc_caps.in b/components/esp_rom/esp32c2/Kconfig.soc_caps.in index 752cf25be62..b2d3381e8c5 100644 --- a/components/esp_rom/esp32c2/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c2/Kconfig.soc_caps.in @@ -39,10 +39,6 @@ config ESP_ROM_HAS_HEAP_TLSF bool default y -config ESP_ROM_TLSF_CHECK_PATCH - bool - default y - config ESP_ROM_HAS_LAYOUT_TABLE bool default y diff --git a/components/esp_rom/esp32c2/esp_rom_caps.h b/components/esp_rom/esp32c2/esp_rom_caps.h index 8eacb1616c0..cc3fdc51804 100644 --- a/components/esp_rom/esp32c2/esp_rom_caps.h +++ b/components/esp_rom/esp32c2/esp_rom_caps.h @@ -15,7 +15,6 @@ #define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver #define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver #define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library -#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check() #define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table #define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver #define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano version of formatting functions diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 5a2367187e4..eb9702f174a 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -1035,9 +1035,7 @@ r_ble_ll_utils_csa2_prng = 0x400013b8; r_ble_ll_utils_remapped_channel = 0x400013bc; r_ble_ll_whitelist_add = 0x400013c0; r_ble_ll_whitelist_chg_allowed = 0x400013c4; -r_ble_ll_whitelist_clear = 0x400013c8; r_ble_ll_whitelist_read_size = 0x400013cc; -r_ble_ll_whitelist_rmv = 0x400013d0; r_ble_ll_write_rf_path_compensation = 0x400013d8; r_ble_lll_adv_aux_schedule = 0x400013e0; r_ble_lll_adv_aux_schedule_first = 0x400013e4; @@ -1113,7 +1111,6 @@ r_ble_lll_conn_master_common_init = 0x40001530; r_ble_lll_conn_master_new = 0x40001534; r_ble_lll_conn_module_reset = 0x40001540; r_ble_lll_conn_pre_process = 0x40001548; -r_ble_lll_conn_process_acked_pdu = 0x4000154c; r_ble_lll_conn_recv_ack = 0x40001554; r_ble_lll_conn_recv_valid_packet = 0x40001558; r_ble_lll_conn_reset_pending_sched = 0x4000155c; @@ -1196,7 +1193,6 @@ r_ble_lll_scan_npl_store = 0x400016dc; r_ble_lll_scan_period_timer_cb = 0x400016e0; r_ble_lll_scan_process_adv_in_isr = 0x400016e4; r_ble_lll_scan_req_backoff = 0x400016ec; -r_ble_lll_scan_restart = 0x400016f0; r_ble_lll_scan_sched_next_aux = 0x40001700; r_ble_lll_scan_sched_remove = 0x40001704; r_ble_lll_scan_start = 0x40001708; @@ -1520,7 +1516,7 @@ mac_tx_set_htsig = 0x40001b5c; mac_tx_set_plcp0 = 0x40001b60; mac_tx_set_plcp1 = 0x40001b64; mac_tx_set_plcp2 = 0x40001b68; -pm_check_state = 0x40001b6c; +/* pm_check_state = 0x40001b6c; */ pm_disable_dream_timer = 0x40001b70; pm_disable_sleep_delay_timer = 0x40001b74; pm_dream = 0x40001b78; @@ -1544,10 +1540,10 @@ pm_on_tbtt = 0x40001ba8; pm_sleep_for = 0x40001bc0; /* pm_tbtt_process = 0x40001bc4; */ ppAMPDU2Normal = 0x40001bc8; -ppAssembleAMPDU = 0x40001bcc; +/*ppAssembleAMPDU = 0x40001bcc;*/ ppCalFrameTimes = 0x40001bd0; ppCalSubFrameLength = 0x40001bd4; -ppCalTxAMPDULength = 0x40001bd8; +/*ppCalTxAMPDULength = 0x40001bd8;*/ ppCheckTxAMPDUlength = 0x40001bdc; ppDequeueRxq_Locked = 0x40001be0; ppDequeueTxQ = 0x40001be4; @@ -1567,8 +1563,8 @@ ppRecycleAmpdu = 0x40001c18; ppRecycleRxPkt = 0x40001c1c; ppResortTxAMPDU = 0x40001c20; ppResumeTxAMPDU = 0x40001c24; -ppRxFragmentProc = 0x40001c28; -ppRxPkt = 0x40001c2c; +/*ppRxFragmentProc = 0x40001c28;*/ +/* ppRxPkt = 0x40001c2c; */ ppRxProtoProc = 0x40001c30; ppSearchTxQueue = 0x40001c34; ppSearchTxframe = 0x40001c38; @@ -1596,7 +1592,7 @@ rcLowerSched = 0x40001c8c; rcSetTxAmpduLimit = 0x40001c90; /* rcTxUpdatePer = 0x40001c94;*/ rcUpdateAckSnr = 0x40001c98; -rcUpdateRate = 0x40001c9c; +/*rcUpdateRate = 0x40001c9c;*/ rcUpdateTxDone = 0x40001ca0; rcUpdateTxDoneAmpdu2 = 0x40001ca4; rcUpSched = 0x40001ca8; @@ -1631,7 +1627,7 @@ ppDequeueTxDone_Locked = 0x40001d18; ppProcTxDone = 0x40001d1c; /*pm_tx_data_done_process = 0x40001d20;*/ config_is_cache_tx_buf_enabled = 0x40001d24; -ppMapWaitTxq = 0x40001d28; +//ppMapWaitTxq = 0x40001d28; ppProcessWaitingQueue = 0x40001d2c; ppDisableQueue = 0x40001d30; pm_allow_tx = 0x40001d34; @@ -1671,7 +1667,7 @@ lmacRetryTxFrame = 0x40001db8; lmacProcessCollisions_task = 0x40001dbc; /*lmacProcessTxopQComplete = 0x40001dc0;*/ lmacInitAc = 0x40001dc4; -lmacInit = 0x40001dc8; +/*lmacInit = 0x40001dc8;*/ mac_tx_set_txop_q = 0x40001dcc; /*hal_init = 0x40001dd0;*/ hal_mac_rx_set_policy = 0x40001dd4; @@ -1729,14 +1725,14 @@ pp_timer_do_process = 0x40001ea0; rcUpdateAMPDUParam = 0x40001ea4; rcUpdatePhyMode = 0x40001ea8; rcGetHighestRateIdx = 0x40001eac; -pm_tx_null_data_done_process = 0x40001eb0; -pm_tx_data_process = 0x40001eb4; +//pm_tx_null_data_done_process = 0x40001eb0; +//pm_tx_data_process = 0x40001eb4; /* pm_attach = 0x40001eb8; */ /* pm_coex_schm_process = 0x40001ebc; */ ppInitTxq = 0x40001ec0; pp_attach = 0x40001ec4; pp_deattach = 0x40001ec8; -pm_on_probe_resp_rx = 0x40001ecc; +//pm_on_probe_resp_rx = 0x40001ecc; hal_set_sta_tsf = 0x40001ed0; ic_update_sta_tsf = 0x40001ed4; ic_tx_pkt = 0x40001ed8; @@ -1880,7 +1876,7 @@ ieee80211_recycle_cache_eb = 0x40001fe8; ieee80211_search_node = 0x40001fec; roundup2 = 0x40001ff0; ieee80211_crypto_encap = 0x40001ff4; -ieee80211_crypto_decap = 0x40001ff8; +/* ieee80211_crypto_decap = 0x40001ff8; */ ieee80211_decap = 0x40001ffc; ieee80211_set_tx_pti = 0x40002000; wifi_is_started = 0x40002004; @@ -1915,7 +1911,7 @@ wifi_get_init_state = 0x40002088; /* cnx_coexist_timeout = 0x40002090; */ /* sta_recv_mgmt = 0x40002094;*/ ieee80211_send_setup = 0x40002098; -ieee80211_send_probereq = 0x4000209c; +//ieee80211_send_probereq = 0x4000209c; sta_auth_shared = 0x400020a4; /* cnx_coexist_timeout_process = 0x400020ac; */ ieee80211_alloc_challenge = 0x400020b0; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld index 8a1c7fc5453..8de0f1f37d4 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld @@ -14,6 +14,7 @@ lmacTxDone = 0x4000162c; lmacTxFrame = 0x40001630; mac_tx_set_htsig = 0x40001638; mac_tx_set_plcp1 = 0x40001640; +pm_check_state = 0x40001648; pm_on_beacon_rx = 0x4000167c; /*pm_parse_beacon = 0x40001688;*/ pm_process_tim = 0x4000168c; @@ -23,7 +24,7 @@ pm_rx_data_process = 0x40001694; /* pm_tbtt_process = 0x400016a0;*/ ppMapTxQueue = 0x400016d8; ppProcTxSecFrame = 0x400016dc; -ppRxFragmentProc = 0x40001704; +/*ppRxFragmentProc = 0x40001704;*/ /* rcGetSched = 0x40001764;*/ rcTxUpdatePer = 0x40001770; rcUpdateTxDone = 0x4000177c; @@ -33,6 +34,7 @@ wDev_ProcessFiq = 0x400017f0; wDev_ProcessRxSucData = 0x400017f4; ppProcTxDone = 0x40001804; pm_tx_data_done_process = 0x40001808; +ppMapWaitTxq = 0x40001810; ieee80211_encap_esfbuf = 0x4000185c; sta_input = 0x40001870; ieee80211_crypto_decap = 0x4000189c; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index f897770b045..3008884be9b 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -1535,7 +1535,7 @@ mac_tx_set_duration = 0x40001634; mac_tx_set_plcp0 = 0x4000163c; /* mac_tx_set_plcp1 = 0x40001640;*/ mac_tx_set_plcp2 = 0x40001644; -pm_check_state = 0x40001648; +/* pm_check_state = 0x40001648; */ pm_disable_dream_timer = 0x4000164c; pm_disable_sleep_delay_timer = 0x40001650; pm_dream = 0x40001654; @@ -1559,10 +1559,10 @@ pm_on_tbtt = 0x40001684; pm_sleep_for = 0x4000169c; /* pm_tbtt_process = 0x400016a0; */ ppAMPDU2Normal = 0x400016a4; -ppAssembleAMPDU = 0x400016a8; +/*ppAssembleAMPDU = 0x400016a8;*/ ppCalFrameTimes = 0x400016ac; ppCalSubFrameLength = 0x400016b0; -ppCalTxAMPDULength = 0x400016b4; +/*ppCalTxAMPDULength = 0x400016b4;*/ ppCheckTxAMPDUlength = 0x400016b8; ppDequeueRxq_Locked = 0x400016bc; ppDequeueTxQ = 0x400016c0; @@ -1581,7 +1581,7 @@ ppRecycleRxPkt = 0x400016f8; ppResortTxAMPDU = 0x400016fc; ppResumeTxAMPDU = 0x40001700; /* ppRxFragmentProc = 0x40001704; */ -ppRxPkt = 0x40001708; +/* ppRxPkt = 0x40001708; */ ppRxProtoProc = 0x4000170c; ppSearchTxQueue = 0x40001710; ppSearchTxframe = 0x40001714; @@ -1608,7 +1608,7 @@ rcLowerSched = 0x40001768; rcSetTxAmpduLimit = 0x4000176c; /* rcTxUpdatePer = 0x40001770;*/ rcUpdateAckSnr = 0x40001774; -rcUpdateRate = 0x40001778; +/*rcUpdateRate = 0x40001778;*/ /* rcUpdateTxDone = 0x4000177c; */ rcUpdateTxDoneAmpdu2 = 0x40001780; rcUpSched = 0x40001784; @@ -1644,7 +1644,7 @@ wdev_csi_len_align = 0x400017fc; ppDequeueTxDone_Locked = 0x40001800; /*pm_tx_data_done_process = 0x40001808;*/ config_is_cache_tx_buf_enabled = 0x4000180c; -ppMapWaitTxq = 0x40001810; +//ppMapWaitTxq = 0x40001810; ppProcessWaitingQueue = 0x40001814; ppDisableQueue = 0x40001818; pm_allow_tx = 0x4000181c; diff --git a/components/esp_rom/esp32c6/Kconfig.soc_caps.in b/components/esp_rom/esp32c6/Kconfig.soc_caps.in index 9e23f349b7e..df5e153a0d2 100644 --- a/components/esp_rom/esp32c6/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c6/Kconfig.soc_caps.in @@ -47,6 +47,10 @@ config ESP_ROM_HAS_HEAP_TLSF bool default y +config ESP_ROM_TLSF_CHECK_PATCH + bool + default y + config ESP_ROM_HAS_LAYOUT_TABLE bool default y diff --git a/components/esp_rom/esp32c6/esp_rom_caps.h b/components/esp_rom/esp32c6/esp_rom_caps.h index 1ec2d872390..1eeab3bd3e8 100644 --- a/components/esp_rom/esp32c6/esp_rom_caps.h +++ b/components/esp_rom/esp32c6/esp_rom_caps.h @@ -17,6 +17,7 @@ #define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver #define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver #define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library +#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool() #define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table #define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver #define ESP_ROM_HAS_REGI2C_BUG (1) // ROM has the regi2c bug diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld index 1e953883832..f09bb74f08a 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld @@ -37,7 +37,6 @@ tlsf_pool_overhead = 0x40000438; tlsf_alloc_overhead = 0x4000043c; tlsf_walk_pool = 0x40000440; tlsf_check = 0x40000444; -tlsf_check_pool = 0x40000448; tlsf_poison_fill_pfunc_set = 0x4000044c; tlsf_poison_check_pfunc_set = 0x40000450; multi_heap_get_block_address_impl = 0x40000454; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld index e5bd02bd984..c096f962399 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld @@ -48,7 +48,7 @@ ieee80211_copy_eb_header = 0x40000bb4; ieee80211_recycle_cache_eb = 0x40000bb8; ieee80211_search_node = 0x40000bbc; ieee80211_crypto_encap = 0x40000bc0; -ieee80211_crypto_decap = 0x40000bc4; +/* ieee80211_crypto_decap = 0x40000bc4; */ ieee80211_decap = 0x40000bc8; wifi_is_started = 0x40000bcc; ieee80211_gettid = 0x40000bd0; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index 418df8e6c28..af1fbbc8e1b 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -56,7 +56,7 @@ mac_tx_set_duration = 0x40000c60; //mac_tx_set_plcp0 = 0x40000c64; //mac_tx_set_plcp1 = 0x40000c68; mac_tx_set_plcp2 = 0x40000c6c; -pm_check_state = 0x40000c70; +/* pm_check_state = 0x40000c70; */ /* pm_disable_dream_timer = 0x40000c74; */ pm_disable_sleep_delay_timer = 0x40000c78; pm_dream = 0x40000c7c; @@ -100,7 +100,7 @@ ppRecycleAmpdu = 0x40000d10; ppRecycleRxPkt = 0x40000d14; //ppResortTxAMPDU = 0x40000d18; ppResumeTxAMPDU = 0x40000d1c; -ppRxFragmentProc = 0x40000d20; +/*ppRxFragmentProc = 0x40000d20;*/ //ppRxPkt = 0x40000d24; ppRxProtoProc = 0x40000d28; ppSearchTxQueue = 0x40000d2c; @@ -129,7 +129,7 @@ rcLowerSched = 0x40000d84; rcSetTxAmpduLimit = 0x40000d88; rcTxUpdatePer = 0x40000d8c; rcUpdateAckSnr = 0x40000d90; -rcUpdateRate = 0x40000d94; +/*rcUpdateRate = 0x40000d94;*/ rcUpdateTxDone = 0x40000d98; rcUpdateTxDoneAmpdu2 = 0x40000d9c; rcUpSched = 0x40000da0; @@ -165,7 +165,7 @@ ppDequeueTxDone_Locked = 0x40000e14; //ppProcTxDone = 0x40000e18; //pm_tx_data_done_process = 0x40000e1c; config_is_cache_tx_buf_enabled = 0x40000e20; -ppMapWaitTxq = 0x40000e24; +//ppMapWaitTxq = 0x40000e24; ppProcessWaitingQueue = 0x40000e28; ppDisableQueue = 0x40000e2c; pm_allow_tx = 0x40000e30; diff --git a/components/esp_rom/esp32h2/Kconfig.soc_caps.in b/components/esp_rom/esp32h2/Kconfig.soc_caps.in index a5b8f879714..9e95fbf265f 100644 --- a/components/esp_rom/esp32h2/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32h2/Kconfig.soc_caps.in @@ -39,6 +39,10 @@ config ESP_ROM_HAS_HEAP_TLSF bool default y +config ESP_ROM_TLSF_CHECK_PATCH + bool + default y + config ESP_ROM_HAS_LAYOUT_TABLE bool default y diff --git a/components/esp_rom/esp32h2/esp_rom_caps.h b/components/esp_rom/esp32h2/esp_rom_caps.h index 321ab91b8e4..375f91137d5 100644 --- a/components/esp_rom/esp32h2/esp_rom_caps.h +++ b/components/esp_rom/esp32h2/esp_rom_caps.h @@ -15,6 +15,7 @@ #define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver #define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver #define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library +#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool() #define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table #define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver #define ESP_ROM_WITHOUT_REGI2C (1) // ROM has no regi2c APIs diff --git a/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld b/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld index 3e17e87eba2..0c176cbbb4e 100644 --- a/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld +++ b/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld @@ -37,7 +37,6 @@ tlsf_pool_overhead = 0x40000430; tlsf_alloc_overhead = 0x40000434; tlsf_walk_pool = 0x40000438; tlsf_check = 0x4000043c; -tlsf_check_pool = 0x40000440; tlsf_poison_fill_pfunc_set = 0x40000444; tlsf_poison_check_pfunc_set = 0x40000448; multi_heap_get_block_address_impl = 0x4000044c; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index af00ff50c22..5a86f0cef7b 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -1837,7 +1837,7 @@ mac_tx_set_duration = 0x400053dc; mac_tx_set_plcp0 = 0x400053f4; /* mac_tx_set_plcp1 = 0x40005400;*/ mac_tx_set_plcp2 = 0x4000540c; -pm_check_state = 0x40005418; +/* pm_check_state = 0x40005418; */ pm_disable_dream_timer = 0x40005424; pm_disable_sleep_delay_timer = 0x40005430; pm_dream = 0x4000543c; @@ -1861,10 +1861,10 @@ pm_on_tbtt = 0x400054cc; pm_sleep_for = 0x40005514; /* pm_tbtt_process = 0x40005520; */ ppAMPDU2Normal = 0x4000552c; -ppAssembleAMPDU = 0x40005538; +/*ppAssembleAMPDU = 0x40005538;*/ ppCalFrameTimes = 0x40005544; ppCalSubFrameLength = 0x40005550; -ppCalTxAMPDULength = 0x4000555c; +/*ppCalTxAMPDULength = 0x4000555c;*/ ppCheckTxAMPDUlength = 0x40005568; ppDequeueRxq_Locked = 0x40005574; ppDequeueTxQ = 0x40005580; @@ -1884,7 +1884,7 @@ ppRecycleRxPkt = 0x40005628; ppResortTxAMPDU = 0x40005634; ppResumeTxAMPDU = 0x40005640; /* ppRxFragmentProc = 0x4000564c; */ -ppRxPkt = 0x40005658; +/* ppRxPkt = 0x40005658; */ ppRxProtoProc = 0x40005664; ppSearchTxQueue = 0x40005670; ppSearchTxframe = 0x4000567c; @@ -1912,7 +1912,7 @@ rcLowerSched = 0x40005778; rcSetTxAmpduLimit = 0x40005784; /* rcTxUpdatePer = 0x40005790;*/ rcUpdateAckSnr = 0x4000579c; -rcUpdateRate = 0x400057a8; +/*rcUpdateRate = 0x400057a8;*/ /* rcUpdateTxDone = 0x400057b4; */ rcUpdateTxDoneAmpdu2 = 0x400057c0; rcUpSched = 0x400057cc; @@ -1950,7 +1950,7 @@ ppDequeueTxDone_Locked = 0x40005940; /*ppProcTxDone = 0x4000594c;*/ /*pm_tx_data_done_process = 0x40005958;*/ config_is_cache_tx_buf_enabled = 0x40005964; -ppMapWaitTxq = 0x40005970; +//ppMapWaitTxq = 0x40005970; ppProcessWaitingQueue = 0x4000597c; ppDisableQueue = 0x40005988; pm_allow_tx = 0x40005994; diff --git a/components/esp_rom/linker.lf b/components/esp_rom/linker.lf index 99ddf6bdd42..bc708c5697b 100644 --- a/components/esp_rom/linker.lf +++ b/components/esp_rom/linker.lf @@ -6,7 +6,7 @@ entries: esp_rom_cache_esp32s2_esp32s3 (noflash) if ESP_ROM_HAS_CACHE_WRITEBACK_BUG = y: esp_rom_cache_writeback_esp32s3 (noflash) - if HEAP_TLSF_USE_ROM_IMPL = y && ESP_ROM_TLSF_CHECK_PATCH = y: + if HEAP_TLSF_USE_ROM_IMPL = y && (ESP_ROM_TLSF_CHECK_PATCH = y || HEAP_TLSF_CHECK_PATCH = y): esp_rom_tlsf (noflash) if SOC_SYSTIMER_SUPPORTED = y: esp_rom_systimer (noflash) diff --git a/components/esp_rom/patches/esp_rom_tlsf.c b/components/esp_rom/patches/esp_rom_tlsf.c index 088248acce7..06da0583289 100644 --- a/components/esp_rom/patches/esp_rom_tlsf.c +++ b/components/esp_rom/patches/esp_rom_tlsf.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: Apache-2.0 */ @@ -33,46 +33,10 @@ typedef void* tlsf_walker; #define tlsf_cast(t, exp) ((t) (exp)) -enum tlsf_config { - /* log2 of number of linear subdivisions of block sizes. Larger - ** values require more memory in the control structure. Values of - ** 4 or 5 are typical. - */ - SL_INDEX_COUNT_LOG2 = 5, - - /* All allocation sizes and addresses are aligned to 4 bytes. */ - ALIGN_SIZE_LOG2 = 2, - ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2), - -/* - ** We support allocations of sizes up to (1 << FL_INDEX_MAX) bits. - ** However, because we linearly subdivide the second-level lists, and - ** our minimum size granularity is 4 bytes, it doesn't make sense to - ** create first-level lists for sizes smaller than SL_INDEX_COUNT * 4, - ** or (1 << (SL_INDEX_COUNT_LOG2 + 2)) bytes, as there we will be - ** trying to split size ranges into more slots than we have available. - ** Instead, we calculate the minimum threshold size, and place all - ** blocks below that size into the 0th first-level list. - */ - - /* Fix the value of FL_INDEX_MAX to match the value that is defined - * in the ROM implementation. */ - FL_INDEX_MAX = 18, //Each pool can have up 256KB - - SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2), - FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2), - FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1), - - SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT), -}; - #define block_header_free_bit (1 << 0) #define block_header_prev_free_bit (1 << 1) #define block_header_overhead (sizeof(size_t)) #define block_start_offset (offsetof(block_header_t, size) + sizeof(size_t)) -#define block_size_min (sizeof(block_header_t) - sizeof(block_header_t*)) - -typedef ptrdiff_t tlsfptr_t; typedef struct block_header_t { @@ -87,26 +51,6 @@ typedef struct block_header_t struct block_header_t* prev_free; } block_header_t; -/* The TLSF control structure. */ -typedef struct control_t -{ - /* Empty lists point at this block to indicate they are free. */ - block_header_t block_null; - - /* Bitmaps for free lists. */ - unsigned int fl_bitmap; - unsigned int sl_bitmap[FL_INDEX_COUNT]; - - /* Head of free lists. */ - block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT]; -} control_t; - -static inline __attribute__((__always_inline__)) int tlsf_fls(unsigned int word) -{ - const int bit = word ? 32 - __builtin_clz(word) : 0; - return bit - 1; -} - static inline __attribute__((__always_inline__)) size_t block_size(const block_header_t* block) { return block->size & ~(block_header_free_bit | block_header_prev_free_bit); @@ -122,41 +66,10 @@ static inline __attribute__((__always_inline__)) int block_is_prev_free(const bl return tlsf_cast(int, block->size & block_header_prev_free_bit); } -static inline __attribute__((__always_inline__)) block_header_t* offset_to_block(const void* ptr, size_t size) -{ - return tlsf_cast(block_header_t*, tlsf_cast(tlsfptr_t, ptr) + size); -} - -static inline __attribute__((__always_inline__)) void* block_to_ptr(const block_header_t* block) -{ - return tlsf_cast(void*, - tlsf_cast(unsigned char*, block) + block_start_offset); -} - -static inline __attribute__((__always_inline__)) block_header_t* block_next(const block_header_t* block) -{ - block_header_t* next = offset_to_block(block_to_ptr(block), - block_size(block) - block_header_overhead); - return next; -} - -static inline __attribute__((__always_inline__)) void mapping_insert(size_t size, int* fli, int* sli) +static inline __attribute__((always_inline)) block_header_t* block_from_ptr(const void* ptr) { - int fl, sl; - if (size < SMALL_BLOCK_SIZE) - { - /* Store small blocks in first list. */ - fl = 0; - sl = tlsf_cast(int, size) >> 2; - } - else - { - fl = tlsf_fls(size); - sl = tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2); - fl -= (FL_INDEX_SHIFT - 1); - } - *fli = fl; - *sli = sl; + return tlsf_cast(block_header_t*, + tlsf_cast(unsigned char*, ptr) - block_start_offset); } /* ---------------------------------------------------------------- @@ -173,74 +86,54 @@ void tlsf_poison_check_pfunc_set(poison_check_pfunc_t pfunc) #define tlsf_insist_no_assert(x) { if (!(x)) { status--; } } -int tlsf_check(tlsf_t tlsf) +typedef struct integrity_t +{ + int prev_status; + int status; +} integrity_t; + +static void integrity_walker(void* ptr, size_t size, int used, void* user) { - int i, j; - - control_t* control = tlsf_cast(control_t*, tlsf); - int status = 0; - - /* Check that the free lists and bitmaps are accurate. */ - for (i = 0; i < FL_INDEX_COUNT; ++i) - { - for (j = 0; j < SL_INDEX_COUNT; ++j) - { - const int fl_map = control->fl_bitmap & (1 << i); - const int sl_list = control->sl_bitmap[i]; - const int sl_map = sl_list & (1 << j); - const block_header_t* block = control->blocks[i][j]; - - /* Check that first- and second-level lists agree. */ - if (!fl_map) - { - tlsf_insist_no_assert(!sl_map && "second-level map must be null"); - } - - if (!sl_map) - { - tlsf_insist_no_assert(block == &control->block_null && "block list must be null"); - continue; - } - - /* Check that there is at least one free block. */ - tlsf_insist_no_assert(sl_list && "no free blocks in second-level map"); - tlsf_insist_no_assert(block != &control->block_null && "block should not be null"); - - while (block != &control->block_null) - { - int fli, sli; - const bool is_block_free = block_is_free(block); - tlsf_insist_no_assert(is_block_free && "block should be free"); - tlsf_insist_no_assert(!block_is_prev_free(block) && "blocks should have coalesced"); - tlsf_insist_no_assert(!block_is_free(block_next(block)) && "blocks should have coalesced"); - tlsf_insist_no_assert(block_is_prev_free(block_next(block)) && "block should be free"); - tlsf_insist_no_assert(block_size(block) >= block_size_min && "block not minimum size"); - - mapping_insert(block_size(block), &fli, &sli); - tlsf_insist_no_assert(fli == i && sli == j && "block size indexed in wrong list"); - - /* block_size(block) returns the size of the usable memory when the block is allocated. - * As the block under test is free, we need to subtract to the block size the next_free - * and prev_free fields of the block header as they are not a part of the usable memory - * when the block is free. In addition, we also need to subtract the size of prev_phys_block - * as this field is in fact part of the current free block and not part of the next (allocated) - * block. Check the comments in block_split function for more details. - */ - const size_t actual_free_block_size = block_size(block) - - offsetof(block_header_t, next_free) - - block_header_overhead; - - if (s_poison_check_region != NULL) { - tlsf_insist_no_assert(s_poison_check_region((char *)block + sizeof(block_header_t), - actual_free_block_size, is_block_free, true /* print errors */)); - } - - block = block->next_free; - } - } - } - - return status; + block_header_t* block = block_from_ptr(ptr); + integrity_t* integ = tlsf_cast(integrity_t*, user); + const int this_prev_status = block_is_prev_free(block) ? 1 : 0; + const int this_status = block_is_free(block) ? 1 : 0; + const size_t this_block_size = block_size(block); + + int status = 0; + tlsf_insist_no_assert(integ->prev_status == this_prev_status && "prev status incorrect"); + tlsf_insist_no_assert(size == this_block_size && "block size incorrect"); + + if (s_poison_check_region != NULL) + { + /* block_size(block) returns the size of the usable memory when the block is allocated. + * As the block under test is free, we need to subtract to the block size the next_free + * and prev_free fields of the block header as they are not a part of the usable memory + * when the block is free. In addition, we also need to subtract the size of prev_phys_block + * as this field is in fact part of the current free block and not part of the next (allocated) + * block. Check the comments in block_split function for more details. + */ + const size_t actual_free_block_size = used ? this_block_size : + this_block_size - offsetof(block_header_t, next_free)- block_header_overhead; + + void* ptr_block = used ? (void*)block + block_start_offset : + (void*)block + sizeof(block_header_t); + + tlsf_insist_no_assert(s_poison_check_region(ptr_block, actual_free_block_size, !used, true)); + } + + integ->prev_status = this_status; + integ->status += status; +} + +extern void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user); +int tlsf_check_pool(pool_t pool) +{ + /* Check that the blocks are physically correct. */ + integrity_t integ = { 0, 0 }; + tlsf_walk_pool(pool, integrity_walker, &integ); + + return integ.status; } #undef tlsf_insist_no_assert @@ -299,7 +192,7 @@ void __attribute__((constructor)) tlsf_set_rom_patches(void) memcpy(&heap_tlsf_patch_table_ptr, heap_tlsf_table_ptr, sizeof(struct heap_tlsf_stub_table_t)); /* Set the patched function here */ - heap_tlsf_patch_table_ptr.tlsf_check = tlsf_check; + heap_tlsf_patch_table_ptr.tlsf_check_pool = tlsf_check_pool; /* Set our table as the one to use in the ROM code */ heap_tlsf_table_ptr = &heap_tlsf_patch_table_ptr; diff --git a/components/esp_system/ld/esp32p4/memory.ld.in b/components/esp_system/ld/esp32p4/memory.ld.in index 41ed1d38477..a4e1c17c62f 100644 --- a/components/esp_system/ld/esp32p4/memory.ld.in +++ b/components/esp_system/ld/esp32p4/memory.ld.in @@ -95,7 +95,7 @@ MEMORY - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). The aim of this is to keep data that will not be moved around and have a fixed address. */ - lp_reserved_seg(RW) : org = 0x50000000 + 0x8000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM + lp_reserved_seg(RW) : org = 0x50108000 + 0x8000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM } /* Heap ends at top of dram0_0_seg */ diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 53d9f3e67f3..99d6e8b42d8 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -101,6 +101,7 @@ #if CONFIG_APP_BUILD_TYPE_RAM #include "esp_rom_spiflash.h" #include "bootloader_init.h" +#include "esp_private/bootloader_flash_internal.h" #endif // CONFIG_APP_BUILD_TYPE_RAM //This dependency will be removed in the future @@ -429,14 +430,10 @@ void IRAM_ATTR call_start_cpu0(void) // When the APP is loaded into ram for execution, some hardware initialization behaviors // in the bootloader are still necessary #if CONFIG_APP_BUILD_TYPE_RAM + bootloader_init(); #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP -#if SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE - esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); -#else - esp_rom_spiflash_attach(0, false); -#endif + bootloader_flash_hardware_init(); #endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP - bootloader_init(); #endif //#if CONFIG_APP_BUILD_TYPE_RAM #ifndef CONFIG_BOOTLOADER_WDT_ENABLE @@ -722,22 +719,19 @@ void IRAM_ATTR call_start_cpu0(void) } #endif //CONFIG_ESP_SYSTEM_MEMPROT_FEATURE && !CONFIG_ESP_SYSTEM_MEMPROT_TEST +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + // External devices (including SPI0/1, cache) should be initialized + +#if !CONFIG_APP_BUILD_TYPE_RAM + // Normal startup flow. We arrive here with the help of 1st, 2nd bootloader. There are valid headers (app/bootloader) + // Read the application binary image header. This will also decrypt the header if the image is encrypted. __attribute__((unused)) esp_image_header_t fhdr = {0}; -#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP - fhdr.spi_mode = ESP_IMAGE_SPI_MODE_DIO; - fhdr.spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2; - fhdr.spi_size = ESP_IMAGE_FLASH_SIZE_4MB; - bootloader_flash_unlock(); -#else // This assumes that DROM is the first segment in the application binary, i.e. that we can read // the binary header through cache by accessing SOC_DROM_LOW address. hal_memcpy(&fhdr, (void *) SOC_DROM_LOW, sizeof(fhdr)); -#endif // CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP - -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if CONFIG_IDF_TARGET_ESP32 #if !CONFIG_SPIRAM_BOOT_INIT // If psram is uninitialized, we need to improve some flash configuration. @@ -756,6 +750,10 @@ void IRAM_ATTR call_start_cpu0(void) } bootloader_flash_update_size(app_flash_size); #endif //CONFIG_SPI_FLASH_SIZE_OVERRIDE +#else + // CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + bootloader_flash_unlock(); +#endif #endif //!CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 4aa76ca57bb..5546b1cd8d6 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -55,13 +55,13 @@ static const char *TAG = "clk"; #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 (2 sec). // 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 2 sec * 150/32 = 9.375 sec). wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; - uint32_t stage_timeout_ticks = (uint32_t)(1600ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); + uint32_t stage_timeout_ticks = (uint32_t)(2000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); 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 diff --git a/components/esp_timer/CMakeLists.txt b/components/esp_timer/CMakeLists.txt index 0129826de1f..faf80921d3b 100644 --- a/components/esp_timer/CMakeLists.txt +++ b/components/esp_timer/CMakeLists.txt @@ -1,28 +1,24 @@ idf_build_get_property(target IDF_TARGET) if(${target} STREQUAL "linux") -idf_component_register(INCLUDE_DIRS include) + idf_component_register(INCLUDE_DIRS include) else() + set(srcs "src/esp_timer.c" + "src/ets_timer_legacy.c" + "src/system_time.c" + "src/esp_timer_impl_common.c") -set(srcs "src/esp_timer.c" - "src/ets_timer_legacy.c" - "src/system_time.c" - "src/esp_timer_impl_common.c") + if(CONFIG_ESP_TIMER_IMPL_TG0_LAC) + list(APPEND srcs "src/esp_timer_impl_lac.c") + elseif(CONFIG_ESP_TIMER_IMPL_SYSTIMER) + list(APPEND srcs "src/esp_timer_impl_systimer.c") + endif() -if(CONFIG_ESP_TIMER_IMPL_TG0_LAC) - list(APPEND srcs "src/esp_timer_impl_lac.c") -elseif(CONFIG_ESP_TIMER_IMPL_SYSTIMER) - list(APPEND srcs "src/esp_timer_impl_systimer.c") -endif() - -if(CONFIG_SOC_SYSTIMER_SUPPORT_ETM) - list(APPEND srcs "src/esp_timer_etm.c") -endif() - -idf_component_register(SRCS "${srcs}" - INCLUDE_DIRS include - PRIV_INCLUDE_DIRS private_include - REQUIRES esp_common - PRIV_REQUIRES soc driver) + if(CONFIG_SOC_SYSTIMER_SUPPORT_ETM) + list(APPEND srcs "src/esp_timer_etm.c") + endif() + idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS include + PRIV_INCLUDE_DIRS private_include) endif() diff --git a/components/esp_wifi/include/esp_now.h b/components/esp_wifi/include/esp_now.h index 728c69ba5e5..3e8e8e299d3 100644 --- a/components/esp_wifi/include/esp_now.h +++ b/components/esp_wifi/include/esp_now.h @@ -97,6 +97,7 @@ typedef struct esp_now_rate_config { wifi_phy_mode_t phymode; /**< ESPNOW phymode of specified interface */ wifi_phy_rate_t rate; /**< ESPNOW rate of specified interface*/ bool ersu; /**< ESPNOW using ersu send frame*/ + bool dcm; /**< ESPNOW using dcm rate to send frame*/ } esp_now_rate_config_t; /** diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 4aef336ec25..f5a8d974681 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -1191,7 +1191,8 @@ esp_err_t esp_wifi_statis_dump(uint32_t modules); * @attention If the user wants to receive another WIFI_EVENT_STA_BSS_RSSI_LOW event after receiving one, this API needs to be * called again with an updated/same RSSI threshold. * - * @param rssi threshold value in dbm between -100 to 0 + * @param rssi threshold value in dbm between -100 to 10 + * Note that in some rare cases where signal strength is very strong, rssi values can be slightly positive. * * @return * - ESP_OK: succeed diff --git a/components/esp_wifi/include/esp_wifi_he_types.h b/components/esp_wifi/include/esp_wifi_he_types.h index 01f753dddb1..507367e53a3 100644 --- a/components/esp_wifi/include/esp_wifi_he_types.h +++ b/components/esp_wifi/include/esp_wifi_he_types.h @@ -157,7 +157,7 @@ typedef struct { unsigned : 15; /**< reserved */ unsigned : 15; /**< reserved */ unsigned : 2; /**< reserved */ - unsigned noise_floor : 8; /**< the noise floor of the reception frame */ + signed noise_floor : 8; /**< the noise floor of the reception frame */ unsigned channel : 4; /**< the primary channel */ unsigned second : 4; /**< the second channel if in HT40 */ unsigned : 8; /**< reserved */ diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index ae525511ba2..8500fb3b762 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -211,7 +211,7 @@ typedef struct { uint8_t ssid[33]; /**< SSID of AP */ uint8_t primary; /**< channel of AP */ wifi_second_chan_t second; /**< secondary channel of AP */ - int8_t rssi; /**< signal strength of AP */ + int8_t rssi; /**< signal strength of AP. Note that in some rare cases where signal strength is very strong, rssi values can be slightly positive */ wifi_auth_mode_t authmode; /**< authmode of AP */ wifi_cipher_type_t pairwise_cipher; /**< pairwise cipher of AP */ wifi_cipher_type_t group_cipher; /**< group cipher of AP */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 71efb6cbce4..a65d997669b 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 71efb6cbce423e457daaaf54129c3da7bfe28704 +Subproject commit a65d997669b98f8348158fb5f47d9832b46eccc7 diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 4473cfc4386..ac2dd2f2cca 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -355,7 +355,77 @@ void ieee80211_ftm_attach(void) #ifndef CONFIG_ESP_WIFI_SOFTAP_SUPPORT void net80211_softap_funcs_init(void) { + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} + +bool ieee80211_ap_try_sa_query(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return false; +} + +bool ieee80211_ap_sa_query_timeout(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return false; +} + +int add_mic_ie_bip(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return 0; +} + +void ieee80211_free_beacon_eb(void) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} + +int ieee80211_pwrsave(void *p1, void *p2) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return 0; +} + +void cnx_node_remove(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ } + +int ieee80211_set_tim(void *p, int arg) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return 0; +} + +bool ieee80211_is_bufferable_mmpdu(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return false; +} + +void cnx_node_leave(void *p, uint8_t arg) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} + +void ieee80211_beacon_construct(void *p1, void *p2, void *p3, void *p4) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} + +void * ieee80211_assoc_resp_construct(void *p, int arg) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return NULL; +} + +void * ieee80211_alloc_proberesp(void *p, int arg) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return NULL; +} + #endif #ifndef CONFIG_ESP_WIFI_NAN_ENABLE diff --git a/components/espcoredump/CMakeLists.txt b/components/espcoredump/CMakeLists.txt index 3b1e88fce32..32eb4012087 100644 --- a/components/espcoredump/CMakeLists.txt +++ b/components/espcoredump/CMakeLists.txt @@ -27,10 +27,14 @@ elseif(CONFIG_IDF_TARGET_ARCH_RISCV) endif() idf_component_register(SRCS ${srcs} - INCLUDE_DIRS ${includes} - PRIV_INCLUDE_DIRS ${priv_includes} - LDFRAGMENTS linker.lf - PRIV_REQUIRES esp_partition spi_flash bootloader_support mbedtls esp_rom soc esp_system driver) + INCLUDE_DIRS ${includes} + PRIV_INCLUDE_DIRS ${priv_includes} + LDFRAGMENTS linker.lf + PRIV_REQUIRES esp_partition spi_flash bootloader_support mbedtls esp_rom soc esp_system + esp_driver_gpio + # [refactor-todo] esp_flash_internal.h -> spi_common_internal.h requires cleanup + driver + ) if(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) target_link_libraries(${COMPONENT_LIB} PRIVATE idf::esp_app_format) diff --git a/components/espcoredump/Kconfig b/components/espcoredump/Kconfig index 7f18ccef03b..175e5347a32 100644 --- a/components/espcoredump/Kconfig +++ b/components/espcoredump/Kconfig @@ -84,6 +84,16 @@ menu "Core dump" Config delay (in ms) before printing core dump to UART. Delay can be interrupted by pressing Enter key. + config ESP_COREDUMP_FLASH_NO_OVERWRITE + bool "Don't overwrite existing core dump" + depends on ESP_COREDUMP_ENABLE_TO_FLASH + default n + help + Don't overwrite an existing core dump already present in flash. + Enable this option to only keep the first of multiple core dumps. + + If enabled, the core dump partition must be erased before the first + core dump can be written. config ESP_COREDUMP_USE_STACK_SIZE bool diff --git a/components/espcoredump/include_core_dump/esp_core_dump_types.h b/components/espcoredump/include_core_dump/esp_core_dump_types.h index fa6b8bf8dcd..578be2df21c 100644 --- a/components/espcoredump/include_core_dump/esp_core_dump_types.h +++ b/components/espcoredump/include_core_dump/esp_core_dump_types.h @@ -19,7 +19,7 @@ extern "C" { #include "core_dump_checksum.h" #if CONFIG_ESP_COREDUMP_LOGS -#define ESP_COREDUMP_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { esp_rom_printf(DRAM_STR(format), esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); } +#define ESP_COREDUMP_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { esp_rom_printf((format), esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); } #else #define ESP_COREDUMP_LOG( level, format, ... ) // dummy define doing nothing #endif @@ -30,6 +30,11 @@ extern "C" { #define ESP_COREDUMP_LOGD( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_DEBUG, LOG_FORMAT(D, format), ##__VA_ARGS__) #define ESP_COREDUMP_LOGV( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_VERBOSE, LOG_FORMAT(V, format), ##__VA_ARGS__) +/** + * @brief Always print the given message, regardless of the log level + */ +#define ESP_COREDUMP_PRINT( format, ... ) do { esp_rom_printf((format), ##__VA_ARGS__); } while(0) + /** * @brief Assertion to be verified in a release context. Cannot be muted. */ diff --git a/components/espcoredump/linker.lf b/components/espcoredump/linker.lf index fe978a7b6ad..d51f4b36368 100644 --- a/components/espcoredump/linker.lf +++ b/components/espcoredump/linker.lf @@ -37,11 +37,13 @@ entries: archive: libespcoredump.a entries: if ESP_PANIC_HANDLER_IRAM = y: - core_dump_uart (noflash_text) - core_dump_flash (noflash_text) - core_dump_common (noflash_text) - core_dump_port (noflash_text) - core_dump_elf (noflash_text) + core_dump_uart (noflash) + core_dump_flash (noflash) + core_dump_common (noflash) + core_dump_port (noflash) + core_dump_elf (noflash) + core_dump_checksum (noflash) + core_dump_binary (noflash) else: * (default) diff --git a/components/espcoredump/src/core_dump_binary.c b/components/espcoredump/src/core_dump_binary.c index 819cff47cff..d2a0122ef15 100644 --- a/components/espcoredump/src/core_dump_binary.c +++ b/components/espcoredump/src/core_dump_binary.c @@ -14,7 +14,7 @@ #if CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_binary"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_binary"; static esp_err_t esp_core_dump_save_task(core_dump_write_config_t *write_cfg, diff --git a/components/espcoredump/src/core_dump_checksum.c b/components/espcoredump/src/core_dump_checksum.c index b29d909fcf5..f61ad89b3d5 100644 --- a/components/espcoredump/src/core_dump_checksum.c +++ b/components/espcoredump/src/core_dump_checksum.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,7 @@ #if CONFIG_ESP_COREDUMP_ENABLE -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_checksum"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_checksum"; #define COREDUMP_SHA256_LEN 32 @@ -147,13 +147,13 @@ static void esp_core_dump_print_sha256(const char* msg, const uint8_t* sha_outpu /* As this function is only called by `esp_core_dump_print_checksum`, we * have the guarantee that sha_output is not NULL. */ if (msg != NULL) { - esp_rom_printf(DRAM_STR("%s='"), msg); + ESP_COREDUMP_PRINT("%s='", msg); } for (int i = 0; i < COREDUMP_SHA256_LEN; i++) { - esp_rom_printf(DRAM_STR("%02x"), sha_output[i]); + ESP_COREDUMP_PRINT("%02x", sha_output[i]); } - esp_rom_printf(DRAM_STR("'\r\n")); + ESP_COREDUMP_PRINT("'\r\n"); } #endif @@ -170,10 +170,10 @@ void esp_core_dump_print_checksum(const char* msg, core_dump_checksum_bytes chec #if CONFIG_ESP_COREDUMP_CHECKSUM_CRC32 if (msg != NULL) { - esp_rom_printf(DRAM_STR("%s='"), msg); + ESP_COREDUMP_PRINT("%s='", msg); } - esp_rom_printf(DRAM_STR("%08x"), *((const uint32_t*) checksum)); - esp_rom_printf(DRAM_STR("'\r\n")); + ESP_COREDUMP_PRINT("%08x", *((const uint32_t*) checksum)); + ESP_COREDUMP_PRINT("'\r\n"); #elif CONFIG_ESP_COREDUMP_CHECKSUM_SHA256 esp_core_dump_print_sha256(msg, (const uint8_t*) checksum); #endif diff --git a/components/espcoredump/src/core_dump_common.c b/components/espcoredump/src/core_dump_common.c index 302737578de..70f8f77f6d3 100644 --- a/components/espcoredump/src/core_dump_common.c +++ b/components/espcoredump/src/core_dump_common.c @@ -15,7 +15,7 @@ #include "core_dump_elf.h" #include "core_dump_binary.h" -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_common"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_common"; #if CONFIG_ESP_COREDUMP_ENABLE diff --git a/components/espcoredump/src/core_dump_elf.c b/components/espcoredump/src/core_dump_elf.c index 42c8938e90e..cd93d26b210 100644 --- a/components/espcoredump/src/core_dump_elf.c +++ b/components/espcoredump/src/core_dump_elf.c @@ -72,7 +72,7 @@ typedef struct uint8_t app_elf_sha256[ELF_APP_SHA256_SIZE]; // sha256 of elf file } core_dump_elf_version_info_t; -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_elf"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_elf"; // Main ELF handle type typedef struct _core_dump_elf_t diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index 0b39a3f6dde..65534189d6b 100644 --- a/components/espcoredump/src/core_dump_flash.c +++ b/components/espcoredump/src/core_dump_flash.c @@ -15,7 +15,7 @@ #define BLANK_COREDUMP_SIZE 0xFFFFFFFF -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_flash"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_flash"; #if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH @@ -27,6 +27,10 @@ typedef struct _core_dump_partition_t uint32_t size; /* Flag set to true if the partition is encrypted. */ bool encrypted; +#if CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE + /* Flag set to true if the partition is empty. */ + bool empty; +#endif } core_dump_partition_t; typedef uint32_t core_dump_crc_t; @@ -82,6 +86,18 @@ void esp_core_dump_flash_init(void) s_core_flash_config.partition.start = core_part->address; s_core_flash_config.partition.size = core_part->size; s_core_flash_config.partition.encrypted = core_part->encrypted; + +#if CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE + uint32_t core_size = 0; + esp_err_t err = esp_partition_read(core_part, 0, &core_size, sizeof(core_size)); + if (err == ESP_OK) { + s_core_flash_config.partition.empty = (core_size == BLANK_COREDUMP_SIZE); + } else { + ESP_COREDUMP_LOGE("Failed to read core dump data size (%d)!", err); + s_core_flash_config.partition.empty = false; + } +#endif + s_core_flash_config.partition_config_crc = esp_core_dump_calc_flash_config_crc(); if (esp_flash_encryption_enabled() && !core_part->encrypted) { @@ -318,6 +334,13 @@ void esp_core_dump_to_flash(panic_info_t *info) return; } +#if CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE + if (!s_core_flash_config.partition.empty) { + ESP_COREDUMP_LOGW("Core dump already exists in flash, will not overwrite it with a new core dump"); + return; + } +#endif + /* Initialize non-OS flash access critical section. */ spi_flash_guard_set(&g_flash_guard_no_os_ops); esp_flash_app_disable_protect(true); @@ -457,6 +480,13 @@ esp_err_t esp_core_dump_image_erase(void) ESP_LOGE(TAG, "Failed to write core dump partition size (%d)!", err); } +#if CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE + if (!s_core_flash_config.partition.empty) { + s_core_flash_config.partition.empty = true; + s_core_flash_config.partition_config_crc = esp_core_dump_calc_flash_config_crc(); + } +#endif + return err; } diff --git a/components/espcoredump/src/core_dump_uart.c b/components/espcoredump/src/core_dump_uart.c index 0071ac18215..c10297d6b79 100644 --- a/components/espcoredump/src/core_dump_uart.c +++ b/components/espcoredump/src/core_dump_uart.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ #include "esp_core_dump_common.h" #include "esp_rom_sys.h" -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_uart"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_uart"; #if CONFIG_ESP_COREDUMP_ENABLE_TO_UART @@ -22,7 +22,7 @@ const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_uart" int esp_clk_cpu_freq(void); static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8_t *dst) { - const static DRAM_ATTR char b64[] = + const static char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int i, j, a, b, c; @@ -53,7 +53,7 @@ static esp_err_t esp_core_dump_uart_write_start(core_dump_write_data_t *priv) ESP_COREDUMP_ASSERT(priv != NULL); esp_core_dump_checksum_init(&wr_data->checksum_ctx); - esp_rom_printf(DRAM_STR("================= CORE DUMP START =================\r\n")); + ESP_COREDUMP_PRINT("================= CORE DUMP START =================\r\n"); return err; } @@ -74,12 +74,12 @@ static esp_err_t esp_core_dump_uart_write_end(core_dump_write_data_t *priv) size_t cs_len = esp_core_dump_checksum_finish(wr_data->checksum_ctx, &cs_addr); wr_data->off += cs_len; esp_core_dump_b64_encode((const uint8_t *)cs_addr, cs_len, (uint8_t*)&buf[0]); - esp_rom_printf(DRAM_STR("%s\r\n"), buf); + ESP_COREDUMP_PRINT("%s\r\n", buf); } - esp_rom_printf(DRAM_STR("================= CORE DUMP END =================\r\n")); + ESP_COREDUMP_PRINT("================= CORE DUMP END =================\r\n"); if (cs_addr) { - esp_core_dump_print_checksum(DRAM_STR("Coredump checksum"), cs_addr); + esp_core_dump_print_checksum("Coredump checksum", cs_addr); } return err; @@ -103,7 +103,7 @@ static esp_err_t esp_core_dump_uart_write_data(core_dump_write_data_t *priv, voi memcpy(tmp, addr, len); esp_core_dump_b64_encode((const uint8_t *)tmp, len, (uint8_t *)buf); addr += len; - esp_rom_printf(DRAM_STR("%s\r\n"), buf); + ESP_COREDUMP_PRINT("%s\r\n", buf); } if (wr_data) { diff --git a/components/espcoredump/src/port/riscv/core_dump_port.c b/components/espcoredump/src/port/riscv/core_dump_port.c index aeb36aafb36..00d76405023 100644 --- a/components/espcoredump/src/port/riscv/core_dump_port.c +++ b/components/espcoredump/src/port/riscv/core_dump_port.c @@ -20,7 +20,7 @@ #include "esp_core_dump_port.h" /* TAG used for logs */ -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_port"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_port"; /* Code associated to RISC-V in ELF format */ #define COREDUMP_EM_RISCV 0xF3 diff --git a/components/espcoredump/src/port/xtensa/core_dump_port.c b/components/espcoredump/src/port/xtensa/core_dump_port.c index fd17ac2584d..452c4259f69 100644 --- a/components/espcoredump/src/port/xtensa/core_dump_port.c +++ b/components/espcoredump/src/port/xtensa/core_dump_port.c @@ -21,7 +21,7 @@ #include "esp_debug_helpers.h" #include "esp_cpu_utils.h" -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_port"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_port"; #define min(a,b) ((a) < (b) ? (a) : (b)) #define max(a,b) ((a) < (b) ? (b) : (a)) diff --git a/components/fatfs/CMakeLists.txt b/components/fatfs/CMakeLists.txt index b6a288e0d0c..e9ae1f88744 100644 --- a/components/fatfs/CMakeLists.txt +++ b/components/fatfs/CMakeLists.txt @@ -24,7 +24,7 @@ else() list(APPEND requires "sdmmc") - list(APPEND priv_requires "vfs") + list(APPEND priv_requires "vfs" "esp_driver_gpio") endif() idf_component_register(SRCS ${srcs} diff --git a/components/fatfs/vfs/vfs_fat.c b/components/fatfs/vfs/vfs_fat.c index 169133a08a8..4ae04c3d617 100644 --- a/components/fatfs/vfs/vfs_fat.c +++ b/components/fatfs/vfs/vfs_fat.c @@ -424,6 +424,7 @@ static ssize_t vfs_fat_write(void* ctx, int fd, const void * data, size_t size) if (res != FR_OK) { ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); errno = fresult_to_errno(res); + _lock_release(&fat_ctx->lock); return -1; } } diff --git a/components/fatfs/vfs/vfs_fat_sdmmc.c b/components/fatfs/vfs/vfs_fat_sdmmc.c index f3625a2f0e7..1a5ac2150b9 100644 --- a/components/fatfs/vfs/vfs_fat_sdmmc.c +++ b/components/fatfs/vfs/vfs_fat_sdmmc.c @@ -439,6 +439,8 @@ esp_err_t esp_vfs_fat_sdcard_unmount(const char *base_path, sdmmc_card_t *card) if (!found) { return ESP_ERR_INVALID_ARG; } + free(s_ctx[id]->base_path); + s_ctx[id]->base_path = NULL; free(s_ctx[id]); s_ctx[id] = NULL; diff --git a/components/freertos/FreeRTOS-Kernel/idf_changes.md b/components/freertos/FreeRTOS-Kernel/idf_changes.md index 752d8fbbcde..28385a40c55 100644 --- a/components/freertos/FreeRTOS-Kernel/idf_changes.md +++ b/components/freertos/FreeRTOS-Kernel/idf_changes.md @@ -193,3 +193,9 @@ List of changes made to Vanilla FreeRTOS V10.5.1 header files to allow for build - In functions/macros that are not meant to be directly called by users (i.e., internal), such as the various `Generic` variants of functions - Some types/functions/macros are manually documented, thus are documented with regular comment blocks (i.e., `/* */`) instead of doxygen comment blocks (i.e., `/** */`). Some of these blocks are changed into doxygen blocks. + +## Changes backported to IDF-FreeRTOS Kernel from upstream kernel beyond v10.5.1 LTS release + +### tasks.c + +- Backported a change where the IDLE tasks are created with the core ID as a suffix in the task name. diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index cbd9eb48aa7..d793e156565 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -596,6 +596,11 @@ PRIVILEGED_DATA static portMUX_TYPE xKernelLock = portMUX_INITIALIZER_UNLOCKED; /* File private functions. --------------------------------*/ +/* + * Creates the idle tasks during scheduler start. + */ +static BaseType_t prvCreateIdleTasks( void ); + /** * Utility function to check whether a yield (on either core) is required after * unblocking (or changing the priority of) a particular task. @@ -2278,14 +2283,73 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) #endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ /*-----------------------------------------------------------*/ -void vTaskStartScheduler( void ) +static BaseType_t prvCreateIdleTasks( void ) { - BaseType_t xReturn; - UBaseType_t x; + BaseType_t xReturn = pdPASS; + BaseType_t xCoreID; - /* Create idle tasks that are pinned to each core */ - for( x = 0; x < configNUMBER_OF_CORES; x++ ) +#if ( configNUMBER_OF_CORES > 1 ) + char cIdleName[ configMAX_TASK_NAME_LEN ]; +#endif /* #if ( configNUMBER_OF_CORES > 1 ) */ + + /* Add each idle task at the lowest priority. */ + for( xCoreID = ( BaseType_t ) 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) { + #if ( configNUMBER_OF_CORES > 1 ) + { + BaseType_t x; + + if( xReturn == pdFAIL ) + { + /* TODO: IDF-8240 - Memory leaks occur if IDLE task creation fails on some core + * as we do not free memory for the successfully created IDLE tasks. */ + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + cIdleName[ x ] = configIDLE_TASK_NAME[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + * configMAX_TASK_NAME_LEN characters just in case the memory after the + * string is not accessible (extremely unlikely). */ + if( cIdleName[ x ] == ( char ) 0x00 ) + { + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Append the idle task number to the end of the name if there is space. */ + if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN ) + { + cIdleName[ x ] = ( char ) ( xCoreID + '0' ); + x++; + + /* And append a null character if there is space. */ + if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN ) + { + cIdleName[ x ] = '\0'; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ + /* Add the idle task at the lowest priority. */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) { @@ -2296,43 +2360,61 @@ void vTaskStartScheduler( void ) /* The Idle task is created using user provided RAM - obtain the * address of the RAM then create the idle task. */ vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); - xIdleTaskHandle[ x ] = xTaskCreateStaticPinnedToCore( prvIdleTask, - configIDLE_TASK_NAME, - ulIdleTaskStackSize, - ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ - portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ - pxIdleTaskStackBuffer, - pxIdleTaskTCBBuffer, /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ - x ); - - if( xIdleTaskHandle[ x ] != NULL ) + xIdleTaskHandle[ xCoreID ] = xTaskCreateStaticPinnedToCore( prvIdleTask, + #if ( configNUMBER_OF_CORES > 1 ) + cIdleName, + #else /* #if ( configNUMBER_OF_CORES > 1 ) */ + configIDLE_TASK_NAME, + #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ + ulIdleTaskStackSize, + ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + pxIdleTaskStackBuffer, + pxIdleTaskTCBBuffer, /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + xCoreID ); + + if( xIdleTaskHandle[ xCoreID ] != NULL ) { xReturn = pdPASS; } else { xReturn = pdFAIL; - break; } } #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ { /* The Idle task is being created using dynamically allocated RAM. */ xReturn = xTaskCreatePinnedToCore( prvIdleTask, - configIDLE_TASK_NAME, + #if ( configNUMBER_OF_CORES > 1 ) + cIdleName, + #else /* #if ( configNUMBER_OF_CORES > 1 ) */ + configIDLE_TASK_NAME, + #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ configMINIMAL_STACK_SIZE, ( void * ) NULL, portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ &xIdleTaskHandle[ xCoreID ], /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ xCoreID ); - if( xReturn == pdFAIL ) - { - break; - } + } #endif /* configSUPPORT_STATIC_ALLOCATION */ } + return xReturn; +} + +/*-----------------------------------------------------------*/ + +void vTaskStartScheduler( void ) +{ + BaseType_t xReturn; + + /* The code for prvCreateIdleTasks() has been backported from the upstream + * FreeRTOS-Kernel source. The reference for the same is on the mainline + * at the commit id# 2f94b181a2f049ec342deba0927bed51f7174ab0. */ + xReturn = prvCreateIdleTasks(); + #if ( configUSE_TIMERS == 1 ) { if( xReturn == pdPASS ) @@ -3267,9 +3349,7 @@ BaseType_t xTaskIncrementTick( void ) * 0, we only need to context switch if the unblocked * task can run on core 0 and has a higher priority * than the current task. */ - - /* ">" changed to ">="" due to IDF incompatibility (IDF-8428) */ - if( ( taskIS_AFFINITY_COMPATIBLE( 0, pxTCB->xCoreID ) == pdTRUE ) && ( pxTCB->uxPriority >= pxCurrentTCBs[ 0 ]->uxPriority ) ) + if( ( taskIS_AFFINITY_COMPATIBLE( 0, pxTCB->xCoreID ) == pdTRUE ) && ( pxTCB->uxPriority > pxCurrentTCBs[ 0 ]->uxPriority ) ) { xSwitchRequired = pdTRUE; } diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index eccb221ff27..d8ca79b487c 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -244,6 +244,25 @@ menu "FreeRTOS" Note: The clock used for run time statistics can be configured in FREERTOS_RUN_TIME_STATS_CLK. + choice FREERTOS_RUN_TIME_COUNTER_TYPE + prompt "configRUN_TIME_COUNTER_TYPE" + depends on FREERTOS_GENERATE_RUN_TIME_STATS && !FREERTOS_SMP + default FREERTOS_RUN_TIME_COUNTER_TYPE_U32 + help + Sets the data type used for the FreeRTOS run time stats. A larger data type can be used to reduce the + frequency of the counter overflowing. + + config FREERTOS_RUN_TIME_COUNTER_TYPE_U32 + bool "uint32_t" + help + configRUN_TIME_COUNTER_TYPE is set to uint32_t + + config FREERTOS_RUN_TIME_COUNTER_TYPE_U64 + bool "uint64_t" + help + configRUN_TIME_COUNTER_TYPE is set to uint64_t + endchoice # FREERTOS_RUN_TIME_COUNTER_TYPE + config FREERTOS_USE_TICKLESS_IDLE # Todo: Currently not supported in SMP FreeRTOS yet (IDF-4986) # Todo: Consider whether this option should still be exposed (IDF-4986) diff --git a/components/freertos/config/include/freertos/FreeRTOSConfig.h b/components/freertos/config/include/freertos/FreeRTOSConfig.h index 623272fbc37..c8e7922615d 100644 --- a/components/freertos/config/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/config/include/freertos/FreeRTOSConfig.h @@ -165,6 +165,14 @@ #define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */ #endif /* CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS */ +#if !CONFIG_FREERTOS_SMP + #if CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U32 + #define configRUN_TIME_COUNTER_TYPE uint32_t + #elif CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64 + #define configRUN_TIME_COUNTER_TYPE uint64_t + #endif /* CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64 */ +#endif /* !CONFIG_FREERTOS_SMP */ + /* -------------------- Co-routines ----------------------- */ #define configUSE_CO_ROUTINES 0 /* CO_ROUTINES are not supported in ESP-IDF */ diff --git a/components/freertos/esp_additions/freertos_tasks_c_additions.h b/components/freertos/esp_additions/freertos_tasks_c_additions.h index 371a9676491..c7a9fe6ab8a 100644 --- a/components/freertos/esp_additions/freertos_tasks_c_additions.h +++ b/components/freertos/esp_additions/freertos_tasks_c_additions.h @@ -6,6 +6,7 @@ #include "sdkconfig.h" #include "esp_assert.h" +#include "esp_heap_caps.h" #include "freertos/idf_additions.h" #if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT #include "esp_private/freertos_debug.h" @@ -1158,3 +1159,102 @@ void * pvTaskGetCurrentTCBForCore( BaseType_t xCoreID ) #endif /* CONFIG_FREERTOS_DEBUG_OCDAWARE */ /*----------------------------------------------------------*/ + +/* ----------------------------------------------------- PSRAM ---------------------------------------------------- */ + +#if CONFIG_SPIRAM + + #if CONFIG_FREERTOS_SMP + BaseType_t prvTaskCreateDynamicAffinitySetWithCaps( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + UBaseType_t uxCoreAffinityMask, + UBaseType_t uxStackMemoryCaps, + TaskHandle_t * const pxCreatedTask ) + #else /* CONFIG_FREERTOS_SMP */ + BaseType_t prvTaskCreateDynamicPinnedToCoreWithCaps( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + const BaseType_t xCoreID, + UBaseType_t uxStackMemoryCaps, + TaskHandle_t * const pxCreatedTask ) + #endif /* CONFIG_FREERTOS_SMP */ + { + TCB_t * pxNewTCB; + BaseType_t xReturn; + + StackType_t * pxStack; + + configASSERT( uxStackMemoryCaps & ( MALLOC_CAP_8BIT ) ); + configASSERT( ( uxStackMemoryCaps & MALLOC_CAP_SPIRAM ) || + ( uxStackMemoryCaps & MALLOC_CAP_INTERNAL ) ); + + /* Allocate space for the stack used by the task being created. */ + pxStack = heap_caps_malloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), uxStackMemoryCaps ); + + if( pxStack != NULL ) + { + /* Allocate space for the TCB. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxStack; + } + else + { + /* The stack cannot be used as the TCB has not been created. Free it. */ + heap_caps_free( pxStack ); + } + } + else + { + pxNewTCB = NULL; + } + + if( pxNewTCB != NULL ) + { + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + * task was created dynamically in case it is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + #if CONFIG_FREERTOS_SMP + { + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + #if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) + { + /* Set the task's affinity before scheduling it */ + pxNewTCB->uxCoreAffinityMask = uxCoreAffinityMask; + } + #endif /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */ + } + #else /* CONFIG_FREERTOS_SMP */ + { + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, xCoreID ); + } + #endif /* CONFIG_FREERTOS_SMP */ + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } + +#endif /* CONFIG_SPIRAM */ +/*----------------------------------------------------------*/ diff --git a/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h b/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h index 4f38f5ec997..596b313c448 100644 --- a/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h +++ b/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h @@ -57,16 +57,16 @@ #define prvENTER_CRITICAL_OR_SUSPEND_ALL( x ) ( { vTaskSuspendAll(); ( void ) ( x ); } ) #define prvEXIT_CRITICAL_OR_RESUME_ALL( x ) xTaskResumeAll() - #define prvENTER_CRITICAL_OR_MASK_ISR( pxLock, uxInterruptStatus ) \ + #define prvENTER_CRITICAL_OR_MASK_ISR( pxLock, uxInterruptStatus ) \ + { \ + ( uxInterruptStatus ) = portSET_INTERRUPT_MASK_FROM_ISR(); \ + ( void ) ( pxLock ); \ + } + #define prvEXIT_CRITICAL_OR_UNMASK_ISR( pxLock, uxInterruptStatus ) \ { \ - ( uxInterruptStatus ) = portSET_INTERRUPT_MASK_FROM_ISR(); \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( ( uxInterruptStatus ) ); \ ( void ) ( pxLock ); \ } - #define prvEXIT_CRITICAL_OR_UNMASK_ISR( pxLock, uxInterruptStatus ) \ - { \ - portCLEAR_INTERRUPT_MASK_FROM_ISR( ( uxInterruptStatus ) ); \ - ( void ) ( pxLock ); \ - } #endif /* ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES == 1 ) ) */ @@ -210,6 +210,88 @@ #endif /* INCLUDE_vTaskPrioritySet == 1 */ +#if CONFIG_SPIRAM + +/** + * Create a new task with stack having the desired heap capabilities and add it to the + * list of tasks that are ready to run. + * + * @note: This is an internal function and meant for usage by pthread only. + * @note: Tasks with stacks not having the default heap capabilities for FreeRTOS may + * not be able to run while flash cache is disabled. + * This is the case if, e.g., any task on the chip is reading or writing + * flash memory. + * + * @note: The difference between this function and xTaskCreatePinnedToCoreWithCaps() + * is the following: + * * A FreeRTOS task created by this function is deleted by normal FreeRTOS deletion functions, + * i.e., vTaskDelete(). + * * A FreeRTOS task created by this function can delete itself. + * + * This function behaves like xTaskCreateAffinitySet(), except that it allocates + * the stack from the heap with the desired heap capabilities. + * + * @param pxTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of bytes. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param xCoreID (only IDF SMP FreeRTOS) + * The core to which the task is pinned to, or tskNO_AFFINITY if + * the task can run on any core. + * + * @param uxCoreAffinityMask (only Amazon SMP FreeRTOS) + * A bitwise value that indicates the cores on which the task can run. + * Cores are numbered from 0 to configNUM_CORES - 1. + * For example, to ensure that a task can run on core 0 and core 1, set + * uxCoreAffinityMask to 0x03. Note that only one of the cores will be used when + * using the IDF SMP version of FreeRTOS instead of Amazon FreeRTOS SMP. + * + * @param uxStackMemoryCaps The heap caps bitfield describing the memory capabilities to + * be used for stack memory. Currently, the capabilities have to include MALLOC_CAP_8BIT + * and one of the following: MALLOC_CAP_SPIRAM, MALLOC_CAP_INTERNAL. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + */ + #if CONFIG_FREERTOS_SMP + BaseType_t prvTaskCreateDynamicAffinitySetWithCaps( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + UBaseType_t uxCoreAffinityMask, + UBaseType_t uxStackMemoryCaps, + TaskHandle_t * const pxCreatedTask ); + #else + BaseType_t prvTaskCreateDynamicPinnedToCoreWithCaps( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + const BaseType_t xCoreID, + UBaseType_t uxStackMemoryCaps, + TaskHandle_t * const pxCreatedTask ); + #endif // CONFIG_FREERTOS_SMP + +#endif // CONFIG_SPIRAM + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c new file mode 100644 index 00000000000..93919f676cb --- /dev/null +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c @@ -0,0 +1,147 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/idf_additions.h" +#include "esp_private/freertos_idf_additions_priv.h" +#include "unity.h" +#include "esp_heap_caps.h" +#include "unity_test_runner.h" +#include "memory_checks.h" + +#define UNITY_FREERTOS_PRIORITY 5 + +#if CONFIG_SPIRAM + +static void task_delete_itself(void *arg) +{ + printf("starting task\n"); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + xTaskNotifyGive((TaskHandle_t)arg); + vTaskDelete(NULL); +} + +static void task_should_never_run(void *arg) +{ + printf("ERROR: this task should not run, aborting\n"); + abort(); +} + +static BaseType_t create_task(TaskFunction_t function, + size_t stack_size, + void *task_arg, + int core_num, + UBaseType_t heap_caps, + TaskHandle_t *task_handle) +{ +#if CONFIG_FREERTOS_SMP + UBaseType_t core_affinity_mask = (core_num == -1) ? tskNO_AFFINITY : 1 << core_num; + return prvTaskCreateDynamicAffinitySetWithCaps(function, + "self_delete", + stack_size, + task_arg, + UNITY_FREERTOS_PRIORITY + 1, + core_affinity_mask, + heap_caps, + task_handle); +#else + const BaseType_t task_core_num = (core_num == -1) ? tskNO_AFFINITY : core_num; + return prvTaskCreateDynamicPinnedToCoreWithCaps(function, + "self_delete", + stack_size, + task_arg, + UNITY_FREERTOS_PRIORITY + 1, + task_core_num, + heap_caps, + task_handle); +#endif +} + +TEST_CASE("Out of memory failure", "[freertos][psram]") +{ + TaskHandle_t task_handle = NULL; + const size_t STACK_SIZE = 0x80000000; // far larger than the virtual address space on ESP32 + UBaseType_t HEAP_CAPS = (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + + BaseType_t result = create_task(task_should_never_run, + STACK_SIZE, + (void *)xTaskGetCurrentTaskHandle(), + -1, + HEAP_CAPS, + &task_handle); + TEST_ASSERT_EQUAL(errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, result); + (void)task_handle; +} + +TEST_CASE("Task with stack memory in PSRAM", "[freertos][psram]") +{ + TaskHandle_t task_handle = NULL; + const size_t STACK_SIZE = 0x80000; // value is too large for any internal RAM on current chips + UBaseType_t HEAP_CAPS = (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + + BaseType_t result = create_task(task_delete_itself, + STACK_SIZE, + (void *)xTaskGetCurrentTaskHandle(), + -1, + HEAP_CAPS, + &task_handle); + TEST_ASSERT_EQUAL(pdPASS, result); + + // synchronize with the task to make sure we don't return too early, thus giving it enough time + // to delete itself and giving the idle task time to clean up memory (see delay in tearDown()). + xTaskNotifyGive(task_handle); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); +} + +#if !CONFIG_FREERTOS_UNICORE +typedef struct { + size_t recorded_core_num; + TaskHandle_t parent_handle; +} report_corenum_info_t; + +static void task_report_corenum(void *arg) +{ + report_corenum_info_t *info = (report_corenum_info_t*) arg; + info->recorded_core_num = xTaskGetAffinity(NULL); + xTaskNotifyGive(info->parent_handle); + vTaskSuspend(NULL); +} + +/** + * This test (roughly) verifies that xTaskCreateWithCapsAffinitySet() pins a task to the correct core. + */ +TEST_CASE("Task on specific core works", "[freertos][psram]") +{ + const size_t STACK_SIZE = 0x1000; + report_corenum_info_t corenum_info; + TaskHandle_t task_handle; + + for (int corenum = 0; corenum < CONFIG_SOC_CPU_CORES_NUM; corenum++) { + corenum_info.recorded_core_num = 0xFFFFFFFF; + corenum_info.parent_handle = xTaskGetCurrentTaskHandle(); + UBaseType_t HEAP_CAPS = (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + BaseType_t result = create_task(task_report_corenum, + STACK_SIZE, + (void *) &(corenum_info), + corenum, + HEAP_CAPS, + &task_handle); + + TEST_ASSERT_EQUAL(pdPASS, result); + + // Wait for the created task to finish its job + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + TEST_ASSERT_EQUAL((size_t) corenum, corenum_info.recorded_core_num); + + vTaskDelete(task_handle); + } +} +#endif // !CONFIG_FREERTOS_UNICORE + +#endif // SPIRAM diff --git a/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options b/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options index 541b767a2a4..38ae8ab7df4 100644 --- a/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options +++ b/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options @@ -13,6 +13,7 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64=y CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_FREERTOS_FPU_IN_ISR=y CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2 diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index eb41bb2dcd5..58698a72195 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -83,6 +83,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "i2c_hal.c" "i2c_hal_iram.c") endif() + if(CONFIG_SOC_ISP_SUPPORTED) + list(APPEND srcs "isp_hal.c") + endif() + if(CONFIG_SOC_RMT_SUPPORTED) list(APPEND srcs "rmt_hal.c") endif() diff --git a/components/hal/adc_oneshot_hal.c b/components/hal/adc_oneshot_hal.c index ce6cb193c66..feddc3178ca 100644 --- a/components/hal/adc_oneshot_hal.c +++ b/components/hal/adc_oneshot_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,6 +60,8 @@ void adc_oneshot_hal_setup(adc_oneshot_hal_ctx_t *hal, adc_channel_t chan) #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED adc_ll_digi_clk_sel(hal->clk_src); + adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT); + adc_ll_digi_set_clk_div(ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT); #else adc_ll_set_sar_clk_div(unit, ADC_LL_SAR_CLK_DIV_DEFAULT(unit)); if (unit == ADC_UNIT_2) { @@ -83,33 +85,42 @@ static void adc_hal_onetime_start(adc_unit_t unit, uint32_t clk_src_freq_hz) { #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED (void)unit; - uint32_t delay = 0; /** * There is a hardware limitation. If the APB clock frequency is high, the step of this reg signal: ``onetime_start`` may not be captured by the * ADC digital controller (when its clock frequency is too slow). A rough estimate for this step should be at least 3 ADC digital controller * clock cycle. */ - uint32_t digi_clk = clk_src_freq_hz / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1); + uint32_t adc_ctrl_clk = clk_src_freq_hz / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1); //Convert frequency to time (us). Since decimals are removed by this division operation. Add 1 here in case of the fact that delay is not enough. - delay = (1000 * 1000) / digi_clk + 1; - //3 ADC digital controller clock cycle - delay = delay * 3; - HAL_EARLY_LOGD("adc_hal", "clk_src_freq_hz: %"PRIu32", digi_clk: %"PRIu32", delay: %"PRIu32"", clk_src_freq_hz, digi_clk, delay); + uint32_t sample_delay_us = ((1000 * 1000) / adc_ctrl_clk + 1) * 3; + HAL_EARLY_LOGD("adc_hal", "clk_src_freq_hz: %"PRIu32", adc_ctrl_clk: %"PRIu32", sample_delay_us: %"PRIu32"", clk_src_freq_hz, adc_ctrl_clk, sample_delay_us); //This coefficient (8) is got from test, and verified from DT. When digi_clk is not smaller than ``APB_CLK_FREQ/8``, no delay is needed. - if (digi_clk >= APB_CLK_FREQ/8) { - delay = 0; + if (adc_ctrl_clk >= APB_CLK_FREQ/8) { + sample_delay_us = 0; } - HAL_EARLY_LOGD("adc_hal", "delay: %"PRIu32"", delay); + HAL_EARLY_LOGD("adc_hal", "delay for `onetime_start` signal captured: %"PRIu32"", sample_delay_us); adc_oneshot_ll_start(false); - esp_rom_delay_us(delay); + esp_rom_delay_us(sample_delay_us); adc_oneshot_ll_start(true); - //No need to delay here. Becuase if the start signal is not seen, there won't be a done intr. +#if ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL + /** + * There is a hardware limitation. + * After ADC get DONE signal, it still need a delay to synchronize ADC raw data or it may get zero. + * A rough estimate for this step should be at least ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL ADC sar clock cycle. + */ + uint32_t sar_clk = adc_ctrl_clk / ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT; + uint32_t read_delay_us = ((1000 * 1000) / sar_clk + 1) * ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL; + HAL_EARLY_LOGD("adc_hal", "clk_src_freq_hz: %"PRIu32", sar_clk: %"PRIu32", read_delay_us: %"PRIu32"", clk_src_freq_hz, sar_clk, read_delay_us); + esp_rom_delay_us(read_delay_us); + +#endif //ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL + #else adc_oneshot_ll_start(unit); -#endif +#endif // SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED } bool adc_oneshot_hal_convert(adc_oneshot_hal_ctx_t *hal, int *out_raw) diff --git a/components/hal/cache_hal.c b/components/hal/cache_hal.c index ea6d3e485f0..423589e7a0a 100644 --- a/components/hal/cache_hal.c +++ b/components/hal/cache_hal.c @@ -286,7 +286,7 @@ void cache_hal_unfreeze(uint32_t cache_level, cache_type_t type) uint32_t cache_hal_get_cache_line_size(uint32_t cache_level, cache_type_t type) { - HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS)); + HAL_ASSERT(cache_level <= CACHE_LL_LEVEL_NUMS); uint32_t line_size = 0; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE diff --git a/components/hal/esp32/cache_hal_esp32.c b/components/hal/esp32/cache_hal_esp32.c index e8acd528317..81592333277 100644 --- a/components/hal/esp32/cache_hal_esp32.c +++ b/components/hal/esp32/cache_hal_esp32.c @@ -55,7 +55,7 @@ bool cache_hal_vaddr_to_cache_level_id(uint32_t vaddr_start, uint32_t len, uint3 uint32_t cache_hal_get_cache_line_size(uint32_t cache_level, cache_type_t type) { - HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS)); + HAL_ASSERT(cache_level <= CACHE_LL_LEVEL_NUMS); uint32_t line_size = 0; diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index 6e5ef9bbcc6..08e93a0c6d0 100644 --- a/components/hal/esp32/include/hal/adc_ll.h +++ b/components/hal/esp32/include/hal/adc_ll.h @@ -30,6 +30,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) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 3a5963f26ce..c78ec7d1127 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -508,6 +508,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { if (gpio_num < 32) { diff --git a/components/hal/esp32/include/hal/i2c_ll.h b/components/hal/esp32/include/hal/i2c_ll.h index 4e327b82ba5..9ca1b16b2f1 100644 --- a/components/hal/esp32/include/hal/i2c_ll.h +++ b/components/hal/esp32/include/hal/i2c_ll.h @@ -13,6 +13,7 @@ #include "soc/i2c_periph.h" #include "soc/i2c_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/dport_reg.h" #include "hal/i2c_types.h" #include "esp_attr.h" #include "hal/assert.h" @@ -45,24 +46,29 @@ typedef union { #define I2C_LL_CMD_END 4 /*!slave_addr.en_10bit = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) || 0x78; hw->slave_addr.addr = addr_14_7 || addr_6_0; } else { @@ -368,6 +374,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.nonfifo_rx_thres = full_thr; hw->fifo_conf.rx_fifo_full_thrhd = full_thr; } @@ -664,6 +671,51 @@ static inline void i2c_ll_update(i2c_dev_t *hw) ;// ESP32 do not support } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + if (i2c_port == 0) { + uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG); + reg_val &= ~DPORT_I2C_EXT0_CLK_EN; + reg_val |= enable << 7; + DPORT_WRITE_PERI_REG(DPORT_PERIP_CLK_EN_REG, reg_val); + } else if (i2c_port == 1) { + uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG); + reg_val &= ~DPORT_I2C_EXT1_CLK_EN; + reg_val |= enable << 18; + DPORT_WRITE_PERI_REG(DPORT_PERIP_CLK_EN_REG, reg_val); + } +} + +/// 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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + if (i2c_port == 0) { + DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT0_RST); + DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 0); + } else if (i2c_port == 1) { + DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT1_RST); + DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 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_ATOMIC_ENV variable in advance +#define i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Set whether slave should auto start, or only start with start signal from master * diff --git a/components/hal/esp32/include/hal/sdmmc_ll.h b/components/hal/esp32/include/hal/sdmmc_ll.h index 497b950d9a3..424528b3a6d 100644 --- a/components/hal/esp32/include/hal/sdmmc_ll.h +++ b/components/hal/esp32/include/hal/sdmmc_ll.h @@ -197,10 +197,10 @@ static inline uint32_t sdmmc_ll_get_card_clock_div(sdmmc_dev_t *hw, uint32_t slo uint32_t card_div = 0; if (slot == 0) { - HAL_ASSERT(hw->clksrc.card0 = 0); + HAL_ASSERT(hw->clksrc.card0 == 0); card_div = hw->clkdiv.div0; } else if (slot == 1) { - HAL_ASSERT(hw->clksrc.card1 = 1); + HAL_ASSERT(hw->clksrc.card1 == 1); card_div = hw->clkdiv.div1; } else { HAL_ASSERT(false); diff --git a/components/hal/esp32/include/hal/twai_ll.h b/components/hal/esp32/include/hal/twai_ll.h index 8c35c5e5baf..6fc14529f66 100644 --- a/components/hal/esp32/include/hal/twai_ll.h +++ b/components/hal/esp32/include/hal/twai_ll.h @@ -194,25 +194,25 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - (void)hw; + (void)group_id; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { - (void)hw; + (void)group_id; HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB); } diff --git a/components/hal/esp32c2/include/hal/adc_ll.h b/components/hal/esp32c2/include/hal/adc_ll.h index 96c3e58bdef..9427b0e4c42 100644 --- a/components/hal/esp32c2/include/hal/adc_ll.h +++ b/components/hal/esp32c2/include/hal/adc_ll.h @@ -33,6 +33,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32c2/include/hal/gpio_ll.h b/components/hal/esp32c2/include/hal/gpio_ll.h index ad705731104..d9ae5c07ed5 100644 --- a/components/hal/esp32c2/include/hal/gpio_ll.h +++ b/components/hal/esp32c2/include/hal/gpio_ll.h @@ -332,6 +332,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { return (hw->in.in_data_next >> gpio_num) & 0x1; diff --git a/components/hal/esp32c2/include/hal/i2c_ll.h b/components/hal/esp32c2/include/hal/i2c_ll.h index c2d2010f1db..44e873aa2d3 100644 --- a/components/hal/esp32c2/include/hal/i2c_ll.h +++ b/components/hal/esp32c2/include/hal/i2c_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,7 @@ #include "hal/i2c_types.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "esp_attr.h" #ifdef __cplusplus @@ -47,23 +48,17 @@ typedef union { #define I2C_LL_CMD_END 4 /*!ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + (void)i2c_port; + SYSTEM.perip_clk_en0.i2c_ext0_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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + (void)i2c_port; + SYSTEM.perip_rst_en0.i2c_ext0_rst = 1; + SYSTEM.perip_rst_en0.i2c_ext0_rst = 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_ATOMIC_ENV variable in advance +#define i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Configure the I2C bus timing related register. * diff --git a/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h index 6717fc87c0d..8d59c99148a 100644 --- a/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/system_reg.h" #include "soc/xts_aes_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(XTS_AES_PLAIN_MEM + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index eb3a42651c7..f62ffb538c6 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -41,6 +41,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32c3/include/hal/clk_tree_ll.h b/components/hal/esp32c3/include/hal/clk_tree_ll.h index 57cd49fcdff..6f1af60f561 100644 --- a/components/hal/esp32c3/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c3/include/hal/clk_tree_ll.h @@ -120,7 +120,7 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S; /* If xtal xpd software control is on */ bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S; - // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled + // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disabled bool enabled = !xtal_xpd_sw || xtal_xpd_st; return enabled; } diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index 75e9e82c60e..6ff4bf6492c 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -344,6 +344,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { return (hw->in.data >> gpio_num) & 0x1; diff --git a/components/hal/esp32c3/include/hal/i2c_ll.h b/components/hal/esp32c3/include/hal/i2c_ll.h index 67ec74f378a..f3e28ad02e5 100644 --- a/components/hal/esp32c3/include/hal/i2c_ll.h +++ b/components/hal/esp32c3/include/hal/i2c_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,7 @@ #include "hal/i2c_types.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "esp_attr.h" #include "hal/misc.h" @@ -24,7 +25,6 @@ extern "C" { #endif - /** * @brief I2C hardware cmd register fields. */ @@ -49,24 +49,23 @@ typedef union { #define I2C_LL_CMD_END 4 /*!scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); + clk_cal->scl_wait_high = (bus_freq >= 80 * 1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high; clk_cal->sda_hold = half_cycle / 4; clk_cal->sda_sample = half_cycle / 2; @@ -127,6 +126,38 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + (void)i2c_port; + SYSTEM.perip_clk_en0.reg_i2c_ext0_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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + (void)i2c_port; + SYSTEM.perip_rst_en0.reg_i2c_ext0_rst = 1; + SYSTEM.perip_rst_en0.reg_i2c_ext0_rst = 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_ATOMIC_ENV variable in advance +#define i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Configure the I2C bus timing related register. * @@ -295,6 +326,36 @@ static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_e hw->ctr.addr_broadcasting_en = broadcast_en; } +/** + * @brief Get the cause of SCL clock stretching in slave mode + * + * @param hw Beginning address of the peripheral registers + * @param stretch_cause Pointer to stretch cause in the slave mode. + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) +{ + switch (hw->sr.stretch_cause) { + case 0: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; + break; + case 1: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY; + break; + case 2: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL; + break; + case 3: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK; + break; + default: + HAL_ASSERT(false); + break; + } +} + /** * @brief Configure I2C slave address * @@ -400,6 +461,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rx_fifo_wm_thrhd = full_thr; } @@ -563,7 +625,7 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h __attribute__((always_inline)) static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len) { - for (int i = 0; i< len; i++) { + for (int i = 0; i < len; i++) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->fifo_data, data, ptr[i]); } } @@ -580,7 +642,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_ __attribute__((always_inline)) static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->fifo_data, data); } } @@ -592,14 +654,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -610,15 +669,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } @@ -669,8 +724,6 @@ static inline void i2c_ll_master_get_filter(i2c_dev_t *hw, uint8_t *filter_conf) *filter_conf = hw->filter_cfg.scl_thres; } - - /** * @brief Reste I2C master FSM. When the master FSM is stuck, call this function to reset the FSM * @@ -889,7 +942,7 @@ static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *even *event = I2C_INTR_EVENT_ARBIT_LOST; } else if (int_sts.nack) { *event = I2C_INTR_EVENT_NACK; - } else if (int_sts.time_out||int_sts.scl_st_to||int_sts.scl_main_st_to) { + } else if (int_sts.time_out || int_sts.scl_st_to || int_sts.scl_main_st_to) { *event = I2C_INTR_EVENT_TOUT; } else if (int_sts.end_detect) { *event = I2C_INTR_EVENT_END_DET; @@ -1026,7 +1079,6 @@ static inline void i2c_ll_slave_disable_rx_it(i2c_dev_t *hw) hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT); } - /** * @brief Configure I2C SCL timing * diff --git a/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h index 1196d16c12f..8857e1f915a 100644 --- a/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/system_reg.h" #include "soc/xts_aes_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(XTS_AES_PLAIN_MEM + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32c3/include/hal/twai_ll.h b/components/hal/esp32c3/include/hal/twai_ll.h index 3283425dfef..d2d713f206a 100644 --- a/components/hal/esp32c3/include/hal/twai_ll.h +++ b/components/hal/esp32c3/include/hal/twai_ll.h @@ -124,25 +124,25 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - (void)hw; + (void)group_id; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { - (void)hw; + (void)group_id; HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB); } diff --git a/components/hal/esp32c6/include/hal/adc_ll.h b/components/hal/esp32c6/include/hal/adc_ll.h index c8c52aadfd3..d7d689e74a6 100644 --- a/components/hal/esp32c6/include/hal/adc_ll.h +++ b/components/hal/esp32c6/include/hal/adc_ll.h @@ -42,6 +42,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index 5bd7ea1178c..a2aab0341b3 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -338,6 +338,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { return (hw->in.in_data_next >> gpio_num) & 0x1; diff --git a/components/hal/esp32c6/include/hal/i2c_ll.h b/components/hal/esp32c6/include/hal/i2c_ll.h index db301dceec8..c0175ef1212 100644 --- a/components/hal/esp32c6/include/hal/i2c_ll.h +++ b/components/hal/esp32c6/include/hal/i2c_ll.h @@ -49,31 +49,31 @@ typedef union { #define I2C_LL_CMD_END 4 /*!ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + (void)i2c_port; + PCR.i2c_conf.i2c_clk_en = enable; +} + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + (void)i2c_port; + PCR.i2c_conf.i2c_rst_en = 1; + PCR.i2c_conf.i2c_rst_en = 0; +} + /** * @brief Configure the I2C bus timing related register. * @@ -299,6 +323,36 @@ static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_e hw->ctr.addr_broadcasting_en = broadcast_en; } +/** + * @brief Get the cause of SCL clock stretching in slave mode + * + * @param hw Beginning address of the peripheral registers + * @param stretch_cause Pointer to stretch cause in the slave mode. + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) +{ + switch (hw->sr.stretch_cause) { + case 0: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; + break; + case 1: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY; + break; + case 2: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL; + break; + case 3: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK; + break; + default: + HAL_ASSERT(false); + break; + } +} + /** * @brief Configure I2C slave address * @@ -312,7 +366,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo { hw->slave_addr.addr_10bit_en = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; hw->slave_addr.slave_addr = addr_14_7 | addr_6_0; hw->ctr.addr_10bit_rw_check_en = addr_10bit_en; @@ -404,6 +458,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rxfifo_wm_thrhd = full_thr; } @@ -596,14 +651,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -614,15 +666,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } diff --git a/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h index 5e05cd6aba0..20c303344a4 100644 --- a/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/hp_system_reg.h" #include "soc/xts_aes_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(XTS_AES_PLAIN_MEM(0) + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32c6/include/hal/twai_ll.h b/components/hal/esp32c6/include/hal/twai_ll.h index b70f92d62e9..f6a893ea1de 100644 --- a/components/hal/esp32c6/include/hal/twai_ll.h +++ b/components/hal/esp32c6/include/hal/twai_ll.h @@ -123,13 +123,13 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - if (hw == &TWAI0) { + if (group_id == 0) { PCR.twai0_func_clk_conf.twai0_func_clk_en = en; } else { PCR.twai1_func_clk_conf.twai1_func_clk_en = en; @@ -139,11 +139,11 @@ static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { uint32_t clk_id = 0; bool valid = true; @@ -158,7 +158,7 @@ static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t } if (valid) { - if (hw == &TWAI0) { + if (group_id == 0) { PCR.twai0_func_clk_conf.twai0_func_clk_sel = clk_id; } else { PCR.twai1_func_clk_conf.twai1_func_clk_sel = clk_id; diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index 269194b6907..5e4fbce2b26 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -42,6 +42,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (2) /*--------------------------------------------------------------- DMA @@ -592,6 +593,37 @@ static inline void adc_ll_calibration_init(adc_unit_t adc_n) REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); } +/** + * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. + * false: Use IO external voltage as calibration voltage. + */ +static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + /* Enable/disable internal connect GND (for calibration). */ + if (internal_gnd) { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 1); + } else { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0); + } +} + +/** + * Resume register status after calibration. + * + * @param adc_n ADC index number. + */ +static inline void adc_ll_calibration_finish(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0); +} + /** * Set the calibration result to ADC. * diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index df08c857bed..f9090a6fa30 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -380,6 +380,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, gpio_num_t gpio_num, uint32 * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, gpio_num_t gpio_num) { return (hw->in.in_data_next >> gpio_num) & 0x1; diff --git a/components/hal/esp32h2/include/hal/i2c_ll.h b/components/hal/esp32h2/include/hal/i2c_ll.h index 70214524fef..d1583c78e90 100644 --- a/components/hal/esp32h2/include/hal/i2c_ll.h +++ b/components/hal/esp32h2/include/hal/i2c_ll.h @@ -47,32 +47,32 @@ typedef union { #define I2C_LL_CMD_END 4 /*!scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); + clk_cal->scl_wait_high = (bus_freq >= 80 * 1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high; clk_cal->sda_hold = half_cycle / 4; clk_cal->sda_sample = half_cycle / 2; @@ -126,6 +126,28 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + PCR.i2c[i2c_port].i2c_conf.i2c_clk_en = enable; +} + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + PCR.i2c[i2c_port].i2c_conf.i2c_rst_en = 1; + PCR.i2c[i2c_port].i2c_conf.i2c_rst_en = 0; +} + /** * @brief Configure the I2C bus timing related register. * @@ -295,6 +317,36 @@ static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_e hw->ctr.addr_broadcasting_en = broadcast_en; } +/** + * @brief Get the cause of SCL clock stretching in slave mode + * + * @param hw Beginning address of the peripheral registers + * @param stretch_cause Pointer to stretch cause in the slave mode. + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) +{ + switch (hw->sr.stretch_cause) { + case 0: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; + break; + case 1: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY; + break; + case 2: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL; + break; + case 3: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK; + break; + default: + HAL_ASSERT(false); + break; + } +} + /** * @brief Configure I2C slave address * @@ -308,7 +360,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo { hw->slave_addr.addr_10bit_en = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; hw->slave_addr.slave_addr = addr_14_7 | addr_6_0; hw->ctr.addr_10bit_rw_check_en = addr_10bit_en; @@ -400,6 +452,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rxfifo_wm_thrhd = full_thr; } @@ -563,7 +616,7 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h __attribute__((always_inline)) static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len) { - for (int i = 0; i< len; i++) { + for (int i = 0; i < len; i++) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]); } } @@ -580,7 +633,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_ __attribute__((always_inline)) static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata); } } @@ -592,14 +645,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -610,15 +660,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } diff --git a/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h index 5e05cd6aba0..20c303344a4 100644 --- a/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/hp_system_reg.h" #include "soc/xts_aes_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(XTS_AES_PLAIN_MEM(0) + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32h2/include/hal/twai_ll.h b/components/hal/esp32h2/include/hal/twai_ll.h index e66bc0a27a1..653404fdb4f 100644 --- a/components/hal/esp32h2/include/hal/twai_ll.h +++ b/components/hal/esp32h2/include/hal/twai_ll.h @@ -116,24 +116,26 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { + (void)group_id; PCR.twai0_func_clk_conf.twai0_func_clk_en = en; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { + (void)group_id; switch (clk_src) { case TWAI_CLK_SRC_DEFAULT: PCR.twai0_func_clk_conf.twai0_func_clk_sel = 0; diff --git a/components/hal/esp32p4/include/hal/clk_gate_ll.h b/components/hal/esp32p4/include/hal/clk_gate_ll.h index 324e16bbe72..b431dd9186e 100644 --- a/components/hal/esp32p4/include/hal/clk_gate_ll.h +++ b/components/hal/esp32p4/include/hal/clk_gate_ll.h @@ -38,12 +38,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return HP_SYS_CLKRST_REG_I2C1_APB_CLK_EN; case PERIPH_LCD_MODULE: return HP_SYS_CLKRST_REG_LCD_CLK_EN; - case PERIPH_TWAI0_MODULE: - return HP_SYS_CLKRST_REG_TWAI0_CLK_EN; - case PERIPH_TWAI1_MODULE: - return HP_SYS_CLKRST_REG_TWAI1_CLK_EN; - case PERIPH_TWAI2_MODULE: - return HP_SYS_CLKRST_REG_TWAI2_CLK_EN; case PERIPH_I3C_MODULE: return HP_SYS_CLKRST_REG_I3C_MST_CLK_EN; case PERIPH_CAM_MODULE: @@ -109,12 +103,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en return HP_SYS_CLKRST_REG_RST_EN_I2C0; case PERIPH_I2C1_MODULE: return HP_SYS_CLKRST_REG_RST_EN_I2C1; - case PERIPH_TWAI0_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_CAN0; - case PERIPH_TWAI1_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_CAN1; - case PERIPH_TWAI2_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_CAN2; case PERIPH_LCD_MODULE: return HP_SYS_CLKRST_REG_RST_EN_LCDCAM; case PERIPH_SARADC_MODULE: @@ -174,9 +162,6 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) return HP_SYS_CLKRST_SOC_CLK_CTRL2_REG; case PERIPH_LCD_MODULE: return HP_SYS_CLKRST_PERI_CLK_CTRL110_REG; - case PERIPH_TWAI0_MODULE: - case PERIPH_TWAI1_MODULE: - case PERIPH_TWAI2_MODULE: return HP_SYS_CLKRST_PERI_CLK_CTRL116_REG; case PERIPH_I3C_MODULE: case PERIPH_CAM_MODULE: @@ -221,9 +206,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) case PERIPH_I2C0_MODULE: case PERIPH_I2C1_MODULE: return HP_SYS_CLKRST_HP_RST_EN1_REG; - case PERIPH_TWAI0_MODULE: - case PERIPH_TWAI1_MODULE: - case PERIPH_TWAI2_MODULE: case PERIPH_CAM_MODULE: case PERIPH_SARADC_MODULE: case PERIPH_AES_MODULE: diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index b3c41a5faaa..986edcdacc7 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -411,6 +411,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { if (gpio_num < 32) { diff --git a/components/hal/esp32p4/include/hal/i2c_ll.h b/components/hal/esp32p4/include/hal/i2c_ll.h index 636f27f4a05..4ae427662bb 100644 --- a/components/hal/esp32p4/include/hal/i2c_ll.h +++ b/components/hal/esp32p4/include/hal/i2c_ll.h @@ -47,18 +47,24 @@ typedef union { #define I2C_LL_CMD_END 4 /*!scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); + clk_cal->scl_wait_high = (bus_freq >= 80 * 1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high; clk_cal->sda_hold = half_cycle / 4; clk_cal->sda_sample = half_cycle / 2; @@ -125,6 +131,45 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + if (i2c_port == 0) { + HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2c0_apb_clk_en = enable; + } else if (i2c_port == 1) { + HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2c1_apb_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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + if (i2c_port == 0) { + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_i2c0 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_i2c0 = 0; + } else if (i2c_port == 1) { + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_i2c1 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_i2c1 = 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_ATOMIC_ENV variable in advance +#define i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Configure the I2C bus timing related register. * @@ -136,7 +181,7 @@ static inline void i2c_ll_update(i2c_dev_t *hw) static inline void i2c_ll_master_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg) { if (hw == &I2C0) { - HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl10, reg_i2c0_clk_div_num, bus_cfg->clkm_div - 1); + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl10, reg_i2c0_clk_div_num, bus_cfg->clkm_div - 1); HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl10, reg_i2c0_clk_div_numerator, 0); HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl10, reg_i2c0_clk_div_denominator, 0); } else if (hw == &I2C1) { @@ -319,7 +364,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo { hw->slave_addr.addr_10bit_en = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; hw->slave_addr.slave_addr = addr_14_7 | addr_6_0; hw->ctr.addr_10bit_rw_check_en = addr_10bit_en; @@ -411,6 +456,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rxfifo_wm_thrhd = full_thr; } @@ -574,7 +620,7 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h __attribute__((always_inline)) static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len) { - for (int i = 0; i< len; i++) { + for (int i = 0; i < len; i++) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]); } } @@ -591,7 +637,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_ __attribute__((always_inline)) static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata); } } @@ -603,14 +649,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -621,15 +664,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } @@ -741,9 +780,9 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c { // src_clk : (1) for RTC_CLK, (0) for XTAL if (hw == &I2C0) { - HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c0_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1: 0; + HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c0_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0; } else if (hw == &I2C1) { - HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c1_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1: 0; + HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c1_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0; } else if (hw == &LP_I2C) { // Do nothing return; @@ -753,6 +792,10 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c } +/// 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 i2c_ll_set_source_clk(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_set_source_clk(__VA_ARGS__);} while(0) + /** * @brief Enable I2C peripheral controller clock * @@ -762,10 +805,8 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en) { if (hw == &I2C0) { - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2c0_apb_clk_en = en; HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c0_clk_en = en; } else if (hw == &I2C1) { - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2c1_apb_clk_en = en; HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c1_clk_en = en; } else if (hw == &LP_I2C) { // Do nothing @@ -828,7 +869,6 @@ static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev) return &dev->int_status; } - /** * @brief Enable I2C slave clock stretch. * diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h new file mode 100644 index 00000000000..96633369b2d --- /dev/null +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -0,0 +1,762 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "esp_attr.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/isp_types.h" +#include "hal/color_types.h" +#include "soc/isp_struct.h" +#include "soc/hp_sys_clkrst_struct.h" +#include "soc/clk_tree_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ISP_LL_GET_HW(num) (((num) == 0) ? (&ISP) : NULL) + + +/*--------------------------------------------------------------- + INTR +---------------------------------------------------------------*/ +#define ISP_LL_EVENT_DATA_TYPE_ERR (1<<0) +#define ISP_LL_EVENT_ASYNC_FIFO_OVF (1<<1) +#define ISP_LL_EVENT_BUF_FULL (1<<2) +#define ISP_LL_EVENT_HVNUM_SETTING_ERR (1<<3) +#define ISP_LL_EVENT_DATA_TYPE_SETTING_ERR (1<<4) +#define ISP_LL_EVENT_MIPI_HNUM_UNMATCH (1<<5) +#define ISP_LL_EVENT_DPC_CHECK_DONE (1<<6) +#define ISP_LL_EVENT_GAMMA_XCOORD_ERR (1<<7) +#define ISP_LL_EVENT_AE_MONITOR (1<<8) +#define ISP_LL_EVENT_AE_FRAME_DONE (1<<9) +#define ISP_LL_EVENT_AF_FDONE (1<<10) +#define ISP_LL_EVENT_AF_ENV (1<<11) +#define ISP_LL_EVENT_AWB_FDONE (1<<12) +#define ISP_LL_EVENT_HIST_FDONE (1<<13) +#define ISP_LL_EVENT_FRAME (1<<14) +#define ISP_LL_EVENT_BLC_FRAME (1<<15) +#define ISP_LL_EVENT_LSC_FRAME (1<<16) +#define ISP_LL_EVENT_DPC_FRAME (1<<17) +#define ISP_LL_EVENT_BF_FRAME (1<<18) +#define ISP_LL_EVENT_DEMOSAIC_FRAME (1<<19) +#define ISP_LL_EVENT_MEDIAN_FRAME (1<<20) +#define ISP_LL_EVENT_CCM_FRAME (1<<21) +#define ISP_LL_EVENT_GAMMA_FRAME (1<<22) +#define ISP_LL_EVENT_RGB2YUV_FRAME (1<<23) +#define ISP_LL_EVENT_SHARP_FRAME (1<<24) +#define ISP_LL_EVENT_COLOR_FRAME (1<<25) +#define ISP_LL_EVENT_YUV2RGB_FRAME (1<<26) +#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) + +/*--------------------------------------------------------------- + AF +---------------------------------------------------------------*/ +#define ISP_LL_AF_WINDOW_MAX_RANGE ((1<<12) - 1) + + +/** + * @brief Env monitor mode + */ +typedef enum { + ISP_LL_AF_ENV_MONITOR_MODE_ABS, ///< Use absolute val for threshold + ISP_LL_AF_ENV_MONITOR_MODE_RATIO, ///< Use ratio val for threshold +} isp_ll_af_env_monitor_mode_t; + +/** + * @brief Edge monitor mode + */ +typedef enum { + ISP_LL_AF_EDGE_MONITOR_MODE_AUTO, ///< Auto set threshold + ISP_LL_AF_EDGE_MONITOR_MODE_MANUAL, ///< Manual set threshold +} isp_ll_af_edge_monitor_mode_t; + + +/*--------------------------------------------------------------- + Clock +---------------------------------------------------------------*/ +/** + * @brief Enable the bus clock for ISP module + * + * @param hw Hardware instance address + * @param en enable / disable + */ +static inline void isp_ll_enable_module_clock(isp_dev_t *hw, bool en) +{ + HP_SYS_CLKRST.peri_clk_ctrl25.reg_isp_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 isp_ll_enable_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_enable_module_clock(__VA_ARGS__) + +/** + * @brief Reset the ISP module + * + * @param hw Hardware instance address + */ +static inline void isp_ll_reset_module_clock(isp_dev_t *hw) +{ + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_isp = 1; + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_isp = 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_ATOMIC_ENV variable in advance +#define isp_ll_reset_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_reset_module_clock(__VA_ARGS__) + +/** + * @brief Select ISP clock source + * + * @param hw Hardware instance address + * @param clk_src clock source, see valid sources in type `soc_periph_isp_clk_src_t` + */ +static inline void isp_ll_select_clk_source(isp_dev_t *hw, soc_periph_isp_clk_src_t clk_src) +{ + uint32_t clk_val = 0; + switch (clk_src) { + case ISP_CLK_SRC_XTAL: + clk_val = 0; + break; + case ISP_CLK_SRC_PLL160: + clk_val = 1; + break; + case ISP_CLK_SRC_PLL240: + clk_val = 2; + break; + default: + HAL_ASSERT(false); + break; + } + + HP_SYS_CLKRST.peri_clk_ctrl25.reg_isp_clk_src_sel = clk_val; +} + +/// 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 isp_ll_select_clk_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_select_clk_source(__VA_ARGS__) + +/** + * @brief Set ISP clock div + * + * @param hw Hardware instance address + * @param div divider value + */ +static inline void isp_ll_set_clock_div(isp_dev_t *hw, uint32_t div) +{ + HP_SYS_CLKRST.peri_clk_ctrl26.reg_isp_clk_div_num = div; +} + +/// 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 isp_ll_set_clock_div(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_set_clock_div(__VA_ARGS__) + +/*--------------------------------------------------------------- + Misc +---------------------------------------------------------------*/ +/** + * @brief Init ISP + * + * @param[in] hw Hardware instance address + */ +static inline void isp_ll_init(isp_dev_t *hw) +{ + hw->cntl.val = 0; + hw->int_clr.val = ISP_LL_EVENT_ALL_MASK; + hw->int_ena.val = ~ISP_LL_EVENT_ALL_MASK; +} + +/** + * @brief Enable / Disable ISP clock + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_en = enable; +} + +/** + * @brief Enable / Disable ISP + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.isp_en = enable; +} + +/** + * @brief Set input data source + * + * @param[in] hw Hardware instance address + * @param[in] source input data source, see `isp_input_data_source_t` + */ +static inline void isp_ll_set_input_data_source(isp_dev_t *hw, isp_input_data_source_t source) +{ + switch (source) { + case ISP_INPUT_DATA_SOURCE_CSI: + hw->cntl.isp_in_src = 0; + hw->cntl.mipi_data_en = 1; + break; + case ISP_INPUT_DATA_SOURCE_DVP: + hw->cntl.isp_in_src = 1; + hw->cntl.mipi_data_en = 0; + break; + case ISP_INPUT_DATA_SOURCE_DWGDMA: + hw->cntl.isp_in_src = 2; + hw->cntl.mipi_data_en = 0; + break; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Set input 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_set_input_data_color_format(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->cntl.isp_data_type = 0; + valid = true; + break; + case COLOR_PIXEL_RAW10: + hw->cntl.isp_data_type = 1; + valid = true; + break; + case COLOR_PIXEL_RAW12: + hw->cntl.isp_data_type = 2; + valid = true; + break; + default: + break; + } + } + + return valid; +} + +/** + * @brief Set input data horizontal pixel number + * + * @param[in] hw Hardware instance address + * @param[in] pixel_num number of pixels + */ +static inline void isp_ll_set_intput_data_h_pixel_num(isp_dev_t *hw, uint32_t pixel_num) +{ + hw->frame_cfg.hadr_num = pixel_num - 1; +} + +/** + * @brief Set input data vertical row number + * + * @param[in] hw Hardware instance address + * @param[in] row_num number of rows + */ +static inline void isp_ll_set_intput_data_v_row_num(isp_dev_t *hw, uint32_t row_num) +{ + hw->frame_cfg.vadr_num = row_num - 1; +} + +/** + * @brief Set output 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_set_output_data_color_format(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->cntl.isp_out_type = 0; + hw->cntl.demosaic_en = 0; + hw->cntl.rgb2yuv_en = 0; + hw->cntl.yuv2rgb_en = 0; + valid = true; + break; + default: + break; + } + } else if (format.color_space == COLOR_SPACE_RGB) { + switch(format.pixel_format) { + case COLOR_PIXEL_RGB888: + hw->cntl.isp_out_type = 2; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 1; + valid = true; + break; + case COLOR_PIXEL_RGB565: + hw->cntl.isp_out_type = 4; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 1; + valid = true; + break; + default: + break; + } + } else if (format.color_space == COLOR_SPACE_YUV) { + switch(format.pixel_format) { + case COLOR_PIXEL_YUV422: + hw->cntl.isp_out_type = 1; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 0; + valid = true; + break; + case COLOR_PIXEL_YUV420: + hw->cntl.isp_out_type = 3; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 0; + valid = true; + break; + default: + break; + } + } + + return valid; +} + +/** + * @brief Set if line start packet exists + * + * @param[in] hw Hardware instance address + * @param[in] en Enable / Disable + */ +static inline void isp_ll_enable_line_start_packet_exist(isp_dev_t *hw, bool en) +{ + hw->frame_cfg.hsync_start_exist = en; +} + +/** + * @brief Set if line end packet exists + * + * @param[in] hw Hardware instance address + * @param[in] en Enable / Disable + */ +static inline void isp_ll_enable_line_end_packet_exist(isp_dev_t *hw, bool en) +{ + hw->frame_cfg.hsync_end_exist = en; +} + +/** + * @brief Get if demosaic is enabled + * + * @param[in] hw Hardware instance address + * + * @return True: enabled + */ +static inline bool isp_ll_is_demosaic_enabled(isp_dev_t *hw) +{ + return hw->cntl.demosaic_en; +} + +/** + * @brief Get if rgb2yuv is enabled + * + * @param[in] hw Hardware instance address + * + * @return True: enabled + */ +static inline bool isp_ll_is_rgb2yuv_enabled(isp_dev_t *hw) +{ + return hw->cntl.rgb2yuv_en; +} + +/*--------------------------------------------------------------- + AF +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable AF clock + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_af_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_af_force_on = enable; +} + +/** + * @brief Enable / Disable AF + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_af_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.af_en = enable; +} + +/** + * @brief Enable / Disable auto aupdate AF + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_af_enable_auto_update(isp_dev_t *hw, bool enable) +{ + hw->af_ctrl0.af_auto_update = enable; +} + +/** + * @brief Manual aupdate AF once + * + * @param[in] hw Hardware instance address + */ +static inline void isp_ll_af_manual_update(isp_dev_t *hw) +{ + //self clear + hw->af_ctrl0.af_manual_update = 1; +} + +/** + * @brief Set edge thresh mode + * + * @param[in] hw Hardware instance address + * @param[in] mode See `isp_ll_af_edge_monitor_mode_t` + */ +static inline void isp_ll_af_set_edge_thresh_mode(isp_dev_t *hw, isp_ll_af_edge_monitor_mode_t mode) +{ + if (mode == ISP_LL_AF_EDGE_MONITOR_MODE_AUTO) { + hw->af_threshold.af_threshold = 0; + } +} + +/** + * @brief Set edge threshold + * + * @param[in] hw Hardware instance address + * @param[in] thresh Edge threshold + */ +static inline void isp_ll_af_set_edge_thresh(isp_dev_t *hw, uint32_t thresh) +{ + HAL_ASSERT(thresh != 0); + + hw->af_threshold.af_threshold = thresh; +} + +/** + * @brief Set auto edge thresh pixel num + * + * @param[in] hw Hardware instance address + * @param[in] pixel_num Pixel numbers + */ +static inline void isp_ll_af_set_auto_edge_thresh_pixel_num(isp_dev_t *hw, uint32_t pixel_num) +{ + HAL_ASSERT(hw->af_threshold.af_threshold == 0); + + hw->af_ctrl1.af_thpixnum = pixel_num; +} + +/** + * @brief Set window range + * + * @param[in] hw Hardware instance address + * @param[in] window_id Window ID + * @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_af_set_window_range(isp_dev_t *hw, uint32_t window_id, uint32_t top_left_x, uint32_t top_left_y, uint32_t bottom_right_x, uint32_t bottom_right_y) +{ + HAL_ASSERT(top_left_x < ISP_LL_AF_WINDOW_MAX_RANGE && + top_left_y < ISP_LL_AF_WINDOW_MAX_RANGE && + bottom_right_x < ISP_LL_AF_WINDOW_MAX_RANGE && + bottom_right_y < ISP_LL_AF_WINDOW_MAX_RANGE); + + switch (window_id) { + case 0: + hw->af_hscale_a.af_lpoint_a = top_left_x; + hw->af_vscale_a.af_tpoint_a = top_left_y; + hw->af_hscale_a.af_rpoint_a = bottom_right_x; + hw->af_vscale_a.af_bpoint_a = bottom_right_y; + break; + case 1: + hw->af_hscale_b.af_lpoint_b = top_left_x; + hw->af_vscale_b.af_tpoint_b = top_left_y; + hw->af_hscale_b.af_rpoint_b = bottom_right_x; + hw->af_vscale_b.af_bpoint_b = bottom_right_y; + break; + case 2: + hw->af_hscale_c.af_lpoint_c = top_left_x; + hw->af_vscale_c.af_tpoint_c = top_left_y; + hw->af_hscale_c.af_rpoint_c = bottom_right_x; + hw->af_vscale_c.af_bpoint_c = bottom_right_y; + break; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Get window sum + * + * @param[in] hw Hardware instance address + * @param[in] window_id Window ID + * + * @return Window sum + */ +static inline uint32_t isp_ll_af_get_window_sum(isp_dev_t *hw, uint32_t window_id) +{ + switch (window_id) { + case 0: + return hw->af_sum_a.af_suma; + case 1: + return hw->af_sum_b.af_sumb; + case 2: + return hw->af_sum_c.af_sumc; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Get window lum + * + * @param[in] hw Hardware instance address + * @param[in] window_id Window ID + * + * @return Window lum + */ +static inline uint32_t isp_ll_af_get_window_lum(isp_dev_t *hw, uint32_t window_id) +{ + switch (window_id) { + case 0: + return hw->af_lum_a.af_luma; + case 1: + return hw->af_lum_b.af_lumb; + case 2: + return hw->af_lum_c.af_lumc; + default: + HAL_ASSERT(false); + } +} + +/*--------------------------------------------- + AF Env Monitor +----------------------------------------------*/ +/** + * @brief Set env monitor period + * + * @param[in] hw Hardware instance address + * @param[in] period period of the env monitor, in frames + */ +static inline void isp_ll_af_env_monitor_set_period(isp_dev_t *hw, uint32_t period) +{ + hw->af_ctrl0.af_env_period = period; +} + +/** + * @brief Set env monitor mode + * + * @param[in] hw Hardware instance address + * @param[in] mode See `isp_ll_af_env_monitor_mode_t` + */ +static inline void isp_ll_af_env_monitor_set_mode(isp_dev_t *hw, isp_ll_af_env_monitor_mode_t mode) +{ + if (mode == ISP_LL_AF_ENV_MONITOR_MODE_RATIO) { + hw->af_env_user_th_sum.af_env_user_threshold_sum = 0x0; + hw->af_env_user_th_lum.af_env_user_threshold_lum = 0x0; + } + + //nothing to do to if using abs mode, it'll be enabled after `isp_ll_af_env_monitor_set_thresh()` +} + +/** + * @brief Set env monitor threshold + * + * @param[in] hw Hardware instance address + * @param[in] sum_thresh Threshold for definition + * @param[in] lum_thresh Threshold for luminance + */ +static inline void isp_ll_af_env_monitor_set_thresh(isp_dev_t *hw, uint32_t sum_thresh, uint32_t lum_thresh) +{ + HAL_ASSERT(sum_thresh != 0 || lum_thresh != 0); + + hw->af_env_user_th_sum.af_env_user_threshold_sum = sum_thresh; + hw->af_env_user_th_lum.af_env_user_threshold_lum = lum_thresh; +} + +/** + * @brief Set env monitor ratio + * + * @param[in] hw Hardware instance address + * @param[in] ratio_val Threshold for ratio + */ +static inline void isp_ll_af_env_monitor_set_ratio(isp_dev_t *hw, uint32_t ratio_val) +{ + HAL_ASSERT(hw->af_env_user_th_sum.af_env_user_threshold_sum == 0 && + hw->af_env_user_th_lum.af_env_user_threshold_lum == 0); + + hw->af_ctrl0.af_env_threshold = ratio_val; +} + +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable BF clock + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_bf_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_bf_force_on = enable; +} + +/** + * @brief Enable / Disable BF + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_bf_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.bf_en = enable; +} + +/*--------------------------------------------------------------- + CCM +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable CCM clock + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_ccm_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_ccm_force_on = enable; +} + +/** + * @brief Enable / Disable CCM + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_ccm_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.ccm_en = enable; +} + +/*--------------------------------------------------------------- + Color +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable Color clock + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_color_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_color_force_on = enable; +} + +/** + * @brief Enable / Disable Color + * + * @param[in] hw Hardware instance address + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_color_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.color_en = enable; +} + +/*--------------------------------------------------------------- + INTR +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable interrupt + * + * @param[in] hw Hardware instance address + * @param[in] mask INTR mask + * @param[in] enable Enable / disable + */ +__attribute__((always_inline)) +static inline void isp_ll_enable_intr(isp_dev_t *hw, uint32_t mask, bool enable) +{ + if (enable) { + hw->int_ena.val |= mask; + } else { + hw->int_ena.val &= ~mask; + } +} + +/** + * @brief Get interrupt status + * + * @param[in] hw Hardware instance address + * + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t isp_ll_get_intr_status(isp_dev_t *hw) +{ + return hw->int_st.val; +} + +/** + * @brief Get interrupt raw + * + * @param[in] hw Hardware instance address + * + * @return Interrupt raw + */ +__attribute__((always_inline)) +static inline uint32_t isp_ll_get_intr_raw(isp_dev_t *hw) +{ + return hw->int_raw.val; +} + +/** + * @brief Clear interrupt + * + * @param[in] hw Hardware instance address + * @param[in] mask INTR mask + */ +__attribute__((always_inline)) +static inline void isp_ll_clear_intr(isp_dev_t *hw, uint32_t mask) +{ + hw->int_clr.val = mask; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/sdmmc_ll.h b/components/hal/esp32p4/include/hal/sdmmc_ll.h index a3c5d099861..4a447433af7 100644 --- a/components/hal/esp32p4/include/hal/sdmmc_ll.h +++ b/components/hal/esp32p4/include/hal/sdmmc_ll.h @@ -245,10 +245,10 @@ static inline uint32_t sdmmc_ll_get_card_clock_div(sdmmc_dev_t *hw, uint32_t slo uint32_t card_div = 0; if (slot == 0) { - HAL_ASSERT(hw->clksrc.card0 = 0); + HAL_ASSERT(hw->clksrc.card0 == 0); card_div = hw->clkdiv.clk_divider0; } else if (slot == 1) { - HAL_ASSERT(hw->clksrc.card1 = 1); + HAL_ASSERT(hw->clksrc.card1 == 1); card_div = hw->clkdiv.clk_divider1; } else { HAL_ASSERT(false); diff --git a/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h index 398839abaf8..de642b56d69 100644 --- a/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/hp_system_reg.h" #include "soc/spi_mem_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -88,7 +89,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(SPI_MEM_XTS_PLAIN_BASE_REG(0) + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32p4/include/hal/twai_ll.h b/components/hal/esp32p4/include/hal/twai_ll.h new file mode 100644 index 00000000000..7dc878ec0c4 --- /dev/null +++ b/components/hal/esp32p4/include/hal/twai_ll.h @@ -0,0 +1,816 @@ +/* + * SPDX-FileCopyrightText: 2023 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/include/hal/readme.md + ******************************************************************************/ + +// The Lowlevel layer for TWAI + +#pragma once + +#include +#include +#include +#include "esp_assert.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/twai_types.h" +#include "soc/twai_struct.h" +#include "soc/hp_sys_clkrst_struct.h" + +#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI0) : \ + (controller_id == 1) ? (&TWAI1) : \ + (&TWAI2)) + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------- Defines and Typedefs --------------------------- */ + +#define TWAI_LL_STATUS_RBS (0x1 << 0) //Receive Buffer Status +#define TWAI_LL_STATUS_DOS (0x1 << 1) //Data Overrun Status +#define TWAI_LL_STATUS_TBS (0x1 << 2) //Transmit Buffer Status +#define TWAI_LL_STATUS_TCS (0x1 << 3) //Transmission Complete Status +#define TWAI_LL_STATUS_RS (0x1 << 4) //Receive Status +#define TWAI_LL_STATUS_TS (0x1 << 5) //Transmit Status +#define TWAI_LL_STATUS_ES (0x1 << 6) //Error Status +#define TWAI_LL_STATUS_BS (0x1 << 7) //Bus Status +#define TWAI_LL_STATUS_MS (0x1 << 8) //Miss Status + +#define TWAI_LL_INTR_RI (0x1 << 0) //Receive Interrupt +#define TWAI_LL_INTR_TI (0x1 << 1) //Transmit Interrupt +#define TWAI_LL_INTR_EI (0x1 << 2) //Error Interrupt +//Data overrun interrupt not supported in SW due to HW peculiarities +#define TWAI_LL_INTR_EPI (0x1 << 5) //Error Passive Interrupt +#define TWAI_LL_INTR_ALI (0x1 << 6) //Arbitration Lost Interrupt +#define TWAI_LL_INTR_BEI (0x1 << 7) //Bus Error Interrupt +#define TWAI_LL_INTR_BISI (0x1 << 8) //Bus Idle Status Interrupt + +/* + * The following frame structure has an NEARLY identical bit field layout to + * each byte of the TX buffer. This allows for formatting and parsing frames to + * be done outside of time critical regions (i.e., ISRs). All the ISR needs to + * do is to copy byte by byte to/from the TX/RX buffer. The two reserved bits in + * TX buffer are used in the frame structure to store the self_reception and + * single_shot flags which in turn indicate the type of transmission to execute. + */ +typedef union { + struct { + struct { + uint8_t dlc: 4; //Data length code (0 to 8) of the frame + uint8_t self_reception: 1; //This frame should be transmitted using self reception command + uint8_t single_shot: 1; //This frame should be transmitted using single shot command + uint8_t rtr: 1; //This frame is a remote transmission request + uint8_t frame_format: 1; //Format of the frame (1 = extended, 0 = standard) + }; + union { + struct { + uint8_t id[2]; //11 bit standard frame identifier + uint8_t data[8]; //Data bytes (0 to 8) + uint8_t reserved8[2]; + } standard; + struct { + uint8_t id[4]; //29 bit extended frame identifier + uint8_t data[8]; //Data bytes (0 to 8) + } extended; + }; + }; + uint8_t bytes[13]; +} __attribute__((packed)) twai_ll_frame_buffer_t; + +ESP_STATIC_ASSERT(sizeof(twai_ll_frame_buffer_t) == 13, "TX/RX buffer type should be 13 bytes"); + +/* ---------------------------- Reset and Clock Control ------------------------------ */ + +/** + * @brief Enable the bus clock for twai module + * + * @param group_id Group ID + * @param enable true to enable, false to disable + */ +static inline void twai_ll_enable_bus_clock(int group_id, bool enable) +{ + switch (group_id) + { + case 0: HP_SYS_CLKRST.soc_clk_ctrl2.reg_twai0_apb_clk_en = enable; break; + case 1: HP_SYS_CLKRST.soc_clk_ctrl2.reg_twai1_apb_clk_en = enable; break; + case 2: HP_SYS_CLKRST.soc_clk_ctrl2.reg_twai2_apb_clk_en = enable; break; + default: HAL_ASSERT(false); + } +} + +/// 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 twai_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; twai_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the twai module + * + * @param group_id Group ID + */ +static inline void twai_ll_reset_register(int group_id) +{ + switch (group_id) + { + case 0: HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai0 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai0 = 0; + break; + case 1: HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai1 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai1 = 0; + break; + case 2: HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai2 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai2 = 0; + break; + default: HAL_ASSERT(false); + } +} + +/// 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 twai_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; twai_ll_reset_register(__VA_ARGS__) + +/* ---------------------------- Peripheral Control Register ----------------- */ + +/** + * @brief Enable TWAI module clock + * + * @param group_id Group ID + * @param en true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void twai_ll_enable_clock(int group_id, bool en) +{ + switch (group_id) { + case 0: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai0_clk_en = en; break; + case 1: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai1_clk_en = en; break; + case 2: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai2_clk_en = en; break; + default: HAL_ASSERT(false); + } +} + +/// 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 twai_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; twai_ll_enable_clock(__VA_ARGS__) + +/** + * @brief Set clock source for TWAI module + * + * @param group_id Group ID + * @param clk_src Clock source + */ +__attribute__((always_inline)) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) +{ + uint32_t clk_id = 0; + + switch (clk_src) { + case TWAI_CLK_SRC_XTAL: clk_id = 0; break; +#if SOC_CLK_TREE_SUPPORTED + case TWAI_CLK_SRC_RC_FAST: clk_id = 1; break; +#endif + default: HAL_ASSERT(false); + } + + switch (group_id) { + case 0: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai0_clk_src_sel = clk_id; break; + case 1: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai1_clk_src_sel = clk_id; break; + case 2: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai2_clk_src_sel = clk_id; break; + default: HAL_ASSERT(false); + } +} + +/// 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 twai_ll_set_clock_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; twai_ll_set_clock_source(__VA_ARGS__) + +/* ---------------------------- Mode Register ------------------------------- */ +/** + * @brief Enter reset mode + * + * When in reset mode, the TWAI controller is effectively disconnected from the + * TWAI bus and will not participate in any bus activates. Reset mode is required + * in order to write the majority of configuration registers. + * + * @param hw Start address of the TWAI registers + * + * @note Reset mode is automatically entered on BUS OFF condition + */ +__attribute__((always_inline)) +static inline void twai_ll_enter_reset_mode(twai_dev_t *hw) +{ + hw->mode.reset_mode = 1; +} + +/** + * @brief Exit reset mode + * + * When not in reset mode, the TWAI controller will take part in bus activities + * (e.g., send/receive/acknowledge messages and error frames) depending on the + * operating mode. + * + * @param hw Start address of the TWAI registers + * + * @note Reset mode must be exit to initiate BUS OFF recovery + */ +__attribute__((always_inline)) +static inline void twai_ll_exit_reset_mode(twai_dev_t *hw) +{ + hw->mode.reset_mode = 0; +} + +/** + * @brief Check if in reset mode + * @param hw Start address of the TWAI registers + * @return true if in reset mode + */ +__attribute__((always_inline)) +static inline bool twai_ll_is_in_reset_mode(twai_dev_t *hw) +{ + return hw->mode.reset_mode; +} + +/** + * @brief Set operating mode of TWAI controller + * + * @param hw Start address of the TWAI registers + * @param mode Operating mode + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_mode(twai_dev_t *hw, twai_mode_t mode) +{ + if (mode == TWAI_MODE_NORMAL) { //Normal Operating mode + hw->mode.listen_only_mode = 0; + hw->mode.self_test_mode = 0; + } else if (mode == TWAI_MODE_NO_ACK) { //Self Test Mode (No Ack) + hw->mode.listen_only_mode = 0; + hw->mode.self_test_mode = 1; + } else if (mode == TWAI_MODE_LISTEN_ONLY) { //Listen Only Mode + hw->mode.listen_only_mode = 1; + hw->mode.self_test_mode = 0; + } +} + +/* --------------------------- Command Register ----------------------------- */ + +/** + * @brief Set TX command + * + * Setting the TX command will cause the TWAI controller to attempt to transmit + * the frame stored in the TX buffer. The TX buffer will be occupied (i.e., + * locked) until TX completes. + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_tx(twai_dev_t *hw) +{ + hw->cmd.tx_request = 1; +} + +/** + * @brief Set single shot TX command + * + * Similar to setting TX command, but the TWAI controller will not automatically + * retry transmission upon an error (e.g., due to an acknowledgement error). + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw) +{ + hw->cmd.val = 0x03; //Set cmd.tx_request and cmd.abort_tx simultaneously for single shot transmitting request +} + +/** + * @brief Aborts TX + * + * Frames awaiting TX will be aborted. Frames already being TX are not aborted. + * Transmission Complete Status bit is automatically set to 1. + * Similar to setting TX command, but the TWAI controller will not automatically + * retry transmission upon an error (e.g., due to acknowledge error). + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_abort_tx(twai_dev_t *hw) +{ + hw->cmd.abort_tx = 1; +} + +/** + * @brief Release RX buffer + * + * Rotates RX buffer to the next frame in the RX FIFO. + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_release_rx_buffer(twai_dev_t *hw) +{ + hw->cmd.release_buffer = 1; +} + +/** + * @brief Clear data overrun + * + * Clears the data overrun status bit + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_clear_data_overrun(twai_dev_t *hw) +{ + hw->cmd.clear_data_overrun = 1; +} + +/** + * @brief Set self reception single shot command + * + * Similar to setting TX command, but the TWAI controller also simultaneously + * receive the transmitted frame and is generally used for self testing + * purposes. The TWAI controller will not ACK the received message, so consider + * using the NO_ACK operating mode. + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw) +{ + hw->cmd.self_rx_request = 1; +} + +/** + * @brief Set self reception request command + * + * Similar to setting the self reception request, but the TWAI controller will + * not automatically retry transmission upon an error (e.g., due to and + * acknowledgement error). + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw) +{ + hw->cmd.val = 0x12; //Set cmd.self_rx_request and cmd.abort_tx simultaneously for single shot self reception request +} + +/* --------------------------- Status Register ------------------------------ */ + +/** + * @brief Get all status bits + * + * @param hw Start address of the TWAI registers + * @return Status bits + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_status(twai_dev_t *hw) +{ + return hw->status.val; +} + +/** + * @brief Check if RX FIFO overrun status bit is set + * + * @param hw Start address of the TWAI registers + * @return Overrun status bit + */ +__attribute__((always_inline)) +static inline bool twai_ll_is_fifo_overrun(twai_dev_t *hw) +{ + return hw->status.status_overrun; +} + +/** + * @brief Check if previously TX was successful + * + * @param hw Start address of the TWAI registers + * @return Whether previous TX was successful + */ +__attribute__((always_inline)) +static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw) +{ + return hw->status.status_transmission_complete; +} + +/* -------------------------- Interrupt Register ---------------------------- */ + +/** + * @brief Get currently set interrupts + * + * Reading the interrupt registers will automatically clear all interrupts + * except for the Receive Interrupt. + * + * @param hw Start address of the TWAI registers + * @return Bit mask of set interrupts + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw) +{ + return hw->interrupt_st.val; +} + +/* ----------------------- Interrupt Enable Register ------------------------ */ + +/** + * @brief Set which interrupts are enabled + * + * @param hw Start address of the TWAI registers + * @param Bit mask of interrupts to enable + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask) +{ + hw->interrupt_ena.val = intr_mask; +} + +/* ------------------------ Bus Timing Registers --------------------------- */ + +/** + * @brief Check if the brp value valid + * + * @param brp Bit rate prescaler value + * @return true or False + */ +__attribute__((always_inline)) +static inline bool twai_ll_check_brp_validation(uint32_t brp) +{ + bool valid = (brp >= SOC_TWAI_BRP_MIN) && (brp <= SOC_TWAI_BRP_MAX); + // should be an even number + valid = valid && !(brp & 0x01); + return valid; +} + +/** + * @brief Set bus timing + * + * @param hw Start address of the TWAI registers + * @param brp Baud Rate Prescaler + * @param sjw Synchronization Jump Width + * @param tseg1 Timing Segment 1 + * @param tseg2 Timing Segment 2 + * @param triple_sampling Triple Sampling enable/disable + * + * @note Must be called in reset mode + * @note ESP32C6 brp can be any even number between 2 to 32768 + */ +__attribute__((always_inline)) +static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2, bool triple_sampling) +{ + hw->bus_timing_0.baud_presc = (brp / 2) - 1; + hw->bus_timing_0.sync_jump_width = sjw - 1; + hw->bus_timing_1.time_segment1 = tseg1 - 1; + hw->bus_timing_1.time_segment2 = tseg2 - 1; + hw->bus_timing_1.time_sampling = triple_sampling; +} + +/* ----------------------------- ALC Register ------------------------------- */ + +/** + * @brief Clear Arbitration Lost Capture Register + * + * Reading the ALC register rearms the Arbitration Lost Interrupt + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw) +{ + (void)hw->arb_lost_cap.val; +} + +/* ----------------------------- ECC Register ------------------------------- */ + +/** + * @brief Clear Error Code Capture register + * + * Reading the ECC register rearms the Bus Error Interrupt + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw) +{ + (void)hw->err_code_cap.val; +} + +/* ----------------------------- EWL Register ------------------------------- */ + +/** + * @brief Set Error Warning Limit + * + * @param hw Start address of the TWAI registers + * @param ewl Error Warning Limit + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_err_warn_lim(twai_dev_t *hw, uint32_t ewl) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->err_warning_limit, err_warning_limit, ewl); +} + +/** + * @brief Get Error Warning Limit + * + * @param hw Start address of the TWAI registers + * @return Error Warning Limit + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_err_warn_lim(twai_dev_t *hw) +{ + return hw->err_warning_limit.val; +} + +/* ------------------------ RX Error Count Register ------------------------- */ + +/** + * @brief Get RX Error Counter + * + * @param hw Start address of the TWAI registers + * @return REC value + * + * @note REC is not frozen in reset mode. Listen only mode will freeze it. A BUS + * OFF condition automatically sets the REC to 0. + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_rec(twai_dev_t *hw) +{ + return hw->rx_err_cnt.val; +} + +/** + * @brief Set RX Error Counter + * + * @param hw Start address of the TWAI registers + * @param rec REC value + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_rec(twai_dev_t *hw, uint32_t rec) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_err_cnt, rx_err_cnt, rec); +} + +/* ------------------------ TX Error Count Register ------------------------- */ + +/** + * @brief Get TX Error Counter + * + * @param hw Start address of the TWAI registers + * @return TEC value + * + * @note A BUS OFF condition will automatically set this to 128 + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_tec(twai_dev_t *hw) +{ + return hw->tx_err_cnt.val; +} + +/** + * @brief Set TX Error Counter + * + * @param hw Start address of the TWAI registers + * @param tec TEC value + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_tec(twai_dev_t *hw, uint32_t tec) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_err_cnt, tx_err_cnt, tec); +} + +/* ---------------------- Acceptance Filter Registers ----------------------- */ + +/** + * @brief Set Acceptance Filter + * @param hw Start address of the TWAI registers + * @param code Acceptance Code + * @param mask Acceptance Mask + * @param single_filter Whether to enable single filter mode + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_acc_filter(twai_dev_t *hw, uint32_t code, uint32_t mask, bool single_filter) +{ + uint32_t code_swapped = HAL_SWAP32(code); + uint32_t mask_swapped = HAL_SWAP32(mask); + for (int i = 0; i < 4; i++) { + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.acr[i], byte, ((code_swapped >> (i * 8)) & 0xFF)); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.amr[i], byte, ((mask_swapped >> (i * 8)) & 0xFF)); + } + hw->mode.acceptance_filter_mode = single_filter; +} + +/* ------------------------- TX/RX Buffer Registers ------------------------- */ + +/** + * @brief Copy a formatted TWAI frame into TX buffer for transmission + * + * @param hw Start address of the TWAI registers + * @param tx_frame Pointer to formatted frame + * + * @note Call twai_ll_format_frame_buffer() to format a frame + */ +__attribute__((always_inline)) +static inline void twai_ll_set_tx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t *tx_frame) +{ + //Copy formatted frame into TX buffer + for (int i = 0; i < 13; i++) { + hw->tx_rx_buffer[i].val = tx_frame->bytes[i]; + } +} + +/** + * @brief Copy a received frame from the RX buffer for parsing + * + * @param hw Start address of the TWAI registers + * @param rx_frame Pointer to store formatted frame + * + * @note Call twai_ll_parse_frame_buffer() to parse the formatted frame + */ +__attribute__((always_inline)) +static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t *rx_frame) +{ + //Copy RX buffer registers into frame + for (int i = 0; i < 13; i++) { + rx_frame->bytes[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->tx_rx_buffer[i], byte); + } +} + +/** + * @brief Format contents of a TWAI frame into layout of TX Buffer + * + * This function encodes a message into a frame structure. The frame structure + * has an identical layout to the TX buffer, allowing the frame structure to be + * directly copied into TX buffer. + * + * @param[in] 11bit or 29bit ID + * @param[in] dlc Data length code + * @param[in] data Pointer to an 8 byte array containing data. NULL if no data + * @param[in] format Type of TWAI frame + * @param[in] single_shot Frame will not be retransmitted on failure + * @param[in] self_rx Frame will also be simultaneously received + * @param[out] tx_frame Pointer to store formatted frame + */ +__attribute__((always_inline)) +static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const uint8_t *data, uint32_t flags, twai_ll_frame_buffer_t *tx_frame) +{ + bool is_extd = flags & TWAI_MSG_FLAG_EXTD; + bool is_rtr = flags & TWAI_MSG_FLAG_RTR; + + //Set frame information + tx_frame->dlc = dlc; + tx_frame->frame_format = is_extd; + tx_frame->rtr = is_rtr; + tx_frame->self_reception = (flags & TWAI_MSG_FLAG_SELF) ? 1 : 0; + tx_frame->single_shot = (flags & TWAI_MSG_FLAG_SS) ? 1 : 0; + + //Set ID. The ID registers are big endian and left aligned, therefore a bswap will be required + if (is_extd) { + uint32_t id_temp = HAL_SWAP32((id & TWAI_EXTD_ID_MASK) << 3); //((id << 3) >> 8*(3-i)) + for (int i = 0; i < 4; i++) { + tx_frame->extended.id[i] = (id_temp >> (8 * i)) & 0xFF; + } + } else { + uint32_t id_temp = HAL_SWAP16((id & TWAI_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i)) + for (int i = 0; i < 2; i++) { + tx_frame->standard.id[i] = (id_temp >> (8 * i)) & 0xFF; + } + } + + uint8_t *data_buffer = (is_extd) ? tx_frame->extended.data : tx_frame->standard.data; + if (!is_rtr) { //Only copy data if the frame is a data frame (i.e not a remote frame) + for (int i = 0; (i < dlc) && (i < TWAI_FRAME_MAX_DLC); i++) { + data_buffer[i] = data[i]; + } + } +} + +/** + * @brief Parse formatted TWAI frame (RX Buffer Layout) into its constituent contents + * + * @param[in] rx_frame Pointer to formatted frame + * @param[out] id 11 or 29bit ID + * @param[out] dlc Data length code + * @param[out] data Data. Left over bytes set to 0. + * @param[out] format Type of TWAI frame + */ +__attribute__((always_inline)) +static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame, uint32_t *id, uint8_t *dlc, uint8_t *data, uint32_t *flags) +{ + //Copy frame information + *dlc = rx_frame->dlc; + uint32_t flags_temp = 0; + flags_temp |= (rx_frame->frame_format) ? TWAI_MSG_FLAG_EXTD : 0; + flags_temp |= (rx_frame->rtr) ? TWAI_MSG_FLAG_RTR : 0; + flags_temp |= (rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_MSG_FLAG_DLC_NON_COMP : 0; + *flags = flags_temp; + + //Copy ID. The ID registers are big endian and left aligned, therefore a bswap will be required + if (rx_frame->frame_format) { + uint32_t id_temp = 0; + for (int i = 0; i < 4; i++) { + id_temp |= rx_frame->extended.id[i] << (8 * i); + } + id_temp = HAL_SWAP32(id_temp) >> 3; //((byte[i] << 8*(3-i)) >> 3) + *id = id_temp & TWAI_EXTD_ID_MASK; + } else { + uint32_t id_temp = 0; + for (int i = 0; i < 2; i++) { + id_temp |= rx_frame->standard.id[i] << (8 * i); + } + id_temp = HAL_SWAP16(id_temp) >> 5; //((byte[i] << 8*(1-i)) >> 5) + *id = id_temp & TWAI_STD_ID_MASK; + } + + uint8_t *data_buffer = (rx_frame->frame_format) ? rx_frame->extended.data : rx_frame->standard.data; + //Only copy data if the frame is a data frame (i.e. not a remote frame) + int data_length = (rx_frame->rtr) ? 0 : ((rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_FRAME_MAX_DLC : rx_frame->dlc); + for (int i = 0; i < data_length; i++) { + data[i] = data_buffer[i]; + } + //Set remaining bytes of data to 0 + for (int i = data_length; i < TWAI_FRAME_MAX_DLC; i++) { + data[i] = 0; + } +} + +/* ----------------------- RX Message Count Register ------------------------ */ + +/** + * @brief Get RX Message Counter + * + * @param hw Start address of the TWAI registers + * @return RX Message Counter + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_rx_msg_count(twai_dev_t *hw) +{ + return hw->rx_message_counter.val; +} + +/* ------------------------- Clock Divider Register ------------------------- */ + +/** + * @brief Set CLKOUT Divider and enable/disable + * + * Configure CLKOUT. CLKOUT is a pre-scaled version of peripheral source clock. Divider can be + * 1, or any even number from 2 to 490. Set the divider to 0 to disable CLKOUT. + * + * @param hw Start address of the TWAI registers + * @param divider Divider for CLKOUT (any even number from 2 to 490). Set to 0 to disable CLKOUT + */ +__attribute__((always_inline)) +static inline void twai_ll_set_clkout(twai_dev_t *hw, uint32_t divider) +{ + if (divider >= 2 && divider <= 490) { + hw->clock_divider.clock_off = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, (divider / 2) - 1); + } else if (divider == 1) { + //Setting the divider reg to max value (255) means a divider of 1 + hw->clock_divider.clock_off = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 255); + } else { + hw->clock_divider.clock_off = 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 0); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index 2985503a52c..1344a64970d 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -39,6 +39,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) /*--------------------------------------------------------------- DMA @@ -848,7 +849,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * - 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_11) gives full-scale voltage 3.9V (see note below) + * - 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.) @@ -860,7 +861,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * - 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_11) between 150 to 2450mV + * - 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. * diff --git a/components/hal/esp32s2/include/hal/clk_tree_ll.h b/components/hal/esp32s2/include/hal/clk_tree_ll.h index b0505b1ce28..70aa45d34ef 100644 --- a/components/hal/esp32s2/include/hal/clk_tree_ll.h +++ b/components/hal/esp32s2/include/hal/clk_tree_ll.h @@ -216,7 +216,7 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S; /* If xtal xpd software control is on */ bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S; - // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled + // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disabled bool enabled = !xtal_xpd_sw || xtal_xpd_st; return enabled; } diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index 80de8598877..8eaf403644a 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -351,6 +351,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { if (gpio_num < 32) { diff --git a/components/hal/esp32s2/include/hal/i2c_ll.h b/components/hal/esp32s2/include/hal/i2c_ll.h index 07fe5b419dc..f7942d94013 100644 --- a/components/hal/esp32s2/include/hal/i2c_ll.h +++ b/components/hal/esp32s2/include/hal/i2c_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ #include "soc/i2c_periph.h" #include "soc/i2c_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/system_reg.h" #include "hal/i2c_types.h" #include "esp_attr.h" #include "hal/misc.h" @@ -44,24 +45,29 @@ typedef union { #define I2C_LL_CMD_END 4 /*!slave_addr.en_10bit = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; - uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) || 0x78; - hw->slave_addr.addr = addr_14_7 || addr_6_0; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; + uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; + hw->slave_addr.addr = addr_14_7 | addr_6_0; } else { hw->slave_addr.addr = slave_addr; } @@ -356,6 +376,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rx_fifo_wm_thrhd = full_thr; } @@ -698,6 +719,51 @@ static inline void i2c_ll_update(i2c_dev_t *hw) ;// ESP32S2 do not support } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + if (i2c_port == 0) { + uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); + reg_val &= ~DPORT_I2C_EXT0_CLK_EN_M; + reg_val |= enable << DPORT_I2C_EXT0_CLK_EN_S; + WRITE_PERI_REG(DPORT_PERIP_CLK_EN0_REG, reg_val); + } else if (i2c_port == 1) { + uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); + reg_val &= ~DPORT_I2C_EXT1_CLK_EN_M; + reg_val |= enable << DPORT_I2C_EXT1_CLK_EN_S; + WRITE_PERI_REG(DPORT_PERIP_CLK_EN0_REG, reg_val); + } +} + +/// 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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + if (i2c_port == 0) { + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, DPORT_I2C_EXT0_RST_M); + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, 0); + } else if (i2c_port == 1) { + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, DPORT_I2C_EXT1_RST_M); + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, 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_ATOMIC_ENV variable in advance +#define i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Set whether slave should auto start, or only start with start signal from master * diff --git a/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h index 34d38742cfe..529fb990076 100644 --- a/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/system_reg.h" #include "soc/hwcrypto_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -93,7 +94,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(AES_XTS_PLAIN_BASE + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32s2/include/hal/twai_ll.h b/components/hal/esp32s2/include/hal/twai_ll.h index 10d4d8bc4d6..3d05c5b0bec 100644 --- a/components/hal/esp32s2/include/hal/twai_ll.h +++ b/components/hal/esp32s2/include/hal/twai_ll.h @@ -127,25 +127,25 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - (void)hw; + (void)group_id; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { - (void)hw; + (void)group_id; HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB); } diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index f647f4c677b..7e0f405e1fc 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -42,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) /*--------------------------------------------------------------- DMA @@ -1108,7 +1109,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * - 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_11) gives full-scale voltage 3.9V (see note below) + * - 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.) @@ -1120,7 +1121,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * - 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_11) between 150 to 2450mV + * - 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. * diff --git a/components/hal/esp32s3/include/hal/clk_tree_ll.h b/components/hal/esp32s3/include/hal/clk_tree_ll.h index 369a4a2ee81..a3a23c41e2a 100644 --- a/components/hal/esp32s3/include/hal/clk_tree_ll.h +++ b/components/hal/esp32s3/include/hal/clk_tree_ll.h @@ -122,7 +122,7 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S; /* If xtal xpd software control is on */ bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S; - // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled + // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disabled bool enabled = !xtal_xpd_sw || xtal_xpd_st; return enabled; } diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index 394d7681d1a..9fe90040f4b 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -367,6 +367,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { if (gpio_num < 32) { diff --git a/components/hal/esp32s3/include/hal/i2c_ll.h b/components/hal/esp32s3/include/hal/i2c_ll.h index 8c1b862bf74..053ae83420f 100644 --- a/components/hal/esp32s3/include/hal/i2c_ll.h +++ b/components/hal/esp32s3/include/hal/i2c_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include "soc/soc_caps.h" #include "soc/i2c_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/i2c_types.h" #include "esp_attr.h" #include "esp_assert.h" @@ -48,18 +49,23 @@ typedef union { #define I2C_LL_CMD_END 4 /*!scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); + clk_cal->scl_wait_high = (bus_freq >= 80 * 1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high; clk_cal->sda_hold = half_cycle / 4; clk_cal->sda_sample = half_cycle / 2; @@ -120,6 +126,46 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + if (i2c_port == 0) { + SYSTEM.perip_clk_en0.i2c_ext0_clk_en = enable; + } else if (i2c_port == 1) { + SYSTEM.perip_clk_en0.i2c_ext1_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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + if (i2c_port == 0) { + SYSTEM.perip_rst_en0.i2c_ext0_rst = 1; + SYSTEM.perip_rst_en0.i2c_ext0_rst = 0; + } else if (i2c_port == 1) { + SYSTEM.perip_rst_en0.i2c_ext1_rst = 1; + SYSTEM.perip_rst_en0.i2c_ext1_rst = 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_ATOMIC_ENV variable in advance +#define i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Configure the I2C bus timing related register. * @@ -288,6 +334,36 @@ static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_e hw->ctr.addr_broadcasting_en = broadcast_en; } +/** + * @brief Get the cause of SCL clock stretching in slave mode + * + * @param hw Beginning address of the peripheral registers + * @param stretch_cause Pointer to stretch cause in the slave mode. + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) +{ + switch (hw->sr.stretch_cause) { + case 0: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; + break; + case 1: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY; + break; + case 2: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL; + break; + case 3: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK; + break; + default: + HAL_ASSERT(false); + break; + } +} + /** * @brief Configure I2C slave address * @@ -301,7 +377,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo { hw->slave_addr.addr_10bit_en = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; hw->slave_addr.slave_addr = addr_14_7 | addr_6_0; hw->ctr.addr_10bit_rw_check_en = addr_10bit_en; @@ -393,6 +469,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rxfifo_wm_thrhd = full_thr; } @@ -556,7 +633,7 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h __attribute__((always_inline)) static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len) { - for (int i = 0; i< len; i++) { + for (int i = 0; i < len; i++) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]); } } @@ -573,7 +650,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_ __attribute__((always_inline)) static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata); } } @@ -585,14 +662,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -603,15 +677,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } diff --git a/components/hal/esp32s3/include/hal/sdmmc_ll.h b/components/hal/esp32s3/include/hal/sdmmc_ll.h index 4581aeb9924..101bb970fc2 100644 --- a/components/hal/esp32s3/include/hal/sdmmc_ll.h +++ b/components/hal/esp32s3/include/hal/sdmmc_ll.h @@ -233,10 +233,10 @@ static inline uint32_t sdmmc_ll_get_card_clock_div(sdmmc_dev_t *hw, uint32_t slo uint32_t card_div = 0; if (slot == 0) { - HAL_ASSERT(hw->clksrc.card0 = 0); + HAL_ASSERT(hw->clksrc.card0 == 0); card_div = hw->clkdiv.div0; } else if (slot == 1) { - HAL_ASSERT(hw->clksrc.card1 = 1); + HAL_ASSERT(hw->clksrc.card1 == 1); card_div = hw->clkdiv.div1; } else { HAL_ASSERT(false); diff --git a/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h index cac478ee514..dae3528dd9d 100644 --- a/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/system_reg.h" #include "soc/hwcrypto_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(AES_XTS_PLAIN_BASE + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32s3/include/hal/twai_ll.h b/components/hal/esp32s3/include/hal/twai_ll.h index fc23d354851..7f921438fa1 100644 --- a/components/hal/esp32s3/include/hal/twai_ll.h +++ b/components/hal/esp32s3/include/hal/twai_ll.h @@ -124,25 +124,25 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - (void)hw; + (void)group_id; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { - (void)hw; + (void)group_id; HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB); } diff --git a/components/hal/i2c_hal.c b/components/hal/i2c_hal.c index 6a44f13939e..2b1248f622a 100644 --- a/components/hal/i2c_hal.c +++ b/components/hal/i2c_hal.c @@ -22,9 +22,8 @@ void i2c_hal_slave_init(i2c_hal_context_t *hal) } #endif -void i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq) +void _i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq) { - i2c_ll_set_source_clk(hal->dev, src_clk); i2c_hal_clk_config_t clk_cal = {0}; i2c_ll_master_cal_bus_clk(source_freq, scl_freq, &clk_cal); i2c_ll_master_set_bus_timing(hal->dev, &clk_cal); @@ -45,7 +44,7 @@ void i2c_hal_master_init(i2c_hal_context_t *hal) i2c_ll_rxfifo_rst(hal->dev); } -void i2c_hal_init(i2c_hal_context_t *hal, int i2c_port) +void _i2c_hal_init(i2c_hal_context_t *hal, int i2c_port) { if (hal->dev == NULL) { hal->dev = I2C_LL_GET_HW(i2c_port); @@ -53,7 +52,7 @@ void i2c_hal_init(i2c_hal_context_t *hal, int i2c_port) i2c_ll_enable_controller_clock(hal->dev, true); } -void i2c_hal_deinit(i2c_hal_context_t *hal) +void _i2c_hal_deinit(i2c_hal_context_t *hal) { i2c_ll_enable_controller_clock(hal->dev, false); hal->dev = NULL; diff --git a/components/hal/i2s_hal.c b/components/hal/i2s_hal.c index ae00f259ee9..56e7e225d5b 100644 --- a/components/hal/i2s_hal.c +++ b/components/hal/i2s_hal.c @@ -255,7 +255,7 @@ void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_ha #if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER uint32_t param0; uint32_t param5; - s_i2s_hal_get_cut_off_coef(slot_cfg->pdm_rx.hp_cut_off_freq_hz, ¶m0, ¶m5); + s_i2s_hal_get_cut_off_coef(slot_cfg->pdm_rx.hp_cut_off_freq_hzx10, ¶m0, ¶m5); i2s_ll_rx_enable_pdm_hp_filter(hal->dev, slot_cfg->pdm_rx.hp_en); i2s_ll_rx_set_pdm_hp_filter_param0(hal->dev, param0); i2s_ll_rx_set_pdm_hp_filter_param5(hal->dev, param5); diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index ede6325c9ae..063e3ab3c42 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -45,9 +45,10 @@ typedef enum { */ typedef enum { ADC_ATTEN_DB_0 = 0, /// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @background + * + * Color Space: a specific representation of colors, e.g. RGB, YUV, etc. + * Color Pixel Format: a specific pixel format of a certain color space, e.g. RGB565, YUV422, etc. + */ + +/*--------------------------------------------------------------- + Color Space +---------------------------------------------------------------*/ +/** + * @brief Color Space + */ +typedef enum { + COLOR_SPACE_RAW, ///< Color space raw + COLOR_SPACE_RGB, ///< Color space rgb + COLOR_SPACE_YUV, ///< Color space yuv + COLOR_SPACE_GRAY, ///< Color space gray +} color_space_t; + +/*--------------------------------------------------------------- + Color Space Format +---------------------------------------------------------------*/ +/** + * @brief Raw Format + */ +typedef enum { + COLOR_PIXEL_RAW8, ///< 8 bits per pixel + COLOR_PIXEL_RAW10, ///< 10 bits per pixel + COLOR_PIXEL_RAW12, ///< 12 bits per pixel +} color_pixel_raw_format_t; + +/** + * @brief RGB Format + */ +typedef enum { + COLOR_PIXEL_RGB888, ///< 24 bits, 8 bits per R/G/B value + COLOR_PIXEL_RGB565, ///< 16 bits, 5 bits per R/B value, 6 bits for G value +} color_pixel_rgb_format_t; + +/** + * @brief YUV Format + */ +typedef enum { + COLOR_PIXEL_YUV444, ///< 24 bits, 8 bits per Y/U/V value + COLOR_PIXEL_YUV422, ///< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels + COLOR_PIXEL_YUV420, ///< 12 bits, 8-bit Y per pixel, 8-bit U and V per four pixels +} color_pixel_yuv_format_t; + +/** + * @brief Gray Format + */ +typedef enum { + COLOR_PIXEL_GRAY4, ///< 4 bits, grayscale + COLOR_PIXEL_GRAY8, ///< 8 bits, grayscale +} color_pixel_gray_format_t; + +/*--------------------------------------------------------------- + Color Space Struct Type +---------------------------------------------------------------*/ +///< Bitwidth of the `color_space_format_t:color_space` field +#define COLOR_SPACE_BITWIDTH 8 +///< Bitwidth of the `color_space_format_t:pixel_format` field +#define COLOR_PIXEL_FORMAT_BITWIDTH 24 +///< Helper to get `color_space_format_t:color_space` from its `color_space_pixel_format_t:color_type_id` +#define COLOR_SPACE_TYPE(color_type_id) (((color_type_id) >> COLOR_PIXEL_FORMAT_BITWIDTH) & ((1 << COLOR_SPACE_BITWIDTH) - 1)) +///< Helper to get `color_space_format_t:pixel_format` from its `color_space_pixel_format_t:color_type_id` +#define COLOR_PIXEL_FORMAT(color_type_id) ((color_type_id) & ((1 << COLOR_PIXEL_FORMAT_BITWIDTH) - 1)) + +/** + * @brief Color Space Info Structure + */ +typedef union { + struct { + uint32_t pixel_format: COLOR_PIXEL_FORMAT_BITWIDTH; ///< Format of a certain color space type + uint32_t color_space: COLOR_SPACE_BITWIDTH; ///< Color space type + }; + uint32_t color_type_id; ///< Unique type of a certain color pixel format +} color_space_pixel_format_t; + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/i2c_hal.h b/components/hal/include/hal/i2c_hal.h index 797bf6e8ab7..ed8a73f7485 100644 --- a/components/hal/include/hal/i2c_hal.h +++ b/components/hal/include/hal/i2c_hal.h @@ -83,7 +83,15 @@ void i2c_hal_master_init(i2c_hal_context_t *hal); * * @return None */ -void i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq); +void _i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq); + +#if SOC_PERIPH_CLK_CTRL_SHARED +/// 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 i2c_hal_set_bus_timing(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; _i2c_hal_set_bus_timing(__VA_ARGS__);} while(0) +#else +#define i2c_hal_set_bus_timing(...) _i2c_hal_set_bus_timing(__VA_ARGS__) +#endif /** * @brief I2C hardware FSM reset @@ -120,14 +128,30 @@ void i2c_hal_master_handle_rx_event(i2c_hal_context_t *hal, i2c_intr_event_t *ev * @param hal Context of the HAL * @param i2c_port I2C port number. */ -void i2c_hal_init(i2c_hal_context_t *hal, int i2c_port); +void _i2c_hal_init(i2c_hal_context_t *hal, int i2c_port); + +#if SOC_PERIPH_CLK_CTRL_SHARED +/// 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 i2c_hal_init(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; _i2c_hal_init(__VA_ARGS__);} while(0) +#else +#define i2c_hal_init(...) _i2c_hal_init(__VA_ARGS__) +#endif /** * @brief Deinit I2C hal layer * * @param hal Context of the HAL */ -void i2c_hal_deinit(i2c_hal_context_t *hal); +void _i2c_hal_deinit(i2c_hal_context_t *hal); + +#if SOC_PERIPH_CLK_CTRL_SHARED +/// 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 i2c_hal_deinit(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; _i2c_hal_deinit(__VA_ARGS__);} while(0) +#else +#define i2c_hal_deinit(...) _i2c_hal_deinit(__VA_ARGS__) +#endif /** * @brief Start I2C master transaction diff --git a/components/hal/include/hal/i2c_types.h b/components/hal/include/hal/i2c_types.h index ef66199ce3c..fba2ad0bad0 100644 --- a/components/hal/include/hal/i2c_types.h +++ b/components/hal/include/hal/i2c_types.h @@ -87,6 +87,16 @@ typedef enum { I2C_MASTER_ACK_MAX, } i2c_ack_type_t; +/** + * @brief Enum for I2C slave stretch causes + */ +typedef enum { + I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH = 0, /*!< Stretching SCL low when the slave is read by the master and the address just matched */ + I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY = 1, /*!< Stretching SCL low when TX FIFO is empty in slave mode */ + I2C_SLAVE_STRETCH_CAUSE_RX_FULL = 2, /*!< Stretching SCL low when RX FIFO is full in slave mode */ + I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK = 3, /*!< Stretching SCL low when slave sending ACK */ +} i2c_slave_stretch_cause_t; + #if SOC_I2C_SUPPORTED /** * @brief I2C group clock source diff --git a/components/hal/include/hal/i2s_hal.h b/components/hal/include/hal/i2s_hal.h index 02e32569493..2be2180b9d0 100644 --- a/components/hal/include/hal/i2s_hal.h +++ b/components/hal/include/hal/i2s_hal.h @@ -94,7 +94,7 @@ typedef struct { i2s_pdm_slot_mask_t slot_mask; /*!< Choose the slots to activate */ #if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER bool hp_en; /*!< High pass filter enable */ - float hp_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ + uint32_t hp_cut_off_freq_hzx10; /*!< High pass filter cut-off frequency times 10, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ uint32_t amplify_num; /*!< The amplification number of the final conversion result */ #endif // SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER diff --git a/components/hal/include/hal/isp_hal.h b/components/hal/include/hal/isp_hal.h new file mode 100644 index 00000000000..80ea6db9de5 --- /dev/null +++ b/components/hal/include/hal/isp_hal.h @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2023 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 + ******************************************************************************/ + +#pragma once + +#include +#include "hal/isp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Context that should be maintained by both the driver and the HAL + */ +typedef struct { + void *hw; ///< Beginning address of the ISP registers +} isp_hal_context_t; + +/** + * @brief Init the ISP hal and set the ISP to the default configuration. + * + * @note This function should be called first before other hal layer function is called. + * + * @param[in] hal Context of the HAL layer + * @param[in] isp_id ISP ID + */ +void isp_hal_init(isp_hal_context_t *hal, int isp_id); + + +/*--------------------------------------------------------------- + AF +---------------------------------------------------------------*/ +/** + * @brief Configure AF window + * + * @param[in] hal Context of the HAL layer + * @param[in] window_id Window ID + * @param[in] window Window info, see `isp_af_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); + +/*--------------------------------------------------------------- + INTR +---------------------------------------------------------------*/ +/** + * @brief Clear ISP HW intr event + * + * @param[in] hal Context of the HAL layer + * @param[in] mask HW event mask + */ +uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask); + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/isp_types.h b/components/hal/include/hal/isp_types.h new file mode 100644 index 00000000000..27d7e0bc129 --- /dev/null +++ b/components/hal/include/hal/isp_types.h @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2023 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" + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------- + Misc +---------------------------------------------------------------*/ +#if SOC_ISP_SUPPORTED +typedef soc_periph_isp_clk_src_t isp_clk_src_t; ///< Clock source type of ISP +#else +typedef int isp_clk_src_t; ///< Default type +#endif + +/** + * @brief ISP Input Source + */ +typedef enum { + ISP_INPUT_DATA_SOURCE_CSI, ///< Input data from CSI + ISP_INPUT_DATA_SOURCE_DVP, ///< Input data from DVP + ISP_INPUT_DATA_SOURCE_DWGDMA, ///< Input data from DW-GDMA +} isp_input_data_source_t; + +/** + * @brief ISP Color Type + */ +typedef enum { + ISP_COLOR_RAW8 = (COLOR_SPACE_RAW << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RAW8, ///< RAW8 + ISP_COLOR_RAW10 = (COLOR_SPACE_RAW << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RAW10, ///< RAW10 + ISP_COLOR_RAW12 = (COLOR_SPACE_RAW << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RAW12, ///< RAW12 + ISP_COLOR_RGB888 = (COLOR_SPACE_RGB << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RGB888, ///< RGB888 + ISP_COLOR_RGB565 = (COLOR_SPACE_RGB << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RGB565, ///< RGB565 + ISP_COLOR_YUV422 = (COLOR_SPACE_YUV << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_YUV422, ///< YUV422 + ISP_COLOR_YUV420 = (COLOR_SPACE_YUV << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_YUV420, ///< YUV420 +} isp_color_t; + +/*--------------------------------------------------------------- + AF +---------------------------------------------------------------*/ +/** + * @brief ISP AF window + */ +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; + +/** + * @brief ISP AF result + */ +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; + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/spi_hal.h b/components/hal/include/hal/spi_hal.h index 93a284f218e..9fbff296eca 100644 --- a/components/hal/include/hal/spi_hal.h +++ b/components/hal/include/hal/spi_hal.h @@ -30,6 +30,7 @@ #include "soc/soc_caps.h" #include "hal/spi_types.h" #include "hal/dma_types.h" +#include "soc/gdma_channel.h" #if SOC_GPSPI_SUPPORTED #include "hal/spi_ll.h" #endif diff --git a/components/hal/include/hal/spi_slave_hal.h b/components/hal/include/hal/spi_slave_hal.h index 4ef6e26db19..30b8f2fbc27 100644 --- a/components/hal/include/hal/spi_slave_hal.h +++ b/components/hal/include/hal/spi_slave_hal.h @@ -27,8 +27,9 @@ #include "sdkconfig.h" #include "esp_types.h" #include "soc/soc_caps.h" +#include "hal/dma_types.h" +#include "soc/gdma_channel.h" #if SOC_GPSPI_SUPPORTED -#include "soc/lldesc.h" #include "hal/spi_ll.h" #endif @@ -37,6 +38,11 @@ extern "C" { #endif #if SOC_GPSPI_SUPPORTED +#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) +typedef dma_descriptor_align4_t spi_dma_desc_t; +#else +typedef dma_descriptor_align8_t spi_dma_desc_t; +#endif /** * Context that should be maintained by both the driver and the HAL. @@ -47,11 +53,11 @@ typedef struct { spi_dma_dev_t *dma_in; ///< Address of the DMA peripheral registers which stores the data received from a peripheral into RAM. spi_dma_dev_t *dma_out; ///< Address of the DMA peripheral registers which transmits the data from RAM to a peripheral. /* should be configured by driver at initialization */ - lldesc_t *dmadesc_rx; /**< Array of DMA descriptor used by the TX DMA. + spi_dma_desc_t *dmadesc_rx; /**< Array of DMA descriptor used by the TX DMA. * The amount should be larger than dmadesc_n. The driver should ensure that * the data to be sent is shorter than the descriptors can hold. */ - lldesc_t *dmadesc_tx; /**< Array of DMA descriptor used by the RX DMA. + spi_dma_desc_t *dmadesc_tx; /**< Array of DMA descriptor used by the RX DMA. * The amount should be larger than dmadesc_n. The driver should ensure that * the data to be sent is shorter than the descriptors can hold. */ diff --git a/components/hal/isp_hal.c b/components/hal/isp_hal.c new file mode 100644 index 00000000000..6fb72413a99 --- /dev/null +++ b/components/hal/isp_hal.c @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#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" + +/** + * ISP HAL layer + */ +void isp_hal_init(isp_hal_context_t *hal, int isp_id) +{ + //ISP hardware instance + hal->hw = ISP_LL_GET_HW(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) +{ + 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); +} + +void isp_hal_af_get_oneshot_result(const isp_hal_context_t *hal, isp_af_result_t *out_res) +{ + 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); + } +} + + +/*--------------------------------------------------------------- + INTR, put in iram +---------------------------------------------------------------*/ +uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask) +{ + uint32_t triggered_events = isp_ll_get_intr_status(hal->hw) & mask; + + if (triggered_events) { + isp_ll_clear_intr(hal->hw, triggered_events); + } + + return triggered_events; +} diff --git a/components/hal/platform_port/include/hal/misc.h b/components/hal/platform_port/include/hal/misc.h index c6e50ad8c31..29ef91136bd 100644 --- a/components/hal/platform_port/include/hal/misc.h +++ b/components/hal/platform_port/include/hal/misc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -66,11 +66,7 @@ extern "C" { * @param len The number of bytes to be copied * @return a pointer to destination */ -__attribute__((always_inline)) static inline void *hal_memcpy(void *dst_mem, const void *src_mem, size_t len) -{ - asm("" : "+r"(dst_mem), "+r"(src_mem)); - return memcpy(dst_mem, src_mem, len); -} +#define hal_memcpy(dst_mem, src_mem, len) (__extension__({memcpy(dst_mem, src_mem, len);})) /** * @brief Sets the first num bytes of the block of memory pointed by ptr to the specified value @@ -82,11 +78,7 @@ __attribute__((always_inline)) static inline void *hal_memcpy(void *dst_mem, con * @param len The number of bytes to be copied * @return a pointer to the memory area */ -__attribute__((always_inline)) static inline void *hal_memset(void *dst_mem, int value, size_t len) -{ - asm("" : "+r"(dst_mem)); - return memset(dst_mem, value, len); -} +#define hal_memset(dst_mem, value, len) (__extension__({memset(dst_mem, value, len);})) #ifdef __cplusplus } diff --git a/components/hal/spi_hal.c b/components/hal/spi_hal.c index d928fe997e4..25b77b8ef6b 100644 --- a/components/hal/spi_hal.c +++ b/components/hal/spi_hal.c @@ -71,7 +71,9 @@ void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config spi_ll_set_mosi_free_level(hw, 0); #endif spi_ll_master_init(hw); - s_spi_hal_dma_init_config(hal); + if (config->dma_enabled) { + s_spi_hal_dma_init_config(hal); + } //Force a transaction done interrupt. This interrupt won't fire yet because //we initialized the SPI interrupt as disabled. This way, we can just diff --git a/components/hal/spi_slave_hal.c b/components/hal/spi_slave_hal.c index 7c437a0b3fa..c53bd600cad 100644 --- a/components/hal/spi_slave_hal.c +++ b/components/hal/spi_slave_hal.c @@ -35,13 +35,14 @@ static void s_spi_slave_hal_dma_init_config(const spi_slave_hal_context_t *hal) void spi_slave_hal_init(spi_slave_hal_context_t *hal, const spi_slave_hal_config_t *hal_config) { - memset(hal, 0, sizeof(spi_slave_hal_context_t)); spi_dev_t *hw = SPI_LL_GET_HW(hal_config->host_id); hal->hw = hw; hal->dma_in = hal_config->dma_in; hal->dma_out = hal_config->dma_out; - s_spi_slave_hal_dma_init_config(hal); + if (hal->use_dma) { + s_spi_slave_hal_dma_init_config(hal); + } spi_ll_slave_init(hal->hw); //Force a transaction done interrupt. This interrupt won't fire yet because we initialized the SPI interrupt as diff --git a/components/hal/spi_slave_hal_iram.c b/components/hal/spi_slave_hal_iram.c index 07c58d4045e..0d0dcef6df7 100644 --- a/components/hal/spi_slave_hal_iram.c +++ b/components/hal/spi_slave_hal_iram.c @@ -45,13 +45,49 @@ void spi_slave_hal_user_start(const spi_slave_hal_context_t *hal) spi_ll_user_start(hal->hw); } +#if SOC_NON_CACHEABLE_OFFSET +#define ADDR_DMA_2_CPU(addr) ((typeof(addr))((uint32_t)(addr) + SOC_NON_CACHEABLE_OFFSET)) +#define ADDR_CPU_2_DMA(addr) ((typeof(addr))((uint32_t)(addr) - SOC_NON_CACHEABLE_OFFSET)) +#else +#define ADDR_DMA_2_CPU(addr) (addr) +#define ADDR_CPU_2_DMA(addr) (addr) +#endif + +static void s_spi_slave_hal_dma_desc_setup_link(spi_dma_desc_t *dmadesc, const void *data, int len, bool is_rx) +{ + dmadesc = ADDR_DMA_2_CPU(dmadesc); + int n = 0; + while (len) { + int dmachunklen = len; + if (dmachunklen > DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) { + dmachunklen = DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; + } + if (is_rx) { + //Receive needs DMA length rounded to next 32-bit boundary + dmadesc[n].dw0.size = (dmachunklen + 3) & (~3); + } else { + dmadesc[n].dw0.size = dmachunklen; + dmadesc[n].dw0.length = dmachunklen; + } + dmadesc[n].buffer = (uint8_t *)data; + dmadesc[n].dw0.suc_eof = 0; + dmadesc[n].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + dmadesc[n].next = ADDR_CPU_2_DMA(&dmadesc[n + 1]); + len -= dmachunklen; + data += dmachunklen; + n++; + } + dmadesc[n - 1].dw0.suc_eof = 1; //Mark last DMA desc as end of stream. + dmadesc[n - 1].next = NULL; +} + void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal) { if (hal->use_dma) { //Fill DMA descriptors if (hal->rx_buffer) { - lldesc_setup_link(hal->dmadesc_rx, hal->rx_buffer, ((hal->bitlen + 7) / 8), true); + s_spi_slave_hal_dma_desc_setup_link(hal->dmadesc_rx, hal->rx_buffer, ((hal->bitlen + 7) / 8), true); //reset dma inlink, this should be reset before spi related reset spi_dma_ll_rx_reset(hal->dma_in, hal->rx_dma_chan); @@ -60,10 +96,10 @@ void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal) spi_ll_infifo_full_clr(hal->hw); spi_ll_dma_rx_enable(hal->hw, 1); - spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, hal->dmadesc_rx); + spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, (lldesc_t *)hal->dmadesc_rx); } if (hal->tx_buffer) { - lldesc_setup_link(hal->dmadesc_tx, hal->tx_buffer, (hal->bitlen + 7) / 8, false); + s_spi_slave_hal_dma_desc_setup_link(hal->dmadesc_tx, hal->tx_buffer, (hal->bitlen + 7) / 8, false); //reset dma outlink, this should be reset before spi related reset spi_dma_ll_tx_reset(hal->dma_out, hal->tx_dma_chan); @@ -72,7 +108,7 @@ void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal) spi_ll_outfifo_empty_clr(hal->hw); spi_ll_dma_tx_enable(hal->hw, 1); - spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, hal->dmadesc_tx); + spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, (lldesc_t *)hal->dmadesc_tx); } } else { //No DMA. Turn off SPI and copy data to transmit buffers. @@ -125,8 +161,8 @@ bool spi_slave_hal_dma_need_reset(const spi_slave_hal_context_t *hal) //In case CS goes high too soon, the transfer is aborted while the DMA channel still thinks it's going. This //leads to issues later on, so in that case we need to reset the channel. The state can be detected because //the DMA system doesn't give back the offending descriptor; the owner is still set to DMA. - for (i = 0; hal->dmadesc_rx[i].eof == 0 && hal->dmadesc_rx[i].owner == 0; i++) {} - if (hal->dmadesc_rx[i].owner) { + for (i = 0; hal->dmadesc_rx[i].dw0.suc_eof == 0 && hal->dmadesc_rx[i].dw0.owner == 0; i++) {} + if (hal->dmadesc_rx[i].dw0.owner) { ret = true; } } diff --git a/components/hal/spi_slave_hd_hal.c b/components/hal/spi_slave_hd_hal.c index c2bf88a5597..81a5bf5dfac 100644 --- a/components/hal/spi_slave_hd_hal.c +++ b/components/hal/spi_slave_hd_hal.c @@ -71,7 +71,9 @@ void spi_slave_hd_hal_init(spi_slave_hd_hal_context_t *hal, const spi_slave_hd_h hal->rx_dma_head = &hal->rx_dummy_head; //Configure slave - s_spi_slave_hd_hal_dma_init_config(hal); + if (hal_config->dma_enabled) { + s_spi_slave_hd_hal_dma_init_config(hal); + } spi_ll_slave_hd_init(hw); spi_ll_set_addr_bitlen(hw, hal_config->address_bits); diff --git a/components/hal/test/CMakeLists.txt b/components/hal/test/CMakeLists.txt deleted file mode 100644 index a06f271e1a9..00000000000 --- a/components/hal/test/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -idf_component_register(SRC_DIRS "." - PRIV_INCLUDE_DIRS "${include_dirs}" - PRIV_REQUIRES cmock test_utils) diff --git a/components/hal/test/test_mpu.c b/components/hal/test/test_mpu.c deleted file mode 100644 index dec5847807a..00000000000 --- a/components/hal/test/test_mpu.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include "unity.h" - -#include "esp_attr.h" - -#include "hal/mpu_hal.h" - -// TODO ESP32-C3 IDF-2375 -// LL still not implemented - -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2, ESP32C6, ESP32H2) -//IDF-5058 - -volatile static int RTC_NOINIT_ATTR access = 0; - -static void trigger_illegal_access(void) -{ - access = 0; - intptr_t addr = 0x80000000; // MPU region 4 - volatile int __attribute__((unused)) val = 0; - - // Marked as an illegal access region at startup in ESP32, ESP32S2. - // Make accessible temporarily. - mpu_hal_set_region_access(4, MPU_REGION_RW); - - val = *((int*) addr); - ++access; - TEST_ASSERT_EQUAL(1, access); - printf("Sucessfully accessed location %p\r\n", (void*)addr); - - // Make access to region illegal again. - mpu_hal_set_region_access(4, MPU_REGION_ILLEGAL); - ++access; - - // Since access to region is illegal, this should fail (causing a reset), and the increment - // to access count is not performed. - val = *((int*) addr); - ++access; -} - -void check_access(void) -{ - TEST_ASSERT_EQUAL(2, access); -} - -TEST_CASE_MULTIPLE_STAGES("Can set illegal access regions", "[soc][mpu]", - trigger_illegal_access, - check_access); - -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(...) -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) diff --git a/components/hal/twai_hal.c b/components/hal/twai_hal.c index e0ff94d51a1..25d0de61a80 100644 --- a/components/hal/twai_hal.c +++ b/components/hal/twai_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,8 +23,6 @@ bool twai_hal_init(twai_hal_context_t *hal_ctx, const twai_hal_config_t *config) hal_ctx->dev = TWAI_LL_GET_HW(config->controller_id); hal_ctx->state_flags = 0; hal_ctx->clock_source_hz = config->clock_source_hz; - //Enable functional clock - twai_ll_enable_clock(hal_ctx->dev, true); //Initialize TWAI controller, and set default values to registers twai_ll_enter_reset_mode(hal_ctx->dev); if (!twai_ll_is_in_reset_mode(hal_ctx->dev)) { //Must enter reset mode to write to config registers @@ -48,8 +46,6 @@ void twai_hal_deinit(twai_hal_context_t *hal_ctx) twai_ll_set_enabled_intrs(hal_ctx->dev, 0); twai_ll_clear_arb_lost_cap(hal_ctx->dev); twai_ll_clear_err_code_cap(hal_ctx->dev); - //Disable functional clock - twai_ll_enable_clock(hal_ctx->dev, false); hal_ctx->dev = NULL; } @@ -62,14 +58,6 @@ void twai_hal_configure(twai_hal_context_t *hal_ctx, const twai_timing_config_t brp = hal_ctx->clock_source_hz / t_config->quanta_resolution_hz; } - // set clock source - twai_clock_source_t clk_src = t_config->clk_src; - //for backward compatible, zero value means default a default clock source - if (t_config->clk_src == 0) { - clk_src = TWAI_CLK_SRC_DEFAULT; - } - twai_ll_set_clock_source(hal_ctx->dev, clk_src); - //Configure bus timing, acceptance filter, CLKOUT, and interrupts twai_ll_set_bus_timing(hal_ctx->dev, brp, t_config->sjw, t_config->tseg_1, t_config->tseg_2, t_config->triple_sampling); twai_ll_set_acc_filter(hal_ctx->dev, f_config->acceptance_code, f_config->acceptance_mask, f_config->single_filter); diff --git a/components/heap/Kconfig b/components/heap/Kconfig index 8de0f77519f..48382f12060 100644 --- a/components/heap/Kconfig +++ b/components/heap/Kconfig @@ -128,4 +128,14 @@ menu "Heap memory debugging" Note that it is only safe to enable this configuration if no functions from esp_heap_caps.h or esp_heap_trace.h are called from ISR. + + config HEAP_TLSF_CHECK_PATCH + bool "Patch the tlsf_check_pool() for ROM HEAP TLSF implementation" + depends on IDF_TARGET_ESP32C2 && ESP32C2_REV_MIN_FULL < 200 + default y + help + ROM does not contain the patch of tlsf_check_pool() allowing perform + the integrity checking on used blocks. The patch to allow such check + needs to be applied. + endmenu diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 501ebe6392e..73ac52d85c4 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -660,31 +660,8 @@ size_t heap_caps_get_allocated_size( void *ptr ) return MULTI_HEAP_REMOVE_BLOCK_OWNER_SIZE(size); } -HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps) +static HEAP_IRAM_ATTR void *heap_caps_aligned_alloc_base(size_t alignment, size_t size, uint32_t caps) { - void *ret = NULL; - - if(!alignment) { - return NULL; - } - - //Alignment must be a power of two: - if((alignment & (alignment - 1)) != 0) { - return NULL; - } - - if (size == 0) { - return NULL; - } - - if (MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size) > HEAP_SIZE_MAX) { - // Avoids int overflow when adding small numbers to size, or - // calculating 'end' from start+size, by limiting 'size' to the possible range - heap_caps_alloc_failed(size, caps, __func__); - - return NULL; - } - for (int prio = 0; prio < SOC_MEMORY_TYPE_NO_PRIOS; prio++) { //Iterate over heaps and check capabilities at this priority heap_t *heap; @@ -697,7 +674,7 @@ HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint //doesn't cover, see if they're available in other prios. if ((get_all_caps(heap) & caps) == caps) { //Just try to alloc, nothing special. - ret = multi_heap_aligned_alloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size), alignment); + void *ret = multi_heap_aligned_alloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size), alignment); if (ret != NULL) { MULTI_HEAP_SET_BLOCK_OWNER(ret); ret = MULTI_HEAP_ADD_BLOCK_OWNER_OFFSET(ret); @@ -709,12 +686,83 @@ HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint } } - heap_caps_alloc_failed(size, caps, __func__); - //Nothing usable found. return NULL; } +static HEAP_IRAM_ATTR esp_err_t heap_caps_aligned_check_args(size_t alignment, size_t size, uint32_t caps, const char *funcname) +{ + if (!alignment) { + return ESP_FAIL; + } + + // Alignment must be a power of two: + if ((alignment & (alignment - 1)) != 0) { + return ESP_FAIL; + } + + if (size == 0) { + return ESP_FAIL; + } + + if (MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size) > HEAP_SIZE_MAX) { + // Avoids int overflow when adding small numbers to size, or + // calculating 'end' from start+size, by limiting 'size' to the possible range + heap_caps_alloc_failed(size, caps, funcname); + return ESP_FAIL; + } + + return ESP_OK; +} + +HEAP_IRAM_ATTR void *heap_caps_aligned_alloc_default(size_t alignment, size_t size) +{ + void *ret = NULL; + + if (malloc_alwaysinternal_limit == MALLOC_DISABLE_EXTERNAL_ALLOCS) { + return heap_caps_aligned_alloc(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + } + + if (heap_caps_aligned_check_args(alignment, size, MALLOC_CAP_DEFAULT, __func__) != ESP_OK) { + return NULL; + } + + if (size <= (size_t)malloc_alwaysinternal_limit) { + ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + } else { + ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM); + } + + if (ret != NULL) { + return ret; + } + + ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT); + + if (ret == NULL) { + heap_caps_alloc_failed(size, MALLOC_CAP_DEFAULT, __func__); + } + + return ret; +} + +HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps) +{ + void *ret = NULL; + + if (heap_caps_aligned_check_args(alignment, size, caps, __func__) != ESP_OK) { + return NULL; + } + + ret = heap_caps_aligned_alloc_base(alignment, size, caps); + + if (ret == NULL) { + heap_caps_alloc_failed(size, caps, __func__); + } + + return ret; +} + HEAP_IRAM_ATTR void heap_caps_aligned_free(void *ptr) { heap_caps_free(ptr); diff --git a/components/heap/heap_private.h b/components/heap/heap_private.h index 51b6773ffad..fde7a78bcfd 100644 --- a/components/heap/heap_private.h +++ b/components/heap/heap_private.h @@ -62,6 +62,7 @@ inline static uint32_t get_all_caps(const heap_t *heap) */ void *heap_caps_realloc_default(void *p, size_t size); void *heap_caps_malloc_default(size_t size); +void *heap_caps_aligned_alloc_default(size_t alignment, size_t size); #ifdef __cplusplus diff --git a/components/heap/test_apps/.build-test-rules.yml b/components/heap/test_apps/.build-test-rules.yml index e323365b561..1e3b8ecd8cf 100644 --- a/components/heap/test_apps/.build-test-rules.yml +++ b/components/heap/test_apps/.build-test-rules.yml @@ -2,8 +2,17 @@ components/heap/test_apps/heap_tests: disable: + - 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 + - if: CONFIG_NAME == "no_poisoning" and (IDF_TARGET != "esp32" and NIGHTLY_RUN != "1") + - if: CONFIG_NAME == "light_poisoning" and (IDF_TARGET != "esp32" and NIGHTLY_RUN != "1") + - if: CONFIG_NAME == "comprehensive_poisoning" and (IDF_TARGET != "esp32" and NIGHTLY_RUN != "1") + # Non-target specific functionality, only test on a single target in default pipeline + - if: CONFIG_NAME == "in_flash" and (IDF_TARGET != "esp32c6" and NIGHTLY_RUN != "1") + depends_components: + - heap components/heap/test_apps/host_test_linux: enable: diff --git a/components/heap/test_apps/heap_tests/main/test_corruption_check.c b/components/heap/test_apps/heap_tests/main/test_corruption_check.c index ec88930c7a9..2ee7aa21e30 100644 --- a/components/heap/test_apps/heap_tests/main/test_corruption_check.c +++ b/components/heap/test_apps/heap_tests/main/test_corruption_check.c @@ -70,8 +70,6 @@ TEST_CASE("multi_heap poisoning detection", "[heap]") } } -#if !defined(CONFIG_HEAP_TLSF_USE_ROM_IMPL) - #ifdef CONFIG_HEAP_TASK_TRACKING #define HEAD_CANARY_OFFSET 3 // head canary | task tracking | allocated size #else @@ -117,6 +115,4 @@ TEST_CASE("canary corruption in light or comprehensive poisoning mode", "[heap]" ptr[TAIL_CANARY_OFFSET] = canary; heap_caps_free(ptr); } - -#endif // !CONFIG_HEAP_TLSF_USE_ROM_IMPL #endif // CONFIG_HEAP_POISONING_LIGHT && CONFIG_HEAP_LIGHT_POISONING diff --git a/components/heap/test_apps/heap_tests/pytest_heap.py b/components/heap/test_apps/heap_tests/pytest_heap.py index 1c51d22fd44..c3684eff2d8 100644 --- a/components/heap/test_apps/heap_tests/pytest_heap.py +++ b/components/heap/test_apps/heap_tests/pytest_heap.py @@ -39,8 +39,7 @@ def test_heap_poisoning_qemu(dut: Dut) -> None: @pytest.mark.generic -@pytest.mark.esp32 -@pytest.mark.esp32c6 +@pytest.mark.supported_targets @pytest.mark.parametrize( 'config', [ @@ -71,27 +70,21 @@ def test_heap(dut: Dut) -> None: @pytest.mark.parametrize( 'config', [ - 'abort_alloc_fail' + 'misc_options' ] ) -def test_heap_abort_on_alloc_failure(dut: Dut) -> None: +def test_heap_misc_options(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') - dut.write('"When enabled, allocation operation failure generates an abort"') - dut.expect('Backtrace: ') + dut.write('"IRAM_8BIT capability test"') + dut.expect_unity_test_output() + dut.expect_exact("Enter next test, or 'enter' to see menu") + dut.write('"test allocation and free function hooks"') + dut.expect_unity_test_output() -@pytest.mark.generic -@pytest.mark.esp32 -@pytest.mark.parametrize( - 'config', - [ - '8bit_access' - ] -) -def test_heap_8bit_access(dut: Dut) -> None: - dut.expect_exact('Press ENTER to see the list of tests') - dut.write('"IRAM_8BIT capability test"') - dut.expect_unity_test_output(timeout=300) + dut.expect_exact("Enter next test, or 'enter' to see menu") + dut.write('"When enabled, allocation operation failure generates an abort"') + dut.expect('Backtrace: ') @pytest.mark.generic @@ -134,17 +127,3 @@ def test_memory_protection(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('[heap][mem_prot]') dut.expect_unity_test_output(timeout=300) - - -@pytest.mark.generic -@pytest.mark.esp32 -@pytest.mark.parametrize( - 'config', - [ - 'func_hooks' - ] -) -def test_heap_func_hooks(dut: Dut) -> None: - dut.expect_exact('Press ENTER to see the list of tests') - dut.write('"test allocation and free function hooks"') - dut.expect_unity_test_output(timeout=300) diff --git a/components/heap/test_apps/heap_tests/sdkconfig.ci.abort_alloc_fail b/components/heap/test_apps/heap_tests/sdkconfig.ci.abort_alloc_fail deleted file mode 100644 index 1dd2c31d338..00000000000 --- a/components/heap/test_apps/heap_tests/sdkconfig.ci.abort_alloc_fail +++ /dev/null @@ -1 +0,0 @@ -CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS=y diff --git a/components/heap/test_apps/heap_tests/sdkconfig.ci.func_hooks b/components/heap/test_apps/heap_tests/sdkconfig.ci.func_hooks deleted file mode 100644 index 9a440b80dea..00000000000 --- a/components/heap/test_apps/heap_tests/sdkconfig.ci.func_hooks +++ /dev/null @@ -1 +0,0 @@ -CONFIG_HEAP_USE_HOOKS=y diff --git a/components/heap/test_apps/heap_tests/sdkconfig.ci.8bit_access b/components/heap/test_apps/heap_tests/sdkconfig.ci.misc_options similarity index 59% rename from components/heap/test_apps/heap_tests/sdkconfig.ci.8bit_access rename to components/heap/test_apps/heap_tests/sdkconfig.ci.misc_options index 3cc667f5322..8e7394bf680 100644 --- a/components/heap/test_apps/heap_tests/sdkconfig.ci.8bit_access +++ b/components/heap/test_apps/heap_tests/sdkconfig.ci.misc_options @@ -1,3 +1,5 @@ CONFIG_IDF_TARGET="esp32" CONFIG_FREERTOS_UNICORE=y CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY=y +CONFIG_HEAP_USE_HOOKS=y +CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS=y diff --git a/components/idf_test/include/esp32h2/idf_performance_target.h b/components/idf_test/include/esp32h2/idf_performance_target.h index 33f100aa546..9bc935c895f 100644 --- a/components/idf_test/include/esp32h2/idf_performance_target.h +++ b/components/idf_test/include/esp32h2/idf_performance_target.h @@ -36,10 +36,10 @@ #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV 70 #define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT 140 -//TODO: IDF-6216 #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/lwip/Kconfig b/components/lwip/Kconfig index dc8e3cf6212..6fadf80b25b 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -582,7 +582,7 @@ menu "LWIP" Can be set lower to save RAM, the default value 1460(ipv4)/1440(ipv6) will give best throughput. IPv4 TCP_MSS Range: 576 <= TCP_MSS <= 1460 - IPv6 TCP_MSS Range: 1220<= TCP_mSS <= 1440 + IPv6 TCP_MSS Range: 1220<= TCP_MSS <= 1440 config LWIP_TCP_TMR_INTERVAL int "TCP timer interval(ms)" @@ -607,7 +607,7 @@ menu "LWIP" config LWIP_TCP_SND_BUF_DEFAULT int "Default send buffer size" - default 5744 # 4 * default MSS + default 5760 # 4 * default MSS range 2440 65535 if !LWIP_WND_SCALE range 2440 1024000 if LWIP_WND_SCALE help @@ -624,7 +624,7 @@ menu "LWIP" config LWIP_TCP_WND_DEFAULT int "Default receive window size" - default 5744 # 4 * default MSS + default 5760 # 4 * default MSS range 2440 65535 if !LWIP_WND_SCALE range 2440 1024000 if LWIP_WND_SCALE help @@ -666,6 +666,37 @@ menu "LWIP" Disable this option to save some RAM during TCP sessions, at the expense of increased retransmissions if segments arrive out of order. + config LWIP_TCP_OOSEQ_TIMEOUT + int "Timeout for each pbuf queued in TCP OOSEQ, in RTOs." + depends on LWIP_TCP_QUEUE_OOSEQ + range 1 30 + default 6 + help + The timeout value is TCP_OOSEQ_TIMEOUT * RTO. + + config LWIP_TCP_OOSEQ_MAX_PBUFS + int "The maximum number of pbufs queued on OOSEQ per pcb" + depends on LWIP_TCP_QUEUE_OOSEQ + range 0 12 + default 4 + help + If LWIP_TCP_OOSEQ_MAX_PBUFS = 0, TCP will not control the number of OOSEQ pbufs. + + In a poor network environment, many out-of-order tcp pbufs will be received. + These out-of-order pbufs will be cached in the TCP out-of-order queue which will + cause Wi-Fi/Ethernet fail to release RX buffer in time. + It is possible that all RX buffers for MAC layer are used by OOSEQ. + + Control the number of out-of-order pbufs to ensure that the MAC layer has enough RX buffer to receive packets. + + In the Wi-Fi scenario, recommended OOSEQ PBUFS Range: 0 <= TCP_OOSEQ_MAX_PBUFS <= CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM/(MAX_TCP_NUMBER + 1) + + In the Ethernet scenario,recommended Ethernet OOSEQ PBUFS Range: 0 <= TCP_OOSEQ_MAX_PBUFS <= CONFIG_ETH_DMA_RX_BUFFER_NUM/(MAX_TCP_NUMBER + 1) + + Within the recommended value range, the larger the value, the better the performance. + + MAX_TCP_NUMBER represent Maximum number of TCP connections in Wi-Fi(STA+SoftAP) and Ethernet scenario. + config LWIP_TCP_SACK_OUT bool "Support sending selective acknowledgements" default n diff --git a/components/lwip/lwip b/components/lwip/lwip index 6bf7044c036..4a8286ab8bc 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 6bf7044c0368d587f70f7083e39e0a619b4d5788 +Subproject commit 4a8286ab8bcf983f22421e3d4be650837b5eb277 diff --git a/components/lwip/port/include/lwipopts.h b/components/lwip/port/include/lwipopts.h index afe2678d3ad..1c981f8fc43 100644 --- a/components/lwip/port/include/lwipopts.h +++ b/components/lwip/port/include/lwipopts.h @@ -545,6 +545,21 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define TCP_QUEUE_OOSEQ 0 #endif +/** + * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs + * queued on ooseq per pcb + */ +#if TCP_QUEUE_OOSEQ +#define TCP_OOSEQ_MAX_PBUFS CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS +#endif + +/** + * TCP_OOSEQ_TIMEOUT: Timeout for each pbuf queued in TCP OOSEQ, in RTOs. + */ +#if TCP_QUEUE_OOSEQ +#define TCP_OOSEQ_TIMEOUT CONFIG_LWIP_TCP_OOSEQ_TIMEOUT +#endif + /** * LWIP_TCP_SACK_OUT==1: TCP will support sending selective acknowledgements (SACKs). */ diff --git a/components/mbedtls/.build-test-rules.yml b/components/mbedtls/.build-test-rules.yml new file mode 100644 index 00000000000..705dd4b66b6 --- /dev/null +++ b/components/mbedtls/.build-test-rules.yml @@ -0,0 +1,7 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/mbedtls/test_apps: + disable: + - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "psram_all_ext" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "ecdsa_sign" and SOC_ECDSA_SUPPORTED != 1 diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 0726b0da97f..a162a0a3abd 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -45,6 +45,12 @@ if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE) list(APPEND args --filter ${DEFAULT_CRT_DIR}/cmn_crt_authorities.csv) endif() + # Add deprecated root certs if enabled. This config is not visible if the default cert + # bundle is not selected + if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST) + list(APPEND crt_paths ${DEFAULT_CRT_DIR}/cacrt_deprecated.pem) + endif() + if(CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE) get_filename_component(custom_bundle_path ${CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH} ABSOLUTE BASE_DIR "${project_dir}") @@ -192,8 +198,10 @@ if(AES_PERIPHERAL_TYPE STREQUAL "dma") endif() -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c" - "${COMPONENT_DIR}/port/esp_mem.c" +if(NOT ${IDF_TARGET} STREQUAL "linux") + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c") +endif() +target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_mem.c" "${COMPONENT_DIR}/port/esp_timing.c" ) diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index e618261230f..8fc0f0eb2b7 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -348,6 +348,21 @@ menu "mbedTLS" Name of the custom certificate directory or file. This path is evaluated relative to the project root directory. + config MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST + bool "Add deprecated root certificates" + depends on MBEDTLS_CERTIFICATE_BUNDLE && !MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE + help + Include the deprecated list of root certificates in the bundle. + This list gets updated when a certificate is removed from the Mozilla's + NSS root certificate store. This config can be enabled if you would like + to ensure that none of the certificates that were deployed in the product + are affected because of the update to bundle. In turn, enabling this + config keeps expired, retracted certificates in the bundle and it may + pose a security risk. + + - Deprecated cert list may grow based based on sync with upstream bundle + - Deprecated certs would be be removed in ESP-IDF (next) major release + config MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS int "Maximum no of certificates allowed in certificate bundle" default 200 diff --git a/components/mbedtls/esp_crt_bundle/cacrt_all.pem b/components/mbedtls/esp_crt_bundle/cacrt_all.pem index 2ae7b6cb21b..9551dfd830b 100644 --- a/components/mbedtls/esp_crt_bundle/cacrt_all.pem +++ b/components/mbedtls/esp_crt_bundle/cacrt_all.pem @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Tue Jan 10 04:12:06 2023 GMT +## Certificate data from Mozilla as of: Tue Aug 22 03:12:04 2023 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 90c470e705b4b5f36f09684dc50e2b79c8b86989a848b62cd1a7bd6460ee65f6 +## SHA256: 0ff137babc6a5561a9cfbe9f29558972e5b528202681b7d3803d03a3e82922bd ## @@ -603,26 +603,6 @@ NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -Hongkong Post Root CA 1 -======================= ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT -DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx -NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n -IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 -ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr -auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh -qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY -V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV -HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i -h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio -l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei -IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps -T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT -c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== ------END CERTIFICATE----- - SecureSign RootCA11 =================== -----BEGIN CERTIFICATE----- @@ -1261,40 +1241,6 @@ Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- -E-Tugra Certification Authority -=============================== ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w -DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls -ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw -NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx -QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl -cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD -DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd -hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K -CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g -ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ -BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 -E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz -rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq -jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 -dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB -/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG -MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK -kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO -XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 -VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo -a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc -dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV -KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT -Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 -8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G -C7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- - T-TeleSec GlobalRoot Class 2 ============================ -----BEGIN CERTIFICATE----- @@ -3276,55 +3222,6 @@ AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR -----END CERTIFICATE----- -E-Tugra Global Root CA RSA v3 -============================= ------BEGIN CERTIFICATE----- -MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQELBQAwgYAxCzAJ -BgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAb -BgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290 -IENBIFJTQSB2MzAeFw0yMDAzMTgwOTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJU -UjEPMA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRF -LVR1Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBSU0Eg -djMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J77gnJY9LTQ91ew6aEOErx -jYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscxuj7X/iWpKo429NEvx7epXTPcMHD4QGxL -sqYxYdE0PD0xesevxKenhOGXpOhL9hd87jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF -/YP9f4RtNGx/ardLAQO/rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8q -QedmCeFLl+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bGwzrw -bMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4znKS4iicvObpCdg6 -04nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBOM/J+JjKsBY04pOZ2PJ8QaQ5tndLB -eSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiM -bIedBi3x7+PmBvrFZhNb/FAHnnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbg -h3cXTJ2w2AmoDVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSytK7mLfcm1ap1 -LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAImocn+M684uGMQQ -gC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN4 -38o2Fi+CiJ+8EUdPdk3ILY7r3y18Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/q -ln0F7psTpURs+APQ3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3s -SdPkvmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn99t2HVhjY -sCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQmhty3QUBjYZgv6Rn7rWl -DdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YAVSgU7NbHEqIbZULpkejLPoeJVF3Zr52X -nGnnCv8PWniLYypMfUeUP95L6VPQMPHF9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFH -IK+WEj5jlB0E5y67hscMmoi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiX -YY60MGo8bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ ------END CERTIFICATE----- - -E-Tugra Global Root CA ECC v3 -============================= ------BEGIN CERTIFICATE----- -MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV -BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB -IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP -MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 -Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2 -w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31 -Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ -zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO -PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W -Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 ------END CERTIFICATE----- - Security Communication RootCA3 ============================== -----BEGIN CERTIFICATE----- @@ -3370,3 +3267,185 @@ BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e N9k= -----END CERTIFICATE----- + +BJCA Global Root CA1 +==================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQG +EwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJK +Q0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAzMTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkG +A1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQD +DBRCSkNBIEdsb2JhbCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFm +CL3ZxRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZspDyRhyS +sTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O558dnJCNPYwpj9mZ9S1Wn +P3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgRat7GGPZHOiJBhyL8xIkoVNiMpTAK+BcW +yqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRj +eulumijWML3mG90Vr4TqnMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNn +MoH1V6XKV0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/pj+b +OT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZOz2nxbkRs1CTqjSSh +GL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXnjSXWgXSHRtQpdaJCbPdzied9v3pK +H9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMB +AAGjQjBAMB0GA1UdDgQWBBTF7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3KliawLwQ8hOnThJ +dMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u+2D2/VnGKhs/I0qUJDAnyIm8 +60Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuh +TaRjAv04l5U/BXCga99igUOLtFkNSoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW +4AB+dAb/OMRyHdOoP2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmp +GQrI+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRzznfSxqxx +4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9eVzYH6Eze9mCUAyTF6ps +3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4S +SPfSKcOYKMryMguTjClPPGAyzQWWYezyr/6zcCwupvI= +-----END CERTIFICATE----- + +BJCA Global Root CA2 +==================== +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQswCQYDVQQGEwJD +TjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJKQ0Eg +R2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgyMVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UE +BhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRC +SkNBIEdsb2JhbCBSb290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jl +SR9BIgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK++kpRuDCK +/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJKsVF/BvDRgh9Obl+rg/xI +1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8 +W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8g +UXOQwKhbYdDFUDn9hf7B43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root E46 +============================================= +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQswCQYDVQQGEwJH +QjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBTZXJ2 +ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5 +WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0 +aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccCWvkEN/U0 +NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+6xnOQ6OjQjBAMB0GA1Ud +DgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAKBggqhkjOPQQDAwNnADBkAjAn7qRaqCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RH +lAFWovgzJQxC36oCMB3q4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21U +SAGKcw== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root R46 +============================================= +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBfMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1 +OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDaef0rty2k +1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnzSDBh+oF8HqcIStw+Kxwf +GExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xfiOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMP +FF1bFOdLvt30yNoDN9HWOaEhUTCDsG3XME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vu +ZDCQOc2TZYEhMbUjUDM3IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5Qaz +Yw6A3OASVYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgESJ/A +wSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu+Zd4KKTIRJLpfSYF +plhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt8uaZFURww3y8nDnAtOFr94MlI1fZ +EoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+LHaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW +6aWWrL3DkJiy4Pmi1KZHQ3xtzwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWI +IUkwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQYKlJfp/imTYp +E0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52gDY9hAaLMyZlbcp+nv4fjFg4 +exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZAFv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M +0ejf5lG5Nkc/kLnHvALcWxxPDkjBJYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI +84HxZmduTILA7rpXDhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9m +pFuiTdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5dHn5Hrwd +Vw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65LvKRRFHQV80MNNVIIb/b +E/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmm +J1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAYQqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +SSL.com TLS RSA Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQG +EwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBSU0Eg +Um9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloXDTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMC +VVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u +9nTPL3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OYt6/wNr/y +7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0insS657Lb85/bRi3pZ7Qcac +oOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3PnxEX4MN8/HdIGkWCVDi1FW24IBydm5M +R7d1VVm0U3TZlMZBrViKMWYPHqIbKUBOL9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDG +D6C1vBdOSHtRwvzpXGk3R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEW +TO6Af77wdr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS+YCk +8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYSd66UNHsef8JmAOSq +g+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoGAtUjHBPW6dvbxrB6y3snm/vg1UYk +7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2fgTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsu +N+7jhHonLs0ZNbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsMQtfhWsSWTVTN +j8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvfR4iyrT7gJ4eLSYwfqUdYe5by +iB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJDPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjU +o3KUQyxi4U5cMj29TH0ZR6LDSeeWP4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqo +ENjwuSfr98t67wVylrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7Egkaib +MOlqbLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2wAgDHbICi +vRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3qr5nsLFR+jM4uElZI7xc7 +P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sjiMho6/4UIyYOf8kpIEFR3N+2ivEC+5BB0 +9+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +SSL.com TLS ECC Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBFQ0MgUm9v +dCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMx +GDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWy +JGYmacCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFNSeR7T5v1 +5wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSJjy+j6CugFFR7 +81a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NWuCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGG +MAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w +7deedWo1dlJF4AIxAMeNb0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5 +Zn6g6g== +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA ECC TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4wLAYDVQQDDCVB +dG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQswCQYD +VQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3Mg +VHJ1c3RlZFJvb3QgUm9vdCBDQSBFQ0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYT +AkRFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6K +DP/XtXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4AjJn8ZQS +b+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2KCXWfeBmmnoJsmo7jjPX +NtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIwW5kp85wxtolrbNa9d+F851F+ +uDrNozZffPc8dz7kUK2o59JZDCaOMDtuCCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGY +a3cpetskz2VAv9LcjBHo9H1/IISpQuQo +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA RSA TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBMMS4wLAYDVQQD +DCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQsw +CQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0 +b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNV +BAYTAkRFMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BB +l01Z4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYvYe+W/CBG +vevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZkmGbzSoXfduP9LVq6hdK +ZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDsGY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt +0xU6kGpn8bRrZtkh68rZYnxGEFzedUlnnkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVK +PNe0OwANwI8f4UDErmwh3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMY +sluMWuPD0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzygeBY +Br3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8ANSbhqRAvNncTFd+ +rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezBc6eUWsuSZIKmAMFwoW4sKeFYV+xa +fJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lIpw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUdEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0G +CSqGSIb3DQEBDAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPso0UvFJ/1TCpl +Q3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJqM7F78PRreBrAwA0JrRUITWX +AdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuywxfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9G +slA9hGCZcbUztVdF5kJHdWoOsAgMrr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2Vkt +afcxBPTy+av5EzH4AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9q +TFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuYo7Ey7Nmj +1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5dDTedk+SKlOxJTnbPP/l +PqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDwN/zIIX8/syQbPYtuzE2wFg2W +HYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- diff --git a/components/mbedtls/esp_crt_bundle/cacrt_deprecated.pem b/components/mbedtls/esp_crt_bundle/cacrt_deprecated.pem new file mode 100644 index 00000000000..f5ec79d41ed --- /dev/null +++ b/components/mbedtls/esp_crt_bundle/cacrt_deprecated.pem @@ -0,0 +1,114 @@ +## +## Deprecated CA Root Certificates +## Deprecated CA Root Certificates that get appended to 'cacrt_all.pem' + +## These certificates have been removed from the newer Mozilla CA certificate store. +## Refer to https://wiki.mozilla.org/CA/Removed_Certificates for more information. + +## These certificates might be removed from ESP-IDF during every major release. + +## The current deprecated certificate bundle is up-to-date with the Mozilla cert bundle (cacrt_all.pem) dated Tue Aug 22 03:12:04 2023 GMT + + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +E-Tugra Certification Authority +=============================== +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w +DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls +ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw +NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx +QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl +cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD +DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd +hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K +CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g +ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ +BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 +E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz +rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq +jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 +dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK +kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO +XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 +VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo +a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc +dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV +KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT +Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 +8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G +C7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +E-Tugra Global Root CA RSA v3 +============================= +-----BEGIN CERTIFICATE----- +MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQELBQAwgYAxCzAJ +BgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAb +BgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290 +IENBIFJTQSB2MzAeFw0yMDAzMTgwOTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJU +UjEPMA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRF +LVR1Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBSU0Eg +djMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J77gnJY9LTQ91ew6aEOErx +jYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscxuj7X/iWpKo429NEvx7epXTPcMHD4QGxL +sqYxYdE0PD0xesevxKenhOGXpOhL9hd87jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF +/YP9f4RtNGx/ardLAQO/rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8q +QedmCeFLl+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bGwzrw +bMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4znKS4iicvObpCdg6 +04nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBOM/J+JjKsBY04pOZ2PJ8QaQ5tndLB +eSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiM +bIedBi3x7+PmBvrFZhNb/FAHnnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbg +h3cXTJ2w2AmoDVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSytK7mLfcm1ap1 +LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAImocn+M684uGMQQ +gC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN4 +38o2Fi+CiJ+8EUdPdk3ILY7r3y18Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/q +ln0F7psTpURs+APQ3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3s +SdPkvmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn99t2HVhjY +sCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQmhty3QUBjYZgv6Rn7rWl +DdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YAVSgU7NbHEqIbZULpkejLPoeJVF3Zr52X +nGnnCv8PWniLYypMfUeUP95L6VPQMPHF9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFH +IK+WEj5jlB0E5y67hscMmoi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiX +YY60MGo8bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ +-----END CERTIFICATE----- + +E-Tugra Global Root CA ECC v3 +============================= +-----BEGIN CERTIFICATE----- +MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV +BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB +IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP +MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 +Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2 +w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31 +Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ +zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO +PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W +Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 +-----END CERTIFICATE----- diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 9aebf99e299..0bf4d3e6036 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -232,6 +232,7 @@ #undef MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK #endif +#ifndef CONFIG_IDF_TARGET_LINUX /** * \def MBEDTLS_ENTROPY_HARDWARE_ALT * @@ -244,6 +245,7 @@ * Uncomment to use your own hardware entropy collector. */ #define MBEDTLS_ENTROPY_HARDWARE_ALT +#endif // !CONFIG_IDF_TARGET_LINUX /** * \def MBEDTLS_AES_ROM_TABLES @@ -866,6 +868,7 @@ */ #define MBEDTLS_FS_IO +#ifndef CONFIG_IDF_TARGET_LINUX /** * \def MBEDTLS_NO_PLATFORM_ENTROPY * @@ -876,6 +879,7 @@ * Uncomment this macro to disable the built-in platform entropy functions. */ #define MBEDTLS_NO_PLATFORM_ENTROPY +#endif // !CONFIG_IDF_TARGET_LINUX /** * \def MBEDTLS_PK_RSA_ALT_SUPPORT diff --git a/components/mbedtls/test_apps/.build-test-rules.yml b/components/mbedtls/test_apps/.build-test-rules.yml new file mode 100644 index 00000000000..705dd4b66b6 --- /dev/null +++ b/components/mbedtls/test_apps/.build-test-rules.yml @@ -0,0 +1,7 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/mbedtls/test_apps: + disable: + - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "psram_all_ext" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "ecdsa_sign" and SOC_ECDSA_SUPPORTED != 1 diff --git a/components/mbedtls/test_apps/pytest_mbedtls_ut.py b/components/mbedtls/test_apps/pytest_mbedtls_ut.py index 1445e9a5a4b..7167a54fdf7 100644 --- a/components/mbedtls/test_apps/pytest_mbedtls_ut.py +++ b/components/mbedtls/test_apps/pytest_mbedtls_ut.py @@ -60,7 +60,6 @@ def test_mbedtls_psram(dut: Dut) -> None: @pytest.mark.parametrize( 'config', [ - 'psram_esp32', 'psram_all_ext', ], indirect=True, diff --git a/components/mbedtls/test_apps/sdkconfig.ci.psram_esp32 b/components/mbedtls/test_apps/sdkconfig.ci.psram_esp32 deleted file mode 100644 index 5acbcfd7fc6..00000000000 --- a/components/mbedtls/test_apps/sdkconfig.ci.psram_esp32 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_SPIRAM=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 -CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y diff --git a/components/newlib/heap.c b/components/newlib/heap.c index fca44906a2d..685e1e3c721 100644 --- a/components/newlib/heap.c +++ b/components/newlib/heap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ */ extern void *heap_caps_malloc_default( size_t size ); extern void *heap_caps_realloc_default( void *ptr, size_t size ); +extern void *heap_caps_aligned_alloc_default( size_t alignment, size_t size ); void* malloc(size_t size) { @@ -71,7 +72,7 @@ void* _calloc_r(struct _reent *r, size_t nmemb, size_t size) void* memalign(size_t alignment, size_t n) { - return heap_caps_aligned_alloc(alignment, n, MALLOC_CAP_DEFAULT); + return heap_caps_aligned_alloc_default(alignment, n); } int posix_memalign(void **out_ptr, size_t alignment, size_t size) @@ -81,7 +82,7 @@ int posix_memalign(void **out_ptr, size_t alignment, size_t size) *out_ptr = NULL; return 0; } - void *result = heap_caps_aligned_alloc(alignment, size, MALLOC_CAP_DEFAULT); + void *result = heap_caps_aligned_alloc_default(alignment, size); if (result != NULL) { /* Modify output pointer only on success */ *out_ptr = result; diff --git a/components/newlib/test_apps/newlib/main/test_misc.c b/components/newlib/test_apps/newlib/main/test_misc.c index 98fe6dcae3b..ec8a69b3f9f 100644 --- a/components/newlib/test_apps/newlib/main/test_misc.c +++ b/components/newlib/test_apps/newlib/main/test_misc.c @@ -13,6 +13,7 @@ #include #include #include "unity.h" +#include "esp_heap_caps.h" TEST_CASE("misc - posix_memalign", "[newlib_misc]") @@ -41,6 +42,26 @@ TEST_CASE("misc - posix_memalign", "[newlib_misc]") TEST_ASSERT_NOT_NULL(outptr); TEST_ASSERT_EQUAL_INT(ret, 0); free(outptr); + + outptr = magic; + heap_caps_malloc_extmem_enable(128); + ret = posix_memalign(&outptr, 16, 64); + TEST_ASSERT_TRUE(outptr != magic); + TEST_ASSERT_NOT_NULL(outptr); + TEST_ASSERT_EQUAL_INT(ret, 0); + free(outptr); + + outptr = magic; + heap_caps_malloc_extmem_enable(64); + ret = posix_memalign(&outptr, 16, 128); + TEST_ASSERT_TRUE(outptr != magic); + TEST_ASSERT_NOT_NULL(outptr); + TEST_ASSERT_EQUAL_INT(ret, 0); + free(outptr); + +#if CONFIG_SPIRAM_USE_MALLOC + heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL); +#endif } TEST_CASE("misc - sysconf", "[newlib_misc]") diff --git a/components/nvs_flash/CMakeLists.txt b/components/nvs_flash/CMakeLists.txt index c0d9421f9fb..d54703ce9b7 100644 --- a/components/nvs_flash/CMakeLists.txt +++ b/components/nvs_flash/CMakeLists.txt @@ -40,5 +40,3 @@ else() target_sources(${COMPONENT_LIB} PRIVATE "src/nvs_encrypted_partition.cpp") target_link_libraries(${COMPONENT_LIB} PRIVATE idf::mbedtls) endif() - -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/nvs_flash/nvs_partition_generator/README.rst b/components/nvs_flash/nvs_partition_generator/README.rst index 21689c5334f..f91918b56b4 100644 --- a/components/nvs_flash/nvs_partition_generator/README.rst +++ b/components/nvs_flash/nvs_partition_generator/README.rst @@ -6,7 +6,7 @@ NVS Partition Generator Utility Introduction ------------ -The utility :component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py` creates a binary file, compatible with the NVS architecture defined in :doc:`Non-Volatile Storage `, based on the key-value pairs provided in a CSV file. +The utility :component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py` creates a binary file, compatible with the NVS architecture defined in :doc:`nvs_flash`, based on the key-value pairs provided in a CSV file. This utility is ideally suited for generating a binary blob, containing data specific to ODM/OEM, which can be flashed externally at the time of device manufacturing. This allows manufacturers to generate many instances of the same application firmware with customized parameters for each device, such as a serial number. @@ -81,7 +81,7 @@ By default, binary blobs are allowed to span over multiple pages and are written Encryption-Decryption Support ----------------------------- -The NVS Partition Generator utility also allows you to create an encrypted binary file and decrypt an encrypted one. The utility uses the XTS-AES encryption. Please refer to :doc:`NVS Encryption ` for more details. +The NVS Partition Generator utility also allows you to create an encrypted binary file and decrypt an encrypted one. The utility uses the XTS-AES encryption. Please refer to :ref:`nvs_encryption` for more details. Running the Utility @@ -93,27 +93,40 @@ Running the Utility **Optional Arguments**: -+-----+------------------------+---------------------------------------------------------------+ -| No. | Parameter | Description | -+=====+========================+===============================================================+ -| 1 | ``-h`` \ ``--help`` | Show the help message and exit | -+-----+------------------------+---------------------------------------------------------------+ +.. list-table:: + :widths: 20 40 40 + :header-rows: 1 -**Commands**:: + * - No. + - Parameter + - Description + * - 1 + - ``-h`` / ``--help`` + - Show the help message and exit - Run nvs_partition_gen.py {command} -h for additional help +**Commands**: -+-----+---------------------+---------------------------------------------------------------+ -| No. | Parameter | Description | -+=====+=====================+===============================================================+ -| 1 | ``generate`` | Generate NVS partition | -+-----+---------------------+---------------------------------------------------------------+ -| 2 | ``generate-key`` | Generate keys for encryption | -+-----+---------------------+---------------------------------------------------------------+ -| 3 | ``encrypt`` | Generate NVS encrypted partition | -+-----+---------------------+---------------------------------------------------------------+ -| 4 | ``decrypt`` | Decrypt NVS encrypted partition | -+-----+---------------------+---------------------------------------------------------------+ + Run ``nvs_partition_gen.py {command} -h`` for additional help + +.. list-table:: + :widths: 20 40 40 + :header-rows: 1 + + * - No. + - Parameter + - Description + * - 1 + - ``generate`` + - Generate NVS partition + * - 2 + - ``generate-key`` + - Generate keys for encryption + * - 3 + - ``encrypt`` + - Generate NVS encrypted partition + * - 4 + - ``decrypt`` + - Decrypt NVS encrypted partition Generate NVS Partition (Default) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -124,22 +137,25 @@ Generate NVS Partition (Default) **Positional Arguments**: -+--------------+---------------------------------------------------------------+ -| Parameter | Description | -+==============+===============================================================+ -| ``input`` | Path to CSV file to parse | -+--------------+---------------------------------------------------------------+ -| ``output`` | Path to output NVS binary file | -+--------------+---------------------------------------------------------------+ -| ``size`` | Size of NVS partition in bytes (must be multiple of 4096) | -+--------------+---------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``input`` + - Path to CSV file to parse + * - ``output`` + - Path to output NVS binary file + * - ``size`` + - Size of NVS partition in bytes (must be multiple of 4096) **Optional Arguments**: +------------------------+----------------------------------------------------------------------+ | Parameter | Description | +========================+======================================================================+ -| ``-h`` \ ``--help`` | Show the help message and exit | +| ``-h`` / ``--help`` | Show the help message and exit | +------------------------+----------------------------------------------------------------------+ | ``--version {1,2}`` | Set multipage blob version (Default: Version 2) | | | | @@ -174,33 +190,37 @@ Generate Encryption Keys Partition **Optional Arguments**: -+---------------------------------------------+-----------------------------------------------------------------------------------+ -| Parameter | Description | -+=============================================+===================================================================================+ -| ``-h`` \ ``--help`` | Show the help message and exit | -+---------------------------------------------+-----------------------------------------------------------------------------------+ -| ``--keyfile KEYFILE`` | Path to output encryption keys file | -+---------------------------------------------+-----------------------------------------------------------------------------------+ -| ``--outdir OUTDIR`` | Output directory to store files created. (Default: current directory) | -+---------------------------------------------+-----------------------------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``-h`` / ``--help`` + - Show the help message and exit + * - ``--keyfile KEYFILE`` + - Path to output encryption keys file + * - ``--outdir OUTDIR`` + - Output directory to store files created. (Default: current directory) .. only:: SOC_HMAC_SUPPORTED **Optional Arguments (HMAC scheme-specific)**: - +---------------------------------------------+-----------------------------------------------------------------------------------+ - | Parameter | Description | - +=============================================+===================================================================================+ - | ``--key_protect_hmac`` | If set, the NVS encryption key protection scheme based on HMAC | - | | peripheral is used; else the default scheme based on Flash Encryption | - | | is used | - +---------------------------------------------+-----------------------------------------------------------------------------------+ - | ``--kp_hmac_keygen`` | Generate the HMAC key for HMAC-based encryption scheme | - +---------------------------------------------+-----------------------------------------------------------------------------------+ - | ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` | Path to output HMAC key file | - +---------------------------------------------+-----------------------------------------------------------------------------------+ - | ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` | File having the HMAC key for generating the NVS encryption keys | - +---------------------------------------------+-----------------------------------------------------------------------------------+ + .. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``--key_protect_hmac`` + - If set, the NVS encryption key protection scheme based on HMAC peripheral is used; else the default scheme based on flash encryption is used + * - ``--kp_hmac_keygen`` + - Generate the HMAC key for HMAC-based encryption scheme + * - ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` + - Path to output the HMAC key file + * - ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` + - File having the HMAC key for generating the NVS encryption keys You can run the utility to generate only the encryption key partition using the command below:: @@ -216,7 +236,7 @@ You can run the utility to generate only the encryption key partition using the .. note:: Encryption key of the format ``/keys/keys-.bin`` and HMAC key of the format ``/keys/hmac-keys-.bin`` are created. - - Generate the NVS encryption keys, given the HMAC-key:: + - Generate the NVS encryption keys, given the HMAC key:: python nvs_partition_gen.py generate-key --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin @@ -246,22 +266,25 @@ Generate Encrypted NVS Partition **Positional Arguments**: -+--------------+---------------------------------------------------------------+ -| Parameter | Description | -+==============+===============================================================+ -| ``input`` | Path to CSV file to parse | -+--------------+---------------------------------------------------------------+ -| ``output`` | Path to output NVS binary file | -+--------------+---------------------------------------------------------------+ -| ``size`` | Size of NVS partition in bytes (must be multiple of 4096) | -+--------------+---------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``input`` + - Path to CSV file to parse + * - ``output`` + - Path to output NVS binary file + * - ``size`` + - Size of NVS partition in bytes (must be multiple of 4096) **Optional Arguments**: +---------------------------------------------+-------------------------------------------------------------------------------+ | Parameter | Description | +=============================================+===============================================================================+ -| ``-h`` \ ``--help`` | Show the help message and exit | +| ``-h`` / ``--help`` | Show the help message and exit | +---------------------------------------------+-------------------------------------------------------------------------------+ | ``--version {1,2}`` | Set multipage blob version (Default: Version 2) | | | | @@ -282,19 +305,20 @@ Generate Encrypted NVS Partition **Optional Arguments (HMAC scheme-specific)**: - +---------------------------------------------+-------------------------------------------------------------------------------+ - | Parameter | Description | - +=============================================+===============================================================================+ - | ``--key_protect_hmac`` | If set, the NVS encryption key protection scheme based on HMAC | - | | peripheral is used; else the default scheme based on Flash Encryption | - | | is used | - +---------------------------------------------+-------------------------------------------------------------------------------+ - | ``--kp_hmac_keygen`` | Generate the HMAC key for HMAC-based encryption scheme | - +---------------------------------------------+-------------------------------------------------------------------------------+ - | ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` | Path to output HMAC key file | - +---------------------------------------------+-------------------------------------------------------------------------------+ - | ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` | File having the HMAC key for generating the NVS encryption keys | - +---------------------------------------------+-------------------------------------------------------------------------------+ + .. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``--key_protect_hmac`` + - If set, the NVS encryption key protection scheme based on HMAC peripheral is used; else the default scheme based on flash encryption is used + * - ``--kp_hmac_keygen`` + - Generate the HMAC key for HMAC-based encryption scheme + * - ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` + - Path to output HMAC key file + * - ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` + - File having the HMAC key for generating the NVS encryption keys You can run the utility to encrypt NVS partition using the command below. A sample CSV file is provided with the utility: @@ -306,7 +330,7 @@ You can run the utility to encrypt NVS partition using the command below. A samp .. only:: SOC_HMAC_SUPPORTED - - To generate an encrypted partition using the HMAC-based scheme, the above command can be used alongwith some additional parameters. + - To generate an encrypted partition using the HMAC-based scheme, the above command can be used along with some additional parameters. - Encrypt by allowing the utility to generate encryption keys and the HMAC-key:: @@ -343,33 +367,39 @@ Decrypt Encrypted NVS Partition **Positional Arguments**: -+--------------+---------------------------------------------------------------+ -| Parameter | Description | -+==============+===============================================================+ -| ``input`` | Path to encrypted NVS partition file to parse | -+--------------+---------------------------------------------------------------+ -| ``key`` | Path to file having keys for decryption | -+--------------+---------------------------------------------------------------+ -| ``output`` | Path to output decrypted binary file | -+--------------+---------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``input`` + - Path to encrypted NVS partition file to parse + * - ``key`` + - Path to file having keys for decryption + * - ``output`` + - Path to output decrypted binary file **Optional Arguments**: -+------------------------+----------------------------------------------------------------------+ -| Parameter | Description | -+========================+======================================================================+ -| ``-h`` / ``--help`` | Show the help message and exit | -+------------------------+----------------------------------------------------------------------+ -| ``--outdir OUTDIR`` | Output directory to store file created (Default: current directory) | -+------------------------+----------------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``-h`` / ``--help`` + - Show the help message and exit + * - ``--outdir OUTDIR`` + - Output directory to store files created. (Default: current directory) You can run the utility to decrypt encrypted NVS partition using the command below:: python nvs_partition_gen.py decrypt sample_encr.bin sample_keys.bin sample_decr.bin You can also provide the format version number: - - Multipage Blob Support Disabled (Version 1) - - Multipage Blob Support Enabled (Version 2) + - Multipage blob support disabled (Version 1) + - Multipage blob support enabled (Version 2) Multipage Blob Support Disabled (Version 1) diff --git a/components/nvs_flash/nvs_partition_generator/README_CN.rst b/components/nvs_flash/nvs_partition_generator/README_CN.rst index 05615c03475..785a49bbe5a 100644 --- a/components/nvs_flash/nvs_partition_generator/README_CN.rst +++ b/components/nvs_flash/nvs_partition_generator/README_CN.rst @@ -1,23 +1,25 @@ NVS 分区生成程序 -=============================== +================ :link_to_translation:`en:[English]` 介绍 ------------- +---- -NVS 分区生成程序 (:component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py`) 根据 CSV 文件中的键值对生成二进制文件。该二进制文件与 :doc:`非易失性存储器 (NVS) ` 中定义的 NVS 结构兼容。NVS 分区生成程序适合用于生成二进制数据(Blob),其中包括设备生产时可从外部烧录的 ODM/OEM 数据。这也使得生产制造商在使用同一个应用固件的基础上,通过自定义参数,如序列号,为每个设备生成不同配置的二进制 NVS 分区。 +NVS 分区生成程序 (:component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py`) 根据 CSV 文件中的键值对生成二进制文件。该二进制文件与 :doc:`nvs_flash` 中定义的 NVS 结构兼容。 + +NVS 分区生成程序适合用于生成二进制数据 (blob),其中包括设备生产时可从外部烧录的 ODM/OEM 数据。这也使得生产制造商在使用同一个应用固件的基础上,通过自定义参数,如序列号,为每个设备生成不同配置的二进制 NVS 分区。 准备工作 -------------- +-------- 在加密模式下使用该程序,需安装下列软件包: - - cryptography package + - ``cryptography`` 根目录下的 `requirements.txt` 包含必需 python 包,请预先安装。 CSV 文件格式 ---------------- +~~~~~~~~~~~~ CSV 文件每行需包含四个参数,以逗号隔开。具体参数描述见下表: @@ -63,31 +65,27 @@ CSV 文件每行需包含四个参数,以逗号隔开。具体参数描述见 NVS 条目和命名空间 (namespace) 的关联 ------------------------------------------ +------------------------------------- 如 CSV 文件中出现命名空间条目,后续条目均会被视为该命名空间的一部分,直至找到下一个命名空间条目。找到新命名空间条目后,后续所有条目都会被视为新命名空间的一部分。 .. note:: CSV 文件中第一个条目应始终为 ``namespace``。 -支持多页 Blob ----------------------- - -默认情况下,二进制 Blob 可跨多页,格式参考 :ref:`structure_of_entry` 章节。如需使用旧版格式,可在程序中禁用该功能。 +支持多页 blob +------------- +默认情况下,二进制 blob 可跨多页,格式参考 :ref:`structure_of_entry` 章节。如需使用旧版格式,可在程序中禁用该功能。 -支持加密 -------------------- -NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。更多信息详见 :ref:`nvs_encryption`。 +支持加解密 +---------- +NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件或对此类文件进行解密。更多信息详见 :ref:`nvs_encryption`。 -支持解密 -------------------- -如果 NVS 二进制文件采用了 XTS-AES 加密,该程序还可对此类文件进行解密,更多信息详见 :ref:`nvs_encryption`。 运行程序 -------------------- +-------- **使用方法**:: @@ -95,77 +93,100 @@ NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。 **可选参数**: -+------+------------+----------------------+ -| 序号 | 参数 | 描述 | -+------+------------+----------------------+ -| 1 | -h, --help | 显示帮助信息并退出 | -+------+------------+----------------------+ +.. list-table:: + :widths: 20 40 40 + :header-rows: 1 + + * - 序号 + - 参数 + - 描述 + * - 1 + - ``-h`` / ``--help`` + - 显示帮助信息并退出 -**命令**:: +**命令**: - 运行 nvs_partition_gen.py {command} -h 查看更多帮助信息 + 运行 ``nvs_partition_gen.py {command} -h`` 查看更多帮助信息 -+------+--------------+---------------+ -| 序号 | 参数 | 描述 | -+------+--------------+---------------+ -| 1 | generate | 生成 NVS 分区 | -+------+--------------+---------------+ -| 2 | generate-key | 生成加密密钥 | -+------+--------------+---------------+ -| 3 | encrypt | 加密 NVS 分区 | -+------+--------------+---------------+ -| 4 | decrypt | 解密 NVS 分区 | -+------+--------------+---------------+ +.. list-table:: + :widths: 20 40 40 + :header-rows: 1 + + * - 序号 + - 参数 + - 描述 + * - 1 + - ``generate`` + - 生成 NVS 分区 + * - 2 + - ``generate-key`` + - 生成加密密钥 + * - 3 + - ``encrypt`` + - 加密 NVS 分区 + * - 4 + - ``decrypt`` + - 解密 NVS 分区 生成 NVS 分区(默认模式) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~ **使用方法**:: - python nvs_partition_gen.py generate [-h] [--version {1,2}] [--outdir OUTDIR] - input output size + python nvs_partition_gen.py generate [-h] [--version {1,2}] [--outdir OUTDIR] input output size **位置参数**: -+--------+--------------------------------------------------+ -| 参数 | 描述 | -+--------+--------------------------------------------------+ -| input | 待解析的 CSV 文件路径 | -+--------+--------------------------------------------------+ -| output | NVS 二进制文件的输出路径 | -+--------+--------------------------------------------------+ -| size | NVS 分区大小(以字节为单位,且为 4096 的整数倍) | -+--------+--------------------------------------------------+ - -**可选参数**: +.. list-table:: + :widths: 30 70 + :header-rows: 1 -+-----------------+------------------------------------------------+ -| 参数 | 描述 | -+-----------------+------------------------------------------------+ -| -h, --help | 显示帮助信息并退出 | -+-----------------+------------------------------------------------+ -| --version {1,2} | - 设置多页 Blob 版本。 | -| | - 版本 1:禁用多页 Blob; | -| | - 版本 2:启用多页 Blob; | -| | - 默认版本:版本 2。 | -+-----------------+------------------------------------------------+ -| --outdir OUTDIR | 输出目录,用于存储创建的文件。(默认当前目录) | -+-----------------+------------------------------------------------+ + * - 参数 + - 描述 + * - ``input`` + - 待解析的 CSV 文件路径 + * - ``output`` + - NVS 二进制文件的输出路径 + * - ``size`` + - NVS 分区大小(以字节为单位,且为 4096 的整数倍) +**可选参数**: ++--------------------------+------------------------------------------------+ +| 参数 | 描述 | ++--------------------------+------------------------------------------------+ +| ``-h`` / ``--help`` | 显示帮助信息并退出 | ++--------------------------+------------------------------------------------+ +| ``--version {1,2}`` | - 设置多页 blob 版本,默认为版本 2。 | +| | | +| | - 版本 1:禁用多页 blob; | +| | | +| | - 版本 2:启用多页 blob。 | ++--------------------------+------------------------------------------------+ +| ``--outdir OUTDIR`` | 输出目录,用于存储创建的文件。(默认当前目录) | ++--------------------------+------------------------------------------------+ 运行如下命令创建 NVS 分区,该程序同时会提供 CSV 示例文件:: python nvs_partition_gen.py generate sample_singlepage_blob.csv sample.bin 0x3000 -仅生成加密密钥分区 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +生成加密密钥分区 +~~~~~~~~~~~~~~~~ -**使用方法**:: +.. only:: SOC_HMAC_SUPPORTED + + **使用方法**:: + + python nvs_partition_gen.py generate-key [-h] [--key_protect_hmac] [--kp_hmac_keygen] + [--kp_hmac_keyfile KP_HMAC_KEYFILE] [--kp_hmac_inputkey KP_HMAC_INPUTKEY] + [--keyfile KEYFILE] [--outdir OUTDIR] - python nvs_partition_gen.py generate-key [-h] [--keyfile KEYFILE] - [--outdir OUTDIR] +.. only:: not SOC_HMAC_SUPPORTED + + **使用方法**:: + + python nvs_partition_gen.py generate-key [-h] [--keyfile KEYFILE] [--outdir OUTDIR] **可选参数**: @@ -175,61 +196,129 @@ NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。 * - 参数 - 描述 - * - -h, --help + * - ``-h`` / ``--help`` - 显示帮助信息并退出 - * - --keyfile KEYFILE + * - ``--keyfile KEYFILE`` - 加密密钥分区文件的输出路径 - * - --outdir OUTDIR + * - ``--outdir OUTDIR`` - 输出目录,用于存储创建的文件(默认当前目录) +.. only:: SOC_HMAC_SUPPORTED + + **可选参数(仅适用于 HMAC 方案)**: + + .. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``--key_protect_hmac`` + - 设置后使用基于 HMAC 的 NVS 加密密钥保护方案,否则使用基于 flash 加密的默认方案 + * - ``--kp_hmac_keygen`` + - 为基于 HMAC 的加密方案生成 HMAC 密钥 + * - ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` + - HMAC 密钥文件的输出路径 + * - ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` + - 包含 HMAC 密钥的文件,用于生成 NVS 加密密钥 + 运行以下命令仅生成加密密钥分区:: python nvs_partition_gen.py generate-key +.. only:: SOC_HMAC_SUPPORTED + + 运行以下命令,为基于 HMAC 的方案生成加密密钥: + + - 生成 HMAC 密钥和 NVS 加密密钥:: + + python nvs_partition_gen.py generate-key --key_protect_hmac --kp_hmac_keygen + + .. note:: 上述命令生成 ``/keys/keys-.bin`` 格式的加密密钥和 ``/keys/hmac-keys-.bin`` 格式的 HMAC 密钥。 + + - 基于 HMAC 密钥生成 NVS 加密密钥:: + + python nvs_partition_gen.py generate-key --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin + + .. note:: 可将自定义文件名作为参数提供给 HMAC 密钥和加密密钥。 + 生成 NVS 加密分区 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~ -**使用方法**:: +.. only:: SOC_HMAC_SUPPORTED + + **使用方法**:: + + python nvs_partition_gen.py encrypt [-h] [--version {1,2}] [--keygen] + [--keyfile KEYFILE] [--inputkey INPUTKEY] [--outdir OUTDIR] + [--key_protect_hmac] [--kp_hmac_keygen] + [--kp_hmac_keyfile KP_HMAC_KEYFILE] [--kp_hmac_inputkey KP_HMAC_INPUTKEY] + input output size + +.. only:: not SOC_HMAC_SUPPORTED + + **使用方法**:: + + python nvs_partition_gen.py encrypt [-h] [--version {1,2}] [--keygen] + [--keyfile KEYFILE] [--inputkey INPUTKEY] [--outdir OUTDIR] + input output size - python nvs_partition_gen.py encrypt [-h] [--version {1,2}] [--keygen] - [--keyfile KEYFILE] [--inputkey INPUTKEY] - [--outdir OUTDIR] - input output size **位置参数**: -+--------+--------------------------------------+ -| 参数 | 描述 | -+--------+--------------------------------------+ -| input | 待解析 CSV 文件的路径 | -+--------+--------------------------------------+ -| output | NVS 二进制文件的输出路径 | -+--------+--------------------------------------+ -| size | NVS 分区大小 | -| | (以字节为单位,且为 4096 的整数倍) | -+--------+--------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``input`` + - 待解析的 CSV 文件路径 + * - ``output`` + - NVS 二进制文件的输出路径 + * - ``size`` + - NVS 分区大小(以字节为单位,且为 4096 的整数倍) **可选参数**: -+---------------------+------------------------------+ -| 参数 | 描述 | -+---------------------+------------------------------+ -| -h, --help | 显示帮助信息并退出 | -+---------------------+------------------------------+ -| --version {1,2} | - 设置多页 Blob 版本。 | -| | - 版本 1:禁用多页 Blob; | -| | - 版本 2:启用多页 Blob; | -| | - 默认版本:版本 2。 | -+---------------------+------------------------------+ -| --keygen | 生成 NVS 分区加密密钥 | -+---------------------+------------------------------+ -| --keyfile KEYFILE | 密钥文件的输出路径 | -+---------------------+------------------------------+ -| --inputkey INPUTKEY | 内含 NVS 分区加密密钥的文件 | -+---------------------+------------------------------+ -| --outdir OUTDIR | 输出目录,用于存储创建的文件 | -| | (默认当前目录) | -+---------------------+------------------------------+ ++--------------------------+------------------------------------------------+ +| 参数 | 描述 | ++--------------------------+------------------------------------------------+ +| ``-h`` / ``--help`` | 显示帮助信息并退出 | ++--------------------------+------------------------------------------------+ +| ``--version {1,2}`` | - 设置多页 blob 版本,默认为版本 2。 | +| | | +| | - 版本 1:禁用多页 blob; | +| | | +| | - 版本 2:启用多页 blob。 | ++--------------------------+------------------------------------------------+ +| ``--keygen`` | 生成 NVS 分区加密密钥 | ++--------------------------+------------------------------------------------+ +| ``--keyfile KEYFILE`` | 密钥文件的输出路径 | ++--------------------------+------------------------------------------------+ +| ``--inputkey INPUTKEY`` | 内含 NVS 分区加密密钥的文件 | ++--------------------------+------------------------------------------------+ +| ``--outdir OUTDIR`` | 输出目录,用于存储创建的文件。(默认当前目录) | ++--------------------------+------------------------------------------------+ + +.. only:: SOC_HMAC_SUPPORTED + + **可选参数(仅适用于 HMAC 方案)**: + + .. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``--key_protect_hmac`` + - 设置后使用基于 HMAC 的 NVS 加密密钥保护方案,否则使用基于 flash 加密的默认方案 + * - ``--kp_hmac_keygen`` + - 为基于 HMAC 的加密方案生成 HMAC 密钥 + * - ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` + - HMAC 密钥文件的输出路径 + * - ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` + - 包含 HMAC 密钥的文件,用于生成 NVS 加密密钥 运行以下命令加密 NVS 分区,该程序同时会提供一个 CSV 示例文件。 @@ -237,21 +326,40 @@ NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。 python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen -.. note:: 创建的加密密钥格式为 ``/keys/keys-.bin``。 + .. note:: 创建的加密密钥格式为 ``/keys/keys-.bin``。 + +.. only:: SOC_HMAC_SUPPORTED + + - 要使用基于 HMAC 的方案生成加密分区,可将上述命令与附加参数搭配使用。 + + - 通过 NVS 分区生成程序生成加密密钥和 HMAC 密钥,从而进行加密:: + + python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen --key_protect_hmac --kp_hmac_keygen + + .. note:: 上述命令生成 ``/keys/keys-.bin`` 格式的加密密钥和 ``/keys/hmac-keys-.bin`` 格式的 HMAC 密钥。 + + - 通过 NVS 分区生成程序使用用户提供的 HMAC 密钥生成加密密钥,从而进行加密:: + + python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin + + .. note:: 可将自定义文件名作为参数提供给 HMAC 密钥和加密密钥。 - 通过 NVS 分区生成程序生成加密密钥,并将密钥存储于自定义的文件中:: python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen --keyfile sample_keys.bin -.. note:: 创建的加密密钥格式为 ``/keys/keys-.bin``。 -.. note:: 加密密钥存储于新建文件的 ``keys/`` 目录下,与 NVS 密钥分区结构兼容。更多信息请参考 :ref:`nvs_encr_key_partition`。 +.. note:: + + - 创建的加密密钥格式为 ``/keys/sample_keys.bin``。 + + - 加密密钥存储于新建文件的 ``keys/`` 目录下,与 NVS 密钥分区结构兼容。更多信息请参考 :ref:`nvs_encr_key_partition`。 - 将加密密钥用作二进制输入文件来进行加密:: python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --inputkey sample_keys.bin 解密 NVS 分区 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~ **使用方法**:: @@ -259,58 +367,65 @@ NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。 **位置参数**: -+--------+-------------------------------+ -| 参数 | 描述 | -+--------+-------------------------------+ -| input | 待解析的 NVS 加密分区文件路径 | -+--------+-------------------------------+ -| key | 含有解密密钥的文件路径 | -+--------+-------------------------------+ -| output | 已解密的二进制文件输出路径 | -+--------+-------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``input`` + - 待解析的 NVS 加密分区文件路径 + * - ``key`` + - 含有解密密钥的文件路径 + * - ``output`` + - 已解密的二进制文件输出路径 **可选参数**: -+-----------------+------------------------------+ -| 参数 | 描述 | -+-----------------+------------------------------+ -| -h, --help | 显示帮助信息并退出 | -+-----------------+------------------------------+ -| --outdir OUTDIR | 输出目录,用于存储创建的文件 | -| | (默认当前目录) | -+-----------------+------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``-h`` / ``--help`` + - 显示帮助信息并退出 + * - ``--outdir OUTDIR`` + - 输出目录,用于存储创建的文件(默认当前目录) 运行以下命令解密已加密的 NVS 分区:: python nvs_partition_gen.py decrypt sample_encr.bin sample_keys.bin sample_decr.bin -您可以自定义格式版本号: -- 版本 1:禁用多页 Blob -- 版本 2:启用多页 Blob +可以在命令中提供版本参数,选择格式版本号: + - 版本 1:禁用多页 blob + - 版本 2:启用多页 blob -版本 1:禁用多页 Blob -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +版本 1:禁用多页 blob +~~~~~~~~~~~~~~~~~~~~~ -如需禁用多页 Blob,请按照如下命令将版本参数设置为 1,以此格式运行分区生成程序。该程序同时会提供一个 CSV 示例文件:: +如需禁用多页 blob,请按照如下命令将版本参数设置为 1,以此格式运行分区生成程序。该程序同时会提供一个 CSV 示例文件:: python nvs_partition_gen.py generate sample_singlepage_blob.csv sample.bin 0x3000 --version 1 -版本 2:启用多页 Blob -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +版本 2:启用多页 blob +~~~~~~~~~~~~~~~~~~~~~ -如需启用多页 Blob,请按照如下命令将版本参数设置为 2,以此格式运行分区生成程序。该程序同时会提供一个 CSV 示例文件:: +如需启用多页 blob,请按照如下命令将版本参数设置为 2,以此格式运行分区生成程序。该程序同时会提供一个 CSV 示例文件:: python nvs_partition_gen.py generate sample_multipage_blob.csv sample.bin 0x4000 --version 2 -.. note:: NVS 分区最小为 0x3000 字节。 +.. note:: + + - NVS 分区最小为 0x3000 字节。 -.. note:: 将二进制文件烧录至设备时,请确保与应用的 sdkconfig 设置一致。 + - 将二进制文件烧录至设备时,请确保与应用的 sdkconfig 设置一致。 说明 -------- +---- - 分区生成程序不会对重复键进行检查,而将数据同时写入这两个重复键中。请注意不要使用同名的键; - 新页面创建后,前一页的空白处不会再写入数据。CSV 文件中的字段须按次序排列以优化内存; diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index b69bcfbdaf3..5fcf39c9650 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "nvs_page.hpp" +#include #include #include #include @@ -1063,7 +1064,8 @@ const char* Page::pageStateToName(PageState ps) void Page::debugDump() const { - printf("state=%x (%s) addr=%x seq=%d\nfirstUsed=%d nextFree=%d used=%d erased=%d\n", (uint32_t) mState, pageStateToName(mState), mBaseAddress, mSeqNumber, static_cast(mFirstUsedEntry), static_cast(mNextFreeEntry), mUsedEntryCount, mErasedEntryCount); + printf("state=%" PRIx32 " (%s) addr=%" PRIx32 " seq=%" PRIu32 "\nfirstUsed=%" PRIu32 " nextFree=%" PRIu32 " used=%" PRIu16 " erased=%" PRIu16 "\n", + static_cast(mState), pageStateToName(mState), mBaseAddress, mSeqNumber, static_cast(mFirstUsedEntry), static_cast(mNextFreeEntry), mUsedEntryCount, mErasedEntryCount); size_t skip = 0; for (size_t i = 0; i < ENTRY_COUNT; ++i) { printf("%3d: ", static_cast(i)); @@ -1080,7 +1082,8 @@ void Page::debugDump() const Item item; readEntry(i, item); if (skip == 0) { - printf("W ns=%2u type=%2u span=%3u key=\"%s\" chunkIdx=%d len=%d\n", item.nsIndex, static_cast(item.datatype), item.span, item.key, item.chunkIndex, (item.span != 1)?((int)item.varLength.dataSize):-1); + printf("W ns=%2" PRIu8 " type=%2" PRIu8 " span=%3" PRIu8 " key=\"%s\" chunkIdx=%" PRIu8 " len=%" PRIi32 "\n", + item.nsIndex, static_cast(item.datatype), item.span, item.key, item.chunkIndex, (item.span != 1)?(static_cast(item.varLength.dataSize)):(-1)); if (item.span > 0 && item.span <= ENTRY_COUNT - i) { skip = item.span - 1; } else { diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index 3f0300f07c0..d18ec6b8924 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -353,4 +353,12 @@ menu "OpenThread" Select this option to enable time synchronization feature, the devices in the same Thread network could sync to the same network time. + config OPENTHREAD_RADIO_STATS_ENABLE + bool "Enable Radio Statistics feature" + depends on OPENTHREAD_FTD || OPENTHREAD_MTD + default n + help + Select this option to enable the radio statistics feature, you can use radio command to print some radio + Statistics informations. + endmenu 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 0da476f5e1a..b27bc539634 100644 --- a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h @@ -579,4 +579,15 @@ #define OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1 #endif +/** + * @def OPENTHREAD_CONFIG_RADIO_STATS_ENABLE + * + * Set to 1 to enable support for Radio Statistics. Note that this option only works for OPENTHREAD_FTD and + * OPENTHREAD_MTD. + * + */ +#if CONFIG_OPENTHREAD_RADIO_STATS_ENABLE +#define OPENTHREAD_CONFIG_RADIO_STATS_ENABLE 1 +#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 e5980244b70..f706d364e2d 100644 --- a/components/openthread/private_include/openthread-core-esp32x-mtd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-mtd-config.h @@ -263,4 +263,15 @@ #define OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1 #endif +/** + * @def OPENTHREAD_CONFIG_RADIO_STATS_ENABLE + * + * Set to 1 to enable support for Radio Statistics. Note that this option only works for OPENTHREAD_FTD and + * OPENTHREAD_MTD. + * + */ +#if CONFIG_OPENTHREAD_RADIO_STATS_ENABLE +#define OPENTHREAD_CONFIG_RADIO_STATS_ENABLE 1 +#endif + #define OPENTHREAD_MTD 1 diff --git a/components/protocomm/include/transports/protocomm_ble.h b/components/protocomm/include/transports/protocomm_ble.h index 085767625ea..51aec06e99f 100644 --- a/components/protocomm/include/transports/protocomm_ble.h +++ b/components/protocomm/include/transports/protocomm_ble.h @@ -59,6 +59,35 @@ typedef struct name_uuid { uint16_t uuid; } protocomm_ble_name_uuid_t; +/** + * @brief Structure for BLE events in Protocomm. + */ +typedef struct { + /** + * This field indicates the type of BLE event that occurred. + */ + uint16_t evt_type; + /** + * The handle of the relevant connection. + */ + uint16_t conn_handle; + + union { + /** + * The status of the connection attempt; + * o 0: the connection was successfully established. + * o BLE host error code: the connection attempt failed for + * the specified reason. + */ + uint16_t conn_status; + + /** + * Return code indicating the reason for the disconnect. + */ + uint16_t disconnect_reason; + }; +} protocomm_ble_event_t; + /** * @brief Config parameters for protocomm BLE service */ diff --git a/components/protocomm/src/simple_ble/simple_ble.c b/components/protocomm/src/simple_ble/simple_ble.c index 426fcc2dce5..a4184b52624 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-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,7 +8,9 @@ #include #include #include +#ifdef CONFIG_BT_CONTROLLER_ENABLED #include "esp_bt.h" +#endif #include #include #include @@ -213,6 +215,7 @@ esp_err_t simple_ble_start(simple_ble_cfg_t *cfg) ESP_LOGD(TAG, "Free mem at start of simple_ble_init %" PRIu32, esp_get_free_heap_size()); esp_err_t ret; +#ifdef CONFIG_BT_CONTROLLER_ENABLED esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); if (ret) { @@ -232,6 +235,7 @@ esp_err_t simple_ble_start(simple_ble_cfg_t *cfg) ESP_LOGE(TAG, "%s enable controller failed %d", __func__, ret); return ret; } +#endif esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); ret = esp_bluedroid_init_with_cfg(&bluedroid_cfg); @@ -307,6 +311,7 @@ esp_err_t simple_ble_stop(void) return err; } ESP_LOGD(TAG, "esp_bluedroid_deinit called successfully"); +#ifdef CONFIG_BT_CONTROLLER_ENABLED err = esp_bt_controller_disable(); if (err != ESP_OK) { return ESP_FAIL; @@ -321,7 +326,7 @@ esp_err_t simple_ble_stop(void) return ESP_FAIL; } ESP_LOGD(TAG, "esp_bt_controller_deinit called successfully"); - +#endif ESP_LOGD(TAG, "Free mem at end of simple_ble_stop %" PRIu32, esp_get_free_heap_size()); return ESP_OK; } diff --git a/components/protocomm/src/transports/protocomm_ble.c b/components/protocomm/src/transports/protocomm_ble.c index 6c070e4001d..322c6086411 100644 --- a/components/protocomm/src/transports/protocomm_ble.c +++ b/components/protocomm/src/transports/protocomm_ble.c @@ -345,7 +345,13 @@ static void transport_simple_ble_disconnect(esp_gatts_cb_event_t event, esp_gatt if (ret != ESP_OK) { ESP_LOGE(TAG, "error closing the session after disconnect"); } else { - if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_DISCONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { + protocomm_ble_event_t ble_event = {}; + /* Assign the event type */ + ble_event.evt_type = PROTOCOMM_TRANSPORT_BLE_DISCONNECTED; + /* Set the Disconnection handle */ + ble_event.conn_handle = param->disconnect.conn_id; + + if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_DISCONNECTED, &ble_event, sizeof(protocomm_ble_event_t), portMAX_DELAY) != ESP_OK) { ESP_LOGE(TAG, "Failed to post transport disconnection event"); } } @@ -371,7 +377,13 @@ static void transport_simple_ble_connect(esp_gatts_cb_event_t event, esp_gatt_if if (ret != ESP_OK) { ESP_LOGE(TAG, "error creating the session"); } else { - if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_CONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { + protocomm_ble_event_t ble_event = {}; + /* Assign the event type */ + ble_event.evt_type = PROTOCOMM_TRANSPORT_BLE_CONNECTED; + /* Set the Connection handle */ + ble_event.conn_handle = param->connect.conn_id; + + if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_CONNECTED, &ble_event, sizeof(protocomm_ble_event_t), portMAX_DELAY) != ESP_OK) { ESP_LOGE(TAG, "Failed to post transport pairing event"); } } diff --git a/components/protocomm/src/transports/protocomm_nimble.c b/components/protocomm/src/transports/protocomm_nimble.c index 29db3940714..1f6e5565783 100644 --- a/components/protocomm/src/transports/protocomm_nimble.c +++ b/components/protocomm/src/transports/protocomm_nimble.c @@ -569,7 +569,14 @@ static void transport_simple_ble_disconnect(struct ble_gap_event *event, void *a if (ret != ESP_OK) { ESP_LOGE(TAG, "error closing the session after disconnect"); } else { - if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_DISCONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { + protocomm_ble_event_t ble_event = {}; + /* Assign the event type */ + ble_event.evt_type = PROTOCOMM_TRANSPORT_BLE_DISCONNECTED; + /* Set the Disconnection handle */ + ble_event.conn_handle = event->disconnect.conn.conn_handle; + ble_event.disconnect_reason = event->disconnect.reason; + + if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_DISCONNECTED, &ble_event, sizeof(protocomm_ble_event_t), portMAX_DELAY) != ESP_OK) { ESP_LOGE(TAG, "Failed to post transport disconnection event"); } } @@ -595,7 +602,14 @@ static void transport_simple_ble_connect(struct ble_gap_event *event, void *arg) if (ret != ESP_OK) { ESP_LOGE(TAG, "error creating the session"); } else { - if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_CONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { + protocomm_ble_event_t ble_event = {}; + /* Assign the event type */ + ble_event.evt_type = PROTOCOMM_TRANSPORT_BLE_CONNECTED; + /* Set the Connection handle */ + ble_event.conn_handle = event->connect.conn_handle; + ble_event.conn_status = event->connect.status; + + if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_CONNECTED, &ble_event, sizeof(protocomm_ble_event_t), portMAX_DELAY) != ESP_OK) { ESP_LOGE(TAG, "Failed to post transport pairing event"); } } diff --git a/components/sdmmc/CMakeLists.txt b/components/sdmmc/CMakeLists.txt index da638db5771..0b65cf19b5d 100644 --- a/components/sdmmc/CMakeLists.txt +++ b/components/sdmmc/CMakeLists.txt @@ -13,5 +13,3 @@ idf_component_register(SRCS "sdmmc_cmd.c" INCLUDE_DIRS include REQUIRES driver PRIV_REQUIRES soc esp_timer) - -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index 4b626129ccd..1a3e331d542 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "esp_timer.h" #include "sdmmc_common.h" @@ -19,15 +20,15 @@ esp_err_t sdmmc_send_cmd(sdmmc_card_t* card, sdmmc_command_t* cmd) } int slot = card->host.slot; - ESP_LOGV(TAG, "sending cmd slot=%d op=%d arg=%x flags=%x data=%p blklen=%d datalen=%d timeout=%d", - slot, cmd->opcode, cmd->arg, cmd->flags, cmd->data, cmd->blklen, cmd->datalen, cmd->timeout_ms); + ESP_LOGV(TAG, "sending cmd slot=%d op=%" PRIu32 " arg=%" PRIx32 " flags=%x data=%p blklen=%" PRIu32 " datalen=%" PRIu32 " timeout=%" PRIu32, + slot, cmd->opcode, cmd->arg, cmd->flags, cmd->data, (uint32_t) cmd->blklen, (uint32_t) cmd->datalen, cmd->timeout_ms); esp_err_t err = (*card->host.do_transaction)(slot, cmd); if (err != 0) { - ESP_LOGD(TAG, "cmd=%d, sdmmc_req_run returned 0x%x", cmd->opcode, err); + ESP_LOGD(TAG, "cmd=%" PRIu32 ", sdmmc_req_run returned 0x%x", cmd->opcode, err); return err; } int state = MMC_R1_CURRENT_STATE(cmd->response); - ESP_LOGV(TAG, "cmd response %08x %08x %08x %08x err=0x%x state=%d", + ESP_LOGV(TAG, "cmd response %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " err=0x%x state=%d", cmd->response[0], cmd->response[1], cmd->response[2], @@ -481,7 +482,7 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, return err; } if (++count % 16 == 0) { - ESP_LOGV(TAG, "waiting for card to become ready (%d)", count); + ESP_LOGV(TAG, "waiting for card to become ready (%" PRIu32 ")", (uint32_t) count); } } /* SPI mode: although card busy indication is based on the busy token, @@ -496,12 +497,12 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, return err; } if (status & SD_SPI_R2_CARD_LOCKED) { - ESP_LOGE(TAG, "%s: write failed, card is locked: r2=0x%04x", + ESP_LOGE(TAG, "%s: write failed, card is locked: r2=0x%04" PRIx32, __func__, status); return ESP_ERR_INVALID_STATE; } if (status != 0) { - ESP_LOGE(TAG, "%s: card status indicates an error after write operation: r2=0x%04x", + ESP_LOGE(TAG, "%s: card status indicates an error after write operation: r2=0x%04" PRIx32, __func__, status); return ESP_ERR_INVALID_RESPONSE; } @@ -687,7 +688,7 @@ esp_err_t sdmmc_erase_sectors(sdmmc_card_t* card, size_t start_sector, return err; } if (status != 0) { - ESP_LOGE(TAG, "%s: card status indicates an error after erase operation: r2=0x%04x", + ESP_LOGE(TAG, "%s: card status indicates an error after erase operation: r2=0x%04" PRIx32, __func__, status); return ESP_ERR_INVALID_RESPONSE; } diff --git a/components/sdmmc/sdmmc_common.c b/components/sdmmc/sdmmc_common.c index f55a48f6ba9..b57e67ef1a4 100644 --- a/components/sdmmc/sdmmc_common.c +++ b/components/sdmmc/sdmmc_common.c @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "sdmmc_common.h" static const char* TAG = "sdmmc_common"; @@ -52,14 +53,14 @@ esp_err_t sdmmc_init_ocr(sdmmc_card_t* card) return err; } } - ESP_LOGD(TAG, "host_ocr=0x%x card_ocr=0x%x", host_ocr, card->ocr); + ESP_LOGD(TAG, "host_ocr=0x%" PRIx32 " card_ocr=0x%" PRIx32, host_ocr, card->ocr); /* Clear all voltage bits in host's OCR which the card doesn't support. * Don't touch CCS bit because in SPI mode cards don't report CCS in ACMD41 * response. */ host_ocr &= (card->ocr | (~SD_OCR_VOL_MASK)); - ESP_LOGD(TAG, "sdmmc_card_init: host_ocr=%08x, card_ocr=%08x", host_ocr, card->ocr); + ESP_LOGD(TAG, "sdmmc_card_init: host_ocr=%08" PRIx32 ", card_ocr=%08" PRIx32, host_ocr, card->ocr); return ESP_OK; } @@ -286,12 +287,12 @@ void sdmmc_card_print_info(FILE* stream, const sdmmc_card_t* card) if (print_csd) { fprintf(stream, "CSD: ver=%d, sector_size=%d, capacity=%d read_bl_len=%d\n", - (card->is_mmc ? card->csd.csd_ver : card->csd.csd_ver + 1), + (int) (card->is_mmc ? card->csd.csd_ver : card->csd.csd_ver + 1), card->csd.sector_size, card->csd.capacity, card->csd.read_block_len); if (card->is_mmc) { - fprintf(stream, "EXT CSD: bus_width=%d\n", (1 << card->log_bus_width)); + fprintf(stream, "EXT CSD: bus_width=%" PRIu32 "\n", (uint32_t) (1 << card->log_bus_width)); } else if (!card->is_sdio){ // make sure card is SD - fprintf(stream, "SSR: bus_width=%d\n", (card->ssr.cur_bus_width ? 4 : 1)); + fprintf(stream, "SSR: bus_width=%" PRIu32 "\n", (uint32_t) (card->ssr.cur_bus_width ? 4 : 1)); } } if (print_scr) { diff --git a/components/sdmmc/sdmmc_io.c b/components/sdmmc/sdmmc_io.c index 1e2e069f4de..90051111ee4 100644 --- a/components/sdmmc/sdmmc_io.c +++ b/components/sdmmc/sdmmc_io.c @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "sdmmc_common.h" #include "esp_attr.h" #include "esp_compiler.h" @@ -240,7 +241,7 @@ esp_err_t sdmmc_io_read_byte(sdmmc_card_t* card, uint32_t function, { esp_err_t ret = sdmmc_io_rw_direct(card, function, addr, SD_ARG_CMD52_READ, out_byte); if (unlikely(ret != ESP_OK)) { - ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (read 0x%x) returned 0x%x", __func__, addr, ret); + ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (read 0x%" PRIx32 ") returned 0x%x", __func__, addr, ret); } return ret; } @@ -252,7 +253,7 @@ esp_err_t sdmmc_io_write_byte(sdmmc_card_t* card, uint32_t function, esp_err_t ret = sdmmc_io_rw_direct(card, function, addr, SD_ARG_CMD52_WRITE | SD_ARG_CMD52_EXCHANGE, &tmp_byte); if (unlikely(ret != ESP_OK)) { - ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (write 0x%x) returned 0x%x", __func__, addr, ret); + ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (write 0x%" PRIu32 ") returned 0x%x", __func__, addr, ret); return ret; } if (out_byte != NULL) { diff --git a/components/sdmmc/sdmmc_mmc.c b/components/sdmmc/sdmmc_mmc.c index c3940eb37de..4d0c756f0d5 100644 --- a/components/sdmmc/sdmmc_mmc.c +++ b/components/sdmmc/sdmmc_mmc.c @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include "sdmmc_common.h" @@ -298,7 +299,7 @@ uint32_t sdmmc_mmc_get_erase_timeout_ms(const sdmmc_card_t* card, int arg, size_ /* TODO: calculate erase timeout based on ext_csd (trim_timeout) */ uint32_t timeout_ms = SDMMC_SD_DISCARD_TIMEOUT * erase_size_kb / card->csd.sector_size; timeout_ms = MAX(1000, timeout_ms); - ESP_LOGD(TAG, "%s: erase timeout %u s (erasing %u kB, %ums per sector)", - __func__, timeout_ms / 1000, erase_size_kb, SDMMC_SD_DISCARD_TIMEOUT); + ESP_LOGD(TAG, "%s: erase timeout %" PRIu32 " s (erasing %" PRIu32 " kB, %" PRIu32 " ms per sector)", + __func__, (uint32_t) (timeout_ms / 1000), (uint32_t) erase_size_kb, (uint32_t) SDMMC_SD_DISCARD_TIMEOUT); return timeout_ms; } diff --git a/components/sdmmc/sdmmc_sd.c b/components/sdmmc/sdmmc_sd.c index 4111ed14e71..6275e7cf7ff 100644 --- a/components/sdmmc/sdmmc_sd.c +++ b/components/sdmmc/sdmmc_sd.c @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "esp_timer.h" #include "sdmmc_common.h" @@ -160,7 +161,7 @@ esp_err_t sdmmc_init_sd_wait_data_ready(sdmmc_card_t* card) return err; } if (++count % 16 == 0) { - ESP_LOGV(TAG, "waiting for card to become ready (%d)", count); + ESP_LOGV(TAG, "waiting for card to become ready (%" PRIu32 ")", count); } } return ESP_OK; @@ -210,12 +211,12 @@ esp_err_t sdmmc_send_cmd_switch_func(sdmmc_card_t* card, /* busy response is never sent */ } else if (resp_ver == 1) { if (SD_SFUNC_BUSY(resp->data, group) & (1 << function)) { - ESP_LOGD(TAG, "%s: response indicates function %d:%d is busy", + ESP_LOGD(TAG, "%s: response indicates function %" PRIu32 ":%" PRIu32 " is busy", __func__, group, function); return ESP_ERR_INVALID_STATE; } } else { - ESP_LOGD(TAG, "%s: got an invalid version of SWITCH_FUNC response: 0x%02x", + ESP_LOGD(TAG, "%s: got an invalid version of SWITCH_FUNC response: 0x%02" PRIx32, __func__, resp_ver); return ESP_ERR_INVALID_RESPONSE; } @@ -446,15 +447,15 @@ uint32_t sdmmc_sd_get_erase_timeout_ms(const sdmmc_card_t* card, int arg, size_t uint32_t timeout_sec = card->ssr.erase_offset + card->ssr.erase_timeout * (erase_size_kb + card->ssr.alloc_unit_kb - 1) / (card->ssr.erase_size_au * card->ssr.alloc_unit_kb); - ESP_LOGD(TAG, "%s: erase timeout %u s (erasing %u kB, ES=%u, ET=%u, EO=%u, AU=%u kB)", - __func__, timeout_sec, erase_size_kb, card->ssr.erase_size_au, - card->ssr.erase_timeout, card->ssr.erase_offset, card->ssr.alloc_unit_kb); + ESP_LOGD(TAG, "%s: erase timeout %" PRIu32 " s (erasing %" PRIu32 " kB, ES=%" PRIu32 ", ET=%" PRIu32 ", EO=%" PRIu32 ", AU=%" PRIu32 " kB)", + __func__, timeout_sec, (uint32_t) erase_size_kb, (uint32_t) card->ssr.erase_size_au, + (uint32_t) card->ssr.erase_timeout, (uint32_t) card->ssr.erase_offset, (uint32_t) card->ssr.alloc_unit_kb); return timeout_sec * 1000; } else { uint32_t timeout_ms = SDMMC_SD_DISCARD_TIMEOUT * erase_size_kb / card->csd.sector_size; timeout_ms = MAX(1000, timeout_ms); - ESP_LOGD(TAG, "%s: erase timeout %u s (erasing %u kB, %ums per sector)", - __func__, timeout_ms / 1000, erase_size_kb, SDMMC_SD_DISCARD_TIMEOUT); + ESP_LOGD(TAG, "%s: erase timeout %" PRIu32 " s (erasing %" PRIu32 " kB, %" PRIu32 " ms per sector)", + __func__, (uint32_t) (timeout_ms / 1000), (uint32_t) erase_size_kb, (uint32_t) SDMMC_SD_DISCARD_TIMEOUT); return timeout_ms; } } else { diff --git a/components/sdmmc/test/CMakeLists.txt b/components/sdmmc/test/CMakeLists.txt index edcf529ce1e..0648951eec3 100644 --- a/components/sdmmc/test/CMakeLists.txt +++ b/components/sdmmc/test/CMakeLists.txt @@ -2,4 +2,3 @@ idf_component_register(SRC_DIRS "." PRIV_INCLUDE_DIRS "." PRIV_REQUIRES cmock sdmmc test_utils ) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 0e433b9c2b6..9a5ea3f9fc3 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -419,6 +419,18 @@ config SOC_I2C_SUPPORT_10BIT_ADDR bool default y +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + config SOC_I2S_NUM int default 1 diff --git a/components/soc/esp32c3/include/soc/i2c_struct.h b/components/soc/esp32c3/include/soc/i2c_struct.h index ccd5fdb5b05..1009fedd6e0 100644 --- a/components/soc/esp32c3/include/soc/i2c_struct.h +++ b/components/soc/esp32c3/include/soc/i2c_struct.h @@ -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-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _SOC_I2C_STRUCT_H_ #define _SOC_I2C_STRUCT_H_ @@ -363,39 +355,8 @@ typedef volatile struct i2c_dev_s { uint32_t reserved_f4; uint32_t date; uint32_t reserved_fc; - uint32_t txfifo_start_addr; - uint32_t reserved_104; - uint32_t reserved_108; - uint32_t reserved_10c; - uint32_t reserved_110; - uint32_t reserved_114; - uint32_t reserved_118; - uint32_t reserved_11c; - uint32_t reserved_120; - uint32_t reserved_124; - uint32_t reserved_128; - uint32_t reserved_12c; - uint32_t reserved_130; - uint32_t reserved_134; - uint32_t reserved_138; - uint32_t reserved_13c; - uint32_t reserved_140; - uint32_t reserved_144; - uint32_t reserved_148; - uint32_t reserved_14c; - uint32_t reserved_150; - uint32_t reserved_154; - uint32_t reserved_158; - uint32_t reserved_15c; - uint32_t reserved_160; - uint32_t reserved_164; - uint32_t reserved_168; - uint32_t reserved_16c; - uint32_t reserved_170; - uint32_t reserved_174; - uint32_t reserved_178; - uint32_t reserved_17c; - uint32_t rxfifo_start_addr; + uint32_t txfifo_mem[32]; + uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; #ifdef __cplusplus diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 27ac1025f55..63e518f6549 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -196,6 +196,9 @@ #define SOC_I2C_SUPPORT_XTAL (1) #define SOC_I2C_SUPPORT_RTC (1) #define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (1U) diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index fd64e062981..fbca618fb76 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -539,6 +539,22 @@ config SOC_I2C_SUPPORT_10BIT_ADDR bool default y +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + bool + default y + config SOC_LP_I2C_NUM int default 1 @@ -1097,7 +1113,7 @@ config SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY config SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX int - default 32 + default 64 config SOC_FLASH_ENCRYPTION_XTS_AES bool diff --git a/components/soc/esp32c6/include/soc/i2c_struct.h b/components/soc/esp32c6/include/soc/i2c_struct.h index e6617dcf5e4..dce4371af42 100644 --- a/components/soc/esp32c6/include/soc/i2c_struct.h +++ b/components/soc/esp32c6/include/soc/i2c_struct.h @@ -948,34 +948,6 @@ typedef union { } i2c_date_reg_t; -/** Group: Address register */ -/** Type of txfifo_start_addr register - * I2C TXFIFO base address register - */ -typedef union { - struct { - /** txfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * This is the I2C txfifo first address. - */ - uint32_t txfifo_start_addr:32; - }; - uint32_t val; -} i2c_txfifo_start_addr_reg_t; - -/** Type of rxfifo_start_addr register - * I2C RXFIFO base address register - */ -typedef union { - struct { - /** rxfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * This is the I2C rxfifo first address. - */ - uint32_t rxfifo_start_addr:32; - }; - uint32_t val; -} i2c_rxfifo_start_addr_reg_t; - - typedef struct i2c_dev_t { volatile i2c_scl_low_period_reg_t scl_low_period; volatile i2c_ctr_reg_t ctr; @@ -1007,16 +979,15 @@ typedef struct i2c_dev_t { uint32_t reserved_088[28]; volatile i2c_date_reg_t date; uint32_t reserved_0fc; - volatile i2c_txfifo_start_addr_reg_t txfifo_start_addr; - uint32_t reserved_104[31]; - volatile i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; + volatile uint32_t txfifo_mem[32]; + volatile uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; extern i2c_dev_t LP_I2C; #ifndef __cplusplus -_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); +_Static_assert(sizeof(i2c_dev_t) == 0x200, "Invalid size of i2c_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index ed69e78246f..d82e4dba855 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -239,6 +239,10 @@ #define SOC_I2C_SUPPORT_XTAL (1) #define SOC_I2C_SUPPORT_RTC (1) #define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) +#define SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH (1) /*-------------------------- LP_I2C CAPS -------------------------------------*/ // ESP32-C6 has 1 LP_I2C @@ -451,7 +455,7 @@ #define SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY 1 /*-------------------------- Flash Encryption CAPS----------------------------*/ -#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (32) +#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64) #define SOC_FLASH_ENCRYPTION_XTS_AES 1 #define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index adc34fbbc83..3185323be1d 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -301,7 +301,15 @@ config SOC_ADC_RTC_MAX_BITWIDTH config SOC_ADC_CALIBRATION_V1_SUPPORTED bool - default n + default y + +config SOC_ADC_SELF_HW_CALI_SUPPORTED + bool + default y + +config SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED + bool + default y config SOC_ADC_TEMPERATURE_SHARE_INTR bool @@ -531,6 +539,22 @@ config SOC_I2C_SUPPORT_10BIT_ADDR bool default y +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + bool + default y + config SOC_I2S_NUM int default 1 @@ -1077,7 +1101,7 @@ config SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY config SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX int - default 32 + default 64 config SOC_FLASH_ENCRYPTION_XTS_AES bool diff --git a/components/soc/esp32h2/include/soc/efuse_reg.h b/components/soc/esp32h2/include/soc/efuse_reg.h index 0eb9572fe85..aaaaf8b2127 100644 --- a/components/soc/esp32h2/include/soc/efuse_reg.h +++ b/components/soc/esp32h2/include/soc/efuse_reg.h @@ -796,49 +796,147 @@ extern "C" { #define EFUSE_DISABLE_BLK_VERSION_MAJOR_M (EFUSE_DISABLE_BLK_VERSION_MAJOR_V << EFUSE_DISABLE_BLK_VERSION_MAJOR_S) #define EFUSE_DISABLE_BLK_VERSION_MAJOR_V 0x00000001U #define EFUSE_DISABLE_BLK_VERSION_MAJOR_S 7 -/** EFUSE_RESERVED_2_136 : R; bitpos: [31:8]; default: 0; - * reserved - */ -#define EFUSE_RESERVED_2_136 0x00FFFFFFU -#define EFUSE_RESERVED_2_136_M (EFUSE_RESERVED_2_136_V << EFUSE_RESERVED_2_136_S) -#define EFUSE_RESERVED_2_136_V 0x00FFFFFFU -#define EFUSE_RESERVED_2_136_S 8 +/** EFUSE_TEMP_CALIB : R; bitpos: [16:8]; default: 0; + * Temperature calibration data + */ +#define EFUSE_TEMP_CALIB 0x000001FFU +#define EFUSE_TEMP_CALIB_M (EFUSE_TEMP_CALIB_V << EFUSE_TEMP_CALIB_S) +#define EFUSE_TEMP_CALIB_V 0x000001FFU +#define EFUSE_TEMP_CALIB_S 8 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN0 : R; bitpos: [26:17]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN0 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN0_M (EFUSE_ADC1_AVE_INITCODE_ATTEN0_V << EFUSE_ADC1_AVE_INITCODE_ATTEN0_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN0_V 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN0_S 17 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN1 : R; bitpos: [31:27]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1 0x0000001FU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_M (EFUSE_ADC1_AVE_INITCODE_ATTEN1_V << EFUSE_ADC1_AVE_INITCODE_ATTEN1_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_V 0x0000001FU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_S 27 /** EFUSE_RD_SYS_PART1_DATA5_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA5_REG (DR_REG_EFUSE_BASE + 0x70) -/** EFUSE_SYS_DATA_PART1_5 : RO; bitpos: [31:0]; default: 0; - * Stores the fifth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_5 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_5_M (EFUSE_SYS_DATA_PART1_5_V << EFUSE_SYS_DATA_PART1_5_S) -#define EFUSE_SYS_DATA_PART1_5_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_5_S 0 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN1_1 : R; bitpos: [4:0]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_1 0x0000001FU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_M (EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_V << EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_V 0x0000001FU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_S 0 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN2 : R; bitpos: [14:5]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN2 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN2_M (EFUSE_ADC1_AVE_INITCODE_ATTEN2_V << EFUSE_ADC1_AVE_INITCODE_ATTEN2_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN2_V 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN2_S 5 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN3 : R; bitpos: [24:15]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN3 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN3_M (EFUSE_ADC1_AVE_INITCODE_ATTEN3_V << EFUSE_ADC1_AVE_INITCODE_ATTEN3_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN3_V 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN3_S 15 +/** EFUSE_ADC1_HI_DOUT_ATTEN0 : R; bitpos: [31:25]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN0 0x0000007FU +#define EFUSE_ADC1_HI_DOUT_ATTEN0_M (EFUSE_ADC1_HI_DOUT_ATTEN0_V << EFUSE_ADC1_HI_DOUT_ATTEN0_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN0_V 0x0000007FU +#define EFUSE_ADC1_HI_DOUT_ATTEN0_S 25 /** EFUSE_RD_SYS_PART1_DATA6_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA6_REG (DR_REG_EFUSE_BASE + 0x74) -/** EFUSE_SYS_DATA_PART1_6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_6 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_6_M (EFUSE_SYS_DATA_PART1_6_V << EFUSE_SYS_DATA_PART1_6_S) -#define EFUSE_SYS_DATA_PART1_6_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_6_S 0 +/** EFUSE_ADC1_HI_DOUT_ATTEN0_1 : R; bitpos: [2:0]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN0_1 0x00000007U +#define EFUSE_ADC1_HI_DOUT_ATTEN0_1_M (EFUSE_ADC1_HI_DOUT_ATTEN0_1_V << EFUSE_ADC1_HI_DOUT_ATTEN0_1_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN0_1_V 0x00000007U +#define EFUSE_ADC1_HI_DOUT_ATTEN0_1_S 0 +/** EFUSE_ADC1_HI_DOUT_ATTEN1 : R; bitpos: [12:3]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN1 0x000003FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN1_M (EFUSE_ADC1_HI_DOUT_ATTEN1_V << EFUSE_ADC1_HI_DOUT_ATTEN1_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN1_V 0x000003FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN1_S 3 +/** EFUSE_ADC1_HI_DOUT_ATTEN2 : R; bitpos: [22:13]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN2 0x000003FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN2_M (EFUSE_ADC1_HI_DOUT_ATTEN2_V << EFUSE_ADC1_HI_DOUT_ATTEN2_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN2_V 0x000003FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN2_S 13 +/** EFUSE_ADC1_HI_DOUT_ATTEN3 : R; bitpos: [31:23]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN3 0x000001FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN3_M (EFUSE_ADC1_HI_DOUT_ATTEN3_V << EFUSE_ADC1_HI_DOUT_ATTEN3_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN3_V 0x000001FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN3_S 23 /** EFUSE_RD_SYS_PART1_DATA7_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA7_REG (DR_REG_EFUSE_BASE + 0x78) -/** EFUSE_SYS_DATA_PART1_7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of the first part of system data. +/** EFUSE_ADC1_HI_DOUT_ATTEN3_1 : R; bitpos: [0]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN3_1 (BIT(0)) +#define EFUSE_ADC1_HI_DOUT_ATTEN3_1_M (EFUSE_ADC1_HI_DOUT_ATTEN3_1_V << EFUSE_ADC1_HI_DOUT_ATTEN3_1_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN3_1_V 0x00000001U +#define EFUSE_ADC1_HI_DOUT_ATTEN3_1_S 0 +/** EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF : R; bitpos: [4:1]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_S 1 +/** EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF : R; bitpos: [8:5]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_S 5 +/** EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF : R; bitpos: [12:9]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_S 9 +/** EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF : R; bitpos: [16:13]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_S 13 +/** EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF : R; bitpos: [20:17]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_S 17 +/** EFUSE_RESERVED_2_245 : R; bitpos: [31:21]; default: 0; + * reserved */ -#define EFUSE_SYS_DATA_PART1_7 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_7_M (EFUSE_SYS_DATA_PART1_7_V << EFUSE_SYS_DATA_PART1_7_S) -#define EFUSE_SYS_DATA_PART1_7_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_7_S 0 +#define EFUSE_RESERVED_2_245 0x000007FFU +#define EFUSE_RESERVED_2_245_M (EFUSE_RESERVED_2_245_V << EFUSE_RESERVED_2_245_S) +#define EFUSE_RESERVED_2_245_V 0x000007FFU +#define EFUSE_RESERVED_2_245_S 21 /** EFUSE_RD_USR_DATA0_REG register * Register $n of BLOCK3 (user). diff --git a/components/soc/esp32h2/include/soc/efuse_struct.h b/components/soc/esp32h2/include/soc/efuse_struct.h index 2ceb9fcefc1..a1029528ce6 100644 --- a/components/soc/esp32h2/include/soc/efuse_struct.h +++ b/components/soc/esp32h2/include/soc/efuse_struct.h @@ -636,10 +636,18 @@ typedef union { * Disables check of blk version major */ uint32_t disable_blk_version_major:1; - /** reserved_2_136 : R; bitpos: [31:8]; default: 0; - * reserved + /** temp_calib : R; bitpos: [16:8]; default: 0; + * Temperature calibration data + */ + uint32_t temp_calib:9; + /** adc1_ave_initcode_atten0 : R; bitpos: [26:17]; default: 0; + * ADC1 calibration data */ - uint32_t reserved_2_136:24; + uint32_t adc1_ave_initcode_atten0:10; + /** adc1_ave_initcode_atten1 : R; bitpos: [31:27]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ave_initcode_atten1:5; }; uint32_t val; } efuse_rd_sys_part1_data4_reg_t; @@ -649,10 +657,22 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_5 : RO; bitpos: [31:0]; default: 0; - * Stores the fifth 32 bits of the first part of system data. + /** adc1_ave_initcode_atten1_1 : R; bitpos: [4:0]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ave_initcode_atten1_1:5; + /** adc1_ave_initcode_atten2 : R; bitpos: [14:5]; default: 0; + * ADC1 calibration data */ - uint32_t sys_data_part1_5:32; + uint32_t adc1_ave_initcode_atten2:10; + /** adc1_ave_initcode_atten3 : R; bitpos: [24:15]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ave_initcode_atten3:10; + /** adc1_hi_dout_atten0 : R; bitpos: [31:25]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten0:7; }; uint32_t val; } efuse_rd_sys_part1_data5_reg_t; @@ -662,10 +682,22 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of the first part of system data. + /** adc1_hi_dout_atten0_1 : R; bitpos: [2:0]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten0_1:3; + /** adc1_hi_dout_atten1 : R; bitpos: [12:3]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten1:10; + /** adc1_hi_dout_atten2 : R; bitpos: [22:13]; default: 0; + * ADC1 calibration data */ - uint32_t sys_data_part1_6:32; + uint32_t adc1_hi_dout_atten2:10; + /** adc1_hi_dout_atten3 : R; bitpos: [31:23]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten3:9; }; uint32_t val; } efuse_rd_sys_part1_data6_reg_t; @@ -675,10 +707,34 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of the first part of system data. + /** adc1_hi_dout_atten3_1 : R; bitpos: [0]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten3_1:1; + /** adc1_ch0_atten0_initcode_diff : R; bitpos: [4:1]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch0_atten0_initcode_diff:4; + /** adc1_ch1_atten0_initcode_diff : R; bitpos: [8:5]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch1_atten0_initcode_diff:4; + /** adc1_ch2_atten0_initcode_diff : R; bitpos: [12:9]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch2_atten0_initcode_diff:4; + /** adc1_ch3_atten0_initcode_diff : R; bitpos: [16:13]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch3_atten0_initcode_diff:4; + /** adc1_ch4_atten0_initcode_diff : R; bitpos: [20:17]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch4_atten0_initcode_diff:4; + /** reserved_2_245 : R; bitpos: [31:21]; default: 0; + * reserved */ - uint32_t sys_data_part1_7:32; + uint32_t reserved_2_245:11; }; uint32_t val; } efuse_rd_sys_part1_data7_reg_t; diff --git a/components/soc/esp32h2/include/soc/i2c_struct.h b/components/soc/esp32h2/include/soc/i2c_struct.h index c0d20904aa0..eec5081e80a 100644 --- a/components/soc/esp32h2/include/soc/i2c_struct.h +++ b/components/soc/esp32h2/include/soc/i2c_struct.h @@ -948,34 +948,6 @@ typedef union { } i2c_date_reg_t; -/** Group: Address register */ -/** Type of txfifo_start_addr register - * I2C TXFIFO base address register - */ -typedef union { - struct { - /** txfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * This is the I2C txfifo first address. - */ - uint32_t txfifo_start_addr:32; - }; - uint32_t val; -} i2c_txfifo_start_addr_reg_t; - -/** Type of rxfifo_start_addr register - * I2C RXFIFO base address register - */ -typedef union { - struct { - /** rxfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * This is the I2C rxfifo first address. - */ - uint32_t rxfifo_start_addr:32; - }; - uint32_t val; -} i2c_rxfifo_start_addr_reg_t; - - typedef struct i2c_dev_t { volatile i2c_scl_low_period_reg_t scl_low_period; volatile i2c_ctr_reg_t ctr; @@ -1007,16 +979,15 @@ typedef struct i2c_dev_t { uint32_t reserved_088[28]; volatile i2c_date_reg_t date; uint32_t reserved_0fc; - volatile i2c_txfifo_start_addr_reg_t txfifo_start_addr; - uint32_t reserved_104[31]; - volatile i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; + volatile uint32_t txfifo_mem[32]; + volatile uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; extern i2c_dev_t I2C1; #ifndef __cplusplus -_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); +_Static_assert(sizeof(i2c_dev_t) == 0x200, "Invalid size of i2c_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32h2/include/soc/regi2c_saradc.h b/components/soc/esp32h2/include/soc/regi2c_saradc.h index 7d211bf6aab..aaa5fcfa7bc 100644 --- a/components/soc/esp32h2/include/soc/regi2c_saradc.h +++ b/components/soc/esp32h2/include/soc/regi2c_saradc.h @@ -69,3 +69,7 @@ #define I2C_SARADC_SAR2_INIT_CODE_MSB 4 #define I2C_SARADC_SAR2_INIT_CODE_MSB_MSB 3 #define I2C_SARADC_SAR2_INIT_CODE_MSB_LSB 0 + +#define ADC_SAR1_ENCAL_GND_ADDR 0x8 +#define ADC_SAR1_ENCAL_GND_ADDR_MSB 0x1 +#define ADC_SAR1_ENCAL_GND_ADDR_LSB 0x1 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 9a3231707e6..f9315797088 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -119,7 +119,9 @@ #define SOC_ADC_RTC_MAX_BITWIDTH (12) /*!< Calibration */ -#define SOC_ADC_CALIBRATION_V1_SUPPORTED (0) /*!< support HW offset calibration version 1*/ +#define SOC_ADC_CALIBRATION_V1_SUPPORTED (1) /*!< support HW offset calibration version 1*/ +#define SOC_ADC_SELF_HW_CALI_SUPPORTED (1) /*!< support HW offset self calibration */ +#define SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED (1) /*!< support channel compensation to the HW offset calibration */ /*!< Interrupt */ #define SOC_ADC_TEMPERATURE_SHARE_INTR (1) @@ -242,6 +244,10 @@ #define SOC_I2C_SUPPORT_XTAL (1) #define SOC_I2C_SUPPORT_RTC (1) #define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) +#define SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH (1) /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (1U) @@ -444,7 +450,7 @@ #define SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY 1 /*-------------------------- Flash Encryption CAPS----------------------------*/ -#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (32) +#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64) #define SOC_FLASH_ENCRYPTION_XTS_AES 1 #define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 608d0485b4e..ded76ad0fb9 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -35,6 +35,10 @@ config SOC_MCPWM_SUPPORTED bool default y +config SOC_TWAI_SUPPORTED + bool + default y + config SOC_ETM_SUPPORTED bool default y @@ -479,6 +483,22 @@ config SOC_I2C_SUPPORT_RTC bool default y +config SOC_I2C_SUPPORT_10BIT_ADDR + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + bool + default y + config SOC_I2S_NUM int default 3 @@ -535,6 +555,22 @@ config SOC_I2S_TDM_FULL_DATA_WIDTH bool default y +config SOC_ISP_NUMS + int + default 1 + +config SOC_ISP_AF_CTLR_NUMS + int + default 1 + +config SOC_ISP_AF_ENV_DETECTOR_NUMS + int + default 1 + +config SOC_ISP_AF_WINDOW_NUMS + int + default 3 + config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK bool default y @@ -993,7 +1029,7 @@ config SOC_MWDT_SUPPORT_XTAL config SOC_TWAI_CONTROLLER_NUM int - default 2 + default 3 config SOC_TWAI_CLK_SUPPORT_XTAL bool @@ -1053,7 +1089,7 @@ config SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY config SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX int - default 32 + default 64 config SOC_FLASH_ENCRYPTION_XTS_AES bool diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index b386fc9d07a..90f56146d0b 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -443,6 +443,23 @@ typedef enum { FLASH_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SOC_MOD_CLK_SPLL as FLASH source clock */ } soc_periph_flash_clk_src_t; +/////////////////////////////////////////////////ISP//////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of ISP + */ +#define SOC_ISP_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_PLL_F240M} + +/** + * @brief Type of ISP clock source. + */ +typedef enum { + ISP_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select SOC_MOD_CLK_PLL_F160M as ISP source clock */ + ISP_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select SOC_MOD_CLK_XTAL as ISP source clock */ + ISP_CLK_SRC_PLL160 = SOC_MOD_CLK_PLL_F160M, /*!< Select SOC_MOD_CLK_PLL_F160M as ISP source clock */ + ISP_CLK_SRC_PLL240 = SOC_MOD_CLK_PLL_F240M, /*!< Select SOC_MOD_CLK_PLL_F240M as ISP source clock */ +} soc_periph_isp_clk_src_t; + //////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// //////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// @@ -464,6 +481,21 @@ typedef enum { } soc_periph_ana_cmpr_clk_src_t; //////////////////////////////////////////////////TWAI////////////////////////////////////////////////////////////////// +/** + * @brief Array initializer for all supported clock sources of TWAI + */ +#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST} + +/** + * @brief TWAI clock source + */ +typedef enum { + TWAI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ +#if SOC_CLK_TREE_SUPPORTED + TWAI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST /*!< Select RC_FAST as the source clock */ +#endif + TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ +} soc_periph_twai_clk_src_t; //////////////////////////////////////////////////ADC/////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32p4/include/soc/gpio_sig_map.h b/components/soc/esp32p4/include/soc/gpio_sig_map.h index 99bd0360b5b..d0653170fdd 100644 --- a/components/soc/esp32p4/include/soc/gpio_sig_map.h +++ b/components/soc/esp32p4/include/soc/gpio_sig_map.h @@ -159,18 +159,18 @@ #define UART4_SLP_CLK_PAD_IN_IDX 78 #define GPIO_SD6_OUT_IDX 78 #define GPIO_SD7_OUT_IDX 79 -#define CAN0_RX_PAD_IN_IDX 80 -#define CAN0_TX_PAD_OUT_IDX 80 -#define CAN0_BUS_OFF_ON_PAD_OUT_IDX 81 -#define CAN0_CLKOUT_PAD_OUT_IDX 82 -#define CAN1_RX_PAD_IN_IDX 83 -#define CAN1_TX_PAD_OUT_IDX 83 -#define CAN1_BUS_OFF_ON_PAD_OUT_IDX 84 -#define CAN1_CLKOUT_PAD_OUT_IDX 85 -#define CAN2_RX_PAD_IN_IDX 86 -#define CAN2_TX_PAD_OUT_IDX 86 -#define CAN2_BUS_OFF_ON_PAD_OUT_IDX 87 -#define CAN2_CLKOUT_PAD_OUT_IDX 88 +#define TWAI0_RX_PAD_IN_IDX 80 +#define TWAI0_TX_PAD_OUT_IDX 80 +#define TWAI0_BUS_OFF_ON_PAD_OUT_IDX 81 +#define TWAI0_CLKOUT_PAD_OUT_IDX 82 +#define TWAI1_RX_PAD_IN_IDX 83 +#define TWAI1_TX_PAD_OUT_IDX 83 +#define TWAI1_BUS_OFF_ON_PAD_OUT_IDX 84 +#define TWAI1_CLKOUT_PAD_OUT_IDX 85 +#define TWAI2_RX_PAD_IN_IDX 86 +#define TWAI2_TX_PAD_OUT_IDX 86 +#define TWAI2_BUS_OFF_ON_PAD_OUT_IDX 87 +#define TWAI2_CLKOUT_PAD_OUT_IDX 88 #define PWM0_SYNC0_PAD_IN_IDX 89 #define PWM0_CH0_A_PAD_OUT_IDX 89 #define PWM0_SYNC1_PAD_IN_IDX 90 diff --git a/components/soc/esp32p4/include/soc/hp_sys_clkrst_reg.h b/components/soc/esp32p4/include/soc/hp_sys_clkrst_reg.h index 4bfc63fc2e3..8a7ad9c6af2 100644 --- a/components/soc/esp32p4/include/soc/hp_sys_clkrst_reg.h +++ b/components/soc/esp32p4/include/soc/hp_sys_clkrst_reg.h @@ -3473,27 +3473,27 @@ extern "C" { #define HP_SYS_CLKRST_REG_RST_EN_PWM1_M (HP_SYS_CLKRST_REG_RST_EN_PWM1_V << HP_SYS_CLKRST_REG_RST_EN_PWM1_S) #define HP_SYS_CLKRST_REG_RST_EN_PWM1_V 0x00000001U #define HP_SYS_CLKRST_REG_RST_EN_PWM1_S 25 -/** HP_SYS_CLKRST_REG_RST_EN_CAN0 : R/W; bitpos: [26]; default: 0; +/** HP_SYS_CLKRST_REG_RST_EN_TWAI0 : R/W; bitpos: [26]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_RST_EN_CAN0 (BIT(26)) -#define HP_SYS_CLKRST_REG_RST_EN_CAN0_M (HP_SYS_CLKRST_REG_RST_EN_CAN0_V << HP_SYS_CLKRST_REG_RST_EN_CAN0_S) -#define HP_SYS_CLKRST_REG_RST_EN_CAN0_V 0x00000001U -#define HP_SYS_CLKRST_REG_RST_EN_CAN0_S 26 -/** HP_SYS_CLKRST_REG_RST_EN_CAN1 : R/W; bitpos: [27]; default: 0; +#define HP_SYS_CLKRST_REG_RST_EN_TWAI0 (BIT(26)) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI0_M (HP_SYS_CLKRST_REG_RST_EN_TWAI0_V << HP_SYS_CLKRST_REG_RST_EN_TWAI0_S) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI0_V 0x00000001U +#define HP_SYS_CLKRST_REG_RST_EN_TWAI0_S 26 +/** HP_SYS_CLKRST_REG_RST_EN_TWAI1 : R/W; bitpos: [27]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_RST_EN_CAN1 (BIT(27)) -#define HP_SYS_CLKRST_REG_RST_EN_CAN1_M (HP_SYS_CLKRST_REG_RST_EN_CAN1_V << HP_SYS_CLKRST_REG_RST_EN_CAN1_S) -#define HP_SYS_CLKRST_REG_RST_EN_CAN1_V 0x00000001U -#define HP_SYS_CLKRST_REG_RST_EN_CAN1_S 27 -/** HP_SYS_CLKRST_REG_RST_EN_CAN2 : R/W; bitpos: [28]; default: 0; +#define HP_SYS_CLKRST_REG_RST_EN_TWAI1 (BIT(27)) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI1_M (HP_SYS_CLKRST_REG_RST_EN_TWAI1_V << HP_SYS_CLKRST_REG_RST_EN_TWAI1_S) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI1_V 0x00000001U +#define HP_SYS_CLKRST_REG_RST_EN_TWAI1_S 27 +/** HP_SYS_CLKRST_REG_RST_EN_TWAI2 : R/W; bitpos: [28]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_RST_EN_CAN2 (BIT(28)) -#define HP_SYS_CLKRST_REG_RST_EN_CAN2_M (HP_SYS_CLKRST_REG_RST_EN_CAN2_V << HP_SYS_CLKRST_REG_RST_EN_CAN2_S) -#define HP_SYS_CLKRST_REG_RST_EN_CAN2_V 0x00000001U -#define HP_SYS_CLKRST_REG_RST_EN_CAN2_S 28 +#define HP_SYS_CLKRST_REG_RST_EN_TWAI2 (BIT(28)) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI2_M (HP_SYS_CLKRST_REG_RST_EN_TWAI2_V << HP_SYS_CLKRST_REG_RST_EN_TWAI2_S) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI2_V 0x00000001U +#define HP_SYS_CLKRST_REG_RST_EN_TWAI2_S 28 /** HP_SYS_CLKRST_REG_RST_EN_LEDC : R/W; bitpos: [29]; default: 0; * Reserved */ @@ -3971,27 +3971,27 @@ extern "C" { #define HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_M (HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_V << HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_S) #define HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_V 0x00000001U #define HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_S 5 -/** HP_SYS_CLKRST_REG_FORCE_NORST_CAN0 : R/W; bitpos: [6]; default: 0; +/** HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0 : R/W; bitpos: [6]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN0 (BIT(6)) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_M (HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_V << HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_S) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_V 0x00000001U -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_S 6 -/** HP_SYS_CLKRST_REG_FORCE_NORST_CAN1 : R/W; bitpos: [7]; default: 0; +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0 (BIT(6)) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_M (HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_V << HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_S) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_V 0x00000001U +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_S 6 +/** HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1 : R/W; bitpos: [7]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN1 (BIT(7)) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_M (HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_V << HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_S) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_V 0x00000001U -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_S 7 -/** HP_SYS_CLKRST_REG_FORCE_NORST_CAN2 : R/W; bitpos: [8]; default: 0; +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1 (BIT(7)) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_M (HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_V << HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_S) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_V 0x00000001U +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_S 7 +/** HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2 : R/W; bitpos: [8]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN2 (BIT(8)) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_M (HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_V << HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_S) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_V 0x00000001U -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_S 8 +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2 (BIT(8)) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_M (HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_V << HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_S) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_V 0x00000001U +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_S 8 /** HP_SYS_CLKRST_REG_FORCE_NORST_LEDC : R/W; bitpos: [9]; default: 0; * Reserved */ diff --git a/components/soc/esp32p4/include/soc/hp_sys_clkrst_struct.h b/components/soc/esp32p4/include/soc/hp_sys_clkrst_struct.h index d672ecc6295..2837628cd60 100644 --- a/components/soc/esp32p4/include/soc/hp_sys_clkrst_struct.h +++ b/components/soc/esp32p4/include/soc/hp_sys_clkrst_struct.h @@ -2350,18 +2350,18 @@ typedef union { * Reserved */ uint32_t reg_rst_en_pwm1:1; - /** reg_rst_en_can0 : R/W; bitpos: [26]; default: 0; + /** reg_rst_en_twai0 : R/W; bitpos: [26]; default: 0; * Reserved */ - uint32_t reg_rst_en_can0:1; - /** reg_rst_en_can1 : R/W; bitpos: [27]; default: 0; + uint32_t reg_rst_en_twai0:1; + /** reg_rst_en_twai1 : R/W; bitpos: [27]; default: 0; * Reserved */ - uint32_t reg_rst_en_can1:1; - /** reg_rst_en_can2 : R/W; bitpos: [28]; default: 0; + uint32_t reg_rst_en_twai1:1; + /** reg_rst_en_twai2 : R/W; bitpos: [28]; default: 0; * Reserved */ - uint32_t reg_rst_en_can2:1; + uint32_t reg_rst_en_twai2:1; /** reg_rst_en_ledc : R/W; bitpos: [29]; default: 0; * Reserved */ @@ -2656,18 +2656,18 @@ typedef union { * Reserved */ uint32_t reg_force_norst_pwm1:1; - /** reg_force_norst_can0 : R/W; bitpos: [6]; default: 0; + /** reg_force_norst_twai0 : R/W; bitpos: [6]; default: 0; * Reserved */ - uint32_t reg_force_norst_can0:1; - /** reg_force_norst_can1 : R/W; bitpos: [7]; default: 0; + uint32_t reg_force_norst_twai0:1; + /** reg_force_norst_twai1 : R/W; bitpos: [7]; default: 0; * Reserved */ - uint32_t reg_force_norst_can1:1; - /** reg_force_norst_can2 : R/W; bitpos: [8]; default: 0; + uint32_t reg_force_norst_twai1:1; + /** reg_force_norst_twai2 : R/W; bitpos: [8]; default: 0; * Reserved */ - uint32_t reg_force_norst_can2:1; + uint32_t reg_force_norst_twai2:1; /** reg_force_norst_ledc : R/W; bitpos: [9]; default: 0; * Reserved */ diff --git a/components/soc/esp32p4/include/soc/i2c_struct.h b/components/soc/esp32p4/include/soc/i2c_struct.h index 876eba6a705..747686285a6 100644 --- a/components/soc/esp32p4/include/soc/i2c_struct.h +++ b/components/soc/esp32p4/include/soc/i2c_struct.h @@ -1047,34 +1047,6 @@ typedef union { } i2c_date_reg_t; -/** Group: Address register */ -/** Type of txfifo_start_addr register - * I2C TXFIFO base address register - */ -typedef union { - struct { - /** txfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * Represents the I2C txfifo first address. - */ - uint32_t txfifo_start_addr:32; - }; - uint32_t val; -} i2c_txfifo_start_addr_reg_t; - -/** Type of rxfifo_start_addr register - * I2C RXFIFO base address register - */ -typedef union { - struct { - /** rxfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * Represents the I2C rxfifo first address. - */ - uint32_t rxfifo_start_addr:32; - }; - uint32_t val; -} i2c_rxfifo_start_addr_reg_t; - - typedef struct { volatile i2c_scl_low_period_reg_t scl_low_period; volatile i2c_ctr_reg_t ctr; @@ -1106,9 +1078,8 @@ typedef struct { uint32_t reserved_088[28]; volatile i2c_date_reg_t date; uint32_t reserved_0fc; - volatile i2c_txfifo_start_addr_reg_t txfifo_start_addr; - uint32_t reserved_104[31]; - volatile i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; + volatile uint32_t txfifo_mem[32]; + volatile uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; @@ -1116,7 +1087,7 @@ extern i2c_dev_t I2C1; extern i2c_dev_t LP_I2C; #ifndef __cplusplus -_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); +_Static_assert(sizeof(i2c_dev_t) == 0x200, "Invalid size of i2c_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 881aee45195..685da9861dc 100644 --- a/components/soc/esp32p4/include/soc/interrupts.h +++ b/components/soc/esp32p4/include/soc/interrupts.h @@ -55,9 +55,9 @@ typedef enum { ETS_ADC_INTR_SOURCE, ETS_PWM0_INTR_SOURCE, ETS_PWM1_INTR_SOURCE, - ETS_CAN0_INTR_SOURCE, - ETS_CAN1_INTR_SOURCE, - ETS_CAN2_INTR_SOURCE, + ETS_TWAI0_INTR_SOURCE, + ETS_TWAI1_INTR_SOURCE, + ETS_TWAI2_INTR_SOURCE, ETS_RMT_INTR_SOURCE, ETS_I2C0_INTR_SOURCE, ETS_I2C1_INTR_SOURCE, diff --git a/components/soc/esp32p4/include/soc/isp_struct.h b/components/soc/esp32p4/include/soc/isp_struct.h index acb3c4a465f..980103687bf 100644 --- a/components/soc/esp32p4/include/soc/isp_struct.h +++ b/components/soc/esp32p4/include/soc/isp_struct.h @@ -247,11 +247,11 @@ typedef union { */ uint32_t bayer_mode:2; /** hsync_start_exist : R/W; bitpos: [29]; default: 1; - * this bit configures the line end packet exist or not. 0: not exist, 1: exist + * this bit configures the line end start exist or not. 0: not exist, 1: exist */ uint32_t hsync_start_exist:1; /** hsync_end_exist : R/W; bitpos: [30]; default: 1; - * this bit configures the line start packet exist or not. 0: not exist, 1: exist + * this bit configures the line end packet exist or not. 0: not exist, 1: exist */ uint32_t hsync_end_exist:1; uint32_t reserved_31:1; @@ -3857,6 +3857,7 @@ typedef struct { volatile isp_rdn_eco_high_reg_t rdn_eco_high; } isp_dev_t; +extern isp_dev_t ISP; #ifndef __cplusplus _Static_assert(sizeof(isp_dev_t) == 0x244, "Invalid size of isp_dev_t structure"); diff --git a/components/soc/esp32p4/include/soc/soc.h b/components/soc/esp32p4/include/soc/soc.h index 735a0b7a59f..7bbcd0618b2 100644 --- a/components/soc/esp32p4/include/soc/soc.h +++ b/components/soc/esp32p4/include/soc/soc.h @@ -142,6 +142,7 @@ #define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define CPU_CLK_FREQ APB_CLK_FREQ #define APB_CLK_FREQ ( 40*1000000 ) +#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) #define XTAL_CLK_FREQ (40*1000000) #define GPIO_MATRIX_DELAY_NS 0 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 65ce09b3812..f351f934b84 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -35,7 +35,7 @@ #define SOC_GPTIMER_SUPPORTED 1 #define SOC_PCNT_SUPPORTED 1 #define SOC_MCPWM_SUPPORTED 1 -// #define SOC_TWAI_SUPPORTED 1 //TODO: IDF-7470 +#define SOC_TWAI_SUPPORTED 1 #define SOC_ETM_SUPPORTED 1 #define SOC_PARLIO_SUPPORTED 1 //TODO: IDF-7471 #define SOC_ASYNC_MEMCPY_SUPPORTED 1 @@ -246,6 +246,10 @@ #define SOC_I2C_SUPPORT_XTAL (1) #define SOC_I2C_SUPPORT_RTC (1) +#define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) +#define SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH (1) /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (3U) @@ -263,6 +267,12 @@ #define SOC_I2S_PDM_MAX_RX_LINES (4) // On I2S0 #define SOC_I2S_TDM_FULL_DATA_WIDTH (1) /*!< No limitation to data bit width when using multiple slots */ +/*-------------------------- ISP CAPS ----------------------------------------*/ +#define SOC_ISP_NUMS 1U +#define SOC_ISP_AF_CTLR_NUMS 1U +#define SOC_ISP_AF_ENV_DETECTOR_NUMS 1U +#define SOC_ISP_AF_WINDOW_NUMS 3 + /*-------------------------- LEDC CAPS ---------------------------------------*/ #define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1) #define SOC_LEDC_SUPPORT_XTAL_CLOCK (1) @@ -454,7 +464,7 @@ #define SOC_MWDT_SUPPORT_XTAL (1) /*-------------------------- TWAI CAPS ---------------------------------------*/ -#define SOC_TWAI_CONTROLLER_NUM 2 +#define SOC_TWAI_CONTROLLER_NUM 3 #define SOC_TWAI_CLK_SUPPORT_XTAL 1 #define SOC_TWAI_BRP_MIN 2 #define SOC_TWAI_BRP_MAX 32768 @@ -475,7 +485,7 @@ #define SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY 1 /*-------------------------- Flash Encryption CAPS----------------------------*/ -#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (32) +#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64) #define SOC_FLASH_ENCRYPTION_XTS_AES 1 #define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 diff --git a/components/soc/esp32p4/include/soc/twai_struct.h b/components/soc/esp32p4/include/soc/twai_struct.h index 758d6462fcb..90290513092 100644 --- a/components/soc/esp32p4/include/soc/twai_struct.h +++ b/components/soc/esp32p4/include/soc/twai_struct.h @@ -434,7 +434,7 @@ typedef union { uint32_t reserved_9:23; }; uint32_t val; -} twai_interrupt_reg_t; +} twai_interrupt_status_reg_t; /** Type of interrupt_enable register * Interrupt enable register. @@ -493,214 +493,43 @@ typedef union { /** Group: Data Registers */ -/** Type of data_0 register - * Data register 0. +/** Type of buffer register + * TX RX Buffer. */ typedef union { struct { - /** data_0 : R/W; bitpos: [7:0]; default: 0; + /** byte : R/W; bitpos: [7:0]; default: 0; * In reset mode, it is acceptance code register 0 with R/W Permission. In operation * mode, when software initiate write operation, it is tx data register 0 and when * software initiate read operation, it is rx data register 0. */ - uint32_t data_0:8; + uint32_t byte:8; uint32_t reserved_8:24; }; uint32_t val; -} twai_data_0_reg_t; - -/** Type of data_1 register - * Data register 1. - */ -typedef union { - struct { - /** data_1 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance code register 1 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 1 and when - * software initiate read operation, it is rx data register 1. - */ - uint32_t data_1:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_1_reg_t; - -/** Type of data_2 register - * Data register 2. - */ -typedef union { - struct { - /** data_2 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance code register 2 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 2 and when - * software initiate read operation, it is rx data register 2. - */ - uint32_t data_2:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_2_reg_t; - -/** Type of data_3 register - * Data register 3. - */ -typedef union { - struct { - /** data_3 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance code register 3 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 3 and when - * software initiate read operation, it is rx data register 3. - */ - uint32_t data_3:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_3_reg_t; - -/** Type of data_4 register - * Data register 4. - */ -typedef union { - struct { - /** data_4 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance mask register 0 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 4 and when - * software initiate read operation, it is rx data register 4. - */ - uint32_t data_4:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_4_reg_t; - -/** Type of data_5 register - * Data register 5. - */ -typedef union { - struct { - /** data_5 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance mask register 1 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 5 and when - * software initiate read operation, it is rx data register 5. - */ - uint32_t data_5:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_5_reg_t; - -/** Type of data_6 register - * Data register 6. - */ -typedef union { - struct { - /** data_6 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance mask register 2 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 6 and when - * software initiate read operation, it is rx data register 6. - */ - uint32_t data_6:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_6_reg_t; - -/** Type of data_7 register - * Data register 7. - */ -typedef union { - struct { - /** data_7 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance mask register 3 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 7 and when - * software initiate read operation, it is rx data register 7. - */ - uint32_t data_7:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_7_reg_t; - -/** Type of data_8 register - * Data register 8. - */ -typedef union { - struct { - /** data_8 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 8 and when software initiate read operation, it - * is rx data register 8. - */ - uint32_t data_8:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_8_reg_t; - -/** Type of data_9 register - * Data register 9. - */ -typedef union { - struct { - /** data_9 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 9 and when software initiate read operation, it - * is rx data register 9. - */ - uint32_t data_9:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_9_reg_t; - -/** Type of data_10 register - * Data register 10. - */ -typedef union { - struct { - /** data_10 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 10 and when software initiate read operation, it - * is rx data register 10. - */ - uint32_t data_10:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_10_reg_t; - -/** Type of data_11 register - * Data register 11. - */ -typedef union { - struct { - /** data_11 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 11 and when software initiate read operation, it - * is rx data register 11. - */ - uint32_t data_11:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_11_reg_t; - -/** Type of data_12 register - * Data register 12. - */ -typedef union { - struct { - /** data_12 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 12 and when software initiate read operation, it - * is rx data register 12. - */ - uint32_t data_12:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_12_reg_t; +} twai_tx_rx_buffer_reg_t; +typedef struct { + union { + struct { + uint32_t byte: 8; /* ACRx[7:0] Acceptance Code */ + uint32_t reserved8: 24; /* Internal Reserved */ + }; + uint32_t val; + } acr[4]; + union { + struct { + uint32_t byte: 8; /* AMRx[7:0] Acceptance Mask */ + uint32_t reserved8: 24; /* Internal Reserved */ + }; + uint32_t val; + } amr[4]; + uint32_t reserved_60; + uint32_t reserved_64; + uint32_t reserved_68; + uint32_t reserved_6c; + uint32_t reserved_70; +} acceptance_filter_reg_t; /** Group: Timestamp Register */ /** Type of timestamp_data register @@ -749,8 +578,8 @@ typedef struct { volatile twai_mode_reg_t mode; volatile twai_cmd_reg_t cmd; volatile twai_status_reg_t status; - volatile twai_interrupt_reg_t interrupt; - volatile twai_interrupt_enable_reg_t interrupt_enable; + volatile twai_interrupt_status_reg_t interrupt_st; + volatile twai_interrupt_enable_reg_t interrupt_ena; uint32_t reserved_014; volatile twai_bus_timing_0_reg_t bus_timing_0; volatile twai_bus_timing_1_reg_t bus_timing_1; @@ -760,19 +589,10 @@ typedef struct { volatile twai_err_warning_limit_reg_t err_warning_limit; volatile twai_rx_err_cnt_reg_t rx_err_cnt; volatile twai_tx_err_cnt_reg_t tx_err_cnt; - volatile twai_data_0_reg_t data_0; - volatile twai_data_1_reg_t data_1; - volatile twai_data_2_reg_t data_2; - volatile twai_data_3_reg_t data_3; - volatile twai_data_4_reg_t data_4; - volatile twai_data_5_reg_t data_5; - volatile twai_data_6_reg_t data_6; - volatile twai_data_7_reg_t data_7; - volatile twai_data_8_reg_t data_8; - volatile twai_data_9_reg_t data_9; - volatile twai_data_10_reg_t data_10; - volatile twai_data_11_reg_t data_11; - volatile twai_data_12_reg_t data_12; + volatile union { + acceptance_filter_reg_t acceptance_filter; + twai_tx_rx_buffer_reg_t tx_rx_buffer[13]; + }; volatile twai_rx_message_counter_reg_t rx_message_counter; uint32_t reserved_078; volatile twai_clock_divider_reg_t clock_divider; @@ -786,6 +606,9 @@ typedef struct { volatile twai_timestamp_cfg_reg_t timestamp_cfg; } twai_dev_t; +extern twai_dev_t TWAI0; +extern twai_dev_t TWAI1; +extern twai_dev_t TWAI2; #ifndef __cplusplus _Static_assert(sizeof(twai_dev_t) == 0xa0, "Invalid size of twai_dev_t structure"); diff --git a/components/soc/esp32p4/interrupts.c b/components/soc/esp32p4/interrupts.c index be8694e6b94..6d76d073e56 100644 --- a/components/soc/esp32p4/interrupts.c +++ b/components/soc/esp32p4/interrupts.c @@ -47,9 +47,9 @@ const char *const esp_isr_names[] = { [ETS_ADC_INTR_SOURCE] = "ADC", [ETS_PWM0_INTR_SOURCE] = "PWM0", [ETS_PWM1_INTR_SOURCE] = "PWM1", - [ETS_CAN0_INTR_SOURCE] = "CAN0", - [ETS_CAN1_INTR_SOURCE] = "CAN1", - [ETS_CAN2_INTR_SOURCE] = "CAN2", + [ETS_TWAI0_INTR_SOURCE] = "TWAI0", + [ETS_TWAI1_INTR_SOURCE] = "TWAI1", + [ETS_TWAI2_INTR_SOURCE] = "TWAI2", [ETS_RMT_INTR_SOURCE] = "RMT", [ETS_I2C0_INTR_SOURCE] = "I2C0", [ETS_I2C1_INTR_SOURCE] = "I2C1", diff --git a/components/soc/esp32p4/twai_periph.c b/components/soc/esp32p4/twai_periph.c index 061cd4a4d78..67b016fa0d6 100644 --- a/components/soc/esp32p4/twai_periph.c +++ b/components/soc/esp32p4/twai_periph.c @@ -8,5 +8,33 @@ #include "soc/gpio_sig_map.h" const twai_controller_signal_conn_t twai_controller_periph_signals = { - + .controllers = { + [0] = { + .module = PERIPH_TWAI0_MODULE, + .irq_id = ETS_TWAI0_INTR_SOURCE, + .tx_sig = TWAI0_TX_PAD_OUT_IDX, + .rx_sig = TWAI0_RX_PAD_IN_IDX, + .bus_off_sig = TWAI0_BUS_OFF_ON_PAD_OUT_IDX, + .clk_out_sig = TWAI0_CLKOUT_PAD_OUT_IDX, + .stand_by_sig = TWAI0_STANDBY_PAD_OUT_IDX, + }, + [1] = { + .module = PERIPH_TWAI1_MODULE, + .irq_id = ETS_TWAI1_INTR_SOURCE, + .tx_sig = TWAI1_TX_PAD_OUT_IDX, + .rx_sig = TWAI1_RX_PAD_IN_IDX, + .bus_off_sig = TWAI1_BUS_OFF_ON_PAD_OUT_IDX, + .clk_out_sig = TWAI1_CLKOUT_PAD_OUT_IDX, + .stand_by_sig = TWAI1_STANDBY_PAD_OUT_IDX, + }, + [2] = { + .module = PERIPH_TWAI2_MODULE, + .irq_id = ETS_TWAI2_INTR_SOURCE, + .tx_sig = TWAI2_TX_PAD_OUT_IDX, + .rx_sig = TWAI2_RX_PAD_IN_IDX, + .bus_off_sig = TWAI2_BUS_OFF_ON_PAD_OUT_IDX, + .clk_out_sig = TWAI2_CLKOUT_PAD_OUT_IDX, + .stand_by_sig = TWAI2_STANDBY_PAD_OUT_IDX, + } + } }; diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 3da46a8c1d1..aa9945311df 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -483,6 +483,14 @@ config SOC_I2C_SUPPORT_10BIT_ADDR bool default y +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + config SOC_I2S_NUM int default 2 diff --git a/components/soc/esp32s3/include/soc/i2c_struct.h b/components/soc/esp32s3/include/soc/i2c_struct.h index 513f55770fa..807ffa508d1 100644 --- a/components/soc/esp32s3/include/soc/i2c_struct.h +++ b/components/soc/esp32s3/include/soc/i2c_struct.h @@ -941,35 +941,6 @@ typedef union { uint32_t val; } i2c_date_reg_t; - -/** Group: Address register */ -/** Type of txfifo_start_addr register - * I2C TXFIFO base address register - */ -typedef union { - struct { - /** txfifo_start_addr : RO; bitpos: [31:0]; default: 0; - * This is the I2C txfifo first address. - */ - uint32_t txfifo_start_addr:32; - }; - uint32_t val; -} i2c_txfifo_start_addr_reg_t; - -/** Type of rxfifo_start_addr register - * I2C RXFIFO base address register - */ -typedef union { - struct { - /** rxfifo_start_addr : RO; bitpos: [31:0]; default: 0; - * This is the I2C rxfifo first address. - */ - uint32_t rxfifo_start_addr:32; - }; - uint32_t val; -} i2c_rxfifo_start_addr_reg_t; - - typedef struct { volatile i2c_scl_low_period_reg_t scl_low_period; volatile i2c_ctr_reg_t ctr; @@ -1001,16 +972,15 @@ typedef struct { uint32_t reserved_088[28]; volatile i2c_date_reg_t date; uint32_t reserved_0fc; - volatile i2c_txfifo_start_addr_reg_t txfifo_start_addr; - uint32_t reserved_104[31]; - volatile i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; + volatile uint32_t txfifo_mem[32]; + volatile uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; extern i2c_dev_t I2C1; #ifndef __cplusplus -_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); +_Static_assert(sizeof(i2c_dev_t) == 0x200, "Invalid size of i2c_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 42aeff02e34..bffb9694938 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -201,6 +201,8 @@ #define SOC_I2C_SUPPORT_RTC (1) #define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (2U) diff --git a/components/soc/include/soc/rtc_io_periph.h b/components/soc/include/soc/rtc_io_periph.h index 95315e064b4..3eadcfda1a0 100644 --- a/components/soc/include/soc/rtc_io_periph.h +++ b/components/soc/include/soc/rtc_io_periph.h @@ -6,8 +6,7 @@ #pragma once - -#include "soc/soc.h" +#include //include soc related (generated) definitions #include "soc/soc_caps.h" diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index f524e6dca1a..0133cf45aae 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -1,6 +1,7 @@ idf_build_get_property(target IDF_TARGET) if(${target} STREQUAL "linux") - idf_component_register(INCLUDE_DIRS include + idf_component_register(SRCS "linux/spi_flash_linux.c" + INCLUDE_DIRS include PRIV_INCLUDE_DIRS include/spi_flash) return() endif() @@ -47,7 +48,9 @@ else() "spi_flash_os_func_noos.c") list(APPEND srcs ${cache_srcs}) - set(priv_requires bootloader_support app_update soc driver esp_mm) + set(priv_requires bootloader_support app_update soc esp_mm + driver esp_driver_gpio # TODO: IDF-8503 move spi_bus_lock to esp_hw_support component + ) endif() idf_component_register(SRCS "${srcs}" @@ -71,5 +74,4 @@ if(NOT BOOTLOADER_BUILD AND NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) # will be replaced with MMU requirements idf_component_optional_requires(PRIVATE esp_psram) endif() - target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") endif() diff --git a/components/spi_flash/linux/spi_flash_linux.c b/components/spi_flash/linux/spi_flash_linux.c new file mode 100644 index 00000000000..e4084680343 --- /dev/null +++ b/components/spi_flash/linux/spi_flash_linux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_flash.h" + +esp_err_t esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size) +{ + (void)chip; + *out_size = UINT32_MAX; + return ESP_OK; +} diff --git a/components/spi_flash/test/CMakeLists.txt b/components/spi_flash/test/CMakeLists.txt index c475f2d993a..7ae600b5b2e 100644 --- a/components/spi_flash/test/CMakeLists.txt +++ b/components/spi_flash/test/CMakeLists.txt @@ -2,4 +2,3 @@ idf_component_register(SRC_DIRS "." PRIV_INCLUDE_DIRS "." PRIV_REQUIRES cmock test_utils spi_flash bootloader_support app_update driver esp_timer) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/spi_flash/test_apps/.build-test-rules.yml b/components/spi_flash/test_apps/.build-test-rules.yml index a348aed09f5..ba39b0d3573 100644 --- a/components/spi_flash/test_apps/.build-test-rules.yml +++ b/components/spi_flash/test_apps/.build-test-rules.yml @@ -6,13 +6,13 @@ components/spi_flash/test_apps/esp_flash: temporary: true reason: target esp32p4 is not supported yet # TODO: IDF-7499 depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* - components/bootloader_support/bootloader_flash/**/* depends_components: - esp_mm - esp_psram - spi_flash + - esp_driver_gpio - esptool_py # Some flash related kconfigs are listed here. components/spi_flash/test_apps/flash_encryption: @@ -38,10 +38,9 @@ components/spi_flash/test_apps/flash_suspend: - if: IDF_TARGET != "esp32c3" temporary: true reason: lack of runners - depends_filepatterns: - - components/driver/gptimer/**/* depends_components: - spi_flash + - esp_driver_gptimer components/spi_flash/test_apps/mspi_test: disable: @@ -54,11 +53,11 @@ components/spi_flash/test_apps/mspi_test: temporary: true reason: not supported yet #TODO: IDF-7556 for p4 depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* - components/bootloader_support/bootloader_flash/**/* depends_components: - esp_mm - esp_psram - spi_flash + - esp_driver_gpio - esptool_py # Some flash related kconfigs are listed here. diff --git a/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt b/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt index 491d7e107de..578f8a60b67 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt +++ b/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt @@ -4,4 +4,3 @@ set(srcs "test_app_main.c" idf_component_register(SRCS ${srcs} PRIV_REQUIRES unity spi_flash bootloader_support esp_partition WHOLE_ARCHIVE) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c b/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c index 52cb3171444..c28c4998752 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c +++ b/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c @@ -1,10 +1,11 @@ /* - * 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 */ #include #include +#include #include "esp_log.h" #include "unity.h" #include "esp_flash.h" @@ -45,13 +46,13 @@ static void setup_tests(void) { const esp_partition_t *part = get_test_data_partition(); start = part->address; - printf("Test data partition @ 0x%x\n", start); + printf("Test data partition @ 0x%" PRIx32 "\n", (uint32_t) start); } static void verify_erased_flash(size_t offset, size_t length) { uint8_t *readback = (uint8_t *)heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - printf("verify erased 0x%x - 0x%x\n", offset, offset + length); + printf("verify erased 0x%" PRIx32 " - 0x%" PRIx32 "\n", (uint32_t) offset, (uint32_t) (offset + length)); TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_read(NULL, readback, offset, length)); for (int i = 0; i < length; i++) { @@ -111,7 +112,7 @@ TEST_CASE("test 16 byte encrypted writes", "[flash_encryption]") static void test_encrypted_write(size_t offset, const uint8_t *data, size_t length) { uint8_t readback[length]; - printf("encrypt %d bytes at 0x%x\n", length, offset); + printf("encrypt %" PRIu32 " bytes at 0x%" PRIx32 "\n", (uint32_t) length, (uint32_t) offset); TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_write_encrypted(NULL, offset, data, length)); @@ -160,7 +161,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]") len = SPI_FLASH_SEC_SIZE - offset; } - printf("write %d bytes to 0x%08x...\n", len, start + offset); + printf("write %d bytes to 0x%08" PRIx32 "...\n", len, (uint32_t) (start + offset)); err = esp_flash_write_encrypted(NULL, start + offset, data_buf, len); TEST_ESP_OK(err); @@ -178,7 +179,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]") err = esp_flash_read_encrypted(NULL, start + offset, data_buf, len); TEST_ESP_OK(err); - printf("compare %d bytes at 0x%08x...\n", len, start + offset); + printf("compare %d bytes at 0x%08" PRIx32 "...\n", len, (uint32_t) (start + offset)); TEST_ASSERT_EQUAL_HEX8_ARRAY(cmp_buf + offset, data_buf, len); offset += len; @@ -193,7 +194,7 @@ static const char plainttext_data[] = "$$$$#### Welcome! This is flash encryptio static void test_encrypted_write_new_impl(size_t offset, const uint8_t *data, size_t length) { uint8_t *readback = (uint8_t *)heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - printf("encrypt %d bytes at 0x%x\n", length, offset); + printf("encrypt %" PRIu32 " bytes at 0x%" PRIx32 "\n", (uint32_t) length, (uint32_t) offset); TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_write_encrypted(NULL, offset, data, length)); @@ -289,7 +290,7 @@ TEST_CASE("test read & write encrypted data(16 bytes alianed but 32 bytes unalig if (start % 32 == 0) { start += 16; } - printf("Write data partition @ 0x%x\n", start); + printf("Write data partition @ 0x%" PRIx32 "\n", (uint32_t) start); ESP_LOG_BUFFER_HEXDUMP(TAG, plainttext_data, sizeof(plainttext_data), ESP_LOG_INFO); printf("Encrypteed writting......\n"); diff --git a/components/tcp_transport/include/esp_transport_ssl.h b/components/tcp_transport/include/esp_transport_ssl.h index 1d3fbc7d0e4..00a76e043b1 100644 --- a/components/tcp_transport/include/esp_transport_ssl.h +++ b/components/tcp_transport/include/esp_transport_ssl.h @@ -61,6 +61,14 @@ void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((* */ void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t); +/** + * @brief Set TLS protocol version for ESP-TLS connection + * + * @param t ssl transport + * @param[in] tls_version TLS version + */ +void esp_transport_ssl_set_tls_version(esp_transport_handle_t t, esp_tls_proto_ver_t tls_version); + /** * @brief Set SSL client certificate data for mutual authentication (as PEM format). * Note that, this function stores the pointer to data, rather than making a copy. diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index bf484b1b0e4..0d5228442c5 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -341,6 +341,12 @@ void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t) ssl->cfg.use_global_ca_store = true; } +void esp_transport_ssl_set_tls_version(esp_transport_handle_t t, esp_tls_proto_ver_t tls_version) +{ + GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t); + ssl->cfg.tls_version = tls_version; +} + #ifdef CONFIG_ESP_TLS_PSK_VERIFICATION void esp_transport_ssl_set_psk_key_hint(esp_transport_handle_t t, const psk_hint_key_t *psk_hint_key) { diff --git a/components/usb/CMakeLists.txt b/components/usb/CMakeLists.txt index aef5ea50ac7..84fdacccc9d 100644 --- a/components/usb/CMakeLists.txt +++ b/components/usb/CMakeLists.txt @@ -10,7 +10,7 @@ set(priv_include) # As CONFIG_USB_OTG_SUPPORTED comes from Kconfig, it is not evaluated yet # when components are being registered. # Thus, always add the (private) requirements, regardless of Kconfig -set(priv_require driver) # usb_phy driver relies on gpio driver API +set(priv_require esp_driver_gpio) # usb_phy driver relies on gpio driver API if(CONFIG_USB_OTG_SUPPORTED) list(APPEND srcs "hcd_dwc.c" diff --git a/components/wear_levelling/CMakeLists.txt b/components/wear_levelling/CMakeLists.txt index 751f6822732..2ca00a42b38 100644 --- a/components/wear_levelling/CMakeLists.txt +++ b/components/wear_levelling/CMakeLists.txt @@ -9,5 +9,3 @@ idf_component_register(SRCS "Partition.cpp" PRIV_INCLUDE_DIRS private_include REQUIRES esp_partition PRIV_REQUIRES spi_flash) - -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/wear_levelling/Partition.cpp b/components/wear_levelling/Partition.cpp index c97f45ba603..210ef56d9f4 100644 --- a/components/wear_levelling/Partition.cpp +++ b/components/wear_levelling/Partition.cpp @@ -3,8 +3,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ + #include "esp_log.h" #include "Partition.h" +#include + static const char *TAG = "wl_partition"; Partition::Partition(const esp_partition_t *partition) @@ -28,9 +31,9 @@ esp_err_t Partition::erase_range(size_t start_address, size_t size) { esp_err_t result = esp_partition_erase_range(this->partition, start_address, size); if (result == ESP_OK) { - ESP_LOGV(TAG, "erase_range - start_address=0x%08x, size=0x%08x, result=0x%08x", start_address, size, result); + ESP_LOGV(TAG, "erase_range - start_address=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) start_address, (uint32_t) size, result); } else { - ESP_LOGE(TAG, "erase_range - start_address=0x%08x, size=0x%08x, result=0x%08x", start_address, size, result); + ESP_LOGE(TAG, "erase_range - start_address=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) start_address, (uint32_t) size, result); } return result; } diff --git a/components/wear_levelling/SPI_Flash.cpp b/components/wear_levelling/SPI_Flash.cpp index 2c16a6f88b0..7f0d2d045d4 100644 --- a/components/wear_levelling/SPI_Flash.cpp +++ b/components/wear_levelling/SPI_Flash.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include "SPI_Flash.h" #include "spi_flash_mmap.h" #include "esp_flash.h" +#include static const char *TAG = "spi_flash"; @@ -26,9 +27,9 @@ esp_err_t SPI_Flash::erase_sector(size_t sector) { esp_err_t result = esp_flash_erase_region(NULL, sector * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);; if (result == ESP_OK) { - ESP_LOGV(TAG, "erase_sector - sector=0x%08x, result=0x%08x", sector, result); + ESP_LOGV(TAG, "erase_sector - sector=0x%08" PRIx32 ", result=0x%08x", (uint32_t) sector, result); } else { - ESP_LOGE(TAG, "erase_sector - sector=0x%08x, result=0x%08x", sector, result); + ESP_LOGE(TAG, "erase_sector - sector=0x%08" PRIx32 ", result=0x%08x", (uint32_t) sector, result); } return result; } @@ -38,9 +39,9 @@ esp_err_t SPI_Flash::erase_range(size_t start_address, size_t size) size = size * SPI_FLASH_SEC_SIZE; esp_err_t result = esp_flash_erase_region(NULL, start_address, size); if (result == ESP_OK) { - ESP_LOGV(TAG, "erase_range - start_address=0x%08x, size=0x%08x, result=0x%08x", start_address, size, result); + ESP_LOGV(TAG, "erase_range - start_address=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) start_address, (uint32_t) size, result); } else { - ESP_LOGE(TAG, "erase_range - start_address=0x%08x, size=0x%08x, result=0x%08x", start_address, size, result); + ESP_LOGE(TAG, "erase_range - start_address=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) start_address, (uint32_t) size, result); } return result; } @@ -49,9 +50,9 @@ esp_err_t SPI_Flash::write(size_t dest_addr, const void *src, size_t size) { esp_err_t result = esp_flash_write(NULL, src, dest_addr, size); if (result == ESP_OK) { - ESP_LOGV(TAG, "write - dest_addr=0x%08x, size=0x%08x, result=0x%08x", dest_addr, size, result); + ESP_LOGV(TAG, "write - dest_addr=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) dest_addr, (uint32_t) size, result); } else { - ESP_LOGE(TAG, "write - dest_addr=0x%08x, size=0x%08x, result=0x%08x", dest_addr, size, result); + ESP_LOGE(TAG, "write - dest_addr=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) dest_addr, (uint32_t) size, result); } return result; } @@ -60,9 +61,9 @@ esp_err_t SPI_Flash::read(size_t src_addr, void *dest, size_t size) { esp_err_t result = esp_flash_read(NULL, dest, src_addr, size); if (result == ESP_OK) { - ESP_LOGV(TAG, "read - src_addr=0x%08x, size=0x%08x, result=0x%08x", src_addr, size, result); + ESP_LOGV(TAG, "read - src_addr=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) src_addr, (uint32_t) size, result); } else { - ESP_LOGE(TAG, "read - src_addr=0x%08x, size=0x%08x, result=0x%08x", src_addr, size, result); + ESP_LOGE(TAG, "read - src_addr=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) src_addr, (uint32_t) size, result); } return result; } diff --git a/components/wear_levelling/WL_Ext_Perf.cpp b/components/wear_levelling/WL_Ext_Perf.cpp index 03fbfdce7e0..2fc89debace 100644 --- a/components/wear_levelling/WL_Ext_Perf.cpp +++ b/components/wear_levelling/WL_Ext_Perf.cpp @@ -6,13 +6,14 @@ #include "WL_Ext_Perf.h" #include "Partition.h" #include +#include #include "esp_log.h" static const char *TAG = "wl_ext_perf"; #define WL_EXT_RESULT_CHECK(result) \ if (result != ESP_OK) { \ - ESP_LOGE(TAG,"%s(%d): result = 0x%08x", __FUNCTION__, __LINE__, result); \ + ESP_LOGE(TAG,"%s(%d): result = 0x%08" PRIx32, __FUNCTION__, __LINE__, (uint32_t) result); \ return (result); \ } @@ -76,7 +77,7 @@ esp_err_t WL_Ext_Perf::erase_sector_fit(uint32_t first_erase_sector, uint32_t co { // This method works with one flash device sector and able to erase "count" of fatfs sectors from this first_erase_sector esp_err_t result = ESP_OK; - ESP_LOGV(TAG, "%s begin, first_erase_sector = 0x%08x, count = %i", __func__, first_erase_sector, count); + ESP_LOGV(TAG, "%s begin, first_erase_sector = 0x%08" PRIx32 ", count = %" PRIu32, __func__, first_erase_sector, count); uint32_t flash_sector_base_addr = first_erase_sector / this->flash_fat_sector_size_factor; uint32_t pre_check_start = first_erase_sector % this->flash_fat_sector_size_factor; @@ -136,7 +137,7 @@ esp_err_t WL_Ext_Perf::erase_range(size_t start_address, size_t size) // erase complete sector and restore data of area which should not be erased. // For the rest check area, this operation not needed because complete flash device sector will be erased. - ESP_LOGV(TAG, "%s begin, addr = 0x%08x, size = %i", __func__, start_address, size); + ESP_LOGV(TAG, "%s begin, addr = 0x%08" PRIx32 ", size = %" PRIu32, __func__, (uint32_t) start_address, (uint32_t) size); uint32_t sectors_count = size / this->fat_sector_size; // Calculate pre check values @@ -164,7 +165,7 @@ esp_err_t WL_Ext_Perf::erase_range(size_t start_address, size_t size) result = this->erase_sector_fit(start_address / this->fat_sector_size, pre_check_count); WL_EXT_RESULT_CHECK(result); } - ESP_LOGV(TAG, "%s rest_check_start = %i, pre_check_count=%i, rest_check_count=%i, post_check_count=%i", __func__, rest_check_start, pre_check_count, rest_check_count, post_check_count); + ESP_LOGV(TAG, "%s rest_check_start = %" PRIu32 ", pre_check_count=%" PRIu32 ", rest_check_count=%" PRIu32 ", post_check_count=%" PRIu32, __func__, rest_check_start, pre_check_count, rest_check_count, post_check_count); // Clear rest_check_count sectors if (rest_check_count > 0) { diff --git a/components/wear_levelling/WL_Ext_Safe.cpp b/components/wear_levelling/WL_Ext_Safe.cpp index 695b6829ce1..73edc79c3ca 100644 --- a/components/wear_levelling/WL_Ext_Safe.cpp +++ b/components/wear_levelling/WL_Ext_Safe.cpp @@ -1,17 +1,18 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "WL_Ext_Safe.h" #include +#include #include "esp_log.h" static const char *TAG = "wl_ext_safe"; #define WL_EXT_RESULT_CHECK(result) \ if (result != ESP_OK) { \ - ESP_LOGE(TAG,"%s(%d): result = 0x%08x", __FUNCTION__, __LINE__, result); \ + ESP_LOGE(TAG,"%s(%d): result = 0x%08" PRIx32, __FUNCTION__, __LINE__, (uint32_t) result); \ return (result); \ } @@ -77,7 +78,7 @@ esp_err_t WL_Ext_Safe::init() size_t WL_Ext_Safe::get_flash_size() { - ESP_LOGV(TAG, "%s size = %i", __func__, WL_Ext_Perf::get_flash_size() - 2 * this->flash_sector_size); + ESP_LOGV(TAG, "%s size = %" PRIu32, __func__, (uint32_t) (WL_Ext_Perf::get_flash_size() - 2 * this->flash_sector_size)); return WL_Ext_Perf::get_flash_size() - 2 * this->flash_sector_size; } @@ -89,7 +90,7 @@ esp_err_t WL_Ext_Safe::recover() WL_Ext_Safe_State state; result = this->read(this->buff_trans_state_addr, &state, sizeof(WL_Ext_Safe_State)); WL_EXT_RESULT_CHECK(result); - ESP_LOGV(TAG, "%s recover, start_addr = 0x%08x, sector_base_addr = 0x%08x, sector_base_addr_offset= %i, count=%i", __func__, state.sector_restore_sign, state.sector_base_addr, state.sector_base_addr_offset, state.count); + ESP_LOGV(TAG, "%s recover, start_addr = 0x%08" PRIx32 ", sector_base_addr = 0x%08" PRIx32 ", sector_base_addr_offset= %" PRIu32 ", count=%" PRIu32, __func__, state.sector_restore_sign, state.sector_base_addr, state.sector_base_addr_offset, state.count); // check if we have any incomplete transaction pending. if (state.sector_restore_sign == WL_EXT_SAFE_OK) { @@ -129,7 +130,7 @@ esp_err_t WL_Ext_Safe::erase_sector_fit(uint32_t first_erase_sector, uint32_t co uint32_t pre_check_start = first_erase_sector % this->flash_fat_sector_size_factor; // Except pre check and post check data area, read and store all other data to sector_buffer - ESP_LOGV(TAG, "%s first_erase_sector=0x%08x, count = %i", __func__, first_erase_sector, count); + ESP_LOGV(TAG, "%s first_erase_sector=0x%08" PRIx32 ", count = %" PRIu32, __func__, first_erase_sector, count); for (int i = 0; i < this->flash_fat_sector_size_factor; i++) { if ((i < pre_check_start) || (i >= count + pre_check_start)) { result = this->read(flash_sector_base_addr * this->flash_sector_size + i * this->fat_sector_size, diff --git a/components/wear_levelling/WL_Flash.cpp b/components/wear_levelling/WL_Flash.cpp index b3fd31e4ff0..626445c467b 100644 --- a/components/wear_levelling/WL_Flash.cpp +++ b/components/wear_levelling/WL_Flash.cpp @@ -12,6 +12,7 @@ #include "crc32.h" #include #include +#include static const char *TAG = "wl_flash"; #ifndef WL_CFG_CRC_CONST @@ -20,7 +21,7 @@ static const char *TAG = "wl_flash"; #define WL_RESULT_CHECK(result) \ if (result != ESP_OK) { \ - ESP_LOGE(TAG,"%s(%d): result = 0x%08x", __FUNCTION__, __LINE__, result); \ + ESP_LOGE(TAG,"%s(%d): result = 0x%08" PRIx32, __FUNCTION__, __LINE__, (uint32_t) result); \ return (result); \ } @@ -40,7 +41,7 @@ WL_Flash::~WL_Flash() esp_err_t WL_Flash::config(wl_config_t *cfg, Partition *partition) { - ESP_LOGV(TAG, "%s partition_start_addr=0x%08x, wl_partition_size=0x%08x, wl_page_size=0x%08x, flash_sector_size=0x%08x, wl_update_rate=0x%08x, wl_pos_update_record_size=0x%08x, version=0x%08x, wl_temp_buff_size=0x%08x", __func__, + ESP_LOGV(TAG, "%s partition_start_addr=0x%08" PRIx32 ", wl_partition_size=0x%08" PRIx32 ", wl_page_size=0x%08" PRIx32 ", flash_sector_size=0x%08" PRIx32 ", wl_update_rate=0x%08" PRIx32 ", wl_pos_update_record_size=0x%08" PRIx32 ", version=0x%08" PRIx32 ", wl_temp_buff_size=0x%08" PRIx32 , __func__, (uint32_t) cfg->wl_partition_start_addr, cfg->wl_partition_size, cfg->wl_page_size, @@ -87,7 +88,7 @@ esp_err_t WL_Flash::config(wl_config_t *cfg, Partition *partition) ptrdiff_t flash_sz = ((this->cfg.wl_partition_size - this->state_size * 2 - this->cfg_size) / this->cfg.wl_page_size - 1) * this->cfg.wl_page_size; // -1 remove dummy block this->flash_size = ((this->cfg.wl_partition_size - this->state_size * 2 - this->cfg_size) / this->cfg.wl_page_size - 1) * this->cfg.wl_page_size; // -1 remove dummy block - ESP_LOGD(TAG, "%s - config result: state_size=0x%08x, cfg_size=0x%08x, addr_cfg=0x%08x, addr_state1=0x%08x, addr_state2=0x%08x, flash_size=0x%08x", __func__, + ESP_LOGD(TAG, "%s - config result: state_size=0x%08" PRIx32 ", cfg_size=0x%08" PRIx32 ", addr_cfg=0x%08" PRIx32 ", addr_state1=0x%08" PRIx32 ", addr_state2=0x%08" PRIx32 ", flash_size=0x%08" PRIx32, __func__, (uint32_t) this->state_size, (uint32_t) this->cfg_size, (uint32_t) this->addr_cfg, @@ -130,7 +131,7 @@ esp_err_t WL_Flash::init() uint32_t crc1 = crc32::crc32_le(WL_CFG_CRC_CONST, (uint8_t *)&this->state, check_size); uint32_t crc2 = crc32::crc32_le(WL_CFG_CRC_CONST, (uint8_t *)state_copy, check_size); - ESP_LOGD(TAG, "%s - config ID=%i, stored ID=%i, wl_sec_erase_cycle_count=%i, wl_block_size=%i, wl_max_sec_erase_cycle_count=%i, wl_dummy_sec_pos=%i, wl_dummy_sec_move_count=0x%8.8X", + ESP_LOGD(TAG, "%s - config ID=%" PRIu32 ", stored ID=%" PRIu32 ", wl_sec_erase_cycle_count=%" PRIu32 ", wl_block_size=%" PRIu32 ", wl_max_sec_erase_cycle_count=%" PRIu32 ", wl_dummy_sec_pos=%" PRIu32 ", wl_dummy_sec_move_count=0x%8.8" PRIX32, __func__, this->cfg.version, this->state.version, @@ -140,7 +141,7 @@ esp_err_t WL_Flash::init() this->state.wl_dummy_sec_pos, this->state.wl_dummy_sec_move_count); - ESP_LOGD(TAG, "%s starts: crc1= 0x%08x, crc2 = 0x%08x, this->state.crc= 0x%08x, state_copy->crc= 0x%08x, version=%i, read_version=%i", __func__, crc1, crc2, this->state.crc32, state_copy->crc32, this->cfg.version, this->state.version); + ESP_LOGD(TAG, "%s starts: crc1= 0x%08" PRIx32 ", crc2 = 0x%08" PRIx32 ", this->state.crc= 0x%08" PRIx32 ", state_copy->crc= 0x%08" PRIx32 ", version=%" PRIu32 ", read_version=%" PRIu32, __func__, crc1, crc2, this->state.crc32, state_copy->crc32, this->cfg.version, this->state.version); if ((crc1 == this->state.crc32) && (crc2 == state_copy->crc32)) { // The state is OK. Check the ID if (this->state.version != this->cfg.version) { @@ -167,13 +168,13 @@ esp_err_t WL_Flash::init() } } } - ESP_LOGD(TAG, "%s: crc1=0x%08x, crc2 = 0x%08x, result= 0x%08x", __func__, crc1, crc2, (uint32_t)result); + ESP_LOGD(TAG, "%s: crc1=0x%08" PRIx32 ", crc2 = 0x%08" PRIx32 ", result= 0x%08" PRIx32 , __func__, crc1, crc2, (uint32_t)result); result = this->recoverPos(); WL_RESULT_CHECK(result); } } else if ((crc1 != this->state.crc32) && (crc2 != state_copy->crc32)) { // This is just new flash or new version // Check if this is new version or just new instance of WL - ESP_LOGD(TAG, "%s: try to update version - crc1= 0x%08x, crc2 = 0x%08x, result= 0x%08x", __func__, (uint32_t)crc1, (uint32_t)crc2, (uint32_t)result); + ESP_LOGD(TAG, "%s: try to update version - crc1= 0x%08" PRIx32 ", crc2 = 0x%08" PRIx32 ", result= 0x%08" PRIx32 , __func__, (uint32_t)crc1, (uint32_t)crc2, (uint32_t)result); result = this->updateVersion(); if (result == ESP_FAIL) { ESP_LOGD(TAG, "%s: init flash sections", __func__); @@ -232,11 +233,11 @@ esp_err_t WL_Flash::init() } if (result != ESP_OK) { this->initialized = false; - ESP_LOGE(TAG, "%s: returned 0x%08x", __func__, (uint32_t)result); + ESP_LOGE(TAG, "%s: returned 0x%08" PRIx32 , __func__, (uint32_t)result); return result; } this->initialized = true; - ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08x", __func__, (uint32_t)this->state.wl_dummy_sec_move_count); + ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08" PRIx32 , __func__, (uint32_t)this->state.wl_dummy_sec_move_count); return ESP_OK; } @@ -251,7 +252,7 @@ esp_err_t WL_Flash::recoverPos() result = this->partition->read(this->addr_state1 + sizeof(wl_state_t) + i * this->cfg.wl_pos_update_record_size, this->temp_buff, this->cfg.wl_pos_update_record_size); pos_bits = this->OkBuffSet(i); WL_RESULT_CHECK(result); - ESP_LOGV(TAG, "%s - check pos: result=0x%08x, position= %i, pos_bits= 0x%08x", __func__, (uint32_t)result, (uint32_t)position, (uint32_t)pos_bits); + ESP_LOGV(TAG, "%s - check pos: result=0x%08" PRIx32 ", position= %" PRIu32 ", pos_bits= 0x%08" PRIx32 , __func__, (uint32_t) result, (uint32_t) position, (uint32_t) pos_bits); if (pos_bits == false) { break; // we have found position } @@ -261,7 +262,7 @@ esp_err_t WL_Flash::recoverPos() if (this->state.wl_dummy_sec_pos == this->state.wl_part_max_sec_pos) { this->state.wl_dummy_sec_pos--; } - ESP_LOGD(TAG, "%s - this->state.wl_dummy_sec_pos= 0x%08x, position= 0x%08x, result= 0x%08x, wl_part_max_sec_pos= 0x%08x", __func__, (uint32_t)this->state.wl_dummy_sec_pos, (uint32_t)position, (uint32_t)result, (uint32_t)this->state.wl_part_max_sec_pos); + ESP_LOGD(TAG, "%s - this->state.wl_dummy_sec_pos= 0x%08" PRIx32 ", position= 0x%08" PRIx32 ", result= 0x%08" PRIx32 ", wl_part_max_sec_pos= 0x%08" PRIx32 , __func__, (uint32_t)this->state.wl_dummy_sec_pos, (uint32_t)position, (uint32_t)result, (uint32_t)this->state.wl_part_max_sec_pos); ESP_LOGV(TAG, "%s done", __func__); return result; } @@ -301,8 +302,8 @@ esp_err_t WL_Flash::initSections() result = this->partition->write(this->addr_cfg, &this->cfg, sizeof(wl_config_t)); WL_RESULT_CHECK(result); - ESP_LOGD(TAG, "%s - this->state->wl_max_sec_erase_cycle_count= 0x%08x, this->state->wl_part_max_sec_pos= 0x%08x", __func__, this->state.wl_max_sec_erase_cycle_count, this->state.wl_part_max_sec_pos); - ESP_LOGD(TAG, "%s - result= 0x%08x", __func__, result); + ESP_LOGD(TAG, "%s - this->state->wl_max_sec_erase_cycle_count= 0x%08" PRIx32 ", this->state->wl_part_max_sec_pos= 0x%08" PRIx32 , __func__, this->state.wl_max_sec_erase_cycle_count, this->state.wl_part_max_sec_pos); + ESP_LOGD(TAG, "%s - result= 0x%08x" , __func__, result); return result; } @@ -336,24 +337,24 @@ esp_err_t WL_Flash::updateV1_V2() uint32_t v1_crc1 = this->state.wl_device_id; uint32_t v1_crc2 = state_copy->wl_device_id; - ESP_LOGD(TAG, "%s - process crc1=0x%08x, crc2=0x%08x, v1_crc1=0x%08x, v1_crc2=0x%08x, version=%i", __func__, crc1, crc2, v1_crc1, v1_crc2, this->state.version); + ESP_LOGD(TAG, "%s - process crc1=0x%08" PRIx32 ", crc2=0x%08" PRIx32 ", v1_crc1=0x%08" PRIx32 ", v1_crc2=0x%08" PRIx32 ", version=%" PRIu32, __func__, crc1, crc2, v1_crc1, v1_crc2, this->state.version); if ((crc1 == v1_crc1) && (crc2 == v1_crc2) && (v1_crc1 == v1_crc2) && (this->state.version == 1) && (state_copy->version == 1)) { // Here we have to update all internal structures - ESP_LOGI(TAG, "%s Update from V1 to V2, crc=0x%08x, ", __func__, crc1); + ESP_LOGI(TAG, "%s Update from V1 to V2, crc=0x%08" PRIx32 ", ", __func__, crc1); uint32_t pos = 0; for (size_t i = 0; i < this->state.wl_part_max_sec_pos; i++) { uint8_t pos_bits; result = this->partition->read(this->addr_state1 + sizeof(wl_state_t) + i * this->cfg.wl_pos_update_record_size, &pos_bits, 1); WL_RESULT_CHECK(result); - ESP_LOGV(TAG, "%s- result= 0x%08x, pos= %i, pos_bits= 0x%08x", __func__, (uint32_t)result, (uint32_t)pos, (uint32_t)pos_bits); + ESP_LOGV(TAG, "%s- result= 0x%08" PRIx32 ", pos= %" PRIu32 ", pos_bits= 0x%08" PRIx32 , __func__, (uint32_t) result, (uint32_t) pos, (uint32_t) pos_bits); pos = i; if (pos_bits == 0xff) { break; // we have found position } } - ESP_LOGI(TAG, "%s wl_part_max_sec_pos=%i, pos=%i, state.ver=%i, state2.ver=%i", __func__, (uint32_t)this->state.wl_part_max_sec_pos, (uint32_t)pos, (uint32_t)this->state.version, (uint32_t)state_copy->version); + ESP_LOGI(TAG, "%s wl_part_max_sec_pos=%" PRIu32 ", pos=%" PRIu32 ", state.ver=%" PRIu32 ", state2.ver=%" PRIu32, __func__, (uint32_t) this->state.wl_part_max_sec_pos, (uint32_t) pos, (uint32_t) this->state.version, (uint32_t) state_copy->version); if (pos == this->state.wl_part_max_sec_pos) { pos--; } @@ -381,7 +382,7 @@ esp_err_t WL_Flash::updateV1_V2() WL_RESULT_CHECK(result); result = this->partition->write(this->addr_state2, &this->state, sizeof(wl_state_t)); WL_RESULT_CHECK(result); - ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08x, pos= 0x%08x", __func__, this->state.wl_dummy_sec_move_count, this->state.wl_dummy_sec_pos); + ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08" PRIx32 ", pos= 0x%08" PRIx32 , __func__, this->state.wl_dummy_sec_move_count, this->state.wl_dummy_sec_pos); memset(this->temp_buff, 0, this->cfg.wl_pos_update_record_size); for (uint32_t i = 0 ; i <= pos; i++) { @@ -430,7 +431,7 @@ esp_err_t WL_Flash::updateWL() } // Here we have to move the block and increase the state this->state.wl_sec_erase_cycle_count = 0; - ESP_LOGV(TAG, "%s - wl_sec_erase_cycle_count= 0x%08x, pos= 0x%08x", __func__, this->state.wl_sec_erase_cycle_count, this->state.wl_dummy_sec_pos); + ESP_LOGV(TAG, "%s - wl_sec_erase_cycle_count= 0x%08" PRIx32 ", pos= 0x%08" PRIx32 , __func__, this->state.wl_sec_erase_cycle_count, this->state.wl_dummy_sec_pos); // copy data to dummy block size_t data_addr = this->state.wl_dummy_sec_pos + 1; // next block, [pos+1] copy to [pos] if (data_addr >= this->state.wl_part_max_sec_pos) { @@ -440,7 +441,7 @@ esp_err_t WL_Flash::updateWL() this->dummy_addr = this->cfg.wl_partition_start_addr + this->state.wl_dummy_sec_pos * this->cfg.wl_page_size; result = this->partition->erase_range(this->dummy_addr, this->cfg.wl_page_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - erase wl dummy sector result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - erase wl dummy sector result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } @@ -449,13 +450,13 @@ esp_err_t WL_Flash::updateWL() for (size_t i = 0; i < copy_count; i++) { result = this->partition->read(data_addr + i * this->cfg.wl_temp_buff_size, this->temp_buff, this->cfg.wl_temp_buff_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - not possible to read buffer, will try next time, result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - not possible to read buffer, will try next time, result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } result = this->partition->write(this->dummy_addr + i * this->cfg.wl_temp_buff_size, this->temp_buff, this->cfg.wl_temp_buff_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - not possible to write buffer, will try next time, result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - not possible to write buffer, will try next time, result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } @@ -468,14 +469,14 @@ esp_err_t WL_Flash::updateWL() // write state to mem. We updating only affected bits result |= this->partition->write(this->addr_state1 + sizeof(wl_state_t) + byte_pos, this->temp_buff, this->cfg.wl_pos_update_record_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - update position 1 result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - update position 1 result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } this->fillOkBuff(this->state.wl_dummy_sec_pos); result |= this->partition->write(this->addr_state2 + sizeof(wl_state_t) + byte_pos, this->temp_buff, this->cfg.wl_pos_update_record_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - update position 2 result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - update position 2 result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } @@ -499,13 +500,13 @@ esp_err_t WL_Flash::updateWL() WL_RESULT_CHECK(result); result = this->partition->write(this->addr_state2, &this->state, sizeof(wl_state_t)); WL_RESULT_CHECK(result); - ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08x, wl_dummy_sec_pos= 0x%08x, ", __func__, this->state.wl_dummy_sec_move_count, this->state.wl_dummy_sec_pos); + ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08" PRIx32 ", wl_dummy_sec_pos= 0x%08" PRIx32 ", ", __func__, this->state.wl_dummy_sec_move_count, this->state.wl_dummy_sec_pos); } // Save structures to the flash... and check result if (result == ESP_OK) { - ESP_LOGV(TAG, "%s - result= 0x%08x", __func__, result); + ESP_LOGV(TAG, "%s - result= 0x%08x" , __func__, result); } else { - ESP_LOGE(TAG, "%s - result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - result= 0x%08x" , __func__, result); } return result; } @@ -518,7 +519,7 @@ size_t WL_Flash::calcAddr(size_t addr) } else { result += this->cfg.wl_page_size; } - ESP_LOGV(TAG, "%s - addr= 0x%08x -> result= 0x%08x, dummy_addr= 0x%08x", __func__, (uint32_t) addr, (uint32_t) result, (uint32_t)dummy_addr); + ESP_LOGV(TAG, "%s - addr= 0x%08" PRIx32 " -> result= 0x%08" PRIx32 ", dummy_addr= 0x%08" PRIx32 , __func__, (uint32_t) addr, (uint32_t) result, (uint32_t)dummy_addr); return result; } @@ -545,7 +546,7 @@ esp_err_t WL_Flash::erase_sector(size_t sector) if (!this->initialized) { return ESP_ERR_INVALID_STATE; } - ESP_LOGD(TAG, "%s - sector= 0x%08x", __func__, (uint32_t) sector); + ESP_LOGD(TAG, "%s - sector= 0x%08" PRIx32 , __func__, (uint32_t) sector); result = this->updateWL(); WL_RESULT_CHECK(result); size_t virt_addr = this->calcAddr(sector * this->cfg.flash_sector_size); @@ -560,14 +561,14 @@ esp_err_t WL_Flash::erase_range(size_t start_address, size_t size) if (!this->initialized) { return ESP_ERR_INVALID_STATE; } - ESP_LOGD(TAG, "%s - start_address= 0x%08x, size= 0x%08x", __func__, (uint32_t) start_address, (uint32_t) size); + ESP_LOGD(TAG, "%s - start_address= 0x%08" PRIx32 ", size= 0x%08" PRIx32 , __func__, (uint32_t) start_address, (uint32_t) size); size_t erase_count = (size + this->cfg.flash_sector_size - 1) / this->cfg.flash_sector_size; size_t start_sector = start_address / this->cfg.flash_sector_size; for (size_t i = 0; i < erase_count; i++) { result = this->erase_sector(start_sector + i); WL_RESULT_CHECK(result); } - ESP_LOGV(TAG, "%s - result= 0x%08x", __func__, result); + ESP_LOGV(TAG, "%s - result= 0x%08x" , __func__, result); return result; } @@ -577,7 +578,7 @@ esp_err_t WL_Flash::write(size_t dest_addr, const void *src, size_t size) if (!this->initialized) { return ESP_ERR_INVALID_STATE; } - ESP_LOGD(TAG, "%s - dest_addr= 0x%08x, size= 0x%08x", __func__, (uint32_t) dest_addr, (uint32_t) size); + ESP_LOGD(TAG, "%s - dest_addr= 0x%08" PRIx32 ", size= 0x%08" PRIx32 , __func__, (uint32_t) dest_addr, (uint32_t) size); uint32_t count = (size - 1) / this->cfg.wl_page_size; for (size_t i = 0; i < count; i++) { size_t virt_addr = this->calcAddr(dest_addr + i * this->cfg.wl_page_size); @@ -596,11 +597,11 @@ esp_err_t WL_Flash::read(size_t src_addr, void *dest, size_t size) if (!this->initialized) { return ESP_ERR_INVALID_STATE; } - ESP_LOGD(TAG, "%s - src_addr= 0x%08x, size= 0x%08x", __func__, (uint32_t) src_addr, (uint32_t) size); + ESP_LOGD(TAG, "%s - src_addr= 0x%08" PRIx32 ", size= 0x%08" PRIx32 , __func__, (uint32_t) src_addr, (uint32_t) size); uint32_t count = (size - 1) / this->cfg.wl_page_size; for (size_t i = 0; i < count; i++) { size_t virt_addr = this->calcAddr(src_addr + i * this->cfg.wl_page_size); - ESP_LOGV(TAG, "%s - real_addr= 0x%08x, size= 0x%08x", __func__, (uint32_t) (this->cfg.wl_partition_start_addr + virt_addr), (uint32_t) size); + ESP_LOGV(TAG, "%s - real_addr= 0x%08" PRIx32 ", size= 0x%08" PRIx32 , __func__, (uint32_t) (this->cfg.wl_partition_start_addr + virt_addr), (uint32_t) size); result = this->partition->read(this->cfg.wl_partition_start_addr + virt_addr, &((uint8_t *)dest)[i * this->cfg.wl_page_size], this->cfg.wl_page_size); WL_RESULT_CHECK(result); } @@ -624,6 +625,6 @@ esp_err_t WL_Flash::flush() esp_err_t result = ESP_OK; this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; result = this->updateWL(); - ESP_LOGD(TAG, "%s - result= 0x%08x, wl_dummy_sec_move_count= 0x%08x", __func__, result, this->state.wl_dummy_sec_move_count); + ESP_LOGD(TAG, "%s - result= 0x%08x, wl_dummy_sec_move_count= 0x%08" PRIx32, __func__, result, this->state.wl_dummy_sec_move_count); return result; } diff --git a/components/wear_levelling/test_apps/main/CMakeLists.txt b/components/wear_levelling/test_apps/main/CMakeLists.txt index 84359c084b0..9273ee133d2 100644 --- a/components/wear_levelling/test_apps/main/CMakeLists.txt +++ b/components/wear_levelling/test_apps/main/CMakeLists.txt @@ -3,4 +3,3 @@ idf_component_register(SRCS test_wl.c PRIV_REQUIRES wear_levelling unity spi_flash EMBED_FILES test_partition_v1.bin ) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/wear_levelling/test_apps/main/test_wl.c b/components/wear_levelling/test_apps/main/test_wl.c index 6585334027f..227c6d90372 100644 --- a/components/wear_levelling/test_apps/main/test_wl.c +++ b/components/wear_levelling/test_apps/main/test_wl.c @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include "unity.h" #include "unity_fixture.h" #include "wear_levelling.h" @@ -120,7 +121,7 @@ static void read_write_task(void *param) uint32_t rval; err = wl_read(args->handle, args->offset + i * sizeof(rval), &rval, sizeof(rval)); if (err != ESP_OK || rval != val) { - printf("E: i=%d, cnt=%d rval=%d val=%d\n\n", i, args->word_count, rval, val); + printf("E: i=%" PRIu32 ", cnt=%" PRIu32 " rval=%" PRIu32 " val=%" PRIu32 "\n\n", (uint32_t) i, (uint32_t) args->word_count, rval, val); args->result = ESP_FAIL; goto done; } @@ -225,7 +226,7 @@ TEST(wear_levelling, write_doesnt_touch_other_sectors) // Erase 8 sectors TEST_ESP_OK(wl_erase_range(handle, 0, sector_size * TEST_SECTORS_COUNT)); // Write data to all sectors - printf("Check 1 sector_size=0x%08x\n", sector_size); + printf("Check 1 sector_size=0x%08" PRIx32 "\n", (uint32_t) sector_size); // Set initial random value uint32_t init_val = rand(); @@ -256,7 +257,7 @@ TEST(wear_levelling, write_doesnt_touch_other_sectors) uint32_t end; end = esp_cpu_get_cycle_count(); uint32_t ms = (end - start) / (esp_clk_cpu_freq() / 1000); - printf("loop %4i pass, time= %ims\n", m, ms); + printf("loop %4d pass, time= %" PRIu32 "ms\n", m, ms); if (ms > 10000) { break; } @@ -288,13 +289,13 @@ TEST(wear_levelling, version_update) } fake_partition.size = (size_t)(test_partition_v1_bin_end - test_partition_v1_bin_start); - printf("Data file size = %i, partition address = 0x%08x, file addr=0x%08x\n", (uint32_t)fake_partition.size, (uint32_t)fake_partition.address, (uint32_t)test_partition_v1_bin_start); + printf("Data file size = %" PRIu32 ", partition address = 0x%08" PRIx32 ", file addr=0x%08" PRIx32 "\n", (uint32_t) fake_partition.size, (uint32_t) fake_partition.address, (uint32_t) test_partition_v1_bin_start); esp_partition_erase_range(&fake_partition, 0, fake_partition.size); esp_partition_write(&fake_partition, 0, test_partition_v1_bin_start, fake_partition.size); for (int i = 0; i < 3; i++) { - printf("Pass %i\n", i); + printf("Pass %d\n", i); wl_handle_t handle; TEST_ESP_OK(wl_mount(&fake_partition, &handle)); size_t sector_size = wl_sector_size(handle); @@ -308,7 +309,7 @@ TEST(wear_levelling, version_update) for (int i = 0; i < sector_size / sizeof(uint32_t); i++) { uint32_t compare_val = init_val + i + m * sector_size; if (buff[i] != compare_val) { - printf("error compare: 0x%08x != 0x%08x \n", buff[i], compare_val); + printf("error compare: 0x%08" PRIx32 " != 0x%08" PRIx32 " \n", buff[i], compare_val); } TEST_ASSERT_EQUAL( buff[i], compare_val); } diff --git a/components/wear_levelling/wear_levelling.cpp b/components/wear_levelling/wear_levelling.cpp index cdbdc923c09..d44e1b484cb 100644 --- a/components/wear_levelling/wear_levelling.cpp +++ b/components/wear_levelling/wear_levelling.cpp @@ -136,14 +136,14 @@ esp_err_t wl_mount(const esp_partition_t *partition, wl_handle_t *out_handle) // Configure data needed by WL layer for respective flash driver result = wl_flash->config(&cfg, part); if (ESP_OK != result) { - ESP_LOGE(TAG, "%s: config instance=0x%08x, result=0x%x", __func__, *out_handle, result); + ESP_LOGE(TAG, "%s: config instance=0x%08" PRIx32 ", result=0x%x", __func__, *out_handle, result); goto out; } // Initialise sectors used by WL layer for respective flash driver result = wl_flash->init(); if (ESP_OK != result) { - ESP_LOGE(TAG, "%s: init instance=0x%08x, result=0x%x", __func__, *out_handle, result); + ESP_LOGE(TAG, "%s: init instance=0x%08" PRIx32 ", result=0x%x", __func__, *out_handle, result); goto out; } @@ -258,11 +258,11 @@ static esp_err_t check_handle(wl_handle_t handle, const char *func) return ESP_ERR_NOT_FOUND; } if (handle >= MAX_WL_HANDLES) { - ESP_LOGE(TAG, "%s: instance[0x%08x] out of range", func, handle); + ESP_LOGE(TAG, "%s: instance[0x%08" PRIx32 "] out of range", func, handle); return ESP_ERR_INVALID_ARG; } if (s_instances[handle].instance == NULL) { - ESP_LOGE(TAG, "%s: instance[0x%08x] not initialized", func, handle); + ESP_LOGE(TAG, "%s: instance[0x%08" PRIx32 "] not initialized", func, handle); return ESP_ERR_NOT_FOUND; } return ESP_OK; diff --git a/components/wifi_provisioning/src/manager.c b/components/wifi_provisioning/src/manager.c index 69ed01e0fcc..07022ecbfd3 100644 --- a/components/wifi_provisioning/src/manager.c +++ b/components/wifi_provisioning/src/manager.c @@ -558,6 +558,16 @@ static void prov_stop_and_notify(bool is_async) vTaskDelay(cleanup_delay / portTICK_PERIOD_MS); } + protocomm_remove_endpoint(prov_ctx->pc, "prov-ctrl"); + + protocomm_remove_endpoint(prov_ctx->pc, "prov-scan"); + + protocomm_remove_endpoint(prov_ctx->pc, "prov-config"); + + protocomm_unset_security(prov_ctx->pc, "prov-session"); + + protocomm_unset_version(prov_ctx->pc, "proto-ver"); + /* All the extra application added endpoints are also * removed automatically when prov_stop is called */ prov_ctx->mgr_config.scheme.prov_stop(prov_ctx->pc); diff --git a/components/wifi_provisioning/src/scheme_ble.c b/components/wifi_provisioning/src/scheme_ble.c index 88e1724e08c..6b594f22c46 100644 --- a/components/wifi_provisioning/src/scheme_ble.c +++ b/components/wifi_provisioning/src/scheme_ble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,9 @@ #include #include #include +#ifdef CONFIG_BT_CONTROLLER_ENABLED #include "esp_bt.h" +#endif #include #include @@ -197,9 +199,10 @@ static esp_err_t set_config_endpoint(void *config, const char *endpoint_name, ui /* Used when both BT and BLE are not needed by application */ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event_t event, void *event_data) { - esp_err_t err; switch (event) { case WIFI_PROV_INIT: +#ifdef CONFIG_BT_CONTROLLER_ENABLED + esp_err_t err; /* Release BT memory, as we need only BLE */ err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT); if (err != ESP_OK) { @@ -207,10 +210,12 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event } else { ESP_LOGI(TAG, "BT memory released"); } +#endif break; case WIFI_PROV_DEINIT: #ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV +#ifdef CONFIG_BT_CONTROLLER_ENABLED /* Release memory used by BLE and Bluedroid host stack */ err = esp_bt_mem_release(ESP_BT_MODE_BTDM); if (err != ESP_OK) { @@ -218,6 +223,7 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event } else { ESP_LOGI(TAG, "BTDM memory released"); } +#endif #endif break; @@ -229,9 +235,10 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event /* Used when BT is not needed by application */ void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t event, void *event_data) { - esp_err_t err; switch (event) { case WIFI_PROV_INIT: +#ifdef CONFIG_BT_CONTROLLER_ENABLED + esp_err_t err; /* Release BT memory, as we need only BLE */ err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT); if (err != ESP_OK) { @@ -239,6 +246,7 @@ void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t } else { ESP_LOGI(TAG, "BT memory released"); } +#endif break; default: @@ -249,10 +257,11 @@ void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t /* Used when BLE is not needed by application */ void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_t event, void *event_data) { - esp_err_t err; switch (event) { case WIFI_PROV_DEINIT: #ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV +#ifdef CONFIG_BT_CONTROLLER_ENABLED + esp_err_t err; /* Release memory used by BLE stack */ err = esp_bt_mem_release(ESP_BT_MODE_BLE); if (err != ESP_OK) { @@ -260,6 +269,7 @@ void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_ } else { ESP_LOGI(TAG, "BLE memory released"); } +#endif #endif break; diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c index 9790a0b3dd8..97b0df675fb 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c @@ -506,16 +506,19 @@ static int crypto_init_cipher_ctx(mbedtls_cipher_context_t *ctx, return -1; } - if (mbedtls_cipher_setkey(ctx, key, key_len * 8, operation) != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_setkey returned error"); + ret = mbedtls_cipher_setkey(ctx, key, key_len * 8, operation); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_cipher_setkey returned error=%d", ret); return -1; } - if (mbedtls_cipher_set_iv(ctx, iv, cipher_info->MBEDTLS_PRIVATE(iv_size)) != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_set_iv returned error"); + ret = mbedtls_cipher_set_iv(ctx, iv, cipher_info->MBEDTLS_PRIVATE(iv_size) << MBEDTLS_IV_SIZE_SHIFT); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_cipher_set_iv returned error=%d", ret); return -1; } - if (mbedtls_cipher_reset(ctx) != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_reset() returned error"); + ret = mbedtls_cipher_reset(ctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_cipher_reset() returned error=%d", ret); return -1; } diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c index 8ac2abbe568..24fc706c638 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c @@ -304,6 +304,65 @@ static int mbedtls_sha1_init_start(mbedtls_sha1_context *ctx) return 0; } +#ifndef MBEDTLS_SHA1_ALT +static int sha1_finish(mbedtls_sha1_context *ctx, + unsigned char output[20]) +{ + int ret = -1; + uint32_t used; + uint32_t high, low; + + /* + * Add padding: 0x80 then 0x00 until 8 bytes remain for the length + */ + used = ctx->MBEDTLS_PRIVATE(total)[0] & 0x3F; + + ctx->MBEDTLS_PRIVATE(buffer)[used++] = 0x80; + + if (used <= 56) { + /* Enough room for padding + length in current block */ + memset(ctx->MBEDTLS_PRIVATE(buffer) + used, 0, 56 - used); + } else { + /* We'll need an extra block */ + memset(ctx->MBEDTLS_PRIVATE(buffer) + used, 0, 64 - used); + + if ((ret = mbedtls_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { + goto exit; + } + + memset(ctx->MBEDTLS_PRIVATE(buffer), 0, 56); + } + + /* + * Add message length + */ + high = (ctx->MBEDTLS_PRIVATE(total)[0] >> 29) + | (ctx->MBEDTLS_PRIVATE(total)[1] << 3); + low = (ctx->MBEDTLS_PRIVATE(total)[0] << 3); + + write32_be(high, ctx->MBEDTLS_PRIVATE(buffer) + 56); + write32_be(low, ctx->MBEDTLS_PRIVATE(buffer) + 60); + + if ((ret = mbedtls_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { + goto exit; + } + + /* + * Output final state + */ + write32_be(ctx->MBEDTLS_PRIVATE(state)[0], output); + write32_be(ctx->MBEDTLS_PRIVATE(state)[1], output + 4); + write32_be(ctx->MBEDTLS_PRIVATE(state)[2], output + 8); + write32_be(ctx->MBEDTLS_PRIVATE(state)[3], output + 12); + write32_be(ctx->MBEDTLS_PRIVATE(state)[4], output + 16); + + ret = 0; + +exit: + return ret; +} +#endif + DECL_PBKDF2(sha1, // _name 64, // _blocksz 20, // _hashsz @@ -311,7 +370,11 @@ DECL_PBKDF2(sha1, // _name mbedtls_sha1_init_start, // _init mbedtls_sha1_update, // _update mbedtls_internal_sha1_process, // _xform +#if defined(MBEDTLS_SHA1_ALT) mbedtls_sha1_finish, // _final +#else + sha1_finish, // _final +#endif sha1_cpy, // _xcpy sha1_extract, // _xtract sha1_xor) // _xxor diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common.c b/components/wpa_supplicant/esp_supplicant/src/esp_common.c index 56399020c73..eeb5e006f88 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common.c @@ -47,7 +47,7 @@ static bool s_supplicant_task_init_done; #define SUPPLICANT_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD) static int handle_action_frm(u8 *frame, size_t len, - u8 *sender, u32 rssi, u8 channel) + u8 *sender, int8_t rssi, u8 channel) { struct ieee_mgmt_frame *frm = os_malloc(sizeof(struct ieee_mgmt_frame) + len); @@ -73,7 +73,7 @@ static int handle_action_frm(u8 *frame, size_t len, #if defined(CONFIG_IEEE80211KV) static void handle_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender, - u8 *payload, size_t len, u32 rssi) + u8 *payload, size_t len, int8_t rssi) { if (payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) { /* neighbor report parsing */ @@ -89,7 +89,7 @@ static void handle_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender, } } -static int mgmt_rx_action(u8 *frame, size_t len, u8 *sender, u32 rssi, u8 channel) +static int mgmt_rx_action(u8 *frame, size_t len, u8 *sender, int8_t rssi, u8 channel) { u8 category; u8 bssid[ETH_ALEN]; @@ -215,7 +215,7 @@ static void register_mgmt_frames(struct wpa_supplicant *wpa_s) #ifdef CONFIG_IEEE80211R static int handle_auth_frame(u8 *frame, size_t len, - u8 *sender, u32 rssi, u8 channel) + u8 *sender, int8_t rssi, u8 channel) { if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK) { if (gWpaSm.ft_protocol) { @@ -230,7 +230,7 @@ static int handle_auth_frame(u8 *frame, size_t len, } static int handle_assoc_frame(u8 *frame, size_t len, - u8 *sender, u32 rssi, u8 channel) + u8 *sender, int8_t rssi, u8 channel) { if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK) { if (gWpaSm.ft_protocol) { @@ -255,7 +255,7 @@ void esp_supplicant_unset_all_appie(void) } static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender, - u32 rssi, u8 channel, u64 current_tsf) + int8_t rssi, u8 channel, u64 current_tsf) { int ret = 0; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_common_i.h index d7d64f36432..e6c1d23290b 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common_i.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,7 @@ extern struct wpa_supplicant g_wpa_supp; struct ieee_mgmt_frame { u8 sender[ETH_ALEN]; u8 channel; - u32 rssi; + int8_t rssi; size_t len; u8 payload[0]; }; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index d1e7256be6f..aee399df901 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -179,6 +179,7 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, { wifi_config_t *wifi_cfg = &s_dpp_ctx.wifi_cfg; + os_memset(wifi_cfg, 0, sizeof(wifi_config_t)); if (conf->ssid_len) { os_memcpy(wifi_cfg->sta.ssid, conf->ssid, conf->ssid_len); } diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_scan.c b/components/wpa_supplicant/esp_supplicant/src/esp_scan.c index f4dc09655b9..d0f5edcef65 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_scan.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_scan.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -114,7 +114,7 @@ void esp_scan_deinit(struct wpa_supplicant *wpa_s) } int esp_handle_beacon_probe(u8 type, u8 *frame, size_t len, u8 *sender, - u32 rssi, u8 channel, u64 current_tsf) + int8_t rssi, u8 channel, u64 current_tsf) { struct wpa_supplicant *wpa_s = &g_wpa_supp; struct os_reltime now; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h index 25442a6ac0c..bbea3798674 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h @@ -1,17 +1,7 @@ -/** - * Copyright 2020 Espressif Systems (Shanghai) PTE LTD +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO 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-License-Identifier: Apache-2.0 */ #ifndef ESP_SCAN_I_H @@ -19,7 +9,7 @@ void esp_scan_init(struct wpa_supplicant *wpa_s); void esp_scan_deinit(struct wpa_supplicant *wpa_s); int esp_handle_beacon_probe(u8 type, u8 *frame, size_t len, u8 *sender, - u32 rssi, u8 channel, u64 current_tsf); + int8_t rssi, u8 channel, u64 current_tsf); void esp_supplicant_handle_scan_done_evt(void); #endif 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 8979dfc69da..0837ef1f0b5 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -137,7 +137,7 @@ struct wpa_funcs { uint8_t *(*wpa3_build_sae_msg)(uint8_t *bssid, uint32_t type, size_t *len); int (*wpa3_parse_sae_msg)(uint8_t *buf, size_t len, uint32_t type, uint16_t status); int (*wpa3_hostap_handle_auth)(uint8_t *buf, size_t len, uint32_t type, uint16_t status, uint8_t *bssid); - int (*wpa_sta_rx_mgmt)(u8 type, u8 *frame, size_t len, u8 *sender, u32 rssi, u8 channel, u64 current_tsf); + int (*wpa_sta_rx_mgmt)(u8 type, u8 *frame, size_t len, u8 *sender, int8_t rssi, u8 channel, u64 current_tsf); 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); 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 8d807836548..6f3c69110f2 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -321,12 +321,15 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len,u8 sta_info = ap_sta_add(hapd, bssid); if (!sta_info) { wpa_printf(MSG_ERROR, "failed to add station " MACSTR, MAC2STR(bssid)); - return false; + goto fail; } #ifdef CONFIG_SAE if (sta_info->lock && os_semphr_take(sta_info->lock, 0) != TRUE) { wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid)); + if (esp_send_assoc_resp(hapd, sta_info, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { + goto fail; + } return false; } #endif /* CONFIG_SAE */ @@ -357,10 +360,7 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len,u8 } fail: - if (sta_info) { - ap_free_sta(hapd, sta_info); - } - + esp_wifi_ap_deauth_internal(bssid, WLAN_REASON_PREV_AUTH_NOT_VALID); return false; } #endif diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 06f564e0840..94cfa95fbc0 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -655,6 +655,7 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, u8 *kde, *kde_buf = NULL; size_t kde_len; +#ifdef CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT if (is_wpa2_enterprise_connection()) { wpa2_ent_eap_state_t state = eap_client_get_eap_state(); if (state == WPA2_ENT_EAP_STATE_IN_PROGRESS) { @@ -663,6 +664,8 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, return; } } +#endif + wpa_sm_set_state(WPA_FIRST_HALF_4WAY_HANDSHAKE); wpa_printf(MSG_DEBUG, "WPA 1/4-Way Handshake"); diff --git a/docs/_static/usb_host/poweron-timings.png b/docs/_static/usb_host/poweron-timings.png new file mode 100644 index 00000000000..867253da18d Binary files /dev/null and b/docs/_static/usb_host/poweron-timings.png differ diff --git a/docs/conf_common.py b/docs/conf_common.py index 05d2bb9748c..6d286875c9a 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -63,12 +63,13 @@ WIFI_DOCS = ['api-guides/wifi.rst', 'api-guides/wifi-security.rst', 'api-guides/wireshark-user-guide.rst', - 'api-reference/network/esp_nan.rst', 'api-reference/network/esp_now.rst', 'api-reference/network/esp_smartconfig.rst', 'api-reference/network/esp_wifi.rst', 'api-reference/network/esp_dpp.rst'] +NAN_DOCS = ['api-reference/network/esp_nan.rst'] + WIFI_MESH_DOCS = ['api-guides/esp-wifi-mesh.rst', 'api-reference/network/esp-wifi-mesh.rst'] @@ -223,6 +224,7 @@ 'SOC_SDM_SUPPORTED':SDM_DOCS, 'SOC_WIFI_MESH_SUPPORT':WIFI_MESH_DOCS, 'SOC_SPI_SUPPORT_SLAVE_HD_VER2':SPI_SLAVE_HD_DOCS, + 'SOC_WIFI_NAN_SUPPORT':NAN_DOCS, 'esp32':ESP32_DOCS, 'esp32s2':ESP32S2_DOCS, 'esp32s3':ESP32S3_DOCS, diff --git a/docs/docs_not_updated/esp32h2.txt b/docs/docs_not_updated/esp32h2.txt index fb3d48388c9..eab138e1bbd 100644 --- a/docs/docs_not_updated/esp32h2.txt +++ b/docs/docs_not_updated/esp32h2.txt @@ -5,7 +5,6 @@ api-guides/dfu api-guides/index api-reference/peripherals/spi_features api-reference/peripherals/sdio_slave -api-reference/peripherals/adc_calibration api-reference/peripherals/dedic_gpio api-reference/peripherals/sd_pullup_requirements api-reference/peripherals/index diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index 2f190dd5440..1423e81b2a0 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -82,7 +82,6 @@ api-reference/peripherals/gpio/esp32p4.inc api-reference/peripherals/adc_continuous.rst api-reference/peripherals/adc_oneshot.rst api-reference/peripherals/usb_host.rst -api-reference/peripherals/twai.rst 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 @@ -90,7 +89,6 @@ api-reference/peripherals/usb_host/usb_host_notes_design.rst api-reference/peripherals/usb_device.rst api-reference/peripherals/gpio.rst api-reference/peripherals/dac.rst -api-reference/peripherals/spi_slave.rst api-reference/peripherals/touch_element.rst api-reference/peripherals/lcd.rst api-reference/peripherals/ana_cmpr.rst diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 209f6b8d069..53ba9d0e7e9 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -79,15 +79,6 @@ INPUT = \ $(PROJECT_PATH)/components/driver/dac/include/driver/dac_cosine.h \ $(PROJECT_PATH)/components/driver/dac/include/driver/dac_oneshot.h \ $(PROJECT_PATH)/components/driver/dac/include/driver/dac_types.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/dedic_gpio.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/gpio.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/gpio_etm.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/gpio_filter.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/lp_io.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/rtc_io.h \ - $(PROJECT_PATH)/components/driver/gptimer/include/driver/gptimer.h \ - $(PROJECT_PATH)/components/driver/gptimer/include/driver/gptimer_etm.h \ - $(PROJECT_PATH)/components/driver/gptimer/include/driver/gptimer_types.h \ $(PROJECT_PATH)/components/driver/i2c/include/driver/i2c.h \ $(PROJECT_PATH)/components/driver/i2s/include/driver/i2s_common.h \ $(PROJECT_PATH)/components/driver/i2s/include/driver/i2s_pdm.h \ @@ -106,7 +97,6 @@ INPUT = \ $(PROJECT_PATH)/components/driver/mcpwm/include/driver/mcpwm_types.h \ $(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_tx.h \ $(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_types.h \ - $(PROJECT_PATH)/components/driver/pcnt/include/driver/pulse_cnt.h \ $(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_common.h \ $(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_encoder.h \ $(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_rx.h \ @@ -140,6 +130,16 @@ INPUT = \ $(PROJECT_PATH)/components/esp_common/include/esp_check.h \ $(PROJECT_PATH)/components/esp_common/include/esp_err.h \ $(PROJECT_PATH)/components/esp_common/include/esp_idf_version.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/dedic_gpio.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/gpio.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/gpio_etm.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/gpio_filter.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/lp_io.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/rtc_io.h \ + $(PROJECT_PATH)/components/esp_driver_gptimer/include/driver/gptimer.h \ + $(PROJECT_PATH)/components/esp_driver_gptimer/include/driver/gptimer_etm.h \ + $(PROJECT_PATH)/components/esp_driver_gptimer/include/driver/gptimer_types.h \ + $(PROJECT_PATH)/components/esp_driver_pcnt/include/driver/pulse_cnt.h \ $(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 \ diff --git a/docs/en/api-guides/flash_psram_config.rst b/docs/en/api-guides/flash_psram_config.rst index fc7e352b63c..a272a91036d 100644 --- a/docs/en/api-guides/flash_psram_config.rst +++ b/docs/en/api-guides/flash_psram_config.rst @@ -173,7 +173,7 @@ Error Handling this means: - either you're using a board with a Quad Flash - - or you're using a board with an Octal Flash, but the eFuse bit ``FLASH_TYPE`` isn't burnt. Espressif guarantees this bit during module manufacturing, but if the module is manufactured by others, this may happen. + - or you're using a board with an Octal Flash, but the eFuse bit ``FLASH_TYPE`` isn't burnt. Espressif guarantees this bit is burnt during module manufacturing, but if the module is manufactured by others, this may happen. Here is a method to burn the eFuse bit: diff --git a/docs/en/api-guides/jtag-debugging/debugging-examples.rst b/docs/en/api-guides/jtag-debugging/debugging-examples.rst index 4b09aa1ac9e..34f1cfea4fb 100644 --- a/docs/en/api-guides/jtag-debugging/debugging-examples.rst +++ b/docs/en/api-guides/jtag-debugging/debugging-examples.rst @@ -497,7 +497,7 @@ If you enter ``s`` instead, then debugger will step inside subroutine calls:: Target halted. PRO_CPU: PC=0x400DB74B (active) APP_CPU: PC=0x400D1128 Target halted. PRO_CPU: PC=0x400DC04C (active) APP_CPU: PC=0x400D1128 Target halted. PRO_CPU: PC=0x400DC04F (active) APP_CPU: PC=0x400D1128 - gpio_set_level (gpio_num=GPIO_NUM_4, level=0) at /home/user-name/esp/esp-idf/components/driver/gpio/gpio.c:183 + gpio_set_level (gpio_num=GPIO_NUM_4, level=0) at /home/user-name/esp/esp-idf/components/esp_driver_gpio/src/gpio.c:183 183 GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG); (gdb) diff --git a/docs/en/api-guides/thread-local-storage.rst b/docs/en/api-guides/thread-local-storage.rst index 79e229fbd3a..8065199430f 100644 --- a/docs/en/api-guides/thread-local-storage.rst +++ b/docs/en/api-guides/thread-local-storage.rst @@ -27,7 +27,7 @@ In this case, the maximum number of variables that can be allocated is limited b Using the APIs above, you can allocate thread local variables of an arbitrary size, and assign them to any number of tasks. Different tasks can have different sets of TLS variables. -If size of the variable is more then 4 bytes, then you need to allocate/deallocate memory for it. Variable's deallocation is initiated by FreeRTOS when task is deleted, but user must provide callback function to do proper cleanup. +If size of the variable is more than 4 bytes, then you need to allocate/deallocate memory for it. Variable's deallocation is initiated by FreeRTOS when task is deleted, but user must provide callback function to do proper cleanup. .. _pthread-api: @@ -41,7 +41,7 @@ The ESP-IDF provides the following :doc:`/api-reference/system/pthread` to manag - :cpp:func:`pthread_getspecific` - :cpp:func:`pthread_setspecific` -These APIs have all benefits of the ones above, but eliminates some their limits. The number of variables is limited only by size of available memory on the heap. Due to the dynamic nature, this APIs introduce additional performance overhead compared to the native one. +These APIs have all benefits of the ones above, but eliminates some their limits. The number of variables is limited only by size of available memory on the heap. Due to the dynamic nature, this API introduces additional performance overhead compared to the native one. .. _c11-std: @@ -52,4 +52,4 @@ The ESP-IDF FreeRTOS supports thread local variables according to C11 standard, Storage for that kind of variables is allocated on the task stack. Note that area for all such variables in the program is allocated on the stack of every task in the system even if that task does not use such variables at all. For example, ESP-IDF system tasks (e.g., ``ipc``, ``timer`` tasks etc.) will also have that extra stack space allocated. Thus feature should be used with care. -Using C11 thread local variables comes at a trade-off. One one hand, they are quite handy to use in programming and can be accessed using minimal CPU instructions. However, this benefit comes at the cost of additional stack usage for all tasks in the system. Due to static nature of variables allocation, all tasks in the system have the same sets of C11 thread local variables. +Using C11 thread local variables comes at a trade-off. On one hand, they are quite handy to use in programming and can be accessed using minimal CPU instructions. However, this benefit comes at the cost of additional stack usage for all tasks in the system. Due to static nature of variables allocation, all tasks in the system have the same sets of C11 thread local variables. diff --git a/docs/en/api-guides/tools/idf-clang-tidy.rst b/docs/en/api-guides/tools/idf-clang-tidy.rst index 7d3e7a802d6..dab019a6e12 100644 --- a/docs/en/api-guides/tools/idf-clang-tidy.rst +++ b/docs/en/api-guides/tools/idf-clang-tidy.rst @@ -10,6 +10,8 @@ The IDF Clang Tidy is a tool that uses `clang-tidy `__ website. Create Curve Fitting Scheme ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -132,10 +141,6 @@ If you use your custom ADC calibration schemes, you could either modify this fun ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle)); -.. only:: esp32h2 - - There is no supported calibration scheme yet. - .. note:: If you want to use your custom calibration schemes, you could provide a creation function to create your calibration scheme handle. Check the function table ``adc_cali_scheme_t`` in ``components/esp_adc/interface/adc_cali_interface.h`` to know the ESP ADC calibration interface. @@ -152,7 +157,7 @@ After setting up the calibration characteristics, you can call :cpp:func:`adc_ca .. note:: - ADC calibration is only supported under :c:macro:`ADC_ATTEN_DB_0` and :c:macro:`ADC_ATTEN_DB_11`. Under :c:macro:`ADC_ATTEN_DB_0`, the attenuation of ADC is set to 0 dB, and input voltage higher than 950 mV is not supported. Under :c:macro:`ADC_ATTEN_DB_11`, the attenuation of ADC is set to 11 dB, and input voltage higher than 2800 mV is not supported. + ADC calibration is only supported under :c:macro:`ADC_ATTEN_DB_0` and :c:macro:`ADC_ATTEN_DB_12`. Under :c:macro:`ADC_ATTEN_DB_0`, the attenuation of ADC is set to 0 dB, and input voltage higher than 950 mV is not supported. Under :c:macro:`ADC_ATTEN_DB_12`, the attenuation of ADC is set to 11 dB, and input voltage higher than 2800 mV is not supported. Get Voltage ~~~~~~~~~~~ @@ -182,7 +187,7 @@ Other functions that take the :cpp:type:`adc_cali_handle_t` as the first positio - :ref:`CONFIG_ADC_CAL_EFUSE_TP_ENABLE` - disable this to decrease the code size, if the calibration eFuse value is not set to :cpp:type:`ADC_CALI_LINE_FITTING_EFUSE_VAL_EFUSE_TP`. - :ref:`CONFIG_ADC_CAL_EFUSE_VREF_ENABLE` - disable this to decrease the code size, if the calibration eFuse value is not set to :cpp:type:`ADC_CALI_LINE_FITTING_EFUSE_VAL_EFUSE_VREF`. - - :ref:`CONFIG_ADC_CAL_LUT_ENABLE` - disable this to decrease the code size, if you do not calibrate the ADC raw results under :c:macro:`ADC_ATTEN_DB_11`. + - :ref:`CONFIG_ADC_CAL_LUT_ENABLE` - disable this to decrease the code size, if you do not calibrate the ADC raw results under :c:macro:`ADC_ATTEN_DB_12`. .. _adc-minimize-noise: diff --git a/docs/en/api-reference/peripherals/adc_oneshot.rst b/docs/en/api-reference/peripherals/adc_oneshot.rst index 74c08471e0f..bec0bee1862 100644 --- a/docs/en/api-reference/peripherals/adc_oneshot.rst +++ b/docs/en/api-reference/peripherals/adc_oneshot.rst @@ -105,7 +105,7 @@ Configure Two ADC Channels adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN0, &config)); ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN1, &config)); diff --git a/docs/en/api-reference/peripherals/ds.rst b/docs/en/api-reference/peripherals/ds.rst index 118147c73f1..4f027ff3d7a 100644 --- a/docs/en/api-reference/peripherals/ds.rst +++ b/docs/en/api-reference/peripherals/ds.rst @@ -1,83 +1,72 @@ Digital Signature (DS) ====================== -The Digital Signature (DS) module provides hardware acceleration of signing messages based on RSA. -It uses pre-encrypted parameters to calculate a signature. -The parameters are encrypted using HMAC as a key-derivation function. -In turn, the HMAC uses eFuses as input key. -The whole process happens in hardware so that neither the decryption key for the RSA parameters nor the input key for the HMAC key derivation function can be seen by the software while calculating the signature. +:link_to_translation:`zh_CN:[中文]` -For more detailed information on the hardware involved in signature calculation and the registers used, see *{IDF_TARGET_NAME} Technical Reference Manual* > *Digital Signature (DS)* [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. +The Digital Signature (DS) module provides hardware acceleration of signing messages based on RSA. It uses pre-encrypted parameters to calculate a signature. The parameters are encrypted using HMAC as a key-derivation function. In turn, the HMAC uses eFuses as the input key. The whole process happens in hardware so that neither the decryption key for the RSA parameters nor the input key for the HMAC key derivation function can be seen by the software while calculating the signature. + +For more detailed information on the hardware involved in the signature calculation and the registers used, see **{IDF_TARGET_NAME} Technical Reference Manual** > **Digital Signature (DS)** [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. Private Key Parameters ---------------------- -The private key parameters for the RSA signature are stored in flash. -To prevent unauthorized access, they are AES-encrypted. -The HMAC module is used as a key-derivation function to calculate the AES encryption key for the private key parameters. -In turn, the HMAC module uses a key from the eFuses key block which can be read-protected to prevent unauthorized access as well. -Upon signature calculation invocation, the software only specifies which eFuse key to use, the corresponding eFuse key purpose, the location of the encrypted RSA parameters and the message. +The private key parameters for the RSA signature are stored in flash. To prevent unauthorized access, they are AES-encrypted. The HMAC module is used as a key-derivation function to calculate the AES encryption key for the private key parameters. In turn, the HMAC module uses a key from the eFuses key block which can be read-protected to prevent unauthorized access as well. + +Upon signature calculation invocation, the software only specifies which eFuse key to use, the corresponding eFuse key purpose, the location of the encrypted RSA parameters, and the message. Key Generation -------------- -Both the HMAC key and the RSA private key have to be created and stored before the DS peripheral can be used. -This needs to be done in software on the {IDF_TARGET_NAME} or alternatively on a host. -For this context, the IDF provides :cpp:func:`esp_efuse_write_block` to set the HMAC key and :cpp:func:`esp_hmac_calculate` to encrypt the private RSA key parameters. -You can find instructions on how to calculate and assemble the private key parameters in *{IDF_TARGET_NAME} Technical Reference Manual* > *Digital Signature (DS)* [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. +Both the HMAC key and the RSA private key have to be created and stored before the DS peripheral can be used. This needs to be done in software on the {IDF_TARGET_NAME} or alternatively on a host. For this context, ESP-IDF provides :cpp:func:`esp_efuse_write_block` to set the HMAC key and :cpp:func:`esp_hmac_calculate` to encrypt the private RSA key parameters. + +You can find instructions on how to calculate and assemble the private key parameters in **{IDF_TARGET_NAME} Technical Reference Manual** > **Digital Signature (DS)** [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. -Signature Calculation with IDF ------------------------------- +Signature Calculation with ESP-IDF +---------------------------------- -For more detailed information on the workflow and the registers used, see *{IDF_TARGET_NAME} Technical Reference Manual* > *Digital Signature (DS)* [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. +For more detailed information on the workflow and the registers used, see **{IDF_TARGET_NAME} Technical Reference Manual** > **Digital Signature (DS)** [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. Three parameters need to be prepared to calculate the digital signature: -#. the eFuse key block ID which is used as key for the HMAC, -#. the location of the encrypted private key parameters, -#. and the message to be signed. +#. The eFuse key block ID which is used as the key for the HMAC +#. The location of the encrypted private key parameters +#. The message to be signed -Since the signature calculation takes some time, there are two possible API versions to use in IDF. -The first one is :cpp:func:`esp_ds_sign` and simply blocks until the calculation is finished. -If software needs to do something else during the calculation, :cpp:func:`esp_ds_start_sign` can be called, followed by periodic calls to :cpp:func:`esp_ds_is_busy` to check when the calculation has finished. -Once the calculation has finished, :cpp:func:`esp_ds_finish_sign` can be called to get the resulting signature. +Since the signature calculation takes some time, there are two possible API versions to use in ESP-IDF. The first one is :cpp:func:`esp_ds_sign` and simply blocks until the calculation is finished. If software needs to do something else during the calculation, :cpp:func:`esp_ds_start_sign` can be called, followed by periodic calls to :cpp:func:`esp_ds_is_busy` to check when the calculation has finished. Once the calculation has finished, :cpp:func:`esp_ds_finish_sign` can be called to get the resulting signature. -The APIs :cpp:func:`esp_ds_sign` and :cpp:func:`esp_ds_start_sign` calculate a plain RSA signature with help of the DS peripheral. This signature needs to be converted to appropriate format for further use. For example, MbedTLS SSL stack supports PKCS#1 format. The API :cpp:func:`esp_ds_rsa_sign` can be used to obtain the signature directly in the PKCS#1 v1.5 format. It internally uses :cpp:func:`esp_ds_start_sign` and converts the signature into PKCS#1 v1.5 format. +The APIs :cpp:func:`esp_ds_sign` and :cpp:func:`esp_ds_start_sign` calculate a plain RSA signature with the help of the DS peripheral. This signature needs to be converted to an appropriate format for further use. For example, the MbedTLS SSL stack supports PKCS#1 format. The API :cpp:func:`esp_ds_rsa_sign` can be used to obtain the signature directly in the PKCS#1 v1.5 format. It internally uses :cpp:func:`esp_ds_start_sign` and converts the signature into PKCS#1 v1.5 format. .. note:: - Note that this is only the basic DS building block, the message length is fixed. - To create signatures of arbitrary messages, the input is normally a hash of the actual message, padded up to the required length. - An API to do this is planned in the future. + + This is only the basic DS building block, the message length is fixed. To create signatures of arbitrary messages, the input is normally a hash of the actual message, padded up to the required length. An API to do this is planned in the future. .. _configure-the-ds-peripheral: -Configure the DS peripheral for a TLS connection +Configure the DS Peripheral for a TLS Connection ------------------------------------------------ -The DS peripheral on {IDF_TARGET_NAME} chip must be configured before it can be used for a TLS connection. -The configuration involves the following steps - +The DS peripheral on {IDF_TARGET_NAME} chip must be configured before it can be used for a TLS connection. The configuration involves the following steps: -1) Randomly generate a 256 bit value called the `Initialization Vector` (IV). -2) Randomly generate a 256 bit value called the `HMAC_KEY`. -3) Calculate the encrypted private key paramters from the client private key (RSA) and the parameters generated in the above steps. -4) Then burn the 256 bit `HMAC_KEY` on the efuse, which can only be read by the DS peripheral. +1) Randomly generate a 256-bit value called the ``Initialization Vector`` (IV). +2) Randomly generate a 256-bit value called the ``HMAC_KEY``. +3) Calculate the encrypted private key parameters from the client private key (RSA) and the parameters generated in the above steps. +4) Then burn the 256-bit ``HMAC_KEY`` on the eFuse, which can only be read by the DS peripheral. -For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *Digital Signature (DS)* [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. +For more details, see **{IDF_TARGET_NAME} Technical Reference Manual** > **Digital Signature (DS)** [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. To configure the DS peripheral for development purposes, you can use the `esp-secure-cert-tool `_. -The encrypted private key parameters obtained after the DS peripheral configuration are then to be kept in flash. Furthermore, they are to be passed to the DS peripheral which makes use of those parameters for the Digital Signature operation. The application then needs to read the ds data from the flash which has been done through the API's provided by the `esp_secure_cert_mgr `_ component. Please refer the `component/README. `_ for more details. +The encrypted private key parameters obtained after the DS peripheral configuration are then to be kept in flash. Furthermore, they are to be passed to the DS peripheral which makes use of those parameters for the Digital Signature operation. The application then needs to read the DS data from the flash, which has been done through the APIs provided by the `esp_secure_cert_mgr `_ component. Please refer to the `component/README `_ for more details. + +The process of initializing the DS peripheral and then performing the Digital Signature operation is done internally with the help of `ESP-TLS`. Please refer to :ref:`digital-signature-with-esp-tls` for more details. -The process of initializing the DS peripheral and then performing the Digital Signature operation is done internally with help of `ESP-TLS`. Please refer to `Digital Signature with ESP-TLS` in :doc:`ESP-TLS <../protocols/esp_tls>` for more details. -As mentioned in the `ESP-TLS` documentation, the application only needs to provide the encrypted private key parameters to the esp_tls context (as `ds_data`), which internally performs -all necessary operations for initializing the DS peripheral and then performing the DS operation. +As mentioned in the `ESP-TLS` documentation, the application only needs to provide the encrypted private key parameters to the esp_tls context (as `ds_data`), which internally performs all necessary operations for initializing the DS peripheral and then performing the DS operation. -Example for SSL Mutual Authentication using DS +Example for SSL Mutual Authentication Using DS ---------------------------------------------- -The example :example:`ssl_ds` shows how to use the DS peripheral for mutual authentication. The example uses `mqtt_client` (Implemented through `ESP-MQTT`) -to connect to broker test.mosquitto.org using ssl transport with mutual authentication. The ssl part is internally performed with `ESP-TLS`. -See :example_file:`example README` for more details. + +The example :example:`protocols/mqtt/ssl_ds` shows how to use the DS peripheral for mutual authentication. The example uses `mqtt_client` (Implemented through `ESP-MQTT`) to connect to broker ``test.mosquitto.org`` using SSL transport with mutual authentication. The SSL part is internally performed with `ESP-TLS`. See :example_file:`protocols/mqtt/ssl_ds/README.md` for more details. API Reference ------------- diff --git a/docs/en/api-reference/peripherals/rmt.rst b/docs/en/api-reference/peripherals/rmt.rst index aff15049054..f1585ecf11a 100644 --- a/docs/en/api-reference/peripherals/rmt.rst +++ b/docs/en/api-reference/peripherals/rmt.rst @@ -56,7 +56,7 @@ The description of the RMT functionality is divided into the following sections: - :ref:`rmt-resource-allocation` - covers how to allocate and properly configure RMT channels. It also covers how to recycle channels and other resources when they are no longer used. - :ref:`rmt-carrier-modulation-and demodulation` - describes how to modulate and demodulate the carrier signals for TX and RX channels respectively. -- :ref:`rmt-register-event-callbacks` - covers how to register user-provided event callbacks in order to receive RMT channel events. +- :ref:`rmt-register-event-callbacks` - covers how to register user-provided event callbacks to receive RMT channel events. - :ref:`rmt-enable-and-disable-channel` - shows how to enable and disable the RMT channel. - :ref:`rmt-initiate-tx-transaction` - describes the steps to initiate a transaction for a TX channel. - :ref:`rmt-initiate-rx-transaction` - describes the steps to initiate a transaction for an RX channel. @@ -84,7 +84,7 @@ To install an RMT TX channel, there is a configuration structure that needs to b - :cpp:member:`rmt_tx_channel_config_t::resolution_hz` sets the resolution of the internal tick counter. The timing parameter of the RMT signal is calculated based on this **tick**. - :cpp:member:`rmt_tx_channel_config_t::mem_block_symbols` has a slightly different meaning based on if the DMA backend is enabled or not. - - If the DMA is enabled via :cpp:member:`rmt_tx_channel_config_t::with_dma`, then this field controls the size of the internal DMA buffer. To achieve a better throughput and smaller CPU overhead, we recommend you set a large value, e.g., ``1024``. + - If the DMA is enabled via :cpp:member:`rmt_tx_channel_config_t::with_dma`, then this field controls the size of the internal DMA buffer. To achieve a better throughput and smaller CPU overhead, you can set a larger value, e.g., ``1024``. - If DMA is not used, this field controls the size of the dedicated memory block owned by the channel, which should be at least {IDF_TARGET_SOC_RMT_MEM_WORDS_PER_CHANNEL}. - :cpp:member:`rmt_tx_channel_config_t::trans_queue_depth` sets the depth of the internal transaction queue, the deeper the queue, the more transactions can be prepared in the backlog. @@ -205,7 +205,7 @@ The RX channel-supported event callbacks are listed in the :cpp:type:`rmt_rx_eve Users can save their own context in :cpp:func:`rmt_tx_register_event_callbacks` and :cpp:func:`rmt_rx_register_event_callbacks` as well, via the parameter ``user_data``. The user data is directly passed to each callback function. -In the callback function, users can fetch the event-specific data that is filled by the driver in the ``edata``. Note that the ``edata`` pointer is only valid for the duration of the callback. +In the callback function, users can fetch the event-specific data that is filled by the driver in the ``edata``. Note that the ``edata`` pointer is only valid during the callback. The TX-done event data is defined in :cpp:type:`rmt_tx_done_event_data_t`: @@ -237,7 +237,7 @@ Initiate TX Transaction RMT is a special communication peripheral, as it is unable to transmit raw byte streams like SPI and I2C. RMT can only send data in its own format :cpp:type:`rmt_symbol_word_t`. However, the hardware does not help to convert the user data into RMT symbols, this can only be done in software by the so-called **RMT Encoder**. The encoder is responsible for encoding user data into RMT symbols and then writing to the RMT memory block or the DMA buffer. For how to create an RMT encoder, please refer to :ref:`rmt-rmt-encoder`. -Once we got an encoder, we can initiate a TX transaction by calling :cpp:func:`rmt_transmit`. This function takes several positional parameters like channel handle, encoder handle, and payload buffer. Besides, we also need to provide a transmission-specific configuration in :cpp:type:`rmt_transmit_config_t`: +Once you created an encoder, you can initiate a TX transaction by calling :cpp:func:`rmt_transmit`. This function takes several positional parameters like channel handle, encoder handle, and payload buffer. Besides, you also need to provide a transmission-specific configuration in :cpp:type:`rmt_transmit_config_t`: - :cpp:member:`rmt_transmit_config_t::loop_count` sets the number of transmission loops. After the transmitter has finished one round of transmission, it can restart the same transmission again if this value is not set to zero. As the loop is controlled by hardware, the RMT channel can be used to generate many periodic sequences with minimal CPU intervention. @@ -249,6 +249,7 @@ Once we got an encoder, we can initiate a TX transaction by calling :cpp:func:`r The **loop transmit** feature is not supported on all ESP chips, please refer to [`TRM <{IDF_TARGET_TRM_EN_URL}#rmt>`__] before you configure this option, or you might encounter :c:macro:`ESP_ERR_NOT_SUPPORTED` error. - :cpp:member:`rmt_transmit_config_t::eot_level` sets the output level when the transmitter finishes working or stops working by calling :cpp:func:`rmt_disable`. +- :cpp:member:`rmt_transmit_config_t::queue_nonblocking` sets whether to wait for a free slot in the transaction queue when it is full. If this value is set to ``true``, then the function will return with an error code :c:macro:`ESP_ERR_INVALID_STATE` when the queue is full. Otherwise, the function will block until a free slot is available in the queue. .. note:: @@ -264,7 +265,7 @@ Internally, :cpp:func:`rmt_transmit` constructs a transaction descriptor and sen Multiple Channels Simultaneous Transmission ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In some real-time control applications (e.g., to make two robotic arms move simultaneously), we do not want any time drift in between when startup multiple TX channels. The RMT driver can help to manage this by creating a so-called **Sync Manager**. The sync manager is represented by :cpp:type:`rmt_sync_manager_handle_t` in the driver. The procedure of RMT sync transmission is shown as follows: +In some real-time control applications (e.g., to make two robotic arms move simultaneously), you do not want any time drift between different channels. The RMT driver can help to manage this by creating a so-called **Sync Manager**. The sync manager is represented by :cpp:type:`rmt_sync_manager_handle_t` in the driver. The procedure of RMT sync transmission is shown as follows: .. figure:: /../_static/rmt_tx_sync.png :align: center @@ -380,20 +381,20 @@ RMT Encoder An RMT encoder is part of the RMT TX transaction, whose responsibility is to generate and write the correct RMT symbols into hardware memory or DMA buffer at a specific time. There are some special restrictions for an encoding function: -- During a single transaction, the encoding function may be called multiple times. This is necessary because the target RMT memory block cannot hold all the artifacts at once. To overcome this limitation, we utilize a **ping-pong** approach, where the encoding session is divided into multiple parts. This means that the encoder needs to **keep track of its state** in order to continue encoding from where it left off in the previous part. +- During a single transaction, the encoding function may be called multiple times. This is necessary because the target RMT memory block cannot hold all the artifacts at once. To overcome this limitation, the driver utilizes a **ping-pong** approach, where the encoding session is divided into multiple parts. This means that the encoder needs to **keep track of its state** to continue encoding from where it left off in the previous part. - The encoding function is running in the ISR context. To speed up the encoding session, it is highly recommended to put the encoding function into IRAM. This can also avoid the cache miss during encoding. -To help get started with the RMT driver faster, some commonly-used encoders are provided out-of-the-box. They can either work alone or be chained together into a new encoder. See also `Composite Pattern `__ for the principle behind it. The driver has defined the encoder interface in :cpp:type:`rmt_encoder_t`, it contains the following functions: +To help get started with the RMT driver faster, some commonly used encoders are provided out-of-the-box. They can either work alone or be chained together into a new encoder. See also `Composite Pattern `__ for the principle behind it. The driver has defined the encoder interface in :cpp:type:`rmt_encoder_t`, it contains the following functions: - :cpp:member:`rmt_encoder_t::encode` is the fundamental function of an encoder. This is where the encoding session happens. - The function might be called multiple times within a single transaction. The encode function should return the state of the current encoding session. - The supported states are listed in the :cpp:type:`rmt_encode_state_t`. If the result contains :cpp:enumerator:`RMT_ENCODING_COMPLETE`, it means the current encoder has finished work. - - If the result contains :cpp:enumerator:`RMT_ENCODING_MEM_FULL`, we need to yield from the current session, as there is no space to save more encoding artifacts. + - If the result contains :cpp:enumerator:`RMT_ENCODING_MEM_FULL`, the program needs to yield from the current session, as there is no space to save more encoding artifacts. - :cpp:member:`rmt_encoder_t::reset` should reset the encoder state back to the initial state (the RMT encoder is stateful). - - If the RMT transmitter is manually stopped without resetting its corresponding encoder, subsequent encoding session can be erroneous. + - If the RMT transmitter is manually stopped without resetting its corresponding encoder, subsequent encoding session can be erroneous. - This function is also called implicitly in :cpp:func:`rmt_disable`. - :cpp:member:`rmt_encoder_t::del` should free the resources allocated by the encoder. @@ -424,7 +425,7 @@ Besides the primitive encoders provided by the driver, the user can implement hi Customize RMT Encoder for NEC Protocol ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In this section, we demonstrates how to write an NEC encoder. The NEC IR protocol uses pulse distance encoding of the message bits. Each pulse burst is ``562.5 µs`` in length, logical bits are transmitted as follows. It is worth mentioning that the least significant bit of each byte is sent first. +This section demonstrates how to write an NEC encoder. The NEC IR protocol uses pulse distance encoding of the message bits. Each pulse burst is ``562.5 µs`` in length, logical bits are transmitted as follows. It is worth mentioning that the least significant bit of each byte is sent first. - Logical ``0``: a ``562.5 µs`` pulse burst followed by a ``562.5 µs`` space, with a total transmit time of ``1.125 ms`` - Logical ``1``: a ``562.5 µs`` pulse burst followed by a ``1.6875 ms`` space, with a total transmit time of ``2.25 ms`` @@ -445,7 +446,7 @@ When a key is pressed on the remote controller, the transmitted message includes - 8-bit logical inverse of the command - a final ``562.5 µs`` pulse burst to signify the end of message transmission -Then we can construct the NEC :cpp:member:`rmt_encoder_t::encode` function in the same order, for example: +Then you can construct the NEC :cpp:member:`rmt_encoder_t::encode` function in the same order, for example: .. code:: c diff --git a/docs/en/api-reference/peripherals/spi_slave.rst b/docs/en/api-reference/peripherals/spi_slave.rst index bd36b381043..9d119dec1a0 100644 --- a/docs/en/api-reference/peripherals/spi_slave.rst +++ b/docs/en/api-reference/peripherals/spi_slave.rst @@ -141,12 +141,12 @@ GPIO Matrix and IO_MUX .. only:: not esp32 - {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1"} - {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4"} - {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5"} - {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0"} - {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3"} - {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2"} + {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7"} + {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9"} + {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8"} + {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10"} + {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6"} + {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11"} Most of chip's peripheral signals have direct connection to their dedicated IO_MUX pins. However, the signals can also be routed to any other available pins using the less direct GPIO matrix. If at least one signal is routed through the GPIO matrix, then all signals will be routed through it. diff --git a/docs/en/api-reference/peripherals/twai.rst b/docs/en/api-reference/peripherals/twai.rst index f55f76efd2e..3a19a7f03a6 100644 --- a/docs/en/api-reference/peripherals/twai.rst +++ b/docs/en/api-reference/peripherals/twai.rst @@ -164,7 +164,7 @@ The operating bit rate of the TWAI driver is configured using the :cpp:type:`twa 2. **Timing Segment 1** consists of 1 to 16 time quanta before sample point 3. **Timing Segment 2** consists of 1 to 8 time quanta after sample point -{IDF_TARGET_MAX_BRP:default="128", esp32="128", esp32s2="32768", esp32s3="16384", esp32c3="16384", esp32c6="32768", esp32h2="32768"} +{IDF_TARGET_MAX_BRP:default="32768", esp32="128", esp32s3="16384", esp32c3="16384"} The **Baudrate Prescaler** is used to determine the period of each time quantum by dividing the TWAI controller's source clock. On the {IDF_TARGET_NAME}, the ``brp`` can be **any even number from 2 to {IDF_TARGET_MAX_BRP}**. Alternatively, you can decide the resolution of each quantum, by setting :cpp:member:`twai_timing_config_t::quanta_resolution_hz` to a non-zero value. In this way, the driver can calculate the underlying ``brp`` value for you. It is useful when you set different clock sources but want the bitrate to keep the same. diff --git a/docs/en/api-reference/peripherals/usb_host.rst b/docs/en/api-reference/peripherals/usb_host.rst index 2f0756b43ff..5007bea0e31 100644 --- a/docs/en/api-reference/peripherals/usb_host.rst +++ b/docs/en/api-reference/peripherals/usb_host.rst @@ -390,6 +390,47 @@ UVC * A host class driver for the USB Video Device Class is distributed as a managed component via the `ESP-IDF Component Registry `__. * The :example:`peripherals/usb/host/uvc` example demonstrates the usage of the UVC host driver to receive a video stream from a USB camera and optionally forward that stream over Wi-Fi. +.. ---------------------------------------------- USB Host Menuconfig -------------------------------------------------- + +Host Stack Configuration +------------------------ + +Non-Compliant Device Support +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To support USB devices that are non-compliant in various scenarios or exhibit specific behaviors it is possible to configure the USB Host stack. + +As a USB device may be hot-plugged, it is essential to have the configurable delays between power switching and device attachment, and when the device's internal power has stabilized. + +Enumeration Configuration +""""""""""""""""""""""""" + +During the process of enumerating connected USB devices, several timeout values ensure the proper functioning of the device. + +.. figure:: ../../../_static/usb_host/poweron-timings.png + :align: center + :alt: USB Root Hub Power-on and Connection Events Timing + :figclass: align-center + + USB Root Hub Power-on and Connection Events Timing + +The figure above shows all the timeouts associated with both turning on port power with a device connected and hot-plugging a device. + +* After a port is reset or resumed, the USB System Software is expected to provide a “recovery” interval of 10 ms before the device attached to the port is expected to respond to data transfers. +* After the reset/resume recovery interval, if a device receives a SetAddress() request, the device must be able to complete processing of the request and be able to successfully complete the Status stage of the request within 50 ms. +* After successful completion of the Status stage, the device is allowed a SetAddress() recovery interval of 2 ms. + +.. note:: + + For more details regarding connection event timings, please refer to the Universal Serial Bus 2.0 specification, chapter 7.1.7.3 "Connect and Disconnect Signaling". + +Configurable parameters of the USB host stack can be configured with multiple options via Menuconfig. + +* For Debounce delay refer to :ref:`CONFIG_USB_HOST_DEBOUNCE_DELAY_MS` +* For Reset hold interval refer to :ref:`CONFIG_USB_HOST_RESET_HOLD_MS` +* For Reset recovery interval refer to :ref:`CONFIG_USB_HOST_RESET_RECOVERY_MS` +* Fer SetAddress() recovery interval refer to: :ref:`CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS` + .. -------------------------------------------------- API Reference ---------------------------------------------------- API Reference diff --git a/docs/en/api-reference/protocols/esp_crt_bundle.rst b/docs/en/api-reference/protocols/esp_crt_bundle.rst index 5a2f5fbe4b0..88e343ab407 100644 --- a/docs/en/api-reference/protocols/esp_crt_bundle.rst +++ b/docs/en/api-reference/protocols/esp_crt_bundle.rst @@ -16,7 +16,7 @@ The bundle comes with the complete list of root certificates from Mozilla's NSS When generating the bundle you may choose between: - * The full root certificate bundle from Mozilla, containing more than 130 certificates. The current bundle was updated Tue Jan 10 04:12:06 2023 GMT. + * The full root certificate bundle from Mozilla, containing more than 130 certificates. The current bundle was updated Tue Aug 22 03:12:04 2023 GMT. * A pre-selected filter list of the name of the most commonly used root certificates, reducing the amount of certificates to around 41 while still having around 90% absolute usage coverage and 99% market share coverage according to SSL certificate authorities statistics. In addition, it is possible to specify a path to a certificate file or a directory containing certificates which then will be added to the generated bundle. @@ -76,6 +76,11 @@ Updating the Certificate Bundle The bundle is embedded into the app and can be updated along with the app by an OTA update. If you want to include a more up-to-date bundle than the bundle currently included in ESP-IDF, then the certificate list can be downloaded from Mozilla as described in :ref:`updating_bundle`. +Periodic Sync +------------- + +The bundle is kept updated by periodic sync with the Mozilla's NSS root certificate store. The deprecated certs from the upstream bundle are added to deprecated list (for compatibility reasons) in ESP-IDF minor or patch release. If required, the deprecated certs can be added to the default bundle by enabling :ref:`CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST`. The deprecated certs shall be removed (reset) on the next major ESP-IDF release. + Application Examples -------------------- diff --git a/docs/en/api-reference/storage/nvs_encryption.rst b/docs/en/api-reference/storage/nvs_encryption.rst index 97efccdf9c5..e9fbaeaa055 100644 --- a/docs/en/api-reference/storage/nvs_encryption.rst +++ b/docs/en/api-reference/storage/nvs_encryption.rst @@ -1,7 +1,7 @@ NVS Encryption ============== -:link_to_translation:`en:[English]` +:link_to_translation:`zh_CN:[中文]` Overview -------- @@ -86,18 +86,18 @@ It is possible for an application to use different keys for different NVS partit .. only:: SOC_HMAC_SUPPORTED -NVS Encryption: HMAC Peripheral-Based Scheme --------------------------------------------- + NVS Encryption: HMAC Peripheral-Based Scheme + -------------------------------------------- -In this scheme, the XTS keys required for NVS encryption are derived from an HMAC key programmed in eFuse with the purpose :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`. Since the encryption keys are derived at runtime, they are not stored anywhere in the flash. Thus, this feature does not require a separate :ref:`nvs_encr_key_partition`. + In this scheme, the XTS keys required for NVS encryption are derived from an HMAC key programmed in eFuse with the purpose :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`. Since the encryption keys are derived at runtime, they are not stored anywhere in the flash. Thus, this feature does not require a separate :ref:`nvs_encr_key_partition`. -.. note:: + .. note:: - This scheme enables us to achieve secure storage on {IDF_TARGET_NAME} **without enabling flash encryption**. + This scheme enables us to achieve secure storage on {IDF_TARGET_NAME} **without enabling flash encryption**. -.. important:: + .. important:: - Please take note that this scheme uses one eFuse block for storing the HMAC key required for deriving the encryption keys. + Please take note that this scheme uses one eFuse block for storing the HMAC key required for deriving the encryption keys. - When NVS encryption is enabled, the :cpp:func:`nvs_flash_init` API function can be used to initialize the encrypted default NVS partition. The API function first checks whether an HMAC key is present at :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`. @@ -146,37 +146,37 @@ Alternatively, :cpp:func:`nvs_flash_secure_init` API function can also be used t .. only:: SOC_HMAC_SUPPORTED - * For the HMAC-based scheme + * For the HMAC-based scheme - - Set the scheme-specific config data with :cpp:type:`nvs_sec_config_hmac_t` and register the HMAC-based scheme with the API :cpp:func:`nvs_sec_provider_register_hmac` which will also populate the scheme-specific handle (see :cpp:type:`nvs_sec_scheme_t`). - - Populate the :cpp:type:`nvs_sec_cfg_t` struct using the :cpp:func:`nvs_flash_read_security_cfg_v2` or :cpp:func:`nvs_flash_generate_keys_v2` API functions. + - Set the scheme-specific config data with :cpp:type:`nvs_sec_config_hmac_t` and register the HMAC-based scheme with the API :cpp:func:`nvs_sec_provider_register_hmac` which will also populate the scheme-specific handle (see :cpp:type:`nvs_sec_scheme_t`). + - Populate the :cpp:type:`nvs_sec_cfg_t` struct using the :cpp:func:`nvs_flash_read_security_cfg_v2` or :cpp:func:`nvs_flash_generate_keys_v2` API functions. - .. code-block:: c + .. code-block:: c - nvs_sec_cfg_t cfg = {}; - nvs_sec_scheme_t *sec_scheme_handle = NULL; + nvs_sec_cfg_t cfg = {}; + nvs_sec_scheme_t *sec_scheme_handle = NULL; - nvs_sec_config_hmac_t sec_scheme_cfg = {}; - hmac_key_id_t hmac_key = HMAC_KEY0; - sec_scheme_cfg.hmac_key_id = hmac_key; + nvs_sec_config_hmac_t sec_scheme_cfg = {}; + hmac_key_id_t hmac_key = HMAC_KEY0; + sec_scheme_cfg.hmac_key_id = hmac_key; - ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle); - if (ret != ESP_OK) { - return ret; - } + ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle); + if (ret != ESP_OK) { + return ret; + } - ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); - if (ret != ESP_OK) { - if (ret == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { - ret = nvs_flash_generate_keys_v2(&sec_scheme_handle, &cfg); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to generate NVS encr-keys!"); - return ret; + ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); + if (ret != ESP_OK) { + if (ret == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { + ret = nvs_flash_generate_keys_v2(&sec_scheme_handle, &cfg); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to generate NVS encr-keys!"); + return ret; + } } + ESP_LOGE(TAG, "Failed to read NVS security cfg!"); + return ret; } - ESP_LOGE(TAG, "Failed to read NVS security cfg!"); - return ret; - } 2. Initialise NVS flash partition using the :cpp:func:`nvs_flash_secure_init` or :cpp:func:`nvs_flash_secure_init_partition` API functions. 3. Open a namespace using the :cpp:func:`nvs_open` or :cpp:func:`nvs_open_from_partition` API functions. @@ -185,8 +185,8 @@ Alternatively, :cpp:func:`nvs_flash_secure_init` API function can also be used t .. only:: SOC_HMAC_SUPPORTED -.. note:: - While using the HMAC-based scheme, the above workflow can be used without enabling any of the config options for NVS encryption - :ref:`CONFIG_NVS_ENCRYPTION`, :ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> ``CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC`` and :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` to encrypt the default as well as custom NVS partitions with :cpp:func:`nvs_flash_secure_init` API. + .. note:: + While using the HMAC-based scheme, the above workflow can be used without enabling any of the config options for NVS encryption - :ref:`CONFIG_NVS_ENCRYPTION`, :ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> ``CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC`` and :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` to encrypt the default as well as custom NVS partitions with :cpp:func:`nvs_flash_secure_init` API. NVS Security Provider diff --git a/docs/en/api-reference/system/heap_debug.rst b/docs/en/api-reference/system/heap_debug.rst index b9ce083c489..599f4f16d1b 100644 --- a/docs/en/api-reference/system/heap_debug.rst +++ b/docs/en/api-reference/system/heap_debug.rst @@ -154,12 +154,6 @@ In both cases, the functions involve checking that the first 4 bytes of an alloc Different values usually indicate buffer underrun or overrun. Overrun indicates that when writing to memory, the data written exceeds the size of the allocated memory, resulting in writing to an unallocated memory area; underrun indicates that when reading memory, the data read exceeds the allocated memory and reads data from an unallocated memory area. -.. only:: CONFIG_ESP_ROM_HAS_HEAP_TLSF - - .. warning:: - - When the ROM implementation of the heap TLSF is used, note that :cpp:func:`heap_caps_check_integrity` will not perform the check of the canary bytes. - Comprehensive +++++++++++++ @@ -184,12 +178,6 @@ Calls to :cpp:func:`heap_caps_check_integrity` may print errors relating to ``0x - For free heap blocks, the checker expects to find all bytes set to ``0xFE``. Any other values indicate a use-after-free bug where free memory has been incorrectly overwritten. - For allocated heap blocks, the behavior is the same as for the Light Impact mode. The canary bytes ``0xABBA1234`` and ``0xBAAD5678`` are checked at the head and tail of each allocated buffer, and any variation indicates a buffer overrun or underrun. -.. only:: CONFIG_ESP_ROM_HAS_HEAP_TLSF - - .. warning:: - - When the ROM implementation of the heap TLSF is used, note that :cpp:func:`heap_caps_check_integrity` will not perform the check of the canary bytes. - .. _heap-task-tracking: Heap Task Tracking diff --git a/docs/en/contribute/documenting-code.rst b/docs/en/contribute/documenting-code.rst index aa5fcd73e3d..5fc2c772527 100644 --- a/docs/en/contribute/documenting-code.rst +++ b/docs/en/contribute/documenting-code.rst @@ -123,7 +123,7 @@ When writing code, please follow the guidelines below: For practical example see :component_file:`nvs_flash/include/nvs.h`. -4. You may want to go even further and skip some code like repetitive defines or enumerations. In such case, enclose the code within ``/** @cond */`` and ``/** @endcond */`` commands. Example of such implementation is provided in :component_file:`driver/gpio/include/driver/gpio.h`. +4. You may want to go even further and skip some code like repetitive defines or enumerations. In such case, enclose the code within ``/** @cond */`` and ``/** @endcond */`` commands. Example of such implementation is provided in :component_file:`esp_driver_gpio/include/driver/gpio.h`. 5. Use markdown to make your documentation even more readable. You will add headers, links, tables and more. :: diff --git a/docs/en/get-started/index.rst b/docs/en/get-started/index.rst index efa8b3349e1..e8869448e52 100644 --- a/docs/en/get-started/index.rst +++ b/docs/en/get-started/index.rst @@ -196,7 +196,7 @@ For the manual procedure, please select according to your operating system. Build Your First Project ======================== -If you already have the ESP-IDF installed and not using IDE, you can build your first project from the command line following the :ref:`Start a Project on Windows ` or :ref:`Start a Project on Linux and macOS `. +If you already have the ESP-IDF installed and are not using an IDE, you can build your first project from the command line following the :ref:`Start a Project on Windows ` or :ref:`Start a Project on Linux and macOS `. .. _Stable version: https://docs.espressif.com/projects/esp-idf/en/stable/ diff --git a/docs/en/migration-guides/index.rst b/docs/en/migration-guides/index.rst index 5ef50545688..199427c2e9d 100644 --- a/docs/en/migration-guides/index.rst +++ b/docs/en/migration-guides/index.rst @@ -12,3 +12,4 @@ ESP-IDF 5.x Migration Guide release-5.x/5.0/index release-5.x/5.1/index release-5.x/5.2/index + release-5.x/5.3/index 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 08cb46d778c..ba52226cac4 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 @@ -83,6 +83,15 @@ The SPI-Ethernet Module initialization is now simplified. Previously, you had to Now, you no longer need to call :cpp:func:`spi_bus_add_device` as SPI devices are allocated internally. As a result, the :cpp:class:`eth_dm9051_config_t`, :cpp:class:`eth_w5500_config_t`, and :cpp:class:`eth_ksz8851snl_config_t` configuration structures are updated to include members for SPI device configuration (e.g., to allow fine tuning of SPI timing which may be dependent on PCB design). Likewise, the ``ETH_DM9051_DEFAULT_CONFIG``, ``ETH_W5500_DEFAULT_CONFIG``, and ``ETH_KSZ8851SNL_DEFAULT_CONFIG`` configuration initialization macros are updated to accept new input parameters. Refer to :doc:`Ethernet API Reference Guide <../../../api-reference/network/esp_eth>` for an example of SPI-Ethernet Module initialization. +Ethernet Driver +--------------- + +APIs for creating MAC instances (`esp_eth_mac_new_*()`) have been reworked to accept two parameters, instead of one common configuration. Now, the configuration includes + +* Vendor specific MAC configuration +* Ethernet driver MAC configuration + +This is applicable to internal Ethernet MAC :cpp:func:`esp_eth_mac_new_esp32()` as well as to external MAC devices, such as :cpp:func:`esp_eth_mac_new_ksz8851snl()`, :cpp:func:`esp_eth_mac_new_dm9051()`, and :cpp:func:`esp_eth_mac_new_w5500()` .. _tcpip-adapter: diff --git a/docs/en/migration-guides/release-5.x/5.3/index.rst b/docs/en/migration-guides/release-5.x/5.3/index.rst new file mode 100644 index 00000000000..caccc541875 --- /dev/null +++ b/docs/en/migration-guides/release-5.x/5.3/index.rst @@ -0,0 +1,9 @@ +Migration from 5.2 to 5.3 +------------------------- + +:link_to_translation:`zh_CN:[中文]` + +.. toctree:: + :maxdepth: 1 + + peripherals diff --git a/docs/en/migration-guides/release-5.x/5.3/peripherals.rst b/docs/en/migration-guides/release-5.x/5.3/peripherals.rst new file mode 100644 index 00000000000..7321835ee14 --- /dev/null +++ b/docs/en/migration-guides/release-5.x/5.3/peripherals.rst @@ -0,0 +1,30 @@ +Peripherals +=========== + +:link_to_translation:`zh_CN:[中文]` + +In order to control the dependence of other components on drivers at a smaller granularity, the original peripheral drivers under the `driver`` component were split into separate components: + +- `esp_driver_gptimer` - Driver for general purpose timers +- `esp_driver_pcnt` - Driver for pulse counter +- `esp_driver_gpio` - Driver for GPIO + +For compatibility, the original `driver`` component is still treated as an all-in-one component by registering these `esp_driver_xyz`` components as its public dependencies. In other words, you do not need to modify the CMake file of an existing project, but you now have a way to specify the specific peripheral driver that your project depends on. + +Originally, you may have used **linker.lf** to specify the link location of some driver functions in memory space, but now, because the location of the driver files have been moved, you need to make changes your **linker.lf** file accordingly. For example, a linker.lf file with the following entries: + +.. code-block:: none + + [mapping:my_mapping_scheme] + archive: libdriver.a + entries: + gpio (noflash) + +Should be changed to: + +.. code-block:: none + + [mapping:my_mapping_scheme] + archive: libesp_driver_gpio.a + entries: + gpio (noflash) diff --git a/docs/en/security/security.rst b/docs/en/security/security.rst index 521f3189510..8b173aaa0ea 100644 --- a/docs/en/security/security.rst +++ b/docs/en/security/security.rst @@ -177,6 +177,23 @@ UART Download Mode It is highly recommended to verify the identity of the server based on X.509 certificates to avoid establishing communication with the **fake** server. + Managing Root Certificates + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Root Certificates embedded inside the application must be managed carefully. Any update to the root certificate list or the :doc:`../api-reference/protocols/esp_crt_bundle` can have an impact on the TLS connection with the remote endpoint. This includes a connection to the OTA update server. In some cases, the problem shall be visible on the next OTA update and it may leave device unable to perform OTA updates forever. + + Root certificates list update could have following reasons: + + - New firmware has different set of remote endpoint(s). + - Existing certificate has expired. + - The certificate has been added or retracted from the upstream certificate bundle. + - The certificate list changed due to market share statistics (``CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN`` case). + + Some guidelines to consider on this topic: + + - Please consider enabling :ref:`OTA rollback ` and then keep the successful connection to the OTA update server as the checkpoint to cancel the rollback process. This ensures that the newly updated firmware can successfully reach till the OTA update server, otherwise rollback process will go back to the previous firmware on the device. + - If you plan to enable the :ref:`CONFIG_MBEDTLS_HAVE_TIME_DATE` option then please consider to have sufficient number of trusted certificates and the time sync mechanism (SNTP) in place. + Product Security ---------------- diff --git a/docs/zh_CN/api-guides/jtag-debugging/debugging-examples.rst b/docs/zh_CN/api-guides/jtag-debugging/debugging-examples.rst index dbfa846cf06..c15f8c50e46 100644 --- a/docs/zh_CN/api-guides/jtag-debugging/debugging-examples.rst +++ b/docs/zh_CN/api-guides/jtag-debugging/debugging-examples.rst @@ -497,7 +497,7 @@ Target halted. PRO_CPU: PC=0x400DB74B (active) APP_CPU: PC=0x400D1128 Target halted. PRO_CPU: PC=0x400DC04C (active) APP_CPU: PC=0x400D1128 Target halted. PRO_CPU: PC=0x400DC04F (active) APP_CPU: PC=0x400D1128 - gpio_set_level (gpio_num=GPIO_NUM_4, level=0) at /home/user-name/esp/esp-idf/components/driver/gpio/gpio.c:183 + gpio_set_level (gpio_num=GPIO_NUM_4, level=0) at /home/user-name/esp/esp-idf/components/esp_driver_gpio/src/gpio.c:183 183 GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG); (gdb) diff --git a/docs/zh_CN/api-guides/tools/idf-clang-tidy.rst b/docs/zh_CN/api-guides/tools/idf-clang-tidy.rst index e66f75fbaa3..628cfacb7fc 100644 --- a/docs/zh_CN/api-guides/tools/idf-clang-tidy.rst +++ b/docs/zh_CN/api-guides/tools/idf-clang-tidy.rst @@ -10,6 +10,8 @@ IDF clang-tidy 是使用 `clang-tidy ` IDF clang-tidy 的功能及其依赖的工具链尚在开发中,最终版本发布前可能有重大变更。 + 目前仅支持基于 clang 的工具链。在配置项目前,必须在环境变量或 CMake 缓存中设置 ``IDF_TOOLCHAIN=clang`` 进行激活。 + .. only:: CONFIG_IDF_TARGET_ARCH_RISCV .. warning:: diff --git a/docs/zh_CN/api-reference/network/index.rst b/docs/zh_CN/api-reference/network/index.rst index dbd53d701d5..7acaac9aeca 100644 --- a/docs/zh_CN/api-reference/network/index.rst +++ b/docs/zh_CN/api-reference/network/index.rst @@ -16,7 +16,7 @@ esp_smartconfig esp_wifi esp_dpp - esp_nan + :SOC_WIFI_NAN_SUPPORT: esp_nan 本部分的 Wi-Fi API 示例代码存放在 ESP-IDF 示例项目的 :example:`wifi` 目录下。 diff --git a/docs/zh_CN/api-reference/peripherals/adc_calibration.rst b/docs/zh_CN/api-reference/peripherals/adc_calibration.rst index df7b345c391..fe599f24d69 100644 --- a/docs/zh_CN/api-reference/peripherals/adc_calibration.rst +++ b/docs/zh_CN/api-reference/peripherals/adc_calibration.rst @@ -82,7 +82,7 @@ ADC 校准驱动程序会提供 ADC 校准方案。对于驱动程序来说, ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle)); -.. only:: esp32c3 or esp32s3 or esp32c6 +.. only:: esp32c3 or esp32s3 or esp32c6 or esp32h2 ADC 校准曲线拟合方案 ```````````````````````````````````` @@ -90,14 +90,14 @@ ADC 校准驱动程序会提供 ADC 校准方案。对于驱动程序来说, {IDF_TARGET_NAME} 支持 :c:macro:`ADC_CALI_SCHEME_VER_CURVE_FITTING` 方案。要创建此方案,请先根据以下配置选项,设置 :cpp:type:`adc_cali_curve_fitting_config_t`。 - .. only:: not esp32c6 + .. only:: esp32c3 or esp32s3 - :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`,表示 ADC 原始结果来自哪个 ADC 单元。 - :cpp:member:`adc_cali_curve_fitting_config_t::chan`,此选项保留以供扩展。校准方案仅因衰减程度而异,与通道选择无关。 - :cpp:member:`adc_cali_curve_fitting_config_t::atten`,表示 ADC 原始结果的衰减程度。 - :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`,表示 ADC 原始结果的位宽。 - .. only:: esp32c6 + .. only:: esp32c6 or esp32h2 - :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`,表示 ADC 原始结果来自哪个 ADC 单元。 - :cpp:member:`adc_cali_curve_fitting_config_t::chan`,表示获取 ADC 原始结果的 ADC 通道。校准方案不仅因衰减程度而异,还与通道选择有关。 @@ -132,10 +132,6 @@ ADC 校准驱动程序会提供 ADC 校准方案。对于驱动程序来说, ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle)); -.. only:: esp32h2 - - 目前尚不支持任何校准方案。 - .. note:: 要使用自定义校准方案,可以通过提供创建函数,创建自己的校准方案句柄。请参阅 ``components/esp_adc/interface/adc_cali_interface.h`` 中的函数表 ``adc_cali_scheme_t``,了解 ESP ADC 校准接口。 @@ -152,7 +148,7 @@ ADC 校准驱动程序会提供 ADC 校准方案。对于驱动程序来说, .. note:: - ADC 校准仅在 :c:macro:`ADC_ATTEN_DB_0` 和 :c:macro:`ADC_ATTEN_DB_11` 时支持。在 :c:macro:`ADC_ATTEN_DB_0` 时,ADC 的衰减程度设置为 0 dB,仅支持低于 950 mV 的输入电压;在 :c:macro:`ADC_ATTEN_DB_11` 时,ADC 的衰减程度设置为 11 dB,仅支持低于 2800 mV 的输入电压。 + ADC 校准仅在 :c:macro:`ADC_ATTEN_DB_0` 和 :c:macro:`ADC_ATTEN_DB_12` 时支持。在 :c:macro:`ADC_ATTEN_DB_0` 时,ADC 的衰减程度设置为 0 dB,仅支持低于 950 mV 的输入电压;在 :c:macro:`ADC_ATTEN_DB_12` 时,ADC 的衰减程度设置为 12 dB,仅支持低于 2800 mV 的输入电压。 获取电压 ~~~~~~~~~~~ @@ -182,7 +178,7 @@ ADC 校准驱动程序会提供 ADC 校准方案。对于驱动程序来说, - :ref:`CONFIG_ADC_CAL_EFUSE_TP_ENABLE` - 如果校准相关的 eFuse 值没有配置为 :cpp:type:`ADC_CALI_LINE_FITTING_EFUSE_VAL_EFUSE_TP`,则可以禁用该选项,减小代码大小。 - :ref:`CONFIG_ADC_CAL_EFUSE_VREF_ENABLE` - 如果校准相关的 eFuse 值没有配置为 :cpp:type:`ADC_CALI_LINE_FITTING_EFUSE_VAL_EFUSE_VREF`,则可以禁用该选项,减小代码大小。 - - :ref:`CONFIG_ADC_CAL_LUT_ENABLE` - 如果校准 ADC 原始结果时,衰减没有设置成 :c:macro:`ADC_ATTEN_DB_11`,则可以禁用该选项,减小代码大小。 + - :ref:`CONFIG_ADC_CAL_LUT_ENABLE` - 如果校准 ADC 原始结果时,衰减没有设置成 :c:macro:`ADC_ATTEN_DB_12`,则可以禁用该选项,减小代码大小。 .. _adc-minimize-noise: diff --git a/docs/zh_CN/api-reference/peripherals/adc_oneshot.rst b/docs/zh_CN/api-reference/peripherals/adc_oneshot.rst index 052d02c575b..7c8687b480e 100644 --- a/docs/zh_CN/api-reference/peripherals/adc_oneshot.rst +++ b/docs/zh_CN/api-reference/peripherals/adc_oneshot.rst @@ -105,7 +105,7 @@ ADC 单次转换模式驱动基于 {IDF_TARGET_NAME} SAR ADC 模块实现,不 adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN0, &config)); ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN1, &config)); diff --git a/docs/zh_CN/api-reference/peripherals/ds.rst b/docs/zh_CN/api-reference/peripherals/ds.rst index b4b133d0e65..3b147c213e8 100644 --- a/docs/zh_CN/api-reference/peripherals/ds.rst +++ b/docs/zh_CN/api-reference/peripherals/ds.rst @@ -1,2 +1,74 @@ -.. include:: ../../../en/api-reference/peripherals/ds.rst +数字签名 (DS) +============= +:link_to_translation:`en:[English]` + +数字签名 (DS) 模块利用 RSA 硬件加速器为信息签名。HMAC 作为密钥派生函数,使用 eFuse 作为输入密钥,输出一组加密参数。随后,数字签名模块利用这组预加密的参数,计算出签名。以上过程均在硬件中完成,因此在计算签名时,软件无法获取 RSA 参数的解密密钥,也无法获取 HMAC 密钥派生函数的输入密钥。 + +签名计算所涉及的硬件信息以及所用寄存器的有关信息,请参阅 **{IDF_TARGET_NAME} 技术参考手册** > **数字签名 (DS)** [`PDF <{IDF_TARGET_TRM_CN_URL}#digsig>`__]。 + + +私钥参数 +-------- + +RSA 签名的私钥参数存储在 flash 中。为防止发生未经授权的访问,这些参数都进行了 AES 加密。此时,HMAC 模块被作为密钥派生函数,用于计算 AES 加密了的私钥参数。同时,HMAC 模块本身使用的来自 eFuse 密钥块的密钥也具有读取保护,可以防止发生未经授权的访问。 + +调用签名计算时,软件只需指定使用的 eFuse 密钥、相应的 eFuse 密钥用途、加密的 RSA 参数位置以及待签名的数据或信息。 + +密钥生成 +--------- + +在使用 DS 外设前,需首先创建并存储 HMAC 密钥和 RSA 私钥,此步骤可在 {IDF_TARGET_NAME} 上通过软件完成,也可在主机上进行。在 ESP-IDF 中,可以使用 :cpp:func:`esp_efuse_write_block` 设置 HMAC 密钥,并使用 :cpp:func:`esp_hmac_calculate` 对 RSA 私钥参数进行加密。 + +计算并组装私钥参数的详细信息,请参阅 **{IDF_TARGET_NAME} 技术参考手册** > **数字签名 (DS)** [`PDF <{IDF_TARGET_TRM_CN_URL}#digsig>`__]。 + +在 ESP-IDF 中进行数字签名计算 +---------------------------------- + +在 ESP-IDF 中进行数字签名计算的工作流程,以及所用寄存器的有关信息,请参阅 **{IDF_TARGET_NAME} 技术参考手册** > **数字签名 (DS)** [`PDF <{IDF_TARGET_TRM_CN_URL}#digsig>`__]。 + +要进行数字签名计算,需要准备以下三个参数: + +#. 用作 HMAC 密钥的 eFuse 密钥块 ID +#. 加密私钥参数的位置 +#. 待签名的数据或信息 + +由于签名计算需要一些时间,ESP-IDF 提供了两种可用的 API。第一种是 :cpp:func:`esp_ds_sign`,调用此 API 后,程序会在计算完成前保持阻塞状态。如果在计算过程中,软件需要执行其他操作,则可以调用 :cpp:func:`esp_ds_start_sign`,用另一种方式启动签名计算,然后周期性地调用 :cpp:func:`esp_ds_is_busy`,检查计算是否已完成。一旦计算完成,即可调用 :cpp:func:`esp_ds_finish_sign` 来获取签名结果。 + +API :cpp:func:`esp_ds_sign` 和 :cpp:func:`esp_ds_start_sign` 会借助 DS 外设计算明文 RSA 签名。RSA 签名需要转换成合适的格式,以供进一步使用。例如,MbedTLS SSL 栈支持 PKCS#1 格式,使用 API :cpp:func:`esp_ds_rsa_sign` 可以直接获得 PKCS#1 v1.5 格式的签名,该 API 内部调用了 :cpp:func:`esp_ds_start_sign` 函数,并将签名转换成 PKCS#1 v1.5 格式。 + +.. note:: + + 此处只是最基本的 DS 构造块,其消息必须是固定长度。为在任意消息上创建签名,通常会将实际消息的哈希值作为输入,并将其填充到所需长度。乐鑫计划在未来提供一个 API 来实现这个功能。 + +.. _configure-the-ds-peripheral: + +TLS 连接所需的 DS 外设配置 +------------------------------ + +在 {IDF_TARGET_NAME} 芯片上使用 TLS 连接之前,必须先配置 DS 外设,具体步骤如下: + +1) 随机生成一个 256 位的值,作为 ``初始化向量`` (IV)。 +2) 随机生成一个 256 位的值,作为 ``HMAC_KEY``。 +3) 使用客户端私钥 (RAS) 和上述步骤生成的参数,计算加密的私钥参数。 +4) 将 256 位的 ``HMAC_KEY`` 烧录到 eFuse 中,只支持 DS 外设读取。 + +更多细节,请参阅 **{IDF_TARGET_NAME} 技术参考手册** > **数字签名 (DS)** [`PDF <{IDF_TARGET_TRM_CN_URL}#digsig>`__]。 + +如果要以开发为目的配置 DS 外设,可以使用 `esp-secure-cert-tool `_。 + +配置完 DS 外设后获取的加密私钥参数需要保存在 flash 中并传递给 DS 外设,DS 外设将使用这些参数完成数字签名。随后,应用程序需要从 flash 中读取 DS 数据,这可以通过 `esp_secure_cert_mgr `_ 组件提供的 API 完成。更多细节,请参阅 `component/README `_。 + +在 esp_tls 仓库内部,`ESP-TLS` 负责完成初始化 DS 外设、执行数字签名的过程。更多细节,请参阅 :ref:`digital-signature-with-esp-tls`。 + +如 `ESP-TLS` 文档所述,应用程序只需将加密私钥参数作为 `ds_data` 传递给 esp_tls 上下文,esp_tls 仓库内部就会执行所有必要操作,以初始化 DS 外设,并执行数字签名。 + +使用 DS 外设进行 SSL 双向认证 +----------------------------- + +示例 :example:`protocols/mqtt/ssl_ds` 展示了如何使用 DS 外设进行 SSL 双向认证。在示例中,使用了 `mqtt_client` (通过 `ESP-MQTT` 实现),通过 SSL 传输连接到代理服务器 ``test.mosquitto.org``,并进行 SSL 双向认证。SSL 部分在内部使用 `ESP-TLS` 完成。更多细节,请参阅 :example_file:`protocols/mqtt/ssl_ds/README.md`。 + +API 参考 +-------- + +.. include-build-file:: inc/esp_ds.inc diff --git a/docs/zh_CN/api-reference/peripherals/rmt.rst b/docs/zh_CN/api-reference/peripherals/rmt.rst index c67db090b6a..9008dd44a26 100644 --- a/docs/zh_CN/api-reference/peripherals/rmt.rst +++ b/docs/zh_CN/api-reference/peripherals/rmt.rst @@ -249,6 +249,7 @@ RMT 是一种特殊的通信外设,无法像 SPI 和 I2C 那样发送原始字 注意,不是所有 ESP 芯片都支持 **循环发送** 功能,在配置此选项前,请参阅 [`TRM <{IDF_TARGET_TRM_EN_URL}#rmt>`__]。若所选芯片不支持配置此选项,可能会报告 :c:macro:`ESP_ERR_NOT_SUPPORTED` 错误。 - :cpp:member:`rmt_transmit_config_t::eot_level` 设置发射器完成工作时的输出电平,该设置同时适用于调用 :cpp:func:`rmt_disable` 停止发射器工作时的输出电平。 +- :cpp:member:`rmt_transmit_config_t::queue_nonblocking` 设置当传输队列满的时候该函数是否需要等待。如果该值设置为 ``true`` 那么当遇到队列满的时候,该函数会立即返回错误代码 :c:macro:`ESP_ERR_INVALID_STATE`。否则,函数会阻塞当前线程,直到传输队列有空档。 .. note:: diff --git a/docs/zh_CN/api-reference/peripherals/spi_slave.rst b/docs/zh_CN/api-reference/peripherals/spi_slave.rst index c80843dab4a..6ab50cf464a 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_slave.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_slave.rst @@ -141,12 +141,12 @@ GPIO 交换矩阵和 IO_MUX .. only:: not esp32 - {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1"} - {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4"} - {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5"} - {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0"} - {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3"} - {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2"} + {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7"} + {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9"} + {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8"} + {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10"} + {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6"} + {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11"} {IDF_TARGET_NAME} 的大多数外设信号都直接连接到其专用的 IO_MUX 管脚。不过,也可以使用 GPIO 交换矩阵,将信号路由到任何可用的其他管脚。如果通过 GPIO 交换矩阵路由了至少一个信号,则所有信号都将通过 GPIO 交换矩阵路由。 diff --git a/docs/zh_CN/api-reference/storage/nvs_encryption.rst b/docs/zh_CN/api-reference/storage/nvs_encryption.rst index d36be49c578..589dfb143ec 100644 --- a/docs/zh_CN/api-reference/storage/nvs_encryption.rst +++ b/docs/zh_CN/api-reference/storage/nvs_encryption.rst @@ -69,7 +69,7 @@ NVS 密钥分区 idf.py partition-table partition-table-flash - 1. 使用 :component_file:`parttool.py` (参见 :doc:`/api-guides/partition-tables` 中分区工具相关章节)将密钥存储在 flash 上的 :ref:`nvs_encr_key_partition` 中 + 2. 使用 :component_file:`parttool.py` (参见 :doc:`/api-guides/partition-tables` 中分区工具相关章节)将密钥存储在 flash 上的 :ref:`nvs_encr_key_partition` 中 :: parttool.py --port PORT --partition-table-offset PARTITION_TABLE_OFFSET write_partition --partition-name="name of nvs_key partition" --input NVS_KEY_PARTITION_FILE @@ -86,18 +86,18 @@ NVS 密钥分区 .. only:: SOC_HMAC_SUPPORTED -NVS 加密:基于 HMAC 外设的方案 --------------------------------------------- + NVS 加密:基于 HMAC 外设的方案 + -------------------------------------------- -此方案中,用于 NVS 加密的 XTS 密钥来自 eFuse 中编程的 HMAC 密钥,其目的是 :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`。由于加密密钥在运行时生成,不存储在 flash 中,因此这个功能不需要单独的 :ref:`nvs_encr_key_partition`。 + 此方案中,用于 NVS 加密的 XTS 密钥来自 eFuse 中编程的 HMAC 密钥,其目的是 :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`。由于加密密钥在运行时生成,不存储在 flash 中,因此这个功能不需要单独的 :ref:`nvs_encr_key_partition`。 -.. note:: + .. note:: - 通过这个方案, **无需启用 flash 加密** 就能在 {IDF_TARGET_NAME} 上实现安全存储。 + 通过这个方案, **无需启用 flash 加密** 就能在 {IDF_TARGET_NAME} 上实现安全存储。 -.. important:: + .. important:: - 注意,此方案使用一个 eFuse 块来存储获取加密密钥所需的 HMAC 密钥。 + 注意,此方案使用一个 eFuse 块来存储获取加密密钥所需的 HMAC 密钥。 - NVS 加密启用时后,可用 API 函数 :cpp:func:`nvs_flash_init` 来初始化加密的默认 NVS 分区。该 API 函数首先检查 :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` 处是否存在一个 HMAC 密钥。 @@ -146,37 +146,37 @@ NVS API 函数 ``nvs_get_*`` 或 ``nvs_set_*`` 也可用于读取和写入加密 .. only:: SOC_HMAC_SUPPORTED - * 对基于 HMAC 的方案 + * 对基于 HMAC 的方案 - - 用 :cpp:type:`nvs_sec_config_hmac_t` 为设置特定方案配置数据,并使用 API :cpp:func:`nvs_sec_provider_register_hmac` 注册此基于 HMAC 的方案。该 API 也将用于填充特定方案的句柄(参见 :cpp:type:`nvs_sec_scheme_t`)。 - - 使用 API 函数 :cpp:func:`nvs_flash_read_security_cfg_v2` 或 :cpp:func:`nvs_flash_generate_keys_v2` 填充 :cpp:type:`nvs_sec_cfg_t` 结构体。 + - 用 :cpp:type:`nvs_sec_config_hmac_t` 为设置特定方案配置数据,并使用 API :cpp:func:`nvs_sec_provider_register_hmac` 注册此基于 HMAC 的方案。该 API 也将用于填充特定方案的句柄(参见 :cpp:type:`nvs_sec_scheme_t`)。 + - 使用 API 函数 :cpp:func:`nvs_flash_read_security_cfg_v2` 或 :cpp:func:`nvs_flash_generate_keys_v2` 填充 :cpp:type:`nvs_sec_cfg_t` 结构体。 - .. code-block:: c + .. code-block:: c - nvs_sec_cfg_t cfg = {}; - nvs_sec_scheme_t *sec_scheme_handle = NULL; + nvs_sec_cfg_t cfg = {}; + nvs_sec_scheme_t *sec_scheme_handle = NULL; - nvs_sec_config_hmac_t sec_scheme_cfg = {}; - hmac_key_id_t hmac_key = HMAC_KEY0; - sec_scheme_cfg.hmac_key_id = hmac_key; + nvs_sec_config_hmac_t sec_scheme_cfg = {}; + hmac_key_id_t hmac_key = HMAC_KEY0; + sec_scheme_cfg.hmac_key_id = hmac_key; - ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle); - if (ret != ESP_OK) { + ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle); + if (ret != ESP_OK) { return ret; - } + } - ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); - if (ret != ESP_OK) { - if (ret == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { - ret = nvs_flash_generate_keys_v2(&sec_scheme_handle, &cfg); - if (ret != ESP_OK) { + ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); + if (ret != ESP_OK) { + if (ret == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { + ret = nvs_flash_generate_keys_v2(&sec_scheme_handle, &cfg); + if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to generate NVS encr-keys!"); - return ret; + return ret; + } } + ESP_LOGE(TAG, "Failed to read NVS security cfg!"); + return ret; } - ESP_LOGE(TAG, "Failed to read NVS security cfg!"); - return ret; - } 2. 使用 API 函数 :cpp:func:`nvs_flash_secure_init` 或 :cpp:func:`nvs_flash_secure_init_partition` 初始化 NVS flash 分区。 3. 使用 API 函数 :cpp:func:`nvs_open` 或 :cpp:func:`nvs_open_from_partition` 打开一个命名空间。 @@ -185,8 +185,8 @@ NVS API 函数 ``nvs_get_*`` 或 ``nvs_set_*`` 也可用于读取和写入加密 .. only:: SOC_HMAC_SUPPORTED -.. note:: - 在采用基于 HMAC 的方案时,可以在不启用任何 NVS 加密的配置选项的情况下开始上述工作流::ref:`CONFIG_NVS_ENCRYPTION`,:ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> `CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC` 和 :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`,以使用 :cpp:func:`nvs_flash_secure_init` API 加密默认分区及自定义的 NVS 分区。 + .. note:: + 在采用基于 HMAC 的方案时,可以在不启用任何 NVS 加密的配置选项的情况下开始上述工作流::ref:`CONFIG_NVS_ENCRYPTION`,:ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> `CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC` 和 :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`,以使用 :cpp:func:`nvs_flash_secure_init` API 加密默认分区及自定义的 NVS 分区。 NVS Security Provider diff --git a/docs/zh_CN/api-reference/system/heap_debug.rst b/docs/zh_CN/api-reference/system/heap_debug.rst index 9a01d6328ab..e437eed71b1 100644 --- a/docs/zh_CN/api-reference/system/heap_debug.rst +++ b/docs/zh_CN/api-reference/system/heap_debug.rst @@ -154,12 +154,6 @@ ESP-IDF 集成了用于请求 :ref:`堆内存信息 `、:ref:` 如果检查到字节与上述值不同,通常表示缓冲区越界或下溢。其中越界表示在写入内存时,写入的数据超过了所分配内存的大小,导致写入到了未分配的内存区域;下溢表示在读取内存时,读取的数据超出了所分配内存的范围,读取了未分配的内存区域的数据。 -.. only:: CONFIG_ESP_ROM_HAS_HEAP_TLSF - - .. warning:: - - 需注意,使用 TLSF 堆的 ROM 实现时,:cpp:func:`heap_caps_check_integrity` 不会对 canary 字节执行检查。 - 全面检测模式 +++++++++++++++++++ @@ -184,12 +178,6 @@ ESP-IDF 集成了用于请求 :ref:`堆内存信息 `、:ref:` - 对于已释放的堆内存块,检测器会检查是否所有字节都设置为 ``0xFE``,检测到任何其他值都表示错误写入了已释放内存。 - 对于已分配的堆内存块,检测器的检查模式与轻微影响模式相同,即在每个分配的缓冲区头部和尾部检查 canary 字节 ``0xABBA1234`` 和 ``0xBAAD5678``,检测到任何其他字节都表示缓冲区越界或下溢。 -.. only:: CONFIG_ESP_ROM_HAS_HEAP_TLSF - - .. warning:: - - 需注意,使用 TLSF 堆的 ROM 实现时,:cpp:func:`heap_caps_check_integrity` 不会对 canary 字节执行检查。 - .. _heap-task-tracking: 堆任务跟踪 diff --git a/docs/zh_CN/contribute/documenting-code.rst b/docs/zh_CN/contribute/documenting-code.rst index 0568aaa1b12..a048b298499 100644 --- a/docs/zh_CN/contribute/documenting-code.rst +++ b/docs/zh_CN/contribute/documenting-code.rst @@ -123,7 +123,7 @@ Doxygen 支持多种格式,并支持文档内部的多个详情级别,具有 如需更多应用示例,请参考 :component_file:`nvs_flash/include/nvs.h`。 -4. 如需进一步跳过重复定义或枚举等代码,可使用 ``/** @cond */`` 和 ``/** @endcond */`` 命令附上该代码。相关应用实例,请参考 :component_file:`driver/gpio/include/driver/gpio.h`。 +4. 如需进一步跳过重复定义或枚举等代码,可使用 ``/** @cond */`` 和 ``/** @endcond */`` 命令附上该代码。相关应用实例,请参考 :component_file:`esp_driver_gpio/include/driver/gpio.h`。 5. 使用 markdown 添加标题、链接和表格等,增强文档的可读性。 :: diff --git a/docs/zh_CN/migration-guides/index.rst b/docs/zh_CN/migration-guides/index.rst index a451fb268d3..c458c6398f3 100644 --- a/docs/zh_CN/migration-guides/index.rst +++ b/docs/zh_CN/migration-guides/index.rst @@ -12,3 +12,4 @@ release-5.x/5.0/index release-5.x/5.1/index release-5.x/5.2/index + release-5.x/5.3/index 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 412abc3dc26..4293fd438c2 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 @@ -83,6 +83,15 @@ SPI 以太网模块的初始化过程已经简化。此前,你需要在实例 现在,SPI 设备已在内部分配,因此无需再调用 :cpp:func:`spi_bus_add_device`。:cpp:class:`eth_dm9051_config_t`、:cpp:class:`eth_w5500_config_t` 和 :cpp:class:`eth_ksz8851snl_config_t` 配置结构体现已包含 SPI 设备配置成员(例如,可以微调可能依赖 PCB 设计的 SPI 时序)。``ETH_DM9051_DEFAULT_CONFIG``、``ETH_W5500_DEFAULT_CONFIG`` 和 ``ETH_KSZ8851SNL_DEFAULT_CONFIG`` 配置初始化宏也已接受新的参数输入。了解 SPI 以太网模块初始化示例,请查看 :doc:`以太网 API 参考指南<../../../api-reference/network/esp_eth>`。 +Ethernet 驱动 +---------------- + +用于创建 MAC 实例的 API (`esp_eth_mac_new_*()`) 的输入参数由一个配置参数改为两个,这两个参数用于 + +* 供应商特定的 MAC 配置 +* Ethernet 驱动 MAC 配置 + +该更新不仅适用于内部 Ethernet MAC :cpp:func:`esp_eth_mac_new_esp32()` 也适用于外部 MAC 设备,如 :cpp:func:`esp_eth_mac_new_ksz8851snl()`、 :cpp:func:`esp_eth_mac_new_dm9051()` 和 :cpp:func:`esp_eth_mac_new_w5500()`。 .. _tcpip-adapter: diff --git a/docs/zh_CN/migration-guides/release-5.x/5.3/index.rst b/docs/zh_CN/migration-guides/release-5.x/5.3/index.rst new file mode 100644 index 00000000000..25aeb7dff3f --- /dev/null +++ b/docs/zh_CN/migration-guides/release-5.x/5.3/index.rst @@ -0,0 +1,9 @@ +从 5.2 迁移到 5.3 +----------------- + +:link_to_translation:`en:[English]` + +.. toctree:: + :maxdepth: 1 + + peripherals diff --git a/docs/zh_CN/migration-guides/release-5.x/5.3/peripherals.rst b/docs/zh_CN/migration-guides/release-5.x/5.3/peripherals.rst new file mode 100644 index 00000000000..81411dc91f5 --- /dev/null +++ b/docs/zh_CN/migration-guides/release-5.x/5.3/peripherals.rst @@ -0,0 +1,30 @@ +外设 +==== + +:link_to_translation:`en:[English]` + +为了细粒度地控制其他组件对外设驱动的依赖,原先位于 `driver` 组件下的驱动程序被拆分到了各自独立的组件中。这些组件包括: + +- `esp_driver_gptimer` - 通用定时器驱动 +- `esp_driver_pcnt` - 脉冲计数器驱动 +- `esp_driver_gpio` - GPIO 驱动 + +为了兼容性,原来的 `driver` 组件仍然存在,并作为一个 “all-in-one" 的组件,将以上这些 `esp_driver_xyz` 组件注册成自己的公共依赖。换句话说,你无需修改既有项目的 CMake 文件,但是你现在多了一个途径去指定你项目依赖的具体的外设驱动。 + +原来你可能使用 **linker.lf** 指定了一些驱动函数在内存空间的链接位置,但是现在,因为驱动文件的位置发生了挪动,就需要你对 **linker.lf** 文件做出相应的改动的。假如,你的 linker.lf 文件里面有以下的条目: + +.. code-block:: none + + [mapping:my_mapping_scheme] + archive: libdriver.a + entries: + gpio (noflash) + +现在需要修改成: + +.. code-block:: none + + [mapping:my_mapping_scheme] + archive: libesp_driver_gpio.a + entries: + gpio (noflash) diff --git a/examples/bluetooth/.build-test-rules.yml b/examples/bluetooth/.build-test-rules.yml index 0da95ba3046..279c3bed760 100644 --- a/examples/bluetooth/.build-test-rules.yml +++ b/examples/bluetooth/.build-test-rules.yml @@ -24,8 +24,8 @@ examples/bluetooth/bluedroid/ble: examples/bluetooth/bluedroid/ble/ble_hid_device_demo: disable: - if: SOC_BT_SUPPORTED != 1 - depends_filepatterns: - - components/driver/gpio/**/* + depends_components: + - esp_driver_gpio examples/bluetooth/bluedroid/ble_50: disable: @@ -41,11 +41,11 @@ examples/bluetooth/bluedroid/classic_bt: - esp_log - esp_console - vfs + - esp_driver_gpio depends_filepatterns: - components/driver/dac/**/* - components/driver/i2s/**/* - components/driver/uart/**/* - - components/driver/gpio/**/* examples/bluetooth/bluedroid/coex/a2dp_gatts_coex: <<: *bt_default_depends @@ -84,9 +84,9 @@ examples/bluetooth/esp_ble_mesh: - vfs - mbedtls - touch_element + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/esp_ble_mesh/common_components/**/* - - components/driver/gpio/**/* examples/bluetooth/esp_ble_mesh/aligenie_demo: enable: @@ -99,9 +99,9 @@ examples/bluetooth/esp_ble_mesh/aligenie_demo: - vfs - mbedtls - driver + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/esp_ble_mesh/common_components/**/* - - components/driver/gpio/**/* examples/bluetooth/esp_ble_mesh/coex_test: enable: @@ -117,9 +117,9 @@ examples/bluetooth/esp_ble_mesh/coex_test: - esp_coex - esp_wifi - esp_netif + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/esp_ble_mesh/common_components/**/* - - components/driver/gpio/**/* examples/bluetooth/esp_ble_mesh/wifi_coexist: disable: @@ -134,9 +134,9 @@ examples/bluetooth/esp_ble_mesh/wifi_coexist: - esp_coex - esp_wifi - esp_netif + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/esp_ble_mesh/common_components/**/* - - components/driver/gpio/**/* examples/bluetooth/hci: <<: *bt_default_depends @@ -271,8 +271,9 @@ examples/bluetooth/nimble/throughput_app: <<: *bt_default_depends disable: - if: SOC_BLE_SUPPORTED != 1 + depends_components: + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/nimble/common/**/* - examples/bluetooth/nimble/throughput_app/blecent_throughput/components/**/* - components/driver/uart/**/* - - components/driver/gpio/**/* diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/CMakeLists.txt b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/CMakeLists.txt new file mode 100644 index 00000000000..632ea6ca8e0 --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/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(host_hci_uart) diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/README.md b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/README.md new file mode 100644 index 00000000000..bbc884518dc --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/README.md @@ -0,0 +1,85 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +ESP-IDF UART HCI Host +===================== + +This is a Bluetooth Host use UART as HCI IO. This require the UART device support RTS/CTS mandatory. + +It can do the configuration of UART baudrate by menuconfig. + +## Example Layout + +This example is modified based on [bt_discovery](../../classic_bt/bt_discovery), and all modifications are listed below: + +- Removed all dependencies on controller from `main.c`. + +``` +#include "esp_bt.h" + +... + +ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); + +esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); +if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(ret)); + return; +} + +if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret)); + return; +} +``` + +- Add support for uart driver: `uart_driver.c` and `uart_driver.h`. + +- Initialize UART driver in `main.c`. + +``` +#include "esp_hci_api.h" +#include "uart_driver.h" + +... + +/* initialize HCI TRANSPORT first */ +hci_uart_open(); +/* get HCI driver operations */ +esp_bluedroid_hci_driver_operations_t operations = { + .send = hci_uart_send, + .check_send_available = hci_check_send_available, + .register_host_callback = hci_register_host_callback, +}; +esp_bluedroid_attach_hci_driver(&operations); +``` + +## How to use example + +### Hardware Required + +This example should be able to run on any commonly available ESP development board. To connect UART to another board running a Bluetooth controller. For example, [controller_hci_uart_esp32](../../../hci/controller_hci_uart_esp32). + +### Configure the project + +``` +idf.py menuconfig +``` + +- UART baudrate can be configured in `Example Configuration > UART Baudrate for HCI` + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Troubleshooting diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/CMakeLists.txt b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/CMakeLists.txt new file mode 100644 index 00000000000..7661c7c45eb --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "main.c" + "uart_driver.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/Kconfig.projbuild new file mode 100644 index 00000000000..5089dc503ce --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/Kconfig.projbuild @@ -0,0 +1,8 @@ +menu "Example Configuration" + config EXAMPLE_HCI_UART_BAUDRATE + int "UART Baudrate for HCI" + range 115200 921600 + default 921600 + help + UART Baudrate for HCI. Please use standard baudrate. +endmenu diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/main.c b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/main.c new file mode 100644 index 00000000000..7bab44ab66d --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/main.c @@ -0,0 +1,306 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + + +/**************************************************************************** +* +* This file is for Classic Bluetooth device and service discovery Demo. +* +****************************************************************************/ + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_system.h" +#include "esp_log.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" +#include "esp_bluedroid_hci.h" +#include "uart_driver.h" + +#define GAP_TAG "GAP" + +typedef enum { + APP_GAP_STATE_IDLE = 0, + APP_GAP_STATE_DEVICE_DISCOVERING, + APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE, + APP_GAP_STATE_SERVICE_DISCOVERING, + APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE, +} app_gap_state_t; + +typedef struct { + bool dev_found; + uint8_t bdname_len; + uint8_t eir_len; + uint8_t rssi; + uint32_t cod; + uint8_t eir[ESP_BT_GAP_EIR_DATA_LEN]; + uint8_t bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; + esp_bd_addr_t bda; + app_gap_state_t state; +} app_gap_cb_t; + +static app_gap_cb_t m_dev_info; + +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 char *uuid2str(esp_bt_uuid_t *uuid, char *str, size_t size) +{ + if (uuid == NULL || str == NULL) { + return NULL; + } + + if (uuid->len == 2 && size >= 5) { + sprintf(str, "%04x", uuid->uuid.uuid16); + } else if (uuid->len == 4 && size >= 9) { + sprintf(str, "%08"PRIx32, uuid->uuid.uuid32); + } else if (uuid->len == 16 && size >= 37) { + uint8_t *p = uuid->uuid.uuid128; + sprintf(str, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + p[15], p[14], p[13], p[12], p[11], p[10], p[9], p[8], + p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]); + } else { + return NULL; + } + + return str; +} + +static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len) +{ + uint8_t *rmt_bdname = NULL; + uint8_t rmt_bdname_len = 0; + + if (!eir) { + return false; + } + + rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len); + if (!rmt_bdname) { + rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len); + } + + if (rmt_bdname) { + if (rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN) { + rmt_bdname_len = ESP_BT_GAP_MAX_BDNAME_LEN; + } + + if (bdname) { + memcpy(bdname, rmt_bdname, rmt_bdname_len); + bdname[rmt_bdname_len] = '\0'; + } + if (bdname_len) { + *bdname_len = rmt_bdname_len; + } + return true; + } + + return false; +} + +static void update_device_info(esp_bt_gap_cb_param_t *param) +{ + char bda_str[18]; + uint32_t cod = 0; + int32_t rssi = -129; /* invalid value */ + uint8_t *bdname = NULL; + uint8_t bdname_len = 0; + uint8_t *eir = NULL; + uint8_t eir_len = 0; + esp_bt_gap_dev_prop_t *p; + + ESP_LOGI(GAP_TAG, "Device found: %s", bda2str(param->disc_res.bda, bda_str, 18)); + for (int i = 0; i < param->disc_res.num_prop; i++) { + p = param->disc_res.prop + i; + switch (p->type) { + case ESP_BT_GAP_DEV_PROP_COD: + cod = *(uint32_t *)(p->val); + ESP_LOGI(GAP_TAG, "--Class of Device: 0x%"PRIx32, cod); + break; + case ESP_BT_GAP_DEV_PROP_RSSI: + rssi = *(int8_t *)(p->val); + ESP_LOGI(GAP_TAG, "--RSSI: %"PRId32, rssi); + break; + case ESP_BT_GAP_DEV_PROP_BDNAME: + bdname_len = (p->len > ESP_BT_GAP_MAX_BDNAME_LEN) ? ESP_BT_GAP_MAX_BDNAME_LEN : + (uint8_t)p->len; + bdname = (uint8_t *)(p->val); + break; + case ESP_BT_GAP_DEV_PROP_EIR: { + eir_len = p->len; + eir = (uint8_t *)(p->val); + break; + } + default: + break; + } + } + + /* search for device with Major device type "PHONE" or "Audio/Video" in COD */ + app_gap_cb_t *p_dev = &m_dev_info; + if (p_dev->dev_found) { + return; + } + + if (!esp_bt_gap_is_valid_cod(cod) || + (!(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_PHONE) && + !(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_AV))) { + return; + } + + memcpy(p_dev->bda, param->disc_res.bda, ESP_BD_ADDR_LEN); + p_dev->dev_found = true; + + p_dev->cod = cod; + p_dev->rssi = rssi; + if (bdname_len > 0) { + memcpy(p_dev->bdname, bdname, bdname_len); + p_dev->bdname[bdname_len] = '\0'; + p_dev->bdname_len = bdname_len; + } + if (eir_len > 0) { + memcpy(p_dev->eir, eir, eir_len); + p_dev->eir_len = eir_len; + } + + if (p_dev->bdname_len == 0) { + get_name_from_eir(p_dev->eir, p_dev->bdname, &p_dev->bdname_len); + } + + ESP_LOGI(GAP_TAG, "Found a target device, address %s, name %s", bda_str, p_dev->bdname); + p_dev->state = APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE; + ESP_LOGI(GAP_TAG, "Cancel device discovery ..."); + esp_bt_gap_cancel_discovery(); +} + +static void bt_app_gap_init(void) +{ + app_gap_cb_t *p_dev = &m_dev_info; + memset(p_dev, 0, sizeof(app_gap_cb_t)); + + p_dev->state = APP_GAP_STATE_IDLE; +} + +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + app_gap_cb_t *p_dev = &m_dev_info; + char bda_str[18]; + char uuid_str[37]; + + switch (event) { + case ESP_BT_GAP_DISC_RES_EVT: { + update_device_info(param); + break; + } + case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: { + if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) { + ESP_LOGI(GAP_TAG, "Device discovery stopped."); + if ( (p_dev->state == APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE || + p_dev->state == APP_GAP_STATE_DEVICE_DISCOVERING) + && p_dev->dev_found) { + p_dev->state = APP_GAP_STATE_SERVICE_DISCOVERING; + ESP_LOGI(GAP_TAG, "Discover services ..."); + esp_bt_gap_get_remote_services(p_dev->bda); + } + } else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) { + ESP_LOGI(GAP_TAG, "Discovery started."); + } + break; + } + case ESP_BT_GAP_RMT_SRVCS_EVT: { + if (memcmp(param->rmt_srvcs.bda, p_dev->bda, ESP_BD_ADDR_LEN) == 0 && + p_dev->state == APP_GAP_STATE_SERVICE_DISCOVERING) { + p_dev->state = APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE; + if (param->rmt_srvcs.stat == ESP_BT_STATUS_SUCCESS) { + ESP_LOGI(GAP_TAG, "Services for device %s found", bda2str(p_dev->bda, bda_str, 18)); + for (int i = 0; i < param->rmt_srvcs.num_uuids; i++) { + esp_bt_uuid_t *u = param->rmt_srvcs.uuid_list + i; + ESP_LOGI(GAP_TAG, "--%s", uuid2str(u, uuid_str, 37)); + } + } else { + ESP_LOGI(GAP_TAG, "Services for device %s not found", bda2str(p_dev->bda, bda_str, 18)); + } + } + break; + } + case ESP_BT_GAP_RMT_SRVC_REC_EVT: + default: { + ESP_LOGI(GAP_TAG, "event: %d", event); + break; + } + } + return; +} + +static void bt_app_gap_start_up(void) +{ + /* register GAP callback function */ + esp_bt_gap_register_callback(bt_app_gap_cb); + + char *dev_name = "ESP_GAP_INQRUIY"; + esp_bt_dev_set_device_name(dev_name); + + /* set discoverable and connectable mode, wait to be connected */ + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + + /* inititialize device information and status */ + bt_app_gap_init(); + + /* start to discover nearby Bluetooth devices */ + app_gap_cb_t *p_dev = &m_dev_info; + p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING; + esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); +} + +void app_main(void) +{ + /* 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) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + /* initialize HCI TRANSPORT first */ + hci_uart_open(); + /* get HCI driver operations */ + esp_bluedroid_hci_driver_operations_t operations = { + .send = hci_uart_send, + .check_send_available = hci_check_send_available, + .register_host_callback = hci_register_host_callback, + }; + esp_bluedroid_attach_hci_driver(&operations); + + esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); + if ((ret = esp_bluedroid_init_with_cfg(&bluedroid_cfg)) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s initialize bluedroid failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + if ((ret = esp_bluedroid_enable()) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s enable bluedroid failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + bt_app_gap_start_up(); +} diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.c b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.c new file mode 100644 index 00000000000..4ac100ec00b --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.c @@ -0,0 +1,165 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "driver/uart.h" +#include "esp_log.h" +#include "esp_attr.h" +#include "esp_bluedroid_hci.h" +#include "uart_driver.h" + +#define TAG "UART_HCI" + +#define UART_NO (1) +#define UART_BUF_SZ (1024) + +#define UART_TX_PIN (5) +#define UART_RX_PIN (18) +#define UART_RTS_PIN (19) +#define UART_CTS_PIN (23) + +enum { + UART_RX_TYPE = 0, + UART_RX_LEN, + UART_RX_DATA, +}; + +enum { + DATA_TYPE_COMMAND = 1, + DATA_TYPE_ACL = 2, + DATA_TYPE_SCO = 3, + DATA_TYPE_EVENT = 4 +}; + +TaskHandle_t s_rx_task_hdl; +esp_bluedroid_hci_driver_callbacks_t s_callback = { 0 }; + +static void IRAM_ATTR hci_uart_rx_task(void *arg) +{ + uint8_t buf[1026]; + int len_now_read = -1; + uint32_t len_to_read = 1; + uint32_t len_total_read = 0; + uint8_t rx_st = UART_RX_TYPE; + + while (1) { + len_now_read = uart_read_bytes(UART_NO, &buf[len_total_read], len_to_read, portMAX_DELAY); + assert(len_now_read == len_to_read); + len_total_read += len_now_read; + + switch (rx_st) { + case UART_RX_TYPE: { + assert(buf[0] >= DATA_TYPE_ACL && buf[0] <= DATA_TYPE_EVENT); + if (buf[0] == DATA_TYPE_ACL) { + len_to_read = 4; + } else if (buf[0] == DATA_TYPE_SCO) { + len_to_read = 3; + } else if (buf[0] == DATA_TYPE_EVENT) { + len_to_read = 2; + } else { + assert(0); + } + rx_st = UART_RX_LEN; + } + break; + + case UART_RX_LEN: { + if (buf[0] == DATA_TYPE_ACL) { + len_to_read = buf[3] | (buf[4] << 8); + } else if (buf[0] == DATA_TYPE_SCO) { + len_to_read = buf[3]; + } else if (buf[0] == DATA_TYPE_EVENT) { + len_to_read = buf[2]; + } else { + assert(0); + } + rx_st = UART_RX_DATA; + } + break; + + case UART_RX_DATA: { + if (s_callback.notify_host_recv) { + s_callback.notify_host_recv(buf, len_total_read); + } + + rx_st = UART_RX_TYPE; + len_to_read = 1; + len_total_read = 0; + } + break; + + default: { + assert(0); + break; + } + } + } + + vTaskDelete(NULL); +} + +void hci_uart_send(uint8_t *buf, uint16_t len) +{ + uint8_t *p = buf; + int len_write = 0; + + while (len) { + len_write = uart_write_bytes(UART_NO, p, len); + assert(len_write > 0); + len -= len_write; + p += len_write; + } +} + +bool hci_check_send_available(void) +{ + return true; +} + +esp_err_t hci_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback) +{ + s_callback.notify_host_send_available = callback->notify_host_send_available; + s_callback.notify_host_recv = callback->notify_host_recv; + + return ESP_OK; +} + +void hci_uart_open(void) +{ + uart_config_t uart_config = { + .baud_rate = CONFIG_EXAMPLE_HCI_UART_BAUDRATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, + .source_clk = UART_SCLK_DEFAULT, + .rx_flow_ctrl_thresh = UART_HW_FIFO_LEN(UART_NO) - 1, + }; + + int intr_alloc_flags = 0; +#if CONFIG_UART_ISR_IN_IRAM + intr_alloc_flags = ESP_INTR_FLAG_IRAM; +#endif + + ESP_ERROR_CHECK(uart_driver_install(UART_NO, UART_BUF_SZ * 2, UART_BUF_SZ * 2, 0, NULL, intr_alloc_flags)); + ESP_ERROR_CHECK(uart_param_config(UART_NO, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(UART_NO, UART_TX_PIN, UART_RX_PIN, UART_RTS_PIN, UART_CTS_PIN)); + + xTaskCreate(hci_uart_rx_task, "hci_uart_rx_task", 2048, NULL, 12, &s_rx_task_hdl); +} + +void hci_uart_close(void) +{ + if (s_rx_task_hdl) { + vTaskDelete(s_rx_task_hdl); + } + uart_driver_delete(UART_NO); + memset(&s_callback, 0, sizeof(esp_bluedroid_hci_driver_callbacks_t)); +} diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.h b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.h new file mode 100644 index 00000000000..077d9381343 --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __UART_DRIVER_H__ +#define __UART_DRIVER_H__ + +#include +#include +#include "esp_bluedroid_hci.h" + +/** + * @brief open HCI transport of uart + */ +void hci_uart_open(void); + +/** + * @brief close HCI transport of uart + */ +void hci_uart_close(void); + +/** + * @brief send data from host to HCI transport + * + * @param[in] data pointer to data buffer + * @param[in] len length of data + */ +void hci_uart_send(uint8_t *data, uint16_t len); + +/** + * @brief host checks whether it can send data to HCI transport + * + * @return true if host can send data, false otherwise + */ +bool hci_check_send_available(void); + +/** + * @brief register host callbacks + * + * @param[in] callback HCI driver callbacks + */ +esp_err_t hci_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback); + +#endif /* __UART_DRIVER_H__ */ diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/sdkconfig.defaults b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/sdkconfig.defaults new file mode 100644 index 00000000000..f23507d897e --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/sdkconfig.defaults @@ -0,0 +1,4 @@ +CONFIG_BT_CONTROLLER_DISABLED=y +CONFIG_BT_ENABLED=y +CONFIG_BT_BLUEDROID_ENABLED=y +CONFIG_BT_CLASSIC_ENABLED=y diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.defaults index a3035995211..1974e0e8cb5 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.defaults @@ -5,6 +5,6 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_CLASSIC_ENABLED=y -CONFIG_WIFI_ENABLED=n +CONFIG_ESP_WIFI_ENABLED=n CONFIG_BT_SPP_ENABLED=y CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.defaults index a3035995211..1974e0e8cb5 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.defaults @@ -5,6 +5,6 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_CLASSIC_ENABLED=y -CONFIG_WIFI_ENABLED=n +CONFIG_ESP_WIFI_ENABLED=n CONFIG_BT_SPP_ENABLED=y CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c index 47cbbd0ce50..f944aa729e6 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c @@ -112,7 +112,7 @@ void spp_task_task_shut_down(void) void spp_wr_task_start_up(spp_wr_task_cb_t p_cback, int fd) { - xTaskCreate(p_cback, "write_read", 2048, (void *)fd, 5, NULL); + xTaskCreate(p_cback, "write_read", 4096, (void *)fd, 5, NULL); } void spp_wr_task_shut_down(void) { diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.defaults index a3035995211..1974e0e8cb5 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.defaults @@ -5,6 +5,6 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_CLASSIC_ENABLED=y -CONFIG_WIFI_ENABLED=n +CONFIG_ESP_WIFI_ENABLED=n CONFIG_BT_SPP_ENABLED=y CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c index 47cbbd0ce50..f944aa729e6 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c @@ -112,7 +112,7 @@ void spp_task_task_shut_down(void) void spp_wr_task_start_up(spp_wr_task_cb_t p_cback, int fd) { - xTaskCreate(p_cback, "write_read", 2048, (void *)fd, 5, NULL); + xTaskCreate(p_cback, "write_read", 4096, (void *)fd, 5, NULL); } void spp_wr_task_shut_down(void) { diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.defaults index a3035995211..1974e0e8cb5 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.defaults @@ -5,6 +5,6 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_CLASSIC_ENABLED=y -CONFIG_WIFI_ENABLED=n +CONFIG_ESP_WIFI_ENABLED=n CONFIG_BT_SPP_ENABLED=y CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/esp_ble_mesh/common_components/button/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/common_components/button/CMakeLists.txt index f9b07dafe52..24adc8d5b3f 100644 --- a/examples/bluetooth/esp_ble_mesh/common_components/button/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/common_components/button/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "button.c" "button_obj.cpp" INCLUDE_DIRS "." "include" - PRIV_REQUIRES driver esp_timer) + PRIV_REQUIRES esp_driver_gpio esp_timer) diff --git a/examples/bluetooth/esp_ble_mesh/common_components/light_driver/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/common_components/light_driver/CMakeLists.txt index 6dc16c7094c..fe06e61668c 100644 --- a/examples/bluetooth/esp_ble_mesh/common_components/light_driver/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/common_components/light_driver/CMakeLists.txt @@ -7,6 +7,6 @@ set(COMPONENT_SRCS set(COMPONENT_ADD_INCLUDEDIRS ". include") # requirements can't depend on config -set(COMPONENT_REQUIRES example_nvs driver) +set(COMPONENT_REQUIRES example_nvs driver esp_driver_gpio) register_component() diff --git a/examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c b/examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c index 33bbfbe11db..7e95cdb65f1 100644 --- a/examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c +++ b/examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -42,27 +42,6 @@ typedef struct #if CONFIG_BT_BLE_ENABLED static local_param_t s_ble_hid_param = {0}; -const unsigned char hidapiReportMap[] = { //8 bytes input, 8 bytes feature - 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) - 0x0A, 0x00, 0x01, // Usage (0x0100) - 0xA1, 0x01, // Collection (Application) - 0x85, 0x01, // Report ID (1) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8) - 0x95, 0x08, // Report Count (8) - 0x09, 0x01, // Usage (0x01) - 0x82, 0x02, 0x01, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Buffered Bytes) - 0x95, 0x08, // Report Count (8) - 0x09, 0x02, // Usage (0x02) - 0xB2, 0x02, 0x01, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes) - 0x95, 0x08, // Report Count (8) - 0x09, 0x03, // Usage (0x03) - 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) - 0xC0, // End Collection - - // 38 bytes -}; const unsigned char mediaReportMap[] = { 0x05, 0x0C, // Usage Page (Consumer) @@ -125,10 +104,6 @@ const unsigned char mediaReportMap[] = { }; static esp_hid_raw_report_map_t ble_report_maps[] = { - { - .data = hidapiReportMap, - .len = sizeof(hidapiReportMap) - }, { .data = mediaReportMap, .len = sizeof(mediaReportMap) @@ -143,7 +118,7 @@ static esp_hid_device_config_t ble_hid_config = { .manufacturer_name = "Espressif", .serial_number = "1234567890", .report_maps = ble_report_maps, - .report_maps_len = 2 + .report_maps_len = 1 }; #define HID_CC_RPT_MUTE 1 @@ -293,7 +268,7 @@ void esp_hidd_send_consumer_value(uint8_t key_cmd, bool key_pressed) break; } } - esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 1, HID_RPT_ID_CC_IN, buffer, HID_CC_IN_RPT_LEN); + esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, HID_RPT_ID_CC_IN, buffer, HID_CC_IN_RPT_LEN); return; } @@ -318,6 +293,10 @@ void ble_hid_demo_task(void *pvParameters) void ble_hid_task_start_up(void) { + if (s_ble_hid_param.task_hdl) { + // Task already exists + return; + } xTaskCreate(ble_hid_demo_task, "ble_hid_demo_task", 2 * 1024, NULL, configMAX_PRIORITIES - 3, &s_ble_hid_param.task_hdl); } @@ -344,7 +323,6 @@ static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, i } case ESP_HIDD_CONNECT_EVENT: { ESP_LOGI(TAG, "CONNECT"); - ble_hid_task_start_up();//todo: this should be on auth_complete (in GAP) break; } case ESP_HIDD_PROTOCOL_MODE_EVENT: { @@ -353,7 +331,15 @@ static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, i } case ESP_HIDD_CONTROL_EVENT: { ESP_LOGI(TAG, "CONTROL[%u]: %sSUSPEND", param->control.map_index, param->control.control ? "EXIT_" : ""); - break; + if (param->control.control) + { + // exit suspend + ble_hid_task_start_up(); + } else { + // suspend + ble_hid_task_shut_down(); + } + break; } case ESP_HIDD_OUTPUT_EVENT: { ESP_LOGI(TAG, "OUTPUT[%u]: %8s ID: %2u, Len: %d, Data:", param->output.map_index, esp_hid_usage_str(param->output.usage), param->output.report_id, param->output.length); diff --git a/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c b/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c index f47933be25c..1f0d2a460b7 100644 --- a/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c +++ b/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c @@ -486,7 +486,7 @@ static esp_err_t start_bt_scan(uint32_t seconds) /* * BLE GAP * */ - +extern void ble_hid_task_start_up(void); static void ble_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { switch (event) { @@ -535,10 +535,12 @@ static void ble_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_p * */ case ESP_GAP_BLE_AUTH_CMPL_EVT: if (!param->ble_security.auth_cmpl.success) { + // if AUTH ERROR,hid maybe don't work. ESP_LOGE(TAG, "BLE GAP AUTH ERROR: 0x%x", param->ble_security.auth_cmpl.fail_reason); } else { ESP_LOGI(TAG, "BLE GAP AUTH SUCCESS"); } + ble_hid_task_start_up(); break; case ESP_GAP_BLE_KEY_EVT: //shows the ble key info share with peer device to the user. diff --git a/examples/bluetooth/esp_hid_host/sdkconfig.defaults b/examples/bluetooth/esp_hid_host/sdkconfig.defaults index 2828e5ca2ac..1c2104eacc6 100644 --- a/examples/bluetooth/esp_hid_host/sdkconfig.defaults +++ b/examples/bluetooth/esp_hid_host/sdkconfig.defaults @@ -7,3 +7,4 @@ CONFIG_BT_BLE_ENABLED=y CONFIG_BT_HID_ENABLED=y CONFIG_BT_HID_HOST_ENABLED=y CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +CONFIG_BT_GATTC_NOTIF_REG_MAX=16 diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/CMakeLists.txt b/examples/bluetooth/nimble/ble_cts/cts_cent/CMakeLists.txt similarity index 90% rename from tools/test_apps/linux_compatible/hello_world_linux_compatible/CMakeLists.txt rename to examples/bluetooth/nimble/ble_cts/cts_cent/CMakeLists.txt index 9e0d431d4ce..30e34b1f9be 100644 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/CMakeLists.txt +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/CMakeLists.txt @@ -3,5 +3,4 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) - -project(hello_world) +project(cts_cent) diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/README.md b/examples/bluetooth/nimble/ble_cts/cts_cent/README.md new file mode 100644 index 00000000000..1dd4b84ff0e --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/README.md @@ -0,0 +1,156 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# BLE CTS Cent Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example creates GATT client and performs passive scan, it then connects to peripheral device if the device advertises connectability and the device advertises support for the Current Time Service (0x1805) as primary service UUID. + +It performs following GATT operations against the specified peer: + +* Reads the Current Time characteristic. + +If the peer does not support a required service, characteristic, or descriptor, then the peer lied when it claimed support for the Current Time Service! When this happens, or if a GATT procedure fails, this function immediately terminates the connection. + +It uses ESP32's Bluetooth controller and NimBLE stack based BLE host. + +This example aims at understanding BLE service discovery, connection, encryption and characteristic operations. + +To test this demo, use any BLE GATT server app that advertises support for the Current Time Service (0x1805) and includes it in the GATT database. + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Hardware Required + +* A development board with ESP32/ESP32-C2/ESP32-C3/ESP32-S3/ESP32-H2/ESP32-C6 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Configure the Project + +Open the project configuration menu: + +```bash +idf.py menuconfig +``` + +In the `Example Configuration` menu: + +* Change the `Peer Address` option if needed. + +### Build and Flash + +Run `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://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +This is the console output on successful connection: + +``` +I (358) BLE_INIT: BT controller compile version [59725b5] +I (358) BLE_INIT: Bluetooth MAC: 60:55:f9:68:c4:fa +I (368) phy_init: phy_version 1110,9c20f0a,Jul 27 2023,10:42:54 +I (408) NimBLE_CTS_CENT: BLE Host Task Started +I (408) NimBLE: GAP procedure initiated: stop advertising. + +I (408) NimBLE: GAP procedure initiated: discovery; +I (408) NimBLE: own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=1 +I (418) NimBLE: duration=forever +I (428) NimBLE: + +I (428) main_task: Returned from app_main() +I (628) NimBLE: GAP procedure initiated: connect; +I (628) NimBLE: peer_addr_type=1 peer_addr= +I (628) NimBLE: 6b:93:b5:30:71:cf +I (638) NimBLE: scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=0 max_ce_len=0 own_addr_type=0 +I (648) NimBLE: + +I (908) NimBLE: Connection established +I (908) NimBLE: + +I (918) NimBLE: Connection secured + +I (1208) NimBLE: received indication; conn_handle=1 attr_handle=3 attr_len=4 + +I (1208) NimBLE: GAP procedure initiated: +I (1208) NimBLE: connection parameter update; conn_handle=1 itvl_min=6 itvl_max=6 latency=0 supervision_timeout=500 min_ce_len=0 max_ce_len=0 +I (1228) NimBLE: + +I (3568) NimBLE: encryption change event; status=0 +I (3568) NimBLE: GATT procedure initiated: discover all services + +I (3608) NimBLE: GATT procedure initiated: discover all characteristics; +I (3608) NimBLE: start_handle=1 end_handle=9 + +I (3658) NimBLE: GATT procedure initiated: discover all characteristics; +I (3658) NimBLE: start_handle=20 end_handle=26 + +I (3688) NimBLE: GATT procedure initiated: discover all characteristics; +I (3688) NimBLE: start_handle=134 end_handle=141 + +I (3718) NimBLE: GATT procedure initiated: discover all characteristics; +I (3718) NimBLE: start_handle=142 end_handle=151 + +I (3758) NimBLE: GATT procedure initiated: discover all characteristics; +I (3758) NimBLE: start_handle=152 end_handle=158 + +I (3788) NimBLE: GATT procedure initiated: discover all characteristics; +I (3788) NimBLE: start_handle=159 end_handle=65535 + +I (3818) NimBLE: GATT procedure initiated: discover all descriptors; +I (3818) NimBLE: chr_val_handle=136 end_handle=137 + +I (3838) NimBLE: GATT procedure initiated: discover all descriptors; +I (3838) NimBLE: chr_val_handle=144 end_handle=148 + +I (3898) NimBLE: GATT procedure initiated: discover all descriptors; +I (3898) NimBLE: chr_val_handle=150 end_handle=151 + +I (3908) NimBLE: GATT procedure initiated: discover all descriptors; +I (3908) NimBLE: chr_val_handle=161 end_handle=162 + +I (3928) NimBLE: GATT procedure initiated: discover all descriptors; +I (3928) NimBLE: chr_val_handle=164 end_handle=65535 + +I (3938) NimBLE: Service discovery complete; status=0 conn_handle=1 + +I (3938) NimBLE: GATT procedure initiated: read; +I (3938) NimBLE: att_handle=161 + +I (3958) NimBLE: Read Current time complete; status=0 conn_handle=1 +I (3958) NimBLE: attr_handle=161 value= +I (3958) NimBLE: 0xe7 +I (3958) NimBLE: :0x07 +I (3958) NimBLE: :0x08 +I (3968) NimBLE: :0x1e +I (3968) NimBLE: :0x14 +I (3968) NimBLE: :0x25 +I (3978) NimBLE: :0x02 +I (3978) NimBLE: :0x03 +I (3978) NimBLE: :0xf6 +I (3978) NimBLE: :0x00 +I (3988) NimBLE: + +I (3988) NimBLE_CTS_CENT: Date : 30/8/2023 +I (3998) NimBLE_CTS_CENT: hours : 20 minutes : 37 +I (3998) NimBLE_CTS_CENT: seconds : 2 + +I (4008) NimBLE_CTS_CENT: fractions : 0 + +``` + +## 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/bluetooth/nimble/ble_cts/cts_cent/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_cts/cts_cent/main/CMakeLists.txt new file mode 100644 index 00000000000..18d510d9882 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(srcs "main.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild new file mode 100644 index 00000000000..8cad8f99527 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild @@ -0,0 +1,27 @@ +menu "Example Configuration" + + config EXAMPLE_PEER_ADDR + string "Peer Address" + default "ADDR_ANY" + help + Enter the peer address in aa:bb:cc:dd:ee:ff form to connect to a specific peripheral + + config EXAMPLE_ENCRYPTION + bool + prompt "Enable Link Encryption" + default y + help + This enables bonding and encryption after connection has been established. + + config EXAMPLE_EXTENDED_ADV + bool + depends on SOC_BLE_50_SUPPORTED + default y if SOC_ESP_NIMBLE_CONTROLLER + select BT_NIMBLE_EXT_ADV + prompt "Enable Extended Adv" + help + Use this option to enable extended advertising in the example. + If this option is disabled, ensure config BT_NIMBLE_EXT_ADV is + also disabled from Nimble stack menuconfig + +endmenu diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/ble_cts_cent.h b/examples/bluetooth/nimble/ble_cts/cts_cent/main/ble_cts_cent.h new file mode 100644 index 00000000000..2a734676bb8 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/ble_cts_cent.h @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_BLE_CTS_CENT_ +#define H_BLE_CTS_CENT_ + +#include "modlog/modlog.h" +#include "esp_central.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_adv_fields; +struct ble_gap_conn_desc; +struct ble_hs_cfg; +union ble_store_value; +union ble_store_key; + +/* 16 BIT CCCD UUID */ +#define BLE_SVC_CTS_DSC_CLT_CFG_UUID16 0x2902 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/idf_component.yml b/examples/bluetooth/nimble/ble_cts/cts_cent/main/idf_component.yml new file mode 100644 index 00000000000..db8886afea4 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/idf_component.yml @@ -0,0 +1,3 @@ +dependencies: + nimble_central_utils: + path: ${IDF_PATH}/examples/bluetooth/nimble/common/nimble_central_utils diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c b/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c new file mode 100644 index 00000000000..fd235c4dfeb --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c @@ -0,0 +1,560 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +/* BLE */ +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "ble_cts_cent.h" +#include "services/cts/ble_svc_cts.h" + +static const char *tag = "NimBLE_CTS_CENT"; +static int ble_cts_cent_gap_event(struct ble_gap_event *event, void *arg); +static uint8_t peer_addr[6]; + +static char *day_of_week[7] = { + "Unknown" + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday" +}; +void ble_store_config_init(void); +static void ble_cts_cent_scan(void); + +void printtime(struct ble_svc_cts_curr_time ctime) { + ESP_LOGI(tag, "Date : %d/%d/%d %s", ctime.et_256.d_d_t.d_t.day, + ctime.et_256.d_d_t.d_t.month, + ctime.et_256.d_d_t.d_t.year, + day_of_week[ctime.et_256.d_d_t.day_of_week]); + ESP_LOGI(tag, "hours : %d minutes : %d ", + ctime.et_256.d_d_t.d_t.hours, + ctime.et_256.d_d_t.d_t.minutes); + ESP_LOGI(tag, "seconds : %d\n", ctime.et_256.d_d_t.d_t.seconds); + ESP_LOGI(tag, "fractions : %d\n", ctime.et_256.fractions_256); +} + +/** + * Application callback. Called when the read of the cts current time + * characteristic has completed. + */ +static int +ble_cts_cent_on_read(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) +{ + struct ble_svc_cts_curr_time ctime; /* store the read time */ + MODLOG_DFLT(INFO, "Read Current time complete; status=%d conn_handle=%d\n", + error->status, conn_handle); + if (error->status == 0) { + MODLOG_DFLT(INFO, " attr_handle=%d value=\n", attr->handle); + print_mbuf(attr->om); + } + else { + goto err; + } + MODLOG_DFLT(INFO, "\n"); + ble_hs_mbuf_to_flat(attr->om, &ctime, sizeof(ctime), NULL); + printtime(ctime); + return 0; +err: + /* Terminate the connection. */ + return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM); +} + +/** + * Performs read on the current time characteristic + * + */ +static int +ble_cts_cent_read_time(const struct peer *peer) +{ + + /* Subscribe to notifications for the Current Time Characteristic. + * A central enables notifications by writing two bytes (1, 0) to the + * characteristic's client-characteristic-configuration-descriptor (CCCD). + */ + const struct peer_chr *chr; + int rc; + + chr = peer_chr_find_uuid(peer, + BLE_UUID16_DECLARE(BLE_SVC_CTS_UUID16), + BLE_UUID16_DECLARE(BLE_SVC_CTS_CHR_UUID16_CURRENT_TIME)); + if (chr == NULL) { + MODLOG_DFLT(ERROR, "Error: Peer doesn't support the CTS " + " characteristic\n"); + goto err; + } + rc = ble_gattc_read(peer->conn_handle, chr->chr.val_handle, + ble_cts_cent_on_read, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Error: Failed to read characteristic; rc=%d\n", + rc); + goto err; + } + + return 0; +err: + /* Terminate the connection. */ + return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM); +} + +/** + * Called when service discovery of the specified peer has completed. + */ +static void +ble_cts_cent_on_disc_complete(const struct peer *peer, int status, void *arg) +{ + + if (status != 0) { + /* Service discovery failed. Terminate the connection. */ + MODLOG_DFLT(ERROR, "Error: Service discovery failed; status=%d " + "conn_handle=%d\n", status, peer->conn_handle); + ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM); + return; + } + + /* Service discovery has completed successfully. Now we have a complete + * list of services, characteristics, and descriptors that the peer + * supports. + */ + MODLOG_DFLT(INFO, "Service discovery complete; status=%d " + "conn_handle=%d\n", status, peer->conn_handle); + + /* Now perform GATT procedure against the peer: read + * for the cts service. + */ + ble_cts_cent_read_time(peer); +} + +/** + * Initiates the GAP general discovery procedure. + */ +static void +ble_cts_cent_scan(void) +{ + uint8_t own_addr_type; + struct ble_gap_disc_params disc_params; + int rc; + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /* Tell the controller to filter duplicates; we don't want to process + * repeated advertisements from the same device. + */ + disc_params.filter_duplicates = 1; + + /** + * Perform a passive scan. I.e., don't send follow-up scan requests to + * each advertiser. + */ + disc_params.passive = 1; + + /* Use defaults for the rest of the parameters. */ + disc_params.itvl = 0; + disc_params.window = 0; + disc_params.filter_policy = 0; + disc_params.limited = 0; + + rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params, + ble_cts_cent_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Error initiating GAP discovery procedure; rc=%d\n", + rc); + } +} + +/** + * Indicates whether we should try to connect to the sender of the specified + * advertisement. The function returns a positive result if the device + * advertises connectability and support for the Current Time Service. + */ + +#if CONFIG_EXAMPLE_EXTENDED_ADV +static int +ext_ble_cts_cent_should_connect(const struct ble_gap_ext_disc_desc *disc) +{ + int offset = 0; + int ad_struct_len = 0; + + if (disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND && + disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) { + return 0; + } + if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) { + ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR); + /* Convert string to address */ + sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &peer_addr[5], &peer_addr[4], &peer_addr[3], + &peer_addr[2], &peer_addr[1], &peer_addr[0]); + if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) { + return 0; + } + } + + /* The device has to advertise support for the CTS + * service (0x1805). + */ + do { + ad_struct_len = disc->data[offset]; + + if (!ad_struct_len) { + break; + } + + /* Search if cts UUID is advertised */ + if (disc->data[offset + 1] == 0x03) { + int temp = 2; + while(temp < disc->data[offset + 1]) { + if(disc->data[offset + temp] == 0x05 && + disc->data[offset + temp + 1] == 0x18) { + return 1; + } + temp += 2; + } + } + offset += ad_struct_len + 1; + } while ( offset < disc->length_data ); + + return 0; +} +#else + +static int +ble_cts_cent_should_connect(const struct ble_gap_disc_desc *disc) +{ + struct ble_hs_adv_fields fields; + int rc; + int i; + + /* The device has to be advertising connectability. */ + if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND && + disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) { + + return 0; + } + + rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data); + if (rc != 0) { + return 0; + } + + if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) { + ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR); + /* Convert string to address */ + sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &peer_addr[5], &peer_addr[4], &peer_addr[3], + &peer_addr[2], &peer_addr[1], &peer_addr[0]); + if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) { + return 0; + } + } + + /* The device has to advertise support for the Current Time + * service (0x1805). + */ + for (i = 0; i < fields.num_uuids16; i++) { + if (ble_uuid_u16(&fields.uuids16[i].u) == BLE_SVC_CTS_UUID16) { + return 1; + } + } + + return 0; +} +#endif + +/** + * Connects to the sender of the specified advertisement of it looks + * interesting. A device is "interesting" if it advertises connectability and + * support for the Current Time service. + */ +static void +ble_cts_cent_connect_if_interesting(void *disc) +{ + uint8_t own_addr_type; + int rc; + ble_addr_t *addr; + + /* Don't do anything if we don't care about this advertiser. */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + if (!ext_ble_cts_cent_should_connect((struct ble_gap_ext_disc_desc *)disc)) { + return; + } +#else + if (!ble_cts_cent_should_connect((struct ble_gap_disc_desc *)disc)) { + return; + } +#endif + + /* Scanning must be stopped before a connection can be initiated. */ + rc = ble_gap_disc_cancel(); + if (rc != 0) { + MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); + return; + } + + /* Figure out address to use for connect (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /* Try to connect the the advertiser. Allow 30 seconds (30000 ms) for + * timeout. + */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + addr = &((struct ble_gap_ext_disc_desc *)disc)->addr; +#else + addr = &((struct ble_gap_disc_desc *)disc)->addr; +#endif + rc = ble_gap_connect(own_addr_type, addr, 30000, NULL, + ble_cts_cent_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Error: Failed to connect to device; addr_type=%d " + "addr=%s; rc=%d\n", + addr->type, addr_str(addr->val), rc); + return; + } +} + +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that is + * established. ble_cts_cent uses the same callback for all connections. + * + * @param event The event being signalled. + * @param arg Application-specified argument; unused by + * ble_cts_cent. + * + * @return 0 if the application successfully handled the + * event; nonzero on failure. The semantics + * of the return code is specific to the + * particular GAP event being signalled. + */ +static int +ble_cts_cent_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + struct ble_hs_adv_fields fields; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_DISC: + rc = ble_hs_adv_parse_fields(&fields, event->disc.data, + event->disc.length_data); + if (rc != 0) { + return 0; + } + + /* An advertisment report was received during GAP discovery. */ + print_adv_fields(&fields); + + /* Try to connect to the advertiser if it looks interesting. */ + ble_cts_cent_connect_if_interesting(&event->disc); + return 0; + + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + if (event->connect.status == 0) { + /* Connection successfully established. */ + MODLOG_DFLT(INFO, "Connection established "); + + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); + MODLOG_DFLT(INFO, "\n"); + + /* Remember peer. */ + rc = peer_add(event->connect.conn_handle); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Failed to add peer; rc=%d\n", rc); + return 0; + } + +#if CONFIG_EXAMPLE_ENCRYPTION + /** Initiate security - It will perform + * Pairing (Exchange keys) + * Bonding (Store keys) + * Encryption (Enable encryption) + * Will invoke event BLE_GAP_EVENT_ENC_CHANGE + **/ + rc = ble_gap_security_initiate(event->connect.conn_handle); + if (rc != 0) { + MODLOG_DFLT(INFO, "Security could not be initiated, rc = %d\n", rc); + return ble_gap_terminate(event->connect.conn_handle, + BLE_ERR_REM_USER_CONN_TERM); + } else { + MODLOG_DFLT(INFO, "Connection secured\n"); + } +#else + /* Perform service discovery */ + rc = peer_disc_all(event->connect.conn_handle, + ble_cts_cent_on_disc_complete, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc); + return 0; + } +#endif + } else { + /* Connection attempt failed; resume scanning. */ + MODLOG_DFLT(ERROR, "Error: Connection failed; status=%d\n", + event->connect.status); + ble_cts_cent_scan(); + } + + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + /* Connection terminated. */ + MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason); + print_conn_desc(&event->disconnect.conn); + MODLOG_DFLT(INFO, "\n"); + + /* Forget about peer. */ + peer_delete(event->disconnect.conn.conn_handle); + + /* Resume scanning. */ + ble_cts_cent_scan(); + return 0; + + case BLE_GAP_EVENT_DISC_COMPLETE: + MODLOG_DFLT(INFO, "discovery complete; reason=%d\n", + event->disc_complete.reason); + return 0; + + case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + MODLOG_DFLT(INFO, "encryption change event; status=%d ", + event->enc_change.status); + rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); +#if CONFIG_EXAMPLE_ENCRYPTION + /*** Go for service discovery after encryption has been successfully enabled ***/ + rc = peer_disc_all(event->connect.conn_handle, + ble_cts_cent_on_disc_complete, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc); + return 0; + } +#endif + return 0; + + case BLE_GAP_EVENT_NOTIFY_RX: + /* Peer sent us a notification or indication. */ + MODLOG_DFLT(INFO, "received %s; conn_handle=%d attr_handle=%d " + "attr_len=%d\n", + event->notify_rx.indication ? + "indication" : + "notification", + event->notify_rx.conn_handle, + event->notify_rx.attr_handle, + OS_MBUF_PKTLEN(event->notify_rx.om)); + + /* Attribute data is contained in event->notify_rx.om. Use + * `os_mbuf_copydata` to copy the data received in notification mbuf */ + return 0; + + case BLE_GAP_EVENT_MTU: + MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.channel_id, + event->mtu.value); + return 0; + +#if CONFIG_EXAMPLE_EXTENDED_ADV + case BLE_GAP_EVENT_EXT_DISC: + /* An advertisment report was received during GAP discovery. */ + ext_print_adv_report(&event->disc); + + ble_cts_cent_connect_if_interesting(&event->disc); + return 0; +#endif + + default: + return 0; + } +} + +static void +ble_cts_cent_on_reset(int reason) +{ + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +ble_cts_cent_on_sync(void) +{ + int rc; + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Begin scanning for a peripheral to connect to. */ + ble_cts_cent_scan(); +} + +void ble_cts_cent_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +void +app_main(void) +{ + int rc; + /* 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) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ret = nimble_port_init(); + if (ret != ESP_OK) { + ESP_LOGE(tag, "Failed to init nimble %d ", ret); + return; + } + + /* Configure the host. */ + ble_hs_cfg.reset_cb = ble_cts_cent_on_reset; + ble_hs_cfg.sync_cb = ble_cts_cent_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Initialize data structures to track connected peers. */ + rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64); + assert(rc == 0); + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("nimble-cts-cent"); + assert(rc == 0); + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(ble_cts_cent_host_task); +} diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/sdkconfig.defaults b/examples/bluetooth/nimble/ble_cts/cts_cent/sdkconfig.defaults new file mode 100644 index 00000000000..c829fc5c002 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/sdkconfig.defaults @@ -0,0 +1,12 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/CMakeLists.txt b/examples/bluetooth/nimble/ble_cts/cts_prph/CMakeLists.txt new file mode 100644 index 00000000000..81409326b1f --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/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(cts_prph) diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/README.md b/examples/bluetooth/nimble/ble_cts/cts_prph/README.md new file mode 100644 index 00000000000..9897fd4c527 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/README.md @@ -0,0 +1,79 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# BLE Current Time Service Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example creates GATT server demonstrating standard Current Time Service. + +It advertises support for the Current Time Service(0x1805) as primary service UUID. + +It uses ESP32's Bluetooth controller and NimBLE stack based BLE host + + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Hardware Required + +* A development board with ESP32/ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Build and Flash + +Run `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://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +This console output can be observed when client is connected to server : + +``` +I (357) BLE_INIT: BT controller compile version [59725b5] +I (357) BLE_INIT: Bluetooth MAC: 60:55:f9:68:c4:fa +I (367) phy_init: phy_version 1110,9c20f0a,Jul 27 2023,10:42:54 +I (407) NimBLE_cts_PRPH: BLE Host Task Started +I (407) NimBLE: GAP procedure initiated: stop advertising. + +I (407) NimBLE: Failed to restore IRKs from store; status=8 + +I (407) NimBLE: Device Address: +I (417) NimBLE: 60:55:f9:68:c4:fa +I (417) NimBLE: + +I (417) NimBLE: GAP procedure initiated: advertise; +I (427) NimBLE: disc_mode=2 +I (427) NimBLE: adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 +I (437) NimBLE: + +I (447) main_task: Returned from app_main() + +I (27317) NimBLE: GAP procedure initiated: advertise; +I (27317) NimBLE: disc_mode=2 +I (27327) NimBLE: adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 +I (27337) NimBLE: + +I (31987) NimBLE: connection established; status=0 + +I (53297) NimBLE: subscribe event; cur_notify=1 + value handle; val_handle=12 + + I (68317) NimBLE: subscribe event; cur_notify=0 + value handle; val_handle=12 + +``` + +## 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/bluetooth/nimble/ble_cts/cts_prph/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_cts/cts_prph/main/CMakeLists.txt new file mode 100644 index 00000000000..e8a76d0b091 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" "gatt_svr.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild new file mode 100644 index 00000000000..a5240035348 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild @@ -0,0 +1,14 @@ +menu "Example Configuration" + + config EXAMPLE_EXTENDED_ADV + bool + depends on SOC_BLE_50_SUPPORTED + default y if SOC_ESP_NIMBLE_CONTROLLER + select BT_NIMBLE_EXT_ADV + prompt "Enable Extended Adv" + help + Use this option to enable extended advertising in the example. + If this option is disabled, ensure config BT_NIMBLE_EXT_ADV is + also disabled from Nimble stack menuconfig + +endmenu diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/ble_cts_prph.h b/examples/bluetooth/nimble/ble_cts/cts_prph/main/ble_cts_prph.h new file mode 100644 index 00000000000..744130053f2 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/ble_cts_prph.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_BLE_CTS_PRPH_ +#define H_BLE_CTS_PRPH_ + +#include "nimble/ble.h" +#include "modlog/modlog.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; +struct ble_gatt_register_ctxt; + +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int gatt_svr_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/gatt_svr.c b/examples/bluetooth/nimble/ble_cts/cts_prph/main/gatt_svr.c new file mode 100644 index 00000000000..7a5cc19367b --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/gatt_svr.c @@ -0,0 +1,163 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "services/gap/ble_svc_gap.h" +#include "services/gatt/ble_svc_gatt.h" +#include "ble_cts_prph.h" +#include "services/cts/ble_svc_cts.h" +#include +#include "sys/time.h" + + +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) +{ + char buf[BLE_UUID_STR_LEN]; + + switch (ctxt->op) { + case BLE_GATT_REGISTER_OP_SVC: + MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n", + ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), + ctxt->svc.handle); + break; + + case BLE_GATT_REGISTER_OP_CHR: + MODLOG_DFLT(DEBUG, "registering characteristic %s with " + "def_handle=%d val_handle=%d\n", + ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), + ctxt->chr.def_handle, + ctxt->chr.val_handle); + break; + + case BLE_GATT_REGISTER_OP_DSC: + MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n", + ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), + ctxt->dsc.handle); + break; + + default: + assert(0); + break; + } +} + +static struct ble_svc_cts_local_time_info local_info = { .timezone = 0, .dst_offset = TIME_STANDARD }; +static struct timeval last_updated; +uint8_t adjust_reason; +int fetch_current_time(struct ble_svc_cts_curr_time *ctime) { + time_t now; + struct tm timeinfo; + struct timeval tv_now; + /* time given by 'time()' api does not persist after reboots */ + time(&now); + localtime_r(&now, &timeinfo); + gettimeofday(&tv_now, NULL); + if(ctime != NULL) { + /* fill date_time */ + ctime->et_256.d_d_t.d_t.year = timeinfo.tm_year + 1900; + ctime->et_256.d_d_t.d_t.month = timeinfo.tm_mon + 1; + ctime->et_256.d_d_t.d_t.day = timeinfo.tm_mday; + ctime->et_256.d_d_t.d_t.hours = timeinfo.tm_hour; + ctime->et_256.d_d_t.d_t.minutes = timeinfo.tm_min; + ctime->et_256.d_d_t.d_t.seconds = timeinfo.tm_sec; + + /* day of week */ + /* time gives day range of [0, 6], current_time_sevice + has day range of [1,7] */ + ctime->et_256.d_d_t.day_of_week = timeinfo.tm_wday + 1; + + /* fractions_256 */ + ctime->et_256.fractions_256 = (((uint64_t)tv_now.tv_usec * 256L )/ 1000000L); + + ctime->adjust_reason = adjust_reason; + } + return 0; +} + +int set_current_time(struct ble_svc_cts_curr_time ctime) { + time_t now; + struct tm timeinfo; + struct timeval tv_now; + /* fill date_time */ + timeinfo.tm_year= ctime.et_256.d_d_t.d_t.year - 1900 ; + timeinfo.tm_mon = ctime.et_256.d_d_t.d_t.month - 1; + timeinfo.tm_mday = ctime.et_256.d_d_t.d_t.day; + timeinfo.tm_hour = ctime.et_256.d_d_t.d_t.hours; + timeinfo.tm_min = ctime.et_256.d_d_t.d_t.minutes; + timeinfo.tm_sec = ctime.et_256.d_d_t.d_t.seconds; + timeinfo.tm_wday = ctime.et_256.d_d_t.day_of_week - 1; + now = mktime(&timeinfo); + tv_now.tv_sec = now; + settimeofday(&tv_now, NULL); + /* set the last updated */ + gettimeofday(&last_updated, NULL); + adjust_reason = ctime.adjust_reason; + return 0; +} + +int fetch_local_time_info(struct ble_svc_cts_local_time_info *info) { + + if(info != NULL) { + memcpy(info, &local_info, sizeof local_info); + } + return 0; +} + +int set_local_time_info(struct ble_svc_cts_local_time_info info) { + /* just store the dst offset and timezone locally + as we don't have the access to time using ntp server */ + local_info.timezone = info.timezone; + local_info.dst_offset = info.dst_offset; + gettimeofday(&last_updated, NULL); + return 0; +} +int fetch_reference_time_info(struct ble_svc_cts_reference_time_info *info) { + struct timeval tv_now; + uint64_t days_since_update; + uint64_t hours_since_update; + + gettimeofday(&tv_now, NULL); + /* subtract the time when the last time was updated */ + tv_now.tv_sec -= last_updated.tv_sec; /* ignore microseconds */ + info->time_source = TIME_SOURCE_MANUAL; + info->time_accuracy = 0; + days_since_update = (tv_now.tv_sec / 86400L); + hours_since_update = (tv_now.tv_sec / 3600); + info->days_since_update = days_since_update < 255 ? days_since_update : 255; + + if(days_since_update > 254) { + info->hours_since_update = 255; + } + else { + hours_since_update = (tv_now.tv_sec % 86400L) / 3600; + info->hours_since_update = hours_since_update; + } + adjust_reason = (CHANGE_OF_DST_MASK | CHANGE_OF_TIME_ZONE_MASK); + + return 0; +} +int +gatt_svr_init(void) +{ + struct ble_svc_cts_cfg cfg; + + ble_svc_gap_init(); + ble_svc_gatt_init(); + + cfg.fetch_time_cb = fetch_current_time; + cfg.local_time_info_cb = fetch_local_time_info; + cfg.ref_time_info_cb = fetch_reference_time_info; + cfg.set_time_cb = set_current_time; + cfg.set_local_time_info_cb = set_local_time_info; + ble_svc_cts_init(cfg); + + return 0; +} diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/idf_component.yml b/examples/bluetooth/nimble/ble_cts/cts_prph/main/idf_component.yml new file mode 100644 index 00000000000..d6e735fe770 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/idf_component.yml @@ -0,0 +1,3 @@ +dependencies: + nimble_peripheral_utils: + path: ${IDF_PATH}/examples/bluetooth/nimble/common/nimble_peripheral_utils diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c new file mode 100644 index 00000000000..53bb6897bc6 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c @@ -0,0 +1,315 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +#include "freertos/FreeRTOSConfig.h" +/* BLE */ +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "ble_cts_prph.h" +#include "services/cts/ble_svc_cts.h" + +#if CONFIG_EXAMPLE_EXTENDED_ADV +static uint8_t ext_adv_pattern_1[] = { + 0x02, 0x01, 0x06, + 0x03, 0x03, 0xab, 0xcd, + 0x03, 0x03, 0x05, 0x18, + 0x12, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'c', 't', 's', '-', 'p', 'r', 'p', 'h', '-', 'e', +}; +#endif + +static const char *tag = "NimBLE_CTS_PRPH"; +static const char *device_name = "ble_cts_prph"; + +static int ble_cts_prph_gap_event(struct ble_gap_event *event, void *arg); + +static uint8_t ble_cts_prph_addr_type; + +/** + * Utility function to log an array of bytes. + */ +void +print_bytes(const uint8_t *bytes, int len) +{ + int i; + for (i = 0; i < len; i++) { + MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} + +void +print_addr(const void *addr) +{ + const uint8_t *u8p; + + u8p = addr; + MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); +} + +#if CONFIG_EXAMPLE_EXTENDED_ADV +/** + * Enables advertising with the following parameters: + * o General discoverable mode. + * o Undirected connectable mode. + */ +static void +ext_ble_cts_prph_advertise(void) +{ + struct ble_gap_ext_adv_params params; + struct os_mbuf *data; + uint8_t instance = 0; + int rc; + + /* First check if any instance is already active */ + if (ble_gap_ext_adv_active(instance)) { + return; + } + + /* use defaults for non-set params */ + memset (¶ms, 0, sizeof(params)); + + /* enable connectable advertising */ + params.connectable = 1; + + /* advertise using random addr */ + params.own_addr_type = BLE_OWN_ADDR_PUBLIC; + + params.primary_phy = BLE_HCI_LE_PHY_1M; + params.secondary_phy = BLE_HCI_LE_PHY_2M; + params.sid = 1; + + params.itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN; + params.itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MIN; + + /* configure instance 0 */ + rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, + ble_cts_prph_gap_event, NULL); + assert (rc == 0); + + /* in this case only scan response is allowed */ + + /* get mbuf for scan rsp data */ + data = os_msys_get_pkthdr(sizeof(ext_adv_pattern_1), 0); + assert(data); + + /* fill mbuf with scan rsp data */ + rc = os_mbuf_append(data, ext_adv_pattern_1, sizeof(ext_adv_pattern_1)); + assert(rc == 0); + + rc = ble_gap_ext_adv_set_data(instance, data); + assert (rc == 0); + + /* start advertising */ + rc = ble_gap_ext_adv_start(instance, 0, 0); + assert (rc == 0); +} +#else + +static void +ble_cts_prph_advertise(void) +{ + struct ble_gap_adv_params adv_params; + struct ble_hs_adv_fields fields; + int rc; + + /* + * Set the advertisement data included in our advertisements: + * o Flags (indicates advertisement type and other general info) + * o Advertising tx power + * o Device name + */ + memset(&fields, 0, sizeof(fields)); + + /* + * Advertise two flags: + * o Discoverability in forthcoming advertisement (general) + * o BLE-only (BR/EDR unsupported) + */ + fields.flags = BLE_HS_ADV_F_DISC_GEN | + BLE_HS_ADV_F_BREDR_UNSUP; + + /* + * Indicate that the TX power level field should be included; have the + * stack fill this value automatically. This is done by assigning the + * special value BLE_HS_ADV_TX_PWR_LVL_AUTO. + */ + fields.tx_pwr_lvl_is_present = 1; + fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + + fields.name = (uint8_t *)device_name; + fields.name_len = strlen(device_name); + fields.name_is_complete = 1; + + fields.uuids16 = (ble_uuid16_t[]) { + BLE_UUID16_INIT(BLE_SVC_CTS_UUID16) + }; + fields.num_uuids16 = 1; + fields.uuids16_is_complete = 1; + + rc = ble_gap_adv_set_fields(&fields); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc); + return; + } + + /* Begin advertising */ + memset(&adv_params, 0, sizeof(adv_params)); + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + rc = ble_gap_adv_start(ble_cts_prph_addr_type, NULL, BLE_HS_FOREVER, + &adv_params, ble_cts_prph_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc); + return; + } +} +#endif + +static int +ble_cts_prph_gap_event(struct ble_gap_event *event, void *arg) +{ + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed */ + MODLOG_DFLT(INFO, "connection %s; status=%d\n", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + + if (event->connect.status != 0) { + /* Connection failed; resume advertising */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + ext_ble_cts_prph_advertise(); +#else + ble_cts_prph_advertise(); +#endif + + } + break; + + case BLE_GAP_EVENT_DISCONNECT: + MODLOG_DFLT(INFO, "disconnect; reason=%d\n", event->disconnect.reason); + + /* Connection terminated; resume advertising */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + ext_ble_cts_prph_advertise(); +#else + ble_cts_prph_advertise(); +#endif + + break; + + case BLE_GAP_EVENT_ADV_COMPLETE: + MODLOG_DFLT(INFO, "adv complete\n"); +#if CONFIG_EXAMPLE_EXTENDED_ADV + ext_ble_cts_prph_advertise(); +#else + ble_cts_prph_advertise(); +#endif + break; + + case BLE_GAP_EVENT_SUBSCRIBE: + MODLOG_DFLT(INFO, "subscribe event; cur_notify=%d\n value handle; " + "val_handle=%d\n", + event->subscribe.cur_notify, event->subscribe.attr_handle); + + break; + + case BLE_GAP_EVENT_MTU: + MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.value); + break; + + } + + return 0; +} + +static void +ble_cts_prph_on_sync(void) +{ + int rc; + + rc = ble_hs_id_infer_auto(0, &ble_cts_prph_addr_type); + assert(rc == 0); + + uint8_t addr_val[6] = {0}; + rc = ble_hs_id_copy_addr(ble_cts_prph_addr_type, addr_val, NULL); + + MODLOG_DFLT(INFO, "Device Address: "); + print_addr(addr_val); + MODLOG_DFLT(INFO, "\n"); + + /* Begin advertising */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + ext_ble_cts_prph_advertise(); +#else + ble_cts_prph_advertise(); +#endif +} + +static void +ble_cts_prph_on_reset(int reason) +{ + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); +} + +void ble_cts_prph_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +void app_main(void) +{ + int rc; + + /* 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) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ret = nimble_port_init(); + if (ret != ESP_OK) { + MODLOG_DFLT(ERROR, "Failed to init nimble %d \n", ret); + return; + } + + /* Initialize the NimBLE host configuration */ + ble_hs_cfg.sync_cb = ble_cts_prph_on_sync; + ble_hs_cfg.reset_cb = ble_cts_prph_on_reset; + + /* Enable bonding */ + ble_hs_cfg.sm_bonding = 1; + ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; + ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; + + ble_hs_cfg.sm_sc = 1; + ble_hs_cfg.sm_mitm = 1; + + rc = gatt_svr_init(); + assert(rc == 0); + + /* Set the default device name */ + rc = ble_svc_gap_device_name_set(device_name); + assert(rc == 0); + + /* Start the task */ + nimble_port_freertos_init(ble_cts_prph_host_task); + +} diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/sdkconfig.defaults b/examples/bluetooth/nimble/ble_cts/cts_prph/sdkconfig.defaults new file mode 100644 index 00000000000..c829fc5c002 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/sdkconfig.defaults @@ -0,0 +1,12 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y diff --git a/examples/common_components/protocol_examples_common/CMakeLists.txt b/examples/common_components/protocol_examples_common/CMakeLists.txt index 4f9ea953cf4..a8f9b81c057 100644 --- a/examples/common_components/protocol_examples_common/CMakeLists.txt +++ b/examples/common_components/protocol_examples_common/CMakeLists.txt @@ -22,6 +22,10 @@ if(CONFIG_EXAMPLE_CONNECT_ETHERNET) list(APPEND srcs "eth_connect.c") endif() +if(CONFIG_EXAMPLE_CONNECT_PPP) + list(APPEND srcs "ppp_connect.c") +endif() + idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "include" @@ -34,3 +38,7 @@ endif() if(CONFIG_EXAMPLE_CONNECT_ETHERNET) idf_component_optional_requires(PRIVATE esp_eth) endif() + +if(CONFIG_EXAMPLE_CONNECT_PPP) + idf_component_optional_requires(PRIVATE esp_tinyusb espressif__esp_tinyusb) +endif() diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index 7eb2a8fd6f8..6329d3a4751 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -306,16 +306,80 @@ menu "Example Connection Configuration" Set PHY address according your board schematic. endif # EXAMPLE_CONNECT_ETHERNET + config EXAMPLE_CONNECT_PPP + bool "connect using Point to Point interface" + select LWIP_PPP_SUPPORT + help + Protocol examples can use PPP connection over serial line. + Choose this option to connect to the ppp server running + on your laptop over a serial line (either UART or USB ACM) + + if EXAMPLE_CONNECT_PPP + choice EXAMPLE_CONNECT_PPP_DEVICE + prompt "Choose PPP device" + default EXAMPLE_CONNECT_PPP_DEVICE_USB + help + Select which peripheral to use to connect to the PPP server. + + config EXAMPLE_CONNECT_PPP_DEVICE_USB + bool "USB" + depends on SOC_USB_OTG_SUPPORTED + select TINYUSB_CDC_ENABLED + help + Use USB ACM device. + + config EXAMPLE_CONNECT_PPP_DEVICE_UART + bool "UART" + help + Use UART. + + endchoice + + menu "UART Configuration" + depends on EXAMPLE_CONNECT_PPP_DEVICE_UART + config EXAMPLE_CONNECT_UART_TX_PIN + int "TXD Pin Number" + default 4 + range 0 31 + help + Pin number of UART TX. + + config EXAMPLE_CONNECT_UART_RX_PIN + int "RXD Pin Number" + default 5 + range 0 31 + help + Pin number of UART RX. + + config EXAMPLE_CONNECT_UART_BAUDRATE + int "UART Baudrate" + default 115200 + range 9600 3000000 + help + Baudrate of the UART device + + endmenu + + config EXAMPLE_PPP_CONN_MAX_RETRY + int "Maximum retry" + default 6 + help + Set the Maximum retry to avoid station reconnecting if the pppd + is not available + + endif # EXAMPLE_CONNECT_PPP + config EXAMPLE_CONNECT_IPV4 bool depends on LWIP_IPV4 default y config EXAMPLE_CONNECT_IPV6 - depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET + depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET || EXAMPLE_CONNECT_PPP bool "Obtain IPv6 address" default y select LWIP_IPV6 + select LWIP_PPP_ENABLE_IPV6 if EXAMPLE_CONNECT_PPP help By default, examples will wait until IPv4 and IPv6 local link addresses are obtained. Disable this option if the network does not support IPv6. diff --git a/examples/common_components/protocol_examples_common/README.md b/examples/common_components/protocol_examples_common/README.md new file mode 100644 index 00000000000..f80d6b2fa8e --- /dev/null +++ b/examples/common_components/protocol_examples_common/README.md @@ -0,0 +1,58 @@ +# protocol_example_connect + +This component implements the most common connection methods for ESP32 boards. It should be used mainly in examples of ESP-IDF to demonstrate functionality of network protocols and other libraries, that need the connection step as a prerequisite. + +## How to use this component + +Choose the preferred interface (WiFi, Ethernet, PPPoS) to connect to the network and configure the interface. + +It is possible to enable multiple interfaces simultaneously making the connection phase to block until all the chosen interfaces acquire IP addresses. +It is also possible to disable all interfaces, skipping the connection phase altogether. + +### WiFi + +Choose WiFi connection method (for chipsets that support it) and configure basic WiFi connection properties: +* WiFi SSID +* WiFI password +* Maximum connection retry (connection would be aborted if it doesn't succeed after specified number of retries) +* WiFi scan method (including RSSI and authorization mode threshold) + + + +### Ethernet + +Choose Ethernet connection if your board supports it. The most common settings is using Espressif Ethernet Kit, which is also the recommended HW for this selection. You can also select an SPI ethernet device (if your chipset doesn't support internal EMAC or if you prefer). It is also possible to use OpenCores Ethernet MAC if you're running the example under QEMU. + +### PPP + +Point to point connection method creates a simple IP tunnel to the counterpart device (running PPP server), typically a Linux machine with pppd service. We currently support only PPP over Serial (using UART or USB CDC). This is useful for simple testing of networking layers, but with some additional configuration on the server side, we could simulate standard model of internet connectivity. The PPP server could be also represented by a cellular modem device with pre-configured connectivity and already switched to PPP mode (this setup is not very flexible though, so we suggest using a standard modem library implementing commands and modes, e.g. [esp_modem](https://components.espressif.com/component/espressif/esp_modem) ). + +> [!Note] +> Note that if you choose USB device, you have to manually add a dependency on `esp_tinyusb` component. This step is necessary to keep the `protocol_example_connect` component simple and dependency free. Please run this command from your project location to add the dependency: +> ```bash +> idf.py add-dependency espressif/esp_tinyusb^1 +> ``` + +#### Setup a PPP server + +Connect the board using UART or USB and note the device name, which would be typically: +* `/dev/ttyACMx` for USB devices +* `/dev/ttyUSBx` for UART devices + +Run the pppd server: + +```bash +sudo pppd /dev/ttyACM0 115200 192.168.11.1:192.168.11.2 ms-dns 8.8.8.8 modem local noauth debug nocrtscts nodetach +ipv6 +``` + +Please update the parameters with the correct serial device, baud rate, IP addresses, DNS server, use `+ipv6` if `EXAMPLE_CONNECT_IPV6=y`. + +#### Connection to outside + +In order to access other network endpoints, we have to configure some IP/translation rules. The easiest method is to setup a masquerade of the PPPD created interface (`ppp0`) to your default networking interface (`${ETH0}`). Here is an example of such rule: + +```bash +sudo iptables -t nat -A POSTROUTING -o ${ETH0} -j MASQUERADE +sudo iptables -A FORWARD -i ${ETH0} -o ppp0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i ppp0 -o ${ETH0} -j ACCEPT +``` diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index 6abc2a3d24c..f6aa9bbee8e 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -101,6 +101,12 @@ esp_err_t example_connect(void) } ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_wifi_shutdown)); #endif +#if CONFIG_EXAMPLE_CONNECT_PPP + if (example_ppp_connect() != ESP_OK) { + return ESP_FAIL; + } + ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_ppp_shutdown)); +#endif #if CONFIG_EXAMPLE_CONNECT_ETHERNET example_print_all_netif_ips(EXAMPLE_NETIF_DESC_ETH); @@ -110,6 +116,10 @@ esp_err_t example_connect(void) example_print_all_netif_ips(EXAMPLE_NETIF_DESC_STA); #endif +#if CONFIG_EXAMPLE_CONNECT_PPP + example_print_all_netif_ips(EXAMPLE_NETIF_DESC_PPP); +#endif + return ESP_OK; } diff --git a/examples/common_components/protocol_examples_common/include/example_common_private.h b/examples/common_components/protocol_examples_common/include/example_common_private.h index b85d26d6360..8a0b880ecbd 100644 --- a/examples/common_components/protocol_examples_common/include/example_common_private.h +++ b/examples/common_components/protocol_examples_common/include/example_common_private.h @@ -45,6 +45,9 @@ void example_wifi_shutdown(void); esp_err_t example_wifi_connect(void); void example_ethernet_shutdown(void); esp_err_t example_ethernet_connect(void); +esp_err_t example_ppp_connect(void); +void example_ppp_start(void); +void example_ppp_shutdown(void); 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 430cdae7f91..fc2e54cd352 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 @@ -31,6 +31,10 @@ extern "C" { #define EXAMPLE_NETIF_DESC_ETH "example_netif_eth" #endif +#if CONFIG_EXAMPLE_CONNECT_PPP +#define EXAMPLE_NETIF_DESC_PPP "example_netif_ppp" +#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) @@ -38,6 +42,9 @@ extern "C" { #elif CONFIG_EXAMPLE_CONNECT_WIFI #define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA) #define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA) +#elif CONFIG_EXAMPLE_CONNECT_PPP +#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_PPP) +#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_PPP) #endif /** diff --git a/examples/common_components/protocol_examples_common/ppp_connect.c b/examples/common_components/protocol_examples_common/ppp_connect.c new file mode 100644 index 00000000000..090a3ed69cb --- /dev/null +++ b/examples/common_components/protocol_examples_common/ppp_connect.c @@ -0,0 +1,260 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "protocol_examples_common.h" +#include "example_common_private.h" + +#if CONFIG_EXAMPLE_CONNECT_PPP +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_netif_ppp.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB +#include "tinyusb.h" +#include "tusb_cdc_acm.h" + +static int s_itf; +static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE]; + +#else // DEVICE is UART + +#include "driver/uart.h" +#define BUF_SIZE (1024) +static bool s_stop_task = false; + +#endif // CONNECT_PPP_DEVICE + + +static const char *TAG = "example_connect_ppp"; +static int s_retry_num = 0; +static EventGroupHandle_t s_event_group = NULL; +static esp_netif_t *s_netif; +static const int GOT_IPV4 = BIT0; +static const int CONNECTION_FAILED = BIT1; +#if CONFIG_EXAMPLE_CONNECT_IPV6 +static const int GOT_IPV6 = BIT2; +#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED) +#else +#define CONNECT_BITS (GOT_IPV4|CONNECTION_FAILED) +#endif + +static esp_err_t transmit(void *h, void *buffer, size_t len) +{ + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + tinyusb_cdcacm_write_queue(s_itf, buffer, len); + tinyusb_cdcacm_write_flush(s_itf, 0); +#else // DEVICE_UART + uart_write_bytes(UART_NUM_1, buffer, len); +#endif // CONNECT_PPP_DEVICE + return ESP_OK; +} + +static esp_netif_driver_ifconfig_t driver_cfg = { + .handle = (void *)1, // singleton driver, just to != NULL + .transmit = transmit, +}; +const esp_netif_driver_ifconfig_t *ppp_driver_cfg = &driver_cfg; + +static void on_ip_event(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + + if (event_id == IP_EVENT_PPP_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_netif_t *netif = event->esp_netif; + esp_netif_dns_info_t dns_info; + ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); + esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info); + ESP_LOGI(TAG, "Main DNS server : " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); + xEventGroupSetBits(s_event_group, GOT_IPV4); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + } else if (event_id == IP_EVENT_GOT_IP6) { + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { + xEventGroupSetBits(s_event_group, GOT_IPV6); + } +#endif + } else if (event_id == IP_EVENT_PPP_LOST_IP) { + ESP_LOGI(TAG, "Disconnect from PPP Server"); + s_retry_num++; + if (s_retry_num > CONFIG_EXAMPLE_PPP_CONN_MAX_RETRY) { + ESP_LOGE(TAG, "PPP Connection failed %d times, stop reconnecting.", s_retry_num); + xEventGroupSetBits(s_event_group, CONNECTION_FAILED); + } else { + ESP_LOGI(TAG, "PPP Connection failed %d times, try to reconnect.", s_retry_num); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + } + + } +} + +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB +static void cdc_rx_callback(int itf, cdcacm_event_t *event) +{ + size_t rx_size = 0; + if (itf != s_itf) { + // Not our channel + return; + } + esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); + if (ret == ESP_OK) { + ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_VERBOSE); + // pass the received data to the network interface + esp_netif_receive(s_netif, buf, rx_size, NULL); + } else { + ESP_LOGE(TAG, "Read error"); + } +} + +static void line_state_changed(int itf, cdcacm_event_t *event) +{ + s_itf = itf; // use this channel for the netif communication + ESP_LOGI(TAG, "Line state changed on channel %d", itf); +} +#else // DEVICE is UART + +static void ppp_task(void *args) +{ + uart_config_t uart_config = {}; + uart_config.baud_rate = CONFIG_EXAMPLE_CONNECT_UART_BAUDRATE; + uart_config.data_bits = UART_DATA_8_BITS; + uart_config.parity = UART_PARITY_DISABLE; + uart_config.stop_bits = UART_STOP_BITS_1; + uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; + uart_config.source_clk = UART_SCLK_DEFAULT; + + QueueHandle_t event_queue; + ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, BUF_SIZE, 0, 16, &event_queue, 0)); + ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, CONFIG_EXAMPLE_CONNECT_UART_TX_PIN, CONFIG_EXAMPLE_CONNECT_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + ESP_ERROR_CHECK(uart_set_rx_timeout(UART_NUM_1, 1)); + + char *buffer = (char*)malloc(BUF_SIZE); + uart_event_t event; + esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected, s_netif); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + while (!s_stop_task) { + xQueueReceive(event_queue, &event, pdMS_TO_TICKS(1000)); + if (event.type == UART_DATA) { + size_t len; + uart_get_buffered_data_len(UART_NUM_1, &len); + if (len) { + len = uart_read_bytes(UART_NUM_1, buffer, BUF_SIZE, 0); + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); + esp_netif_receive(s_netif, buffer, len, NULL); + } + } else { + ESP_LOGW(TAG, "Received UART event: %d", event.type); + } + } + free(buffer); + vTaskDelete(NULL); +} + +#endif // CONNECT_PPP_DEVICE + +esp_err_t example_ppp_connect(void) +{ + ESP_LOGI(TAG, "Start example_connect."); + +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + ESP_LOGI(TAG, "USB initialization"); + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .external_phy = false, + .configuration_descriptor = NULL, + }; + + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_config_cdcacm_t acm_cfg = { + .usb_dev = TINYUSB_USBDEV_0, + .cdc_port = TINYUSB_CDC_ACM_0, + .callback_rx = &cdc_rx_callback, + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = NULL, + .callback_line_coding_changed = NULL + }; + + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + /* the second way to register a callback */ + ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( + TINYUSB_CDC_ACM_0, + CDC_EVENT_LINE_STATE_CHANGED, + &line_state_changed)); +#endif // CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + + s_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); + + esp_netif_inherent_config_t base_netif_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); + base_netif_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP; + esp_netif_config_t netif_ppp_config = { .base = &base_netif_cfg, + .driver = ppp_driver_cfg, + .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP + }; + + s_netif = esp_netif_new(&netif_ppp_config); + assert(s_netif); +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); +#else // DEVICE is UART + s_stop_task = false; + if (xTaskCreate(ppp_task, "ppp connect", 4096, NULL, 5, NULL) != pdTRUE) { + ESP_LOGE(TAG, "Failed to create a ppp connection task"); + return ESP_FAIL; + } +#endif // CONNECT_PPP_DEVICE + + ESP_LOGI(TAG, "Waiting for IP address"); + EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY); + if (bits & CONNECTION_FAILED) { + ESP_LOGE(TAG, "Connection failed!"); + return ESP_FAIL; + } + ESP_LOGI(TAG, "Connected!"); + + return ESP_OK; +} + +void example_ppp_shutdown(void) +{ + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event)); +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_UART + s_stop_task = true; + vTaskDelay(pdMS_TO_TICKS(1000)); // wait for the ppp task to stop +#endif + + esp_netif_action_disconnected(s_netif, 0, 0, 0); + + vEventGroupDelete(s_event_group); + esp_netif_action_stop(s_netif, 0, 0, 0); + esp_netif_destroy(s_netif); + s_netif = NULL; + s_event_group = NULL; +} + +#endif // CONFIG_EXAMPLE_CONNECT_PPP diff --git a/examples/ethernet/.build-test-rules.yml b/examples/ethernet/.build-test-rules.yml index af1670d1c63..c0e129ef801 100644 --- a/examples/ethernet/.build-test-rules.yml +++ b/examples/ethernet/.build-test-rules.yml @@ -8,8 +8,8 @@ examples/ethernet/basic: - esp_netif - lwip - esp_event + - esp_driver_gpio depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* examples/ethernet/enc28j60: @@ -22,8 +22,8 @@ examples/ethernet/enc28j60: - esp_netif - lwip - esp_event + - esp_driver_gpio depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* examples/ethernet/iperf: @@ -37,8 +37,8 @@ examples/ethernet/iperf: - lwip - esp_event - console + - esp_driver_gpio depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* - examples/common_components/iperf/**/* - examples/common_components/protocol_examples_common/**/* diff --git a/examples/get-started/.build-test-rules.yml b/examples/get-started/.build-test-rules.yml index 0e70fd65b4b..0d1df0e98bd 100644 --- a/examples/get-started/.build-test-rules.yml +++ b/examples/get-started/.build-test-rules.yml @@ -8,4 +8,4 @@ examples/get-started/blink: examples/get-started/hello_world: enable: - - if: INCLUDE_DEFAULT == 1 + - if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "linux" diff --git a/examples/get-started/hello_world/README.md b/examples/get-started/hello_world/README.md index 8bbda44cc6d..29171c316c8 100644 --- a/examples/get-started/hello_world/README.md +++ b/examples/get-started/hello_world/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-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | Linux | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ----- | # Hello World Example diff --git a/examples/get-started/hello_world/pytest_hello_world.py b/examples/get-started/hello_world/pytest_hello_world.py index e7380003dcb..caeeff16b79 100644 --- a/examples/get-started/hello_world/pytest_hello_world.py +++ b/examples/get-started/hello_world/pytest_hello_world.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import hashlib @@ -21,6 +21,12 @@ def test_hello_world( log_minimum_free_heap_size() +@pytest.mark.linux +@pytest.mark.host_test +def test_hello_world_linux(dut: IdfDut) -> None: + dut.expect('Hello world!') + + def verify_elf_sha256_embedding(app: QemuApp, sha256_reported: str) -> None: sha256 = hashlib.sha256() with open(app.elf_file, 'rb') as f: diff --git a/examples/openthread/ot_sleepy_device/CMakeLists.txt b/examples/openthread/ot_sleepy_device/deep_sleep/CMakeLists.txt similarity index 100% rename from examples/openthread/ot_sleepy_device/CMakeLists.txt rename to examples/openthread/ot_sleepy_device/deep_sleep/CMakeLists.txt diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/README.md b/examples/openthread/ot_sleepy_device/deep_sleep/README.md new file mode 100644 index 00000000000..5ee3f7d9b2d --- /dev/null +++ b/examples/openthread/ot_sleepy_device/deep_sleep/README.md @@ -0,0 +1,64 @@ +| Supported Targets | ESP32-H2 | +| ----------------- | -------- | + +# OpenThread Sleepy Device Example + +The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Deep Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/system/sleep_modes.html#sleep-modes) during idle state. + +This example is designed to address a specific deep sleep application scenario. First, it connects to the Thread network, and after 5 seconds when the state changes to CHILD, it enters deep sleep mode. There are two ways to wake up in this example: one is by using a 20-second periodic RTC timer, and the other is through GPIO input. Deep sleep is part of the upper-layer logic, and it's the user's responsibility to manage it in their own applications. If you need more wake-up methods, you can refer to the [Exapmle deep sleep](../../../system/deep_sleep/). Additionally, Espressif provides a stub for handling wake-ups, which allows for a quick check, and the user can decide whether to wake up or continue deep sleep in this stub, as explained in the [Example deep sleep stub](../../../system/deep_sleep_wake_stub). + +Note: Implementing a standard Thread Sleepy Device is recommended using the [Light Sleep example](../light_sleep). Deep sleep triggers a reboot, and the device needs to undergo a re-attach process to rejoin the network. This means additional packet interactions are necessary after each wake-up from deep sleep. It can be advantageous in reducing power consumption, especially when the device remains in a sleep state for extended periods, such as more than 30 minutes. +## How to use example + +### Hardware Required + +* Prepare two 802.15.4 SoC development boards, one for an OpenThread Leader and the other one for an OpenThread Sleepy End Device (SED). +* Connect the board using a USB cable for power supply and programming. + +## Configure the Openthread Dataset + +* Run [ot_cli](../../ot_cli/) on another 802.15.4 SoC device to create openthread dataset configuration and start an openthread network as the Leader. +* Configure the Openthread dataset using `idf.py menuconfig` in `Component config ---> Openthread ---> Thread Operation Dataset`, ensuring that the openthread sleepy device's dataset matches the dataset of the Leader device. + +### Build and Flash + +Build the project and flash it to the board. Use the following command: `idf.py -p erase-flash flash monitor`. + +### Example Output + +As the example runs, you will see the log output indicating the initialization and operation of OpenThread, including the device joining the OpenThread network as a Sleepy End Device (SED). + +``` +I(281) OPENTHREAD:[I] Settings------: Read NetworkInfo {rloc:0x4001, extaddr:623954c9725869e6, role:child, mode:0x04, version:4, keyseq:0x0, ... +I(291) OPENTHREAD:[I] Settings------: ... pid:0x3b33d767, mlecntr:0x3ba17, maccntr:0x3baa8, mliid:868f19ce8c3f6207} +I(301) OPENTHREAD:[I] Settings------: Read ParentInfo {extaddr:3afe8db4802dc1aa, version:4} +I (311) ot_esp_power_save: Wake up from timer. Time spent in deep sleep and boot: 20321ms +I (331) ot_esp_power_save: Enabling timer wakeup, 20s +I (331) OPENTHREAD: OpenThread attached to netif +I(341) OPENTHREAD:[N] Mle-----------: Role disabled -> detached +I (291) main_task: Returned from app_main() +I (371) OT_STATE: netif up +I(511) OPENTHREAD:[N] Mle-----------: Role detached -> child +I (531) ot_esp_power_save: Start one-shot timer for 5s to enter the deep sleep +I (5531) ot_esp_power_save: Enter deep sleep +``` + +When the device enter deep sleep, GPIO9 also can wake up the device, you can push down the BOOT button then you can see the device wakes up: + +``` +I(281) OPENTHREAD:[I] Settings------: Read NetworkInfo {rloc:0x4001, extaddr:623954c9725869e6, role:child, mode:0x04, version:4, keyseq:0x0, ... +I(291) OPENTHREAD:[I] Settings------: ... pid:0x3b33d767, mlecntr:0x3d576, maccntr:0x3d609, mliid:868f19ce8c3f6207} +I(301) OPENTHREAD:[I] Settings------: Read ParentInfo {extaddr:3afe8db4802dc1aa, version:4} +I (321) ot_esp_power_save: Wake up from GPIO. Time spent in deep sleep and boot: 8470ms +I (331) ot_esp_power_save: Enabling timer wakeup, 20s +I (331) OPENTHREAD: OpenThread attached to netif +I(341) OPENTHREAD:[N] Mle-----------: Role disabled -> detached +I (291) main_task: Returned from app_main() +I (371) OT_STATE: netif up +I(511) OPENTHREAD:[N] Mle-----------: Role detached -> child +I (531) ot_esp_power_save: Start one-shot timer for 5s to enter the deep sleep +I (5531) ot_esp_power_save: Enter deep sleep +``` + +During the deep sleep, a typical power consumption is shown below: +![H2-deep-sleep-power-consumption](image/H2-deep-sleep-power-consumption.png) \ No newline at end of file diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/image/H2-deep-sleep-power-consumption.png b/examples/openthread/ot_sleepy_device/deep_sleep/image/H2-deep-sleep-power-consumption.png new file mode 100644 index 00000000000..26df5450153 Binary files /dev/null and b/examples/openthread/ot_sleepy_device/deep_sleep/image/H2-deep-sleep-power-consumption.png differ diff --git a/examples/openthread/ot_sleepy_device/main/CMakeLists.txt b/examples/openthread/ot_sleepy_device/deep_sleep/main/CMakeLists.txt similarity index 100% rename from examples/openthread/ot_sleepy_device/main/CMakeLists.txt rename to examples/openthread/ot_sleepy_device/deep_sleep/main/CMakeLists.txt diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device.c b/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device.c new file mode 100644 index 00000000000..4c2e5924854 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device.c @@ -0,0 +1,220 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + * + * OpenThread Command Line 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 +#include +#include "esp_err.h" +#include "esp_event.h" +#include "esp_log.h" +#include "esp_sleep.h" +#include "esp_timer.h" +#include "esp_openthread.h" +#include "esp_openthread_netif_glue.h" +#include "esp_ot_sleepy_device_config.h" +#include "esp_vfs_eventfd.h" +#include "nvs_flash.h" +#include "driver/rtc_io.h" +#include "driver/uart.h" +#include "openthread/logging.h" +#include "openthread/thread.h" + +#if !SOC_IEEE802154_SUPPORTED +#error "Openthread sleepy device is only supported for the SoCs which have IEEE 802.15.4 module" +#endif + +#define TAG "ot_esp_power_save" + +static RTC_DATA_ATTR struct timeval s_sleep_enter_time; +static esp_timer_handle_t s_oneshot_timer; + +static void create_config_network(otInstance *instance) +{ + otLinkModeConfig linkMode = { 0 }; + + linkMode.mRxOnWhenIdle = false; + linkMode.mDeviceType = false; + linkMode.mNetworkData = false; + + if (otLinkSetPollPeriod(instance, CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME) != OT_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to set OpenThread pollperiod."); + abort(); + } + + if (otThreadSetLinkMode(instance, linkMode) != OT_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to set OpenThread linkmode."); + abort(); + } + ESP_ERROR_CHECK(esp_openthread_auto_start(NULL)); +} + +static esp_netif_t *init_openthread_netif(const esp_openthread_platform_config_t *config) +{ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD(); + esp_netif_t *netif = esp_netif_new(&cfg); + assert(netif != NULL); + ESP_ERROR_CHECK(esp_netif_attach(netif, esp_openthread_netif_glue_init(config))); + + return netif; +} + +static void ot_state_change_callback(otChangedFlags changed_flags, void* ctx) +{ + OT_UNUSED_VARIABLE(ctx); + static otDeviceRole s_previous_role = OT_DEVICE_ROLE_DISABLED; + otInstance* instance = esp_openthread_get_instance(); + if (!instance) { + return; + } + otDeviceRole role = otThreadGetDeviceRole(instance); + if (role == OT_DEVICE_ROLE_CHILD && s_previous_role != OT_DEVICE_ROLE_CHILD) { + // Start the one-shot timer + const int before_deep_sleep_time_sec = 5; + ESP_LOGI(TAG, "Start one-shot timer for %ds to enter the deep sleep", before_deep_sleep_time_sec); + ESP_ERROR_CHECK(esp_timer_start_once(s_oneshot_timer, before_deep_sleep_time_sec * 1000000)); + } + s_previous_role = role; +} + +static void s_oneshot_timer_callback(void* arg) +{ + // Enter deep sleep + ESP_LOGI(TAG, "Enter deep sleep"); + gettimeofday(&s_sleep_enter_time, NULL); + esp_deep_sleep_start(); +} + +static void ot_deep_sleep_init(void) +{ + // Within this function, we print the reason for the wake-up and configure the method of waking up from deep sleep. + // This example provides support for two wake-up sources from deep sleep: RTC timer and GPIO. + + // The one-shot timer will start when the device transitions to the CHILD state for the first time. + // After a 5-second delay, the device will enter deep sleep. + + const esp_timer_create_args_t s_oneshot_timer_args = { + .callback = &s_oneshot_timer_callback, + .name = "one-shot" + }; + + ESP_ERROR_CHECK(esp_timer_create(&s_oneshot_timer_args, &s_oneshot_timer)); + + // Print the wake-up reason: + struct timeval now; + gettimeofday(&now, NULL); + int sleep_time_ms = (now.tv_sec - s_sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - s_sleep_enter_time.tv_usec) / 1000; + esp_sleep_wakeup_cause_t wake_up_cause = esp_sleep_get_wakeup_cause(); + switch (wake_up_cause) { + case ESP_SLEEP_WAKEUP_TIMER: { + ESP_LOGI(TAG, "Wake up from timer. Time spent in deep sleep and boot: %dms", sleep_time_ms); + break; + } + case ESP_SLEEP_WAKEUP_EXT1: { + ESP_LOGI(TAG, "Wake up from GPIO. Time spent in deep sleep and boot: %dms", sleep_time_ms); + break; + } + case ESP_SLEEP_WAKEUP_UNDEFINED: + default: + ESP_LOGI(TAG, "Not a deep sleep reset"); + break; + } + + // Set the methods of how to wake up: + // 1. RTC timer waking-up + const int wakeup_time_sec = 20; + ESP_LOGI(TAG, "Enabling timer wakeup, %ds\n", wakeup_time_sec); + ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000)); + + // 2. GPIO waking-up +#if CONFIG_IDF_TARGET_ESP32C6 + // For ESP32C6 boards, RTCIO only supports GPIO0~GPIO7 + // GPIO7 pull down to wake up + const int gpio_wakeup_pin = 7; +#elif CONFIG_IDF_TARGET_ESP32H2 + // You can wake up by pulling down GPIO9. On ESP32H2 development boards, the BOOT button is connected to GPIO9. + // You can use the BOOT button to wake up the boards directly. + const int gpio_wakeup_pin = 9; +#endif + const uint64_t gpio_wakeup_pin_mask = 1ULL << gpio_wakeup_pin; + // The configuration mode depends on your hardware design. + // Since the BOOT button is connected to a pull-up resistor, the wake-up mode is configured as LOW. + const uint64_t ext_wakeup_mode = 0 << gpio_wakeup_pin; + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_with_level_mask(gpio_wakeup_pin_mask, ext_wakeup_mode)); + + // Also these two GPIO configurations are also depended on the hardware design. + // The BOOT button is connected to the pull-up resistor, so enable the pull-up mode and disable the pull-down mode. + + // Notice: if these GPIO configurations do not match the hardware design, the deep sleep module will enable the GPIO hold + // feature to hold the GPIO voltage when enter the sleep, which will ensure the board be waked up by GPIO. But it will cause + // 3~4 times power consumption increasing during sleep. + ESP_ERROR_CHECK(gpio_pullup_en(gpio_wakeup_pin)); + ESP_ERROR_CHECK(gpio_pulldown_dis(gpio_wakeup_pin)); +} + + +static void ot_task_worker(void *aContext) +{ + esp_openthread_platform_config_t config = { + .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), + .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), + .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), + }; + + // Initialize the OpenThread stack + ESP_ERROR_CHECK(esp_openthread_init(&config)); + + ot_deep_sleep_init(); + +#if CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC + // The OpenThread log level directly matches ESP log level + (void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL); +#endif + esp_netif_t *openthread_netif; + // Initialize the esp_netif bindings + openthread_netif = init_openthread_netif(&config); + esp_netif_set_default_netif(openthread_netif); + otSetStateChangedCallback(esp_openthread_get_instance(), ot_state_change_callback, NULL); + + create_config_network(esp_openthread_get_instance()); + + // Run the main loop + esp_openthread_launch_mainloop(); + + // Clean up + esp_netif_destroy(openthread_netif); + esp_openthread_netif_glue_deinit(); + + esp_vfs_eventfd_unregister(); + vTaskDelete(NULL); +} + + +void app_main(void) +{ + // Used eventfds: + // * netif + // * ot task queue + // * radio driver + esp_vfs_eventfd_config_t eventfd_config = { + .max_fds = 3, + }; + + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config)); + + xTaskCreate(ot_task_worker, "ot_power_save_main", 4096, NULL, 5, NULL); +} diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device_config.h b/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device_config.h new file mode 100644 index 00000000000..145bb245ccc --- /dev/null +++ b/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device_config.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + * + * OpenThread Command Line 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. + */ + +#pragma once + +#include "esp_openthread_types.h" + +# define CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME 30000 + +#if SOC_IEEE802154_SUPPORTED +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_NATIVE, \ + } +#endif + +#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \ + { \ + .host_connection_mode = HOST_CONNECTION_MODE_CLI_UART, \ + .host_uart_config = { \ + .port = 0, \ + .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, \ + .rx_flow_ctrl_thresh = 0, \ + .source_clk = UART_SCLK_DEFAULT, \ + }, \ + .rx_pin = UART_PIN_NO_CHANGE, \ + .tx_pin = UART_PIN_NO_CHANGE, \ + }, \ + } + +#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ + { \ + .storage_partition_name = "nvs", \ + .netif_queue_size = 10, \ + .task_queue_size = 10, \ + } diff --git a/examples/openthread/ot_sleepy_device/partitions.csv b/examples/openthread/ot_sleepy_device/deep_sleep/partitions.csv similarity index 100% rename from examples/openthread/ot_sleepy_device/partitions.csv rename to examples/openthread/ot_sleepy_device/deep_sleep/partitions.csv diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/sdkconfig.defaults b/examples/openthread/ot_sleepy_device/deep_sleep/sdkconfig.defaults new file mode 100644 index 00000000000..00774aa81de --- /dev/null +++ b/examples/openthread/ot_sleepy_device/deep_sleep/sdkconfig.defaults @@ -0,0 +1,54 @@ +# +# Partition Table +# +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +# end of Partition Table + +# +# mbedTLS +# +# TODO: Re-enable HW acceleration when HW AES support pm_lock (IDF-7704) +CONFIG_MBEDTLS_HARDWARE_AES=n +CONFIG_MBEDTLS_HARDWARE_MPI=n +CONFIG_MBEDTLS_HARDWARE_SHA=n +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y +CONFIG_MBEDTLS_ECJPAKE_C=y +# end of mbedTLS + +# +# OpenThread +# +CONFIG_OPENTHREAD_ENABLED=y +CONFIG_OPENTHREAD_BORDER_ROUTER=n +CONFIG_OPENTHREAD_DNS64_CLIENT=y +# end of OpenThread + +# +# lwIP +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096 +CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 +CONFIG_LWIP_IPV4=n +CONFIG_LWIP_ND6=n +# end of lwIP + +# +# IEEE 802.15.4 +# +CONFIG_IEEE802154_ENABLED=y +# end of IEEE 802.15.4 + +# +# deep sleep +# +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=80 +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_RESERVE_MEM=512 +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_RTC_CLK_SRC_INT_RC=y +CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y diff --git a/examples/openthread/ot_sleepy_device/light_sleep/CMakeLists.txt b/examples/openthread/ot_sleepy_device/light_sleep/CMakeLists.txt new file mode 100644 index 00000000000..876f5798c56 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/light_sleep/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(ot_sleepy_device) diff --git a/examples/openthread/ot_sleepy_device/README.md b/examples/openthread/ot_sleepy_device/light_sleep/README.md similarity index 89% rename from examples/openthread/ot_sleepy_device/README.md rename to examples/openthread/ot_sleepy_device/light_sleep/README.md index 5c832db28de..ebcf8eae273 100644 --- a/examples/openthread/ot_sleepy_device/README.md +++ b/examples/openthread/ot_sleepy_device/light_sleep/README.md @@ -3,7 +3,7 @@ # OpenThread Sleepy Device Example -The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Light Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/system/sleep_modes.html#sleep-modes) during idle state. +The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Light Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32h2/api-reference/system/sleep_modes.html#sleep-modes) during idle state. ## How to use example ### Hardware Required @@ -14,7 +14,7 @@ The example demonstrates the Thread Sleepy End Device (SED), the device will ent ## Configure the Openthread Dataset -* Run [ot_cli](../ot_cli/) on another 802.15.4 SoC device to create openthread dataset configuration and start an openthread network as the leader. +* Run [ot_cli](../../ot_cli/) on another 802.15.4 SoC device to create openthread dataset configuration and start an openthread network as the leader. * Configure the Openthread dataset using `idf.py menuconfig` in `Component config ---> Openthread ---> Thread Operation Dataset`, ensuring that the openthread sleepy device's dataset matches the dataset of the leader. ### Build and Flash diff --git a/examples/openthread/ot_sleepy_device/light_sleep/main/CMakeLists.txt b/examples/openthread/ot_sleepy_device/light_sleep/main/CMakeLists.txt new file mode 100644 index 00000000000..a7cde9d16a0 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/light_sleep/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "esp_ot_sleepy_device.c" + INCLUDE_DIRS ".") diff --git a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c b/examples/openthread/ot_sleepy_device/light_sleep/main/esp_ot_sleepy_device.c similarity index 100% rename from examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c rename to examples/openthread/ot_sleepy_device/light_sleep/main/esp_ot_sleepy_device.c diff --git a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h b/examples/openthread/ot_sleepy_device/light_sleep/main/esp_ot_sleepy_device_config.h similarity index 100% rename from examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h rename to examples/openthread/ot_sleepy_device/light_sleep/main/esp_ot_sleepy_device_config.h diff --git a/examples/openthread/ot_sleepy_device/light_sleep/partitions.csv b/examples/openthread/ot_sleepy_device/light_sleep/partitions.csv new file mode 100644 index 00000000000..6c0e048dba5 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/light_sleep/partitions.csv @@ -0,0 +1,5 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 0x120000, diff --git a/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_c6 b/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_c6 new file mode 100644 index 00000000000..80eea908010 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_c6 @@ -0,0 +1,6 @@ +CONFIG_IDF_TARGET="esp32c6" +CONFIG_IDF_TARGET_ESP32C6=y +CONFIG_OPENTHREAD_NETWORK_CHANNEL=12 +CONFIG_OPENTHREAD_NETWORK_MASTERKEY="aabbccddeeff00112233445566778899" +CONFIG_ESP_SLEEP_DEBUG=y +CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y diff --git a/examples/openthread/ot_sleepy_device/sdkconfig.ci.sleepy_h2 b/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_h2 similarity index 100% rename from examples/openthread/ot_sleepy_device/sdkconfig.ci.sleepy_h2 rename to examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_h2 diff --git a/examples/openthread/ot_sleepy_device/sdkconfig.defaults b/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.defaults similarity index 100% rename from examples/openthread/ot_sleepy_device/sdkconfig.defaults rename to examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.defaults diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 5141971ac67..bba8410d58f 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -27,6 +27,10 @@ examples/peripherals/dac: disable: - if: SOC_DAC_SUPPORTED != 1 +examples/peripherals/gpio: + depends_components: + - esp_driver_gpio + examples/peripherals/gpio/matrix_keyboard: enable: - if: IDF_TARGET == "esp32s2" @@ -193,6 +197,8 @@ examples/peripherals/parlio/simple_rgb_led_matrix: examples/peripherals/pcnt: disable: - if: SOC_PCNT_SUPPORTED != 1 + depends_components: + - esp_driver_pcnt examples/peripherals/rmt: disable: @@ -258,9 +264,6 @@ examples/peripherals/spi_master/lcd: examples/peripherals/spi_slave: disable: - if: SOC_GPSPI_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-7503 slave support examples/peripherals/spi_slave_hd/append_mode/master: disable: @@ -296,13 +299,23 @@ examples/peripherals/temperature_sensor/temp_sensor_monitor: disable: - if: SOC_TEMPERATURE_SENSOR_INTR_SUPPORT != 1 -examples/peripherals/timer_group: +examples/peripherals/timer_group/gptimer: disable: - if: SOC_GPTIMER_SUPPORTED != 1 + depends_components: + - esp_driver_gptimer examples/peripherals/timer_group/gptimer_capture_hc_sr04: disable: - if: SOC_TIMER_SUPPORT_ETM != 1 + depends_components: + - esp_driver_gptimer + +examples/peripherals/timer_group/legacy_driver: + disable: + - if: SOC_GPTIMER_SUPPORTED != 1 + depends_components: + - driver # legacy driver is still located in the "driver" component examples/peripherals/touch_sensor: disable: diff --git a/examples/peripherals/adc/oneshot_read/main/oneshot_read_main.c b/examples/peripherals/adc/oneshot_read/main/oneshot_read_main.c index 1183d0fddf7..3e17294b506 100644 --- a/examples/peripherals/adc/oneshot_read/main/oneshot_read_main.c +++ b/examples/peripherals/adc/oneshot_read/main/oneshot_read_main.c @@ -45,7 +45,7 @@ const static char *TAG = "EXAMPLE"; #endif #endif //#if EXAMPLE_USE_ADC2 -#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_11 +#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_12 static int adc_raw[2][10]; static int voltage[2][10]; diff --git a/examples/peripherals/dac/dac_continuous/signal_generator/main/dac_continuous_example_main.c b/examples/peripherals/dac/dac_continuous/signal_generator/main/dac_continuous_example_main.c index a20c65e9391..cf158d48b0e 100644 --- a/examples/peripherals/dac/dac_continuous/signal_generator/main/dac_continuous_example_main.c +++ b/examples/peripherals/dac/dac_continuous/signal_generator/main/dac_continuous_example_main.c @@ -38,7 +38,7 @@ #endif #define EXAMPLE_DAC_CHAN0_IO DAC_CHAN0_GPIO_NUM // DAC channel 0 io number #define EXAMPLE_DAC_CHAN1_IO DAC_CHAN1_GPIO_NUM // DAC channel 1 io number -#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_11 +#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_12 _Static_assert(EXAMPLE_DAC_AMPLITUDE < 256, "The DAC accuracy is 8 bit-width, doesn't support the amplitude beyond 255"); diff --git a/examples/peripherals/dac/dac_cosine_wave/main/dac_cosine_example_main.c b/examples/peripherals/dac/dac_cosine_wave/main/dac_cosine_example_main.c index 56167944655..72178238826 100644 --- a/examples/peripherals/dac/dac_cosine_wave/main/dac_cosine_example_main.c +++ b/examples/peripherals/dac/dac_cosine_wave/main/dac_cosine_example_main.c @@ -19,7 +19,7 @@ #define EXAMPLE_DAC_CHAN1_ADC_CHAN ADC_CHANNEL_7 // GPIO18, same as DAC channel 1 #define EXAMPLE_ADC_WIDTH ADC_WIDTH_BIT_13 #endif -#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_11 +#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_12 static void adc_monitor_task(void *args) { diff --git a/examples/peripherals/dac/dac_oneshot/main/dac_oneshot_example_main.c b/examples/peripherals/dac/dac_oneshot/main/dac_oneshot_example_main.c index 672d611fe9e..bd8861be79f 100644 --- a/examples/peripherals/dac/dac_oneshot/main/dac_oneshot_example_main.c +++ b/examples/peripherals/dac/dac_oneshot/main/dac_oneshot_example_main.c @@ -19,7 +19,7 @@ #define EXAMPLE_DAC_CHAN1_ADC_CHAN ADC_CHANNEL_7 // GPIO18, same as DAC channel 1 #define EXAMPLE_ADC_WIDTH ADC_WIDTH_BIT_13 #endif -#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_11 +#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_12 static void adc_monitor_task(void *args) { diff --git a/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c b/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c index 840c5bcd878..1561da8d9d5 100644 --- a/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c +++ b/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c @@ -29,8 +29,8 @@ static void example_ledc_init(void) // Prepare and then apply the LEDC PWM timer configuration ledc_timer_config_t ledc_timer = { .speed_mode = LEDC_MODE, - .timer_num = LEDC_TIMER, .duty_resolution = LEDC_DUTY_RES, + .timer_num = LEDC_TIMER, .freq_hz = LEDC_FREQUENCY, // Set output frequency at 4 kHz .clk_cfg = LEDC_AUTO_CLK }; diff --git a/examples/peripherals/sdio/host/README.md b/examples/peripherals/sdio/host/README.md index 1796fd93b4f..213ba44961d 100644 --- a/examples/peripherals/sdio/host/README.md +++ b/examples/peripherals/sdio/host/README.md @@ -1,4 +1,20 @@ | Supported Targets | ESP32 | ESP32-S3 | | ----------------- | ----- | -------- | + +## Troubleshooting + +### Getting the following error + +> `E (2562) sdmmc_io: sdmmc_io_read_byte: sdmmc_io_rw_direct (read 0x2) returned 0x107` + +Kindly activate the debug log from `idf.py menuconfig -> Component config -> Log output -> Default log verbosity` option and verify the card's IO type status. If the card does not possess IO capabilities, it will encounter issues while attempting to read IO buffers. + +To identify the card type, please inspect the following lines in the debug log. + +``` +D (659) sdmmc_io: sdmmc_init_io: io_send_op_cond (1) returned 0x106; not IO card +D (729) sdmmc_init: sdmmc_card_init: card type is SD +``` + See README.md in the parent folder diff --git a/examples/peripherals/spi_master/hd_eeprom/components/eeprom/linker.lf b/examples/peripherals/spi_master/hd_eeprom/components/eeprom/linker.lf index b0d89b8d770..e9b6befe51e 100644 --- a/examples/peripherals/spi_master/hd_eeprom/components/eeprom/linker.lf +++ b/examples/peripherals/spi_master/hd_eeprom/components/eeprom/linker.lf @@ -5,20 +5,23 @@ [mapping:eeprom] archive: libeeprom.a entries: - * (noflash) + if EXAMPLE_USE_SPI1_PINS = y: + * (noflash) [mapping:ext_driver] -archive: libdriver.a +archive: libesp_driver_gpio.a entries: - # gpio_set_level, gpio_get_level, gpio_context, _gpio_hal, etc... - gpio (noflash) + if EXAMPLE_USE_SPI1_PINS = y: + gpio: gpio_intr_enable (noflash) [mapping:ext_soc] archive: libhal.a entries: - gpio_hal (noflash) + if EXAMPLE_USE_SPI1_PINS = y: + gpio_hal: gpio_hal_intr_enable_on_core (noflash) [mapping:ext_newlib] archive: libnewlib.a entries: - time:usleep (noflash) + if EXAMPLE_USE_SPI1_PINS = y: + time:usleep (noflash) diff --git a/examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.c b/examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.c index 4d014823971..4e57ba6e648 100644 --- a/examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.c +++ b/examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.c @@ -51,16 +51,6 @@ typedef struct eeprom_context_t eeprom_context_t; static const char TAG[] = "eeprom"; -// Workaround: The driver depends on some data in the flash and cannot be placed to DRAM easily for -// now. Using the version in LL instead. -#define gpio_set_level gpio_set_level_patch -#include "hal/gpio_ll.h" -static inline esp_err_t gpio_set_level_patch(gpio_num_t gpio_num, uint32_t level) -{ - gpio_ll_set_level(&GPIO, gpio_num, level); - return ESP_OK; -} - static esp_err_t eeprom_simple_cmd(eeprom_context_t *ctx, uint16_t cmd) { spi_transaction_t t = { diff --git a/examples/peripherals/spi_master/hd_eeprom/main/Kconfig.projbuild b/examples/peripherals/spi_master/hd_eeprom/main/Kconfig.projbuild index e48344e2fc1..4bee4e13813 100644 --- a/examples/peripherals/spi_master/hd_eeprom/main/Kconfig.projbuild +++ b/examples/peripherals/spi_master/hd_eeprom/main/Kconfig.projbuild @@ -4,9 +4,12 @@ menu "Example Configuration" bool "The example uses SPI1 shared pins for EEPROM connection" default n depends on SPI_FLASH_SHARE_SPI1_BUS + select GPIO_CTRL_FUNC_IN_IRAM + select COMPILER_OPTIMIZATION_CHECKS_SILENT # silent the error check, as the error string are stored in rodata help Enable this option will make the EEPROM use SPI1 pins, which is shared with the main - flash chip. + flash chip. Therefore, when doing transaction on SPI1 bus, data cannot be fetched + from the flash, so all the data used during this time should be put into the internal RAM. Currently this example hasn't supported SPI1 pins on other chips yet. diff --git a/examples/peripherals/spi_slave/README.md b/examples/peripherals/spi_slave/README.md index c094825d329..dd8d85b8059 100644 --- a/examples/peripherals/spi_slave/README.md +++ b/examples/peripherals/spi_slave/README.md @@ -1,22 +1,23 @@ -| 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ## SPI slave example These two projects illustrate the SPI Slave driver. They're supposed to be flashed into two separate Espressif chips connected to eachother using the SPI pins defined in app_main.c. Once connected and flashed, they will use the spi master and spi slave driver to communicate with eachother. The example also includes a handshaking line to allow the master to only poll the slave when it is actually ready to parse a transaction. +### Connection For different chip and host used, the connections may be different. Here show a example diagram of hardware connection, you can freely change the GPIO settings by editing defines in the top of `main/app_main.c` in the master/slave source code. and change the hardware relatively. The default GPIOs used in the example are the following: -| Signal | ESP32 | -|-----------|--------| -| Handshake | GPIO2 | -| MOSI | GPIO12 | -| MISO | GPIO13 | -| SCLK | GPIO15 | -| CS | GPIO14 | - + + + + + + + +
Signal Handshake MOSI MISO SCLK CS
Pin GPIO2 GPIO12 GPIO13 GPIO15 GPIO14
Please run wires between the following GPIOs between the slave and master to make the example function: diff --git a/examples/peripherals/spi_slave/receiver/main/app_main.c b/examples/peripherals/spi_slave/receiver/main/app_main.c index 1dde1494478..8032f2b8307 100644 --- a/examples/peripherals/spi_slave/receiver/main/app_main.c +++ b/examples/peripherals/spi_slave/receiver/main/app_main.c @@ -30,54 +30,21 @@ ready to send/receive data, this code uses a callback to set the handshake pin h sending a transaction. As soon as the transaction is done, the line gets set low again. */ -/* -Pins in use. The SPI Master can use the GPIO mux, so feel free to change these if needed. -*/ -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 -#define GPIO_HANDSHAKE 2 -#define GPIO_MOSI 12 -#define GPIO_MISO 13 -#define GPIO_SCLK 15 -#define GPIO_CS 14 - -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 -#define GPIO_HANDSHAKE 3 -#define GPIO_MOSI 7 -#define GPIO_MISO 2 -#define GPIO_SCLK 6 -#define GPIO_CS 10 - -#elif CONFIG_IDF_TARGET_ESP32C6 -#define GPIO_HANDSHAKE 15 -#define GPIO_MOSI 19 -#define GPIO_MISO 20 -#define GPIO_SCLK 18 -#define GPIO_CS 9 - -#elif CONFIG_IDF_TARGET_ESP32H2 -#define GPIO_HANDSHAKE 2 -#define GPIO_MOSI 5 -#define GPIO_MISO 0 -#define GPIO_SCLK 4 -#define GPIO_CS 1 - -#elif CONFIG_IDF_TARGET_ESP32S3 -#define GPIO_HANDSHAKE 2 -#define GPIO_MOSI 11 -#define GPIO_MISO 13 -#define GPIO_SCLK 12 -#define GPIO_CS 10 - -#endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 - +////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////// Please update the following configuration according to your HardWare spec ///////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef CONFIG_IDF_TARGET_ESP32 #define RCV_HOST HSPI_HOST - #else #define RCV_HOST SPI2_HOST - #endif +#define GPIO_HANDSHAKE 2 +#define GPIO_MOSI 12 +#define GPIO_MISO 13 +#define GPIO_SCLK 15 +#define GPIO_CS 14 + //Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high. void my_post_setup_cb(spi_slave_transaction_t *trans) { @@ -119,7 +86,7 @@ void app_main(void) gpio_config_t io_conf = { .intr_type = GPIO_INTR_DISABLE, .mode = GPIO_MODE_OUTPUT, - .pin_bit_mask = (1 << GPIO_HANDSHAKE) + .pin_bit_mask = BIT64(GPIO_HANDSHAKE), }; //Configure handshake line as output diff --git a/examples/peripherals/spi_slave/sender/main/app_main.c b/examples/peripherals/spi_slave/sender/main/app_main.c index fc8421109da..1154e3ba0ce 100644 --- a/examples/peripherals/spi_slave/sender/main/app_main.c +++ b/examples/peripherals/spi_slave/sender/main/app_main.c @@ -105,7 +105,7 @@ void app_main(void) .intr_type = GPIO_INTR_POSEDGE, .mode = GPIO_MODE_INPUT, .pull_up_en = 1, - .pin_bit_mask = (1 << GPIO_HANDSHAKE) + .pin_bit_mask = BIT64(GPIO_HANDSHAKE), }; int n = 0; diff --git a/examples/peripherals/twai/twai_alert_and_recovery/README.md b/examples/peripherals/twai/twai_alert_and_recovery/README.md index 0c8b1c9a963..860c76d4949 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/README.md +++ b/examples/peripherals/twai/twai_alert_and_recovery/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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # TWAI Alert and Recovery Example diff --git a/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c b/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c index fa740a8ce02..ac138733cf3 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c +++ b/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -26,7 +26,7 @@ #include "driver/twai.h" #include "esp_rom_gpio.h" #include "esp_rom_sys.h" -#include "soc/gpio_sig_map.h" // For GPIO matrix signal index +#include "soc/twai_periph.h" // For GPIO matrix signal index /* --------------------- Definitions and static variables ------------------ */ //Example Configuration @@ -38,12 +38,6 @@ #define ERR_PERIOD_US 80 //Approximate time for two bits at 25KBPS #define EXAMPLE_TAG "TWAI Alert and Recovery" -#if CONFIG_IDF_TARGET_ESP32C6 -#define TWAI_TX_SIGNAL_IDX TWAI0_TX_IDX -#else -#define TWAI_TX_SIGNAL_IDX TWAI_TX_IDX -#endif - static const twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_25KBITS(); static const twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TX_GPIO_NUM, RX_GPIO_NUM, TWAI_MODE_NO_ACK); @@ -54,15 +48,15 @@ static SemaphoreHandle_t ctrl_task_sem; static bool trigger_tx_error = false; /* --------------------------- Tasks and Functions -------------------------- */ - +extern const twai_controller_signal_conn_t twai_controller_periph_signals; static void invert_tx_bits(bool enable) { if (enable) { //Inverts output of TX to trigger errors - esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, TWAI_TX_SIGNAL_IDX, true, false); + esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, twai_controller_periph_signals.controllers[0].tx_sig, true, false); } else { //Returns TX to default settings - esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, TWAI_TX_SIGNAL_IDX, false, false); + esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, twai_controller_periph_signals.controllers[0].tx_sig, false, false); } } diff --git a/examples/peripherals/twai/twai_network/README.md b/examples/peripherals/twai/twai_network/README.md index dd0fd36ccf7..a10d4ca76ff 100644 --- a/examples/peripherals/twai/twai_network/README.md +++ b/examples/peripherals/twai/twai_network/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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # TWAI Network Example diff --git a/examples/peripherals/twai/twai_self_test/README.md b/examples/peripherals/twai/twai_self_test/README.md index 38902161ddd..ae75e832317 100644 --- a/examples/peripherals/twai/twai_self_test/README.md +++ b/examples/peripherals/twai/twai_self_test/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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # TWAI Self Test Example diff --git a/examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c b/examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c index 94c18378abf..cf67cc86f33 100644 --- a/examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c +++ b/examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c @@ -72,6 +72,6 @@ static void rx_task(void *arg) void app_main(void) { init(); - xTaskCreate(rx_task, "uart_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES, NULL); - xTaskCreate(tx_task, "uart_tx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(rx_task, "uart_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(tx_task, "uart_tx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 2, NULL); } diff --git a/examples/peripherals/usb/device/tusb_msc/main/idf_component.yml b/examples/peripherals/usb/device/tusb_msc/main/idf_component.yml index 06b047d6a2d..1659a1ebe3e 100644 --- a/examples/peripherals/usb/device/tusb_msc/main/idf_component.yml +++ b/examples/peripherals/usb/device/tusb_msc/main/idf_component.yml @@ -1,4 +1,4 @@ ## IDF Component Manager Manifest File dependencies: - espressif/esp_tinyusb: "^1.2" + espressif/esp_tinyusb: "^1.4.2" idf: "^5.0" diff --git a/examples/peripherals/usb/device/tusb_msc/main/tusb_msc_main.c b/examples/peripherals/usb/device/tusb_msc/main/tusb_msc_main.c index 7c157bf0371..89f3dd9ef9d 100644 --- a/examples/peripherals/usb/device/tusb_msc/main/tusb_msc_main.c +++ b/examples/peripherals/usb/device/tusb_msc/main/tusb_msc_main.c @@ -347,7 +347,8 @@ void app_main(void) const tinyusb_msc_spiflash_config_t config_spi = { .wl_handle = wl_handle, - .callback_mount_changed = storage_mount_changed_cb /* First way to register the callback. This is while initializing the storage. */ + .callback_mount_changed = storage_mount_changed_cb, /* First way to register the callback. This is while initializing the storage. */ + .mount_config.max_files = 5, }; ESP_ERROR_CHECK(tinyusb_msc_storage_init_spiflash(&config_spi)); ESP_ERROR_CHECK(tinyusb_msc_register_callback(TINYUSB_MSC_EVENT_MOUNT_CHANGED, storage_mount_changed_cb)); /* Other way to register the callback i.e. registering using separate API. If the callback had been already registered, it will be overwritten. */ @@ -357,7 +358,8 @@ void app_main(void) const tinyusb_msc_sdmmc_config_t config_sdmmc = { .card = card, - .callback_mount_changed = storage_mount_changed_cb /* First way to register the callback. This is while initializing the storage. */ + .callback_mount_changed = storage_mount_changed_cb, /* First way to register the callback. This is while initializing the storage. */ + .mount_config.max_files = 5, }; ESP_ERROR_CHECK(tinyusb_msc_storage_init_sdmmc(&config_sdmmc)); ESP_ERROR_CHECK(tinyusb_msc_register_callback(TINYUSB_MSC_EVENT_MOUNT_CHANGED, storage_mount_changed_cb)); /* Other way to register the callback i.e. registering using separate API. If the callback had been already registered, it will be overwritten. */ diff --git a/examples/peripherals/usb/host/hid/main/hid_host_example.c b/examples/peripherals/usb/host/hid/main/hid_host_example.c index 2ed93839199..ca8783f0b25 100644 --- a/examples/peripherals/usb/host/hid/main/hid_host_example.c +++ b/examples/peripherals/usb/host/hid/main/hid_host_example.c @@ -26,19 +26,37 @@ #define APP_QUIT_PIN GPIO_NUM_0 static const char *TAG = "example"; -QueueHandle_t hid_host_event_queue; -bool user_shutdown = false; + +QueueHandle_t app_event_queue = NULL; + +/** + * @brief APP event group + * + * Application logic can be different. There is a one among other ways to distingiush the + * event by application event group. + * In this example we have two event groups: + * APP_EVENT - General event, which is APP_QUIT_PIN press event (Generally, it is IO0). + * APP_EVENT_HID_HOST - HID Host Driver event, such as device connection/disconnection or input report. + */ +typedef enum { + APP_EVENT = 0, + APP_EVENT_HID_HOST +} app_event_group_t; /** - * @brief HID Host event + * @brief APP event queue * * This event is used for delivering the HID Host event from callback to a task. */ typedef struct { - hid_host_device_handle_t hid_device_handle; - hid_host_driver_event_t event; - void *arg; -} hid_host_event_queue_t; + app_event_group_t event_group; + /* HID Host - Device related info */ + struct { + hid_host_device_handle_t handle; + hid_host_driver_event_t event; + void *arg; + } hid_host_device; +} app_event_queue_t; /** * @brief HID Protocol string names @@ -437,13 +455,6 @@ void hid_host_device_event(hid_host_device_handle_t hid_device_handle, */ static void usb_lib_task(void *arg) { - const gpio_config_t input_pin = { - .pin_bit_mask = BIT64(APP_QUIT_PIN), - .mode = GPIO_MODE_INPUT, - .pull_up_en = GPIO_PULLUP_ENABLE, - }; - ESP_ERROR_CHECK(gpio_config(&input_pin)); - const usb_host_config_t host_config = { .skip_phy_setup = false, .intr_flags = ESP_INTR_FLAG_LEVEL1, @@ -452,22 +463,17 @@ static void usb_lib_task(void *arg) ESP_ERROR_CHECK(usb_host_install(&host_config)); xTaskNotifyGive(arg); - while (gpio_get_level(APP_QUIT_PIN) != 0) { + while (true) { uint32_t event_flags; usb_host_lib_handle_events(portMAX_DELAY, &event_flags); - - // Release devices once all clients has deregistered + // In this example, there is only one client registered + // So, once we deregister the client, this call must succeed with ESP_OK if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { - usb_host_device_free_all(); - ESP_LOGI(TAG, "USB Event flags: NO_CLIENTS"); - } - // All devices were removed - if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { - ESP_LOGI(TAG, "USB Event flags: ALL_FREE"); + ESP_ERROR_CHECK(usb_host_device_free_all()); + break; } } - // App Button was pressed, trigger the flag - user_shutdown = true; + ESP_LOGI(TAG, "USB shutdown"); // Clean up USB Host vTaskDelay(10); // Short delay to allow clients clean-up @@ -476,30 +482,26 @@ static void usb_lib_task(void *arg) } /** - * @brief HID Host main task + * @brief BOOT button pressed callback * - * Creates queue and get new event from the queue + * Signal application to exit the HID Host task * - * @param[in] pvParameters Not used + * @param[in] arg Unused */ -void hid_host_task(void *pvParameters) +static void gpio_isr_cb(void *arg) { - hid_host_event_queue_t evt_queue; - // Create queue - hid_host_event_queue = xQueueCreate(10, sizeof(hid_host_event_queue_t)); - - // Wait queue - while (!user_shutdown) { - if (xQueueReceive(hid_host_event_queue, &evt_queue, pdMS_TO_TICKS(50))) { - hid_host_device_event(evt_queue.hid_device_handle, - evt_queue.event, - evt_queue.arg); - } + BaseType_t xTaskWoken = pdFALSE; + const app_event_queue_t evt_queue = { + .event_group = APP_EVENT, + }; + + if (app_event_queue) { + xQueueSendFromISR(app_event_queue, &evt_queue, &xTaskWoken); } - xQueueReset(hid_host_event_queue); - vQueueDelete(hid_host_event_queue); - vTaskDelete(NULL); + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } } /** @@ -515,19 +517,37 @@ void hid_host_device_callback(hid_host_device_handle_t hid_device_handle, const hid_host_driver_event_t event, void *arg) { - const hid_host_event_queue_t evt_queue = { - .hid_device_handle = hid_device_handle, - .event = event, - .arg = arg + const app_event_queue_t evt_queue = { + .event_group = APP_EVENT_HID_HOST, + // HID Host Device related info + .hid_host_device.handle = hid_device_handle, + .hid_host_device.event = event, + .hid_host_device.arg = arg }; - xQueueSend(hid_host_event_queue, &evt_queue, 0); + + if (app_event_queue) { + xQueueSend(app_event_queue, &evt_queue, 0); + } } void app_main(void) { BaseType_t task_created; + app_event_queue_t evt_queue; ESP_LOGI(TAG, "HID Host example"); + // Init BOOT button: Pressing the button simulates app request to exit + // It will disconnect the USB device and uninstall the HID driver and USB Host Lib + const gpio_config_t input_pin = { + .pin_bit_mask = BIT64(APP_QUIT_PIN), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&input_pin)); + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); + ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_isr_cb, NULL)); + /* * Create usb_lib_task to: * - initialize USB Host library @@ -559,14 +579,38 @@ void app_main(void) ESP_ERROR_CHECK(hid_host_install(&hid_host_driver_config)); - // Task is working until the devices are gone (while 'user_shutdown' if false) - user_shutdown = false; + // Create queue + app_event_queue = xQueueCreate(10, sizeof(app_event_queue_t)); + + ESP_LOGI(TAG, "Waiting for HID Device to be connected"); + + while (1) { + // Wait queue + if (xQueueReceive(app_event_queue, &evt_queue, portMAX_DELAY)) { + if (APP_EVENT == evt_queue.event_group) { + // User pressed button + usb_host_lib_info_t lib_info; + ESP_ERROR_CHECK(usb_host_lib_info(&lib_info)); + if (lib_info.num_devices == 0) { + // End while cycle + break; + } else { + ESP_LOGW(TAG, "To shutdown example, remove all USB devices and press button again."); + // Keep polling + } + } - /* - * Create HID Host task process for handle events - * IMPORTANT: Task is necessary here while there is no possibility to interact - * with USB device from the callback. - */ - task_created = xTaskCreate(&hid_host_task, "hid_task", 4 * 1024, NULL, 2, NULL); - assert(task_created == pdTRUE); + if (APP_EVENT_HID_HOST == evt_queue.event_group) { + hid_host_device_event(evt_queue.hid_host_device.handle, + evt_queue.hid_host_device.event, + evt_queue.hid_host_device.arg); + } + } + } + + ESP_LOGI(TAG, "HID Driver uninstall"); + ESP_ERROR_CHECK(hid_host_uninstall()); + gpio_isr_handler_remove(APP_QUIT_PIN); + xQueueReset(app_event_queue); + vQueueDelete(app_event_queue); } diff --git a/examples/peripherals/usb/host/hid/main/idf_component.yml b/examples/peripherals/usb/host/hid/main/idf_component.yml index 46a1c21a43d..0c3620e3d57 100644 --- a/examples/peripherals/usb/host/hid/main/idf_component.yml +++ b/examples/peripherals/usb/host/hid/main/idf_component.yml @@ -1,4 +1,4 @@ ## IDF Component Manager Manifest File dependencies: idf: ">=4.4" - usb_host_hid: "1.0.0" + usb_host_hid: "^1.0.1" diff --git a/examples/peripherals/usb/host/msc/README.md b/examples/peripherals/usb/host/msc/README.md index ad2f7824019..873554fa9af 100644 --- a/examples/peripherals/usb/host/msc/README.md +++ b/examples/peripherals/usb/host/msc/README.md @@ -5,15 +5,24 @@ ## Overview -This example demonstrates usage of Mass Storage Class to get access to storage on USB memory stick. -Upon connection of USB stick, storage is mounted to Virtual filesystem. Example then creates `ESP` subdirectory(if not present already), as well as `text.txt` file. Its content is then repetitively printed to monitor until USB stick is manually ejected. User can decide whether or not to deinitialize the whole -USB stack or not by shorting GPIO10 to ground. When GPIO10 is left unconnected USB stack is not deinitialized, USB stick can be plugged-in again. +This example demonstrates usage of the MSC (Mass Storage Class) to access storage on a USB flash drive. Upon connection of the flash drive, it is mounted to the Virtual filesystem. The following example operations are then performed: + +1. Print device info (capacity, sectors size, and count...) +2. List all folders and files in the root directory of the USB flash drive +3. Create `ESP` subdirectory (if not present already), as well as a `text.txt` file +4. Run read/write benchmarks by transferring 1 MB of data to a `dummy` file + + +### USB Reconnections + +The example is run in a loop so that it can demonstrate USB connection and reconnection handling. If you want to deinitialize the entire USB Host Stack, you can short GPIO0 to GND. GPIO0 is usually mapped to a BOOT button, thus pressing the button will deinitialize the stack. + ### Hardware Required * Development board with USB capable ESP SoC (ESP32-S2/ESP32-S3) * A USB cable for Power supply and programming -* A USB memory stick +* A USB flash drive ### Common Pin Assignments @@ -30,7 +39,7 @@ ESP BOARD USB CONNECTOR (type A) -- ``` -Additionally, GPIO10 can be shorted to ground in order to deinitialize USB stack after ejecting USB stick. +Additionally, GPIO0 can be shorted to ground in order to deinitialize USB stack. ### Build and Flash @@ -48,16 +57,27 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ``` ... -I (274) cpu_start: Starting scheduler on PRO CPU. -I (339) APP: Waiting for USB stick to be connected +I (380) example: Waiting for USB flash drive to be connected +I (790) example: MSC device connected +... Device info: - PID: 0x5678 - VID: 0xFFFF - iProduct: Disk 2.0 - iManufacturer: USB - iSerialNumber: 92072836B2589224378 -I (719) APP: Writing file -I (749) APP: Reading file -I (749) APP: Read from file: 'Hello World!' -I (759) APP: Done + Capacity: 29339 MB + Sector size: 512 + Sector count: 60088319 + PID: 0x5595 + VID: 0x0781 + iProduct: SanDisk 3.2Gen1 + iManufacturer: USB + iSerialNumber: 0401545df64623a907abf299bae54c9 +I (990) example: ls command output: +SYSTEM~1 +ESP +DUMMY +I (1000) example: Reading file +I (1010) example: Read from file '/usb/esp/test.txt': 'Hello World!' +I (1030) example: Writing to file /usb/esp/dummy +I (2160) example: Write speed 0.93 MiB/s +I (2160) example: Reading from file /usb/esp/dummy +I (3110) example: Read speed 1.10 MiB/s +I (3140) example: Example finished, you can disconnect the USB flash drive ``` diff --git a/examples/peripherals/usb/host/msc/main/idf_component.yml b/examples/peripherals/usb/host/msc/main/idf_component.yml index fc50aa0adfc..198a93bbf4c 100644 --- a/examples/peripherals/usb/host/msc/main/idf_component.yml +++ b/examples/peripherals/usb/host/msc/main/idf_component.yml @@ -1,4 +1,4 @@ ## IDF Component Manager Manifest File dependencies: idf: ">=4.4" - usb_host_msc: "^1.0.4" + usb_host_msc: "^1.1.1" diff --git a/examples/peripherals/usb/host/msc/main/msc_example_main.c b/examples/peripherals/usb/host/msc/main/msc_example_main.c index 1fbe55afc8a..c6be757d9c1 100644 --- a/examples/peripherals/usb/host/msc/main/msc_example_main.c +++ b/examples/peripherals/usb/host/msc/main/msc_example_main.c @@ -8,43 +8,87 @@ #include #include #include +#include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "esp_timer.h" #include "esp_err.h" #include "esp_log.h" #include "usb/usb_host.h" -#include "msc_host.h" -#include "msc_host_vfs.h" +#include "usb/msc_host.h" +#include "usb/msc_host_vfs.h" #include "ffconf.h" #include "errno.h" #include "driver/gpio.h" -#include "esp_vfs_fat.h" -#define USB_DISCONNECT_PIN GPIO_NUM_10 +static const char *TAG = "example"; +#define MNT_PATH "/usb" // Path in the Virtual File System, where the USB flash drive is going to be mounted +#define APP_QUIT_PIN GPIO_NUM_0 // BOOT button on most boards +#define BUFFER_SIZE 4096 // The read/write performance can be improved with larger buffer for the cost of RAM, 4kB is enough for most usecases -#define READY_TO_UNINSTALL (HOST_NO_CLIENT | HOST_ALL_FREE) +/** + * @brief Application Queue and its messages ID + */ +static QueueHandle_t app_queue; +typedef struct { + enum { + APP_QUIT, // Signals request to exit the application + APP_DEVICE_CONNECTED, // USB device connect event + APP_DEVICE_DISCONNECTED, // USB device disconnect event + } id; + union { + uint8_t new_dev_address; // Address of new USB device for APP_DEVICE_CONNECTED event if + } data; +} app_message_t; + +/** + * @brief BOOT button pressed callback + * + * Signal application to exit the main task + * + * @param[in] arg Unused + */ +static void gpio_cb(void *arg) +{ + BaseType_t xTaskWoken = pdFALSE; + app_message_t message = { + .id = APP_QUIT, + }; -typedef enum { - HOST_NO_CLIENT = 0x1, - HOST_ALL_FREE = 0x2, - DEVICE_CONNECTED = 0x4, - DEVICE_DISCONNECTED = 0x8, - DEVICE_ADDRESS_MASK = 0xFF0, -} app_event_t; + if (app_queue) { + xQueueSendFromISR(app_queue, &message, &xTaskWoken); + } -static const char *TAG = "example"; -static EventGroupHandle_t usb_flags; + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} +/** + * @brief MSC driver callback + * + * Signal device connection/disconnection to the main task + * + * @param[in] event MSC event + * @param[in] arg MSC event data + */ static void msc_event_cb(const msc_host_event_t *event, void *arg) { if (event->event == MSC_DEVICE_CONNECTED) { ESP_LOGI(TAG, "MSC device connected"); - // Obtained USB device address is placed after application events - xEventGroupSetBits(usb_flags, DEVICE_CONNECTED | (event->device.address << 4)); + app_message_t message = { + .id = APP_DEVICE_CONNECTED, + .data.new_dev_address = event->device.address, + }; + xQueueSend(app_queue, &message, portMAX_DELAY); } else if (event->event == MSC_DEVICE_DISCONNECTED) { - xEventGroupSetBits(usb_flags, DEVICE_DISCONNECTED); ESP_LOGI(TAG, "MSC device disconnected"); + app_message_t message = { + .id = APP_DEVICE_DISCONNECTED, + }; + xQueueSend(app_queue, &message, portMAX_DELAY); } } @@ -57,24 +101,19 @@ static void print_device_info(msc_host_device_info_t *info) printf("\t Capacity: %llu MB\n", capacity); printf("\t Sector size: %"PRIu32"\n", info->sector_size); printf("\t Sector count: %"PRIu32"\n", info->sector_count); - printf("\t PID: 0x%4X \n", info->idProduct); - printf("\t VID: 0x%4X \n", info->idVendor); + printf("\t PID: 0x%04X \n", info->idProduct); + printf("\t VID: 0x%04X \n", info->idVendor); wprintf(L"\t iProduct: %S \n", info->iProduct); wprintf(L"\t iManufacturer: %S \n", info->iManufacturer); wprintf(L"\t iSerialNumber: %S \n", info->iSerialNumber); } -static bool file_exists(const char *file_path) -{ - struct stat buffer; - return stat(file_path, &buffer) == 0; -} - static void file_operations(void) { const char *directory = "/usb/esp"; const char *file_path = "/usb/esp/test.txt"; + // Create /usb/esp directory struct stat s = {0}; bool directory_exists = stat(directory, &s) == 0; if (!directory_exists) { @@ -83,7 +122,8 @@ static void file_operations(void) } } - if (!file_exists(file_path)) { + // Create /usb/esp/test.txt file, if it doesn't exist + if (stat(file_path, &s) != 0) { ESP_LOGI(TAG, "Creating file"); FILE *f = fopen(file_path, "w"); if (f == NULL) { @@ -94,6 +134,7 @@ static void file_operations(void) fclose(f); } + // Read back the file FILE *f; ESP_LOGI(TAG, "Reading file"); f = fopen(file_path, "r"); @@ -109,69 +150,64 @@ static void file_operations(void) if (pos) { *pos = '\0'; } - ESP_LOGI(TAG, "Read from file: '%s'", line); + ESP_LOGI(TAG, "Read from file '%s': '%s'", file_path, line); } -// Handles common USB host library events -static void handle_usb_events(void *args) +void speed_test(void) { - while (1) { - uint32_t event_flags; - usb_host_lib_handle_events(portMAX_DELAY, &event_flags); +#define TEST_FILE "/usb/esp/dummy" +#define ITERATIONS 256 // 256 * 4kb = 1MB + int64_t test_start, test_end; - // Release devices once all clients has deregistered - if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { - usb_host_device_free_all(); - xEventGroupSetBits(usb_flags, HOST_NO_CLIENT); - } - // Give ready_to_uninstall_usb semaphore to indicate that USB Host library - // can be deinitialized, and terminate this task. - if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { - xEventGroupSetBits(usb_flags, HOST_ALL_FREE); - } + FILE *f = fopen(TEST_FILE, "wb+"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for writing"); + return; } + // Set larger buffer for this file. It results in larger and more effective USB transfers + setvbuf(f, NULL, _IOFBF, BUFFER_SIZE); - vTaskDelete(NULL); -} + // Allocate application buffer used for read/write + uint8_t *data = malloc(BUFFER_SIZE); + assert(data); -static uint8_t wait_for_msc_device(void) -{ - EventBits_t event; - - ESP_LOGI(TAG, "Waiting for USB stick to be connected"); - event = xEventGroupWaitBits(usb_flags, DEVICE_CONNECTED | DEVICE_ADDRESS_MASK, - pdTRUE, pdFALSE, portMAX_DELAY); - ESP_LOGI(TAG, "connection..."); - // Extract USB device address from event group bits - return (event & DEVICE_ADDRESS_MASK) >> 4; -} + ESP_LOGI(TAG, "Writing to file %s", TEST_FILE); + test_start = esp_timer_get_time(); + for (int i = 0; i < ITERATIONS; i++) { + if (fwrite(data, BUFFER_SIZE, 1, f) == 0) { + return; + } + } + test_end = esp_timer_get_time(); + ESP_LOGI(TAG, "Write speed %1.2f MiB/s", (BUFFER_SIZE * ITERATIONS) / (float)(test_end - test_start)); + rewind(f); + + ESP_LOGI(TAG, "Reading from file %s", TEST_FILE); + test_start = esp_timer_get_time(); + for (int i = 0; i < ITERATIONS; i++) { + if (0 == fread(data, BUFFER_SIZE, 1, f)) { + return; + } + } + test_end = esp_timer_get_time(); + ESP_LOGI(TAG, "Read speed %1.2f MiB/s", (BUFFER_SIZE * ITERATIONS) / (float)(test_end - test_start)); -static bool wait_for_event(EventBits_t event, TickType_t timeout) -{ - return xEventGroupWaitBits(usb_flags, event, pdTRUE, pdTRUE, timeout) & event; + fclose(f); + free(data); } -void app_main(void) +/** + * @brief USB task + * + * Install USB Host Library and MSC driver. + * Handle USB Host Library events + * + * @param[in] args Unused + */ +static void usb_task(void *args) { - msc_host_device_handle_t msc_device; - msc_host_vfs_handle_t vfs_handle; - msc_host_device_info_t info; - BaseType_t task_created; - - const gpio_config_t input_pin = { - .pin_bit_mask = BIT64(USB_DISCONNECT_PIN), - .mode = GPIO_MODE_INPUT, - .pull_up_en = GPIO_PULLUP_ENABLE, - }; - ESP_ERROR_CHECK(gpio_config(&input_pin)); - - usb_flags = xEventGroupCreate(); - assert(usb_flags); - const usb_host_config_t host_config = { .intr_flags = ESP_INTR_FLAG_LEVEL1 }; ESP_ERROR_CHECK(usb_host_install(&host_config)); - task_created = xTaskCreate(handle_usb_events, "usb_events", 2048, NULL, 2, NULL); - assert(task_created); const msc_host_driver_config_t msc_config = { .create_backround_task = true, @@ -181,37 +217,109 @@ void app_main(void) }; ESP_ERROR_CHECK(msc_host_install(&msc_config)); - const esp_vfs_fat_mount_config_t mount_config = { - .format_if_mount_failed = false, - .max_files = 3, - .allocation_unit_size = 1024, - }; + while (true) { + uint32_t event_flags; + usb_host_lib_handle_events(portMAX_DELAY, &event_flags); - do { - uint8_t device_address = wait_for_msc_device(); + // Release devices once all clients has deregistered + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + if (usb_host_device_free_all() == ESP_OK) { + break; + }; + } + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + break; + } + } - ESP_ERROR_CHECK(msc_host_install_device(device_address, &msc_device)); + vTaskDelay(10); // Give clients some time to uninstall + ESP_LOGI(TAG, "Deinitializing USB"); + ESP_ERROR_CHECK(usb_host_uninstall()); + vTaskDelete(NULL); +} - msc_host_print_descriptors(msc_device); +void app_main(void) +{ + // Create FreeRTOS primitives + app_queue = xQueueCreate(5, sizeof(app_message_t)); + assert(app_queue); - ESP_ERROR_CHECK(msc_host_get_device_info(msc_device, &info)); - print_device_info(&info); + BaseType_t task_created = xTaskCreate(usb_task, "usb_task", 4096, NULL, 2, NULL); + assert(task_created); - ESP_ERROR_CHECK(msc_host_vfs_register(msc_device, "/usb", &mount_config, &vfs_handle)); + // Init BOOT button: Pressing the button simulates app request to exit + // It will disconnect the USB device and uninstall the MSC driver and USB Host Lib + const gpio_config_t input_pin = { + .pin_bit_mask = BIT64(APP_QUIT_PIN), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&input_pin)); + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); + ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_cb, NULL)); + + ESP_LOGI(TAG, "Waiting for USB flash drive to be connected"); + msc_host_device_handle_t msc_device = NULL; + msc_host_vfs_handle_t vfs_handle = NULL; - while (!wait_for_event(DEVICE_DISCONNECTED, 200)) { + // Perform all example operations in a loop to allow USB reconnections + while (1) { + app_message_t msg; + xQueueReceive(app_queue, &msg, portMAX_DELAY); + + if (msg.id == APP_DEVICE_CONNECTED) { + // 1. MSC flash drive connected. Open it and map it to Virtual File System + ESP_ERROR_CHECK(msc_host_install_device(msg.data.new_dev_address, &msc_device)); + const esp_vfs_fat_mount_config_t mount_config = { + .format_if_mount_failed = false, + .max_files = 3, + .allocation_unit_size = 8192, + }; + ESP_ERROR_CHECK(msc_host_vfs_register(msc_device, MNT_PATH, &mount_config, &vfs_handle)); + + // 2. Print information about the connected disk + msc_host_device_info_t info; + ESP_ERROR_CHECK(msc_host_get_device_info(msc_device, &info)); + msc_host_print_descriptors(msc_device); + print_device_info(&info); + + // 3. List all the files in root directory + ESP_LOGI(TAG, "ls command output:"); + struct dirent *d; + DIR *dh = opendir(MNT_PATH); + assert(dh); + while ((d = readdir(dh)) != NULL) { + printf("%s\n", d->d_name); + } + closedir(dh); + + // 4. The disk is mounted to Virtual File System, perform some basic demo file operation file_operations(); - } - xEventGroupClearBits(usb_flags, READY_TO_UNINSTALL); - ESP_ERROR_CHECK(msc_host_vfs_unregister(vfs_handle)); - ESP_ERROR_CHECK(msc_host_uninstall_device(msc_device)); + // 5. Perform speed test + speed_test(); - } while (gpio_get_level(USB_DISCONNECT_PIN) != 0); + ESP_LOGI(TAG, "Example finished, you can disconnect the USB flash drive"); + } + if ((msg.id == APP_DEVICE_DISCONNECTED) || (msg.id == APP_QUIT)) { + if (vfs_handle) { + ESP_ERROR_CHECK(msc_host_vfs_unregister(vfs_handle)); + vfs_handle = NULL; + } + if (msc_device) { + ESP_ERROR_CHECK(msc_host_uninstall_device(msc_device)); + msc_device = NULL; + } + if (msg.id == APP_QUIT) { + // This will cause the usb_task to exit + ESP_ERROR_CHECK(msc_host_uninstall()); + break; + } + } + } - ESP_LOGI(TAG, "Uninitializing USB ..."); - ESP_ERROR_CHECK(msc_host_uninstall()); - wait_for_event(READY_TO_UNINSTALL, portMAX_DELAY); - ESP_ERROR_CHECK(usb_host_uninstall()); ESP_LOGI(TAG, "Done"); + gpio_isr_handler_remove(APP_QUIT_PIN); + vQueueDelete(app_queue); } diff --git a/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py b/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py new file mode 100644 index 00000000000..74474226293 --- /dev/null +++ b/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py @@ -0,0 +1,27 @@ + +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.usb_host_flash_disk +def test_usb_host_msc_example(dut: Dut) -> None: + # Check result of file_operations() + dut.expect_exact("example: Read from file '/usb/esp/test.txt': 'Hello World!'") + + # Check result of speed_test() + write_throughput = float(dut.expect(r'example: Write speed ([0-9]*[.]?[0-9]+) MiB')[1].decode()) + read_throughput = float(dut.expect(r'example: Read speed ([0-9]*[.]?[0-9]+) MiB')[1].decode()) + + # These values should be updated for HS targets + if write_throughput > 0.9: + print('Write throughput put OK') + else: + print('write throughput too slow!') + if read_throughput > 1.0: + print('Read throughput put OK') + else: + print('Read throughput too slow!') diff --git a/examples/peripherals/usb/host/usb_host_lib/README.md b/examples/peripherals/usb/host/usb_host_lib/README.md index f6b746c7a71..bb60eab1114 100644 --- a/examples/peripherals/usb/host/usb_host_lib/README.md +++ b/examples/peripherals/usb/host/usb_host_lib/README.md @@ -5,19 +5,21 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example demonstrates the basic usage of the [USB Host Library API](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_host.html) by implementing a pseudo class driver and a Host Library daemon task. The example does the following: +This example demonstrates the basic usage of the [USB Host Library API](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_host.html) by implementing a pseudo class driver and a Host Library task. The example does the following: 1. Install Host Library and register a client 2. Waits for a device connection 3. Prints the device's information (such as device/configuration/string descriptors) 4. Waits for the device to disconnect -5. Deregister the client and uninstall the Host Library +5. Repeats steps 2 to 4 until a user pressess a button, which quits the `app` +6. If the button has been pressed, while a USB device is still connected, the user will be prompted to remove the device and push the button again to quit the `app` +7. Deregister the client, uninstall the Host Library and quit the `app` The example demonstrates the following aspects of the USB Host Library API: - How to use the Library API to: - Install and uninstall the USB Host Library - - Run the library event handler function a daemon task + - Run the library event handler function and usb host library task - How to handle library events - How to use the Client API from a client task to: - Register and deregister a client of the USB Host Library @@ -30,7 +32,7 @@ The example demonstrates the following aspects of the USB Host Library API: ### Hardware Required -An ESP board that supports USB-OTG. The example uses the ESP's internal USB PHY, however the internal USB PHY's pins will need to be connected to a USB port (i.e., a USB breakout board) as follows: +An ESP board that has a push button and supports USB-OTG. The example uses the ESP's internal USB PHY, however the internal USB PHY's pins will need to be connected to a USB port (i.e., a USB breakout board) as follows: - GND and 5V signals of the ESP board to the GND and 5V lines of the USB port - GPIO 19 to D- @@ -43,6 +45,7 @@ idf.py menuconfig ``` * The USB Host Stack has a maximum supported transfer size for control transfer during device enumeration. This size is specified via the USB_HOST_CONTROL_TRANSFER_MAX_SIZE configuration option and has a default value of 256 bytes. Therefore, if devices with length config/string descriptors are used, users may want to increase the size of this configuration. +* Push button GPIO selection ### Build and Flash @@ -61,14 +64,17 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ## Example Output ``` -I (261) cpu_start: Starting scheduler on PRO CPU. -I (267) DAEMON: Installing USB Host Library -I (297) CLASS: Registering Client -I (5067) CLASS: Opening device at address 1 -I (5067) CLASS: Getting device information -I (5067) CLASS: Full speed -I (5067) CLASS: bConfigurationValue 1 -I (5067) CLASS: Getting device descriptor +I (305) main_task: Started on CPU0 +I (315) main_task: Calling app_main() +I (315) USB host lib: USB host library example +I (315) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2 +I (325) USB host lib: Installing USB Host Library +I (365) CLASS: Registering Client +I (745) CLASS: Opening device at address 1 +I (745) CLASS: Getting device information +I (745) CLASS: Full speed +I (745) CLASS: bConfigurationValue 1 +I (745) CLASS: Getting device descriptor *** Device descriptor *** bLength 18 bDescriptorType 1 @@ -84,7 +90,7 @@ iManufacturer 1 iProduct 2 iSerialNumber 3 bNumConfigurations 1 -I (5097) CLASS: Getting config descriptor +I (775) CLASS: Getting config descriptor *** Configuration descriptor *** bLength 9 bDescriptorType 2 @@ -153,12 +159,20 @@ bMaxPower 500mA bmAttributes 0x2 BULK wMaxPacketSize 64 bInterval 1 -I (5227) CLASS: Getting Manufacturer string descriptor +I (855) CLASS: Getting Manufacturer string descriptor Espressif -I (5237) CLASS: Getting Product string descriptor +I (855) CLASS: Getting Product string descriptor USB JTAG/serial debug unit -I (5247) CLASS: Getting Serial Number string descriptor +I (865) CLASS: Getting Serial Number string descriptor 7C:DF:A1:E0:10:50 +W (2855) USB host lib: To shutdown example, remove all USB devices and press button again. +E (6135) USBH: Device 1 gone +I (9545) CLASS: Deregistering Client +I (9545) USB host lib: No more clients +I (9545) USB host lib: All devices marked as free +I (9545) USB host lib: No more clients and devices +I (9645) USB host lib: End of the example +I (9645) main_task: Returned from app_main() ``` ## Troubleshooting diff --git a/examples/peripherals/usb/host/usb_host_lib/main/CMakeLists.txt b/examples/peripherals/usb/host/usb_host_lib/main/CMakeLists.txt index 260f313feae..5d0a296fb9c 100644 --- a/examples/peripherals/usb/host/usb_host_lib/main/CMakeLists.txt +++ b/examples/peripherals/usb/host/usb_host_lib/main/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "usb_host_lib_main.c" "class_driver.c" INCLUDE_DIRS "." - PRIV_REQUIRES usb + PRIV_REQUIRES usb driver ) diff --git a/examples/peripherals/usb/host/usb_host_lib/main/Kconfig.projbuild b/examples/peripherals/usb/host/usb_host_lib/main/Kconfig.projbuild new file mode 100644 index 00000000000..680b0cc3c83 --- /dev/null +++ b/examples/peripherals/usb/host/usb_host_lib/main/Kconfig.projbuild @@ -0,0 +1,12 @@ +menu "Example Configuration" + + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + + config APP_QUIT_PIN + int "APP Quit button GPIO pin" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 0 + help + GPIO pin number to be used as APP_QUIT button. + +endmenu diff --git a/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c b/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c index ce7ee444870..e7a06ea59fe 100644 --- a/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c +++ b/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c @@ -12,13 +12,16 @@ #define CLIENT_NUM_EVENT_MSG 5 -#define ACTION_OPEN_DEV 0x01 -#define ACTION_GET_DEV_INFO 0x02 -#define ACTION_GET_DEV_DESC 0x04 -#define ACTION_GET_CONFIG_DESC 0x08 -#define ACTION_GET_STR_DESC 0x10 -#define ACTION_CLOSE_DEV 0x20 -#define ACTION_EXIT 0x40 +typedef enum { + ACTION_OPEN_DEV = 0x01, + ACTION_GET_DEV_INFO = 0x02, + ACTION_GET_DEV_DESC = 0x04, + ACTION_GET_CONFIG_DESC = 0x08, + ACTION_GET_STR_DESC = 0x10, + ACTION_CLOSE_DEV = 0x20, + ACTION_EXIT = 0x40, + ACTION_RECONNECT = 0x80, +} action_t; typedef struct { usb_host_client_handle_t client_hdl; @@ -28,6 +31,7 @@ typedef struct { } class_driver_t; static const char *TAG = "CLASS"; +static class_driver_t *s_driver_obj; static void client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg) { @@ -122,24 +126,20 @@ static void action_get_str_desc(class_driver_t *driver_obj) driver_obj->actions &= ~ACTION_GET_STR_DESC; } -static void aciton_close_dev(class_driver_t *driver_obj) +static void action_close_dev(class_driver_t *driver_obj) { ESP_ERROR_CHECK(usb_host_device_close(driver_obj->client_hdl, driver_obj->dev_hdl)); driver_obj->dev_hdl = NULL; driver_obj->dev_addr = 0; - //We need to exit the event handler loop + //We need to connect a new device driver_obj->actions &= ~ACTION_CLOSE_DEV; - driver_obj->actions |= ACTION_EXIT; + driver_obj->actions |= ACTION_RECONNECT; } void class_driver_task(void *arg) { - SemaphoreHandle_t signaling_sem = (SemaphoreHandle_t)arg; class_driver_t driver_obj = {0}; - //Wait until daemon task has installed USB Host Library - xSemaphoreTake(signaling_sem, portMAX_DELAY); - ESP_LOGI(TAG, "Registering Client"); usb_host_client_config_t client_config = { .is_synchronous = false, //Synchronous clients currently not supported. Set this to false @@ -150,6 +150,7 @@ void class_driver_task(void *arg) }, }; ESP_ERROR_CHECK(usb_host_client_register(&client_config, &driver_obj.client_hdl)); + s_driver_obj = &driver_obj; while (1) { if (driver_obj.actions == 0) { @@ -171,18 +172,29 @@ void class_driver_task(void *arg) action_get_str_desc(&driver_obj); } if (driver_obj.actions & ACTION_CLOSE_DEV) { - aciton_close_dev(&driver_obj); + action_close_dev(&driver_obj); } if (driver_obj.actions & ACTION_EXIT) { break; } + if (driver_obj.actions & ACTION_RECONNECT) { + driver_obj.actions = 0; + } } } ESP_LOGI(TAG, "Deregistering Client"); ESP_ERROR_CHECK(usb_host_client_deregister(driver_obj.client_hdl)); - - //Wait to be deleted - xSemaphoreGive(signaling_sem); vTaskSuspend(NULL); } + +void class_driver_client_deregister(void) +{ + if (s_driver_obj->dev_hdl != NULL) { + s_driver_obj->actions = ACTION_CLOSE_DEV; + } + s_driver_obj->actions |= ACTION_EXIT; + + // Unblock, exit the loop and proceed to deregister client + ESP_ERROR_CHECK(usb_host_client_unblock(s_driver_obj->client_hdl)); +} diff --git a/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c b/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c index f73880cabcb..db41bd32657 100644 --- a/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c +++ b/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c @@ -1,27 +1,78 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" #include "esp_log.h" #include "esp_intr_alloc.h" #include "usb/usb_host.h" +#include "driver/gpio.h" -#define DAEMON_TASK_PRIORITY 2 +#define HOST_LIB_TASK_PRIORITY 2 #define CLASS_TASK_PRIORITY 3 +#define APP_QUIT_PIN CONFIG_APP_QUIT_PIN extern void class_driver_task(void *arg); +extern void class_driver_client_deregister(void); -static const char *TAG = "DAEMON"; +static const char *TAG = "USB host lib"; -static void host_lib_daemon_task(void *arg) +QueueHandle_t app_event_queue = NULL; + +/** + * @brief APP event group + * + * APP_EVENT - General event, which is APP_QUIT_PIN press event in this example. + */ +typedef enum { + APP_EVENT = 0, +} app_event_group_t; + +/** + * @brief APP event queue + * + * This event is used for delivering events from callback to a task. + */ +typedef struct { + app_event_group_t event_group; +} app_event_queue_t; + +/** + * @brief BOOT button pressed callback + * + * Signal application to exit the Host lib task + * + * @param[in] arg Unused + */ +static void gpio_cb(void *arg) { - SemaphoreHandle_t signaling_sem = (SemaphoreHandle_t)arg; + const app_event_queue_t evt_queue = { + .event_group = APP_EVENT, + }; + + BaseType_t xTaskWoken = pdFALSE; + + if (app_event_queue) { + xQueueSendFromISR(app_event_queue, &evt_queue, &xTaskWoken); + } + + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} +/** + * @brief Start USB Host install and handle common USB host library events while app pin not low + * + * @param[in] arg Not used + */ +static void usb_host_lib_task(void *arg) +{ ESP_LOGI(TAG, "Installing USB Host Library"); usb_host_config_t host_config = { .skip_phy_setup = false, @@ -29,9 +80,8 @@ static void host_lib_daemon_task(void *arg) }; ESP_ERROR_CHECK(usb_host_install(&host_config)); - //Signal to the class driver task that the host library is installed - xSemaphoreGive(signaling_sem); - vTaskDelay(10); //Short delay to let client task spin up + //Signalize the app_main, the USB host library has been installed + xTaskNotifyGive(arg); bool has_clients = true; bool has_devices = true; @@ -39,52 +89,101 @@ static void host_lib_daemon_task(void *arg) uint32_t event_flags; ESP_ERROR_CHECK(usb_host_lib_handle_events(portMAX_DELAY, &event_flags)); if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + ESP_LOGI(TAG, "No more clients"); has_clients = false; + if (ESP_OK == usb_host_device_free_all()) { + ESP_LOGI(TAG, "All devices marked as free"); + } else { + ESP_LOGI(TAG, "Wait for the ALL FREE EVENT"); + } } if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + ESP_LOGI(TAG, "No more devices"); has_devices = false; } + } ESP_LOGI(TAG, "No more clients and devices"); //Uninstall the USB Host Library ESP_ERROR_CHECK(usb_host_uninstall()); - //Wait to be deleted - xSemaphoreGive(signaling_sem); vTaskSuspend(NULL); } void app_main(void) { - SemaphoreHandle_t signaling_sem = xSemaphoreCreateBinary(); - - TaskHandle_t daemon_task_hdl; - TaskHandle_t class_driver_task_hdl; - //Create daemon task - xTaskCreatePinnedToCore(host_lib_daemon_task, - "daemon", - 4096, - (void *)signaling_sem, - DAEMON_TASK_PRIORITY, - &daemon_task_hdl, - 0); - //Create the class driver task - xTaskCreatePinnedToCore(class_driver_task, - "class", - 4096, - (void *)signaling_sem, - CLASS_TASK_PRIORITY, - &class_driver_task_hdl, - 0); + ESP_LOGI(TAG, "USB host library example"); + + // Init BOOT button: Pressing the button simulates app request to exit + // It will uninstall the class driver and USB Host Lib + const gpio_config_t input_pin = { + .pin_bit_mask = BIT64(APP_QUIT_PIN), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&input_pin)); + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); + ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_cb, NULL)); + app_event_queue = xQueueCreate(10, sizeof(app_event_queue_t)); + app_event_queue_t evt_queue; + + TaskHandle_t host_lib_task_hdl, class_driver_task_hdl; + + //Create usb host lib task + BaseType_t task_created; + task_created = xTaskCreatePinnedToCore(usb_host_lib_task, + "usb_host", + 4096, + xTaskGetCurrentTaskHandle(), + HOST_LIB_TASK_PRIORITY, + &host_lib_task_hdl, + 0); + assert(task_created == pdTRUE); + + //Wait unit the USB host library is installed + ulTaskNotifyTake(false, 1000); + + //Create class driver task + task_created = xTaskCreatePinnedToCore(class_driver_task, + "class", + 4096, + NULL, + CLASS_TASK_PRIORITY, + &class_driver_task_hdl, + 0); + assert(task_created == pdTRUE); vTaskDelay(10); //Add a short delay to let the tasks run - //Wait for the tasks to complete - for (int i = 0; i < 2; i++) { - xSemaphoreTake(signaling_sem, portMAX_DELAY); + while (1) { + if (xQueueReceive(app_event_queue, &evt_queue, portMAX_DELAY)) { + if (APP_EVENT == evt_queue.event_group) { + // User pressed button + usb_host_lib_info_t lib_info; + ESP_ERROR_CHECK(usb_host_lib_info(&lib_info)); + if (lib_info.num_devices == 0) { + // End while cycle + break; + } else { + ESP_LOGW(TAG, "To shutdown example, remove all USB devices and press button again."); + // Keep polling + } + } + } } + //Deregister client + class_driver_client_deregister(); + vTaskDelay(10); + //Delete the tasks vTaskDelete(class_driver_task_hdl); - vTaskDelete(daemon_task_hdl); + vTaskDelete(host_lib_task_hdl); + + // Delete interrupt and queue + gpio_isr_handler_remove(APP_QUIT_PIN); + xQueueReset(app_event_queue); + vQueueDelete(app_event_queue); + ESP_LOGI(TAG, "End of the example"); } diff --git a/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn b/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn index 22c15d6572c..a682b25bbc9 100644 --- a/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn +++ b/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn @@ -9,7 +9,6 @@ CONFIG_EXAMPLE_ETH_PHY_ADDR=1 CONFIG_EXAMPLE_CONNECT_IPV6=y CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH=y CONFIG_MBEDTLS_DYNAMIC_BUFFER=y -CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y CONFIG_MBEDTLS_DHM_C=y CONFIG_EXAMPLE_HTTP_ENDPOINT="httpbin.espressif.cn" diff --git a/examples/protocols/http_server/restful_server/sdkconfig.defaults b/examples/protocols/http_server/restful_server/sdkconfig.defaults index 87b6ea1e572..648ade5093a 100644 --- a/examples/protocols/http_server/restful_server/sdkconfig.defaults +++ b/examples/protocols/http_server/restful_server/sdkconfig.defaults @@ -1,6 +1,5 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 CONFIG_SPIFFS_OBJ_NAME_LEN=64 -CONFIG_FATFS_LONG_FILENAME=y CONFIG_FATFS_LFN_HEAP=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c index e65b656c4bc..32118ffad58 100644 --- a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c +++ b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c @@ -128,10 +128,6 @@ static void https_get_task(void *pvParameters) mbedtls_esp_enable_debug_log(&conf, CONFIG_MBEDTLS_DEBUG_LEVEL); #endif -#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - mbedtls_ssl_conf_min_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_3); - mbedtls_ssl_conf_max_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_3); -#endif if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) { ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%x", -ret); diff --git a/examples/protocols/https_request/main/time_sync.c b/examples/protocols/https_request/main/time_sync.c index 5e158c17cea..268c819a958 100644 --- a/examples/protocols/https_request/main/time_sync.c +++ b/examples/protocols/https_request/main/time_sync.c @@ -54,14 +54,15 @@ static esp_err_t obtain_time(void) esp_err_t fetch_and_store_time_in_nvs(void *args) { + nvs_handle_t my_handle = 0; + esp_err_t err; + initialize_sntp(); if (obtain_time() != ESP_OK) { - return ESP_FAIL; + err = ESP_FAIL; + goto exit; } - nvs_handle_t my_handle; - esp_err_t err; - time_t now; time(&now); @@ -82,10 +83,12 @@ esp_err_t fetch_and_store_time_in_nvs(void *args) goto exit; } - nvs_close(my_handle); - esp_netif_deinit(); - exit: + if (my_handle != 0) { + nvs_close(my_handle); + } + esp_netif_sntp_deinit(); + if (err != ESP_OK) { ESP_LOGE(TAG, "Error updating time in nvs"); } else { @@ -96,7 +99,7 @@ esp_err_t fetch_and_store_time_in_nvs(void *args) esp_err_t update_time_from_nvs(void) { - nvs_handle_t my_handle; + nvs_handle_t my_handle = 0; esp_err_t err; err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle); @@ -122,6 +125,8 @@ esp_err_t update_time_from_nvs(void) } exit: - nvs_close(my_handle); + if (my_handle != 0) { + nvs_close(my_handle); + } return err; } diff --git a/examples/protocols/https_request/sdkconfig.ci b/examples/protocols/https_request/sdkconfig.ci index 5577f9549a7..9f61f58c61b 100644 --- a/examples/protocols/https_request/sdkconfig.ci +++ b/examples/protocols/https_request/sdkconfig.ci @@ -10,3 +10,4 @@ CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 CONFIG_EXAMPLE_ETH_PHY_ADDR=1 CONFIG_EXAMPLE_CONNECT_IPV6=y CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST=y diff --git a/examples/protocols/https_request/sdkconfig.ci.mbedtls_config b/examples/protocols/https_request/sdkconfig.ci.mbedtls_config index 2a24a07e03e..113bcf6336a 100644 --- a/examples/protocols/https_request/sdkconfig.ci.mbedtls_config +++ b/examples/protocols/https_request/sdkconfig.ci.mbedtls_config @@ -37,10 +37,7 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=n # end of TLS Key Exchange Methods CONFIG_MBEDTLS_SSL_RENEGOTIATION=n -CONFIG_MBEDTLS_SSL_PROTO_SSL3=n CONFIG_MBEDTLS_SSL_PROTO_DTLS=n -CONFIG_MBEDTLS_SSL_PROTO_TLS1=n -CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=n CONFIG_MBEDTLS_SSL_ALPN=n CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=n @@ -52,9 +49,6 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=n CONFIG_MBEDTLS_AES_C=n CONFIG_MBEDTLS_CAMELLIA_C=n CONFIG_MBEDTLS_DES_C=n -CONFIG_MBEDTLS_RC4_DISABLED=n -CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT=n -CONFIG_MBEDTLS_RC4_ENABLED=n CONFIG_MBEDTLS_BLOWFISH_C=n CONFIG_MBEDTLS_XTEA_C=n CONFIG_MBEDTLS_CCM_C=n @@ -94,5 +88,4 @@ CONFIG_MBEDTLS_CHACHA20_C=n CONFIG_MBEDTLS_HKDF_C=n CONFIG_MBEDTLS_THREADING_C=n CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI=n -CONFIG_MBEDTLS_SECURITY_RISKS=n # end of mbedTLS diff --git a/examples/protocols/https_request/sdkconfig.ci.ssldyn b/examples/protocols/https_request/sdkconfig.ci.ssldyn index 7840b586497..a6c2b2db42c 100644 --- a/examples/protocols/https_request/sdkconfig.ci.ssldyn +++ b/examples/protocols/https_request/sdkconfig.ci.ssldyn @@ -10,5 +10,4 @@ CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 CONFIG_EXAMPLE_ETH_PHY_ADDR=1 CONFIG_EXAMPLE_CONNECT_IPV6=y CONFIG_MBEDTLS_DYNAMIC_BUFFER=y -CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y diff --git a/examples/protocols/https_server/simple/sdkconfig.ci b/examples/protocols/https_server/simple/sdkconfig.ci index 84ffce91b89..badfd866fe2 100644 --- a/examples/protocols/https_server/simple/sdkconfig.ci +++ b/examples/protocols/https_server/simple/sdkconfig.ci @@ -1,3 +1,4 @@ CONFIG_ESP_HTTPS_SERVER_ENABLE=y +CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK=y CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK=y CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn b/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn index a8773f6a04c..9fd5735ca20 100644 --- a/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn +++ b/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn @@ -2,7 +2,6 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="certs" CONFIG_MBEDTLS_DYNAMIC_BUFFER=y -CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y CONFIG_EXAMPLE_CONNECT_ETHERNET=y diff --git a/examples/protocols/mqtt/tcp/sdkconfig.ci.ppp_connect b/examples/protocols/mqtt/tcp/sdkconfig.ci.ppp_connect new file mode 100644 index 00000000000..7366a909ec9 --- /dev/null +++ b/examples/protocols/mqtt/tcp/sdkconfig.ci.ppp_connect @@ -0,0 +1,3 @@ +CONFIG_EXAMPLE_CONNECT_WIFI=n +CONFIG_EXAMPLE_CONNECT_PPP=y +CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_UART=y diff --git a/examples/storage/.build-test-rules.yml b/examples/storage/.build-test-rules.yml index 701a5601b1f..7840ae2ad70 100644 --- a/examples/storage/.build-test-rules.yml +++ b/examples/storage/.build-test-rules.yml @@ -1,117 +1,113 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps examples/storage/custom_flash_driver: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - spi_flash + - driver + disable_test: + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/emmc: + depends_components: + - sdmmc + - driver + - fatfs + - vfs enable: - if: IDF_TARGET == "esp32s3" reason: only support on esp32s3 examples/storage/ext_flash_fatfs: + depends_components: + - fatfs + - vfs + - spi_flash + - driver disable: - - if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2", "esp32p4"] - temporary: true - reason: target(s) not supported yet + - if: IDF_TARGET == "esp32p4" + reason: not supported yet disable_test: - - if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3"] + - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners examples/storage/fatfsgen: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - fatfs + - vfs disable_test: - - if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET != "esp32" + reason: only one target needed examples/storage/nvs_rw_blob: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - nvs_flash + - driver disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/nvs_rw_value: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - nvs_flash disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/nvs_rw_value_cxx: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - nvs_flash disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/nvsgen: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - nvs_flash disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners, should be same for every target + - if: IDF_TARGET != "esp32" + reason: only one target needed examples/storage/partition_api/partition_find: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - esp_partition disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/partition_api/partition_mmap: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - esp_partition disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/partition_api/partition_ops: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - esp_partition + - spi_flash disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/parttool: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - partition_table disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET != "esp32" + reason: only one target needed examples/storage/perf_benchmark: + depends_components: + - fatfs + - spi_flash + - vfs + - sdmmc + - spiffs + - wear_levelling + - esp_partition + - driver disable: - if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["sdmmc_1line", "sdmmc_4line", "sdspi_1line"] temporary: true @@ -122,57 +118,59 @@ examples/storage/perf_benchmark: reason: SPIFLASH not supported on P4 yet, only build stage enabled # TODO: IDF-7499 examples/storage/sd_card/sdmmc: + depends_components: + - vfs + - sdmmc + - driver disable: - if: SOC_SDMMC_HOST_SUPPORTED != 1 disable_test: - - if: IDF_TARGET == "esp32s3" + - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners examples/storage/sd_card/sdspi: + depends_components: + - vfs + - sdmmc + - driver disable: - if: SOC_GPSPI_SUPPORTED != 1 disable_test: - - if: IDF_TARGET in ["esp32s3", "esp32c2", "esp32c6", "esp32h2", "esp32p4"] + - if: IDF_TARGET not in ["esp32", "esp32c3"] temporary: true reason: lack of runners examples/storage/semihost_vfs: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - vfs disable_test: - - if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3", "esp32c6", "esp32h2"] + - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners examples/storage/spiffs: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - spiffs + - vfs disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/spiffsgen: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - spiffs + - vfs + - mbedtls disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET != "esp32" + reason: only one target needed examples/storage/wear_levelling: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + depends_components: + - vfs + - wear_levelling + - fatfs disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed diff --git a/examples/storage/README.md b/examples/storage/README.md index 5618ee20b38..bb5c821fe89 100644 --- a/examples/storage/README.md +++ b/examples/storage/README.md @@ -1,5 +1,27 @@ # Storage Examples Storage and management of user and system data in module’s flash and on external memory / devices. +This directory contains a range of examples ESP-IDF projects. These are intended to demonstrate the storage features, and to provide code that you can copy and adapt into your own projects. + +# Example Layout + +The examples are grouped into sub-directories by category. Each category directory contains one or more example projects: + +* `custom_flash_driver` example demonstrates how to implement your own flash chip driver by overriding the default driver. +* `emmc` example demonstrates how to use an eMMC chip with an ESP device. +* `ext_flash_fatfs` example demonstrates how to use FATFS partition with external SPI FLASH chip. +* `fatfsgen` example demonstrates how to use FATFS partition +* `nvs_rw_blob` example demonstrates how to read and write a single integer value and a blob (binary large object) using NVS to preserve them between ESP module restarts. +* `nvs_rw_value` example demonstrates how to read and write a single integer value using NVS. +* `nvs_rw_value_cxx` example demonstrates how to read and write a single integer value using NVS (it uses the C++ NVS handle API). +* `partition_api` examples demonstrate how to use different partition APIs. +* `parttool` example demonstrates common operations the partitions tool allows the user to perform. +* `sd_card` examples demonstrate how to use an SD card with an ESP device. +* `semihost_vfs` example demonstrates how to use semihosting VFS driver with ESP device. +* `spiffs` example demonstrates how to use SPIFFS with ESP device. +* `spiffsgen` example demonstrates how to use the SPIFFS image generation tool spiffsgen.py to automatically create a SPIFFS. +* `wear_levelling` example demonstrates how to use wear levelling library and FATFS library to store files in a partition inside SPI flash. + +# More See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. diff --git a/examples/storage/custom_flash_driver/README.md b/examples/storage/custom_flash_driver/README.md index c124504499d..9c251e68cc2 100644 --- a/examples/storage/custom_flash_driver/README.md +++ b/examples/storage/custom_flash_driver/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Custom Flash Driver Example diff --git a/examples/storage/ext_flash_fatfs/README.md b/examples/storage/ext_flash_fatfs/README.md index 6db77cb4208..55538e2e4d7 100644 --- a/examples/storage/ext_flash_fatfs/README.md +++ b/examples/storage/ext_flash_fatfs/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # FAT FS on External Flash example diff --git a/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py b/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py index 8b85b85d2da..afe81763a3a 100644 --- a/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py +++ b/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py @@ -1,4 +1,4 @@ -# 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 diff --git a/examples/storage/fatfsgen/README.md b/examples/storage/fatfsgen/README.md index 1beb6fd676c..683d59534f8 100644 --- a/examples/storage/fatfsgen/README.md +++ b/examples/storage/fatfsgen/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # FATFS partition generation example diff --git a/examples/storage/fatfsgen/main/fatfsgen_example_main.c b/examples/storage/fatfsgen/main/fatfsgen_example_main.c index 491622c4e42..1c0c94dc3f3 100644 --- a/examples/storage/fatfsgen/main/fatfsgen_example_main.c +++ b/examples/storage/fatfsgen/main/fatfsgen_example_main.c @@ -9,7 +9,6 @@ #include #include "esp_vfs.h" #include "esp_vfs_fat.h" -#include "esp_system.h" #include "sdkconfig.h" #if CONFIG_EXAMPLE_FATFS_MODE_READ_ONLY diff --git a/examples/storage/fatfsgen/pytest_fatfsgen_example.py b/examples/storage/fatfsgen/pytest_fatfsgen_example.py index c19201c5a3a..74ed3d8051b 100644 --- a/examples/storage/fatfsgen/pytest_fatfsgen_example.py +++ b/examples/storage/fatfsgen/pytest_fatfsgen_example.py @@ -1,4 +1,4 @@ -# 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 import os diff --git a/examples/storage/nvs_rw_blob/README.md b/examples/storage/nvs_rw_blob/README.md index e9e2f52b8af..7563617da8c 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-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Non-Volatile Storage (NVS) Read and Write Example diff --git a/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py b/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py index 23430e76d15..01840dcda3a 100644 --- a/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py +++ b/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py @@ -1,4 +1,4 @@ -# 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 import logging diff --git a/examples/storage/nvs_rw_value/README.md b/examples/storage/nvs_rw_value/README.md index ca311bb26e1..dd67cc5f5eb 100644 --- a/examples/storage/nvs_rw_value/README.md +++ b/examples/storage/nvs_rw_value/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Non-Volatile Storage (NVS) Read and Write Example diff --git a/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py b/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py index f42756d6f4f..aae3f1e038c 100644 --- a/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py +++ b/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py @@ -1,4 +1,4 @@ -# 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 import logging diff --git a/examples/storage/nvs_rw_value_cxx/README.md b/examples/storage/nvs_rw_value_cxx/README.md index 7108fef8bde..5d9248d662d 100644 --- a/examples/storage/nvs_rw_value_cxx/README.md +++ b/examples/storage/nvs_rw_value_cxx/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Non-Volatile Storage (NVS) C++ Read and Write Example diff --git a/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py b/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py index 86cf0105faa..cd1237058cf 100644 --- a/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py +++ b/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py @@ -1,4 +1,4 @@ -# 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 import logging diff --git a/examples/storage/nvsgen/README.md b/examples/storage/nvsgen/README.md index 622573a4d0e..e0f68366c0e 100644 --- a/examples/storage/nvsgen/README.md +++ b/examples/storage/nvsgen/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # NVS Partition Image Generation on Build Example diff --git a/examples/storage/partition_api/partition_find/README.md b/examples/storage/partition_api/partition_find/README.md index 823f05a9442..50b471279fc 100644 --- a/examples/storage/partition_api/partition_find/README.md +++ b/examples/storage/partition_api/partition_find/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Finding Partitions Example diff --git a/examples/storage/partition_api/partition_find/pytest_partition_find_example.py b/examples/storage/partition_api/partition_find/pytest_partition_find_example.py index 1bd7d5a22ab..6b03f8174c2 100644 --- a/examples/storage/partition_api/partition_find/pytest_partition_find_example.py +++ b/examples/storage/partition_api/partition_find/pytest_partition_find_example.py @@ -1,4 +1,4 @@ -# 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 import re diff --git a/examples/storage/partition_api/partition_mmap/README.md b/examples/storage/partition_api/partition_mmap/README.md index 94ea4430d37..d63e67af9c8 100644 --- a/examples/storage/partition_api/partition_mmap/README.md +++ b/examples/storage/partition_api/partition_mmap/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Partition Memory Map Example diff --git a/examples/storage/partition_api/partition_mmap/pytest_partition_mmap_example.py b/examples/storage/partition_api/partition_mmap/pytest_partition_mmap_example.py index e77d29fe5bc..46d306fc770 100644 --- a/examples/storage/partition_api/partition_mmap/pytest_partition_mmap_example.py +++ b/examples/storage/partition_api/partition_mmap/pytest_partition_mmap_example.py @@ -1,4 +1,4 @@ -# 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 import re diff --git a/examples/storage/partition_api/partition_ops/README.md b/examples/storage/partition_api/partition_ops/README.md index 8ff19ce942c..0ca9e6dce52 100644 --- a/examples/storage/partition_api/partition_ops/README.md +++ b/examples/storage/partition_api/partition_ops/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Partition Read, Write, Erase Example diff --git a/examples/storage/partition_api/partition_ops/pytest_partition_ops_example.py b/examples/storage/partition_api/partition_ops/pytest_partition_ops_example.py index c5f031a7032..74abd28608b 100644 --- a/examples/storage/partition_api/partition_ops/pytest_partition_ops_example.py +++ b/examples/storage/partition_api/partition_ops/pytest_partition_ops_example.py @@ -1,4 +1,4 @@ -# 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 import re diff --git a/examples/storage/parttool/README.md b/examples/storage/parttool/README.md index a26adf289de..e369b66c210 100644 --- a/examples/storage/parttool/README.md +++ b/examples/storage/parttool/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Partitions Tool Example diff --git a/examples/storage/parttool/pytest_parttool_example.py b/examples/storage/parttool/pytest_parttool_example.py index 9f984cfc1af..8411418ab50 100644 --- a/examples/storage/parttool/pytest_parttool_example.py +++ b/examples/storage/parttool/pytest_parttool_example.py @@ -1,4 +1,4 @@ -# 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 import os @@ -10,7 +10,6 @@ @pytest.mark.esp32 -@pytest.mark.esp32c3 def test_examples_parttool(dut: Dut) -> None: # Verify factory firmware dut.expect('Partitions Tool Example') diff --git a/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py b/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py index 34758fbe96a..6275e231f68 100644 --- a/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py +++ b/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py @@ -52,8 +52,8 @@ def test_examples_perf_benchmark_sdcard_sdmmc(dut: Dut) -> None: @pytest.mark.esp32 -@pytest.mark.esp32s2 @pytest.mark.esp32c3 +@pytest.mark.esp32s2 @pytest.mark.sdcard_spimode @pytest.mark.parametrize( 'config', diff --git a/examples/storage/sd_card/sdspi/README.md b/examples/storage/sd_card/sdspi/README.md index 334ff29f388..c8a223ab115 100644 --- a/examples/storage/sd_card/sdspi/README.md +++ b/examples/storage/sd_card/sdspi/README.md @@ -111,6 +111,19 @@ I (7396) example: Card unmounted The example will be able to mount only cards formatted using FAT32 filesystem. If the card is formatted as exFAT or some other filesystem, you have an option to format it in the example code. Enable the `CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED` menuconfig option, then build and flash the example. +> Once you've enabled the `CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED` option, if you continue to encounter the following error: + +``` +E (600) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x108 +E (600) diskio_sdmmc: sdmmc_read_blocks failed (264) +W (610) vfs_fat_sdmmc: failed to mount card (1) +E (610) vfs_fat_sdmmc: mount_to_vfs failed (0xffffffff). +I (620) gpio: GPIO[13]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +E (630) example: Failed to mount filesystem. If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option. +``` + +Please ensure that your SD card is operational and not experiencing any malfunctions. + ### Unable to flash the example, or serial port not available (ESP32 only) @@ -125,3 +138,20 @@ An attempt to download a new firmware under this conditions may also result in t `esptool --port PORT --before no_reset --baud 115200 --chip esp32 erase_flash` to erase your board's flash, then flash the firmware again. + +> If you insert an SD card into the slot and encounter issues when attempting to flash a supported target using the `idf.py flash` command, please consider removing the SD card and attempting to flash the target again. If the flashing process succeeds after removing the SD card, it suggests potential issues with power supply. + +Ensure that the board and SD card adapter you are using are powered using the appropriate power source. + + +### Getting the following errors + +> `vfs_fat_sdmmc: slot init failed (0x103)` + +> `vfs_fat_sdmmc: sdmmc_card_init failed (0x102)` + +> `sdmmc_init_ocr: send_op_cond (1) returned 0x107` + +Attempt to reboot the board. This error may occur if you reset the ESP board or host controller without power-cycling it. In such cases, the card may remain in its previous state, causing it to potentially not respond to commands sent by the host controller. + +Additionally, if the example works with certain SD cards but encounters issues with others, please confirm the read/write speed of the SD card. If the card is not compatible with the host frequency, consider lowering the host frequency and then attempting the operation again. 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 480aa9f2d63..4f2b42bb58e 100644 --- a/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py +++ b/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py @@ -11,7 +11,6 @@ @pytest.mark.esp32 @pytest.mark.esp32c3 # no runner available at the moment -@pytest.mark.esp32s2 @pytest.mark.sdcard_spimode def test_examples_sd_card_sdspi(dut: Dut) -> None: dut.expect('example: Initializing SD card', timeout=20) diff --git a/examples/storage/semihost_vfs/README.md b/examples/storage/semihost_vfs/README.md index ae14f9a1c2f..5a744c2cddd 100644 --- a/examples/storage/semihost_vfs/README.md +++ b/examples/storage/semihost_vfs/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Semihosting VFS driver example diff --git a/examples/storage/semihost_vfs/main/semihost_vfs_example_main.c b/examples/storage/semihost_vfs/main/semihost_vfs_example_main.c index 3db7d566b0b..05a61e3f4bb 100644 --- a/examples/storage/semihost_vfs/main/semihost_vfs_example_main.c +++ b/examples/storage/semihost_vfs/main/semihost_vfs_example_main.c @@ -14,6 +14,7 @@ #include #include "esp_err.h" #include "esp_log.h" +#include "esp_cpu.h" #include "esp_vfs_semihost.h" static const char *TAG = "example"; diff --git a/examples/storage/semihost_vfs/pytest_semihost_vfs.py b/examples/storage/semihost_vfs/pytest_semihost_vfs.py index ba5e5478d9c..03dd2acdb2b 100644 --- a/examples/storage/semihost_vfs/pytest_semihost_vfs.py +++ b/examples/storage/semihost_vfs/pytest_semihost_vfs.py @@ -1,4 +1,4 @@ -# 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 import os @@ -24,7 +24,6 @@ def prepare() -> t.Generator[None, None, None]: shutil.rmtree(TEMP_DIR, ignore_errors=True) -@pytest.mark.esp32 @pytest.mark.jtag @pytest.mark.parametrize( 'embedded_services, no_gdb, openocd_cli_args', diff --git a/examples/storage/semihost_vfs/sdkconfig.defaults b/examples/storage/semihost_vfs/sdkconfig.defaults index 989d01c23a1..c24918731c0 100644 --- a/examples/storage/semihost_vfs/sdkconfig.defaults +++ b/examples/storage/semihost_vfs/sdkconfig.defaults @@ -1,2 +1,2 @@ # need this to detect that OpenOCD is connected -CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_ESP_DEBUG_OCDAWARE=y diff --git a/examples/storage/spiffs/README.md b/examples/storage/spiffs/README.md index eaa6959f485..23508289c2e 100644 --- a/examples/storage/spiffs/README.md +++ b/examples/storage/spiffs/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # SPIFFS example diff --git a/examples/storage/spiffsgen/README.md b/examples/storage/spiffsgen/README.md index 8ec3c47be73..eecc6230dca 100644 --- a/examples/storage/spiffsgen/README.md +++ b/examples/storage/spiffsgen/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # SPIFFS Image Generation on Build Example diff --git a/examples/storage/spiffsgen/pytest_spiffsgen_example.py b/examples/storage/spiffsgen/pytest_spiffsgen_example.py index a4c9a7976f1..75f2a9ad319 100644 --- a/examples/storage/spiffsgen/pytest_spiffsgen_example.py +++ b/examples/storage/spiffsgen/pytest_spiffsgen_example.py @@ -9,7 +9,6 @@ @pytest.mark.esp32 -@pytest.mark.esp32c3 def test_spiffsgen_example(dut: Dut) -> None: # Test with default build configurations base_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'spiffs_image') diff --git a/examples/storage/wear_levelling/README.md b/examples/storage/wear_levelling/README.md index 8f12b1a4931..3fbc2db4c6f 100644 --- a/examples/storage/wear_levelling/README.md +++ b/examples/storage/wear_levelling/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Wear levelling example diff --git a/examples/system/.build-test-rules.yml b/examples/system/.build-test-rules.yml index 84e57b7bc90..812425a15b7 100644 --- a/examples/system/.build-test-rules.yml +++ b/examples/system/.build-test-rules.yml @@ -6,6 +6,10 @@ examples/system/app_trace_basic: temporary: true reason: target esp32c6, esp32h2 is not supported yet +examples/system/base_mac_address: + depends_components: + - esp_hw_support + examples/system/console/advanced: disable: - if: IDF_TARGET == "esp32p4" @@ -14,10 +18,16 @@ examples/system/console/advanced: disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: Sufficient to run this app on one chip with each architecture + depends_components: + - console + - vfs examples/system/console/advanced_usb_cdc: disable: - if: SOC_USB_PERIPH_NUM == 0 + depends_components: + - console + - vfs examples/system/console/basic: disable: @@ -27,6 +37,9 @@ examples/system/console/basic: disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: Sufficient to run this app on one chip with each architecture + depends_components: + - console + - vfs examples/system/deep_sleep: disable: @@ -40,15 +53,35 @@ examples/system/deep_sleep_wake_stub: temporary: true reason: target(s) is not supported yet +examples/system/efuse: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - efuse + - bootloader_support + examples/system/esp_timer: disable: - - if: IDF_TARGET in ["esp32c6", "esp32h2", "esp32p4"] + - if: IDF_TARGET in ["esp32p4"] temporary: true reason: target(s) is not supported yet # TODO: IDF-7529 + disable_test: + - if: IDF_TARGET in ["esp32c6", "esp32h2"] + temporary: true + reason: lack of runner + depends_components: + - esp_timer examples/system/eventfd: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient disable: - if: SOC_GPTIMER_SUPPORTED != 1 + depends_components: + - vfs + - esp_driver_gptimer examples/system/flash_suspend: enable: @@ -56,6 +89,13 @@ examples/system/flash_suspend: temporary: true reason: the other targets are not tested yet +examples/system/freertos: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - freertos + examples/system/gcov: disable_test: - if: IDF_TARGET != "esp32" @@ -69,28 +109,34 @@ examples/system/gdbstub: reason: not supported yet #TODO: IDF-7510 examples/system/heap_task_tracking: - disable: - - if: IDF_TARGET == "esp32c2" or IDF_TARGET == "esp32h2" - temporary: true - reason: target esp32c2, esp32h2 is not supported yet + enable: + - if: IDF_TARGET == "esp32c3" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - heap examples/system/himem: enable: - if: IDF_TARGET == "esp32" - temporary: true - reason: the other targets are not tested yet + reason: Feature is only needed/supported on ESP32 examples/system/ipc/ipc_isr/riscv: enable: - - if: IDF_TARGET in ["esp32p4"] - temporary: true + - if: IDF_TARGET_ARCH_RISCV == 1 and ESP_IPC_ISR_ENABLE == 1 reason: The test is intended only for multi-core chips + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: lack of runners + depends_components: + - esp_system examples/system/ipc/ipc_isr/xtensa: enable: - - if: IDF_TARGET in ["esp32", "esp32s3"] - temporary: true + - if: IDF_TARGET_ARCH_XTENSA == 1 and ESP_IPC_ISR_ENABLE == 1 reason: The test is intended only for multi-core chips + depends_components: + - esp_system examples/system/light_sleep: disable: @@ -139,6 +185,7 @@ examples/system/ota/simple_ota_example: - if: IDF_TARGET in ["esp32h2", "esp32p4"] temporary: true reason: target esp32h2, esp32p4 is not supported yet + - if: CONFIG_NAME == "spiram" and SOC_SPIRAM_SUPPORTED != 1 disable_test: - if: IDF_TARGET == "esp32c2" or IDF_TARGET == "esp32c6" temporary: true @@ -146,22 +193,26 @@ examples/system/ota/simple_ota_example: examples/system/perfmon: enable: - - if: IDF_TARGET in ["esp32", "esp32s2", "esp32s3"] - temporary: true - reason: the other targets are not tested yet + - if: IDF_TARGET in ["esp32", "esp32s2", "esp32s3"] and NIGHTLY_RUN == "1" + reason: xtensa only feature + - if: IDF_TARGET == "esp32" + reason: testing on a single target is sufficient + depends_components: + - perfmon + +examples/system/pthread: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - pthread examples/system/select: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet - disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3"] - temporary: true - reason: lack of runners - - if: IDF_TARGET == "esp32c6" or IDF_TARGET == "esp32h2" - temporary: true - reason: target esp32c6 is not supported yet + enable: + - if: IDF_TARGET == "esp32c3" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - vfs examples/system/sysview_tracing: disable: @@ -186,72 +237,100 @@ examples/system/sysview_tracing_heap_log: reason: lack of runners examples/system/task_watchdog: - disable_test: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - esp_system examples/system/ulp/lp_core/gpio: enable: - if: SOC_LP_CORE_SUPPORTED == 1 + depends_components: + - ulp examples/system/ulp/lp_core/lp_i2c: enable: - if: SOC_LP_I2C_SUPPORTED == 1 + depends_components: + - ulp examples/system/ulp/lp_core/lp_uart/lp_uart_echo: disable: - if: SOC_ULP_LP_UART_SUPPORTED != 1 + depends_components: + - ulp examples/system/ulp/lp_core/lp_uart/lp_uart_print: disable: - if: SOC_ULP_LP_UART_SUPPORTED != 1 + depends_components: + - ulp examples/system/ulp/ulp_fsm/ulp: disable: - if: SOC_ULP_FSM_SUPPORTED != 1 + depends_components: + - ulp examples/system/ulp/ulp_fsm/ulp_adc: enable: - if: IDF_TARGET in ["esp32", "esp32s3"] temporary: true reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/adc: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 - temporary: true - reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/ds18b20_onewire: enable: - if: IDF_TARGET == "esp32s2" temporary: true reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/gpio: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 - temporary: true - reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/gpio_interrupt: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 - temporary: true - reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/i2c: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 + depends_components: + - ulp examples/system/ulp/ulp_riscv/touch: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 + depends_components: + - ulp examples/system/ulp/ulp_riscv/uart_print: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 + depends_components: + - ulp + +examples/system/unit_test/: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - unity examples/system/xip_from_psram: enable: diff --git a/examples/system/console/advanced/components/cmd_system/CMakeLists.txt b/examples/system/console/advanced/components/cmd_system/CMakeLists.txt index 4c0eae43a74..4fa5d30b917 100644 --- a/examples/system/console/advanced/components/cmd_system/CMakeLists.txt +++ b/examples/system/console/advanced/components/cmd_system/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register(SRCS "cmd_system.c" "cmd_system_common.c" INCLUDE_DIRS . - REQUIRES console spi_flash driver) + REQUIRES console spi_flash driver esp_driver_gpio) target_sources(${COMPONENT_LIB} PRIVATE cmd_system_sleep.c) diff --git a/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c3 b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c3 index 9ba5277387d..93a21dd5abd 100644 --- a/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c3 +++ b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c3 @@ -4,7 +4,6 @@ CONFIG_IDF_TARGET="esp32c3" # ESP32C3 supports SECURE_BOOT_V2 only in ECO3 CONFIG_ESP32C3_REV_MIN_3=y -CONFIG_ESP32C3_REV_MIN=3 CONFIG_PARTITION_TABLE_OFFSET=0xD000 CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c3 b/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c3 index 35dc608a612..c209bc98b60 100644 --- a/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c3 +++ b/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c3 @@ -4,7 +4,6 @@ CONFIG_IDF_TARGET="esp32c3" # ESP32C3 supports SECURE_BOOT_V2 only in ECO3 CONFIG_ESP32C3_REV_MIN_3=y -CONFIG_ESP32C3_REV_MIN=3 CONFIG_PARTITION_TABLE_OFFSET=0xC000 CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/examples/system/esp_timer/README.md b/examples/system/esp_timer/README.md index 6a6a075bf6f..63469493487 100644 --- a/examples/system/esp_timer/README.md +++ b/examples/system/esp_timer/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # High Resolution Timer Example (`esp_timer`) diff --git a/examples/system/eventfd/pytest_eventfd.py b/examples/system/eventfd/pytest_eventfd.py index 3bdb1d5bccd..8c0aa6a1042 100644 --- a/examples/system/eventfd/pytest_eventfd.py +++ b/examples/system/eventfd/pytest_eventfd.py @@ -8,13 +8,7 @@ from pytest_embedded import Dut -@pytest.mark.esp32 -@pytest.mark.esp32c2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 +@pytest.mark.supported_targets @pytest.mark.generic def test_eventfd(dut: Dut) -> None: diff --git a/examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c b/examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c index 03639c1b209..517177a64f5 100644 --- a/examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c +++ b/examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c @@ -53,7 +53,7 @@ static esp_err_t print_real_time_stats(TickType_t xTicksToWait) { TaskStatus_t *start_array = NULL, *end_array = NULL; UBaseType_t start_array_size, end_array_size; - uint32_t start_run_time, end_run_time; + configRUN_TIME_COUNTER_TYPE start_run_time, end_run_time; esp_err_t ret; //Allocate array to store current task states diff --git a/examples/system/freertos/real_time_stats/sdkconfig.ci b/examples/system/freertos/real_time_stats/sdkconfig.ci index c87713d246d..e69de29bb2d 100644 --- a/examples/system/freertos/real_time_stats/sdkconfig.ci +++ b/examples/system/freertos/real_time_stats/sdkconfig.ci @@ -1,2 +0,0 @@ -CONFIG_FREERTOS_USE_TRACE_FACILITY=y -CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y diff --git a/examples/system/freertos/real_time_stats/sdkconfig.defaults b/examples/system/freertos/real_time_stats/sdkconfig.defaults index c87713d246d..81c4a2635c7 100644 --- a/examples/system/freertos/real_time_stats/sdkconfig.defaults +++ b/examples/system/freertos/real_time_stats/sdkconfig.defaults @@ -1,2 +1,3 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64=y diff --git a/examples/system/heap_task_tracking/README.md b/examples/system/heap_task_tracking/README.md index 5113b3ea461..755d754fc57 100644 --- a/examples/system/heap_task_tracking/README.md +++ b/examples/system/heap_task_tracking/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Heap Task Tracking Example diff --git a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c index 52b70bff0e9..6cdb8845512 100644 --- a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c +++ b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c @@ -272,7 +272,7 @@ void app_main(void) #endif // CONFIG_BT_ENABLED #endif // CONFIG_EXAMPLE_CONNECT_WIFI -#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED) ESP_ERROR_CHECK(esp_ble_helper_init()); #endif diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c b/examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c index 02b0375f846..701a6c7768a 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c @@ -6,7 +6,7 @@ #include "sdkconfig.h" -#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED) #include "ble_api.h" #include "esp_log.h" diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c b/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c index c6c6482bcc2..ac4bdfa91cf 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c @@ -9,7 +9,7 @@ #include "esp_log.h" #include "string.h" -#if CONFIG_BT_BLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && CONFIG_BT_BLE_ENABLED static const char *TAG = "bluedroid_gatts"; static prepare_type_env_t a_prepare_write_env; diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h b/examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h index 740355c1e26..2dc59f4c86f 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h @@ -12,7 +12,7 @@ extern "C" { #endif -#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED) esp_err_t esp_ble_helper_init(void); #endif diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h b/examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h index b685a3d0312..2ebbcc8b587 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h @@ -9,7 +9,7 @@ #include "sdkconfig.h" -#if CONFIG_BT_BLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && CONFIG_BT_BLE_ENABLED #ifdef __cplusplus extern "C" { diff --git a/examples/system/select/README.md b/examples/system/select/README.md index 4518f097bb9..3abeb838b30 100644 --- a/examples/system/select/README.md +++ b/examples/system/select/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | 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 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Synchronous I/O multiplexing example diff --git a/examples/system/select/pytest_select.py b/examples/system/select/pytest_select.py index 3cefe3eb15b..367739d8eb7 100644 --- a/examples/system/select/pytest_select.py +++ b/examples/system/select/pytest_select.py @@ -20,8 +20,7 @@ def get_uart_msgs(i: int) -> List[str]: 'uart_select_example: {} bytes were received through UART1: {}'.format(len(msg), msg)] -@pytest.mark.esp32 -@pytest.mark.esp32c3 +@pytest.mark.supported_targets @pytest.mark.generic def test_examples_select(dut: Dut) -> None: diff --git a/examples/system/task_watchdog/pytest_task_watchdog.py b/examples/system/task_watchdog/pytest_task_watchdog.py index 91028453ced..0627967675c 100644 --- a/examples/system/task_watchdog/pytest_task_watchdog.py +++ b/examples/system/task_watchdog/pytest_task_watchdog.py @@ -5,13 +5,7 @@ from pytest_embedded import Dut -# IDF-5055 -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 +@pytest.mark.supported_targets @pytest.mark.generic def test_task_watchdog(dut: Dut) -> None: diff --git a/examples/system/ulp/lp_core/gpio/sdkconfig.defaults b/examples/system/ulp/lp_core/gpio/sdkconfig.defaults index b51373abf71..42aa360e61d 100644 --- a/examples/system/ulp/lp_core/gpio/sdkconfig.defaults +++ b/examples/system/ulp/lp_core/gpio/sdkconfig.defaults @@ -1,6 +1,6 @@ # Enable ULP CONFIG_ULP_COPROC_ENABLED=y -CONFIG_ULP_COPROC_LP_CORE=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y CONFIG_ULP_COPROC_RESERVE_MEM=4096 # Set log level to Warning to produce clean output CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y diff --git a/examples/system/ulp/ulp_fsm/ulp_adc/main/ulp/example_config.h b/examples/system/ulp/ulp_fsm/ulp_adc/main/ulp/example_config.h index 7613e780cc4..434bde230df 100644 --- a/examples/system/ulp/ulp_fsm/ulp_adc/main/ulp/example_config.h +++ b/examples/system/ulp/ulp_fsm/ulp_adc/main/ulp/example_config.h @@ -8,7 +8,7 @@ /* Ints are used here to be able to include the file in assembly as well */ #define EXAMPLE_ADC_CHANNEL 6 // ADC_CHANNEL_6, GPIO34 on ESP32, GPIO7 on ESP32-S3 #define EXAMPLE_ADC_UNIT 0 // ADC_UNIT_1 -#define EXAMPLE_ADC_ATTEN 3 // ADC_ATTEN_DB_11 +#define EXAMPLE_ADC_ATTEN 3 // ADC_ATTEN_DB_12 #define EXAMPLE_ADC_WIDTH 0 // ADC_BITWIDTH_DEFAULT /* Set low and high thresholds, approx. 1.35V - 1.75V*/ diff --git a/examples/system/ulp/ulp_riscv/adc/main/ulp/example_config.h b/examples/system/ulp/ulp_riscv/adc/main/ulp/example_config.h index 1f196756d67..2c6f0e4f321 100644 --- a/examples/system/ulp/ulp_riscv/adc/main/ulp/example_config.h +++ b/examples/system/ulp/ulp_riscv/adc/main/ulp/example_config.h @@ -9,7 +9,7 @@ #define EXAMPLE_ADC_CHANNEL ADC_CHANNEL_0 #define EXAMPLE_ADC_UNIT ADC_UNIT_1 -#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_11 +#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_12 #define EXAMPLE_ADC_WIDTH ADC_BITWIDTH_DEFAULT /* Set high threshold, approx. 1.75V*/ diff --git a/examples/system/ulp/ulp_riscv/i2c/README.md b/examples/system/ulp/ulp_riscv/i2c/README.md index 11ba448c066..a1496bd3eca 100644 --- a/examples/system/ulp/ulp_riscv/i2c/README.md +++ b/examples/system/ulp/ulp_riscv/i2c/README.md @@ -7,13 +7,28 @@ This example demonstrates how to use the RTC I2C peripheral from the ULP RISC-V The ULP program is based on the BMP180 Temperature and Pressure sensor (https://cz.mouser.com/datasheet/2/783/BST-BMP180-DS000-1509579.pdf) which has an I2C interface. The main CPU initializes the RTC I2C peripheral, the BMP180 sensor and loads the ULP program. It then goes into deep sleep. -The ULP program periodically measures the temperature and pressure values from the BMP180 sensor and wakesup the main CPU when the values are above a certain thershold. +The ULP program periodically measures the temperature and pressure values from the BMP180 sensor and wakes up the main CPU when the values are above a certain threshold. + +## How to use example + ### Hardware Required * A development board with a SOC which has a RISC-V ULP coprocessor (e.g., ESP32-S2 Saola) * A BMP180 sensor module * A USB cable for power supply and programming +#### Pin Assignment: + +**Note:** The following pin assignments are used by default. + +| | SDA | SCL | +| --------------------------- | ------| ------| +| ESP32-S2/S3 RTC I2C Master | GPIO3 | GPIO2 | +| BMP180 Sensor | SDA | SCL | + +**Note:** The SDA line can only be configured to use either GPIO1 or GPIO3 and the SCL line can only be configured to use either GPIO0 or GPIO2. +**Note:** This example enables the internal pull-up resistors for the SDA/SCL lines by default. + ## Example output Below is the output from this example. diff --git a/examples/system/ulp/ulp_riscv/touch/README.md b/examples/system/ulp/ulp_riscv/touch/README.md index d8d9afb923f..7c3694b9065 100644 --- a/examples/system/ulp/ulp_riscv/touch/README.md +++ b/examples/system/ulp/ulp_riscv/touch/README.md @@ -17,6 +17,30 @@ The ULP Program scans all touch pad sensors periodically. When the ULP program f * A development board with ESP32-S2 or ESP32-S3 +The following capacitive touch pads are supported on ESP32-S2/S3: + +``` + ---------------------------------------------------------- + | Touch Pad | GPIO Pin | + |------------|-------------------------------------------| + | T0 | Internal channel, not connected to a GPIO | + | T1 | GPIO1 | + | T2 | GPIO2 | + | T3 | GPIO3 | + | T4 | GPIO4 | + | T5 | GPIO5 | + | T6 | GPIO6 | + | T7 | GPIO7 | + | T8 | GPIO8 | + | T9 | GPIO9 | + | T10 | GPIO10 | + | T11 | GPIO11 | + | T12 | GPIO12 | + | T13 | GPIO13 | + | T14 | GPIO14 | + ---------------------------------------------------------- +``` + ### Build and Flash Build the project and flash it to the board, then run monitor tool to view serial output: diff --git a/examples/system/ulp/ulp_riscv/uart_print/sdkconfig.defaults b/examples/system/ulp/ulp_riscv/uart_print/sdkconfig.defaults index a28f71162ea..e3745e50576 100644 --- a/examples/system/ulp/ulp_riscv/uart_print/sdkconfig.defaults +++ b/examples/system/ulp/ulp_riscv/uart_print/sdkconfig.defaults @@ -1,6 +1,6 @@ # Enable ULP CONFIG_ULP_COPROC_ENABLED=y -CONFIG_ULP_COPROC_RISCV=y +CONFIG_ULP_COPROC_TYPE_RISCV=y CONFIG_ULP_COPROC_RESERVE_MEM=4096 # Set log level to Warning to produce clean output CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y diff --git a/tools/ci/artifacts_handler.py b/tools/ci/artifacts_handler.py index 070a88e5ca3..496e88e6b89 100644 --- a/tools/ci/artifacts_handler.py +++ b/tools/ci/artifacts_handler.py @@ -21,6 +21,7 @@ class ArtifactType(str, Enum): LOGS = 'logs' SIZE_REPORTS = 'size_reports' + JUNIT_REPORTS = 'junit_reports' TYPE_PATTERNS_DICT = { @@ -48,6 +49,9 @@ class ArtifactType(str, Enum): '**/build*/size.json', 'size_info.txt', ], + ArtifactType.JUNIT_REPORTS: [ + 'XUNIT_RESULT.xml', + ], } diff --git a/tools/ci/check_build_test_rules.py b/tools/ci/check_build_test_rules.py index 11e964d1cb0..080ce2ad550 100755 --- a/tools/ci/check_build_test_rules.py +++ b/tools/ci/check_build_test_rules.py @@ -481,6 +481,7 @@ def check_exist() -> None: ) if arg.action == 'check-readmes': + os.environ['INCLUDE_NIGHTLY_RUN'] = '1' os.environ['NIGHTLY_RUN'] = '1' check_readme( list(check_dirs), @@ -489,6 +490,7 @@ def check_exist() -> None: ) elif arg.action == 'check-test-scripts': os.environ['INCLUDE_NIGHTLY_RUN'] = '1' + os.environ['NIGHTLY_RUN'] = '1' check_test_scripts( list(check_dirs), exclude_dirs=_exclude_dirs, diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index d50a18ca49c..0dd14e756db 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -546,7 +546,6 @@ components/freertos/FreeRTOS-Kernel-SMP/timers.c components/hal/include/hal/dac_types.h components/hal/spi_slave_hal.c components/hal/spi_slave_hal_iram.c -components/hal/test/test_mpu.c components/heap/test_multi_heap_host/main.cpp components/heap/test_multi_heap_host/test_multi_heap.cpp components/idf_test/include/idf_performance.h @@ -667,7 +666,6 @@ components/soc/esp32c3/include/soc/fe_reg.h components/soc/esp32c3/include/soc/gpio_reg.h components/soc/esp32c3/include/soc/gpio_struct.h components/soc/esp32c3/include/soc/i2c_reg.h -components/soc/esp32c3/include/soc/i2c_struct.h components/soc/esp32c3/include/soc/interrupt_core0_reg.h components/soc/esp32c3/include/soc/ledc_reg.h components/soc/esp32c3/include/soc/nrx_reg.h @@ -834,7 +832,6 @@ components/wifi_provisioning/python/wifi_scan_pb2.py components/wifi_provisioning/src/scheme_console.c components/wifi_provisioning/src/wifi_config.c components/wifi_provisioning/src/wifi_scan.c -components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h components/wpa_supplicant/esp_supplicant/src/esp_wpa_err.h components/wpa_supplicant/include/utils/wpa_debug.h components/wpa_supplicant/include/utils/wpabuf.h diff --git a/tools/ci/ignore_build_warnings.txt b/tools/ci/ignore_build_warnings.txt index 0f2daf214b8..301da338fa9 100644 --- a/tools/ci/ignore_build_warnings.txt +++ b/tools/ci/ignore_build_warnings.txt @@ -15,3 +15,88 @@ CryptographyDeprecationWarning Warning: \d+/\d+ app partitions are too small for binary CMake Deprecation Warning at main/lib/tinyxml2/CMakeLists\.txt:11 \(cmake_policy\) The smallest .+ partition is nearly full \(\d+% free space left\)! +warning: unknown kconfig symbol 'A2DP_SINK_ENABLE' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults +warning: unknown kconfig symbol 'A2DP_SRC_ENABLE' assigned to 'n' in /builds/espressif/esp-idf/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults +warning: unknown kconfig symbol 'APP_OFFSET' assigned to '0x10000' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'BLE_ENABLE_SRVCHG_REG' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults +warning: unknown kconfig symbol 'BT_CTRL_BLE_MESH_SCAN_DUPL_EN' assigned to* +warning: unknown kconfig symbol 'BT_CTRL_COEX_PARAMETERS_ENABLE' assigned to* +warning: unknown kconfig symbol 'BT_CTRL_COEX_USE_HOOKS' assigned to* +warning: unknown kconfig symbol 'BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE' assigned to* +warning: unknown kconfig symbol 'BT_LE_50_FEATURE_SUPPORT' assigned to* +warning: unknown kconfig symbol 'BT_LE_MAX_EXT_ADV_INSTANCES' assigned to* +warning: unknown kconfig symbol 'BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER' assigned to 'n' in /builds/espressif/esp-idf/examples/bluetooth/nimble/power_save/sdkconfig.defaults.* +warning: unknown kconfig symbol 'BTDM_BLE_MESH_SCAN_DUPL_EN' assigned to* +warning: unknown kconfig symbol 'BTDM_CTRL_HCI_MODE_VHCI' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_hid_device/sdkconfig.defaults +warning: unknown kconfig symbol 'BTDM_CTRL_HCI_MODE_VHCI' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_hid_host/sdkconfig.defaults +warning: unknown kconfig symbol 'BTDM_CTRL_MODE_BLE_ONLY' assigned to* +warning: unknown kconfig symbol 'BTDM_CTRL_MODE_BR_EDR_ONLY' assigned to* +warning: unknown kconfig symbol 'BTDM_CTRL_MODE_BTDM' assigned to* +warning: unknown kconfig symbol 'BTDM_MODEM_SLEEP' assigned to* +warning: unknown kconfig symbol 'BTDM_SCAN_DUPL_TYPE_DATA_DEVICE' assigned to* +warning: unknown kconfig symbol 'CTRL_BTDM_MODEM_SLEEP' assigned to* +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_240' assigned to 'y' in /builds/espressif/esp-idf/components/vfs/test_apps/* +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_240' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/wifi_coexist/ +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_80' assigned to 'y' in /builds/espressif/esp-idf/examples/system/deep_sleep/* +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_80' assigned to 'y' in /builds/espressif/esp-idf/examples/system/light_sleep/* +warning: unknown kconfig symbol 'ESP_WIFI_SW_COEXIST_PREFERENCE_BALANCE' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESP_WIFI_SW_COEXIST_PREFERENCE_VALUE' assigned to '2' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/fast_provisioning/fast_prov_server/sdkconfig.ci.iram +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/fast_provisioninging/fast_prov_server/sdkconfig.ci.iram +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/nimble/ble_htp/htp_prph/sdkconfig.ci +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/sdkconfig.ci +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/nimble/blehr/sdkconfig.ci +warning: unknown kconfig symbol 'ESP32_REV_MIN_3' assigned to 'y' in /builds/espressif/esp-idf/examples/system/ota/simple_ota_example/sdkconfig.ci.on_update_no_sb_rsa +warning: unknown kconfig symbol 'ESP32_REV_MIN' assigned to '3' in /builds/espressif/esp-idf/examples/system/ota/simple_ota_example/sdkconfig.ci.on_update_no_sb_rsa +warning: unknown kconfig symbol 'ESP32H4_RTC_CLK_CAL_CYCLES' assigned to '576' in /builds/espressif/esp-idf/examples/bluetooth/nimble/blecent/sdkconfig.defaults.esp32h4 +warning: unknown kconfig symbol 'ESP32H4_RTC_CLK_SRC_EXT_CRYS' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/nimble/blecent/sdkconfig.defaults.esp32h4 +warning: unknown kconfig symbol 'ESPTOOLPY_BAUD_921600B' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE_4MB' assigned to 'y' in /builds/espressif/esp-idf/components/esp_partition/host_test/partition_api_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE_4MB' assigned to 'y' in /builds/espressif/esp-idf/components/spiffs/host_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE' assigned to '"4MB"' in /builds/espressif/esp-idf/components/esp_partition/host_test/partition_api_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE' assigned to '"4MB"' in /builds/espressif/esp-idf/components/spiffs/host_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE' assigned to '"8MB"' in /builds/espressif/esp-idf/components/wear_levelling/host_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_MONITOR_BAUD_921600B' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/vendor_models/* +warning: unknown kconfig symbol 'FMB_TIMER_GROUP' assigned to '0' in /builds/espressif/esp-idf/examples/protocols/modbus/tcp/* +warning: unknown kconfig symbol 'FMB_TIMER_INDEX' assigned to '0' in /builds/espressif/esp-idf/examples/protocols/modbus/tcp/* +warning: unknown kconfig symbol 'FMB_TIMER_ISR_IN_IRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/modbus/* +warning: unknown kconfig symbol 'LIBSODIUM_USE_MBEDTLS_SHA' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_br/* +warning: unknown kconfig symbol 'LIBSODIUM_USE_MBEDTLS_SHA' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_cli/* +warning: unknown kconfig symbol 'LIBSODIUM_USE_MBEDTLS_SHA' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_rcp/* +warning: unknown kconfig symbol 'LWIP_ETHARP_TRUST_IP_MAC' assigned to 'n' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/* +warning: unknown kconfig symbol 'LWIP_ETHARP_TRUST_IP_MAC' assigned to 'n' in /builds/espressif/esp-idf/examples/wifi/iperf/* +warning: unknown kconfig symbol 'LWIP_ETHARP_TRUST_IP_MAC' assigned to 'n' in /builds/espressif/esp-idf/idf-app-test/apps/iperf/* +warning: unknown kconfig symbol 'LWIP_IP_FRAG' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'LWIP_IP_REASSEMBLY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'MB_SLAVE_IP_FROM_STDIN' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/modbus/* +warning: unknown kconfig symbol 'MDNS_STRICT_MODE' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_br/* +warning: unknown kconfig symbol 'OPENTHREAD_TREL' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_br/* +warning: unknown kconfig symbol 'PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET' assigned to '0x10000' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'SDK_MAKE_WARN_UNDEFINED_VARIABLES' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'SPI_FLASH_USE_LEGACY_IMPL' assigned to '1' in /builds/espressif/esp-idf/components/wear_levelling/host_test/sdkconfig.defaults +warning: unknown kconfig symbol 'SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/fast_provisioning/fast_prov_server/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_FETCH_INSTRUCTIONS' assigned to 'y' in /builds/espressif/esp-idf/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_IGNORE_NOTFOUND' assigned to 'y' in /builds/espressif/esp-idf/examples/network/simple_sniffer/sdkconfig.ci.mem +warning: unknown kconfig symbol 'SPIRAM_MALLOC_ALWAYSINTERNAL' assigned to '0' in /builds/espressif/esp-idf/components/fatfs/test_apps/flash_wl/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_MALLOC_ALWAYSINTERNAL' assigned to '0' in /builds/espressif/esp-idf/components/fatfs/test_apps/sdcard/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_MALLOC_ALWAYSINTERNAL' assigned to '0' in /builds/espressif/esp-idf/components/spiffs/test_apps/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_MALLOC_ALWAYSINTERNAL' assigned to '0' in /builds/espressif/esp-idf/components/vfs/test_apps/* +warning: unknown kconfig symbol 'SPIRAM_MALLOC_RESERVE_INTERNAL' assigned to '150000' in /builds/espressif/esp-idf/examples/peripherals/usb/host/uvc/sdkconfig.defaults +warning: unknown kconfig symbol 'SPIRAM_RODATA' assigned to 'y' in /builds/espressif/esp-idf/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_TRY_ALLOCATE_WIFI_LWIP' assigned to 'y' in /builds/espressif/esp-idf/examples/peripherals/usb/host/uvc/sdkconfig.defaults +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/components/fatfs/test_apps/flash_wl/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/components/fatfs/test_apps/sdcard/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/components/spiffs/test_apps/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/components/vfs/test_apps/* +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/fast_provisioning/fast_prov_server/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/network/simple_sniffer/sdkconfig.ci.mem +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/peripherals/usb/host/uvc/sdkconfig.defaults +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/http2_request/sdkconfig.ci +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/https_mbedtls/sdkconfig.ci +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/https_request/sdkconfig.ci +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/https_request/sdkconfig.ci.ssldyn +warning: unknown kconfig symbol 'TINYUSB' assigned to 'y' in /builds/espressif/esp-idf/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/sdkconfig.defaults +warning: unknown kconfig symbol 'UNITY_FREERTOS_STACK_SIZE' assigned to '12288' in /builds/espressif/esp-idf/components/bt/test_apps/sdkconfig.defaults +warning: unknown kconfig symbol 'WIFI_ENABLED' assigned to 'n' in /builds/espressif/esp-idf/examples/bluetooth/bluedroid/classic_bt/* +warning: unknown kconfig symbol 'WPA3_SAE' assigned to 'y' in /builds/espressif/esp-idf/components/wpa_supplicant/test_apps/sdkconfig.defaults +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_80' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_sleepy_device/deep_sleep/sdkconfig.defaults diff --git a/tools/ci/integration_test/KnownIssues b/tools/ci/integration_test/KnownIssues deleted file mode 100644 index 186b7a90c39..00000000000 --- a/tools/ci/integration_test/KnownIssues +++ /dev/null @@ -1,12 +0,0 @@ -# CI -ESP32.BLUEDROID_GAP_03003 -ESP32.NIMBLE_GAP_11002 -ESP32.NIMBLE_GAP_14007 - -ESP32C3.NIMBLE_GAP_14009 - -ESP32C2.NIMBLE_GAP_03001 -ESP32C2.NIMBLE_GAP_03004 -ESP32C2.BLUEDROID_GAP_23004 -ESP32C2.BLUEDROID_GAP_03001 -ESP32C2.BLUEDROID_GAP_03004 diff --git a/tools/ci/integration_test/README.md b/tools/ci/integration_test/README.md deleted file mode 100644 index 40d81e78c49..00000000000 --- a/tools/ci/integration_test/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Integration Test Description - -## Case Lists -- WiFi Standard cases for only esp32. -- BLE Standard cases for esp32 and esp32c3. - -## Trigger -- By labels: - - `integration_test[_wifi/ble]` -- By file changes: - - integration test related files - - See `patterns-integration_test[_wifi/ble]` in `.gitlab/ci/rules.yml` diff --git a/tools/cmake/version.cmake b/tools/cmake/version.cmake index 037b9c088fe..4db536bdaa5 100644 --- a/tools/cmake/version.cmake +++ b/tools/cmake/version.cmake @@ -1,5 +1,5 @@ set(IDF_VERSION_MAJOR 5) -set(IDF_VERSION_MINOR 2) +set(IDF_VERSION_MINOR 3) set(IDF_VERSION_PATCH 0) set(ENV{IDF_VERSION} "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}") diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 8ce979b8cdb..f81ede10675 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -68,6 +68,7 @@ RUN echo IDF_CHECKOUT_REF=$IDF_CHECKOUT_REF IDF_CLONE_BRANCH_OR_TAG=$IDF_CLONE_B ${IDF_CLONE_SHALLOW:+--depth=1 --shallow-submodules} \ ${IDF_CLONE_BRANCH_OR_TAG:+-b $IDF_CLONE_BRANCH_OR_TAG} \ $IDF_CLONE_URL $IDF_PATH && \ + git config --system --add safe.directory $IDF_PATH && \ if [ -n "$IDF_CHECKOUT_REF" ]; then \ cd $IDF_PATH && \ if [ -n "$IDF_CLONE_SHALLOW" ]; then \ diff --git a/tools/idf.py b/tools/idf.py index 9ab0d90f57c..1ddf6b0c95b 100755 --- a/tools/idf.py +++ b/tools/idf.py @@ -105,6 +105,15 @@ def check_environment() -> List: debug_print_idf_version() raise SystemExit(1) + # Check used Python interpreter + checks_output.append('Checking used Python interpreter...') + try: + python_venv_path = os.environ['IDF_PYTHON_ENV_PATH'] + if python_venv_path and not sys.executable.startswith(python_venv_path): + print_warning(f'WARNING: Python interpreter "{sys.executable}" used to start idf.py is not from installed venv "{python_venv_path}"') + except KeyError: + print_warning('WARNING: The IDF_PYTHON_ENV_PATH is missing in environmental variables!') + return checks_output diff --git a/tools/idf_py_actions/debug_ext.py b/tools/idf_py_actions/debug_ext.py index 65619bef0ee..db7083c4696 100644 --- a/tools/idf_py_actions/debug_ext.py +++ b/tools/idf_py_actions/debug_ext.py @@ -584,7 +584,7 @@ def coredump_debug(action: str, gdb_timeout_sec_opt = { 'names': ['--gdb-timeout-sec'], 'type': INT, - 'default': 1, + 'default': 3, 'help': 'Overwrite the default internal delay for gdb responses', } fail_if_openocd_failed = { diff --git a/tools/idf_py_actions/hints.yml b/tools/idf_py_actions/hints.yml index e1053bcf7f8..28020658b5b 100644 --- a/tools/idf_py_actions/hints.yml +++ b/tools/idf_py_actions/hints.yml @@ -275,6 +275,35 @@ re: "warning: 'esp_vfs_fat_sdmmc_unmount' is deprecated: Please use esp_vfs_fat_sdcard_unmount instead [-Wdeprecated-declarations]" hint: "``esp_vfs_fat_sdmmc_unmount()`` is now deprecated, you can use :cpp:func:`esp_vfs_fat_sdcard_unmount()` instead. See Storage migration guide 5.1 for more details" +- + re: "vfs_fat_sdmmc: sdmmc_card_init failed" + hint: "Please verify if there is an SD card inserted into the SD slot. Then, try rebooting the board." + +- + re: "sdmmc_common: sdmmc_init_ocr: send_op_cond" + hint: "Please reboot the board and then try again" + +- + re: "sdmmc_io: sdmmc_io_read_byte: sdmmc_io_rw_direct" + hint: "Please verify that card supports IO capabilities. Refer 'IDF_PATH/examples/peripherals/sdio/host/README.md' for more details" + +- + re: "example: Failed to initialize the card \\({}\\). Make sure SD card lines have pull-up resistors in place." + hint: "Please refer ./README.md for details" + variables: + - + re_variables: ['ESP_ERR_TIMEOUT'] + hint_variables: [] + - + re_variables: ['ESP_ERR_INVALID_RESPONSE'] + hint_variables: [] + - + re_variables: ['ESP_ERR_INVALID_STATE'] + hint_variables: [] + - + re_variables: ['ESP_ERR_INVALID_ARG'] + hint_variables: [] + - re: "esp_usb_jtag: could not find or open device!" hint: "Please check the wire connection to debugging device or access rights to a serial port." diff --git a/tools/idf_tools.py b/tools/idf_tools.py index e4be2a98402..f55a8811f1f 100755 --- a/tools/idf_tools.py +++ b/tools/idf_tools.py @@ -1802,6 +1802,15 @@ def action_export(args): # type: ignore if paths_to_export: export_vars['PATH'] = path_sep.join(to_shell_specific_paths(paths_to_export) + [old_path]) + # Correct PATH order check for Windows platform + # idf-exe has to be before \tools in PATH + if sys.platform == 'win32': + paths_to_check = rf"{export_vars['PATH']}{os.environ['PATH']}" + try: + if paths_to_check.index(r'\tools;') < paths_to_check.index(r'\idf-exe'): + warn('The PATH is not in correct order (idf-exe should be before esp-idf\\tools)') + except ValueError: + fatal(f'Both of the directories (..\\idf-exe\\.. and ..\\tools) has to be in the PATH:\n\n{paths_to_check}\n') if export_vars: # if not copy of export_vars is given to function, it brekas the formatting string for 'export_statements' diff --git a/tools/mocks/driver/CMakeLists.txt b/tools/mocks/driver/CMakeLists.txt index 7460356fefc..5733e1b34c8 100644 --- a/tools/mocks/driver/CMakeLists.txt +++ b/tools/mocks/driver/CMakeLists.txt @@ -5,14 +5,14 @@ message(STATUS "building DRIVER MOCKS (only SPI master, I2C, RMT, USB-serial and idf_component_get_property(original_driver_dir driver COMPONENT_OVERRIDEN_DIR) set(include_dirs + "${IDF_PATH}/components/esp_driver_gpio/include/driver" + "${IDF_PATH}/components/esp_driver_gpio/include" "${original_driver_dir}/i2c/include/driver" "${original_driver_dir}/spi/include/driver" - "${original_driver_dir}/gpio/include/driver" "${original_driver_dir}/rmt/include/driver" "${original_driver_dir}/usb_serial_jtag/include/driver" "${original_driver_dir}/i2c/include" "${original_driver_dir}/spi/include" - "${original_driver_dir}/gpio/include" "${original_driver_dir}/rmt/include" "${original_driver_dir}/usb_serial_jtag/include" "${CMAKE_CURRENT_SOURCE_DIR}/../hal/include") @@ -20,10 +20,10 @@ set(include_dirs idf_component_mock(INCLUDE_DIRS ${include_dirs} REQUIRES freertos MOCK_HEADER_FILES + ${IDF_PATH}/components/esp_driver_gpio/include/driver/gpio.h ${original_driver_dir}/spi/include/driver/spi_master.h ${original_driver_dir}/spi/include/driver/spi_common.h ${original_driver_dir}/i2c/include/driver/i2c.h - ${original_driver_dir}/gpio/include/driver/gpio.h ${original_driver_dir}/rmt/include/driver/rmt_rx.h ${original_driver_dir}/rmt/include/driver/rmt_tx.h ${original_driver_dir}/rmt/include/driver/rmt_common.h diff --git a/tools/test_apps/.build-test-rules.yml b/tools/test_apps/.build-test-rules.yml index f659a0a6377..faef23a9e21 100644 --- a/tools/test_apps/.build-test-rules.yml +++ b/tools/test_apps/.build-test-rules.yml @@ -15,10 +15,6 @@ tools/test_apps/linux_compatible/driver_mock: enable: - if: IDF_TARGET == "linux" -tools/test_apps/linux_compatible/hello_world_linux_compatible: - enable: - - if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "linux" - tools/test_apps/linux_compatible/linux_freertos: enable: - if: IDF_TARGET == "linux" @@ -177,12 +173,6 @@ tools/test_apps/system/panic: temporary: true reason: target(s) not supported yet # TODO: IDF-7511 -tools/test_apps/system/ram_loadable_app: - disable: - - if: IDF_TARGET == "esp32h2" - temporary: true - reason: lack of runners - tools/test_apps/system/startup: disable: - if: CONFIG_NAME == "main_task_cpu1" and IDF_TARGET not in ["esp32", "esp32s3"] diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/README.md b/tools/test_apps/linux_compatible/hello_world_linux_compatible/README.md deleted file mode 100644 index c0152d05416..00000000000 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/README.md +++ /dev/null @@ -1,45 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | Linux | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ----- | - -# Hello World Example Compatible with POSIX-port - -This is a version of the "Hello World" example compatible with the linux target. Just by using `idf.py (--preview) set-target `, it can be compiled for chip targets as well as for the [FreeRTOS POSIX/Linux simulator](https://www.freertos.org/FreeRTOS-simulator-for-Linux.html), i.e., for running it on Linux. The applications can then be run on the chosen target. - -## Requirements - -If you want to use this example on Linux, you need a Linux machine as host. The remaining requirements are the same requirements as for [Unit Testing on Linux (using cmock)](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/linux-host-testing.html#requirements), except you do not need Ruby. - -## How to use example - -### Configure the project - -No special configuration is required, we also do not recommend changing configuration when compiled for the POSIX/Linux simulator as this is still in preview. If you have to configure something, use the usual IDF menuconfig: -``` -idf.py menuconfig -``` - -### Build and Flash - -You can compile this example for chip targets, e.g. ESP32 and then run it by using: -``` -idf.py set-target esp32 -idf.py build -idf.py -p flash monitor -``` - -If you want to build this example for the linux target and run it, use the same commands except setting the linux target and omitting the flash command: -``` -idf.py --preview set-target linux -idf.by build -idf.py monitor -``` -The linux target is still in preview, hence the necessary `--preview` argument. Flashing can be omitted on Linux. - - -## Example folder contents - -The files in this project have the same structure as the files in the [original Hello World application](../../../../examples/get-started/hello_world/). - -## Example Output - -The output is similar to the output of the [original Hello World application](../../../../examples/get-started/hello_world/), except that no chip information is printed and there won't be any bootloader output on the linux target. diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/CMakeLists.txt b/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/CMakeLists.txt deleted file mode 100644 index 07686dc8e11..00000000000 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "hello_world_main.c" - INCLUDE_DIRS "") diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/hello_world_main.c b/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/hello_world_main.c deleted file mode 100644 index d8696bba6e1..00000000000 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/hello_world_main.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: CC0-1.0 - */ - -#include -#include -#include "sdkconfig.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_chip_info.h" -#include "esp_system.h" - -void app_main(void) -{ - printf("Hello world!\n"); - - /* Print chip information */ - esp_chip_info_t chip_info; - uint32_t flash_size; - esp_chip_info(&chip_info); - printf("This is %s chip with %d CPU core(s), WiFi%s%s%s, ", - CONFIG_IDF_TARGET, - chip_info.cores, - (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", - (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "", - (chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : ""); - - unsigned major_rev = chip_info.revision / 100; - unsigned minor_rev = chip_info.revision % 100; - printf("silicon revision v%d.%d, ", major_rev, minor_rev); - - /* get_flash_size API not available on Linux*/ - flash_size = UINT32_MAX; - - printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024), - (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); - - printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size()); - - for (int i = 10; i >= 0; i--) { - printf("Restarting in %d seconds...\n", i); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - printf("Restarting now.\n"); - fflush(stdout); - esp_restart(); -} diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/pytest_hello_world_linux_compatible.py b/tools/test_apps/linux_compatible/hello_world_linux_compatible/pytest_hello_world_linux_compatible.py deleted file mode 100644 index a73a140314b..00000000000 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/pytest_hello_world_linux_compatible.py +++ /dev/null @@ -1,17 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: CC0-1.0 - -import pytest -from pytest_embedded_idf.dut import IdfDut - - -@pytest.mark.supported_targets -@pytest.mark.generic -def test_hello_world_linux_compatible(dut: IdfDut) -> None: - dut.expect('Hello world!') - - -@pytest.mark.linux -@pytest.mark.host_test -def test_hello_world_linux(dut: IdfDut) -> None: - dut.expect('Hello world!') diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/sdkconfig.defaults b/tools/test_apps/linux_compatible/hello_world_linux_compatible/sdkconfig.defaults deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tools/test_apps/system/g1_components/CMakeLists.txt b/tools/test_apps/system/g1_components/CMakeLists.txt index 2c1925c027d..582efb40ad0 100644 --- a/tools/test_apps/system/g1_components/CMakeLists.txt +++ b/tools/test_apps/system/g1_components/CMakeLists.txt @@ -33,9 +33,9 @@ set(extra_components_which_shouldnt_be_included bootloader_support # [refactor-todo]: should cxx be in G1? Can it exist without FreeRTOS? cxx - # [refactor-todo]: driver is a dependency of esp_pm, esp_timer, spi_flash, vfs, esp_wifi, ${IDF_TARGET} + # [refactor-todo]: driver is a dependency of esp_pm, spi_flash, vfs, esp_wifi # all of these should be removed from G1 except for spi_flash. - driver + driver esp_driver_gpio esp_driver_pcnt esp_driver_gptimer # esp_app_format is dependency of bootloader_support, app_update esp_app_format # esp_bootloader_format is dependency of bootloader_support, app_update 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 1121a626481..6b681a4f5e6 100644 --- a/tools/test_apps/system/panic/main/include/test_panic.h +++ b/tools/test_apps/system/panic/main/include/test_panic.h @@ -53,6 +53,8 @@ void test_assert(void); void test_assert_cache_disabled(void); +void test_illegal_access(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 d97d7341731..ac4120d7b6d 100644 --- a/tools/test_apps/system/panic/main/test_app_main.c +++ b/tools/test_apps/system/panic/main/test_app_main.c @@ -100,6 +100,9 @@ void app_main(void) HANDLE_TEST(test_name, test_ub); HANDLE_TEST(test_name, test_assert); HANDLE_TEST(test_name, test_assert_cache_disabled); +#if CONFIG_IDF_TARGET_ESP32 + HANDLE_TEST(test_name, test_illegal_access); +#endif #if CONFIG_TEST_MEMPROT diff --git a/tools/test_apps/system/panic/main/test_panic.c b/tools/test_apps/system/panic/main/test_panic.c index 9c33b74cca2..655f9bd42aa 100644 --- a/tools/test_apps/system/panic/main/test_panic.c +++ b/tools/test_apps/system/panic/main/test_panic.c @@ -19,6 +19,8 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "hal/mpu_hal.h" + /* Test utility function */ extern void esp_restart_noos(void) __attribute__ ((noreturn)); @@ -202,3 +204,31 @@ void test_ub(void) uint8_t stuff[1] = {rand()}; printf("%d\n", stuff[rand()]); } + +/* NOTE: The following test verifies the behaviour for the + * Xtensa-specific MPU instructions (Refer WDTLB, DSYNC, WDTIB, ISYNC) + * used for memory protection. + * + * However, this test is not valid for S2 and S3, because they have PMS + * enabled on top of this, giving unpredicatable results. + */ +#if CONFIG_IDF_TARGET_ESP32 +void test_illegal_access(void) +{ + intptr_t addr = 0x80000000; // MPU region 4 + volatile int __attribute__((unused)) val = INT16_MAX; + + // Marked as an illegal access region at startup in ESP32, ESP32S2. + // Make accessible temporarily. + mpu_hal_set_region_access(4, MPU_REGION_RW); + + val = *((int*) addr); + printf("[1] val: %d at %p\n", val, (void *)addr); + + // Make access to region illegal again. + mpu_hal_set_region_access(4, MPU_REGION_ILLEGAL); + val = *((int*) addr); + // Does not reach here as device resets due to illegal access + printf("[2] val: %d at %p\n", val, (void *)addr); +} +#endif diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index e1de4a805cc..3f110d4e018 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -822,3 +822,17 @@ def test_hw_stack_guard_cpu0(dut: PanicTestDut, config: str, test_func_name: str dut.expect_exact('Stack pointer: 0x') dut.expect(r'Stack bounds: 0x(.*) - 0x') common_test(dut, config) + + +@pytest.mark.esp32 +@pytest.mark.parametrize('config', ['panic'], indirect=True) +@pytest.mark.generic +def test_illegal_access(dut: PanicTestDut, config: str, test_func_name: str) -> None: + dut.run_test_func(test_func_name) + if dut.is_xtensa: + dut.expect(r'\[1\] val: (-?\d+) at 0x80000000', timeout=30) + dut.expect_gme('LoadProhibited') + dut.expect_reg_dump(0) + dut.expect_backtrace() + dut.expect_elf_sha256() + dut.expect_none('Guru Meditation') diff --git a/tools/test_apps/system/ram_loadable_app/README.md b/tools/test_apps/system/ram_loadable_app/README.md index f5350571549..0283938f981 100644 --- a/tools/test_apps/system/ram_loadable_app/README.md +++ b/tools/test_apps/system/ram_loadable_app/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # RAM loadable app Example diff --git a/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py b/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py index 71953f16f26..22b6011a38e 100644 --- a/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py +++ b/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py @@ -5,12 +5,7 @@ from pytest_embedded_idf.dut import IdfDut -@pytest.mark.esp32 -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 +@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['pure_ram',], indirect=True,) def test_pure_ram_loadable_app(dut: IdfDut) -> None: @@ -18,11 +13,7 @@ def test_pure_ram_loadable_app(dut: IdfDut) -> None: dut.expect('Time since boot: 3 seconds...', timeout=10) -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 +@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['defaults',], indirect=True,) def test_ram_loadable_app(dut: IdfDut) -> None: diff --git a/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 b/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 deleted file mode 100644 index d2816a3ebd6..00000000000 --- a/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG_APP_BUILD_TYPE_RAM=y - -# Reset is meaningless to ram_app -CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y - -CONFIG_APP_BUILD_TYPE_PURE_RAM_APP=y diff --git a/tools/unit-test-app/components/test_utils/CMakeLists.txt b/tools/unit-test-app/components/test_utils/CMakeLists.txt index 27748db9ed2..860cbf717fb 100644 --- a/tools/unit-test-app/components/test_utils/CMakeLists.txt +++ b/tools/unit-test-app/components/test_utils/CMakeLists.txt @@ -16,5 +16,7 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS include REQUIRES esp_partition idf_test cmock - PRIV_REQUIRES perfmon driver esp_netif) + PRIV_REQUIRES perfmon esp_driver_pcnt esp_driver_gptimer esp_netif + driver # TODO: replace with esp_driver_rmt + ) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/tools/unit-test-app/sdkconfig.defaults b/tools/unit-test-app/sdkconfig.defaults index 59e5fa46bfb..fc6ce0a1c6e 100644 --- a/tools/unit-test-app/sdkconfig.defaults +++ b/tools/unit-test-app/sdkconfig.defaults @@ -1,6 +1,5 @@ CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y -CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=n CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partition_table_unit_test_app.csv" CONFIG_PARTITION_TABLE_FILENAME="partition_table_unit_test_app.csv" @@ -18,4 +17,3 @@ CONFIG_COMPILER_WARN_WRITE_STRINGS=y CONFIG_SPI_MASTER_IN_IRAM=y CONFIG_EFUSE_VIRTUAL=y CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y -CONFIG_MQTT_TEST_BROKER_URI="mqtt://${EXAMPLE_MQTT_BROKER_TCP}"